[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 6b/7] PCI device register/unregister + pci_dev cleanups



Option 2: Add PCI device add/remove guards to Linux

Before calling the device probe function and after calling the device
remove function invoke guard callbacks if so registered.  This option
may be viewed as cleaner.  It also proves helpful if someone wants to
implement coarse grained IOMMU protection in native Linux.

Signed-off-by: Espen Skoglund <espen.skoglund@xxxxxxxxxxxxx>


--
 b/drivers/xen/core/pci_guard.c |   47 +++++++++++++++++++++++++++++++++++++++++
 drivers/pci/pci-driver.c       |   11 +++++++--
 drivers/xen/core/Makefile      |    1 
 include/linux/pci.h            |   23 ++++++++++++++++++++
 4 files changed, 80 insertions(+), 2 deletions(-)
--
diff -r ef74eb78b86c drivers/pci/pci-driver.c
--- a/drivers/pci/pci-driver.c  Fri Jul 04 14:54:57 2008 +0100
+++ b/drivers/pci/pci-driver.c  Fri Jul 04 14:57:12 2008 +0100
@@ -16,6 +16,8 @@
 /*
  *  Registration of PCI drivers and handling of hot-pluggable devices.
  */
+
+struct pci_dev_guard *pci_dev_guard = NULL;
 
 /*
  * Dynamic device IDs are disabled for !CONFIG_HOTPLUG
@@ -233,9 +235,13 @@
        drv = to_pci_driver(dev->driver);
        pci_dev = to_pci_dev(dev);
        pci_dev_get(pci_dev);
-       error = __pci_device_probe(drv, pci_dev);
-       if (error)
+       error = pci_dev_guard_enable(pci_dev);
+        if (!error)
+               error = __pci_device_probe(drv, pci_dev);
+       if (error) {
+               pci_dev_guard_disable(pci_dev);
                pci_dev_put(pci_dev);
+       }
 
        return error;
 }
@@ -260,6 +266,7 @@
         * horrible the crap we have to deal with is when we are awake...
         */
 
+       pci_dev_guard_disable(pci_dev);
        pci_dev_put(pci_dev);
        return 0;
 }
diff -r ef74eb78b86c drivers/xen/core/Makefile
--- a/drivers/xen/core/Makefile Fri Jul 04 14:54:57 2008 +0100
+++ b/drivers/xen/core/Makefile Fri Jul 04 14:57:12 2008 +0100
@@ -12,3 +12,4 @@
 obj-$(CONFIG_XEN_SMPBOOT)      += smpboot.o
 obj-$(CONFIG_KEXEC)            += machine_kexec.o
 obj-$(CONFIG_XEN_XENCOMM)      += xencomm.o
+obj-$(CONFIG_PCI)              += pci_guard.o
diff -r ef74eb78b86c drivers/xen/core/pci_guard.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/xen/core/pci_guard.c      Fri Jul 04 14:57:12 2008 +0100
@@ -0,0 +1,47 @@
+/*
+ * vim:shiftwidth=8:noexpandtab
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <xen/interface/physdev.h>
+
+static int xen_pci_dev_guard_enable(struct pci_dev *pci_dev)
+{
+       struct physdev_manage_pci manage_pci;
+       manage_pci.bus = pci_dev->bus->number;
+       manage_pci.devfn = pci_dev->devfn;
+
+       return HYPERVISOR_physdev_op(PHYSDEVOP_manage_pci_add, &manage_pci);
+}
+
+static int xen_pci_dev_guard_disable(struct pci_dev *pci_dev)
+{
+       struct physdev_manage_pci manage_pci;
+       manage_pci.bus = pci_dev->bus->number;
+       manage_pci.devfn = pci_dev->devfn;
+
+       return HYPERVISOR_physdev_op(PHYSDEVOP_manage_pci_remove, &manage_pci);
+}
+
+static struct pci_dev_guard xen_pci_dev_guard = {
+       .enable = xen_pci_dev_guard_enable,
+       .disable = xen_pci_dev_guard_disable,
+};
+
+static int __init init_pci_guard(void)
+{
+       if (!is_running_on_xen() || !is_initial_xendomain())
+               return 0;
+
+       if (pci_dev_guard) {
+               printk(KERN_ERR "Can't use pci_dev_guard\n");
+               return 0;
+       }
+
+       pci_dev_guard = &xen_pci_dev_guard;
+       return 0;
+}
+core_initcall(init_pci_guard);
+
diff -r ef74eb78b86c include/linux/pci.h
--- a/include/linux/pci.h       Fri Jul 04 14:54:57 2008 +0100
+++ b/include/linux/pci.h       Fri Jul 04 14:57:12 2008 +0100
@@ -338,6 +338,29 @@
        /* Device driver may resume normal operations */
        void (*resume)(struct pci_dev *dev);
 };
+
+/* ---------------------------------------------------------------- */
+
+struct pci_dev_guard {
+       int (*enable)(struct pci_dev *dev);
+       int (*disable)(struct pci_dev *dev);
+};
+
+extern struct pci_dev_guard *pci_dev_guard;
+
+static inline int pci_dev_guard_enable(struct pci_dev *pci_dev)
+{
+       if (pci_dev_guard && pci_dev_guard->enable)
+               return pci_dev_guard->enable(pci_dev);
+       return 0;
+}
+
+static inline int pci_dev_guard_disable(struct pci_dev *pci_dev)
+{
+       if (pci_dev_guard && pci_dev_guard->disable)
+               return pci_dev_guard->disable(pci_dev);
+       return 0;
+}
 
 /* ---------------------------------------------------------------- */
 

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.