aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-12-07 13:50:07 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-12-07 13:50:07 -0500
commit62ea1ec5e17fe36e2c728bc534f9f78b216dfe83 (patch)
tree7d398881db98f2c2b28f45ba595688db6bbe602b
parentf41683a204ea61568f0fd0804d47c19561f2ee39 (diff)
parentf277ec42f38f406ed073569b24b04f1c291fec0f (diff)
Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
Pull virtio fixes from Michael Tsirkin: "This includes some fixes and cleanups in virtio and vhost code. Most notably, shadowing the index fixes the excessive cacheline bouncing observed on AMD platforms" * tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost: virtio_ring: shadow available ring flags & index virtio: Do not drop __GFP_HIGH in alloc_indirect vhost: replace % with & on data path tools/virtio: fix byteswap logic tools/virtio: move list macro stubs virtio: fix memory leak of virtio ida cache layers vhost: relax log address alignment virtio-net: Stop doing DMA from the stack
-rw-r--r--drivers/net/virtio_net.c34
-rw-r--r--drivers/vhost/vhost.c8
-rw-r--r--drivers/virtio/virtio.c1
-rw-r--r--drivers/virtio/virtio_ring.c48
-rw-r--r--tools/virtio/linux/kernel.h6
-rw-r--r--tools/virtio/linux/virtio.h6
-rw-r--r--tools/virtio/linux/virtio_config.h20
7 files changed, 78 insertions, 45 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index d8838dedb7a4..f94ab786088f 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -140,6 +140,12 @@ struct virtnet_info {
140 140
141 /* CPU hot plug notifier */ 141 /* CPU hot plug notifier */
142 struct notifier_block nb; 142 struct notifier_block nb;
143
144 /* Control VQ buffers: protected by the rtnl lock */
145 struct virtio_net_ctrl_hdr ctrl_hdr;
146 virtio_net_ctrl_ack ctrl_status;
147 u8 ctrl_promisc;
148 u8 ctrl_allmulti;
143}; 149};
144 150
145struct padded_vnet_hdr { 151struct padded_vnet_hdr {
@@ -976,31 +982,30 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd,
976 struct scatterlist *out) 982 struct scatterlist *out)
977{ 983{
978 struct scatterlist *sgs[4], hdr, stat; 984 struct scatterlist *sgs[4], hdr, stat;
979 struct virtio_net_ctrl_hdr ctrl;
980 virtio_net_ctrl_ack status = ~0;
981 unsigned out_num = 0, tmp; 985 unsigned out_num = 0, tmp;
982 986
983 /* Caller should know better */ 987 /* Caller should know better */
984 BUG_ON(!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ)); 988 BUG_ON(!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ));
985 989
986 ctrl.class = class; 990 vi->ctrl_status = ~0;
987 ctrl.cmd = cmd; 991 vi->ctrl_hdr.class = class;
992 vi->ctrl_hdr.cmd = cmd;
988 /* Add header */ 993 /* Add header */
989 sg_init_one(&hdr, &ctrl, sizeof(ctrl)); 994 sg_init_one(&hdr, &vi->ctrl_hdr, sizeof(vi->ctrl_hdr));
990 sgs[out_num++] = &hdr; 995 sgs[out_num++] = &hdr;
991 996
992 if (out) 997 if (out)
993 sgs[out_num++] = out; 998 sgs[out_num++] = out;
994 999
995 /* Add return status. */ 1000 /* Add return status. */
996 sg_init_one(&stat, &status, sizeof(status)); 1001 sg_init_one(&stat, &vi->ctrl_status, sizeof(vi->ctrl_status));
997 sgs[out_num] = &stat; 1002 sgs[out_num] = &stat;
998 1003
999 BUG_ON(out_num + 1 > ARRAY_SIZE(sgs)); 1004 BUG_ON(out_num + 1 > ARRAY_SIZE(sgs));
1000 virtqueue_add_sgs(vi->cvq, sgs, out_num, 1, vi, GFP_ATOMIC); 1005 virtqueue_add_sgs(vi->cvq, sgs, out_num, 1, vi, GFP_ATOMIC);
1001 1006
1002 if (unlikely(!virtqueue_kick(vi->cvq))) 1007 if (unlikely(!virtqueue_kick(vi->cvq)))
1003 return status == VIRTIO_NET_OK; 1008 return vi->ctrl_status == VIRTIO_NET_OK;
1004 1009
1005 /* Spin for a response, the kick causes an ioport write, trapping 1010 /* Spin for a response, the kick causes an ioport write, trapping
1006 * into the hypervisor, so the request should be handled immediately. 1011 * into the hypervisor, so the request should be handled immediately.
@@ -1009,7 +1014,7 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd,
1009 !virtqueue_is_broken(vi->cvq)) 1014 !virtqueue_is_broken(vi->cvq))
1010 cpu_relax(); 1015 cpu_relax();
1011 1016
1012 return status == VIRTIO_NET_OK; 1017 return vi->ctrl_status == VIRTIO_NET_OK;
1013} 1018}
1014 1019
1015static int virtnet_set_mac_address(struct net_device *dev, void *p) 1020static int virtnet_set_mac_address(struct net_device *dev, void *p)
@@ -1151,7 +1156,6 @@ static void virtnet_set_rx_mode(struct net_device *dev)
1151{ 1156{
1152 struct virtnet_info *vi = netdev_priv(dev); 1157 struct virtnet_info *vi = netdev_priv(dev);
1153 struct scatterlist sg[2]; 1158 struct scatterlist sg[2];
1154 u8 promisc, allmulti;
1155 struct virtio_net_ctrl_mac *mac_data; 1159 struct virtio_net_ctrl_mac *mac_data;
1156 struct netdev_hw_addr *ha; 1160 struct netdev_hw_addr *ha;
1157 int uc_count; 1161 int uc_count;
@@ -1163,22 +1167,22 @@ static void virtnet_set_rx_mode(struct net_device *dev)
1163 if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_RX)) 1167 if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_RX))
1164 return; 1168 return;
1165 1169
1166 promisc = ((dev->flags & IFF_PROMISC) != 0); 1170 vi->ctrl_promisc = ((dev->flags & IFF_PROMISC) != 0);
1167 allmulti = ((dev->flags & IFF_ALLMULTI) != 0); 1171 vi->ctrl_allmulti = ((dev->flags & IFF_ALLMULTI) != 0);
1168 1172
1169 sg_init_one(sg, &promisc, sizeof(promisc)); 1173 sg_init_one(sg, &vi->ctrl_promisc, sizeof(vi->ctrl_promisc));
1170 1174
1171 if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX, 1175 if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX,
1172 VIRTIO_NET_CTRL_RX_PROMISC, sg)) 1176 VIRTIO_NET_CTRL_RX_PROMISC, sg))
1173 dev_warn(&dev->dev, "Failed to %sable promisc mode.\n", 1177 dev_warn(&dev->dev, "Failed to %sable promisc mode.\n",
1174 promisc ? "en" : "dis"); 1178 vi->ctrl_promisc ? "en" : "dis");
1175 1179
1176 sg_init_one(sg, &allmulti, sizeof(allmulti)); 1180 sg_init_one(sg, &vi->ctrl_allmulti, sizeof(vi->ctrl_allmulti));
1177 1181
1178 if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX, 1182 if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX,
1179 VIRTIO_NET_CTRL_RX_ALLMULTI, sg)) 1183 VIRTIO_NET_CTRL_RX_ALLMULTI, sg))
1180 dev_warn(&dev->dev, "Failed to %sable allmulti mode.\n", 1184 dev_warn(&dev->dev, "Failed to %sable allmulti mode.\n",
1181 allmulti ? "en" : "dis"); 1185 vi->ctrl_allmulti ? "en" : "dis");
1182 1186
1183 uc_count = netdev_uc_count(dev); 1187 uc_count = netdev_uc_count(dev);
1184 mc_count = netdev_mc_count(dev); 1188 mc_count = netdev_mc_count(dev);
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index eec2f11809ff..ad2146a9ab2d 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -819,7 +819,7 @@ long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp)
819 BUILD_BUG_ON(__alignof__ *vq->used > VRING_USED_ALIGN_SIZE); 819 BUILD_BUG_ON(__alignof__ *vq->used > VRING_USED_ALIGN_SIZE);
820 if ((a.avail_user_addr & (VRING_AVAIL_ALIGN_SIZE - 1)) || 820 if ((a.avail_user_addr & (VRING_AVAIL_ALIGN_SIZE - 1)) ||
821 (a.used_user_addr & (VRING_USED_ALIGN_SIZE - 1)) || 821 (a.used_user_addr & (VRING_USED_ALIGN_SIZE - 1)) ||
822 (a.log_guest_addr & (sizeof(u64) - 1))) { 822 (a.log_guest_addr & (VRING_USED_ALIGN_SIZE - 1))) {
823 r = -EINVAL; 823 r = -EINVAL;
824 break; 824 break;
825 } 825 }
@@ -1369,7 +1369,7 @@ int vhost_get_vq_desc(struct vhost_virtqueue *vq,
1369 /* Grab the next descriptor number they're advertising, and increment 1369 /* Grab the next descriptor number they're advertising, and increment
1370 * the index we've seen. */ 1370 * the index we've seen. */
1371 if (unlikely(__get_user(ring_head, 1371 if (unlikely(__get_user(ring_head,
1372 &vq->avail->ring[last_avail_idx % vq->num]))) { 1372 &vq->avail->ring[last_avail_idx & (vq->num - 1)]))) {
1373 vq_err(vq, "Failed to read head: idx %d address %p\n", 1373 vq_err(vq, "Failed to read head: idx %d address %p\n",
1374 last_avail_idx, 1374 last_avail_idx,
1375 &vq->avail->ring[last_avail_idx % vq->num]); 1375 &vq->avail->ring[last_avail_idx % vq->num]);
@@ -1489,7 +1489,7 @@ static int __vhost_add_used_n(struct vhost_virtqueue *vq,
1489 u16 old, new; 1489 u16 old, new;
1490 int start; 1490 int start;
1491 1491
1492 start = vq->last_used_idx % vq->num; 1492 start = vq->last_used_idx & (vq->num - 1);
1493 used = vq->used->ring + start; 1493 used = vq->used->ring + start;
1494 if (count == 1) { 1494 if (count == 1) {
1495 if (__put_user(heads[0].id, &used->id)) { 1495 if (__put_user(heads[0].id, &used->id)) {
@@ -1531,7 +1531,7 @@ int vhost_add_used_n(struct vhost_virtqueue *vq, struct vring_used_elem *heads,
1531{ 1531{
1532 int start, n, r; 1532 int start, n, r;
1533 1533
1534 start = vq->last_used_idx % vq->num; 1534 start = vq->last_used_idx & (vq->num - 1);
1535 n = vq->num - start; 1535 n = vq->num - start;
1536 if (n < count) { 1536 if (n < count) {
1537 r = __vhost_add_used_n(vq, heads, n); 1537 r = __vhost_add_used_n(vq, heads, n);
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index b1877d73fa56..7062bb0975a5 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -412,6 +412,7 @@ static int virtio_init(void)
412static void __exit virtio_exit(void) 412static void __exit virtio_exit(void)
413{ 413{
414 bus_unregister(&virtio_bus); 414 bus_unregister(&virtio_bus);
415 ida_destroy(&virtio_index_ida);
415} 416}
416core_initcall(virtio_init); 417core_initcall(virtio_init);
417module_exit(virtio_exit); 418module_exit(virtio_exit);
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 096b857e7b75..ee663c458b20 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -80,6 +80,12 @@ struct vring_virtqueue {
80 /* Last used index we've seen. */ 80 /* Last used index we've seen. */
81 u16 last_used_idx; 81 u16 last_used_idx;
82 82
83 /* Last written value to avail->flags */
84 u16 avail_flags_shadow;
85
86 /* Last written value to avail->idx in guest byte order */
87 u16 avail_idx_shadow;
88
83 /* How to notify other side. FIXME: commonalize hcalls! */ 89 /* How to notify other side. FIXME: commonalize hcalls! */
84 bool (*notify)(struct virtqueue *vq); 90 bool (*notify)(struct virtqueue *vq);
85 91
@@ -109,7 +115,7 @@ static struct vring_desc *alloc_indirect(struct virtqueue *_vq,
109 * otherwise virt_to_phys will give us bogus addresses in the 115 * otherwise virt_to_phys will give us bogus addresses in the
110 * virtqueue. 116 * virtqueue.
111 */ 117 */
112 gfp &= ~(__GFP_HIGHMEM | __GFP_HIGH); 118 gfp &= ~__GFP_HIGHMEM;
113 119
114 desc = kmalloc(total_sg * sizeof(struct vring_desc), gfp); 120 desc = kmalloc(total_sg * sizeof(struct vring_desc), gfp);
115 if (!desc) 121 if (!desc)
@@ -235,13 +241,14 @@ static inline int virtqueue_add(struct virtqueue *_vq,
235 241
236 /* Put entry in available array (but don't update avail->idx until they 242 /* Put entry in available array (but don't update avail->idx until they
237 * do sync). */ 243 * do sync). */
238 avail = virtio16_to_cpu(_vq->vdev, vq->vring.avail->idx) & (vq->vring.num - 1); 244 avail = vq->avail_idx_shadow & (vq->vring.num - 1);
239 vq->vring.avail->ring[avail] = cpu_to_virtio16(_vq->vdev, head); 245 vq->vring.avail->ring[avail] = cpu_to_virtio16(_vq->vdev, head);
240 246
241 /* Descriptors and available array need to be set before we expose the 247 /* Descriptors and available array need to be set before we expose the
242 * new available array entries. */ 248 * new available array entries. */
243 virtio_wmb(vq->weak_barriers); 249 virtio_wmb(vq->weak_barriers);
244 vq->vring.avail->idx = cpu_to_virtio16(_vq->vdev, virtio16_to_cpu(_vq->vdev, vq->vring.avail->idx) + 1); 250 vq->avail_idx_shadow++;
251 vq->vring.avail->idx = cpu_to_virtio16(_vq->vdev, vq->avail_idx_shadow);
245 vq->num_added++; 252 vq->num_added++;
246 253
247 pr_debug("Added buffer head %i to %p\n", head, vq); 254 pr_debug("Added buffer head %i to %p\n", head, vq);
@@ -354,8 +361,8 @@ bool virtqueue_kick_prepare(struct virtqueue *_vq)
354 * event. */ 361 * event. */
355 virtio_mb(vq->weak_barriers); 362 virtio_mb(vq->weak_barriers);
356 363
357 old = virtio16_to_cpu(_vq->vdev, vq->vring.avail->idx) - vq->num_added; 364 old = vq->avail_idx_shadow - vq->num_added;
358 new = virtio16_to_cpu(_vq->vdev, vq->vring.avail->idx); 365 new = vq->avail_idx_shadow;
359 vq->num_added = 0; 366 vq->num_added = 0;
360 367
361#ifdef DEBUG 368#ifdef DEBUG
@@ -510,7 +517,7 @@ void *virtqueue_get_buf(struct virtqueue *_vq, unsigned int *len)
510 /* If we expect an interrupt for the next entry, tell host 517 /* If we expect an interrupt for the next entry, tell host
511 * by writing event index and flush out the write before 518 * by writing event index and flush out the write before
512 * the read in the next get_buf call. */ 519 * the read in the next get_buf call. */
513 if (!(vq->vring.avail->flags & cpu_to_virtio16(_vq->vdev, VRING_AVAIL_F_NO_INTERRUPT))) { 520 if (!(vq->avail_flags_shadow & VRING_AVAIL_F_NO_INTERRUPT)) {
514 vring_used_event(&vq->vring) = cpu_to_virtio16(_vq->vdev, vq->last_used_idx); 521 vring_used_event(&vq->vring) = cpu_to_virtio16(_vq->vdev, vq->last_used_idx);
515 virtio_mb(vq->weak_barriers); 522 virtio_mb(vq->weak_barriers);
516 } 523 }
@@ -537,7 +544,11 @@ void virtqueue_disable_cb(struct virtqueue *_vq)
537{ 544{
538 struct vring_virtqueue *vq = to_vvq(_vq); 545 struct vring_virtqueue *vq = to_vvq(_vq);
539 546
540 vq->vring.avail->flags |= cpu_to_virtio16(_vq->vdev, VRING_AVAIL_F_NO_INTERRUPT); 547 if (!(vq->avail_flags_shadow & VRING_AVAIL_F_NO_INTERRUPT)) {
548 vq->avail_flags_shadow |= VRING_AVAIL_F_NO_INTERRUPT;
549 vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow);
550 }
551
541} 552}
542EXPORT_SYMBOL_GPL(virtqueue_disable_cb); 553EXPORT_SYMBOL_GPL(virtqueue_disable_cb);
543 554
@@ -565,7 +576,10 @@ unsigned virtqueue_enable_cb_prepare(struct virtqueue *_vq)
565 /* Depending on the VIRTIO_RING_F_EVENT_IDX feature, we need to 576 /* Depending on the VIRTIO_RING_F_EVENT_IDX feature, we need to
566 * either clear the flags bit or point the event index at the next 577 * either clear the flags bit or point the event index at the next
567 * entry. Always do both to keep code simple. */ 578 * entry. Always do both to keep code simple. */
568 vq->vring.avail->flags &= cpu_to_virtio16(_vq->vdev, ~VRING_AVAIL_F_NO_INTERRUPT); 579 if (vq->avail_flags_shadow & VRING_AVAIL_F_NO_INTERRUPT) {
580 vq->avail_flags_shadow &= ~VRING_AVAIL_F_NO_INTERRUPT;
581 vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow);
582 }
569 vring_used_event(&vq->vring) = cpu_to_virtio16(_vq->vdev, last_used_idx = vq->last_used_idx); 583 vring_used_event(&vq->vring) = cpu_to_virtio16(_vq->vdev, last_used_idx = vq->last_used_idx);
570 END_USE(vq); 584 END_USE(vq);
571 return last_used_idx; 585 return last_used_idx;
@@ -633,9 +647,12 @@ bool virtqueue_enable_cb_delayed(struct virtqueue *_vq)
633 /* Depending on the VIRTIO_RING_F_USED_EVENT_IDX feature, we need to 647 /* Depending on the VIRTIO_RING_F_USED_EVENT_IDX feature, we need to
634 * either clear the flags bit or point the event index at the next 648 * either clear the flags bit or point the event index at the next
635 * entry. Always do both to keep code simple. */ 649 * entry. Always do both to keep code simple. */
636 vq->vring.avail->flags &= cpu_to_virtio16(_vq->vdev, ~VRING_AVAIL_F_NO_INTERRUPT); 650 if (vq->avail_flags_shadow & VRING_AVAIL_F_NO_INTERRUPT) {
651 vq->avail_flags_shadow &= ~VRING_AVAIL_F_NO_INTERRUPT;
652 vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow);
653 }
637 /* TODO: tune this threshold */ 654 /* TODO: tune this threshold */
638 bufs = (u16)(virtio16_to_cpu(_vq->vdev, vq->vring.avail->idx) - vq->last_used_idx) * 3 / 4; 655 bufs = (u16)(vq->avail_idx_shadow - vq->last_used_idx) * 3 / 4;
639 vring_used_event(&vq->vring) = cpu_to_virtio16(_vq->vdev, vq->last_used_idx + bufs); 656 vring_used_event(&vq->vring) = cpu_to_virtio16(_vq->vdev, vq->last_used_idx + bufs);
640 virtio_mb(vq->weak_barriers); 657 virtio_mb(vq->weak_barriers);
641 if (unlikely((u16)(virtio16_to_cpu(_vq->vdev, vq->vring.used->idx) - vq->last_used_idx) > bufs)) { 658 if (unlikely((u16)(virtio16_to_cpu(_vq->vdev, vq->vring.used->idx) - vq->last_used_idx) > bufs)) {
@@ -670,7 +687,8 @@ void *virtqueue_detach_unused_buf(struct virtqueue *_vq)
670 /* detach_buf clears data, so grab it now. */ 687 /* detach_buf clears data, so grab it now. */
671 buf = vq->data[i]; 688 buf = vq->data[i];
672 detach_buf(vq, i); 689 detach_buf(vq, i);
673 vq->vring.avail->idx = cpu_to_virtio16(_vq->vdev, virtio16_to_cpu(_vq->vdev, vq->vring.avail->idx) - 1); 690 vq->avail_idx_shadow--;
691 vq->vring.avail->idx = cpu_to_virtio16(_vq->vdev, vq->avail_idx_shadow);
674 END_USE(vq); 692 END_USE(vq);
675 return buf; 693 return buf;
676 } 694 }
@@ -735,6 +753,8 @@ struct virtqueue *vring_new_virtqueue(unsigned int index,
735 vq->weak_barriers = weak_barriers; 753 vq->weak_barriers = weak_barriers;
736 vq->broken = false; 754 vq->broken = false;
737 vq->last_used_idx = 0; 755 vq->last_used_idx = 0;
756 vq->avail_flags_shadow = 0;
757 vq->avail_idx_shadow = 0;
738 vq->num_added = 0; 758 vq->num_added = 0;
739 list_add_tail(&vq->vq.list, &vdev->vqs); 759 list_add_tail(&vq->vq.list, &vdev->vqs);
740#ifdef DEBUG 760#ifdef DEBUG
@@ -746,8 +766,10 @@ struct virtqueue *vring_new_virtqueue(unsigned int index,
746 vq->event = virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX); 766 vq->event = virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX);
747 767
748 /* No callback? Tell other side not to bother us. */ 768 /* No callback? Tell other side not to bother us. */
749 if (!callback) 769 if (!callback) {
750 vq->vring.avail->flags |= cpu_to_virtio16(vdev, VRING_AVAIL_F_NO_INTERRUPT); 770 vq->avail_flags_shadow |= VRING_AVAIL_F_NO_INTERRUPT;
771 vq->vring.avail->flags = cpu_to_virtio16(vdev, vq->avail_flags_shadow);
772 }
751 773
752 /* Put everything in free lists. */ 774 /* Put everything in free lists. */
753 vq->free_head = 0; 775 vq->free_head = 0;
diff --git a/tools/virtio/linux/kernel.h b/tools/virtio/linux/kernel.h
index 0a3da64638ce..4db7d5691ba7 100644
--- a/tools/virtio/linux/kernel.h
+++ b/tools/virtio/linux/kernel.h
@@ -110,4 +110,10 @@ static inline void free_page(unsigned long addr)
110 (void) (&_min1 == &_min2); \ 110 (void) (&_min1 == &_min2); \
111 _min1 < _min2 ? _min1 : _min2; }) 111 _min1 < _min2 ? _min1 : _min2; })
112 112
113/* TODO: empty stubs for now. Broken but enough for virtio_ring.c */
114#define list_add_tail(a, b) do {} while (0)
115#define list_del(a) do {} while (0)
116#define list_for_each_entry(a, b, c) while (0)
117/* end of stubs */
118
113#endif /* KERNEL_H */ 119#endif /* KERNEL_H */
diff --git a/tools/virtio/linux/virtio.h b/tools/virtio/linux/virtio.h
index a3e07016a440..ee125e714053 100644
--- a/tools/virtio/linux/virtio.h
+++ b/tools/virtio/linux/virtio.h
@@ -3,12 +3,6 @@
3#include <linux/scatterlist.h> 3#include <linux/scatterlist.h>
4#include <linux/kernel.h> 4#include <linux/kernel.h>
5 5
6/* TODO: empty stubs for now. Broken but enough for virtio_ring.c */
7#define list_add_tail(a, b) do {} while (0)
8#define list_del(a) do {} while (0)
9#define list_for_each_entry(a, b, c) while (0)
10/* end of stubs */
11
12struct virtio_device { 6struct virtio_device {
13 void *dev; 7 void *dev;
14 u64 features; 8 u64 features;
diff --git a/tools/virtio/linux/virtio_config.h b/tools/virtio/linux/virtio_config.h
index 806d683ab107..57a6964a1e35 100644
--- a/tools/virtio/linux/virtio_config.h
+++ b/tools/virtio/linux/virtio_config.h
@@ -40,33 +40,39 @@ static inline void __virtio_clear_bit(struct virtio_device *vdev,
40#define virtio_has_feature(dev, feature) \ 40#define virtio_has_feature(dev, feature) \
41 (__virtio_test_bit((dev), feature)) 41 (__virtio_test_bit((dev), feature))
42 42
43static inline bool virtio_is_little_endian(struct virtio_device *vdev)
44{
45 return virtio_has_feature(vdev, VIRTIO_F_VERSION_1) ||
46 virtio_legacy_is_little_endian();
47}
48
49/* Memory accessors */
43static inline u16 virtio16_to_cpu(struct virtio_device *vdev, __virtio16 val) 50static inline u16 virtio16_to_cpu(struct virtio_device *vdev, __virtio16 val)
44{ 51{
45 return __virtio16_to_cpu(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val); 52 return __virtio16_to_cpu(virtio_is_little_endian(vdev), val);
46} 53}
47 54
48static inline __virtio16 cpu_to_virtio16(struct virtio_device *vdev, u16 val) 55static inline __virtio16 cpu_to_virtio16(struct virtio_device *vdev, u16 val)
49{ 56{
50 return __cpu_to_virtio16(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val); 57 return __cpu_to_virtio16(virtio_is_little_endian(vdev), val);
51} 58}
52 59
53static inline u32 virtio32_to_cpu(struct virtio_device *vdev, __virtio32 val) 60static inline u32 virtio32_to_cpu(struct virtio_device *vdev, __virtio32 val)
54{ 61{
55 return __virtio32_to_cpu(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val); 62 return __virtio32_to_cpu(virtio_is_little_endian(vdev), val);
56} 63}
57 64
58static inline __virtio32 cpu_to_virtio32(struct virtio_device *vdev, u32 val) 65static inline __virtio32 cpu_to_virtio32(struct virtio_device *vdev, u32 val)
59{ 66{
60 return __cpu_to_virtio32(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val); 67 return __cpu_to_virtio32(virtio_is_little_endian(vdev), val);
61} 68}
62 69
63static inline u64 virtio64_to_cpu(struct virtio_device *vdev, __virtio64 val) 70static inline u64 virtio64_to_cpu(struct virtio_device *vdev, __virtio64 val)
64{ 71{
65 return __virtio64_to_cpu(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val); 72 return __virtio64_to_cpu(virtio_is_little_endian(vdev), val);
66} 73}
67 74
68static inline __virtio64 cpu_to_virtio64(struct virtio_device *vdev, u64 val) 75static inline __virtio64 cpu_to_virtio64(struct virtio_device *vdev, u64 val)
69{ 76{
70 return __cpu_to_virtio64(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val); 77 return __cpu_to_virtio64(virtio_is_little_endian(vdev), val);
71} 78}
72