virtualization.lists.linux-foundation.org archive mirror
 help / color / mirror / Atom feed
From: "Michael S. Tsirkin" <mst@redhat.com>
To: Rusty Russell <rusty@rustcorp.com.au>
Cc: virtualization@lists.linux-foundation.org
Subject: Re: [PATCH 16/22] virtio_pci: use separate notification offsets for each vq.
Date: Thu, 21 Mar 2013 12:13:00 +0200	[thread overview]
Message-ID: <20130321101300.GA30493@redhat.com> (raw)
In-Reply-To: <1363854584-25795-17-git-send-email-rusty@rustcorp.com.au>

On Thu, Mar 21, 2013 at 06:59:37PM +1030, Rusty Russell wrote:
> (MST, is this what you were thinking?)

Almost.

Three points:

1. this is still an offset in BAR so for KVM we are still forced to use
an IO BAR.  I would like an option for hypervisor to simply say "Do IO
to this fixed address for this VQ". Then virtio can avoid using IO BARs
completely.

2.  for a real virtio device, offset is only 16 bit, using a 32 bit
offset in a memory BAR giving each VQ a separate 4K page would allow
priveledge separation where e.g. RXVQ/TXVQ are passed through to
hardware but CVQ is handled by the hypervisor.

3. last thing - (1) applies to ISR reads as well.

So I had in mind a structure like:

	struct vq_notify {
		u32 offset;
		u16 data;
		u16 flags;
	}

enum vq_notify_flags {
	VQ_NOTIFY_BAR0,
	VQ_NOTIFY_BAR1,
	VQ_NOTIFY_BAR2,
	VQ_NOTIFY_BAR3,
	VQ_NOTIFY_BAR4,
	VQ_NOTIFY_BAR5,
	VQ_NOTIFY_FIXED_IOPORT,
}

And then to notify a vq we write a given data at given offset
or into a given port for VQ_NOTIFY_FIXED_IOPORT.

Only point 1 is really important for me though, I can be
flexible on the rest of it.


> This uses the previously-unused field for "queue_notify".  This contains
> the offset from the notification area given by the VIRTIO_PCI_CAP_NOTIFY_CFG
> header.
> 
> (A device can still make them all overlap if it wants, since the queue
> index is written: it can still distinguish different notifications).
> 
> Cc: "Michael S. Tsirkin" <mst@redhat.com>
> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
> ---
>  drivers/virtio/virtio_pci.c     |   61 +++++++++++++++++++++++++++------------
>  include/uapi/linux/virtio_pci.h |    2 +-
>  2 files changed, 44 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c
> index f252afe..d492361 100644
> --- a/drivers/virtio/virtio_pci.c
> +++ b/drivers/virtio/virtio_pci.c
> @@ -37,11 +37,15 @@ struct virtio_pci_device {
>  	struct virtio_pci_common_cfg __iomem *common;
>  	/* Where to read and clear interrupt */
>  	u8 __iomem *isr;
> -	/* Write the virtqueue index here to notify device of activity. */
> -	__le16 __iomem *notify;
> +	/* Write the vq index here to notify device of activity. */
> +	void __iomem *notify_base;
>  	/* Device-specific data. */
>  	void __iomem *device;
>  
> +	/* So we can sanity-check accesses. */
> +	size_t notify_len;
> +	size_t device_len;
> +
>  	/* a list of queues so we can dispatch IRQs */
>  	spinlock_t lock;
>  	struct list_head virtqueues;
> @@ -84,6 +88,9 @@ struct virtio_pci_vq_info {
>  	/* the list node for the virtqueues list */
>  	struct list_head node;
>  
> +	/* Notify area for this vq. */
> +	u16 __iomem *notify;
> +
>  	/* MSI-X vector (or none) */
>  	unsigned msix_vector;
>  };
> @@ -240,11 +247,11 @@ static void vp_reset(struct virtio_device *vdev)
>  /* the notify function used when creating a virt queue */
>  static void vp_notify(struct virtqueue *vq)
>  {
> -	struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev);
> +	struct virtio_pci_vq_info *info = vq->priv;
>  
> -	/* we write the queue's selector into the notification register to
> -	 * signal the other end */
> -	iowrite16(vq->index, vp_dev->notify);
> +	/* we write the queue selector into the notification register
> +	 * to signal the other end */
> +	iowrite16(vq->index, info->notify);
>  }
>  
>  /* Handle a configuration change: Tell driver if it wants to know. */
> @@ -460,7 +467,7 @@ static struct virtqueue *setup_vq(struct virtio_device *vdev, unsigned index,
>  	struct virtio_pci_vq_info *info;
>  	struct virtqueue *vq;
>  	u16 num;
> -	int err;
> +	int err, off;
>  
>  	if (index >= ioread16(&vp_dev->common->num_queues))
>  		return ERR_PTR(-ENOENT);
> @@ -492,6 +499,17 @@ static struct virtqueue *setup_vq(struct virtio_device *vdev, unsigned index,
>  
>  	info->msix_vector = msix_vec;
>  
> +	/* get offset of notification byte for this virtqueue */
> +	off = ioread16(&vp_dev->common->queue_notify);
> +	if (off > vp_dev->notify_len) {
> +		dev_warn(&vp_dev->pci_dev->dev,
> +			 "bad notification offset %u for queue %u (> %u)",
> +			 off, index, vp_dev->notify_len);
> +		err = -EINVAL;
> +		goto out_info;
> +	}
> +	info->notify = vp_dev->notify_base + off;
> +
>  	info->queue = alloc_virtqueue_pages(&num);
>  	if (info->queue == NULL) {
>  		err = -ENOMEM;
> @@ -787,7 +805,8 @@ static void virtio_pci_release_dev(struct device *_d)
>  	 */
>  }
>  
> -static void __iomem *map_capability(struct pci_dev *dev, int off, size_t expect)
> +static void __iomem *map_capability(struct pci_dev *dev, int off, size_t minlen,
> +				    size_t *len)
>  {
>  	u8 bar;
>  	u32 offset, length;
> @@ -800,13 +819,16 @@ static void __iomem *map_capability(struct pci_dev *dev, int off, size_t expect)
>  	pci_read_config_dword(dev, off + offsetof(struct virtio_pci_cap, length),
>  			     &length);
>  
> -	if (length < expect) {
> +	if (length < minlen) {
>  		dev_err(&dev->dev,
> -			"virtio_pci: small capability len %u (%u expected)\n",
> -			length, expect);
> +			"virtio_pci: small capability len %u (%zu expected)\n",
> +			length, minlen);
>  		return NULL;
>  	}
>  
> +	if (len)
> +		*len = length;
> +
>  	/* We want uncachable mapping, even if bar is cachable. */
>  	p = pci_iomap_range(dev, bar, offset, length, PAGE_SIZE, true);
>  	if (!p)
> @@ -883,16 +905,19 @@ static int virtio_pci_probe(struct pci_dev *pci_dev,
>  
>  	err = -EINVAL;
>  	vp_dev->common = map_capability(pci_dev, common,
> -					sizeof(struct virtio_pci_common_cfg));
> +					sizeof(struct virtio_pci_common_cfg),
> +					NULL);
>  	if (!vp_dev->common)
>  		goto out_req_regions;
> -	vp_dev->isr = map_capability(pci_dev, isr, sizeof(u8));
> +	vp_dev->isr = map_capability(pci_dev, isr, sizeof(u8), NULL);
>  	if (!vp_dev->isr)
>  		goto out_map_common;
> -	vp_dev->notify = map_capability(pci_dev, notify, sizeof(u16));
> -	if (!vp_dev->notify)
> +	vp_dev->notify_base = map_capability(pci_dev, notify, sizeof(u8),
> +					     &vp_dev->notify_len);
> +	if (!vp_dev->notify_len)
>  		goto out_map_isr;
> -	vp_dev->device = map_capability(pci_dev, device, 0);
> +	vp_dev->device = map_capability(pci_dev, device, 0,
> +					&vp_dev->device_len);
>  	if (!vp_dev->device)
>  		goto out_map_notify;
>  
> @@ -917,7 +942,7 @@ out_set_drvdata:
>  	pci_set_drvdata(pci_dev, NULL);
>  	pci_iounmap(pci_dev, vp_dev->device);
>  out_map_notify:
> -	pci_iounmap(pci_dev, vp_dev->notify);
> +	pci_iounmap(pci_dev, vp_dev->notify_base);
>  out_map_isr:
>  	pci_iounmap(pci_dev, vp_dev->isr);
>  out_map_common:
> @@ -940,7 +965,7 @@ static void virtio_pci_remove(struct pci_dev *pci_dev)
>  	vp_del_vqs(&vp_dev->vdev);
>  	pci_set_drvdata(pci_dev, NULL);
>  	pci_iounmap(pci_dev, vp_dev->device);
> -	pci_iounmap(pci_dev, vp_dev->notify);
> +	pci_iounmap(pci_dev, vp_dev->notify_base);
>  	pci_iounmap(pci_dev, vp_dev->isr);
>  	pci_iounmap(pci_dev, vp_dev->common);
>  	pci_release_regions(pci_dev);
> diff --git a/include/uapi/linux/virtio_pci.h b/include/uapi/linux/virtio_pci.h
> index b334cd9..23b90cb 100644
> --- a/include/uapi/linux/virtio_pci.h
> +++ b/include/uapi/linux/virtio_pci.h
> @@ -144,13 +144,13 @@ struct virtio_pci_common_cfg {
>  	__le16 num_queues;		/* read-only */
>  	__u8 device_status;		/* read-write */
>  	__u8 unused1;
> -	__le16 unused2;
>  
>  	/* About a specific virtqueue. */
>  	__le16 queue_select;	/* read-write */
>  	__le16 queue_size;	/* read-write, power of 2. */
>  	__le16 queue_msix_vector;/* read-write */
>  	__le16 queue_enable;	/* read-write */
> +	__le16 queue_notify;	/* read-only */
>  	__le64 queue_desc;	/* read-write */
>  	__le64 queue_avail;	/* read-write */
>  	__le64 queue_used;	/* read-write */
> -- 
> 1.7.10.4
> 
> _______________________________________________
> Virtualization mailing list
> Virtualization@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/virtualization

  reply	other threads:[~2013-03-21 10:13 UTC|newest]

Thread overview: 94+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-03-21  8:29 [PATCH 00/22] New virtio PCI layout Rusty Russell
2013-03-21  8:29 ` [PATCH 01/22] virtio_config: introduce size-based accessors Rusty Russell
2013-03-21  8:29 ` [PATCH 02/22] virtio_config: use " Rusty Russell
2013-03-21  8:29 ` [PATCH 03/22] virtio_config: make transports implement accessors Rusty Russell
2013-03-21  9:09   ` Cornelia Huck
2013-03-22  0:31     ` Rusty Russell
2013-03-22  9:13       ` Cornelia Huck
2013-03-22 14:43   ` Sjur Brændeland
2013-03-24  4:24     ` Rusty Russell
2013-04-03 15:58       ` Sjur Brændeland
2013-04-02 17:16   ` Pawel Moll
2013-03-21  8:29 ` [PATCH 04/22] virtio: use u32, not bitmap for struct virtio_device's features Rusty Russell
2013-03-21 10:00   ` Cornelia Huck
2013-03-22  0:48     ` Rusty Russell
2013-03-21  8:29 ` [PATCH 05/22] virtio: add support for 64 bit features Rusty Russell
2013-03-21 10:06   ` Cornelia Huck
2013-03-22  0:50     ` Rusty Russell
2013-03-22  9:15       ` Cornelia Huck
2013-03-22 14:50     ` Sjur Brændeland
2013-03-22 20:12       ` Ohad Ben-Cohen
2013-03-25  8:30         ` Rusty Russell
2013-04-02 17:09   ` Pawel Moll
2013-03-21  8:29 ` [PATCH 06/22] virtio: move vring structure into struct virtqueue Rusty Russell
2013-03-21  8:29 ` [PATCH 07/22] pci: add pci_iomap_range Rusty Russell
2013-03-21  8:29 ` [PATCH 08/22] virtio-pci: define layout for virtio vendor-specific capabilities Rusty Russell
2013-03-21  8:29 ` [PATCH 09/22] virtio_pci: move old defines to legacy, introduce new structure Rusty Russell
2013-03-21  8:29 ` [PATCH 10/22] virtio_pci: use _LEGACY_ defines in virtio_pci_legacy.c Rusty Russell
2013-03-21  8:29 ` [PATCH 11/22] virtio_pci: don't use the legacy driver if we find the new PCI capabilities Rusty Russell
2013-03-21  8:29 ` [PATCH 12/22] virtio_pci: allow duplicate capabilities Rusty Russell
2013-03-21 10:28   ` Michael S. Tsirkin
2013-03-21 14:26     ` H. Peter Anvin
2013-03-21 14:43       ` Michael S. Tsirkin
2013-03-21 14:45         ` H. Peter Anvin
2013-03-21 15:19           ` Michael S. Tsirkin
2013-03-21 15:26             ` H. Peter Anvin
2013-03-21 15:58               ` Michael S. Tsirkin
2013-03-21 16:04                 ` H. Peter Anvin
2013-03-21 16:11                   ` Michael S. Tsirkin
2013-03-21 16:15                     ` H. Peter Anvin
2013-03-21 16:26                       ` Michael S. Tsirkin
2013-03-21 16:32                         ` H. Peter Anvin
2013-03-21 17:07                           ` Michael S. Tsirkin
2013-03-21 17:09                             ` H. Peter Anvin
2013-03-21 17:13                               ` Michael S. Tsirkin
2013-03-21 17:49                                 ` Michael S. Tsirkin
2013-03-21 17:54                                   ` H. Peter Anvin
2013-03-21 18:01                                     ` Michael S. Tsirkin
2013-03-22  0:57                                     ` Rusty Russell
2013-03-22  3:17                                       ` H. Peter Anvin
2013-03-24 13:14                                       ` Michael S. Tsirkin
2013-03-24 23:23                                         ` H. Peter Anvin
2013-03-25  6:53                                           ` Michael S. Tsirkin
2013-03-25  6:54                                             ` H. Peter Anvin
2013-03-25 10:03                                               ` Rusty Russell
2013-03-21  8:29 ` [PATCH 13/22] virtio_pci: new, capability-aware driver Rusty Russell
2013-03-21 10:24   ` Michael S. Tsirkin
2013-03-22  1:02     ` Rusty Russell
2013-03-24 13:08       ` Michael S. Tsirkin
2013-03-21  8:29 ` [PATCH 14/22] virtio_pci: layout changes as per hpa's suggestions Rusty Russell
2013-03-21  8:29 ` [PATCH 15/22] virtio_pci: use little endian for config space Rusty Russell
2013-03-21  8:29 ` [PATCH 16/22] virtio_pci: use separate notification offsets for each vq Rusty Russell
2013-03-21 10:13   ` Michael S. Tsirkin [this message]
2013-03-21 10:35     ` Michael S. Tsirkin
2013-03-22  2:52     ` Rusty Russell
2013-03-24 14:38       ` Michael S. Tsirkin
2013-03-24 20:19       ` Michael S. Tsirkin
2013-03-24 23:27         ` H. Peter Anvin
2013-03-25  7:05           ` Michael S. Tsirkin
2013-03-25 10:00         ` Rusty Russell
2013-03-26 19:39           ` Michael S. Tsirkin
2013-03-27  0:07             ` Rusty Russell
2013-03-27  0:22               ` H. Peter Anvin
2013-03-27  2:31                 ` H. Peter Anvin
2013-03-27 11:26                   ` Michael S. Tsirkin
2013-03-27 14:21                     ` H. Peter Anvin
2013-03-27 11:25               ` Michael S. Tsirkin
2013-03-28  4:50                 ` H. Peter Anvin
2013-03-30  3:19                   ` Rusty Russell
2013-04-02 22:51                     ` H. Peter Anvin
2013-04-03  6:10                       ` Rusty Russell
2013-04-03 11:22                         ` Michael S. Tsirkin
2013-04-03 14:10                           ` H. Peter Anvin
2013-04-03 14:35                             ` Michael S. Tsirkin
2013-04-03 14:35                               ` H. Peter Anvin
2013-04-03 17:02                                 ` Michael S. Tsirkin
2013-04-04  5:48                           ` Rusty Russell
2013-04-04  8:25                             ` Michael S. Tsirkin
2013-04-05  1:25                               ` Rusty Russell
2013-03-21  8:29 ` [PATCH 17/22] virtio_pci_legacy: cleanup struct virtio_pci_vq_info Rusty Russell
2013-03-21  8:29 ` [PATCH 18/22] virtio_pci: share structure between legacy and modern Rusty Russell
2013-03-21  8:29 ` [PATCH 19/22] virtio_pci: share interrupt/notify handlers " Rusty Russell
2013-03-21  8:29 ` [PATCH 20/22] virtio_pci: share virtqueue setup/teardown between modern and legacy driver Rusty Russell
2013-03-21  8:29 ` [PATCH 21/22] virtio_pci: simplify common helpers Rusty Russell
2013-03-21  8:29 ` [PATCH 22/22] virtio_pci: fix finalize_features in modern driver Rusty Russell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20130321101300.GA30493@redhat.com \
    --to=mst@redhat.com \
    --cc=rusty@rustcorp.com.au \
    --cc=virtualization@lists.linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).