diff options
author | Bjorn Helgaas <bhelgaas@google.com> | 2012-09-13 10:41:01 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2012-09-13 10:41:01 -0400 |
commit | 78890b5989d96ddce989cde929c45ceeded0fcaf (patch) | |
tree | 4e2da81fc7c97f11aee174b1eedac110c9a68b3a /drivers/iommu/intel-iommu.c | |
parent | 1959ec5f82acbdf91425b41600f119ebecb5f6a8 (diff) | |
parent | 55d512e245bc7699a8800e23df1a24195dd08217 (diff) |
Merge commit 'v3.6-rc5' into next
* commit 'v3.6-rc5': (1098 commits)
Linux 3.6-rc5
HID: tpkbd: work even if the new Lenovo Keyboard driver is not configured
Remove user-triggerable BUG from mpol_to_str
xen/pciback: Fix proper FLR steps.
uml: fix compile error in deliver_alarm()
dj: memory scribble in logi_dj
Fix order of arguments to compat_put_time[spec|val]
xen: Use correct masking in xen_swiotlb_alloc_coherent.
xen: fix logical error in tlb flushing
xen/p2m: Fix one-off error in checking the P2M tree directory.
powerpc: Don't use __put_user() in patch_instruction
powerpc: Make sure IPI handlers see data written by IPI senders
powerpc: Restore correct DSCR in context switch
powerpc: Fix DSCR inheritance in copy_thread()
powerpc: Keep thread.dscr and thread.dscr_inherit in sync
powerpc: Update DSCR on all CPUs when writing sysfs dscr_default
powerpc/powernv: Always go into nap mode when CPU is offline
powerpc: Give hypervisor decrementer interrupts their own handler
powerpc/vphn: Fix arch_update_cpu_topology() return value
ARM: gemini: fix the gemini build
...
Conflicts:
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
drivers/rapidio/devices/tsi721.c
Diffstat (limited to 'drivers/iommu/intel-iommu.c')
-rw-r--r-- | drivers/iommu/intel-iommu.c | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 8b5075d6dd5a..db820d7dd0bc 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c | |||
@@ -2008,6 +2008,7 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw) | |||
2008 | if (!drhd) { | 2008 | if (!drhd) { |
2009 | printk(KERN_ERR "IOMMU: can't find DMAR for device %s\n", | 2009 | printk(KERN_ERR "IOMMU: can't find DMAR for device %s\n", |
2010 | pci_name(pdev)); | 2010 | pci_name(pdev)); |
2011 | free_domain_mem(domain); | ||
2011 | return NULL; | 2012 | return NULL; |
2012 | } | 2013 | } |
2013 | iommu = drhd->iommu; | 2014 | iommu = drhd->iommu; |
@@ -4124,8 +4125,13 @@ static int intel_iommu_add_device(struct device *dev) | |||
4124 | } else | 4125 | } else |
4125 | dma_pdev = pci_dev_get(pdev); | 4126 | dma_pdev = pci_dev_get(pdev); |
4126 | 4127 | ||
4128 | /* Account for quirked devices */ | ||
4127 | swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev)); | 4129 | swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev)); |
4128 | 4130 | ||
4131 | /* | ||
4132 | * If it's a multifunction device that does not support our | ||
4133 | * required ACS flags, add to the same group as function 0. | ||
4134 | */ | ||
4129 | if (dma_pdev->multifunction && | 4135 | if (dma_pdev->multifunction && |
4130 | !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) | 4136 | !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) |
4131 | swap_pci_ref(&dma_pdev, | 4137 | swap_pci_ref(&dma_pdev, |
@@ -4133,14 +4139,28 @@ static int intel_iommu_add_device(struct device *dev) | |||
4133 | PCI_DEVFN(PCI_SLOT(dma_pdev->devfn), | 4139 | PCI_DEVFN(PCI_SLOT(dma_pdev->devfn), |
4134 | 0))); | 4140 | 0))); |
4135 | 4141 | ||
4142 | /* | ||
4143 | * Devices on the root bus go through the iommu. If that's not us, | ||
4144 | * find the next upstream device and test ACS up to the root bus. | ||
4145 | * Finding the next device may require skipping virtual buses. | ||
4146 | */ | ||
4136 | while (!pci_is_root_bus(dma_pdev->bus)) { | 4147 | while (!pci_is_root_bus(dma_pdev->bus)) { |
4137 | if (pci_acs_path_enabled(dma_pdev->bus->self, | 4148 | struct pci_bus *bus = dma_pdev->bus; |
4138 | NULL, REQ_ACS_FLAGS)) | 4149 | |
4150 | while (!bus->self) { | ||
4151 | if (!pci_is_root_bus(bus)) | ||
4152 | bus = bus->parent; | ||
4153 | else | ||
4154 | goto root_bus; | ||
4155 | } | ||
4156 | |||
4157 | if (pci_acs_path_enabled(bus->self, NULL, REQ_ACS_FLAGS)) | ||
4139 | break; | 4158 | break; |
4140 | 4159 | ||
4141 | swap_pci_ref(&dma_pdev, pci_dev_get(dma_pdev->bus->self)); | 4160 | swap_pci_ref(&dma_pdev, pci_dev_get(bus->self)); |
4142 | } | 4161 | } |
4143 | 4162 | ||
4163 | root_bus: | ||
4144 | group = iommu_group_get(&dma_pdev->dev); | 4164 | group = iommu_group_get(&dma_pdev->dev); |
4145 | pci_dev_put(dma_pdev); | 4165 | pci_dev_put(dma_pdev); |
4146 | if (!group) { | 4166 | if (!group) { |