diff options
author | Michael S. Tsirkin <mst@redhat.com> | 2014-12-01 10:39:39 -0500 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2014-12-09 05:05:29 -0500 |
commit | 64f7f0510c7e6f61eab080e3f51d314849f47ac1 (patch) | |
tree | a439f647cb9e2a8737deacdd80752b743e432d7e /drivers/vhost/vhost.c | |
parent | bf995734969c3ca9de9e00138151201eab4cbb01 (diff) |
vhost: switch to __get/__put_user exclusively
Most places in vhost can use __get/__put_user rather than
get/put_user since addresses are pre-validated.
This should be good for performance, but this also
will help make code sparse-clean: get/put_user macros
don't play well with __virtioXX bitwise tags.
Switch to get/put_user to __ variants everywhere in vhost.
There's one exception - for consistency switch that
as well, and add an explicit access_ok check.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'drivers/vhost/vhost.c')
-rw-r--r-- | drivers/vhost/vhost.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index c90f4374442a..6a408377598a 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c | |||
@@ -1038,6 +1038,7 @@ static int vhost_update_avail_event(struct vhost_virtqueue *vq, u16 avail_event) | |||
1038 | 1038 | ||
1039 | int vhost_init_used(struct vhost_virtqueue *vq) | 1039 | int vhost_init_used(struct vhost_virtqueue *vq) |
1040 | { | 1040 | { |
1041 | u16 last_used_idx; | ||
1041 | int r; | 1042 | int r; |
1042 | if (!vq->private_data) | 1043 | if (!vq->private_data) |
1043 | return 0; | 1044 | return 0; |
@@ -1046,7 +1047,13 @@ int vhost_init_used(struct vhost_virtqueue *vq) | |||
1046 | if (r) | 1047 | if (r) |
1047 | return r; | 1048 | return r; |
1048 | vq->signalled_used_valid = false; | 1049 | vq->signalled_used_valid = false; |
1049 | return get_user(vq->last_used_idx, &vq->used->idx); | 1050 | if (!access_ok(VERIFY_READ, &vq->used->idx, sizeof vq->used->idx)) |
1051 | return -EFAULT; | ||
1052 | r = __get_user(last_used_idx, &vq->used->idx); | ||
1053 | if (r) | ||
1054 | return r; | ||
1055 | vq->last_used_idx = last_used_idx; | ||
1056 | return 0; | ||
1050 | } | 1057 | } |
1051 | EXPORT_SYMBOL_GPL(vhost_init_used); | 1058 | EXPORT_SYMBOL_GPL(vhost_init_used); |
1052 | 1059 | ||
@@ -1404,7 +1411,7 @@ int vhost_add_used_n(struct vhost_virtqueue *vq, struct vring_used_elem *heads, | |||
1404 | 1411 | ||
1405 | /* Make sure buffer is written before we update index. */ | 1412 | /* Make sure buffer is written before we update index. */ |
1406 | smp_wmb(); | 1413 | smp_wmb(); |
1407 | if (put_user(vq->last_used_idx, &vq->used->idx)) { | 1414 | if (__put_user(vq->last_used_idx, &vq->used->idx)) { |
1408 | vq_err(vq, "Failed to increment used idx"); | 1415 | vq_err(vq, "Failed to increment used idx"); |
1409 | return -EFAULT; | 1416 | return -EFAULT; |
1410 | } | 1417 | } |
@@ -1449,7 +1456,7 @@ static bool vhost_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq) | |||
1449 | if (unlikely(!v)) | 1456 | if (unlikely(!v)) |
1450 | return true; | 1457 | return true; |
1451 | 1458 | ||
1452 | if (get_user(event, vhost_used_event(vq))) { | 1459 | if (__get_user(event, vhost_used_event(vq))) { |
1453 | vq_err(vq, "Failed to get used event idx"); | 1460 | vq_err(vq, "Failed to get used event idx"); |
1454 | return true; | 1461 | return true; |
1455 | } | 1462 | } |