aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShaohua Li <shli@fb.com>2017-04-26 12:18:35 -0400
committerJoerg Roedel <jroedel@suse.de>2017-04-26 17:57:53 -0400
commitbfd20f1cc85010d2f2d77e544da05cd8c149ba9b (patch)
tree1da8f1e85622fbf83264b356e1a840c0639b9b65
parent161b28aae1651aa7ad63ec14753aa8a751154340 (diff)
x86, iommu/vt-d: Add an option to disable Intel IOMMU force on
IOMMU harms performance signficantly when we run very fast networking workloads. It's 40GB networking doing XDP test. Software overhead is almost unaware, but it's the IOTLB miss (based on our analysis) which kills the performance. We observed the same performance issue even with software passthrough (identity mapping), only the hardware passthrough survives. The pps with iommu (with software passthrough) is only about ~30% of that without it. This is a limitation in hardware based on our observation, so we'd like to disable the IOMMU force on, but we do want to use TBOOT and we can sacrifice the DMA security bought by IOMMU. I must admit I know nothing about TBOOT, but TBOOT guys (cc-ed) think not eabling IOMMU is totally ok. So introduce a new boot option to disable the force on. It's kind of silly we need to run into intel_iommu_init even without force on, but we need to disable TBOOT PMR registers. For system without the boot option, nothing is changed. Signed-off-by: Shaohua Li <shli@fb.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
-rw-r--r--Documentation/admin-guide/kernel-parameters.txt9
-rw-r--r--arch/x86/kernel/tboot.c3
-rw-r--r--drivers/iommu/intel-iommu.c18
-rw-r--r--include/linux/dma_remapping.h1
4 files changed, 31 insertions, 0 deletions
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 2ba45caabada..17135bfade6a 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -1578,6 +1578,15 @@
1578 extended tables themselves, and also PASID support. With 1578 extended tables themselves, and also PASID support. With
1579 this option set, extended tables will not be used even 1579 this option set, extended tables will not be used even
1580 on hardware which claims to support them. 1580 on hardware which claims to support them.
1581 tboot_noforce [Default Off]
1582 Do not force the Intel IOMMU enabled under tboot.
1583 By default, tboot will force Intel IOMMU on, which
1584 could harm performance of some high-throughput
1585 devices like 40GBit network cards, even if identity
1586 mapping is enabled.
1587 Note that using this option lowers the security
1588 provided by tboot because it makes the system
1589 vulnerable to DMA attacks.
1581 1590
1582 intel_idle.max_cstate= [KNL,HW,ACPI,X86] 1591 intel_idle.max_cstate= [KNL,HW,ACPI,X86]
1583 0 disables intel_idle and fall back on acpi_idle. 1592 0 disables intel_idle and fall back on acpi_idle.
diff --git a/arch/x86/kernel/tboot.c b/arch/x86/kernel/tboot.c
index b868fa1b812b..edbdfe6ab60a 100644
--- a/arch/x86/kernel/tboot.c
+++ b/arch/x86/kernel/tboot.c
@@ -510,6 +510,9 @@ int tboot_force_iommu(void)
510 if (!tboot_enabled()) 510 if (!tboot_enabled())
511 return 0; 511 return 0;
512 512
513 if (!intel_iommu_tboot_noforce)
514 return 1;
515
513 if (no_iommu || swiotlb || dmar_disabled) 516 if (no_iommu || swiotlb || dmar_disabled)
514 pr_warning("Forcing Intel-IOMMU to enabled\n"); 517 pr_warning("Forcing Intel-IOMMU to enabled\n");
515 518
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 5f08ba13972b..b0ced1c13713 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -183,6 +183,7 @@ static int rwbf_quirk;
183 * (used when kernel is launched w/ TXT) 183 * (used when kernel is launched w/ TXT)
184 */ 184 */
185static int force_on = 0; 185static int force_on = 0;
186int intel_iommu_tboot_noforce;
186 187
187/* 188/*
188 * 0: Present 189 * 0: Present
@@ -607,6 +608,10 @@ static int __init intel_iommu_setup(char *str)
607 "Intel-IOMMU: enable pre-production PASID support\n"); 608 "Intel-IOMMU: enable pre-production PASID support\n");
608 intel_iommu_pasid28 = 1; 609 intel_iommu_pasid28 = 1;
609 iommu_identity_mapping |= IDENTMAP_GFX; 610 iommu_identity_mapping |= IDENTMAP_GFX;
611 } else if (!strncmp(str, "tboot_noforce", 13)) {
612 printk(KERN_INFO
613 "Intel-IOMMU: not forcing on after tboot. This could expose security risk for tboot\n");
614 intel_iommu_tboot_noforce = 1;
610 } 615 }
611 616
612 str += strcspn(str, ","); 617 str += strcspn(str, ",");
@@ -4851,6 +4856,19 @@ int __init intel_iommu_init(void)
4851 4856
4852 if (no_iommu || dmar_disabled) { 4857 if (no_iommu || dmar_disabled) {
4853 /* 4858 /*
4859 * We exit the function here to ensure IOMMU's remapping and
4860 * mempool aren't setup, which means that the IOMMU's PMRs
4861 * won't be disabled via the call to init_dmars(). So disable
4862 * it explicitly here. The PMRs were setup by tboot prior to
4863 * calling SENTER, but the kernel is expected to reset/tear
4864 * down the PMRs.
4865 */
4866 if (intel_iommu_tboot_noforce) {
4867 for_each_iommu(iommu, drhd)
4868 iommu_disable_protect_mem_regions(iommu);
4869 }
4870
4871 /*
4854 * Make sure the IOMMUs are switched off, even when we 4872 * Make sure the IOMMUs are switched off, even when we
4855 * boot into a kexec kernel and the previous kernel left 4873 * boot into a kexec kernel and the previous kernel left
4856 * them enabled 4874 * them enabled
diff --git a/include/linux/dma_remapping.h b/include/linux/dma_remapping.h
index 187c10299722..90884072fa73 100644
--- a/include/linux/dma_remapping.h
+++ b/include/linux/dma_remapping.h
@@ -39,6 +39,7 @@ extern int iommu_calculate_agaw(struct intel_iommu *iommu);
39extern int iommu_calculate_max_sagaw(struct intel_iommu *iommu); 39extern int iommu_calculate_max_sagaw(struct intel_iommu *iommu);
40extern int dmar_disabled; 40extern int dmar_disabled;
41extern int intel_iommu_enabled; 41extern int intel_iommu_enabled;
42extern int intel_iommu_tboot_noforce;
42#else 43#else
43static inline int iommu_calculate_agaw(struct intel_iommu *iommu) 44static inline int iommu_calculate_agaw(struct intel_iommu *iommu)
44{ 45{