]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
s390/vmem: Support 2G page splitting for KASAN shadow freeing
authorVasily Gorbik <gor@linux.ibm.com>
Fri, 28 Nov 2025 22:01:05 +0000 (23:01 +0100)
committerHeiko Carstens <hca@linux.ibm.com>
Sun, 7 Dec 2025 15:15:19 +0000 (16:15 +0100)
Export split_pud_page() so it can be used from the vmem code and teach
modify_pud_table() to split PUD-sized mappings when only a subrange
needs to be removed.

If the range to be removed covers a full PUD-sized mapping, keep the
existing behavior: clear the PUD entry and free the backing large page
(for non-direct mappings). Otherwise, split the PUD-mapped page into
PMD mappings and let the walker handle the smaller ranges.

This is needed for KASAN early shadow removal support: memory hotplug
freeing the KASAN early shadow is the only expected caller that will
try to free 2G PUD-mapped regions of non-direct mappings.

Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
arch/s390/include/asm/page.h
arch/s390/mm/pageattr.c
arch/s390/mm/vmem.c

index 9240a363c893553ec4ed9b5aa44f91f2313060e2..c1d63b613bf9bf81f780064dfdde79b52f45b171 100644 (file)
@@ -166,6 +166,8 @@ static inline int page_reset_referenced(unsigned long addr)
        return CC_TRANSFORM(cc);
 }
 
+int split_pud_page(pud_t *pudp, unsigned long addr);
+
 /* Bits int the storage key */
 #define _PAGE_CHANGED          0x02    /* HW changed bit               */
 #define _PAGE_REFERENCED       0x04    /* HW referenced bit            */
index 3042647c9dbf4e70f439b03b9ea43ad64c622f8e..d3ce04a4b24864bbed62f878f7133ab71063fee9 100644 (file)
@@ -204,7 +204,7 @@ static int walk_pmd_level(pud_t *pudp, unsigned long addr, unsigned long end,
        return rc;
 }
 
-static int split_pud_page(pud_t *pudp, unsigned long addr)
+int split_pud_page(pud_t *pudp, unsigned long addr)
 {
        unsigned long pmd_addr, prot;
        pmd_t *pm_dir, *pmdp;
index d96587b84e81f54e22ebba191db280f6a2142996..faed09531499b1635b44e8b2ff2d8ebb4a248972 100644 (file)
@@ -330,10 +330,14 @@ static int modify_pud_table(p4d_t *p4d, unsigned long addr, unsigned long end,
                        if (pud_leaf(*pud)) {
                                if (IS_ALIGNED(addr, PUD_SIZE) &&
                                    IS_ALIGNED(next, PUD_SIZE)) {
+                                       if (!direct)
+                                               vmem_free_pages(pud_deref(*pud), get_order(PUD_SIZE), altmap);
                                        pud_clear(pud);
                                        pages++;
+                                       continue;
+                               } else {
+                                       split_pud_page(pud, addr & PUD_MASK);
                                }
-                               continue;
                        }
                } else if (pud_none(*pud)) {
                        if (IS_ALIGNED(addr, PUD_SIZE) &&