From: Colton Lewis <coltonlewis@google.com>
To: kvm@vger.kernel.org
Cc: Paolo Bonzini <pbonzini@redhat.com>,
Jonathan Corbet <corbet@lwn.net>,
Russell King <linux@armlinux.org.uk>,
Catalin Marinas <catalin.marinas@arm.com>,
Will Deacon <will@kernel.org>, Marc Zyngier <maz@kernel.org>,
Oliver Upton <oliver.upton@linux.dev>,
Mingwei Zhang <mizhang@google.com>,
Joey Gouly <joey.gouly@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Zenghui Yu <yuzenghui@huawei.com>,
Mark Rutland <mark.rutland@arm.com>,
Shuah Khan <shuah@kernel.org>,
linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev,
linux-perf-users@vger.kernel.org,
linux-kselftest@vger.kernel.org,
Colton Lewis <coltonlewis@google.com>
Subject: [PATCH v3 21/22] KVM: arm64: Add ioctl to partition the PMU when supported
Date: Thu, 26 Jun 2025 20:04:57 +0000 [thread overview]
Message-ID: <20250626200459.1153955-22-coltonlewis@google.com> (raw)
In-Reply-To: <20250626200459.1153955-1-coltonlewis@google.com>
Add KVM_ARM_PMU_PARTITION to enable the partitioned PMU for a given
vCPU. Add a corresponding KVM_CAP_ARM_PMU_PARTITION to check for this
ability. This capability is allowed on an initialized vCPU where PMUv3
and VHE are supported.
However, because the underlying ability relies on the driver being
passed some command line arguments to configure the hardware partition
at boot, enabling the partitioned PMU will not be allowed without the
underlying driver configuration even though the capability exists.
Signed-off-by: Colton Lewis <coltonlewis@google.com>
---
Documentation/virt/kvm/api.rst | 21 +++++++++++++++++++++
arch/arm64/include/asm/kvm_host.h | 3 +++
arch/arm64/kvm/arm.c | 20 ++++++++++++++++++++
arch/arm64/kvm/pmu-part.c | 3 ++-
include/uapi/linux/kvm.h | 4 ++++
5 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index 4ef3d8482000..7e76f7c87598 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -6478,6 +6478,27 @@ the capability to be present.
`flags` must currently be zero.
+4.144 KVM_ARM_PARTITION_PMU
+---------------------------
+
+:Capability: KVM_CAP_ARM_PARTITION_PMU
+:Architectures: arm64
+:Type: vcpu ioctl
+:Parameters: arg[0] is a boolean to enable the partitioned PMU
+
+This API controls the PMU implementation used for VMs. The capability
+is only available if the host PMUv3 driver was configured for
+partitioning via the module parameters `arm-pmuv3.partition_pmu=y` and
+`arm-pmuv3.reserved_guest_counters=[0-$NR_COUNTERS]`. When enabled,
+VMs are configured to have direct hardware access to the most
+frequently used registers for the counters configured by the
+aforementioned module parameters, bypassing the KVM traps in the
+standard emulated PMU implementation and reducing overhead of any
+guest software that uses PMU capabilities such as `perf`.
+
+If the host driver was configured for partitioning but the partitioned
+PMU is disabled through this interface, the VM will use the legacy PMU
+that shares the host partition.
.. _kvm_run:
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 2df76689381a..3f835b28c855 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -369,6 +369,9 @@ struct kvm_arch {
/* Maximum number of counters for the guest */
u8 nr_pmu_counters;
+ /* Whether this guest uses the partitioned PMU */
+ bool partitioned_pmu_enable;
+
/* Iterator for idreg debugfs */
u8 idreg_debugfs_iter;
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 7c007ee44ecb..cb4380f39d98 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -21,6 +21,7 @@
#include <linux/irqbypass.h>
#include <linux/sched/stat.h>
#include <linux/psci.h>
+#include <linux/perf/arm_pmu.h>
#include <trace/events/kvm.h>
#define CREATE_TRACE_POINTS
@@ -38,6 +39,7 @@
#include <asm/kvm_emulate.h>
#include <asm/kvm_mmu.h>
#include <asm/kvm_nested.h>
+#include <asm/kvm_pmu.h>
#include <asm/kvm_pkvm.h>
#include <asm/kvm_pmu.h>
#include <asm/kvm_ptrauth.h>
@@ -383,6 +385,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
case KVM_CAP_ARM_PMU_V3:
r = kvm_supports_guest_pmuv3();
break;
+ case KVM_CAP_ARM_PARTITION_PMU:
+ r = kvm_pmu_partition_supported();
+ break;
case KVM_CAP_ARM_INJECT_SERROR_ESR:
r = cpus_have_final_cap(ARM64_HAS_RAS_EXTN);
break;
@@ -1810,6 +1815,21 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
return kvm_arm_vcpu_finalize(vcpu, what);
}
+ case KVM_ARM_PARTITION_PMU: {
+ bool enable;
+
+ if (unlikely(!kvm_vcpu_initialized(vcpu)))
+ return -ENOEXEC;
+
+ if (!kvm_pmu_is_partitioned(vcpu->kvm->arch.arm_pmu))
+ return -EPERM;
+
+ if (copy_from_user(&enable, argp, sizeof(enable)))
+ return -EFAULT;
+
+ vcpu->kvm->arch.partitioned_pmu_enable = enable;
+ return 0;
+ }
default:
r = -EINVAL;
}
diff --git a/arch/arm64/kvm/pmu-part.c b/arch/arm64/kvm/pmu-part.c
index 165d1eae2634..7b5c5fcc6623 100644
--- a/arch/arm64/kvm/pmu-part.c
+++ b/arch/arm64/kvm/pmu-part.c
@@ -53,7 +53,8 @@ bool kvm_pmu_is_partitioned(struct arm_pmu *pmu)
*/
bool kvm_vcpu_pmu_is_partitioned(struct kvm_vcpu *vcpu)
{
- return kvm_pmu_is_partitioned(vcpu->kvm->arch.arm_pmu);
+ return kvm_pmu_is_partitioned(vcpu->kvm->arch.arm_pmu)
+ && vcpu->kvm->arch.partitioned_pmu_enable;
}
/**
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index c74cf8f73337..2f8a8d4cfe3c 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -935,6 +935,7 @@ struct kvm_enable_cap {
#define KVM_CAP_ARM_EL2_E2H0 241
#define KVM_CAP_RISCV_MP_STATE_RESET 242
#define KVM_CAP_GMEM_SHARED_MEM 243
+#define KVM_CAP_ARM_PARTITION_PMU 244
struct kvm_irq_routing_irqchip {
__u32 irqchip;
@@ -1413,6 +1414,9 @@ struct kvm_enc_region {
#define KVM_GET_SREGS2 _IOR(KVMIO, 0xcc, struct kvm_sregs2)
#define KVM_SET_SREGS2 _IOW(KVMIO, 0xcd, struct kvm_sregs2)
+/* Available with KVM_CAP_ARM_PARTITION_PMU */
+#define KVM_ARM_PARTITION_PMU _IOWR(KVMIO, 0xce, bool)
+
#define KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE (1 << 0)
#define KVM_DIRTY_LOG_INITIALLY_SET (1 << 1)
--
2.50.0.727.gbf7dc18ff4-goog
next prev parent reply other threads:[~2025-06-26 20:06 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-26 20:04 [PATCH v3 00/22] ARM64 PMU Partitioning Colton Lewis
2025-06-26 20:04 ` [PATCH v3 01/22] arm64: cpufeature: Add cpucap for HPMN0 Colton Lewis
2025-07-07 16:05 ` Mark Rutland
2025-07-08 22:34 ` Colton Lewis
2025-06-26 20:04 ` [PATCH v3 02/22] arm64: Generate sign macro for sysreg Enums Colton Lewis
2025-06-27 9:04 ` Ben Horgan
2025-06-27 20:45 ` Colton Lewis
2025-06-27 20:55 ` Oliver Upton
2025-06-30 17:42 ` Colton Lewis
2025-06-27 13:23 ` Marc Zyngier
2025-07-07 16:07 ` Mark Rutland
2025-06-26 20:04 ` [PATCH v3 03/22] KVM: arm64: Define PMI{CNTR,FILTR}_EL0 as undef_access Colton Lewis
2025-06-27 13:31 ` Marc Zyngier
2025-06-27 20:45 ` Colton Lewis
2025-06-26 20:04 ` [PATCH v3 04/22] KVM: arm64: Cleanup PMU includes Colton Lewis
2025-07-07 16:13 ` Mark Rutland
2025-07-08 22:37 ` Colton Lewis
2025-06-26 20:04 ` [PATCH v3 05/22] KVM: arm64: Reorganize PMU functions Colton Lewis
2025-06-26 20:04 ` [PATCH v3 06/22] perf: arm_pmuv3: Introduce method to partition the PMU Colton Lewis
2025-07-07 16:57 ` Mark Rutland
2025-07-07 19:07 ` Oliver Upton
2025-07-08 22:38 ` Colton Lewis
2025-07-08 22:41 ` Oliver Upton
2025-06-26 20:04 ` [PATCH v3 07/22] perf: arm_pmuv3: Generalize counter bitmasks Colton Lewis
2025-07-07 16:58 ` Mark Rutland
2025-07-08 22:38 ` Colton Lewis
2025-06-26 20:04 ` [PATCH v3 08/22] perf: arm_pmuv3: Keep out of guest counter partition Colton Lewis
2025-06-26 20:04 ` [PATCH v3 09/22] KVM: arm64: Correct kvm_arm_pmu_get_max_counters() Colton Lewis
2025-06-27 13:36 ` Marc Zyngier
2025-06-30 17:42 ` Colton Lewis
2025-06-26 20:04 ` [PATCH v3 10/22] KVM: arm64: Set up FGT for Partitioned PMU Colton Lewis
2025-06-27 15:01 ` Marc Zyngier
2025-06-27 20:45 ` Colton Lewis
2025-06-28 8:25 ` Marc Zyngier
2025-06-26 20:04 ` [PATCH v3 11/22] KVM: arm64: Writethrough trapped PMEVTYPER register Colton Lewis
2025-06-26 20:04 ` [PATCH v3 12/22] KVM: arm64: Use physical PMSELR for PMXEVTYPER if partitioned Colton Lewis
2025-06-26 20:04 ` [PATCH v3 13/22] KVM: arm64: Writethrough trapped PMOVS register Colton Lewis
2025-06-26 20:04 ` [PATCH v3 14/22] KVM: arm64: Write fast path PMU register handlers Colton Lewis
2025-06-26 20:04 ` [PATCH v3 15/22] KVM: arm64: Setup MDCR_EL2 to handle a partitioned PMU Colton Lewis
2025-06-26 20:04 ` [PATCH v3 16/22] KVM: arm64: Account for partitioning in PMCR_EL0 access Colton Lewis
2025-06-26 20:04 ` [PATCH v3 17/22] KVM: arm64: Context swap Partitioned PMU guest registers Colton Lewis
2025-06-26 20:04 ` [PATCH v3 18/22] KVM: arm64: Enforce PMU event filter at vcpu_load() Colton Lewis
2025-06-26 20:04 ` [PATCH v3 19/22] perf: arm_pmuv3: Handle IRQs for Partitioned PMU guest counters Colton Lewis
2025-06-26 20:04 ` [PATCH v3 20/22] KVM: arm64: Inject recorded guest interrupts Colton Lewis
2025-06-26 20:04 ` Colton Lewis [this message]
2025-06-26 20:04 ` [PATCH v3 22/22] KVM: arm64: selftests: Add test case for partitioned PMU 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=20250626200459.1153955-22-coltonlewis@google.com \
--to=coltonlewis@google.com \
--cc=catalin.marinas@arm.com \
--cc=corbet@lwn.net \
--cc=joey.gouly@arm.com \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-doc@vger.kernel.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=mizhang@google.com \
--cc=oliver.upton@linux.dev \
--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;
as well as URLs for NNTP newsgroup(s).