Re: [PATCH 1/2] KVM: SVM: Serialize the owner's mirror list in sev_migrate_from()
Tom Lendacky <[email protected]> Tue, 4 Aug 2026 10:13:21 -0500
| Newsgroups | org.kernel.vger.kvm |
|---|---|
| Message-ID | <[email protected]> |
On 8/4/26 09:54, Shen Yongchao wrote:
> In sev_migrate_from(), when the destination KVM is a mirror, the mirror
> entry is moved from the source's list to the owner's mirror_vms list
> without holding the owner's lock. All other writers of the owner's
> mirror list (KVM_SEV_MIRROR_CREATE, sev_vm_destroy()) serialize on the
> owner's lock, so a concurrent COPY or destroy can race with
> KVM_SEV_MIGRATE_VM and corrupt the list, e.g. leaving a dangling
> mirror_entry that is later dereferenced.
>
> All kernels with SEV mirroring and intra-host migration support
> (KVM_SEV_MIRROR_CREATE / KVM_SEV_MIGRATE_VM) are affected. The mirror
> list mechanism was introduced by commit b2125513dfc0 ("KVM: SEV: Allow
> SEV intra-host migration of VM with mirrors", v5.18, 2022-02-18);
> upstream mainline is unfixed as of 2026-08-04. Triggering requires an
> AMD SEV-capable host with CONFIG_KVM_AMD_SEV and a local user able to
> create SEV VMs and mirrors, racing KVM_SEV_MIGRATE_VM against
> KVM_SEV_MIRROR_CREATE or mirror destroy (instruction-level window).
>
> Take the owner's lock around the list operations. The lock is taken
> after sev_lock_two_vms() and the migration_in_progress flags prevent
> two migrations from interleaving. The owner is a third VM whose lock
> is not held: the destination cannot already own an encryption context
> (sev_vm_move_enc_context_from() rejects SEV guests as the destination,
> gating on ->active), and a VM cannot be its own mirror owner. Hence
> SINGLE_DEPTH_NESTING is sufficient and cannot deadlock.
>
> This patch was drafted with AI assistance.
>
> Fixes: b2125513dfc0 ("KVM: SEV: Allow SEV intra-host migration of VM with mirrors")
> Cc: [email protected]
> Assisted-by: Hermes:deepseek-v4-flash
> Signed-off-by: Shen Yongchao <[email protected]>
For future reference, you should run your patch through
scripts/get_maintainer.pl so that you include the proper people/lists when
sending the patch, especially the originator of the patch being fixed.
Thanks,
Tom
> ---
> Reproducer: static analysis only (no SEV-capable hardware available);
> no reproducer has been run. The triggering sequence is described in
> the commit message.
>
> This issue was initially reported privately to security@; Sean
> Christopherson OK'd handling it on-list.
>
> Mitigations: none; SEV is an optional platform feature and the attack
> requires a local user with SEV VM creation privileges.
> arch/x86/kvm/svm/sev.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
> index 944aaea6501..4fa4e9bf408 100644
> --- a/arch/x86/kvm/svm/sev.c
> +++ b/arch/x86/kvm/svm/sev.c
> @@ -2050,8 +2050,14 @@ static void sev_migrate_from(struct kvm *dst_kvm, struct kvm *src_kvm)
> if (is_mirroring_enc_context(dst_kvm)) {
> struct kvm_sev_info *owner_sev_info = to_kvm_sev_info(dst->enc_context_owner);
>
> + /*
> + * All other writers of the owner's mirror list (COPY,
> + * destroy) serialize on the owner's lock; do the same.
> + */
> + mutex_lock_nested(&dst->enc_context_owner->lock, SINGLE_DEPTH_NESTING);
> list_del(&src->mirror_entry);
> list_add_tail(&dst->mirror_entry, &owner_sev_info->mirror_vms);
> + mutex_unlock(&dst->enc_context_owner->lock);
> }
>
> kvm_for_each_vcpu(i, dst_vcpu, dst_kvm) {