diff options
| -rw-r--r-- | drivers/vhost/vhost.c | 30 |
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 |
| 46 | static void vhost_vq_reset_user_be(struct vhost_virtqueue *vq) | 46 | static 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 | ||
| 51 | static void vhost_enable_cross_endian_big(struct vhost_virtqueue *vq) | ||
| 52 | { | ||
| 53 | vq->user_be = true; | ||
| 54 | } | ||
| 55 | |||
| 56 | static void vhost_enable_cross_endian_little(struct vhost_virtqueue *vq) | ||
| 57 | { | ||
| 58 | vq->user_be = false; | ||
| 59 | } | ||
| 60 | |||
| 51 | static long vhost_set_vring_endian(struct vhost_virtqueue *vq, int __user *argp) | 61 | static 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 |
| 94 | static void vhost_vq_reset_user_be(struct vhost_virtqueue *vq) | 107 | static 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 | ||
| 129 | static void vhost_reset_is_le(struct vhost_virtqueue *vq) | ||
| 130 | { | ||
| 131 | vq->is_le = virtio_legacy_is_little_endian(); | ||
| 132 | } | ||
| 133 | |||
| 116 | static void vhost_poll_func(struct file *file, wait_queue_head_t *wqh, | 134 | static 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 | ||
| 283 | static int vhost_worker(void *data) | 301 | static 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 | ||
