]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
assorted variants of irqfd setup: convert to CLASS(fd)
authorAl Viro <viro@zeniv.linux.org.uk>
Sat, 20 Jul 2024 05:48:34 +0000 (01:48 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Sun, 3 Nov 2024 06:28:07 +0000 (01:28 -0500)
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>
drivers/vfio/virqfd.c
drivers/virt/acrn/irqfd.c
drivers/xen/privcmd.c
virt/kvm/eventfd.c

index d22881245e89146891d236eed9351f49dec4f200..aa2891f975087efc226917cadc8352307ffc6ca7 100644 (file)
@@ -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);
 
index 9994d818bb7e1107ae55123378113b7ac2db7cdb..b7da24ca147576664f97261d501d6ffd353e7921 100644 (file)
@@ -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);
+       eventfd_ctx_put(eventfd);
 out:
        kfree(irqfd);
        return ret;
index 79070494070d9916a47a86ec005da408cfe64765..0ca532614343d9457068daa3100ff7d8524eb5ba 100644 (file)
@@ -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;
index 6b390b622b728ef3fb08c586046f27b2a49188b9..249ba5b72e9b09472c97aa90b10a2d9d1be9bdc0 100644 (file)
@@ -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 @@ fail:
        if (eventfd && !IS_ERR(eventfd))
                eventfd_ctx_put(eventfd);
 
-       fdput(f);
-
 out:
        kfree(irqfd);
        return ret;