ARM: rockchip_defconfig: enable DEVFREQ_GOV_SIMPLE_ONDEMAND
[firefly-linux-kernel-4.4.55.git] / drivers / iommu / amd_iommu_v2.c
index d21d4edf7236abac49072c086290b76d2ae201b5..4831eb910fc743b71cd1fc4e11a1c5732f989cdd 100644 (file)
@@ -494,6 +494,22 @@ static void handle_fault_error(struct fault *fault)
        }
 }
 
+static bool access_error(struct vm_area_struct *vma, struct fault *fault)
+{
+       unsigned long requested = 0;
+
+       if (fault->flags & PPR_FAULT_EXEC)
+               requested |= VM_EXEC;
+
+       if (fault->flags & PPR_FAULT_READ)
+               requested |= VM_READ;
+
+       if (fault->flags & PPR_FAULT_WRITE)
+               requested |= VM_WRITE;
+
+       return (requested & ~vma->vm_flags) != 0;
+}
+
 static void do_fault(struct work_struct *work)
 {
        struct fault *fault = container_of(work, struct fault, work);
@@ -516,8 +532,8 @@ static void do_fault(struct work_struct *work)
                goto out;
        }
 
-       if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))) {
-               /* handle_mm_fault would BUG_ON() */
+       /* Check if we have the right permissions on the vma */
+       if (access_error(vma, fault)) {
                up_read(&mm->mmap_sem);
                handle_fault_error(fault);
                goto out;
@@ -793,8 +809,10 @@ int amd_iommu_init_device(struct pci_dev *pdev, int pasids)
                goto out_free_domain;
 
        group = iommu_group_get(&pdev->dev);
-       if (!group)
+       if (!group) {
+               ret = -EINVAL;
                goto out_free_domain;
+       }
 
        ret = iommu_attach_group(dev_state->domain, group);
        if (ret != 0)