PCI device register/unregister + pci_dev cleanups
authorKeir Fraser <keir.fraser@citrix.com>
Fri, 4 Jul 2008 16:51:16 +0000 (17:51 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Fri, 4 Jul 2008 16:51:16 +0000 (17:51 +0100)
Move pci_dev lists from hvm to arch_domain

Move the pci_dev list from hvm to arch_domain since PCI devs are no
longer hvm specific.  Also removed locking for pci_dev lists.  Will
reintroduce them later.

Signed-off-by: Espen Skoglund <espen.skoglund@netronome.com>
14 files changed:
xen/arch/x86/domain.c
xen/arch/x86/hvm/hvm.c
xen/arch/x86/hvm/svm/svm.c
xen/arch/x86/hvm/vmx/vmcs.c
xen/arch/x86/hvm/vmx/vmx.c
xen/arch/x86/mm/shadow/multi.c
xen/drivers/passthrough/amd/pci_amd_iommu.c
xen/drivers/passthrough/iommu.c
xen/drivers/passthrough/vtd/dmar.h
xen/drivers/passthrough/vtd/iommu.c
xen/include/asm-x86/domain.h
xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
xen/include/xen/hvm/iommu.h
xen/include/xen/pci.h

index b6a84972066fc88c4649493dc2d07a35ea49bbc8..d6a79195914829fe5a17c1c18fb9bb8ccfb16ccb 100644 (file)
@@ -350,6 +350,8 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags)
         hvm_funcs.hap_supported &&
         (domcr_flags & DOMCRF_hap);
 
+    INIT_LIST_HEAD(&d->arch.pdev_list);
+
     d->arch.relmem = RELMEM_not_started;
     INIT_LIST_HEAD(&d->arch.relmem_list);
 
index 6f410bfd0444eff061ad135de38653d961261f8b..cac26e0d039ce862e5e14cb415e60ec951dc3f70 100644 (file)
@@ -911,7 +911,7 @@ int hvm_set_cr0(unsigned long value)
         }
     }
 
