[RFC PATCH v7 20/28] KVM: arm64: Allow guest SPE physical timestamps only if kernel allows it

Alexandru Elisei alexandru.elisei at arm.com
Thu Sep 3 09:06:15 PDT 2026


The SPE driver allows userspace to use physical timestamps for records only
if the kernel allows it, do the same for a virtual machine.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arch/arm64/include/asm/kvm_spe.h | 1 +
 arch/arm64/kvm/hyp/vhe/spe-sr.c  | 5 +++--
 arch/arm64/kvm/spe.c             | 8 ++++++++
 3 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_spe.h b/arch/arm64/include/asm/kvm_spe.h
index ad0ad6ace93c..8a55ea0de4e5 100644
--- a/arch/arm64/include/asm/kvm_spe.h
+++ b/arch/arm64/include/asm/kvm_spe.h
@@ -15,6 +15,7 @@ struct arm_spe_pmu;
 struct kvm_spe {
 	struct arm_spe_pmu *spe_pmu;
 	u64 pmblimitr_el1_res0_mask;
+	u64 guest_pmscr_el2;
 };
 
 struct kvm_vcpu_spe {
diff --git a/arch/arm64/kvm/hyp/vhe/spe-sr.c b/arch/arm64/kvm/hyp/vhe/spe-sr.c
index 978620ad99fa..3c32a1338cc8 100644
--- a/arch/arm64/kvm/hyp/vhe/spe-sr.c
+++ b/arch/arm64/kvm/hyp/vhe/spe-sr.c
@@ -107,6 +107,7 @@ static bool __kvm_spe_profiling_buffer_enabled(u64 pmblimitr, u64 pmbsr)
  */
 void __kvm_spe_restore_guest_state_vhe(struct kvm_vcpu *vcpu, struct kvm_cpu_context *guest_ctxt)
 {
+	struct kvm *kvm = vcpu->kvm;
 	u64 pmblimitr, pmbsr;
 
 	pmbsr = ctxt_sys_reg(guest_ctxt, PMBSR_EL1);
@@ -120,10 +121,10 @@ void __kvm_spe_restore_guest_state_vhe(struct kvm_vcpu *vcpu, struct kvm_cpu_con
 		write_sysreg_s(pmbsr, SYS_PMBSR_EL1);
 	}
 
-	__kvm_spe_restore_sampling_regs(vcpu->kvm, guest_ctxt);
+	__kvm_spe_restore_sampling_regs(kvm, guest_ctxt);
 
 	write_sysreg_el1(ctxt_sys_reg(guest_ctxt, PMSCR_EL1), SYS_PMSCR);
-	write_sysreg_el2(0, SYS_PMSCR);
+	write_sysreg_el2(kvm->arch.kvm_spe.guest_pmscr_el2, SYS_PMSCR);
 }
 NOKPROBE_SYMBOL(__kvm_spe_restore_guest_state_vhe);
 
diff --git a/arch/arm64/kvm/spe.c b/arch/arm64/kvm/spe.c
index af1e19cb8e9a..68b751bdb384 100644
--- a/arch/arm64/kvm/spe.c
+++ b/arch/arm64/kvm/spe.c
@@ -3,9 +3,11 @@
  * Copyright (C) 2021 - ARM Ltd
  */
 
+#include <linux/capability.h>
 #include <linux/cpumask.h>
 #include <linux/kvm_host.h>
 #include <linux/perf/arm_spe_pmu.h>
+#include <linux/perf_event.h>
 
 #include <asm/kvm_emulate.h>
 #include <asm/kvm_spe.h>
@@ -97,6 +99,12 @@ int kvm_spe_vcpu_first_run_init(struct kvm_vcpu *vcpu)
 	if (!kvm_spe->pmblimitr_el1_res0_mask)
 		kvm_spe_compute_pmblimitr_el1_res0_mask(kvm);
 
+	if (kvm_vm_has_ran_once(kvm))
+		return 0;
+
+	if (perf_allow_kernel())
+		kvm_spe->guest_pmscr_el2 = PMSCR_EL2_PCT_PHYS;
+
 	return 0;
 }
 
-- 
2.43.0




More information about the linux-arm-kernel mailing list