linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg Kurz <gkurz@linux.vnet.ibm.com>
To: Rusty Russell <rusty@rustcorp.com.au>,
	"Michael S. Tsirkin" <mst@redhat.com>
Cc: linux-api@vger.kernel.org, linux-kernel@vger.kernel.org,
	kvm@vger.kernel.org, virtualization@lists.linux-foundation.org
Subject: [PATCH v2 7/7] vhost: feature to set the vring endianness
Date: Thu, 02 Apr 2015 15:17:13 +0200	[thread overview]
Message-ID: <20150402131713.24676.9924.stgit@bahia.lab.toulouse-stg.fr.ibm.com> (raw)
In-Reply-To: <20150402131637.24676.60700.stgit@bahia.lab.toulouse-stg.fr.ibm.com>

This patch brings cross-endian support to vhost when used to implement
legacy virtio devices. Since it is a relatively rare situation, the feature
availability is controlled by a kernel config option (not set by default).

If cross-endian support is compiled in, vhost abvertises a new feature
to be negotiated with userspace. If userspace acknowledges the feature,
it can inform vhost about the endianness to use with a new ioctl.

This feature is mutually exclusive with virtio 1.0. Even if the vhost device
advertises virtio 1.0 and legacy cross-endian features, it cannot receive
aknowledgement for both at the same time.

Hot paths are being preserved from any penalty when the config option is
disabled or when virtio 1.0 is being used.

Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
---
 drivers/vhost/Kconfig      |   10 ++++++++++
 drivers/vhost/net.c        |    5 +++++
 drivers/vhost/scsi.c       |    4 ++++
 drivers/vhost/test.c       |    4 ++++
 drivers/vhost/vhost.c      |   19 +++++++++++++++++++
 drivers/vhost/vhost.h      |   13 ++++++++++++-
 include/uapi/linux/vhost.h |   10 ++++++++++
 7 files changed, 64 insertions(+), 1 deletion(-)

diff --git a/drivers/vhost/Kconfig b/drivers/vhost/Kconfig
index 017a1e8..5bb8da9 100644
--- a/drivers/vhost/Kconfig
+++ b/drivers/vhost/Kconfig
@@ -32,3 +32,13 @@ config VHOST
 	---help---
 	  This option is selected by any driver which needs to access
 	  the core of vhost.
+
+config VHOST_SET_ENDIAN_LEGACY
+	bool "Cross-endian support for host kernel accelerator"
+	default n
+	---help---
+	  This option allows vhost to support guests with a different byte
+	  ordering. It is disabled by default since it adds overhead and it
+	  is only needed by a few platforms (powerpc and arm).
+
+	  If unsure, say "n".
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 2bbfc25..5274a44 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -1011,6 +1011,11 @@ static int vhost_net_set_features(struct vhost_net *n, u64 features)
 		vhost_hlen = 0;
 		sock_hlen = hdr_len;
 	}
+
+	if (features & ((1ULL << VHOST_F_SET_ENDIAN_LEGACY) |
+			(1ULL << VIRTIO_F_VERSION_1)))
+		return -EINVAL;
+
 	mutex_lock(&n->dev.mutex);
 	if ((features & (1 << VHOST_F_LOG_ALL)) &&
 	    !vhost_log_access_ok(&n->dev)) {
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 71df240..b53e9c2 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -1544,6 +1544,10 @@ static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features)
 	if (features & ~VHOST_SCSI_FEATURES)
 		return -EOPNOTSUPP;
 
