KVM: SEV: accept signals in sev_lock_two_vms
Generally, kvm->lock is not taken for a long time, but sev_lock_two_vms is different: it takes vCPU locks inside, so userspace can hold it back just by calling a vCPU ioctl. Play it safe and use mutex_lock_killable. Message-Id: <20211123005036.2954379-13-pbonzini@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Родитель
10a37929ef
Коммит
c9d61dcb0b
|
@ -1547,6 +1547,7 @@ static int sev_lock_two_vms(struct kvm *dst_kvm, struct kvm *src_kvm)
|
|||
{
|
||||
struct kvm_sev_info *dst_sev = &to_kvm_svm(dst_kvm)->sev_info;
|
||||
struct kvm_sev_info *src_sev = &to_kvm_svm(src_kvm)->sev_info;
|
||||
int r = -EBUSY;
|
||||
|
||||
if (dst_kvm == src_kvm)
|
||||
return -EINVAL;
|
||||
|
@ -1558,14 +1559,23 @@ static int sev_lock_two_vms(struct kvm *dst_kvm, struct kvm *src_kvm)
|
|||
if (atomic_cmpxchg_acquire(&dst_sev->migration_in_progress, 0, 1))
|
||||
return -EBUSY;
|
||||
|
||||
if (atomic_cmpxchg_acquire(&src_sev->migration_in_progress, 0, 1)) {
|
||||
atomic_set_release(&dst_sev->migration_in_progress, 0);
|
||||
return -EBUSY;
|
||||
}
|
||||
if (atomic_cmpxchg_acquire(&src_sev->migration_in_progress, 0, 1))
|
||||
goto release_dst;
|
||||
|
||||
mutex_lock(&dst_kvm->lock);
|
||||
mutex_lock(&src_kvm->lock);
|
||||
r = -EINTR;
|
||||
if (mutex_lock_killable(&dst_kvm->lock))
|
||||
goto release_src;
|
||||
if (mutex_lock_killable(&src_kvm->lock))
|
||||
goto unlock_dst;
|
||||
return 0;
|
||||
|
||||
unlock_dst:
|
||||
mutex_unlock(&dst_kvm->lock);
|
||||
release_src:
|
||||
atomic_set_release(&src_sev->migration_in_progress, 0);
|
||||
release_dst:
|
||||
atomic_set_release(&dst_sev->migration_in_progress, 0);
|
||||
return r;
|
||||
}
|
||||
|
||||
static void sev_unlock_two_vms(struct kvm *dst_kvm, struct kvm *src_kvm)
|
||||
|
|
Загрузка…
Ссылка в новой задаче