KVM: SEV: Decouple the need to sync the GHCB SA from the need to free the SA
Decouple synchronizing the GHCB SA from freeing/unpinning the SA, so that the free/unpin path can be reused when freeing a vCPU. Opportunistically add a WARN to harden KVM against stomping over (and thus leaking) an already-allocated scratch area. Cc: stable@vger.kernel.org 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-17-seanjc@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Message-ID: <20260529183549.1104619-17-pbonzini@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>master
parent
08385c5e18
commit
f041dc80de
|
|
@ -3560,20 +3560,17 @@ void sev_es_unmap_ghcb(struct vcpu_svm *svm)
|
|||
if (!svm->sev_es.ghcb)
|
||||
return;
|
||||
|
||||
if (svm->sev_es.ghcb_sa_free) {
|
||||
/*
|
||||
* The scratch area lives outside the GHCB, so there is a
|
||||
* buffer that, depending on the operation performed, may
|
||||
* need to be synced, then freed.
|
||||
*/
|
||||
if (svm->sev_es.ghcb_sa_sync) {
|
||||
kvm_write_guest(svm->vcpu.kvm,
|
||||
svm->sev_es.sw_scratch,
|
||||
svm->sev_es.ghcb_sa,
|
||||
svm->sev_es.ghcb_sa_len);
|
||||
svm->sev_es.ghcb_sa_sync = false;
|
||||
}
|
||||
/*
|
||||
* If the scratch area lives outside the GHCB, there's a buffer that,
|
||||
* depending on the operation performed, may need to be synced.
|
||||
*/
|
||||
if (svm->sev_es.ghcb_sa_sync) {
|
||||
kvm_write_guest(svm->vcpu.kvm, svm->sev_es.sw_scratch,
|
||||
svm->sev_es.ghcb_sa, svm->sev_es.ghcb_sa_len);
|
||||
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;
|
||||
|
|
@ -3685,6 +3682,8 @@ static int setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 min_len)
|
|||
goto e_scratch;
|
||||
}
|
||||
|
||||
WARN_ON_ONCE(svm->sev_es.ghcb_sa_sync || svm->sev_es.ghcb_sa_free);
|
||||
|
||||
if ((scratch_gpa_beg & PAGE_MASK) == control->ghcb_gpa) {
|
||||
/* Scratch area begins within GHCB */
|
||||
ghcb_scratch_beg = control->ghcb_gpa +
|
||||
|
|
@ -3706,6 +3705,8 @@ static int setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 min_len)
|
|||
scratch_va = (void *)svm->sev_es.ghcb;
|
||||
scratch_va += (scratch_gpa_beg - control->ghcb_gpa);
|
||||
|
||||
svm->sev_es.ghcb_sa_sync = false;
|
||||
svm->sev_es.ghcb_sa_free = false;
|
||||
svm->sev_es.ghcb_sa_len = ghcb_scratch_end - scratch_gpa_beg;
|
||||
} else {
|
||||
/* GHCB v2 requires the scratch area to be within the GHCB. */
|
||||
|
|
|
|||
Loading…
Reference in New Issue