Commit 66c0b394 authored by Al Viro's avatar Al Viro Committed by Avi Kivity

KVM: kill file->f_count abuse in kvm

Use kvm own refcounting instead of playing with ->filp->f_count.
That will allow to get rid of a lot of crap in anon_inode_getfd() and
kill a race in kvm_dev_ioctl_create_vm() (file might have been closed
immediately by another thread, so ->filp might point to already freed
struct file when we get around to setting it).
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
Signed-off-by: default avatarAvi Kivity <avi@qumranet.com>
parent 960b3991
...@@ -110,7 +110,6 @@ struct kvm { ...@@ -110,7 +110,6 @@ struct kvm {
KVM_PRIVATE_MEM_SLOTS]; KVM_PRIVATE_MEM_SLOTS];
struct kvm_vcpu *vcpus[KVM_MAX_VCPUS]; struct kvm_vcpu *vcpus[KVM_MAX_VCPUS];
struct list_head vm_list; struct list_head vm_list;
struct file *filp;
struct kvm_io_bus mmio_bus; struct kvm_io_bus mmio_bus;
struct kvm_io_bus pio_bus; struct kvm_io_bus pio_bus;
struct kvm_vm_stat stat; struct kvm_vm_stat stat;
......
...@@ -818,7 +818,7 @@ static int kvm_vcpu_release(struct inode *inode, struct file *filp) ...@@ -818,7 +818,7 @@ static int kvm_vcpu_release(struct inode *inode, struct file *filp)
{ {
struct kvm_vcpu *vcpu = filp->private_data; struct kvm_vcpu *vcpu = filp->private_data;
fput(vcpu->kvm->filp); kvm_put_kvm(vcpu->kvm);
return 0; return 0;
} }
...@@ -840,9 +840,10 @@ static int create_vcpu_fd(struct kvm_vcpu *vcpu) ...@@ -840,9 +840,10 @@ static int create_vcpu_fd(struct kvm_vcpu *vcpu)
r = anon_inode_getfd(&fd, &inode, &file, r = anon_inode_getfd(&fd, &inode, &file,
"kvm-vcpu", &kvm_vcpu_fops, vcpu); "kvm-vcpu", &kvm_vcpu_fops, vcpu);
if (r) if (r) {
kvm_put_kvm(vcpu->kvm);
return r; return r;
atomic_inc(&vcpu->kvm->filp->f_count); }
return fd; return fd;
} }
...@@ -877,6 +878,7 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, int n) ...@@ -877,6 +878,7 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, int n)
mutex_unlock(&kvm->lock); mutex_unlock(&kvm->lock);
/* Now it's all set up, let userspace reach it */ /* Now it's all set up, let userspace reach it */
kvm_get_kvm(kvm);
r = create_vcpu_fd(vcpu); r = create_vcpu_fd(vcpu);
if (r < 0) if (r < 0)
goto unlink; goto unlink;
...@@ -1176,12 +1178,10 @@ static int kvm_dev_ioctl_create_vm(void) ...@@ -1176,12 +1178,10 @@ static int kvm_dev_ioctl_create_vm(void)
return PTR_ERR(kvm); return PTR_ERR(kvm);
r = anon_inode_getfd(&fd, &inode, &file, "kvm-vm", &kvm_vm_fops, kvm); r = anon_inode_getfd(&fd, &inode, &file, "kvm-vm", &kvm_vm_fops, kvm);
if (r) { if (r) {
kvm_destroy_vm(kvm); kvm_put_kvm(kvm);
return r; return r;
} }
kvm->filp = file;
return fd; return fd;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment