* [PATCH v2 1/3] KVM: arm64: Read PMUVer as unsigned
2026-03-05 16:28 [PATCH v2 0/3] KVM: arm64: Read PMUVer as unsigned James Clark
@ 2026-03-05 16:28 ` James Clark
2026-03-05 16:28 ` [PATCH v2 2/3] arm64: cpufeature: Make PMUVer and PerfMon unsigned James Clark
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: James Clark @ 2026-03-05 16:28 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Joey Gouly, Suzuki K Poulose,
Zenghui Yu, Catalin Marinas, Will Deacon, Colton Lewis,
Alexandru Elisei
Cc: linux-arm-kernel, kvmarm, linux-kernel, James Clark
ID_AA64DFR0_EL1.PMUVer is an unsigned field, so this skips
initialization of host_data_ptr(nr_event_counters) for PMUv3 for Armv8.8
onwards as they appear as negative values.
Fix it by reading it as unsigned. Now ID_AA64DFR0_EL1_PMUVer_IMP_DEF
needs to be special cased, so use pmuv3_implemented() which already does
it.
Fixes: 2417218f2f23 ("KVM: arm64: Get rid of __kvm_get_mdcr_el2() and related warts")
Signed-off-by: James Clark <james.clark@linaro.org>
---
arch/arm64/kvm/debug.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index 3ad6b7c6e4ba..f4d7b12045e8 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -10,6 +10,7 @@
#include <linux/kvm_host.h>
#include <linux/hw_breakpoint.h>
+#include <asm/arm_pmuv3.h>
#include <asm/debug-monitors.h>
#include <asm/kvm_asm.h>
#include <asm/kvm_arm.h>
@@ -75,8 +76,10 @@ static void kvm_arm_setup_mdcr_el2(struct kvm_vcpu *vcpu)
void kvm_init_host_debug_data(void)
{
u64 dfr0 = read_sysreg(id_aa64dfr0_el1);
+ unsigned int pmuver = cpuid_feature_extract_unsigned_field(dfr0,
+ ID_AA64DFR0_EL1_PMUVer_SHIFT);
- if (cpuid_feature_extract_signed_field(dfr0, ID_AA64DFR0_EL1_PMUVer_SHIFT) > 0)
+ if (pmuv3_implemented(pmuver))
*host_data_ptr(nr_event_counters) = FIELD_GET(ARMV8_PMU_PMCR_N,
read_sysreg(pmcr_el0));
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v2 2/3] arm64: cpufeature: Make PMUVer and PerfMon unsigned
2026-03-05 16:28 [PATCH v2 0/3] KVM: arm64: Read PMUVer as unsigned James Clark
2026-03-05 16:28 ` [PATCH v2 1/3] " James Clark
@ 2026-03-05 16:28 ` James Clark
2026-03-05 16:28 ` [PATCH v2 3/3] arm64: cpufeature: Use pmuv3_implemented() function James Clark
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: James Clark @ 2026-03-05 16:28 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Joey Gouly, Suzuki K Poulose,
Zenghui Yu, Catalin Marinas, Will Deacon, Colton Lewis,
Alexandru Elisei
Cc: linux-arm-kernel, kvmarm, linux-kernel, James Clark
On the host, this change doesn't make a difference because the fields
are defined as FTR_EXACT. However, KVM allows userspace to set these
fields for a guest and overrides the type to be FTR_LOWER_SAFE. And
while KVM used to do an unsigned comparison to validate that the new
value is lower than what the hardware provides, since the linked commit
it uses the generic sanitization framework which does a signed
comparison.
Fix it by defining these fields as unsigned. In theory, without this
fix, userspace could set a higher PMU version than the hardware supports
by providing any value with the top bit set.
Fixes: c118cead07a7 ("KVM: arm64: Use generic sanitisation for ID_(AA64)DFR0_EL1")
Signed-off-by: James Clark <james.clark@linaro.org>
---
arch/arm64/kernel/cpufeature.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index c31f8e17732a..07abdfd40756 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -565,7 +565,7 @@ static const struct arm64_ftr_bits ftr_id_aa64dfr0[] = {
* We can instantiate multiple PMU instances with different levels
* of support.
*/
- S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_EXACT, ID_AA64DFR0_EL1_PMUVer_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_EXACT, ID_AA64DFR0_EL1_PMUVer_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, ID_AA64DFR0_EL1_DebugVer_SHIFT, 4, 0x6),
ARM64_FTR_END,
};
@@ -709,7 +709,7 @@ static const struct arm64_ftr_bits ftr_id_pfr2[] = {
static const struct arm64_ftr_bits ftr_id_dfr0[] = {
/* [31:28] TraceFilt */
- S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_EXACT, ID_DFR0_EL1_PerfMon_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_EXACT, ID_DFR0_EL1_PerfMon_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_DFR0_EL1_MProfDbg_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_DFR0_EL1_MMapTrc_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_DFR0_EL1_CopTrc_SHIFT, 4, 0),
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v2 3/3] arm64: cpufeature: Use pmuv3_implemented() function
2026-03-05 16:28 [PATCH v2 0/3] KVM: arm64: Read PMUVer as unsigned James Clark
2026-03-05 16:28 ` [PATCH v2 1/3] " James Clark
2026-03-05 16:28 ` [PATCH v2 2/3] arm64: cpufeature: Make PMUVer and PerfMon unsigned James Clark
@ 2026-03-05 16:28 ` James Clark
2026-03-12 21:44 ` [PATCH v2 0/3] KVM: arm64: Read PMUVer as unsigned Colton Lewis
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: James Clark @ 2026-03-05 16:28 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Joey Gouly, Suzuki K Poulose,
Zenghui Yu, Catalin Marinas, Will Deacon, Colton Lewis,
Alexandru Elisei
Cc: linux-arm-kernel, kvmarm, linux-kernel, James Clark
Other places that are doing this version comparison are already using
pmuv3_implemented(), so might as well use it here too for consistency.
Signed-off-by: James Clark <james.clark@linaro.org>
---
arch/arm/include/asm/arm_pmuv3.h | 7 +++++++
arch/arm64/kernel/cpufeature.c | 12 ++----------
2 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/arch/arm/include/asm/arm_pmuv3.h b/arch/arm/include/asm/arm_pmuv3.h
index 2ec0e5e83fc9..ecfede0c0348 100644
--- a/arch/arm/include/asm/arm_pmuv3.h
+++ b/arch/arm/include/asm/arm_pmuv3.h
@@ -238,6 +238,13 @@ static inline void kvm_vcpu_pmu_resync_el0(void) {}
static inline bool pmuv3_implemented(int pmuver)
{
+ /*
+ * PMUVer follows the standard ID scheme for an unsigned field with the
+ * exception of 0xF (IMP_DEF) which is treated specially and implies
+ * FEAT_PMUv3 is not implemented.
+ *
+ * See DDI0487L.a D24.1.3.2 for more details.
+ */
return !(pmuver == ARMV8_PMU_DFR_VER_IMP_DEF ||
pmuver == ARMV8_PMU_DFR_VER_NI);
}
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 07abdfd40756..cc9783b26443 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -77,6 +77,7 @@
#include <linux/percpu.h>
#include <linux/sched/isolation.h>
+#include <asm/arm_pmuv3.h>
#include <asm/cpu.h>
#include <asm/cpufeature.h>
#include <asm/cpu_ops.h>
@@ -1927,19 +1928,10 @@ static bool has_pmuv3(const struct arm64_cpu_capabilities *entry, int scope)
u64 dfr0 = read_sanitised_ftr_reg(SYS_ID_AA64DFR0_EL1);
unsigned int pmuver;
- /*
- * PMUVer follows the standard ID scheme for an unsigned field with the
- * exception of 0xF (IMP_DEF) which is treated specially and implies
- * FEAT_PMUv3 is not implemented.
- *
- * See DDI0487L.a D24.1.3.2 for more details.
- */
pmuver = cpuid_feature_extract_unsigned_field(dfr0,
ID_AA64DFR0_EL1_PMUVer_SHIFT);
- if (pmuver == ID_AA64DFR0_EL1_PMUVer_IMP_DEF)
- return false;
- return pmuver >= ID_AA64DFR0_EL1_PMUVer_IMP;
+ return pmuv3_implemented(pmuver);
}
#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH v2 0/3] KVM: arm64: Read PMUVer as unsigned
2026-03-05 16:28 [PATCH v2 0/3] KVM: arm64: Read PMUVer as unsigned James Clark
` (2 preceding siblings ...)
2026-03-05 16:28 ` [PATCH v2 3/3] arm64: cpufeature: Use pmuv3_implemented() function James Clark
@ 2026-03-12 21:44 ` Colton Lewis
2026-03-19 16:51 ` Marc Zyngier
2026-03-24 15:08 ` Will Deacon
5 siblings, 0 replies; 7+ messages in thread
From: Colton Lewis @ 2026-03-12 21:44 UTC (permalink / raw)
To: James Clark
Cc: maz, oupton, joey.gouly, suzuki.poulose, yuzenghui,
catalin.marinas, will, alexandru.elisei, linux-arm-kernel, kvmarm,
linux-kernel, james.clark
James Clark <james.clark@linaro.org> writes:
> Fix some issues with the signedness of PMUVer and PerfMon ID fields.
> I ran into the first issue when testing "ARM64 PMU Partitioning" patches
> on the FVP. The second issue was only found by inspection.
> Signed-off-by: James Clark <james.clark@linaro.org>
> ---
> Changes in v2:
> - Handle ID_AA64DFR0_EL1_PMUVer_IMP_DEF correctly by using
> pmuv3_implemented()
> - Fix another issue with incorrect sign in cpufeature.c
> - Add a commit to refactor has_pmuv3() to use pmuv3_implemented() for
> consistency
> - Link to v1:
> https://lore.kernel.org/r/20260305-james-kvm-pmuver-sign-v1-1-eea0a2116dd0@linaro.org
> ---
> James Clark (3):
> KVM: arm64: Read PMUVer as unsigned
> arm64: cpufeature: Make PMUVer and PerfMon unsigned
> arm64: cpufeature: Use pmuv3_implemented() function
> arch/arm/include/asm/arm_pmuv3.h | 7 +++++++
> arch/arm64/kernel/cpufeature.c | 16 ++++------------
> arch/arm64/kvm/debug.c | 5 ++++-
> 3 files changed, 15 insertions(+), 13 deletions(-)
> ---
> base-commit: 11439c4635edd669ae435eec308f4ab8a0804808
> change-id: 20260305-james-kvm-pmuver-sign-fe830bdead2d
> Best regards,
> --
> James Clark <james.clark@linaro.org>
Thanks for testing my series James. Glad you caught this
Reviewed-by: Colton Lewis <coltonlewis@google.com>
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH v2 0/3] KVM: arm64: Read PMUVer as unsigned
2026-03-05 16:28 [PATCH v2 0/3] KVM: arm64: Read PMUVer as unsigned James Clark
` (3 preceding siblings ...)
2026-03-12 21:44 ` [PATCH v2 0/3] KVM: arm64: Read PMUVer as unsigned Colton Lewis
@ 2026-03-19 16:51 ` Marc Zyngier
2026-03-24 15:08 ` Will Deacon
5 siblings, 0 replies; 7+ messages in thread
From: Marc Zyngier @ 2026-03-19 16:51 UTC (permalink / raw)
To: Will Deacon, James Clark
Cc: Oliver Upton, Joey Gouly, Suzuki K Poulose, Zenghui Yu,
Catalin Marinas, Colton Lewis, Alexandru Elisei, linux-arm-kernel,
kvmarm, linux-kernel
On Thu, 05 Mar 2026 16:28:16 +0000,
James Clark <james.clark@linaro.org> wrote:
>
> Fix some issues with the signedness of PMUVer and PerfMon ID fields.
>
> I ran into the first issue when testing "ARM64 PMU Partitioning" patches
> on the FVP. The second issue was only found by inspection.
>
> Signed-off-by: James Clark <james.clark@linaro.org>
> ---
> Changes in v2:
> - Handle ID_AA64DFR0_EL1_PMUVer_IMP_DEF correctly by using
> pmuv3_implemented()
> - Fix another issue with incorrect sign in cpufeature.c
> - Add a commit to refactor has_pmuv3() to use pmuv3_implemented() for
> consistency
> - Link to v1: https://lore.kernel.org/r/20260305-james-kvm-pmuver-sign-v1-1-eea0a2116dd0@linaro.org
>
> ---
> James Clark (3):
> KVM: arm64: Read PMUVer as unsigned
> arm64: cpufeature: Make PMUVer and PerfMon unsigned
> arm64: cpufeature: Use pmuv3_implemented() function
>
> arch/arm/include/asm/arm_pmuv3.h | 7 +++++++
> arch/arm64/kernel/cpufeature.c | 16 ++++------------
> arch/arm64/kvm/debug.c | 5 ++++-
> 3 files changed, 15 insertions(+), 13 deletions(-)
Given that this only tangentially affects KVM, it'd better be routed
via the arm64/perf tree.
With that in mind:
Reviewed-by: Marc Zyngier <maz@kernel.org>
Thanks,
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH v2 0/3] KVM: arm64: Read PMUVer as unsigned
2026-03-05 16:28 [PATCH v2 0/3] KVM: arm64: Read PMUVer as unsigned James Clark
` (4 preceding siblings ...)
2026-03-19 16:51 ` Marc Zyngier
@ 2026-03-24 15:08 ` Will Deacon
5 siblings, 0 replies; 7+ messages in thread
From: Will Deacon @ 2026-03-24 15:08 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Joey Gouly, Suzuki K Poulose,
Zenghui Yu, Catalin Marinas, Colton Lewis, Alexandru Elisei,
James Clark
Cc: kernel-team, Will Deacon, linux-arm-kernel, kvmarm, linux-kernel
On Thu, 05 Mar 2026 16:28:16 +0000, James Clark wrote:
> Fix some issues with the signedness of PMUVer and PerfMon ID fields.
>
> I ran into the first issue when testing "ARM64 PMU Partitioning" patches
> on the FVP. The second issue was only found by inspection.
>
>
Applied to will (for-next/perf), thanks!
[1/3] KVM: arm64: Read PMUVer as unsigned
https://git.kernel.org/will/c/2e30447b233a
[2/3] arm64: cpufeature: Make PMUVer and PerfMon unsigned
https://git.kernel.org/will/c/d1dcc20bcc40
[3/3] arm64: cpufeature: Use pmuv3_implemented() function
https://git.kernel.org/will/c/15ed3fa23cbc
Cheers,
--
Will
https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev
^ permalink raw reply [flat|nested] 7+ messages in thread