diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-07-20 14:43:21 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-07-20 14:43:21 -0400 |
commit | 47736af324fc47598afdf3407467da7eaa65c86a (patch) | |
tree | 27024ec6262d0676336c04b976ea689e01fde5fc | |
parent | de87dcdedc133c1368566250e251ed1a6335e001 (diff) | |
parent | 2db1581e1f432ac6b4efe152c57fdfb4de85c154 (diff) |
Merge tag 'iommu-fixes-v4.18-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu
Pull IOMMU fix from Joerg Roedel:
"Only one revert, for an an Intel VT-d patch that caused issues with
the i915 GPU driver"
* tag 'iommu-fixes-v4.18-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu:
Revert "iommu/vt-d: Clean up pasid quirk for pre-production devices"
-rw-r--r-- | drivers/iommu/intel-iommu.c | 32 | ||||
-rw-r--r-- | include/linux/intel-iommu.h | 1 |
2 files changed, 31 insertions, 2 deletions
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index b344a883f116..115ff26e9ced 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c | |||
@@ -484,14 +484,37 @@ static int dmar_forcedac; | |||
484 | static int intel_iommu_strict; | 484 | static int intel_iommu_strict; |
485 | static int intel_iommu_superpage = 1; | 485 | static int intel_iommu_superpage = 1; |
486 | static int intel_iommu_ecs = 1; | 486 | static int intel_iommu_ecs = 1; |
487 | static int intel_iommu_pasid28; | ||
487 | static int iommu_identity_mapping; | 488 | static int iommu_identity_mapping; |
488 | 489 | ||
489 | #define IDENTMAP_ALL 1 | 490 | #define IDENTMAP_ALL 1 |
490 | #define IDENTMAP_GFX 2 | 491 | #define IDENTMAP_GFX 2 |
491 | #define IDENTMAP_AZALIA 4 | 492 | #define IDENTMAP_AZALIA 4 |
492 | 493 | ||
493 | #define ecs_enabled(iommu) (intel_iommu_ecs && ecap_ecs(iommu->ecap)) | 494 | /* Broadwell and Skylake have broken ECS support — normal so-called "second |
494 | #define pasid_enabled(iommu) (ecs_enabled(iommu) && ecap_pasid(iommu->ecap)) | 495 | * level" translation of DMA requests-without-PASID doesn't actually happen |
496 | * unless you also set the NESTE bit in an extended context-entry. Which of | ||
497 | * course means that SVM doesn't work because it's trying to do nested | ||
498 | * translation of the physical addresses it finds in the process page tables, | ||
499 | * through the IOVA->phys mapping found in the "second level" page tables. | ||
500 | * | ||
501 | * The VT-d specification was retroactively changed to change the definition | ||
502 | * of the capability bits and pretend that Broadwell/Skylake never happened... | ||
503 | * but unfortunately the wrong bit was changed. It's ECS which is broken, but | ||
504 | * for some reason it was the PASID capability bit which was redefined (from | ||
505 | * bit 28 on BDW/SKL to bit 40 in future). | ||
506 | * | ||
507 | * So our test for ECS needs to eschew those implementations which set the old | ||
508 | * PASID capabiity bit 28, since those are the ones on which ECS is broken. | ||
509 | * Unless we are working around the 'pasid28' limitations, that is, by putting | ||
510 | * the device into passthrough mode for normal DMA and thus masking the bug. | ||
511 | */ | ||
512 | #define ecs_enabled(iommu) (intel_iommu_ecs && ecap_ecs(iommu->ecap) && \ | ||
513 | (intel_iommu_pasid28 || !ecap_broken_pasid(iommu->ecap))) | ||
514 | /* PASID support is thus enabled if ECS is enabled and *either* of the old | ||
515 | * or new capability bits are set. */ | ||
516 | #define pasid_enabled(iommu) (ecs_enabled(iommu) && \ | ||
517 | (ecap_pasid(iommu->ecap) || ecap_broken_pasid(iommu->ecap))) | ||
495 | 518 | ||
496 | int intel_iommu_gfx_mapped; | 519 | int intel_iommu_gfx_mapped; |
497 | EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped); | 520 | EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped); |
@@ -554,6 +577,11 @@ static int __init intel_iommu_setup(char *str) | |||
554 | printk(KERN_INFO | 577 | printk(KERN_INFO |
555 | "Intel-IOMMU: disable extended context table support\n"); | 578 | "Intel-IOMMU: disable extended context table support\n"); |
556 | intel_iommu_ecs = 0; | 579 | intel_iommu_ecs = 0; |
580 | } else if (!strncmp(str, "pasid28", 7)) { | ||
581 | printk(KERN_INFO | ||
582 | "Intel-IOMMU: enable pre-production PASID support\n"); | ||
583 | intel_iommu_pasid28 = 1; | ||
584 | iommu_identity_mapping |= IDENTMAP_GFX; | ||
557 | } else if (!strncmp(str, "tboot_noforce", 13)) { | 585 | } else if (!strncmp(str, "tboot_noforce", 13)) { |
558 | printk(KERN_INFO | 586 | printk(KERN_INFO |
559 | "Intel-IOMMU: not forcing on after tboot. This could expose security risk for tboot\n"); | 587 | "Intel-IOMMU: not forcing on after tboot. This could expose security risk for tboot\n"); |
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h index 1df940196ab2..ef169d67df92 100644 --- a/include/linux/intel-iommu.h +++ b/include/linux/intel-iommu.h | |||
@@ -121,6 +121,7 @@ | |||
121 | #define ecap_srs(e) ((e >> 31) & 0x1) | 121 | #define ecap_srs(e) ((e >> 31) & 0x1) |
122 | #define ecap_ers(e) ((e >> 30) & 0x1) | 122 | #define ecap_ers(e) ((e >> 30) & 0x1) |
123 | #define ecap_prs(e) ((e >> 29) & 0x1) | 123 | #define ecap_prs(e) ((e >> 29) & 0x1) |
124 | #define ecap_broken_pasid(e) ((e >> 28) & 0x1) | ||
124 | #define ecap_dis(e) ((e >> 27) & 0x1) | 125 | #define ecap_dis(e) ((e >> 27) & 0x1) |
125 | #define ecap_nest(e) ((e >> 26) & 0x1) | 126 | #define ecap_nest(e) ((e >> 26) & 0x1) |
126 | #define ecap_mts(e) ((e >> 25) & 0x1) | 127 | #define ecap_mts(e) ((e >> 25) & 0x1) |