The Linux Kernel Mailing List
 help / color / mirror / Atom feed
* [PATCH] KVM: arm64: Expose PMMIR_EL1.SLOTS to guests
@ 2026-06-01 19:39 Congkai Tan
  2026-06-01 20:06 ` Oliver Upton
  2026-06-02  4:14 ` kernel test robot
  0 siblings, 2 replies; 6+ messages in thread
From: Congkai Tan @ 2026-06-01 19:39 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel
  Cc: Congkai Tan, Marc Zyngier, Oliver Upton, Joey Gouly,
	Suzuki K Poulose, Zenghui Yu, Catalin Marinas, Will Deacon,
	Mark Rutland, Haris Okanovic, Geoff Blake, linux-kernel

Commit 46081078feb4 ("KVM: arm64: Upgrade PMU support to ARMv8.4")
trapped PMMIR_EL1 as RAZ/WI and masked STALL_SLOT* from PMCEID1 to
discourage guests from relying on a register they could not read.

Forward the SLOTS field of PMMIR_EL1 so that the perf userspace tool
can read the correct value from
/sys/bus/event_source/devices/armv8_pmuv3_0/caps/slots. Today, perf
stat fails with message "Failure to read '#slots'" because it can
only read 0x0 from the sysfs location, causing the parsing failure
of the default metrics.

Fix this by:
1. Adding an access_pmmir() handler that reads arm_pmu->reg_pmmir
   and returns a masked value containing only the SLOTS field [7:0]
   to the guest. Other PMMIR_EL1 fields are kept as RAZ to limit
   the extra information that this change exposes; individual
   fields can be unmasked as KVM gains support for each feature.
2. Removing the STALL_SLOT, STALL_SLOT_FRONTEND and STALL_SLOT_BACKEND
   mask in PMCEID1. The mask existed to hide these events under the
   sysfs events/ directory when PMMIR_EL1 was RAZ; with SLOTS now
   readable they should be correctly exposed.

Tested on Graviton 2 (Neoverse N1, pre-PMUv3p4), Graviton 3
(Neoverse V1) and Graviton 4 (Neoverse V2) metal hosts with QEMU:
caps/slots reads 0x00000008 in guests on Graviton 3/4 and 0x00000000
on Graviton 2 (correct for pre-PMUv3p4). perf stat correctly
evaluates the default metrics.

Fixes: 46081078feb4 ("KVM: arm64: Upgrade PMU support to ARMv8.4")
Cc: stable@vger.kernel.org
Signed-off-by: Congkai Tan <congkai@amazon.com>
Reviewed-by: Haris Okanovic <harisokn@amazon.com>
Reviewed-by: Geoff Blake <blakgeof@amazon.com>
---
 arch/arm64/kvm/pmu-emul.c | 11 +----------
 arch/arm64/kvm/sys_regs.c | 26 ++++++++++++++++++++++++--
 2 files changed, 25 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index e1860acae641..bafd5a258927 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -864,16 +864,7 @@ static u64 compute_pmceid0(struct arm_pmu *pmu)
 
 static u64 compute_pmceid1(struct arm_pmu *pmu)
 {
-	u64 val = __compute_pmceid(pmu, 1);
-
-	/*
-	 * Don't advertise STALL_SLOT*, as PMMIR_EL0 is handled
-	 * as RAZ
-	 */
-	val &= ~(BIT_ULL(ARMV8_PMUV3_PERFCTR_STALL_SLOT - 32) |
-		 BIT_ULL(ARMV8_PMUV3_PERFCTR_STALL_SLOT_FRONTEND - 32) |
-		 BIT_ULL(ARMV8_PMUV3_PERFCTR_STALL_SLOT_BACKEND - 32));
-	return val;
+	return __compute_pmceid(pmu, 1);
 }
 
 u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1)
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 148fc3400ea8..7da7566dfd9f 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -18,6 +18,7 @@
 #include <linux/printk.h>
 #include <linux/uaccess.h>
 #include <linux/irqchip/arm-gic-v3.h>
