KVM: arm64: Make timer_get_offset() work in all contexts

We currently have two implementations of get_timer offset(), one
in arm_arch_timer.h, and another one in switch.h.

These two only differ by a pair of kern_hyp_va(), which seems a
pretty weak reason to open-code it.

Turn this function into a macro to avoid the include dependency hell
on kern_hyp_va(), and make it work correctly in all contexts.

Signed-off-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Mostafa Saleh <smostafa@google.com>
Link: https://patch.msgid.link/20260808085824.732659-2-smostafa@google.com
Signed-off-by: Oliver Upton <oupton@kernel.org>
This commit is contained in:
Marc Zyngier
2026-08-08 08:58:22 +00:00
committed by Oliver Upton
parent 979ae12a2d
commit 2858600ecd
2 changed files with 22 additions and 27 deletions

View File

@@ -705,22 +705,9 @@ 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() - hyp_timer_get_offset(ctxt);
return arch_timer_read_cntpct_el0() - timer_get_offset(ctxt);
}
static bool kvm_handle_cntxct(struct kvm_vcpu *vcpu)

View File

@@ -162,20 +162,28 @@ static inline bool has_cntpoff(void)
return (has_vhe() && cpus_have_final_cap(ARM64_HAS_ECV_CNTPOFF));
}
static inline u64 timer_get_offset(struct arch_timer_context *ctxt)
{
u64 offset = 0;
#ifdef __KVM_NVHE_HYPERVISOR__
#define KERN_HYP_VA(x) kern_hyp_va(x)
#else
#define KERN_HYP_VA(x) x
#endif
if (!ctxt)
return 0;
if (ctxt->offset.vm_offset)
offset += *ctxt->offset.vm_offset;
if (ctxt->offset.vcpu_offset)
offset += *ctxt->offset.vcpu_offset;
return offset;
}
#define timer_get_offset(ctxt) \
({ \
struct arch_timer_context *__ctxt = (ctxt); \
u64 off = 0; \
\
if (__ctxt) { \
struct arch_timer_offset *ato = &__ctxt->offset;\
\
if (ato->vm_offset) \
off += *KERN_HYP_VA(ato->vm_offset); \
if (ato->vcpu_offset) \
off += *KERN_HYP_VA(ato->vcpu_offset); \
} \
\
off; \
})
static inline void timer_set_offset(struct arch_timer_context *ctxt, u64 offset)
{