Skip to content

Commit 1e0eec0

Browse files
author
Marc Zyngier
committed
KVM: arm64: nv: timers: Add a per-timer, per-vcpu offset
Being able to set a global offset isn't enough. With NV, we also need to a per-vcpu, per-timer offset (for example, CNTVCT_EL0 being offset by CNTVOFF_EL2). Use a similar method as the VM-wide offset to have a timer point to the shadow register that contains the offset value. Reviewed-by: Colton Lewis <coltonlewis@google.com> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20230330174800.2677007-17-maz@kernel.org
1 parent 1935d34 commit 1e0eec0

3 files changed

Lines changed: 17 additions & 3 deletions

File tree

arch/arm64/kvm/arch_timer.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,17 @@ u64 timer_get_cval(struct arch_timer_context *ctxt)
8989

9090
static u64 timer_get_offset(struct arch_timer_context *ctxt)
9191
{
92-
if (ctxt && ctxt->offset.vm_offset)
93-
return *ctxt->offset.vm_offset;
92+
u64 offset = 0;
9493

95-
return 0;
94+
if (!ctxt)
95+
return 0;
96+
97+
if (ctxt->offset.vm_offset)
98+
offset += *ctxt->offset.vm_offset;
99+
if (ctxt->offset.vcpu_offset)
100+
offset += *ctxt->offset.vcpu_offset;
101+
102+
return offset;
96103
}
97104

98105
static void timer_set_ctl(struct arch_timer_context *ctxt, u32 ctl)

arch/arm64/kvm/hyp/include/hyp/switch.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,8 @@ static bool kvm_hyp_handle_cntpct(struct kvm_vcpu *vcpu)
353353

354354
if (ctxt->offset.vm_offset)
355355
val -= *kern_hyp_va(ctxt->offset.vm_offset);
356+
if (ctxt->offset.vcpu_offset)
357+
val -= *kern_hyp_va(ctxt->offset.vcpu_offset);
356358

357359
vcpu_set_reg(vcpu, kvm_vcpu_sys_get_rt(vcpu), val);
358360
__kvm_skip_instr(vcpu);

include/kvm/arm_arch_timer.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ struct arch_timer_offset {
2929
* structure. If NULL, assume a zero offset.
3030
*/
3131
u64 *vm_offset;
32+
/*
33+
* If set, pointer to one of the offsets in the vcpu's sysreg
34+
* array. If NULL, assume a zero offset.
35+
*/
36+
u64 *vcpu_offset;
3237
};
3338

3439
struct arch_timer_vm_data {

0 commit comments

Comments
 (0)