Commit 5df04f17 authored by Felipe Franciosi's avatar Felipe Franciosi Committed by Michael S. Tsirkin
Browse files

vhost-user: fix legacy cross-endian configurations



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: default avatarFelipe Franciosi <felipe@nutanix.com>
Signed-off-by: default avatarMike Cui <cui@nutanix.com>
parent 08b9e0ba
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -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
--------------------
@@ -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
-------------------

+21 −2
Original line number Diff line number Diff line
@@ -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
};
@@ -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;

@@ -367,10 +369,27 @@ 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)
{
    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,
                           unsigned long int request,
                           struct vhost_vring_state *ring)