From nobody Sat Jul 25 03:22:07 2026 Received: from www3579.sakura.ne.jp (www3579.sakura.ne.jp [49.212.243.89]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3B3F73A9DAE; Mon, 20 Jul 2026 05:39:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=49.212.243.89 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784525972; cv=none; b=VYqqD6GwdsdmzkRggrNUWiO4wttQ9aBwqMrGv3GTYzita5wDJJm114tvdQ7XNs3JWOpTO3UzBLAJaq7J1xNb9DaLL8NSY5CteF8hpIDGRE/Gm0daXxLti3Emm/4IRKio6RnHyCH4rhhCDxMIxxnuJQkBKwctPM8v3CWgXhOJuec= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784525972; c=relaxed/simple; bh=B/aTTBwSppIIw7reVtSzRCsQnZmIJ/JGamCuAzhFrHE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=PFSpTfSjUcG6pcttoILlWmD2wNJsCuQNx9i140WrS3ouleZ+ey7xvOKAQ6K81EgpWptJZrDZ++WToaEqXR3hgNY+xdEMqcMKZ2LQmApw+7cJWTTib+sBjB8Ax97Z3gA047lElbgm9EoEjJEPuZbmLxZ5Zxq5aKZx359toDIfkXQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp; spf=pass smtp.mailfrom=rsg.ci.i.u-tokyo.ac.jp; dkim=fail (0-bit key) header.d=rsg.ci.i.u-tokyo.ac.jp header.i=@rsg.ci.i.u-tokyo.ac.jp header.b=FjP2Zp/g reason="key not found in DNS"; arc=none smtp.client-ip=49.212.243.89 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rsg.ci.i.u-tokyo.ac.jp Authentication-Results: smtp.subspace.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=rsg.ci.i.u-tokyo.ac.jp header.i=@rsg.ci.i.u-tokyo.ac.jp header.b="FjP2Zp/g" Received: from h183.csg.ci.i.u-tokyo.ac.jp (h183.csg.ci.i.u-tokyo.ac.jp [133.11.54.183]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 66K5c7oj075973 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Mon, 20 Jul 2026 14:38:25 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=W4lqbbuFRL8zkHdtyIDwRkuJmQS4zljitCYbt4eFEpU=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Message-Id:To:Subject:Date; s=rs20250326; t=1784525905; v=1; b=FjP2Zp/gShL+KSdp17onx0WTPALVsK0YZkJSLbAHoGXn67MFLivI0gGT/lbQEZWk 1OTRjgJVtX/Cr4u0gJvYsYiQGfsDGm56wjMOC/FkJ0zVTZMp6FBghXTfn0go2lxU yn//GSzCNfOjb2owuSH25gD2PZ1dKi7AdhlAt16SLmWm9sCSMsKj0IKQp3jOSUK6 m4alfzGyQJg5oxh86XVKklL//pjBcdEGy0xMtq6uRFXrH0VNcrhUoGbT0zY3c1NN O4zStZHqi4B9zl177zBuF81j2NaT8zR5MGLDIczZgVQU/IVnr36xedlhA68Sbo22 S8e5EOp61Ph97PjdbQgWPg== From: Akihiko Odaki Date: Mon, 20 Jul 2026 14:37:55 +0900 Subject: [PATCH v9 01/16] KVM: arm64: Serialize repeated vCPU initialization Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260720-hybrid-v9-1-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> References: <20260720-hybrid-v9-0-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20260720-hybrid-v9-0-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> To: Marc Zyngier , Oliver Upton , Joey Gouly , Suzuki K Poulose , Zenghui Yu , Catalin Marinas , Will Deacon , Kees Cook , "Gustavo A. R. Silva" , Paolo Bonzini , Jonathan Corbet , Shuah Khan , Shuah Khan , Yury Norov , Rasmus Villemoes , Steffen Eiden Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, devel@daynix.com, kvm@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Akihiko Odaki X-Mailer: b4 0.16-dev-925f5 X-Developer-Signature: v=1; a=openpgp-sha256; l=2147; i=odaki@rsg.ci.i.u-tokyo.ac.jp; h=from:subject:message-id; bh=B/aTTBwSppIIw7reVtSzRCsQnZmIJ/JGamCuAzhFrHE=; b=owGbwMvMwCWmMbc20y1CyJDxtFoSQ1bsFqeYJVcEshYYc1SJLGk5GHSwSutY5GzVvw19XP/yt 5y7sNS6o5SFQYyLQVZMkSWlaDe3RnTtp8KE+BaYOaxMIEMYuDgFYCIP9Bj+ym2ouDvLa29bkRGX +KmyeGa2p0/jLG72XejufW2vZjxRhZHh0jTR06ZXvzTefuA1Mavej/PskiSuGbyu87e1Tv2Y8lC WGwA= X-Developer-Key: i=odaki@rsg.ci.i.u-tokyo.ac.jp; a=openpgp; fpr=AEDC03C9AF734F2EC26A7BFFA4BAEAA73536753C The initial KVM_ARM_VCPU_INIT path holds config_lock while resetting the vCPU, but repeated initialization of an existing vCPU does not. As a result, reset_mdcr() can race with VM-wide PMU configuration and overwrite MDCR_EL2 with a stale counter count. Take config_lock around the repeated-init checks and reset. The vCPU ioctl already holds vcpu->mutex, matching the established lock ordering. Fixes: c8823e51b534 ("KVM: arm64: Fix MDCR_EL2.HPMN reset value") Closes: https://sashiko.dev/#/patchset/20260710-hybrid-v8-0-621409f3a592@rs= g.ci.i.u-tokyo.ac.jp?part=3D1 Assisted-by: Codex:gpt-5.6-sol Signed-off-by: Akihiko Odaki --- arch/arm64/kvm/arm.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 50adfff75be8..a06ea39f57b1 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -1652,29 +1652,26 @@ static int __kvm_vcpu_set_target(struct kvm_vcpu *v= cpu, { unsigned long features =3D init->features[0]; struct kvm *kvm =3D vcpu->kvm; - int ret =3D -EINVAL; + int ret; =20 - mutex_lock(&kvm->arch.config_lock); + lockdep_assert_held(&kvm->arch.config_lock); =20 if (test_bit(KVM_ARCH_FLAG_VCPU_FEATURES_CONFIGURED, &kvm->arch.flags) && kvm_vcpu_init_changed(vcpu, init)) - goto out_unlock; + return -EINVAL; =20 bitmap_copy(kvm->arch.vcpu_features, &features, KVM_VCPU_MAX_FEATURES); =20 ret =3D kvm_setup_vcpu(vcpu); if (ret) - goto out_unlock; + return ret; =20 /* Now we know what it is, we can reset it. */ kvm_reset_vcpu(vcpu); =20 set_bit(KVM_ARCH_FLAG_VCPU_FEATURES_CONFIGURED, &kvm->arch.flags); vcpu_set_flag(vcpu, VCPU_INITIALIZED); - ret =3D 0; -out_unlock: - mutex_unlock(&kvm->arch.config_lock); - return ret; + return 0; } =20 static int kvm_vcpu_set_target(struct kvm_vcpu *vcpu, @@ -1690,6 +1687,8 @@ static int kvm_vcpu_set_target(struct kvm_vcpu *vcpu, if (ret) return ret; =20 + guard(mutex)(&vcpu->kvm->arch.config_lock); + if (!kvm_vcpu_initialized(vcpu)) return __kvm_vcpu_set_target(vcpu, init); =20 --=20 2.55.0 From nobody Sat Jul 25 03:22:07 2026 Received: from www3579.sakura.ne.jp (www3579.sakura.ne.jp [49.212.243.89]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9759A3AB26D; Mon, 20 Jul 2026 05:39:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=49.212.243.89 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784525972; cv=none; b=A2M95avSo3FereHzVAuAS53NGwbuuTqDh407LdsGuf39/t5bypCNDIH4TbWjpU3We6M6LIEI719HEZ/uBeNLTCgDNG4zWJT274d+aZ08jHAaAjasONPSdtQKiSvdEyIkEX32I/AVXWcdqOINtmqOG7r7QD2wv9VSr8T6iGT4Bs0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784525972; c=relaxed/simple; bh=nVWYQRDoBQAI06C2RUbthgzk2Kfs5Hf1NWsam/Gw8DY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Y5BGpiW+PFdzCUMcfhxzaAhMnZ0/pZA2l5VLLJx3ohcRZAdToC4GsC8ayVtTHYOt8yRkR/I4urFITYNEfWSfnVWpA1N4FLBgHb2up0xknDasH20GTSZThKrKxi5yxUpXpr9RhEQbwl9TNwxJ8Ao7BD2pk4kYUmX9mUXSVGcIuV8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp; spf=pass smtp.mailfrom=rsg.ci.i.u-tokyo.ac.jp; dkim=fail (0-bit key) header.d=rsg.ci.i.u-tokyo.ac.jp header.i=@rsg.ci.i.u-tokyo.ac.jp header.b=lqHHtZvp reason="key not found in DNS"; arc=none smtp.client-ip=49.212.243.89 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rsg.ci.i.u-tokyo.ac.jp Authentication-Results: smtp.subspace.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=rsg.ci.i.u-tokyo.ac.jp header.i=@rsg.ci.i.u-tokyo.ac.jp header.b="lqHHtZvp" Received: from h183.csg.ci.i.u-tokyo.ac.jp (h183.csg.ci.i.u-tokyo.ac.jp [133.11.54.183]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 66K5c7ok075973 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Mon, 20 Jul 2026 14:38:25 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=A8hJg+9Z0Ujtup1LyIFYnUgGhYCp0lA0bXWDMbXVkPA=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Message-Id:To:Subject:Date; s=rs20250326; t=1784525905; v=1; b=lqHHtZvpwpzjGPVXsETS1NfB8Yz6VbPoC9T+/FFTIlYdISuJZkd86DqgilI8qaUa 98hprXWolDHkj3Yet5sa5QJpiINnObNtrm1XYYRxkLsgnEIfl7c5tDR/vIBc290U e5Wbnz1606G64rgqyTzhWkB7oS9iHNWxojRvGMrhSOWpAUaWuVZZhb6C0dY9RadY mxOLS3ZyyfQGrzv7kErs3pCJ5IK7W02X00Xa6iHyVwUa4zBz8R7eTwA30ok3vhqa /PUbC20EXZn7VCm7eY+mBydK2GHh2FJ0uRxubLeuexdWWdcGmCWGIQ7SXkD11IbU DWIAOm9FQSv2lhPvMdxtpg== From: Akihiko Odaki Date: Mon, 20 Jul 2026 14:37:56 +0900 Subject: [PATCH v9 02/16] KVM: arm64: PMU: Stop updating MDCR_EL2.HPMN Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260720-hybrid-v9-2-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> References: <20260720-hybrid-v9-0-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20260720-hybrid-v9-0-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> To: Marc Zyngier , Oliver Upton , Joey Gouly , Suzuki K Poulose , Zenghui Yu , Catalin Marinas , Will Deacon , Kees Cook , "Gustavo A. R. Silva" , Paolo Bonzini , Jonathan Corbet , Shuah Khan , Shuah Khan , Yury Norov , Rasmus Villemoes , Steffen Eiden Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, devel@daynix.com, kvm@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Akihiko Odaki X-Mailer: b4 0.16-dev-925f5 X-Developer-Signature: v=1; a=openpgp-sha256; l=2325; i=odaki@rsg.ci.i.u-tokyo.ac.jp; h=from:subject:message-id; bh=nVWYQRDoBQAI06C2RUbthgzk2Kfs5Hf1NWsam/Gw8DY=; b=owGbwMvMwCWmMbc20y1CyJDxtFoSQ1bsFudQpsA3e2S5L8fGzL82y/BM2/I5P7azdp4qm2u2Y o5P9NmbHaUsDGJcDLJiiiwpRbu5NaJrPxUmxLfAzGFlAhnCwMUpABNhPsHIsPJaxOwbkW94q7Ob jMSD7b9z9ZT/YVQ9+F+kwrWf5Ux2OcMfPl0/E4ZFrXV80SYTxXN+blskU3TzY8rtphWHPRtOr+3 jAwA= X-Developer-Key: i=odaki@rsg.ci.i.u-tokyo.ac.jp; a=openpgp; fpr=AEDC03C9AF734F2EC26A7BFFA4BAEAA73536753C KVM allows userspace to write any value to MDCR_EL2.HPMN. However, kvm_arm_set_nr_counters() rewrites HPMN for every vCPU whenever userspace changes the PMU or its counter count. This can discard a value previously restored with KVM_SET_ONE_REG. The architecture only defines HPMN's value on warm reset. Stop rewriting it after vCPU initialization and update nr_pmu_counters directly instead. reset_mdcr() continues to initialize HPMN from the counter count current at KVM_ARM_VCPU_INIT. Fixes: c8823e51b534 ("KVM: arm64: Fix MDCR_EL2.HPMN reset value") Closes: https://sashiko.dev/#/patchset/20260706-hybrid-v8-0-de459617b59d%40= rsg.ci.i.u-tokyo.ac.jp?part=3D6 Assisted-by: Codex:gpt-5.5 Signed-off-by: Akihiko Odaki --- arch/arm64/kvm/pmu-emul.c | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c index 98305bbfc095..b5df6843dbcd 100644 --- a/arch/arm64/kvm/pmu-emul.c +++ b/arch/arm64/kvm/pmu-emul.c @@ -1022,30 +1022,12 @@ u8 kvm_arm_pmu_get_max_counters(struct kvm *kvm) return bitmap_weight(arm_pmu->cntr_mask, ARMV8_PMU_MAX_GENERAL_COUNTERS); } =20 -static void kvm_arm_set_nr_counters(struct kvm *kvm, unsigned int nr) -{ - kvm->arch.nr_pmu_counters =3D nr; - - /* Reset MDCR_EL2.HPMN behind the vcpus' back... */ - if (test_bit(KVM_ARM_VCPU_HAS_EL2, kvm->arch.vcpu_features)) { - struct kvm_vcpu *vcpu; - unsigned long i; - - kvm_for_each_vcpu(i, vcpu, kvm) { - u64 val =3D __vcpu_sys_reg(vcpu, MDCR_EL2); - val &=3D ~MDCR_EL2_HPMN; - val |=3D FIELD_PREP(MDCR_EL2_HPMN, kvm->arch.nr_pmu_counters); - __vcpu_assign_sys_reg(vcpu, MDCR_EL2, val); - } - } -} - static void kvm_arm_set_pmu(struct kvm *kvm, struct arm_pmu *arm_pmu) { lockdep_assert_held(&kvm->arch.config_lock); =20 kvm->arch.arm_pmu =3D arm_pmu; - kvm_arm_set_nr_counters(kvm, kvm_arm_pmu_get_max_counters(kvm)); + kvm->arch.nr_pmu_counters =3D kvm_arm_pmu_get_max_counters(kvm); } =20 /** @@ -1111,7 +1093,7 @@ static int kvm_arm_pmu_v3_set_nr_counters(struct kvm_= vcpu *vcpu, unsigned int n) if (n > kvm_arm_pmu_get_max_counters(kvm)) return -EINVAL; =20 - kvm_arm_set_nr_counters(kvm, n); + kvm->arch.nr_pmu_counters =3D n; return 0; } =20 --=20 2.55.0 From nobody Sat Jul 25 03:22:07 2026 Received: from www3579.sakura.ne.jp (www3579.sakura.ne.jp [49.212.243.89]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 77FF73A8759; Mon, 20 Jul 2026 05:39:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=49.212.243.89 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784525970; cv=none; b=eXz5m5KUMaTlh89SwM2YI7CiaBjVFJudN2XrOOOF5znGRr2uAFHsPvmXIlorxoiDhyaVNYH+yVk8bonqkDW90zRZqpuQc/nQDIN9WBfzOApWW3bBTQvKomgqIG5OfUKfcQ7N0ZYxatfQEU65yFebn/R4cativr2i5r6Baj81mvc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784525970; c=relaxed/simple; bh=8DcNWD473O5mxKX4hIYKD0DwQc9QDM6rn/VJdtyi9jg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=hcCej4HRPPKlbAO4MaxgccKroqXBN7irphOWmd2a9Zrc0mXoXkcgtdqs2FIC5UMhi+YJ4BvqM4LjXFKogagzeytKHQASOpziOrFYIh8s1CTrtEnp2PSIBEuENIBhT1aQ2DR4Mbu8iZEcKEo6h5jtU0j0qjVuqdesLNTzmTAA7jQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp; spf=pass smtp.mailfrom=rsg.ci.i.u-tokyo.ac.jp; dkim=fail (0-bit key) header.d=rsg.ci.i.u-tokyo.ac.jp header.i=@rsg.ci.i.u-tokyo.ac.jp header.b=KR9J/1Ls reason="key not found in DNS"; arc=none smtp.client-ip=49.212.243.89 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rsg.ci.i.u-tokyo.ac.jp Authentication-Results: smtp.subspace.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=rsg.ci.i.u-tokyo.ac.jp header.i=@rsg.ci.i.u-tokyo.ac.jp header.b="KR9J/1Ls" Received: from h183.csg.ci.i.u-tokyo.ac.jp (h183.csg.ci.i.u-tokyo.ac.jp [133.11.54.183]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 66K5c7ol075973 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Mon, 20 Jul 2026 14:38:25 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=0hksgsoHb+5DPEqDI69vVoWioOdWpzFWo2XEINBkKEY=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Message-Id:To:Subject:Date; s=rs20250326; t=1784525906; v=1; b=KR9J/1LsfcCUHiMKtSXTbiglekYsTdFxmUTKfBN55AS3aEINv6Zv7uLbXeoND/tQ l6KYch1zNeOAzBqeI6GLTxYhk2ipCxNMldf9dSHxe2QBEa3KDNLTq8ggkCM6LGC8 jvllIlTKUkZ4GajUWKNaX9xxYcEC3e6cWc/8JYo6vLDHbfVba32+o/MGxLwA5Ic0 x8KCZu4IWmDazK5jEb7xM055vqqzghw2I+ey/rMrk/7IMpIKNcvT8lUSLaxboOAC DcmrbrJphLS3jNQNMS3Ev9h7VJsSS39Ldps22jVT18l/zL9/8p5gbzyqv4F9AdsB vojYUpqc+eLoLvjkgmZszg== From: Akihiko Odaki Date: Mon, 20 Jul 2026 14:37:57 +0900 Subject: [PATCH v9 03/16] KVM: arm64: PMU: Freeze counter count after first run Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260720-hybrid-v9-3-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> References: <20260720-hybrid-v9-0-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20260720-hybrid-v9-0-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> To: Marc Zyngier , Oliver Upton , Joey Gouly , Suzuki K Poulose , Zenghui Yu , Catalin Marinas , Will Deacon , Kees Cook , "Gustavo A. R. Silva" , Paolo Bonzini , Jonathan Corbet , Shuah Khan , Shuah Khan , Yury Norov , Rasmus Villemoes , Steffen Eiden Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, devel@daynix.com, kvm@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Akihiko Odaki X-Mailer: b4 0.16-dev-925f5 X-Developer-Signature: v=1; a=openpgp-sha256; l=1114; i=odaki@rsg.ci.i.u-tokyo.ac.jp; h=from:subject:message-id; bh=8DcNWD473O5mxKX4hIYKD0DwQc9QDM6rn/VJdtyi9jg=; b=owGbwMvMwCWmMbc20y1CyJDxtFoSQ1bsFpdWCZXNC13nb33sknhDYZrRs2Sm3+/el3NfSjvy3 zRLJWZyRykLgxgXg6yYIktK0W5ujejaT4UJ8S0wc1iZQIYwcHEKwETaWRgZ5u/ee9gnmnfj3v6J b7mDJJRMom8/c/N4wBYteE73ZW3zcoY/POq3P779e25nZtBbjySrZw5aOhuLKjJOumSvPmAU+eA bGwA= X-Developer-Key: i=odaki@rsg.ci.i.u-tokyo.ac.jp; a=openpgp; fpr=AEDC03C9AF734F2EC26A7BFFA4BAEAA73536753C PMU configuration is VM-scoped, but SET_NR_COUNTERS can be issued through any vCPU. Checking only whether that vCPU's PMU has been initialized allows userspace to change the counter count through an idle sibling after another vCPU has run. Reject the attribute once any vCPU has run. This keeps the VM-wide implemented counter mask and the PMCR_EL0.N value stable after guest execution begins. Fixes: b7628c797376 ("KVM: arm64: Allow userspace to limit the number of PM= U counters for EL2 VMs") Assisted-by: Codex:gpt-5.6-sol Signed-off-by: Akihiko Odaki --- arch/arm64/kvm/pmu-emul.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c index b5df6843dbcd..b4b877f31097 100644 --- a/arch/arm64/kvm/pmu-emul.c +++ b/arch/arm64/kvm/pmu-emul.c @@ -1087,6 +1087,9 @@ static int kvm_arm_pmu_v3_set_nr_counters(struct kvm_= vcpu *vcpu, unsigned int n) { struct kvm *kvm =3D vcpu->kvm; =20 + if (kvm_vm_has_ran_once(kvm)) + return -EBUSY; + if (!kvm->arch.arm_pmu) return -EINVAL; =20 --=20 2.55.0 From nobody Sat Jul 25 03:22:07 2026 Received: from www3579.sakura.ne.jp (www3579.sakura.ne.jp [49.212.243.89]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B084A3ABD95; Mon, 20 Jul 2026 05:44:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=49.212.243.89 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784526257; cv=none; b=mZbGDFqkBeVNOFkW+Chc9Tbbfn9Eq+qJZHBRbrTbQamTNW7udGWfW+qsSVl5LcnAAEKvgu828rE3g3GxZHScgga0AD+ylhd6cQQF79MmAz/YqRYQSjIrNDIfxrs6UJPKdP8rkwshtp/9S6/Dys9rtMn9H23tvD5pKyyTghP7F1o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784526257; c=relaxed/simple; bh=BBucYUZX8Oc0BbLNMW6+Moe/S16AQy1iES1ROmKJY08=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=SYrayZVvN2ekS/f6GVSCXRMiQZL35tjHD/bUByI5oUM0PmTqaEEm7mPGPajAo/PfPIRD/CGDHpzVdo5JPqqfdsi7g1gajt2lQLPqUL2lpL9REcNBNlJhB0LPvS0zAwHcCgZc5ldsbVlIEM+jPYjw2DfgqBe1Z/WemCHe2Tw+GfY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp; spf=pass smtp.mailfrom=rsg.ci.i.u-tokyo.ac.jp; dkim=fail (0-bit key) header.d=rsg.ci.i.u-tokyo.ac.jp header.i=@rsg.ci.i.u-tokyo.ac.jp header.b=VRFSVgfu reason="key not found in DNS"; arc=none smtp.client-ip=49.212.243.89 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rsg.ci.i.u-tokyo.ac.jp Authentication-Results: smtp.subspace.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=rsg.ci.i.u-tokyo.ac.jp header.i=@rsg.ci.i.u-tokyo.ac.jp header.b="VRFSVgfu" Received: from h183.csg.ci.i.u-tokyo.ac.jp (h183.csg.ci.i.u-tokyo.ac.jp [133.11.54.183]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 66K5c7om075973 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Mon, 20 Jul 2026 14:38:26 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=KpB6X7mai5xhV0NQDiFgu0TlCfG7qzHiZetXWMkwXj8=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Message-Id:To:Subject:Date; s=rs20250326; t=1784525906; v=1; b=VRFSVgfuDBUuzl46mrVXSkdUt/QVcXmSxeYj6ooPaG7UUl7t7g4pH+Haj+rIlZON 4iyeSpzYZIqOEtfzo16vw4IBD0mkG2T1VTuCbtYlIVgywykpAO+SqwqpBRT3q8Hb HASHNq3hiQNrs7FfQoBA3edbe7CmQxUYFd+y94xYnv0IgYTgnSPRtntikLGkMs+i uVnQx7lZQBp4OYxJiIw/a9O+4YK0nZaI+TkNWOAQMpRvSyUjPJHwCdlD0rP42LDN cTLYXwgfuG6VoE1H3N18aGNJu6mjoht3BQak3iISV+Yp3peIlz7LYHTu73USooNJ IzCUbviI5gY8ObXp+81Z/A== From: Akihiko Odaki Date: Mon, 20 Jul 2026 14:37:58 +0900 Subject: [PATCH v9 04/16] KVM: arm64: selftests: Test SET_NR_COUNTERS after first run Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260720-hybrid-v9-4-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> References: <20260720-hybrid-v9-0-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20260720-hybrid-v9-0-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> To: Marc Zyngier , Oliver Upton , Joey Gouly , Suzuki K Poulose , Zenghui Yu , Catalin Marinas , Will Deacon , Kees Cook , "Gustavo A. R. Silva" , Paolo Bonzini , Jonathan Corbet , Shuah Khan , Shuah Khan , Yury Norov , Rasmus Villemoes , Steffen Eiden Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, devel@daynix.com, kvm@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Akihiko Odaki X-Mailer: b4 0.16-dev-925f5 X-Developer-Signature: v=1; a=openpgp-sha256; l=2438; i=odaki@rsg.ci.i.u-tokyo.ac.jp; h=from:subject:message-id; bh=BBucYUZX8Oc0BbLNMW6+Moe/S16AQy1iES1ROmKJY08=; b=owGbwMvMwCWmMbc20y1CyJDxtFoSQ1bsFtdpMrefTNexDn347KXQ5IZ122eIOZhOvpOvfVc6f G/eVPG9HaUsDGJcDLJiiiwpRbu5NaJrPxUmxLfAzGFlAhnCwMUpABPR6GJkWCGtMePinozcHy2M XFwHPZJcMjpX2Wxf1cT77ULplvZnagz/U9sX+hZq8Wge05APa1o4l8m/vjNfyuxcraSB8c4HDbt 4AQ== X-Developer-Key: i=odaki@rsg.ci.i.u-tokyo.ac.jp; a=openpgp; fpr=AEDC03C9AF734F2EC26A7BFFA4BAEAA73536753C Add a regression test that runs one vCPU and then tries to change the VM-scoped PMU counter count through an idle sibling. Verify that SET_NR_COUNTERS fails with EBUSY once any vCPU has run. Assisted-by: Codex:gpt-5.6-sol Signed-off-by: Akihiko Odaki --- .../selftests/kvm/arm64/vpmu_counter_access.c | 38 ++++++++++++++++++= ++++ 1 file changed, 38 insertions(+) diff --git a/tools/testing/selftests/kvm/arm64/vpmu_counter_access.c b/tool= s/testing/selftests/kvm/arm64/vpmu_counter_access.c index 22223395969e..3b5bb421f401 100644 --- a/tools/testing/selftests/kvm/arm64/vpmu_counter_access.c +++ b/tools/testing/selftests/kvm/arm64/vpmu_counter_access.c @@ -461,6 +461,11 @@ static void run_vcpu(struct kvm_vcpu *vcpu, u64 pmcr_n) } } =20 +static void guest_code_done(void) +{ + GUEST_DONE(); +} + static void test_create_vpmu_vm_with_nr_counters(unsigned int nr_counters,= bool expect_fail) { struct kvm_vcpu *vcpu; @@ -622,6 +627,37 @@ static bool kvm_supports_nr_counters_attr(void) return supported; } =20 +static void test_set_nr_counters_after_vcpu_run(void) +{ + struct kvm_vcpu *running_vcpu, *stopped_vcpu; + unsigned int nr_counters =3D 0; + struct kvm_vcpu_init init; + struct kvm_vm *vm; + int ret; + u64 irq =3D 23; + + vm =3D vm_create(2); + vm_ioctl(vm, KVM_ARM_PREFERRED_TARGET, &init); + init.features[0] |=3D BIT(KVM_ARM_VCPU_PMU_V3); + running_vcpu =3D aarch64_vcpu_add(vm, 0, &init, guest_code_done); + stopped_vcpu =3D aarch64_vcpu_add(vm, 1, &init, guest_code_done); + kvm_arch_vm_finalize_vcpus(vm); + + vcpu_device_attr_set(running_vcpu, KVM_ARM_VCPU_PMU_V3_CTRL, + KVM_ARM_VCPU_PMU_V3_IRQ, &irq); + vcpu_device_attr_set(running_vcpu, KVM_ARM_VCPU_PMU_V3_CTRL, + KVM_ARM_VCPU_PMU_V3_INIT, NULL); + vcpu_run(running_vcpu); + + ret =3D __vcpu_device_attr_set(stopped_vcpu, KVM_ARM_VCPU_PMU_V3_CTRL, + KVM_ARM_VCPU_PMU_V3_SET_NR_COUNTERS, + &nr_counters); + TEST_ASSERT(ret =3D=3D -1 && errno =3D=3D EBUSY, + KVM_IOCTL_ERROR(KVM_SET_DEVICE_ATTR, ret)); + + kvm_vm_free(vm); +} + int main(void) { u64 i, pmcr_n; @@ -630,6 +666,8 @@ int main(void) TEST_REQUIRE(kvm_supports_vgic_v3()); TEST_REQUIRE(kvm_supports_nr_counters_attr()); =20 + test_set_nr_counters_after_vcpu_run(); + pmcr_n =3D get_pmcr_n_limit(); for (i =3D 0; i <=3D pmcr_n; i++) { run_access_test(i); --=20 2.55.0 From nobody Sat Jul 25 03:22:07 2026 Received: from www3579.sakura.ne.jp (www3579.sakura.ne.jp [49.212.243.89]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 700683A874B; Mon, 20 Jul 2026 05:39:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=49.212.243.89 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784525970; cv=none; b=XRaN3d3JKCwuDzh6PwLxecZ2TE5TYUiRn3WZH6ggPJETJoYltWA3IL6rtbIM+x/hcNlRLXZVZ5YjyPUKCEfxNTxxckNkM4PrILEi8u6HR8A+jrSaK4ZlVi43lrcXOWex8LtRakWPHC4GKt7y5e7ipBYM3AKrezRIiE2lKnZSzT8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784525970; c=relaxed/simple; bh=s242nEr/47FPc5ZwVePZZQB+vYSDHKir8Bpuzgyr/Yg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Fi75IzIlGwd4SyTS6jW6w4FY4fWHs2m1waFSCi5eFRT1bJmRE90a4/sR4jZN5w9Vccm3Q8e4Ru55BoiRP1tG3ipqSeLCxnoJNx9Akl22w+kcD60b/EqKXoS7nL8VpOdJS03E29A2IDzFyb5rKi5yE1dvNPCiyPnZOqPcDWqg1Dg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp; spf=pass smtp.mailfrom=rsg.ci.i.u-tokyo.ac.jp; dkim=fail (0-bit key) header.d=rsg.ci.i.u-tokyo.ac.jp header.i=@rsg.ci.i.u-tokyo.ac.jp header.b=D6b/WSqH reason="key not found in DNS"; arc=none smtp.client-ip=49.212.243.89 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rsg.ci.i.u-tokyo.ac.jp Authentication-Results: smtp.subspace.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=rsg.ci.i.u-tokyo.ac.jp header.i=@rsg.ci.i.u-tokyo.ac.jp header.b="D6b/WSqH" Received: from h183.csg.ci.i.u-tokyo.ac.jp (h183.csg.ci.i.u-tokyo.ac.jp [133.11.54.183]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 66K5c7on075973 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Mon, 20 Jul 2026 14:38:26 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=mUQHRYBlGhx5jURjlXWULskvPAxw9G3BCiuXa0uo3a8=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Message-Id:To:Subject:Date; s=rs20250326; t=1784525906; v=1; b=D6b/WSqHVovJK4Q19o97DKJGiP5FZ3aAp1jwFdZSVC1NUzq6XL6sV+0VPW3PRyTE BP7g5aVoJWrq2AnqRWPNEw9QVi97Wyub8d3dgYwntZGD9ePfu7E73HdgytX2jSQB U01UJcWXDFO8NO32aEJtd3S5MBM5U7rJR2yXZBwI0uwgncWUN/u7GxehqDWAPvxZ 6qayUI9WJKUGzvOekrn7d66lM3/QlfFBsxhL4Gjp01YwJqda5ZfYGKWjSeJ8gbbB GOU9L9dWXvpA799uD1CubWPGFL9waYBe1xmVUmJ9ObKtMb/+aYnkSqMJC/oKA/qg asjkra+9gF9PHWDfqoJscQ== From: Akihiko Odaki Date: Mon, 20 Jul 2026 14:37:59 +0900 Subject: [PATCH v9 05/16] KVM: arm64: PMU: Keep implemented counter mask EL-independent Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260720-hybrid-v9-5-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> References: <20260720-hybrid-v9-0-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20260720-hybrid-v9-0-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> To: Marc Zyngier , Oliver Upton , Joey Gouly , Suzuki K Poulose , Zenghui Yu , Catalin Marinas , Will Deacon , Kees Cook , "Gustavo A. R. Silva" , Paolo Bonzini , Jonathan Corbet , Shuah Khan , Shuah Khan , Yury Norov , Rasmus Villemoes , Steffen Eiden Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, devel@daynix.com, kvm@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Akihiko Odaki X-Mailer: b4 0.16-dev-925f5 X-Developer-Signature: v=1; a=openpgp-sha256; l=1527; i=odaki@rsg.ci.i.u-tokyo.ac.jp; h=from:subject:message-id; bh=s242nEr/47FPc5ZwVePZZQB+vYSDHKir8Bpuzgyr/Yg=; b=owGbwMvMwCWmMbc20y1CyJDxtFoSQ1bsFrep77uTlWZPWFb33eD2WsXbO9RNPbrL2q7OffNCu rNizkH1jlIWBjEuBlkxRZaUot3cGtG1nwoT4ltg5rAygQxh4OIUgIlc3s/I0CH5ybX8QPeuRves iL69hQtmyl2x1lD4fN4898qsq3MmKTL8U4qd6bfF+Umxr6uMs+OFianbt+Wp35W9uWl2e95Fzjg +ZgA= X-Developer-Key: i=odaki@rsg.ci.i.u-tokyo.ac.jp; a=openpgp; fpr=AEDC03C9AF734F2EC26A7BFFA4BAEAA73536753C kvm_pmu_implemented_counter_mask() derives the counter count from kvm_vcpu_read_pmcr(). For a nested vCPU outside EL2, PMCR_EL0.N reflects MDCR_EL2.HPMN instead of the VM-wide counter count. Consequently, processing a PMU reload while the saved context is L2 can clear and fail to recreate state for counters reserved for EL2. Build the implemented counter mask from nr_pmu_counters instead. Keep the EL-dependent HPMN restriction in kvm_pmu_accessible_counter_mask(), where it controls guest access. Fixes: 600f6fa5c90c ("KVM: arm64: Let kvm_vcpu_read_pmcr() return an EL-dep= endent value for PMCR_EL0.N") Assisted-by: Codex:gpt-5.6-sol Signed-off-by: Akihiko Odaki --- arch/arm64/kvm/pmu-emul.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c index b4b877f31097..5281d37634a0 100644 --- a/arch/arm64/kvm/pmu-emul.c +++ b/arch/arm64/kvm/pmu-emul.c @@ -317,12 +317,12 @@ u64 kvm_pmu_accessible_counter_mask(struct kvm_vcpu *= vcpu) =20 u64 kvm_pmu_implemented_counter_mask(struct kvm_vcpu *vcpu) { - u64 val =3D FIELD_GET(ARMV8_PMU_PMCR_N, kvm_vcpu_read_pmcr(vcpu)); + u64 n =3D vcpu->kvm->arch.nr_pmu_counters; =20 - if (val =3D=3D 0) + if (n =3D=3D 0) return BIT(ARMV8_PMU_CYCLE_IDX); else - return GENMASK(val - 1, 0) | BIT(ARMV8_PMU_CYCLE_IDX); + return GENMASK(n - 1, 0) | BIT(ARMV8_PMU_CYCLE_IDX); } =20 static void kvm_pmc_enable_perf_event(struct kvm_pmc *pmc) --=20 2.55.0 From nobody Sat Jul 25 03:22:07 2026 Received: from www3579.sakura.ne.jp (www3579.sakura.ne.jp [49.212.243.89]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E33193AB496; Mon, 20 Jul 2026 05:44:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=49.212.243.89 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784526254; cv=none; b=G8ZdBBx6nWml6Z3D+J38A8czajw8lybgFKuc+soljkmrx4ED1nYFYNbcMH+o3SkMbTwP0O6LENRK4PObxyJ0Tgd+STlnKd4Vy57jqxOtgOkw0J+/ykwbE4399F4kMSVoRdmJ3V0AR8Y4vZMv1X1yHto29DhOu6Gm6ianmpMvKbc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784526254; c=relaxed/simple; bh=M/PETtsyeQ9dlXizOVrQk9S6JHEFBMx7jxtJuQJHeoc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=LiRhHbh8doEOKbmn3SLyzVvM2ldiB0vvlvioowef59xjG/yLLLwbonMM8dnPQ+l2qbE84ixqIkwRb0eWJMzzhO4wVz8tHH5BoLEjkPDM12MWXXn5o1hLZ7LFpwkrKEXdNVwEp3Rd2422eQpblwMfMSkK+Isu/KmTxEWIErB8i20= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp; spf=pass smtp.mailfrom=rsg.ci.i.u-tokyo.ac.jp; dkim=fail (0-bit key) header.d=rsg.ci.i.u-tokyo.ac.jp header.i=@rsg.ci.i.u-tokyo.ac.jp header.b=dy4RLNt/ reason="key not found in DNS"; arc=none smtp.client-ip=49.212.243.89 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rsg.ci.i.u-tokyo.ac.jp Authentication-Results: smtp.subspace.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=rsg.ci.i.u-tokyo.ac.jp header.i=@rsg.ci.i.u-tokyo.ac.jp header.b="dy4RLNt/" Received: from h183.csg.ci.i.u-tokyo.ac.jp (h183.csg.ci.i.u-tokyo.ac.jp [133.11.54.183]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 66K5c7oo075973 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Mon, 20 Jul 2026 14:38:26 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=4/MEVwLMiiLRlqBOgGpJ/BxA199hp2Gm7pyB1iMNam8=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Message-Id:To:Subject:Date; s=rs20250326; t=1784525907; v=1; b=dy4RLNt/SPZeSLaQbOEBrUo92vcqI9bpAuOKLRJR/w8B7T8WeYCIocVsCCL19G9Z gYWIWuUNYFxa+BDD6AFgBMFMycVtEZ/zcwKya0+WYt0amIUcaiNtI+JBV/aJe2WQ aJJkg97KeQSH/O7YwwR5xWIGvesJwFhpdZ9+skyTFTO6JfJsUXa3wFqEfACT/ilq 6wcUP+Si3vbYZUdBYmFhdB6Mvpbzh4v/gjURNZvhmXi86AvWh4G68gezw1tKQmFB +zKzH8gklU70Eu30O3ZfF84uWcj86z7hsT67lgy9ywEUUQC7wV69P7p010qZEf4e DPZXwiLEXmKOA7GxP62EcA== From: Akihiko Odaki Date: Mon, 20 Jul 2026 14:38:00 +0900 Subject: [PATCH v9 06/16] KVM: arm64: PMU: Recreate events after MDCR_EL2 changes Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260720-hybrid-v9-6-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> References: <20260720-hybrid-v9-0-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20260720-hybrid-v9-0-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> To: Marc Zyngier , Oliver Upton , Joey Gouly , Suzuki K Poulose , Zenghui Yu , Catalin Marinas , Will Deacon , Kees Cook , "Gustavo A. R. Silva" , Paolo Bonzini , Jonathan Corbet , Shuah Khan , Shuah Khan , Yury Norov , Rasmus Villemoes , Steffen Eiden Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, devel@daynix.com, kvm@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Akihiko Odaki X-Mailer: b4 0.16-dev-925f5 X-Developer-Signature: v=1; a=openpgp-sha256; l=6507; i=odaki@rsg.ci.i.u-tokyo.ac.jp; h=from:subject:message-id; bh=M/PETtsyeQ9dlXizOVrQk9S6JHEFBMx7jxtJuQJHeoc=; b=owGbwMvMwCWmMbc20y1CyJDxtFoSQ1bsFrfrHAoHXUo97zzUn7rQ/FfhhsdvDy1aFxN3qJBjl sqcQo/zHaUsDGJcDLJiiiwpRbu5NaJrPxUmxLfAzGFlAhnCwMUpABNRPcbIMHvK8YmfnR8JdpnM On1MlE97zqOQA5kPt//bfK5c1s61/yLDP7s4gZnFXw/0ihiH3JDWDXv30vVr/9fD5XOrJy046Gx 6gwcA X-Developer-Key: i=odaki@rsg.ci.i.u-tokyo.ac.jp; a=openpgp; fpr=AEDC03C9AF734F2EC26A7BFFA4BAEAA73536753C MDCR_EL2.HPMN changes which counters are reserved for EL2 and thus which enable control, event filter, and overflow width apply. HPMD changes EL2 filtering, while HLP changes the overflow width and sample period. The existing guest MDCR_EL2 handling only requests a PMU reload for HPME. Reloading enables or disables existing perf events, but does not rebuild events whose attributes have become stale. Generic userspace writes through KVM_SET_ONE_REG do not request a reload at all. Route guest writes, userspace writes, and reset through a common helper. Mark the vCPU's perf events for recreation when HPMN, HPMD, or HLP changes. Consume the marker on the vCPU thread before reprogramming the counters, which also preserves counter values and avoids creating events on an arbitrary ioctl thread. Use a setter-only accessor so register restore gains these side effects without changing generic reads or rejecting register values. Fixes: fe827f916662 ("KVM: arm64: nv: Honor MDCR_EL2.HPME") Fixes: 8a34979030f6 ("KVM: arm64: nv: Apply EL2 event filtering when in hyp= context") Fixes: 16535d55e91f ("KVM: arm64: nv: Honor MDCR_EL2.HLP") Assisted-by: Codex:gpt-5.6-sol Signed-off-by: Akihiko Odaki --- arch/arm64/kvm/pmu-emul.c | 27 +++++++++++++++++++++++++++ arch/arm64/kvm/sys_regs.c | 31 +++++++++++++++++++++---------- include/kvm/arm_pmu.h | 3 +++ 3 files changed, 51 insertions(+), 10 deletions(-) diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c index 5281d37634a0..9ac5f307ea31 100644 --- a/arch/arm64/kvm/pmu-emul.c +++ b/arch/arm64/kvm/pmu-emul.c @@ -17,6 +17,9 @@ =20 #define PERF_ATTR_CFG1_COUNTER_64BIT BIT(0) =20 +#define MDCR_EL2_PMU_RECREATE_MASK (MDCR_EL2_HPMN | MDCR_EL2_HPMD | \ + MDCR_EL2_HLP) + static LIST_HEAD(arm_pmus); static DEFINE_MUTEX(arm_pmus_lock); =20 @@ -606,6 +609,21 @@ void kvm_pmu_handle_pmcr(struct kvm_vcpu *vcpu, u64 va= l) } } =20 +void kvm_pmu_handle_mdcr(struct kvm_vcpu *vcpu, u64 old, u64 val) +{ + u64 changed =3D old ^ val; + + /* + * HPMN determines which counters HPMD and HLP apply to. Changes to + * these fields require new perf event filters and sample periods. + */ + if (changed & MDCR_EL2_PMU_RECREATE_MASK) + vcpu->arch.pmu.events_need_recreate =3D true; + + if (changed & (MDCR_EL2_HPME | MDCR_EL2_PMU_RECREATE_MASK)) + kvm_make_request(KVM_REQ_RELOAD_PMU, vcpu); +} + static bool kvm_pmu_counter_is_enabled(struct kvm_pmc *pmc) { struct kvm_vcpu *vcpu =3D kvm_pmc_to_vcpu(pmc); @@ -899,7 +917,16 @@ u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmc= eid1) =20 void kvm_vcpu_reload_pmu(struct kvm_vcpu *vcpu) { + struct kvm_pmu *pmu =3D &vcpu->arch.pmu; u64 mask =3D kvm_pmu_implemented_counter_mask(vcpu); + int i; + + if (pmu->events_need_recreate) { + for (i =3D 0; i < KVM_ARMV8_PMU_MAX_COUNTERS; i++) + kvm_pmu_stop_counter(kvm_vcpu_idx_to_pmc(vcpu, i)); + + pmu->events_need_recreate =3D false; + } =20 __vcpu_rmw_sys_reg(vcpu, PMOVSSET_EL0, &=3D, mask); __vcpu_rmw_sys_reg(vcpu, PMINTENSET_EL1, &=3D, mask); diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 5d5c579d4579..9e905d9be9f6 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -3020,17 +3020,22 @@ static bool access_mdcr(struct kvm_vcpu *vcpu, } =20 __vcpu_assign_sys_reg(vcpu, MDCR_EL2, val); - - /* - * Request a reload of the PMU to enable/disable the counters - * affected by HPME. - */ - if ((old ^ val) & MDCR_EL2_HPME) - kvm_make_request(KVM_REQ_RELOAD_PMU, vcpu); + kvm_pmu_handle_mdcr(vcpu, old, val); =20 return true; } =20 +static int set_mdcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, + u64 val) +{ + u64 old =3D __vcpu_sys_reg(vcpu, MDCR_EL2); + + __vcpu_assign_sys_reg(vcpu, MDCR_EL2, val); + kvm_pmu_handle_mdcr(vcpu, old, val); + + return 0; +} + static bool access_ras(struct kvm_vcpu *vcpu, struct sys_reg_params *p, const struct sys_reg_desc *r) @@ -3177,8 +3182,13 @@ static int set_imp_id_reg(struct kvm_vcpu *vcpu, con= st struct sys_reg_desc *r, =20 static u64 reset_mdcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) { - __vcpu_assign_sys_reg(vcpu, r->reg, vcpu->kvm->arch.nr_pmu_counters); - return vcpu->kvm->arch.nr_pmu_counters; + u64 old =3D __vcpu_sys_reg(vcpu, r->reg); + u64 val =3D vcpu->kvm->arch.nr_pmu_counters; + + __vcpu_assign_sys_reg(vcpu, r->reg, val); + kvm_pmu_handle_mdcr(vcpu, old, val); + + return val; } =20 /* @@ -3741,7 +3751,8 @@ static const struct sys_reg_desc sys_reg_descs[] =3D { EL2_REG_FILTERED(SCTLR2_EL2, access_vm_reg, reset_val, 0, sctlr2_el2_visibility), EL2_REG_VNCR(HCR_EL2, reset_hcr, 0), - EL2_REG(MDCR_EL2, access_mdcr, reset_mdcr, 0), + SYS_REG_USER_FILTER(MDCR_EL2, access_mdcr, reset_mdcr, 0, + NULL, set_mdcr, el2_visibility), EL2_REG(CPTR_EL2, access_rw, reset_val, CPTR_NVHE_EL2_RES1), EL2_REG_VNCR(HSTR_EL2, reset_val, 0), EL2_REG_VNCR_FILT(HFGRTR_EL2, fgt_visibility), diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h index b5e5942204fc..1971f8794c9d 100644 --- a/include/kvm/arm_pmu.h +++ b/include/kvm/arm_pmu.h @@ -32,6 +32,7 @@ struct kvm_pmu { struct kvm_pmc pmc[KVM_ARMV8_PMU_MAX_COUNTERS]; int irq_num; bool created; + bool events_need_recreate; }; =20 struct arm_pmu_entry { @@ -56,6 +57,7 @@ bool kvm_pmu_should_notify_user(struct kvm_vcpu *vcpu); bool kvm_pmu_update_run(struct kvm_vcpu *vcpu); void kvm_pmu_software_increment(struct kvm_vcpu *vcpu, u64 val); void kvm_pmu_handle_pmcr(struct kvm_vcpu *vcpu, u64 val); +void kvm_pmu_handle_mdcr(struct kvm_vcpu *vcpu, u64 old, u64 val); void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, u64 data, u64 select_idx); void kvm_vcpu_reload_pmu(struct kvm_vcpu *vcpu); @@ -133,6 +135,7 @@ static inline bool kvm_pmu_should_notify_user(struct kv= m_vcpu *vcpu) static inline bool kvm_pmu_update_run(struct kvm_vcpu *vcpu) { return fals= e; } static inline void kvm_pmu_software_increment(struct kvm_vcpu *vcpu, u64 v= al) {} static inline void kvm_pmu_handle_pmcr(struct kvm_vcpu *vcpu, u64 val) {} +static inline void kvm_pmu_handle_mdcr(struct kvm_vcpu *vcpu, u64 old, u64= val) {} static inline void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, u64 data, u64 select_idx) {} static inline int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, --=20 2.55.0 From nobody Sat Jul 25 03:22:07 2026 Received: from www3579.sakura.ne.jp (www3579.sakura.ne.jp [49.212.243.89]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 914303AB26B; Mon, 20 Jul 2026 05:39:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=49.212.243.89 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784525972; cv=none; b=XtDFTZmHDjzLTgMDSiVfRHtXX3dotsBBfkhJX400oMPvjjRRZjiq1PS870eVbaciKJFGUy8jdY5NIZ8Q+h9efVg5lFYzgN9Q1P7Uc6+8AkqOXglfocogT2YVybeR9SZ5nMa1Pih/qlXGFO753PvY46l3W419eGuSZ8pD9wMw5Ds= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784525972; c=relaxed/simple; bh=N/y16fl48YztPTKgFTuZ9+7HYNROEUxLYFOVWXFM1KA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=FZ8/bkYTRHYWOBoZsS6GaTEU6z6/IM6LO/6NdEO3+WXQPb9+L4eKD4WRa1/uJ84qUwd89/t3HiLeThnR5UGjRgWib2MRe5CPple9nYJvrhtNHMgloQQL1pbKD+JrVk1StpB6z4iB8zpwduj9TjHdAfhsJKInfT4p1DLlHbBcMrk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp; spf=pass smtp.mailfrom=rsg.ci.i.u-tokyo.ac.jp; dkim=fail (0-bit key) header.d=rsg.ci.i.u-tokyo.ac.jp header.i=@rsg.ci.i.u-tokyo.ac.jp header.b=sKrvylHv reason="key not found in DNS"; arc=none smtp.client-ip=49.212.243.89 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rsg.ci.i.u-tokyo.ac.jp Authentication-Results: smtp.subspace.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=rsg.ci.i.u-tokyo.ac.jp header.i=@rsg.ci.i.u-tokyo.ac.jp header.b="sKrvylHv" Received: from h183.csg.ci.i.u-tokyo.ac.jp (h183.csg.ci.i.u-tokyo.ac.jp [133.11.54.183]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 66K5c7op075973 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Mon, 20 Jul 2026 14:38:27 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=ditAkCCrXh+YkXADVfso0W9S/4JCyLrDicaPFc0dzLo=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Message-Id:To:Subject:Date; s=rs20250326; t=1784525907; v=1; b=sKrvylHvOFrgFgsKcvVyGlVdk09KMkw2VoCaXwweA310Gkwg6SDz0I+BSvv7csa1 aFmYwRJ/DELX5kni8QcgyNDgx3vhgbQUgWfKCwT4DRxfIW7wAWYl5hs/8bqlka24 3M6b89oyqlKw+ed4fRP9z7tlENma4BO6c2x9y5KbBAwYi+XINfUwHy59xyYPxEWb Icx6+7UkMxMPrWsirsMPDi5GhRSebEumzfHNukXNGV7ih/A6XmQycXtPagI71FXi tSgpMufa/27qnQtj8rHgcUOZW+FDFKbZH38ufixIaqO+ZGlSBGrKtrwcsUI5KcWw jbuASudKIvN21KjbOt4lHg== From: Akihiko Odaki Date: Mon, 20 Jul 2026 14:38:01 +0900 Subject: [PATCH v9 07/16] tools headers: Use u* types for bitfield helpers Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260720-hybrid-v9-7-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> References: <20260720-hybrid-v9-0-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20260720-hybrid-v9-0-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> To: Marc Zyngier , Oliver Upton , Joey Gouly , Suzuki K Poulose , Zenghui Yu , Catalin Marinas , Will Deacon , Kees Cook , "Gustavo A. R. Silva" , Paolo Bonzini , Jonathan Corbet , Shuah Khan , Shuah Khan , Yury Norov , Rasmus Villemoes , Steffen Eiden Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, devel@daynix.com, kvm@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Akihiko Odaki X-Mailer: b4 0.16-dev-925f5 X-Developer-Signature: v=1; a=openpgp-sha256; l=2957; i=odaki@rsg.ci.i.u-tokyo.ac.jp; h=from:subject:message-id; bh=N/y16fl48YztPTKgFTuZ9+7HYNROEUxLYFOVWXFM1KA=; b=owGbwMvMwCWmMbc20y1CyJDxtFoSQ1bsFnfRCQ82B4gwHfVaf47LffbMy1bMIt93yv4+e9Osn 2Na5NuqjlIWBjEuBlkxRZaUot3cGtG1nwoT4ltg5rAygQxh4OIUgInkmjD84fp1vzpN7O/LY7dP HG1+/Cap1KRykVpGQOevAuG1pe03bBgZ5ijOjGteWHfAdo4295xfndOerrzrn6MXzbBqx2H3b8y rWQA= X-Developer-Key: i=odaki@rsg.ci.i.u-tokyo.ac.jp; a=openpgp; fpr=AEDC03C9AF734F2EC26A7BFFA4BAEAA73536753C Commit 9486aa387716 ("perf tools: Fix 64 bit integer format strings") defined the tools-local u64 as uint64_t so that PRI*64 format macros match its underlying C type. On architectures where uint64_t and __u64 are distinct types, however, ____MAKE_OP() still gives the u64_* helpers an __u64 interface. Teach ____MAKE_OP() to accept the helper name and storage type separately. Keep endian helpers on __le* and __be*, and generate the native helpers using the tools-local u* types. Assisted-by: Codex:gpt-5.6-sol Signed-off-by: Akihiko Odaki --- tools/include/linux/bitfield.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tools/include/linux/bitfield.h b/tools/include/linux/bitfield.h index ddf81f24956b..1c633343d576 100644 --- a/tools/include/linux/bitfield.h +++ b/tools/include/linux/bitfield.h @@ -142,32 +142,32 @@ static __always_inline u64 field_mask(u64 field) return field / field_multiplier(field); } #define field_max(field) ((typeof(field))field_mask(field)) -#define ____MAKE_OP(type,base,to,from) \ -static __always_inline __##type type##_encode_bits(base v, base field) \ +#define ____MAKE_OP(name,type,base,to,from) \ +static __always_inline type name##_encode_bits(base v, base field) \ { \ if (__builtin_constant_p(v) && (v & ~field_mask(field))) \ __field_overflow(); \ return to((v & field_mask(field)) * field_multiplier(field)); \ } \ -static __always_inline __##type type##_replace_bits(__##type old, \ - base val, base field) \ +static __always_inline type name##_replace_bits(type old, \ + base val, base field) \ { \ - return (old & ~to(field)) | type##_encode_bits(val, field); \ + return (old & ~to(field)) | name##_encode_bits(val, field); \ } \ -static __always_inline void type##p_replace_bits(__##type *p, \ +static __always_inline void name##p_replace_bits(type *p, \ base val, base field) \ { \ - *p =3D (*p & ~to(field)) | type##_encode_bits(val, field); \ + *p =3D (*p & ~to(field)) | name##_encode_bits(val, field); \ } \ -static __always_inline base type##_get_bits(__##type v, base field) \ +static __always_inline base name##_get_bits(type v, base field) \ { \ return (from(v) & field)/field_multiplier(field); \ } -#define __MAKE_OP(size) \ - ____MAKE_OP(le##size,u##size,cpu_to_le##size,le##size##_to_cpu) \ - ____MAKE_OP(be##size,u##size,cpu_to_be##size,be##size##_to_cpu) \ - ____MAKE_OP(u##size,u##size,,) -____MAKE_OP(u8,u8,,) +#define __MAKE_OP(size) \ + ____MAKE_OP(le##size,__le##size,u##size,cpu_to_le##size,le##size##_to_cpu= ) \ + ____MAKE_OP(be##size,__be##size,u##size,cpu_to_be##size,be##size##_to_cpu= ) \ + ____MAKE_OP(u##size,u##size,u##size,,) +____MAKE_OP(u8,u8,u8,,) __MAKE_OP(16) __MAKE_OP(32) __MAKE_OP(64) --=20 2.55.0 From nobody Sat Jul 25 03:22:07 2026 Received: from www3579.sakura.ne.jp (www3579.sakura.ne.jp [49.212.243.89]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B674E3ABDA5; Mon, 20 Jul 2026 05:44:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=49.212.243.89 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784526257; cv=none; b=rADTnnJwPcTK8gdpRxSDb61xeYfPD+SIfG+9/12E5nUumtR/VwdhHiWSWjqi+Wxzbtx7JF6ECmh8gd5MRl2GI2zBOzhW2f37YOVcfeYfUZJwmFs0ezo+fEHRrYGzWWLiI3/zvcemg6LGCPQA6NEmKp/E5x4PfVQpfyf2/EF74vA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784526257; c=relaxed/simple; bh=zDiEZfUb4Wk9v0QAFrUyM8SDCUY7xwuAT+HVrDy+8eQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=IcZEWyL+Yr04YSJTiJqc6MAqV+P5EYIFCvKpokSKZ8v+yRw3eAslu3Wb3x2HTRti3G0gw/yvE4EHEJnIEsdKghWK8YAKFq4E8EZ8acmp1kesOkv2kLMhSOQEjzpSEQe5/ugLmNt48bcUyFOg7aUllOFLCZUDIjzulCFoYps6Qnk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp; spf=pass smtp.mailfrom=rsg.ci.i.u-tokyo.ac.jp; dkim=fail (0-bit key) header.d=rsg.ci.i.u-tokyo.ac.jp header.i=@rsg.ci.i.u-tokyo.ac.jp header.b=Z4LPlSJP reason="key not found in DNS"; arc=none smtp.client-ip=49.212.243.89 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rsg.ci.i.u-tokyo.ac.jp Authentication-Results: smtp.subspace.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=rsg.ci.i.u-tokyo.ac.jp header.i=@rsg.ci.i.u-tokyo.ac.jp header.b="Z4LPlSJP" Received: from h183.csg.ci.i.u-tokyo.ac.jp (h183.csg.ci.i.u-tokyo.ac.jp [133.11.54.183]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 66K5c7oq075973 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Mon, 20 Jul 2026 14:38:27 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=vDCWnGaiEP2ySay81C7I99nmBfHqK6DuGU0r4029XQA=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Message-Id:To:Subject:Date; s=rs20250326; t=1784525907; v=1; b=Z4LPlSJPiZFjec0somQKs9subJfYB8f8vDQ2wRAuv9VRcw/0/waK8bHL4sqsFU0u ubAFP8JQ+bswnSZmDhFZGXMdKlh3Up0atPHRXe3N/BjLAOINxs2DxYVf0dDySS1G iqOKQqj/jrTl1vZFuo0YWUZqjo4Bhrod47H3cgsRQ/346lockebeaCMiu8T4v22i URwOqihDgxL+bYpIcshzW+5gJHpux58/afedAIDIThI9s5NDlsHmGoa11lyn8ePk bUEHBZMOhhum+Kb9+qFrPthvw0zZcRdRvMAyBEiOT4TIgDF/azzQzid0L2XmdxOg oo4LKJQB/DBt7SqSVzWDlw== From: Akihiko Odaki Date: Mon, 20 Jul 2026 14:38:02 +0900 Subject: [PATCH v9 08/16] KVM: arm64: selftests: Cover PMU state in MDCR_EL2 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260720-hybrid-v9-8-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> References: <20260720-hybrid-v9-0-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20260720-hybrid-v9-0-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> To: Marc Zyngier , Oliver Upton , Joey Gouly , Suzuki K Poulose , Zenghui Yu , Catalin Marinas , Will Deacon , Kees Cook , "Gustavo A. R. Silva" , Paolo Bonzini , Jonathan Corbet , Shuah Khan , Shuah Khan , Yury Norov , Rasmus Villemoes , Steffen Eiden Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, devel@daynix.com, kvm@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Akihiko Odaki X-Mailer: b4 0.16-dev-925f5 X-Developer-Signature: v=1; a=openpgp-sha256; l=5002; i=odaki@rsg.ci.i.u-tokyo.ac.jp; h=from:subject:message-id; bh=zDiEZfUb4Wk9v0QAFrUyM8SDCUY7xwuAT+HVrDy+8eQ=; b=owGbwMvMwCWmMbc20y1CyJDxtFoSQ1bsFo/ku37tRz+cOa3JH+rr4vz4xopp1V0rZ9Y88/zUG PLmhMmpjlIWBjEuBlkxRZaUot3cGtG1nwoT4ltg5rAygQxh4OIUgIns1GVkmNxr63ie+VXKl5or 5wJPnf/8T//Y7juHX0QbnlHKMZl1KJzhn3riAlMt/S0sz3yvR5yXvHDj22Sfk4d1GWIl62Iv35L l5AAA X-Developer-Key: i=odaki@rsg.ci.i.u-tokyo.ac.jp; a=openpgp; fpr=AEDC03C9AF734F2EC26A7BFFA4BAEAA73536753C Add MDCR_EL2 coverage to vpmu_counter_access when EL2 is available. For each configured PMCR_EL0.N value, verify that an arbitrary HPMN value, including one above the configured counter count, round-trips through KVM_SET_ONE_REG and survives SET_NR_COUNTERS. Also verify that HPME can be toggled without disturbing HPMN and that KVM_ARM_VCPU_INIT resets HPMN from the configured count. Assisted-by: Codex:gpt-5.5 Signed-off-by: Akihiko Odaki --- .../selftests/kvm/arm64/vpmu_counter_access.c | 90 ++++++++++++++++++= ++-- 1 file changed, 85 insertions(+), 5 deletions(-) diff --git a/tools/testing/selftests/kvm/arm64/vpmu_counter_access.c b/tool= s/testing/selftests/kvm/arm64/vpmu_counter_access.c index 3b5bb421f401..73f04e4c6ca3 100644 --- a/tools/testing/selftests/kvm/arm64/vpmu_counter_access.c +++ b/tools/testing/selftests/kvm/arm64/vpmu_counter_access.c @@ -25,6 +25,14 @@ /* The cycle counter bit position that's common among the PMU registers */ #define ARMV8_PMU_CYCLE_IDX 31 =20 +#ifndef MDCR_EL2_HPMN +#define MDCR_EL2_HPMN GENMASK_ULL(4, 0) +#endif + +#ifndef MDCR_EL2_HPME +#define MDCR_EL2_HPME BIT_ULL(7) +#endif + struct vpmu_vm { struct kvm_vm *vm; struct kvm_vcpu *vcpu; @@ -466,15 +474,12 @@ static void guest_code_done(void) GUEST_DONE(); } =20 -static void test_create_vpmu_vm_with_nr_counters(unsigned int nr_counters,= bool expect_fail) +static void set_nr_counters(struct kvm_vcpu *vcpu, + unsigned int nr_counters, bool expect_fail) { - struct kvm_vcpu *vcpu; unsigned int prev; int ret; =20 - create_vpmu_vm(guest_code); - vcpu =3D vpmu_vm.vcpu; - prev =3D get_pmcr_n(vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_PMCR_EL0))); =20 ret =3D __vcpu_device_attr_set(vcpu, KVM_ARM_VCPU_PMU_V3_CTRL, @@ -486,6 +491,17 @@ static void test_create_vpmu_vm_with_nr_counters(unsig= ned int nr_counters, bool nr_counters, prev); else TEST_ASSERT(!ret, KVM_IOCTL_ERROR(KVM_SET_DEVICE_ATTR, ret)); +} + +static void test_create_vpmu_vm_with_nr_counters(unsigned int nr_counters, + bool expect_fail) +{ + struct kvm_vcpu *vcpu; + + create_vpmu_vm(guest_code); + vcpu =3D vpmu_vm.vcpu; + + set_nr_counters(vcpu, nr_counters, expect_fail); =20 vcpu_device_attr_set(vcpu, KVM_ARM_VCPU_PMU_V3_CTRL, KVM_ARM_VCPU_PMU_V3_= INIT, NULL); } @@ -588,6 +604,69 @@ static void run_pmregs_validity_test(u64 pmcr_n) destroy_vpmu_vm(); } =20 +static void run_mdcr_el2_validity_test(u64 pmcr_n) +{ + struct kvm_vcpu_init init; + struct kvm_vcpu *vcpu; + u64 expected_mdcr, mdcr; + + pr_debug("MDCR_EL2 test with pmcr_n %lu\n", pmcr_n); + + create_vpmu_vm(guest_code); + if (!vm_supports_el2(vpmu_vm.vm)) { + destroy_vpmu_vm(); + return; + } + + vcpu =3D vpmu_vm.vcpu; + + mdcr =3D vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_MDCR_EL2)); + expected_mdcr =3D u64_replace_bits(mdcr, FIELD_MAX(MDCR_EL2_HPMN), + MDCR_EL2_HPMN); + vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_MDCR_EL2), + expected_mdcr); + + mdcr =3D vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_MDCR_EL2)); + TEST_ASSERT(mdcr =3D=3D expected_mdcr, + "MDCR_EL2 was not properly updated after HPMN write (expected 0x%lx,= got 0x%lx)", + expected_mdcr, mdcr); + + set_nr_counters(vcpu, pmcr_n, false); + + mdcr =3D vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_MDCR_EL2)); + TEST_ASSERT(mdcr =3D=3D expected_mdcr, + "MDCR_EL2 changed after PMU_V3_SET_NR_COUNTERS (expected 0x%lx, got = 0x%lx)", + expected_mdcr, mdcr); + + vcpu_device_attr_set(vcpu, KVM_ARM_VCPU_PMU_V3_CTRL, + KVM_ARM_VCPU_PMU_V3_INIT, NULL); + + mdcr =3D vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_MDCR_EL2)); + TEST_ASSERT(mdcr =3D=3D expected_mdcr, + "MDCR_EL2 changed after PMU_V3_INIT (expected 0x%lx, got 0x%lx)", + expected_mdcr, mdcr); + + expected_mdcr =3D mdcr ^ MDCR_EL2_HPME; + vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_MDCR_EL2), + expected_mdcr); + + mdcr =3D vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_MDCR_EL2)); + TEST_ASSERT(mdcr =3D=3D expected_mdcr, + "MDCR_EL2 was not properly updated after HPME write (expected 0x%lx,= got 0x%lx)", + expected_mdcr, mdcr); + + kvm_get_default_vcpu_target(vpmu_vm.vm, &init); + init.features[0] |=3D (1 << KVM_ARM_VCPU_PMU_V3); + aarch64_vcpu_setup(vcpu, &init); + + mdcr =3D vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_MDCR_EL2)); + TEST_ASSERT(FIELD_GET(MDCR_EL2_HPMN, mdcr) =3D=3D pmcr_n, + "MDCR_EL2.HPMN is not reset after INIT (expected %lu, got %lu)", + pmcr_n, FIELD_GET(MDCR_EL2_HPMN, mdcr)); + + destroy_vpmu_vm(); +} + /* * Create a guest with one vCPU, and attempt to set the PMCR_EL0.N for * the vCPU to @pmcr_n, which is larger than the host value. @@ -672,6 +751,7 @@ int main(void) for (i =3D 0; i <=3D pmcr_n; i++) { run_access_test(i); run_pmregs_validity_test(i); + run_mdcr_el2_validity_test(i); } =20 for (i =3D pmcr_n + 1; i < ARMV8_PMU_MAX_COUNTERS; i++) --=20 2.55.0 From nobody Sat Jul 25 03:22:07 2026 Received: from www3579.sakura.ne.jp (www3579.sakura.ne.jp [49.212.243.89]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5FE7D3AC0D3; Mon, 20 Jul 2026 05:39:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=49.212.243.89 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784525973; cv=none; b=QTP8zBduEihktb1DeW4YmDaEZ/jRhsOgA8pH72p97azRoNOsrnEZcsPBcBs7ynhEupto9vqfkO0fyR5MdLQiPpbWizOGfPg/glz8+4GgvU9n2fbftlcC/Mxi2GjDX4UrRjJwGqL5fJ/U0m0uyslVpemEE8K/2KRHUBGOIAXGq7s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784525973; c=relaxed/simple; bh=0/AxsHDzqRNEUmxs91LVTqutnKtgRFxtYi0EdojCRKc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZQDBw03o98o47+aG98ZIrv04V/k//S5lv7NwILk/kl2zEehtFF/f0mkls1oaD/XgyRUUvxErk3KS4Edo/VgH1+mRWAYt1RK5OrpSO0Yyu9AorWnNytTqGyU5b33a7CFhiBVBPpfsCmzoYzcYYwrMVZYtyhq6GXqlzzwFfGUm90M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp; spf=pass smtp.mailfrom=rsg.ci.i.u-tokyo.ac.jp; dkim=fail (0-bit key) header.d=rsg.ci.i.u-tokyo.ac.jp header.i=@rsg.ci.i.u-tokyo.ac.jp header.b=aaJWz8Z2 reason="key not found in DNS"; arc=none smtp.client-ip=49.212.243.89 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rsg.ci.i.u-tokyo.ac.jp Authentication-Results: smtp.subspace.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=rsg.ci.i.u-tokyo.ac.jp header.i=@rsg.ci.i.u-tokyo.ac.jp header.b="aaJWz8Z2" Received: from h183.csg.ci.i.u-tokyo.ac.jp (h183.csg.ci.i.u-tokyo.ac.jp [133.11.54.183]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 66K5c7or075973 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Mon, 20 Jul 2026 14:38:27 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=rJV0BGKbynLh6AlkNF+I9wFJA5WzrqYIibCC+crWIrc=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Message-Id:To:Subject:Date; s=rs20250326; t=1784525908; v=1; b=aaJWz8Z2r8aKeqevDWxaOX1DzDQ1yUXHDWGsKzE8AMyuugf7Y+IHXQdO26GtKzXF nAzfzv5UgNJjPbmrzkbyfa9BgEjcCJNoA2MkCYpq9iUMlkJT/6kUZ8j7PbbYZQTl VJKcuD0ukMiAL9+rilKtoM85pbmwPiLbO08c4/KfKqItRIXywInZZRcOpIRiX8VU Ap3VR9l1jaRfG8oNq79s/OtbMdZ04tEWXVaxIApm/F+ZxzeN+TEDTkqLXJJnogus WVpzNszhj/VINT9zJH5QiXm90Yj5wOusRFQR9dEzHcMtmsolYQfXwHv8IfHTDoRL KlfIIpTNoRabJtm84xd3/Q== From: Akihiko Odaki Date: Mon, 20 Jul 2026 14:38:03 +0900 Subject: [PATCH v9 09/16] arm64: errata: Require Apple IMPDEF PMUv3 traps on all CPUs Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260720-hybrid-v9-9-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> References: <20260720-hybrid-v9-0-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20260720-hybrid-v9-0-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> To: Marc Zyngier , Oliver Upton , Joey Gouly , Suzuki K Poulose , Zenghui Yu , Catalin Marinas , Will Deacon , Kees Cook , "Gustavo A. R. Silva" , Paolo Bonzini , Jonathan Corbet , Shuah Khan , Shuah Khan , Yury Norov , Rasmus Villemoes , Steffen Eiden Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, devel@daynix.com, kvm@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Akihiko Odaki X-Mailer: b4 0.16-dev-925f5 X-Developer-Signature: v=1; a=openpgp-sha256; l=1700; i=odaki@rsg.ci.i.u-tokyo.ac.jp; h=from:subject:message-id; bh=0/AxsHDzqRNEUmxs91LVTqutnKtgRFxtYi0EdojCRKc=; b=owGbwMvMwCWmMbc20y1CyJDxtFoSQ1bsFs9HDkrl4hJbU4X+CDQdKat2Y5O9JXD2MstJ9YDXD +qL66w7SlkYxLgYZMUUWVKKdnNrRNd+KkyIb4GZw8oEMoSBi1MAJmL3hJHhsU/xsQdRJWaiRx/v D9Teb7Ryn8j0m8WRjc+eFuQlG4Y8ZvhncrN889szTuo+tuLmt3cJvWisEq+T9drU0DJZxCL8hzk rAA== X-Developer-Key: i=odaki@rsg.ci.i.u-tokyo.ac.jp; a=openpgp; fpr=AEDC03C9AF734F2EC26A7BFFA4BAEAA73536753C KVM relies on ARM64_WORKAROUND_PMUV3_IMPDEF_TRAPS as a system-wide precondition for PMUv3 emulation on affected Apple CPUs. A local CPU erratum is too weak for that: once the workaround is enabled, a late CPU that misses it may still be onlined. Make the workaround an all-early-CPU capability instead. The matcher is still local because it depends on MIDR_EL1, but the capability is only advertised if all early CPUs match. A late CPU that misses an advertised capability is therefore rejected. Although kept in the errata capability table, this capability describes optional trap support rather than a workaround required for safe CPU operation. A late CPU may therefore match it when the system does not. KVM treats an IMPDEF PMU as unimplemented unless the capability was finalized system-wide, so the additional trap support remains unused. Fixes: bed9b8ec8c71 ("KVM: arm64: Advertise PMUv3 if IMPDEF traps are prese= nt") Assisted-by: Codex:gpt-5.5 Signed-off-by: Akihiko Odaki --- arch/arm64/kernel/cpu_errata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index 1995e1198648..a5ae628204a1 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -1005,7 +1005,7 @@ const struct arm64_cpu_capabilities arm64_errata[] = =3D { { .desc =3D "Apple IMPDEF PMUv3 Traps", .capability =3D ARM64_WORKAROUND_PMUV3_IMPDEF_TRAPS, - .type =3D ARM64_CPUCAP_LOCAL_CPU_ERRATUM, + .type =3D ARM64_CPUCAP_EARLY_LOCAL_CPU_FEATURE, .matches =3D has_impdef_pmuv3, .cpu_enable =3D cpu_enable_impdef_pmuv3_traps, }, --=20 2.55.0 From nobody Sat Jul 25 03:22:07 2026 Received: from www3579.sakura.ne.jp (www3579.sakura.ne.jp [49.212.243.89]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EA7463A9852; Mon, 20 Jul 2026 05:39:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=49.212.243.89 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784525971; cv=none; b=q0tIurLpjCSv3mtlhW1v//ncTU35eiKIjMl7IdXNVH7zXpL5eqNYbCTsnC7GyzzQdYjayTQsB1QAMJWegii2zVtpDo6BRTPwzD2+OsB4vBsdfNRR9T+2ukSuHbKuRStQmyupHOAkMaPjb+uBbeh6e9t7jjXYUNlDH1c1e+AFAtE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784525971; c=relaxed/simple; bh=6akE14fE/frYWWq4DQRLjppr5V9zQSSM5zLzfJqWQNE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=VODw4xWL0WmTVBP3lRRWtf50zABm4fc2gXZ77ncA9Vq1ZCa1zb/fgg/JAK4uYLcWa2LJ1CqtQa6+eHgzb2WkDW/y5TbQEihOPb88D72+8PrXLH2LAy7jrg4Wb1HaDUgwInd2Eh1tyk6X9H9bNvTW5uq/ju+T+OpHR0SwMQDIAvM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp; spf=pass smtp.mailfrom=rsg.ci.i.u-tokyo.ac.jp; dkim=fail (0-bit key) header.d=rsg.ci.i.u-tokyo.ac.jp header.i=@rsg.ci.i.u-tokyo.ac.jp header.b=WnMAJ3dI reason="key not found in DNS"; arc=none smtp.client-ip=49.212.243.89 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rsg.ci.i.u-tokyo.ac.jp Authentication-Results: smtp.subspace.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=rsg.ci.i.u-tokyo.ac.jp header.i=@rsg.ci.i.u-tokyo.ac.jp header.b="WnMAJ3dI" Received: from h183.csg.ci.i.u-tokyo.ac.jp (h183.csg.ci.i.u-tokyo.ac.jp [133.11.54.183]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 66K5c7os075973 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Mon, 20 Jul 2026 14:38:28 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=Zeko5Okd0jmlXlufon0CsSK3pmAlC49DCGY0aE+GABo=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Message-Id:To:Subject:Date; s=rs20250326; t=1784525908; v=1; b=WnMAJ3dIkHmkuiqDCsnt4MjIe9dqnfg2ATTdY+MRDFkvitOqigwxPPug/AXXn1I2 FqxrK+zXqUw9yoKz+WGlVI6zm409Iy9PJCaQG56UmEUu+YI+I8b0nQ1Y66+gNZGI R3Mwc/E5hA7KJ/UzL/onFdVhQpgs3F6EUpG9HnUHWxUktYi1D4tv+qJQptD8X6zV wnzjiJ1ZoTPLAg1U/9ZLU5FandWDVNcanAkQNxtCs9sd/LNZM+PihluvfJhfs7i9 et5b8v7RNH1/uzTvCicaSrcaYnqio4jsxz7kN5ke9JYK+FKLJJB4qWo7zr8ZJpI4 3400pJYncgK0vr5CwQngfA== From: Akihiko Odaki Date: Mon, 20 Jul 2026 14:38:04 +0900 Subject: [PATCH v9 10/16] KVM: arm64: Don't clear vcpu->cpu in kvm_arch_vcpu_put() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260720-hybrid-v9-10-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> References: <20260720-hybrid-v9-0-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20260720-hybrid-v9-0-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> To: Marc Zyngier , Oliver Upton , Joey Gouly , Suzuki K Poulose , Zenghui Yu , Catalin Marinas , Will Deacon , Kees Cook , "Gustavo A. R. Silva" , Paolo Bonzini , Jonathan Corbet , Shuah Khan , Shuah Khan , Yury Norov , Rasmus Villemoes , Steffen Eiden Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, devel@daynix.com, kvm@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Akihiko Odaki X-Mailer: b4 0.16-dev-925f5 X-Developer-Signature: v=1; a=openpgp-sha256; l=2455; i=odaki@rsg.ci.i.u-tokyo.ac.jp; h=from:subject:message-id; bh=aa7MZ4VKOeuhZU18cZFCsTpkNsElv6XslXDKEEI3kxo=; b=owGbwMvMwCWmMbc20y1CyJDxtFoSQ1bsFi/eHTc/Baje89v/bsb3GysZA5O/TYl8ufORy8mcd qbDDzr2dJSyMIhxMciKKbKkFO3m1oiu/VSYEN8CM4eVCWQIAxenAEzkmCDDfxfVpheSr1QDuDW+ d7alOl5MOsYULLvYTcPxatjp1ODc+Qz/DByfKZo+y17MoDfHpXbxL/3jp559e9n1U/PajBCR58x POQE= X-Developer-Key: i=odaki@rsg.ci.i.u-tokyo.ac.jp; a=openpgp; fpr=AEDC03C9AF734F2EC26A7BFFA4BAEAA73536753C From: Oliver Upton commit e9b152cb957c ("arm/arm64: kvm: Set vcpu->cpu to -1 on vcpu_put") reset vcpu->cpu in order for the VGIC to determine if there was any vCPU running at the time of access. The VGIC has gone through an entire rewrite since then, and with commit 7d450e282171 ("KVM: arm/arm64: vgic-new: Add userland access to VGIC dist registers") the user accessors just grab all vCPU mutexes instead. Drop this remaining vestige such that kvm_arch_vcpu_load() can properly detect a CPU migration. While at it, rework kvm_reset_vcpu() to do a much more pedantic check that the provided vCPU is actually what's running on the present CPU. Signed-off-by: Oliver Upton Signed-off-by: Akihiko Odaki --- arch/arm64/kvm/arm.c | 1 - arch/arm64/kvm/reset.c | 16 +++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index a06ea39f57b1..72ce79ce4d5e 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -749,7 +749,6 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) kvm_arm_vmid_clear_active(); =20 vcpu_clear_on_unsupported_cpu(vcpu); - vcpu->cpu =3D -1; } =20 static void __kvm_arm_vcpu_power_off(struct kvm_vcpu *vcpu) diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c index b963fd975aac..6bfb21f00444 100644 --- a/arch/arm64/kvm/reset.c +++ b/arch/arm64/kvm/reset.c @@ -190,7 +190,8 @@ static void kvm_vcpu_reset_sve(struct kvm_vcpu *vcpu) void kvm_reset_vcpu(struct kvm_vcpu *vcpu) { struct vcpu_reset_state reset_state; - bool loaded; + struct kvm_vcpu *running; + bool loaded =3D false; u32 pstate; =20 spin_lock(&vcpu->arch.mp_state_lock); @@ -198,10 +199,16 @@ void kvm_reset_vcpu(struct kvm_vcpu *vcpu) vcpu->arch.reset_state.reset =3D false; spin_unlock(&vcpu->arch.mp_state_lock); =20 - preempt_disable(); - loaded =3D (vcpu->cpu !=3D -1); - if (loaded) + guard(preempt)(); + + running =3D kvm_get_running_vcpu(); + if (running) { + if (KVM_BUG_ON(running !=3D vcpu, vcpu->kvm)) + return; + + loaded =3D true; kvm_arch_vcpu_put(vcpu); + } =20 if (!kvm_arm_vcpu_sve_finalized(vcpu)) { if (vcpu_has_feature(vcpu, KVM_ARM_VCPU_SVE)) @@ -269,7 +276,6 @@ void kvm_reset_vcpu(struct kvm_vcpu *vcpu) =20 if (loaded) kvm_arch_vcpu_load(vcpu, smp_processor_id()); - preempt_enable(); } =20 u32 kvm_get_pa_bits(struct kvm *kvm) --=20 2.55.0 From nobody Sat Jul 25 03:22:07 2026 Received: from www3579.sakura.ne.jp (www3579.sakura.ne.jp [49.212.243.89]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 645443A59A7; Mon, 20 Jul 2026 05:39:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=49.212.243.89 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784525971; cv=none; b=YqowzUXXrLA439VhsT6tggzp3jHBjugh4He5H9bsZEVoG0tKZGou2WZbEYpKYURSTwmiMhykvIB87TKhoxb6rBBoHepkUm432bKSVlG7q6z6xX/59fyxbsPwhvfB5TgNU5mpLKv/WPCEoeHwamNMqrK9E5I+zDWMgnwsKuIIBqw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784525971; c=relaxed/simple; bh=sA6PHZrE+eChltBNP/YRFOEZoFp0fBLLFqrnJLkkuLQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=BtZwpwGG1lZ7Pgj4Tu+Mf34zog6KYOvxnZMv1vCw2PT0+C/fOIz9b5ZW/fmzk4FjUIRi9yUGP5vxfViNFffemmw6H9JHR8yw+ROvKUF5ai3cKkzmJjLo0JvGDoqttEo/49++m1Y49xhup/7ytRj3mK+TJcp0Y3IWxibNDU0LjDk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp; spf=pass smtp.mailfrom=rsg.ci.i.u-tokyo.ac.jp; dkim=fail (0-bit key) header.d=rsg.ci.i.u-tokyo.ac.jp header.i=@rsg.ci.i.u-tokyo.ac.jp header.b=fiQY9CsU reason="key not found in DNS"; arc=none smtp.client-ip=49.212.243.89 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rsg.ci.i.u-tokyo.ac.jp Authentication-Results: smtp.subspace.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=rsg.ci.i.u-tokyo.ac.jp header.i=@rsg.ci.i.u-tokyo.ac.jp header.b="fiQY9CsU" Received: from h183.csg.ci.i.u-tokyo.ac.jp (h183.csg.ci.i.u-tokyo.ac.jp [133.11.54.183]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 66K5c7ot075973 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Mon, 20 Jul 2026 14:38:28 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=O8vvC+qcqQ6sKtJfRDWaxkOkLTGUo5713aT+sloywJY=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Message-Id:To:Subject:Date; s=rs20250326; t=1784525908; v=1; b=fiQY9CsUT0ihHExzZEwRWZZdmAoL946rPzpyecbrDAQWhBZ3qiExm8AcHzhUGZi4 L56D0g/EcaOwZQBzUmobrELA4Pvhkv0DUzPJnpp6tzTBjlTIf/2ktZKS4G97AlYq 1CCeFl9vj1T3lRxgnZvVN2UbkrCPDbadu4Clvch/VWVpwbVsKQ7+1oz33ajawIb2 g0j+2RNKJZzKteqeYHMcfJr7ZSTyoDH81UF8dI5ZiZZ5Q4mPM7NKFOMtLt1PLDFW 852XA0mEEGzTNEsCBXp1dPYO+0vMRHVCaJCGmDp/t95yYP+Ueo39XVW1TMzOyQvb ln0j+f36X9juDnSSLTuAYQ== From: Akihiko Odaki Date: Mon, 20 Jul 2026 14:38:05 +0900 Subject: [PATCH v9 11/16] KVM: arm64: PMU: Protect the list of PMUs with RCU Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260720-hybrid-v9-11-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> References: <20260720-hybrid-v9-0-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20260720-hybrid-v9-0-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> To: Marc Zyngier , Oliver Upton , Joey Gouly , Suzuki K Poulose , Zenghui Yu , Catalin Marinas , Will Deacon , Kees Cook , "Gustavo A. R. Silva" , Paolo Bonzini , Jonathan Corbet , Shuah Khan , Shuah Khan , Yury Norov , Rasmus Villemoes , Steffen Eiden Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, devel@daynix.com, kvm@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Akihiko Odaki X-Mailer: b4 0.16-dev-925f5 X-Developer-Signature: v=1; a=openpgp-sha256; l=2740; i=odaki@rsg.ci.i.u-tokyo.ac.jp; h=from:subject:message-id; bh=sA6PHZrE+eChltBNP/YRFOEZoFp0fBLLFqrnJLkkuLQ=; b=owGbwMvMwCWmMbc20y1CyJDxtFoSQ1bsFu/yoJM/xSy9atJ3Zy2embnIxuXT/tjS3Sfmfyvkv pPA8fVMRykLgxgXg6yYIktK0W5ujejaT4UJ8S0wc1iZQIYwcHEKwEROSTH8d33MzFvGu+rNwXpB 7/+XRZ9YON8x6bVbvNDqKZcQ38lnvQy/2ZcE9C87vCWuwOqxGcfbS8/FOT/82rjjkOmnv9n5tmX tXAA= X-Developer-Key: i=odaki@rsg.ci.i.u-tokyo.ac.jp; a=openpgp; fpr=AEDC03C9AF734F2EC26A7BFFA4BAEAA73536753C Convert the list of PMUs to a RCU-protected list that has primitives to avoid read-side contention. Assisted-by: Codex:gpt-5.5 Signed-off-by: Akihiko Odaki --- arch/arm64/kvm/pmu-emul.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c index 9ac5f307ea31..c5c505b6fc61 100644 --- a/arch/arm64/kvm/pmu-emul.c +++ b/arch/arm64/kvm/pmu-emul.c @@ -7,9 +7,9 @@ #include #include #include -#include #include #include +#include #include #include #include @@ -20,6 +20,10 @@ #define MDCR_EL2_PMU_RECREATE_MASK (MDCR_EL2_HPMN | MDCR_EL2_HPMD | \ MDCR_EL2_HLP) =20 +/* + * arm_pmus is append-only. kvm_supports_guest_pmuv3() feeds persistent + * VM state, so a true result must remain valid after the check. + */ static LIST_HEAD(arm_pmus); static DEFINE_MUTEX(arm_pmus_lock); =20 @@ -29,7 +33,6 @@ static bool kvm_pmu_counter_is_enabled(struct kvm_pmc *pm= c); =20 bool kvm_supports_guest_pmuv3(void) { - guard(mutex)(&arm_pmus_lock); return !list_empty(&arm_pmus); } =20 @@ -807,7 +810,7 @@ void kvm_host_pmu_init(struct arm_pmu *pmu) return; =20 entry->arm_pmu =3D pmu; - list_add_tail(&entry->entry, &arm_pmus); + list_add_tail_rcu(&entry->entry, &arm_pmus); } =20 static struct arm_pmu *kvm_pmu_probe_armpmu(void) @@ -816,7 +819,7 @@ static struct arm_pmu *kvm_pmu_probe_armpmu(void) struct arm_pmu *pmu; int cpu; =20 - guard(mutex)(&arm_pmus_lock); + guard(rcu)(); =20 /* * It is safe to use a stale cpu to iterate the list of PMUs so long as @@ -836,7 +839,7 @@ static struct arm_pmu *kvm_pmu_probe_armpmu(void) * carried here. */ cpu =3D raw_smp_processor_id(); - list_for_each_entry(entry, &arm_pmus, entry) { + list_for_each_entry_rcu(entry, &arm_pmus, entry) { pmu =3D entry->arm_pmu; =20 if (cpumask_test_cpu(cpu, &pmu->supported_cpus)) @@ -1088,9 +1091,9 @@ static int kvm_arm_pmu_v3_set_pmu(struct kvm_vcpu *vc= pu, int pmu_id) int ret =3D -ENXIO; =20 lockdep_assert_held(&kvm->arch.config_lock); - mutex_lock(&arm_pmus_lock); + guard(rcu)(); =20 - list_for_each_entry(entry, &arm_pmus, entry) { + list_for_each_entry_rcu(entry, &arm_pmus, entry) { arm_pmu =3D entry->arm_pmu; if (arm_pmu->pmu.type =3D=3D pmu_id) { if (kvm_vm_has_ran_once(kvm) || @@ -1106,7 +1109,6 @@ static int kvm_arm_pmu_v3_set_pmu(struct kvm_vcpu *vc= pu, int pmu_id) } } =20 - mutex_unlock(&arm_pmus_lock); return ret; } =20 --=20 2.55.0 From nobody Sat Jul 25 03:22:07 2026 Received: from www3579.sakura.ne.jp (www3579.sakura.ne.jp [49.212.243.89]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5F0EF3AC0CE; Mon, 20 Jul 2026 05:39:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=49.212.243.89 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784525973; cv=none; b=S6VoSKBN7mu5qR29SDySSFaqvDePrHHRyOUiAnqvO35/ZidrbyQD3oiRWnRhiIfay1wnAnAoyBiXWI+7so2ASJI3G26TwE2wmUOFe/pRH+usVlS6YuK2IOo3F9c1CWTttvYIWMa841TJEcIZ0lssKJuEy+jPnJsm92/LwJo2ts4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784525973; c=relaxed/simple; bh=nDU8HixdRK1d+2i2v52T+AZ6ha5pTl2G+ZCt/ZW0yyI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=sVIaEIZmY8VoDk2Nc7SsgUxWvyG4Ykw4/xHww/qFIGoD+j2hYTUYdF0QM6Wbc8zNui6nkLOmD+MgDxprojeJMsV0U66hyeED0PGoSiQRSOjwhksxuLjUwYlLdxR/4V5FxyUc/N5sdMRpZL6Pba7nxlhNvD5ue8cPBQSFi28sQ/E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp; spf=pass smtp.mailfrom=rsg.ci.i.u-tokyo.ac.jp; dkim=fail (0-bit key) header.d=rsg.ci.i.u-tokyo.ac.jp header.i=@rsg.ci.i.u-tokyo.ac.jp header.b=AZH0nuF/ reason="key not found in DNS"; arc=none smtp.client-ip=49.212.243.89 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rsg.ci.i.u-tokyo.ac.jp Authentication-Results: smtp.subspace.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=rsg.ci.i.u-tokyo.ac.jp header.i=@rsg.ci.i.u-tokyo.ac.jp header.b="AZH0nuF/" Received: from h183.csg.ci.i.u-tokyo.ac.jp (h183.csg.ci.i.u-tokyo.ac.jp [133.11.54.183]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 66K5c7ou075973 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Mon, 20 Jul 2026 14:38:28 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=ieFQW3xe2YYYDcYZo+2gysoiQSrGYoM9MEjQ+nrFpOg=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Message-Id:To:Subject:Date; s=rs20250326; t=1784525909; v=1; b=AZH0nuF/xXQaSP46dM8HH0MZuKjJeAaUaaLl83y8jHsvOO6qDlwtf97xkLV6DbnN OX+5w3p1K2tj8MMwz8cVtKWD8w90P+22cS7CZMIZ2/PFsoZTjf6lBjPyAgwKD6Nu UmN3n3lSV3YbSNU1fHpnGchMu89JPetp4+9wFrolKvroAmFZ2ozpkXrFdZhV/Pr8 fV3O0YtthXdPE7wQRwXU5jmK7KszqgvUpCspETi7Iyb3OAM16VQbX4uXUXwTbkf+ DsL6fuSG6j4XPSachvWDDGdJqNqx7fhKRyLNWWvB6/M4oyR/vnGtSa7ozWKoZey6 6dJoDjigTDDYVtiac9Q5GA== From: Akihiko Odaki Date: Mon, 20 Jul 2026 14:38:06 +0900 Subject: [PATCH v9 12/16] KVM: arm64: PMU: Pass the pPMU to kvm_map_pmu_event() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260720-hybrid-v9-12-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> References: <20260720-hybrid-v9-0-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20260720-hybrid-v9-0-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> To: Marc Zyngier , Oliver Upton , Joey Gouly , Suzuki K Poulose , Zenghui Yu , Catalin Marinas , Will Deacon , Kees Cook , "Gustavo A. R. Silva" , Paolo Bonzini , Jonathan Corbet , Shuah Khan , Shuah Khan , Yury Norov , Rasmus Villemoes , Steffen Eiden Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, devel@daynix.com, kvm@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Akihiko Odaki X-Mailer: b4 0.16-dev-925f5 X-Developer-Signature: v=1; a=openpgp-sha256; l=1455; i=odaki@rsg.ci.i.u-tokyo.ac.jp; h=from:subject:message-id; bh=nDU8HixdRK1d+2i2v52T+AZ6ha5pTl2G+ZCt/ZW0yyI=; b=owGbwMvMwCWmMbc20y1CyJDxtFoSQ1bsFh8vq4BJpRNjM/9+n1184c2Pm9Pue6hynNdcUKfyp n32CWWrjlIWBjEuBlkxRZaUot3cGtG1nwoT4ltg5rAygQxh4OIUgIkIszAyvEhaL5L38Dr30hvn BIw/d3v8XGnSnPB3Kyvvlkmz/8mc/MbIcN3BuLRCqfuH4nfH98eOz1J7O41p6b7yiD37Hr7g6JO 6zQgA X-Developer-Key: i=odaki@rsg.ci.i.u-tokyo.ac.jp; a=openpgp; fpr=AEDC03C9AF734F2EC26A7BFFA4BAEAA73536753C Replace the VM argument with the pPMU used for event creation. The current caller still passes the VM's default pPMU, but this removes the implicit lookup from kvm_map_pmu_event() so later changes can map events against the pPMU selected for an individual vCPU. Signed-off-by: Akihiko Odaki --- arch/arm64/kvm/pmu-emul.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c index c5c505b6fc61..27db8877f96e 100644 --- a/arch/arm64/kvm/pmu-emul.c +++ b/arch/arm64/kvm/pmu-emul.c @@ -670,10 +670,8 @@ static bool kvm_pmc_counts_at_el2(struct kvm_pmc *pmc) return kvm_pmc_read_evtreg(pmc) & ARMV8_PMU_INCLUDE_EL2; } =20 -static int kvm_map_pmu_event(struct kvm *kvm, unsigned int eventsel) +static int kvm_map_pmu_event(struct arm_pmu *pmu, unsigned int eventsel) { - struct arm_pmu *pmu =3D kvm->arch.arm_pmu; - /* * The CPU PMU likely isn't PMUv3; let the driver provide a mapping * for the guest's PMUv3 event ID. @@ -725,7 +723,7 @@ static void kvm_pmu_create_perf_event(struct kvm_pmc *p= mc) * Don't create an event if we're running on hardware that requires * PMUv3 event translation and we couldn't find a valid mapping. */ - eventsel =3D kvm_map_pmu_event(vcpu->kvm, eventsel); + eventsel =3D kvm_map_pmu_event(vcpu->kvm->arch.arm_pmu, eventsel); if (eventsel < 0) return; =20 --=20 2.55.0 From nobody Sat Jul 25 03:22:07 2026 Received: from www3579.sakura.ne.jp (www3579.sakura.ne.jp [49.212.243.89]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6526D3AC0D9; Mon, 20 Jul 2026 05:39:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=49.212.243.89 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784525973; cv=none; b=APnvt4b0RU0gIJswkhVqNGYCaUWyj6eRkMAbS9UzMTv+rdKngrktRjckwdkVVST6SwalHnLkjvGlGEsEvi2VKehWn/Y2ClHDJ916i+YkLzHriDgSp3TnPVORFhWulKGOr+YexHYgJasgvlkL6CdLTxE4ZQWjNF3yBilAOuqKoU0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784525973; c=relaxed/simple; bh=WMFStzPwxGo9/CLh6+gBDb79KsWaVVshyeopvFLJ5WE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=LzJNsJrg7uaDMYGo5gt5HCHNxxf0UBzMWhAco09CqjGP67ufZBmCRBErNaghnz0q/2YFbk9g9Y1ywSua2KkFRhHq34xs09XcD+Tujo/2D83PPkKP9XIjLieN6bIg9vPOueIRer+C9eF46Q7YkMVMUPFJkG5kQVS2LiP9e903kTw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp; spf=pass smtp.mailfrom=rsg.ci.i.u-tokyo.ac.jp; dkim=fail (0-bit key) header.d=rsg.ci.i.u-tokyo.ac.jp header.i=@rsg.ci.i.u-tokyo.ac.jp header.b=Au52tJQ7 reason="key not found in DNS"; arc=none smtp.client-ip=49.212.243.89 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rsg.ci.i.u-tokyo.ac.jp Authentication-Results: smtp.subspace.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=rsg.ci.i.u-tokyo.ac.jp header.i=@rsg.ci.i.u-tokyo.ac.jp header.b="Au52tJQ7" Received: from h183.csg.ci.i.u-tokyo.ac.jp (h183.csg.ci.i.u-tokyo.ac.jp [133.11.54.183]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 66K5c7ov075973 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Mon, 20 Jul 2026 14:38:29 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=j7sWr3lP3gUNcCOHDT5toIViFIw3oVR+P1TswXAYwYE=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Message-Id:To:Subject:Date; s=rs20250326; t=1784525909; v=1; b=Au52tJQ7rNRnAi3NSc4uvcvWimSIxCHYyvECNrRbILLgxPedffesNzYPfUkdI164 shKvAEQJn9w2V1cQXDQZb/2uTVuMoOPbw4aCR2k9opLzdPrQNDRwTjCDTNLwt0tI ArPxnHZqsgG3Mk0GZMYcwwUDJD/XntyDvee0Vnu57GXMQxDJiqjcf28Q1OF+FGbl dtXvLunmd5j0Hxv6aFsif18H2hqr0TabZUrV2wAOC8n88auY5XsIRGUH6EsIO5h5 kKfKo1b6DMqw3+Pr3THni50RYTbngpDN1jmj/LkkbQLM/mHc/Z5IhuLu6sJZzLYZ mZS87X4MFkZOKoywJJZvvg== From: Akihiko Odaki Date: Mon, 20 Jul 2026 14:38:07 +0900 Subject: [PATCH v9 13/16] KVM: arm64: PMU: Pass the target CPU to kvm_pmu_probe_armpmu() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260720-hybrid-v9-13-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> References: <20260720-hybrid-v9-0-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20260720-hybrid-v9-0-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> To: Marc Zyngier , Oliver Upton , Joey Gouly , Suzuki K Poulose , Zenghui Yu , Catalin Marinas , Will Deacon , Kees Cook , "Gustavo A. R. Silva" , Paolo Bonzini , Jonathan Corbet , Shuah Khan , Shuah Khan , Yury Norov , Rasmus Villemoes , Steffen Eiden Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, devel@daynix.com, kvm@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Akihiko Odaki X-Mailer: b4 0.16-dev-925f5 X-Developer-Signature: v=1; a=openpgp-sha256; l=4094; i=odaki@rsg.ci.i.u-tokyo.ac.jp; h=from:subject:message-id; bh=WMFStzPwxGo9/CLh6+gBDb79KsWaVVshyeopvFLJ5WE=; b=owGbwMvMwCWmMbc20y1CyJDxtFoSQ1bsFt8+htCtDpP4lrMvCP64IifidfSmL3YSK6aFJu6pK 3q48cyrjlIWBjEuBlkxRZaUot3cGtG1nwoT4ltg5rAygQxh4OIUgInwpjAyHH7csk32nalxpxf3 iXmfSphOaMk+u7Q+gOnOhZD1G5XFHjD8T99jY3ZB9PVzk6WvugMvPHqYquUy+8/9LxGsKyd874l byg0A X-Developer-Key: i=odaki@rsg.ci.i.u-tokyo.ac.jp; a=openpgp; fpr=AEDC03C9AF734F2EC26A7BFFA4BAEAA73536753C kvm_pmu_probe_armpmu() currently samples the current CPU internally, which ties the helper to default PMU selection. Move that policy to kvm_arm_set_default_pmu() by passing raw_smp_processor_id() from the caller, and make the helper search for the pPMU covering an explicit CPU. Move the helper above kvm_pmu_create_perf_event() so later code can reuse it when creating PMU events for a VCPU's current pCPU. This preserves the existing default PMU selection behavior while preparing fixed-counters-only mode to select a pPMU at runtime. Signed-off-by: Akihiko Odaki --- arch/arm64/kvm/pmu-emul.c | 72 +++++++++++++++++++++++--------------------= ---- 1 file changed, 35 insertions(+), 37 deletions(-) diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c index 27db8877f96e..78611eaecca2 100644 --- a/arch/arm64/kvm/pmu-emul.c +++ b/arch/arm64/kvm/pmu-emul.c @@ -682,6 +682,23 @@ static int kvm_map_pmu_event(struct arm_pmu *pmu, unsi= gned int eventsel) return eventsel; } =20 +static struct arm_pmu *kvm_pmu_probe_armpmu(int cpu) +{ + struct arm_pmu_entry *entry; + struct arm_pmu *pmu; + + guard(rcu)(); + + list_for_each_entry_rcu(entry, &arm_pmus, entry) { + pmu =3D entry->arm_pmu; + + if (cpumask_test_cpu(cpu, &pmu->supported_cpus)) + return pmu; + } + + return NULL; +} + /** * kvm_pmu_create_perf_event - create a perf event for a counter * @pmc: Counter context @@ -811,42 +828,6 @@ void kvm_host_pmu_init(struct arm_pmu *pmu) list_add_tail_rcu(&entry->entry, &arm_pmus); } =20 -static struct arm_pmu *kvm_pmu_probe_armpmu(void) -{ - struct arm_pmu_entry *entry; - struct arm_pmu *pmu; - int cpu; - - guard(rcu)(); - - /* - * It is safe to use a stale cpu to iterate the list of PMUs so long as - * the same value is used for the entirety of the loop. Given this, and - * the fact that no percpu data is used for the lookup there is no need - * to disable preemption. - * - * It is still necessary to get a valid cpu, though, to probe for the - * default PMU instance as userspace is not required to specify a PMU - * type. In order to uphold the preexisting behavior KVM selects the - * PMU instance for the core during vcpu init. A dependent use - * case would be a user with disdain of all things big.LITTLE that - * affines the VMM to a particular cluster of cores. - * - * In any case, userspace should just do the sane thing and use the UAPI - * to select a PMU type directly. But, be wary of the baggage being - * carried here. - */ - cpu =3D raw_smp_processor_id(); - list_for_each_entry_rcu(entry, &arm_pmus, entry) { - pmu =3D entry->arm_pmu; - - if (cpumask_test_cpu(cpu, &pmu->supported_cpus)) - return pmu; - } - - return NULL; -} - static u64 __compute_pmceid(struct arm_pmu *pmu, bool pmceid1) { u32 hi[2], lo[2]; @@ -1072,7 +1053,24 @@ static void kvm_arm_set_pmu(struct kvm *kvm, struct = arm_pmu *arm_pmu) */ int kvm_arm_set_default_pmu(struct kvm *kvm) { - struct arm_pmu *arm_pmu =3D kvm_pmu_probe_armpmu(); + /* + * It is safe to use a stale cpu to iterate the list of PMUs so long as + * the same value is used for the entirety of the loop. Given this, and + * the fact that no percpu data is used for the lookup there is no need + * to disable preemption. + * + * It is still necessary to get a valid cpu, though, to probe for the + * default PMU instance as userspace is not required to specify a PMU + * type. In order to uphold the preexisting behavior KVM selects the + * PMU instance for the core during vcpu init. A dependent use + * case would be a user with disdain of all things big.LITTLE that + * affines the VMM to a particular cluster of cores. + * + * In any case, userspace should just do the sane thing and use the UAPI + * to select a PMU type directly. But, be wary of the baggage being + * carried here. + */ + struct arm_pmu *arm_pmu =3D kvm_pmu_probe_armpmu(raw_smp_processor_id()); =20 if (!arm_pmu) return -ENODEV; --=20 2.55.0 From nobody Sat Jul 25 03:22:07 2026 Received: from www3579.sakura.ne.jp (www3579.sakura.ne.jp [49.212.243.89]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 401322288D5; Mon, 20 Jul 2026 05:39:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=49.212.243.89 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784525971; cv=none; b=bPNkMmEIlHwxTP0n+onE+cQoAM5eFgUEGSeR+7Kou0Wmhbaum2biOXHaYKXJnLwpjIK/wyP2X6g0zKquaZFXjBEDNEliEyV9rq3ZK9w2gbsUHFcae74FeKLY0Ac4pzwDlEBld67YvwDPH0p0c4MKC20PFngbE9ypIXIfR0QKd2o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784525971; c=relaxed/simple; bh=5blB3RQA8m7tyXEU5zKNBsOf3WzXJjE+M59TXrU1UJM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=KXU+5cPoOx7JrrnmcS0MS4f+NGOC+EuLl0Qx4jZwyhBnhw4r0A3D83wcNHtcpObltzw6hQSm4joDGhMS/AT6UwsCiEXMmmRvPH1GYniTiLRgrJJnDBgxYe3PsuJSUWZSntG0qXkWkyhUVf2eAhtHf/kxclPUciJx0TLQ87ALz5Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp; spf=pass smtp.mailfrom=rsg.ci.i.u-tokyo.ac.jp; dkim=fail (0-bit key) header.d=rsg.ci.i.u-tokyo.ac.jp header.i=@rsg.ci.i.u-tokyo.ac.jp header.b=fGKFB0Ct reason="key not found in DNS"; arc=none smtp.client-ip=49.212.243.89 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rsg.ci.i.u-tokyo.ac.jp Authentication-Results: smtp.subspace.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=rsg.ci.i.u-tokyo.ac.jp header.i=@rsg.ci.i.u-tokyo.ac.jp header.b="fGKFB0Ct" Received: from h183.csg.ci.i.u-tokyo.ac.jp (h183.csg.ci.i.u-tokyo.ac.jp [133.11.54.183]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 66K5c7ow075973 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Mon, 20 Jul 2026 14:38:29 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=SbquS8dThfLjYTgQykWTIghGlpNUg51V5DGNR0iEF9k=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Message-Id:To:Subject:Date; s=rs20250326; t=1784525909; v=1; b=fGKFB0CtohssBDNzN4qHamVhFszaiCizEGqkIi/y7A7jbbs2aWautoxOQU15FiC0 tcx3qqa+ipVc2vRDb6QgcUOo+oYUaXsHGelMmtCYj6GG+HbXTvlMHGv8ENAU7tp0 bXpzOa7svRB7BR3XGTSmmppbIZpGZ2IH2VrlXpEMRLn9H+v15cCAEb9ws992w+Gm iTbcOAF8kNjv1M29DsmRzZHH3zzaVaUkfsz8+cCyWoNuXTmHz69gK+2YrmYl+DD7 7FLccL/NLazXbTJ43OXAapPPmAdl1eI/bOAxLlJB4VHJCQ0enPQb/+yIv245xt2Z ffEduXKf1JHE5ET9LfS37A== From: Akihiko Odaki Date: Mon, 20 Jul 2026 14:38:08 +0900 Subject: [PATCH v9 14/16] KVM: arm64: PMU: Implement fixed-counters-only emulation Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260720-hybrid-v9-14-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> References: <20260720-hybrid-v9-0-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20260720-hybrid-v9-0-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> To: Marc Zyngier , Oliver Upton , Joey Gouly , Suzuki K Poulose , Zenghui Yu , Catalin Marinas , Will Deacon , Kees Cook , "Gustavo A. R. Silva" , Paolo Bonzini , Jonathan Corbet , Shuah Khan , Shuah Khan , Yury Norov , Rasmus Villemoes , Steffen Eiden Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, devel@daynix.com, kvm@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Akihiko Odaki X-Mailer: b4 0.16-dev-925f5 X-Developer-Signature: v=1; a=openpgp-sha256; l=8638; i=odaki@rsg.ci.i.u-tokyo.ac.jp; h=from:subject:message-id; bh=5blB3RQA8m7tyXEU5zKNBsOf3WzXJjE+M59TXrU1UJM=; b=owGbwMvMwCWmMbc20y1CyJDxtFoSQ1bsFj9u6aBb/7Z8yHtpYvnnxZvbecrb7DmD62+nyvZ/q n2u9up/RykLgxgXg6yYIktK0W5ujejaT4UJ8S0wc1iZQIYwcHEKwEQy+Bh+MbVtEnr2b81nY1fe XzoPeOuPyPD7Wyo11h3o/PHadiv7XYb/qbmvVnJfjn/3zPXiwkqhfL1D1wX0t38tCLRWa60RXba IEQA= X-Developer-Key: i=odaki@rsg.ci.i.u-tokyo.ac.jp; a=openpgp; fpr=AEDC03C9AF734F2EC26A7BFFA4BAEAA73536753C Add internal state for PMUv3 emulation without programmable event counters. When fixed-counters-only mode is active, KVM reports no programmable counters and hides PMCEID, avoiding event-counter state whose behavior can depend on the selected hardware PMU. The cycle counter still uses a host perf event. Unlike the normal PMU path, fixed-counters-only mode may create that event from the hardware PMU attached to the VCPU's current pCPU. If the VCPU later loads on a pCPU that is not covered by the existing event's PMU, request a PMU reload so the cycle counter can be recreated against the new pCPU's PMU. Keep this affinity check limited to fixed-counters-only VMs; the normal programmable-counter mode continues to use the VM-wide PMU and does not need per-load reload decisions. Registered pPMUs must cover every CPU on which fixed-counters-only emulation runs. On ACPI systems, a CPU brought online after PMU probing may have an unregistered PMU implementation. Full coverage is also not guaranteed when ARM64_WORKAROUND_PMUV3_IMPDEF_TRAPS is present. Treat uncovered CPUs as unsupported and add TAINT_CPU_OUT_OF_SPEC. Add a separate internal flag for explicit userspace PMU selection. The UAPI wiring added later will use it to keep explicit PMU selection and fixed-counters-only mode mutually exclusive while still allowing fixed-counters-only mode to replace the default PMU selected during KVM_ARM_VCPU_INIT. The UAPI wiring that sets the fixed-counters-only flag and records explicit PMU selection is added later in the series. Assisted-by: Codex:gpt-5.5 Signed-off-by: Akihiko Odaki --- arch/arm64/include/asm/kvm_host.h | 4 +++ arch/arm64/kvm/arm.c | 2 ++ arch/arm64/kvm/pmu-emul.c | 67 ++++++++++++++++++++++++++++++++++-= ---- include/kvm/arm_pmu.h | 2 ++ 4 files changed, 67 insertions(+), 8 deletions(-) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm= _host.h index bae2c4f92ef5..3998e66c6571 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -367,6 +367,10 @@ 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 + /* PMUv3 is emulated with an explicitly specified hardware PMU */ +#define KVM_ARCH_FLAG_PMU_V3_EXPLICIT 12 + /* PMUv3 is emulated without programmable event counters */ +#define KVM_ARCH_FLAG_PMU_V3_FIXED_COUNTERS_ONLY 13 unsigned long flags; =20 /* VM-wide vCPU feature set */ diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 72ce79ce4d5e..a866beb8d873 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -651,6 +651,7 @@ static bool kvm_vcpu_should_clear_twe(struct kvm_vcpu *= vcpu) void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) { struct kvm_s2_mmu *mmu; + int last_cpu =3D vcpu->cpu; int *last_ran; =20 if (is_protected_kvm_enabled()) @@ -700,6 +701,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) if (has_vhe()) kvm_vcpu_load_vhe(vcpu); kvm_arch_vcpu_load_fp(vcpu); + kvm_vcpu_load_pmu(vcpu, last_cpu); kvm_vcpu_pmu_restore_guest(vcpu); if (kvm_arm_is_pvtime_enabled(&vcpu->arch)) kvm_make_request(KVM_REQ_RECORD_STEAL, vcpu); diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c index 78611eaecca2..1ec09ef28467 100644 --- a/arch/arm64/kvm/pmu-emul.c +++ b/arch/arm64/kvm/pmu-emul.c @@ -86,6 +86,11 @@ u64 kvm_pmu_evtyper_mask(struct kvm *kvm) return mask; } =20 +static bool kvm_pmu_fixed_counters_only(struct kvm *kvm) +{ + return test_bit(KVM_ARCH_FLAG_PMU_V3_FIXED_COUNTERS_ONLY, &kvm->arch.flag= s); +} + /** * kvm_pmc_is_64bit - determine if counter is 64bit * @pmc: counter context @@ -333,7 +338,12 @@ u64 kvm_pmu_implemented_counter_mask(struct kvm_vcpu *= vcpu) =20 static void kvm_pmc_enable_perf_event(struct kvm_pmc *pmc) { - if (!pmc->perf_event) { + struct kvm_vcpu *vcpu =3D kvm_pmc_to_vcpu(pmc); + + if (!pmc->perf_event || + (kvm_pmu_fixed_counters_only(vcpu->kvm) && + !cpumask_test_cpu(READ_ONCE(vcpu->cpu), + &to_arm_pmu(pmc->perf_event->pmu)->supported_cpus))) { kvm_pmu_create_perf_event(pmc); return; } @@ -699,14 +709,10 @@ static struct arm_pmu *kvm_pmu_probe_armpmu(int cpu) return NULL; } =20 -/** - * kvm_pmu_create_perf_event - create a perf event for a counter - * @pmc: Counter context - */ -static void kvm_pmu_create_perf_event(struct kvm_pmc *pmc) +static void kvm_pmu_create_perf_event_with_pmu(struct kvm_pmc *pmc, + struct arm_pmu *arm_pmu) { struct kvm_vcpu *vcpu =3D kvm_pmc_to_vcpu(pmc); - struct arm_pmu *arm_pmu =3D vcpu->kvm->arch.arm_pmu; struct perf_event *event; struct perf_event_attr attr; int eventsel; @@ -740,7 +746,7 @@ static void kvm_pmu_create_perf_event(struct kvm_pmc *p= mc) * Don't create an event if we're running on hardware that requires * PMUv3 event translation and we couldn't find a valid mapping. */ - eventsel =3D kvm_map_pmu_event(vcpu->kvm->arch.arm_pmu, eventsel); + eventsel =3D kvm_map_pmu_event(arm_pmu, eventsel); if (eventsel < 0) return; =20 @@ -785,6 +791,32 @@ static void kvm_pmu_create_perf_event(struct kvm_pmc *= pmc) pmc->perf_event =3D event; } =20 +/** + * kvm_pmu_create_perf_event - create a perf event for a counter + * @pmc: Counter context + */ +static void kvm_pmu_create_perf_event(struct kvm_pmc *pmc) +{ + struct kvm_vcpu *vcpu =3D kvm_pmc_to_vcpu(pmc); + struct arm_pmu *arm_pmu =3D vcpu->kvm->arch.arm_pmu; + + if (kvm_pmu_fixed_counters_only(vcpu->kvm)) { + do { + arm_pmu =3D kvm_pmu_probe_armpmu(READ_ONCE(vcpu->cpu)); + + if (!arm_pmu) { + pr_warn_once("kvm: Unsupported PMU variation detected.\n"); + add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_STILL_OK); + return; + } + + kvm_pmu_create_perf_event_with_pmu(pmc, arm_pmu); + } while (!cpumask_test_cpu(READ_ONCE(vcpu->cpu), &arm_pmu->supported_cpu= s)); + } else { + kvm_pmu_create_perf_event_with_pmu(pmc, arm_pmu); + } +} + /** * kvm_pmu_set_counter_event_type - set selected counter to monitor some e= vent * @vcpu: The vcpu pointer @@ -870,6 +902,13 @@ u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmc= eid1) u64 val, mask =3D 0; int base, i, nr_events; =20 + /* + * Hide the hardware PMU's event set to keep PMCEID stable across + * physical CPU migration. + */ + if (kvm_pmu_fixed_counters_only(vcpu->kvm)) + return 0; + if (!pmceid1) { val =3D compute_pmceid0(cpu_pmu); base =3D 0; @@ -897,6 +936,15 @@ u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmc= eid1) return val & mask; } =20 +void kvm_vcpu_load_pmu(struct kvm_vcpu *vcpu, int last_cpu) +{ + if (!kvm_pmu_fixed_counters_only(vcpu->kvm) || vcpu->cpu =3D=3D last_cpu = || last_cpu =3D=3D -1) + return; + + if (kvm_pmu_probe_armpmu(vcpu->cpu) !=3D kvm_pmu_probe_armpmu(last_cpu)) + kvm_make_request(KVM_REQ_RELOAD_PMU, vcpu); +} + void kvm_vcpu_reload_pmu(struct kvm_vcpu *vcpu) { struct kvm_pmu *pmu =3D &vcpu->arch.pmu; @@ -1017,6 +1065,9 @@ u8 kvm_arm_pmu_get_max_counters(struct kvm *kvm) { struct arm_pmu *arm_pmu =3D kvm->arch.arm_pmu; =20 + if (kvm_pmu_fixed_counters_only(kvm)) + return 0; + /* * PMUv3 requires that all event counters are capable of counting any * event, though the same may not be true of non-PMUv3 hardware. diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h index 1971f8794c9d..0c31b72e3435 100644 --- a/include/kvm/arm_pmu.h +++ b/include/kvm/arm_pmu.h @@ -60,6 +60,7 @@ void kvm_pmu_handle_pmcr(struct kvm_vcpu *vcpu, u64 val); void kvm_pmu_handle_mdcr(struct kvm_vcpu *vcpu, u64 old, u64 val); void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, u64 data, u64 select_idx); +void kvm_vcpu_load_pmu(struct kvm_vcpu *vcpu, int last_cpu); void kvm_vcpu_reload_pmu(struct kvm_vcpu *vcpu); int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr); @@ -166,6 +167,7 @@ static inline u64 kvm_pmu_get_pmceid(struct kvm_vcpu *v= cpu, bool pmceid1) static inline void kvm_pmu_update_vcpu_events(struct kvm_vcpu *vcpu) {} static inline void kvm_vcpu_pmu_restore_guest(struct kvm_vcpu *vcpu) {} static inline void kvm_vcpu_pmu_restore_host(struct kvm_vcpu *vcpu) {} +static inline void kvm_vcpu_load_pmu(struct kvm_vcpu *vcpu, int last_cpu) = {} static inline void kvm_vcpu_reload_pmu(struct kvm_vcpu *vcpu) {} static inline u8 kvm_arm_pmu_get_pmuver_limit(void) { --=20 2.55.0 From nobody Sat Jul 25 03:22:07 2026 Received: from www3579.sakura.ne.jp (www3579.sakura.ne.jp [49.212.243.89]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C280F3A960F; Mon, 20 Jul 2026 05:39:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=49.212.243.89 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784525971; cv=none; b=Wiy+O/Yp1/lOdMou1uq34BbeNc5afKi+r2hlZ5RmQJGyuJ2l0T6ffnK3wlX+lcJyyvcusLcA5o9lT7LlXsu9x5kNeiAWVjDucZKLvg9YEOCd30o1xxntVdEgZ+3mV5/trWLMN0CV9UTngMPAPrOBjJWalJAIvG+Sz49UOTHA+/w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784525971; c=relaxed/simple; bh=QXLi4BaISj6K96xiBotXfi41vMcOQpXCXihj7bhuZOM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=lW/FUzcHb3lPPCVe269wSITndpOwOpZ8dFIz5dIMoz6XF29JrSKoPXQzEogVkmNdMHMCLEkNXiklwme0U+tK/tU6Eetkj94F+YJU7di51GoA/wBNEOTeneig+3mT0LF9M2G8pynbVwN8PzW1aVJuwSKM/13eeNB930tWddAMPHE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp; spf=pass smtp.mailfrom=rsg.ci.i.u-tokyo.ac.jp; dkim=fail (0-bit key) header.d=rsg.ci.i.u-tokyo.ac.jp header.i=@rsg.ci.i.u-tokyo.ac.jp header.b=UX/qEQ9y reason="key not found in DNS"; arc=none smtp.client-ip=49.212.243.89 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rsg.ci.i.u-tokyo.ac.jp Authentication-Results: smtp.subspace.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=rsg.ci.i.u-tokyo.ac.jp header.i=@rsg.ci.i.u-tokyo.ac.jp header.b="UX/qEQ9y" Received: from h183.csg.ci.i.u-tokyo.ac.jp (h183.csg.ci.i.u-tokyo.ac.jp [133.11.54.183]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 66K5c7ox075973 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Mon, 20 Jul 2026 14:38:29 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=sryd5wgM/WV7CCzgVPBhME2gOGQl3p56pZ3ofzm2E08=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Message-Id:To:Subject:Date; s=rs20250326; t=1784525910; v=1; b=UX/qEQ9ylaxpkctA5ySyBA6yOHyXvDr22pzL85d60tX9o/nmTj/K7NZnyqvY1UZp HBrPor2P/qv/NkME6lLKJ+G0A5D9HqQN3MLOls0ZIGpGZHIdCdxKBMftZCsSgfD1 sg9KNytv4e7BK8PhB6OrAf8uD8j84zvBOzSX0bMRL/MHwG5tcHGX2bVmwSLxfZFk tuCZSjF6eR+rha283jCf5F8qzJdzXDndUPI0tED0TIV8wsawfZj5ogG8dWBI0Zhz QdxniXXZ2hXtM/6eeOUqr8Y8zCZwp8CtdPetiPLha8QDazrbGUpR6bOewpDWQmT5 5R/vN+29NsL34sQMamx3Tg== From: Akihiko Odaki Date: Mon, 20 Jul 2026 14:38:09 +0900 Subject: [PATCH v9 15/16] KVM: arm64: PMU: Introduce FIXED_COUNTERS_ONLY Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260720-hybrid-v9-15-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> References: <20260720-hybrid-v9-0-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20260720-hybrid-v9-0-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> To: Marc Zyngier , Oliver Upton , Joey Gouly , Suzuki K Poulose , Zenghui Yu , Catalin Marinas , Will Deacon , Kees Cook , "Gustavo A. R. Silva" , Paolo Bonzini , Jonathan Corbet , Shuah Khan , Shuah Khan , Yury Norov , Rasmus Villemoes , Steffen Eiden Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, devel@daynix.com, kvm@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Akihiko Odaki X-Mailer: b4 0.16-dev-925f5 X-Developer-Signature: v=1; a=openpgp-sha256; l=7747; i=odaki@rsg.ci.i.u-tokyo.ac.jp; h=from:subject:message-id; bh=QXLi4BaISj6K96xiBotXfi41vMcOQpXCXihj7bhuZOM=; b=owGbwMvMwCWmMbc20y1CyJDxtFoSQ1bsFj+vq09nSe4q5bYWmLu3ReXc8lP+L+SYD51NY1ymN S9Puyapo5SFQYyLQVZMkSWlaDe3RnTtp8KE+BaYOaxMIEMYuDgFYCJ5XowM7/UjPtyP+ZU26/F6 7sTZ6+yk7lhLnXdXeWju/SKk7KDjLUaG42tdMgIFS9d2rIz2V5G3c/l25Mjqa4kRH5bu4JW9xSb FDgA= X-Developer-Key: i=odaki@rsg.ci.i.u-tokyo.ac.jp; a=openpgp; fpr=AEDC03C9AF734F2EC26A7BFFA4BAEAA73536753C Introduce the KVM_ARM_VCPU_PMU_V3_FIXED_COUNTERS_ONLY attribute to create a "fixed-counters-only" PMU. Much like KVM_ARM_VCPU_PMU_V3_IRQ and other read-write attributes, this attribute provides a getter that facilitates kernel and userspace debugging/testing. Assisted-by: Codex:gpt-5.6-sol Signed-off-by: Akihiko Odaki --- Documentation/virt/kvm/devices/vcpu.rst | 30 ++++++++++++++++++++++++++---- arch/arm64/include/uapi/asm/kvm.h | 1 + arch/arm64/kvm/pmu-emul.c | 30 +++++++++++++++++++++++++++--- tools/arch/arm64/include/uapi/asm/kvm.h | 1 + 4 files changed, 55 insertions(+), 7 deletions(-) diff --git a/Documentation/virt/kvm/devices/vcpu.rst b/Documentation/virt/k= vm/devices/vcpu.rst index 66e714f2fcfa..1d592e70bdea 100644 --- a/Documentation/virt/kvm/devices/vcpu.rst +++ b/Documentation/virt/kvm/devices/vcpu.rst @@ -74,7 +74,8 @@ irqchip. -ENODEV PMUv3 not supported or GIC not initialized -ENXIO PMUv3 not properly configured or in-kernel irqchip not configured as required prior to calling this attribute - -EBUSY PMUv3 already initialized or a VCPU has already run + -EBUSY PMUv3 already initialized, a VCPU has already run or + FIXED_COUNTERS_ONLY has already been set -EINVAL Invalid filter range =3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 @@ -116,14 +117,14 @@ using event 0x11 (CPU_CYCLES). =20 :Returns: =20 - =3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + =3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -EBUSY PMUv3 already initialized, a VCPU has already run or - an event filter has already been set + an event filter or FIXED_COUNTERS_ONLY has already been = set -EFAULT Error accessing the PMU identifier -ENXIO PMU not found -ENODEV PMUv3 not supported or GIC not initialized -ENOMEM Could not allocate memory - =3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + =3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 Request that the VCPU uses the specified hardware PMU when creating guest = events for the purpose of PMU emulation. The PMU identifier can be read from the = "type" @@ -165,6 +166,27 @@ explicitly selected, or the number of counters is out = of range for the selected PMU. Selecting a new PMU cancels the effect of setting this attribute. =20 +1.6 ATTRIBUTE: KVM_ARM_VCPU_PMU_V3_FIXED_COUNTERS_ONLY +------------------------------------------------------ + +:Parameters: no additional parameter in kvm_device_attr.addr + +:Returns: + + =3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D + -EBUSY PMUv3 already initialized, a VCPU has already run, + an event filter has already been set or + a hardware PMU has already been specified + -ENXIO Attempted to get before setting + -ENODEV Attempted to set while PMUv3 not supported + =3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D + +If set, KVM emulates PMUv3 without programmable event counters. + +When this attribute is enabled, the vCPU can run on any physical CPU +that has a PMU, regardless of the underlying implementation. This +attribute is VM-scoped. + 2. GROUP: KVM_ARM_VCPU_TIMER_CTRL =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D =20 diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/as= m/kvm.h index 1c13bfa2d38a..39a1a1e412e6 100644 --- a/arch/arm64/include/uapi/asm/kvm.h +++ b/arch/arm64/include/uapi/asm/kvm.h @@ -437,6 +437,7 @@ 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_FIXED_COUNTERS_ONLY 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-emul.c b/arch/arm64/kvm/pmu-emul.c index 1ec09ef28467..ff5d5f66a9c0 100644 --- a/arch/arm64/kvm/pmu-emul.c +++ b/arch/arm64/kvm/pmu-emul.c @@ -1118,8 +1118,8 @@ int kvm_arm_set_default_pmu(struct kvm *kvm) * affines the VMM to a particular cluster of cores. * * In any case, userspace should just do the sane thing and use the UAPI - * to select a PMU type directly. But, be wary of the baggage being - * carried here. + * to select a PMU type directly, or request fixed-counters-only + * emulation. But, be wary of the baggage being carried here. */ struct arm_pmu *arm_pmu =3D kvm_pmu_probe_armpmu(raw_smp_processor_id()); =20 @@ -1144,11 +1144,13 @@ static int kvm_arm_pmu_v3_set_pmu(struct kvm_vcpu *= vcpu, int pmu_id) arm_pmu =3D entry->arm_pmu; if (arm_pmu->pmu.type =3D=3D pmu_id) { if (kvm_vm_has_ran_once(kvm) || + kvm_pmu_fixed_counters_only(kvm) || (kvm->arch.pmu_filter && kvm->arch.arm_pmu !=3D arm_pmu)) { ret =3D -EBUSY; break; } =20 + set_bit(KVM_ARCH_FLAG_PMU_V3_EXPLICIT, &kvm->arch.flags); kvm_arm_set_pmu(kvm, arm_pmu); cpumask_copy(kvm->arch.supported_cpus, &arm_pmu->supported_cpus); ret =3D 0; @@ -1159,6 +1161,22 @@ static int kvm_arm_pmu_v3_set_pmu(struct kvm_vcpu *v= cpu, int pmu_id) return ret; } =20 +static int kvm_arm_pmu_v3_set_pmu_fixed_counters_only(struct kvm_vcpu *vcp= u) +{ + struct kvm *kvm =3D vcpu->kvm; + + lockdep_assert_held(&kvm->arch.config_lock); + + if (kvm_vm_has_ran_once(kvm) || kvm->arch.pmu_filter || + test_bit(KVM_ARCH_FLAG_PMU_V3_EXPLICIT, &kvm->arch.flags)) + return -EBUSY; + + set_bit(KVM_ARCH_FLAG_PMU_V3_FIXED_COUNTERS_ONLY, &kvm->arch.flags); + kvm->arch.nr_pmu_counters =3D 0; + + return 0; +} + static int kvm_arm_pmu_v3_set_nr_counters(struct kvm_vcpu *vcpu, unsigned = int n) { struct kvm *kvm =3D vcpu->kvm; @@ -1236,7 +1254,7 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, st= ruct kvm_device_attr *attr) filter.action !=3D KVM_PMU_EVENT_DENY)) return -EINVAL; =20 - if (kvm_vm_has_ran_once(kvm)) + if (kvm_vm_has_ran_once(kvm) || kvm_pmu_fixed_counters_only(kvm)) return -EBUSY; =20 if (!kvm->arch.pmu_filter) { @@ -1281,6 +1299,8 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, st= ruct kvm_device_attr *attr) =20 return kvm_arm_pmu_v3_set_nr_counters(vcpu, n); } + case KVM_ARM_VCPU_PMU_V3_FIXED_COUNTERS_ONLY: + return kvm_arm_pmu_v3_set_pmu_fixed_counters_only(vcpu); case KVM_ARM_VCPU_PMU_V3_INIT: return kvm_arm_pmu_v3_init(vcpu); } @@ -1307,6 +1327,9 @@ int kvm_arm_pmu_v3_get_attr(struct kvm_vcpu *vcpu, st= ruct kvm_device_attr *attr) irq =3D vcpu->arch.pmu.irq_num; return put_user(irq, uaddr); } + case KVM_ARM_VCPU_PMU_V3_FIXED_COUNTERS_ONLY: + if (kvm_pmu_fixed_counters_only(vcpu->kvm)) + return 0; } =20 return -ENXIO; @@ -1320,6 +1343,7 @@ int kvm_arm_pmu_v3_has_attr(struct kvm_vcpu *vcpu, st= ruct 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_FIXED_COUNTERS_ONLY: if (kvm_vcpu_has_pmu(vcpu)) return 0; } diff --git a/tools/arch/arm64/include/uapi/asm/kvm.h b/tools/arch/arm64/inc= lude/uapi/asm/kvm.h index 1c13bfa2d38a..39a1a1e412e6 100644 --- a/tools/arch/arm64/include/uapi/asm/kvm.h +++ b/tools/arch/arm64/include/uapi/asm/kvm.h @@ -437,6 +437,7 @@ 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_FIXED_COUNTERS_ONLY 5 #define KVM_ARM_VCPU_TIMER_CTRL 1 #define KVM_ARM_VCPU_TIMER_IRQ_VTIMER 0 #define KVM_ARM_VCPU_TIMER_IRQ_PTIMER 1 --=20 2.55.0 From nobody Sat Jul 25 03:22:07 2026 Received: from www3579.sakura.ne.jp (www3579.sakura.ne.jp [49.212.243.89]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9057C3A875A; Mon, 20 Jul 2026 05:39:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=49.212.243.89 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784525971; cv=none; b=H5ar/JJgFcxDKOxEI1rSs+h5pQTOLbKqnXdBuh+8iMvyLPgoi0REiMbuAMH+x/jI03yYBjh+uyXJJAEmosVVeXCzdw2pmRyxPHsp7EpUWe4AUcO2phfFQ1DOuvrjOP4ELfilnEN5rgD/kkCbiKyEFbYeeNalTcxAJw7qFQb2K0s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784525971; c=relaxed/simple; bh=QxYfesgpezdHGHYgb0sNgkTIGVjf82YDNRISkQTQw6w=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=HSmmdRpngLVYPUabCTSWEfIExhlYanhfh6zxcLtHF2P03iOV4qPq2DVHJQ4ohPHn/FP9Pf1a17Beb4/+Cn7fYtKhNpFK0p7O5q36N92T75qUgogQ1l+lFm910yGP3ukm4erAfB2FKoAy7MNYeNAHkTpCAu83+EyRt03z7lU+R6c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp; spf=pass smtp.mailfrom=rsg.ci.i.u-tokyo.ac.jp; dkim=fail (0-bit key) header.d=rsg.ci.i.u-tokyo.ac.jp header.i=@rsg.ci.i.u-tokyo.ac.jp header.b=fVLdZnxI reason="key not found in DNS"; arc=none smtp.client-ip=49.212.243.89 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rsg.ci.i.u-tokyo.ac.jp Authentication-Results: smtp.subspace.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=rsg.ci.i.u-tokyo.ac.jp header.i=@rsg.ci.i.u-tokyo.ac.jp header.b="fVLdZnxI" Received: from h183.csg.ci.i.u-tokyo.ac.jp (h183.csg.ci.i.u-tokyo.ac.jp [133.11.54.183]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 66K5c7p0075973 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Mon, 20 Jul 2026 14:38:30 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=WTJnzEcjT7CSvcpTYWo0Y5oVZ5v2vXY721L2tBYPEe0=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Message-Id:To:Subject:Date; s=rs20250326; t=1784525910; v=1; b=fVLdZnxIWqeq2yQP9sZEdP3Oy05G2mxsyz77xO/Wn4xF/fjUKZjpFIDG5sJDbaDM 6jEyO8lJAZOhPy13+4oklrNhfg0wRg8z9h4m4MoVe6pLwa2lq3rMPcfAX8B9GGn9 OSSZHw6OMn5mBeduz3Rk0InvjfjrEaN+UXlr2jyZMuFb9cj7tQIzca/Jicy9MYvX meUOguxeNiLibtI3e26Gd17mkDRLMImUgWrfKh7xXR69IyrQZKRhlRJP+/JneB2i 6oGhzf6jCTLO6UQ2P1DNhpAj5IDvKsVo7yJfJzJQXIttnKeq3Sztuld6UasP8ARd Ez9SBJfzYbe5xZKOlVdPGA== From: Akihiko Odaki Date: Mon, 20 Jul 2026 14:38:10 +0900 Subject: [PATCH v9 16/16] KVM: arm64: selftests: Test PMU_V3_FIXED_COUNTERS_ONLY Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260720-hybrid-v9-16-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> References: <20260720-hybrid-v9-0-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20260720-hybrid-v9-0-2b713ca1b5dc@rsg.ci.i.u-tokyo.ac.jp> To: Marc Zyngier , Oliver Upton , Joey Gouly , Suzuki K Poulose , Zenghui Yu , Catalin Marinas , Will Deacon , Kees Cook , "Gustavo A. R. Silva" , Paolo Bonzini , Jonathan Corbet , Shuah Khan , Shuah Khan , Yury Norov , Rasmus Villemoes , Steffen Eiden Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, devel@daynix.com, kvm@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Akihiko Odaki X-Mailer: b4 0.16-dev-925f5 X-Developer-Signature: v=1; a=openpgp-sha256; l=10394; i=odaki@rsg.ci.i.u-tokyo.ac.jp; h=from:subject:message-id; bh=QxYfesgpezdHGHYgb0sNgkTIGVjf82YDNRISkQTQw6w=; b=owGbwMvMwCWmMbc20y1CyJDxtFoSQ1bsFv9gE/nk3uXeFr4uVlZZokWdEr7/pZij440ni19zZ 5/EcK2jlIVBjItBVkyRJaVoN7dGdO2nwoT4Fpg5rEwgQxi4OAVgIktuMPzTzUt5/ulnt7QP/3ph G9lz9Yt752x5V+9TMqXlDfck95kbGP7wPFlZ7CPTmPUocXfl5Wy3pbsLI8r7xWXciguWP3eXf8g NAA== X-Developer-Key: i=odaki@rsg.ci.i.u-tokyo.ac.jp; a=openpgp; fpr=AEDC03C9AF734F2EC26A7BFFA4BAEAA73536753C Assert the following: - FIXED_COUNTERS_ONLY is unset at initialization. - FIXED_COUNTERS_ONLY can be set. - Setting an event filter when FIXED_COUNTERS_ONLY has already been set results in EBUSY. - Setting FIXED_COUNTERS_ONLY when an event filter has already been set results in EBUSY. - Setting FIXED_COUNTERS_ONLY when a VCPU has already run results in EBUSY. Run the existing PMU and MDCR_EL2 tests in fixed-only mode. Verify that enabling the mode preserves the userspace MDCR_EL2 value until a subsequent KVM_ARM_VCPU_INIT resets HPMN to zero. Assisted-by: Codex:gpt-5.5 Signed-off-by: Akihiko Odaki --- .../selftests/kvm/arm64/vpmu_counter_access.c | 166 +++++++++++++++++= ---- 1 file changed, 137 insertions(+), 29 deletions(-) diff --git a/tools/testing/selftests/kvm/arm64/vpmu_counter_access.c b/tool= s/testing/selftests/kvm/arm64/vpmu_counter_access.c index 73f04e4c6ca3..b5f8ce8d3451 100644 --- a/tools/testing/selftests/kvm/arm64/vpmu_counter_access.c +++ b/tools/testing/selftests/kvm/arm64/vpmu_counter_access.c @@ -411,12 +411,7 @@ static void create_vpmu_vm(void *guest_code) { struct kvm_vcpu_init init; u8 pmuver, ec; - u64 dfr0, irq =3D 23; - struct kvm_device_attr irq_attr =3D { - .group =3D KVM_ARM_VCPU_PMU_V3_CTRL, - .attr =3D KVM_ARM_VCPU_PMU_V3_IRQ, - .addr =3D (u64)&irq, - }; + u64 dfr0; =20 /* The test creates the vpmu_vm multiple times. Ensure a clean state */ memset(&vpmu_vm, 0, sizeof(vpmu_vm)); @@ -442,8 +437,6 @@ static void create_vpmu_vm(void *guest_code) TEST_ASSERT(pmuver !=3D ID_AA64DFR0_EL1_PMUVer_IMP_DEF && pmuver >=3D ID_AA64DFR0_EL1_PMUVer_IMP, "Unexpected PMUVER (0x%x) on the vCPU with PMUv3", pmuver); - - vcpu_ioctl(vpmu_vm.vcpu, KVM_SET_DEVICE_ATTR, &irq_attr); } =20 static void destroy_vpmu_vm(void) @@ -494,13 +487,22 @@ static void set_nr_counters(struct kvm_vcpu *vcpu, } =20 static void test_create_vpmu_vm_with_nr_counters(unsigned int nr_counters, + bool fixed_counters_only, bool expect_fail) { struct kvm_vcpu *vcpu; + u64 irq =3D 23; =20 create_vpmu_vm(guest_code); vcpu =3D vpmu_vm.vcpu; =20 + if (fixed_counters_only) + vcpu_device_attr_set(vcpu, KVM_ARM_VCPU_PMU_V3_CTRL, + KVM_ARM_VCPU_PMU_V3_FIXED_COUNTERS_ONLY, NULL); + + vcpu_device_attr_set(vcpu, KVM_ARM_VCPU_PMU_V3_CTRL, + KVM_ARM_VCPU_PMU_V3_IRQ, &irq); + set_nr_counters(vcpu, nr_counters, expect_fail); =20 vcpu_device_attr_set(vcpu, KVM_ARM_VCPU_PMU_V3_CTRL, KVM_ARM_VCPU_PMU_V3_= INIT, NULL); @@ -510,15 +512,15 @@ static void test_create_vpmu_vm_with_nr_counters(unsi= gned int nr_counters, * Create a guest with one vCPU, set the PMCR_EL0.N for the vCPU to @pmcr_= n, * and run the test. */ -static void run_access_test(u64 pmcr_n) +static void run_access_test(u64 pmcr_n, bool fixed_counters_only) { u64 sp; struct kvm_vcpu *vcpu; struct kvm_vcpu_init init; =20 - pr_debug("Test with pmcr_n %lu\n", pmcr_n); + pr_debug("Test with pmcr_n %lu, fixed_counters_only %d\n", pmcr_n, fixed_= counters_only); =20 - test_create_vpmu_vm_with_nr_counters(pmcr_n, false); + test_create_vpmu_vm_with_nr_counters(pmcr_n, fixed_counters_only, false); vcpu =3D vpmu_vm.vcpu; =20 /* Save the initial sp to restore them later to run the guest again */ @@ -552,14 +554,14 @@ static struct pmreg_sets validity_check_reg_sets[] = =3D { * Create a VM, and check if KVM handles the userspace accesses of * the PMU register sets in @validity_check_reg_sets[] correctly. */ -static void run_pmregs_validity_test(u64 pmcr_n) +static void run_pmregs_validity_test(u64 pmcr_n, bool fixed_counters_only) { int i; struct kvm_vcpu *vcpu; u64 set_reg_id, clr_reg_id, reg_val; u64 valid_counters_mask, max_counters_mask; =20 - test_create_vpmu_vm_with_nr_counters(pmcr_n, false); + test_create_vpmu_vm_with_nr_counters(pmcr_n, fixed_counters_only, false); vcpu =3D vpmu_vm.vcpu; =20 valid_counters_mask =3D get_counters_mask(pmcr_n); @@ -604,13 +606,15 @@ static void run_pmregs_validity_test(u64 pmcr_n) destroy_vpmu_vm(); } =20 -static void run_mdcr_el2_validity_test(u64 pmcr_n) +static void run_mdcr_el2_validity_test(u64 pmcr_n, bool fixed_counters_onl= y) { struct kvm_vcpu_init init; struct kvm_vcpu *vcpu; u64 expected_mdcr, mdcr; + u64 irq =3D 23; =20 - pr_debug("MDCR_EL2 test with pmcr_n %lu\n", pmcr_n); + pr_debug("MDCR_EL2 test with pmcr_n %lu, fixed_counters_only %d\n", + pmcr_n, fixed_counters_only); =20 create_vpmu_vm(guest_code); if (!vm_supports_el2(vpmu_vm.vm)) { @@ -631,6 +635,16 @@ static void run_mdcr_el2_validity_test(u64 pmcr_n) "MDCR_EL2 was not properly updated after HPMN write (expected 0x%lx,= got 0x%lx)", expected_mdcr, mdcr); =20 + if (fixed_counters_only) { + vcpu_device_attr_set(vcpu, KVM_ARM_VCPU_PMU_V3_CTRL, + KVM_ARM_VCPU_PMU_V3_FIXED_COUNTERS_ONLY, NULL); + + mdcr =3D vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_MDCR_EL2)); + TEST_ASSERT(mdcr =3D=3D expected_mdcr, + "MDCR_EL2 changed after PMU_V3_FIXED_COUNTERS_ONLY (expected 0x%lx,= got 0x%lx)", + expected_mdcr, mdcr); + } + set_nr_counters(vcpu, pmcr_n, false); =20 mdcr =3D vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_MDCR_EL2)); @@ -638,6 +652,9 @@ static void run_mdcr_el2_validity_test(u64 pmcr_n) "MDCR_EL2 changed after PMU_V3_SET_NR_COUNTERS (expected 0x%lx, got = 0x%lx)", expected_mdcr, mdcr); =20 + vcpu_device_attr_set(vcpu, KVM_ARM_VCPU_PMU_V3_CTRL, + KVM_ARM_VCPU_PMU_V3_IRQ, &irq); + vcpu_device_attr_set(vcpu, KVM_ARM_VCPU_PMU_V3_CTRL, KVM_ARM_VCPU_PMU_V3_INIT, NULL); =20 @@ -672,11 +689,11 @@ static void run_mdcr_el2_validity_test(u64 pmcr_n) * the vCPU to @pmcr_n, which is larger than the host value. * The attempt should fail as @pmcr_n is too big to set for the vCPU. */ -static void run_error_test(u64 pmcr_n) +static void run_error_test(u64 pmcr_n, bool fixed_counters_only) { pr_debug("Error test with pmcr_n %lu (larger than the host)\n", pmcr_n); =20 - test_create_vpmu_vm_with_nr_counters(pmcr_n, true); + test_create_vpmu_vm_with_nr_counters(pmcr_n, fixed_counters_only, true); destroy_vpmu_vm(); } =20 @@ -737,25 +754,116 @@ static void test_set_nr_counters_after_vcpu_run(void) kvm_vm_free(vm); } =20 -int main(void) +static void test_config(u64 pmcr_n, bool fixed_counters_only) +{ + u64 i; + + for (i =3D 0; i <=3D pmcr_n; i++) { + run_access_test(i, fixed_counters_only); + run_pmregs_validity_test(i, fixed_counters_only); + run_mdcr_el2_validity_test(i, fixed_counters_only); + } + + for (i =3D pmcr_n + 1; i < ARMV8_PMU_MAX_COUNTERS; i++) + run_error_test(i, fixed_counters_only); +} + +static void test_fixed_counters_only(void) { - u64 i, pmcr_n; + struct kvm_pmu_event_filter filter =3D { .nevents =3D 0 }; + struct kvm_vm *vm; + struct kvm_vcpu *running_vcpu; + struct kvm_vcpu *stopped_vcpu; + struct kvm_vcpu_init init; + int ret; + u64 irq =3D 23; + + create_vpmu_vm(guest_code); + ret =3D __vcpu_has_device_attr(vpmu_vm.vcpu, KVM_ARM_VCPU_PMU_V3_CTRL, + KVM_ARM_VCPU_PMU_V3_FIXED_COUNTERS_ONLY); + if (ret) { + TEST_ASSERT(ret =3D=3D -1 && errno =3D=3D ENXIO, + KVM_IOCTL_ERROR(KVM_HAS_DEVICE_ATTR, ret)); + destroy_vpmu_vm(); + return; + } + + /* Assert that FIXED_COUNTERS_ONLY is unset at initialization. */ + ret =3D __vcpu_device_attr_get(vpmu_vm.vcpu, KVM_ARM_VCPU_PMU_V3_CTRL, + KVM_ARM_VCPU_PMU_V3_FIXED_COUNTERS_ONLY, NULL); + TEST_ASSERT(ret =3D=3D -1 && errno =3D=3D ENXIO, + KVM_IOCTL_ERROR(KVM_GET_DEVICE_ATTR, ret)); + + /* Assert that setting FIXED_COUNTERS_ONLY succeeds. */ + vcpu_device_attr_set(vpmu_vm.vcpu, KVM_ARM_VCPU_PMU_V3_CTRL, + KVM_ARM_VCPU_PMU_V3_FIXED_COUNTERS_ONLY, NULL); + + /* Assert that FIXED_COUNTERS_ONLY is set. */ + vcpu_device_attr_get(vpmu_vm.vcpu, KVM_ARM_VCPU_PMU_V3_CTRL, + KVM_ARM_VCPU_PMU_V3_FIXED_COUNTERS_ONLY, NULL); + + /* + * Setting an event filter when FIXED_COUNTERS_ONLY has already been set + * results in EBUSY. + */ + ret =3D __vcpu_device_attr_set(vpmu_vm.vcpu, KVM_ARM_VCPU_PMU_V3_CTRL, + KVM_ARM_VCPU_PMU_V3_FILTER, &filter); + TEST_ASSERT(ret =3D=3D -1 && errno =3D=3D EBUSY, + KVM_IOCTL_ERROR(KVM_SET_DEVICE_ATTR, ret)); + + destroy_vpmu_vm(); + + create_vpmu_vm(guest_code); + + /* + * Assert that setting FIXED_COUNTERS_ONLY when an event filter has + * already been set results in EBUSY. + */ + vcpu_device_attr_set(vpmu_vm.vcpu, KVM_ARM_VCPU_PMU_V3_CTRL, + KVM_ARM_VCPU_PMU_V3_FILTER, &filter); + + ret =3D __vcpu_device_attr_set(vpmu_vm.vcpu, KVM_ARM_VCPU_PMU_V3_CTRL, + KVM_ARM_VCPU_PMU_V3_FIXED_COUNTERS_ONLY, NULL); + TEST_ASSERT(ret =3D=3D -1 && errno =3D=3D EBUSY, + KVM_IOCTL_ERROR(KVM_SET_DEVICE_ATTR, ret)); + + destroy_vpmu_vm(); + + /* + * Assert that setting FIXED_COUNTERS_ONLY when a VCPU has already run + * results in EBUSY. + */ + vm =3D vm_create(2); + vm_ioctl(vm, KVM_ARM_PREFERRED_TARGET, &init); + init.features[0] |=3D (1 << KVM_ARM_VCPU_PMU_V3); + running_vcpu =3D aarch64_vcpu_add(vm, 0, &init, guest_code_done); + stopped_vcpu =3D aarch64_vcpu_add(vm, 1, &init, guest_code_done); + kvm_arch_vm_finalize_vcpus(vm); + vcpu_device_attr_set(running_vcpu, KVM_ARM_VCPU_PMU_V3_CTRL, + KVM_ARM_VCPU_PMU_V3_IRQ, &irq); + vcpu_device_attr_set(running_vcpu, KVM_ARM_VCPU_PMU_V3_CTRL, + KVM_ARM_VCPU_PMU_V3_INIT, NULL); + vcpu_run(running_vcpu); + + ret =3D __vcpu_device_attr_set(stopped_vcpu, KVM_ARM_VCPU_PMU_V3_CTRL, + KVM_ARM_VCPU_PMU_V3_FIXED_COUNTERS_ONLY, NULL); + TEST_ASSERT(ret =3D=3D -1 && errno =3D=3D EBUSY, + KVM_IOCTL_ERROR(KVM_SET_DEVICE_ATTR, ret)); + + kvm_vm_free(vm); + + test_config(0, true); +} =20 +int main(void) +{ TEST_REQUIRE(kvm_has_cap(KVM_CAP_ARM_PMU_V3)); TEST_REQUIRE(kvm_supports_vgic_v3()); TEST_REQUIRE(kvm_supports_nr_counters_attr()); =20 test_set_nr_counters_after_vcpu_run(); - - pmcr_n =3D get_pmcr_n_limit(); - for (i =3D 0; i <=3D pmcr_n; i++) { - run_access_test(i); - run_pmregs_validity_test(i); - run_mdcr_el2_validity_test(i); - } - - for (i =3D pmcr_n + 1; i < ARMV8_PMU_MAX_COUNTERS; i++) - run_error_test(i); + test_config(get_pmcr_n_limit(), false); + test_fixed_counters_only(); =20 return 0; } --=20 2.55.0