-    if ( !list_empty(&domain_hvm_iommu(v->domain)->pdev_list) )
+    if ( has_arch_pdevs(v->domain) )
     {
         if ( (value & X86_CR0_CD) && !(value & X86_CR0_NW) )
         {
index 3f0dd62ce27905963c11539c9cf15002a541c56c..86a476773786cdb6f2f78690647b327e34e4c3c0 100644 (file)
@@ -1132,7 +1132,7 @@ static void wbinvd_ipi(void *info)
 
 static void svm_wbinvd_intercept(void)
 {
-    if ( !list_empty(&(domain_hvm_iommu(current->domain)->pdev_list)) )
+    if ( has_arch_pdevs(current->domain) )
         on_each_cpu(wbinvd_ipi, NULL, 1, 1);
 }
 
index ff5ca4e7d486ac5f2f19f87698216b9e97079900..bda2ec953e3eee51d8376b6500b4add59805ec1c 100644 (file)
@@ -849,8 +849,7 @@ void vmx_do_resume(struct vcpu *v)
          *     there is no wbinvd exit, or
          *  2: execute wbinvd on all dirty pCPUs when guest wbinvd exits.
          */
-        if ( !list_empty(&(domain_hvm_iommu(v->domain)->pdev_list)) &&
-             !cpu_has_wbinvd_exiting )
+        if ( has_arch_pdevs(v->domain) && !cpu_has_wbinvd_exiting )
         {
             int cpu = v->arch.hvm_vmx.active_cpu;
             if ( cpu != -1 )
index a614ea5839f4b162815d9952bd9f9f6e918a032d..a59685e8283b6da5590d2011b11ab1ee58c3a7fb 100644 (file)
@@ -1926,7 +1926,7 @@ static void wbinvd_ipi(void *info)
 
 static void vmx_wbinvd_intercept(void)
 {
-    if ( list_empty(&(domain_hvm_iommu(current->domain)->pdev_list)) )
+    if ( !has_arch_pdevs(current->domain) )
         return;
 
     if ( cpu_has_wbinvd_exiting )
index 4253f57328b710ce980ef4f70b28bc3eb82e24c1..6b8b43d651b570f54c2916050cf792a0bae3b415 100644 (file)
@@ -840,8 +840,7 @@ _sh_propagate(struct vcpu *v,
      * For HVM domains with direct access to MMIO areas, set the correct
      * caching attributes in the shadows to match what was asked for.
      */
-    if ( (level == 1) && is_hvm_domain(d) &&
-         !list_empty(&(domain_hvm_iommu(d)->pdev_list)) &&
+    if ( (level == 1) && is_hvm_domain(d) && has_arch_pdevs(d) &&
          !is_xen_heap_mfn(mfn_x(target_mfn)) )
     {
         unsigned int type;
index 03c50d10f566b265b0b108fa0c072a0cc3a481da..f8488c21946ea58acb650ce875f93d2ac4617451 100644 (file)
@@ -292,7 +292,6 @@ static void amd_iommu_setup_domain_device(
 
 static void amd_iommu_setup_dom0_devices(struct domain *d)
 {
-    struct hvm_iommu *hd = domain_hvm_iommu(d);
     struct amd_iommu *iommu;
     struct pci_dev *pdev;
     int bus, dev, func;
@@ -314,7 +313,7 @@ static void amd_iommu_setup_dom0_devices(struct domain *d)
                 pdev = xmalloc(struct pci_dev);
                 pdev->bus = bus;
                 pdev->devfn = PCI_DEVFN(dev, func);
-                list_add_tail(&pdev->list, &hd->pdev_list);
+                list_add_tail(&pdev->domain_list, &d->arch.pdev_list);
 
                 bdf = (bus << 8) | pdev->devfn;
                 /* supported device? */
@@ -490,12 +489,9 @@ extern void pdev_flr(u8 bus, u8 devfn);
 static int reassign_device( struct domain *source, struct domain *target,
                             u8 bus, u8 devfn)
 {
-    struct hvm_iommu *source_hd = domain_hvm_iommu(source);
-    struct hvm_iommu *target_hd = domain_hvm_iommu(target);
     struct pci_dev *pdev;
     struct amd_iommu *iommu;
     int bdf;
-    unsigned long flags;
 
     for_each_pdev ( source, pdev )
     {
@@ -520,11 +516,7 @@ static int reassign_device( struct domain *source, struct domain *target,
 
         amd_iommu_disable_domain_device(source, iommu, bdf);
         /* Move pci device from the source domain to target domain. */
-        spin_lock_irqsave(&source_hd->iommu_list_lock, flags);
-        spin_lock_irqsave(&target_hd->iommu_list_lock, flags);
-        list_move(&pdev->list, &target_hd->pdev_list);
-        spin_unlock_irqrestore(&target_hd->iommu_list_lock, flags);
-        spin_unlock_irqrestore(&source_hd->iommu_list_lock, flags);
+        list_move(&pdev->domain_list, &target->arch.pdev_list);
 
         amd_iommu_setup_domain_device(target, iommu, bdf);
         amd_iov_info("reassign %x:%x.%x domain %d -> domain %d\n",
@@ -559,12 +551,11 @@ static int amd_iommu_assign_device(struct domain *d, u8 bus, u8 devfn)
 
 static void release_domain_devices(struct domain *d)
 {
-    struct hvm_iommu *hd  = domain_hvm_iommu(d);
     struct pci_dev *pdev;
 
-    while ( !list_empty(&hd->pdev_list) )
+    while ( has_arch_pdevs(d) )
     {
-        pdev = list_entry(hd->pdev_list.next, typeof(*pdev), list);
+        pdev = list_entry(d->arch.pdev_list.next, typeof(*pdev), domain_list);
         pdev_flr(pdev->bus, pdev->devfn);
         amd_iov_info("release domain %d devices %x:%x.%x\n", d->domain_id,
                  pdev->bus, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
index b6147b69792245adaedcb2613faf48ea2ed31729..abf3ca7631f6b8fc98abc0179e035de4f862ffe6 100644 (file)
@@ -35,8 +35,6 @@ int iommu_domain_init(struct domain *domain)
     struct hvm_iommu *hd = domain_hvm_iommu(domain);
 
     spin_lock_init(&hd->mapping_lock);
-    spin_lock_init(&hd->iommu_list_lock);
-    INIT_LIST_HEAD(&hd->pdev_list);
     INIT_LIST_HEAD(&hd->g2m_ioport_list);
 
     if ( !iommu_enabled )
@@ -68,7 +66,7 @@ int assign_device(struct domain *d, u8 bus, u8 devfn)
     if ( (rc = hd->platform_ops->assign_device(d, bus, devfn)) )
         return rc;
 
-    if ( has_iommu_pdevs(d) && !is_hvm_domain(d) && !need_iommu(d) )
+    if ( has_arch_pdevs(d) && !is_hvm_domain(d) && !need_iommu(d) )
     {
         d->need_iommu = 1;
         return iommu_populate_page_table(d);
@@ -190,7 +188,7 @@ void deassign_device(struct domain *d, u8 bus, u8 devfn)
 
     hd->platform_ops->reassign_device(d, dom0, bus, devfn);
 
-    if ( !has_iommu_pdevs(d) && need_iommu(d) )
+    if ( !has_arch_pdevs(d) && need_iommu(d) )
     {
         d->need_iommu = 0;
         hd->platform_ops->teardown(d);
@@ -242,8 +240,7 @@ int iommu_get_device_group(struct domain *d, u8 bus, u8 devfn,
 
     group_id = ops->get_device_group_id(bus, devfn);
 
-    list_for_each_entry(pdev,
-        &(dom0->arch.hvm_domain.hvm_iommu.pdev_list), list)
+    for_each_pdev( d, pdev )
     {
         if ( (pdev->bus == bus) && (pdev->devfn == devfn) )
             continue;
index 444d7e4acb06827510b82058ad8b6b57b1e63741..0b09a4fe4806f047a6e2f1b6638885e2f8f5dab8 100644 (file)
@@ -70,10 +70,6 @@ struct acpi_atsr_unit {
     list_for_each_entry(iommu, \
         &(domain->arch.hvm_domain.hvm_iommu.iommu_list), list)
 
-#define for_each_pdev(domain, pdev) \
-    list_for_each_entry(pdev, \
-         &(domain->arch.hvm_domain.hvm_iommu.pdev_list), list)
-
 #define for_each_drhd_unit(drhd) \
     list_for_each_entry(drhd, &acpi_drhd_units, list)
 #define for_each_rmrr_device(rmrr, pdev) \
index f9e9e13ad4b37589ce3005a5c25576f6c3e29b99..09125e34f6c7700f25be1b58bfa9f5c10c64d86c 100644 (file)
@@ -1023,8 +1023,6 @@ static int intel_iommu_domain_init(struct domain *d)
     u64 i;
     struct acpi_drhd_unit *drhd;
 
-    INIT_LIST_HEAD(&hd->pdev_list);
-
     drhd = list_entry(acpi_drhd_units.next, typeof(*drhd), list);
     iommu = drhd->iommu;
 
@@ -1366,12 +1364,10 @@ void reassign_device_ownership(
     u8 bus, u8 devfn)
 {
     struct hvm_iommu *source_hd = domain_hvm_iommu(source);
-    struct hvm_iommu *target_hd = domain_hvm_iommu(target);
     struct pci_dev *pdev, *pdev2;
     struct acpi_drhd_unit *drhd;
     struct iommu *iommu;
     int status;
-    unsigned long flags;
     int found = 0;
 
     pdev_flr(bus, devfn);
@@ -1388,11 +1384,7 @@ void reassign_device_ownership(
     domain_context_unmap(iommu, pdev);
 
     /* Move pci device from the source domain to target domain. */
-    spin_lock_irqsave(&source_hd->iommu_list_lock, flags);
-    spin_lock_irqsave(&target_hd->iommu_list_lock, flags);
-    list_move(&pdev->list, &target_hd->pdev_list);
-    spin_unlock_irqrestore(&target_hd->iommu_list_lock, flags);
-    spin_unlock_irqrestore(&source_hd->iommu_list_lock, flags);
+    list_move(&pdev->domain_list, &target->arch.pdev_list);
 
     for_each_pdev ( source, pdev2 )
     {
@@ -1413,12 +1405,11 @@ void reassign_device_ownership(
 
 void return_devices_to_dom0(struct domain *d)
 {
-    struct hvm_iommu *hd  = domain_hvm_iommu(d);
     struct pci_dev *pdev;
 
-    while ( !list_empty(&hd->pdev_list) )
+    while ( has_arch_pdevs(d) )
     {
-        pdev = list_entry(hd->pdev_list.next, typeof(*pdev), list);
+        pdev = list_entry(d->arch.pdev_list.next, typeof(*pdev), domain_list);
         pci_cleanup_msi(pdev->bus, pdev->devfn);
         reassign_device_ownership(d, dom0, pdev->bus, pdev->devfn);
     }
@@ -1631,7 +1622,7 @@ static void setup_dom0_devices(struct domain *d)
                 pdev = xmalloc(struct pci_dev);
                 pdev->bus = bus;
                 pdev->devfn = PCI_DEVFN(dev, func);
-                list_add_tail(&pdev->list, &hd->pdev_list);
+                list_add_tail(&pdev->domain_list, &d->arch.pdev_list);
 
                 drhd = acpi_find_matched_drhd_unit(pdev);
                 ret = domain_context_mapping(d, drhd->iommu, pdev);
index abf822315d8c6442556cfd950942dd637adaca5e..c19b42136e033d89270f41a54a3299941147ae97 100644 (file)
@@ -228,6 +228,7 @@ struct arch_domain
     struct rangeset *ioport_caps;
     uint32_t pci_cf8;
 
+    struct list_head pdev_list;
     struct hvm_domain hvm_domain;
 
     struct paging_domain paging;
@@ -266,6 +267,9 @@ struct arch_domain
     cpuid_input_t cpuids[MAX_CPUID_INPUT];
 } __cacheline_aligned;
 
+#define has_arch_pdevs(d)    (!list_empty(&(d)->arch.pdev_list))
+
+
 #ifdef __i386__
 struct pae_l3_cache {
     /*
index 207b17c5959ddf7b0a677f55dcf3d43a5759539d..b6fa94f49f58fdca795d9d521dac729f203983f5 100644 (file)
     list_for_each_entry(amd_iommu, \
         &amd_iommu_head, list)
 
-#define for_each_pdev(domain, pdev) \
-    list_for_each_entry(pdev, \
-         &(domain->arch.hvm_domain.hvm_iommu.pdev_list), list)
-
 #define DMA_32BIT_MASK  0x00000000ffffffffULL
 #define PAGE_ALIGN(addr)    (((addr) + PAGE_SIZE - 1) & PAGE_MASK)
 
index 4fa664c982ce3ee5f18450fc7c1ee863c8fb4747..cf2c09883e6eb1b63f430ebbb5551e51001bac04 100644 (file)
@@ -36,8 +36,6 @@ struct g2m_ioport {
 };
 
 struct hvm_iommu {
-    spinlock_t iommu_list_lock;    /* protect iommu specific lists */
-    struct list_head pdev_list;    /* direct accessed pci devices */
     u64 pgd_maddr;                 /* io page directory machine address */
     spinlock_t mapping_lock;       /* io page table lock */
     int agaw;     /* adjusted guest address width, 0 is level 2 30-bit */
@@ -55,7 +53,4 @@ struct hvm_iommu {
     struct iommu_ops *platform_ops;
 };
 
-#define has_iommu_pdevs(domain) \
-    (!list_empty(&(domain->arch.hvm_domain.hvm_iommu.pdev_list)))
-
 #endif /* __ASM_X86_HVM_IOMMU_H__ */
index 431c18e96b75212deb3b453d71f39ab7fb29af42..95a87c93010caeb54d6195bc1f74d9fea2355da6 100644 (file)
@@ -25,7 +25,7 @@
 #define PCI_FUNC(devfn)       ((devfn) & 0x07)
 
 struct pci_dev {
-    struct list_head list;
+    struct list_head domain_list;
     struct list_head msi_dev_list;
     u8 bus;
     u8 devfn;
@@ -50,4 +50,9 @@ void pci_conf_write32(
 int pci_find_cap_offset(u8 bus, u8 dev, u8 func, u8 cap);
 int pci_find_next_cap(u8 bus, unsigned int devfn, u8 pos, int cap);
 
+
+#define for_each_pdev(domain, pdev) \
+    list_for_each_entry(pdev, &(domain->arch.pdev_list), domain_list)
+
+
 #endif /* __XEN_PCI_H__ */