+#include <linux/perf/arm_pmu.h>
 
 #include <asm/arm_pmuv3.h>
 #include <asm/cacheflush.h>
@@ -1370,6 +1371,27 @@ static bool access_pminten(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
 	return true;
 }
 
+/*
+ * Expose only PMMIR_EL1.SLOTS to the guest, which is consumed by perf in its
+ * topdown default metric group. Other PMMIR_EL1 fields remain RAZ. Future
+ * patches can extend the exposed mask incrementally as KVM gains support for
+ * those features.
+ */
+static bool access_pmmir(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
+			 const struct sys_reg_desc *r)
+{
+	struct arm_pmu *cpu_pmu = vcpu->kvm->arch.arm_pmu;
+
+	if (p->is_write)
+		return write_to_read_only(vcpu, p, r);
+
+	if (check_pmu_access_disabled(vcpu, 0))
+		return false;
+
+	p->regval = cpu_pmu->reg_pmmir & ARMV8_PMU_SLOTS;
+	return true;
+}
+
 static bool access_pmovs(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
 			 const struct sys_reg_desc *r)
 {
@@ -3456,7 +3478,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	{ PMU_SYS_REG(PMINTENCLR_EL1),
 	  .access = access_pminten, .reg = PMINTENSET_EL1,
 	  .get_user = get_pmreg, .set_user = set_pmreg },
-	{ SYS_DESC(SYS_PMMIR_EL1), trap_raz_wi },
+	{ PMU_SYS_REG(PMMIR_EL1), .access = access_pmmir, .reset = NULL },
 
 	{ SYS_DESC(SYS_MAIR_EL1), access_vm_reg, reset_unknown, MAIR_EL1 },
 	{ SYS_DESC(SYS_PIRE0_EL1), NULL, reset_unknown, PIRE0_EL1,
@@ -4600,7 +4622,7 @@ static const struct sys_reg_desc cp15_regs[] = {
 	{ CP15_PMU_SYS_REG(HI,     0, 9, 14, 4), .access = access_pmceid },
 	{ CP15_PMU_SYS_REG(HI,     0, 9, 14, 5), .access = access_pmceid },
 	/* PMMIR */
-	{ CP15_PMU_SYS_REG(DIRECT, 0, 9, 14, 6), .access = trap_raz_wi },
+	{ CP15_PMU_SYS_REG(DIRECT, 0, 9, 14, 6), .access = access_pmmir },
 
 	/* PRRR/MAIR0 */
 	{ AA32(LO), Op1( 0), CRn(10), CRm( 2), Op2( 0), access_vm_reg, NULL, MAIR_EL1 },

base-commit: 1702da76e017ae0fbe1a92b07bc332972c293e89
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH] KVM: arm64: Expose PMMIR_EL1.SLOTS to guests
  2026-06-01 19:39 [PATCH] KVM: arm64: Expose PMMIR_EL1.SLOTS to guests Congkai Tan
@ 2026-06-01 20:06 ` Oliver Upton
  2026-06-01 20:13   ` Oliver Upton
  2026-06-08 21:03   ` Congkai Tan
  2026-06-02  4:14 ` kernel test robot
  1 sibling, 2 replies; 6+ messages in thread
From: Oliver Upton @ 2026-06-01 20:06 UTC (permalink / raw)
  To: Congkai Tan
  Cc: kvmarm, linux-arm-kernel, Marc Zyngier, Joey Gouly,
	Suzuki K Poulose, Zenghui Yu, Catalin Marinas, Will Deacon,
	Mark Rutland, Haris Okanovic, Geoff Blake, linux-kernel

Hi Congkai,

On Mon, Jun 01, 2026 at 07:39:54PM +0000, Congkai Tan wrote:
> Commit 46081078feb4 ("KVM: arm64: Upgrade PMU support to ARMv8.4")
> trapped PMMIR_EL1 as RAZ/WI and masked STALL_SLOT* from PMCEID1 to
> discourage guests from relying on a register they could not read.
> 
> Forward the SLOTS field of PMMIR_EL1 so that the perf userspace tool
> can read the correct value from
> /sys/bus/event_source/devices/armv8_pmuv3_0/caps/slots. Today, perf
> stat fails with message "Failure to read '#slots'" because it can
> only read 0x0 from the sysfs location, causing the parsing failure
> of the default metrics.
> 
> Fix this by:
> 1. Adding an access_pmmir() handler that reads arm_pmu->reg_pmmir
>    and returns a masked value containing only the SLOTS field [7:0]
>    to the guest. Other PMMIR_EL1 fields are kept as RAZ to limit
>    the extra information that this change exposes; individual
>    fields can be unmasked as KVM gains support for each feature.
> 2. Removing the STALL_SLOT, STALL_SLOT_FRONTEND and STALL_SLOT_BACKEND
>    mask in PMCEID1. The mask existed to hide these events under the
>    sysfs events/ directory when PMMIR_EL1 was RAZ; with SLOTS now
>    readable they should be correctly exposed.
> 
> Tested on Graviton 2 (Neoverse N1, pre-PMUv3p4), Graviton 3
> (Neoverse V1) and Graviton 4 (Neoverse V2) metal hosts with QEMU:
> caps/slots reads 0x00000008 in guests on Graviton 3/4 and 0x00000000
> on Graviton 2 (correct for pre-PMUv3p4). perf stat correctly
> evaluates the default metrics.
> 
> Fixes: 46081078feb4 ("KVM: arm64: Upgrade PMU support to ARMv8.4")
> Cc: stable@vger.kernel.org

This is not stable-worthy, nor is it a bugfix. As KVM presently does not
implement the STALL_SLOTS* events, PMMIR_EL0.SLOTS = 0 is a legal
implementation of FEAT_PMUv3p4.

> ---
>  arch/arm64/kvm/pmu-emul.c | 11 +----------
>  arch/arm64/kvm/sys_regs.c | 26 ++++++++++++++++++++++++--
>  2 files changed, 25 insertions(+), 12 deletions(-)
> 
> diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
> index e1860acae641..bafd5a258927 100644
> --- a/arch/arm64/kvm/pmu-emul.c
> +++ b/arch/arm64/kvm/pmu-emul.c
> @@ -864,16 +864,7 @@ static u64 compute_pmceid0(struct arm_pmu *pmu)
>  
>  static u64 compute_pmceid1(struct arm_pmu *pmu)
>  {
> -	u64 val = __compute_pmceid(pmu, 1);
> -
> -	/*
> -	 * Don't advertise STALL_SLOT*, as PMMIR_EL0 is handled
> -	 * as RAZ
> -	 */
> -	val &= ~(BIT_ULL(ARMV8_PMUV3_PERFCTR_STALL_SLOT - 32) |
> -		 BIT_ULL(ARMV8_PMUV3_PERFCTR_STALL_SLOT_FRONTEND - 32) |
> -		 BIT_ULL(ARMV8_PMUV3_PERFCTR_STALL_SLOT_BACKEND - 32));
> -	return val;
> +	return __compute_pmceid(pmu, 1);
>  }

Make the change to PMCEID1 in a separate patch from PMMIR_EL1.

> +/*
> + * Expose only PMMIR_EL1.SLOTS to the guest, which is consumed by perf in its
> + * topdown default metric group. Other PMMIR_EL1 fields remain RAZ. Future
> + * patches can extend the exposed mask incrementally as KVM gains support for
> + * those features.
> + */
> +static bool access_pmmir(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
> +			 const struct sys_reg_desc *r)
> +{
> +	struct arm_pmu *cpu_pmu = vcpu->kvm->arch.arm_pmu;
> +
> +	if (p->is_write)
> +		return write_to_read_only(vcpu, p, r);
> +
> +	if (check_pmu_access_disabled(vcpu, 0))
> +		return false;
> +
> +	p->regval = cpu_pmu->reg_pmmir & ARMV8_PMU_SLOTS;
> +	return true;
> +}
> +

We can't change the value of PMMIR_EL1 unconditionally since older KVM
treated this register as RAZ/WI. This also mixes poorly with the default
PMU garbage that we have since as the value of the register can change
based on where KVM_ARM_VCPU_INIT gets called...

Considering everything, I'd like to see this wired up where:

 - PMMIR_EL1.SLOTS takes the value of the underlying hardware PMU only
   if the VMM explicitly selects a particular PMU implementation

 - KVM allows userspace to set PMMIR_EL1.SLOTS=0 for backwards
   compatibility

Thanks,
Oliver

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] KVM: arm64: Expose PMMIR_EL1.SLOTS to guests
  2026-06-01 20:06 ` Oliver Upton
@ 2026-06-01 20:13   ` Oliver Upton
  2026-06-08 21:03   ` Congkai Tan
  1 sibling, 0 replies; 6+ messages in thread
From: Oliver Upton @ 2026-06-01 20:13 UTC (permalink / raw)
  To: Congkai Tan
  Cc: kvmarm, linux-arm-kernel, Marc Zyngier, Joey Gouly,
	Suzuki K Poulose, Zenghui Yu, Catalin Marinas, Will Deacon,
	Mark Rutland, Haris Okanovic, Geoff Blake, linux-kernel

On Mon, Jun 01, 2026 at 01:06:17PM -0700, Oliver Upton wrote:
> Hi Congkai,
> 
> On Mon, Jun 01, 2026 at 07:39:54PM +0000, Congkai Tan wrote:
> > Commit 46081078feb4 ("KVM: arm64: Upgrade PMU support to ARMv8.4")
> > trapped PMMIR_EL1 as RAZ/WI and masked STALL_SLOT* from PMCEID1 to
> > discourage guests from relying on a register they could not read.
> > 
> > Forward the SLOTS field of PMMIR_EL1 so that the perf userspace tool
> > can read the correct value from
> > /sys/bus/event_source/devices/armv8_pmuv3_0/caps/slots. Today, perf
> > stat fails with message "Failure to read '#slots'" because it can
> > only read 0x0 from the sysfs location, causing the parsing failure
> > of the default metrics.
> > 
> > Fix this by:
> > 1. Adding an access_pmmir() handler that reads arm_pmu->reg_pmmir
> >    and returns a masked value containing only the SLOTS field [7:0]
> >    to the guest. Other PMMIR_EL1 fields are kept as RAZ to limit
> >    the extra information that this change exposes; individual
> >    fields can be unmasked as KVM gains support for each feature.
> > 2. Removing the STALL_SLOT, STALL_SLOT_FRONTEND and STALL_SLOT_BACKEND
> >    mask in PMCEID1. The mask existed to hide these events under the
> >    sysfs events/ directory when PMMIR_EL1 was RAZ; with SLOTS now
> >    readable they should be correctly exposed.
> > 
> > Tested on Graviton 2 (Neoverse N1, pre-PMUv3p4), Graviton 3
> > (Neoverse V1) and Graviton 4 (Neoverse V2) metal hosts with QEMU:
> > caps/slots reads 0x00000008 in guests on Graviton 3/4 and 0x00000000
> > on Graviton 2 (correct for pre-PMUv3p4). perf stat correctly
> > evaluates the default metrics.
> > 
> > Fixes: 46081078feb4 ("KVM: arm64: Upgrade PMU support to ARMv8.4")
> > Cc: stable@vger.kernel.org
> 
> This is not stable-worthy, nor is it a bugfix. As KVM presently does not
> implement the STALL_SLOTS* events, PMMIR_EL0.SLOTS = 0 is a legal
> implementation of FEAT_PMUv3p4.
> 
> > ---
> >  arch/arm64/kvm/pmu-emul.c | 11 +----------
> >  arch/arm64/kvm/sys_regs.c | 26 ++++++++++++++++++++++++--
> >  2 files changed, 25 insertions(+), 12 deletions(-)
> > 
> > diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
> > index e1860acae641..bafd5a258927 100644
> > --- a/arch/arm64/kvm/pmu-emul.c
> > +++ b/arch/arm64/kvm/pmu-emul.c
> > @@ -864,16 +864,7 @@ static u64 compute_pmceid0(struct arm_pmu *pmu)
> >  
> >  static u64 compute_pmceid1(struct arm_pmu *pmu)
> >  {
> > -	u64 val = __compute_pmceid(pmu, 1);
> > -
> > -	/*
> > -	 * Don't advertise STALL_SLOT*, as PMMIR_EL0 is handled
> > -	 * as RAZ
> > -	 */
> > -	val &= ~(BIT_ULL(ARMV8_PMUV3_PERFCTR_STALL_SLOT - 32) |
> > -		 BIT_ULL(ARMV8_PMUV3_PERFCTR_STALL_SLOT_FRONTEND - 32) |
> > -		 BIT_ULL(ARMV8_PMUV3_PERFCTR_STALL_SLOT_BACKEND - 32));
> > -	return val;
> > +	return __compute_pmceid(pmu, 1);
> >  }
> 
> Make the change to PMCEID1 in a separate patch from PMMIR_EL1.
> 
> > +/*
> > + * Expose only PMMIR_EL1.SLOTS to the guest, which is consumed by perf in its
> > + * topdown default metric group. Other PMMIR_EL1 fields remain RAZ. Future
> > + * patches can extend the exposed mask incrementally as KVM gains support for
> > + * those features.
> > + */
> > +static bool access_pmmir(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
> > +			 const struct sys_reg_desc *r)
> > +{
> > +	struct arm_pmu *cpu_pmu = vcpu->kvm->arch.arm_pmu;
> > +
> > +	if (p->is_write)
> > +		return write_to_read_only(vcpu, p, r);
> > +
> > +	if (check_pmu_access_disabled(vcpu, 0))
> > +		return false;

Also, we don't need this check. PMMIR_EL1 is UNDEF at EL0 so we should
never take a trap from userspace. Same goes for access_pminten() which
is where this probably came from.

> > +	p->regval = cpu_pmu->reg_pmmir & ARMV8_PMU_SLOTS;
> > +	return true;
> > +}
> > +
> 
> We can't change the value of PMMIR_EL1 unconditionally since older KVM
> treated this register as RAZ/WI. This also mixes poorly with the default
> PMU garbage that we have since as the value of the register can change
> based on where KVM_ARM_VCPU_INIT gets called...
> 
> Considering everything, I'd like to see this wired up where:
> 
>  - PMMIR_EL1.SLOTS takes the value of the underlying hardware PMU only
>    if the VMM explicitly selects a particular PMU implementation
> 
>  - KVM allows userspace to set PMMIR_EL1.SLOTS=0 for backwards
>    compatibility
> 
> Thanks,
> Oliver
>

Thanks,
Oliver

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] KVM: arm64: Expose PMMIR_EL1.SLOTS to guests
  2026-06-01 19:39 [PATCH] KVM: arm64: Expose PMMIR_EL1.SLOTS to guests Congkai Tan
  2026-06-01 20:06 ` Oliver Upton
@ 2026-06-02  4:14 ` kernel test robot
  1 sibling, 0 replies; 6+ messages in thread
From: kernel test robot @ 2026-06-02  4:14 UTC (permalink / raw)
  To: Congkai Tan, kvmarm, linux-arm-kernel
  Cc: oe-kbuild-all, Congkai Tan, Marc Zyngier, Oliver Upton,
	Joey Gouly, Suzuki K Poulose, Zenghui Yu, Catalin Marinas,
	Will Deacon, Mark Rutland, Haris Okanovic, Geoff Blake,
	linux-kernel

Hi Congkai,

kernel test robot noticed the following build errors:

[auto build test ERROR on 1702da76e017ae0fbe1a92b07bc332972c293e89]

url:    https://github.com/intel-lab-lkp/linux/commits/Congkai-Tan/KVM-arm64-Expose-PMMIR_EL1-SLOTS-to-guests/20260602-034527
base:   1702da76e017ae0fbe1a92b07bc332972c293e89
patch link:    https://lore.kernel.org/r/20260601193954.2103455-1-congkai%40amazon.com
patch subject: [PATCH] KVM: arm64: Expose PMMIR_EL1.SLOTS to guests
config: arm64-randconfig-r123-20260602 (https://download.01.org/0day-ci/archive/20260602/202606021209.2lvgE216-lkp@intel.com/config)
compiler: aarch64-linux-gcc (GCC) 11.5.0
sparse: v0.6.5-rc1
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260602/202606021209.2lvgE216-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202606021209.2lvgE216-lkp@intel.com/

All errors (new ones prefixed by >>):

   arch/arm64/kvm/sys_regs.c: In function 'access_pmmir':
>> arch/arm64/kvm/sys_regs.c:1391:28: error: invalid use of undefined type 'struct arm_pmu'
    1391 |         p->regval = cpu_pmu->reg_pmmir & ARMV8_PMU_SLOTS;
         |                            ^~


vim +1391 arch/arm64/kvm/sys_regs.c

  1373	
  1374	/*
  1375	 * Expose only PMMIR_EL1.SLOTS to the guest, which is consumed by perf in its
  1376	 * topdown default metric group. Other PMMIR_EL1 fields remain RAZ. Future
  1377	 * patches can extend the exposed mask incrementally as KVM gains support for
  1378	 * those features.
  1379	 */
  1380	static bool access_pmmir(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
  1381				 const struct sys_reg_desc *r)
  1382	{
  1383		struct arm_pmu *cpu_pmu = vcpu->kvm->arch.arm_pmu;
  1384	
  1385		if (p->is_write)
  1386			return write_to_read_only(vcpu, p, r);
  1387	
  1388		if (check_pmu_access_disabled(vcpu, 0))
  1389			return false;
  1390	
> 1391		p->regval = cpu_pmu->reg_pmmir & ARMV8_PMU_SLOTS;
  1392		return true;
  1393	}
  1394	

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] KVM: arm64: Expose PMMIR_EL1.SLOTS to guests
  2026-06-01 20:06 ` Oliver Upton
  2026-06-01 20:13   ` Oliver Upton
@ 2026-06-08 21:03   ` Congkai Tan
  2026-06-09  4:54     ` Oliver Upton
  1 sibling, 1 reply; 6+ messages in thread
From: Congkai Tan @ 2026-06-08 21:03 UTC (permalink / raw)
  To: oupton
  Cc: blakgeof, catalin.marinas, congkai, harisokn, joey.gouly, kvmarm,
	linux-arm-kernel, linux-kernel, mark.rutland, maz, suzuki.poulose,
	will, yuzenghui

On Mon, Jun 01, 2026 at 01:06:17PM -0700, Oliver Upton wrote:
> We can't change the value of PMMIR_EL1 unconditionally since older KVM
> treated this register as RAZ/WI. This also mixes poorly with the default
> PMU garbage that we have since as the value of the register can change
> based on where KVM_ARM_VCPU_INIT gets called...
>
> Considering everything, I'd like to see this wired up where:
>
>  - PMMIR_EL1.SLOTS takes the value of the underlying hardware PMU only
>    if the VMM explicitly selects a particular PMU implementation
>
>  - KVM allows userspace to set PMMIR_EL1.SLOTS=0 for backwards
>    compatibility

Thanks a lot for the review! Makes sense. We'll work on v2, and here is
the high-level design we plan to follow:

  - Introduce a new VM-wide field, e.g. kvm->arch.pmmir_slots.

  - Seed it from the underlying hardware value only when handling
    KVM_ARM_VCPU_PMU_V3_SET_PMU; otherwise it stays 0.

  - access_pmmir() returns whatever is in pmmir_slots.
  
  - set_pmmir() writes pmmir_slots to 0 if the user input is 0;
    otherwise it no-ops or rejects.

This way the guest only sees the underlying hardware value if the VMM
selects a PMU via KVM_ARM_VCPU_PMU_V3_SET_PMU, and userspace can pin
SLOTS = 0 through KVM_SET_ONE_REG for backwards compatibility.

Please let me know if there are any concerns. I'll send v2 once it's
ready.

Thanks,
Congkai

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] KVM: arm64: Expose PMMIR_EL1.SLOTS to guests
  2026-06-08 21:03   ` Congkai Tan
@ 2026-06-09  4:54     ` Oliver Upton
  0 siblings, 0 replies; 6+ messages in thread
From: Oliver Upton @ 2026-06-09  4:54 UTC (permalink / raw)
  To: Congkai Tan
  Cc: blakgeof, catalin.marinas, harisokn, joey.gouly, kvmarm,
	linux-arm-kernel, linux-kernel, mark.rutland, maz, suzuki.poulose,
	will, yuzenghui

On Mon, Jun 08, 2026 at 09:03:59PM +0000, Congkai Tan wrote:
> On Mon, Jun 01, 2026 at 01:06:17PM -0700, Oliver Upton wrote:
> > We can't change the value of PMMIR_EL1 unconditionally since older KVM
> > treated this register as RAZ/WI. This also mixes poorly with the default
> > PMU garbage that we have since as the value of the register can change
> > based on where KVM_ARM_VCPU_INIT gets called...
> >
> > Considering everything, I'd like to see this wired up where:
> >
> >  - PMMIR_EL1.SLOTS takes the value of the underlying hardware PMU only
> >    if the VMM explicitly selects a particular PMU implementation
> >
> >  - KVM allows userspace to set PMMIR_EL1.SLOTS=0 for backwards
> >    compatibility
> 
> Thanks a lot for the review! Makes sense. We'll work on v2, and here is
> the high-level design we plan to follow:
> 
>   - Introduce a new VM-wide field, e.g. kvm->arch.pmmir_slots.
> 
>   - Seed it from the underlying hardware value only when handling
>     KVM_ARM_VCPU_PMU_V3_SET_PMU; otherwise it stays 0.
> 
>   - access_pmmir() returns whatever is in pmmir_slots.
>   
>   - set_pmmir() writes pmmir_slots to 0 if the user input is 0;
>     otherwise it no-ops or rejects.

Reject is always better heh :)

So I was previously under the impression that we already expose PMMIR_EL1
to userspace but we actually don't. Grr.

The UAPI around PMUv3 is crappy enough that we should just add a new
vCPU feature flag. When that flag is set:

 - KVM will not create a 'default' PMU, userspace must select a PMU
   implementation to init the vCPU

 - PMMIR_EL1 becomes a user-visible register with the behavior that you
   outline above

 - No PMCEID masking for STALL_SLOT* events

There's a couple larger PMU features underway (e.g. Colton's partitioned
PMU, Akihiko's fixed counters PMU) that we can also condition on the new
feature flag.

Does this sound OK to you?

Thanks,
Oliver

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-06-09  4:54 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-01 19:39 [PATCH] KVM: arm64: Expose PMMIR_EL1.SLOTS to guests Congkai Tan
2026-06-01 20:06 ` Oliver Upton
2026-06-01 20:13   ` Oliver Upton
2026-06-08 21:03   ` Congkai Tan
2026-06-09  4:54     ` Oliver Upton
2026-06-02  4:14 ` kernel test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox