From 49426147aace9bdcca4f9cdb803f8a248df57ce0 Mon Sep 17 00:00:00 2001 From: Liu Long Date: Wed, 11 May 2022 14:14:01 +0800 Subject: [PATCH] ACRN: DM: Fix the virtio negotiated features bug. The virtio feature bits is 64bits but the access will be split as two times 32bits access. This patch fixes the bug which overwrites another side 32bits, and causes feature bits are lost. Tracked-On: #7456 Signed-off-by: Liu Long Reviewed-by: Conghui Acked-by: Wang, Yu1 --- devicemodel/hw/pci/virtio/virtio.c | 13 ++++++++++--- devicemodel/include/vhost.h | 14 +++++++------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/devicemodel/hw/pci/virtio/virtio.c b/devicemodel/hw/pci/virtio/virtio.c index 58d935736..5c77fc900 100644 --- a/devicemodel/hw/pci/virtio/virtio.c +++ b/devicemodel/hw/pci/virtio/virtio.c @@ -1387,6 +1387,7 @@ virtio_common_cfg_write(struct pci_vdev *dev, uint64_t offset, int size, struct virtio_ops *vops; const struct config_reg *cr; const char *name; + uint64_t features = 0; vops = base->vops; name = vops->name; @@ -1421,9 +1422,15 @@ virtio_common_cfg_write(struct pci_vdev *dev, uint64_t offset, int size, break; if (base->driver_feature_select < 2) { value &= 0xffffffff; - base->negotiated_caps = - (value << (base->driver_feature_select * 32)) - & base->device_caps; + if (base->driver_feature_select == 0) { + features = base->device_caps & value; + base->negotiated_caps &= ~0xffffffffULL; + } else { + features = (value << 32) + & base->device_caps; + base->negotiated_caps &= 0xffffffffULL; + } + base->negotiated_caps |= features; if (vops->apply_features) (*vops->apply_features)(DEV_STRUCT(base), base->negotiated_caps); diff --git a/devicemodel/include/vhost.h b/devicemodel/include/vhost.h index bea28af16..945d890d0 100644 --- a/devicemodel/include/vhost.h +++ b/devicemodel/include/vhost.h @@ -20,7 +20,7 @@ * @brief vhost APIs * * @addtogroup acrn_virtio - * @{ + * */ struct vhost_vq { @@ -132,15 +132,15 @@ int vhost_dev_start(struct vhost_dev *vdev); int vhost_dev_stop(struct vhost_dev *vdev); /** - * @brief vhost kernel dev ioctrl function + * @brief vhost kernel dev ioctrl function. * * This interface is used to operation the vhost dev kernel. * - * @param vdev Pointer to struct vhost_dev - * @param The request to vhost kernel - * @param The arguments of vhost kernel operation + * @param vdev Pointer to struct vhost_dev. + * @param request to vhost kernel. + * @param arg of vhost kernel operation. * - * @return 0 on success and -1 on failure + * @return 0 on success and -1 on failure. */ int vhost_kernel_ioctl(struct vhost_dev *vdev, unsigned long int request, void *arg); -#endif +#endif /* __VHOST_H__ */