@@ -240,6 +240,10 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
if (WARN_ON((old & PTE_ATTRINDX_MASK) != (new & PTE_ATTRINDX_MASK)))
goto pte_bad;
+ /* Changing contiguity may lead to a TLB conflict */
+ if (WARN_ON((old & PTE_CONT) != (new & PTE_CONT)))
+ goto pte_bad;
+
/* Change of OA is only an issue if one mapping is writable */
if (!(old & new & PTE_RDONLY) &&
WARN_ON(pte_pfn(*ptep) != pte_pfn(pte)))
--------------8<--------------------
But it doesn't look nice afterwards. It's the fixup_init() trying to
re-write the entries and we start changing the PTE_CONT bit:
Call trace:
[<ffffffc0000952b8>] __create_mapping.isra.5+0x360/0x530
[<ffffffc0000954ec>] fixup_init+0x64/0x80
[<ffffffc0000945a4>] free_initmem+0xc/0x38
[<ffffffc0005eb9f8>] kernel_init+0x20/0xe0
[<ffffffc000085c50>] ret_from_fork+0x10/0x40
What I don't get is why we have fixup_init() even when
!CONFIG_DEBUG_RODATA. It probably breaks the initial mapping just to get
a non-executable init section. However, the other sections are left
executable when this config option is disabled. The patch below fixes
the warnings above:
--------------8<--------------------
@@ -482,9 +482,11 @@ void mark_rodata_ro(void)
void fixup_init(void)
{
+#ifdef CONFIG_DEBUG_RODATA
create_mapping_late(__pa(__init_begin), (unsigned long)__init_begin,
(unsigned long)__init_end - (unsigned long)__init_begin,
PAGE_KERNEL);
+#endif
}
/*