Skip to contentSkip to conversation

KVM: arm64: Tear down vGIC on failed vCPU creation

PATCH Applied Will Deacon 3 participants 3 messages Mar 14, 2025 – Mar 18, 2025

Subsystems (3)
lore
Share & tools
lore

Will Deacon

author maintainer
#0 lore raw

PATCH 1/1 KVM: arm64: Tear down vGIC on failed vCPU creation

If kvm_arch_vcpu_create() fails to share the vCPU page with the hypervisor, we propagate the error back to the ioctl but leave the vGIC vCPU data initialised. Note only does this leak the corresponding memory when the vCPU is destroyed but it can also lead to use-after-free if the redistributor device handling tries to walk into the vCPU.

Add the missing cleanup to kvm_arch_vcpu_create(), ensuring that the vGIC vCPU structures are destroyed on error.

Cc Marc Zyngier <[email protected]>
Cc Oliver Upton <[email protected]>
Cc Quentin Perret <[email protected]>

---

It's hard to come up with a "Fixes:" tag for this. Prior to 3f868e142c0b ("KVM: arm64: Introduce kvm_share_hyp()"), create_hyp_mappings() could still have failed, although if you go back before 66c57edd3bc7 ("KVM:
arm64: Restrict EL2 stage-1 changes in protected mode") then it's vanishingly unlikely.

 arch/arm64/kvm/arm.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
arch/arm64/kvm/arm.c +5 -1
index b8e55a441282..fa71cee02faa 100644
@@ -466,7 +466,11 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
 	if (err)
 		return err;
 
-	return kvm_share_hyp(vcpu, vcpu + 1);
+	err = kvm_share_hyp(vcpu, vcpu + 1);
+	if (err)
+		kvm_vgic_vcpu_destroy(vcpu);
+
+	return err;
 }
 
 void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
Signature · 1 line
2.49.0.rc1.451.g8f38331e32-goog
maintainer Reviewed-by on v1 1/1
#1 lore raw
Quoted 33 lines · Will Deacon

If kvm_arch_vcpu_create() fails to share the vCPU page with the hypervisor, we propagate the error back to the ioctl but leave the vGIC vCPU data initialised. Note only does this leak the corresponding memory when the vCPU is destroyed but it can also lead to use-after-free if the redistributor device handling tries to walk into the vCPU.

Add the missing cleanup to kvm_arch_vcpu_create(), ensuring that the vGIC vCPU structures are destroyed on error.

Cc Marc Zyngier <[email protected]>
Cc Oliver Upton <[email protected]>
Cc Quentin Perret <[email protected]>

---

It's hard to come up with a "Fixes:" tag for this. Prior to 3f868e142c0b ("KVM: arm64: Introduce kvm_share_hyp()"), create_hyp_mappings() could still have failed, although if you go back before 66c57edd3bc7 ("KVM:
arm64: Restrict EL2 stage-1 changes in protected mode") then it's vanishingly unlikely.

 arch/arm64/kvm/arm.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
arch/arm64/kvm/arm.c +0 -0
index b8e55a441282..fa71cee02faa 100644
@@ -466,7 +466,11 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
 	if (err)
 		return err;

arch/arm64/kvm/arm.c int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) · line 476

Quoted 10 lines
arch/arm64/kvm/arm.c +5 -1
 
-	return kvm_share_hyp(vcpu, vcpu + 1);
+	err = kvm_share_hyp(vcpu, vcpu + 1);
+	if (err)
+		kvm_vgic_vcpu_destroy(vcpu);
+
+	return err;
 }
 
 void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
	M.
Signature · 1 line
Without deviation from the norm, progress is not possible.
Applied
#2 lore raw
In reply to Will Deacon
Quoted 10 lines · Will Deacon

If kvm_arch_vcpu_create() fails to share the vCPU page with the hypervisor, we propagate the error back to the ioctl but leave the vGIC vCPU data initialised. Note only does this leak the corresponding memory when the vCPU is destroyed but it can also lead to use-after-free if the redistributor device handling tries to walk into the vCPU.

Add the missing cleanup to kvm_arch_vcpu_create(), ensuring that the vGIC vCPU structures are destroyed on error.

[...]

Applied to next, thanks!

[1/1] KVM: arm64: Tear down vGIC on failed vCPU creation

      https://git.kernel.org/kvmarm/kvmarm/c/250f25367b58

--
Best,
Oliver