| @@ -13,6 +13,8 @@ · 12 unmodified lines |
| 13 | #include "pfn.h" | 13 | #include "pfn.h" |
| 14 | #include "nd.h" | 14 | #include "nd.h" |
| 15 | | 15 | |
| | 16 | static const bool page_struct_override = IS_ENABLED(CONFIG_NVDIMM_KMSAN); |
| | 17 | |
| 16 | static void nd_pfn_release(struct device *dev) | 18 | static void nd_pfn_release(struct device *dev) |
| 17 | { | 19 | { |
| 18 | struct nd_region *nd_region = to_nd_region(dev->parent); | 20 | struct nd_region *nd_region = to_nd_region(dev->parent); |
| @@ -758,12 +760,6 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn) · 739 unmodified lines |
| 758 | return -ENXIO; | 760 | return -ENXIO; |
| 759 | } | 761 | } |
| 760 | | 762 | |
| 761 | /* | | |
| 762 | * Note, we use 64 here for the standard size of struct page, | | |
| 763 | * debugging options may cause it to be larger in which case the | | |
| 764 | * implementation will limit the pfns advertised through | | |
| 765 | * ->direct_access() to those that are included in the memmap. | | |
| 766 | */ | | |
| 767 | start = nsio->res.start; | 763 | start = nsio->res.start; |
| 768 | size = resource_size(&nsio->res); | 764 | size = resource_size(&nsio->res); |
| 769 | npfns = PHYS_PFN(size - SZ_8K); | 765 | npfns = PHYS_PFN(size - SZ_8K); |
| @@ -782,20 +778,33 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn) · 12 unmodified lines |
| 782 | } | 778 | } |
| 783 | end_trunc = start + size - ALIGN_DOWN(start + size, align); | 779 | end_trunc = start + size - ALIGN_DOWN(start + size, align); |
| 784 | if (nd_pfn->mode == PFN_MODE_PMEM) { | 780 | if (nd_pfn->mode == PFN_MODE_PMEM) { |
| | 781 | unsigned long page_map_size = MAX_STRUCT_PAGE_SIZE * npfns; |
| | 782 | |
| 785 | /* | 783 | /* |
| 786 | * The altmap should be padded out to the block size used | 784 | * The altmap should be padded out to the block size used |
| 787 | * when populating the vmemmap. This *should* be equal to | 785 | * when populating the vmemmap. This *should* be equal to |
| 788 | * PMD_SIZE for most architectures. | 786 | * PMD_SIZE for most architectures. |
| 789 | * | 787 | * |
| 790 | * Also make sure size of struct page is less than 128. We | 788 | * Also make sure size of struct page is less than |
| 791 | * want to make sure we use large enough size here so that | 789 | * MAX_STRUCT_PAGE_SIZE. The goal here is compatibility in the |
| 792 | * we don't have a dynamic reserve space depending on | 790 | * face of production kernel configurations that reduce the |
| 793 | * struct page size. But we also want to make sure we notice | 791 | * 'struct page' size below MAX_STRUCT_PAGE_SIZE. For debug |
| 794 | * when we end up adding new elements to struct page. | 792 | * kernel configurations that increase the 'struct page' size |
| | 793 | * above MAX_STRUCT_PAGE_SIZE, the page_struct_override allows |
| | 794 | * for continuing with the capacity that will be wasted when |
| | 795 | * reverting to a production kernel configuration. Otherwise, |
| | 796 | * those configurations are blocked by default. |
| 795 | */ | 797 | */ |
| 796 | BUILD_BUG_ON(sizeof(struct page) > MAX_STRUCT_PAGE_SIZE); | 798 | if (sizeof(struct page) > MAX_STRUCT_PAGE_SIZE) { |
| 797 | offset = ALIGN(start + SZ_8K + MAX_STRUCT_PAGE_SIZE * npfns, align) | 799 | if (page_struct_override) |
| 798 | - start; | 800 | page_map_size = sizeof(struct page) * npfns; |
| | 801 | else { |
| | 802 | dev_err(&nd_pfn->dev, |
| | 803 | "Memory debug options prevent using pmem for the page map\n"); |
| | 804 | return -EINVAL; |
| | 805 | } |
| | 806 | } |
| | 807 | offset = ALIGN(start + SZ_8K + page_map_size, align) - start; |
| 799 | } else if (nd_pfn->mode == PFN_MODE_RAM) | 808 | } else if (nd_pfn->mode == PFN_MODE_RAM) |
| 800 | offset = ALIGN(start + SZ_8K, align) - start; | 809 | offset = ALIGN(start + SZ_8K, align) - start; |
| 801 | else | 810 | else |
| @@ -818,7 +827,10 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn) · 16 unmodified lines |
| 818 | pfn_sb->version_minor = cpu_to_le16(4); | 827 | pfn_sb->version_minor = cpu_to_le16(4); |
| 819 | pfn_sb->end_trunc = cpu_to_le32(end_trunc); | 828 | pfn_sb->end_trunc = cpu_to_le32(end_trunc); |
| 820 | pfn_sb->align = cpu_to_le32(nd_pfn->align); | 829 | pfn_sb->align = cpu_to_le32(nd_pfn->align); |
| 821 | pfn_sb->page_struct_size = cpu_to_le16(MAX_STRUCT_PAGE_SIZE); | 830 | if (sizeof(struct page) > MAX_STRUCT_PAGE_SIZE && page_struct_override) |
| | 831 | pfn_sb->page_struct_size = cpu_to_le16(sizeof(struct page)); |
| | 832 | else |
| | 833 | pfn_sb->page_struct_size = cpu_to_le16(MAX_STRUCT_PAGE_SIZE); |
| 822 | pfn_sb->page_size = cpu_to_le32(PAGE_SIZE); | 834 | pfn_sb->page_size = cpu_to_le32(PAGE_SIZE); |
| 823 | checksum = nd_sb_checksum((struct nd_gen_sb *) pfn_sb); | 835 | checksum = nd_sb_checksum((struct nd_gen_sb *) pfn_sb); |
| 824 | pfn_sb->checksum = cpu_to_le64(checksum); | 836 | pfn_sb->checksum = cpu_to_le64(checksum); |