From: Oliver Upton <oliver.upton@linux.dev>
To: Colton Lewis <coltonlewis@google.com>
Cc: kvm@vger.kernel.org, Russell King <linux@armlinux.org.uk>,
Catalin Marinas <catalin.marinas@arm.com>,
Will Deacon <will@kernel.org>, Marc Zyngier <maz@kernel.org>,
Joey Gouly <joey.gouly@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Zenghui Yu <yuzenghui@huawei.com>,
Mark Rutland <mark.rutland@arm.com>,
Paolo Bonzini <pbonzini@redhat.com>,
Shuah Khan <shuah@kernel.org>,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, kvmarm@lists.linux.dev,
linux-perf-users@vger.kernel.org,
linux-kselftest@vger.kernel.org
Subject: Re: [RFC PATCH v2 4/4] KVM: arm64: Make guests see only counters they can access
Date: Sun, 9 Feb 2025 23:37:45 -0800 [thread overview]
Message-ID: <Z6msyUG0HWM2EImQ@linux.dev> (raw)
In-Reply-To: <20250208020111.2068239-5-coltonlewis@google.com>
On Sat, Feb 08, 2025 at 02:01:11AM +0000, Colton Lewis wrote:
> The ARM architecture specifies that when MDCR_EL2.HPMN is set, EL1 and
> EL0, which includes KVM guests, should read that value for PMCR.N.
>
> Signed-off-by: Colton Lewis <coltonlewis@google.com>
> ---
> arch/arm64/kvm/debug.c | 3 +--
> arch/arm64/kvm/pmu-emul.c | 8 +++++++-
> tools/testing/selftests/kvm/arm64/vpmu_counter_access.c | 2 +-
> 3 files changed, 9 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
> index 0e4c805e7e89..7c04db00bf6c 100644
> --- a/arch/arm64/kvm/debug.c
> +++ b/arch/arm64/kvm/debug.c
> @@ -36,8 +36,7 @@ static void kvm_arm_setup_mdcr_el2(struct kvm_vcpu *vcpu)
> * This also clears MDCR_EL2_E2PB_MASK and MDCR_EL2_E2TB_MASK
> * to disable guest access to the profiling and trace buffers
> */
> - vcpu->arch.mdcr_el2 = FIELD_PREP(MDCR_EL2_HPMN,
> - *host_data_ptr(nr_event_counters));
> + vcpu->arch.mdcr_el2 = FIELD_PREP(MDCR_EL2_HPMN, read_mdcr());
Please avoid unnecessary accesses to MDCR_EL2 at all costs. This is a
guaranteed trap to EL2 with nested virt.
> vcpu->arch.mdcr_el2 |= (MDCR_EL2_TPM |
> MDCR_EL2_TPMS |
> MDCR_EL2_TTRF |
> diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
> index 6c5950b9ceac..052ce8c721fe 100644
> --- a/arch/arm64/kvm/pmu-emul.c
> +++ b/arch/arm64/kvm/pmu-emul.c
> @@ -993,12 +993,18 @@ static bool pmu_irq_is_valid(struct kvm *kvm, int irq)
> u8 kvm_arm_pmu_get_max_counters(struct kvm *kvm)
> {
> struct arm_pmu *arm_pmu = kvm->arch.arm_pmu;
> + u8 limit;
> +
> + if (arm_pmu->partitioned)
> + limit = arm_pmu->hpmn - 1;
> + else
> + limit = ARMV8_PMU_MAX_GENERAL_COUNTERS;
>
> /*
> * The arm_pmu->cntr_mask considers the fixed counter(s) as well.
> * Ignore those and return only the general-purpose counters.
> */
> - return bitmap_weight(arm_pmu->cntr_mask, ARMV8_PMU_MAX_GENERAL_COUNTERS);
> + return bitmap_weight(arm_pmu->cntr_mask, limit);
> }
This isn't necessary and is likely to regress the existing behavior.
When the architecture says the lower ELs should see PMCR_EL0.N have the
same value as MDCR_EL2.HPMN, what it really means is direct reads from
hardware will return the value.
So my expectation would be that a VM using the partitioned PMU
implementation would never reach any of the *emulated* PMU handlers, as
we would've disabled the associated traps.
The partitioned PMU will not replace the emulated vPMU implementation in
KVM, so it'd be good to refactor what we have today to make room for
your work. I think that'd be along the lines of:
- Shared code for event filter enforcement and handling of the vPMU
overflow IRQ.
- Emulated PMU implementation that provides trap handlers for all PMUv3
registers and backs into host perf
- Partitioned PMU implementation that doesn't rely on traps and instead
saves / restores a portion of the PMU that contains the guest
context.
These should be done in separate files, i.e. I do not want to see a
bunch of inline handling to cope with emulated v. partitioned PMUs.
> static void kvm_arm_set_pmu(struct kvm *kvm, struct arm_pmu *arm_pmu)
> diff --git a/tools/testing/selftests/kvm/arm64/vpmu_counter_access.c b/tools/testing/selftests/kvm/arm64/vpmu_counter_access.c
> index f16b3b27e32e..b5bc18b7528d 100644
> --- a/tools/testing/selftests/kvm/arm64/vpmu_counter_access.c
> +++ b/tools/testing/selftests/kvm/arm64/vpmu_counter_access.c
> @@ -609,7 +609,7 @@ static void run_pmregs_validity_test(uint64_t pmcr_n)
> */
> static void run_error_test(uint64_t pmcr_n)
> {
> - pr_debug("Error test with pmcr_n %lu (larger than the host)\n", pmcr_n);
> + pr_debug("Error test with pmcr_n %lu (larger than the host allows)\n", pmcr_n);
NBD for an RFC, but in the future please do selftests changes in a
separate patch.
--
Thanks,
Oliver
next prev parent reply other threads:[~2025-02-10 7:38 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-08 2:01 [RFC PATCH v2 0/4] PMU partitioning driver support Colton Lewis
2025-02-08 2:01 ` [RFC PATCH v2 1/4] perf: arm_pmuv3: Generalize counter bitmasks Colton Lewis
2025-02-08 2:01 ` [RFC PATCH v2 2/4] perf: arm_pmuv3: Introduce module param to partition the PMU Colton Lewis
2025-02-10 7:25 ` Oliver Upton
2025-02-10 23:07 ` Colton Lewis
2025-02-08 2:01 ` [RFC PATCH v2 3/4] perf: arm_pmuv3: Keep out of guest counter partition Colton Lewis
2025-02-08 2:01 ` [RFC PATCH v2 4/4] KVM: arm64: Make guests see only counters they can access Colton Lewis
2025-02-10 7:37 ` Oliver Upton [this message]
2025-02-10 23:08 ` Colton Lewis
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Z6msyUG0HWM2EImQ@linux.dev \
--to=oliver.upton@linux.dev \
--cc=catalin.marinas@arm.com \
--cc=coltonlewis@google.com \
--cc=joey.gouly@arm.com \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=mark.rutland@arm.com \
--cc=maz@kernel.org \
--cc=pbonzini@redhat.com \
--cc=shuah@kernel.org \
--cc=suzuki.poulose@arm.com \
--cc=will@kernel.org \
--cc=yuzenghui@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox