From: Al Viro Date: Sat, 19 Apr 2008 19:33:56 +0000 (+0100) Subject: KVM: kill file->f_count abuse in kvm X-Git-Tag: v2.6.26-rc1~1028^2 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=66c0b394f08fd89236515c1c84485ea712a157be;p=linux-2.6 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 Signed-off-by: Avi Kivity --- diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 4e16682ee8..398978972b 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -110,7 +110,6 @@ struct kvm { KVM_PRIVATE_MEM_SLOTS]; struct kvm_vcpu *vcpus[KVM_MAX_VCPUS]; struct list_head vm_list; - struct file *filp; struct kvm_io_bus mmio_bus; struct kvm_io_bus pio_bus; struct kvm_vm_stat stat; diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index d3cb4cc0a5..c82cf15730 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; }