summaryrefslogtreecommitdiffstats
path: root/drivers/iommu/dmar.c
diff options
context:
space:
mode:
authorLu Baolu <baolu.lu@linux.intel.com>2018-10-23 15:45:01 +0800
committerMika Westerberg <mika.westerberg@linux.intel.com>2018-12-05 12:01:55 +0300
commit89a6079df791aeace2044ea93be1b397195824ec (patch)
tree4a6b9484088da92e47195dd106503ab75abde5ed /drivers/iommu/dmar.c
parent617654aae50eb59dd98aa53fb562e850937f4cde (diff)
downloadlinux-stable-89a6079df791aeace2044ea93be1b397195824ec.tar.gz
linux-stable-89a6079df791aeace2044ea93be1b397195824ec.tar.bz2
linux-stable-89a6079df791aeace2044ea93be1b397195824ec.zip
iommu/vt-d: Force IOMMU on for platform opt in hint
Intel VT-d spec added a new DMA_CTRL_PLATFORM_OPT_IN_FLAG flag in DMAR ACPI table [1] for BIOS to report compliance about platform initiated DMA restricted to RMRR ranges when transferring control to the OS. This means that during OS boot, before it enables IOMMU none of the connected devices can bypass DMA protection for instance by overwriting the data structures used by the IOMMU. The OS also treats this as a hint that the IOMMU should be enabled to prevent DMA attacks from possible malicious devices. A use of this flag is Kernel DMA protection for Thunderbolt [2] which in practice means that IOMMU should be enabled for PCIe devices connected to the Thunderbolt ports. With IOMMU enabled for these devices, all DMA operations are limited in the range reserved for it, thus the DMA attacks are prevented. All these devices are enumerated in the PCI/PCIe module and marked with an untrusted flag. This forces IOMMU to be enabled if DMA_CTRL_PLATFORM_OPT_IN_FLAG is set in DMAR ACPI table and there are PCIe devices marked as untrusted in the system. This can be turned off by adding "intel_iommu=off" in the kernel command line, if any problems are found. [1] https://software.intel.com/sites/default/files/managed/c5/15/vt-directed-io-spec.pdf [2] https://docs.microsoft.com/en-us/windows/security/information-protection/kernel-dma-protection-for-thunderbolt Cc: Jacob Pan <jacob.jun.pan@linux.intel.com> Cc: Sohil Mehta <sohil.mehta@intel.com> Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Reviewed-by: Ashok Raj <ashok.raj@intel.com> Reviewed-by: Joerg Roedel <jroedel@suse.de> Acked-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers/iommu/dmar.c')
-rw-r--r--drivers/iommu/dmar.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index d9c748b6f9e4..1edf2a251336 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -2042,3 +2042,28 @@ int dmar_device_remove(acpi_handle handle)
{
return dmar_device_hotplug(handle, false);
}
+
+/*
+ * dmar_platform_optin - Is %DMA_CTRL_PLATFORM_OPT_IN_FLAG set in DMAR table
+ *
+ * Returns true if the platform has %DMA_CTRL_PLATFORM_OPT_IN_FLAG set in
+ * the ACPI DMAR table. This means that the platform boot firmware has made
+ * sure no device can issue DMA outside of RMRR regions.
+ */
+bool dmar_platform_optin(void)
+{
+ struct acpi_table_dmar *dmar;
+ acpi_status status;
+ bool ret;
+
+ status = acpi_get_table(ACPI_SIG_DMAR, 0,
+ (struct acpi_table_header **)&dmar);
+ if (ACPI_FAILURE(status))
+ return false;
+
+ ret = !!(dmar->flags & DMAR_PLATFORM_OPT_IN);
+ acpi_put_table((struct acpi_table_header *)dmar);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(dmar_platform_optin);