Skip to contentSkip to conversation

KVM: arm64: Convert timer offset VA when accessed in HYP code

PATCH Applied Marc Zyngier 3 participants 4 messages Feb 12, 2025 – Feb 13, 2025

Subsystems (2)
lore
Share & tools
lore

Marc Zyngier

author maintainer
#0 lore raw

PATCH 1/1 KVM: arm64: Convert timer offset VA when accessed in HYP code

Now that EL2 has gained some early timer emulation, it accesses the offsets pointed to by the timer structure, both of which live in the KVM structure.

Of course, these are *kernel* pointers, so the dereferencing of these pointers in non-kernel code must be itself be offset.

Given switch.h its own version of timer_get_offset() and use that instead.

Fixes b86fc215dc26d ("KVM: arm64: Handle counter access early in non-HYP context")
---
 arch/arm64/kvm/hyp/include/hyp/switch.h | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)
arch/arm64/kvm/hyp/include/hyp/switch.h +14 -1
index f5e882a358e2d..23bbe28eaaf95 100644
@@ -581,9 +581,22 @@ static inline bool handle_tx2_tvm(struct kvm_vcpu *vcpu)
 	return true;
 }
 
+/* Open-coded version of timer_get_offset() to allow for kern_hyp_va() */
+static inline u64 hyp_timer_get_offset(struct arch_timer_context *ctxt)
+{
+	u64 offset = 0;
+
+	if (ctxt->offset.vm_offset)
+		offset += *kern_hyp_va(ctxt->offset.vm_offset);
+	if (ctxt->offset.vcpu_offset)
+		offset += *kern_hyp_va(ctxt->offset.vcpu_offset);
+
+	return offset;
+}
+
 static inline u64 compute_counter_value(struct arch_timer_context *ctxt)
 {
-	return arch_timer_read_cntpct_el0() - timer_get_offset(ctxt);
+	return arch_timer_read_cntpct_el0() - hyp_timer_get_offset(ctxt);
 }
 
 static bool kvm_handle_cntxct(struct kvm_vcpu *vcpu)
Signature · 1 line
2.39.2
Reviewed-by on v1 1/1
#1 lore raw
Quoted 7 lines · Marc Zyngier

Now that EL2 has gained some early timer emulation, it accesses the offsets pointed to by the timer structure, both of which live in the KVM structure.

Of course, these are *kernel* pointers, so the dereferencing of these pointers in non-kernel code must be itself be offset.

Quoted 6 lines

Given switch.h its own version of timer_get_offset() and use that instead.

Fixes b86fc215dc26d ("KVM: arm64: Handle counter access early in non-HYP context")
Tested-by on v1 1/1
#2 lore raw
In reply to Marc Zyngier
Quoted 8 lines · Marc Zyngier' via lkft

Now that EL2 has gained some early timer emulation, it accesses the offsets pointed to by the timer structure, both of which live in the KVM structure.

Of course, these are *kernel* pointers, so the dereferencing of these pointers in non-kernel code must be itself be offset.

Quoted 6 lines

Given switch.h its own version of timer_get_offset() and use that instead.

Fixes b86fc215dc26d ("KVM: arm64: Handle counter access early in non-HYP context")

Build this patch ontop of next-20250212 and ran kvm-unit-tests on a rockpi4. And it ran fine without any kernel panic.

Cheers,
Anders

author maintainer Applied
#3 lore raw
In reply to Marc Zyngier
Quoted 8 lines · Marc Zyngier

Now that EL2 has gained some early timer emulation, it accesses the offsets pointed to by the timer structure, both of which live in the KVM structure.

Of course, these are *kernel* pointers, so the dereferencing of these pointers in non-kernel code must be itself be offset.

[...]

Applied to fixes, thanks!

[1/1] KVM: arm64: Convert timer offset VA when accessed in HYP code

      commit: 18ec0be672a4a27aa045cf692eeb1e180a202e0c

Cheers,

	M.
Signature · 1 line
Without deviation from the norm, progress is not possible.