summaryrefslogtreecommitdiff
path: root/drivers/iommu
AgeCommit message (Collapse)Author
2014-04-16Merge git://git.infradead.org/iommu-2.6 into iommu/fixesJoerg Roedel
2014-04-15iommu/arm-smmu: fix panic in arm_smmu_alloc_init_pteBin Wang
kernel panic happened when iommu_unmap a buffer larger than 2MB, more than expected pmd entries got “invalidated”, due to a wrong range passed to arm_smmu_alloc_init_pte. it was likely a typo, now we fix it, passing the correct "end" address to arm_smmu_alloc_init_pte. Signed-off-by: Bin Wang <binw@marvell.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
2014-04-15iommu/arm-smmu: Return 0 on unmap failureLaurent Pinchart
The IOMMU core expects the unmap operation to return the number of bytes that have been unmapped or 0 on failure, a negative return value being treated like a number of bytes. Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
2014-04-14iommu/vt-d: fix bug in matching PCI devices with DRHD/RMRR descriptorsJiang Liu
Commit "59ce0515cdaf iommu/vt-d: Update DRHD/RMRR/ATSR device scope caches when PCI hotplug happens" introduces a bug, which fails to match PCI devices with DMAR device scope entries if PCI path array in the entry has more than one level. For example, it fails to handle [1D2h 0466 1] Device Scope Entry Type : 01 [1D3h 0467 1] Entry Length : 0A [1D4h 0468 2] Reserved : 0000 [1D6h 0470 1] Enumeration ID : 00 [1D7h 0471 1] PCI Bus Number : 00 [1D8h 0472 2] PCI Path : 1C,04 [1DAh 0474 2] PCI Path : 00,02 And cause DMA failure on HP DL980 as: DMAR:[fault reason 02] Present bit in context entry is clear dmar: DRHD: handling fault status reg 602 dmar: DMAR:[DMA Read] Request device [02:00.2] fault addr 7f61e000 Reported-and-tested-by: Davidlohr Bueso <davidlohr@hp.com> Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-04-14iommu/vt-d: Fix get_domain_for_dev() handling of upstream PCIe bridgesDavid Woodhouse
Commit 146922ec79 ("iommu/vt-d: Make get_domain_for_dev() take struct device") introduced new variables bridge_bus and bridge_devfn to identify the upstream PCIe to PCI bridge responsible for the given target device. Leaving the original bus/devfn variables to identify the target device itself, now that it is no longer assumed to be PCI and we can no longer trivially find that information. However, the patch failed to correctly use the new variables in all cases; instead using the as-yet-uninitialised 'bus' and 'devfn' variables. Reported-by: Alex Williamson <alex.williamson@redhat.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-04-13iommu/vt-d: fix memory leakage caused by commit ea8ea46Jiang Liu
Commit ea8ea46 "iommu/vt-d: Clean up and fix page table clear/free behaviour" introduces possible leakage of DMA page tables due to: for (pte = page_address(pg); !first_pte_in_page(pte); pte++) { if (dma_pte_present(pte) && !dma_pte_superpage(pte)) freelist = dma_pte_list_pagetables(domain, level - 1, pte, freelist); } For the first pte in a page, first_pte_in_page(pte) will always be true, thus dma_pte_list_pagetables() will never be called and leak DMA page tables if level is bigger than 1. Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-04-05Merge tag 'iommu-updates-v3.15' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu Pull IOMMU upates from Joerg Roedel: "This time a few more updates queued up. - Rework VT-d code to support ACPI devices - Improvements for memory and PCI hotplug support in the VT-d driver - Device-tree support for OMAP IOMMU - Convert OMAP IOMMU to use devm_* interfaces - Fixed PASID support for AMD IOMMU - Other random cleanups and fixes for OMAP, ARM-SMMU and SHMOBILE IOMMU Most of the changes are in the VT-d driver because some rework was necessary for better hotplug and ACPI device support" * tag 'iommu-updates-v3.15' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: (75 commits) iommu/vt-d: Fix error handling in ANDD processing iommu/vt-d: returning free pointer in get_domain_for_dev() iommu/vt-d: Only call dmar_acpi_dev_scope_init() if DRHD units present iommu/vt-d: Check for NULL pointer in dmar_acpi_dev_scope_init() iommu/amd: Fix logic to determine and checking max PASID iommu/vt-d: Include ACPI devices in iommu=pt iommu/vt-d: Finally enable translation for non-PCI devices iommu/vt-d: Remove to_pci_dev() in intel_map_page() iommu/vt-d: Remove pdev from intel_iommu_attach_device() iommu/vt-d: Remove pdev from iommu_no_mapping() iommu/vt-d: Make domain_add_dev_info() take struct device iommu/vt-d: Make domain_remove_one_dev_info() take struct device iommu/vt-d: Rename 'hwdev' variables to 'dev' now that that's the norm iommu/vt-d: Remove some pointless to_pci_dev() calls iommu/vt-d: Make get_valid_domain_for_dev() take struct device iommu/vt-d: Make iommu_should_identity_map() take struct device iommu/vt-d: Handle RMRRs for non-PCI devices iommu/vt-d: Make get_domain_for_dev() take struct device iommu/vt-d: Make domain_context_mapp{ed,ing}() take struct device iommu/vt-d: Make device_to_iommu() cope with non-PCI devices ...
2014-04-02Merge branch 'for-3.15' of ↵Linus Torvalds
git://git.linaro.org/people/mszyprowski/linux-dma-mapping Pull DMA-mapping updates from Marek Szyprowski: "This contains extension for more efficient handling of io address space for dma-mapping subsystem for ARM architecture" * 'for-3.15' of git://git.linaro.org/people/mszyprowski/linux-dma-mapping: arm: dma-mapping: remove order parameter from arm_iommu_create_mapping() arm: dma-mapping: Add support to extend DMA IOMMU mappings
2014-04-02Merge branches 'iommu/fixes', 'arm/smmu', 'x86/amd', 'arm/omap', ↵Joerg Roedel
'arm/shmobile' and 'x86/vt-d' into next
2014-04-01Merge tag 'pci-v3.15-changes' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci Pull PCI changes from Bjorn Helgaas: "Enumeration - Increment max correctly in pci_scan_bridge() (Andreas Noever) - Clarify the "scan anyway" comment in pci_scan_bridge() (Andreas Noever) - Assign CardBus bus number only during the second pass (Andreas Noever) - Use request_resource_conflict() instead of insert_ for bus numbers (Andreas Noever) - Make sure bus number resources stay within their parents bounds (Andreas Noever) - Remove pci_fixup_parent_subordinate_busnr() (Andreas Noever) - Check for child busses which use more bus numbers than allocated (Andreas Noever) - Don't scan random busses in pci_scan_bridge() (Andreas Noever) - x86: Drop pcibios_scan_root() check for bus already scanned (Bjorn Helgaas) - x86: Use pcibios_scan_root() instead of pci_scan_bus_with_sysdata() (Bjorn Helgaas) - x86: Use pcibios_scan_root() instead of pci_scan_bus_on_node() (Bjorn Helgaas) - x86: Merge pci_scan_bus_on_node() into pcibios_scan_root() (Bjorn Helgaas) - x86: Drop return value of pcibios_scan_root() (Bjorn Helgaas) NUMA - x86: Add x86_pci_root_bus_node() to look up NUMA node from PCI bus (Bjorn Helgaas) - x86: Use x86_pci_root_bus_node() instead of get_mp_bus_to_node() (Bjorn Helgaas) - x86: Remove mp_bus_to_node[], set_mp_bus_to_node(), get_mp_bus_to_node() (Bjorn Helgaas) - x86: Use NUMA_NO_NODE, not -1, for unknown node (Bjorn Helgaas) - x86: Remove acpi_get_pxm() usage (Bjorn Helgaas) - ia64: Use NUMA_NO_NODE, not MAX_NUMNODES, for unknown node (Bjorn Helgaas) - ia64: Remove acpi_get_pxm() usage (Bjorn Helgaas) - ACPI: Fix acpi_get_node() prototype (Bjorn Helgaas) Resource management - i2o: Fix and refactor PCI space allocation (Bjorn Helgaas) - Add resource_contains() (Bjorn Helgaas) - Add %pR support for IORESOURCE_UNSET (Bjorn Helgaas) - Mark resources as IORESOURCE_UNSET if we can't assign them (Bjorn Helgaas) - Don't clear IORESOURCE_UNSET when updating BAR (Bjorn Helgaas) - Check IORESOURCE_UNSET before updating BAR (Bjorn Helgaas) - Don't try to claim IORESOURCE_UNSET resources (Bjorn Helgaas) - Mark 64-bit resource as IORESOURCE_UNSET if we only support 32-bit (Bjorn Helgaas) - Don't enable decoding if BAR hasn't been assigned an address (Bjorn Helgaas) - Add "weak" generic pcibios_enable_device() implementation (Bjorn Helgaas) - alpha, microblaze, sh, sparc, tile: Use default pcibios_enable_device() (Bjorn Helgaas) - s390: Use generic pci_enable_resources() (Bjorn Helgaas) - Don't check resource_size() in pci_bus_alloc_resource() (Bjorn Helgaas) - Set type in __request_region() (Bjorn Helgaas) - Check all IORESOURCE_TYPE_BITS in pci_bus_alloc_from_region() (Bjorn Helgaas) - Change pci_bus_alloc_resource() type_mask to unsigned long (Bjorn Helgaas) - Log IDE resource quirk in dmesg (Bjorn Helgaas) - Revert "[PATCH] Insert GART region into resource map" (Bjorn Helgaas) PCI device hotplug - Make check_link_active() non-static (Rajat Jain) - Use link change notifications for hot-plug and removal (Rajat Jain) - Enable link state change notifications (Rajat Jain) - Don't disable the link permanently during removal (Rajat Jain) - Don't check adapter or latch status while disabling (Rajat Jain) - Disable link notification across slot reset (Rajat Jain) - Ensure very fast hotplug events are also processed (Rajat Jain) - Add hotplug_lock to serialize hotplug events (Rajat Jain) - Remove a non-existent card, regardless of "surprise" capability (Rajat Jain) - Don't turn slot off when hot-added device already exists (Yijing Wang) MSI - Keep pci_enable_msi() documentation (Alexander Gordeev) - ahci: Fix broken single MSI fallback (Alexander Gordeev) - ahci, vfio: Use pci_enable_msi_range() (Alexander Gordeev) - Check kmalloc() return value, fix leak of name (Greg Kroah-Hartman) - Fix leak of msi_attrs (Greg Kroah-Hartman) - Fix pci_msix_vec_count() htmldocs failure (Masanari Iida) Virtualization - Device-specific ACS support (Alex Williamson) Freescale i.MX6 - Wait for retraining (Marek Vasut) Marvell MVEBU - Use Device ID and revision from underlying endpoint (Andrew Lunn) - Fix incorrect size for PCI aperture resources (Jason Gunthorpe) - Call request_resource() on the apertures (Jason Gunthorpe) - Fix potential issue in range parsing (Jean-Jacques Hiblot) Renesas R-Car - Check platform_get_irq() return code (Ben Dooks) - Add error interrupt handling (Ben Dooks) - Fix bridge logic configuration accesses (Ben Dooks) - Register each instance independently (Magnus Damm) - Break out window size handling (Magnus Damm) - Make the Kconfig dependencies more generic (Magnus Damm) Synopsys DesignWare - Fix RC BAR to be single 64-bit non-prefetchable memory (Mohit Kumar) Miscellaneous - Remove unused SR-IOV VF Migration support (Bjorn Helgaas) - Enable INTx if BIOS left them disabled (Bjorn Helgaas) - Fix hex vs decimal typo in cpqhpc_probe() (Dan Carpenter) - Clean up par-arch object file list (Liviu Dudau) - Set IORESOURCE_ROM_SHADOW only for the default VGA device (Sander Eikelenboom) - ACPI, ARM, drm, powerpc, pcmcia, PCI: Use list_for_each_entry() for bus traversal (Yijing Wang) - Fix pci_bus_b() build failure (Paul Gortmaker)" * tag 'pci-v3.15-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (108 commits) Revert "[PATCH] Insert GART region into resource map" PCI: Log IDE resource quirk in dmesg PCI: Change pci_bus_alloc_resource() type_mask to unsigned long PCI: Check all IORESOURCE_TYPE_BITS in pci_bus_alloc_from_region() resources: Set type in __request_region() PCI: Don't check resource_size() in pci_bus_alloc_resource() s390/PCI: Use generic pci_enable_resources() tile PCI RC: Use default pcibios_enable_device() sparc/PCI: Use default pcibios_enable_device() (Leon only) sh/PCI: Use default pcibios_enable_device() microblaze/PCI: Use default pcibios_enable_device() alpha/PCI: Use default pcibios_enable_device() PCI: Add "weak" generic pcibios_enable_device() implementation PCI: Don't enable decoding if BAR hasn't been assigned an address PCI: Enable INTx in pci_reenable_device() only when MSI/MSI-X not enabled PCI: Mark 64-bit resource as IORESOURCE_UNSET if we only support 32-bit PCI: Don't try to claim IORESOURCE_UNSET resources PCI: Check IORESOURCE_UNSET before updating BAR PCI: Don't clear IORESOURCE_UNSET when updating BAR PCI: Mark resources as IORESOURCE_UNSET if we can't assign them ... Conflicts: arch/x86/include/asm/topology.h drivers/ata/ahci.c
2014-04-01iommu/vt-d: Fix error handling in ANDD processingDavid Woodhouse
If we failed to find an ACPI device to correspond to an ANDD record, we would fail to increment our pointer and would just process the same record over and over again, with predictable results. Turn it from a while() loop into a for() loop to let the 'continue' in the error paths work correctly. Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-28iommu/vt-d: returning free pointer in get_domain_for_dev()Dan Carpenter
If we hit this error condition then we want to return a NULL pointer and not a freed variable. Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-28iommu/vt-d: Only call dmar_acpi_dev_scope_init() if DRHD units presentDavid Woodhouse
As pointed out by Jörg and fixed in commit 11f1a7768 ("iommu/vt-d: Check for NULL pointer in dmar_acpi_dev_scope_init(), this code path can bizarrely get exercised even on AMD IOMMU systems with IRQ remapping enabled. In addition to the defensive check for NULL which Jörg added, let's also just avoid calling the function at all if there aren't an Intel IOMMU units in the system. Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-25iommu/vt-d: Check for NULL pointer in dmar_acpi_dev_scope_init()Joerg Roedel
When ir_dev_scope_init() is called via a rootfs initcall it will check for irq_remapping_enabled before it calls (indirectly) into dmar_acpi_dev_scope_init() which uses the dmar_tbl pointer without any checks. The AMD IOMMU driver also sets the irq_remapping_enabled flag which causes the dmar_acpi_dev_scope_init() function to be called on systems with AMD IOMMU hardware too, causing a boot-time kernel crash. Signed-off-by: Joerg Roedel <joro@8bytes.org>
2014-03-24iommu/amd: Fix logic to determine and checking max PASIDSuravee Suthikulpanit
In reality, the spec can only support 16-bit PASID since INVALIDATE_IOTLB_PAGES and COMPLETE_PPR_REQUEST commands only allow 16-bit PASID. So, we updated the PASID_MASK accordingly and invoke BUG_ON if the hardware is reporting PASmax more than 16-bit. Besides, max PASID is defined as ((2^(PASmax+1)) - 1). The current does not determine this correctly. Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> Tested-by: Jay Cornwall <Jay.Cornwall@amd.com> Signed-off-by: Joerg Roedel <joro@8bytes.org>
2014-03-24iommu/vt-d: Include ACPI devices in iommu=ptDavid Woodhouse
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-24iommu/vt-d: Finally enable translation for non-PCI devicesDavid Woodhouse
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-24iommu/vt-d: Remove to_pci_dev() in intel_map_page()David Woodhouse
It might not be... Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-24iommu/vt-d: Remove pdev from intel_iommu_attach_device()David Woodhouse
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-24iommu/vt-d: Remove pdev from iommu_no_mapping()David Woodhouse
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-24iommu/vt-d: Make domain_add_dev_info() take struct deviceDavid Woodhouse
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-24iommu/vt-d: Make domain_remove_one_dev_info() take struct deviceDavid Woodhouse
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-24iommu/vt-d: Rename 'hwdev' variables to 'dev' now that that's the normDavid Woodhouse
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-24iommu/vt-d: Remove some pointless to_pci_dev() callsDavid Woodhouse
Mostly made redundant by using dev_name() instead of pci_name(), and one instance of using *dev->dma_mask instead of pdev->dma_mask. Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-24iommu/vt-d: Make get_valid_domain_for_dev() take struct deviceDavid Woodhouse
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-24iommu/vt-d: Make iommu_should_identity_map() take struct deviceDavid Woodhouse
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-24iommu/vt-d: Handle RMRRs for non-PCI devicesDavid Woodhouse
Should hopefully never happen (RMRRs are an abomination) but while we're busy eliminating all the PCI assumptions, we might as well do it. Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-24iommu/vt-d: Make get_domain_for_dev() take struct deviceDavid Woodhouse
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-24iommu/vt-d: Make domain_context_mapp{ed,ing}() take struct deviceDavid Woodhouse
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-24iommu/vt-d: Make device_to_iommu() cope with non-PCI devicesDavid Woodhouse
Pass the struct device to it, and also make it return the bus/devfn to use, since that is also stored in the DMAR table. Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-24iommu/vt-d: Make identity_mapping() take struct device not struct pci_devDavid Woodhouse
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-24iommu/vt-d: Remove segment from struct device_domain_info()David Woodhouse
It's accessible via info->iommu->segment so this is redundant. Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-24iommu/vt-d: Store PCI segment number in struct intel_iommuDavid Woodhouse
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-24iommu/vt-d: Remove device_to_iommu() call from domain_remove_dev_info()David Woodhouse
This was problematic because it works by domain/bus/devfn and we want to make device_to_iommu() use only a struct device * (for handling non-PCI devices). Now that the iommu pointer is reliably stored in the device_domain_info, we don't need to look it up. Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-24iommu/vt-d: Simplify iommu check in domain_remove_one_dev_info()David Woodhouse
Now we store the iommu in the device_domain_info, we don't need to do a lookup. Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-24iommu/vt-d: Always store iommu in device_domain_infoDavid Woodhouse
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-24iommu/vt-d: Use domain_remove_one_dev_info() in domain_add_dev_info() error pathDavid Woodhouse
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-24iommu/vt-d: use dmar_insert_dev_info() from dma_add_dev_info()David Woodhouse
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-24iommu/vt-d: Stop dmar_insert_dev_info() freeing domains on losing raceDavid Woodhouse
By moving this into get_domain_for_dev() we can make dmar_insert_dev_info() suitable for use with "special" domains such as the si_domain, which currently use domain_add_dev_info(). Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-24iommu/vt-d: Pass iommu to domain_context_mapping_one() and ↵David Woodhouse
iommu_support_dev_iotlb() Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-24iommu/vt-d: Use struct device in device_domain_info, not struct pci_devDavid Woodhouse
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-24iommu/vt-d: Make dmar_insert_dev_info() take struct device instead of struct ↵David Woodhouse
pci_dev Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-24iommu/vt-d: Make iommu_dummy() take struct device instead of struct pci_devDavid Woodhouse
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-24iommu/vt-d: Add ACPI devices into dmaru->devices[] arrayDavid Woodhouse
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-24iommu/vt-d: Change scope lists to struct device, bus, devfnDavid Woodhouse
It's not only for PCI devices any more, and the scope information for an ACPI device provides the bus and devfn so that has to be stored here too. It is the device pointer itself which needs to be protected with RCU, so the __rcu annotation follows it into the definition of struct dmar_dev_scope, since we're no longer just passing arrays of device pointers around. Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-20iommu/vt-d: Allocate space for ACPI devicesDavid Woodhouse
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-20iommu/vt-d: Parse ANDD recordsDavid Woodhouse
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-19iommu/vt-d: Be less pessimistic about domain coherency where possibleDavid Woodhouse
In commit 2e12bc29 ("intel-iommu: Default to non-coherent for domains unattached to iommus") we decided to err on the side of caution and always assume that it's possible that a device will be attached which is behind a non-coherent IOMMU. In some cases, however, that just *cannot* happen. If there *are* no IOMMUs in the system which are non-coherent, then we don't need to do it. And flushing the dcache is a *significant* performance hit. Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-19iommu/vt-d: Honour intel_iommu=sp_off for non-VMM domainsDavid Woodhouse
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2014-03-19iommu/vt-d: Clean up and fix page table clear/free behaviourDavid Woodhouse
There is a race condition between the existing clear/free code and the hardware. The IOMMU is actually permitted to cache the intermediate levels of the page tables, and doesn't need to walk the table from the very top of the PGD each time. So the existing back-to-back calls to dma_pte_clear_range() and dma_pte_free_pagetable() can lead to a use-after-free where the IOMMU reads from a freed page table. When freeing page tables we actually need to do the IOTLB flush, with the 'invalidation hint' bit clear to indicate that it's not just a leaf-node flush, after unlinking each page table page from the next level up but before actually freeing it. So in the rewritten domain_unmap() we just return a list of pages (using pg->freelist to make a list of them), and then the caller is expected to do the appropriate IOTLB flush (or tear down the domain completely, whatever), before finally calling dma_free_pagelist() to free the pages. As an added bonus, we no longer need to flush the CPU's data cache for pages which are about to be *removed* from the page table hierarchy anyway, in the non-cache-coherent case. This drastically improves the performance of large unmaps. As a side-effect of all these changes, this also fixes the fact that intel_iommu_unmap() was neglecting to free the page tables for the range in question after clearing them. Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>