From nobody Sat Apr 18 04:21:49 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2D846CCA479 for ; Mon, 18 Jul 2022 17:05:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235766AbiGRRFu (ORCPT ); Mon, 18 Jul 2022 13:05:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57254 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235677AbiGRRFq (ORCPT ); Mon, 18 Jul 2022 13:05:46 -0400 Received: from mail-pg1-x535.google.com (mail-pg1-x535.google.com [IPv6:2607:f8b0:4864:20::535]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 77B752BB2C for ; Mon, 18 Jul 2022 10:05:45 -0700 (PDT) Received: by mail-pg1-x535.google.com with SMTP id o18so11133101pgu.9 for ; Mon, 18 Jul 2022 10:05:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=8D/oi8qgxVglaE+KkXtnFYaHMrc21lTodlCKwN8q0IQ=; b=6NTHNWDkGfN7I+U3W+qmMcN0LlUVIhzQVfmatvueYDhm8xc3F4XrNe3HMFoK47IaeP wezuL4aRYBbBQbfcTX6JLbwTLYCb6mq25SW67gKOZRSMVOOn9ugx9Du/yLIya1jEXiGa VaLqwovf483nx9vII+fm0YIOZKj3Je/TzzINbqEZBo+KvLTzAQ79d3DtpvrydepRM+i5 YsD2Eidv3FO5D50/wsetAe86PBnZdrehL4o2bdHfVEgSmy+pVZKLQ4n4yt4wPXyejx2Q yZkNzkd/0jDcSycMCWUv6lNEvloqo4BB9asMOgTq7RRA5XOLGZGz8j+W2LKSmBcQCAU9 k4aQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=8D/oi8qgxVglaE+KkXtnFYaHMrc21lTodlCKwN8q0IQ=; b=3lnK6TQUeWjYk7gg3bumt/ZdpkXd8OkO4OL7eOo5HSpJTk0mPMPVSRDbOMeA/DWLCu NmqSUndZ+PAkvm7HpXeA48/6ql/yPd4R925XObTRl6mC84pGxdKp0xF5kHAploihm5HP ppAmGnpmmUPVTzf1KPXX2/+e3WJgohMq++xcJHpM1FVXJU2EcAbtCIhjJzGuSh8C/2/f Ap36RnEUs2iHNrLrbt5Qcx+PPxO8r+1mc5rfgNDZV4mTGTGC1NU2e7OVrXOqB9u51L1J C/NzxckQVqBrwRCHcJwfzhDCP+b0hPS04GdZelT89o/LQ25q/Rik4ph+xEOpbdw439Bp g+aQ== X-Gm-Message-State: AJIora+BzpD/W0rfcwqoH75YBmu2khfuvt3u/1NwheupINRF87U6CLng lLe70CTQzKIwxYVMVMgYEweP/H6LeE7FzQ== X-Google-Smtp-Source: AGRyM1vFaRliljxiyhBObWT8RV5lv8cN9afUQtCB8wCNEDbktpQqD63FFaGhCAEBugkoEzCPluKhgw== X-Received: by 2002:a63:ec15:0:b0:412:6fb4:88fb with SMTP id j21-20020a63ec15000000b004126fb488fbmr24847293pgh.49.1658163944724; Mon, 18 Jul 2022 10:05:44 -0700 (PDT) Received: from atishp.ba.rivosinc.com ([66.220.2.162]) by smtp.gmail.com with ESMTPSA id r10-20020a170902be0a00b0016bc947c5b7sm9733402pls.38.2022.07.18.10.05.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Jul 2022 10:05:44 -0700 (PDT) From: Atish Patra To: linux-kernel@vger.kernel.org Cc: Atish Patra , Albert Ou , Anup Patel , Atish Patra , Guo Ren , kvm-riscv@lists.infradead.org, kvm@vger.kernel.org, linux-riscv@lists.infradead.org, Mark Rutland , Palmer Dabbelt , Paul Walmsley , Will Deacon Subject: [RFC 1/9] RISC-V: Define a helper function to probe number of hardware counters Date: Mon, 18 Jul 2022 10:01:57 -0700 Message-Id: <20220718170205.2972215-2-atishp@rivosinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220718170205.2972215-1-atishp@rivosinc.com> References: <20220718170205.2972215-1-atishp@rivosinc.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" KVM module needs to know how many hardware counters the platform supports. Otherwise, it will not be able to show optimal value of virtual counters to the guest. Signed-off-by: Atish Patra --- drivers/perf/riscv_pmu_sbi.c | 23 +++++++++++++++++------ include/linux/perf/riscv_pmu.h | 4 ++++ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c index 24124546844c..1723af68ffa1 100644 --- a/drivers/perf/riscv_pmu_sbi.c +++ b/drivers/perf/riscv_pmu_sbi.c @@ -27,6 +27,7 @@ */ static union sbi_pmu_ctr_info *pmu_ctr_list; static unsigned int riscv_pmu_irq; +static struct riscv_pmu *rvpmu; =20 struct sbi_pmu_event_data { union { @@ -227,6 +228,12 @@ static const struct sbi_pmu_event_data pmu_cache_event= _map[PERF_COUNT_HW_CACHE_M }, }; =20 +int riscv_pmu_sbi_get_num_hw_ctrs(void) +{ + return rvpmu ? rvpmu->num_hw_counters : 0; +} +EXPORT_SYMBOL(riscv_pmu_sbi_get_num_hw_ctrs); + static int pmu_sbi_ctr_get_width(int idx) { return pmu_ctr_list[idx].width; @@ -443,7 +450,7 @@ static int pmu_sbi_find_num_ctrs(void) return sbi_err_map_linux_errno(ret.error); } =20 -static int pmu_sbi_get_ctrinfo(int nctr) +static int pmu_sbi_get_ctrinfo(int nctr, int *num_hw_ctrs) { struct sbiret ret; int i, num_hw_ctr =3D 0, num_fw_ctr =3D 0; @@ -453,7 +460,7 @@ static int pmu_sbi_get_ctrinfo(int nctr) if (!pmu_ctr_list) return -ENOMEM; =20 - for (i =3D 0; i <=3D nctr; i++) { + for (i =3D 0; i < nctr; i++) { ret =3D sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_GET_INFO, i, 0, 0, 0,= 0, 0); if (ret.error) /* The logical counter ids are not expected to be contiguous */ @@ -466,6 +473,7 @@ static int pmu_sbi_get_ctrinfo(int nctr) pmu_ctr_list[i].value =3D cinfo.value; } =20 + *num_hw_ctrs =3D num_hw_ctr; pr_info("%d firmware and %d hardware counters\n", num_fw_ctr, num_hw_ctr); =20 return 0; @@ -698,7 +706,7 @@ static int pmu_sbi_setup_irqs(struct riscv_pmu *pmu, st= ruct platform_device *pde static int pmu_sbi_device_probe(struct platform_device *pdev) { struct riscv_pmu *pmu =3D NULL; - int num_counters; + int num_counters, num_hw_ctrs =3D 0; int ret =3D -ENODEV; =20 pr_info("SBI PMU extension is available\n"); @@ -713,7 +721,7 @@ static int pmu_sbi_device_probe(struct platform_device = *pdev) } =20 /* cache all the information about counters now */ - if (pmu_sbi_get_ctrinfo(num_counters)) + if (pmu_sbi_get_ctrinfo(num_counters, &num_hw_ctrs)) goto out_free; =20 ret =3D pmu_sbi_setup_irqs(pmu, pdev); @@ -723,6 +731,7 @@ static int pmu_sbi_device_probe(struct platform_device = *pdev) pmu->pmu.capabilities |=3D PERF_PMU_CAP_NO_EXCLUDE; } pmu->num_counters =3D num_counters; + pmu->num_hw_counters =3D num_hw_ctrs; pmu->ctr_start =3D pmu_sbi_ctr_start; pmu->ctr_stop =3D pmu_sbi_ctr_stop; pmu->event_map =3D pmu_sbi_event_map; @@ -733,14 +742,16 @@ static int pmu_sbi_device_probe(struct platform_devic= e *pdev) =20 ret =3D cpuhp_state_add_instance(CPUHP_AP_PERF_RISCV_STARTING, &pmu->node= ); if (ret) - return ret; + goto out_free; =20 ret =3D perf_pmu_register(&pmu->pmu, "cpu", PERF_TYPE_RAW); if (ret) { cpuhp_state_remove_instance(CPUHP_AP_PERF_RISCV_STARTING, &pmu->node); - return ret; + goto out_free; } =20 + rvpmu =3D pmu; + return 0; =20 out_free: diff --git a/include/linux/perf/riscv_pmu.h b/include/linux/perf/riscv_pmu.h index 46f9b6fe306e..fc47167e000c 100644 --- a/include/linux/perf/riscv_pmu.h +++ b/include/linux/perf/riscv_pmu.h @@ -46,6 +46,7 @@ struct riscv_pmu { irqreturn_t (*handle_irq)(int irq_num, void *dev); =20 int num_counters; + int num_hw_counters; u64 (*ctr_read)(struct perf_event *event); int (*ctr_get_idx)(struct perf_event *event); int (*ctr_get_width)(int idx); @@ -69,6 +70,9 @@ void riscv_pmu_legacy_skip_init(void); static inline void riscv_pmu_legacy_skip_init(void) {}; #endif struct riscv_pmu *riscv_pmu_alloc(void); +#ifdef CONFIG_RISCV_PMU_SBI +int riscv_pmu_sbi_get_num_hw_ctrs(void); +#endif =20 #endif /* CONFIG_RISCV_PMU */ =20 --=20 2.25.1 From nobody Sat Apr 18 04:21:49 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 77E3AC433EF for ; Mon, 18 Jul 2022 17:05:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234759AbiGRRFy (ORCPT ); Mon, 18 Jul 2022 13:05:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57232 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235625AbiGRRFr (ORCPT ); Mon, 18 Jul 2022 13:05:47 -0400 Received: from mail-pj1-x1035.google.com (mail-pj1-x1035.google.com [IPv6:2607:f8b0:4864:20::1035]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id ACF192BB1A for ; Mon, 18 Jul 2022 10:05:46 -0700 (PDT) Received: by mail-pj1-x1035.google.com with SMTP id b10so1434286pjq.5 for ; Mon, 18 Jul 2022 10:05:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=H7ChdRBKS+9A003EiQbM2SMDrKCCYQePnInXhSsyMB0=; b=2V7H54kc+3zNv1TcuveEZhkWNgIt1ocwR1qZtOLzfciyvULmAUYAVdSYvDM/LMqPW7 B2K1L+wSiEDZFuMDMucw3/YkGg89OijRh8dtnIplDxavoLr+HLhF1RSyQXxCnRG/72Tf KHeNwRoBhGw0rXQdnYIWadk5aSrZwLj7I/0cV0ZkgQrHx0ezw5iLQkZg1Uak7Z5I0sqE qFLiHdxohtP+MR29CMLuGTlZRid3ndTvwyv2IFhPeeJPuBbWKdNqbpz4KKb8bRDh9SWd v8nTz6wqG+l9bP6qNs15D6dX6qH+nOrr4SmzAUcKI22h5JluwKsyWFI5ud4IQSpY+eeR W4Xg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=H7ChdRBKS+9A003EiQbM2SMDrKCCYQePnInXhSsyMB0=; b=GKI0/4YhsEzxmyf0Q4K+6QBAOn5EKlLnj50/8Zw9s6RXatvjYOSSRBMxpA7X+9hci3 H1z8mmNki8qn6BTjBaOJsHtuK7S1CF8831HKnT5qcnrDDdzpxZxST680SE7lU0FsLG1L C2WF11/pFj3gyzmHNoqG7oTg6oSncToKY+L36i67yaPfUOo0e88Kl/3ksimCmbcyIM9Z n8cBG/kviOUW/aqeKQccPE0uee0nELvydBsi112xKzQq3BAaoOuBpSjOj0ZaMr1KSw3m GdSbDG/TXJ4K2Fjdxp2wVO1g99+/JkcYC3gLRAAzay3YYb+nGYETdCDdM8olbuojh7oA txBQ== X-Gm-Message-State: AJIora/ci7AhZqlZD4t1DInUtQWmrHozhiHSxT5HCFVrhd/5kim/R3rQ 4ZQKyqYJPO6ZmQg+oM3/pMDbmer0iGpiQQ== X-Google-Smtp-Source: AGRyM1uvFkWFiSwIv2bxiYnsB/Me0O2umAIdMXnBAJupJyduccoZ2CTvIm6kzqVVu3DQdq7Cn7s+hQ== X-Received: by 2002:a17:902:a413:b0:156:15b:524a with SMTP id p19-20020a170902a41300b00156015b524amr30012463plq.106.1658163945893; Mon, 18 Jul 2022 10:05:45 -0700 (PDT) Received: from atishp.ba.rivosinc.com ([66.220.2.162]) by smtp.gmail.com with ESMTPSA id r10-20020a170902be0a00b0016bc947c5b7sm9733402pls.38.2022.07.18.10.05.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Jul 2022 10:05:45 -0700 (PDT) From: Atish Patra To: linux-kernel@vger.kernel.org Cc: Atish Patra , Albert Ou , Anup Patel , Atish Patra , Guo Ren , kvm-riscv@lists.infradead.org, kvm@vger.kernel.org, linux-riscv@lists.infradead.org, Mark Rutland , Palmer Dabbelt , Paul Walmsley , Will Deacon Subject: [RFC 2/9] RISC-V: Define a helper function to return counter width Date: Mon, 18 Jul 2022 10:01:58 -0700 Message-Id: <20220718170205.2972215-3-atishp@rivosinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220718170205.2972215-1-atishp@rivosinc.com> References: <20220718170205.2972215-1-atishp@rivosinc.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The virtual hardware counters need to have the same width as the logical hardware counters for simplicity. However, there shouldn't be mapping between virtual hardware counters and logical hardware counters. As we don't support hetergeneous harts or counters with different width as of now, the implementation relies on the counter width of the first available programmable counter. Signed-off-by: Atish Patra --- drivers/perf/riscv_pmu_sbi.c | 25 +++++++++++++++++++++++++ include/linux/perf/riscv_pmu.h | 1 + 2 files changed, 26 insertions(+) diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c index 1723af68ffa1..5d0eef3ef136 100644 --- a/drivers/perf/riscv_pmu_sbi.c +++ b/drivers/perf/riscv_pmu_sbi.c @@ -250,6 +250,31 @@ static bool pmu_sbi_ctr_is_fw(int cidx) return (info->type =3D=3D SBI_PMU_CTR_TYPE_FW) ? true : false; } =20 +/* + * Returns the counter width of a programmable counter + * As we don't support heterneous CPUs yet, it is okay to just + * return the counter width of the first programmable counter. + */ +int riscv_pmu_sbi_hpmc_width(void) +{ + int i; + union sbi_pmu_ctr_info *info; + + if (!rvpmu) + return -EINVAL; + + for (i =3D 0; i < rvpmu->num_counters; i++) { + info =3D &pmu_ctr_list[i]; + if (!info) + continue; + if (info->type =3D=3D SBI_PMU_CTR_TYPE_HW) + return info->width; + } + + return 0; +} +EXPORT_SYMBOL(riscv_pmu_sbi_hpmc_width); + static int pmu_sbi_ctr_get_idx(struct perf_event *event) { struct hw_perf_event *hwc =3D &event->hw; diff --git a/include/linux/perf/riscv_pmu.h b/include/linux/perf/riscv_pmu.h index fc47167e000c..6fee211c27b5 100644 --- a/include/linux/perf/riscv_pmu.h +++ b/include/linux/perf/riscv_pmu.h @@ -72,6 +72,7 @@ static inline void riscv_pmu_legacy_skip_init(void) {}; struct riscv_pmu *riscv_pmu_alloc(void); #ifdef CONFIG_RISCV_PMU_SBI int riscv_pmu_sbi_get_num_hw_ctrs(void); +int riscv_pmu_sbi_hpmc_width(void); #endif =20 #endif /* CONFIG_RISCV_PMU */ --=20 2.25.1 From nobody Sat Apr 18 04:21:49 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DB04DC433EF for ; Mon, 18 Jul 2022 17:05:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235807AbiGRRF6 (ORCPT ); Mon, 18 Jul 2022 13:05:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57368 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235719AbiGRRFt (ORCPT ); Mon, 18 Jul 2022 13:05:49 -0400 Received: from mail-pj1-x102e.google.com (mail-pj1-x102e.google.com [IPv6:2607:f8b0:4864:20::102e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D41652BB07 for ; Mon, 18 Jul 2022 10:05:47 -0700 (PDT) Received: by mail-pj1-x102e.google.com with SMTP id u7-20020a17090a3fc700b001f1efc76be2so67818pjm.1 for ; Mon, 18 Jul 2022 10:05:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=yTc6DPtRL3G/t0xkTGIGozwG47F+csFvT/B18Fnd6bA=; b=FzhoHCa1YsaXYQ8x7nWgTmqf0KgVR4ynTwb6sSm5eIdHHC8iMhZW6RP3czhrR5n8g/ X2JKnvYBb1H58qTMZKXWi9CM1ZQO1mXLe07lVJd/+LwRh8tfBcmzbSFcotIZJhPLOUWu aehAPylHZQU7yz4IYfdL02Wz2JwbZBANg72NQqo5gHm2pA6TKHd81Ze1FoShkQs4WMAt J+F55ANKBQ+2NGW0+hnosnafLochQp/Rt3MrI+yMQtV7Uur5M1fuFzysZl9w/7EcuczN G2ZkIM824pXrYATCqnGXtVd4QVts+VWdN9ZLCDXaCjhqlcydUTORkG9xZukPNK7yHSzu CVBQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=yTc6DPtRL3G/t0xkTGIGozwG47F+csFvT/B18Fnd6bA=; b=cKqHIoADxIZad6lJQL/b8zRHgNMKo+q+1b9WTYf/fnguRFk9JJ4XRRiBut622xAjQ3 a7hZ06ZKHlF4YBZK2+K9YFMp/BK79p9RxuZbEYGw25KljklYNjP5AxLH9pn8prxkpGya 0N5PUyv3n2aFia0YcFXWVWTj1ZrO753j7Zx+4UxVbKHSL8mbGfNQ02DSM0CvMmDZ3iRO aUOC+FBn4jD/TQxOBi2uDSI63PfDKfpHoAA5Tp08ltNRIQ1ebJBp72dpMb+b44BHYk6N vqckNcROJalLtonFd4AvuZG9+7VBf21Eh/rs9p3bZRmieYR0wV2QtJ1iAEQ7p5vhhkuV A6FA== X-Gm-Message-State: AJIora9nFlr7OAseBpeOpUMJl6iFN9NzODq0oNS1ex3sz2A/XdNEmfMi xEvK1XNKl3s4CjwpDqEwQkzOcDqRFBwjVA== X-Google-Smtp-Source: AGRyM1vW5t5W2twVvakvKZTko7lrN5ufYsRsPOvNvHFZUUuebHERK+y/x9Mil/Ly2FlTRRbMLZDwYg== X-Received: by 2002:a17:90a:ca14:b0:1f1:664a:241 with SMTP id x20-20020a17090aca1400b001f1664a0241mr17356543pjt.184.1658163947139; Mon, 18 Jul 2022 10:05:47 -0700 (PDT) Received: from atishp.ba.rivosinc.com ([66.220.2.162]) by smtp.gmail.com with ESMTPSA id r10-20020a170902be0a00b0016bc947c5b7sm9733402pls.38.2022.07.18.10.05.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Jul 2022 10:05:46 -0700 (PDT) From: Atish Patra To: linux-kernel@vger.kernel.org Cc: Atish Patra , Albert Ou , Anup Patel , Atish Patra , Guo Ren , kvm-riscv@lists.infradead.org, kvm@vger.kernel.org, linux-riscv@lists.infradead.org, Mark Rutland , Palmer Dabbelt , Paul Walmsley , Will Deacon Subject: [RFC 3/9] RISC-V: KVM: Define a probe function for SBI extension data structures Date: Mon, 18 Jul 2022 10:01:59 -0700 Message-Id: <20220718170205.2972215-4-atishp@rivosinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220718170205.2972215-1-atishp@rivosinc.com> References: <20220718170205.2972215-1-atishp@rivosinc.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" c,urrently the probe function just check if an SBI extension is registered or not. However, the extension may not want to advertise itself depending on some other condition. An additional extension specific probe function will allow extensions to decide if they want to be advertised to the caller or not. Any extension that do not require additional dependency check does not required to implement this function. Signed-off-by: Atish Patra Reviewed-by: Andrew Jones --- arch/riscv/include/asm/kvm_vcpu_sbi.h | 3 +++ arch/riscv/kvm/vcpu_sbi_base.c | 13 +++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/arch/riscv/include/asm/kvm_vcpu_sbi.h b/arch/riscv/include/asm= /kvm_vcpu_sbi.h index 83d6d4d2b1df..5853a1ef71ea 100644 --- a/arch/riscv/include/asm/kvm_vcpu_sbi.h +++ b/arch/riscv/include/asm/kvm_vcpu_sbi.h @@ -25,6 +25,9 @@ struct kvm_vcpu_sbi_extension { int (*handler)(struct kvm_vcpu *vcpu, struct kvm_run *run, unsigned long *out_val, struct kvm_cpu_trap *utrap, bool *exit); + + /* Extension specific probe function */ + unsigned long (*probe)(unsigned long extid); }; =20 void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, struct kvm_run *run= ); diff --git a/arch/riscv/kvm/vcpu_sbi_base.c b/arch/riscv/kvm/vcpu_sbi_base.c index 48f431091cdb..14be1a819588 100644 --- a/arch/riscv/kvm/vcpu_sbi_base.c +++ b/arch/riscv/kvm/vcpu_sbi_base.c @@ -22,6 +22,7 @@ static int kvm_sbi_ext_base_handler(struct kvm_vcpu *vcpu= , struct kvm_run *run, int ret =3D 0; struct kvm_cpu_context *cp =3D &vcpu->arch.guest_context; struct sbiret ecall_ret; + const struct kvm_vcpu_sbi_extension *sbi_ext; =20 switch (cp->a6) { case SBI_EXT_BASE_GET_SPEC_VERSION: @@ -46,8 +47,16 @@ static int kvm_sbi_ext_base_handler(struct kvm_vcpu *vcp= u, struct kvm_run *run, */ kvm_riscv_vcpu_sbi_forward(vcpu, run); *exit =3D true; - } else - *out_val =3D kvm_vcpu_sbi_find_ext(cp->a0) ? 1 : 0; + } else { + sbi_ext =3D kvm_vcpu_sbi_find_ext(cp->a0); + if (sbi_ext) { + if (sbi_ext->probe) + *out_val =3D sbi_ext->probe(cp->a0); + else + *out_val =3D 1; + } else + *out_val =3D 0; + } break; case SBI_EXT_BASE_GET_MVENDORID: case SBI_EXT_BASE_GET_MARCHID: --=20 2.25.1 From nobody Sat Apr 18 04:21:49 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 76DDBCCA486 for ; Mon, 18 Jul 2022 17:06:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235730AbiGRRGD (ORCPT ); Mon, 18 Jul 2022 13:06:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57602 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235625AbiGRRF5 (ORCPT ); Mon, 18 Jul 2022 13:05:57 -0400 Received: from mail-pj1-x102c.google.com (mail-pj1-x102c.google.com [IPv6:2607:f8b0:4864:20::102c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 442582C11D for ; Mon, 18 Jul 2022 10:05:49 -0700 (PDT) Received: by mail-pj1-x102c.google.com with SMTP id q13-20020a17090a304d00b001f1af9a18a2so4742795pjl.5 for ; Mon, 18 Jul 2022 10:05:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=/3vtOzL7H/3FhOEqt+TCzYFt3aLP8b6PmqU5Yxo7Fj8=; b=4uEa5LBy0DKcY8uwawFXfJDcyP2Fi+jae6+kTt2b2wiPbEE7wbhzRSXq/FBGMgOi/f hw86VLNxjdNtEI0yE51+u//XmslDWbju8DkFTny20OYQvzxqBoeGLkiEKPgITsrsNH0h qQRnpeE8Hwj4q3l6kiYjSyvG3r9D1tENLERXnC58erWdoBU1yy9KVWDXVVuCJbNyZVMu sq8BZOG2Ng3wxgfDGCyKf5yxkMdcvfdb+2Bf7FYJ4fM5MEmBHRL43SS/HZ+TFCiGQNl/ eungSt9TWAodD9oHT7M2KCyNnNMMLzfGz5/ts/D2ADF68OzVyKx2zafdBTLeTq5jeMw+ oYUw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/3vtOzL7H/3FhOEqt+TCzYFt3aLP8b6PmqU5Yxo7Fj8=; b=mD4aXJvfQX1gGYbyWKa1w2aFmPT77TMO5gLJRg/lMKk+3H1IEK9tQUPIBBy9fCU6zT RcTUnkz1ZqsQrmo1RlP2uxiMileVOK2k46V3O59Rcm0hy5mTCYCDr89W4kFnYWxCGJ/b KFw2SxmZ8ml08tygwi9qZejelhXG2lQkvfPqvDTKK2qdtob3LmQ7WIm/cfn5oBHGw8DK 9yLwUrCXQqTlXp1Hh3+qGMJkkKg202sAWuE1JWDyZX7UovaGlu/Q2kSaMKTj8Dgo0I2g OXfAkLdi8APFLBVLYykRPa61MYSmYmsivqAzxBC91gUlppK8uGDbmuWqAjRsf59ZIvXF 8W8w== X-Gm-Message-State: AJIora83czC5Q2kvMTlVyArpSCm4nqdwwtjKTgn2d/sFLe2DFET4wqAX eJ2Z3nmOolw4UOo87WSPUc7wEn3fhkWsZg== X-Google-Smtp-Source: AGRyM1uSWzV58VCzHYwLZkTFFYZNxcIXLVpIo0ybe2iNKjofq3fVvwFRP5hLtK6LTf38a8cYPsHKQw== X-Received: by 2002:a17:90b:388e:b0:1f0:3d7f:e620 with SMTP id mu14-20020a17090b388e00b001f03d7fe620mr34153286pjb.31.1658163948380; Mon, 18 Jul 2022 10:05:48 -0700 (PDT) Received: from atishp.ba.rivosinc.com ([66.220.2.162]) by smtp.gmail.com with ESMTPSA id r10-20020a170902be0a00b0016bc947c5b7sm9733402pls.38.2022.07.18.10.05.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Jul 2022 10:05:48 -0700 (PDT) From: Atish Patra To: linux-kernel@vger.kernel.org Cc: Atish Patra , Albert Ou , Anup Patel , Atish Patra , Guo Ren , kvm-riscv@lists.infradead.org, kvm@vger.kernel.org, linux-riscv@lists.infradead.org, Mark Rutland , Palmer Dabbelt , Paul Walmsley , Will Deacon Subject: [RFC 4/9] RISC-V: KVM: Improve privilege mode filtering for perf Date: Mon, 18 Jul 2022 10:02:00 -0700 Message-Id: <20220718170205.2972215-5-atishp@rivosinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220718170205.2972215-1-atishp@rivosinc.com> References: <20220718170205.2972215-1-atishp@rivosinc.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Currently, the host driver doesn't have any method to identify if the requested perf event is from kvm or bare metal. As KVM runs in HS mode, there are no separate hypervisor privilege mode to distinguish between the attributes for guest/host. Improve the privilege mode filtering by using the event specific config1 field. Signed-off-by: Atish Patra Reviewed-by: Andrew Jones --- drivers/perf/riscv_pmu_sbi.c | 27 ++++++++++++++++++++++----- include/linux/perf/riscv_pmu.h | 2 ++ 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c index 5d0eef3ef136..34f9fcc221a8 100644 --- a/drivers/perf/riscv_pmu_sbi.c +++ b/drivers/perf/riscv_pmu_sbi.c @@ -275,6 +275,27 @@ int riscv_pmu_sbi_hpmc_width(void) } EXPORT_SYMBOL(riscv_pmu_sbi_hpmc_width); =20 +static unsigned long pmu_sbi_get_filter_flags(struct perf_event *event) +{ + unsigned long cflags =3D 0; + bool guest_events =3D false; + + if (event->attr.config1 & RISCV_KVM_PMU_CONFIG1_GUEST_EVENTS) + guest_events =3D true; + if (event->attr.exclude_kernel) + cflags |=3D guest_events ? SBI_PMU_CFG_FLAG_SET_VSINH : SBI_PMU_CFG_FLAG= _SET_SINH; + if (event->attr.exclude_user) + cflags |=3D guest_events ? SBI_PMU_CFG_FLAG_SET_VUINH : SBI_PMU_CFG_FLAG= _SET_UINH; + if (guest_events && event->attr.exclude_hv) + cflags |=3D SBI_PMU_CFG_FLAG_SET_SINH; + if (event->attr.exclude_host) + cflags |=3D SBI_PMU_CFG_FLAG_SET_UINH | SBI_PMU_CFG_FLAG_SET_SINH; + if (event->attr.exclude_guest) + cflags |=3D SBI_PMU_CFG_FLAG_SET_VSINH | SBI_PMU_CFG_FLAG_SET_VUINH; + + return cflags; +} + static int pmu_sbi_ctr_get_idx(struct perf_event *event) { struct hw_perf_event *hwc =3D &event->hw; @@ -286,11 +307,7 @@ static int pmu_sbi_ctr_get_idx(struct perf_event *even= t) uint64_t cmask =3D GENMASK_ULL(rvpmu->num_counters - 1, 0); unsigned long cflags =3D 0; =20 - if (event->attr.exclude_kernel) - cflags |=3D SBI_PMU_CFG_FLAG_SET_SINH; - if (event->attr.exclude_user) - cflags |=3D SBI_PMU_CFG_FLAG_SET_UINH; - + cflags =3D pmu_sbi_get_filter_flags(event); /* retrieve the available counter index */ #if defined(CONFIG_32BIT) ret =3D sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_CFG_MATCH, cbase, cmas= k, diff --git a/include/linux/perf/riscv_pmu.h b/include/linux/perf/riscv_pmu.h index 6fee211c27b5..825b95253bc5 100644 --- a/include/linux/perf/riscv_pmu.h +++ b/include/linux/perf/riscv_pmu.h @@ -26,6 +26,8 @@ =20 #define RISCV_PMU_STOP_FLAG_RESET 1 =20 +#define RISCV_KVM_PMU_CONFIG1_GUEST_EVENTS 0x1 + struct cpu_hw_events { /* currently enabled events */ int n_events; --=20 2.25.1 From nobody Sat Apr 18 04:21:49 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4B903C433EF for ; Mon, 18 Jul 2022 17:06:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235822AbiGRRGL (ORCPT ); Mon, 18 Jul 2022 13:06:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57624 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235778AbiGRRF5 (ORCPT ); Mon, 18 Jul 2022 13:05:57 -0400 Received: from mail-pj1-x1035.google.com (mail-pj1-x1035.google.com [IPv6:2607:f8b0:4864:20::1035]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 233D52C101 for ; Mon, 18 Jul 2022 10:05:50 -0700 (PDT) Received: by mail-pj1-x1035.google.com with SMTP id b10so1434467pjq.5 for ; Mon, 18 Jul 2022 10:05:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=g0GXt84vLJgSh96R08zPlPoGq5zRKrVm2Ojh33nPRNc=; b=HgvjExTpPKlEjTRtSNLbdzm9LKmieF9qEs4xJP2LurrKxwYLXTas/D1PhqWPwMtd17 uXNpptix6gFoMRy6B5gqVQdxRTc4tB8ag+7kUYjb4odhRT9dPaA5Lc2kvgVSzyf5meKI W/tfu4dz7K9rPUjRI4dHd+CRVB8u+x8nEqgRSaK+YgC5zDoy41GtLW5AMij16DZqhZBD UN7HC11UkbvvCvj1rgEwWpDwaeva3Ou9kmA11c49GJg83V2o0TpHm2tHQ3EgVIL40njI ny3LFt5kRDkD+YLUDrZyeMC0Pn9/wYDY8mosBvrqoaUEhGWWf7jYhMliDxX1ZNq9sryw vAbg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=g0GXt84vLJgSh96R08zPlPoGq5zRKrVm2Ojh33nPRNc=; b=nN7dSBi4j7dvl9i/N41pde/avMc0uWLn9usgtP+BGAKdHJxm3wYc6PpTDemwMy51Zj r+Ku+Oe986kHypfpjG6RPFeKkqsCQ0tOSb+Mu41bPQgn+Y+NxK7ch+co6x6bq1jXUbJr Hc1EsUAtF4pmKgFuO0UR4CpjaCACMpw+wZfdcJ6F3i+iIl6BhfzNtLImGI6hN/HgzpN0 CAC03KrRh0U04uwKKMZIOp27t/A6V8KKH5f7pdmclHsuSjvRRBaTmbnp2b4wIWlZpreo W0YvERb2NGxUZphuTC59PcfVgUe7zVgo5TmCHnPTXLrVCA2b9/YO1RiUwPfyfwqN5+vr 4s/w== X-Gm-Message-State: AJIora825J1unrz7scpMUMa7qQkt/kRriOiIWsPDAqXGSWdlJx4bYfA4 PBq5jwwZMCMWnEhjkFu4H+FRBUry/kdmwA== X-Google-Smtp-Source: AGRyM1tS6zC84MRMFbRJz9tvWCxV+RPsnhP4oYyrw87iUd3saJSSLC62JLntxczMfiMlDUf7vVWivA== X-Received: by 2002:a17:90b:33ce:b0:1ef:e5f4:f8e2 with SMTP id lk14-20020a17090b33ce00b001efe5f4f8e2mr41166287pjb.70.1658163949636; Mon, 18 Jul 2022 10:05:49 -0700 (PDT) Received: from atishp.ba.rivosinc.com ([66.220.2.162]) by smtp.gmail.com with ESMTPSA id r10-20020a170902be0a00b0016bc947c5b7sm9733402pls.38.2022.07.18.10.05.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Jul 2022 10:05:49 -0700 (PDT) From: Atish Patra To: linux-kernel@vger.kernel.org Cc: Atish Patra , Albert Ou , Anup Patel , Atish Patra , Guo Ren , kvm-riscv@lists.infradead.org, kvm@vger.kernel.org, linux-riscv@lists.infradead.org, Mark Rutland , Palmer Dabbelt , Paul Walmsley , Will Deacon Subject: [RFC 5/9] RISC-V: KVM: Add skeleton support for perf Date: Mon, 18 Jul 2022 10:02:01 -0700 Message-Id: <20220718170205.2972215-6-atishp@rivosinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220718170205.2972215-1-atishp@rivosinc.com> References: <20220718170205.2972215-1-atishp@rivosinc.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This patch only adds barebore structure of perf implementation. Most of the function returns zero at this point and will be implemented fully in the future. Signed-off-by: Atish Patra --- arch/riscv/include/asm/kvm_host.h | 3 + arch/riscv/include/asm/kvm_vcpu_pmu.h | 70 +++++++++++++ arch/riscv/kvm/Makefile | 1 + arch/riscv/kvm/main.c | 3 +- arch/riscv/kvm/vcpu.c | 5 + arch/riscv/kvm/vcpu_insn.c | 3 +- arch/riscv/kvm/vcpu_pmu.c | 136 ++++++++++++++++++++++++++ 7 files changed, 219 insertions(+), 2 deletions(-) create mode 100644 arch/riscv/include/asm/kvm_vcpu_pmu.h create mode 100644 arch/riscv/kvm/vcpu_pmu.c diff --git a/arch/riscv/include/asm/kvm_host.h b/arch/riscv/include/asm/kvm= _host.h index 59a0cf2ca7b9..5d2312828bb2 100644 --- a/arch/riscv/include/asm/kvm_host.h +++ b/arch/riscv/include/asm/kvm_host.h @@ -18,6 +18,7 @@ #include #include #include +#include =20 #define KVM_MAX_VCPUS 1024 =20 @@ -226,6 +227,8 @@ struct kvm_vcpu_arch { =20 /* Don't run the VCPU (blocked) */ bool pause; + + struct kvm_pmu pmu; }; =20 static inline void kvm_arch_hardware_unsetup(void) {} diff --git a/arch/riscv/include/asm/kvm_vcpu_pmu.h b/arch/riscv/include/asm= /kvm_vcpu_pmu.h new file mode 100644 index 000000000000..bffee052f2ae --- /dev/null +++ b/arch/riscv/include/asm/kvm_vcpu_pmu.h @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022 Rivos Inc + * + * Authors: + * Atish Patra + */ + +#ifndef _KVM_VCPU_RISCV_PMU_H +#define _KVM_VCPU_RISCV_PMU_H + +#include +#include + +#ifdef CONFIG_RISCV_PMU_SBI +#define RISCV_KVM_MAX_FW_CTRS 32 + +/* Per virtual pmu counter data */ +struct kvm_pmc { + u8 idx; + struct kvm_vcpu *vcpu; + struct perf_event *perf_event; + uint64_t counter_val; + union sbi_pmu_ctr_info cinfo; +}; + +/* PMU data structure per vcpu */ +struct kvm_pmu { + struct kvm_pmc pmc[RISCV_MAX_COUNTERS]; + /* Number of the virtual firmware counters available */ + int num_fw_ctrs; + /* Number of the virtual hardware counters available */ + int num_hw_ctrs; + /* Bit map of all the virtual counter used */ + DECLARE_BITMAP(used_pmc, RISCV_MAX_COUNTERS); +}; + +#define vcpu_to_pmu(vcpu) (&(vcpu)->arch.pmu) +#define pmu_to_vcpu(pmu) (container_of((pmu), struct kvm_vcpu, arch.pmu)) +#define pmc_to_pmu(pmc) (&(pmc)->vcpu->arch.pmu) + +int kvm_riscv_vcpu_pmu_num_ctrs(struct kvm_vcpu *vcpu, unsigned long *out_= val); +int kvm_riscv_vcpu_pmu_ctr_info(struct kvm_vcpu *vcpu, unsigned long cidx, + unsigned long *ctr_info); + +int kvm_riscv_vcpu_pmu_ctr_start(struct kvm_vcpu *vcpu, unsigned long ctr_= base, + unsigned long ctr_mask, unsigned long flag, uint64_t ival); +int kvm_riscv_vcpu_pmu_ctr_stop(struct kvm_vcpu *vcpu, unsigned long ctr_b= ase, + unsigned long ctr_mask, unsigned long flag); +int kvm_riscv_vcpu_pmu_ctr_cfg_match(struct kvm_vcpu *vcpu, unsigned long = ctr_base, + unsigned long ctr_mask, unsigned long flag, + unsigned long eidx, uint64_t edata); +int kvm_riscv_vcpu_pmu_ctr_read(struct kvm_vcpu *vcpu, unsigned long cidx, + unsigned long *out_val); +int kvm_riscv_vcpu_pmu_init(struct kvm_vcpu *vcpu); +void kvm_riscv_vcpu_pmu_deinit(struct kvm_vcpu *vcpu); +void kvm_riscv_vcpu_pmu_reset(struct kvm_vcpu *vcpu); + +#else +struct kvm_pmu { +}; + +static inline int kvm_riscv_vcpu_pmu_init(struct kvm_vcpu *vcpu) +{ + return 0; +} +static inline void kvm_riscv_vcpu_pmu_deinit(struct kvm_vcpu *vcpu) {} +static inline void kvm_riscv_vcpu_pmu_reset(struct kvm_vcpu *vcpu) {} +#endif +#endif diff --git a/arch/riscv/kvm/Makefile b/arch/riscv/kvm/Makefile index 019df9208bdd..342d7199e89d 100644 --- a/arch/riscv/kvm/Makefile +++ b/arch/riscv/kvm/Makefile @@ -25,3 +25,4 @@ kvm-y +=3D vcpu_sbi_base.o kvm-y +=3D vcpu_sbi_replace.o kvm-y +=3D vcpu_sbi_hsm.o kvm-y +=3D vcpu_timer.o +kvm-$(CONFIG_RISCV_PMU_SBI) +=3D vcpu_sbi_pmu.o vcpu_pmu.o diff --git a/arch/riscv/kvm/main.c b/arch/riscv/kvm/main.c index 1549205fe5fe..d41ab6d1987d 100644 --- a/arch/riscv/kvm/main.c +++ b/arch/riscv/kvm/main.c @@ -49,7 +49,8 @@ int kvm_arch_hardware_enable(void) hideleg |=3D (1UL << IRQ_VS_EXT); csr_write(CSR_HIDELEG, hideleg); =20 - csr_write(CSR_HCOUNTEREN, -1UL); + /* VS should access only TM bit. Everything else should trap */ + csr_write(CSR_HCOUNTEREN, 0x02); =20 csr_write(CSR_HVIP, 0); =20 diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c index 3c95924d38c7..4cc964aaf2ad 100644 --- a/arch/riscv/kvm/vcpu.c +++ b/arch/riscv/kvm/vcpu.c @@ -122,6 +122,7 @@ static void kvm_riscv_reset_vcpu(struct kvm_vcpu *vcpu) =20 WRITE_ONCE(vcpu->arch.irqs_pending, 0); WRITE_ONCE(vcpu->arch.irqs_pending_mask, 0); + kvm_riscv_vcpu_pmu_reset(vcpu); =20 vcpu->arch.hfence_head =3D 0; vcpu->arch.hfence_tail =3D 0; @@ -174,6 +175,9 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) /* Setup VCPU timer */ kvm_riscv_vcpu_timer_init(vcpu); =20 + /* setup performance monitoring */ + kvm_riscv_vcpu_pmu_init(vcpu); + /* Reset VCPU */ kvm_riscv_reset_vcpu(vcpu); =20 @@ -196,6 +200,7 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) /* Cleanup VCPU timer */ kvm_riscv_vcpu_timer_deinit(vcpu); =20 + kvm_riscv_vcpu_pmu_deinit(vcpu); /* Free unused pages pre-allocated for G-stage page table mappings */ kvm_mmu_free_memory_cache(&vcpu->arch.mmu_page_cache); } diff --git a/arch/riscv/kvm/vcpu_insn.c b/arch/riscv/kvm/vcpu_insn.c index 7eb90a47b571..0aa334f853c8 100644 --- a/arch/riscv/kvm/vcpu_insn.c +++ b/arch/riscv/kvm/vcpu_insn.c @@ -214,7 +214,8 @@ struct csr_func { unsigned long wr_mask); }; =20 -static const struct csr_func csr_funcs[] =3D { }; +static const struct csr_func csr_funcs[] =3D { +}; =20 /** * kvm_riscv_vcpu_csr_return -- Handle CSR read/write after user space diff --git a/arch/riscv/kvm/vcpu_pmu.c b/arch/riscv/kvm/vcpu_pmu.c new file mode 100644 index 000000000000..3168ed740bdd --- /dev/null +++ b/arch/riscv/kvm/vcpu_pmu.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 Rivos Inc + * + * Authors: + * Atish Patra + */ + +#include +#include +#include +#include +#include +#include +#include + +int kvm_riscv_vcpu_pmu_num_ctrs(struct kvm_vcpu *vcpu, unsigned long *out_= val) +{ + struct kvm_pmu *kvpmu =3D vcpu_to_pmu(vcpu); + + if (!kvpmu) + return -EINVAL; + + *out_val =3D kvpmu->num_fw_ctrs + kvpmu->num_hw_ctrs; + return 0; +} + +int kvm_riscv_vcpu_pmu_ctr_info(struct kvm_vcpu *vcpu, unsigned long cidx, + unsigned long *ctr_info) +{ + struct kvm_pmu *kvpmu =3D vcpu_to_pmu(vcpu); + + if (!kvpmu || (cidx > RISCV_MAX_COUNTERS) || (cidx =3D=3D 1)) + return -EINVAL; + + *ctr_info =3D kvpmu->pmc[cidx].cinfo.value; + + return 0; +} + +int kvm_riscv_vcpu_pmu_ctr_start(struct kvm_vcpu *vcpu, unsigned long ctr_= base, + unsigned long ctr_mask, unsigned long flag, uint64_t ival) +{ + /* TODO */ + return 0; +} + +int kvm_riscv_vcpu_pmu_ctr_stop(struct kvm_vcpu *vcpu, unsigned long ctr_b= ase, + unsigned long ctr_mask, unsigned long flag) +{ + /* TODO */ + return 0; +} + +int kvm_riscv_vcpu_pmu_ctr_cfg_match(struct kvm_vcpu *vcpu, unsigned long = ctr_base, + unsigned long ctr_mask, unsigned long flag, + unsigned long eidx, uint64_t edata) +{ + /* TODO */ + return 0; +} + +int kvm_riscv_vcpu_pmu_ctr_read(struct kvm_vcpu *vcpu, unsigned long cidx, + unsigned long *out_val) +{ + /* TODO */ + return 0; +} + +int kvm_riscv_vcpu_pmu_init(struct kvm_vcpu *vcpu) +{ + int i =3D 0, num_hw_ctrs, num_fw_ctrs, hpm_width; + struct kvm_pmu *kvpmu =3D vcpu_to_pmu(vcpu); + + if (!kvpmu) + return -EINVAL; + + num_hw_ctrs =3D riscv_pmu_sbi_get_num_hw_ctrs(); + if ((num_hw_ctrs + RISCV_KVM_MAX_FW_CTRS) > RISCV_MAX_COUNTERS) + num_fw_ctrs =3D RISCV_MAX_COUNTERS - num_hw_ctrs; + else + num_fw_ctrs =3D RISCV_KVM_MAX_FW_CTRS; + + hpm_width =3D riscv_pmu_sbi_hpmc_width(); + if (hpm_width <=3D 0) { + pr_err("Can not initialize PMU for vcpu as hpmcounter width is not avail= able\n"); + return -EINVAL; + } + + kvpmu->num_hw_ctrs =3D num_hw_ctrs; + kvpmu->num_fw_ctrs =3D num_fw_ctrs; + /* + * There is no corelation betwen the logical hardware counter and virtual= counters. + * However, we need to encode a hpmcounter CSR in the counter info field = so that + * KVM can trap n emulate the read. This works well in the migraiton usec= ase as well + * KVM doesn't care if the actual hpmcounter is available in the hardware= or not. + */ + for (i =3D 0; i < num_hw_ctrs + num_fw_ctrs; i++) { + /* TIME CSR shouldn't be read from perf interface */ + if (i =3D=3D 1) + continue; + kvpmu->pmc[i].idx =3D i; + kvpmu->pmc[i].vcpu =3D vcpu; + if (i < kvpmu->num_hw_ctrs) { + kvpmu->pmc[i].cinfo.type =3D SBI_PMU_CTR_TYPE_HW; + if (i < 3) + /* CY, IR counters */ + kvpmu->pmc[i].cinfo.width =3D 63; + else + kvpmu->pmc[i].cinfo.width =3D hpm_width; + /* + * The CSR number doesn't have any relation with the logical + * hardware counters. The CSR numbers are encoded sequentially + * to avoid maintaining a map between the virtual counter + * and CSR number. + */ + kvpmu->pmc[i].cinfo.csr =3D CSR_CYCLE + i; + } else { + kvpmu->pmc[i].cinfo.type =3D SBI_PMU_CTR_TYPE_FW; + kvpmu->pmc[i].cinfo.width =3D BITS_PER_LONG - 1; + } + } + + return 0; +} + +void kvm_riscv_vcpu_pmu_reset(struct kvm_vcpu *vcpu) +{ + /* TODO */ +} + +void kvm_riscv_vcpu_pmu_deinit(struct kvm_vcpu *vcpu) +{ + /* TODO */ +} + --=20 2.25.1 From nobody Sat Apr 18 04:21:49 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 416D0CCA479 for ; Mon, 18 Jul 2022 17:06:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235873AbiGRRGF (ORCPT ); Mon, 18 Jul 2022 13:06:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57404 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235786AbiGRRF6 (ORCPT ); Mon, 18 Jul 2022 13:05:58 -0400 Received: from mail-pj1-x102c.google.com (mail-pj1-x102c.google.com [IPv6:2607:f8b0:4864:20::102c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A553A2C126 for ; Mon, 18 Jul 2022 10:05:51 -0700 (PDT) Received: by mail-pj1-x102c.google.com with SMTP id q13-20020a17090a304d00b001f1af9a18a2so4742922pjl.5 for ; Mon, 18 Jul 2022 10:05:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=6NyzMxmt/WAE6+0kMZIP7wK2TvVq8SGkQD4SMxCtamA=; b=rE2p2vnI0/LzOurYbXKj4a1dOYnbseYzbfsMdemkPv4As2iWMSTt2DB6SveWWZ83bE Tk9XPTQiBtGl6zi8QHUbOgHAaWFo189CV6uO9dPD2VMSxoS+PCn3rGrPakfP7DUDkotq kcYB4LiERhIDMCqNxqoHIZvTKepp323ApuWpGfOTSPo09TedaCwpzo5VqXF1t8psbA/h BYIk+vIJz+xRlek2rg4cIzEodJRQQan/1Mc/KaIisB/nVHTMfNIeW8pGXUwe3MMuKCAw LlCcf9/S3UkVz/oLdgk5vIIOdiDkiRq4geG4fQwQ9kVhYvFln1fahMBqkktEb1awnhh2 RcIw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=6NyzMxmt/WAE6+0kMZIP7wK2TvVq8SGkQD4SMxCtamA=; b=X2smUvOyHpOJfclio+/iarw3FW0pzD6rmWG8dw6WRfSGXh8JAyIBqRFKVO/j4VfWKp 4rq+/5AzMsZyuDKQkwRQ3WdCJ2We/pqm9P4UKkMs4vauvdhYz7f8/sLTNAmnjjpWxwQg oOtlheT/0zYL5BwGR1uG1oXM/BFd73MxfGd2WARTxw0MK/gBK+7V6oqyIWFWHqPPmyAb ucqehsw0jpFlmgq/cTOgiDHWsXFSIl3R+d5ew7wEwWv3G3D0NXeOEfphsdKy7oWbGILz R8Fshp3JOjVK+qge33RHWFZhR8OG/QxTWg1xOHJ8By290W2Ajtk3XvkNSj58b26yAuFl KDbA== X-Gm-Message-State: AJIora98DQZaVwrviu3Lz3HQXgSEEAjga2tUKaHrilJUBfIb7xJy3LCs 4fWCL5MIP0iK0NhYY/VTPNBAit2CuI0CzA== X-Google-Smtp-Source: AGRyM1uH69PKvvBNxNCme8+NWvuUJNuL8CI0U/0FZX6mfAo3vPZF1+2AA8FuSPDj+/ikwZ2KkGTmsw== X-Received: by 2002:a17:90a:c088:b0:1ef:b85c:576b with SMTP id o8-20020a17090ac08800b001efb85c576bmr39888216pjs.237.1658163950929; Mon, 18 Jul 2022 10:05:50 -0700 (PDT) Received: from atishp.ba.rivosinc.com ([66.220.2.162]) by smtp.gmail.com with ESMTPSA id r10-20020a170902be0a00b0016bc947c5b7sm9733402pls.38.2022.07.18.10.05.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Jul 2022 10:05:50 -0700 (PDT) From: Atish Patra To: linux-kernel@vger.kernel.org Cc: Atish Patra , Albert Ou , Anup Patel , Atish Patra , Guo Ren , kvm-riscv@lists.infradead.org, kvm@vger.kernel.org, linux-riscv@lists.infradead.org, Mark Rutland , Palmer Dabbelt , Paul Walmsley , Will Deacon Subject: [RFC 6/9] RISC-V: KVM: Add SBI PMU extension support Date: Mon, 18 Jul 2022 10:02:02 -0700 Message-Id: <20220718170205.2972215-7-atishp@rivosinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220718170205.2972215-1-atishp@rivosinc.com> References: <20220718170205.2972215-1-atishp@rivosinc.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" SBI PMU extension allows KVM guests to configure/start/stop/query about the PMU counters in virtualized enviornment as well. In order to allow that, KVM implements the entire SBI PMU extension. Signed-off-by: Atish Patra --- arch/riscv/kvm/vcpu_sbi.c | 11 +++++ arch/riscv/kvm/vcpu_sbi_pmu.c | 81 +++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 arch/riscv/kvm/vcpu_sbi_pmu.c diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c index d45e7da3f0d3..da9f7959340e 100644 --- a/arch/riscv/kvm/vcpu_sbi.c +++ b/arch/riscv/kvm/vcpu_sbi.c @@ -50,6 +50,16 @@ extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_= hsm; extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_experimental; extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_vendor; =20 +#ifdef CONFIG_RISCV_PMU_SBI +extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_pmu; +#else +static const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_pmu =3D { + .extid_start =3D -1UL, + .extid_end =3D -1UL, + .handler =3D NULL, +}; +#endif + static const struct kvm_vcpu_sbi_extension *sbi_ext[] =3D { &vcpu_sbi_ext_v01, &vcpu_sbi_ext_base, @@ -58,6 +68,7 @@ static const struct kvm_vcpu_sbi_extension *sbi_ext[] =3D= { &vcpu_sbi_ext_rfence, &vcpu_sbi_ext_srst, &vcpu_sbi_ext_hsm, + &vcpu_sbi_ext_pmu, &vcpu_sbi_ext_experimental, &vcpu_sbi_ext_vendor, }; diff --git a/arch/riscv/kvm/vcpu_sbi_pmu.c b/arch/riscv/kvm/vcpu_sbi_pmu.c new file mode 100644 index 000000000000..90c51a95d4f4 --- /dev/null +++ b/arch/riscv/kvm/vcpu_sbi_pmu.c @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 Rivos Inc + * + * Authors: + * Atish Patra + */ + +#include +#include +#include +#include +#include +#include + +static int kvm_sbi_ext_pmu_handler(struct kvm_vcpu *vcpu, struct kvm_run *= run, + unsigned long *out_val, + struct kvm_cpu_trap *utrap, + bool *exit) +{ + int ret =3D -EOPNOTSUPP; + struct kvm_cpu_context *cp =3D &vcpu->arch.guest_context; + unsigned long funcid =3D cp->a6; + uint64_t temp; + + switch (funcid) { + case SBI_EXT_PMU_NUM_COUNTERS: + ret =3D kvm_riscv_vcpu_pmu_num_ctrs(vcpu, out_val); + break; + case SBI_EXT_PMU_COUNTER_GET_INFO: + ret =3D kvm_riscv_vcpu_pmu_ctr_info(vcpu, cp->a0, out_val); + break; + case SBI_EXT_PMU_COUNTER_CFG_MATCH: +#if defined(CONFIG_32BIT) + temp =3D ((uint64_t)cp->a5 << 32) | cp->a4; +#else + temp =3D cp->a4; +#endif + ret =3D kvm_riscv_vcpu_pmu_ctr_cfg_match(vcpu, cp->a0, cp->a1, cp->a2, c= p->a3, temp); + if (ret >=3D 0) { + *out_val =3D ret; + ret =3D 0; + } + break; + case SBI_EXT_PMU_COUNTER_START: +#if defined(CONFIG_32BIT) + temp =3D ((uint64_t)cp->a4 << 32) | cp->a3; +#else + temp =3D cp->a3; +#endif + ret =3D kvm_riscv_vcpu_pmu_ctr_start(vcpu, cp->a0, cp->a1, cp->a2, temp); + break; + case SBI_EXT_PMU_COUNTER_STOP: + ret =3D kvm_riscv_vcpu_pmu_ctr_stop(vcpu, cp->a0, cp->a1, cp->a2); + break; + case SBI_EXT_PMU_COUNTER_FW_READ: + ret =3D kvm_riscv_vcpu_pmu_ctr_read(vcpu, cp->a0, out_val); + break; + default: + ret =3D -EOPNOTSUPP; + } + + return ret; +} + +unsigned long kvm_sbi_ext_pmu_probe(unsigned long extid) +{ + /* + * PMU Extension is only available to guests if privilege mode filtering + * is available. Otherwise, guest will always count events while the + * execution is in hypervisor mode. + */ + return riscv_isa_extension_available(NULL, SSCOFPMF); +} + +const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_pmu =3D { + .extid_start =3D SBI_EXT_PMU, + .extid_end =3D SBI_EXT_PMU, + .handler =3D kvm_sbi_ext_pmu_handler, + .probe =3D kvm_sbi_ext_pmu_probe, +}; --=20 2.25.1 From nobody Sat Apr 18 04:21:49 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 63320CCA479 for ; Mon, 18 Jul 2022 17:06:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235904AbiGRRGR (ORCPT ); Mon, 18 Jul 2022 13:06:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57670 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235804AbiGRRF6 (ORCPT ); Mon, 18 Jul 2022 13:05:58 -0400 Received: from mail-pg1-x532.google.com (mail-pg1-x532.google.com [IPv6:2607:f8b0:4864:20::532]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 043FA2C132 for ; Mon, 18 Jul 2022 10:05:53 -0700 (PDT) Received: by mail-pg1-x532.google.com with SMTP id f65so11113296pgc.12 for ; Mon, 18 Jul 2022 10:05:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=5MMCsELdRAdJh5aLmNFcZOyRr/D0RiLtBOcd/jSRJiU=; b=SZ6A4CByNWqPAfqTGaz70lPNVZuptERZ0n0u8v6E97djjISARvexx57xy8GGUdpF+7 r/wz4gME1iPiN5m7T/2MCqyMwwdb3xeM41QcjwrrZmA5tMKBIkMLySe/imOL/raWFmnG xKa2mhJFZi0teVbY57hPs2+Bzzc0QSh8qG7kXumoXK9+hpWi6PD4chu1ayhJkh+miktd kXl5bOQIqIO/rE0/ExIZcBvmUHepnI2gs3SEIrxc3DXGAcDopac/yjWfOFX1XQdiPV6v 0OgNbjia5UFMdtMEtdDpfKRXrszArD3bfhiVSlVxJie93lXnVZuvy7mPDqFJzLTsWe0j j/mg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=5MMCsELdRAdJh5aLmNFcZOyRr/D0RiLtBOcd/jSRJiU=; b=0YU2Sd2hLPDpjfi26pS1TuAGEJWLbqcVGs+4CJIRgFVFsf22fglGXc4HuE2zgxv3X2 mny3THMceYc3xtyZ9qmEio3lX0N3/rCAjJqkUu52TGWpTQCtgWWIXyrmvmZzP6HfNRvR YMQQaDXRLGedX0EeVPPLCN8eR9yJw9vaXyVWsKiuIRS2KJIZ9kNZQxJIUvqxRGT7Fe9x il0HiH0xaf5KVbeFmH8mTk6/cGiPT3YLRYeg/Q20FmGsKyfgg2si68bB5ABs2sxnHC41 qzMfm2W0/gSlbom+nIEORgw1+tkOXSNBuTPKVLikXNd/aEcDBr5KZVf4Mh36b0/FEmND J5Xw== X-Gm-Message-State: AJIora+PXMMbPDGjv+K66R81hXeVjJn8BKo5ojY2COxT1yNvZIFHUsNT tD7lR+VMqInxOlHwJBOcP9XEdgqNGC09/g== X-Google-Smtp-Source: AGRyM1vVmhagOiYrnqGiFf5EZMjik6HESCVupUtRm1lG/F6JRUTWiEEbCeHwm6Al2hYOL7mbJoR4Ng== X-Received: by 2002:a63:6bc1:0:b0:40d:ffa8:2605 with SMTP id g184-20020a636bc1000000b0040dffa82605mr26252146pgc.299.1658163952186; Mon, 18 Jul 2022 10:05:52 -0700 (PDT) Received: from atishp.ba.rivosinc.com ([66.220.2.162]) by smtp.gmail.com with ESMTPSA id r10-20020a170902be0a00b0016bc947c5b7sm9733402pls.38.2022.07.18.10.05.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Jul 2022 10:05:51 -0700 (PDT) From: Atish Patra To: linux-kernel@vger.kernel.org Cc: Atish Patra , Albert Ou , Anup Patel , Atish Patra , Guo Ren , kvm-riscv@lists.infradead.org, kvm@vger.kernel.org, linux-riscv@lists.infradead.org, Mark Rutland , Palmer Dabbelt , Paul Walmsley , Will Deacon Subject: [RFC 7/9] RISC-V: KVM: Implement trap & emulate for hpmcounters Date: Mon, 18 Jul 2022 10:02:03 -0700 Message-Id: <20220718170205.2972215-8-atishp@rivosinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220718170205.2972215-1-atishp@rivosinc.com> References: <20220718170205.2972215-1-atishp@rivosinc.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" As the KVM guests only see the virtual PMU counters, all hpmcounter access should trap and KVM emulates the read access on behalf of guests. Signed-off-by: Atish Patra --- arch/riscv/include/asm/kvm_vcpu_pmu.h | 16 +++++++++ arch/riscv/kvm/vcpu_insn.c | 1 + arch/riscv/kvm/vcpu_pmu.c | 47 +++++++++++++++++++++++---- 3 files changed, 57 insertions(+), 7 deletions(-) diff --git a/arch/riscv/include/asm/kvm_vcpu_pmu.h b/arch/riscv/include/asm= /kvm_vcpu_pmu.h index bffee052f2ae..5410236b62a8 100644 --- a/arch/riscv/include/asm/kvm_vcpu_pmu.h +++ b/arch/riscv/include/asm/kvm_vcpu_pmu.h @@ -39,6 +39,19 @@ struct kvm_pmu { #define pmu_to_vcpu(pmu) (container_of((pmu), struct kvm_vcpu, arch.pmu)) #define pmc_to_pmu(pmc) (&(pmc)->vcpu->arch.pmu) =20 +#if defined(CONFIG_32BIT) +#define KVM_RISCV_VCPU_HPMCOUNTER_CSR_FUNCS \ +{ .base =3D CSR_CYCLEH, .count =3D 31, .func =3D kvm_riscv_vcpu_pmu_r= ead_hpm }, \ +{ .base =3D CSR_CYCLE, .count =3D 31, .func =3D kvm_riscv_vcpu_pmu_re= ad_hpm }, +#else +#define KVM_RISCV_VCPU_HPMCOUNTER_CSR_FUNCS \ +{ .base =3D CSR_CYCLE, .count =3D 31, .func =3D kvm_riscv_vcpu_pmu_re= ad_hpm }, +#endif + +int kvm_riscv_vcpu_pmu_read_hpm(struct kvm_vcpu *vcpu, unsigned int csr_nu= m, + unsigned long *val, unsigned long new_val, + unsigned long wr_mask); + int kvm_riscv_vcpu_pmu_num_ctrs(struct kvm_vcpu *vcpu, unsigned long *out_= val); int kvm_riscv_vcpu_pmu_ctr_info(struct kvm_vcpu *vcpu, unsigned long cidx, unsigned long *ctr_info); @@ -59,6 +72,9 @@ void kvm_riscv_vcpu_pmu_reset(struct kvm_vcpu *vcpu); #else struct kvm_pmu { }; +#define KVM_RISCV_VCPU_HPMCOUNTER_CSR_FUNCS \ +{ .base =3D 0, .count =3D 0, .func =3D NULL }, + =20 static inline int kvm_riscv_vcpu_pmu_init(struct kvm_vcpu *vcpu) { diff --git a/arch/riscv/kvm/vcpu_insn.c b/arch/riscv/kvm/vcpu_insn.c index 0aa334f853c8..7c2a4b1a69f7 100644 --- a/arch/riscv/kvm/vcpu_insn.c +++ b/arch/riscv/kvm/vcpu_insn.c @@ -215,6 +215,7 @@ struct csr_func { }; =20 static const struct csr_func csr_funcs[] =3D { + KVM_RISCV_VCPU_HPMCOUNTER_CSR_FUNCS }; =20 /** diff --git a/arch/riscv/kvm/vcpu_pmu.c b/arch/riscv/kvm/vcpu_pmu.c index 3168ed740bdd..5434051f495d 100644 --- a/arch/riscv/kvm/vcpu_pmu.c +++ b/arch/riscv/kvm/vcpu_pmu.c @@ -14,6 +14,46 @@ #include #include =20 +int kvm_riscv_vcpu_pmu_ctr_read(struct kvm_vcpu *vcpu, unsigned long cidx, + unsigned long *out_val) +{ + struct kvm_pmu *kvpmu =3D vcpu_to_pmu(vcpu); + struct kvm_pmc *pmc; + u64 enabled, running; + + if (!kvpmu) + return -EINVAL; + + pmc =3D &kvpmu->pmc[cidx]; + if (!pmc->perf_event) + return -EINVAL; + + pmc->counter_val +=3D perf_event_read_value(pmc->perf_event, &enabled, &r= unning); + *out_val =3D pmc->counter_val; + + return 0; +} + +int kvm_riscv_vcpu_pmu_read_hpm(struct kvm_vcpu *vcpu, unsigned int csr_nu= m, + unsigned long *val, unsigned long new_val, + unsigned long wr_mask) +{ + struct kvm_pmu *kvpmu =3D vcpu_to_pmu(vcpu); + int cidx, ret =3D KVM_INSN_CONTINUE_NEXT_SEPC; + + if (!kvpmu) + return KVM_INSN_EXIT_TO_USER_SPACE; + //TODO: Should we check if vcpu pmu is initialized or not! + if (wr_mask) + return KVM_INSN_ILLEGAL_TRAP; + cidx =3D csr_num - CSR_CYCLE; + + if (kvm_riscv_vcpu_pmu_ctr_read(vcpu, cidx, val) < 0) + return KVM_INSN_EXIT_TO_USER_SPACE; + + return ret; +} + int kvm_riscv_vcpu_pmu_num_ctrs(struct kvm_vcpu *vcpu, unsigned long *out_= val) { struct kvm_pmu *kvpmu =3D vcpu_to_pmu(vcpu); @@ -60,13 +100,6 @@ int kvm_riscv_vcpu_pmu_ctr_cfg_match(struct kvm_vcpu *v= cpu, unsigned long ctr_ba return 0; } =20 -int kvm_riscv_vcpu_pmu_ctr_read(struct kvm_vcpu *vcpu, unsigned long cidx, - unsigned long *out_val) -{ - /* TODO */ - return 0; -} - int kvm_riscv_vcpu_pmu_init(struct kvm_vcpu *vcpu) { int i =3D 0, num_hw_ctrs, num_fw_ctrs, hpm_width; --=20 2.25.1 From nobody Sat Apr 18 04:21:49 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 738C6CCA485 for ; Mon, 18 Jul 2022 17:06:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235951AbiGRRGU (ORCPT ); Mon, 18 Jul 2022 13:06:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57688 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235811AbiGRRF6 (ORCPT ); Mon, 18 Jul 2022 13:05:58 -0400 Received: from mail-pf1-x432.google.com (mail-pf1-x432.google.com [IPv6:2607:f8b0:4864:20::432]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2BDF42BB1A for ; Mon, 18 Jul 2022 10:05:54 -0700 (PDT) Received: by mail-pf1-x432.google.com with SMTP id b9so11179837pfp.10 for ; Mon, 18 Jul 2022 10:05:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=DudDSxwzmUDI8860lqzmSl3O3ezUAmmtuRpFvcpbiqM=; b=JMzb1okk1veZl1WbSRPR3z17BIsd9O28rSDVH2XWQZCNRxgtk2tCWrlaeK5NxJTDEb FJWxY4TJmoF3uHGy9WZrm9GYkZ36LMHqAlVR2tm8j+c2ZoCZDQrPIBdkGgR+QgAH1Ohi z7tYM8RpqGojLgmmp0e0PRXY6gyP8SzP2CCBeQRg95QP6tk4fxllVfcixW1Rm5j/2Zna XGs69YvPA2xMlFeY76U7OYenE5lcyVzTa5y98YGTtRBKYt94Azob+tJYzUlSxIseK/ob esOf2ChMSWIasebDWTQgiuQoUzqQc/CzzoPjCeNeUQFhr5ygWelbNFItPI9EZr7XrFHo 8zsA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=DudDSxwzmUDI8860lqzmSl3O3ezUAmmtuRpFvcpbiqM=; b=FkiBoEJ369SKprFfPMzFidOFX6s+jUhQKDEsjIbFLb3Bycf/ZQGAnYd2lv8OJkl1p+ KQOqc1CYI/oTEvQA44hrEmKgX7LweTOZ12jJxZgN09i2T4GFYsuo0ZNTc+feHpQxt9cr Iw1JymjYURwYbznYc3P6DtXqGQZB6ngYBzSspXBtA9lMu7MMyyl3ObtI8WVTYkmOelMI YxgrJQEMG4eWEARZwmLrFcrAviNPFGDeiPEIToM7aWIJc9e3ctcJgrQfRHl1P/+SzBwE CNMjAti7Ua5wL0um18DTko+DwrfVQLm6uxJ72G1FMEeUEXEis16gQsbSCke3iG8oeeAu BR1w== X-Gm-Message-State: AJIora+slJbICenxvg7K8Q2tvKfG8wU0ja20Kjnm+gOA7x9pYwh0Om8h Wl44cdYRz0jvEZoYiuYg4rp84B9NIlJvQA== X-Google-Smtp-Source: AGRyM1uaEuvYAKQDRhJRtgw3nQLKDv5Q+LFtC+ezT9Le6ONfC43Kv6qU/4zj/oJlbv8mg+IvdwsCug== X-Received: by 2002:a63:5c42:0:b0:412:b2e9:97e4 with SMTP id n2-20020a635c42000000b00412b2e997e4mr26596777pgm.36.1658163953563; Mon, 18 Jul 2022 10:05:53 -0700 (PDT) Received: from atishp.ba.rivosinc.com ([66.220.2.162]) by smtp.gmail.com with ESMTPSA id r10-20020a170902be0a00b0016bc947c5b7sm9733402pls.38.2022.07.18.10.05.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Jul 2022 10:05:53 -0700 (PDT) From: Atish Patra To: linux-kernel@vger.kernel.org Cc: Atish Patra , Albert Ou , Anup Patel , Atish Patra , Guo Ren , kvm-riscv@lists.infradead.org, kvm@vger.kernel.org, linux-riscv@lists.infradead.org, Mark Rutland , Palmer Dabbelt , Paul Walmsley , Will Deacon Subject: [RFC 8/9] RISC-V: KVM: Implement perf support Date: Mon, 18 Jul 2022 10:02:04 -0700 Message-Id: <20220718170205.2972215-9-atishp@rivosinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220718170205.2972215-1-atishp@rivosinc.com> References: <20220718170205.2972215-1-atishp@rivosinc.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" RISC-V SBI PMU & Sscofpmf ISA extension allows supporting perf in the virtualization enviornment as well. KVM implementation relies on SBI PMU extension for most of the part while traps & emulates the CSRs read for counter access. Signed-off-by: Atish Patra --- arch/riscv/kvm/vcpu_pmu.c | 318 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 301 insertions(+), 17 deletions(-) diff --git a/arch/riscv/kvm/vcpu_pmu.c b/arch/riscv/kvm/vcpu_pmu.c index 5434051f495d..278c261efad3 100644 --- a/arch/riscv/kvm/vcpu_pmu.c +++ b/arch/riscv/kvm/vcpu_pmu.c @@ -11,9 +11,163 @@ #include #include #include +#include #include #include =20 +#define get_event_type(x) ((x & SBI_PMU_EVENT_IDX_TYPE_MASK) >> 16) +#define get_event_code(x) (x & SBI_PMU_EVENT_IDX_CODE_MASK) + +static inline u64 pmu_get_sample_period(struct kvm_pmc *pmc) +{ + u64 counter_val_mask =3D GENMASK(pmc->cinfo.width, 0); + u64 sample_period; + + if (!pmc->counter_val) + sample_period =3D counter_val_mask; + else + sample_period =3D pmc->counter_val & counter_val_mask; + + return sample_period; +} + +static u32 pmu_get_perf_event_type(unsigned long eidx) +{ + enum sbi_pmu_event_type etype =3D get_event_type(eidx); + u32 type; + + if (etype =3D=3D SBI_PMU_EVENT_TYPE_HW) + type =3D PERF_TYPE_HARDWARE; + else if (etype =3D=3D SBI_PMU_EVENT_TYPE_CACHE) + type =3D PERF_TYPE_HW_CACHE; + else if (etype =3D=3D SBI_PMU_EVENT_TYPE_RAW || etype =3D=3D SBI_PMU_EVEN= T_TYPE_FW) + type =3D PERF_TYPE_RAW; + else + type =3D PERF_TYPE_MAX; + + return type; +} + +static inline bool pmu_is_fw_event(unsigned long eidx) +{ + enum sbi_pmu_event_type etype =3D get_event_type(eidx); + + return (etype =3D=3D SBI_PMU_EVENT_TYPE_FW) ? true : false; +} + +static void pmu_release_perf_event(struct kvm_pmc *pmc) +{ + if (pmc->perf_event) { + perf_event_disable(pmc->perf_event); + perf_event_release_kernel(pmc->perf_event); + pmc->perf_event =3D NULL; + } +} + +static u64 pmu_get_perf_event_hw_config(u32 sbi_event_code) +{ + /* SBI PMU HW event code is offset by 1 from perf hw event codes */ + return (u64)sbi_event_code - 1; +} + +static u64 pmu_get_perf_event_cache_config(u32 sbi_event_code) +{ + u64 config =3D U64_MAX; + unsigned int cache_type, cache_op, cache_result; + + /* All the cache event masks lie within 0xFF. No separate masking is nece= sssary */ + cache_type =3D (sbi_event_code & SBI_PMU_EVENT_CACHE_ID_CODE_MASK) >> 3; + cache_op =3D (sbi_event_code & SBI_PMU_EVENT_CACHE_OP_ID_CODE_MASK) >> 1; + cache_result =3D sbi_event_code & SBI_PMU_EVENT_CACHE_RESULT_ID_CODE_MASK; + + if (cache_type >=3D PERF_COUNT_HW_CACHE_MAX || + cache_op >=3D PERF_COUNT_HW_CACHE_OP_MAX || + cache_result >=3D PERF_COUNT_HW_CACHE_RESULT_MAX) + goto out; + config =3D cache_type | (cache_op << 8) | (cache_result << 16); +out: + return config; +} + +static u64 pmu_get_perf_event_config(unsigned long eidx, uint64_t edata) +{ + enum sbi_pmu_event_type etype =3D get_event_type(eidx); + u32 ecode =3D get_event_code(eidx); + u64 config =3D U64_MAX; + + if (etype =3D=3D SBI_PMU_EVENT_TYPE_HW) + config =3D pmu_get_perf_event_hw_config(ecode); + else if (etype =3D=3D SBI_PMU_EVENT_TYPE_CACHE) + config =3D pmu_get_perf_event_cache_config(ecode); + else if (etype =3D=3D SBI_PMU_EVENT_TYPE_RAW) + config =3D edata & RISCV_PMU_RAW_EVENT_MASK; + else if ((etype =3D=3D SBI_PMU_EVENT_TYPE_FW) && (ecode < SBI_PMU_FW_MAX)) + config =3D (1ULL << 63) | ecode; + + return config; +} + +static int pmu_get_fixed_pmc_index(unsigned long eidx) +{ + u32 etype =3D pmu_get_perf_event_type(eidx); + u32 ecode =3D get_event_code(eidx); + int ctr_idx; + + if (etype !=3D SBI_PMU_EVENT_TYPE_HW) + return -EINVAL; + + if (ecode =3D=3D SBI_PMU_HW_CPU_CYCLES) + ctr_idx =3D 0; + else if (ecode =3D=3D SBI_PMU_HW_INSTRUCTIONS) + ctr_idx =3D 2; + else + return -EINVAL; + + return ctr_idx; +} + +static int pmu_get_programmable_pmc_index(struct kvm_pmu *kvpmu, unsigned = long eidx, + unsigned long cbase, unsigned long cmask) +{ + int ctr_idx =3D -1; + int i, pmc_idx; + int min, max; + + if (pmu_is_fw_event(eidx)) { + /* Firmware counters are mapped 1:1 starting from num_hw_ctrs for simpli= city */ + min =3D kvpmu->num_hw_ctrs; + max =3D min + kvpmu->num_fw_ctrs; + } else { + /* First 3 counters are reserved for fixed counters */ + min =3D 3; + max =3D kvpmu->num_hw_ctrs; + } + + for_each_set_bit(i, &cmask, BITS_PER_LONG) { + pmc_idx =3D i + cbase; + if ((pmc_idx >=3D min && pmc_idx < max) && + !test_bit(pmc_idx, kvpmu->used_pmc)) { + ctr_idx =3D pmc_idx; + break; + } + } + + return ctr_idx; +} + +static int pmu_get_pmc_index(struct kvm_pmu *pmu, unsigned long eidx, + unsigned long cbase, unsigned long cmask) +{ + int ret; + + /* Fixed counters need to be have fixed mapping as they have different wi= dth */ + ret =3D pmu_get_fixed_pmc_index(eidx); + if (ret >=3D 0) + return ret; + + return pmu_get_programmable_pmc_index(pmu, eidx, cbase, cmask); +} + int kvm_riscv_vcpu_pmu_ctr_read(struct kvm_vcpu *vcpu, unsigned long cidx, unsigned long *out_val) { @@ -43,7 +197,6 @@ int kvm_riscv_vcpu_pmu_read_hpm(struct kvm_vcpu *vcpu, u= nsigned int csr_num, =20 if (!kvpmu) return KVM_INSN_EXIT_TO_USER_SPACE; - //TODO: Should we check if vcpu pmu is initialized or not! if (wr_mask) return KVM_INSN_ILLEGAL_TRAP; cidx =3D csr_num - CSR_CYCLE; @@ -81,14 +234,62 @@ int kvm_riscv_vcpu_pmu_ctr_info(struct kvm_vcpu *vcpu,= unsigned long cidx, int kvm_riscv_vcpu_pmu_ctr_start(struct kvm_vcpu *vcpu, unsigned long ctr_= base, unsigned long ctr_mask, unsigned long flag, uint64_t ival) { - /* TODO */ + struct kvm_pmu *kvpmu =3D vcpu_to_pmu(vcpu); + int i, num_ctrs, pmc_index; + struct kvm_pmc *pmc; + + num_ctrs =3D kvpmu->num_fw_ctrs + kvpmu->num_hw_ctrs; + if (ctr_base + __fls(ctr_mask) >=3D num_ctrs) + return -EINVAL; + + /* Start the counters that have been configured and requested by the gues= t */ + for_each_set_bit(i, &ctr_mask, RISCV_MAX_COUNTERS) { + pmc_index =3D i + ctr_base; + if (!test_bit(pmc_index, kvpmu->used_pmc)) + continue; + pmc =3D &kvpmu->pmc[pmc_index]; + if (flag & SBI_PMU_START_FLAG_SET_INIT_VALUE) + pmc->counter_val =3D ival; + if (pmc->perf_event) { + perf_event_period(pmc->perf_event, pmu_get_sample_period(pmc)); + perf_event_enable(pmc->perf_event); + } + } + return 0; } =20 int kvm_riscv_vcpu_pmu_ctr_stop(struct kvm_vcpu *vcpu, unsigned long ctr_b= ase, unsigned long ctr_mask, unsigned long flag) { - /* TODO */ + struct kvm_pmu *kvpmu =3D vcpu_to_pmu(vcpu); + int i, num_ctrs, pmc_index; + u64 enabled, running; + struct kvm_pmc *pmc; + + num_ctrs =3D kvpmu->num_fw_ctrs + kvpmu->num_hw_ctrs; + if ((ctr_base + __fls(ctr_mask)) >=3D num_ctrs) + return -EINVAL; + + /* Stop the counters that have been configured and requested by the guest= */ + for_each_set_bit(i, &ctr_mask, RISCV_MAX_COUNTERS) { + pmc_index =3D i + ctr_base; + if (!test_bit(pmc_index, kvpmu->used_pmc)) + continue; + pmc =3D &kvpmu->pmc[pmc_index]; + if (pmc->perf_event) { + /* Stop counting the counter */ + perf_event_disable(pmc->perf_event); + if (flag & SBI_PMU_STOP_FLAG_RESET) { + /* Relase the counter if this is a reset request */ + pmc->counter_val +=3D perf_event_read_value(pmc->perf_event, + &enabled, &running); + pmu_release_perf_event(pmc); + clear_bit(pmc_index, kvpmu->used_pmc); + } + } + } + return 0; } =20 @@ -96,14 +297,85 @@ int kvm_riscv_vcpu_pmu_ctr_cfg_match(struct kvm_vcpu *= vcpu, unsigned long ctr_ba unsigned long ctr_mask, unsigned long flag, unsigned long eidx, uint64_t edata) { - /* TODO */ - return 0; + struct kvm_pmu *kvpmu =3D vcpu_to_pmu(vcpu); + struct perf_event *event; + struct perf_event_attr attr; + int num_ctrs, ctr_idx; + u32 etype =3D pmu_get_perf_event_type(eidx); + u64 config; + struct kvm_pmc *pmc; + + num_ctrs =3D kvpmu->num_fw_ctrs + kvpmu->num_hw_ctrs; + if ((etype =3D=3D PERF_TYPE_MAX) || ((ctr_base + __fls(ctr_mask)) >=3D nu= m_ctrs)) + return -EINVAL; + + if (pmu_is_fw_event(eidx)) + return -EOPNOTSUPP; + /* + * SKIP_MATCH flag indicates the caller is aware of the assigned counter + * for this event. Just do a sanity check if it already marked used. + */ + if (flag & SBI_PMU_CFG_FLAG_SKIP_MATCH) { + if (!test_bit(ctr_base, kvpmu->used_pmc)) + return -EINVAL; + ctr_idx =3D ctr_base; + goto match_done; + } + + ctr_idx =3D pmu_get_pmc_index(kvpmu, eidx, ctr_base, ctr_mask); + if (ctr_idx < 0) + return -EOPNOTSUPP; + +match_done: + pmc =3D &kvpmu->pmc[ctr_idx]; + pmu_release_perf_event(pmc); + pmc->idx =3D ctr_idx; + + config =3D pmu_get_perf_event_config(eidx, edata); + memset(&attr, 0, sizeof(struct perf_event_attr)); + attr.type =3D etype; + attr.size =3D sizeof(attr); + attr.pinned =3D true; + + /* + * It should never reach here if the platform doesn't support sscofpmf ex= tensio + * as mode filtering won't work without it. + */ + attr.exclude_host =3D true; + attr.exclude_hv =3D true; + attr.exclude_user =3D flag & SBI_PMU_CFG_FLAG_SET_UINH ? 1 : 0; + attr.exclude_kernel =3D flag & SBI_PMU_CFG_FLAG_SET_SINH ? 1 : 0; + attr.config =3D config; + attr.config1 =3D RISCV_KVM_PMU_CONFIG1_GUEST_EVENTS; + if (flag & SBI_PMU_CFG_FLAG_CLEAR_VALUE) { + //TODO: Do we really want to clear the value in hardware counter + pmc->counter_val =3D 0; + } + /* + * Set the default sample_period for now. The guest specified value + * will be updated in the start call. + */ + attr.sample_period =3D pmu_get_sample_period(pmc); + + event =3D perf_event_create_kernel_counter(&attr, -1, current, NULL, pmc); + if (IS_ERR(event)) { + pr_err("kvm pmu event creation failed event %pe for eidx %lx\n", event, = eidx); + return -EOPNOTSUPP; + } + + set_bit(ctr_idx, kvpmu->used_pmc); + pmc->perf_event =3D event; + if (flag & SBI_PMU_CFG_FLAG_AUTO_START) + perf_event_enable(pmc->perf_event); + + return ctr_idx; } =20 int kvm_riscv_vcpu_pmu_init(struct kvm_vcpu *vcpu) { int i =3D 0, num_hw_ctrs, num_fw_ctrs, hpm_width; struct kvm_pmu *kvpmu =3D vcpu_to_pmu(vcpu); + struct kvm_pmc *pmc; =20 if (!kvpmu) return -EINVAL; @@ -120,6 +392,7 @@ int kvm_riscv_vcpu_pmu_init(struct kvm_vcpu *vcpu) return -EINVAL; } =20 + bitmap_zero(kvpmu->used_pmc, RISCV_MAX_COUNTERS); kvpmu->num_hw_ctrs =3D num_hw_ctrs; kvpmu->num_fw_ctrs =3D num_fw_ctrs; /* @@ -132,38 +405,49 @@ int kvm_riscv_vcpu_pmu_init(struct kvm_vcpu *vcpu) /* TIME CSR shouldn't be read from perf interface */ if (i =3D=3D 1) continue; - kvpmu->pmc[i].idx =3D i; - kvpmu->pmc[i].vcpu =3D vcpu; + pmc =3D &kvpmu->pmc[i]; + pmc->idx =3D i; + pmc->counter_val =3D 0; + pmc->vcpu =3D vcpu; if (i < kvpmu->num_hw_ctrs) { kvpmu->pmc[i].cinfo.type =3D SBI_PMU_CTR_TYPE_HW; if (i < 3) /* CY, IR counters */ - kvpmu->pmc[i].cinfo.width =3D 63; + pmc->cinfo.width =3D 63; else - kvpmu->pmc[i].cinfo.width =3D hpm_width; + pmc->cinfo.width =3D hpm_width; /* * The CSR number doesn't have any relation with the logical * hardware counters. The CSR numbers are encoded sequentially * to avoid maintaining a map between the virtual counter * and CSR number. */ - kvpmu->pmc[i].cinfo.csr =3D CSR_CYCLE + i; + pmc->cinfo.csr =3D CSR_CYCLE + i; } else { - kvpmu->pmc[i].cinfo.type =3D SBI_PMU_CTR_TYPE_FW; - kvpmu->pmc[i].cinfo.width =3D BITS_PER_LONG - 1; + pmc->cinfo.type =3D SBI_PMU_CTR_TYPE_FW; + pmc->cinfo.width =3D BITS_PER_LONG - 1; } } =20 return 0; } =20 -void kvm_riscv_vcpu_pmu_reset(struct kvm_vcpu *vcpu) +void kvm_riscv_vcpu_pmu_deinit(struct kvm_vcpu *vcpu) { - /* TODO */ + struct kvm_pmu *kvpmu =3D vcpu_to_pmu(vcpu); + struct kvm_pmc *pmc; + int i; + + if (!kvpmu) + return; + + for_each_set_bit(i, kvpmu->used_pmc, RISCV_MAX_COUNTERS) { + pmc =3D &kvpmu->pmc[i]; + pmu_release_perf_event(pmc); + } } =20 -void kvm_riscv_vcpu_pmu_deinit(struct kvm_vcpu *vcpu) +void kvm_riscv_vcpu_pmu_reset(struct kvm_vcpu *vcpu) { - /* TODO */ + kvm_riscv_vcpu_pmu_deinit(vcpu); } - --=20 2.25.1 From nobody Sat Apr 18 04:21:49 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 87A84CCA482 for ; Mon, 18 Jul 2022 17:06:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235975AbiGRRGW (ORCPT ); Mon, 18 Jul 2022 13:06:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57704 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235818AbiGRRF6 (ORCPT ); Mon, 18 Jul 2022 13:05:58 -0400 Received: from mail-pg1-x533.google.com (mail-pg1-x533.google.com [IPv6:2607:f8b0:4864:20::533]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E3B602C643 for ; Mon, 18 Jul 2022 10:05:55 -0700 (PDT) Received: by mail-pg1-x533.google.com with SMTP id 23so11133868pgc.8 for ; Mon, 18 Jul 2022 10:05:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=oOsWXe1XlE7Dvyt6YnaIl4l/lBbF3+FHoY2EVuHBogc=; b=yDEh3i7cvGOG1Tg6a3LH5g6p9IZ71ROXWiKkAcCBDzpRGIkynsCnDocSHaB+p5lMtJ un3KvvMO1rR4R6lnmasBC5U/GtKZCLfazzQczKJ460Swi58kGxQQGVKHHLwGSZmXg52d jAtF35upbVQffkVvkequyyH558IkEUcoc8q2Ta0kG9/goGLIh6PxPSMEhL/edqqRa/RU 3SY6aBwkzzhR/2uFSpIH2LMHaADdwA9v2eYNcHXpv5YnJIYXvNJVnj53+Dslhe2tZold mCQD+57SYP0fEBMAGQSZHaskYwdskEPm0nGJwtL0AYAaeMlsu4wrXigjxkFByncTorSX Lt7A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=oOsWXe1XlE7Dvyt6YnaIl4l/lBbF3+FHoY2EVuHBogc=; b=H8Xqtudcw19xvJffhApz2xy4dD0uSCZEf0vKWAdSMzNeVar9qxFfdY1t1KSwK2RvEr r3L4vLxDVF23Z6kvhKPNvi2QfJs5CZIgXoWJgDzBGcSpVC7SBBxBHswoeH0RtaBawQQZ ToqQdKEB/yEXHBVsUrIydlY0AoREVWbVmty5P6IlQ/q8S/lF8J1h/UGS/nLoVURVMuy+ nFSObYEpJ6kK+UXy1eueOO8EZ43cbIXbm+GolfgyvCWY3bWM4z16tde9qmBiXQXx0ZOs NQGcoNZJHOnxyJ3XQUQRJRaIe2CfFE6ByZdJcVYnknNNMF0EG9OO7kLf74jWedNKizOc c2jw== X-Gm-Message-State: AJIora+wXJZakG80tJP87FbWCp9RHq8T+gDqiM5BqDDRdH9kFbuGgTps JIk7Js1v9yZbcEpkfh1Y0sPEMj+ujHfedA== X-Google-Smtp-Source: AGRyM1u3Q+C0LQCywanESfw4GyKuwBIrIwjITjzR6A1JvgUVZ5Tnlck04W/lkZFWguLgJ06YyWcaMA== X-Received: by 2002:a63:3101:0:b0:419:a4c7:649a with SMTP id x1-20020a633101000000b00419a4c7649amr23650792pgx.199.1658163954901; Mon, 18 Jul 2022 10:05:54 -0700 (PDT) Received: from atishp.ba.rivosinc.com ([66.220.2.162]) by smtp.gmail.com with ESMTPSA id r10-20020a170902be0a00b0016bc947c5b7sm9733402pls.38.2022.07.18.10.05.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Jul 2022 10:05:54 -0700 (PDT) From: Atish Patra To: linux-kernel@vger.kernel.org Cc: Atish Patra , Albert Ou , Anup Patel , Atish Patra , Guo Ren , kvm-riscv@lists.infradead.org, kvm@vger.kernel.org, linux-riscv@lists.infradead.org, Mark Rutland , Palmer Dabbelt , Paul Walmsley , Will Deacon Subject: [RFC 9/9] RISC-V: KVM: Implement firmware events Date: Mon, 18 Jul 2022 10:02:05 -0700 Message-Id: <20220718170205.2972215-10-atishp@rivosinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220718170205.2972215-1-atishp@rivosinc.com> References: <20220718170205.2972215-1-atishp@rivosinc.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" SBI PMU extension defines a set of firmware events which can provide useful information to guests about number of SBI calls. As hypervisor implements the SBI PMU extension, these firmware events corresponds to ecall invocations between VS->HS mode. All other firmware events will always report zero if monitored as KVM doesn't implement them. Signed-off-by: Atish Patra --- arch/riscv/include/asm/kvm_vcpu_pmu.h | 16 +++++ arch/riscv/include/asm/sbi.h | 2 +- arch/riscv/kvm/tlb.c | 6 +- arch/riscv/kvm/vcpu_pmu.c | 90 +++++++++++++++++++++++---- arch/riscv/kvm/vcpu_sbi_replace.c | 7 +++ 5 files changed, 106 insertions(+), 15 deletions(-) diff --git a/arch/riscv/include/asm/kvm_vcpu_pmu.h b/arch/riscv/include/asm= /kvm_vcpu_pmu.h index 5410236b62a8..d68b17ea796b 100644 --- a/arch/riscv/include/asm/kvm_vcpu_pmu.h +++ b/arch/riscv/include/asm/kvm_vcpu_pmu.h @@ -15,6 +15,14 @@ #ifdef CONFIG_RISCV_PMU_SBI #define RISCV_KVM_MAX_FW_CTRS 32 =20 +struct kvm_fw_event { + /* Current value of the event */ + unsigned long value; + + /* Event monitoring status */ + bool started; +}; + /* Per virtual pmu counter data */ struct kvm_pmc { u8 idx; @@ -22,11 +30,14 @@ struct kvm_pmc { struct perf_event *perf_event; uint64_t counter_val; union sbi_pmu_ctr_info cinfo; + /* Monitoring event ID */ + unsigned long event_idx; }; =20 /* PMU data structure per vcpu */ struct kvm_pmu { struct kvm_pmc pmc[RISCV_MAX_COUNTERS]; + struct kvm_fw_event fw_event[RISCV_KVM_MAX_FW_CTRS]; /* Number of the virtual firmware counters available */ int num_fw_ctrs; /* Number of the virtual hardware counters available */ @@ -48,6 +59,7 @@ struct kvm_pmu { { .base =3D CSR_CYCLE, .count =3D 31, .func =3D kvm_riscv_vcpu_pmu_re= ad_hpm }, #endif =20 +int kvm_riscv_vcpu_pmu_incr_fw(struct kvm_vcpu *vcpu, unsigned long fid); int kvm_riscv_vcpu_pmu_read_hpm(struct kvm_vcpu *vcpu, unsigned int csr_nu= m, unsigned long *val, unsigned long new_val, unsigned long wr_mask); @@ -75,6 +87,10 @@ struct kvm_pmu { #define KVM_RISCV_VCPU_HPMCOUNTER_CSR_FUNCS \ { .base =3D 0, .count =3D 0, .func =3D NULL }, =20 +static inline int kvm_riscv_vcpu_pmu_incr_fw(struct kvm_vcpu *vcpu, unsign= ed long fid) +{ + return 0; +} =20 static inline int kvm_riscv_vcpu_pmu_init(struct kvm_vcpu *vcpu) { diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h index 2a0ef738695e..a192a95a34eb 100644 --- a/arch/riscv/include/asm/sbi.h +++ b/arch/riscv/include/asm/sbi.h @@ -171,7 +171,7 @@ enum sbi_pmu_fw_generic_events_t { SBI_PMU_FW_IPI_SENT =3D 6, SBI_PMU_FW_IPI_RECVD =3D 7, SBI_PMU_FW_FENCE_I_SENT =3D 8, - SBI_PMU_FW_FENCE_I_RECVD =3D 9, + SBI_PMU_FW_FENCE_I_RCVD =3D 9, SBI_PMU_FW_SFENCE_VMA_SENT =3D 10, SBI_PMU_FW_SFENCE_VMA_RCVD =3D 11, SBI_PMU_FW_SFENCE_VMA_ASID_SENT =3D 12, diff --git a/arch/riscv/kvm/tlb.c b/arch/riscv/kvm/tlb.c index 1a76d0b1907d..0793d39e8ff7 100644 --- a/arch/riscv/kvm/tlb.c +++ b/arch/riscv/kvm/tlb.c @@ -240,6 +240,7 @@ void kvm_riscv_local_tlb_sanitize(struct kvm_vcpu *vcpu) =20 void kvm_riscv_fence_i_process(struct kvm_vcpu *vcpu) { + kvm_riscv_vcpu_pmu_incr_fw(vcpu, SBI_PMU_FW_FENCE_I_RCVD); local_flush_icache_all(); } =20 @@ -323,15 +324,18 @@ void kvm_riscv_hfence_process(struct kvm_vcpu *vcpu) d.addr, d.size, d.order); break; case KVM_RISCV_HFENCE_VVMA_ASID_GVA: + kvm_riscv_vcpu_pmu_incr_fw(vcpu, SBI_PMU_FW_HFENCE_VVMA_ASID_RCVD); kvm_riscv_local_hfence_vvma_asid_gva( READ_ONCE(v->vmid), d.asid, d.addr, d.size, d.order); break; case KVM_RISCV_HFENCE_VVMA_ASID_ALL: + kvm_riscv_vcpu_pmu_incr_fw(vcpu, SBI_PMU_FW_HFENCE_VVMA_ASID_RCVD); kvm_riscv_local_hfence_vvma_asid_all( READ_ONCE(v->vmid), d.asid); break; case KVM_RISCV_HFENCE_VVMA_GVA: + kvm_riscv_vcpu_pmu_incr_fw(vcpu, SBI_PMU_FW_HFENCE_VVMA_RCVD); kvm_riscv_local_hfence_vvma_gva( READ_ONCE(v->vmid), d.addr, d.size, d.order); @@ -382,7 +386,7 @@ void kvm_riscv_fence_i(struct kvm *kvm, unsigned long hbase, unsigned long hmask) { make_xfence_request(kvm, hbase, hmask, KVM_REQ_FENCE_I, - KVM_REQ_FENCE_I, NULL); + KVM_REQ_FENCE_I, NULL); } =20 void kvm_riscv_hfence_gvma_vmid_gpa(struct kvm *kvm, diff --git a/arch/riscv/kvm/vcpu_pmu.c b/arch/riscv/kvm/vcpu_pmu.c index 278c261efad3..f451d7ac2608 100644 --- a/arch/riscv/kvm/vcpu_pmu.c +++ b/arch/riscv/kvm/vcpu_pmu.c @@ -168,21 +168,39 @@ static int pmu_get_pmc_index(struct kvm_pmu *pmu, uns= igned long eidx, return pmu_get_programmable_pmc_index(pmu, eidx, cbase, cmask); } =20 +int kvm_riscv_vcpu_pmu_incr_fw(struct kvm_vcpu *vcpu, unsigned long fid) +{ + struct kvm_pmu *kvpmu =3D vcpu_to_pmu(vcpu); + struct kvm_fw_event *fevent; + + if (!kvpmu || fid >=3D SBI_PMU_FW_MAX) + return -EINVAL; + + fevent =3D &kvpmu->fw_event[fid]; + if (fevent->started) + fevent->value++; + + return 0; +} + int kvm_riscv_vcpu_pmu_ctr_read(struct kvm_vcpu *vcpu, unsigned long cidx, unsigned long *out_val) { struct kvm_pmu *kvpmu =3D vcpu_to_pmu(vcpu); struct kvm_pmc *pmc; u64 enabled, running; + int fevent_code; =20 if (!kvpmu) return -EINVAL; =20 pmc =3D &kvpmu->pmc[cidx]; - if (!pmc->perf_event) - return -EINVAL; =20 - pmc->counter_val +=3D perf_event_read_value(pmc->perf_event, &enabled, &r= unning); + if (pmc->cinfo.type =3D=3D SBI_PMU_CTR_TYPE_FW) { + fevent_code =3D get_event_code(pmc->event_idx); + pmc->counter_val =3D kvpmu->fw_event[fevent_code].value; + } else if (pmc->perf_event) + pmc->counter_val +=3D perf_event_read_value(pmc->perf_event, &enabled, &= running); *out_val =3D pmc->counter_val; =20 return 0; @@ -237,6 +255,7 @@ int kvm_riscv_vcpu_pmu_ctr_start(struct kvm_vcpu *vcpu,= unsigned long ctr_base, struct kvm_pmu *kvpmu =3D vcpu_to_pmu(vcpu); int i, num_ctrs, pmc_index; struct kvm_pmc *pmc; + int fevent_code; =20 num_ctrs =3D kvpmu->num_fw_ctrs + kvpmu->num_hw_ctrs; if (ctr_base + __fls(ctr_mask) >=3D num_ctrs) @@ -250,7 +269,14 @@ int kvm_riscv_vcpu_pmu_ctr_start(struct kvm_vcpu *vcpu= , unsigned long ctr_base, pmc =3D &kvpmu->pmc[pmc_index]; if (flag & SBI_PMU_START_FLAG_SET_INIT_VALUE) pmc->counter_val =3D ival; - if (pmc->perf_event) { + if (pmc->cinfo.type =3D=3D SBI_PMU_CTR_TYPE_FW) { + fevent_code =3D get_event_code(pmc->event_idx); + if (fevent_code >=3D SBI_PMU_FW_MAX) + return -EINVAL; + + kvpmu->fw_event[fevent_code].started =3D true; + kvpmu->fw_event[fevent_code].value =3D pmc->counter_val; + } else if (pmc->perf_event) { perf_event_period(pmc->perf_event, pmu_get_sample_period(pmc)); perf_event_enable(pmc->perf_event); } @@ -266,6 +292,7 @@ int kvm_riscv_vcpu_pmu_ctr_stop(struct kvm_vcpu *vcpu, = unsigned long ctr_base, int i, num_ctrs, pmc_index; u64 enabled, running; struct kvm_pmc *pmc; + int fevent_code; =20 num_ctrs =3D kvpmu->num_fw_ctrs + kvpmu->num_hw_ctrs; if ((ctr_base + __fls(ctr_mask)) >=3D num_ctrs) @@ -277,7 +304,12 @@ int kvm_riscv_vcpu_pmu_ctr_stop(struct kvm_vcpu *vcpu,= unsigned long ctr_base, if (!test_bit(pmc_index, kvpmu->used_pmc)) continue; pmc =3D &kvpmu->pmc[pmc_index]; - if (pmc->perf_event) { + if (pmc->cinfo.type =3D=3D SBI_PMU_CTR_TYPE_FW) { + fevent_code =3D get_event_code(pmc->event_idx); + if (fevent_code >=3D SBI_PMU_FW_MAX) + return -EINVAL; + kvpmu->fw_event[fevent_code].started =3D false; + } else if (pmc->perf_event) { /* Stop counting the counter */ perf_event_disable(pmc->perf_event); if (flag & SBI_PMU_STOP_FLAG_RESET) { @@ -285,9 +317,12 @@ int kvm_riscv_vcpu_pmu_ctr_stop(struct kvm_vcpu *vcpu,= unsigned long ctr_base, pmc->counter_val +=3D perf_event_read_value(pmc->perf_event, &enabled, &running); pmu_release_perf_event(pmc); - clear_bit(pmc_index, kvpmu->used_pmc); } } + if (flag & SBI_PMU_STOP_FLAG_RESET) { + pmc->event_idx =3D SBI_PMU_EVENT_IDX_INVALID; + clear_bit(pmc_index, kvpmu->used_pmc); + } } =20 return 0; @@ -303,14 +338,19 @@ int kvm_riscv_vcpu_pmu_ctr_cfg_match(struct kvm_vcpu = *vcpu, unsigned long ctr_ba int num_ctrs, ctr_idx; u32 etype =3D pmu_get_perf_event_type(eidx); u64 config; - struct kvm_pmc *pmc; + struct kvm_pmc *pmc =3D NULL; + bool is_fevent; + unsigned long event_code; =20 num_ctrs =3D kvpmu->num_fw_ctrs + kvpmu->num_hw_ctrs; if ((etype =3D=3D PERF_TYPE_MAX) || ((ctr_base + __fls(ctr_mask)) >=3D nu= m_ctrs)) return -EINVAL; =20 - if (pmu_is_fw_event(eidx)) + event_code =3D get_event_code(eidx); + is_fevent =3D pmu_is_fw_event(eidx); + if (is_fevent && event_code >=3D SBI_PMU_FW_MAX) return -EOPNOTSUPP; + /* * SKIP_MATCH flag indicates the caller is aware of the assigned counter * for this event. Just do a sanity check if it already marked used. @@ -319,13 +359,23 @@ int kvm_riscv_vcpu_pmu_ctr_cfg_match(struct kvm_vcpu = *vcpu, unsigned long ctr_ba if (!test_bit(ctr_base, kvpmu->used_pmc)) return -EINVAL; ctr_idx =3D ctr_base; - goto match_done; + if (is_fevent) + goto perf_event_done; + else + goto match_done; } =20 ctr_idx =3D pmu_get_pmc_index(kvpmu, eidx, ctr_base, ctr_mask); if (ctr_idx < 0) return -EOPNOTSUPP; =20 + /* + * No need to create perf events for firmware events as the firmware coun= ter + * is supposed to return the measurement of VS->HS mode invocations. + */ + if (is_fevent) + goto perf_event_done; + match_done: pmc =3D &kvpmu->pmc[ctr_idx]; pmu_release_perf_event(pmc); @@ -363,17 +413,26 @@ int kvm_riscv_vcpu_pmu_ctr_cfg_match(struct kvm_vcpu = *vcpu, unsigned long ctr_ba return -EOPNOTSUPP; } =20 - set_bit(ctr_idx, kvpmu->used_pmc); pmc->perf_event =3D event; - if (flag & SBI_PMU_CFG_FLAG_AUTO_START) - perf_event_enable(pmc->perf_event); +perf_event_done: + if (flag & SBI_PMU_CFG_FLAG_AUTO_START) { + if (is_fevent) + kvpmu->fw_event[event_code].started =3D true; + else + perf_event_enable(pmc->perf_event); + } + /* This should be only true for firmware events */ + if (!pmc) + pmc =3D &kvpmu->pmc[ctr_idx]; + pmc->event_idx =3D eidx; + set_bit(ctr_idx, kvpmu->used_pmc); =20 return ctr_idx; } =20 int kvm_riscv_vcpu_pmu_init(struct kvm_vcpu *vcpu) { - int i =3D 0, num_hw_ctrs, num_fw_ctrs, hpm_width; + int i, num_hw_ctrs, num_fw_ctrs, hpm_width; struct kvm_pmu *kvpmu =3D vcpu_to_pmu(vcpu); struct kvm_pmc *pmc; =20 @@ -395,6 +454,7 @@ int kvm_riscv_vcpu_pmu_init(struct kvm_vcpu *vcpu) bitmap_zero(kvpmu->used_pmc, RISCV_MAX_COUNTERS); kvpmu->num_hw_ctrs =3D num_hw_ctrs; kvpmu->num_fw_ctrs =3D num_fw_ctrs; + memset(&kvpmu->fw_event, 0, SBI_PMU_FW_MAX * sizeof(struct kvm_fw_event)); /* * There is no corelation betwen the logical hardware counter and virtual= counters. * However, we need to encode a hpmcounter CSR in the counter info field = so that @@ -409,6 +469,7 @@ int kvm_riscv_vcpu_pmu_init(struct kvm_vcpu *vcpu) pmc->idx =3D i; pmc->counter_val =3D 0; pmc->vcpu =3D vcpu; + pmc->event_idx =3D SBI_PMU_EVENT_IDX_INVALID; if (i < kvpmu->num_hw_ctrs) { kvpmu->pmc[i].cinfo.type =3D SBI_PMU_CTR_TYPE_HW; if (i < 3) @@ -444,7 +505,10 @@ void kvm_riscv_vcpu_pmu_deinit(struct kvm_vcpu *vcpu) for_each_set_bit(i, kvpmu->used_pmc, RISCV_MAX_COUNTERS) { pmc =3D &kvpmu->pmc[i]; pmu_release_perf_event(pmc); + pmc->counter_val =3D 0; + pmc->event_idx =3D SBI_PMU_EVENT_IDX_INVALID; } + memset(&kvpmu->fw_event, 0, SBI_PMU_FW_MAX * sizeof(struct kvm_fw_event)); } =20 void kvm_riscv_vcpu_pmu_reset(struct kvm_vcpu *vcpu) diff --git a/arch/riscv/kvm/vcpu_sbi_replace.c b/arch/riscv/kvm/vcpu_sbi_re= place.c index 4c034d8a606a..614ae127e102 100644 --- a/arch/riscv/kvm/vcpu_sbi_replace.c +++ b/arch/riscv/kvm/vcpu_sbi_replace.c @@ -12,6 +12,7 @@ #include #include #include +#include #include =20 static int kvm_sbi_ext_time_handler(struct kvm_vcpu *vcpu, struct kvm_run = *run, @@ -25,6 +26,7 @@ static int kvm_sbi_ext_time_handler(struct kvm_vcpu *vcpu= , struct kvm_run *run, if (cp->a6 !=3D SBI_EXT_TIME_SET_TIMER) return -EINVAL; =20 + kvm_riscv_vcpu_pmu_incr_fw(vcpu, SBI_PMU_FW_SET_TIMER); #if __riscv_xlen =3D=3D 32 next_cycle =3D ((u64)cp->a1 << 32) | (u64)cp->a0; #else @@ -55,6 +57,7 @@ static int kvm_sbi_ext_ipi_handler(struct kvm_vcpu *vcpu,= struct kvm_run *run, if (cp->a6 !=3D SBI_EXT_IPI_SEND_IPI) return -EINVAL; =20 + kvm_riscv_vcpu_pmu_incr_fw(vcpu, SBI_PMU_FW_IPI_SENT); kvm_for_each_vcpu(i, tmp, vcpu->kvm) { if (hbase !=3D -1UL) { if (tmp->vcpu_id < hbase) @@ -65,6 +68,7 @@ static int kvm_sbi_ext_ipi_handler(struct kvm_vcpu *vcpu,= struct kvm_run *run, ret =3D kvm_riscv_vcpu_set_interrupt(tmp, IRQ_VS_SOFT); if (ret < 0) break; + kvm_riscv_vcpu_pmu_incr_fw(tmp, SBI_PMU_FW_IPI_RECVD); } =20 return ret; @@ -89,6 +93,7 @@ static int kvm_sbi_ext_rfence_handler(struct kvm_vcpu *vc= pu, struct kvm_run *run switch (funcid) { case SBI_EXT_RFENCE_REMOTE_FENCE_I: kvm_riscv_fence_i(vcpu->kvm, hbase, hmask); + kvm_riscv_vcpu_pmu_incr_fw(vcpu, SBI_PMU_FW_FENCE_I_SENT); break; case SBI_EXT_RFENCE_REMOTE_SFENCE_VMA: if (cp->a2 =3D=3D 0 && cp->a3 =3D=3D 0) @@ -96,6 +101,7 @@ static int kvm_sbi_ext_rfence_handler(struct kvm_vcpu *v= cpu, struct kvm_run *run else kvm_riscv_hfence_vvma_gva(vcpu->kvm, hbase, hmask, cp->a2, cp->a3, PAGE_SHIFT); + kvm_riscv_vcpu_pmu_incr_fw(vcpu, SBI_PMU_FW_HFENCE_VVMA_SENT); break; case SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID: if (cp->a2 =3D=3D 0 && cp->a3 =3D=3D 0) @@ -106,6 +112,7 @@ static int kvm_sbi_ext_rfence_handler(struct kvm_vcpu *= vcpu, struct kvm_run *run hbase, hmask, cp->a2, cp->a3, PAGE_SHIFT, cp->a4); + kvm_riscv_vcpu_pmu_incr_fw(vcpu, SBI_PMU_FW_HFENCE_VVMA_ASID_SENT); break; case SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA: case SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID: --=20 2.25.1