aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-10-26 18:44:13 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-10-26 18:44:13 -0400
commit858e904bd71dd0057a548d6785d94ce5ec4aeabd (patch)
treee93d9c0ac41cd061e0852186ffdc587c55eb6dc4
parentce6f9886037f5566cb8e440b9caa5e7d7334e53b (diff)
parentcbf3ccd09d683abf1cacd36e3640872ee912d99b (diff)
Merge tag 'iommu-fixes-v4.3-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu
Pull iommu fixes from Joerg Roedel: "Two late fixes for the AMD IOMMU driver: - add an additional check to the io page-fault handler to avoid a BUG_ON being hit in handle_mm_fault() - fix a problem with devices writing to the system management area and were blocked by the IOMMU because the driver wrongly cleared out the DTE flags allowing that access" * tag 'iommu-fixes-v4.3-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: iommu/amd: Don't clear DTE flags when modifying it iommu/amd: Fix BUG when faulting a PROT_NONE VMA
-rw-r--r--drivers/iommu/amd_iommu.c4
-rw-r--r--drivers/iommu/amd_iommu_types.h1
-rw-r--r--drivers/iommu/amd_iommu_v2.c7
3 files changed, 10 insertions, 2 deletions
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 08d2775887f7..532e2a211fe1 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -1974,8 +1974,8 @@ static void set_dte_entry(u16 devid, struct protection_domain *domain, bool ats)
1974static void clear_dte_entry(u16 devid) 1974static void clear_dte_entry(u16 devid)
1975{ 1975{
1976 /* remove entry from the device table seen by the hardware */ 1976 /* remove entry from the device table seen by the hardware */
1977 amd_iommu_dev_table[devid].data[0] = IOMMU_PTE_P | IOMMU_PTE_TV; 1977 amd_iommu_dev_table[devid].data[0] = IOMMU_PTE_P | IOMMU_PTE_TV;
1978 amd_iommu_dev_table[devid].data[1] = 0; 1978 amd_iommu_dev_table[devid].data[1] &= DTE_FLAG_MASK;
1979 1979
1980 amd_iommu_apply_erratum_63(devid); 1980 amd_iommu_apply_erratum_63(devid);
1981} 1981}
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h
index f65908841be0..c9b64722f623 100644
--- a/drivers/iommu/amd_iommu_types.h
+++ b/drivers/iommu/amd_iommu_types.h
@@ -295,6 +295,7 @@
295#define IOMMU_PTE_IR (1ULL << 61) 295#define IOMMU_PTE_IR (1ULL << 61)
296#define IOMMU_PTE_IW (1ULL << 62) 296#define IOMMU_PTE_IW (1ULL << 62)
297 297
298#define DTE_FLAG_MASK (0x3ffULL << 32)
298#define DTE_FLAG_IOTLB (0x01UL << 32) 299#define DTE_FLAG_IOTLB (0x01UL << 32)
299#define DTE_FLAG_GV (0x01ULL << 55) 300#define DTE_FLAG_GV (0x01ULL << 55)
300#define DTE_GLX_SHIFT (56) 301#define DTE_GLX_SHIFT (56)
diff --git a/drivers/iommu/amd_iommu_v2.c b/drivers/iommu/amd_iommu_v2.c
index 1131664b918b..d21d4edf7236 100644
--- a/drivers/iommu/amd_iommu_v2.c
+++ b/drivers/iommu/amd_iommu_v2.c
@@ -516,6 +516,13 @@ static void do_fault(struct work_struct *work)
516 goto out; 516 goto out;
517 } 517 }
518 518
519 if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))) {
520 /* handle_mm_fault would BUG_ON() */
521 up_read(&mm->mmap_sem);
522 handle_fault_error(fault);
523 goto out;
524 }
525
519 ret = handle_mm_fault(mm, vma, address, write); 526 ret = handle_mm_fault(mm, vma, address, write);
520 if (ret & VM_FAULT_ERROR) { 527 if (ret & VM_FAULT_ERROR) {
521 /* failed to service fault */ 528 /* failed to service fault */