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 | |
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')
-rw-r--r-- | drivers/iommu/amd_iommu.c | 25 | ||||
-rw-r--r-- | drivers/iommu/amd_iommu_init.c | 8 | ||||
-rw-r--r-- | drivers/iommu/exynos-iommu.c | 6 | ||||
-rw-r--r-- | drivers/iommu/intel-iommu.c | 26 | ||||
-rw-r--r-- | drivers/iommu/intel_irq_remapping.c | 18 | ||||
-rw-r--r-- | drivers/iommu/tegra-smmu.c | 17 |
6 files changed, 75 insertions, 25 deletions
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 6d1cbdfc9b2a..b64502dfa9f4 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c | |||
@@ -296,8 +296,13 @@ static int iommu_init_device(struct device *dev) | |||
296 | } else | 296 | } else |
297 | dma_pdev = pci_dev_get(pdev); | 297 | dma_pdev = pci_dev_get(pdev); |
298 | 298 | ||
299 | /* Account for quirked devices */ | ||
299 | swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev)); | 300 | swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev)); |
300 | 301 | ||
302 | /* | ||
303 | * If it's a multifunction device that does not support our | ||
304 | * required ACS flags, add to the same group as function 0. | ||
305 | */ | ||
301 | if (dma_pdev->multifunction && | 306 | if (dma_pdev->multifunction && |
302 | !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) | 307 | !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) |
303 | swap_pci_ref(&dma_pdev, | 308 | swap_pci_ref(&dma_pdev, |
@@ -305,14 +310,28 @@ static int iommu_init_device(struct device *dev) | |||
305 | PCI_DEVFN(PCI_SLOT(dma_pdev->devfn), | 310 | PCI_DEVFN(PCI_SLOT(dma_pdev->devfn), |
306 | 0))); | 311 | 0))); |
307 | 312 | ||
313 | /* | ||
314 | * Devices on the root bus go through the iommu. If that's not us, | ||
315 | * find the next upstream device and test ACS up to the root bus. | ||
316 | * Finding the next device may require skipping virtual buses. | ||
317 | */ | ||
308 | while (!pci_is_root_bus(dma_pdev->bus)) { | 318 | while (!pci_is_root_bus(dma_pdev->bus)) { |
309 | if (pci_acs_path_enabled(dma_pdev->bus->self, | 319 | struct pci_bus *bus = dma_pdev->bus; |
310 | NULL, REQ_ACS_FLAGS)) | 320 | |
321 | while (!bus->self) { | ||
322 | if (!pci_is_root_bus(bus)) | ||
323 | bus = bus->parent; | ||
324 | else | ||
325 | goto root_bus; | ||
326 | } | ||
327 | |||
328 | if (pci_acs_path_enabled(bus->self, NULL, REQ_ACS_FLAGS)) | ||
311 | break; | 329 | break; |
312 | 330 | ||
313 | swap_pci_ref(&dma_pdev, pci_dev_get(dma_pdev->bus->self)); | 331 | swap_pci_ref(&dma_pdev, pci_dev_get(bus->self)); |
314 | } | 332 | } |
315 | 333 | ||
334 | root_bus: | ||
316 | group = iommu_group_get(&dma_pdev->dev); | 335 | group = iommu_group_get(&dma_pdev->dev); |
317 | pci_dev_put(dma_pdev); | 336 | pci_dev_put(dma_pdev); |
318 | if (!group) { | 337 | if (!group) { |
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 500e7f15f5c2..18a89b760aaa 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c | |||
@@ -1111,7 +1111,7 @@ static void print_iommu_info(void) | |||
1111 | 1111 | ||
1112 | if (iommu->cap & (1 << IOMMU_CAP_EFR)) { | 1112 | if (iommu->cap & (1 << IOMMU_CAP_EFR)) { |
1113 | pr_info("AMD-Vi: Extended features: "); | 1113 | pr_info("AMD-Vi: Extended features: "); |
1114 | for (i = 0; ARRAY_SIZE(feat_str); ++i) { | 1114 | for (i = 0; i < ARRAY_SIZE(feat_str); ++i) { |
1115 | if (iommu_feature(iommu, (1ULL << i))) | 1115 | if (iommu_feature(iommu, (1ULL << i))) |
1116 | pr_cont(" %s", feat_str[i]); | 1116 | pr_cont(" %s", feat_str[i]); |
1117 | } | 1117 | } |
@@ -1131,9 +1131,6 @@ static int __init amd_iommu_init_pci(void) | |||
1131 | break; | 1131 | break; |
1132 | } | 1132 | } |
1133 | 1133 | ||
1134 | /* Make sure ACS will be enabled */ | ||
1135 | pci_request_acs(); | ||
1136 | |||
1137 | ret = amd_iommu_init_devices(); | 1134 | ret = amd_iommu_init_devices(); |
1138 | 1135 | ||
1139 | print_iommu_info(); | 1136 | print_iommu_info(); |
@@ -1652,6 +1649,9 @@ static bool detect_ivrs(void) | |||
1652 | 1649 | ||
1653 | early_acpi_os_unmap_memory((char __iomem *)ivrs_base, ivrs_size); | 1650 | early_acpi_os_unmap_memory((char __iomem *)ivrs_base, ivrs_size); |
1654 | 1651 | ||
1652 | /* Make sure ACS will be enabled during PCI probe */ | ||
1653 | pci_request_acs(); | ||
1654 | |||
1655 | return true; | 1655 | return true; |
1656 | } | 1656 | } |
1657 | 1657 | ||
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 45350ff5e93c..80bad32aa463 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c | |||
@@ -732,9 +732,9 @@ static int exynos_iommu_domain_init(struct iommu_domain *domain) | |||
732 | spin_lock_init(&priv->pgtablelock); | 732 | spin_lock_init(&priv->pgtablelock); |
733 | INIT_LIST_HEAD(&priv->clients); | 733 | INIT_LIST_HEAD(&priv->clients); |
734 | 734 | ||
735 | dom->geometry.aperture_start = 0; | 735 | domain->geometry.aperture_start = 0; |
736 | dom->geometry.aperture_end = ~0UL; | 736 | domain->geometry.aperture_end = ~0UL; |
737 | dom->geometry.force_aperture = true; | 737 | domain->geometry.force_aperture = true; |
738 | 738 | ||
739 | domain->priv = priv; | 739 | domain->priv = priv; |
740 | return 0; | 740 | return 0; |
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) { |
diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c index e0b18f3ae9a8..af8904de1d44 100644 --- a/drivers/iommu/intel_irq_remapping.c +++ b/drivers/iommu/intel_irq_remapping.c | |||
@@ -736,6 +736,7 @@ int __init parse_ioapics_under_ir(void) | |||
736 | { | 736 | { |
737 | struct dmar_drhd_unit *drhd; | 737 | struct dmar_drhd_unit *drhd; |
738 | int ir_supported = 0; | 738 | int ir_supported = 0; |
739 | int ioapic_idx; | ||
739 | 740 | ||
740 | for_each_drhd_unit(drhd) { | 741 | for_each_drhd_unit(drhd) { |
741 | struct intel_iommu *iommu = drhd->iommu; | 742 | struct intel_iommu *iommu = drhd->iommu; |
@@ -748,13 +749,20 @@ int __init parse_ioapics_under_ir(void) | |||
748 | } | 749 | } |
749 | } | 750 | } |
750 | 751 | ||
751 | if (ir_supported && ir_ioapic_num != nr_ioapics) { | 752 | if (!ir_supported) |
752 | printk(KERN_WARNING | 753 | return 0; |
753 | "Not all IO-APIC's listed under remapping hardware\n"); | 754 | |
754 | return -1; | 755 | for (ioapic_idx = 0; ioapic_idx < nr_ioapics; ioapic_idx++) { |
756 | int ioapic_id = mpc_ioapic_id(ioapic_idx); | ||
757 | if (!map_ioapic_to_ir(ioapic_id)) { | ||
758 | pr_err(FW_BUG "ioapic %d has no mapping iommu, " | ||
759 | "interrupt remapping will be disabled\n", | ||
760 | ioapic_id); | ||
761 | return -1; | ||
762 | } | ||
755 | } | 763 | } |
756 | 764 | ||
757 | return ir_supported; | 765 | return 1; |
758 | } | 766 | } |
759 | 767 | ||
760 | int __init ir_dev_scope_init(void) | 768 | int __init ir_dev_scope_init(void) |
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c index 4ba325ab6262..2a4bb36bc688 100644 --- a/drivers/iommu/tegra-smmu.c +++ b/drivers/iommu/tegra-smmu.c | |||
@@ -799,14 +799,14 @@ static void smmu_iommu_detach_dev(struct iommu_domain *domain, | |||
799 | goto out; | 799 | goto out; |
800 | } | 800 | } |
801 | } | 801 | } |
802 | dev_err(smmu->dev, "Couldn't find %s\n", dev_name(c->dev)); | 802 | dev_err(smmu->dev, "Couldn't find %s\n", dev_name(dev)); |
803 | out: | 803 | out: |
804 | spin_unlock(&as->client_lock); | 804 | spin_unlock(&as->client_lock); |
805 | } | 805 | } |
806 | 806 | ||
807 | static int smmu_iommu_domain_init(struct iommu_domain *domain) | 807 | static int smmu_iommu_domain_init(struct iommu_domain *domain) |
808 | { | 808 | { |
809 | int i, err = -ENODEV; | 809 | int i, err = -EAGAIN; |
810 | unsigned long flags; | 810 | unsigned long flags; |
811 | struct smmu_as *as; | 811 | struct smmu_as *as; |
812 | struct smmu_device *smmu = smmu_handle; | 812 | struct smmu_device *smmu = smmu_handle; |
@@ -814,11 +814,14 @@ static int smmu_iommu_domain_init(struct iommu_domain *domain) | |||
814 | /* Look for a free AS with lock held */ | 814 | /* Look for a free AS with lock held */ |
815 | for (i = 0; i < smmu->num_as; i++) { | 815 | for (i = 0; i < smmu->num_as; i++) { |
816 | as = &smmu->as[i]; | 816 | as = &smmu->as[i]; |
817 | if (!as->pdir_page) { | 817 | |
818 | err = alloc_pdir(as); | 818 | if (as->pdir_page) |
819 | if (!err) | 819 | continue; |
820 | goto found; | 820 | |
821 | } | 821 | err = alloc_pdir(as); |
822 | if (!err) | ||
823 | goto found; | ||
824 | |||
822 | if (err != -EAGAIN) | 825 | if (err != -EAGAIN) |
823 | break; | 826 | break; |
824 | } | 827 | } |