+	if (features & ((1ULL << VHOST_F_SET_ENDIAN_LEGACY) |
+			(1ULL << VIRTIO_F_VERSION_1)))
+		return -EINVAL;
+
 	mutex_lock(&vs->dev.mutex);
 	if ((features & (1 << VHOST_F_LOG_ALL)) &&
 	    !vhost_log_access_ok(&vs->dev)) {
diff --git a/drivers/vhost/test.c b/drivers/vhost/test.c
index d9c501e..cfefdad 100644
--- a/drivers/vhost/test.c
+++ b/drivers/vhost/test.c
@@ -243,6 +243,10 @@ static int vhost_test_set_features(struct vhost_test *n, u64 features)
 {
 	struct vhost_virtqueue *vq;
 
+	if (features & ((1ULL << VHOST_F_SET_ENDIAN_LEGACY) |
+			(1ULL << VIRTIO_F_VERSION_1)))
+		return -EINVAL;
+
 	mutex_lock(&n->dev.mutex);
 	if ((features & (1 << VHOST_F_LOG_ALL)) &&
 	    !vhost_log_access_ok(&n->dev)) {
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 2ee2826..60a0f32 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -199,6 +199,7 @@ static void vhost_vq_reset(struct vhost_dev *dev,
 	vq->call = NULL;
 	vq->log_ctx = NULL;
 	vq->memory = NULL;
+	vq->legacy_big_endian = false;
 }
 
 static int vhost_worker(void *data)
@@ -806,6 +807,24 @@ long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp)
 		} else
 			filep = eventfp;
 		break;
+#ifdef CONFIG_VHOST_SET_ENDIAN_LEGACY
+	case VHOST_SET_VRING_ENDIAN_LEGACY:
+	{
+		struct vhost_vring_endian e;
+
+		if (!vhost_has_feature(vq, VHOST_F_SET_ENDIAN_LEGACY)) {
+			r = -EINVAL;
+			break;
+		}
+
+		if (copy_from_user(&e, argp, sizeof(e))) {
+			r = -EFAULT;
+			break;
+		}
+		vq->legacy_big_endian = e.is_big_endian;
+		break;
+	}
+#endif
 	default:
 		r = -ENOIOCTLCMD;
 	}
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
index 4e9a186..d50881d 100644
--- a/drivers/vhost/vhost.h
+++ b/drivers/vhost/vhost.h
@@ -106,6 +106,9 @@ struct vhost_virtqueue {
 	/* Log write descriptors */
 	void __user *log_base;
 	struct vhost_log *log;
+
+	/* We need to know the device endianness with legacy virtio. */
+	bool legacy_big_endian;
 };
 
 struct vhost_dev {
@@ -165,7 +168,11 @@ enum {
 	VHOST_FEATURES = (1ULL << VIRTIO_F_NOTIFY_ON_EMPTY) |
 			 (1ULL << VIRTIO_RING_F_INDIRECT_DESC) |
 			 (1ULL << VIRTIO_RING_F_EVENT_IDX) |
-			 (1ULL << VHOST_F_LOG_ALL),
+			 (1ULL << VHOST_F_LOG_ALL) |
+#ifdef CONFIG_VHOST_SET_ENDIAN_LEGACY
+			 (1ULL << VHOST_F_SET_ENDIAN_LEGACY) |
+#endif
+			 0ULL,
 };
 
 static inline bool vhost_has_feature(struct vhost_virtqueue *vq, int bit)
@@ -177,6 +184,10 @@ static inline bool vhost_is_little_endian(struct vhost_virtqueue *vq)
 {
 	if (vhost_has_feature(vq, VIRTIO_F_VERSION_1))
 		return true;
+#ifdef CONFIG_VHOST_SET_ENDIAN_LEGACY
+	if (vhost_has_feature(vq, VHOST_F_SET_ENDIAN_LEGACY))
+		return !vq->legacy_big_endian;
+#endif
 	return virtio_legacy_is_little_endian();
 }
 
diff --git a/include/uapi/linux/vhost.h b/include/uapi/linux/vhost.h
index bb6a5b4..09d2a48 100644
--- a/include/uapi/linux/vhost.h
+++ b/include/uapi/linux/vhost.h
@@ -47,6 +47,11 @@ struct vhost_vring_addr {
 	__u64 log_guest_addr;
 };
 
+struct vhost_vring_endian {
+	unsigned int index;
+	bool is_big_endian;
+};
+
 struct vhost_memory_region {
 	__u64 guest_phys_addr;
 	__u64 memory_size; /* bytes */
@@ -103,6 +108,9 @@ struct vhost_memory {
 /* Get accessor: reads index, writes value in num */
 #define VHOST_GET_VRING_BASE _IOWR(VHOST_VIRTIO, 0x12, struct vhost_vring_state)
 
+/* Set endianness for the ring (legacy virtio only) */
+#define VHOST_SET_VRING_ENDIAN_LEGACY _IOW(VHOST_VIRTIO, 0x13, struct vhost_vring_endian)
+
 /* The following ioctls use eventfd file descriptors to signal and poll
  * for events. */
 
@@ -126,6 +134,8 @@ struct vhost_memory {
 #define VHOST_F_LOG_ALL 26
 /* vhost-net should add virtio_net_hdr for RX, and strip for TX packets. */
 #define VHOST_NET_F_VIRTIO_NET_HDR 27
+/* the vring endianness can be explicitly set (legacy virtio only). */
+#define VHOST_F_SET_ENDIAN_LEGACY 28
 
 /* VHOST_SCSI specific definitions */
 


  parent reply	other threads:[~2015-04-02 13:17 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-04-02 13:16 [PATCH v2 0/7] vhost: support for cross endian guests Greg Kurz
2015-04-02 13:16 ` [PATCH v2 1/7] virtio: introduce virtio_is_little_endian() helper Greg Kurz
2015-04-02 13:16 ` [PATCH v2 2/7] tun: add tun_is_little_endian() helper Greg Kurz
2015-04-02 13:16 ` [PATCH v2 3/7] macvtap: introduce macvtap_is_little_endian() helper Greg Kurz
2015-04-02 13:16 ` [PATCH v2 4/7] vringh: introduce vringh_is_little_endian() helper Greg Kurz
2015-04-02 13:17 ` [PATCH v2 5/7] vhost: introduce vhost_is_little_endian() helper Greg Kurz
2015-04-02 13:17 ` [PATCH v2 6/7] virtio: add explicit big-endian support to memory accessors Greg Kurz
2015-04-02 13:17 ` Greg Kurz [this message]
2015-04-02 14:20   ` [PATCH v2 7/7] vhost: feature to set the vring endianness Michael S. Tsirkin
2015-04-02 16:45     ` Greg Kurz
2015-04-02 18:53       ` Michael S. Tsirkin
2015-04-02 14:23 ` [PATCH v2 0/7] vhost: support for cross endian guests Michael S. Tsirkin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150402131713.24676.9924.stgit@bahia.lab.toulouse-stg.fr.ibm.com \
    --to=gkurz@linux.vnet.ibm.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-api@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mst@redhat.com \
    --cc=rusty@rustcorp.com.au \
    --cc=virtualization@lists.linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).