summaryrefslogtreecommitdiff
path: root/arch/mips
diff options
context:
space:
mode:
authorHenry Willard <henry.willard@oracle.com>2023-04-13 00:29:53 +0300
committerThomas Bogendoerfer <tsbogend@alpha.franken.de>2023-04-24 10:48:51 +0300
commit1492c6b1874ac5ed57d8ffef89e2b5c59f804aa8 (patch)
tree97e8b222bc88a2c0f929c483530b73bc5e63f6b5 /arch/mips
parentf4670a1b30f886e843258ca4a69c442811a90302 (diff)
downloadlinux-1492c6b1874ac5ed57d8ffef89e2b5c59f804aa8.tar.xz
MIPS: Don't clear _PAGE_SPECIAL in _PAGE_CHG_MASK
In the special case where p = mmap(NULL, ALLOC_SIZE, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0); is followed by rc = mprotect(p, ALLOC_SIZE, PROT_NONE); the _PAGE_SPECIAL bit in the page tables will be cleared by mistake and the later unmapped operations will incorrectly modify the struct page for the the zero page. This sequence occurs in the madvise05 test of the Linux Test Project suite of tests. This was discovered while testing an older version of the kernel (5.4.17) on a MIPS device. Unfortunately, support for this device is not available in newer kernels, so I can't test this with the latest Linux kernel code. It looks like the problem exists in newer kernels, but I can't verify it. Except for the LTP test, this sequence of calls is probably not common. Passing it along in the hope it will be useful to someone. Signed-off-by: Henry Willard <henry.willard@oracle.com> Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/include/asm/pgtable-bits.h3
1 files changed, 2 insertions, 1 deletions
diff --git a/arch/mips/include/asm/pgtable-bits.h b/arch/mips/include/asm/pgtable-bits.h
index 2362842ee2b5..1c576679aa87 100644
--- a/arch/mips/include/asm/pgtable-bits.h
+++ b/arch/mips/include/asm/pgtable-bits.h
@@ -280,6 +280,7 @@ static inline uint64_t pte_to_entrylo(unsigned long pte_val)
#define __WRITEABLE (_PAGE_SILENT_WRITE | _PAGE_WRITE | _PAGE_MODIFIED)
#define _PAGE_CHG_MASK (_PAGE_ACCESSED | _PAGE_MODIFIED | \
- _PAGE_SOFT_DIRTY | _PFN_MASK | _CACHE_MASK)
+ _PAGE_SOFT_DIRTY | _PFN_MASK | \
+ _CACHE_MASK | _PAGE_SPECIAL)
#endif /* _ASM_PGTABLE_BITS_H */