diff options
| author | Jason Wang <jasowang@redhat.com> | 2016-06-23 02:04:30 -0400 |
|---|---|---|
| committer | Michael S. Tsirkin <mst@redhat.com> | 2016-08-01 19:57:30 -0400 |
| commit | bfe2bc512884d0b1c5297a15350f940ca80e439b (patch) | |
| tree | 7074f1f1e398f71944b9fc0d954fe63a09e810af /drivers/vhost | |
| parent | 304ba62fd4e670c1a5784585da0fac9f7309ef6c (diff) | |
vhost: introduce vhost memory accessors
This patch introduces vhost memory accessors which were just wrappers
for userspace address access helpers. This is a requirement for vhost
device iotlb implementation which will add iotlb translations in those
accessors.
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'drivers/vhost')
| -rw-r--r-- | drivers/vhost/vhost.c | 50 |
1 files changed, 35 insertions, 15 deletions
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 0061a7bd85f6..e1b5047d8f19 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c | |||
| @@ -638,6 +638,22 @@ static int memory_access_ok(struct vhost_dev *d, struct vhost_memory *mem, | |||
| 638 | return 1; | 638 | return 1; |
| 639 | } | 639 | } |
| 640 | 640 | ||
| 641 | #define vhost_put_user(vq, x, ptr) __put_user(x, ptr) | ||
| 642 | |||
| 643 | static int vhost_copy_to_user(struct vhost_virtqueue *vq, void *to, | ||
| 644 | const void *from, unsigned size) | ||
| 645 | { | ||
| 646 | return __copy_to_user(to, from, size); | ||
| 647 | } | ||
| 648 | |||
| 649 | #define vhost_get_user(vq, x, ptr) __get_user(x, ptr) | ||
| 650 | |||
| 651 | static int vhost_copy_from_user(struct vhost_virtqueue *vq, void *to, | ||
| 652 | void *from, unsigned size) | ||
| 653 | { | ||
| 654 | return __copy_from_user(to, from, size); | ||
| 655 | } | ||
| 656 | |||
| 641 | static int vq_access_ok(struct vhost_virtqueue *vq, unsigned int num, | 657 | static int vq_access_ok(struct vhost_virtqueue *vq, unsigned int num, |
| 642 | struct vring_desc __user *desc, | 658 | struct vring_desc __user *desc, |
| 643 | struct vring_avail __user *avail, | 659 | struct vring_avail __user *avail, |
| @@ -1143,7 +1159,8 @@ EXPORT_SYMBOL_GPL(vhost_log_write); | |||
| 1143 | static int vhost_update_used_flags(struct vhost_virtqueue *vq) | 1159 | static int vhost_update_used_flags(struct vhost_virtqueue *vq) |
| 1144 | { | 1160 | { |
| 1145 | void __user *used; | 1161 | void __user *used; |
| 1146 | if (__put_user(cpu_to_vhost16(vq, vq->used_flags), &vq->used->flags) < 0) | 1162 | if (vhost_put_user(vq, cpu_to_vhost16(vq, vq->used_flags), |
| 1163 | &vq->used->flags) < 0) | ||
| 1147 | return -EFAULT; | 1164 | return -EFAULT; |
| 1148 | if (unlikely(vq->log_used)) { | 1165 | if (unlikely(vq->log_used)) { |
| 1149 | /* Make sure the flag is seen before log. */ | 1166 | /* Make sure the flag is seen before log. */ |
| @@ -1161,7 +1178,8 @@ static int vhost_update_used_flags(struct vhost_virtqueue *vq) | |||
| 1161 | 1178 | ||
| 1162 | static int vhost_update_avail_event(struct vhost_virtqueue *vq, u16 avail_event) | 1179 | static int vhost_update_avail_event(struct vhost_virtqueue *vq, u16 avail_event) |
| 1163 | { | 1180 | { |
| 1164 | if (__put_user(cpu_to_vhost16(vq, vq->avail_idx), vhost_avail_event(vq))) | 1181 | if (vhost_put_user(vq, cpu_to_vhost16(vq, vq->avail_idx), |
| 1182 | vhost_avail_event(vq))) | ||
| 1165 | return -EFAULT; | 1183 | return -EFAULT; |
| 1166 | if (unlikely(vq->log_used)) { | 1184 | if (unlikely(vq->log_used)) { |
| 1167 | void __user *used; | 1185 | void __user *used; |
| @@ -1199,7 +1217,7 @@ int vhost_vq_init_access(struct vhost_virtqueue *vq) | |||
| 1199 | r = -EFAULT; | 1217 | r = -EFAULT; |
| 1200 | goto err; | 1218 | goto err; |
| 1201 | } | 1219 | } |
| 1202 | r = __get_user(last_used_idx, &vq->used->idx); | 1220 | r = vhost_get_user(vq, last_used_idx, &vq->used->idx); |
| 1203 | if (r) | 1221 | if (r) |
| 1204 | goto err; | 1222 | goto err; |
| 1205 | vq->last_used_idx = vhost16_to_cpu(vq, last_used_idx); | 1223 | vq->last_used_idx = vhost16_to_cpu(vq, last_used_idx); |
| @@ -1379,7 +1397,7 @@ int vhost_get_vq_desc(struct vhost_virtqueue *vq, | |||
| 1379 | 1397 | ||
| 1380 | /* Check it isn't doing very strange things with descriptor numbers. */ | 1398 | /* Check it isn't doing very strange things with descriptor numbers. */ |
| 1381 | last_avail_idx = vq->last_avail_idx; | 1399 | last_avail_idx = vq->last_avail_idx; |
| 1382 | if (unlikely(__get_user(avail_idx, &vq->avail->idx))) { | 1400 | if (unlikely(vhost_get_user(vq, avail_idx, &vq->avail->idx))) { |
| 1383 | vq_err(vq, "Failed to access avail idx at %p\n", | 1401 | vq_err(vq, "Failed to access avail idx at %p\n", |
| 1384 | &vq->avail->idx); | 1402 | &vq->avail->idx); |
| 1385 | return -EFAULT; | 1403 | return -EFAULT; |
| @@ -1401,8 +1419,8 @@ int vhost_get_vq_desc(struct vhost_virtqueue *vq, | |||
| 1401 | 1419 | ||
| 1402 | /* Grab the next descriptor number they're advertising, and increment | 1420 | /* Grab the next descriptor number they're advertising, and increment |
| 1403 | * the index we've seen. */ | 1421 | * the index we've seen. */ |
| 1404 | if (unlikely(__get_user(ring_head, | 1422 | if (unlikely(vhost_get_user(vq, ring_head, |
| 1405 | &vq->avail->ring[last_avail_idx & (vq->num - 1)]))) { | 1423 | &vq->avail->ring[last_avail_idx & (vq->num - 1)]))) { |
| 1406 | vq_err(vq, "Failed to read head: idx %d address %p\n", | 1424 | vq_err(vq, "Failed to read head: idx %d address %p\n", |
| 1407 | last_avail_idx, | 1425 | last_avail_idx, |
| 1408 | &vq->avail->ring[last_avail_idx % vq->num]); | 1426 | &vq->avail->ring[last_avail_idx % vq->num]); |
| @@ -1437,7 +1455,8 @@ int vhost_get_vq_desc(struct vhost_virtqueue *vq, | |||
| 1437 | i, vq->num, head); | 1455 | i, vq->num, head); |
| 1438 | return -EINVAL; | 1456 | return -EINVAL; |
| 1439 | } | 1457 | } |
| 1440 | ret = __copy_from_user(&desc, vq->desc + i, sizeof desc); | 1458 | ret = vhost_copy_from_user(vq, &desc, vq->desc + i, |
| 1459 | sizeof desc); | ||
| 1441 | if (unlikely(ret)) { | 1460 | if (unlikely(ret)) { |
| 1442 | vq_err(vq, "Failed to get descriptor: idx %d addr %p\n", | 1461 | vq_err(vq, "Failed to get descriptor: idx %d addr %p\n", |
| 1443 | i, vq->desc + i); | 1462 | i, vq->desc + i); |
| @@ -1525,15 +1544,15 @@ static int __vhost_add_used_n(struct vhost_virtqueue *vq, | |||
| 1525 | start = vq->last_used_idx & (vq->num - 1); | 1544 | start = vq->last_used_idx & (vq->num - 1); |
| 1526 | used = vq->used->ring + start; | 1545 | used = vq->used->ring + start; |
| 1527 | if (count == 1) { | 1546 | if (count == 1) { |
| 1528 | if (__put_user(heads[0].id, &used->id)) { | 1547 | if (vhost_put_user(vq, heads[0].id, &used->id)) { |
| 1529 | vq_err(vq, "Failed to write used id"); | 1548 | vq_err(vq, "Failed to write used id"); |
| 1530 | return -EFAULT; | 1549 | return -EFAULT; |
| 1531 | } | 1550 | } |
| 1532 | if (__put_user(heads[0].len, &used->len)) { | 1551 | if (vhost_put_user(vq, heads[0].len, &used->len)) { |
| 1533 | vq_err(vq, "Failed to write used len"); | 1552 | vq_err(vq, "Failed to write used len"); |
| 1534 | return -EFAULT; | 1553 | return -EFAULT; |
| 1535 | } | 1554 | } |
| 1536 | } else if (__copy_to_user(used, heads, count * sizeof *used)) { | 1555 | } else if (vhost_copy_to_user(vq, used, heads, count * sizeof *used)) { |
| 1537 | vq_err(vq, "Failed to write used"); | 1556 | vq_err(vq, "Failed to write used"); |
| 1538 | return -EFAULT; | 1557 | return -EFAULT; |
| 1539 | } | 1558 | } |
| @@ -1577,7 +1596,8 @@ int vhost_add_used_n(struct vhost_virtqueue *vq, struct vring_used_elem *heads, | |||
| 1577 | 1596 | ||
| 1578 | /* Make sure buffer is written before we update index. */ | 1597 | /* Make sure buffer is written before we update index. */ |
| 1579 | smp_wmb(); | 1598 | smp_wmb(); |
| 1580 | if (__put_user(cpu_to_vhost16(vq, vq->last_used_idx), &vq->used->idx)) { | 1599 | if (vhost_put_user(vq, cpu_to_vhost16(vq, vq->last_used_idx), |
| 1600 | &vq->used->idx)) { | ||
| 1581 | vq_err(vq, "Failed to increment used idx"); | 1601 | vq_err(vq, "Failed to increment used idx"); |
| 1582 | return -EFAULT; | 1602 | return -EFAULT; |
| 1583 | } | 1603 | } |
| @@ -1609,7 +1629,7 @@ static bool vhost_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq) | |||
| 1609 | 1629 | ||
| 1610 | if (!vhost_has_feature(vq, VIRTIO_RING_F_EVENT_IDX)) { | 1630 | if (!vhost_has_feature(vq, VIRTIO_RING_F_EVENT_IDX)) { |
| 1611 | __virtio16 flags; | 1631 | __virtio16 flags; |
| 1612 | if (__get_user(flags, &vq->avail->flags)) { | 1632 | if (vhost_get_user(vq, flags, &vq->avail->flags)) { |
| 1613 | vq_err(vq, "Failed to get flags"); | 1633 | vq_err(vq, "Failed to get flags"); |
| 1614 | return true; | 1634 | return true; |
| 1615 | } | 1635 | } |
| @@ -1623,7 +1643,7 @@ static bool vhost_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq) | |||
| 1623 | if (unlikely(!v)) | 1643 | if (unlikely(!v)) |
| 1624 | return true; | 1644 | return true; |
| 1625 | 1645 | ||
| 1626 | if (__get_user(event, vhost_used_event(vq))) { | 1646 | if (vhost_get_user(vq, event, vhost_used_event(vq))) { |
| 1627 | vq_err(vq, "Failed to get used event idx"); | 1647 | vq_err(vq, "Failed to get used event idx"); |
| 1628 | return true; | 1648 | return true; |
| 1629 | } | 1649 | } |
| @@ -1665,7 +1685,7 @@ bool vhost_vq_avail_empty(struct vhost_dev *dev, struct vhost_virtqueue *vq) | |||
| 1665 | __virtio16 avail_idx; | 1685 | __virtio16 avail_idx; |
| 1666 | int r; | 1686 | int r; |
| 1667 | 1687 | ||
| 1668 | r = __get_user(avail_idx, &vq->avail->idx); | 1688 | r = vhost_get_user(vq, avail_idx, &vq->avail->idx); |
| 1669 | if (r) | 1689 | if (r) |
| 1670 | return false; | 1690 | return false; |
| 1671 | 1691 | ||
| @@ -1700,7 +1720,7 @@ bool vhost_enable_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq) | |||
| 1700 | /* They could have slipped one in as we were doing that: make | 1720 | /* They could have slipped one in as we were doing that: make |
| 1701 | * sure it's written, then check again. */ | 1721 | * sure it's written, then check again. */ |
| 1702 | smp_mb(); | 1722 | smp_mb(); |
| 1703 | r = __get_user(avail_idx, &vq->avail->idx); | 1723 | r = vhost_get_user(vq, avail_idx, &vq->avail->idx); |
| 1704 | if (r) { | 1724 | if (r) { |
| 1705 | vq_err(vq, "Failed to check avail idx at %p: %d\n", | 1725 | vq_err(vq, "Failed to check avail idx at %p: %d\n", |
| 1706 | &vq->avail->idx, r); | 1726 | &vq->avail->idx, r); |
