aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2016-05-21 14:01:41 -0400
committerDan Williams <dan.j.williams@intel.com>2016-05-21 14:01:41 -0400
commit5e24c9fd36285535c704e84748d6c890be870fb6 (patch)
tree72482127094e47042d46d9e8892466852f0e5347
parentc5ed9268643c7c4c9f2aaa0fd4c936095e6480ef (diff)
libnvdimm, dax: fix alignment validation
Testing the dax-device autodetect support revealed a probe failure with the following result: dax0.1: bad offset: 0x8200000 dax disabled The original pfn-device implementation inferred the alignment from ilog2(offset), now that the alignment is explicit the is_power_of_2() needs replacing with a real sanity check against the recorded alignment. Otherwise the alignment check is useless in the implicit case and only the minimum size of the offset matters. This self-consistency check is further validated by the probe path that will re-check that the offset is large enough to contain all the metadata required to enable the device. Cc: <stable@vger.kernel.org> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r--drivers/nvdimm/pfn_devs.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c
index 816cd9828ca5..04f71d6d304d 100644
--- a/drivers/nvdimm/pfn_devs.c
+++ b/drivers/nvdimm/pfn_devs.c
@@ -416,6 +416,8 @@ int nd_pfn_validate(struct nd_pfn *nd_pfn, const char *sig)
416 return -ENODEV; 416 return -ENODEV;
417 } 417 }
418 418
419 if (nd_pfn->align == 0)
420 nd_pfn->align = le32_to_cpu(pfn_sb->align);
419 if (nd_pfn->align > nvdimm_namespace_capacity(ndns)) { 421 if (nd_pfn->align > nvdimm_namespace_capacity(ndns)) {
420 dev_err(&nd_pfn->dev, "alignment: %lx exceeds capacity %llx\n", 422 dev_err(&nd_pfn->dev, "alignment: %lx exceeds capacity %llx\n",
421 nd_pfn->align, nvdimm_namespace_capacity(ndns)); 423 nd_pfn->align, nvdimm_namespace_capacity(ndns));
@@ -436,8 +438,8 @@ int nd_pfn_validate(struct nd_pfn *nd_pfn, const char *sig)
436 return -EBUSY; 438 return -EBUSY;
437 } 439 }
438 440
439 nd_pfn->align = le32_to_cpu(pfn_sb->align); 441 if ((nd_pfn->align && !IS_ALIGNED(offset, nd_pfn->align))
440 if (!is_power_of_2(offset) || offset < PAGE_SIZE) { 442 || !IS_ALIGNED(offset, PAGE_SIZE)) {
441 dev_err(&nd_pfn->dev, "bad offset: %#llx dax disabled\n", 443 dev_err(&nd_pfn->dev, "bad offset: %#llx dax disabled\n",
442 offset); 444 offset);
443 return -ENXIO; 445 return -ENXIO;