[SLOF] [PATCH v2 13/19] virtio: make all virtio apis 1.0 aware

Alexey Kardashevskiy aik at ozlabs.ru
Fri Jan 22 15:56:09 AEDT 2016


On 01/20/2016 11:10 PM, Nikunj A Dadhania wrote:
> Convert the following routines:
>      virtio_get_qsize
>      virtio_vring_desc
>      virtio_get_vring_avail
>      virtio_get_vring_used
>      virtio_set_status: also use it in device reset.
>      virtio_queue_notify
>      virtio_set_qaddr
>      virtio_{get,read}_config
>      virtio_fill_desc
>
> Signed-off-by: Nikunj A Dadhania <nikunj at linux.vnet.ibm.com>
> ---
>   lib/libvirtio/virtio.c | 127 +++++++++++++++++++++++++++++++++++++++++--------
>   lib/libvirtio/virtio.h |   2 +-
>   2 files changed, 108 insertions(+), 21 deletions(-)
>
> diff --git a/lib/libvirtio/virtio.c b/lib/libvirtio/virtio.c
> index 1331efd..c2dd7dc 100644
> --- a/lib/libvirtio/virtio.c
> +++ b/lib/libvirtio/virtio.c
> @@ -94,11 +94,20 @@ unsigned long virtio_vring_size(unsigned int qsize)
>    * @param   queue virtio queue number
>    * @return  number of elements
>    */
> -int virtio_get_qsize(struct virtio_device *dev, int queue)
> +unsigned int virtio_get_qsize(struct virtio_device *dev, int queue)
>   {
> -	int size = 0;
> +	unsigned int size = 0;
>
> -	if (dev->type == VIRTIO_TYPE_PCI) {
> +	if (dev->type != VIRTIO_TYPE_PCI)
> +		return 0;
> +	if (dev->is_modern) {
> +		void *addr = dev->common.addr + offset_of(struct virtio_dev_common, q_select);
> +		ci_write_16(addr, cpu_to_le16(queue));
> +		eieio();
> +		/* read qsize */

addr = dev->common.addr + offset_of(struct virtio_dev_common, q_size);


> +		size = le16_to_cpu(ci_read_16(addr + 2));


size = le16_to_cpu(ci_read_16(addr));

as the legacy code uses VIRTIOHDR_QUEUE_SELECT and VIRTIOHDR_QUEUE_SIZE, 
not magic constant, like you have it done in virtio_get_vring_desc() and 
other places.


> +	}
> +	else {
>   		ci_write_16(dev->base+VIRTIOHDR_QUEUE_SELECT,
>   			    cpu_to_le16(queue));
>   		eieio();
> @@ -119,7 +128,16 @@ struct vring_desc *virtio_get_vring_desc(struct virtio_device *dev, int queue)
>   {
>   	struct vring_desc *desc = 0;
>
> -	if (dev->type == VIRTIO_TYPE_PCI) {
> +	if (dev->type != VIRTIO_TYPE_PCI)
> +		return NULL;
> +	if (dev->is_modern) {
> +		void *q_sel = dev->common.addr + offset_of(struct virtio_dev_common, q_select);
> +		void *q_desc = dev->common.addr + offset_of(struct virtio_dev_common, q_desc);
> +
> +		ci_write_16(q_sel, cpu_to_le16(queue));
> +		eieio();
> +		desc = (void *)(virtio_read64(q_desc));
> +	} else {
>   		ci_write_16(dev->base+VIRTIOHDR_QUEUE_SELECT,
>   			    cpu_to_le16(queue));
>   		eieio();
> @@ -139,8 +157,20 @@ struct vring_desc *virtio_get_vring_desc(struct virtio_device *dev, int queue)
>    */
>   struct vring_avail *virtio_get_vring_avail(struct virtio_device *dev, int queue)
>   {
> -	return (void*)((uint64_t)virtio_get_vring_desc(dev, queue)
> -		       + virtio_get_qsize(dev, queue) * sizeof(struct vring_desc));
> +	if (dev->type != VIRTIO_TYPE_PCI)
> +		return NULL;
> +	if (dev->is_modern) {
> +		void *q_sel = dev->common.addr + offset_of(struct virtio_dev_common, q_select);
> +		void *q_avail = dev->common.addr + offset_of(struct virtio_dev_common, q_avail);
> +
> +		ci_write_16(q_sel, cpu_to_le16(queue));
> +		eieio();
> +		return (void *)(virtio_read64(q_avail));
> +	}
> +	else {
> +		return (void*)((uint64_t)virtio_get_vring_desc(dev, queue) +
> +			       virtio_get_qsize(dev, queue) * sizeof(struct vring_desc));
> +	}
>   }
>
>
> @@ -152,9 +182,20 @@ struct vring_avail *virtio_get_vring_avail(struct virtio_device *dev, int queue)
>    */
>   struct vring_used *virtio_get_vring_used(struct virtio_device *dev, int queue)
>   {
> -	return (void*)VQ_ALIGN((uint64_t)virtio_get_vring_avail(dev, queue)
> -			       + virtio_get_qsize(dev, queue)
> -			       * sizeof(struct vring_avail));
> +	if (dev->type != VIRTIO_TYPE_PCI)
> +		return NULL;
> +	if (dev->is_modern) {
> +		void *q_sel = dev->common.addr + offset_of(struct virtio_dev_common, q_select);
> +		void *q_used = dev->common.addr + offset_of(struct virtio_dev_common, q_used);
> +
> +		ci_write_16(q_sel, cpu_to_le16(queue));
> +		eieio();
> +		return (void *)(virtio_read64(q_used));
> +	} else {
> +		return (void*)VQ_ALIGN((uint64_t)virtio_get_vring_avail(dev, queue)
> +				       + virtio_get_qsize(dev, queue)
> +				       * sizeof(struct vring_avail));
> +	}
>   }
>
>   /**
> @@ -182,9 +223,7 @@ void virtio_fill_desc(struct vring_desc *desc, bool is_modern,
>    */
>   void virtio_reset_device(struct virtio_device *dev)
>   {
> -	if (dev->type == VIRTIO_TYPE_PCI) {
> -		ci_write_8(dev->base+VIRTIOHDR_DEVICE_STATUS, 0);
> -	}
> +	virtio_set_status(dev, 0);
>   }
>
>
> @@ -193,7 +232,20 @@ void virtio_reset_device(struct virtio_device *dev)
>    */
>   void virtio_queue_notify(struct virtio_device *dev, int queue)
>   {
> -	if (dev->type == VIRTIO_TYPE_PCI) {
> +	if (dev->type != VIRTIO_TYPE_PCI)
> +		return;
> +	if (dev->is_modern) {
> +		void *q_sel = dev->common.addr + offset_of(struct virtio_dev_common, q_select);
> +		void *q_ntfy = dev->common.addr + offset_of(struct virtio_dev_common, q_notify_off);
> +		void *addr;
> +		uint16_t q_notify_off = 0;

Redundant "= 0".



-- 
Alexey


More information about the SLOF mailing list