Commit 1e0eec09 authored by Marc Zyngier's avatar Marc Zyngier

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: default avatarColton Lewis <coltonlewis@google.com>
Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20230330174800.2677007-17-maz@kernel.org
parent 1935d34a
...@@ -89,10 +89,17 @@ u64 timer_get_cval(struct arch_timer_context *ctxt) ...@@ -89,10 +89,17 @@ u64 timer_get_cval(struct arch_timer_context *ctxt)
static u64 timer_get_offset(struct arch_timer_context *ctxt) static u64 timer_get_offset(struct arch_timer_context *ctxt)
{ {
if (ctxt && ctxt->offset.vm_offset) u64 offset = 0;
return *ctxt->offset.vm_offset;
return 0; 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;
} }
static void timer_set_ctl(struct arch_timer_context *ctxt, u32 ctl) static void timer_set_ctl(struct arch_timer_context *ctxt, u32 ctl)
......
...@@ -353,6 +353,8 @@ static bool kvm_hyp_handle_cntpct(struct kvm_vcpu *vcpu) ...@@ -353,6 +353,8 @@ static bool kvm_hyp_handle_cntpct(struct kvm_vcpu *vcpu)
if (ctxt->offset.vm_offset) if (ctxt->offset.vm_offset)
val -= *kern_hyp_va(ctxt->offset.vm_offset); val -= *kern_hyp_va(ctxt->offset.vm_offset);
if (ctxt->offset.vcpu_offset)
val -= *kern_hyp_va(ctxt->offset.vcpu_offset);
vcpu_set_reg(vcpu, kvm_vcpu_sys_get_rt(vcpu), val); vcpu_set_reg(vcpu, kvm_vcpu_sys_get_rt(vcpu), val);
__kvm_skip_instr(vcpu); __kvm_skip_instr(vcpu);
......
...@@ -29,6 +29,11 @@ struct arch_timer_offset { ...@@ -29,6 +29,11 @@ struct arch_timer_offset {
* structure. If NULL, assume a zero offset. * structure. If NULL, assume a zero offset.
*/ */
u64 *vm_offset; u64 *vm_offset;
/*
* If set, pointer to one of the offsets in the vcpu's sysreg
* array. If NULL, assume a zero offset.
*/
u64 *vcpu_offset;
}; };
struct arch_timer_vm_data { struct arch_timer_vm_data {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment