virtualization.lists.linux-foundation.org archive mirror
 help / color / mirror / Atom feed
From: Arnd Bergmann <arnd@arndb.de>
To: virtualization@lists.linux-foundation.org
Subject: Re: [RFC 1/4] New virtio bus driver
Date: Sun, 8 Jul 2007 22:29:00 +0200	[thread overview]
Message-ID: <200707082229.00810.arnd@arndb.de> (raw)
In-Reply-To: <4691076B.5050106@qumranet.com>

On Sunday 08 July 2007, Avi Kivity wrote:

> > Alternatively, we could have a mechanism separate from the
> > virtqueue concept, like a synchronous get_config_data/set_config_data
> > callback into the host driver.
> >   
> 
> You also need to allow the host to notify the guest about configuration 
> changes.

That is much harder to do, it would require a separate interrupt if you
want to have a device independent mechanism. Most real buses (like PCI)
don't have this, so I'm not sure it's good to do this at the virtio
layer. You already listed the media change notification, which can
be handled without this by either removing and adding the complete
virtio device, or by using a channel for out-of-band data like scsi.
 
> > So in your example, you get
> >
> > virtnet.ko (, virtblock.ko, hwrng-virtio.ko, ...): host-independent
> >   device driver
> > virtbus-lguest.ko, virtbus-kvm.ko, virtbus-pci.ko, virtbus-xen.ko:
> >   device independent host drivers
> >
> > In cases where some of the code can be shared, e.g. virtbus-lguest
> > and virtbus-kvm, you can have multiple host drivers sharing part
> > of their code by using symbols from a library module, but my basic
> > idea is that each host driver has a single module that handles
> > the transport and the device probing.
> >   
> 
> Is that module linked to both the pci libraries and the virtbus 
> libraries?  Or does virtbus abstract pci in some way?

The virtbus-pci module would be linked against both the virtio_bus
and against the pci layer, like this (not compile tested):

========
#define MAX_PCI_VIRTQUEUES 8

struct virtio_pci_config {
	char pci_config[64]; /* standard config space */
	char device_type[16]; /* for matching the driver */
	__le16 virtqueue_id[MAX_PCI_VIRTQUEUES]; /* global IDs */
	__le16 device_hd /* global device id */
	u8 num_virtqueues;
	char pad[31]; /* host config space is 128 bytes */
};

struct virtio_pci_device {
	struct virtio_device vdev;
	struct virtio_pci_config *config;
	/* more data related to the transport, as needed */
};

static struct virtio_device_ops virtbus_pci_hcall_ops = {
	...
};

/* irq: one of the queues for this device wants a callback */
static int virtbus_pci_irq(int irq, void *data)
{
	struct virtio_pci_device *pdev = data;
	unsigned int irq_mask;
	int i;
	
	/* note: this hcall could easily be an mmio read from one
	   of the PCI BARs, if we went to a model without hcalls. */
	irq_mask = hcall_get_pending_queues(pdev->config->device_id);

	for (i=0; i < pdev->config->num_virqueues; i++) {
		if (irq_mask & 1) {
			struct virtqueue *vq = &pdev->vdev.virtqueue[i];
			vq->cb(vq);
		}
	}
}

/* probe: we have found a PCI device for us, now create the virtio device as
   a child device below it */
static int virtbus_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
	struct virtio_pci_device *pdev;
	int i;
	char *config;
	int ret;

	pdev = kzalloc(sizeof (*pdev), GFP_KERNEL);
	if (!pdev)
		return -ENOMEM;

	/* copy PCI config space data into virtio_device */
	config = (void *)&pdev->vdev.config;
	for (i = 0; i < 256; i++) {
		ret = pci_read_config_byte(dev, i, config + i);
		if (ret)
			goto out;
	}

	/* set up device so we can register it */
	pdev->config = (void *)&pdev->vdev.config;
	pdev->vdev.dev.parent = &dev->dev;
	pdev->vdev.ops = &virtbus_pci_hcall_ops;
	pdev->vdev.device_type = pdev->device_type;
	dev->dev.driver_data = pdev;
	snprintf(pdev->vdev.dev.bus_id, BUS_ID_SIZE, "pciv:%s",
		 &dev->dev.bus_id);

	ret = request_irq(dev->irq, virtbus_pci_irq, IRQF_SHARED,
			pdev->vdev.dev.bus_id, pdev);
	if (ret)
		goto out;

	ret = virtio_device_register(&pdev->vdev,
				pdev->config.num_virtqueues);
	if (ret)
		goto out_irq;

	return 0;

out_irq:
	free_irq(dev->irq);
out:
	dev->driver_data = NULL;
	kfree(pdev);
	return ret;
}

static void virtbus_pci_remove(struct pci_dev *dev)
{
	struct virtio_pci_device *pdev = dev->dev.driver_data;
	virtio_device_unregister(pdev);
	free_irq(dev->irq, pdev);
	dev->driver_data = NULL;
	kfree(pdev);
}

static struct pci_device_id virtbus_pci_ids = {
	{ PCI_DEVICE(PCI_VENDOR_LINUX, PCI_DEVICE_VIRTIO_RAW), },
	{},
};
MODULE_DEVICE_TABLE(pci, virtbus_pci_ids);

static struct pci_driver virtbus_pci = {
	.name = "virtbus_pci_hcall",
	.probe = virtbus_pci_probe,
	.id_table = &virtbus_pci_ids,
};

static int __init virtbus_pci_init(void)
{
	return pci_register_driver(&virtbus_pci);
}
module_init(virtbus_pci_init);

  reply	other threads:[~2007-07-08 20:29 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-07-06 12:42 [RFC 0/4] Using a generic bus_type for virtio arnd
2007-07-06 12:42 ` [RFC 1/4] New virtio bus driver arnd
2007-07-08  9:59   ` Avi Kivity
2007-07-08 15:29     ` Arnd Bergmann
2007-07-08 15:48       ` Avi Kivity
2007-07-08 20:29         ` Arnd Bergmann [this message]
2007-07-08 23:42           ` Rusty Russell
2007-07-09  6:49           ` Avi Kivity
2007-07-09 11:18             ` Arnd Bergmann
2007-07-09 11:41               ` Avi Kivity
2007-07-09 11:38                 ` Arnd Bergmann
2007-07-09 12:09                   ` Avi Kivity
2007-07-09 14:24                     ` Arnd Bergmann
2007-07-09 14:56                       ` Avi Kivity
2007-07-09 16:33                         ` Arnd Bergmann
2007-07-10  1:53                     ` Rusty Russell
2007-07-10  7:56                       ` Avi Kivity
2007-07-10  1:17             ` Rusty Russell
2007-07-10  6:06               ` Avi Kivity
2007-07-06 12:42 ` [RFC 2/4] Convert virtio_net to new virtio bus arnd
2007-07-06 12:42 ` [RFC 3/4] Convert virtio_blk " arnd
2007-07-06 12:42 ` [RFC 4/4] Example virtio host implementation, using chardev arnd
2007-07-08  2:15 ` [RFC 0/4] Using a generic bus_type for virtio Rusty Russell
2007-07-08  9:45   ` Avi Kivity
2007-07-08 15:55   ` Arnd Bergmann
2007-07-08  9:42 ` Avi Kivity

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=200707082229.00810.arnd@arndb.de \
    --to=arnd@arndb.de \
    --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).