[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |