diff options
author | Al Viro <viro@ZenIV.linux.org.uk> | 2008-04-19 20:33:56 +0100 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-04-27 18:21:46 +0300 |
commit | 66c0b394f08fd89236515c1c84485ea712a157be (patch) | |
tree | bb6e9e5c0d6297f93617d222ea11f3c134ccab99 /virt/kvm/kvm_main.c | |
parent | 960b3991698872f68f09d51f4c2794ad484fe1fd (diff) | |
download | lwn-66c0b394f08fd89236515c1c84485ea712a157be.tar.gz lwn-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/kvm_main.c')
-rw-r--r-- | virt/kvm/kvm_main.c | 12 |
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; } |