Skip to content

Commit

Permalink
vhost-user: fix legacy cross-endian configurations
Browse files Browse the repository at this point in the history
Currently, vhost-user does not implement any means for notifying the
backend about guest endianess. This commit introduces a new message
called VHOST_USER_SET_VRING_ENDIAN which is analogous to the ioctl()
called VHOST_SET_VRING_ENDIAN used for kernel vhost backends. Such
message is necessary for backends supporting legacy (pre-1.0) virtio
devices running in big-endian guests.

Signed-off-by: Felipe Franciosi <felipe@nutanix.com>
Signed-off-by: Mike Cui <cui@nutanix.com>
  • Loading branch information
franciozzy authored and mstsirkin committed Aug 1, 2017
1 parent 08b9e0b commit 5df04f1
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 2 deletions.
16 changes: 16 additions & 0 deletions docs/interop/vhost-user.txt
Expand Up @@ -326,6 +326,7 @@ Protocol features
#define VHOST_USER_PROTOCOL_F_REPLY_ACK 3
#define VHOST_USER_PROTOCOL_F_MTU 4
#define VHOST_USER_PROTOCOL_F_SLAVE_REQ 5
#define VHOST_USER_PROTOCOL_F_CROSS_ENDIAN 6

Master message types
--------------------
Expand Down Expand Up @@ -580,6 +581,21 @@ Master message types
This request should be send only when VIRTIO_F_IOMMU_PLATFORM feature
has been successfully negotiated.

* VHOST_USER_SET_VRING_ENDIAN

Id: 23
Equivalent ioctl: VHOST_SET_VRING_ENDIAN
Master payload: vring state description

Set the endianess of a VQ for legacy devices. Little-endian is indicated
with state.num set to 0 and big-endian is indicated with state.num set
to 1. Other values are invalid.
This request should be sent only when VHOST_USER_PROTOCOL_F_CROSS_ENDIAN
has been negotiated.
Backends that negotiated this feature should handle both endianesses
and expect this message once (per VQ) during device configuration
(ie. before the master starts the VQ).

Slave message types
-------------------

Expand Down
23 changes: 21 additions & 2 deletions hw/virtio/vhost-user.c
Expand Up @@ -33,6 +33,7 @@ enum VhostUserProtocolFeature {
VHOST_USER_PROTOCOL_F_REPLY_ACK = 3,
VHOST_USER_PROTOCOL_F_NET_MTU = 4,
VHOST_USER_PROTOCOL_F_SLAVE_REQ = 5,
VHOST_USER_PROTOCOL_F_CROSS_ENDIAN = 6,

VHOST_USER_PROTOCOL_F_MAX
};
Expand Down Expand Up @@ -63,6 +64,7 @@ typedef enum VhostUserRequest {
VHOST_USER_NET_SET_MTU = 20,
VHOST_USER_SET_SLAVE_REQ_FD = 21,
VHOST_USER_IOTLB_MSG = 22,
VHOST_USER_SET_VRING_ENDIAN = 23,
VHOST_USER_MAX
} VhostUserRequest;

Expand Down Expand Up @@ -367,8 +369,25 @@ static int vhost_user_set_vring_addr(struct vhost_dev *dev,
static int vhost_user_set_vring_endian(struct vhost_dev *dev,
struct vhost_vring_state *ring)
{
error_report("vhost-user trying to send unhandled ioctl");
return -1;
bool cross_endian = virtio_has_feature(dev->protocol_features,
VHOST_USER_PROTOCOL_F_CROSS_ENDIAN);
VhostUserMsg msg = {
.request = VHOST_USER_SET_VRING_ENDIAN,
.flags = VHOST_USER_VERSION,
.payload.state = *ring,
.size = sizeof(msg.payload.state),
};

if (!cross_endian) {
error_report("vhost-user trying to send unhandled ioctl");
return -1;
}

if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
return -1;
}

return 0;
}

static int vhost_set_vring(struct vhost_dev *dev,
Expand Down

0 comments on commit 5df04f1

Please sign in to comment.