mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 20:22:09 +00:00
Revert "MIPS: make userspace mapping young by default"
This reverts commitf685a533a7
. The MIPS cache flush logic needs to know whether the mapping was already established to decide how to flush caches. This is done by checking the valid bit in the PTE. The commit above breaks this logic by setting the valid in the PTE in new mappings, which causes kernel crashes. Link: https://lkml.kernel.org/r/20210526094335.92948-1-tsbogend@alpha.franken.de Fixes:f685a533a7
("MIPS: make userspace mapping young by default") Reported-by: Zhou Yanjie <zhouyanjie@wanyeetech.com> Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de> Cc: Huang Pei <huangpei@loongson.cn> Cc: Nicholas Piggin <npiggin@gmail.com> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
16f0596fc1
commit
50c25ee97c
@ -158,31 +158,29 @@ unsigned long _page_cachable_default;
|
||||
EXPORT_SYMBOL(_page_cachable_default);
|
||||
|
||||
#define PM(p) __pgprot(_page_cachable_default | (p))
|
||||
#define PVA(p) PM(_PAGE_VALID | _PAGE_ACCESSED | (p))
|
||||
|
||||
static inline void setup_protection_map(void)
|
||||
{
|
||||
protection_map[0] = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
|
||||
protection_map[1] = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC);
|
||||
protection_map[2] = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
|
||||
protection_map[3] = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC);
|
||||
protection_map[4] = PVA(_PAGE_PRESENT);
|
||||
protection_map[5] = PVA(_PAGE_PRESENT);
|
||||
protection_map[6] = PVA(_PAGE_PRESENT);
|
||||
protection_map[7] = PVA(_PAGE_PRESENT);
|
||||
protection_map[1] = PM(_PAGE_PRESENT | _PAGE_NO_EXEC);
|
||||
protection_map[2] = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
|
||||
protection_map[3] = PM(_PAGE_PRESENT | _PAGE_NO_EXEC);
|
||||
protection_map[4] = PM(_PAGE_PRESENT);
|
||||
protection_map[5] = PM(_PAGE_PRESENT);
|
||||
protection_map[6] = PM(_PAGE_PRESENT);
|
||||
protection_map[7] = PM(_PAGE_PRESENT);
|
||||
|
||||
protection_map[8] = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
|
||||
protection_map[9] = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC);
|
||||
protection_map[10] = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE |
|
||||
protection_map[9] = PM(_PAGE_PRESENT | _PAGE_NO_EXEC);
|
||||
protection_map[10] = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE |
|
||||
_PAGE_NO_READ);
|
||||
protection_map[11] = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE);
|
||||
protection_map[12] = PVA(_PAGE_PRESENT);
|
||||
protection_map[13] = PVA(_PAGE_PRESENT);
|
||||
protection_map[14] = PVA(_PAGE_PRESENT);
|
||||
protection_map[15] = PVA(_PAGE_PRESENT);
|
||||
protection_map[11] = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE);
|
||||
protection_map[12] = PM(_PAGE_PRESENT);
|
||||
protection_map[13] = PM(_PAGE_PRESENT);
|
||||
protection_map[14] = PM(_PAGE_PRESENT | _PAGE_WRITE);
|
||||
protection_map[15] = PM(_PAGE_PRESENT | _PAGE_WRITE);
|
||||
}
|
||||
|
||||
#undef _PVA
|
||||
#undef PM
|
||||
|
||||
void cpu_cache_init(void)
|
||||
|
@ -432,6 +432,14 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres
|
||||
* To be differentiate with macro pte_mkyoung, this macro is used on platforms
|
||||
* where software maintains page access bit.
|
||||
*/
|
||||
#ifndef pte_sw_mkyoung
|
||||
static inline pte_t pte_sw_mkyoung(pte_t pte)
|
||||
{
|
||||
return pte;
|
||||
}
|
||||
#define pte_sw_mkyoung pte_sw_mkyoung
|
||||
#endif
|
||||
|
||||
#ifndef pte_savedwrite
|
||||
#define pte_savedwrite pte_write
|
||||
#endif
|
||||
|
@ -2939,6 +2939,7 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
|
||||
}
|
||||
flush_cache_page(vma, vmf->address, pte_pfn(vmf->orig_pte));
|
||||
entry = mk_pte(new_page, vma->vm_page_prot);
|
||||
entry = pte_sw_mkyoung(entry);
|
||||
entry = maybe_mkwrite(pte_mkdirty(entry), vma);
|
||||
|
||||
/*
|
||||
@ -3602,6 +3603,7 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
|
||||
__SetPageUptodate(page);
|
||||
|
||||
entry = mk_pte(page, vma->vm_page_prot);
|
||||
entry = pte_sw_mkyoung(entry);
|
||||
if (vma->vm_flags & VM_WRITE)
|
||||
entry = pte_mkwrite(pte_mkdirty(entry));
|
||||
|
||||
@ -3786,6 +3788,8 @@ void do_set_pte(struct vm_fault *vmf, struct page *page, unsigned long addr)
|
||||
|
||||
if (prefault && arch_wants_old_prefaulted_pte())
|
||||
entry = pte_mkold(entry);
|
||||
else
|
||||
entry = pte_sw_mkyoung(entry);
|
||||
|
||||
if (write)
|
||||
entry = maybe_mkwrite(pte_mkdirty(entry), vma);
|
||||
|
Loading…
Reference in New Issue
Block a user