diff options
-rw-r--r-- | Documentation/kernel-parameters.txt | 6 | ||||
-rw-r--r-- | drivers/iommu/intel-iommu.c | 18 | ||||
-rw-r--r-- | include/linux/intel-iommu.h | 3 |
3 files changed, 23 insertions, 4 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 61ab1628a057..6726139bd289 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -1481,6 +1481,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
1481 | By default, super page will be supported if Intel IOMMU | 1481 | By default, super page will be supported if Intel IOMMU |
1482 | has the capability. With this option, super page will | 1482 | has the capability. With this option, super page will |
1483 | not be supported. | 1483 | not be supported. |
1484 | ecs_off [Default Off] | ||
1485 | By default, extended context tables will be supported if | ||
1486 | the hardware advertises that it has support both for the | ||
1487 | extended tables themselves, and also PASID support. With | ||
1488 | this option set, extended tables will not be used even | ||
1489 | on hardware which claims to support them. | ||
1484 | 1490 | ||
1485 | intel_idle.max_cstate= [KNL,HW,ACPI,X86] | 1491 | intel_idle.max_cstate= [KNL,HW,ACPI,X86] |
1486 | 0 disables intel_idle and fall back on acpi_idle. | 1492 | 0 disables intel_idle and fall back on acpi_idle. |
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 2ffe58969944..5ecfaf29933a 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c | |||
@@ -422,6 +422,14 @@ static int dmar_map_gfx = 1; | |||
422 | static int dmar_forcedac; | 422 | static int dmar_forcedac; |
423 | static int intel_iommu_strict; | 423 | static int intel_iommu_strict; |
424 | static int intel_iommu_superpage = 1; | 424 | static int intel_iommu_superpage = 1; |
425 | static int intel_iommu_ecs = 1; | ||
426 | |||
427 | /* We only actually use ECS when PASID support (on the new bit 40) | ||
428 | * is also advertised. Some early implementations — the ones with | ||
429 | * PASID support on bit 28 — have issues even when we *only* use | ||
430 | * extended root/context tables. */ | ||
431 | #define ecs_enabled(iommu) (intel_iommu_ecs && ecap_ecs(iommu->ecap) && \ | ||
432 | ecap_pasid(iommu->ecap)) | ||
425 | 433 | ||
426 | int intel_iommu_gfx_mapped; | 434 | int intel_iommu_gfx_mapped; |
427 | EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped); | 435 | EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped); |
@@ -465,6 +473,10 @@ static int __init intel_iommu_setup(char *str) | |||
465 | printk(KERN_INFO | 473 | printk(KERN_INFO |
466 | "Intel-IOMMU: disable supported super page\n"); | 474 | "Intel-IOMMU: disable supported super page\n"); |
467 | intel_iommu_superpage = 0; | 475 | intel_iommu_superpage = 0; |
476 | } else if (!strncmp(str, "ecs_off", 7)) { | ||
477 | printk(KERN_INFO | ||
478 | "Intel-IOMMU: disable extended context table support\n"); | ||
479 | intel_iommu_ecs = 0; | ||
468 | } | 480 | } |
469 | 481 | ||
470 | str += strcspn(str, ","); | 482 | str += strcspn(str, ","); |
@@ -669,7 +681,7 @@ static inline struct context_entry *iommu_context_addr(struct intel_iommu *iommu | |||
669 | struct context_entry *context; | 681 | struct context_entry *context; |
670 | u64 *entry; | 682 | u64 *entry; |
671 | 683 | ||
672 | if (ecap_ecs(iommu->ecap)) { | 684 | if (ecs_enabled(iommu)) { |
673 | if (devfn >= 0x80) { | 685 | if (devfn >= 0x80) { |
674 | devfn -= 0x80; | 686 | devfn -= 0x80; |
675 | entry = &root->hi; | 687 | entry = &root->hi; |
@@ -806,7 +818,7 @@ static void free_context_table(struct intel_iommu *iommu) | |||
806 | if (context) | 818 | if (context) |
807 | free_pgtable_page(context); | 819 | free_pgtable_page(context); |
808 | 820 | ||
809 | if (!ecap_ecs(iommu->ecap)) | 821 | if (!ecs_enabled(iommu)) |
810 | continue; | 822 | continue; |
811 | 823 | ||
812 | context = iommu_context_addr(iommu, i, 0x80, 0); | 824 | context = iommu_context_addr(iommu, i, 0x80, 0); |
@@ -1141,7 +1153,7 @@ static void iommu_set_root_entry(struct intel_iommu *iommu) | |||
1141 | unsigned long flag; | 1153 | unsigned long flag; |
1142 | 1154 | ||
1143 | addr = virt_to_phys(iommu->root_entry); | 1155 | addr = virt_to_phys(iommu->root_entry); |
1144 | if (ecap_ecs(iommu->ecap)) | 1156 | if (ecs_enabled(iommu)) |
1145 | addr |= DMA_RTADDR_RTT; | 1157 | addr |= DMA_RTADDR_RTT; |
1146 | 1158 | ||
1147 | raw_spin_lock_irqsave(&iommu->register_lock, flag); | 1159 | raw_spin_lock_irqsave(&iommu->register_lock, flag); |
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h index 796ef9645827..a240e61a7700 100644 --- a/include/linux/intel-iommu.h +++ b/include/linux/intel-iommu.h | |||
@@ -115,13 +115,14 @@ static inline void dmar_writeq(void __iomem *addr, u64 val) | |||
115 | * Extended Capability Register | 115 | * Extended Capability Register |
116 | */ | 116 | */ |
117 | 117 | ||
118 | #define ecap_pasid(e) ((e >> 40) & 0x1) | ||
118 | #define ecap_pss(e) ((e >> 35) & 0x1f) | 119 | #define ecap_pss(e) ((e >> 35) & 0x1f) |
119 | #define ecap_eafs(e) ((e >> 34) & 0x1) | 120 | #define ecap_eafs(e) ((e >> 34) & 0x1) |
120 | #define ecap_nwfs(e) ((e >> 33) & 0x1) | 121 | #define ecap_nwfs(e) ((e >> 33) & 0x1) |
121 | #define ecap_srs(e) ((e >> 31) & 0x1) | 122 | #define ecap_srs(e) ((e >> 31) & 0x1) |
122 | #define ecap_ers(e) ((e >> 30) & 0x1) | 123 | #define ecap_ers(e) ((e >> 30) & 0x1) |
123 | #define ecap_prs(e) ((e >> 29) & 0x1) | 124 | #define ecap_prs(e) ((e >> 29) & 0x1) |
124 | #define ecap_pasid(e) ((e >> 28) & 0x1) | 125 | /* PASID support used to be on bit 28 */ |
125 | #define ecap_dis(e) ((e >> 27) & 0x1) | 126 | #define ecap_dis(e) ((e >> 27) & 0x1) |
126 | #define ecap_nest(e) ((e >> 26) & 0x1) | 127 | #define ecap_nest(e) ((e >> 26) & 0x1) |
127 | #define ecap_mts(e) ((e >> 25) & 0x1) | 128 | #define ecap_mts(e) ((e >> 25) & 0x1) |