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); |