diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-23 18:27:19 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-23 18:27:19 -0700 |
commit | 6eae81a5e2d6646a61146501fd3032a340863c1d (patch) | |
tree | c1c8a5fd7930f756d4d124870e0076903e3b4ba0 /drivers/iommu/dmar.c | |
parent | 54245ed870c8cf9ff87fdf78955ffbc93b261e9f (diff) | |
parent | 5ffde2f67181195d457b95df44b8f88e8d969d89 (diff) | |
download | op-kernel-dev-6eae81a5e2d6646a61146501fd3032a340863c1d.zip op-kernel-dev-6eae81a5e2d6646a61146501fd3032a340863c1d.tar.gz |
Merge tag 'iommu-updates-v4.2' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu
Pull IOMMU updates from Joerg Roedel:
"This time with bigger changes than usual:
- A new IOMMU driver for the ARM SMMUv3.
This IOMMU is pretty different from SMMUv1 and v2 in that it is
configured through in-memory structures and not through the MMIO
register region. The ARM SMMUv3 also supports IO demand paging for
PCI devices with PRI/PASID capabilities, but this is not
implemented in the driver yet.
- Lots of cleanups and device-tree support for the Exynos IOMMU
driver. This is part of the effort to bring Exynos DRM support
upstream.
- Introduction of default domains into the IOMMU core code.
The rationale behind this is to move functionalily out of the IOMMU
drivers to common code to get to a unified behavior between
different drivers. The patches here introduce a default domain for
iommu-groups (isolation groups).
A device will now always be attached to a domain, either the
default domain or another domain handled by the device driver. The
IOMMU drivers have to be modified to make use of that feature. So
long the AMD IOMMU driver is converted, with others to follow.
- Patches for the Intel VT-d drvier to fix DMAR faults that happen
when a kdump kernel boots.
When the kdump kernel boots it re-initializes the IOMMU hardware,
which destroys all mappings from the crashed kernel. As this
happens before the endpoint devices are re-initialized, any
in-flight DMA causes a DMAR fault. These faults cause PCI master
aborts, which some devices can't handle properly and go into an
undefined state, so that the device driver in the kdump kernel
fails to initialize them and the dump fails.
This is now fixed by copying over the mapping structures (only
context tables and interrupt remapping tables) from the old kernel
and keep the old mappings in place until the device driver of the
new kernel takes over. This emulates the the behavior without an
IOMMU to the best degree possible.
- A couple of other small fixes and cleanups"
* tag 'iommu-updates-v4.2' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: (69 commits)
iommu/amd: Handle large pages correctly in free_pagetable
iommu/vt-d: Don't disable IR when it was previously enabled
iommu/vt-d: Make sure copied over IR entries are not reused
iommu/vt-d: Copy IR table from old kernel when in kdump mode
iommu/vt-d: Set IRTA in intel_setup_irq_remapping
iommu/vt-d: Disable IRQ remapping in intel_prepare_irq_remapping
iommu/vt-d: Move QI initializationt to intel_setup_irq_remapping
iommu/vt-d: Move EIM detection to intel_prepare_irq_remapping
iommu/vt-d: Enable Translation only if it was previously disabled
iommu/vt-d: Don't disable translation prior to OS handover
iommu/vt-d: Don't copy translation tables if RTT bit needs to be changed
iommu/vt-d: Don't do early domain assignment if kdump kernel
iommu/vt-d: Allocate si_domain in init_dmars()
iommu/vt-d: Mark copied context entries
iommu/vt-d: Do not re-use domain-ids from the old kernel
iommu/vt-d: Copy translation tables from old kernel
iommu/vt-d: Detect pre enabled translation
iommu/vt-d: Make root entry visible for hardware right after allocation
iommu/vt-d: Init QI before root entry is allocated
iommu/vt-d: Cleanup log messages
...
Diffstat (limited to 'drivers/iommu/dmar.c')
-rw-r--r-- | drivers/iommu/dmar.c | 28 |
1 files changed, 14 insertions, 14 deletions
diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c index 536f2d8..c9db04d 100644 --- a/drivers/iommu/dmar.c +++ b/drivers/iommu/dmar.c @@ -26,7 +26,7 @@ * These routines are used by both DMA-remapping and Interrupt-remapping */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt /* has to precede printk.h */ +#define pr_fmt(fmt) "DMAR: " fmt #include <linux/pci.h> #include <linux/dmar.h> @@ -555,7 +555,7 @@ static int dmar_walk_remapping_entries(struct acpi_dmar_header *start, break; } else if (next > end) { /* Avoid passing table end */ - pr_warn(FW_BUG "record passes table end\n"); + pr_warn(FW_BUG "Record passes table end\n"); ret = -EINVAL; break; } @@ -802,7 +802,7 @@ int __init dmar_table_init(void) ret = parse_dmar_table(); if (ret < 0) { if (ret != -ENODEV) - pr_info("parse DMAR table failure.\n"); + pr_info("Parse DMAR table failure.\n"); } else if (list_empty(&dmar_drhd_units)) { pr_info("No DMAR devices found\n"); ret = -ENODEV; @@ -847,7 +847,7 @@ dmar_validate_one_drhd(struct acpi_dmar_header *entry, void *arg) else addr = early_ioremap(drhd->address, VTD_PAGE_SIZE); if (!addr) { - pr_warn("IOMMU: can't validate: %llx\n", drhd->address); + pr_warn("Can't validate DRHD address: %llx\n", drhd->address); return -EINVAL; } @@ -921,14 +921,14 @@ static int map_iommu(struct intel_iommu *iommu, u64 phys_addr) iommu->reg_size = VTD_PAGE_SIZE; if (!request_mem_region(iommu->reg_phys, iommu->reg_size, iommu->name)) { - pr_err("IOMMU: can't reserve memory\n"); + pr_err("Can't reserve memory\n"); err = -EBUSY; goto out; } iommu->reg = ioremap(iommu->reg_phys, iommu->reg_size); if (!iommu->reg) { - pr_err("IOMMU: can't map the region\n"); + pr_err("Can't map the region\n"); err = -ENOMEM; goto release; } @@ -952,13 +952,13 @@ static int map_iommu(struct intel_iommu *iommu, u64 phys_addr) iommu->reg_size = map_size; if (!request_mem_region(iommu->reg_phys, iommu->reg_size, iommu->name)) { - pr_err("IOMMU: can't reserve memory\n"); + pr_err("Can't reserve memory\n"); err = -EBUSY; goto out; } iommu->reg = ioremap(iommu->reg_phys, iommu->reg_size); if (!iommu->reg) { - pr_err("IOMMU: can't map the region\n"); + pr_err("Can't map the region\n"); err = -ENOMEM; goto release; } @@ -1014,14 +1014,14 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd) return -ENOMEM; if (dmar_alloc_seq_id(iommu) < 0) { - pr_err("IOMMU: failed to allocate seq_id\n"); + pr_err("Failed to allocate seq_id\n"); err = -ENOSPC; goto error; } err = map_iommu(iommu, drhd->reg_base_addr); if (err) { - pr_err("IOMMU: failed to map %s\n", iommu->name); + pr_err("Failed to map %s\n", iommu->name); goto error_free_seq_id; } @@ -1045,8 +1045,8 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd) iommu->node = -1; ver = readl(iommu->reg + DMAR_VER_REG); - pr_info("IOMMU %d: reg_base_addr %llx ver %d:%d cap %llx ecap %llx\n", - iommu->seq_id, + pr_info("%s: reg_base_addr %llx ver %d:%d cap %llx ecap %llx\n", + iommu->name, (unsigned long long)drhd->reg_base_addr, DMAR_VER_MAJOR(ver), DMAR_VER_MINOR(ver), (unsigned long long)iommu->cap, @@ -1646,13 +1646,13 @@ int dmar_set_interrupt(struct intel_iommu *iommu) if (irq > 0) { iommu->irq = irq; } else { - pr_err("IOMMU: no free vectors\n"); + pr_err("No free IRQ vectors\n"); return -EINVAL; } ret = request_irq(irq, dmar_fault, IRQF_NO_THREAD, iommu->name, iommu); if (ret) - pr_err("IOMMU: can't request irq\n"); + pr_err("Can't request irq\n"); return ret; } |