diff options
author | Marc Zyngier <maz@kernel.org> | 2023-03-30 19:47:56 +0200 |
---|---|---|
committer | Marc Zyngier <maz@kernel.org> | 2023-03-30 20:01:10 +0200 |
commit | 1e0eec09d43a55125ff80e40b2d6e2f369a338b9 (patch) | |
tree | 2a359e5a80f73aec8a9fad6d30f7851fc5ade982 /arch/arm64 | |
parent | KVM: arm64: Document KVM_ARM_SET_CNT_OFFSETS and co (diff) | |
download | linux-1e0eec09d43a55125ff80e40b2d6e2f369a338b9.tar.xz linux-1e0eec09d43a55125ff80e40b2d6e2f369a338b9.zip |
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
Diffstat (limited to 'arch/arm64')
-rw-r--r-- | arch/arm64/kvm/arch_timer.c | 13 | ||||
-rw-r--r-- | arch/arm64/kvm/hyp/include/hyp/switch.h | 2 |
2 files changed, 12 insertions, 3 deletions
diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c index d3a7902269c1..b87bf182af33 100644 --- a/arch/arm64/kvm/arch_timer.c +++ b/arch/arm64/kvm/arch_timer.c @@ -89,10 +89,17 @@ u64 timer_get_cval(struct arch_timer_context *ctxt) static u64 timer_get_offset(struct arch_timer_context *ctxt) { - if (ctxt && ctxt->offset.vm_offset) - return *ctxt->offset.vm_offset; + u64 offset = 0; - 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) diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h index 9954368f639d..d07cbc313889 100644 --- a/arch/arm64/kvm/hyp/include/hyp/switch.h +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h @@ -353,6 +353,8 @@ static bool kvm_hyp_handle_cntpct(struct kvm_vcpu *vcpu) if (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); __kvm_skip_instr(vcpu); |