summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Christopherson <seanjc@google.com>2026-03-10 16:48:13 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-04-22 13:30:49 +0200
commit4df77742e8b9a6b935bdf46f02fd0aca4d4ee7f5 (patch)
tree29706a43d5bb0063d6bb0737170f4472e8bbfda4
parente00ef00eb7f9b2be18516fa3732377ffe3ecaf6d (diff)
downloadlinux-stable-4df77742e8b9a6b935bdf46f02fd0aca4d4ee7f5.tar.gz
linux-stable-4df77742e8b9a6b935bdf46f02fd0aca4d4ee7f5.zip
KVM: SEV: Lock all vCPUs when synchronzing VMSAs for SNP launch finish
commit cb923ee6a80f4e604e6242a4702b59251e61a380 upstream. Lock all vCPUs when synchronizing and encrypting VMSAs for SNP guests, as allowing userspace to manipulate and/or run a vCPU while its state is being synchronized would at best corrupt vCPU state, and at worst crash the host kernel. Opportunistically assert that vcpu->mutex is held when synchronizing its VMSA (the SEV-ES path already locks vCPUs). Fixes: ad27ce155566 ("KVM: SEV: Add KVM_SEV_SNP_LAUNCH_FINISH command") Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260310234829.2608037-6-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--arch/x86/kvm/svm/sev.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index 5d4b4d74704d..4370dde0ea25 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -875,6 +875,8 @@ static int sev_es_sync_vmsa(struct vcpu_svm *svm)
u8 *d;
int i;
+ lockdep_assert_held(&vcpu->mutex);
+
if (vcpu->arch.guest_state_protected)
return -EINVAL;
@@ -2460,6 +2462,10 @@ static int snp_launch_update_vmsa(struct kvm *kvm, struct kvm_sev_cmd *argp)
if (kvm_is_vcpu_creation_in_progress(kvm))
return -EBUSY;
+ ret = kvm_lock_all_vcpus(kvm);
+ if (ret)
+ return ret;
+
data.gctx_paddr = __psp_pa(sev->snp_context);
data.page_type = SNP_PAGE_TYPE_VMSA;
@@ -2469,12 +2475,12 @@ static int snp_launch_update_vmsa(struct kvm *kvm, struct kvm_sev_cmd *argp)
ret = sev_es_sync_vmsa(svm);
if (ret)
- return ret;
+ goto out;
/* Transition the VMSA page to a firmware state. */
ret = rmp_make_private(pfn, INITIAL_VMSA_GPA, PG_LEVEL_4K, sev->asid, true);
if (ret)
- return ret;
+ goto out;
/* Issue the SNP command to encrypt the VMSA */
data.address = __sme_pa(svm->sev_es.vmsa);
@@ -2483,7 +2489,7 @@ static int snp_launch_update_vmsa(struct kvm *kvm, struct kvm_sev_cmd *argp)
if (ret) {
snp_page_reclaim(kvm, pfn);
- return ret;
+ goto out;
}
svm->vcpu.arch.guest_state_protected = true;
@@ -2497,7 +2503,9 @@ static int snp_launch_update_vmsa(struct kvm *kvm, struct kvm_sev_cmd *argp)
svm_enable_lbrv(vcpu);
}
- return 0;
+out:
+ kvm_unlock_all_vcpus(kvm);
+ return ret;
}
static int snp_launch_finish(struct kvm *kvm, struct kvm_sev_cmd *argp)