From nobody Sat Jun 13 15:24:19 2026 Received: from out-188.mta1.migadu.com (out-188.mta1.migadu.com [95.215.58.188]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F265F3C942C for ; Tue, 9 Jun 2026 06:01:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.188 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984894; cv=none; b=QeZuX4praLfo+ejnLxBkNQVWXgTEXxk2NEpJGJusRaYwRuW91z5IdRkMBgHprU/HWOT3bSCoOE8gsAxWizCSUZ190gEt+VUPY9xFPC+1AIsPQModrnwGa//Lh04zgh69yaSBsc3J9w62uGzLv2g86Qud0zwrI0zYMZYRB31kGg0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984894; c=relaxed/simple; bh=49sToyKTSjS66TuV/1Gvj6ise9Amt4gQHPByMHgSiiE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=KgIRqR9530oioCCVareB3DvaPwzlLjrAZUkDcFCK3RtXEryEhmd/kwNbNf32ObXhD4ufftx20mP87dUIPjval+oE1Zi7regVEDGU1isKBsrk1nhDXDxZB88FxIt/DYE4gj8/lxLt7jsVRXTs240rQMis9d92W5wBJxFiva/fGWs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=NsosH7lb; arc=none smtp.client-ip=95.215.58.188 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="NsosH7lb" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1780984890; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=gg1b4NvG9irnTlONKFumTIckFqfflTt6uFIpf+8fltI=; b=NsosH7lbdAl7llskJQxfh1OWH6ncadC5/IE7tZbtlVGfpjv934jV9d3zmZMBdc6S5g2Fk8 0N5/gFzI9ACuZ3tKwejhs4QeDUNnDi42zgShxf5Gt4C7AN+EswLRMspCWU1C5UTHVdbEmM VjERLNCyvxoLOCfb3RPeFRIUsStL4RA= From: Atish Patra Date: Mon, 08 Jun 2026 23:01:15 -0700 Subject: [PATCH v6 01/21] RISC-V: Add Sxcsrind ISA extension CSR definitions Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260608-counter_delegation-v6-1-285b72ed65a9@meta.com> References: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> In-Reply-To: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> To: James Clark , Rob Herring , Atish Patra , Arnaldo Carvalho de Melo , Jiri Olsa , Will Deacon , Mark Rutland , Anup Patel , Namhyung Kim , Paul Walmsley , Krzysztof Kozlowski , Ian Rogers Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Conor Dooley , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org X-Migadu-Flow: FLOW_OUT From: Kaiwen Xue This adds definitions of new CSRs and bits defined in Sxcsrind ISA extension. These CSR enables indirect accesses mechanism to access any CSRs in M-, S-, and VS-mode. The range of the select values and ireg will be define by the ISA extension using Sxcsrind extension. Signed-off-by: Kaiwen Xue Reviewed-by: Cl=C3=A9ment L=C3=A9ger Signed-off-by: Atish Patra --- arch/riscv/include/asm/csr.h | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h index 31b8988f4488..b4551a6cf7cb 100644 --- a/arch/riscv/include/asm/csr.h +++ b/arch/riscv/include/asm/csr.h @@ -347,6 +347,12 @@ /* Supervisor-Level Window to Indirectly Accessed Registers (AIA) */ #define CSR_SISELECT 0x150 #define CSR_SIREG 0x151 +/* Supervisor-Level Window to Indirectly Accessed Registers (Sxcsrind) */ +#define CSR_SIREG2 0x152 +#define CSR_SIREG3 0x153 +#define CSR_SIREG4 0x155 +#define CSR_SIREG5 0x156 +#define CSR_SIREG6 0x157 =20 /* Supervisor-Level Interrupts (AIA) */ #define CSR_STOPEI 0x15c @@ -394,6 +400,14 @@ /* VS-Level Window to Indirectly Accessed Registers (H-extension with AIA)= */ #define CSR_VSISELECT 0x250 #define CSR_VSIREG 0x251 +/* + * VS-Level Window to Indirectly Accessed Registers (H-extension with Sxcs= rind) + */ +#define CSR_VSIREG2 0x252 +#define CSR_VSIREG3 0x253 +#define CSR_VSIREG4 0x255 +#define CSR_VSIREG5 0x256 +#define CSR_VSIREG6 0x257 =20 /* VS-Level Interrupts (H-extension with AIA) */ #define CSR_VSTOPEI 0x25c @@ -436,6 +450,12 @@ /* Machine-Level Window to Indirectly Accessed Registers (AIA) */ #define CSR_MISELECT 0x350 #define CSR_MIREG 0x351 +/* Machine-Level Window to Indirectly Accessed Registers (Sxcsrind) */ +#define CSR_MIREG2 0x352 +#define CSR_MIREG3 0x353 +#define CSR_MIREG4 0x355 +#define CSR_MIREG5 0x356 +#define CSR_MIREG6 0x357 =20 /* Machine-Level Interrupts (AIA) */ #define CSR_MTOPEI 0x35c @@ -498,6 +518,11 @@ # define CSR_IEH CSR_MIEH # define CSR_ISELECT CSR_MISELECT # define CSR_IREG CSR_MIREG +# define CSR_IREG2 CSR_MIREG2 +# define CSR_IREG3 CSR_MIREG3 +# define CSR_IREG4 CSR_MIREG4 +# define CSR_IREG5 CSR_MIREG5 +# define CSR_IREG6 CSR_MIREG6 # define CSR_IPH CSR_MIPH # define CSR_TOPEI CSR_MTOPEI # define CSR_TOPI CSR_MTOPI @@ -523,6 +548,11 @@ # define CSR_IEH CSR_SIEH # define CSR_ISELECT CSR_SISELECT # define CSR_IREG CSR_SIREG +# define CSR_IREG2 CSR_SIREG2 +# define CSR_IREG3 CSR_SIREG3 +# define CSR_IREG4 CSR_SIREG4 +# define CSR_IREG5 CSR_SIREG5 +# define CSR_IREG6 CSR_SIREG6 # define CSR_IPH CSR_SIPH # define CSR_TOPEI CSR_STOPEI # define CSR_TOPI CSR_STOPI --=20 2.53.0-Meta From nobody Sat Jun 13 15:24:19 2026 Received: from out-186.mta0.migadu.com (out-186.mta0.migadu.com [91.218.175.186]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BB4FB3CB8F4 for ; Tue, 9 Jun 2026 06:01:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.186 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984909; cv=none; b=Rhygg7b3qzfm1b5eUV7llGS1LvnzwsHhtgK2GL7NvOkfJacone6EykQm8LAuRwQsYzSxIAglahCr5b6AnfaX+MOexO+2mdIkWAZYXywCRgPWI+z3LT0y4ePXsVxQkxa0akFUMNOAlk5OcD9N1+ToMmqKCASE8SrAT40hIizxxrc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984909; c=relaxed/simple; bh=GGx0NZaHhk7E2NAtvsdpcvF5HPVyVNDE83nBISLAwX0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=uD22uMeA6l49a2ckFhDDFJo3SxYUTkikt3rZLCWIuY+x7fSBrnVD0gKaXcAPCgQBSa79nScdKc6d6l3IxSnaMSqYJ+pheMA9MzkEnMwvb+EtVEGReclRZ++3XvH1MS82iRmlUrJimQ7nz3mnIJuZ4dB+yLvqTzr8N86UKBwcWvg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=tBdD5u7R; arc=none smtp.client-ip=91.218.175.186 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="tBdD5u7R" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1780984894; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=zryXcVid5vc6uq/c5lbU5QHgsNUYuSSps54Hsm8mVUc=; b=tBdD5u7RSv6pJnLvLh9+DfeLkFJY1MT2YNmCgUZ5fH3XrgUDZEb0VNN8MVGWNVPT0zjE28 1Gsv/OWsCjlQwG/S58P0ojmSG6Bsrm592iVYmRwYJwdwXqcDYIeAjWyWqfyXhALbu2Pxlh r7j/1X64Tx/jRATUrgMOfYqCsNn0HCk= From: Atish Patra Date: Mon, 08 Jun 2026 23:01:16 -0700 Subject: [PATCH v6 02/21] RISC-V: Add Sxcsrind ISA extension definition and parsing Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260608-counter_delegation-v6-2-285b72ed65a9@meta.com> References: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> In-Reply-To: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> To: James Clark , Rob Herring , Atish Patra , Arnaldo Carvalho de Melo , Jiri Olsa , Will Deacon , Mark Rutland , Anup Patel , Namhyung Kim , Paul Walmsley , Krzysztof Kozlowski , Ian Rogers Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Conor Dooley , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org X-Migadu-Flow: FLOW_OUT From: Atish Patra The S[m|s]csrind extension extends the indirect CSR access mechanism defined in Smaia/Ssaia extensions. This patch just enables the definition and parsing. Signed-off-by: Atish Patra --- arch/riscv/include/asm/hwcap.h | 4 ++++ arch/riscv/kernel/cpufeature.c | 2 ++ 2 files changed, 6 insertions(+) diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h index 7ef8e5f55c8d..d4a7b90e2d78 100644 --- a/arch/riscv/include/asm/hwcap.h +++ b/arch/riscv/include/asm/hwcap.h @@ -112,6 +112,8 @@ #define RISCV_ISA_EXT_ZCLSD 103 #define RISCV_ISA_EXT_ZICFILP 104 #define RISCV_ISA_EXT_ZICFISS 105 +#define RISCV_ISA_EXT_SSCSRIND 106 +#define RISCV_ISA_EXT_SMCSRIND 107 =20 #define RISCV_ISA_EXT_XLINUXENVCFG 127 =20 @@ -121,9 +123,11 @@ #ifdef CONFIG_RISCV_M_MODE #define RISCV_ISA_EXT_SxAIA RISCV_ISA_EXT_SMAIA #define RISCV_ISA_EXT_SUPM RISCV_ISA_EXT_SMNPM +#define RISCV_ISA_EXT_SxCSRIND RISCV_ISA_EXT_SMCSRIND #else #define RISCV_ISA_EXT_SxAIA RISCV_ISA_EXT_SSAIA #define RISCV_ISA_EXT_SUPM RISCV_ISA_EXT_SSNPM +#define RISCV_ISA_EXT_SxCSRIND RISCV_ISA_EXT_SSCSRIND #endif =20 #endif /* _ASM_RISCV_HWCAP_H */ diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c index f46aa5602d74..3fa0a563fb21 100644 --- a/arch/riscv/kernel/cpufeature.c +++ b/arch/riscv/kernel/cpufeature.c @@ -576,11 +576,13 @@ const struct riscv_isa_ext_data riscv_isa_ext[] =3D { __RISCV_ISA_EXT_BUNDLE_VALIDATE(zvksg, riscv_zvksg_bundled_exts, riscv_ex= t_vector_crypto_validate), __RISCV_ISA_EXT_DATA_VALIDATE(zvkt, RISCV_ISA_EXT_ZVKT, riscv_ext_vector_= crypto_validate), __RISCV_ISA_EXT_DATA(smaia, RISCV_ISA_EXT_SMAIA), + __RISCV_ISA_EXT_DATA(smcsrind, RISCV_ISA_EXT_SMCSRIND), __RISCV_ISA_EXT_DATA(smmpm, RISCV_ISA_EXT_SMMPM), __RISCV_ISA_EXT_SUPERSET(smnpm, RISCV_ISA_EXT_SMNPM, riscv_xlinuxenvcfg_e= xts), __RISCV_ISA_EXT_DATA(smstateen, RISCV_ISA_EXT_SMSTATEEN), __RISCV_ISA_EXT_DATA(ssaia, RISCV_ISA_EXT_SSAIA), __RISCV_ISA_EXT_DATA(sscofpmf, RISCV_ISA_EXT_SSCOFPMF), + __RISCV_ISA_EXT_DATA(sscsrind, RISCV_ISA_EXT_SSCSRIND), __RISCV_ISA_EXT_SUPERSET(ssnpm, RISCV_ISA_EXT_SSNPM, riscv_xlinuxenvcfg_e= xts), __RISCV_ISA_EXT_DATA(sstc, RISCV_ISA_EXT_SSTC), __RISCV_ISA_EXT_DATA(svade, RISCV_ISA_EXT_SVADE), --=20 2.53.0-Meta From nobody Sat Jun 13 15:24:19 2026 Received: from out-179.mta0.migadu.com (out-179.mta0.migadu.com [91.218.175.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3AD193CB2E5; Tue, 9 Jun 2026 06:01:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984901; cv=none; b=T2fFlHyim9A6Au87qYcyzojJ/+3x6ibs2kEwjQo9giLxjkiYm0sXl4zk5HXiLJsS32bzAwkqwM2meFAi5Z/zeNJgX7/JUYVb15cw6dsYRJf4/Eklp5GaItirJgbAMHSTG4Mppvs5EXwhsNEfr41hgmv/vSZ81AydWRM6SeoqfmE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984901; c=relaxed/simple; bh=Uy+6u+zVVnKDyhH828jdTZwad1FK1t8vFUHFHWkaisM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=GMamlalffWg/3KmYg66wnrRdQIf70m5YCeyh84XtuLcde17M42sa7an4uc5iHCgpndfmnKT/25l9WGcoiRh+b+s1oxgePAGr3/DP0VyxQrxhUiETKUYO87FdqDpgoOv3oMvs++f2S4k2z5W8HHzb1e1NeLEz1OzTRQTWGLh1qQM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=sw3aDZVd; arc=none smtp.client-ip=91.218.175.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="sw3aDZVd" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1780984898; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=UiQdcLZt3TDwJvzued5odyBBsjPd7XdI6I5xzQS3xEM=; b=sw3aDZVdPfe7llAGxyxlkoeaj+NZpqQ/1TJM1oDrs+kUR3wvHtJBHbN1vZstxRbklghJic rWrY5YxoeQ5ifGmmA6R1Nv+8t2fDwbJSDpCAFMwNpY8pxwetZhFooBdJ0YArhjPejNqGuh AwS5gfWT188HhM3CpvbwxQ+bkjvke7E= From: Atish Patra Date: Mon, 08 Jun 2026 23:01:17 -0700 Subject: [PATCH v6 03/21] dt-bindings: riscv: add Sxcsrind ISA extension description Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260608-counter_delegation-v6-3-285b72ed65a9@meta.com> References: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> In-Reply-To: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> To: James Clark , Rob Herring , Atish Patra , Arnaldo Carvalho de Melo , Jiri Olsa , Will Deacon , Mark Rutland , Anup Patel , Namhyung Kim , Paul Walmsley , Krzysztof Kozlowski , Ian Rogers Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Conor Dooley , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org X-Migadu-Flow: FLOW_OUT From: Atish Patra Add the S[m|s]csrind ISA extension description. Acked-by: Rob Herring (Arm) Signed-off-by: Atish Patra --- Documentation/devicetree/bindings/riscv/extensions.yaml | 16 +++++++++++++= +++ 1 file changed, 16 insertions(+) diff --git a/Documentation/devicetree/bindings/riscv/extensions.yaml b/Docu= mentation/devicetree/bindings/riscv/extensions.yaml index 2b0a8a93bb21..4be557dc215d 100644 --- a/Documentation/devicetree/bindings/riscv/extensions.yaml +++ b/Documentation/devicetree/bindings/riscv/extensions.yaml @@ -181,6 +181,14 @@ properties: changes to interrupts as frozen at commit ccbddab ("Merge pull request #42 from riscv/jhauser-2023-RC4") of riscv-aia. =20 + - const: smcsrind + description: | + The standard Smcsrind supervisor-level extension extends the + indirect CSR access mechanism defined by the Smaia extension. = This + extension allows other ISA extension to use indirect CSR access + mechanism in M-mode as ratified in the 20240326 version of the + privileged ISA specification. + - const: smmpm description: | The standard Smmpm extension for M-mode pointer masking as @@ -199,6 +207,14 @@ properties: added by other RISC-V extensions in H/S/VS/U/VU modes and as ratified at commit a28bfae (Ratified (#7)) of riscv-state-enab= le. =20 + - const: sscsrind + description: | + The standard Sscsrind supervisor-level extension extends the + indirect CSR access mechanism defined by the Ssaia extension. = This + extension allows other ISA extension to use indirect CSR access + mechanism in S-mode as ratified in the 20240326 version of the + privileged ISA specification. + - const: ssaia description: | The standard Ssaia supervisor-level extension for the advanced --=20 2.53.0-Meta From nobody Sat Jun 13 15:24:19 2026 Received: from out-176.mta1.migadu.com (out-176.mta1.migadu.com [95.215.58.176]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EF9EF3CA4B6 for ; Tue, 9 Jun 2026 06:01:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.176 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984907; cv=none; b=gFmj5DjE2LwDny4H6mQpCZWL6iEMHrbYUca8Sa8KdJiS8e7XeETqzUZOK5FQPAJ69+prypJBDH+7+c56I4eOEu88j9sWCjx7c4ZTiQ8A5WCPy6QY45PyNI0rn6s5KptfZdzNmmEeWgCvy0BPzdEdF4eJxxy0kwWf93MD1dVxUEc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984907; c=relaxed/simple; bh=d8QlKHkfqNhfYohsE98McxXyqugfqZ6DLhV9E4Pu1qY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=e+I1mCdDF+EOt+mtvSJAX2Kq9YNaGN2sxf/2X6ufKxe+RH9Ta9mZm2uO7ZfsIL5KuFgCifD6sWp3HgW/eUjv66xhnItoH5nM/b/EqeCQk3xcbTVhQTBrMrDIni3eozv/pA0y3io1UfijoQYAiVYDLWC8SLyfxb6Qc0wrr8Ul9TA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=WT6Ohiol; arc=none smtp.client-ip=95.215.58.176 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="WT6Ohiol" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1780984904; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Vu7UaTVidpWvsx9wHZ3XDd5Hh0ON6Lo1UHqkFEyPu34=; b=WT6OhiolxkqKy78e365lfBny3qt/Y9J9QpcCcbQCiUH4bVvJ1B7zNHjqqhd4DdLpaYR80E A2QRg/b7jfIiLkugqJ/E/q3b+J14jz5G1N2XO1RBuYwGMyZ1/+yk37nEPvFTrczG6IUSNi bdMcj6deKuZJV7MmAtHWwZ1q8pPNb7Q= From: Atish Patra Date: Mon, 08 Jun 2026 23:01:18 -0700 Subject: [PATCH v6 04/21] RISC-V: Define indirect CSR access helpers Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260608-counter_delegation-v6-4-285b72ed65a9@meta.com> References: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> In-Reply-To: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> To: James Clark , Rob Herring , Atish Patra , Arnaldo Carvalho de Melo , Jiri Olsa , Will Deacon , Mark Rutland , Anup Patel , Namhyung Kim , Paul Walmsley , Krzysztof Kozlowski , Ian Rogers Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Conor Dooley , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org X-Migadu-Flow: FLOW_OUT From: Atish Patra The indriect CSR requires multiple instructions to read/write CSR. Add a few helper functions for ease of usage. Signed-off-by: Atish Patra --- arch/riscv/include/asm/csr_ind.h | 44 ++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 44 insertions(+) diff --git a/arch/riscv/include/asm/csr_ind.h b/arch/riscv/include/asm/csr_= ind.h new file mode 100644 index 000000000000..6fd7d44dc640 --- /dev/null +++ b/arch/riscv/include/asm/csr_ind.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2024 Rivos Inc. + */ + +#ifndef _ASM_RISCV_CSR_IND_H +#define _ASM_RISCV_CSR_IND_H + +#include + +#include + +#define csr_ind_read(iregcsr, iselbase, iseloff) ({ \ + unsigned long __value =3D 0; \ + unsigned long __flags; \ + local_irq_save(__flags); \ + csr_write(CSR_ISELECT, (iselbase) + (iseloff)); \ + __value =3D csr_read(iregcsr); \ + local_irq_restore(__flags); \ + __value; \ +}) + +#define csr_ind_write(iregcsr, iselbase, iseloff, value) ({ \ + unsigned long __flags; \ + local_irq_save(__flags); \ + csr_write(CSR_ISELECT, (iselbase) + (iseloff)); \ + csr_write(iregcsr, (value)); \ + local_irq_restore(__flags); \ +}) + +#define csr_ind_warl(iregcsr, iselbase, iseloff, warl_val) ({ \ + unsigned long __old_val =3D 0, __value =3D 0; \ + unsigned long __flags; \ + local_irq_save(__flags); \ + csr_write(CSR_ISELECT, (iselbase) + (iseloff)); \ + __old_val =3D csr_read(iregcsr); \ + csr_write(iregcsr, (warl_val)); \ + __value =3D csr_read(iregcsr); \ + csr_write(iregcsr, __old_val); \ + local_irq_restore(__flags); \ + __value; \ +}) + +#endif --=20 2.53.0-Meta From nobody Sat Jun 13 15:24:19 2026 Received: from out-170.mta0.migadu.com (out-170.mta0.migadu.com [91.218.175.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 99F103CE495 for ; Tue, 9 Jun 2026 06:01:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984911; cv=none; b=HopShrhoGvBx9bc+vM9RVt2LNutrQrHA39UvlB4lYy8b/qWIjuobGAqo2iCNoyRpoSOsW/JlhC/4Agy0aTMjHIL5Ayn7IUrj/ypuRzab9pRd341Dujea6q3fAhHyZjdyNvjADptmg6NH2a3LG30JNnyWOELVwXEnbeoBdgiUeIM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984911; c=relaxed/simple; bh=FwlMtQ49kbp1glYfmPcDRRhVmKYRsjTnj8YKFWSrXlo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=FGN9jW9SGt8PdHbOkNCEyW/jtWSMhDuT/CoB8/+Rsq2i9m/MT1Xd+X82RtjVWTLF8aBWlv5HZ5FHOUdgfOFxecAYb9/yhdVksO/scwuvHBB+w7fAXUgZun8MVLyyP4xxwHRg5NZc0eRcteDOmlXmEcArNIOZ6bAngBDpFvbd5Bo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=mK5dqfHy; arc=none smtp.client-ip=91.218.175.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="mK5dqfHy" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1780984907; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=g0CMNWEqrDOucVLL8KJozQojI6+LfSI56XzYeVMxjRY=; b=mK5dqfHyJvdr6BZk1BEPRAOOBoUrzsqiJToe6+57nd3OgfEwMMrTqUyrc3C6R13eoQV5bK GUd32G9qEHzpJgzCqyn0F5yG34JjsrJYcKg9DLtbQluj8ZeTgYYOfoj9ghxvNFsaJ8AipB BIL+VGKswhlCmSmJs/bHwvc2vYkoVLk= From: Atish Patra Date: Mon, 08 Jun 2026 23:01:19 -0700 Subject: [PATCH v6 05/21] RISC-V: Add Smcntrpmf extension parsing Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260608-counter_delegation-v6-5-285b72ed65a9@meta.com> References: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> In-Reply-To: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> To: James Clark , Rob Herring , Atish Patra , Arnaldo Carvalho de Melo , Jiri Olsa , Will Deacon , Mark Rutland , Anup Patel , Namhyung Kim , Paul Walmsley , Krzysztof Kozlowski , Ian Rogers Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Conor Dooley , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org X-Migadu-Flow: FLOW_OUT From: Atish Patra Smcntrpmf extension allows M-mode to enable privilege mode filtering for cycle/instret counters. However, the cyclecfg/instretcfg CSRs are only available only in Ssccfg only Smcntrpmf is present. That's why, kernel needs to detect presence of Smcntrpmf extension and enable privilege mode filtering for cycle/instret counters. Reviewed-by: Cl=C3=A9ment L=C3=A9ger Signed-off-by: Atish Patra --- arch/riscv/include/asm/hwcap.h | 1 + arch/riscv/kernel/cpufeature.c | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h index d4a7b90e2d78..51ad55b9677a 100644 --- a/arch/riscv/include/asm/hwcap.h +++ b/arch/riscv/include/asm/hwcap.h @@ -114,6 +114,7 @@ #define RISCV_ISA_EXT_ZICFISS 105 #define RISCV_ISA_EXT_SSCSRIND 106 #define RISCV_ISA_EXT_SMCSRIND 107 +#define RISCV_ISA_EXT_SMCNTRPMF 108 =20 #define RISCV_ISA_EXT_XLINUXENVCFG 127 =20 diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c index 3fa0a563fb21..1452521d740a 100644 --- a/arch/riscv/kernel/cpufeature.c +++ b/arch/riscv/kernel/cpufeature.c @@ -576,6 +576,7 @@ const struct riscv_isa_ext_data riscv_isa_ext[] =3D { __RISCV_ISA_EXT_BUNDLE_VALIDATE(zvksg, riscv_zvksg_bundled_exts, riscv_ex= t_vector_crypto_validate), __RISCV_ISA_EXT_DATA_VALIDATE(zvkt, RISCV_ISA_EXT_ZVKT, riscv_ext_vector_= crypto_validate), __RISCV_ISA_EXT_DATA(smaia, RISCV_ISA_EXT_SMAIA), + __RISCV_ISA_EXT_DATA(smcntrpmf, RISCV_ISA_EXT_SMCNTRPMF), __RISCV_ISA_EXT_DATA(smcsrind, RISCV_ISA_EXT_SMCSRIND), __RISCV_ISA_EXT_DATA(smmpm, RISCV_ISA_EXT_SMMPM), __RISCV_ISA_EXT_SUPERSET(smnpm, RISCV_ISA_EXT_SMNPM, riscv_xlinuxenvcfg_e= xts), --=20 2.53.0-Meta From nobody Sat Jun 13 15:24:19 2026 Received: from out-185.mta0.migadu.com (out-185.mta0.migadu.com [91.218.175.185]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CB0ED3CA4B6 for ; Tue, 9 Jun 2026 06:01:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.185 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984920; cv=none; b=iPWaGuRYDQqX2szq+TPk66IP+WtjBdTVmcd0MjWw/QoyZ6TINWGnx+u+lmxd2Fe8DbjolcjgjqHd9Ribz+jsQPbrGtD+5uUPpBtfWg/dlZikjQy9JViMHNuEOB4LZSC0x58RRtFlWgMUbCkXKA78Ua7NKC7tkX1+hqJ64YOUbBA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984920; c=relaxed/simple; bh=nJOcWJBEV9fadgP8JEjTL/5e2EUZM1JR6LrsPHWKLIc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=twexu+pzJRK9mieBju7OI52un7T+zYc2AcMTfrW9k/u2tc1xqEKtDCKUV6m5NOMjI+Zc0qjvX4IQNPPGKVJkzlDG/FRl0yY8xaFmI2+YrI+9pKtawwpAluAsGyroYxeEQLvw1Z41nOcmuf9Zwp+oTBSPUmj/Z1zXWB9OoG+4OaM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=Aq/6FHUG; arc=none smtp.client-ip=91.218.175.185 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="Aq/6FHUG" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1780984916; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=E82w67fq9EBYXBV6jCxGeX2AO5J6owLbBNFrIt5fD0A=; b=Aq/6FHUGy1MFnD7UhRFq2ls14v0LzlHHh3gqMxZZYRUpcAEWBtjxqjPBpiEY6wIVtkLpZN BV6VDQGEPM4yKusFGdKKOt5rTq4YKfrjJJUT0tjVpyv7k4PyZEH57pZmlFUX+74cA1y545 Z6JxgYRYQOgAPIKQay1poWzSMLcUjPk= From: Atish Patra Date: Mon, 08 Jun 2026 23:01:20 -0700 Subject: [PATCH v6 06/21] dt-bindings: riscv: add Smcntrpmf ISA extension description Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260608-counter_delegation-v6-6-285b72ed65a9@meta.com> References: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> In-Reply-To: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> To: James Clark , Rob Herring , Atish Patra , Arnaldo Carvalho de Melo , Jiri Olsa , Will Deacon , Mark Rutland , Anup Patel , Namhyung Kim , Paul Walmsley , Krzysztof Kozlowski , Ian Rogers Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Conor Dooley , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org X-Migadu-Flow: FLOW_OUT From: Atish Patra Add the description for Smcntrpmf ISA extension Acked-by: Rob Herring (Arm) Signed-off-by: Atish Patra --- Documentation/devicetree/bindings/riscv/extensions.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/riscv/extensions.yaml b/Docu= mentation/devicetree/bindings/riscv/extensions.yaml index 4be557dc215d..ece3edccee42 100644 --- a/Documentation/devicetree/bindings/riscv/extensions.yaml +++ b/Documentation/devicetree/bindings/riscv/extensions.yaml @@ -189,6 +189,12 @@ properties: mechanism in M-mode as ratified in the 20240326 version of the privileged ISA specification. =20 + - const: smcntrpmf + description: | + The standard Smcntrpmf supervisor-level extension for the mach= ine mode + to enable privilege mode filtering for cycle and instret count= ers as + ratified in the 20240326 version of the privileged ISA specifi= cation. + - const: smmpm description: | The standard Smmpm extension for M-mode pointer masking as --=20 2.53.0-Meta From nobody Sat Jun 13 15:24:19 2026 Received: from out-189.mta1.migadu.com (out-189.mta1.migadu.com [95.215.58.189]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D1C403CB2E5 for ; Tue, 9 Jun 2026 06:02:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.189 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984938; cv=none; b=jpl0vhCWj6ijnng0duUxml4Isu+0H9No2sn7k3a42TV/Jy6eRd2SHih6+n3qMjuI6JBx2RGsaj6SMNEaYgNdC2S5yg3yRdokPm1F4mEcEVI5sgJXbd1S+dJBW9NIjnh+NWNc47txsuhwvSPaGnkPn11H5/Dz7zsmaEHlc4vZmFs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984938; c=relaxed/simple; bh=PhrnjQNoHHekVxD7lhFqNH8ZhNIYm6hdQS1My0ZyNtc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=RhaueHFqDyaIHkGxmMSHGGIqZPvuZP1pYOkcCEXM8qiy8vSLG1UiqnmBtH3jjKvODviyXgI4FJa2/JBvbuk8CSJUvQ/wX+05wW5OXAVHyVkOOKyAxxdrilxL6nzAwXSmpDiwX454I5Ez+40DsdSZZOf3Ex/BePkufY06xp5KqX0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=dFw0aLQc; arc=none smtp.client-ip=95.215.58.189 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="dFw0aLQc" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1780984934; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=VQXL+H2+WehLdwmI2owi3GLpWwMtdQ4h0ysYeLBCJ7Q=; b=dFw0aLQcYAf00tYQgPc0vZjfN3tICce2mjvDxDboqJyEtkKsieeJKyGSYVrpm/Q64lA6k+ CuZJsmufEUpmQZsRL0zVHHtIxUzwJqK+6m0nMHkq5rCCYGZvJWqQquSO05AMIn9W/R2BxQ oBESg9DTLX4BwguGVy90rz0n5J6BLPE= From: Atish Patra Date: Mon, 08 Jun 2026 23:01:21 -0700 Subject: [PATCH v6 07/21] RISC-V: Add Sscfg extension CSR definition Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260608-counter_delegation-v6-7-285b72ed65a9@meta.com> References: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> In-Reply-To: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> To: James Clark , Rob Herring , Atish Patra , Arnaldo Carvalho de Melo , Jiri Olsa , Will Deacon , Mark Rutland , Anup Patel , Namhyung Kim , Paul Walmsley , Krzysztof Kozlowski , Ian Rogers Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Conor Dooley , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org X-Migadu-Flow: FLOW_OUT From: Kaiwen Xue This adds the scountinhibit CSR definition and S-mode accessible hpmevent bits defined by smcdeleg/ssccfg. scountinhibit allows S-mode to start/stop counters directly from S-mode without invoking SBI calls to M-mode. It is also used to figure out the counters delegated to S-mode by the M-mode as well. Signed-off-by: Kaiwen Xue Reviewed-by: Cl=C3=A9ment L=C3=A9ger --- arch/riscv/include/asm/csr.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h index b4551a6cf7cb..26cb78dee2fd 100644 --- a/arch/riscv/include/asm/csr.h +++ b/arch/riscv/include/asm/csr.h @@ -241,6 +241,31 @@ #define SMSTATEEN0_HSENVCFG (_ULL(1) << SMSTATEEN0_HSENVCFG_SHIFT) #define SMSTATEEN0_SSTATEEN0_SHIFT 63 #define SMSTATEEN0_SSTATEEN0 (_ULL(1) << SMSTATEEN0_SSTATEEN0_SHIFT) +/* HPMEVENT bits. These are accessible in S-mode via Smcdeleg/Ssccfg */ +#ifdef CONFIG_64BIT +#define HPMEVENT_OF (BIT_ULL(63)) +#define HPMEVENT_MINH (BIT_ULL(62)) +#define HPMEVENT_SINH (BIT_ULL(61)) +#define HPMEVENT_UINH (BIT_ULL(60)) +#define HPMEVENT_VSINH (BIT_ULL(59)) +#define HPMEVENT_VUINH (BIT_ULL(58)) +#else +#define HPMEVENTH_OF (BIT_ULL(31)) +#define HPMEVENTH_MINH (BIT_ULL(30)) +#define HPMEVENTH_SINH (BIT_ULL(29)) +#define HPMEVENTH_UINH (BIT_ULL(28)) +#define HPMEVENTH_VSINH (BIT_ULL(27)) +#define HPMEVENTH_VUINH (BIT_ULL(26)) + +#define HPMEVENT_OF (HPMEVENTH_OF << 32) +#define HPMEVENT_MINH (HPMEVENTH_MINH << 32) +#define HPMEVENT_SINH (HPMEVENTH_SINH << 32) +#define HPMEVENT_UINH (HPMEVENTH_UINH << 32) +#define HPMEVENT_VSINH (HPMEVENTH_VSINH << 32) +#define HPMEVENT_VUINH (HPMEVENTH_VUINH << 32) +#endif + +#define SISELECT_SSCCFG_BASE 0x40 =20 /* mseccfg bits */ #define MSECCFG_PMM ENVCFG_PMM @@ -322,6 +347,7 @@ #define CSR_SCOUNTEREN 0x106 #define CSR_SENVCFG 0x10a #define CSR_SSTATEEN0 0x10c +#define CSR_SCOUNTINHIBIT 0x120 #define CSR_SSCRATCH 0x140 #define CSR_SEPC 0x141 #define CSR_SCAUSE 0x142 --=20 2.53.0-Meta From nobody Sat Jun 13 15:24:19 2026 Received: from out-177.mta0.migadu.com (out-177.mta0.migadu.com [91.218.175.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0A62C3CF054 for ; Tue, 9 Jun 2026 06:02:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.177 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984944; cv=none; b=OPES1cnPXvSKUsDvh6txIqyWf2U3QAZMLpcl+sybpUz8n6CO+RHPkb62P+X3a9u17Z28DS6cX1WBizyFwjIldUS8HyM2H1O1lCW99U/Lloj0ZwqnqyHs0ZqA5M3Dff38faDJjM6D45JeBFRdwN1XU2Xr64Gfna0pfEVx2eunasc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984944; c=relaxed/simple; bh=qI7ylPGhf6GPYHa6rJhXo0UFdpIqMb7rB+hO27t6rWw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DjRB6rK2VnaRdEvypPFbt3vUBnd/4S0etVkivFkf7uop7g6zdPntEGP1Vg+ugMfwhF3lH16nKJfT+QsnEfiBE70+NClHY5sDU08ee6Wb6WuNg11S4NLBFqYuWmqIY7ueuZparFaSdp3BYvFeRWF6ONND1m7ekODjoEb34ARTJfI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=NsmLtSBp; arc=none smtp.client-ip=91.218.175.177 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="NsmLtSBp" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1780984941; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=NUBImEnq8hbrnJQhJKzk1cL/zkOMmDZcmfYv80HVE44=; b=NsmLtSBptUWXHcKm7DpTShuwbjiQTkqfyAQv+YX8QR78qXKFwPH5eSqrjKbsWMANmdO3rC PZ6LOSoQvrBuGlOXBwxDdMbXsFQ7/Qbp5c+6pv5Qqd0bOwdXIEtyUkMkLVpEugw9ZvNczO gJ63rlUBpUyNC23GHMRLf0Wr5RQmqD0= From: Atish Patra Date: Mon, 08 Jun 2026 23:01:22 -0700 Subject: [PATCH v6 08/21] RISC-V: Add Ssccfg/Smcdeleg ISA extension definition and parsing Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260608-counter_delegation-v6-8-285b72ed65a9@meta.com> References: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> In-Reply-To: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> To: James Clark , Rob Herring , Atish Patra , Arnaldo Carvalho de Melo , Jiri Olsa , Will Deacon , Mark Rutland , Anup Patel , Namhyung Kim , Paul Walmsley , Krzysztof Kozlowski , Ian Rogers Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Conor Dooley , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org X-Migadu-Flow: FLOW_OUT From: Atish Patra Smcdeleg extension allows the M-mode to delegate selected counters to S-mode so that it can access those counters and correpsonding hpmevent CSRs without M-mode. Ssccfg (=E2=80=98Ss=E2=80=99 for Privileged architecture and Supervisor-lev= el extension, =E2=80=98ccfg=E2=80=99 for Counter Configuration) provides acces= s to delegated counters and new supervisor-level state. This patch just enables these definitions and enable parsing. Signed-off-by: Atish Patra --- arch/riscv/include/asm/hwcap.h | 2 ++ arch/riscv/kernel/cpufeature.c | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h index 51ad55b9677a..089353b250b0 100644 --- a/arch/riscv/include/asm/hwcap.h +++ b/arch/riscv/include/asm/hwcap.h @@ -115,6 +115,8 @@ #define RISCV_ISA_EXT_SSCSRIND 106 #define RISCV_ISA_EXT_SMCSRIND 107 #define RISCV_ISA_EXT_SMCNTRPMF 108 +#define RISCV_ISA_EXT_SSCCFG 109 +#define RISCV_ISA_EXT_SMCDELEG 110 =20 #define RISCV_ISA_EXT_XLINUXENVCFG 127 =20 diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c index 1452521d740a..1fe647e03515 100644 --- a/arch/riscv/kernel/cpufeature.c +++ b/arch/riscv/kernel/cpufeature.c @@ -330,6 +330,27 @@ static const unsigned int riscv_a_exts[] =3D { RISCV_ISA_EXT_ZKNE, \ RISCV_ISA_EXT_ZKNH =20 +static int riscv_ext_smcdeleg_validate(const struct riscv_isa_ext_data *da= ta, + const unsigned long *isa_bitmap) +{ + if (__riscv_isa_extension_available(isa_bitmap, RISCV_ISA_EXT_SSCSRIND) && + __riscv_isa_extension_available(isa_bitmap, RISCV_ISA_EXT_ZIHPM) && + __riscv_isa_extension_available(isa_bitmap, RISCV_ISA_EXT_ZICNTR)) + return 0; + + return -EPROBE_DEFER; +} + +static int riscv_ext_ssccfg_validate(const struct riscv_isa_ext_data *data, + const unsigned long *isa_bitmap) +{ + if (!riscv_ext_smcdeleg_validate(data, isa_bitmap) && + __riscv_isa_extension_available(isa_bitmap, RISCV_ISA_EXT_SMCDELEG)) + return 0; + + return -EPROBE_DEFER; +} + static const unsigned int riscv_zk_bundled_exts[] =3D { RISCV_ISA_EXT_ZKN, RISCV_ISA_EXT_ZKR, @@ -576,12 +597,15 @@ const struct riscv_isa_ext_data riscv_isa_ext[] =3D { __RISCV_ISA_EXT_BUNDLE_VALIDATE(zvksg, riscv_zvksg_bundled_exts, riscv_ex= t_vector_crypto_validate), __RISCV_ISA_EXT_DATA_VALIDATE(zvkt, RISCV_ISA_EXT_ZVKT, riscv_ext_vector_= crypto_validate), __RISCV_ISA_EXT_DATA(smaia, RISCV_ISA_EXT_SMAIA), + __RISCV_ISA_EXT_DATA_VALIDATE(smcdeleg, RISCV_ISA_EXT_SMCDELEG, + riscv_ext_smcdeleg_validate), __RISCV_ISA_EXT_DATA(smcntrpmf, RISCV_ISA_EXT_SMCNTRPMF), __RISCV_ISA_EXT_DATA(smcsrind, RISCV_ISA_EXT_SMCSRIND), __RISCV_ISA_EXT_DATA(smmpm, RISCV_ISA_EXT_SMMPM), __RISCV_ISA_EXT_SUPERSET(smnpm, RISCV_ISA_EXT_SMNPM, riscv_xlinuxenvcfg_e= xts), __RISCV_ISA_EXT_DATA(smstateen, RISCV_ISA_EXT_SMSTATEEN), __RISCV_ISA_EXT_DATA(ssaia, RISCV_ISA_EXT_SSAIA), + __RISCV_ISA_EXT_DATA_VALIDATE(ssccfg, RISCV_ISA_EXT_SSCCFG, riscv_ext_ssc= cfg_validate), __RISCV_ISA_EXT_DATA(sscofpmf, RISCV_ISA_EXT_SSCOFPMF), __RISCV_ISA_EXT_DATA(sscsrind, RISCV_ISA_EXT_SSCSRIND), __RISCV_ISA_EXT_SUPERSET(ssnpm, RISCV_ISA_EXT_SSNPM, riscv_xlinuxenvcfg_e= xts), --=20 2.53.0-Meta From nobody Sat Jun 13 15:24:19 2026 Received: from out-185.mta0.migadu.com (out-185.mta0.migadu.com [91.218.175.185]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 402D13CF1EF for ; Tue, 9 Jun 2026 06:02:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.185 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984948; cv=none; b=UzX2786C5RnfzUlkJHSkpGBWGSSTMhPPzyx30x8i99/zuw5J/yMEc9LpYtX1YgKbujEav6+MycjF7vlb5b/CBJDEWJ73Pgzn6O87VmXm98z+FT7KUoicXZ0efs1DPHX38kzefq9202n8mfRnXEGOJ6SK5z+2lpVbSu+XdJCXxUA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984948; c=relaxed/simple; bh=7ow3HXtkGYv3O+Gcpz4xW1Y7vVhlGubdttlkFIF3aEo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Ua6WGm8pwyXZJy6c3oMyliOqTayVFDGyzqEQEMgtmrBmErmmVASyFpKtL6gBmaC401e0TAyeMaMbnirREa/UfZFmluqePkrZmjtFd0ZOOIrgYT1HRqVYuFH9PlRLk+TUklDAjWDrzqzkl4FCQP92GRHlteHZBYuYrC2p2bsW/vc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=lYn1jx2/; arc=none smtp.client-ip=91.218.175.185 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="lYn1jx2/" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1780984945; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=o5qCNbZWxJ2eaZKPD0fiX8UMgOwRHPlmfMwkbht8Nv4=; b=lYn1jx2/wE5iAiy4iduZmTtvXwAlsQ5axkxbKlGh9vtQc3d+NGuM2JrTF37/MfIAPIoAHA XgJ+STR11Z/02ZmtSFGrt280FC4AKwyver4Q5S1i3ULozv8TMpvyd5p2pt58dfCfXd3cVH 1L55260FjkG0HYQZ1YtD0o6e/6lJ418= From: Atish Patra Date: Mon, 08 Jun 2026 23:01:23 -0700 Subject: [PATCH v6 09/21] dt-bindings: riscv: add Counter delegation ISA extensions description Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260608-counter_delegation-v6-9-285b72ed65a9@meta.com> References: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> In-Reply-To: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> To: James Clark , Rob Herring , Atish Patra , Arnaldo Carvalho de Melo , Jiri Olsa , Will Deacon , Mark Rutland , Anup Patel , Namhyung Kim , Paul Walmsley , Krzysztof Kozlowski , Ian Rogers Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Conor Dooley , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org X-Migadu-Flow: FLOW_OUT From: Atish Patra Add description for the Smcdeleg/Ssccfg extension. Signed-off-by: Atish Patra Acked-by: Conor Dooley --- .../devicetree/bindings/riscv/extensions.yaml | 45 ++++++++++++++++++= ++++ 1 file changed, 45 insertions(+) diff --git a/Documentation/devicetree/bindings/riscv/extensions.yaml b/Docu= mentation/devicetree/bindings/riscv/extensions.yaml index ece3edccee42..2845e8e2999a 100644 --- a/Documentation/devicetree/bindings/riscv/extensions.yaml +++ b/Documentation/devicetree/bindings/riscv/extensions.yaml @@ -181,6 +181,13 @@ properties: changes to interrupts as frozen at commit ccbddab ("Merge pull request #42 from riscv/jhauser-2023-RC4") of riscv-aia. =20 + - const: smcdeleg + description: | + The standard Smcdeleg supervisor-level extension for the machi= ne mode + to delegate the hpmcounters to supervisor mode so that they are + directly accessible in the supervisor mode as ratified in the + 20240213 version of the privileged ISA specification. + - const: smcsrind description: | The standard Smcsrind supervisor-level extension extends the @@ -228,6 +235,14 @@ properties: behavioural changes to interrupts as frozen at commit ccbddab ("Merge pull request #42 from riscv/jhauser-2023-RC4") of risc= v-aia. =20 + - const: ssccfg + description: | + The standard Ssccfg supervisor-level extension for configuring + the delegated hpmcounters to be accessible directly in supervi= sor + mode as ratified in the 20240213 version of the privileged ISA + specification. This extension depends on Sscsrind, Smcdeleg, S= scofpmf, + Smcntrpmf, Zihpm, Zicntr extensions. + - const: ssccptr description: | The standard Ssccptr extension for main memory (cacheability a= nd @@ -1135,6 +1150,36 @@ properties: allOf: - const: zilsd - const: zca + # Smcdeleg depends on Sscsrind, Zihpm, Zicntr + - if: + contains: + const: smcdeleg + then: + allOf: + - contains: + const: sscsrind + - contains: + const: zihpm + - contains: + const: zicntr + # Ssccfg depends on Smcdeleg, Sscsrind, Zihpm, Zicntr, Sscofpmf, Smc= ntrpmf + - if: + contains: + const: ssccfg + then: + allOf: + - contains: + const: smcdeleg + - contains: + const: sscsrind + - contains: + const: sscofpmf + - contains: + const: smcntrpmf + - contains: + const: zihpm + - contains: + const: zicntr =20 allOf: # Zcf extension does not exist on rv64 --=20 2.53.0-Meta From nobody Sat Jun 13 15:24:19 2026 Received: from out-188.mta1.migadu.com (out-188.mta1.migadu.com [95.215.58.188]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E39F63CF1E6 for ; Tue, 9 Jun 2026 06:02:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.188 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984953; cv=none; b=q2JdLHtHwrvqMZdWcwm7yzdBtZjNQat/qafy+5kK7SHCitgBgk7Qt6yckiDnUeXyYy4G4VhX1kgqdm2SmG3YoKOa6eB+ck/OFSe8t0kviky76W+jT8Bf0bfyRmdDU/Ljembu4Ue1aooraIeTToiUaZv1FtO6+Cy2/oxmB16gCus= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984953; c=relaxed/simple; bh=0Ve0x3TdRh6t7jYMroP8yG9BXp1XwQ/ae7c4gaZG9AM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DUBKRj/7VvCsSqnPJdQWMaH1Nqq1MDLRNOoLBhT9Hu2LA/nNVYL3Ny16TBw/tzPd6ewmVZGfLMDIUOwRmqjyIRvblvX3eT7Bp1HbYkm6x2wYt1VULWyp3ATB9npsGIn4Nski5rCLVbb7lAy1vFLnstgF1INzcqC4kPHtZ2IseOk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=L93y1++r; arc=none smtp.client-ip=95.215.58.188 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="L93y1++r" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1780984949; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=s3o9uIosieKwWlzprCsV4ya2Q4BvTbYIQpMePHzG/S8=; b=L93y1++r6uQFelgLyyV+wS/kDUpGsREfuWof7kud5azmUfTyjpBN/3kYnV0xQiGn//sxtV /b5N8DZ+7az3a57GKT1TM4TDk8Hruv3+jkGx2WtJsnpMpTalOwoYwC0sz3dOP2c9Fcw8DJ Fr59aAhjXKyXde1gsMnuRm3XDJOkSvY= From: Atish Patra Date: Mon, 08 Jun 2026 23:01:24 -0700 Subject: [PATCH v6 10/21] RISC-V: perf: Restructure the SBI PMU code Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260608-counter_delegation-v6-10-285b72ed65a9@meta.com> References: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> In-Reply-To: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> To: James Clark , Rob Herring , Atish Patra , Arnaldo Carvalho de Melo , Jiri Olsa , Will Deacon , Mark Rutland , Anup Patel , Namhyung Kim , Paul Walmsley , Krzysztof Kozlowski , Ian Rogers Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Conor Dooley , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org X-Migadu-Flow: FLOW_OUT From: Atish Patra With Ssccfg/Smcdeleg, supervisor mode can program and access the hpmcounters and events directly, without the SBI PMU extension. The SBI PMU extension is still required for firmware counters. Restructure the existing SBI PMU code= so the hpmcounter/event helpers can be shared between the SBI and the counter delegation paths that follow. The driver, file, module and Kconfig names are intentionally kept unchanged= to avoid backport churn and userspace breakage (module listings, udev rules, cmdline options). No functional change intended. Signed-off-by: Atish Patra --- drivers/perf/Kconfig | 14 ++- drivers/perf/riscv_pmu_sbi.c | 238 +++++++++++++++++++++++++--------------= ---- 2 files changed, 150 insertions(+), 102 deletions(-) diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig index ab90932fc2d0..3245bb2969e1 100644 --- a/drivers/perf/Kconfig +++ b/drivers/perf/Kconfig @@ -97,13 +97,17 @@ config RISCV_PMU_LEGACY =20 config RISCV_PMU_SBI depends on RISCV_PMU && RISCV_SBI - bool "RISC-V PMU based on SBI PMU extension" + bool "RISC-V PMU based on SBI PMU extension and/or counter delegation" default y help - Say y if you want to use the CPU performance monitor - using SBI PMU extension on RISC-V based systems. This option provides - full perf feature support i.e. counter overflow, privilege mode - filtering, counter configuration. + Say y if you want to use the CPU performance monitor on RISC-V based + systems. This single driver supports both hardware counter access + mechanisms: it uses the counter delegation (Smcdeleg/Ssccfg) ISA + extension to program and read the hpmcounters directly in supervisor + mode when available, and uses the SBI PMU extension for firmware + counters and when counter delegation is not present. This option + provides full perf feature support i.e. counter overflow, privilege + mode filtering, counter configuration. =20 config STARFIVE_STARLINK_PMU depends on ARCH_STARFIVE || COMPILE_TEST diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c index 385af5e6e6d0..7f21c16003f0 100644 --- a/drivers/perf/riscv_pmu_sbi.c +++ b/drivers/perf/riscv_pmu_sbi.c @@ -88,6 +88,8 @@ static const struct attribute_group *riscv_pmu_attr_group= s[] =3D { static int sysctl_perf_user_access __read_mostly =3D SYSCTL_USER_ACCESS; =20 /* + * This structure is SBI specific but counter delegation also require coun= ter + * width, csr mapping. Reuse it for now. * RISC-V doesn't have heterogeneous harts yet. This need to be part of * per_cpu in case of harts with different pmu counters */ @@ -100,7 +102,7 @@ static unsigned int riscv_pmu_irq; /* Cache the available counters in a bitmask */ static unsigned long cmask; =20 -static int pmu_event_find_cache(u64 config); +static int sbi_pmu_event_find_cache(u64 config); struct sbi_pmu_event_data { union { union { @@ -121,7 +123,7 @@ struct sbi_pmu_event_data { }; }; =20 -static struct sbi_pmu_event_data pmu_hw_event_map[] =3D { +static struct sbi_pmu_event_data pmu_hw_event_sbi_map[] =3D { [PERF_COUNT_HW_CPU_CYCLES] =3D {.hw_gen_event =3D { SBI_PMU_HW_CPU_CYCLES, SBI_PMU_EVENT_TYPE_HW, 0}}, @@ -155,7 +157,7 @@ static struct sbi_pmu_event_data pmu_hw_event_map[] =3D= { }; =20 #define C(x) PERF_COUNT_HW_CACHE_##x -static struct sbi_pmu_event_data pmu_cache_event_map[PERF_COUNT_HW_CACHE_M= AX] +static struct sbi_pmu_event_data pmu_cache_event_sbi_map[PERF_COUNT_HW_CAC= HE_MAX] [PERF_COUNT_HW_CACHE_OP_MAX] [PERF_COUNT_HW_CACHE_RESULT_MAX] =3D { [C(L1D)] =3D { @@ -302,7 +304,7 @@ static struct sbi_pmu_event_data pmu_cache_event_map[PE= RF_COUNT_HW_CACHE_MAX] =20 static int pmu_sbi_check_event_info(void) { - int num_events =3D ARRAY_SIZE(pmu_hw_event_map) + PERF_COUNT_HW_CACHE_MAX= * + int num_events =3D ARRAY_SIZE(pmu_hw_event_sbi_map) + PERF_COUNT_HW_CACHE= _MAX * PERF_COUNT_HW_CACHE_OP_MAX * PERF_COUNT_HW_CACHE_RESULT_MAX; struct riscv_pmu_event_info *event_info_shmem; phys_addr_t base_addr; @@ -313,14 +315,14 @@ static int pmu_sbi_check_event_info(void) if (!event_info_shmem) return -ENOMEM; =20 - for (i =3D 0; i < ARRAY_SIZE(pmu_hw_event_map); i++) - event_info_shmem[count++].event_idx =3D pmu_hw_event_map[i].event_idx; + for (i =3D 0; i < ARRAY_SIZE(pmu_hw_event_sbi_map); i++) + event_info_shmem[count++].event_idx =3D pmu_hw_event_sbi_map[i].event_id= x; =20 - for (i =3D 0; i < ARRAY_SIZE(pmu_cache_event_map); i++) { - for (j =3D 0; j < ARRAY_SIZE(pmu_cache_event_map[i]); j++) { - for (k =3D 0; k < ARRAY_SIZE(pmu_cache_event_map[i][j]); k++) + for (i =3D 0; i < ARRAY_SIZE(pmu_cache_event_sbi_map); i++) { + for (j =3D 0; j < ARRAY_SIZE(pmu_cache_event_sbi_map[i]); j++) { + for (k =3D 0; k < ARRAY_SIZE(pmu_cache_event_sbi_map[i][j]); k++) event_info_shmem[count++].event_idx =3D - pmu_cache_event_map[i][j][k].event_idx; + pmu_cache_event_sbi_map[i][j][k].event_idx; } } =20 @@ -336,19 +338,19 @@ static int pmu_sbi_check_event_info(void) goto free_mem; } =20 - for (i =3D 0; i < ARRAY_SIZE(pmu_hw_event_map); i++) { + for (i =3D 0; i < ARRAY_SIZE(pmu_hw_event_sbi_map); i++) { if (!(event_info_shmem[i].output & RISCV_PMU_EVENT_INFO_OUTPUT_MASK)) - pmu_hw_event_map[i].event_idx =3D -ENOENT; + pmu_hw_event_sbi_map[i].event_idx =3D -ENOENT; } =20 - count =3D ARRAY_SIZE(pmu_hw_event_map); + count =3D ARRAY_SIZE(pmu_hw_event_sbi_map); =20 - for (i =3D 0; i < ARRAY_SIZE(pmu_cache_event_map); i++) { - for (j =3D 0; j < ARRAY_SIZE(pmu_cache_event_map[i]); j++) { - for (k =3D 0; k < ARRAY_SIZE(pmu_cache_event_map[i][j]); k++) { + for (i =3D 0; i < ARRAY_SIZE(pmu_cache_event_sbi_map); i++) { + for (j =3D 0; j < ARRAY_SIZE(pmu_cache_event_sbi_map[i]); j++) { + for (k =3D 0; k < ARRAY_SIZE(pmu_cache_event_sbi_map[i][j]); k++) { if (!(event_info_shmem[count].output & RISCV_PMU_EVENT_INFO_OUTPUT_MASK)) - pmu_cache_event_map[i][j][k].event_idx =3D -ENOENT; + pmu_cache_event_sbi_map[i][j][k].event_idx =3D -ENOENT; count++; } } @@ -360,7 +362,7 @@ static int pmu_sbi_check_event_info(void) return result; } =20 -static void pmu_sbi_check_event(struct sbi_pmu_event_data *edata) +static void rvpmu_sbi_check_event(struct sbi_pmu_event_data *edata) { struct sbiret ret; =20 @@ -375,7 +377,7 @@ static void pmu_sbi_check_event(struct sbi_pmu_event_da= ta *edata) } } =20 -static void pmu_sbi_check_std_events(struct work_struct *work) +static void rvpmu_sbi_check_std_events(struct work_struct *work) { int ret; =20 @@ -386,23 +388,23 @@ static void pmu_sbi_check_std_events(struct work_stru= ct *work) return; } =20 - for (int i =3D 0; i < ARRAY_SIZE(pmu_hw_event_map); i++) - pmu_sbi_check_event(&pmu_hw_event_map[i]); + for (int i =3D 0; i < ARRAY_SIZE(pmu_hw_event_sbi_map); i++) + rvpmu_sbi_check_event(&pmu_hw_event_sbi_map[i]); =20 - for (int i =3D 0; i < ARRAY_SIZE(pmu_cache_event_map); i++) - for (int j =3D 0; j < ARRAY_SIZE(pmu_cache_event_map[i]); j++) - for (int k =3D 0; k < ARRAY_SIZE(pmu_cache_event_map[i][j]); k++) - pmu_sbi_check_event(&pmu_cache_event_map[i][j][k]); + for (int i =3D 0; i < ARRAY_SIZE(pmu_cache_event_sbi_map); i++) + for (int j =3D 0; j < ARRAY_SIZE(pmu_cache_event_sbi_map[i]); j++) + for (int k =3D 0; k < ARRAY_SIZE(pmu_cache_event_sbi_map[i][j]); k++) + rvpmu_sbi_check_event(&pmu_cache_event_sbi_map[i][j][k]); } =20 -static DECLARE_WORK(check_std_events_work, pmu_sbi_check_std_events); +static DECLARE_WORK(check_std_events_work, rvpmu_sbi_check_std_events); =20 -static int pmu_sbi_ctr_get_width(int idx) +static int rvpmu_ctr_get_width(int idx) { return pmu_ctr_list[idx].width; } =20 -static bool pmu_sbi_ctr_is_fw(int cidx) +static bool rvpmu_ctr_is_fw(int cidx) { union sbi_pmu_ctr_info *info; =20 @@ -421,10 +423,10 @@ int riscv_pmu_get_event_info(u32 type, u64 config, u6= 4 *econfig) case PERF_TYPE_HARDWARE: if (config >=3D PERF_COUNT_HW_MAX) return -EINVAL; - ret =3D pmu_hw_event_map[config].event_idx; + ret =3D pmu_hw_event_sbi_map[config].event_idx; break; case PERF_TYPE_HW_CACHE: - ret =3D pmu_event_find_cache(config); + ret =3D sbi_pmu_event_find_cache(config); break; case PERF_TYPE_RAW: /* @@ -509,12 +511,12 @@ int riscv_pmu_get_hpm_info(u32 *hw_ctr_width, u32 *nu= m_hw_ctr) } EXPORT_SYMBOL_GPL(riscv_pmu_get_hpm_info); =20 -static uint8_t pmu_sbi_csr_index(struct perf_event *event) +static uint8_t rvpmu_csr_index(struct perf_event *event) { return pmu_ctr_list[event->hw.idx].csr - CSR_CYCLE; } =20 -static unsigned long pmu_sbi_get_filter_flags(struct perf_event *event) +static unsigned long rvpmu_sbi_get_filter_flags(struct perf_event *event) { unsigned long cflags =3D 0; bool guest_events =3D false; @@ -535,7 +537,7 @@ static unsigned long pmu_sbi_get_filter_flags(struct pe= rf_event *event) return cflags; } =20 -static int pmu_sbi_ctr_get_idx(struct perf_event *event) +static int rvpmu_sbi_ctr_get_idx(struct perf_event *event) { struct hw_perf_event *hwc =3D &event->hw; struct riscv_pmu *rvpmu =3D to_riscv_pmu(event->pmu); @@ -545,7 +547,7 @@ static int pmu_sbi_ctr_get_idx(struct perf_event *event) uint64_t cbase =3D 0, cmask =3D rvpmu->cmask; unsigned long cflags =3D 0; =20 - cflags =3D pmu_sbi_get_filter_flags(event); + cflags =3D rvpmu_sbi_get_filter_flags(event); =20 /* * In legacy mode, we have to force the fixed counters for those events @@ -582,7 +584,7 @@ static int pmu_sbi_ctr_get_idx(struct perf_event *event) return -ENOENT; =20 /* Additional sanity check for the counter id */ - if (pmu_sbi_ctr_is_fw(idx)) { + if (rvpmu_ctr_is_fw(idx)) { if (!test_and_set_bit(idx, cpuc->used_fw_ctrs)) return idx; } else { @@ -593,7 +595,7 @@ static int pmu_sbi_ctr_get_idx(struct perf_event *event) return -ENOENT; } =20 -static void pmu_sbi_ctr_clear_idx(struct perf_event *event) +static void rvpmu_ctr_clear_idx(struct perf_event *event) { =20 struct hw_perf_event *hwc =3D &event->hw; @@ -601,13 +603,13 @@ static void pmu_sbi_ctr_clear_idx(struct perf_event *= event) struct cpu_hw_events *cpuc =3D this_cpu_ptr(rvpmu->hw_events); int idx =3D hwc->idx; =20 - if (pmu_sbi_ctr_is_fw(idx)) + if (rvpmu_ctr_is_fw(idx)) clear_bit(idx, cpuc->used_fw_ctrs); else clear_bit(idx, cpuc->used_hw_ctrs); } =20 -static int pmu_event_find_cache(u64 config) +static int sbi_pmu_event_find_cache(u64 config) { unsigned int cache_type, cache_op, cache_result, ret; =20 @@ -623,7 +625,7 @@ static int pmu_event_find_cache(u64 config) if (cache_result >=3D PERF_COUNT_HW_CACHE_RESULT_MAX) return -EINVAL; =20 - ret =3D pmu_cache_event_map[cache_type][cache_op][cache_result].event_idx; + ret =3D pmu_cache_event_sbi_map[cache_type][cache_op][cache_result].event= _idx; =20 return ret; } @@ -639,7 +641,7 @@ static bool pmu_sbi_is_fw_event(struct perf_event *even= t) return false; } =20 -static int pmu_sbi_event_map(struct perf_event *event, u64 *econfig) +static int rvpmu_sbi_event_map(struct perf_event *event, u64 *econfig) { u32 type =3D event->attr.type; u64 config =3D event->attr.config; @@ -736,7 +738,7 @@ static int pmu_sbi_snapshot_setup(struct riscv_pmu *pmu= , int cpu) return 0; } =20 -static u64 pmu_sbi_ctr_read(struct perf_event *event) +static u64 rvpmu_sbi_ctr_read(struct perf_event *event) { struct hw_perf_event *hwc =3D &event->hw; int idx =3D hwc->idx; @@ -778,25 +780,25 @@ static u64 pmu_sbi_ctr_read(struct perf_event *event) return val; } =20 -static void pmu_sbi_set_scounteren(void *arg) +static void rvpmu_set_scounteren(void *arg) { struct perf_event *event =3D (struct perf_event *)arg; =20 if (event->hw.idx !=3D -1) csr_write(CSR_SCOUNTEREN, - csr_read(CSR_SCOUNTEREN) | BIT(pmu_sbi_csr_index(event))); + csr_read(CSR_SCOUNTEREN) | BIT(rvpmu_csr_index(event))); } =20 -static void pmu_sbi_reset_scounteren(void *arg) +static void rvpmu_reset_scounteren(void *arg) { struct perf_event *event =3D (struct perf_event *)arg; =20 if (event->hw.idx !=3D -1) csr_write(CSR_SCOUNTEREN, - csr_read(CSR_SCOUNTEREN) & ~BIT(pmu_sbi_csr_index(event))); + csr_read(CSR_SCOUNTEREN) & ~BIT(rvpmu_csr_index(event))); } =20 -static void pmu_sbi_ctr_start(struct perf_event *event, u64 ival) +static void rvpmu_sbi_ctr_start(struct perf_event *event, u64 ival) { struct sbiret ret; struct hw_perf_event *hwc =3D &event->hw; @@ -816,10 +818,10 @@ static void pmu_sbi_ctr_start(struct perf_event *even= t, u64 ival) =20 if ((hwc->flags & PERF_EVENT_FLAG_USER_ACCESS) && (hwc->flags & PERF_EVENT_FLAG_USER_READ_CNT)) - pmu_sbi_set_scounteren((void *)event); + rvpmu_set_scounteren((void *)event); } =20 -static void pmu_sbi_ctr_stop(struct perf_event *event, unsigned long flag) +static void rvpmu_sbi_ctr_stop(struct perf_event *event, unsigned long fla= g) { struct sbiret ret; struct hw_perf_event *hwc =3D &event->hw; @@ -829,7 +831,7 @@ static void pmu_sbi_ctr_stop(struct perf_event *event, = unsigned long flag) =20 if ((hwc->flags & PERF_EVENT_FLAG_USER_ACCESS) && (hwc->flags & PERF_EVENT_FLAG_USER_READ_CNT)) - pmu_sbi_reset_scounteren((void *)event); + rvpmu_reset_scounteren((void *)event); =20 if (sbi_pmu_snapshot_available()) flag |=3D SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT; @@ -855,7 +857,7 @@ static void pmu_sbi_ctr_stop(struct perf_event *event, = unsigned long flag) } } =20 -static int pmu_sbi_find_num_ctrs(void) +static int rvpmu_sbi_find_num_ctrs(void) { struct sbiret ret; =20 @@ -866,7 +868,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, unsigned long *mask) +static int rvpmu_sbi_get_ctrinfo(int nctr, unsigned long *mask) { struct sbiret ret; int i, num_hw_ctr =3D 0, num_fw_ctr =3D 0; @@ -897,7 +899,7 @@ static int pmu_sbi_get_ctrinfo(int nctr, unsigned long = *mask) return 0; } =20 -static inline void pmu_sbi_stop_all(struct riscv_pmu *pmu) +static inline void rvpmu_sbi_stop_all(struct riscv_pmu *pmu) { /* * No need to check the error because we are disabling all the counters @@ -907,7 +909,7 @@ static inline void pmu_sbi_stop_all(struct riscv_pmu *p= mu) 0, pmu->cmask, SBI_PMU_STOP_FLAG_RESET, 0, 0, 0); } =20 -static inline void pmu_sbi_stop_hw_ctrs(struct riscv_pmu *pmu) +static inline void rvpmu_sbi_stop_hw_ctrs(struct riscv_pmu *pmu) { struct cpu_hw_events *cpu_hw_evt =3D this_cpu_ptr(pmu->hw_events); struct riscv_pmu_snapshot_data *sdata =3D cpu_hw_evt->snapshot_addr; @@ -951,8 +953,8 @@ static inline void pmu_sbi_stop_hw_ctrs(struct riscv_pm= u *pmu) * while the overflowed counters need to be started with updated initializ= ation * value. */ -static inline void pmu_sbi_start_ovf_ctrs_sbi(struct cpu_hw_events *cpu_hw= _evt, - u64 ctr_ovf_mask) +static inline void rvpmu_sbi_start_ovf_ctrs_sbi(struct cpu_hw_events *cpu_= hw_evt, + u64 ctr_ovf_mask) { int idx =3D 0, i; struct perf_event *event; @@ -992,8 +994,8 @@ static inline void pmu_sbi_start_ovf_ctrs_sbi(struct cp= u_hw_events *cpu_hw_evt, } } =20 -static inline void pmu_sbi_start_ovf_ctrs_snapshot(struct cpu_hw_events *c= pu_hw_evt, - u64 ctr_ovf_mask) +static inline void rvpmu_sbi_start_ovf_ctrs_snapshot(struct cpu_hw_events = *cpu_hw_evt, + u64 ctr_ovf_mask) { int i, idx =3D 0; struct perf_event *event; @@ -1027,18 +1029,18 @@ static inline void pmu_sbi_start_ovf_ctrs_snapshot(= struct cpu_hw_events *cpu_hw_ } } =20 -static void pmu_sbi_start_overflow_mask(struct riscv_pmu *pmu, - u64 ctr_ovf_mask) +static void rvpmu_sbi_start_overflow_mask(struct riscv_pmu *pmu, + u64 ctr_ovf_mask) { struct cpu_hw_events *cpu_hw_evt =3D this_cpu_ptr(pmu->hw_events); =20 if (sbi_pmu_snapshot_available()) - pmu_sbi_start_ovf_ctrs_snapshot(cpu_hw_evt, ctr_ovf_mask); + rvpmu_sbi_start_ovf_ctrs_snapshot(cpu_hw_evt, ctr_ovf_mask); else - pmu_sbi_start_ovf_ctrs_sbi(cpu_hw_evt, ctr_ovf_mask); + rvpmu_sbi_start_ovf_ctrs_sbi(cpu_hw_evt, ctr_ovf_mask); } =20 -static irqreturn_t pmu_sbi_ovf_handler(int irq, void *dev) +static irqreturn_t rvpmu_ovf_handler(int irq, void *dev) { struct perf_sample_data data; struct pt_regs *regs; @@ -1070,7 +1072,7 @@ static irqreturn_t pmu_sbi_ovf_handler(int irq, void = *dev) } =20 pmu =3D to_riscv_pmu(event->pmu); - pmu_sbi_stop_hw_ctrs(pmu); + rvpmu_sbi_stop_hw_ctrs(pmu); =20 /* Overflow status register should only be read after counter are stopped= */ if (sbi_pmu_snapshot_available()) @@ -1139,13 +1141,55 @@ static irqreturn_t pmu_sbi_ovf_handler(int irq, voi= d *dev) hw_evt->state =3D 0; } =20 - pmu_sbi_start_overflow_mask(pmu, overflowed_ctrs); + rvpmu_sbi_start_overflow_mask(pmu, overflowed_ctrs); perf_sample_event_took(sched_clock() - start_clock); =20 return IRQ_HANDLED; } =20 -static int pmu_sbi_starting_cpu(unsigned int cpu, struct hlist_node *node) +static void rvpmu_ctr_start(struct perf_event *event, u64 ival) +{ + rvpmu_sbi_ctr_start(event, ival); + /* TODO: Counter delegation implementation */ +} + +static void rvpmu_ctr_stop(struct perf_event *event, unsigned long flag) +{ + rvpmu_sbi_ctr_stop(event, flag); + /* TODO: Counter delegation implementation */ +} + +static int rvpmu_find_num_ctrs(void) +{ + return rvpmu_sbi_find_num_ctrs(); + /* TODO: Counter delegation implementation */ +} + +static int rvpmu_get_ctrinfo(int nctr, unsigned long *mask) +{ + return rvpmu_sbi_get_ctrinfo(nctr, mask); + /* TODO: Counter delegation implementation */ +} + +static int rvpmu_event_map(struct perf_event *event, u64 *econfig) +{ + return rvpmu_sbi_event_map(event, econfig); + /* TODO: Counter delegation implementation */ +} + +static int rvpmu_ctr_get_idx(struct perf_event *event) +{ + return rvpmu_sbi_ctr_get_idx(event); + /* TODO: Counter delegation implementation */ +} + +static u64 rvpmu_ctr_read(struct perf_event *event) +{ + return rvpmu_sbi_ctr_read(event); + /* TODO: Counter delegation implementation */ +} + +static int rvpmu_starting_cpu(unsigned int cpu, struct hlist_node *node) { struct riscv_pmu *pmu =3D hlist_entry_safe(node, struct riscv_pmu, node); struct cpu_hw_events *cpu_hw_evt =3D this_cpu_ptr(pmu->hw_events); @@ -1160,7 +1204,7 @@ static int pmu_sbi_starting_cpu(unsigned int cpu, str= uct hlist_node *node) csr_write(CSR_SCOUNTEREN, 0x2); =20 /* Stop all the counters so that they can be enabled from perf */ - pmu_sbi_stop_all(pmu); + rvpmu_sbi_stop_all(pmu); =20 if (riscv_pmu_use_irq) { cpu_hw_evt->irq =3D riscv_pmu_irq; @@ -1174,7 +1218,7 @@ static int pmu_sbi_starting_cpu(unsigned int cpu, str= uct hlist_node *node) return 0; } =20 -static int pmu_sbi_dying_cpu(unsigned int cpu, struct hlist_node *node) +static int rvpmu_dying_cpu(unsigned int cpu, struct hlist_node *node) { if (riscv_pmu_use_irq) { disable_percpu_irq(riscv_pmu_irq); @@ -1189,7 +1233,7 @@ static int pmu_sbi_dying_cpu(unsigned int cpu, struct= hlist_node *node) return 0; } =20 -static int pmu_sbi_setup_irqs(struct riscv_pmu *pmu, struct platform_devic= e *pdev) +static int rvpmu_setup_irqs(struct riscv_pmu *pmu, struct platform_device = *pdev) { int ret; struct cpu_hw_events __percpu *hw_events =3D pmu->hw_events; @@ -1229,7 +1273,7 @@ static int pmu_sbi_setup_irqs(struct riscv_pmu *pmu, = struct platform_device *pde return -ENODEV; } =20 - ret =3D request_percpu_irq(riscv_pmu_irq, pmu_sbi_ovf_handler, "riscv-pmu= ", hw_events); + ret =3D request_percpu_irq(riscv_pmu_irq, rvpmu_ovf_handler, "riscv-pmu",= hw_events); if (ret) { pr_err("registering percpu irq failed [%d]\n", ret); return ret; @@ -1305,7 +1349,7 @@ static void riscv_pmu_destroy(struct riscv_pmu *pmu) cpuhp_state_remove_instance(CPUHP_AP_PERF_RISCV_STARTING, &pmu->node); } =20 -static void pmu_sbi_event_init(struct perf_event *event) +static void rvpmu_event_init(struct perf_event *event) { /* * The permissions are set at event_init so that we do not depend @@ -1319,7 +1363,7 @@ static void pmu_sbi_event_init(struct perf_event *eve= nt) event->hw.flags |=3D PERF_EVENT_FLAG_LEGACY; } =20 -static void pmu_sbi_event_mapped(struct perf_event *event, struct mm_struc= t *mm) +static void rvpmu_event_mapped(struct perf_event *event, struct mm_struct = *mm) { if (event->hw.flags & PERF_EVENT_FLAG_NO_USER_ACCESS) return; @@ -1347,14 +1391,14 @@ static void pmu_sbi_event_mapped(struct perf_event = *event, struct mm_struct *mm) * that it is possible to do so to avoid any race. * And we must notify all cpus here because threads that currently run * on other cpus will try to directly access the counter too without - * calling pmu_sbi_ctr_start. + * calling rvpmu_sbi_ctr_start. */ if (event->hw.flags & PERF_EVENT_FLAG_USER_ACCESS) on_each_cpu_mask(mm_cpumask(mm), - pmu_sbi_set_scounteren, (void *)event, 1); + rvpmu_set_scounteren, (void *)event, 1); } =20 -static void pmu_sbi_event_unmapped(struct perf_event *event, struct mm_str= uct *mm) +static void rvpmu_event_unmapped(struct perf_event *event, struct mm_struc= t *mm) { if (event->hw.flags & PERF_EVENT_FLAG_NO_USER_ACCESS) return; @@ -1376,7 +1420,7 @@ static void pmu_sbi_event_unmapped(struct perf_event = *event, struct mm_struct *m =20 if (event->hw.flags & PERF_EVENT_FLAG_USER_ACCESS) on_each_cpu_mask(mm_cpumask(mm), - pmu_sbi_reset_scounteren, (void *)event, 1); + rvpmu_reset_scounteren, (void *)event, 1); } =20 static void riscv_pmu_update_counter_access(void *info) @@ -1419,7 +1463,7 @@ static const struct ctl_table sbi_pmu_sysctl_table[] = =3D { }, }; =20 -static int pmu_sbi_device_probe(struct platform_device *pdev) +static int rvpmu_device_probe(struct platform_device *pdev) { struct riscv_pmu *pmu =3D NULL; int ret =3D -ENODEV; @@ -1430,7 +1474,7 @@ static int pmu_sbi_device_probe(struct platform_devic= e *pdev) if (!pmu) return -ENOMEM; =20 - num_counters =3D pmu_sbi_find_num_ctrs(); + num_counters =3D rvpmu_find_num_ctrs(); if (num_counters < 0) { pr_err("SBI PMU extension doesn't provide any counters\n"); goto out_free; @@ -1443,10 +1487,10 @@ static int pmu_sbi_device_probe(struct platform_dev= ice *pdev) } =20 /* cache all the information about counters now */ - if (pmu_sbi_get_ctrinfo(num_counters, &cmask)) + if (rvpmu_get_ctrinfo(num_counters, &cmask)) goto out_free; =20 - ret =3D pmu_sbi_setup_irqs(pmu, pdev); + ret =3D rvpmu_setup_irqs(pmu, pdev); if (ret < 0) { pr_info("Perf sampling/filtering is not supported as sscof extension is = not available\n"); pmu->pmu.capabilities |=3D PERF_PMU_CAP_NO_INTERRUPT; @@ -1456,17 +1500,17 @@ static int pmu_sbi_device_probe(struct platform_dev= ice *pdev) pmu->pmu.attr_groups =3D riscv_pmu_attr_groups; pmu->pmu.parent =3D &pdev->dev; pmu->cmask =3D cmask; - pmu->ctr_start =3D pmu_sbi_ctr_start; - pmu->ctr_stop =3D pmu_sbi_ctr_stop; - pmu->event_map =3D pmu_sbi_event_map; - pmu->ctr_get_idx =3D pmu_sbi_ctr_get_idx; - pmu->ctr_get_width =3D pmu_sbi_ctr_get_width; - pmu->ctr_clear_idx =3D pmu_sbi_ctr_clear_idx; - pmu->ctr_read =3D pmu_sbi_ctr_read; - pmu->event_init =3D pmu_sbi_event_init; - pmu->event_mapped =3D pmu_sbi_event_mapped; - pmu->event_unmapped =3D pmu_sbi_event_unmapped; - pmu->csr_index =3D pmu_sbi_csr_index; + pmu->ctr_start =3D rvpmu_ctr_start; + pmu->ctr_stop =3D rvpmu_ctr_stop; + pmu->event_map =3D rvpmu_event_map; + pmu->ctr_get_idx =3D rvpmu_ctr_get_idx; + pmu->ctr_get_width =3D rvpmu_ctr_get_width; + pmu->ctr_clear_idx =3D rvpmu_ctr_clear_idx; + pmu->ctr_read =3D rvpmu_ctr_read; + pmu->event_init =3D rvpmu_event_init; + pmu->event_mapped =3D rvpmu_event_mapped; + pmu->event_unmapped =3D rvpmu_event_unmapped; + pmu->csr_index =3D rvpmu_csr_index; =20 ret =3D riscv_pm_pmu_register(pmu); if (ret) @@ -1522,14 +1566,14 @@ static int pmu_sbi_device_probe(struct platform_dev= ice *pdev) return ret; } =20 -static struct platform_driver pmu_sbi_driver =3D { - .probe =3D pmu_sbi_device_probe, +static struct platform_driver rvpmu_driver =3D { + .probe =3D rvpmu_device_probe, .driver =3D { .name =3D RISCV_PMU_SBI_PDEV_NAME, }, }; =20 -static int __init pmu_sbi_devinit(void) +static int __init rvpmu_devinit(void) { int ret; struct platform_device *pdev; @@ -1547,20 +1591,20 @@ static int __init pmu_sbi_devinit(void) =20 ret =3D cpuhp_setup_state_multi(CPUHP_AP_PERF_RISCV_STARTING, "perf/riscv/pmu:starting", - pmu_sbi_starting_cpu, pmu_sbi_dying_cpu); + rvpmu_starting_cpu, rvpmu_dying_cpu); if (ret) { pr_err("CPU hotplug notifier could not be registered: %d\n", ret); return ret; } =20 - ret =3D platform_driver_register(&pmu_sbi_driver); + ret =3D platform_driver_register(&rvpmu_driver); if (ret) return ret; =20 pdev =3D platform_device_register_simple(RISCV_PMU_SBI_PDEV_NAME, -1, NUL= L, 0); if (IS_ERR(pdev)) { - platform_driver_unregister(&pmu_sbi_driver); + platform_driver_unregister(&rvpmu_driver); return PTR_ERR(pdev); } =20 @@ -1569,4 +1613,4 @@ static int __init pmu_sbi_devinit(void) =20 return ret; } -device_initcall(pmu_sbi_devinit) +device_initcall(rvpmu_devinit) --=20 2.53.0-Meta From nobody Sat Jun 13 15:24:19 2026 Received: from out-180.mta1.migadu.com (out-180.mta1.migadu.com [95.215.58.180]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C2E723CF20D for ; Tue, 9 Jun 2026 06:02:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984956; cv=none; b=sbLWXT8BOcYk2pTJhTXW0QQbiC74N2m/bIJ3pIETp2pPy84t9JnMOAj+/+Ec5ns/YnMdf8OLdAAR2XyWTbroVMrXZY7/haS026WaCHxz0rLGK2RWaf2FpZrn9B/fko0O0uvnaE9MVzFq/cGPKiiOKX7pzK2p8U285hheGr+FoEw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984956; c=relaxed/simple; bh=sFfAeDDeGl8gLoArKOzWNGFy+xUUDQO5VChXif10Xxg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Z2nHSAg+2AHG/1jnrX30VWDC931k3xMK2toeOVmNd1f9RG1p82tWFJ4Squ1u/muO3Vd6wK/Wm/e1DsQ86hTR1rmMVeGsVbIOmXTvjdXgvMQV8kZ/fuLIH8rMLlSMQZTMUN3jQNb8JPX1Wi16i88E2nFVTGTzMalGHQEqo4x8de8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=kRS79nQv; arc=none smtp.client-ip=95.215.58.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="kRS79nQv" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1780984952; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=yTMFJ4P46JbQ3PbG4ipLuwyTV2alsEa1iaAZ3bXyziU=; b=kRS79nQvYNTJuSshHzAQY1/Emb/IQJY0QR0c6nCauWNla/TRa8I9VM3okgCJ1LlpahjTlr TyHp3gOt1WVi/RVw2PgsCWs+hqWQshkvN1TDf+5hYIu5oITML5Il2XQaYNgjTUEdLl5cg9 Wmrb9fTFSPfe+7i+j9LPEXF7e8ulEuU= From: Atish Patra Date: Mon, 08 Jun 2026 23:01:25 -0700 Subject: [PATCH v6 11/21] RISC-V: perf: Modify the counter discovery mechanism Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260608-counter_delegation-v6-11-285b72ed65a9@meta.com> References: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> In-Reply-To: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> To: James Clark , Rob Herring , Atish Patra , Arnaldo Carvalho de Melo , Jiri Olsa , Will Deacon , Mark Rutland , Anup Patel , Namhyung Kim , Paul Walmsley , Krzysztof Kozlowski , Ian Rogers Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Conor Dooley , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org X-Migadu-Flow: FLOW_OUT From: Atish Patra If both counter delegation and SBI PMU is present, the counter delegation will be used for hardware pmu counters while the SBI PMU will be used for firmware counters. Thus, the driver has to probe the counters info via SBI PMU to distinguish the firmware counters. The hybrid scheme also requires improvements of the informational logging messages to indicate the user about underlying interface used for each use case. Signed-off-by: Atish Patra --- drivers/perf/riscv_pmu_sbi.c | 131 ++++++++++++++++++++++++++++++++-------= ---- 1 file changed, 97 insertions(+), 34 deletions(-) diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c index 7f21c16003f0..57ab15beab3e 100644 --- a/drivers/perf/riscv_pmu_sbi.c +++ b/drivers/perf/riscv_pmu_sbi.c @@ -67,6 +67,20 @@ static bool sbi_v3_available; static DEFINE_STATIC_KEY_FALSE(sbi_pmu_snapshot_available); #define sbi_pmu_snapshot_available() \ static_branch_unlikely(&sbi_pmu_snapshot_available) +static DEFINE_STATIC_KEY_FALSE(riscv_pmu_sbi_available); +static DEFINE_STATIC_KEY_FALSE(riscv_pmu_cdeleg_available); + +/* Avoid unnecessary code patching in the one time booting path*/ +#define riscv_pmu_cdeleg_available_boot() \ + static_key_enabled(&riscv_pmu_cdeleg_available) +#define riscv_pmu_sbi_available_boot() \ + static_key_enabled(&riscv_pmu_sbi_available) + +/* Perform a runtime code patching with static key */ +#define riscv_pmu_cdeleg_available() \ + static_branch_unlikely(&riscv_pmu_cdeleg_available) +#define riscv_pmu_sbi_available() \ + static_branch_likely(&riscv_pmu_sbi_available) =20 static struct attribute *riscv_arch_formats_attr[] =3D { &format_attr_event.attr, @@ -89,7 +103,8 @@ static int sysctl_perf_user_access __read_mostly =3D SYS= CTL_USER_ACCESS; =20 /* * This structure is SBI specific but counter delegation also require coun= ter - * width, csr mapping. Reuse it for now. + * width, csr mapping. Reuse it for now we can have firmware counters for + * platfroms with counter delegation support. * RISC-V doesn't have heterogeneous harts yet. This need to be part of * per_cpu in case of harts with different pmu counters */ @@ -101,6 +116,8 @@ static unsigned int riscv_pmu_irq; =20 /* Cache the available counters in a bitmask */ static unsigned long cmask; +/* Cache the available firmware counters in another bitmask */ +static unsigned long firmware_cmask; =20 static int sbi_pmu_event_find_cache(u64 config); struct sbi_pmu_event_data { @@ -868,34 +885,38 @@ static int rvpmu_sbi_find_num_ctrs(void) return sbi_err_map_linux_errno(ret.error); } =20 -static int rvpmu_sbi_get_ctrinfo(int nctr, unsigned long *mask) +static u32 rvpmu_deleg_find_ctrs(void) +{ + /* TODO */ + return 0; +} + +static int rvpmu_sbi_get_ctrinfo(u32 nsbi_ctr, u32 *num_fw_ctr, u32 *num_h= w_ctr) { struct sbiret ret; - int i, num_hw_ctr =3D 0, num_fw_ctr =3D 0; + int i; union sbi_pmu_ctr_info cinfo; =20 - pmu_ctr_list =3D kzalloc_objs(*pmu_ctr_list, nctr); - if (!pmu_ctr_list) - return -ENOMEM; - - for (i =3D 0; i < nctr; i++) { + for (i =3D 0; i < nsbi_ctr; 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 */ continue; =20 - *mask |=3D BIT(i); - cinfo.value =3D ret.value; - if (cinfo.type =3D=3D SBI_PMU_CTR_TYPE_FW) - num_fw_ctr++; - else - num_hw_ctr++; - pmu_ctr_list[i].value =3D cinfo.value; + if (cinfo.type =3D=3D SBI_PMU_CTR_TYPE_FW) { + /* Track firmware counters in a different mask */ + firmware_cmask |=3D BIT(i); + pmu_ctr_list[i].value =3D cinfo.value; + *num_fw_ctr =3D *num_fw_ctr + 1; + } else if (cinfo.type =3D=3D SBI_PMU_CTR_TYPE_HW && + !riscv_pmu_cdeleg_available_boot()) { + *num_hw_ctr =3D *num_hw_ctr + 1; + cmask |=3D BIT(i); + pmu_ctr_list[i].value =3D cinfo.value; + } } =20 - pr_info("%d firmware and %d hardware counters\n", num_fw_ctr, num_hw_ctr); - return 0; } =20 @@ -1159,16 +1180,42 @@ static void rvpmu_ctr_stop(struct perf_event *event= , unsigned long flag) /* TODO: Counter delegation implementation */ } =20 -static int rvpmu_find_num_ctrs(void) +static int rvpmu_find_ctrs(void) { - return rvpmu_sbi_find_num_ctrs(); - /* TODO: Counter delegation implementation */ -} + u32 num_sbi_counters =3D 0, num_deleg_counters =3D 0; + u32 num_hw_ctr =3D 0, num_fw_ctr =3D 0, num_ctr =3D 0; + /* + * We don't know how many firmware counters are available. Just allocate + * for maximum counters the driver can support. The default is 64 anyways. + */ + pmu_ctr_list =3D kcalloc(RISCV_MAX_COUNTERS, sizeof(*pmu_ctr_list), + GFP_KERNEL); + if (!pmu_ctr_list) + return -ENOMEM; =20 -static int rvpmu_get_ctrinfo(int nctr, unsigned long *mask) -{ - return rvpmu_sbi_get_ctrinfo(nctr, mask); - /* TODO: Counter delegation implementation */ + if (riscv_pmu_cdeleg_available_boot()) + num_deleg_counters =3D rvpmu_deleg_find_ctrs(); + + /* This is required for firmware counters even if the above is true */ + if (riscv_pmu_sbi_available_boot()) + num_sbi_counters =3D rvpmu_sbi_find_num_ctrs(); + + if (num_sbi_counters > RISCV_MAX_COUNTERS || num_deleg_counters > RISCV_M= AX_COUNTERS) + return -ENOSPC; + + /* cache all the information about counters now */ + if (riscv_pmu_sbi_available_boot()) + rvpmu_sbi_get_ctrinfo(num_sbi_counters, &num_fw_ctr, &num_hw_ctr); + + if (riscv_pmu_cdeleg_available_boot()) { + pr_info("%u firmware and %u hardware counters\n", num_fw_ctr, num_deleg_= counters); + num_ctr =3D num_fw_ctr + num_deleg_counters; + } else { + pr_info("%u firmware and %u hardware counters\n", num_fw_ctr, num_hw_ctr= ); + num_ctr =3D num_sbi_counters; + } + + return num_ctr; } =20 static int rvpmu_event_map(struct perf_event *event, u64 *econfig) @@ -1469,12 +1516,21 @@ static int rvpmu_device_probe(struct platform_devic= e *pdev) int ret =3D -ENODEV; int num_counters; =20 - pr_info("SBI PMU extension is available\n"); + if (riscv_pmu_cdeleg_available_boot()) { + pr_info("hpmcounters will use the counter delegation ISA extension\n"); + if (riscv_pmu_sbi_available_boot()) + pr_info("Firmware counters will use SBI PMU extension\n"); + else + pr_info("Firmware counters will not be available as SBI PMU extension i= s not present\n"); + } else if (riscv_pmu_sbi_available_boot()) { + pr_info("Both hpmcounters and firmware counters will use SBI PMU extensi= on\n"); + } + pmu =3D riscv_pmu_alloc(); if (!pmu) return -ENOMEM; =20 - num_counters =3D rvpmu_find_num_ctrs(); + num_counters =3D rvpmu_find_ctrs(); if (num_counters < 0) { pr_err("SBI PMU extension doesn't provide any counters\n"); goto out_free; @@ -1486,9 +1542,6 @@ static int rvpmu_device_probe(struct platform_device = *pdev) pr_info("SBI returned more than maximum number of counters. Limiting the= number of counters to %d\n", num_counters); } =20 - /* cache all the information about counters now */ - if (rvpmu_get_ctrinfo(num_counters, &cmask)) - goto out_free; =20 ret =3D rvpmu_setup_irqs(pmu, pdev); if (ret < 0) { @@ -1578,13 +1631,23 @@ static int __init rvpmu_devinit(void) int ret; struct platform_device *pdev; =20 - if (sbi_spec_version < sbi_mk_version(0, 3) || - !sbi_probe_extension(SBI_EXT_PMU)) { - return 0; - } + if (sbi_spec_version >=3D sbi_mk_version(0, 3) && + sbi_probe_extension(SBI_EXT_PMU)) + static_branch_enable(&riscv_pmu_sbi_available); =20 if (sbi_spec_version >=3D sbi_mk_version(2, 0)) sbi_v2_available =3D true; + /* + * We need all three extensions to be present to access the counters + * in S-mode via Supervisor Counter delegation. + */ + if (riscv_isa_extension_available(NULL, SSCCFG) && + riscv_isa_extension_available(NULL, SMCDELEG) && + riscv_isa_extension_available(NULL, SSCSRIND)) + static_branch_enable(&riscv_pmu_cdeleg_available); + + if (!(riscv_pmu_sbi_available_boot() || riscv_pmu_cdeleg_available_boot()= )) + return 0; =20 if (sbi_spec_version >=3D sbi_mk_version(3, 0)) sbi_v3_available =3D true; --=20 2.53.0-Meta From nobody Sat Jun 13 15:24:19 2026 Received: from out-183.mta1.migadu.com (out-183.mta1.migadu.com [95.215.58.183]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 19CA83CF69E for ; Tue, 9 Jun 2026 06:02:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.183 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984959; cv=none; b=D+nia31NhxhevNr9ZL+hkTpg9aKFLLg768WLc4LSSaYHVKzd16Biruie0CtV7TFicO6UFBK/76E+mvTKHapvASj7ty2nSMdNbVWqimRWck8MbcpKC2hG/BaYjrdLix61x5fDX/HF4PN8oBtxiUohJsxgXcWeCo7N43hyZUQLBqM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984959; c=relaxed/simple; bh=VrttyV9D+qBeS0hxU4VlV2uLCj1nw4zBG5ULHu2FIE8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=kbvBD9qwZyXnF/d8BCa+yA1rqw1vXvBeKBIyTCmqdYrXfWKiP9sJSQ1l0/A7P7k2XzRzJTKMyoN7JEYjyn9wg2Hdbf83ohkUzvj9bmF2S2/sXTsoqY8IlKgeAUze9tQC1QliJPyklxnE1ryUEh6YN/wynuNUb+xED/hiG49A9vY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=ekI97+OL; arc=none smtp.client-ip=95.215.58.183 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="ekI97+OL" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1780984956; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=dI3T9Syv/F7UBtrHfN9ztjqJivTsyiuB0g714VMRlRI=; b=ekI97+OLYDLY5IUXpxCC+SN10+OdASUqSS0n/O5Soyx/8FvkpFG636XaQZL3m5MHgGDUxu 9pN34vht5d1DFjwSBfkCc84u+E+86Kt8WuP2dM6TAw/DNBedYxbGuo4/XAoSEm5TtnXh68 GGYqs3N/43exj/PEq/cqV4k8V9bt+zk= From: Atish Patra Date: Mon, 08 Jun 2026 23:01:26 -0700 Subject: [PATCH v6 12/21] RISC-V: perf: Add a mechanism to defined legacy event encoding Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260608-counter_delegation-v6-12-285b72ed65a9@meta.com> References: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> In-Reply-To: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> To: James Clark , Rob Herring , Atish Patra , Arnaldo Carvalho de Melo , Jiri Olsa , Will Deacon , Mark Rutland , Anup Patel , Namhyung Kim , Paul Walmsley , Krzysztof Kozlowski , Ian Rogers Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Conor Dooley , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org X-Migadu-Flow: FLOW_OUT From: Atish Patra RISC-V ISA doesn't define any standard event encodings or specify any event to counter mapping. Thus, event encoding information and corresponding counter mapping fot those events needs to be provided in the driver for each vendor. Add a framework to support that. The individual platform events will be added later. Signed-off-by: Atish Patra --- drivers/perf/riscv_pmu_sbi.c | 54 ++++++++++++++++++++++++++++++++++++++= +++- include/linux/perf/riscv_pmu.h | 13 ++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c index 57ab15beab3e..46a25979e95e 100644 --- a/drivers/perf/riscv_pmu_sbi.c +++ b/drivers/perf/riscv_pmu_sbi.c @@ -379,6 +379,56 @@ static int pmu_sbi_check_event_info(void) return result; } =20 +/* + * Vendor specific PMU events. + */ +struct riscv_pmu_event { + u64 event_id; + u32 counter_mask; +}; + +struct riscv_vendor_pmu_events { + unsigned long vendorid; + unsigned long archid; + unsigned long implid; + const struct riscv_pmu_event *hw_event_map; + const struct riscv_pmu_event (*cache_event_map)[PERF_COUNT_HW_CACHE_OP_MA= X] + [PERF_COUNT_HW_CACHE_RESULT_MAX]; +}; + +#define RISCV_VENDOR_PMU_EVENTS(_vendorid, _archid, _implid, _hw_event_map= , _cache_event_map) \ + { .vendorid =3D _vendorid, .archid =3D _archid, .implid =3D _implid, \ + .hw_event_map =3D _hw_event_map, .cache_event_map =3D _cache_event_map = }, + +static struct riscv_vendor_pmu_events pmu_vendor_events_table[] =3D { +}; + +static const struct riscv_pmu_event *current_pmu_hw_event_map; +static const struct riscv_pmu_event (*current_pmu_cache_event_map)[PERF_CO= UNT_HW_CACHE_OP_MAX] + [PERF_COUNT_HW_CACHE_RESULT_MAX]; + +static void rvpmu_vendor_register_events(void) +{ + int cpu =3D raw_smp_processor_id(); + unsigned long vendor_id =3D riscv_cached_mvendorid(cpu); + unsigned long impl_id =3D riscv_cached_mimpid(cpu); + unsigned long arch_id =3D riscv_cached_marchid(cpu); + + for (int i =3D 0; i < ARRAY_SIZE(pmu_vendor_events_table); i++) { + if (pmu_vendor_events_table[i].vendorid =3D=3D vendor_id && + pmu_vendor_events_table[i].implid =3D=3D impl_id && + pmu_vendor_events_table[i].archid =3D=3D arch_id) { + current_pmu_hw_event_map =3D pmu_vendor_events_table[i].hw_event_map; + current_pmu_cache_event_map =3D pmu_vendor_events_table[i].cache_event_= map; + break; + } + } + + if (!current_pmu_hw_event_map || !current_pmu_cache_event_map) { + pr_info("No default PMU events found\n"); + } +} + static void rvpmu_sbi_check_event(struct sbi_pmu_event_data *edata) { struct sbiret ret; @@ -1643,8 +1693,10 @@ static int __init rvpmu_devinit(void) */ if (riscv_isa_extension_available(NULL, SSCCFG) && riscv_isa_extension_available(NULL, SMCDELEG) && - riscv_isa_extension_available(NULL, SSCSRIND)) + riscv_isa_extension_available(NULL, SSCSRIND)) { static_branch_enable(&riscv_pmu_cdeleg_available); + rvpmu_vendor_register_events(); + } =20 if (!(riscv_pmu_sbi_available_boot() || riscv_pmu_cdeleg_available_boot()= )) return 0; diff --git a/include/linux/perf/riscv_pmu.h b/include/linux/perf/riscv_pmu.h index f82a28040594..6c75106989b6 100644 --- a/include/linux/perf/riscv_pmu.h +++ b/include/linux/perf/riscv_pmu.h @@ -28,6 +28,19 @@ =20 #define RISCV_PMU_CONFIG1_GUEST_EVENTS 0x1 =20 +#define HW_OP_UNSUPPORTED 0xFFFF +#define CACHE_OP_UNSUPPORTED 0xFFFF + +#define PERF_MAP_ALL_UNSUPPORTED \ + [0 ... PERF_COUNT_HW_MAX - 1] =3D {HW_OP_UNSUPPORTED, 0x0} + +#define PERF_CACHE_MAP_ALL_UNSUPPORTED \ +[0 ... C(MAX) - 1] =3D { \ + [0 ... C(OP_MAX) - 1] =3D { \ + [0 ... C(RESULT_MAX) - 1] =3D {CACHE_OP_UNSUPPORTED, 0x0} \ + }, \ +} + struct cpu_hw_events { /* currently enabled events */ int n_events; --=20 2.53.0-Meta From nobody Sat Jun 13 15:24:19 2026 Received: from out-185.mta0.migadu.com (out-185.mta0.migadu.com [91.218.175.185]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 033223D1CA5 for ; Tue, 9 Jun 2026 06:02:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.185 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984964; cv=none; b=KOLsijlnHTUIx2GMmDKABF9YKzKn0+0cfXF8Isxe65qmQNAtII5r0Wk68mkGCCDHxUrCCLDj0cbU0QBJ4yMXu9JqGX72pZjbNJjSoR1Ebn4U/bb0ZvlSC3pMNPrW9V1TcHHA77B5UJtzjw2JWKEUu6CguMqNvTGtkUOqObtfSFI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984964; c=relaxed/simple; bh=FVwPgDxEDpFdMp2w1ybk8Wr/qSJZlgVsDolfF/llf6o=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=YNtYE9dfALJI8zmrRlneuAAUkoXjwwwRgG3I/DgvGGBuNdXibo495InEP60Q9+vjs+WcyLFlgSquHRRp+Yo5gWWgZ/j3Sel3GIqdey2+I64tMLtOtGnsAq+O6aO/5fZC2mxmNJcBpxB+mpbQk/ZHIwD/QLKbkBhzzz/Qgpd9Okc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=J2aVt3HC; arc=none smtp.client-ip=91.218.175.185 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="J2aVt3HC" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1780984960; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=LyFrKesVoJ2su3NmASUNC81KCnUo0z9zGGT0XccBC4s=; b=J2aVt3HCbTDZB8qIynxr6xi5L6zjifwdR36VM+xS07OCceBOeA8LLzhdkz24In4yupU1Vq nig5ZYvRCg+iVELfXoPH+h/0tU+G1CNvpLEqbeSDmt0ANUfv6Y3sYh/Md5sv1ucgzAPV4c 4NB33JpkIlu3WWKqOqeBZKqr4q5MNIw= From: Atish Patra Date: Mon, 08 Jun 2026 23:01:27 -0700 Subject: [PATCH v6 13/21] RISC-V: perf: Implement supervisor counter delegation support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260608-counter_delegation-v6-13-285b72ed65a9@meta.com> References: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> In-Reply-To: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> To: James Clark , Rob Herring , Atish Patra , Arnaldo Carvalho de Melo , Jiri Olsa , Will Deacon , Mark Rutland , Anup Patel , Namhyung Kim , Paul Walmsley , Krzysztof Kozlowski , Ian Rogers Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Conor Dooley , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org X-Migadu-Flow: FLOW_OUT From: Atish Patra There are few new RISC-V ISA exensions (ssccfg, sscsrind, smcntrpmf) which allows the hpmcounter/hpmevents to be programmed directly from S-mode. The implementation detects the ISA extension at runtime and uses them if available instead of SBI PMU extension. SBI PMU extension will still be used for firmware counters if the user requests it. The current linux driver relies on event encoding defined by SBI PMU specification for standard perf events. However, there are no standard event encoding available in the ISA. In the future, we may want to decouple the counter delegation and SBI PMU completely. In that case, counter delegation supported platforms must rely on the event encoding defined in the perf json file or in the pmu driver. For firmware events, it will continue to use the SBI PMU encoding as one can not support firmware event without SBI PMU. Signed-off-by: Atish Patra --- arch/riscv/include/asm/csr.h | 1 + drivers/perf/riscv_pmu_sbi.c | 574 +++++++++++++++++++++++++++++++++----= ---- include/linux/perf/riscv_pmu.h | 3 + 3 files changed, 473 insertions(+), 105 deletions(-) diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h index 26cb78dee2fd..25ebf853bfef 100644 --- a/arch/riscv/include/asm/csr.h +++ b/arch/riscv/include/asm/csr.h @@ -266,6 +266,7 @@ #endif =20 #define SISELECT_SSCCFG_BASE 0x40 +#define HPMEVENT_MASK GENMASK_ULL(63, 56) =20 /* mseccfg bits */ #define MSECCFG_PMM ENVCFG_PMM diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c index 46a25979e95e..1f16df9d0dd0 100644 --- a/drivers/perf/riscv_pmu_sbi.c +++ b/drivers/perf/riscv_pmu_sbi.c @@ -27,6 +27,8 @@ #include #include #include +#include +#include =20 #define ALT_SBI_PMU_OVERFLOW(__ovl) \ asm volatile(ALTERNATIVE_2( \ @@ -59,7 +61,20 @@ asm volatile(ALTERNATIVE( \ #define PERF_EVENT_FLAG_USER_ACCESS BIT(SYSCTL_USER_ACCESS) #define PERF_EVENT_FLAG_LEGACY BIT(SYSCTL_LEGACY) =20 -PMU_FORMAT_ATTR(event, "config:0-55"); +#define RVPMU_SBI_PMU_FORMAT_ATTR "config:0-47" +#define RVPMU_CDELEG_PMU_FORMAT_ATTR "config:0-55" + +static ssize_t __maybe_unused rvpmu_format_show(struct device *dev, struct= device_attribute *attr, + char *buf); + +#define RVPMU_ATTR_ENTRY(_name, _func, _config) ( \ + &((struct dev_ext_attribute[]) { \ + { __ATTR(_name, 0444, _func, NULL), (void *)_config } \ + })[0].attr.attr) + +#define RVPMU_FORMAT_ATTR_ENTRY(_name, _config) \ + RVPMU_ATTR_ENTRY(_name, rvpmu_format_show, (char *)_config) + PMU_FORMAT_ATTR(firmware, "config:62-63"); =20 static bool sbi_v2_available; @@ -67,7 +82,11 @@ static bool sbi_v3_available; static DEFINE_STATIC_KEY_FALSE(sbi_pmu_snapshot_available); #define sbi_pmu_snapshot_available() \ static_branch_unlikely(&sbi_pmu_snapshot_available) + static DEFINE_STATIC_KEY_FALSE(riscv_pmu_sbi_available); +#define riscv_pmu_sbi_available() \ + static_branch_likely(&riscv_pmu_sbi_available) + static DEFINE_STATIC_KEY_FALSE(riscv_pmu_cdeleg_available); =20 /* Avoid unnecessary code patching in the one time booting path*/ @@ -82,19 +101,35 @@ static DEFINE_STATIC_KEY_FALSE(riscv_pmu_cdeleg_availa= ble); #define riscv_pmu_sbi_available() \ static_branch_likely(&riscv_pmu_sbi_available) =20 -static struct attribute *riscv_arch_formats_attr[] =3D { - &format_attr_event.attr, +static struct attribute *riscv_sbi_pmu_formats_attr[] =3D { + RVPMU_FORMAT_ATTR_ENTRY(event, RVPMU_SBI_PMU_FORMAT_ATTR), + &format_attr_firmware.attr, + NULL, +}; + +static struct attribute_group riscv_sbi_pmu_format_group =3D { + .name =3D "format", + .attrs =3D riscv_sbi_pmu_formats_attr, +}; + +static const struct attribute_group *riscv_sbi_pmu_attr_groups[] =3D { + &riscv_sbi_pmu_format_group, + NULL, +}; + +static struct attribute *riscv_cdeleg_pmu_formats_attr[] =3D { + RVPMU_FORMAT_ATTR_ENTRY(event, RVPMU_CDELEG_PMU_FORMAT_ATTR), &format_attr_firmware.attr, NULL, }; =20 -static struct attribute_group riscv_pmu_format_group =3D { +static struct attribute_group riscv_cdeleg_pmu_format_group =3D { .name =3D "format", - .attrs =3D riscv_arch_formats_attr, + .attrs =3D riscv_cdeleg_pmu_formats_attr, }; =20 -static const struct attribute_group *riscv_pmu_attr_groups[] =3D { - &riscv_pmu_format_group, +static const struct attribute_group *riscv_cdeleg_pmu_attr_groups[] =3D { + &riscv_cdeleg_pmu_format_group, NULL, }; =20 @@ -466,6 +501,14 @@ static void rvpmu_sbi_check_std_events(struct work_str= uct *work) =20 static DECLARE_WORK(check_std_events_work, rvpmu_sbi_check_std_events); =20 +static ssize_t rvpmu_format_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct dev_ext_attribute *eattr =3D container_of(attr, + struct dev_ext_attribute, attr); + return sysfs_emit(buf, "%s\n", (char *)eattr->var); +} + static int rvpmu_ctr_get_width(int idx) { return pmu_ctr_list[idx].width; @@ -583,6 +626,38 @@ static uint8_t rvpmu_csr_index(struct perf_event *even= t) return pmu_ctr_list[event->hw.idx].csr - CSR_CYCLE; } =20 +static uint64_t get_deleg_priv_filter_bits(struct perf_event *event) +{ + u64 priv_filter_bits =3D 0; + bool guest_events =3D false; + + if (event->attr.config1 & RISCV_PMU_CONFIG1_GUEST_EVENTS) + guest_events =3D true; + if (event->attr.exclude_kernel) + priv_filter_bits |=3D guest_events ? HPMEVENT_VSINH : HPMEVENT_SINH; + if (event->attr.exclude_user) + priv_filter_bits |=3D guest_events ? HPMEVENT_VUINH : HPMEVENT_UINH; + if (guest_events && event->attr.exclude_hv) + priv_filter_bits |=3D HPMEVENT_SINH; + if (event->attr.exclude_host) + priv_filter_bits |=3D HPMEVENT_UINH | HPMEVENT_SINH; + if (event->attr.exclude_guest) + priv_filter_bits |=3D HPMEVENT_VSINH | HPMEVENT_VUINH; + + return priv_filter_bits; +} + +static bool pmu_sbi_is_fw_event(struct perf_event *event) +{ + u32 type =3D event->attr.type; + u64 config =3D event->attr.config; + + if (type =3D=3D PERF_TYPE_RAW && ((config >> 63) =3D=3D 1)) + return true; + else + return false; +} + static unsigned long rvpmu_sbi_get_filter_flags(struct perf_event *event) { unsigned long cflags =3D 0; @@ -611,7 +686,8 @@ static int rvpmu_sbi_ctr_get_idx(struct perf_event *eve= nt) struct cpu_hw_events *cpuc =3D this_cpu_ptr(rvpmu->hw_events); struct sbiret ret; int idx; - uint64_t cbase =3D 0, cmask =3D rvpmu->cmask; + u64 cbase =3D 0; + unsigned long ctr_mask =3D rvpmu->cmask; unsigned long cflags =3D 0; =20 cflags =3D rvpmu_sbi_get_filter_flags(event); @@ -624,21 +700,23 @@ static int rvpmu_sbi_ctr_get_idx(struct perf_event *e= vent) if ((hwc->flags & PERF_EVENT_FLAG_LEGACY) && (event->attr.type =3D=3D PER= F_TYPE_HARDWARE)) { if (event->attr.config =3D=3D PERF_COUNT_HW_CPU_CYCLES) { cflags |=3D SBI_PMU_CFG_FLAG_SKIP_MATCH; - cmask =3D 1; + ctr_mask =3D 1; } else if (event->attr.config =3D=3D PERF_COUNT_HW_INSTRUCTIONS) { cflags |=3D SBI_PMU_CFG_FLAG_SKIP_MATCH; - cmask =3D BIT(CSR_INSTRET - CSR_CYCLE); + ctr_mask =3D BIT(CSR_INSTRET - CSR_CYCLE); } + } else if (pmu_sbi_is_fw_event(event)) { + ctr_mask =3D firmware_cmask; } =20 /* retrieve the available counter index */ #if defined(CONFIG_32BIT) ret =3D sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_CFG_MATCH, cbase, - cmask, cflags, hwc->event_base, hwc->config, + ctr_mask, cflags, hwc->event_base, hwc->config, hwc->config >> 32); #else ret =3D sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_CFG_MATCH, cbase, - cmask, cflags, hwc->event_base, hwc->config, 0); + ctr_mask, cflags, hwc->event_base, hwc->config, 0); #endif if (ret.error) { pr_debug("Not able to find a counter for event %lx config %llx\n", @@ -647,7 +725,7 @@ static int rvpmu_sbi_ctr_get_idx(struct perf_event *eve= nt) } =20 idx =3D ret.value; - if (!test_bit(idx, &rvpmu->cmask) || !pmu_ctr_list[idx].value) + if (!test_bit(idx, &ctr_mask) || !pmu_ctr_list[idx].value) return -ENOENT; =20 /* Additional sanity check for the counter id */ @@ -697,29 +775,96 @@ static int sbi_pmu_event_find_cache(u64 config) return ret; } =20 -static bool pmu_sbi_is_fw_event(struct perf_event *event) +static int rvpmu_sbi_event_map(struct perf_event *event, u64 *econfig) { u32 type =3D event->attr.type; u64 config =3D event->attr.config; =20 - if ((type =3D=3D PERF_TYPE_RAW) && ((config >> 63) =3D=3D 1)) - return true; - else - return false; + /* + * Ensure we are finished checking standard hardware events for + * validity before allowing userspace to configure any events. + */ + flush_work(&check_std_events_work); + + return riscv_pmu_get_event_info(type, config, econfig); } =20 -static int rvpmu_sbi_event_map(struct perf_event *event, u64 *econfig) +static int cdeleg_pmu_event_find_cache(u64 config, u64 *eventid, uint32_t = *counter_mask) +{ + unsigned int cache_type, cache_op, cache_result; + + if (!current_pmu_cache_event_map) + return -ENOENT; + + cache_type =3D (config >> 0) & 0xff; + if (cache_type >=3D PERF_COUNT_HW_CACHE_MAX) + return -EINVAL; + + cache_op =3D (config >> 8) & 0xff; + if (cache_op >=3D PERF_COUNT_HW_CACHE_OP_MAX) + return -EINVAL; + + cache_result =3D (config >> 16) & 0xff; + if (cache_result >=3D PERF_COUNT_HW_CACHE_RESULT_MAX) + return -EINVAL; + + if (eventid) + *eventid =3D current_pmu_cache_event_map[cache_type][cache_op] + [cache_result].event_id; + if (counter_mask) + *counter_mask =3D current_pmu_cache_event_map[cache_type][cache_op] + [cache_result].counter_mask; + + return 0; +} + +static int rvpmu_cdeleg_event_map(struct perf_event *event, u64 *econfig) { u32 type =3D event->attr.type; u64 config =3D event->attr.config; + int ret =3D 0; =20 /* - * Ensure we are finished checking standard hardware events for - * validity before allowing userspace to configure any events. + * There are two ways standard perf events can be mapped to platform spec= ific + * encoding. + * 1. The vendor may specify the encodings in the driver. + * 2. The Perf tool for RISC-V may remap the standard perf event to platf= orm + * specific encoding. + * + * As RISC-V ISA doesn't define any standard event encoding. Thus, perf t= ool allows + * vendor to define it via json file. The encoding defined in the json wi= ll override + * the perf legacy encoding. However, some user may want to run performan= ce + * monitoring without perf tool as well. That's why, vendors may specify = the event + * encoding in the driver as well if they want to support that use case t= oo. + * If an encoding is defined in the json, it will be encoded as a raw eve= nt. */ - flush_work(&check_std_events_work); =20 - return riscv_pmu_get_event_info(type, config, econfig); + switch (type) { + case PERF_TYPE_HARDWARE: + if (config >=3D PERF_COUNT_HW_MAX) + return -EINVAL; + if (!current_pmu_hw_event_map) + return -ENOENT; + + *econfig =3D current_pmu_hw_event_map[config].event_id; + if (*econfig =3D=3D HW_OP_UNSUPPORTED) + ret =3D -ENOENT; + break; + case PERF_TYPE_HW_CACHE: + ret =3D cdeleg_pmu_event_find_cache(config, econfig, NULL); + if (*econfig =3D=3D HW_OP_UNSUPPORTED) + ret =3D -ENOENT; + break; + case PERF_TYPE_RAW: + *econfig =3D config & RISCV_PMU_DELEG_RAW_EVENT_MASK; + break; + default: + ret =3D -ENOENT; + break; + } + + /* event_base is not used for counter delegation */ + return ret; } =20 static void pmu_sbi_snapshot_free(struct riscv_pmu *pmu) @@ -805,7 +950,7 @@ static int pmu_sbi_snapshot_setup(struct riscv_pmu *pmu= , int cpu) return 0; } =20 -static u64 rvpmu_sbi_ctr_read(struct perf_event *event) +static u64 rvpmu_ctr_read(struct perf_event *event) { struct hw_perf_event *hwc =3D &event->hw; int idx =3D hwc->idx; @@ -882,10 +1027,6 @@ static void rvpmu_sbi_ctr_start(struct perf_event *ev= ent, u64 ival) if (ret.error && (ret.error !=3D SBI_ERR_ALREADY_STARTED)) pr_err("Starting counter idx %d failed with error %d\n", hwc->idx, sbi_err_map_linux_errno(ret.error)); - - if ((hwc->flags & PERF_EVENT_FLAG_USER_ACCESS) && - (hwc->flags & PERF_EVENT_FLAG_USER_READ_CNT)) - rvpmu_set_scounteren((void *)event); } =20 static void rvpmu_sbi_ctr_stop(struct perf_event *event, unsigned long fla= g) @@ -896,10 +1037,6 @@ static void rvpmu_sbi_ctr_stop(struct perf_event *eve= nt, unsigned long flag) struct cpu_hw_events *cpu_hw_evt =3D this_cpu_ptr(pmu->hw_events); struct riscv_pmu_snapshot_data *sdata =3D cpu_hw_evt->snapshot_addr; =20 - if ((hwc->flags & PERF_EVENT_FLAG_USER_ACCESS) && - (hwc->flags & PERF_EVENT_FLAG_USER_READ_CNT)) - rvpmu_reset_scounteren((void *)event); - if (sbi_pmu_snapshot_available()) flag |=3D SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT; =20 @@ -935,12 +1072,6 @@ static int rvpmu_sbi_find_num_ctrs(void) return sbi_err_map_linux_errno(ret.error); } =20 -static u32 rvpmu_deleg_find_ctrs(void) -{ - /* TODO */ - return 0; -} - static int rvpmu_sbi_get_ctrinfo(u32 nsbi_ctr, u32 *num_fw_ctr, u32 *num_h= w_ctr) { struct sbiret ret; @@ -1018,55 +1149,75 @@ static inline void rvpmu_sbi_stop_hw_ctrs(struct ri= scv_pmu *pmu) } } =20 -/* - * This function starts all the used counters in two step approach. - * Any counter that did not overflow can be start in a single step - * while the overflowed counters need to be started with updated initializ= ation - * value. - */ -static inline void rvpmu_sbi_start_ovf_ctrs_sbi(struct cpu_hw_events *cpu_= hw_evt, - u64 ctr_ovf_mask) +static void rvpmu_deleg_ctr_start_mask(unsigned long mask) { - int idx =3D 0, i; - struct perf_event *event; - unsigned long flag =3D SBI_PMU_START_FLAG_SET_INIT_VALUE; - unsigned long ctr_start_mask =3D 0; - uint64_t max_period; - struct hw_perf_event *hwc; - u64 init_val =3D 0; + unsigned long scountinhibit_val =3D 0; =20 - for (i =3D 0; i < BITS_TO_LONGS(RISCV_MAX_COUNTERS); i++) { - ctr_start_mask =3D cpu_hw_evt->used_hw_ctrs[i] & ~ctr_ovf_mask; - /* Start all the counters that did not overflow in a single shot */ - if (ctr_start_mask) { - sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_START, i * BITS_PER_LONG, - ctr_start_mask, 0, 0, 0, 0); - } - } + scountinhibit_val =3D csr_read(CSR_SCOUNTINHIBIT); + scountinhibit_val &=3D ~mask; + + csr_write(CSR_SCOUNTINHIBIT, scountinhibit_val); +} + +static void rvpmu_deleg_ctr_enable_irq(struct perf_event *event) +{ + unsigned long hpmevent_curr; + unsigned long of_mask; + struct hw_perf_event *hwc =3D &event->hw; + int counter_idx =3D hwc->idx; + unsigned long sip_val =3D csr_read(CSR_SIP); + + if (!is_sampling_event(event) || (sip_val & SIP_LCOFIP)) + return; =20 - /* Reinitialize and start all the counter that overflowed */ - while (ctr_ovf_mask) { - if (ctr_ovf_mask & 0x01) { - event =3D cpu_hw_evt->events[idx]; - hwc =3D &event->hw; - max_period =3D riscv_pmu_ctr_get_width_mask(event); - init_val =3D local64_read(&hwc->prev_count) & max_period; #if defined(CONFIG_32BIT) - sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_START, idx, 1, - flag, init_val, init_val >> 32, 0); + hpmevent_curr =3D csr_ind_read(CSR_SIREG5, SISELECT_SSCCFG_BASE, counter_= idx); + of_mask =3D (u32)~HPMEVENTH_OF; #else - sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_START, idx, 1, - flag, init_val, 0, 0); + hpmevent_curr =3D csr_ind_read(CSR_SIREG2, SISELECT_SSCCFG_BASE, counter_= idx); + of_mask =3D ~HPMEVENT_OF; #endif - perf_event_update_userpage(event); - } - ctr_ovf_mask =3D ctr_ovf_mask >> 1; - idx++; - } + + hpmevent_curr &=3D of_mask; +#if defined(CONFIG_32BIT) + csr_ind_write(CSR_SIREG4, SISELECT_SSCCFG_BASE, counter_idx, hpmevent_cur= r); +#else + csr_ind_write(CSR_SIREG2, SISELECT_SSCCFG_BASE, counter_idx, hpmevent_cur= r); +#endif +} + +static void rvpmu_deleg_ctr_start(struct perf_event *event, u64 ival) +{ + unsigned long scountinhibit_val =3D 0; + struct hw_perf_event *hwc =3D &event->hw; + +#if defined(CONFIG_32BIT) + csr_ind_write(CSR_SIREG, SISELECT_SSCCFG_BASE, hwc->idx, ival & 0xFFFFFFF= F); + csr_ind_write(CSR_SIREG4, SISELECT_SSCCFG_BASE, hwc->idx, ival >> BITS_PE= R_LONG); +#else + csr_ind_write(CSR_SIREG, SISELECT_SSCCFG_BASE, hwc->idx, ival); +#endif + + rvpmu_deleg_ctr_enable_irq(event); + + scountinhibit_val =3D csr_read(CSR_SCOUNTINHIBIT); + scountinhibit_val &=3D ~(1 << hwc->idx); + + csr_write(CSR_SCOUNTINHIBIT, scountinhibit_val); +} + +static void rvpmu_deleg_ctr_stop_mask(unsigned long mask) +{ + unsigned long scountinhibit_val =3D 0; + + scountinhibit_val =3D csr_read(CSR_SCOUNTINHIBIT); + scountinhibit_val |=3D mask; + + csr_write(CSR_SCOUNTINHIBIT, scountinhibit_val); } =20 -static inline void rvpmu_sbi_start_ovf_ctrs_snapshot(struct cpu_hw_events = *cpu_hw_evt, - u64 ctr_ovf_mask) +static void rvpmu_sbi_start_ovf_ctrs_snapshot(struct cpu_hw_events *cpu_hw= _evt, + u64 ctr_ovf_mask) { int i, idx =3D 0; struct perf_event *event; @@ -1100,15 +1251,53 @@ static inline void rvpmu_sbi_start_ovf_ctrs_snapsho= t(struct cpu_hw_events *cpu_h } } =20 -static void rvpmu_sbi_start_overflow_mask(struct riscv_pmu *pmu, - u64 ctr_ovf_mask) +/* + * This function starts all the used counters in two step approach. + * Any counter that did not overflow can be start in a single step + * while the overflowed counters need to be started with updated initializ= ation + * value. + */ +static void rvpmu_start_overflow_mask(struct riscv_pmu *pmu, u64 ctr_ovf_m= ask) { + int idx =3D 0, i; + struct perf_event *event; + unsigned long ctr_start_mask =3D 0; + u64 max_period, init_val =3D 0; + struct hw_perf_event *hwc; struct cpu_hw_events *cpu_hw_evt =3D this_cpu_ptr(pmu->hw_events); =20 if (sbi_pmu_snapshot_available()) - rvpmu_sbi_start_ovf_ctrs_snapshot(cpu_hw_evt, ctr_ovf_mask); - else - rvpmu_sbi_start_ovf_ctrs_sbi(cpu_hw_evt, ctr_ovf_mask); + return rvpmu_sbi_start_ovf_ctrs_snapshot(cpu_hw_evt, ctr_ovf_mask); + + /* Start all the counters that did not overflow */ + if (riscv_pmu_cdeleg_available()) { + ctr_start_mask =3D cpu_hw_evt->used_hw_ctrs[0] & ~ctr_ovf_mask; + rvpmu_deleg_ctr_start_mask(ctr_start_mask); + } else { + for (i =3D 0; i < BITS_TO_LONGS(RISCV_MAX_COUNTERS); i++) { + ctr_start_mask =3D cpu_hw_evt->used_hw_ctrs[i] & ~ctr_ovf_mask; + /* Start all the counters that did not overflow in a single shot */ + sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_START, i * BITS_PER_LONG, + ctr_start_mask, 0, 0, 0, 0); + } + } + + /* Reinitialize and start all the counter that overflowed */ + while (ctr_ovf_mask) { + if (ctr_ovf_mask & 0x01) { + event =3D cpu_hw_evt->events[idx]; + hwc =3D &event->hw; + max_period =3D riscv_pmu_ctr_get_width_mask(event); + init_val =3D local64_read(&hwc->prev_count) & max_period; + if (riscv_pmu_cdeleg_available()) + rvpmu_deleg_ctr_start(event, init_val); + else + rvpmu_sbi_ctr_start(event, init_val); + perf_event_update_userpage(event); + } + ctr_ovf_mask =3D ctr_ovf_mask >> 1; + idx++; + } } =20 static irqreturn_t rvpmu_ovf_handler(int irq, void *dev) @@ -1143,10 +1332,18 @@ static irqreturn_t rvpmu_ovf_handler(int irq, void = *dev) } =20 pmu =3D to_riscv_pmu(event->pmu); - rvpmu_sbi_stop_hw_ctrs(pmu); + if (riscv_pmu_cdeleg_available()) + rvpmu_deleg_ctr_stop_mask(cpu_hw_evt->used_hw_ctrs[0]); + else + rvpmu_sbi_stop_hw_ctrs(pmu); =20 - /* Overflow status register should only be read after counter are stopped= */ - if (sbi_pmu_snapshot_available()) + /* + * Overflow status register should only be read after counter are stopped. + * In counter delegation mode the overflows are reported in scountovf, not + * in the SBI snapshot area, so read the CSR directly even when an SBI PMU + * snapshot is also available. + */ + if (sbi_pmu_snapshot_available() && !riscv_pmu_cdeleg_available()) overflow =3D sdata->ctr_overflow_mask; else ALT_SBI_PMU_OVERFLOW(overflow); @@ -1212,25 +1409,182 @@ static irqreturn_t rvpmu_ovf_handler(int irq, void= *dev) hw_evt->state =3D 0; } =20 - rvpmu_sbi_start_overflow_mask(pmu, overflowed_ctrs); + rvpmu_start_overflow_mask(pmu, overflowed_ctrs); perf_sample_event_took(sched_clock() - start_clock); =20 return IRQ_HANDLED; } =20 +static int get_deleg_hw_ctr_width(int counter_offset) +{ + unsigned long hpm_warl; + int num_bits; + + if (counter_offset < 3 || counter_offset > 31) + return 0; + + hpm_warl =3D csr_ind_warl(CSR_SIREG, SISELECT_SSCCFG_BASE, counter_offset= , -1); + num_bits =3D __fls(hpm_warl); + +#if defined(CONFIG_32BIT) + /* + * The low half contributes a full BITS_PER_LONG bits when the counter is + * wider than 32 bits; the high half's __fls() gives the remaining width. + */ + hpm_warl =3D csr_ind_warl(CSR_SIREG4, SISELECT_SSCCFG_BASE, counter_offse= t, -1); + if (hpm_warl) + num_bits =3D BITS_PER_LONG + __fls(hpm_warl); +#endif + return num_bits; +} + +static int rvpmu_deleg_find_ctrs(void) +{ + int i, num_hw_ctr =3D 0; + union sbi_pmu_ctr_info cinfo; + unsigned long scountinhibit_old =3D 0; + + /* Do a WARL write/read to detect which hpmcounters have been delegated */ + scountinhibit_old =3D csr_read(CSR_SCOUNTINHIBIT); + csr_write(CSR_SCOUNTINHIBIT, -1); + cmask =3D csr_read(CSR_SCOUNTINHIBIT); + + csr_write(CSR_SCOUNTINHIBIT, scountinhibit_old); + + for_each_set_bit(i, &cmask, RISCV_MAX_HW_COUNTERS) { + if (unlikely(i =3D=3D 1)) + continue; /* This should never happen as TM is read only */ + cinfo.value =3D 0; + cinfo.type =3D SBI_PMU_CTR_TYPE_HW; + /* + * If counter delegation is enabled, the csr stored to the cinfo will + * be a virtual counter that the delegation attempts to read. + */ + cinfo.csr =3D CSR_CYCLE + i; + if (i =3D=3D 0 || i =3D=3D 2) + cinfo.width =3D 63; + else + cinfo.width =3D get_deleg_hw_ctr_width(i); + + num_hw_ctr++; + pmu_ctr_list[i].value =3D cinfo.value; + } + + return num_hw_ctr; +} + +static int get_deleg_fixed_hw_idx(struct cpu_hw_events *cpuc, struct perf_= event *event) +{ + return -EINVAL; +} + +static int get_deleg_next_hpm_hw_idx(struct cpu_hw_events *cpuc, struct pe= rf_event *event) +{ + unsigned long hw_ctr_mask =3D 0; + + /* + * TODO: Treat every hpmcounter can monitor every event for now. + * The event to counter mapping should come from the json file. + * The mapping should also tell if sampling is supported or not. + */ + + /* Select only hpmcounters */ + hw_ctr_mask =3D cmask & (~0x7); + hw_ctr_mask &=3D ~(cpuc->used_hw_ctrs[0]); + return __ffs(hw_ctr_mask); +} + +static void update_deleg_hpmevent(int counter_idx, uint64_t event_value, u= int64_t filter_bits) +{ + u64 hpmevent_value =3D 0; + + /* OF bit should be enable during the start if sampling is requested */ + hpmevent_value =3D (event_value & ~HPMEVENT_MASK) | filter_bits | HPMEVEN= T_OF; +#if defined(CONFIG_32BIT) + csr_ind_write(CSR_SIREG2, SISELECT_SSCCFG_BASE, counter_idx, hpmevent_val= ue & 0xFFFFFFFF); + if (riscv_isa_extension_available(NULL, SSCOFPMF)) + csr_ind_write(CSR_SIREG5, SISELECT_SSCCFG_BASE, counter_idx, + hpmevent_value >> BITS_PER_LONG); +#else + csr_ind_write(CSR_SIREG2, SISELECT_SSCCFG_BASE, counter_idx, hpmevent_val= ue); +#endif +} + +static int rvpmu_deleg_ctr_get_idx(struct perf_event *event) +{ + struct hw_perf_event *hwc =3D &event->hw; + struct riscv_pmu *rvpmu =3D to_riscv_pmu(event->pmu); + struct cpu_hw_events *cpuc =3D this_cpu_ptr(rvpmu->hw_events); + unsigned long hw_ctr_max_id; + u64 priv_filter; + int idx; + + /* + * TODO: We should not rely on SBI Perf encoding to check if the event + * is a fixed one or not. + */ + if (!is_sampling_event(event)) { + idx =3D get_deleg_fixed_hw_idx(cpuc, event); + if (idx =3D=3D 0 || idx =3D=3D 2) { + /* Priv mode filter bits are only available if smcntrpmf is present */ + if (riscv_isa_extension_available(NULL, SMCNTRPMF)) + goto found_idx; + else + goto skip_update; + } + } + + hw_ctr_max_id =3D __fls(cmask); + idx =3D get_deleg_next_hpm_hw_idx(cpuc, event); + if (idx < 3 || idx > hw_ctr_max_id) + goto out_err; +found_idx: + priv_filter =3D get_deleg_priv_filter_bits(event); + update_deleg_hpmevent(idx, hwc->config, priv_filter); +skip_update: + if (!test_and_set_bit(idx, cpuc->used_hw_ctrs)) + return idx; +out_err: + return -ENOENT; +} + static void rvpmu_ctr_start(struct perf_event *event, u64 ival) { - rvpmu_sbi_ctr_start(event, ival); - /* TODO: Counter delegation implementation */ + struct hw_perf_event *hwc =3D &event->hw; + + if (riscv_pmu_cdeleg_available() && !pmu_sbi_is_fw_event(event)) + rvpmu_deleg_ctr_start(event, ival); + else + rvpmu_sbi_ctr_start(event, ival); + + if ((hwc->flags & PERF_EVENT_FLAG_USER_ACCESS) && + (hwc->flags & PERF_EVENT_FLAG_USER_READ_CNT)) + rvpmu_set_scounteren((void *)event); } =20 static void rvpmu_ctr_stop(struct perf_event *event, unsigned long flag) { - rvpmu_sbi_ctr_stop(event, flag); - /* TODO: Counter delegation implementation */ + struct hw_perf_event *hwc =3D &event->hw; + + if ((hwc->flags & PERF_EVENT_FLAG_USER_ACCESS) && + (hwc->flags & PERF_EVENT_FLAG_USER_READ_CNT)) + rvpmu_reset_scounteren((void *)event); + + if (riscv_pmu_cdeleg_available() && !pmu_sbi_is_fw_event(event)) { + /* + * The counter is already stopped. No need to stop again. Counter + * mapping will be reset in clear_idx function. + */ + if (flag !=3D RISCV_PMU_STOP_FLAG_RESET) + rvpmu_deleg_ctr_stop_mask((1 << hwc->idx)); + else + update_deleg_hpmevent(hwc->idx, 0, 0); + } else { + rvpmu_sbi_ctr_stop(event, flag); + } } =20 -static int rvpmu_find_ctrs(void) +static u32 rvpmu_find_ctrs(void) { u32 num_sbi_counters =3D 0, num_deleg_counters =3D 0; u32 num_hw_ctr =3D 0, num_fw_ctr =3D 0, num_ctr =3D 0; @@ -1270,20 +1624,18 @@ static int rvpmu_find_ctrs(void) =20 static int rvpmu_event_map(struct perf_event *event, u64 *econfig) { - return rvpmu_sbi_event_map(event, econfig); - /* TODO: Counter delegation implementation */ + if (riscv_pmu_cdeleg_available() && !pmu_sbi_is_fw_event(event)) + return rvpmu_cdeleg_event_map(event, econfig); + else + return rvpmu_sbi_event_map(event, econfig); } =20 static int rvpmu_ctr_get_idx(struct perf_event *event) { - return rvpmu_sbi_ctr_get_idx(event); - /* TODO: Counter delegation implementation */ -} - -static u64 rvpmu_ctr_read(struct perf_event *event) -{ - return rvpmu_sbi_ctr_read(event); - /* TODO: Counter delegation implementation */ + if (riscv_pmu_cdeleg_available() && !pmu_sbi_is_fw_event(event)) + return rvpmu_deleg_ctr_get_idx(event); + else + return rvpmu_sbi_ctr_get_idx(event); } =20 static int rvpmu_starting_cpu(unsigned int cpu, struct hlist_node *node) @@ -1301,7 +1653,16 @@ static int rvpmu_starting_cpu(unsigned int cpu, stru= ct hlist_node *node) csr_write(CSR_SCOUNTEREN, 0x2); =20 /* Stop all the counters so that they can be enabled from perf */ - rvpmu_sbi_stop_all(pmu); + if (riscv_pmu_cdeleg_available()) { + rvpmu_deleg_ctr_stop_mask(cmask); + if (riscv_pmu_sbi_available()) { + /* Stop the firmware counters as well */ + sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_STOP, 0, firmware_cmask, + 0, 0, 0, 0); + } + } else { + rvpmu_sbi_stop_all(pmu); + } =20 if (riscv_pmu_use_irq) { cpu_hw_evt->irq =3D riscv_pmu_irq; @@ -1600,8 +1961,11 @@ static int rvpmu_device_probe(struct platform_device= *pdev) pmu->pmu.capabilities |=3D PERF_PMU_CAP_NO_EXCLUDE; } =20 - pmu->pmu.attr_groups =3D riscv_pmu_attr_groups; pmu->pmu.parent =3D &pdev->dev; + if (riscv_pmu_cdeleg_available_boot()) + pmu->pmu.attr_groups =3D riscv_cdeleg_pmu_attr_groups; + else + pmu->pmu.attr_groups =3D riscv_sbi_pmu_attr_groups; pmu->cmask =3D cmask; pmu->ctr_start =3D rvpmu_ctr_start; pmu->ctr_stop =3D rvpmu_ctr_stop; diff --git a/include/linux/perf/riscv_pmu.h b/include/linux/perf/riscv_pmu.h index 6c75106989b6..f6a710c83a4c 100644 --- a/include/linux/perf/riscv_pmu.h +++ b/include/linux/perf/riscv_pmu.h @@ -20,6 +20,7 @@ */ =20 #define RISCV_MAX_COUNTERS 64 +#define RISCV_MAX_HW_COUNTERS 32 #define RISCV_OP_UNSUPP (-EOPNOTSUPP) #define RISCV_PMU_SBI_PDEV_NAME "riscv-pmu-sbi" #define RISCV_PMU_LEGACY_PDEV_NAME "riscv-pmu-legacy" @@ -28,6 +29,8 @@ =20 #define RISCV_PMU_CONFIG1_GUEST_EVENTS 0x1 =20 +#define RISCV_PMU_DELEG_RAW_EVENT_MASK GENMASK_ULL(55, 0) + #define HW_OP_UNSUPPORTED 0xFFFF #define CACHE_OP_UNSUPPORTED 0xFFFF =20 --=20 2.53.0-Meta From nobody Sat Jun 13 15:24:19 2026 Received: from out-171.mta0.migadu.com (out-171.mta0.migadu.com [91.218.175.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DC8363CF695 for ; Tue, 9 Jun 2026 06:02:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984967; cv=none; b=QZL4dRm/mkYF+BBD1+DbCPS6XjE84nfejaAsjfTgGU1Ctj6SikmcZAB6WR/apKQFyxsG/2wKE9wQ+xQLeBFf3GQ9BkFZxgMVbvTotdvvuX0xCwKa0F4YxbKONWKiH+6YikyZBcLmgbNybvOO+axsioCbeRkHlDE3QVGG04nJNBU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984967; c=relaxed/simple; bh=6eZbdU9r01O5U5cRm3lfBtUDAYJFjIGr572PLFh0R2o=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=LELbwO+1rG4dcFWdBq0spjVbhjEkXBt95gzMokyEyOs8rQUdXa5B8gVBFPCGuR77K2A50AIyHCvI385UvEEmymqPyishdjJvIlaNh9IVLN503WkugNB/sMqLdq6kkBFmXw0XVxoDj5WUkBO3pocXRxH03WqfiOh0cMoAumpTpP4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=jCjDz6SV; arc=none smtp.client-ip=91.218.175.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="jCjDz6SV" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1780984963; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=O1z/SRTOq77wAaiCHEBuev51rOxTNht3QVh4Cw0HEOc=; b=jCjDz6SVbqt1iFak016WIHhEhWUYY1Ntq9uNSAFshLgBB1QMxE46zOIGO1IDOlzq4ljGSV RB6Zb8r9VIIei0ry7myIiFXQtsDMiiTihsUFcDaeDapkoaeH1xLKSXV2DfPl30CkKTw1q3 LWwjKbJhA1NqXMhcm8jentvBSk/tKXo= From: Atish Patra Date: Mon, 08 Jun 2026 23:01:28 -0700 Subject: [PATCH v6 14/21] RISC-V: perf: Skip PMU SBI extension when not implemented Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260608-counter_delegation-v6-14-285b72ed65a9@meta.com> References: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> In-Reply-To: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> To: James Clark , Rob Herring , Atish Patra , Arnaldo Carvalho de Melo , Jiri Olsa , Will Deacon , Mark Rutland , Anup Patel , Namhyung Kim , Paul Walmsley , Krzysztof Kozlowski , Ian Rogers Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Conor Dooley , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org X-Migadu-Flow: FLOW_OUT From: Charlie Jenkins When the PMU SBI extension is not implemented, sbi_v2_available should not be set to true. The SBI implementation for counter config matching and firmware counter read should also be skipped when the SBI extension is not implemented. Signed-off-by: Atish Patra Signed-off-by: Charlie Jenkins --- drivers/perf/riscv_pmu_sbi.c | 48 ++++++++++++++++++++++++++--------------= ---- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c index 1f16df9d0dd0..5bfcd3821f57 100644 --- a/drivers/perf/riscv_pmu_sbi.c +++ b/drivers/perf/riscv_pmu_sbi.c @@ -479,27 +479,31 @@ static void rvpmu_sbi_check_event(struct sbi_pmu_even= t_data *edata) } } =20 -static void rvpmu_sbi_check_std_events(struct work_struct *work) +static void rvpmu_check_std_events(struct work_struct *work) { int ret; =20 - if (sbi_v3_available) { - ret =3D pmu_sbi_check_event_info(); - if (ret) - pr_err("pmu_sbi_check_event_info failed with error %d\n", ret); - return; - } + if (riscv_pmu_sbi_available()) { + if (sbi_v3_available) { + ret =3D pmu_sbi_check_event_info(); + if (ret) + pr_err("pmu_sbi_check_event_info failed with error %d\n", ret); + return; + } =20 - for (int i =3D 0; i < ARRAY_SIZE(pmu_hw_event_sbi_map); i++) - rvpmu_sbi_check_event(&pmu_hw_event_sbi_map[i]); + for (int i =3D 0; i < ARRAY_SIZE(pmu_hw_event_sbi_map); i++) + rvpmu_sbi_check_event(&pmu_hw_event_sbi_map[i]); =20 - for (int i =3D 0; i < ARRAY_SIZE(pmu_cache_event_sbi_map); i++) - for (int j =3D 0; j < ARRAY_SIZE(pmu_cache_event_sbi_map[i]); j++) - for (int k =3D 0; k < ARRAY_SIZE(pmu_cache_event_sbi_map[i][j]); k++) - rvpmu_sbi_check_event(&pmu_cache_event_sbi_map[i][j][k]); + for (int i =3D 0; i < ARRAY_SIZE(pmu_cache_event_sbi_map); i++) + for (int j =3D 0; j < ARRAY_SIZE(pmu_cache_event_sbi_map[i]); j++) + for (int k =3D 0; k < ARRAY_SIZE(pmu_cache_event_sbi_map[i][j]); k++) + rvpmu_sbi_check_event(&pmu_cache_event_sbi_map[i][j][k]); + } else { + DO_ONCE_LITE_IF(1, pr_info, "Boot time config matching not required for = smcdeleg\n"); + } } =20 -static DECLARE_WORK(check_std_events_work, rvpmu_sbi_check_std_events); +static DECLARE_WORK(check_std_events_work, rvpmu_check_std_events); =20 static ssize_t rvpmu_format_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -692,6 +696,9 @@ static int rvpmu_sbi_ctr_get_idx(struct perf_event *eve= nt) =20 cflags =3D rvpmu_sbi_get_filter_flags(event); =20 + if (!riscv_pmu_sbi_available()) + return -ENOENT; + /* * In legacy mode, we have to force the fixed counters for those events * but not in the user access mode as we want to use the other counters @@ -967,7 +974,7 @@ static u64 rvpmu_ctr_read(struct perf_event *event) return val; } =20 - if (pmu_sbi_is_fw_event(event)) { + if (pmu_sbi_is_fw_event(event) && riscv_pmu_sbi_available()) { ret =3D sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_FW_READ, hwc->idx, 0, 0, 0, 0, 0); if (ret.error) @@ -2045,12 +2052,13 @@ static int __init rvpmu_devinit(void) int ret; struct platform_device *pdev; =20 - if (sbi_spec_version >=3D sbi_mk_version(0, 3) && - sbi_probe_extension(SBI_EXT_PMU)) - static_branch_enable(&riscv_pmu_sbi_available); + if (sbi_probe_extension(SBI_EXT_PMU)) { + if (sbi_spec_version >=3D sbi_mk_version(0, 3)) + static_branch_enable(&riscv_pmu_sbi_available); + if (sbi_spec_version >=3D sbi_mk_version(2, 0)) + sbi_v2_available =3D true; + } =20 - if (sbi_spec_version >=3D sbi_mk_version(2, 0)) - sbi_v2_available =3D true; /* * We need all three extensions to be present to access the counters * in S-mode via Supervisor Counter delegation. --=20 2.53.0-Meta From nobody Sat Jun 13 15:24:19 2026 Received: from out-180.mta1.migadu.com (out-180.mta1.migadu.com [95.215.58.180]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B2FC63D332B for ; Tue, 9 Jun 2026 06:02:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984971; cv=none; b=aS5OI8lGzfAhg7fOCBZ8Y8iTjhE4bmbnqAlwwtPJOu1WbRKN94OkmbB3OgYc8UkxJI22exALBGe3J4dl5tb9++2TmW0tJgrAVdTYaK1dQu6bvwt0GchOP9Q61YeNAXipImVOdmnWpXAo+spctkeVTbqB92+V2DI1qxf7KxMYaMc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984971; c=relaxed/simple; bh=a2/nxaZY8U0qpxrtvqbdJ8quGuEwBrzaoRnQVPeEQZ0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dCkgLolzHZ8dyMTU5kvhONfseFVMuHiVgY97iTzJnP7iuocLtxy4FSpQT0wuD1ByD8/EBi89ALox282LutYboKdPUf8FV5Gw/nkmid0wuP4bpUfl3eV/R9pVS/3yB6LE44y/xCDynOxTZ2I30qraetubGMBGezuF/SjZLhq+M5E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=Qujoi4g+; arc=none smtp.client-ip=95.215.58.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="Qujoi4g+" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1780984967; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=nYwOg3xzzJ1xkjPHiCCBV9Leo3HRwljOW68csu9Byzs=; b=Qujoi4g+vT6bPokPwyYQmNVIIl8pnWS/KScH7W9dvSqvkSltJKq09HpK1gpdBXGlrbd2pr NApCP2Pfk/HgQp0sCslatu48VMeiOIlksRxu6Q06uOn16Ml7Uti95EoDENPR/WYPNyumSz AY1zPC47yN12tnR540knXSgNs5S16b4= From: Atish Patra Date: Mon, 08 Jun 2026 23:01:29 -0700 Subject: [PATCH v6 15/21] RISC-V: perf: Use config2/vendor table for event to counter mapping Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260608-counter_delegation-v6-15-285b72ed65a9@meta.com> References: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> In-Reply-To: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> To: James Clark , Rob Herring , Atish Patra , Arnaldo Carvalho de Melo , Jiri Olsa , Will Deacon , Mark Rutland , Anup Patel , Namhyung Kim , Paul Walmsley , Krzysztof Kozlowski , Ian Rogers Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Conor Dooley , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org X-Migadu-Flow: FLOW_OUT From: Atish Patra The counter restriction specified in the json file is passed to the drivers via config2 paarameter in perf attributes. This allows any platform vendor to define their custom mapping between event and hpmcounters without any rules defined in the ISA. For legacy events, the platform vendor may define the mapping in the driver in the vendor event table. The fixed cycle and instruction counters are fixed (0 and 2 respectively) by the ISA and maps to the legacy events. The platform vendor must specify this in the driver if intended to be used while profiling. Otherwise, they can just specify the alternate hpmcounters that may monitor and/or sample the cycle/instruction counts. Signed-off-by: Atish Patra --- drivers/perf/riscv_pmu_sbi.c | 90 ++++++++++++++++++++++++++++++++++----= ---- include/linux/perf/riscv_pmu.h | 2 + 2 files changed, 76 insertions(+), 16 deletions(-) diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c index 5bfcd3821f57..4b4f151a0744 100644 --- a/drivers/perf/riscv_pmu_sbi.c +++ b/drivers/perf/riscv_pmu_sbi.c @@ -76,6 +76,7 @@ static ssize_t __maybe_unused rvpmu_format_show(struct de= vice *dev, struct devic RVPMU_ATTR_ENTRY(_name, rvpmu_format_show, (char *)_config) =20 PMU_FORMAT_ATTR(firmware, "config:62-63"); +PMU_FORMAT_ATTR(counterid_mask, "config2:0-31"); =20 static bool sbi_v2_available; static bool sbi_v3_available; @@ -120,6 +121,7 @@ static const struct attribute_group *riscv_sbi_pmu_attr= _groups[] =3D { static struct attribute *riscv_cdeleg_pmu_formats_attr[] =3D { RVPMU_FORMAT_ATTR_ENTRY(event, RVPMU_CDELEG_PMU_FORMAT_ATTR), &format_attr_firmware.attr, + &format_attr_counterid_mask.attr, NULL, }; =20 @@ -1480,24 +1482,80 @@ static int rvpmu_deleg_find_ctrs(void) return num_hw_ctr; } =20 +/* + * The json file must correctly specify counter 0 or counter 2 is available + * in the counter lists for cycle/instret events. Otherwise, the drivers h= ave + * no way to figure out if a fixed counter must be used and pick a program= mable + * counter if available. + */ static int get_deleg_fixed_hw_idx(struct cpu_hw_events *cpuc, struct perf_= event *event) { - return -EINVAL; + struct hw_perf_event *hwc =3D &event->hw; + bool guest_events =3D event->attr.config1 & RISCV_PMU_CONFIG1_GUEST_EVENT= S; + + if (guest_events) { + if (hwc->event_base =3D=3D SBI_PMU_HW_CPU_CYCLES) + return 0; + if (hwc->event_base =3D=3D SBI_PMU_HW_INSTRUCTIONS) + return 2; + else + return -EINVAL; + } + + if (!event->attr.config2) + return -EINVAL; + + if (event->attr.config2 & RISCV_PMU_CYCLE_FIXED_CTR_MASK) + return 0; /* CY counter */ + else if (event->attr.config2 & RISCV_PMU_INSTRUCTION_FIXED_CTR_MASK) + return 2; /* IR counter */ + else + return -EINVAL; } =20 static int get_deleg_next_hpm_hw_idx(struct cpu_hw_events *cpuc, struct pe= rf_event *event) { - unsigned long hw_ctr_mask =3D 0; + u32 hw_ctr_mask =3D 0, temp_mask =3D 0; + u32 type =3D event->attr.type; + u64 config =3D event->attr.config; + int ret; =20 - /* - * TODO: Treat every hpmcounter can monitor every event for now. - * The event to counter mapping should come from the json file. - * The mapping should also tell if sampling is supported or not. - */ + /* Select only available hpmcounters */ + hw_ctr_mask =3D cmask & (~0x7) & ~(cpuc->used_hw_ctrs[0]); + + switch (type) { + case PERF_TYPE_HARDWARE: + temp_mask =3D current_pmu_hw_event_map[config].counter_mask; + break; + case PERF_TYPE_HW_CACHE: + ret =3D cdeleg_pmu_event_find_cache(config, NULL, &temp_mask); + if (ret) + return ret; + break; + case PERF_TYPE_RAW: + /* + * Mask off the counters that can't monitor this event (specified via js= on) + * The counter mask for this event is set in config2 via the property 'C= ounter' + * in the json file or manual configuration of config2. If the config2 i= s not set, + * it is assumed all the available hpmcounters can monitor this event. + * Note: This assumption may fail for virtualization use case where they= hypervisor + * (e.g. KVM) virtualizes the counter. Any event to counter mapping prov= ided by the + * guest is meaningless from a hypervisor perspective. Thus, the hypervi= sor doesn't + * set config2 when creating kernel counter and relies default host mapp= ing. + */ + if (event->attr.config2) + temp_mask =3D event->attr.config2; + break; + default: + break; + } + + if (temp_mask) + hw_ctr_mask &=3D temp_mask; + + if (!hw_ctr_mask) + return -EINVAL; =20 - /* Select only hpmcounters */ - hw_ctr_mask =3D cmask & (~0x7); - hw_ctr_mask &=3D ~(cpuc->used_hw_ctrs[0]); return __ffs(hw_ctr_mask); } =20 @@ -1526,10 +1584,6 @@ static int rvpmu_deleg_ctr_get_idx(struct perf_event= *event) u64 priv_filter; int idx; =20 - /* - * TODO: We should not rely on SBI Perf encoding to check if the event - * is a fixed one or not. - */ if (!is_sampling_event(event)) { idx =3D get_deleg_fixed_hw_idx(cpuc, event); if (idx =3D=3D 0 || idx =3D=3D 2) { @@ -1547,10 +1601,14 @@ static int rvpmu_deleg_ctr_get_idx(struct perf_even= t *event) goto out_err; found_idx: priv_filter =3D get_deleg_priv_filter_bits(event); + if (test_and_set_bit(idx, cpuc->used_hw_ctrs)) + goto out_err; update_deleg_hpmevent(idx, hwc->config, priv_filter); + return idx; skip_update: - if (!test_and_set_bit(idx, cpuc->used_hw_ctrs)) - return idx; + if (test_and_set_bit(idx, cpuc->used_hw_ctrs)) + goto out_err; + return idx; out_err: return -ENOENT; } diff --git a/include/linux/perf/riscv_pmu.h b/include/linux/perf/riscv_pmu.h index f6a710c83a4c..06171e7aadfb 100644 --- a/include/linux/perf/riscv_pmu.h +++ b/include/linux/perf/riscv_pmu.h @@ -30,6 +30,8 @@ #define RISCV_PMU_CONFIG1_GUEST_EVENTS 0x1 =20 #define RISCV_PMU_DELEG_RAW_EVENT_MASK GENMASK_ULL(55, 0) +#define RISCV_PMU_CYCLE_FIXED_CTR_MASK 0x01 +#define RISCV_PMU_INSTRUCTION_FIXED_CTR_MASK 0x04 =20 #define HW_OP_UNSUPPORTED 0xFFFF #define CACHE_OP_UNSUPPORTED 0xFFFF --=20 2.53.0-Meta From nobody Sat Jun 13 15:24:19 2026 Received: from out-177.mta1.migadu.com (out-177.mta1.migadu.com [95.215.58.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 293173CF1F8 for ; Tue, 9 Jun 2026 06:02:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.177 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984979; cv=none; b=KTSmnMkqv2TWyPR4ZzB0bpZe/niAVE+Zn7X3HtdI3xQcg7/Gzez9o+/O4iAP7S7dMeAI8DCIjHfMlnn6xCUt784tSiW57q4FCVBUUoBkwSbqaUhvZvtOMLclaVAyGLs8+2A/w24efSbrpfs5bGBFcC+VJg0broWEbkwcnshamM8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984979; c=relaxed/simple; bh=BHR1e41gLgqpbFojagMPR+XYPEIf8v0+NW6a44ZbZ30=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=hKYV0eyyHnjfgoGo1T19DAE/fwoFb3fOF3DUk8e37x3vN324tbhFAuT6lXXAOEwNdNaFndfO/NO0IA5VKCNTWGsmdq/W0/ligDewJutRC2SJ5lZe5kqLTMQK5Yq3Lg7vxeWz2nN1iLzutRXUa6K6KL5pAjVgfn3N5VC0lh7jmR8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=jJMKX5yr; arc=none smtp.client-ip=95.215.58.177 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="jJMKX5yr" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1780984976; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=RGfvtqtSRbm7XGzyftXzdD+Hm1sGp6DXlZOLRoWzqRc=; b=jJMKX5yrw/cwx9QtPhqnZ+n4EiNXOfSqMtPQv9vMXU+DV9bi6XUTl5OK1b8ohNarRld1IE sXa6gXC3eAflOi3OUXWjKoQHHv67bsKv9GBRxlQ3aSCOh2qtyekJrVdpNWKeANP57GRRja QxltgqWzzUj1hjelrx9nKTbRhendWUE= From: Atish Patra Date: Mon, 08 Jun 2026 23:01:30 -0700 Subject: [PATCH v6 16/21] RISC-V: perf: Add legacy event encodings via sysfs Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260608-counter_delegation-v6-16-285b72ed65a9@meta.com> References: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> In-Reply-To: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> To: James Clark , Rob Herring , Atish Patra , Arnaldo Carvalho de Melo , Jiri Olsa , Will Deacon , Mark Rutland , Anup Patel , Namhyung Kim , Paul Walmsley , Krzysztof Kozlowski , Ian Rogers Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Conor Dooley , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org X-Migadu-Flow: FLOW_OUT From: Atish Patra Define sysfs details for the legacy events so that any tool can parse these to understand the minimum set of legacy events supported by the platform. The sysfs entry will describe both event encoding and corresponding counter map so that an perf event can be programmed accordingly. Signed-off-by: Atish Patra --- drivers/perf/riscv_pmu_sbi.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c index 4b4f151a0744..00b84b28117a 100644 --- a/drivers/perf/riscv_pmu_sbi.c +++ b/drivers/perf/riscv_pmu_sbi.c @@ -130,7 +130,20 @@ static struct attribute_group riscv_cdeleg_pmu_format_= group =3D { .attrs =3D riscv_cdeleg_pmu_formats_attr, }; =20 +#define RVPMU_EVENT_ATTR_RESOLVE(m) #m +#define RVPMU_EVENT_CMASK_ATTR(_name, _var, config, mask) \ + PMU_EVENT_ATTR_STRING(_name, rvpmu_event_attr_##_var, \ + "event=3D" RVPMU_EVENT_ATTR_RESOLVE(config) \ + ",counterid_mask=3D" RVPMU_EVENT_ATTR_RESOLVE(mask)) + +#define RVPMU_EVENT_ATTR_PTR(name) (&rvpmu_event_attr_##name.attr.attr) + +static struct attribute_group riscv_cdeleg_pmu_event_group __ro_after_init= =3D { + .name =3D "events", +}; + static const struct attribute_group *riscv_cdeleg_pmu_attr_groups[] =3D { + &riscv_cdeleg_pmu_event_group, &riscv_cdeleg_pmu_format_group, NULL, }; @@ -431,11 +444,14 @@ struct riscv_vendor_pmu_events { const struct riscv_pmu_event *hw_event_map; const struct riscv_pmu_event (*cache_event_map)[PERF_COUNT_HW_CACHE_OP_MA= X] [PERF_COUNT_HW_CACHE_RESULT_MAX]; + struct attribute **attrs_events; }; =20 -#define RISCV_VENDOR_PMU_EVENTS(_vendorid, _archid, _implid, _hw_event_map= , _cache_event_map) \ +#define RISCV_VENDOR_PMU_EVENTS(_vendorid, _archid, _implid, _hw_event_map= , \ + _cache_event_map, _attrs) \ { .vendorid =3D _vendorid, .archid =3D _archid, .implid =3D _implid, \ - .hw_event_map =3D _hw_event_map, .cache_event_map =3D _cache_event_map = }, + .hw_event_map =3D _hw_event_map, .cache_event_map =3D _cache_event_map,= \ + .attrs_events =3D _attrs }, =20 static struct riscv_vendor_pmu_events pmu_vendor_events_table[] =3D { }; @@ -457,6 +473,8 @@ static void rvpmu_vendor_register_events(void) pmu_vendor_events_table[i].archid =3D=3D arch_id) { current_pmu_hw_event_map =3D pmu_vendor_events_table[i].hw_event_map; current_pmu_cache_event_map =3D pmu_vendor_events_table[i].cache_event_= map; + riscv_cdeleg_pmu_event_group.attrs =3D + pmu_vendor_events_table[i].attrs_events; break; } } --=20 2.53.0-Meta From nobody Sat Jun 13 15:24:19 2026 Received: from out-182.mta0.migadu.com (out-182.mta0.migadu.com [91.218.175.182]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2483C3CF1F8 for ; Tue, 9 Jun 2026 06:03:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984983; cv=none; b=TQQH4Mb1gR4Nj8Bo3A2Iw3HsbesSrK9wI5pHJmjHbH2+m0T665m5/X1Hjl4NEbWIm/3ohbnwWsi6cbNw1DcpgxVtFB5shfkzjapMNK24FiE2coNDy+j9r/V82Y7dh+fwYgvjHQbmB9VT6BXfu8CYpXYtjeUTy7OarXDzSMl6Ozg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984983; c=relaxed/simple; bh=QbBaPxT7s1b1jPzeD+iq8/WvKXssXMLH2iRDqE6W1jU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=iObF5T0Fh3yzwdIZfy+RAN0yylgt/lbGSoLxEnWjpZPHGS+IQL3A9ALpfPeKYsh3anV3xlkYVrd1Cnq3etsAEdw6VQKWIzYgkFVMxdUSPPOd2Z98NClagRbaasnls+l3nOqUT1c/8I5ohTtWHDZINuK4x9U7vunzvQ31u0SEZF8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=c+wlLUuL; arc=none smtp.client-ip=91.218.175.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="c+wlLUuL" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1780984979; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=vK22QclrqWlVFeZAaMKoG1n2ghTct2ZGDhzycPW76SU=; b=c+wlLUuLeYT4LaPrrtD13kT1vCjCloRJAI52hQ2yeRHUOMX6/jz4Gq9+sh92uY6inm5Xa5 OHM0yAshy839ZaMjpx8j15pP5pdDxEhB8bH8Q0Vy7VXs+BbGJ53mjPs3HGHEx9gUv/XAFD ahb+18TmkqmTI6oXvkOCqeDVa+mh1fc= From: Atish Patra Date: Mon, 08 Jun 2026 23:01:31 -0700 Subject: [PATCH v6 17/21] RISC-V: perf: Add Qemu virt machine events Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260608-counter_delegation-v6-17-285b72ed65a9@meta.com> References: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> In-Reply-To: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> To: James Clark , Rob Herring , Atish Patra , Arnaldo Carvalho de Melo , Jiri Olsa , Will Deacon , Mark Rutland , Anup Patel , Namhyung Kim , Paul Walmsley , Krzysztof Kozlowski , Ian Rogers Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Conor Dooley , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org X-Migadu-Flow: FLOW_OUT From: Atish Patra Qemu virt machine supports a very minimal set of legacy perf events. Add them to the vendor table so that users can use them when counter delegation is enabled. Signed-off-by: Atish Patra --- arch/riscv/include/asm/vendorid_list.h | 4 ++++ drivers/perf/riscv_pmu_sbi.c | 36 ++++++++++++++++++++++++++++++= ++++ 2 files changed, 40 insertions(+) diff --git a/arch/riscv/include/asm/vendorid_list.h b/arch/riscv/include/as= m/vendorid_list.h index 7f5030ee1fcf..603aa2b21c0b 100644 --- a/arch/riscv/include/asm/vendorid_list.h +++ b/arch/riscv/include/asm/vendorid_list.h @@ -11,4 +11,8 @@ #define SIFIVE_VENDOR_ID 0x489 #define THEAD_VENDOR_ID 0x5b7 =20 +#define QEMU_VIRT_VENDOR_ID 0x000 +#define QEMU_VIRT_IMPL_ID 0x000 +#define QEMU_VIRT_ARCH_ID 0x000 + #endif diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c index 00b84b28117a..74acac54328e 100644 --- a/drivers/perf/riscv_pmu_sbi.c +++ b/drivers/perf/riscv_pmu_sbi.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -453,7 +454,42 @@ struct riscv_vendor_pmu_events { .hw_event_map =3D _hw_event_map, .cache_event_map =3D _cache_event_map,= \ .attrs_events =3D _attrs }, =20 +/* QEMU virt PMU events */ +static const struct riscv_pmu_event qemu_virt_hw_event_map[PERF_COUNT_HW_M= AX] =3D { + PERF_MAP_ALL_UNSUPPORTED, + [PERF_COUNT_HW_CPU_CYCLES] =3D {0x01, 0xFFFFFFF8}, + [PERF_COUNT_HW_INSTRUCTIONS] =3D {0x02, 0xFFFFFFF8} +}; + +static const struct riscv_pmu_event qemu_virt_cache_event_map[PERF_COUNT_H= W_CACHE_MAX] + [PERF_COUNT_HW_CACHE_OP_MAX] + [PERF_COUNT_HW_CACHE_RESULT_MAX] =3D { + PERF_CACHE_MAP_ALL_UNSUPPORTED, + [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] =3D {0x10019, 0xFFFFFFF8}, + [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] =3D {0x1001B, 0xFFFFFFF8}, + + [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] =3D {0x10021, 0xFFFFFFF8}, +}; + +RVPMU_EVENT_CMASK_ATTR(cycles, cycles, 0x01, 0xFFFFFFF8); +RVPMU_EVENT_CMASK_ATTR(instructions, instructions, 0x02, 0xFFFFFFF8); +RVPMU_EVENT_CMASK_ATTR(dTLB-load-misses, dTLB_load_miss, 0x10019, 0xFFFFFF= F8); +RVPMU_EVENT_CMASK_ATTR(dTLB-store-misses, dTLB_store_miss, 0x1001B, 0xFFFF= FFF8); +RVPMU_EVENT_CMASK_ATTR(iTLB-load-misses, iTLB_load_miss, 0x10021, 0xFFFFFF= F8); + +static struct attribute *qemu_virt_event_group[] =3D { + RVPMU_EVENT_ATTR_PTR(cycles), + RVPMU_EVENT_ATTR_PTR(instructions), + RVPMU_EVENT_ATTR_PTR(dTLB_load_miss), + RVPMU_EVENT_ATTR_PTR(dTLB_store_miss), + RVPMU_EVENT_ATTR_PTR(iTLB_load_miss), + NULL, +}; + static struct riscv_vendor_pmu_events pmu_vendor_events_table[] =3D { + RISCV_VENDOR_PMU_EVENTS(QEMU_VIRT_VENDOR_ID, QEMU_VIRT_ARCH_ID, QEMU_VIRT= _IMPL_ID, + qemu_virt_hw_event_map, qemu_virt_cache_event_map, + qemu_virt_event_group) }; =20 static const struct riscv_pmu_event *current_pmu_hw_event_map; --=20 2.53.0-Meta From nobody Sat Jun 13 15:24:19 2026 Received: from out-173.mta0.migadu.com (out-173.mta0.migadu.com [91.218.175.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 491F33D34A8 for ; Tue, 9 Jun 2026 06:03:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984986; cv=none; b=S8U+GU08+yzw/fD83SFBCJIHON85yVpMBWTCnxO17mlS/DtriwOjpySAN9HDbYFqDJN6OWUSMFCXCuETVzU08l1pE3LpB3raogNrd7veX+BDP1pJx23qDg68RytK3vYGwLUegiaoV9buBizUefboO2Vy5LbAsUcm57qZ5XZFanc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984986; c=relaxed/simple; bh=k+17zveiXsgYna87PZZulndW185hWQCYAep4cJQQgb0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=gqRCwwU+kV81fP2G7Vv4DNqDcaSPSrhJAYdIEpCFlVnuDCoH1BnbFokfYK6hzE/skM643CGIfVQYPzbVvCSG5ZLa+80sh/4maWcA7/s4djOdDrjaxCg8nRrU9GHZ6N3vAOoCpmK8Ui8AR7dV4cAlyCqFSyGVbJTvmSvnZHfDSPU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=hP9Rm69m; arc=none smtp.client-ip=91.218.175.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="hP9Rm69m" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1780984983; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=D+RY5vs8Ycg6LE30rSiyWAmudN3MbQny6JzyIGr7w5M=; b=hP9Rm69mOpasNJw11/lRGlyztBd+hadPrkDV5aRjA3ORORrIZs+J6QDIwHl8yzt28C5xis IOKTkP8psc4VuO54NNW8FxTrKPJUkDumKoFTr6XdHjPB1aIRpcmV9Kp2DgwpOp6fKoqI8L sGTDNS1Ath5FnCtwfgNSX2lm9pIjYRY= From: Atish Patra Date: Mon, 08 Jun 2026 23:01:32 -0700 Subject: [PATCH v6 18/21] tools/perf: Support event code for arch standard events Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260608-counter_delegation-v6-18-285b72ed65a9@meta.com> References: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> In-Reply-To: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> To: James Clark , Rob Herring , Atish Patra , Arnaldo Carvalho de Melo , Jiri Olsa , Will Deacon , Mark Rutland , Anup Patel , Namhyung Kim , Paul Walmsley , Krzysztof Kozlowski , Ian Rogers Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Conor Dooley , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org X-Migadu-Flow: FLOW_OUT From: Atish Patra RISC-V relies on the event encoding from the json file. That includes arch standard events. If event code is present, event is already updated with correct encoding. No need to update it again which results in losing the event encoding. Signed-off-by: Atish Patra --- tools/perf/pmu-events/arch/riscv/arch-standard.json | 10 ++++++++++ tools/perf/pmu-events/jevents.py | 6 +++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/tools/perf/pmu-events/arch/riscv/arch-standard.json b/tools/pe= rf/pmu-events/arch/riscv/arch-standard.json new file mode 100644 index 000000000000..96e21f088558 --- /dev/null +++ b/tools/perf/pmu-events/arch/riscv/arch-standard.json @@ -0,0 +1,10 @@ +[ + { + "EventName": "cycles", + "BriefDescription": "cycle executed" + }, + { + "EventName": "instructions", + "BriefDescription": "instruction retired" + } +] diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index 3a1bcdcdc685..457fce7a5982 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -413,7 +413,11 @@ class JsonEvent: self.long_desc =3D None if arch_std: if arch_std.lower() in _arch_std_events: - event =3D _arch_std_events[arch_std.lower()].event + # If the JSON event already specified an event code, the encoding = has + # been set above; don't overwrite it with the arch standard event = or + # the event encoding would be lost. + if not eventcode: + event =3D _arch_std_events[arch_std.lower()].event # Copy from the architecture standard event to self for undefined = fields. for attr, value in _arch_std_events[arch_std.lower()].__dict__.ite= ms(): if hasattr(self, attr) and not getattr(self, attr): --=20 2.53.0-Meta From nobody Sat Jun 13 15:24:19 2026 Received: from out-177.mta0.migadu.com (out-177.mta0.migadu.com [91.218.175.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A350C3CF680 for ; Tue, 9 Jun 2026 06:03:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.177 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984989; cv=none; b=nJtKejdyF8ocw3avnJ0rRhq22Gu9P0+g3fGxmRIHwA3w8f/6snhMTtcf66FhLnEnW7hasRJDeFyJ+TldHMyc5+FZhO8NhHPUyWH+kzCl3tL7/NmA/EIcRSOELOUCDNO6axlJJyN2l0q5fvJqd9hK7ekDNOqojZgL2x9mtx78R5k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984989; c=relaxed/simple; bh=7dq/L7o9aRDXneezbxF9gRbrQNC3a6O/cyzbsxJ4D0A=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=FsOvZ58fC4cE/tKGF8qvIFbQ4FzF6u+VJowzrGZtMbQGMUUmJHYDmdBhogRs9RKY3c/WSKXqYQLTjjrERgaZVX1NAu9gA2H9zIUYMtlUTuDbsQK+ss6mD0nSJwg7oNf3OhO+nAdV/KhqhWPHLXaYPkbARXKffHOQjUbTz+9wuzg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=gvRwUWko; arc=none smtp.client-ip=91.218.175.177 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="gvRwUWko" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1780984986; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=sMReWLDLXVskrK7YvKiFAJhgJ2Bnx+tOpFTmEt9zhgs=; b=gvRwUWkoqGKbVUgPgeiG7/g1s8sdwcUdIJLcVniP2hi4alfPvPizJHNpMvj/acPeEM//pw jkn9A0DD8DgGaEyoEm4GXmghWb3BktXQ2A2xZEzzXtCPKQ4SniAx95gCMnAwL5jSmAowFc /b6lCTnqECHLw7/opEnGd5Kii5Arzcc= From: Atish Patra Date: Mon, 08 Jun 2026 23:01:33 -0700 Subject: [PATCH v6 19/21] tools/perf: Add RISC-V CounterIDMask event field Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260608-counter_delegation-v6-19-285b72ed65a9@meta.com> References: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> In-Reply-To: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> To: James Clark , Rob Herring , Atish Patra , Arnaldo Carvalho de Melo , Jiri Olsa , Will Deacon , Mark Rutland , Anup Patel , Namhyung Kim , Paul Walmsley , Krzysztof Kozlowski , Ian Rogers Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Conor Dooley , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org X-Migadu-Flow: FLOW_OUT From: Atish Patra Counter delegation lets supervisor mode choose the hpmcounter for an event, but the hardware may only allow a given event on a subset of counters. Add a RISC-V specific "CounterIDMask" json event field, handled like the other arch-specific entries in event_fields[], that carries the allowed-counter bitmask through to the driver's existing counterid_mask (config2:0-31) form= at. The value is the bitmask directly so no counter-list to bitmask conversion = is needed, and because the field is RISC-V specific it is a no-op for every ot= her architecture's events (unlike the shared "Counter" field). Signed-off-by: Atish Patra --- tools/perf/pmu-events/jevents.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index 457fce7a5982..c1ed8a05c9a4 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -396,6 +396,7 @@ class JsonEvent: ('EnAllSlices', 'enallslices=3D'), ('SliceId', 'sliceid=3D'), ('ThreadMask', 'threadmask=3D'), + ('CounterIDMask', 'counterid_mask=3D'), ] for key, value in event_fields: if key in jd and not is_zero(jd[key]): --=20 2.53.0-Meta From nobody Sat Jun 13 15:24:19 2026 Received: from out-180.mta0.migadu.com (out-180.mta0.migadu.com [91.218.175.180]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EFBF03D5C2C; Tue, 9 Jun 2026 06:03:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984993; cv=none; b=Q+yoKer/2z9eSfvR8RSCmBmw6TzP13THxRaEJ8qEknu6lAfYt23wy5ecad6ce3LUGMQqOyKpWc60RjZraUeNbFHmgvSU6nYFcFKyVPdwJKAMjL/GRssA92A5FIvkk49GSUFfTzA8proLJOGliYsVlgjsyK0kX9gxD4XyHby1wAc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984993; c=relaxed/simple; bh=1QogxSyPX7FywvVaFCnOg2eE+pP5EQh82n+ltbBK2zY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=s/5Qn5xwxTbyM9drGlXi2Oym6cZH77cjrgRGNjJwx8ZiiSxSAexS9+VpnRazaAKIuxKKu13ePdgsHrUWtgc7kk6uLeeFcPB6nGYB6yQSlgH83taMiHC59opbSk1rqXhkIYoUsPo+rvt+Svn5Z4rLhaARrbSvgiMtgC4hHdGNTpw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=T4cVLiBK; arc=none smtp.client-ip=91.218.175.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="T4cVLiBK" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1780984990; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=CeVq8nIFWuQTYTDv2nXLX/gfQ3GPv2/MmaJpRnKjBUM=; b=T4cVLiBKpub52d9V/sOMY+nhHhBdp+01hm4SMjSruiz278dhwElAEu3t5HWnq2fP/MYHOU LR0NxNlDcXAU5jpTOY9CKWBMlGdRjf9cL9rL2xrH0a/LXTVo+a3bi+OedYecR9sFeiMUyA LIUS7sF025t5x1y9+yM2oMFOyCMI1sQ= From: Atish Patra Date: Mon, 08 Jun 2026 23:01:34 -0700 Subject: [PATCH v6 20/21] TEST(do-not-upstream): fake qemu-virt PMU events for cdeleg counter-mask testing Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260608-counter_delegation-v6-20-285b72ed65a9@meta.com> References: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> In-Reply-To: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> To: James Clark , Rob Herring , Atish Patra , Arnaldo Carvalho de Melo , Jiri Olsa , Will Deacon , Mark Rutland , Anup Patel , Namhyung Kim , Paul Walmsley , Krzysztof Kozlowski , Ian Rogers Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Conor Dooley , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org X-Migadu-Flow: FLOW_OUT From: Atish Patra Adds fake-any/fake-ctr3/fake-ctr34 (event codes 0xF0x QEMU doesn't model) w= ith counterid_masks, to exercise the counter-delegation allocation + counter-ma= sk constraint in QEMU (events read 0 =3D allocated/programmed, vs 'not support= ed'). Signed-off-by: Atish Patra --- drivers/perf/riscv_pmu_sbi.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c index 74acac54328e..3c0829c0a42a 100644 --- a/drivers/perf/riscv_pmu_sbi.c +++ b/drivers/perf/riscv_pmu_sbi.c @@ -476,6 +476,12 @@ RVPMU_EVENT_CMASK_ATTR(instructions, instructions, 0x0= 2, 0xFFFFFFF8); RVPMU_EVENT_CMASK_ATTR(dTLB-load-misses, dTLB_load_miss, 0x10019, 0xFFFFFF= F8); RVPMU_EVENT_CMASK_ATTR(dTLB-store-misses, dTLB_store_miss, 0x1001B, 0xFFFF= FFF8); RVPMU_EVENT_CMASK_ATTR(iTLB-load-misses, iTLB_load_miss, 0x10021, 0xFFFFFF= F8); +/* + * FAKE events for cdeleg mechanism testing: event codes QEMU does NOT mod= el. + */ +RVPMU_EVENT_CMASK_ATTR(fake-any, fake_any, 0xF00, 0xFFFFFFF8); +RVPMU_EVENT_CMASK_ATTR(fake-ctr3, fake_ctr3, 0xF01, 0x8); +RVPMU_EVENT_CMASK_ATTR(fake-ctr34, fake_ctr34, 0xF02, 0x18); =20 static struct attribute *qemu_virt_event_group[] =3D { RVPMU_EVENT_ATTR_PTR(cycles), @@ -483,6 +489,9 @@ static struct attribute *qemu_virt_event_group[] =3D { RVPMU_EVENT_ATTR_PTR(dTLB_load_miss), RVPMU_EVENT_ATTR_PTR(dTLB_store_miss), RVPMU_EVENT_ATTR_PTR(iTLB_load_miss), + RVPMU_EVENT_ATTR_PTR(fake_any), + RVPMU_EVENT_ATTR_PTR(fake_ctr3), + RVPMU_EVENT_ATTR_PTR(fake_ctr34), NULL, }; =20 --=20 2.53.0-Meta From nobody Sat Jun 13 15:24:19 2026 Received: from out-172.mta0.migadu.com (out-172.mta0.migadu.com [91.218.175.172]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 87D5E3DC4A9 for ; Tue, 9 Jun 2026 06:03:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984996; cv=none; b=ELVEuLrCPyhlHzK2FC8r1c+GqkaLtonxpdS+gijyO8d9n7CHm0Cw5+i1n8dD7kb+5jVuMuU8F2H9IW1p8kxpQOYPnIgXJY//qguhpoa74oD0/OChqnjyBsOIhAHw8qo++BeIWl4FSwDbGmCI+HXx++30ET+mzYZDDUtDBU6txZ4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780984996; c=relaxed/simple; bh=+0MhYWvDoVqixJolM+MtR3Uaco3QucCwRBMSFs+rT58=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=AumNv7EcGC1G4cKQZbu7SiK6ObeaU31AhK5jiNi8ePfGVkcDBOuce/GRpQIXshNP5q9nh6DTkWpzPihDU5rAIXoZ6d/xBQxaNcA6rlX8JlOPQ1Y8JEmjlOzqIkEpomsFnAp3QkXcfuhHG9Ho/b/JE9bzC6JySTOSuWYI9QfD9II= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=vpM6FHFJ; arc=none smtp.client-ip=91.218.175.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="vpM6FHFJ" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1780984993; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=+74FvUBZxlbST9+7oM0jYayJwnBAvv8czrcrU+bwgIY=; b=vpM6FHFJf+/bhrb1nhFUxA9NhY0bKIHiu9hZC4M74ql0x/+s2OW8XYklNsJN2Wqjb+aDgm TuW+Rb6lccksKUK79R+bswVAVlucisHM3wAIY53BkTvXnckQhJh6EMm1O8xxg/xFzGUadQ pYOfEDg6bHiwaiIUlD7swclvmTkv7FQ= From: Atish Patra Date: Mon, 08 Jun 2026 23:01:35 -0700 Subject: [PATCH v6 21/21] TEST(do-not-upstream): fake qemu vendor JSON + mapfile entry for CounterIDMask path Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260608-counter_delegation-v6-21-285b72ed65a9@meta.com> References: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> In-Reply-To: <20260608-counter_delegation-v6-0-285b72ed65a9@meta.com> To: James Clark , Rob Herring , Atish Patra , Arnaldo Carvalho de Melo , Jiri Olsa , Will Deacon , Mark Rutland , Anup Patel , Namhyung Kim , Paul Walmsley , Krzysztof Kozlowski , Ian Rogers Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Conor Dooley , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org X-Migadu-Flow: FLOW_OUT From: Atish Patra arch/riscv/qemu/virt/events.json: fake-json-{any,ctr3,ctr34,ctr6} with Even= tCode + CounterIDMask; mapfile.csv: 0x0-0x0-0x0 -> qemu/virt. Exercises jevents CounterIDMask -> counterid_mask=3D -> config2 -> cdeleg counter allocation. Signed-off-by: Atish Patra --- tools/perf/pmu-events/arch/riscv/mapfile.csv | 1 + .../pmu-events/arch/riscv/qemu/virt/events.json | 26 ++++++++++++++++++= ++++ 2 files changed, 27 insertions(+) diff --git a/tools/perf/pmu-events/arch/riscv/mapfile.csv b/tools/perf/pmu-= events/arch/riscv/mapfile.csv index 87cfb0e0849f..3533a8c0253f 100644 --- a/tools/perf/pmu-events/arch/riscv/mapfile.csv +++ b/tools/perf/pmu-events/arch/riscv/mapfile.csv @@ -24,3 +24,4 @@ 0x602-0x3-0x0,v1,openhwgroup/cva6,core 0x67e-0x80000000db0000[89]0-0x[[:xdigit:]]+,v1,starfive/dubhe-80,core 0x31e-0x8000000000008a45-0x[[:xdigit:]]+,v1,andes/ax45,core +0x0-0x0-0x0,v1,qemu/virt,core diff --git a/tools/perf/pmu-events/arch/riscv/qemu/virt/events.json b/tools= /perf/pmu-events/arch/riscv/qemu/virt/events.json new file mode 100644 index 000000000000..294c4ed645f6 --- /dev/null +++ b/tools/perf/pmu-events/arch/riscv/qemu/virt/events.json @@ -0,0 +1,26 @@ +[ + { + "EventName": "fake-json-any", + "EventCode": "0xF10", + "CounterIDMask": "0xFFFFFFF8", + "BriefDescription": "FAKE json event (any hpmcounter 3-31) - QEMU does= not model 0xF10" + }, + { + "EventName": "fake-json-ctr3", + "EventCode": "0xF11", + "CounterIDMask": "0x8", + "BriefDescription": "FAKE json event constrained to hpmcounter3" + }, + { + "EventName": "fake-json-ctr34", + "EventCode": "0xF12", + "CounterIDMask": "0x18", + "BriefDescription": "FAKE json event constrained to hpmcounter3,4" + }, + { + "EventName": "fake-json-ctr6", + "EventCode": "0xF13", + "CounterIDMask": "0x40", + "BriefDescription": "FAKE json event constrained to hpmcounter6 (out o= f a small pmu-mask)" + } +] --=20 2.53.0-Meta