|
@@ -427,6 +427,7 @@ static int __dax_dev_pte_fault(struct dax_dev *dax_dev, struct vm_fault *vmf)
|
|
|
int rc = VM_FAULT_SIGBUS;
|
|
|
phys_addr_t phys;
|
|
|
pfn_t pfn;
|
|
|
+ unsigned int fault_size = PAGE_SIZE;
|
|
|
|
|
|
if (check_vma(dax_dev, vmf->vma, __func__))
|
|
|
return VM_FAULT_SIGBUS;
|
|
@@ -437,6 +438,9 @@ static int __dax_dev_pte_fault(struct dax_dev *dax_dev, struct vm_fault *vmf)
|
|
|
return VM_FAULT_SIGBUS;
|
|
|
}
|
|
|
|
|
|
+ if (fault_size != dax_region->align)
|
|
|
+ return VM_FAULT_SIGBUS;
|
|
|
+
|
|
|
phys = pgoff_to_phys(dax_dev, vmf->pgoff, PAGE_SIZE);
|
|
|
if (phys == -1) {
|
|
|
dev_dbg(dev, "%s: phys_to_pgoff(%#lx) failed\n", __func__,
|
|
@@ -464,6 +468,7 @@ static int __dax_dev_pmd_fault(struct dax_dev *dax_dev, struct vm_fault *vmf)
|
|
|
phys_addr_t phys;
|
|
|
pgoff_t pgoff;
|
|
|
pfn_t pfn;
|
|
|
+ unsigned int fault_size = PMD_SIZE;
|
|
|
|
|
|
if (check_vma(dax_dev, vmf->vma, __func__))
|
|
|
return VM_FAULT_SIGBUS;
|
|
@@ -480,6 +485,16 @@ static int __dax_dev_pmd_fault(struct dax_dev *dax_dev, struct vm_fault *vmf)
|
|
|
return VM_FAULT_SIGBUS;
|
|
|
}
|
|
|
|
|
|
+ if (fault_size < dax_region->align)
|
|
|
+ return VM_FAULT_SIGBUS;
|
|
|
+ else if (fault_size > dax_region->align)
|
|
|
+ return VM_FAULT_FALLBACK;
|
|
|
+
|
|
|
+ /* if we are outside of the VMA */
|
|
|
+ if (pmd_addr < vmf->vma->vm_start ||
|
|
|
+ (pmd_addr + PMD_SIZE) > vmf->vma->vm_end)
|
|
|
+ return VM_FAULT_SIGBUS;
|
|
|
+
|
|
|
pgoff = linear_page_index(vmf->vma, pmd_addr);
|
|
|
phys = pgoff_to_phys(dax_dev, pgoff, PMD_SIZE);
|
|
|
if (phys == -1) {
|