Hi Maxime, > -----Original Message----- > From: dev <dev-boun...@dpdk.org> On Behalf Of Maxime Coquelin > Sent: Thursday, May 14, 2020 4:02 PM > To: Ye, Xiaolong <xiaolong...@intel.com>; shah...@mellanox.com; > ma...@mellanox.com; amore...@redhat.com; Wang, Xiao W > <xiao.w.w...@intel.com>; viachesl...@mellanox.com; dev@dpdk.org > Cc: jasow...@redhat.com; l...@redhat.com; Maxime Coquelin > <maxime.coque...@redhat.com> > Subject: [dpdk-dev] [PATCH 6/9] vhost: add support for virtio status > > This patch adds support to the new Virtio device status Vhost-user protocol > feature. > > Getting such information in the backend helps to know when the driver is done > with the device configuration and so makes the initialization phase more > robust. > > Signed-off-by: Maxime Coquelin <maxime.coque...@redhat.com> > --- > lib/librte_vhost/rte_vhost.h | 4 ++++ > lib/librte_vhost/vhost.h | 9 ++++++++ > lib/librte_vhost/vhost_user.c | 40 +++++++++++++++++++++++++++++++++++ > lib/librte_vhost/vhost_user.h | 6 ++++-- > 4 files changed, 57 insertions(+), 2 deletions(-) > > diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h index > 5c72fba797..b4b7aa1928 100644 > --- a/lib/librte_vhost/rte_vhost.h > +++ b/lib/librte_vhost/rte_vhost.h > @@ -85,6 +85,10 @@ extern "C" { > #define VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD 12 #endif > > +#ifndef VHOST_USER_PROTOCOL_F_STATUS > +#define VHOST_USER_PROTOCOL_F_STATUS 15 #endif > + > /** Indicate whether protocol features negotiation is supported. */ #ifndef > VHOST_USER_F_PROTOCOL_FEATURES > #define VHOST_USER_F_PROTOCOL_FEATURES 30 > diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h index > df98d15de6..9a9c0a98f5 100644 > --- a/lib/librte_vhost/vhost.h > +++ b/lib/librte_vhost/vhost.h > @@ -202,6 +202,14 @@ struct vhost_virtqueue { > TAILQ_HEAD(, vhost_iotlb_entry) iotlb_pending_list; } > __rte_cache_aligned; > > +/* Virtio device status as per Virtio specification */ > +#define VIRTIO_DEVICE_STATUS_ACK 0x01 > +#define VIRTIO_DEVICE_STATUS_DRIVER 0x02 > +#define VIRTIO_DEVICE_STATUS_DRIVER_OK 0x04 > +#define VIRTIO_DEVICE_STATUS_FEATURES_OK 0x08 > +#define VIRTIO_DEVICE_STATUS_DEV_NEED_RESET 0x40 > +#define VIRTIO_DEVICE_STATUS_FAILED 0x80 > + > /* Old kernels have no such macros defined */ #ifndef > VIRTIO_NET_F_GUEST_ANNOUNCE > #define VIRTIO_NET_F_GUEST_ANNOUNCE 21 @@ -364,6 +372,7 @@ struct > virtio_net { > uint64_t log_addr; > struct rte_ether_addr mac; > uint16_t mtu; > + uint8_t status; > > struct vhost_device_ops const *notify_ops; > > diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c > index > 4a847f368c..e5a44be58d 100644 > --- a/lib/librte_vhost/vhost_user.c > +++ b/lib/librte_vhost/vhost_user.c > @@ -87,6 +87,7 @@ static const char *vhost_message_str[VHOST_USER_MAX] > = { > [VHOST_USER_POSTCOPY_END] = "VHOST_USER_POSTCOPY_END", > [VHOST_USER_GET_INFLIGHT_FD] = "VHOST_USER_GET_INFLIGHT_FD", > [VHOST_USER_SET_INFLIGHT_FD] = "VHOST_USER_SET_INFLIGHT_FD", > + [VHOST_USER_SET_STATUS] = "VHOST_USER_SET_STATUS", > }; > > static int send_vhost_reply(int sockfd, struct VhostUserMsg *msg); @@ -1328,6 > +1329,11 @@ virtio_is_ready(struct virtio_net *dev) > return 0; > } > > + /* If supported, ensure the frontend is really done with config */ > + if (dev->protocol_features & (1ULL << > VHOST_USER_PROTOCOL_F_STATUS)) > + if (!(dev->status & VIRTIO_DEVICE_STATUS_DRIVER_OK)) > + return 0; > + > dev->flags |= VIRTIO_DEV_READY; > > VHOST_LOG_CONFIG(INFO, > @@ -2425,6 +2431,39 @@ vhost_user_postcopy_end(struct virtio_net **pdev, > struct VhostUserMsg *msg, > return RTE_VHOST_MSG_RESULT_REPLY; > } > > +static int > +vhost_user_set_status(struct virtio_net **pdev, struct VhostUserMsg *msg, > + int main_fd __rte_unused) > +{ > + struct virtio_net *dev = *pdev; > +
Should we do 'validate_msg_fds' to avoid malicious messages as it is done in every message handler? Thanks, Chenbo > + /* As per Virtio specification, the device status is 8bits long */ > + if (msg->payload.u64 > UINT8_MAX) { > + VHOST_LOG_CONFIG(ERR, "Invalid VHOST_USER_SET_STATUS > payload 0x%" PRIx64 "\n", > + msg->payload.u64); > + return RTE_VHOST_MSG_RESULT_ERR; > + } > + > + dev->status = msg->payload.u64; > + > + VHOST_LOG_CONFIG(INFO, "New device status(0x%08x):\n" > + "\t-ACKNOWLEDGE: %u\n" > + "\t-DRIVER: %u\n" > + "\t-FEATURES_OK: %u\n" > + "\t-DRIVER_OK: %u\n" > + "\t-DEVICE_NEED_RESET: %u\n" > + "\t-FAILED: %u\n", > + dev->status, > + !!(dev->status & VIRTIO_DEVICE_STATUS_ACK), > + !!(dev->status & VIRTIO_DEVICE_STATUS_DRIVER), > + !!(dev->status & > VIRTIO_DEVICE_STATUS_FEATURES_OK), > + !!(dev->status & VIRTIO_DEVICE_STATUS_DRIVER_OK), > + !!(dev->status & > VIRTIO_DEVICE_STATUS_DEV_NEED_RESET), > + !!(dev->status & VIRTIO_DEVICE_STATUS_FAILED)); > + > + return RTE_VHOST_MSG_RESULT_OK; > +} > + > typedef int (*vhost_message_handler_t)(struct virtio_net **pdev, > struct VhostUserMsg *msg, > int main_fd); > @@ -2457,6 +2496,7 @@ static vhost_message_handler_t > vhost_message_handlers[VHOST_USER_MAX] = { > [VHOST_USER_POSTCOPY_END] = vhost_user_postcopy_end, > [VHOST_USER_GET_INFLIGHT_FD] = vhost_user_get_inflight_fd, > [VHOST_USER_SET_INFLIGHT_FD] = vhost_user_set_inflight_fd, > + [VHOST_USER_SET_STATUS] = vhost_user_set_status, > }; > > /* return bytes# of read on success or negative val on failure. */ diff --git > a/lib/librte_vhost/vhost_user.h b/lib/librte_vhost/vhost_user.h index > 1f65efa4a9..74fd361e3a 100644 > --- a/lib/librte_vhost/vhost_user.h > +++ b/lib/librte_vhost/vhost_user.h > @@ -23,7 +23,8 @@ > (1ULL << > VHOST_USER_PROTOCOL_F_CRYPTO_SESSION) | \ > (1ULL << > VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD) | \ > (1ULL << > VHOST_USER_PROTOCOL_F_HOST_NOTIFIER) | \ > - (1ULL << > VHOST_USER_PROTOCOL_F_PAGEFAULT)) > + (1ULL << > VHOST_USER_PROTOCOL_F_PAGEFAULT) | \ > + (1ULL << > VHOST_USER_PROTOCOL_F_STATUS)) > > typedef enum VhostUserRequest { > VHOST_USER_NONE = 0, > @@ -56,7 +57,8 @@ typedef enum VhostUserRequest { > VHOST_USER_POSTCOPY_END = 30, > VHOST_USER_GET_INFLIGHT_FD = 31, > VHOST_USER_SET_INFLIGHT_FD = 32, > - VHOST_USER_MAX = 33 > + VHOST_USER_SET_STATUS = 36, > + VHOST_USER_MAX = 37 > } VhostUserRequest; > > typedef enum VhostUserSlaveRequest { > -- > 2.25.4