Skip to content

Commit a28ebea

Browse files
chazyrkrcmar
authored andcommitted
KVM: Protect device ops->create and list_add with kvm->lock
KVM devices were manipulating list data structures without any form of synchronization, and some implementations of the create operations also suffered from a lack of synchronization. Now when we've split the xics create operation into create and init, we can hold the kvm->lock mutex while calling the create operation and when manipulating the devices list. The error path in the generic code gets slightly ugly because we have to take the mutex again and delete the device from the list, but holding the mutex during anon_inode_getfd or releasing/locking the mutex in the common non-error path seemed wrong. Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Acked-by: Christian Borntraeger <borntraeger@de.ibm.com> Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
1 parent 023e9fd commit a28ebea

File tree

5 files changed

+27
-17
lines changed

5 files changed

+27
-17
lines changed

arch/arm/kvm/arm.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1009,9 +1009,13 @@ long kvm_arch_vm_ioctl(struct file *filp,
10091009

10101010
switch (ioctl) {
10111011
case KVM_CREATE_IRQCHIP: {
1012+
int ret;
10121013
if (!vgic_present)
10131014
return -ENXIO;
1014-
return kvm_vgic_create(kvm, KVM_DEV_TYPE_ARM_VGIC_V2);
1015+
mutex_lock(&kvm->lock);
1016+
ret = kvm_vgic_create(kvm, KVM_DEV_TYPE_ARM_VGIC_V2);
1017+
mutex_unlock(&kvm->lock);
1018+
return ret;
10151019
}
10161020
case KVM_ARM_SET_DEVICE_ADDR: {
10171021
struct kvm_arm_device_addr dev_addr;

arch/powerpc/kvm/book3s_xics.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,12 +1329,10 @@ static int kvmppc_xics_create(struct kvm_device *dev, u32 type)
13291329
xics->kvm = kvm;
13301330

13311331
/* Already there ? */
1332-
mutex_lock(&kvm->lock);
13331332
if (kvm->arch.xics)
13341333
ret = -EEXIST;
13351334
else
13361335
kvm->arch.xics = xics;
1337-
mutex_unlock(&kvm->lock);
13381336

13391337
if (ret) {
13401338
kfree(xics);

include/linux/kvm_host.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,6 +1113,12 @@ struct kvm_device {
11131113
/* create, destroy, and name are mandatory */
11141114
struct kvm_device_ops {
11151115
const char *name;
1116+
1117+
/*
1118+
* create is called holding kvm->lock and any operations not suitable
1119+
* to do while holding the lock should be deferred to init (see
1120+
* below).
1121+
*/
11161122
int (*create)(struct kvm_device *dev, u32 type);
11171123

11181124
/*

virt/kvm/arm/vgic/vgic-init.c

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,8 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
7373
int i, vcpu_lock_idx = -1, ret;
7474
struct kvm_vcpu *vcpu;
7575

76-
mutex_lock(&kvm->lock);
77-
78-
if (irqchip_in_kernel(kvm)) {
79-
ret = -EEXIST;
80-
goto out;
81-
}
76+
if (irqchip_in_kernel(kvm))
77+
return -EEXIST;
8278

8379
/*
8480
* This function is also called by the KVM_CREATE_IRQCHIP handler,
@@ -87,10 +83,8 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
8783
* the proper checks already.
8884
*/
8985
if (type == KVM_DEV_TYPE_ARM_VGIC_V2 &&
90-
!kvm_vgic_global_state.can_emulate_gicv2) {
91-
ret = -ENODEV;
92-
goto out;
93-
}
86+
!kvm_vgic_global_state.can_emulate_gicv2)
87+
return -ENODEV;
9488

9589
/*
9690
* Any time a vcpu is run, vcpu_load is called which tries to grab the
@@ -138,9 +132,6 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
138132
vcpu = kvm_get_vcpu(kvm, vcpu_lock_idx);
139133
mutex_unlock(&vcpu->mutex);
140134
}
141-
142-
out:
143-
mutex_unlock(&kvm->lock);
144135
return ret;
145136
}
146137

virt/kvm/kvm_main.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,11 @@ static void kvm_destroy_devices(struct kvm *kvm)
696696
{
697697
struct kvm_device *dev, *tmp;
698698

699+
/*
700+
* We do not need to take the kvm->lock here, because nobody else
701+
* has a reference to the struct kvm at this point and therefore
702+
* cannot access the devices list anyhow.
703+
*/
699704
list_for_each_entry_safe(dev, tmp, &kvm->devices, vm_node) {
700705
list_del(&dev->vm_node);
701706
dev->ops->destroy(dev);
@@ -2832,22 +2837,28 @@ static int kvm_ioctl_create_device(struct kvm *kvm,
28322837
dev->ops = ops;
28332838
dev->kvm = kvm;
28342839

2840+
mutex_lock(&kvm->lock);
28352841
ret = ops->create(dev, cd->type);
28362842
if (ret < 0) {
2843+
mutex_unlock(&kvm->lock);
28372844
kfree(dev);
28382845
return ret;
28392846
}
2847+
list_add(&dev->vm_node, &kvm->devices);
2848+
mutex_unlock(&kvm->lock);
28402849

28412850
if (ops->init)
28422851
ops->init(dev);
28432852

28442853
ret = anon_inode_getfd(ops->name, &kvm_device_fops, dev, O_RDWR | O_CLOEXEC);
28452854
if (ret < 0) {
28462855
ops->destroy(dev);
2856+
mutex_lock(&kvm->lock);
2857+
list_del(&dev->vm_node);
2858+
mutex_unlock(&kvm->lock);
28472859
return ret;
28482860
}
28492861

2850-
list_add(&dev->vm_node, &kvm->devices);
28512862
kvm_get_kvm(kvm);
28522863
cd->fd = ret;
28532864
return 0;

0 commit comments

Comments
 (0)