Loading arch/arm64/Kconfig.debug +3 −0 Original line number Original line Diff line number Diff line Loading @@ -96,6 +96,9 @@ config ARM64_RELOC_TEST depends on m depends on m tristate "Relocation testing module" tristate "Relocation testing module" config ARM64_STRICT_BREAK_BEFORE_MAKE bool "Enforce strict break-before-make on page table updates " source "drivers/hwtracing/coresight/Kconfig" source "drivers/hwtracing/coresight/Kconfig" endmenu endmenu arch/arm64/include/asm/pgtable.h +29 −0 Original line number Original line Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <asm/bug.h> #include <asm/bug.h> #include <asm/proc-fns.h> #include <asm/proc-fns.h> #include <asm/bug.h> #include <asm/memory.h> #include <asm/memory.h> #include <asm/pgtable-hwdef.h> #include <asm/pgtable-hwdef.h> #include <asm/pgtable-prot.h> #include <asm/pgtable-prot.h> Loading Loading @@ -218,6 +219,34 @@ static inline pmd_t pmd_mkcont(pmd_t pmd) static inline void set_pte(pte_t *ptep, pte_t pte) static inline void set_pte(pte_t *ptep, pte_t pte) { { #ifdef CONFIG_ARM64_STRICT_BREAK_BEFORE_MAKE pteval_t old = pte_val(*ptep); pteval_t new = pte_val(pte); /* Only problematic if valid -> valid */ if (!(old & new & PTE_VALID)) goto pte_ok; /* Changing attributes should go via an invalid entry */ if (WARN_ON((old & PTE_ATTRINDX_MASK) != (new & PTE_ATTRINDX_MASK))) 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))) goto pte_bad; goto pte_ok; pte_bad: *ptep = __pte(0); dsb(ishst); asm("tlbi vmalle1is"); dsb(ish); isb(); pte_ok: #endif WRITE_ONCE(*ptep, pte); WRITE_ONCE(*ptep, pte); /* /* Loading Loading
arch/arm64/Kconfig.debug +3 −0 Original line number Original line Diff line number Diff line Loading @@ -96,6 +96,9 @@ config ARM64_RELOC_TEST depends on m depends on m tristate "Relocation testing module" tristate "Relocation testing module" config ARM64_STRICT_BREAK_BEFORE_MAKE bool "Enforce strict break-before-make on page table updates " source "drivers/hwtracing/coresight/Kconfig" source "drivers/hwtracing/coresight/Kconfig" endmenu endmenu
arch/arm64/include/asm/pgtable.h +29 −0 Original line number Original line Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <asm/bug.h> #include <asm/bug.h> #include <asm/proc-fns.h> #include <asm/proc-fns.h> #include <asm/bug.h> #include <asm/memory.h> #include <asm/memory.h> #include <asm/pgtable-hwdef.h> #include <asm/pgtable-hwdef.h> #include <asm/pgtable-prot.h> #include <asm/pgtable-prot.h> Loading Loading @@ -218,6 +219,34 @@ static inline pmd_t pmd_mkcont(pmd_t pmd) static inline void set_pte(pte_t *ptep, pte_t pte) static inline void set_pte(pte_t *ptep, pte_t pte) { { #ifdef CONFIG_ARM64_STRICT_BREAK_BEFORE_MAKE pteval_t old = pte_val(*ptep); pteval_t new = pte_val(pte); /* Only problematic if valid -> valid */ if (!(old & new & PTE_VALID)) goto pte_ok; /* Changing attributes should go via an invalid entry */ if (WARN_ON((old & PTE_ATTRINDX_MASK) != (new & PTE_ATTRINDX_MASK))) 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))) goto pte_bad; goto pte_ok; pte_bad: *ptep = __pte(0); dsb(ishst); asm("tlbi vmalle1is"); dsb(ish); isb(); pte_ok: #endif WRITE_ONCE(*ptep, pte); WRITE_ONCE(*ptep, pte); /* /* Loading