diff options
author | Michael S. Tsirkin <mst@redhat.com> | 2010-03-17 10:06:11 -0400 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2010-03-17 17:07:35 -0400 |
commit | 535297a6ae4c3b7a0562e71fac15c213eeec68e7 (patch) | |
tree | 878526e743260b3666e36fb0655c0800a5d21afc /drivers/vhost/vhost.c | |
parent | 0e255572121180c900e24e33b87047abd8153cce (diff) |
vhost: fix error handling in vring ioctls
Stanse found a locking problem in vhost_set_vring:
several returns from VHOST_SET_VRING_KICK, VHOST_SET_VRING_CALL,
VHOST_SET_VRING_ERR with the vq->mutex held.
Fix these up.
Reported-by: Jiri Slaby <jirislaby@gmail.com>
Acked-by: Laurent Chavey <chavey@google.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'drivers/vhost/vhost.c')
-rw-r--r-- | drivers/vhost/vhost.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 7cd55e078794..7bd7a1e4409d 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c | |||
@@ -476,8 +476,10 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp) | |||
476 | if (r < 0) | 476 | if (r < 0) |
477 | break; | 477 | break; |
478 | eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd); | 478 | eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd); |
479 | if (IS_ERR(eventfp)) | 479 | if (IS_ERR(eventfp)) { |
480 | return PTR_ERR(eventfp); | 480 | r = PTR_ERR(eventfp); |
481 | break; | ||
482 | } | ||
481 | if (eventfp != vq->kick) { | 483 | if (eventfp != vq->kick) { |
482 | pollstop = filep = vq->kick; | 484 | pollstop = filep = vq->kick; |
483 | pollstart = vq->kick = eventfp; | 485 | pollstart = vq->kick = eventfp; |
@@ -489,8 +491,10 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp) | |||
489 | if (r < 0) | 491 | if (r < 0) |
490 | break; | 492 | break; |
491 | eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd); | 493 | eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd); |
492 | if (IS_ERR(eventfp)) | 494 | if (IS_ERR(eventfp)) { |
493 | return PTR_ERR(eventfp); | 495 | r = PTR_ERR(eventfp); |
496 | break; | ||
497 | } | ||
494 | if (eventfp != vq->call) { | 498 | if (eventfp != vq->call) { |
495 | filep = vq->call; | 499 | filep = vq->call; |
496 | ctx = vq->call_ctx; | 500 | ctx = vq->call_ctx; |
@@ -505,8 +509,10 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp) | |||
505 | if (r < 0) | 509 | if (r < 0) |
506 | break; | 510 | break; |
507 | eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd); | 511 | eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd); |
508 | if (IS_ERR(eventfp)) | 512 | if (IS_ERR(eventfp)) { |
509 | return PTR_ERR(eventfp); | 513 | r = PTR_ERR(eventfp); |
514 | break; | ||
515 | } | ||
510 | if (eventfp != vq->error) { | 516 | if (eventfp != vq->error) { |
511 | filep = vq->error; | 517 | filep = vq->error; |
512 | vq->error = eventfp; | 518 | vq->error = eventfp; |