diff options
-rw-r--r-- | drivers/dax/dax.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/drivers/dax/dax.c b/drivers/dax/dax.c index 286447a83dab..152552d2c306 100644 --- a/drivers/dax/dax.c +++ b/drivers/dax/dax.c | |||
@@ -334,6 +334,7 @@ static int __dax_dev_fault(struct dax_dev *dax_dev, struct vm_area_struct *vma, | |||
334 | int rc = VM_FAULT_SIGBUS; | 334 | int rc = VM_FAULT_SIGBUS; |
335 | phys_addr_t phys; | 335 | phys_addr_t phys; |
336 | pfn_t pfn; | 336 | pfn_t pfn; |
337 | unsigned int fault_size = PAGE_SIZE; | ||
337 | 338 | ||
338 | if (check_vma(dax_dev, vma, __func__)) | 339 | if (check_vma(dax_dev, vma, __func__)) |
339 | return VM_FAULT_SIGBUS; | 340 | return VM_FAULT_SIGBUS; |
@@ -344,6 +345,9 @@ static int __dax_dev_fault(struct dax_dev *dax_dev, struct vm_area_struct *vma, | |||
344 | return VM_FAULT_SIGBUS; | 345 | return VM_FAULT_SIGBUS; |
345 | } | 346 | } |
346 | 347 | ||
348 | if (fault_size != dax_region->align) | ||
349 | return VM_FAULT_SIGBUS; | ||
350 | |||
347 | phys = pgoff_to_phys(dax_dev, vmf->pgoff, PAGE_SIZE); | 351 | phys = pgoff_to_phys(dax_dev, vmf->pgoff, PAGE_SIZE); |
348 | if (phys == -1) { | 352 | if (phys == -1) { |
349 | dev_dbg(dev, "%s: phys_to_pgoff(%#lx) failed\n", __func__, | 353 | dev_dbg(dev, "%s: phys_to_pgoff(%#lx) failed\n", __func__, |
@@ -389,6 +393,7 @@ static int __dax_dev_pmd_fault(struct dax_dev *dax_dev, | |||
389 | phys_addr_t phys; | 393 | phys_addr_t phys; |
390 | pgoff_t pgoff; | 394 | pgoff_t pgoff; |
391 | pfn_t pfn; | 395 | pfn_t pfn; |
396 | unsigned int fault_size = PMD_SIZE; | ||
392 | 397 | ||
393 | if (check_vma(dax_dev, vma, __func__)) | 398 | if (check_vma(dax_dev, vma, __func__)) |
394 | return VM_FAULT_SIGBUS; | 399 | return VM_FAULT_SIGBUS; |
@@ -405,6 +410,16 @@ static int __dax_dev_pmd_fault(struct dax_dev *dax_dev, | |||
405 | return VM_FAULT_SIGBUS; | 410 | return VM_FAULT_SIGBUS; |
406 | } | 411 | } |
407 | 412 | ||
413 | if (fault_size < dax_region->align) | ||
414 | return VM_FAULT_SIGBUS; | ||
415 | else if (fault_size > dax_region->align) | ||
416 | return VM_FAULT_FALLBACK; | ||
417 | |||
418 | /* if we are outside of the VMA */ | ||
419 | if (pmd_addr < vma->vm_start || | ||
420 | (pmd_addr + PMD_SIZE) > vma->vm_end) | ||
421 | return VM_FAULT_SIGBUS; | ||
422 | |||
408 | pgoff = linear_page_index(vma, pmd_addr); | 423 | pgoff = linear_page_index(vma, pmd_addr); |
409 | phys = pgoff_to_phys(dax_dev, pgoff, PMD_SIZE); | 424 | phys = pgoff_to_phys(dax_dev, pgoff, PMD_SIZE); |
410 | if (phys == -1) { | 425 | if (phys == -1) { |