]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
KVM: arm64: Prevent host from managing timer offsets for protected VMs
authorFuad Tabba <tabba@google.com>
Thu, 11 Dec 2025 10:47:09 +0000 (10:47 +0000)
committerMarc Zyngier <maz@kernel.org>
Thu, 15 Jan 2026 15:55:50 +0000 (15:55 +0000)
For protected VMs, the guest's timer offset state should not be
controlled by the host and must always run with a virtual counter offset
of 0. The existing timer logic allowed the host to set and manage the
timer counter offsets for protected VMs in certain cases.

Disable all host-side management of timer offsets for protected VMs by
adding checks in the relevant code paths.

Signed-off-by: Fuad Tabba <tabba@google.com>
Link: https://patch.msgid.link/20251211104710.151771-10-tabba@google.com
Signed-off-by: Marc Zyngier <maz@kernel.org>
arch/arm64/kvm/arch_timer.c

index 99a07972068d1ec8aeb63e5a7b8e55acffa3ba2a..600f250753b45b834890d1ed9285288484c890bd 100644 (file)
@@ -1056,10 +1056,14 @@ static void timer_context_init(struct kvm_vcpu *vcpu, int timerid)
 
        ctxt->timer_id = timerid;
 
-       if (timerid == TIMER_VTIMER)
-               ctxt->offset.vm_offset = &kvm->arch.timer_data.voffset;
-       else
-               ctxt->offset.vm_offset = &kvm->arch.timer_data.poffset;
+       if (!kvm_vm_is_protected(vcpu->kvm)) {
+               if (timerid == TIMER_VTIMER)
+                       ctxt->offset.vm_offset = &kvm->arch.timer_data.voffset;
+               else
+                       ctxt->offset.vm_offset = &kvm->arch.timer_data.poffset;
+       } else {
+               ctxt->offset.vm_offset = NULL;
+       }
 
        hrtimer_setup(&ctxt->hrtimer, kvm_hrtimer_expire, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_HARD);
 
@@ -1083,7 +1087,8 @@ void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu)
                timer_context_init(vcpu, i);
 
        /* Synchronize offsets across timers of a VM if not already provided */
-       if (!test_bit(KVM_ARCH_FLAG_VM_COUNTER_OFFSET, &vcpu->kvm->arch.flags)) {
+       if (!vcpu_is_protected(vcpu) &&
+           !test_bit(KVM_ARCH_FLAG_VM_COUNTER_OFFSET, &vcpu->kvm->arch.flags)) {
                timer_set_offset(vcpu_vtimer(vcpu), kvm_phys_timer_read());
                timer_set_offset(vcpu_ptimer(vcpu), 0);
        }
@@ -1687,6 +1692,9 @@ int kvm_vm_ioctl_set_counter_offset(struct kvm *kvm,
        if (offset->reserved)
                return -EINVAL;
 
+       if (kvm_vm_is_protected(kvm))
+               return -EINVAL;
+
        mutex_lock(&kvm->lock);
 
        if (!kvm_trylock_all_vcpus(kvm)) {