| .. | .. |
|---|
| 669 | 669 | } |
|---|
| 670 | 670 | EXPORT_SYMBOL_GPL(vhost_dev_stop); |
|---|
| 671 | 671 | |
|---|
| 672 | | -static void vhost_clear_msg(struct vhost_dev *dev) |
|---|
| 672 | +void vhost_clear_msg(struct vhost_dev *dev) |
|---|
| 673 | 673 | { |
|---|
| 674 | 674 | struct vhost_msg_node *node, *n; |
|---|
| 675 | 675 | |
|---|
| .. | .. |
|---|
| 687 | 687 | |
|---|
| 688 | 688 | spin_unlock(&dev->iotlb_lock); |
|---|
| 689 | 689 | } |
|---|
| 690 | +EXPORT_SYMBOL_GPL(vhost_clear_msg); |
|---|
| 690 | 691 | |
|---|
| 691 | 692 | void vhost_dev_cleanup(struct vhost_dev *dev) |
|---|
| 692 | 693 | { |
|---|
| .. | .. |
|---|
| 1620 | 1621 | r = -EFAULT; |
|---|
| 1621 | 1622 | break; |
|---|
| 1622 | 1623 | } |
|---|
| 1623 | | - if (s.num > 0xffff) { |
|---|
| 1624 | | - r = -EINVAL; |
|---|
| 1625 | | - break; |
|---|
| 1624 | + if (vhost_has_feature(vq, VIRTIO_F_RING_PACKED)) { |
|---|
| 1625 | + vq->last_avail_idx = s.num & 0xffff; |
|---|
| 1626 | + vq->last_used_idx = (s.num >> 16) & 0xffff; |
|---|
| 1627 | + } else { |
|---|
| 1628 | + if (s.num > 0xffff) { |
|---|
| 1629 | + r = -EINVAL; |
|---|
| 1630 | + break; |
|---|
| 1631 | + } |
|---|
| 1632 | + vq->last_avail_idx = s.num; |
|---|
| 1626 | 1633 | } |
|---|
| 1627 | | - vq->last_avail_idx = s.num; |
|---|
| 1628 | 1634 | /* Forget the cached index value. */ |
|---|
| 1629 | 1635 | vq->avail_idx = vq->last_avail_idx; |
|---|
| 1630 | 1636 | break; |
|---|
| 1631 | 1637 | case VHOST_GET_VRING_BASE: |
|---|
| 1632 | 1638 | s.index = idx; |
|---|
| 1633 | | - s.num = vq->last_avail_idx; |
|---|
| 1639 | + if (vhost_has_feature(vq, VIRTIO_F_RING_PACKED)) |
|---|
| 1640 | + s.num = (u32)vq->last_avail_idx | ((u32)vq->last_used_idx << 16); |
|---|
| 1641 | + else |
|---|
| 1642 | + s.num = vq->last_avail_idx; |
|---|
| 1634 | 1643 | if (copy_to_user(argp, &s, sizeof s)) |
|---|
| 1635 | 1644 | r = -EFAULT; |
|---|
| 1636 | 1645 | break; |
|---|
| .. | .. |
|---|
| 2041 | 2050 | struct vhost_dev *dev = vq->dev; |
|---|
| 2042 | 2051 | struct vhost_iotlb *umem = dev->iotlb ? dev->iotlb : dev->umem; |
|---|
| 2043 | 2052 | struct iovec *_iov; |
|---|
| 2044 | | - u64 s = 0; |
|---|
| 2053 | + u64 s = 0, last = addr + len - 1; |
|---|
| 2045 | 2054 | int ret = 0; |
|---|
| 2046 | 2055 | |
|---|
| 2047 | 2056 | while ((u64)len > s) { |
|---|
| .. | .. |
|---|
| 2051 | 2060 | break; |
|---|
| 2052 | 2061 | } |
|---|
| 2053 | 2062 | |
|---|
| 2054 | | - map = vhost_iotlb_itree_first(umem, addr, addr + len - 1); |
|---|
| 2063 | + map = vhost_iotlb_itree_first(umem, addr, last); |
|---|
| 2055 | 2064 | if (map == NULL || map->start > addr) { |
|---|
| 2056 | 2065 | if (umem != dev->iotlb) { |
|---|
| 2057 | 2066 | ret = -EFAULT; |
|---|