Skip to content

Commit 501b580

Browse files
committed
KVM: SEV: cleanup locking for KVM_CAP_VM_MOVE_ENC_CONTEXT_FROM
Encapsulate the handling of the migration_in_progress flag for both VMs in two functions sev_lock_two_vms and sev_unlock_two_vms. It does not matter if KVM_CAP_VM_MOVE_ENC_CONTEXT_FROM locks the destination struct kvm a bit later, and this change 1) keeps the cleanup chain of labels smaller 2) makes it possible for KVM_CAP_VM_COPY_ENC_CONTEXT_FROM to reuse the logic. Cc: Peter Gonda <[email protected]> Cc: Sean Christopherson <[email protected]> Message-Id: <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 4674164 commit 501b580

File tree

1 file changed

+27
-26
lines changed

1 file changed

+27
-26
lines changed

arch/x86/kvm/svm/sev.c

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1543,28 +1543,40 @@ static bool is_cmd_allowed_from_mirror(u32 cmd_id)
15431543
return false;
15441544
}
15451545

1546-
static int sev_lock_for_migration(struct kvm *kvm)
1546+
static int sev_lock_two_vms(struct kvm *dst_kvm, struct kvm *src_kvm)
15471547
{
1548-
struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
1548+
struct kvm_sev_info *dst_sev = &to_kvm_svm(dst_kvm)->sev_info;
1549+
struct kvm_sev_info *src_sev = &to_kvm_svm(src_kvm)->sev_info;
1550+
1551+
if (dst_kvm == src_kvm)
1552+
return -EINVAL;
15491553

15501554
/*
1551-
* Bail if this VM is already involved in a migration to avoid deadlock
1552-
* between two VMs trying to migrate to/from each other.
1555+
* Bail if these VMs are already involved in a migration to avoid
1556+
* deadlock between two VMs trying to migrate to/from each other.
15531557
*/
1554-
if (atomic_cmpxchg_acquire(&sev->migration_in_progress, 0, 1))
1558+
if (atomic_cmpxchg_acquire(&dst_sev->migration_in_progress, 0, 1))
15551559
return -EBUSY;
15561560

1557-
mutex_lock(&kvm->lock);
1561+
if (atomic_cmpxchg_acquire(&src_sev->migration_in_progress, 0, 1)) {
1562+
atomic_set_release(&dst_sev->migration_in_progress, 0);
1563+
return -EBUSY;
1564+
}
15581565

1566+
mutex_lock(&dst_kvm->lock);
1567+
mutex_lock(&src_kvm->lock);
15591568
return 0;
15601569
}
15611570

1562-
static void sev_unlock_after_migration(struct kvm *kvm)
1571+
static void sev_unlock_two_vms(struct kvm *dst_kvm, struct kvm *src_kvm)
15631572
{
1564-
struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
1573+
struct kvm_sev_info *dst_sev = &to_kvm_svm(dst_kvm)->sev_info;
1574+
struct kvm_sev_info *src_sev = &to_kvm_svm(src_kvm)->sev_info;
15651575

1566-
mutex_unlock(&kvm->lock);
1567-
atomic_set_release(&sev->migration_in_progress, 0);
1576+
mutex_unlock(&dst_kvm->lock);
1577+
mutex_unlock(&src_kvm->lock);
1578+
atomic_set_release(&dst_sev->migration_in_progress, 0);
1579+
atomic_set_release(&src_sev->migration_in_progress, 0);
15681580
}
15691581

15701582

@@ -1665,29 +1677,20 @@ int svm_vm_migrate_from(struct kvm *kvm, unsigned int source_fd)
16651677
bool charged = false;
16661678
int ret;
16671679

1668-
ret = sev_lock_for_migration(kvm);
1669-
if (ret)
1670-
return ret;
1671-
1672-
if (sev_guest(kvm)) {
1673-
ret = -EINVAL;
1674-
goto out_unlock;
1675-
}
1676-
16771680
source_kvm_file = fget(source_fd);
16781681
if (!file_is_kvm(source_kvm_file)) {
16791682
ret = -EBADF;
16801683
goto out_fput;
16811684
}
16821685

16831686
source_kvm = source_kvm_file->private_data;
1684-
ret = sev_lock_for_migration(source_kvm);
1687+
ret = sev_lock_two_vms(kvm, source_kvm);
16851688
if (ret)
16861689
goto out_fput;
16871690

1688-
if (!sev_guest(source_kvm)) {
1691+
if (sev_guest(kvm) || !sev_guest(source_kvm)) {
16891692
ret = -EINVAL;
1690-
goto out_source;
1693+
goto out_unlock;
16911694
}
16921695

16931696
src_sev = &to_kvm_svm(source_kvm)->sev_info;
@@ -1727,13 +1730,11 @@ int svm_vm_migrate_from(struct kvm *kvm, unsigned int source_fd)
17271730
sev_misc_cg_uncharge(cg_cleanup_sev);
17281731
put_misc_cg(cg_cleanup_sev->misc_cg);
17291732
cg_cleanup_sev->misc_cg = NULL;
1730-
out_source:
1731-
sev_unlock_after_migration(source_kvm);
1733+
out_unlock:
1734+
sev_unlock_two_vms(kvm, source_kvm);
17321735
out_fput:
17331736
if (source_kvm_file)
17341737
fput(source_kvm_file);
1735-
out_unlock:
1736-
sev_unlock_after_migration(kvm);
17371738
return ret;
17381739
}
17391740

0 commit comments

Comments
 (0)