Le 28/03/2024 à 08:57, Christophe Leroy a écrit : > > > Le 28/03/2024 à 07:52, Christophe Leroy a écrit : >> >> >> Le 28/03/2024 à 05:55, Rohan McLure a écrit : >>> Support page table check on all PowerPC platforms. This works by >>> serialising assignments, reassignments and clears of page table >>> entries at each level in order to ensure that anonymous mappings >>> have at most one writable consumer, and likewise that file-backed >>> mappings are not simultaneously also anonymous mappings. >>> >>> In order to support this infrastructure, a number of stubs must be >>> defined for all powerpc platforms. Additionally, seperate set_pte_at() >>> and set_pte_at_unchecked(), to allow for internal, uninstrumented >>> mappings. >> >> I gave it a try on QEMU e500 (64 bits), and get the following Oops. >> What do I have to look for ? >> >> Freeing unused kernel image (initmem) memory: 2588K >> This architecture does not have kernel memory protection. >> Run /init as init process >> ------------[ cut here ]------------ >> kernel BUG at mm/page_table_check.c:119! >> Oops: Exception in kernel mode, sig: 5 [#1] >> BE PAGE_SIZE=4K SMP NR_CPUS=32 QEMU e500 > > Same problem on my 8xx board: > > [ 7.358146] Freeing unused kernel image (initmem) memory: 448K > [ 7.363957] Run /init as init process > [ 7.370955] ------------[ cut here ]------------ > [ 7.375411] kernel BUG at mm/page_table_check.c:119! > [ 7.380393] Oops: Exception in kernel mode, sig: 5 [#1] > [ 7.385621] BE PAGE_SIZE=16K PREEMPT CMPC885 Both problems are fixed by following change: diff --git a/arch/powerpc/include/asm/nohash/pgtable.h b/arch/powerpc/include/asm/nohash/pgtable.h index 413d01a51e6f..5b932632a5d7 100644 --- a/arch/powerpc/include/asm/nohash/pgtable.h +++ b/arch/powerpc/include/asm/nohash/pgtable.h @@ -29,6 +29,8 @@ static inline pte_basic_t pte_update(struct mm_struct *mm, unsigned long addr, p #ifndef __ASSEMBLY__ +#include <linux/page_table_check.h> + extern int icache_44x_need_flush; /* @@ -92,7 +94,11 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { - return __pte(pte_update(mm, addr, ptep, ~0UL, 0, 0)); + pte_t old_pte = __pte(pte_update(mm, addr, ptep, ~0UL, 0, 0)); + + page_table_check_pte_clear(mm, addr, old_pte); + + return old_pte; } #define __HAVE_ARCH_PTEP_GET_AND_CLEAR