mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2024-12-29 17:22:07 +00:00
assorted variants of irqfd setup: convert to CLASS(fd)
in all of those failure exits prior to fdget() are plain returns and the only thing done after fdput() is (on failure exits) a kfree(), which can be done before fdput() just fine. NOTE: in acrn_irqfd_assign() 'fail:' failure exit is wrong for eventfd_ctx_fileget() failure (we only want fdput() there) and once we stop doing that, it doesn't need to check if eventfd is NULL or ERR_PTR(...) there. NOTE: in privcmd we move fdget() up before the allocation - more to the point, before the copy_from_user() attempt. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
8935989798
commit
66635b0776
@ -113,7 +113,6 @@ int vfio_virqfd_enable(void *opaque,
|
||||
void (*thread)(void *, void *),
|
||||
void *data, struct virqfd **pvirqfd, int fd)
|
||||
{
|
||||
struct fd irqfd;
|
||||
struct eventfd_ctx *ctx;
|
||||
struct virqfd *virqfd;
|
||||
int ret = 0;
|
||||
@ -133,8 +132,8 @@ int vfio_virqfd_enable(void *opaque,
|
||||
INIT_WORK(&virqfd->inject, virqfd_inject);
|
||||
INIT_WORK(&virqfd->flush_inject, virqfd_flush_inject);
|
||||
|
||||
irqfd = fdget(fd);
|
||||
if (!fd_file(irqfd)) {
|
||||
CLASS(fd, irqfd)(fd);
|
||||
if (fd_empty(irqfd)) {
|
||||
ret = -EBADF;
|
||||
goto err_fd;
|
||||
}
|
||||
@ -142,7 +141,7 @@ int vfio_virqfd_enable(void *opaque,
|
||||
ctx = eventfd_ctx_fileget(fd_file(irqfd));
|
||||
if (IS_ERR(ctx)) {
|
||||
ret = PTR_ERR(ctx);
|
||||
goto err_ctx;
|
||||
goto err_fd;
|
||||
}
|
||||
|
||||
virqfd->eventfd = ctx;
|
||||
@ -181,18 +180,9 @@ int vfio_virqfd_enable(void *opaque,
|
||||
if ((!handler || handler(opaque, data)) && thread)
|
||||
schedule_work(&virqfd->inject);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do not drop the file until the irqfd is fully initialized,
|
||||
* otherwise we might race against the EPOLLHUP.
|
||||
*/
|
||||
fdput(irqfd);
|
||||
|
||||
return 0;
|
||||
err_busy:
|
||||
eventfd_ctx_put(ctx);
|
||||
err_ctx:
|
||||
fdput(irqfd);
|
||||
err_fd:
|
||||
kfree(virqfd);
|
||||
|
||||
|
@ -112,7 +112,6 @@ static int acrn_irqfd_assign(struct acrn_vm *vm, struct acrn_irqfd *args)
|
||||
struct eventfd_ctx *eventfd = NULL;
|
||||
struct hsm_irqfd *irqfd, *tmp;
|
||||
__poll_t events;
|
||||
struct fd f;
|
||||
int ret = 0;
|
||||
|
||||
irqfd = kzalloc(sizeof(*irqfd), GFP_KERNEL);
|
||||
@ -124,8 +123,8 @@ static int acrn_irqfd_assign(struct acrn_vm *vm, struct acrn_irqfd *args)
|
||||
INIT_LIST_HEAD(&irqfd->list);
|
||||
INIT_WORK(&irqfd->shutdown, hsm_irqfd_shutdown_work);
|
||||
|
||||
f = fdget(args->fd);
|
||||
if (!fd_file(f)) {
|
||||
CLASS(fd, f)(args->fd);
|
||||
if (fd_empty(f)) {
|
||||
ret = -EBADF;
|
||||
goto out;
|
||||
}
|
||||
@ -133,7 +132,7 @@ static int acrn_irqfd_assign(struct acrn_vm *vm, struct acrn_irqfd *args)
|
||||
eventfd = eventfd_ctx_fileget(fd_file(f));
|
||||
if (IS_ERR(eventfd)) {
|
||||
ret = PTR_ERR(eventfd);
|
||||
goto fail;
|
||||
goto out;
|
||||
}
|
||||
|
||||
irqfd->eventfd = eventfd;
|
||||
@ -162,13 +161,9 @@ static int acrn_irqfd_assign(struct acrn_vm *vm, struct acrn_irqfd *args)
|
||||
if (events & EPOLLIN)
|
||||
acrn_irqfd_inject(irqfd);
|
||||
|
||||
fdput(f);
|
||||
return 0;
|
||||
fail:
|
||||
if (eventfd && !IS_ERR(eventfd))
|
||||
eventfd_ctx_put(eventfd);
|
||||
|
||||
fdput(f);
|
||||
out:
|
||||
kfree(irqfd);
|
||||
return ret;
|
||||
|
@ -967,10 +967,11 @@ static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd)
|
||||
struct privcmd_kernel_irqfd *kirqfd, *tmp;
|
||||
unsigned long flags;
|
||||
__poll_t events;
|
||||
struct fd f;
|
||||
void *dm_op;
|
||||
int ret, idx;
|
||||
|
||||
CLASS(fd, f)(irqfd->fd);
|
||||
|
||||
kirqfd = kzalloc(sizeof(*kirqfd) + irqfd->size, GFP_KERNEL);
|
||||
if (!kirqfd)
|
||||
return -ENOMEM;
|
||||
@ -986,8 +987,7 @@ static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd)
|
||||
kirqfd->dom = irqfd->dom;
|
||||
INIT_WORK(&kirqfd->shutdown, irqfd_shutdown);
|
||||
|
||||
f = fdget(irqfd->fd);
|
||||
if (!fd_file(f)) {
|
||||
if (fd_empty(f)) {
|
||||
ret = -EBADF;
|
||||
goto error_kfree;
|
||||
}
|
||||
@ -995,7 +995,7 @@ static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd)
|
||||
kirqfd->eventfd = eventfd_ctx_fileget(fd_file(f));
|
||||
if (IS_ERR(kirqfd->eventfd)) {
|
||||
ret = PTR_ERR(kirqfd->eventfd);
|
||||
goto error_fd_put;
|
||||
goto error_kfree;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1028,20 +1028,11 @@ static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd)
|
||||
irqfd_inject(kirqfd);
|
||||
|
||||
srcu_read_unlock(&irqfds_srcu, idx);
|
||||
|
||||
/*
|
||||
* Do not drop the file until the kirqfd is fully initialized, otherwise
|
||||
* we might race against the EPOLLHUP.
|
||||
*/
|
||||
fdput(f);
|
||||
return 0;
|
||||
|
||||
error_eventfd:
|
||||
eventfd_ctx_put(kirqfd->eventfd);
|
||||
|
||||
error_fd_put:
|
||||
fdput(f);
|
||||
|
||||
error_kfree:
|
||||
kfree(kirqfd);
|
||||
return ret;
|
||||
|
@ -304,7 +304,6 @@ static int
|
||||
kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
|
||||
{
|
||||
struct kvm_kernel_irqfd *irqfd, *tmp;
|
||||
struct fd f;
|
||||
struct eventfd_ctx *eventfd = NULL, *resamplefd = NULL;
|
||||
int ret;
|
||||
__poll_t events;
|
||||
@ -327,8 +326,8 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
|
||||
INIT_WORK(&irqfd->shutdown, irqfd_shutdown);
|
||||
seqcount_spinlock_init(&irqfd->irq_entry_sc, &kvm->irqfds.lock);
|
||||
|
||||
f = fdget(args->fd);
|
||||
if (!fd_file(f)) {
|
||||
CLASS(fd, f)(args->fd);
|
||||
if (fd_empty(f)) {
|
||||
ret = -EBADF;
|
||||
goto out;
|
||||
}
|
||||
@ -336,7 +335,7 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
|
||||
eventfd = eventfd_ctx_fileget(fd_file(f));
|
||||
if (IS_ERR(eventfd)) {
|
||||
ret = PTR_ERR(eventfd);
|
||||
goto fail;
|
||||
goto out;
|
||||
}
|
||||
|
||||
irqfd->eventfd = eventfd;
|
||||
@ -440,12 +439,6 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
|
||||
#endif
|
||||
|
||||
srcu_read_unlock(&kvm->irq_srcu, idx);
|
||||
|
||||
/*
|
||||
* do not drop the file until the irqfd is fully initialized, otherwise
|
||||
* we might race against the EPOLLHUP
|
||||
*/
|
||||
fdput(f);
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
@ -458,8 +451,6 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
|
||||
if (eventfd && !IS_ERR(eventfd))
|
||||
eventfd_ctx_put(eventfd);
|
||||
|
||||
fdput(f);
|
||||
|
||||
out:
|
||||
kfree(irqfd);
|
||||
return ret;
|
||||
|
Loading…
Reference in New Issue
Block a user