[SLOF] [PATCH v2 15/19] virtio: 1.0 guest features negotiation
Thomas Huth
thuth at redhat.com
Thu Jan 21 08:04:17 AEDT 2016
On 20.01.2016 13:10, Nikunj A Dadhania wrote:
> With virtio 1.0, there feature negotiation step needs to be completed
> before starting to notify the device.
>
> This includes following steps:
> * Read host supported features
> * Check if virtio 1.0 is supported
> * Set guest supported features
> * Read host features and compare with the guest features.
> * Write FEATURES_OK and check it back to confirm.
>
> Add virtio_get_status supporting routine.
>
> Signed-off-by: Nikunj A Dadhania <nikunj at linux.vnet.ibm.com>
> ---
> lib/libvirtio/virtio.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
> lib/libvirtio/virtio.h | 4 +++-
> 2 files changed, 49 insertions(+), 2 deletions(-)
>
> diff --git a/lib/libvirtio/virtio.c b/lib/libvirtio/virtio.c
> index b88aa61..0b939fc 100644
> --- a/lib/libvirtio/virtio.c
> +++ b/lib/libvirtio/virtio.c
> @@ -299,7 +299,7 @@ int virtio_queue_init_vq(struct virtio_device *dev, struct vqs *vq, unsigned int
> /**
> * Set device status bits
> */
> -void virtio_set_status(struct virtio_device *dev, int status)
> +void virtio_set_status(struct virtio_device *dev, uint32_t status)
Why do you force an uint32_t here? That sounds like status would be a
32-bit type ... but in the PCI space, this is only a single byte...
so using "uint8_t" or keeping "int" would be better, I think.
> {
> if (dev->type != VIRTIO_TYPE_PCI)
> return;
> @@ -311,6 +311,20 @@ void virtio_set_status(struct virtio_device *dev, int status)
> }
> }
>
> +/**
> + * Get device status bits
> + */
> +void virtio_get_status(struct virtio_device *dev, uint32_t *status)
> +{
> + if (dev->type != VIRTIO_TYPE_PCI)
> + return;
> + if (dev->is_modern) {
> + *status = ci_read_8(dev->common.addr +
> + offset_of(struct virtio_dev_common, dev_status));
> + } else {
> + *status = ci_read_8(dev->base+VIRTIOHDR_DEVICE_STATUS);
> + }
> +}
>
> /**
> * Set guest feature bits
> @@ -380,6 +394,37 @@ void virtio_get_host_features_long(struct virtio_device *dev, uint64_t *features
> }
> }
>
> +int virtio_negotiate_guest_features(struct virtio_device *dev, uint64_t features)
> +{
> + uint64_t host_features = 0;
> + uint32_t status;
> +
> + /* Negotiate features */
> + virtio_get_host_features_long(dev, &host_features);
> + if (!(host_features & VIRTIO_F_VERSION_1)) {
> + fprintf(stderr, "Device does not support virtio 1.0 %llx\n", host_features);
> + return false;
> + }
> +
> + virtio_set_guest_features_long(dev, features);
> + virtio_get_host_features_long(dev, &host_features);
> + if ((host_features & features) != features) {
> + fprintf(stderr, "Features error %llx\n", features);
> + return false;
> + }
> +
> + virtio_get_status(dev, &status);
> + status |= VIRTIO_STAT_FEATURES_OK;
> + virtio_set_status(dev, status);
> +
> + /* Read back to verify the FEATURES_OK bit */
> + virtio_get_status(dev, &status);
> + if ((status & VIRTIO_STAT_FEATURES_OK) != VIRTIO_STAT_FEATURES_OK)
> + return false;
> +
> + return true;
> +}
May I suggest to either change the return type into "bool" instead of
"int", or to return 0 for success and a negative error code for failures?
Thomas
More information about the SLOF
mailing list