History

Merge tag 'iommu-fixes-v4.4-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu

Pull IOMMU fixes from Joerg Roedel: "Two similar fixes for the Intel and AMD IOMMU drivers to add proper access checks before calling handle_mm_fault" * tag 'iommu-fixes-v4.4-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: iommu/vt-d: Do access checks before calling handle_mm_fault() iommu/amd: Do proper access checking before calling handle_mm_fault()

Linus Torvalds committed 10 years ago

Commit ccdd96b2 parents 3273cba 7f8312a2 files · +38 −2Browse files

Unified · Split

2 files
  1. drivers/iommu/amd_iommu_v2.c +18 −2
  2. drivers/iommu/intel-svm.c +20 −0
drivers/iommu/amd_iommu_v2.c+18−2
@@ -494,6 +494,22 @@ static void handle_fault_error(struct fault *fault) · 493 unmodified lines
494 }494 }
495}495}
496 496
497static bool access_error(struct vm_area_struct *vma, struct fault *fault)
498{
499 unsigned long requested = 0;
500
501 if (fault->flags & PPR_FAULT_EXEC)
502 requested |= VM_EXEC;
503
504 if (fault->flags & PPR_FAULT_READ)
505 requested |= VM_READ;
506
507 if (fault->flags & PPR_FAULT_WRITE)
508 requested |= VM_WRITE;
509
510 return (requested & ~vma->vm_flags) != 0;
511}
512
497static void do_fault(struct work_struct *work)513static void do_fault(struct work_struct *work)
498{514{
499 struct fault *fault = container_of(work, struct fault, work);515 struct fault *fault = container_of(work, struct fault, work);
@@ -516,8 +532,8 @@ static void do_fault(struct work_struct *work) · 16 unmodified lines
516 goto out;532 goto out;
517 }533 }
518 534
519 if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))) {535 /* Check if we have the right permissions on the vma */
520 /* handle_mm_fault would BUG_ON() */536 if (access_error(vma, fault)) {
521 up_read(&mm->mmap_sem);537 up_read(&mm->mmap_sem);
522 handle_fault_error(fault);538 handle_fault_error(fault);
523 goto out;539 goto out;
drivers/iommu/intel-svm.c+20−0
@@ -484,6 +484,23 @@ struct page_req_dsc { · 483 unmodified lines
484};484};
485 485
486#define PRQ_RING_MASK ((0x1000 << PRQ_ORDER) - 0x10)486#define PRQ_RING_MASK ((0x1000 << PRQ_ORDER) - 0x10)
487
488static bool access_error(struct vm_area_struct *vma, struct page_req_dsc *req)
489{
490 unsigned long requested = 0;
491
492 if (req->exe_req)
493 requested |= VM_EXEC;
494
495 if (req->rd_req)
496 requested |= VM_READ;
497
498 if (req->wr_req)
499 requested |= VM_WRITE;
500
501 return (requested & ~vma->vm_flags) != 0;
502}
503
487static irqreturn_t prq_event_thread(int irq, void *d)504static irqreturn_t prq_event_thread(int irq, void *d)
488{505{
489 struct intel_iommu *iommu = d;506 struct intel_iommu *iommu = d;
@@ -539,6 +556,9 @@ static irqreturn_t prq_event_thread(int irq, void *d) · 49 unmodified lines
539 if (!vma || address < vma->vm_start)556 if (!vma || address < vma->vm_start)
540 goto invalid;557 goto invalid;
541 558
559 if (access_error(vma, req))
560 goto invalid;
561
542 ret = handle_mm_fault(svm->mm, vma, address,562 ret = handle_mm_fault(svm->mm, vma, address,
543 req->wr_req ? FAULT_FLAG_WRITE : 0);563 req->wr_req ? FAULT_FLAG_WRITE : 0);
544 if (ret & VM_FAULT_ERROR)564 if (ret & VM_FAULT_ERROR)