Merge branch 'libnvdimm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm

Pull device-dax fixes from Dan Williams:
"The device-dax driver was not being careful to handle falling back to
smaller fault-granularity sizes.

The driver already fails fault attempts that are smaller than the
device's alignment, but it also needs to handle the cases where a
larger page mapping could be established. For simplicity of the
immediate fix the implementation just signals VM_FAULT_FALLBACK until
fault-size == device-alignment.

One fix is for -stable to address pmd-to-pte fallback from the
original implementation, another fix is for the new (introduced in
4.11-rc1) pud-to-pmd regression, and a typo fix comes along for the
ride.

These have received a build success notification from the kbuild
robot"

* 'libnvdimm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm:
device-dax: fix debug output typo
device-dax: fix pud fault fallback handling
device-dax: fix pmd/pte fault fallback handling

Changed files
+30 -3
drivers
dax
+30 -3
drivers/dax/dax.c
··· 427 427 int rc = VM_FAULT_SIGBUS; 428 428 phys_addr_t phys; 429 429 pfn_t pfn; 430 + unsigned int fault_size = PAGE_SIZE; 430 431 431 432 if (check_vma(dax_dev, vmf->vma, __func__)) 432 433 return VM_FAULT_SIGBUS; ··· 438 437 return VM_FAULT_SIGBUS; 439 438 } 440 439 440 + if (fault_size != dax_region->align) 441 + return VM_FAULT_SIGBUS; 442 + 441 443 phys = pgoff_to_phys(dax_dev, vmf->pgoff, PAGE_SIZE); 442 444 if (phys == -1) { 443 - dev_dbg(dev, "%s: phys_to_pgoff(%#lx) failed\n", __func__, 445 + dev_dbg(dev, "%s: pgoff_to_phys(%#lx) failed\n", __func__, 444 446 vmf->pgoff); 445 447 return VM_FAULT_SIGBUS; 446 448 } ··· 468 464 phys_addr_t phys; 469 465 pgoff_t pgoff; 470 466 pfn_t pfn; 467 + unsigned int fault_size = PMD_SIZE; 471 468 472 469 if (check_vma(dax_dev, vmf->vma, __func__)) 473 470 return VM_FAULT_SIGBUS; ··· 485 480 return VM_FAULT_SIGBUS; 486 481 } 487 482 483 + if (fault_size < dax_region->align) 484 + return VM_FAULT_SIGBUS; 485 + else if (fault_size > dax_region->align) 486 + return VM_FAULT_FALLBACK; 487 + 488 + /* if we are outside of the VMA */ 489 + if (pmd_addr < vmf->vma->vm_start || 490 + (pmd_addr + PMD_SIZE) > vmf->vma->vm_end) 491 + return VM_FAULT_SIGBUS; 492 + 488 493 pgoff = linear_page_index(vmf->vma, pmd_addr); 489 494 phys = pgoff_to_phys(dax_dev, pgoff, PMD_SIZE); 490 495 if (phys == -1) { 491 - dev_dbg(dev, "%s: phys_to_pgoff(%#lx) failed\n", __func__, 496 + dev_dbg(dev, "%s: pgoff_to_phys(%#lx) failed\n", __func__, 492 497 pgoff); 493 498 return VM_FAULT_SIGBUS; 494 499 } ··· 518 503 phys_addr_t phys; 519 504 pgoff_t pgoff; 520 505 pfn_t pfn; 506 + unsigned int fault_size = PUD_SIZE; 507 + 521 508 522 509 if (check_vma(dax_dev, vmf->vma, __func__)) 523 510 return VM_FAULT_SIGBUS; ··· 536 519 return VM_FAULT_SIGBUS; 537 520 } 538 521 522 + if (fault_size < dax_region->align) 523 + return VM_FAULT_SIGBUS; 524 + else if (fault_size > dax_region->align) 525 + return VM_FAULT_FALLBACK; 526 + 527 + /* if we are outside of the VMA */ 528 + if (pud_addr < vmf->vma->vm_start || 529 + (pud_addr + PUD_SIZE) > vmf->vma->vm_end) 530 + return VM_FAULT_SIGBUS; 531 + 539 532 pgoff = linear_page_index(vmf->vma, pud_addr); 540 533 phys = pgoff_to_phys(dax_dev, pgoff, PUD_SIZE); 541 534 if (phys == -1) { 542 - dev_dbg(dev, "%s: phys_to_pgoff(%#lx) failed\n", __func__, 535 + dev_dbg(dev, "%s: pgoff_to_phys(%#lx) failed\n", __func__, 543 536 pgoff); 544 537 return VM_FAULT_SIGBUS; 545 538 }