aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@ZenIV.linux.org.uk>2008-04-19 15:33:56 -0400
committerAvi Kivity <avi@qumranet.com>2008-04-27 11:21:46 -0400
commit66c0b394f08fd89236515c1c84485ea712a157be (patch)
treebb6e9e5c0d6297f93617d222ea11f3c134ccab99
parent960b3991698872f68f09d51f4c2794ad484fe1fd (diff)
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: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Avi Kivity <avi@qumranet.com>
-rw-r--r--include/linux/kvm_host.h1
-rw-r--r--virt/kvm/kvm_main.c12
2 files changed, 6 insertions, 7 deletions
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 4e16682ee8bb..398978972b7a 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -110,7 +110,6 @@ struct kvm {
110 KVM_PRIVATE_MEM_SLOTS]; 110 KVM_PRIVATE_MEM_SLOTS];
111 struct kvm_vcpu *vcpus[KVM_MAX_VCPUS]; 111 struct kvm_vcpu *vcpus[KVM_MAX_VCPUS];
112 struct list_head vm_list; 112 struct list_head vm_list;
113 struct file *filp;
114 struct kvm_io_bus mmio_bus; 113 struct kvm_io_bus mmio_bus;
115 struct kvm_io_bus pio_bus; 114 struct kvm_io_bus pio_bus;
116 struct kvm_vm_stat stat; 115 struct kvm_vm_stat stat;
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index d3cb4cc0a5aa..c82cf15730a1 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -818,7 +818,7 @@ static int kvm_vcpu_release(struct inode *inode, struct file *filp)
818{ 818{
819 struct kvm_vcpu *vcpu = filp->private_data; 819 struct kvm_vcpu *vcpu = filp->private_data;
820 820
821 fput(vcpu->kvm->filp); 821 kvm_put_kvm(vcpu->kvm);
822 return 0; 822 return 0;
823} 823}
824 824
@@ -840,9 +840,10 @@ static int create_vcpu_fd(struct kvm_vcpu *vcpu)
840 840
841 r = anon_inode_getfd(&fd, &inode, &file, 841 r = anon_inode_getfd(&fd, &inode, &file,
842 "kvm-vcpu", &kvm_vcpu_fops, vcpu); 842 "kvm-vcpu", &kvm_vcpu_fops, vcpu);
843 if (r) 843 if (r) {
844 kvm_put_kvm(vcpu->kvm);
844 return r; 845 return r;
845 atomic_inc(&vcpu->kvm->filp->f_count); 846 }
846 return fd; 847 return fd;
847} 848}
848 849
@@ -877,6 +878,7 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, int n)
877 mutex_unlock(&kvm->lock); 878 mutex_unlock(&kvm->lock);
878 879
879 /* Now it's all set up, let userspace reach it */ 880 /* Now it's all set up, let userspace reach it */
881 kvm_get_kvm(kvm);
880 r = create_vcpu_fd(vcpu); 882 r = create_vcpu_fd(vcpu);
881 if (r < 0) 883 if (r < 0)
882 goto unlink; 884 goto unlink;
@@ -1176,12 +1178,10 @@ static int kvm_dev_ioctl_create_vm(void)
1176 return PTR_ERR(kvm); 1178 return PTR_ERR(kvm);
1177 r = anon_inode_getfd(&fd, &inode, &file, "kvm-vm", &kvm_vm_fops, kvm); 1179 r = anon_inode_getfd(&fd, &inode, &file, "kvm-vm", &kvm_vm_fops, kvm);
1178 if (r) { 1180 if (r) {
1179 kvm_destroy_vm(kvm); 1181 kvm_put_kvm(kvm);
1180 return r; 1182 return r;
1181 } 1183 }
1182 1184
1183 kvm->filp = file;
1184
1185 return fd; 1185 return fd;
1186} 1186}
1187 1187