summaryrefslogtreecommitdiffstats
path: root/virt/kvm
diff options
context:
space:
mode:
authorAl Viro <viro@ZenIV.linux.org.uk>2008-04-19 21:33:56 +0200
committerAvi Kivity <avi@qumranet.com>2008-04-27 17:21:46 +0200
commit66c0b394f08fd89236515c1c84485ea712a157be (patch)
treebb6e9e5c0d6297f93617d222ea11f3c134ccab99 /virt/kvm
parentKVM: MMU: kvm_pv_mmu_op should not take mmap_sem (diff)
downloadlinux-66c0b394f08fd89236515c1c84485ea712a157be.tar.xz
linux-66c0b394f08fd89236515c1c84485ea712a157be.zip
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>
Diffstat (limited to 'virt/kvm')
-rw-r--r--virt/kvm/kvm_main.c12
1 files changed, 6 insertions, 6 deletions
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)
{
struct kvm_vcpu *vcpu = filp->private_data;
- fput(vcpu->kvm->filp);
+ kvm_put_kvm(vcpu->kvm);
return 0;
}
@@ -840,9 +840,10 @@ static int create_vcpu_fd(struct kvm_vcpu *vcpu)
r = anon_inode_getfd(&fd, &inode, &file,
"kvm-vcpu", &kvm_vcpu_fops, vcpu);
- if (r)
+ if (r) {
+ kvm_put_kvm(vcpu->kvm);
return r;
- atomic_inc(&vcpu->kvm->filp->f_count);
+ }
return fd;
}
@@ -877,6 +878,7 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, int n)
mutex_unlock(&kvm->lock);
/* Now it's all set up, let userspace reach it */
+ kvm_get_kvm(kvm);
r = create_vcpu_fd(vcpu);
if (r < 0)
goto unlink;
@@ -1176,12 +1178,10 @@ static int kvm_dev_ioctl_create_vm(void)
return PTR_ERR(kvm);
r = anon_inode_getfd(&fd, &inode, &file, "kvm-vm", &kvm_vm_fops, kvm);
if (r) {
- kvm_destroy_vm(kvm);
+ kvm_put_kvm(kvm);
return r;
}
- kvm->filp = file;
-
return fd;
}