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

[Xen-devel] [PATCH 2/6] Provide a mechanism to register domain owner of a PCI device.



. and also to find the domain owner based on the PCI device and
to unregister a domain owner of a PCI device.

Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>
---
 arch/x86/include/asm/xen/pci.h |   18 +++++++++
 arch/x86/xen/pci.c             |   81 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 99 insertions(+), 0 deletions(-)

diff --git a/arch/x86/include/asm/xen/pci.h b/arch/x86/include/asm/xen/pci.h
index cb84abe..d335c90 100644
--- a/arch/x86/include/asm/xen/pci.h
+++ b/arch/x86/include/asm/xen/pci.h
@@ -7,6 +7,11 @@ int xen_create_msi_irq(struct pci_dev *dev,
                        struct msi_desc *msidesc,
                        int type);
 int xen_destroy_irq(int irq);
+
+int xen_find_device_domain_owner(struct pci_dev *dev);
+int xen_register_device_domain_owner(struct pci_dev *dev, domid_t domain);
+int xen_unregister_device_domain_owner(struct pci_dev *dev);
+
 #else
 static inline int xen_register_gsi(u32 gsi, int triggering, int polarity)
 {
@@ -23,6 +28,19 @@ static inline int xen_destroy_irq(int irq)
 {
        return -1;
 }
+static inline int xen_find_device_domain_owner(struct pci_dev *dev)
+{
+       return -1;
+}
+static inline int xen_register_device_domain_owner(struct pci_dev *dev,
+                                                  domid_t domain)
+{
+       return -1;
+}
+static inline int xen_unregister_device_domain_owner(struct pci_dev *dev)
+{
+       return -1;
+}
 #endif
 
 #if defined(CONFIG_PCI_MSI) && defined(CONFIG_XEN_DOM0_PCI)
diff --git a/arch/x86/xen/pci.c b/arch/x86/xen/pci.c
index 44d91ad..6948d20 100644
--- a/arch/x86/xen/pci.c
+++ b/arch/x86/xen/pci.c
@@ -2,6 +2,7 @@
 #include <linux/acpi.h>
 #include <linux/pci.h>
 #include <linux/msi.h>
+#include <linux/slab.h>
 
 #include <asm/mpspec.h>
 #include <asm/io_apic.h>
@@ -109,3 +110,83 @@ error:
        return ret;
 }
 #endif
+
+struct xen_device_domain_owner {
+       domid_t domain;
+       struct pci_dev *dev;
+       struct list_head list;
+};
+
+static DEFINE_SPINLOCK(dev_domain_list_spinlock);
+static struct list_head dev_domain_list = LIST_HEAD_INIT(dev_domain_list);
+
+static struct xen_device_domain_owner *find_device(struct pci_dev *dev)
+{
+       struct xen_device_domain_owner *owner;
+
+       list_for_each_entry(owner, &dev_domain_list, list) {
+               if (owner->dev == dev)
+                       return owner;
+       }
+       return NULL;
+}
+
+int xen_find_device_domain_owner(struct pci_dev *dev)
+{
+       struct xen_device_domain_owner *owner;
+       unsigned long flags;
+       int domain = -ENODEV;
+
+       spin_lock_irqsave(&dev_domain_list_spinlock, flags);
+       owner = find_device(dev);
+       if (owner)
+               domain = owner->domain;
+       spin_unlock_irqrestore(&dev_domain_list_spinlock, flags);
+       return domain;
+}
+EXPORT_SYMBOL(xen_find_device_domain_owner);
+
+int xen_register_device_domain_owner(struct pci_dev *dev, domid_t domain)
+{
+       struct xen_device_domain_owner *owner;
+       unsigned long flags;
+       int rc = 0;
+
+       spin_lock_irqsave(&dev_domain_list_spinlock, flags);
+       if (find_device(dev)) {
+               rc = -EEXIST;
+               goto out;
+       }
+       owner = kzalloc(sizeof(struct xen_device_domain_owner), GFP_KERNEL);
+       if (!owner) {
+               rc = -ENOMEM;
+               goto out;
+       }
+       owner->domain = domain;
+       owner->dev = dev;
+       list_add_tail(&owner->list, &dev_domain_list);
+out:
+       spin_unlock_irqrestore(&dev_domain_list_spinlock, flags);
+       return rc;
+}
+EXPORT_SYMBOL(xen_register_device_domain_owner);
+
+int xen_unregister_device_domain_owner(struct pci_dev *dev)
+{
+       struct xen_device_domain_owner *owner;
+       unsigned long flags;
+       int rc = 0;
+
+       spin_lock_irqsave(&dev_domain_list_spinlock, flags);
+       owner = find_device(dev);
+       if (!owner) {
+               rc = -ENODEV;
+               goto out;
+       }
+       list_del(&owner->list);
+       kfree(owner);
+out:
+       spin_unlock_irqrestore(&dev_domain_list_spinlock, flags);
+       return rc;
+}
+EXPORT_SYMBOL(xen_unregister_device_domain_owner);
-- 
1.6.2.2


_______________________________________________
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®.