[PATCH] dax/pmem: fix unaligned compound devmap initialization
From: Muchun Song
Date: Fri Oct 16 2026 - 01:49:32 EST
Static pmem Device DAX namespaces reserve space for namespace metadata
before the user-visible data range, and may also include padding needed
to satisfy the Device DAX alignment. __dax_pmem_probe() adjusts the
dax_region range to start at the data range, but the dev_pagemap range
still starts at the beginning of the namespace.
That is not valid for compound devmap mappings whose memmap is stored in
system RAM. Compound page initialization requires the start PFN to be
naturally aligned to the compound page size, because the head and tail
struct pages are initialized according to that geometry. If the pgmap
starts before the aligned data range, memmap_init_zone_device() can build
compound page metadata from an unaligned PFN.
The resulting struct page layout is inconsistent with the Device DAX
mapping. A later mmap fault can then resolve the user-visible PFN through
invalid compound page metadata and hit a kernel panic while inserting the
DAX folio.
Fix this by advancing the pgmap start to the aligned Device DAX data
range for non-altmap compound mappings. Leave base-page namespaces
unchanged, and leave the altmap path unchanged because
memmap_init_zone_device() already skips the altmap reservation itself.
Fixes: 14606001efb4 ("device-dax: compound devmap support")
Cc: <stable@xxxxxxxxxxxxxxx>
Reported-by: Ritesh Harjani (IBM) <ritesh.list@xxxxxxxxx>
Closes: https://lore.kernel.org/r/wlrkqqvg.ritesh.list@xxxxxxxxx
Assisted-by: LLM
Signed-off-by: Muchun Song <songmuchun@xxxxxxxxxxxxx>
---
drivers/dax/pmem.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/dax/pmem.c b/drivers/dax/pmem.c
index bee93066a849..d3a9b85107b0 100644
--- a/drivers/dax/pmem.c
+++ b/drivers/dax/pmem.c
@@ -51,6 +51,13 @@ static struct dev_dax *__dax_pmem_probe(struct device *dev)
/* adjust the dax_region range to the start of data */
range = pgmap.range;
range.start += offset;
+ /*
+ * When the memmap is stored in RAM, exclude metadata and alignment
+ * padding from compound page initialization. Otherwise, the pgmap
+ * may start before the naturally aligned Device DAX data range.
+ */
+ if (!pgmap_altmap(&pgmap) && le32_to_cpu(pfn_sb->align) > PAGE_SIZE)
+ pgmap.range.start = range.start;
dax_region = alloc_dax_region(dev, region_id, &range,
nd_region->target_node, le32_to_cpu(pfn_sb->align),
IORESOURCE_DAX_STATIC);
base-commit: 0fcb05b72344f40806cbe810de8872f1698bf053
--
2.54.0