mirror of
https://github.com/torvalds/linux.git
synced 2026-05-26 08:02:27 +02:00
powerpc, mm: Fix mprotect on book3s 32-bit
On 32-bit book3s with hash-MMUs, tlb_flush() was a no-op. This was unnoticed because all uses until recently were for unmaps, and thus handled by __tlb_remove_tlb_entry(). After commit4a18419f71("mm/mprotect: use mmu_gather") in kernel 5.19, tlb_gather_mmu() started being used for mprotect as well. This caused mprotect to simply not work on these machines: int *ptr = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); *ptr = 1; // force HPTE to be created mprotect(ptr, 4096, PROT_READ); *ptr = 2; // should segfault, but succeeds Fixed by making tlb_flush() actually flush TLB pages. This finally agrees with the behaviour of boot3s64's tlb_flush(). Fixes:4a18419f71("mm/mprotect: use mmu_gather") Cc: stable@vger.kernel.org Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu> Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com> Signed-off-by: Dave Vasilevsky <dave@vasilevsky.ca> Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com> Link: https://patch.msgid.link/20251116-vasi-mprotect-g3-v3-1-59a9bd33ba00@vasilevsky.ca
This commit is contained in:
parent
fb2ff9fa72
commit
78fc63ffa7
|
|
@ -11,6 +11,7 @@
|
|||
void hash__flush_tlb_mm(struct mm_struct *mm);
|
||||
void hash__flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
|
||||
void hash__flush_range(struct mm_struct *mm, unsigned long start, unsigned long end);
|
||||
void hash__flush_gather(struct mmu_gather *tlb);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
void _tlbie(unsigned long address);
|
||||
|
|
@ -29,7 +30,9 @@ void _tlbia(void);
|
|||
static inline void tlb_flush(struct mmu_gather *tlb)
|
||||
{
|
||||
/* 603 needs to flush the whole TLB here since it doesn't use a hash table. */
|
||||
if (!mmu_has_feature(MMU_FTR_HPTE_TABLE))
|
||||
if (mmu_has_feature(MMU_FTR_HPTE_TABLE))
|
||||
hash__flush_gather(tlb);
|
||||
else
|
||||
_tlbia();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -105,3 +105,12 @@ void hash__flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
|
|||
flush_hash_pages(mm->context.id, vmaddr, pmd_val(*pmd), 1);
|
||||
}
|
||||
EXPORT_SYMBOL(hash__flush_tlb_page);
|
||||
|
||||
void hash__flush_gather(struct mmu_gather *tlb)
|
||||
{
|
||||
if (tlb->fullmm || tlb->need_flush_all)
|
||||
hash__flush_tlb_mm(tlb->mm);
|
||||
else
|
||||
hash__flush_range(tlb->mm, tlb->start, tlb->end);
|
||||
}
|
||||
EXPORT_SYMBOL(hash__flush_gather);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user