Skip to content

Commit df5fd75

Browse files
author
Marc Zyngier
committed
KVM: arm64: Don't eagerly teardown the vgic on init error
As there is very little ordering in the KVM API, userspace can instanciate a half-baked GIC (missing its memory map, for example) at almost any time. This means that, with the right timing, a thread running vcpu-0 can enter the kernel without a GIC configured and get a GIC created behind its back by another thread. Amusingly, it will pick up that GIC and start messing with the data structures without the GIC having been fully initialised. Similarly, a thread running vcpu-1 can enter the kernel, and try to init the GIC that was previously created. Since this GIC isn't properly configured (no memory map), it fails to correctly initialise. And that's the point where we decide to teardown the GIC, freeing all its resources. Behind vcpu-0's back. Things stop pretty abruptly, with a variety of symptoms. Clearly, this isn't good, we should be a bit more careful about this. It is obvious that this guest is not viable, as it is missing some important part of its configuration. So instead of trying to tear bits of it down, let's just mark it as *dead*. It means that any further interaction from userspace will result in -EIO. The memory will be released on the "normal" path, when userspace gives up. Cc: stable@vger.kernel.org Reported-by: Alexander Potapenko <glider@google.com> Reviewed-by: Oliver Upton <oliver.upton@linux.dev> Link: https://lore.kernel.org/r/20241009183603.3221824-1-maz@kernel.org Signed-off-by: Marc Zyngier <maz@kernel.org>
1 parent d4a89e5 commit df5fd75

File tree

2 files changed

+6
-3
lines changed

2 files changed

+6
-3
lines changed

arch/arm64/kvm/arm.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,9 @@ static int kvm_vcpu_suspend(struct kvm_vcpu *vcpu)
997997
static int check_vcpu_requests(struct kvm_vcpu *vcpu)
998998
{
999999
if (kvm_request_pending(vcpu)) {
1000+
if (kvm_check_request(KVM_REQ_VM_DEAD, vcpu))
1001+
return -EIO;
1002+
10001003
if (kvm_check_request(KVM_REQ_SLEEP, vcpu))
10011004
kvm_vcpu_sleep(vcpu);
10021005

arch/arm64/kvm/vgic/vgic-init.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -556,10 +556,10 @@ int kvm_vgic_map_resources(struct kvm *kvm)
556556
out:
557557
mutex_unlock(&kvm->arch.config_lock);
558558
out_slots:
559-
mutex_unlock(&kvm->slots_lock);
560-
561559
if (ret)
562-
kvm_vgic_destroy(kvm);
560+
kvm_vm_dead(kvm);
561+
562+
mutex_unlock(&kvm->slots_lock);
563563

564564
return ret;
565565
}

0 commit comments

Comments
 (0)