[v3,1/2] net/virtio: fix missing backend features negotiation

Message ID 20210108094149.215384-2-maxime.coquelin@redhat.com (mailing list archive)
State Accepted, archived
Delegated to: Maxime Coquelin
Headers
Series Vhost-vDPA fixes |

Checks

Context Check Description
ci/checkpatch warning coding style issues

Commit Message

Maxime Coquelin Jan. 8, 2021, 9:41 a.m. UTC
  This patch adds missing backend features negotiation for
in Vhost-vDPA. Without it, IOTLB messages v2 could be sent
by Virtio-user PMD while not supported by the backend.

Fixes: 6b901437056e ("net/virtio: introduce vhost-vDPA backend")
Cc: stable@dpdk.org

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 drivers/net/virtio/virtio_user/vhost.h           |  4 ++++
 drivers/net/virtio/virtio_user/vhost_vdpa.c      | 14 ++++++++++++++
 drivers/net/virtio/virtio_user/virtio_user_dev.c | 14 ++++++++++----
 drivers/net/virtio/virtio_user/virtio_user_dev.h |  4 +---
 4 files changed, 29 insertions(+), 7 deletions(-)
  

Comments

Chenbo Xia Jan. 11, 2021, 5:43 a.m. UTC | #1
> -----Original Message-----
> From: Maxime Coquelin <maxime.coquelin@redhat.com>
> Sent: Friday, January 8, 2021 5:42 PM
> To: dev@dpdk.org; stable@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>;
> amorenoz@redhat.com; jasowang@redhat.com; david.marchand@redhat.com
> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
> Subject: [PATCH v3 1/2] net/virtio: fix missing backend features negotiation
> 
> This patch adds missing backend features negotiation for
> in Vhost-vDPA. Without it, IOTLB messages v2 could be sent
> by Virtio-user PMD while not supported by the backend.
> 
> Fixes: 6b901437056e ("net/virtio: introduce vhost-vDPA backend")
> Cc: stable@dpdk.org
> 
> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> ---
>  drivers/net/virtio/virtio_user/vhost.h           |  4 ++++
>  drivers/net/virtio/virtio_user/vhost_vdpa.c      | 14 ++++++++++++++
>  drivers/net/virtio/virtio_user/virtio_user_dev.c | 14 ++++++++++----
>  drivers/net/virtio/virtio_user/virtio_user_dev.h |  4 +---
>  4 files changed, 29 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/net/virtio/virtio_user/vhost.h
> b/drivers/net/virtio/virtio_user/vhost.h
> index 210a3704e7..c1dcc50b58 100644
> --- a/drivers/net/virtio/virtio_user/vhost.h
> +++ b/drivers/net/virtio/virtio_user/vhost.h
> @@ -86,6 +86,10 @@ enum vhost_user_request {
>  	VHOST_USER_MAX
>  };
> 
> +#ifndef VHOST_BACKEND_F_IOTLB_MSG_V2
> +#define VHOST_BACKEND_F_IOTLB_MSG_V2 1
> +#endif
> +
>  extern const char * const vhost_msg_strings[VHOST_USER_MAX];
> 
>  struct vhost_memory_region {
> diff --git a/drivers/net/virtio/virtio_user/vhost_vdpa.c
> b/drivers/net/virtio/virtio_user/vhost_vdpa.c
> index c5b59e2f95..83c60ea660 100644
> --- a/drivers/net/virtio/virtio_user/vhost_vdpa.c
> +++ b/drivers/net/virtio/virtio_user/vhost_vdpa.c
> @@ -35,6 +35,8 @@
>  #define VHOST_VDPA_SET_STATUS _IOW(VHOST_VIRTIO, 0x72, __u8)
>  #define VHOST_VDPA_SET_VRING_ENABLE	_IOW(VHOST_VIRTIO, 0x75, \
>  					     struct vhost_vring_state)
> +#define VHOST_SET_BACKEND_FEATURES _IOW(VHOST_VIRTIO, 0x25, __u64)
> +#define VHOST_GET_BACKEND_FEATURES _IOR(VHOST_VIRTIO, 0x26, __u64)
> 
>  static uint64_t vhost_req_user_to_vdpa[] = {
>  	[VHOST_USER_SET_OWNER] = VHOST_SET_OWNER,
> @@ -51,6 +53,8 @@ static uint64_t vhost_req_user_to_vdpa[] = {
>  	[VHOST_USER_SET_STATUS] = VHOST_VDPA_SET_STATUS,
>  	[VHOST_USER_GET_STATUS] = VHOST_VDPA_GET_STATUS,
>  	[VHOST_USER_SET_VRING_ENABLE] = VHOST_VDPA_SET_VRING_ENABLE,
> +	[VHOST_USER_GET_PROTOCOL_FEATURES] = VHOST_GET_BACKEND_FEATURES,
> +	[VHOST_USER_SET_PROTOCOL_FEATURES] = VHOST_SET_BACKEND_FEATURES,
>  };
> 
>  /* no alignment requirement */
> @@ -86,6 +90,11 @@ vhost_vdpa_dma_map(struct virtio_user_dev *dev, void *addr,
>  {
>  	struct vhost_msg msg = {};
> 
> +	if (!(dev->protocol_features & (1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2)))
> {
> +		PMD_DRV_LOG(ERR, "IOTLB_MSG_V2 not supported by the backend.");
> +		return -1;
> +	}
> +
>  	msg.type = VHOST_IOTLB_MSG_V2;
>  	msg.iotlb.type = VHOST_IOTLB_UPDATE;
>  	msg.iotlb.iova = iova;
> @@ -111,6 +120,11 @@ vhost_vdpa_dma_unmap(struct virtio_user_dev *dev,
> __rte_unused void *addr,
>  {
>  	struct vhost_msg msg = {};
> 
> +	if (!(dev->protocol_features & (1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2)))
> {
> +		PMD_DRV_LOG(ERR, "IOTLB_MSG_V2 not supported by the backend.");
> +		return -1;
> +	}
> +
>  	msg.type = VHOST_IOTLB_MSG_V2;
>  	msg.iotlb.type = VHOST_IOTLB_INVALIDATE;
>  	msg.iotlb.iova = iova;
> diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c
> b/drivers/net/virtio/virtio_user/virtio_user_dev.c
> index e1cbad0d90..39c5dfc9e4 100644
> --- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
> +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
> @@ -440,11 +440,13 @@ virtio_user_dev_setup(struct virtio_user_dev *dev)
>  	 1ULL << VIRTIO_F_RING_PACKED		|	\
>  	 1ULL << VHOST_USER_F_PROTOCOL_FEATURES)
> 
> -#define VIRTIO_USER_SUPPORTED_PROTOCOL_FEATURES		\
> +#define VHOST_USER_SUPPORTED_PROTOCOL_FEATURES		\
>  	(1ULL << VHOST_USER_PROTOCOL_F_MQ |		\
>  	 1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK |	\
>  	 1ULL << VHOST_USER_PROTOCOL_F_STATUS)
> 
> +#define VHOST_VDPA_SUPPORTED_PROTOCOL_FEATURES		\
> +	(1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2)
>  int
>  virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
>  		     int cq, int queue_size, const char *mac, char **ifname,
> @@ -463,9 +465,13 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char
> *path, int queues,
>  	dev->mac_specified = 0;
>  	dev->frontend_features = 0;
>  	dev->unsupported_features = ~VIRTIO_USER_SUPPORTED_FEATURES;
> -	dev->protocol_features = VIRTIO_USER_SUPPORTED_PROTOCOL_FEATURES;
>  	dev->backend_type = backend_type;
> 
> +	if (dev->backend_type == VIRTIO_USER_BACKEND_VHOST_USER)
> +		dev->protocol_features = VHOST_USER_SUPPORTED_PROTOCOL_FEATURES;
> +	else if (dev->backend_type == VIRTIO_USER_BACKEND_VHOST_VDPA)
> +		dev->protocol_features = VHOST_VDPA_SUPPORTED_PROTOCOL_FEATURES;
> +
>  	parse_mac(dev, mac);
> 
>  	if (*ifname) {
> @@ -498,8 +504,8 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char
> *path, int queues,
>  		}
> 
> 
> -		if (dev->device_features &
> -				(1ULL << VHOST_USER_F_PROTOCOL_FEATURES)) {
> +		if ((dev->device_features & (1ULL <<
> VHOST_USER_F_PROTOCOL_FEATURES)) ||
> +				(dev->backend_type == VIRTIO_USER_BACKEND_VHOST_VDPA))
> {
>  			if (dev->ops->send_request(dev,
>  					VHOST_USER_GET_PROTOCOL_FEATURES,
>  					&protocol_features))
> diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.h
> b/drivers/net/virtio/virtio_user/virtio_user_dev.h
> index e053897d8f..3b5b6bc3ae 100644
> --- a/drivers/net/virtio/virtio_user/virtio_user_dev.h
> +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.h
> @@ -48,9 +48,7 @@ struct virtio_user_dev {
>  	uint64_t	device_features; /* supported features by device */
>  	uint64_t	frontend_features; /* enabled frontend features */
>  	uint64_t	unsupported_features; /* unsupported features mask */
> -	uint64_t	protocol_features; /* negotiated protocol features
> -					    * (Vhost-user only)
> -					    */
> +	uint64_t	protocol_features; /* negotiated protocol features */
>  	uint8_t		status;
>  	uint16_t	net_status;
>  	uint16_t	port_id;
> --
> 2.29.2


Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
  

Patch

diff --git a/drivers/net/virtio/virtio_user/vhost.h b/drivers/net/virtio/virtio_user/vhost.h
index 210a3704e7..c1dcc50b58 100644
--- a/drivers/net/virtio/virtio_user/vhost.h
+++ b/drivers/net/virtio/virtio_user/vhost.h
@@ -86,6 +86,10 @@  enum vhost_user_request {
 	VHOST_USER_MAX
 };
 
+#ifndef VHOST_BACKEND_F_IOTLB_MSG_V2
+#define VHOST_BACKEND_F_IOTLB_MSG_V2 1
+#endif
+
 extern const char * const vhost_msg_strings[VHOST_USER_MAX];
 
 struct vhost_memory_region {
diff --git a/drivers/net/virtio/virtio_user/vhost_vdpa.c b/drivers/net/virtio/virtio_user/vhost_vdpa.c
index c5b59e2f95..83c60ea660 100644
--- a/drivers/net/virtio/virtio_user/vhost_vdpa.c
+++ b/drivers/net/virtio/virtio_user/vhost_vdpa.c
@@ -35,6 +35,8 @@ 
 #define VHOST_VDPA_SET_STATUS _IOW(VHOST_VIRTIO, 0x72, __u8)
 #define VHOST_VDPA_SET_VRING_ENABLE	_IOW(VHOST_VIRTIO, 0x75, \
 					     struct vhost_vring_state)
+#define VHOST_SET_BACKEND_FEATURES _IOW(VHOST_VIRTIO, 0x25, __u64)
+#define VHOST_GET_BACKEND_FEATURES _IOR(VHOST_VIRTIO, 0x26, __u64)
 
 static uint64_t vhost_req_user_to_vdpa[] = {
 	[VHOST_USER_SET_OWNER] = VHOST_SET_OWNER,
@@ -51,6 +53,8 @@  static uint64_t vhost_req_user_to_vdpa[] = {
 	[VHOST_USER_SET_STATUS] = VHOST_VDPA_SET_STATUS,
 	[VHOST_USER_GET_STATUS] = VHOST_VDPA_GET_STATUS,
 	[VHOST_USER_SET_VRING_ENABLE] = VHOST_VDPA_SET_VRING_ENABLE,
+	[VHOST_USER_GET_PROTOCOL_FEATURES] = VHOST_GET_BACKEND_FEATURES,
+	[VHOST_USER_SET_PROTOCOL_FEATURES] = VHOST_SET_BACKEND_FEATURES,
 };
 
 /* no alignment requirement */
@@ -86,6 +90,11 @@  vhost_vdpa_dma_map(struct virtio_user_dev *dev, void *addr,
 {
 	struct vhost_msg msg = {};
 
+	if (!(dev->protocol_features & (1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2))) {
+		PMD_DRV_LOG(ERR, "IOTLB_MSG_V2 not supported by the backend.");
+		return -1;
+	}
+
 	msg.type = VHOST_IOTLB_MSG_V2;
 	msg.iotlb.type = VHOST_IOTLB_UPDATE;
 	msg.iotlb.iova = iova;
@@ -111,6 +120,11 @@  vhost_vdpa_dma_unmap(struct virtio_user_dev *dev, __rte_unused void *addr,
 {
 	struct vhost_msg msg = {};
 
+	if (!(dev->protocol_features & (1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2))) {
+		PMD_DRV_LOG(ERR, "IOTLB_MSG_V2 not supported by the backend.");
+		return -1;
+	}
+
 	msg.type = VHOST_IOTLB_MSG_V2;
 	msg.iotlb.type = VHOST_IOTLB_INVALIDATE;
 	msg.iotlb.iova = iova;
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c
index e1cbad0d90..39c5dfc9e4 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
@@ -440,11 +440,13 @@  virtio_user_dev_setup(struct virtio_user_dev *dev)
 	 1ULL << VIRTIO_F_RING_PACKED		|	\
 	 1ULL << VHOST_USER_F_PROTOCOL_FEATURES)
 
-#define VIRTIO_USER_SUPPORTED_PROTOCOL_FEATURES		\
+#define VHOST_USER_SUPPORTED_PROTOCOL_FEATURES		\
 	(1ULL << VHOST_USER_PROTOCOL_F_MQ |		\
 	 1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK |	\
 	 1ULL << VHOST_USER_PROTOCOL_F_STATUS)
 
+#define VHOST_VDPA_SUPPORTED_PROTOCOL_FEATURES		\
+	(1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2)
 int
 virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
 		     int cq, int queue_size, const char *mac, char **ifname,
@@ -463,9 +465,13 @@  virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
 	dev->mac_specified = 0;
 	dev->frontend_features = 0;
 	dev->unsupported_features = ~VIRTIO_USER_SUPPORTED_FEATURES;
-	dev->protocol_features = VIRTIO_USER_SUPPORTED_PROTOCOL_FEATURES;
 	dev->backend_type = backend_type;
 
+	if (dev->backend_type == VIRTIO_USER_BACKEND_VHOST_USER)
+		dev->protocol_features = VHOST_USER_SUPPORTED_PROTOCOL_FEATURES;
+	else if (dev->backend_type == VIRTIO_USER_BACKEND_VHOST_VDPA)
+		dev->protocol_features = VHOST_VDPA_SUPPORTED_PROTOCOL_FEATURES;
+
 	parse_mac(dev, mac);
 
 	if (*ifname) {
@@ -498,8 +504,8 @@  virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
 		}
 
 
-		if (dev->device_features &
-				(1ULL << VHOST_USER_F_PROTOCOL_FEATURES)) {
+		if ((dev->device_features & (1ULL << VHOST_USER_F_PROTOCOL_FEATURES)) ||
+				(dev->backend_type == VIRTIO_USER_BACKEND_VHOST_VDPA)) {
 			if (dev->ops->send_request(dev,
 					VHOST_USER_GET_PROTOCOL_FEATURES,
 					&protocol_features))
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.h b/drivers/net/virtio/virtio_user/virtio_user_dev.h
index e053897d8f..3b5b6bc3ae 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.h
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.h
@@ -48,9 +48,7 @@  struct virtio_user_dev {
 	uint64_t	device_features; /* supported features by device */
 	uint64_t	frontend_features; /* enabled frontend features */
 	uint64_t	unsupported_features; /* unsupported features mask */
-	uint64_t	protocol_features; /* negotiated protocol features
-					    * (Vhost-user only)
-					    */
+	uint64_t	protocol_features; /* negotiated protocol features */
 	uint8_t		status;
 	uint16_t	net_status;
 	uint16_t	port_id;