summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm64/kvm/hyp/nvhe/pkvm.c14
-rw-r--r--arch/arm64/kvm/hyp/nvhe/timer-sr.c6
2 files changed, 17 insertions, 3 deletions
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index c54aa5031336..5a2c7f7d956b 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -528,6 +528,20 @@ static int init_pkvm_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu,
hyp_vcpu->vcpu.arch.cflags = READ_ONCE(host_vcpu->arch.cflags);
hyp_vcpu->vcpu.arch.mp_state.mp_state = KVM_MP_STATE_STOPPED;
+ if (!pkvm_hyp_vcpu_is_protected(hyp_vcpu)) {
+ /*
+ * Timer offsets are pointing to the untrusted KVM copy,
+ * which is pinned in __pkvm_init_vm() for the VM life time.
+ * It is worth noting that hyp_vm->host_kvm points to an EL2
+ * linear map address and timer_get_offset() will use
+ * kern_hyp_va() which is safe as it is idempotent.
+ */
+ vcpu_vtimer(&hyp_vcpu->vcpu)->offset.vm_offset =
+ &hyp_vm->host_kvm->arch.timer_data.voffset;
+ vcpu_ptimer(&hyp_vcpu->vcpu)->offset.vm_offset =
+ &hyp_vm->host_kvm->arch.timer_data.poffset;
+ }
+
ret = pkvm_vcpu_init_sysregs(hyp_vcpu);
if (ret)
goto done;
diff --git a/arch/arm64/kvm/hyp/nvhe/timer-sr.c b/arch/arm64/kvm/hyp/nvhe/timer-sr.c
index ff176f4ce7de..51b4f5010b66 100644
--- a/arch/arm64/kvm/hyp/nvhe/timer-sr.c
+++ b/arch/arm64/kvm/hyp/nvhe/timer-sr.c
@@ -45,11 +45,11 @@ void __timer_enable_traps(struct kvm_vcpu *vcpu)
/*
* Disallow physical timer access for the guest
* Physical counter access is allowed if no offset is enforced
- * or running protected (we don't offset anything in this case).
+ * or running a protected VM (we don't offset anything in this case).
*/
clr = CNTHCTL_EL1PCEN;
- if (is_protected_kvm_enabled() ||
- !kern_hyp_va(vcpu->kvm)->arch.timer_data.poffset)
+ if (vcpu_is_protected(vcpu) ||
+ !timer_get_offset(vcpu_ptimer(vcpu)))
set |= CNTHCTL_EL1PCTEN;
else
clr |= CNTHCTL_EL1PCTEN;