From nobody Tue Feb 10 22:00:05 2026 Received: from mail-oo1-f73.google.com (mail-oo1-f73.google.com [209.85.161.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CF5CC329368 for ; Mon, 9 Feb 2026 22:41:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770676868; cv=none; b=mdojoBrfS3eLfXNah4dpl+VmcFLPjLTKJhQDWMz+HaRNKB6Yd1htL9yefEjyJD7NpuYNyAgkf1ieWqC9ZxbUNeihmEh9b8wkShDyTRtUruV3yRy5uY4pL7aB/0N+FnxUCLeLv1FY84AftYEcBfpxEYbBj1XlEcvbtcTd1TT80qk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770676868; c=relaxed/simple; bh=IGbjYf4aDEdJzYqyHxQ48Lwc7zrh6q6MUfA91xc3mH0=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Sf4oeom1UY2uCB82NvjtkTALvjoKjltxGg2o8fqhI/oSNTwJiH57sbgnBhObl92FuKKv7gux3xROPgmMVZIhRFRFgUQkvxnB5usiqiKNVqeRPxZBrMXel/3/bn6TyLbpHW7ZMKw4OZdW1+9rnnG6r4TlCE0Ywro4WEVI8zu97Ao= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--coltonlewis.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=FCnRNsjs; arc=none smtp.client-ip=209.85.161.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--coltonlewis.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="FCnRNsjs" Received: by mail-oo1-f73.google.com with SMTP id 006d021491bc7-6630b0a016aso1063581eaf.0 for ; Mon, 09 Feb 2026 14:41:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1770676862; x=1771281662; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=I8vsvPCwrm4qK2tJSRhYymVMX8OUXdkNYkDGMZ9conM=; b=FCnRNsjsHKpi4R/Z7BA/JIekd/KAfoQtmFDSrv8v5si1BWF6MMUVNBl2FzT/GImE/M LgJJiXquTh4TlPkpWeLD66dJtESVNQHV4Gj5Qyz5lqcfPbi/tJNYq0XrSYttmzg3IqXA IV4eByYjAhn2icP6a2aPmoj4AuF22iTPl6B0DI5o8lOhILYmcDsWaNKHc5HVuej1F2qz hbflSOwydlkvf3j5Ip2XCVnN5oFbbVshcy62O7vZXYySJY8OuhUHrDBM6NaIesAEhEFU 9jCF002ElO1Tu079fNDi/fHk+H/tDw0A7TmuXfp8TpdGSLLssme/FNhxSTfUiTuuv6TB qDNg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770676862; x=1771281662; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=I8vsvPCwrm4qK2tJSRhYymVMX8OUXdkNYkDGMZ9conM=; b=EBBugRATPu0jrTDTkw6d66oyqwPaB2v9CJq8GbxZgF2Rn4Jonu8XzG5pLDYHeVS3G0 vFIpNjpmWkCPVsl4Z9QCtzCx9ztAdFQIDEbxtcXpy0Mxomh3q+FzvIDOtxLkLKb9Ajto UhkHkyrzy4JfBEmm8C/QT2h36O2guhHf740/+56S4+c+V8qL6M3oWzOwigT0IwtEKNMp P0/n8u03ppwygHs6zrwRMtUOwFNsS+2yTwjmwCnBcn2Os316ZBL+2xQbkAVMc22Fe0Sv yWFhopCc1sRKh4ZE1aCLyvHrS378RzzgaT+fkeSZgPVrSHdUtQMMTtjL8rkbSdh8CG9X Ytew== X-Forwarded-Encrypted: i=1; AJvYcCXULxUxCDfTybaynf0wbYKhgFVkByfa8OLdXy1FvDHhHTOiiK2i+5ax1U6qVKvrNoJuzajAj2mPEDy0x8U=@vger.kernel.org X-Gm-Message-State: AOJu0YwELnb4x/VJJSLKhD/nUmXUqcbQETe6wG7vvlEGe61CvnkH6MvP ehQQ5EvWeQIFHZRDggU/YyI0boW3NnegMSBxqeo0oTtQXBq2yOcRFlBuy9YTtjfEY8CO23F8ffl Ur1SGbg7XhAcw4y69rPchz2nymg== X-Received: from iomv22.prod.google.com ([2002:a5e:d716:0:b0:957:5d25:584]) (user=coltonlewis job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6820:1622:b0:662:f8f6:e8d1 with SMTP id 006d021491bc7-66d09ac24cdmr6817429eaf.6.1770676861761; Mon, 09 Feb 2026 14:41:01 -0800 (PST) Date: Mon, 9 Feb 2026 22:14:11 +0000 In-Reply-To: <20260209221414.2169465-1-coltonlewis@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260209221414.2169465-1-coltonlewis@google.com> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog Message-ID: <20260209221414.2169465-17-coltonlewis@google.com> Subject: [PATCH v6 16/19] KVM: arm64: Add vCPU device attr to partition the PMU From: Colton Lewis To: kvm@vger.kernel.org Cc: Alexandru Elisei , Paolo Bonzini , Jonathan Corbet , Russell King , Catalin Marinas , Will Deacon , Marc Zyngier , Oliver Upton , Mingwei Zhang , Joey Gouly , Suzuki K Poulose , Zenghui Yu , Mark Rutland , Shuah Khan , Ganapatrao Kulkarni , 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 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a new PMU device attr to enable the partitioned PMU for a given VM. This capability can be set when the PMU is initially configured before the vCPU starts running and is allowed where PMUv3 and VHE are supported and the host driver was configured with arm_pmuv3.reserved_host_counters. The enabled capability is tracked by the new flag KVM_ARCH_FLAG_PARTITIONED_PMU_ENABLED. Signed-off-by: Colton Lewis --- arch/arm64/include/asm/kvm_host.h | 2 ++ arch/arm64/include/uapi/asm/kvm.h | 2 ++ arch/arm64/kvm/pmu-direct.c | 35 ++++++++++++++++++++++++++++--- arch/arm64/kvm/pmu.c | 14 +++++++++++++ include/kvm/arm_pmu.h | 9 ++++++++ 5 files changed, 59 insertions(+), 3 deletions(-) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm= _host.h index 41577ede0254f..f0b0a5edc7252 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -353,6 +353,8 @@ struct kvm_arch { #define KVM_ARCH_FLAG_WRITABLE_IMP_ID_REGS 10 /* Unhandled SEAs are taken to userspace */ #define KVM_ARCH_FLAG_EXIT_SEA 11 + /* Partitioned PMU Enabled */ +#define KVM_ARCH_FLAG_PARTITION_PMU_ENABLED 12 unsigned long flags; =20 /* VM-wide vCPU feature set */ diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/as= m/kvm.h index a792a599b9d68..3e0b7619f781d 100644 --- a/arch/arm64/include/uapi/asm/kvm.h +++ b/arch/arm64/include/uapi/asm/kvm.h @@ -436,6 +436,8 @@ enum { #define KVM_ARM_VCPU_PMU_V3_FILTER 2 #define KVM_ARM_VCPU_PMU_V3_SET_PMU 3 #define KVM_ARM_VCPU_PMU_V3_SET_NR_COUNTERS 4 +#define KVM_ARM_VCPU_PMU_V3_ENABLE_PARTITION 5 + #define KVM_ARM_VCPU_TIMER_CTRL 1 #define KVM_ARM_VCPU_TIMER_IRQ_VTIMER 0 #define KVM_ARM_VCPU_TIMER_IRQ_PTIMER 1 diff --git a/arch/arm64/kvm/pmu-direct.c b/arch/arm64/kvm/pmu-direct.c index 6ebb59d2aa0e7..1dbf50b8891f6 100644 --- a/arch/arm64/kvm/pmu-direct.c +++ b/arch/arm64/kvm/pmu-direct.c @@ -44,8 +44,8 @@ bool kvm_pmu_is_partitioned(struct arm_pmu *pmu) } =20 /** - * kvm_vcpu_pmu_is_partitioned() - Determine if given VCPU has a partition= ed PMU - * @vcpu: Pointer to kvm_vcpu struct + * kvm_pmu_is_partitioned() - Determine if given VCPU has a partitioned PMU + * @kvm: Pointer to kvm_vcpu struct * * Determine if given VCPU has a partitioned PMU by extracting that * field and passing it to :c:func:`kvm_pmu_is_partitioned` @@ -55,7 +55,36 @@ 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) && - false; + test_bit(KVM_ARCH_FLAG_PARTITION_PMU_ENABLED, &vcpu->kvm->arch.flags); +} + +/** + * has_kvm_pmu_partition_support() - If we can enable/disable partition + * + * Return: true if allowed, false otherwise. + */ +bool has_kvm_pmu_partition_support(void) +{ + return has_host_pmu_partition_support() && + kvm_supports_guest_pmuv3() && + armv8pmu_max_guest_counters > -1; +} + +/** + * kvm_pmu_partition_enable() - Enable/disable partition flag + * @kvm: Pointer to vcpu + * @enable: Whether to enable or disable + * + * If we want to enable the partition, the guest is free to grab + * hardware by accessing PMU registers. Otherwise, the host maintains + * control. + */ +void kvm_pmu_partition_enable(struct kvm *kvm, bool enable) +{ + if (enable) + set_bit(KVM_ARCH_FLAG_PARTITION_PMU_ENABLED, &kvm->arch.flags); + else + clear_bit(KVM_ARCH_FLAG_PARTITION_PMU_ENABLED, &kvm->arch.flags); } =20 /** diff --git a/arch/arm64/kvm/pmu.c b/arch/arm64/kvm/pmu.c index 72d5b7cb3d93e..cdf51f24fdaf3 100644 --- a/arch/arm64/kvm/pmu.c +++ b/arch/arm64/kvm/pmu.c @@ -759,6 +759,19 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, str= uct kvm_device_attr *attr) =20 return kvm_arm_pmu_v3_set_nr_counters(vcpu, n); } + case KVM_ARM_VCPU_PMU_V3_ENABLE_PARTITION: { + unsigned int __user *uaddr =3D (unsigned int __user *)(long)attr->addr; + bool enable; + + if (get_user(enable, uaddr)) + return -EFAULT; + + if (!has_kvm_pmu_partition_support()) + return -EPERM; + + kvm_pmu_partition_enable(kvm, enable); + return 0; + } case KVM_ARM_VCPU_PMU_V3_INIT: return kvm_arm_pmu_v3_init(vcpu); } @@ -798,6 +811,7 @@ int kvm_arm_pmu_v3_has_attr(struct kvm_vcpu *vcpu, stru= ct kvm_device_attr *attr) case KVM_ARM_VCPU_PMU_V3_FILTER: case KVM_ARM_VCPU_PMU_V3_SET_PMU: case KVM_ARM_VCPU_PMU_V3_SET_NR_COUNTERS: + case KVM_ARM_VCPU_PMU_V3_ENABLE_PARTITION: if (kvm_vcpu_has_pmu(vcpu)) return 0; } diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h index 93586691a2790..ff898370fa63f 100644 --- a/include/kvm/arm_pmu.h +++ b/include/kvm/arm_pmu.h @@ -109,6 +109,8 @@ void kvm_pmu_load(struct kvm_vcpu *vcpu); void kvm_pmu_put(struct kvm_vcpu *vcpu); =20 void kvm_pmu_set_physical_access(struct kvm_vcpu *vcpu); +bool has_kvm_pmu_partition_support(void); +void kvm_pmu_partition_enable(struct kvm *kvm, bool enable); =20 #if !defined(__KVM_NVHE_HYPERVISOR__) bool kvm_vcpu_pmu_is_partitioned(struct kvm_vcpu *vcpu); @@ -311,6 +313,13 @@ static inline void kvm_pmu_host_counters_enable(void) = {} static inline void kvm_pmu_host_counters_disable(void) {} static inline void kvm_pmu_handle_guest_irq(struct arm_pmu *pmu, u64 pmovs= r) {} =20 +static inline bool has_kvm_pmu_partition_support(void) +{ + return false; +} + +static inline void kvm_pmu_partition_enable(struct kvm *kvm, bool enable) = {} + #endif =20 #endif --=20 2.53.0.rc2.204.g2597b5adb4-goog