[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 2/6] [xen-pci] 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 | 16 +++++++++ arch/x86/xen/pci.c | 73 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 0 deletions(-) diff --git a/arch/x86/include/asm/xen/pci.h b/arch/x86/include/asm/xen/pci.h index 6c022c8..6e9e9f2 100644 --- a/arch/x86/include/asm/xen/pci.h +++ b/arch/x86/include/asm/xen/pci.h @@ -8,6 +8,11 @@ int xen_create_msi_irq(struct pci_dev *dev, int type, int pirq_override); int xen_destroy_irq(int irq); void xen_teardown_msi_dev(struct pci_dev *dev); + +int find_device_owner(struct pci_dev *dev); +int register_device_owner(struct pci_dev *dev, domid_t domain); +int unregister_device_owner(struct pci_dev *dev); + #else static inline int xen_register_gsi(u32 gsi, int triggering, int polarity) { @@ -25,6 +30,17 @@ static inline int xen_destroy_irq(int irq) return -1; } static inline void xen_teardown_msi_dev(struct pci_dev *dev) { } + +static inline int find_device_owner(struct pci_dev *dev) { return -1; } +static inline int register_device_owner(struct pci_dev *dev, domid_t domain) +{ + return -1; +} +static inline int unregister_device_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 fc3508c..151b4b7 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> @@ -151,3 +152,75 @@ void xen_teardown_msi_dev(struct pci_dev *dev) } #endif + +struct device_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); + +struct device_owner *find_device(struct pci_dev *dev) +{ + + struct device_owner *owner; + + list_for_each_entry(owner, &dev_domain_list, list) { + if (owner->dev == dev) + return owner; + } + return NULL; +} + +int find_device_owner(struct pci_dev *dev) +{ + + struct device_owner *owner = NULL; + + owner = find_device(dev); + if (!owner) + return -ENODEV; + + return owner->domain; +} +EXPORT_SYMBOL(find_device_owner); + +int register_device_owner(struct pci_dev *dev, domid_t domain) +{ + struct device_owner *owner; + unsigned long flags; + + if (find_device(dev)) + return -EEXIST; + + owner = kzalloc(sizeof(struct device_owner), GFP_KERNEL); + owner->domain = domain; + owner->dev = dev; + + spin_lock_irqsave(&dev_domain_list_spinlock, flags); + list_add_tail(&owner->list, &dev_domain_list); + spin_unlock_irqrestore(&dev_domain_list_spinlock, flags); + + return 0; +} +EXPORT_SYMBOL(register_device_owner); + +int unregister_device_owner(struct pci_dev *dev) +{ + struct device_owner *owner = NULL; + unsigned long flags; + + owner = find_device(dev); + if (!owner) + return -ENODEV; + + spin_lock_irqsave(&dev_domain_list_spinlock, flags); + list_del(&owner->list); + spin_unlock_irqrestore(&dev_domain_list_spinlock, flags); + + kfree(owner); + return 0; +} +EXPORT_SYMBOL(unregister_device_owner); -- 1.6.2.5 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |