aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/vhost
diff options
context:
space:
mode:
authorGreg Kurz <gkurz@linux.vnet.ibm.com>2016-02-16 09:59:34 -0500
committerMichael S. Tsirkin <mst@redhat.com>2016-03-02 10:02:00 -0500
commitc507203756ca6303df2191c96c1385e965e2f0b7 (patch)
treea272cf68a2b2f974581b85c3cb259fd1f512c74f /drivers/vhost
parent592002f55e6e0b198a01d4a9315f74ddfea1c403 (diff)
vhost: rename cross-endian helpers
The default use case for vhost is when the host and the vring have the same endianness (default native endianness). But there are cases where they differ and vhost should byteswap when accessing the vring. The first case is when the host is big endian and the vring belongs to a virtio 1.0 device, which is always little endian. This is covered by the vq->is_le field. This field is initialized when userspace calls the VHOST_SET_FEATURES ioctl. It is reset when the device stops. We already have a vhost_init_is_le() helper, but the reset operation is opencoded as follows: vq->is_le = virtio_legacy_is_little_endian(); It isn't clear that we are resetting vq->is_le here. This patch moves the code to a helper with a more explicit name. The other case where we may have to byteswap is when the architecture can switch endianness at runtime (bi-endian). If endianness differs in the host and in the guest, then legacy devices need to be used in cross-endian mode. This mode is available with CONFIG_VHOST_CROSS_ENDIAN_LEGACY=y, which introduces a vq->user_be field. Userspace may enable cross-endian mode by calling the SET_VRING_ENDIAN ioctl before the device is started. The cross-endian mode is disabled when the device is stopped. The current names of the helpers that manipulate vq->user_be are unclear. This patch renames those helpers to clearly show that this is cross-endian stuff and with explicit enable/disable semantics. No behaviour change. Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'drivers/vhost')
-rw-r--r--drivers/vhost/vhost.c30
1 files changed, 24 insertions, 6 deletions
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 236553e81027..69f6463e11bd 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -43,11 +43,21 @@ enum {
43#define vhost_avail_event(vq) ((__virtio16 __user *)&vq->used->ring[vq->num]) 43#define vhost_avail_event(vq) ((__virtio16 __user *)&vq->used->ring[vq->num])
44 44
45#ifdef CONFIG_VHOST_CROSS_ENDIAN_LEGACY 45#ifdef CONFIG_VHOST_CROSS_ENDIAN_LEGACY
46static void vhost_vq_reset_user_be(struct vhost_virtqueue *vq) 46static void vhost_disable_cross_endian(struct vhost_virtqueue *vq)
47{ 47{
48 vq->user_be = !virtio_legacy_is_little_endian(); 48 vq->user_be = !virtio_legacy_is_little_endian();
49} 49}
50 50
51static void vhost_enable_cross_endian_big(struct vhost_virtqueue *vq)
52{
53 vq->user_be = true;
54}
55
56static void vhost_enable_cross_endian_little(struct vhost_virtqueue *vq)
57{
58 vq->user_be = false;
59}
60
51static long vhost_set_vring_endian(struct vhost_virtqueue *vq, int __user *argp) 61static long vhost_set_vring_endian(struct vhost_virtqueue *vq, int __user *argp)
52{ 62{
53 struct vhost_vring_state s; 63 struct vhost_vring_state s;
@@ -62,7 +72,10 @@ static long vhost_set_vring_endian(struct vhost_virtqueue *vq, int __user *argp)
62 s.num != VHOST_VRING_BIG_ENDIAN) 72 s.num != VHOST_VRING_BIG_ENDIAN)
63 return -EINVAL; 73 return -EINVAL;
64 74
65 vq->user_be = s.num; 75 if (s.num == VHOST_VRING_BIG_ENDIAN)
76 vhost_enable_cross_endian_big(vq);
77 else
78 vhost_enable_cross_endian_little(vq);
66 79
67 return 0; 80 return 0;
68} 81}
@@ -91,7 +104,7 @@ static void vhost_init_is_le(struct vhost_virtqueue *vq)
91 vq->is_le = vhost_has_feature(vq, VIRTIO_F_VERSION_1) || !vq->user_be; 104 vq->is_le = vhost_has_feature(vq, VIRTIO_F_VERSION_1) || !vq->user_be;
92} 105}
93#else 106#else
94static void vhost_vq_reset_user_be(struct vhost_virtqueue *vq) 107static void vhost_disable_cross_endian(struct vhost_virtqueue *vq)
95{ 108{
96} 109}
97 110
@@ -113,6 +126,11 @@ static void vhost_init_is_le(struct vhost_virtqueue *vq)
113} 126}
114#endif /* CONFIG_VHOST_CROSS_ENDIAN_LEGACY */ 127#endif /* CONFIG_VHOST_CROSS_ENDIAN_LEGACY */
115 128
129static void vhost_reset_is_le(struct vhost_virtqueue *vq)
130{
131 vq->is_le = virtio_legacy_is_little_endian();
132}
133
116static void vhost_poll_func(struct file *file, wait_queue_head_t *wqh, 134static void vhost_poll_func(struct file *file, wait_queue_head_t *wqh,
117 poll_table *pt) 135 poll_table *pt)
118{ 136{
@@ -276,8 +294,8 @@ static void vhost_vq_reset(struct vhost_dev *dev,
276 vq->call = NULL; 294 vq->call = NULL;
277 vq->log_ctx = NULL; 295 vq->log_ctx = NULL;
278 vq->memory = NULL; 296 vq->memory = NULL;
279 vq->is_le = virtio_legacy_is_little_endian(); 297 vhost_reset_is_le(vq);
280 vhost_vq_reset_user_be(vq); 298 vhost_disable_cross_endian(vq);
281} 299}
282 300
283static int vhost_worker(void *data) 301static int vhost_worker(void *data)
@@ -1159,7 +1177,7 @@ int vhost_init_used(struct vhost_virtqueue *vq)
1159 bool is_le = vq->is_le; 1177 bool is_le = vq->is_le;
1160 1178
1161 if (!vq->private_data) { 1179 if (!vq->private_data) {
1162 vq->is_le = virtio_legacy_is_little_endian(); 1180 vhost_reset_is_le(vq);
1163 return 0; 1181 return 0;
1164 } 1182 }
1165 1183