mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 19:51:31 -04:00
Merge branch 'x86/vt-d' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu into x86/apic-picks
Required to apply Jiangs x86 irq handling rework without creating a nightmare of conflicts. Signed-off-by: Thomas Gleixner <[email protected]>
This commit is contained in:
commit
8ab7913675
2709 changed files with 87200 additions and 64252 deletions
|
|
@ -163,14 +163,14 @@ config TEGRA_IOMMU_GART
|
|||
hardware included on Tegra SoCs.
|
||||
|
||||
config TEGRA_IOMMU_SMMU
|
||||
bool "Tegra SMMU IOMMU Support"
|
||||
depends on ARCH_TEGRA && TEGRA_AHB
|
||||
bool "NVIDIA Tegra SMMU Support"
|
||||
depends on ARCH_TEGRA
|
||||
depends on TEGRA_AHB
|
||||
depends on TEGRA_MC
|
||||
select IOMMU_API
|
||||
help
|
||||
Enables support for remapping discontiguous physical memory
|
||||
shared with the operating system into contiguous I/O virtual
|
||||
space through the SMMU (System Memory Management Unit)
|
||||
hardware included on Tegra SoCs.
|
||||
This driver supports the IOMMU hardware (SMMU) found on NVIDIA Tegra
|
||||
SoCs (Tegra30 up to Tegra124).
|
||||
|
||||
config EXYNOS_IOMMU
|
||||
bool "Exynos IOMMU Support"
|
||||
|
|
|
|||
|
|
@ -3424,6 +3424,7 @@ static const struct iommu_ops amd_iommu_ops = {
|
|||
.detach_dev = amd_iommu_detach_device,
|
||||
.map = amd_iommu_map,
|
||||
.unmap = amd_iommu_unmap,
|
||||
.map_sg = default_iommu_map_sg,
|
||||
.iova_to_phys = amd_iommu_iova_to_phys,
|
||||
.pgsize_bitmap = AMD_IOMMU_PGSIZES,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1652,6 +1652,7 @@ static const struct iommu_ops arm_smmu_ops = {
|
|||
.detach_dev = arm_smmu_detach_dev,
|
||||
.map = arm_smmu_map,
|
||||
.unmap = arm_smmu_unmap,
|
||||
.map_sg = default_iommu_map_sg,
|
||||
.iova_to_phys = arm_smmu_iova_to_phys,
|
||||
.add_device = arm_smmu_add_device,
|
||||
.remove_device = arm_smmu_remove_device,
|
||||
|
|
|
|||
|
|
@ -1178,6 +1178,7 @@ static const struct iommu_ops exynos_iommu_ops = {
|
|||
.detach_dev = exynos_iommu_detach_device,
|
||||
.map = exynos_iommu_map,
|
||||
.unmap = exynos_iommu_unmap,
|
||||
.map_sg = default_iommu_map_sg,
|
||||
.iova_to_phys = exynos_iommu_iova_to_phys,
|
||||
.add_device = exynos_iommu_add_device,
|
||||
.remove_device = exynos_iommu_remove_device,
|
||||
|
|
|
|||
|
|
@ -4630,6 +4630,7 @@ static const struct iommu_ops intel_iommu_ops = {
|
|||
.detach_dev = intel_iommu_detach_device,
|
||||
.map = intel_iommu_map,
|
||||
.unmap = intel_iommu_unmap,
|
||||
.map_sg = default_iommu_map_sg,
|
||||
.iova_to_phys = intel_iommu_iova_to_phys,
|
||||
.add_device = intel_iommu_add_device,
|
||||
.remove_device = intel_iommu_remove_device,
|
||||
|
|
|
|||
|
|
@ -818,7 +818,15 @@ static int iommu_bus_init(struct bus_type *bus, const struct iommu_ops *ops)
|
|||
kfree(nb);
|
||||
return err;
|
||||
}
|
||||
return bus_for_each_dev(bus, NULL, &cb, add_iommu_group);
|
||||
|
||||
err = bus_for_each_dev(bus, NULL, &cb, add_iommu_group);
|
||||
if (err) {
|
||||
bus_unregister_notifier(bus, nb);
|
||||
kfree(nb);
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -836,13 +844,19 @@ static int iommu_bus_init(struct bus_type *bus, const struct iommu_ops *ops)
|
|||
*/
|
||||
int bus_set_iommu(struct bus_type *bus, const struct iommu_ops *ops)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (bus->iommu_ops != NULL)
|
||||
return -EBUSY;
|
||||
|
||||
bus->iommu_ops = ops;
|
||||
|
||||
/* Do IOMMU specific setup for this bus-type */
|
||||
return iommu_bus_init(bus, ops);
|
||||
err = iommu_bus_init(bus, ops);
|
||||
if (err)
|
||||
bus->iommu_ops = NULL;
|
||||
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(bus_set_iommu);
|
||||
|
||||
|
|
@ -1124,6 +1138,38 @@ size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(iommu_unmap);
|
||||
|
||||
size_t default_iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
|
||||
struct scatterlist *sg, unsigned int nents, int prot)
|
||||
{
|
||||
struct scatterlist *s;
|
||||
size_t mapped = 0;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
for_each_sg(sg, s, nents, i) {
|
||||
phys_addr_t phys = page_to_phys(sg_page(s));
|
||||
|
||||
/* We are mapping on page boundarys, so offset must be 0 */
|
||||
if (s->offset)
|
||||
goto out_err;
|
||||
|
||||
ret = iommu_map(domain, iova + mapped, phys, s->length, prot);
|
||||
if (ret)
|
||||
goto out_err;
|
||||
|
||||
mapped += s->length;
|
||||
}
|
||||
|
||||
return mapped;
|
||||
|
||||
out_err:
|
||||
/* undo mappings already done */
|
||||
iommu_unmap(domain, iova, mapped);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(default_iommu_map_sg);
|
||||
|
||||
int iommu_domain_window_enable(struct iommu_domain *domain, u32 wnd_nr,
|
||||
phys_addr_t paddr, u64 size, int prot)
|
||||
|
|
|
|||
|
|
@ -1127,6 +1127,7 @@ static const struct iommu_ops ipmmu_ops = {
|
|||
.detach_dev = ipmmu_detach_device,
|
||||
.map = ipmmu_map,
|
||||
.unmap = ipmmu_unmap,
|
||||
.map_sg = default_iommu_map_sg,
|
||||
.iova_to_phys = ipmmu_iova_to_phys,
|
||||
.add_device = ipmmu_add_device,
|
||||
.remove_device = ipmmu_remove_device,
|
||||
|
|
|
|||
|
|
@ -56,19 +56,13 @@ static int do_setup_msi_irqs(struct pci_dev *dev, int nvec)
|
|||
unsigned int irq;
|
||||
struct msi_desc *msidesc;
|
||||
|
||||
WARN_ON(!list_is_singular(&dev->msi_list));
|
||||
msidesc = list_entry(dev->msi_list.next, struct msi_desc, list);
|
||||
WARN_ON(msidesc->irq);
|
||||
WARN_ON(msidesc->msi_attrib.multiple);
|
||||
WARN_ON(msidesc->nvec_used);
|
||||
|
||||
irq = irq_alloc_hwirqs(nvec, dev_to_node(&dev->dev));
|
||||
if (irq == 0)
|
||||
return -ENOSPC;
|
||||
|
||||
nvec_pow2 = __roundup_pow_of_two(nvec);
|
||||
msidesc->nvec_used = nvec;
|
||||
msidesc->msi_attrib.multiple = ilog2(nvec_pow2);
|
||||
for (sub_handle = 0; sub_handle < nvec; sub_handle++) {
|
||||
if (!sub_handle) {
|
||||
index = msi_alloc_remapped_irq(dev, irq, nvec_pow2);
|
||||
|
|
@ -96,8 +90,6 @@ error:
|
|||
* IRQs from tearing down again in default_teardown_msi_irqs()
|
||||
*/
|
||||
msidesc->irq = 0;
|
||||
msidesc->nvec_used = 0;
|
||||
msidesc->msi_attrib.multiple = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -681,6 +681,7 @@ static const struct iommu_ops msm_iommu_ops = {
|
|||
.detach_dev = msm_iommu_detach_dev,
|
||||
.map = msm_iommu_map,
|
||||
.unmap = msm_iommu_unmap,
|
||||
.map_sg = default_iommu_map_sg,
|
||||
.iova_to_phys = msm_iommu_iova_to_phys,
|
||||
.pgsize_bitmap = MSM_IOMMU_PGSIZES,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1288,6 +1288,7 @@ static const struct iommu_ops omap_iommu_ops = {
|
|||
.detach_dev = omap_iommu_detach_dev,
|
||||
.map = omap_iommu_map,
|
||||
.unmap = omap_iommu_unmap,
|
||||
.map_sg = default_iommu_map_sg,
|
||||
.iova_to_phys = omap_iommu_iova_to_phys,
|
||||
.add_device = omap_iommu_add_device,
|
||||
.remove_device = omap_iommu_remove_device,
|
||||
|
|
|
|||
|
|
@ -361,6 +361,7 @@ static const struct iommu_ops shmobile_iommu_ops = {
|
|||
.detach_dev = shmobile_iommu_detach_device,
|
||||
.map = shmobile_iommu_map,
|
||||
.unmap = shmobile_iommu_unmap,
|
||||
.map_sg = default_iommu_map_sg,
|
||||
.iova_to_phys = shmobile_iommu_iova_to_phys,
|
||||
.add_device = shmobile_iommu_add_device,
|
||||
.pgsize_bitmap = SZ_1M | SZ_64K | SZ_4K,
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue