diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-21 20:55:29 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-21 20:55:29 +0300 |
commit | 6cb2e9ee51b5f1539f027346a02904e282b87d4d (patch) | |
tree | bf940785b622e8792ae943af9b92f55c5202612e /drivers/nvdimm/pfn_devs.c | |
parent | 10fd71780f7d155f4e35fecfad0ebd4a725a244b (diff) | |
parent | 5b26db95fee3f1ce0d096b2de0ac6f3716171093 (diff) | |
download | linux-6cb2e9ee51b5f1539f027346a02904e282b87d4d.tar.xz |
Merge tag 'libnvdimm-for-5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm
Pull libnvdimm updates from Dan Williams:
"Some reworks to better support nvdimms on powerpc and an nvdimm
security interface update:
- Rework the nvdimm core to accommodate architectures with different
page sizes and ones that can change supported huge page sizes at
boot time rather than a compile time constant.
- Introduce a distinct 'frozen' attribute for the nvdimm security
state since it is independent of the locked state.
- Miscellaneous fixups"
* tag 'libnvdimm-for-5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm:
libnvdimm: Use PAGE_SIZE instead of SZ_4K for align check
libnvdimm/label: Remove the dpa align check
libnvdimm/pfn_dev: Add page size and struct page size to pfn superblock
libnvdimm/pfn_dev: Add a build check to make sure we notice when struct page size change
libnvdimm/pmem: Advance namespace seed for specific probe errors
libnvdimm/region: Rewrite _probe_success() to _advance_seeds()
libnvdimm/security: Consolidate 'security' operations
libnvdimm/security: Tighten scope of nvdimm->busy vs security operations
libnvdimm/security: Introduce a 'frozen' attribute
libnvdimm, region: Use struct_size() in kzalloc()
tools/testing/nvdimm: Fix fallthrough warning
libnvdimm/of_pmem: Provide a unique name for bus provider
Diffstat (limited to 'drivers/nvdimm/pfn_devs.c')
-rw-r--r-- | drivers/nvdimm/pfn_devs.c | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c index cb98b8fe786e..bb9cc5cf0873 100644 --- a/drivers/nvdimm/pfn_devs.c +++ b/drivers/nvdimm/pfn_devs.c @@ -460,6 +460,11 @@ int nd_pfn_validate(struct nd_pfn *nd_pfn, const char *sig) if (__le16_to_cpu(pfn_sb->version_minor) < 2) pfn_sb->align = 0; + if (__le16_to_cpu(pfn_sb->version_minor) < 4) { + pfn_sb->page_struct_size = cpu_to_le16(64); + pfn_sb->page_size = cpu_to_le32(PAGE_SIZE); + } + switch (le32_to_cpu(pfn_sb->mode)) { case PFN_MODE_RAM: case PFN_MODE_PMEM: @@ -475,6 +480,22 @@ int nd_pfn_validate(struct nd_pfn *nd_pfn, const char *sig) align = 1UL << ilog2(offset); mode = le32_to_cpu(pfn_sb->mode); + if ((le32_to_cpu(pfn_sb->page_size) > PAGE_SIZE) && + (mode == PFN_MODE_PMEM)) { + dev_err(&nd_pfn->dev, + "init failed, page size mismatch %d\n", + le32_to_cpu(pfn_sb->page_size)); + return -EOPNOTSUPP; + } + + if ((le16_to_cpu(pfn_sb->page_struct_size) < sizeof(struct page)) && + (mode == PFN_MODE_PMEM)) { + dev_err(&nd_pfn->dev, + "init failed, struct page size mismatch %d\n", + le16_to_cpu(pfn_sb->page_struct_size)); + return -EOPNOTSUPP; + } + if (!nd_pfn->uuid) { /* * When probing a namepace via nd_pfn_probe() the uuid @@ -703,8 +724,16 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn) * The altmap should be padded out to the block size used * when populating the vmemmap. This *should* be equal to * PMD_SIZE for most architectures. + * + * Also make sure size of struct page is less than 64. We + * want to make sure we use large enough size here so that + * we don't have a dynamic reserve space depending on + * struct page size. But we also want to make sure we notice + * when we end up adding new elements to struct page. */ - offset = ALIGN(start + SZ_8K + 64 * npfns, align) - start; + BUILD_BUG_ON(sizeof(struct page) > MAX_STRUCT_PAGE_SIZE); + offset = ALIGN(start + SZ_8K + MAX_STRUCT_PAGE_SIZE * npfns, align) + - start; } else if (nd_pfn->mode == PFN_MODE_RAM) offset = ALIGN(start + SZ_8K, align) - start; else @@ -724,9 +753,11 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn) memcpy(pfn_sb->uuid, nd_pfn->uuid, 16); memcpy(pfn_sb->parent_uuid, nd_dev_to_uuid(&ndns->dev), 16); pfn_sb->version_major = cpu_to_le16(1); - pfn_sb->version_minor = cpu_to_le16(3); + pfn_sb->version_minor = cpu_to_le16(4); pfn_sb->end_trunc = cpu_to_le32(end_trunc); pfn_sb->align = cpu_to_le32(nd_pfn->align); + pfn_sb->page_struct_size = cpu_to_le16(MAX_STRUCT_PAGE_SIZE); + pfn_sb->page_size = cpu_to_le32(PAGE_SIZE); checksum = nd_sb_checksum((struct nd_gen_sb *) pfn_sb); pfn_sb->checksum = cpu_to_le64(checksum); |