Skip to content

Commit 66635b0

Browse files
author
Al Viro
committed
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 <[email protected]>
1 parent 8935989 commit 66635b0

File tree

4 files changed

+14
-47
lines changed

4 files changed

+14
-47
lines changed

drivers/vfio/virqfd.c

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,6 @@ int vfio_virqfd_enable(void *opaque,
113113
void (*thread)(void *, void *),
114114
void *data, struct virqfd **pvirqfd, int fd)
115115
{
116-
struct fd irqfd;
117116
struct eventfd_ctx *ctx;
118117
struct virqfd *virqfd;
119118
int ret = 0;
@@ -133,16 +132,16 @@ int vfio_virqfd_enable(void *opaque,
133132
INIT_WORK(&virqfd->inject, virqfd_inject);
134133
INIT_WORK(&virqfd->flush_inject, virqfd_flush_inject);
135134

136-
irqfd = fdget(fd);
137-
if (!fd_file(irqfd)) {
135+
CLASS(fd, irqfd)(fd);
136+
if (fd_empty(irqfd)) {
138137
ret = -EBADF;
139138
goto err_fd;
140139
}
141140

142141
ctx = eventfd_ctx_fileget(fd_file(irqfd));
143142
if (IS_ERR(ctx)) {
144143
ret = PTR_ERR(ctx);
145-
goto err_ctx;
144+
goto err_fd;
146145
}
147146

148147
virqfd->eventfd = ctx;
@@ -181,18 +180,9 @@ int vfio_virqfd_enable(void *opaque,
181180
if ((!handler || handler(opaque, data)) && thread)
182181
schedule_work(&virqfd->inject);
183182
}
184-
185-
/*
186-
* Do not drop the file until the irqfd is fully initialized,
187-
* otherwise we might race against the EPOLLHUP.
188-
*/
189-
fdput(irqfd);
190-
191183
return 0;
192184
err_busy:
193185
eventfd_ctx_put(ctx);
194-
err_ctx:
195-
fdput(irqfd);
196186
err_fd:
197187
kfree(virqfd);
198188

drivers/virt/acrn/irqfd.c

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@ static int acrn_irqfd_assign(struct acrn_vm *vm, struct acrn_irqfd *args)
112112
struct eventfd_ctx *eventfd = NULL;
113113
struct hsm_irqfd *irqfd, *tmp;
114114
__poll_t events;
115-
struct fd f;
116115
int ret = 0;
117116

118117
irqfd = kzalloc(sizeof(*irqfd), GFP_KERNEL);
@@ -124,16 +123,16 @@ static int acrn_irqfd_assign(struct acrn_vm *vm, struct acrn_irqfd *args)
124123
INIT_LIST_HEAD(&irqfd->list);
125124
INIT_WORK(&irqfd->shutdown, hsm_irqfd_shutdown_work);
126125

127-
f = fdget(args->fd);
128-
if (!fd_file(f)) {
126+
CLASS(fd, f)(args->fd);
127+
if (fd_empty(f)) {
129128
ret = -EBADF;
130129
goto out;
131130
}
132131

133132
eventfd = eventfd_ctx_fileget(fd_file(f));
134133
if (IS_ERR(eventfd)) {
135134
ret = PTR_ERR(eventfd);
136-
goto fail;
135+
goto out;
137136
}
138137

139138
irqfd->eventfd = eventfd;
@@ -162,13 +161,9 @@ static int acrn_irqfd_assign(struct acrn_vm *vm, struct acrn_irqfd *args)
162161
if (events & EPOLLIN)
163162
acrn_irqfd_inject(irqfd);
164163

165-
fdput(f);
166164
return 0;
167165
fail:
168-
if (eventfd && !IS_ERR(eventfd))
169-
eventfd_ctx_put(eventfd);
170-
171-
fdput(f);
166+
eventfd_ctx_put(eventfd);
172167
out:
173168
kfree(irqfd);
174169
return ret;

drivers/xen/privcmd.c

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -967,10 +967,11 @@ static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd)
967967
struct privcmd_kernel_irqfd *kirqfd, *tmp;
968968
unsigned long flags;
969969
__poll_t events;
970-
struct fd f;
971970
void *dm_op;
972971
int ret, idx;
973972

973+
CLASS(fd, f)(irqfd->fd);
974+
974975
kirqfd = kzalloc(sizeof(*kirqfd) + irqfd->size, GFP_KERNEL);
975976
if (!kirqfd)
976977
return -ENOMEM;
@@ -986,16 +987,15 @@ static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd)
986987
kirqfd->dom = irqfd->dom;
987988
INIT_WORK(&kirqfd->shutdown, irqfd_shutdown);
988989

989-
f = fdget(irqfd->fd);
990-
if (!fd_file(f)) {
990+
if (fd_empty(f)) {
991991
ret = -EBADF;
992992
goto error_kfree;
993993
}
994994

995995
kirqfd->eventfd = eventfd_ctx_fileget(fd_file(f));
996996
if (IS_ERR(kirqfd->eventfd)) {
997997
ret = PTR_ERR(kirqfd->eventfd);
998-
goto error_fd_put;
998+
goto error_kfree;
999999
}
10001000

10011001
/*
@@ -1028,20 +1028,11 @@ static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd)
10281028
irqfd_inject(kirqfd);
10291029

10301030
srcu_read_unlock(&irqfds_srcu, idx);
1031-
1032-
/*
1033-
* Do not drop the file until the kirqfd is fully initialized, otherwise
1034-
* we might race against the EPOLLHUP.
1035-
*/
1036-
fdput(f);
10371031
return 0;
10381032

10391033
error_eventfd:
10401034
eventfd_ctx_put(kirqfd->eventfd);
10411035

1042-
error_fd_put:
1043-
fdput(f);
1044-
10451036
error_kfree:
10461037
kfree(kirqfd);
10471038
return ret;

virt/kvm/eventfd.c

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,6 @@ static int
304304
kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
305305
{
306306
struct kvm_kernel_irqfd *irqfd, *tmp;
307-
struct fd f;
308307
struct eventfd_ctx *eventfd = NULL, *resamplefd = NULL;
309308
int ret;
310309
__poll_t events;
@@ -327,16 +326,16 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
327326
INIT_WORK(&irqfd->shutdown, irqfd_shutdown);
328327
seqcount_spinlock_init(&irqfd->irq_entry_sc, &kvm->irqfds.lock);
329328

330-
f = fdget(args->fd);
331-
if (!fd_file(f)) {
329+
CLASS(fd, f)(args->fd);
330+
if (fd_empty(f)) {
332331
ret = -EBADF;
333332
goto out;
334333
}
335334

336335
eventfd = eventfd_ctx_fileget(fd_file(f));
337336
if (IS_ERR(eventfd)) {
338337
ret = PTR_ERR(eventfd);
339-
goto fail;
338+
goto out;
340339
}
341340

342341
irqfd->eventfd = eventfd;
@@ -440,12 +439,6 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
440439
#endif
441440

442441
srcu_read_unlock(&kvm->irq_srcu, idx);
443-
444-
/*
445-
* do not drop the file until the irqfd is fully initialized, otherwise
446-
* we might race against the EPOLLHUP
447-
*/
448-
fdput(f);
449442
return 0;
450443

451444
fail:
@@ -458,8 +451,6 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
458451
if (eventfd && !IS_ERR(eventfd))
459452
eventfd_ctx_put(eventfd);
460453

461-
fdput(f);
462-
463454
out:
464455
kfree(irqfd);
465456
return ret;

0 commit comments

Comments
 (0)