mirror of
https://github.com/torvalds/linux.git
synced 2024-11-07 20:51:47 +00:00
Revert "x86, mm: Make spurious_fault check explicitly check explicitly check the PRESENT bit"
I got a report for a minor regression introduced by commit027ef6c878
("mm: thp: fix pmd_present for split_huge_page and PROT_NONE with THP"). So the problem is, pageattr creates kernel pagetables (pte and pmds) that breaks pte_present/pmd_present and the patch above exposed this invariant breakage for pmd_present. The same problem already existed for the pte and pte_present and it was fixed by commit660a293ea9
("x86, mm: Make spurious_fault check explicitly check the PRESENT bit") (if it wasn't for that commit, it wouldn't even be a regression). That fix avoids the pagefault to use pte_present. I could follow through by stopping using pmd_present/pmd_huge too. However I think it's more robust to fix pageattr and to clear the PSE/GLOBAL bitflags too in addition to the present bitflag. So the kernel page fault can keep using the regular pte_present/pmd_present/pmd_huge. The confusion arises because _PAGE_GLOBAL and _PAGE_PROTNONE are sharing the same bit, and in the pmd case we pretend _PAGE_PSE to be set only in present pmds (to facilitate split_huge_page final tlb flush). Signed-off-by: Andrea Arcangeli <aarcange@redhat.com> Cc: Andi Kleen <andi@firstfloor.org> Cc: Shaohua Li <shaohua.li@intel.com> Cc: "H. Peter Anvin" <hpa@linux.intel.com> Cc: Mel Gorman <mgorman@suse.de> Cc: Hugh Dickins <hughd@google.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
parent
942670d0dc
commit
954f857187
@ -939,14 +939,8 @@ spurious_fault(unsigned long error_code, unsigned long address)
|
||||
if (pmd_large(*pmd))
|
||||
return spurious_fault_check(error_code, (pte_t *) pmd);
|
||||
|
||||
/*
|
||||
* Note: don't use pte_present() here, since it returns true
|
||||
* if the _PAGE_PROTNONE bit is set. However, this aliases the
|
||||
* _PAGE_GLOBAL bit, which for kernel pages give false positives
|
||||
* when CONFIG_DEBUG_PAGEALLOC is used.
|
||||
*/
|
||||
pte = pte_offset_kernel(pmd, address);
|
||||
if (!(pte_flags(*pte) & _PAGE_PRESENT))
|
||||
if (!pte_present(*pte))
|
||||
return 0;
|
||||
|
||||
ret = spurious_fault_check(error_code, pte);
|
||||
|
Loading…
Reference in New Issue
Block a user