KVM: SEV: Unmap and unpin the GHCB as needed on vCPU free
Unmap and unpin the GHCB as needed when freeing a vCPU. If the VM is
destroyed after mapping+pinning the GHCB on #VMGEXIT, without re-running
the vCPU, KVM will effectively leak the GHCB and any mappings created for
the GHCB.
Fixes: 291bd20d5d ("KVM: SVM: Add initial support for a VMGEXIT VMEXIT")
Cc: stable@vger.kernel.org
Tested-by: Michael Roth <michael.roth@amd.com>
Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
Reviewed-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
Message-ID: <20260501202250.2115252-18-seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Message-ID: <20260529183549.1104619-18-pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
f041dc80de
commit
db38bcb331
1 changed files with 16 additions and 10 deletions
|
|
@ -3552,6 +3552,20 @@ vmgexit_err:
|
|||
return 1;
|
||||
}
|
||||
|
||||
static void __sev_es_unmap_ghcb(struct vcpu_svm *svm)
|
||||
{
|
||||
if (svm->sev_es.ghcb_sa_free) {
|
||||
kvfree(svm->sev_es.ghcb_sa);
|
||||
svm->sev_es.ghcb_sa = NULL;
|
||||
svm->sev_es.ghcb_sa_free = false;
|
||||
}
|
||||
|
||||
if (svm->sev_es.ghcb) {
|
||||
kvm_vcpu_unmap(&svm->vcpu, &svm->sev_es.ghcb_map);
|
||||
svm->sev_es.ghcb = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void sev_es_unmap_ghcb(struct vcpu_svm *svm)
|
||||
{
|
||||
/* Clear any indication that the vCPU is in a type of AP Reset Hold */
|
||||
|
|
@ -3570,18 +3584,11 @@ void sev_es_unmap_ghcb(struct vcpu_svm *svm)
|
|||
svm->sev_es.ghcb_sa_sync = false;
|
||||
}
|
||||
|
||||
if (svm->sev_es.ghcb_sa_free) {
|
||||
kvfree(svm->sev_es.ghcb_sa);
|
||||
svm->sev_es.ghcb_sa = NULL;
|
||||
svm->sev_es.ghcb_sa_free = false;
|
||||
}
|
||||
|
||||
trace_kvm_vmgexit_exit(svm->vcpu.vcpu_id, svm->sev_es.ghcb);
|
||||
|
||||
sev_es_sync_to_ghcb(svm);
|
||||
|
||||
kvm_vcpu_unmap(&svm->vcpu, &svm->sev_es.ghcb_map);
|
||||
svm->sev_es.ghcb = NULL;
|
||||
__sev_es_unmap_ghcb(svm);
|
||||
}
|
||||
|
||||
void sev_free_vcpu(struct kvm_vcpu *vcpu)
|
||||
|
|
@ -3611,8 +3618,7 @@ void sev_free_vcpu(struct kvm_vcpu *vcpu)
|
|||
__free_page(virt_to_page(svm->sev_es.vmsa));
|
||||
|
||||
skip_vmsa_free:
|
||||
if (svm->sev_es.ghcb_sa_free)
|
||||
kvfree(svm->sev_es.ghcb_sa);
|
||||
__sev_es_unmap_ghcb(svm);
|
||||
}
|
||||
|
||||
int pre_sev_run(struct vcpu_svm *svm, int cpu)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue