aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2017-12-19 18:07:10 -0500
committerDan Williams <dan.j.williams@intel.com>2017-12-19 18:10:06 -0500
commit19deaa217bc04e83b59b5e8c8229eb0e53ad9efc (patch)
treee287ec08be453ffb14fa7cc99184c7fe785d5626
parentadf6895754e2503d994a765535fd1813f8834674 (diff)
libnvdimm, pfn: fix start_pad handling for aligned namespaces
The alignment checks at pfn driver startup fail to properly account for the 'start_pad' in the case where the namespace is misaligned relative to its internal alignment. This is typically triggered in 1G aligned namespace, but could theoretically trigger with small namespace alignments. When this triggers the kernel reports messages of the form: dax2.1: bad offset: 0x3c000000 dax disabled align: 0x40000000 Cc: <stable@vger.kernel.org> Fixes: 1ee6667cd8d1 ("libnvdimm, pfn, dax: fix initialization vs autodetect...") Reported-by: Jane Chu <jane.chu@oracle.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r--drivers/nvdimm/pfn_devs.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c
index 65cc171c721d..db2fc7c02e01 100644
--- a/drivers/nvdimm/pfn_devs.c
+++ b/drivers/nvdimm/pfn_devs.c
@@ -364,9 +364,9 @@ struct device *nd_pfn_create(struct nd_region *nd_region)
364int nd_pfn_validate(struct nd_pfn *nd_pfn, const char *sig) 364int nd_pfn_validate(struct nd_pfn *nd_pfn, const char *sig)
365{ 365{
366 u64 checksum, offset; 366 u64 checksum, offset;
367 unsigned long align;
368 enum nd_pfn_mode mode; 367 enum nd_pfn_mode mode;
369 struct nd_namespace_io *nsio; 368 struct nd_namespace_io *nsio;
369 unsigned long align, start_pad;
370 struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb; 370 struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb;
371 struct nd_namespace_common *ndns = nd_pfn->ndns; 371 struct nd_namespace_common *ndns = nd_pfn->ndns;
372 const u8 *parent_uuid = nd_dev_to_uuid(&ndns->dev); 372 const u8 *parent_uuid = nd_dev_to_uuid(&ndns->dev);
@@ -410,6 +410,7 @@ int nd_pfn_validate(struct nd_pfn *nd_pfn, const char *sig)
410 410
411 align = le32_to_cpu(pfn_sb->align); 411 align = le32_to_cpu(pfn_sb->align);
412 offset = le64_to_cpu(pfn_sb->dataoff); 412 offset = le64_to_cpu(pfn_sb->dataoff);
413 start_pad = le32_to_cpu(pfn_sb->start_pad);
413 if (align == 0) 414 if (align == 0)
414 align = 1UL << ilog2(offset); 415 align = 1UL << ilog2(offset);
415 mode = le32_to_cpu(pfn_sb->mode); 416 mode = le32_to_cpu(pfn_sb->mode);
@@ -468,7 +469,7 @@ int nd_pfn_validate(struct nd_pfn *nd_pfn, const char *sig)
468 return -EBUSY; 469 return -EBUSY;
469 } 470 }
470 471
471 if ((align && !IS_ALIGNED(offset, align)) 472 if ((align && !IS_ALIGNED(nsio->res.start + offset + start_pad, align))
472 || !IS_ALIGNED(offset, PAGE_SIZE)) { 473 || !IS_ALIGNED(offset, PAGE_SIZE)) {
473 dev_err(&nd_pfn->dev, 474 dev_err(&nd_pfn->dev,
474 "bad offset: %#llx dax disabled align: %#lx\n", 475 "bad offset: %#llx dax disabled align: %#lx\n",