On Fri, Jul 18, 2025 at 4:53 PM Paolo Abeni <pab...@redhat.com> wrote:
>
> Similar to virtio infra, vhost core maintains the features status
> in the full extended format and allows the devices to implement
> extended version of the getter/setter.
>
> Note that 'protocol_features' are not extended: they are only
> used by vhost-user, and the latter device is not going to implement
> extended features soon.
>
> Signed-off-by: Paolo Abeni <pab...@redhat.com>
> ---
> v2 -> v3:
>   - fix compile warning
>   - _array -> _ex
>
> v1 -> v2:
>   - uint128_t -> uint64_t[]
>   - add _ex() variant of features manipulation helpers
> ---
>  hw/virtio/vhost.c                 | 73 +++++++++++++++++++++++++++----
>  include/hw/virtio/vhost-backend.h |  6 +++
>  include/hw/virtio/vhost.h         | 33 ++++++++++++--
>  3 files changed, 100 insertions(+), 12 deletions(-)
>
> diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
> index c30ea1156e..85ae1e4d4c 100644
> --- a/hw/virtio/vhost.c
> +++ b/hw/virtio/vhost.c
> @@ -972,20 +972,34 @@ static int vhost_virtqueue_set_addr(struct vhost_dev 
> *dev,
>  static int vhost_dev_set_features(struct vhost_dev *dev,
>                                    bool enable_log)
>  {
> -    uint64_t features = dev->acked_features;
> +    uint64_t features[VIRTIO_FEATURES_DWORDS];
>      int r;
> +
> +    virtio_features_copy(features, dev->acked_features_ex);
>      if (enable_log) {
> -        features |= 0x1ULL << VHOST_F_LOG_ALL;
> +        virtio_add_feature_ex(features, VHOST_F_LOG_ALL);
>      }
>      if (!vhost_dev_has_iommu(dev)) {
> -        features &= ~(0x1ULL << VIRTIO_F_IOMMU_PLATFORM);
> +        virtio_clear_feature_ex(features, VIRTIO_F_IOMMU_PLATFORM);
>      }
>      if (dev->vhost_ops->vhost_force_iommu) {
>          if (dev->vhost_ops->vhost_force_iommu(dev) == true) {
> -            features |= 0x1ULL << VIRTIO_F_IOMMU_PLATFORM;
> +            virtio_add_feature_ex(features, VIRTIO_F_IOMMU_PLATFORM);
>         }
>      }
> -    r = dev->vhost_ops->vhost_set_features(dev, features);
> +
> +    if (virtio_features_use_extended(features) &&
> +        !dev->vhost_ops->vhost_set_features_ex) {
> +        VHOST_OPS_DEBUG(r, "extended features without device support");
> +        r = -EINVAL;
> +        goto out;
> +    }
> +
> +    if (dev->vhost_ops->vhost_set_features_ex) {
> +        r = dev->vhost_ops->vhost_set_features_ex(dev, features);
> +    } else {
> +        r = dev->vhost_ops->vhost_set_features(dev, features[0]);
> +    }
>      if (r < 0) {
>          VHOST_OPS_DEBUG(r, "vhost_set_features failed");
>          goto out;
> @@ -1506,12 +1520,27 @@ static void vhost_virtqueue_cleanup(struct 
> vhost_virtqueue *vq)
>      }
>  }
>
> +static int vhost_dev_get_features(struct vhost_dev *hdev,
> +                                  uint64_t *features)
> +{
> +    uint64_t features64;
> +    int r;
> +
> +    if (hdev->vhost_ops->vhost_get_features_ex) {
> +        return hdev->vhost_ops->vhost_get_features_ex(hdev, features);
> +    }
> +
> +    r = hdev->vhost_ops->vhost_get_features(hdev, &features64);
> +    virtio_features_from_u64(features, features64);
> +    return r;
> +}

Nit: let's have a vhost_dev_set_features() as well?

Thanks


Reply via email to