[PATCH 6.12.y 2/2] mm/early_ioremap: Sign-extend PAGE_MASK when aligning the physical address

From: Radek Marciňa

Date: Sat Oct 31 2026 - 11:45:39 EST


From: Radek Marciňa <github.unusual340@xxxxxxxxxx>

[ Stable-only fix: mainline is not affected since v6.13, see below. ]

On 32-bit kernels with a 64-bit phys_addr_t and an unsigned long
PAGE_MASK, which in this tree is x86-32 with PAE, __early_ioremap()

phys_addr &= PAGE_MASK;

clears bits 32-63, so early_ioremap() and early_memremap() of anything
above 4 GiB map the alias at the low 32 bits instead. Cast PAGE_MASK
to signed long so it sign-extends.

Mainline lost the bug when commit efe8419ae78d ("vdso: Introduce
vdso/page.h") and commit d4a65302dd84 ("vdso: Change PAGE_MASK to
signed on all 32-bit architectures") made PAGE_MASK signed on 32-bit.
Those rework PAGE_MASK for every architecture, so they are not
backported.

Fixes: 9e5c33d7aeee ("mm: create generic early_ioremap() support")
Assisted-by: LLM
Signed-off-by: Radek Marciňa <github.unusual340@xxxxxxxxxx>
---
mm/early_ioremap.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mm/early_ioremap.c b/mm/early_ioremap.c
index ce06b2884789..ba0acdb72396 100644
--- a/mm/early_ioremap.c
+++ b/mm/early_ioremap.c
@@ -129,7 +129,7 @@ __early_ioremap(resource_size_t phys_addr, unsigned long size, pgprot_t prot)
* Mappings have to be page-aligned
*/
offset = offset_in_page(phys_addr);
- phys_addr &= PAGE_MASK;
+ phys_addr &= (signed long)PAGE_MASK;
size = PAGE_ALIGN(last_addr + 1) - phys_addr;

/*
--
2.56.0