[PATCH v2 06/14] KVM: arm64: Remap PMUv3 events onto hardware

Oliver Upton posted 14 patches 10 months, 2 weeks ago
[PATCH v2 06/14] KVM: arm64: Remap PMUv3 events onto hardware
Posted by Oliver Upton 10 months, 2 weeks ago
Use the provided helper to map PMUv3 event IDs onto hardware, if the
driver exposes such a helper. This is expected to be quite rare, and
only useful for non-PMUv3 hardware.

Tested-by: Janne Grunau <j@jannau.net>
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
 arch/arm64/kvm/pmu-emul.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index 62349b670cf9..60cf973e2af9 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -673,6 +673,18 @@ static bool kvm_pmc_counts_at_el2(struct kvm_pmc *pmc)
 	return kvm_pmc_read_evtreg(pmc) & ARMV8_PMU_INCLUDE_EL2;
 }
 
+static u64 kvm_map_pmu_event(struct kvm *kvm, u64 eventsel)
+{
+	struct arm_pmu *pmu = kvm->arch.arm_pmu;
+	int hw_event;
+
+	if (!pmu->map_pmuv3_event)
+		return eventsel;
+
+	hw_event = pmu->map_pmuv3_event(eventsel);
+	return (hw_event < 0) ? eventsel : hw_event;
+}
+
 /**
  * kvm_pmu_create_perf_event - create a perf event for a counter
  * @pmc: Counter context
@@ -711,13 +723,13 @@ static void kvm_pmu_create_perf_event(struct kvm_pmc *pmc)
 
 	memset(&attr, 0, sizeof(struct perf_event_attr));
 	attr.type = arm_pmu->pmu.type;
+	attr.config = kvm_map_pmu_event(vcpu->kvm, eventsel);
 	attr.size = sizeof(attr);
 	attr.pinned = 1;
 	attr.disabled = !kvm_pmu_counter_is_enabled(pmc);
 	attr.exclude_user = !kvm_pmc_counts_at_el0(pmc);
 	attr.exclude_hv = 1; /* Don't count EL2 events */
 	attr.exclude_host = 1; /* Don't count host events */
-	attr.config = eventsel;
 
 	/*
 	 * Filter events at EL1 (i.e. vEL2) when in a hyp context based on the
-- 
2.39.5
Re: [PATCH v2 06/14] KVM: arm64: Remap PMUv3 events onto hardware
Posted by Marc Zyngier 10 months ago
On Mon, 03 Feb 2025 18:31:03 +0000,
Oliver Upton <oliver.upton@linux.dev> wrote:
> 
> Use the provided helper to map PMUv3 event IDs onto hardware, if the
> driver exposes such a helper. This is expected to be quite rare, and
> only useful for non-PMUv3 hardware.
> 
> Tested-by: Janne Grunau <j@jannau.net>
> Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
> ---
>  arch/arm64/kvm/pmu-emul.c | 14 +++++++++++++-
>  1 file changed, 13 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
> index 62349b670cf9..60cf973e2af9 100644
> --- a/arch/arm64/kvm/pmu-emul.c
> +++ b/arch/arm64/kvm/pmu-emul.c
> @@ -673,6 +673,18 @@ static bool kvm_pmc_counts_at_el2(struct kvm_pmc *pmc)
>  	return kvm_pmc_read_evtreg(pmc) & ARMV8_PMU_INCLUDE_EL2;
>  }
>  
> +static u64 kvm_map_pmu_event(struct kvm *kvm, u64 eventsel)
> +{
> +	struct arm_pmu *pmu = kvm->arch.arm_pmu;
> +	int hw_event;
> +
> +	if (!pmu->map_pmuv3_event)
> +		return eventsel;
> +
> +	hw_event = pmu->map_pmuv3_event(eventsel);
> +	return (hw_event < 0) ? eventsel : hw_event;

I find this a bit odd. If we can translate events, but failed to do
so, we still install the originally requested event, and we have no
idea what this maps to on the HW.

I'd rather we just don't install that event at all rather than
counting something random.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.
Re: [PATCH v2 06/14] KVM: arm64: Remap PMUv3 events onto hardware
Posted by Oliver Upton 10 months ago
On Wed, Feb 19, 2025 at 04:45:27PM +0000, Marc Zyngier wrote:
> On Mon, 03 Feb 2025 18:31:03 +0000,
> Oliver Upton <oliver.upton@linux.dev> wrote:
> > 
> > Use the provided helper to map PMUv3 event IDs onto hardware, if the
> > driver exposes such a helper. This is expected to be quite rare, and
> > only useful for non-PMUv3 hardware.
> > 
> > Tested-by: Janne Grunau <j@jannau.net>
> > Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
> > ---
> >  arch/arm64/kvm/pmu-emul.c | 14 +++++++++++++-
> >  1 file changed, 13 insertions(+), 1 deletion(-)
> > 
> > diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
> > index 62349b670cf9..60cf973e2af9 100644
> > --- a/arch/arm64/kvm/pmu-emul.c
> > +++ b/arch/arm64/kvm/pmu-emul.c
> > @@ -673,6 +673,18 @@ static bool kvm_pmc_counts_at_el2(struct kvm_pmc *pmc)
> >  	return kvm_pmc_read_evtreg(pmc) & ARMV8_PMU_INCLUDE_EL2;
> >  }
> >  
> > +static u64 kvm_map_pmu_event(struct kvm *kvm, u64 eventsel)
> > +{
> > +	struct arm_pmu *pmu = kvm->arch.arm_pmu;
> > +	int hw_event;
> > +
> > +	if (!pmu->map_pmuv3_event)
> > +		return eventsel;
> > +
> > +	hw_event = pmu->map_pmuv3_event(eventsel);
> > +	return (hw_event < 0) ? eventsel : hw_event;
> 
> I find this a bit odd. If we can translate events, but failed to do
> so, we still install the originally requested event, and we have no
> idea what this maps to on the HW.
> 
> I'd rather we just don't install that event at all rather than
> counting something random.

Heh, this was a leftover party trick that I was using to try "raw"
events from inside a VM. Happy to limit things to the PMUv3 event space
though.

Thanks,
Oliver