PV devices are currently discovered by pci bus.
It is standard bus for x86 and good for HVM guests.
Further flexibility will be achieved by a virtual bus, although
some HVM guest will still require pci.

Signed-off-by: Dor Laor <[EMAIL PROTECTED]>
---
 drivers/kvm/Makefile      |    2 +-
 drivers/kvm/kvm_pci_bus.c |  158
+++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 159 insertions(+), 1 deletions(-)
 create mode 100644 drivers/kvm/kvm_pci_bus.c

diff --git a/drivers/kvm/Makefile b/drivers/kvm/Makefile
index 7f5607d..e51dba4 100644
--- a/drivers/kvm/Makefile
+++ b/drivers/kvm/Makefile
@@ -8,7 +8,7 @@ kvm-intel-objs = vmx.o
 obj-$(CONFIG_KVM_INTEL) += kvm-intel.o
 kvm-amd-objs = svm.o
 obj-$(CONFIG_KVM_AMD) += kvm-amd.o
-kvm-pv-objs = kvm_pv.o
+kvm-pv-objs = kvm_pv.o kvm_pci_bus.o
 obj-$(CONFIG_KVM_PV) += kvm-pv.o
 virtio-be-objs = virtio_backend.o
 obj-$(CONFIG_VIRTIO_BE) += virtio-be.o
diff --git a/drivers/kvm/kvm_pci_bus.c b/drivers/kvm/kvm_pci_bus.c
new file mode 100644
index 0000000..c06771e
--- /dev/null
+++ b/drivers/kvm/kvm_pci_bus.c
@@ -0,0 +1,158 @@
+/*
+ * KVM virtio pci bus backend implementation
+ *
+ * Copyright (C) 2007, Qumranet, Inc., Dor Laor <[EMAIL PROTECTED]>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
See
+ * the COPYING file in the top-level directory.
+ */
+
+//#define DEBUG
+#include <linux/virtio.h>
+#include <linux/spinlock.h>
+#include <linux/kvm.h>
+#include <linux/kvm_para.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <asm/hypercall.h>
+#include <asm/io.h>
+#include "kvm_pv.h"
+#include "virtio_backend.h"
+
+static int debug = 3;
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
+
+#define DPRINTK(klevel, fmt, args...) \
+       if (('0' + debug) >= (int)(klevel[1])) \
+               printk(klevel "%s:%d: " fmt, \
+                       __FUNCTION__, __LINE__, ## args)
+
+/*
+ * Map between a pci device to it's dma key.
+ * It uses io port read to read the key value from the 
+ * pci device.
+ */
+static int get_device_key(struct pci_dev *pdev, unsigned int *key)
+{
+        unsigned long ioaddr;
+        int rc;
+        unsigned long pio_start, pio_end, pio_flags, pio_len;
+
+        rc = pci_enable_device(pdev);
+        if (rc)
+                goto err_out;
+
+        pio_start = pci_resource_start (pdev, 0);
+        pio_end = pci_resource_end (pdev, 0);
+        pio_flags = pci_resource_flags (pdev, 0);
+        pio_len = pci_resource_len (pdev, 0);
+
+        DPRINTK(KERN_DEBUG, "PIO region size == 0x%lx\n", pio_len);
+
+        rc = pci_request_regions (pdev, "kvm_virtio");
+        if (rc) {
+               DPRINTK(KERN_DEBUG, "Failed register pci region\n");
+                goto err_out;
+       }
+
+        ioaddr = (unsigned long)pci_iomap(pdev, 0, 0);
+        if (!ioaddr) {
+                printk(KERN_ERR "%s: cannot map PIO, aborting\n",
pci_name(pdev));
+                rc = -EIO;
+                goto err_out;
+        }
+
+       DPRINTK(KERN_DEBUG, "ioaddr is %lx\n", ioaddr);
+       *key = ioread32((void __iomem*)ioaddr);
+       DPRINTK(KERN_DEBUG, "Got key = %d\n", *key);
+       *key = 0;
+
+err_out:
+        return rc;
+}
+
+/*
+ * General pci init function
+ */
+int kvmbus_init_one(struct pci_dev *pdev,
+                   const struct pci_device_id *ent,
+                   struct virtio_bus *vbus,
+                   u16 dev_type)
+{
+       struct virtio_device *vdev;
+       u8 pci_rev;
+       int rs;
+
+       vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
+       if (vdev < 0) {
+               DPRINTK(KERN_ERR, "failed allocating virtio_device");
+               return ENOMEM;
+       }
+
+       pci_set_drvdata(pdev, vdev);
+
+       if ((rs = kvm_guest_register_para(raw_smp_processor_id())) != 0)
{
+               DPRINTK(KERN_ERR, "failed registering para\n");
+               goto out_unreg_para;
+       }
+
+       DPRINTK(KERN_DEBUG, "irq is %d\n", pdev->irq);
+
+       pci_read_config_byte(pdev, PCI_REVISION_ID, &pci_rev);
+
+       DPRINTK(KERN_INFO, "pci dev %s (id %04x:%04x rev %02x) is a "
+               "guest paravirt %s device\n",
+               pci_name(pdev), pdev->vendor, pdev->device, pci_rev,
vbus->name);
+
+       vdev->dev.bus = pdev->dev.bus;
+       vdev->dev.parent = &pdev->dev;
+       sprintf(vdev->dev.bus_id, "%u", 0);
+       device_initialize(&vdev->dev);
+       if (device_register(&vdev->dev) != 0) {
+               DPRINTK(KERN_EMERG, "Cannot register device\n");
+               goto out_unreg_para;
+       }
+
+       if (get_device_key(pdev, &vdev->id) < 0) {
+               DPRINTK(KERN_ERR, "pci dev %s cannot use ioports\n",
pci_name(pdev));
+               goto out_unreg_para;
+       }
+        DPRINTK(KERN_DEBUG, "Got key = %x\n", vdev->id);
+
+       vdev->desc.irq = pdev->irq;
+       vdev->desc.type = dev_type;
+       vdev->desc.status = VIRTIO_DEVICE_S_DRIVER;
+
+
+       rs = vbus->vbus_probe(vdev);
+       if (vdev < 0) {
+               DPRINTK(KERN_ERR, "failed probing for %s, err=%d\n",
vbus->name, rs);
+               goto out_unreg_para;
+       }
+
+       return 0;
+
+out_unreg_para:
+       kfree(vdev);
+
+       return rs;
+}
+EXPORT_SYMBOL_GPL(kvmbus_init_one);
+
+void kvmbus_remove_one(struct pci_dev *pdev, struct virtio_bus *vbus)
+{
+       struct virtio_device *vdev = pci_get_drvdata(pdev);
+
+       vbus->vbus_unprobe(vdev);
+       kfree(vdev);
+       pci_disable_device(pdev);
+}
+EXPORT_SYMBOL_GPL(kvmbus_remove_one);
+
+MODULE_DESCRIPTION("KVM virtual pci bus driver");
+MODULE_LICENSE("GPL");
+
+

-----
In simplicity there is elegance.
Dor Laor ;)


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
_______________________________________________
kvm-devel mailing list
kvm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-devel

Reply via email to