147d99948SChristophe Leroy // SPDX-License-Identifier: GPL-2.0
247d99948SChristophe Leroy #include <linux/mm.h>
347d99948SChristophe Leroy #include <linux/hugetlb.h>
447d99948SChristophe Leroy #include <linux/security.h>
547d99948SChristophe Leroy #include <asm/cacheflush.h>
647d99948SChristophe Leroy #include <asm/machdep.h>
747d99948SChristophe Leroy #include <asm/mman.h>
847d99948SChristophe Leroy #include <asm/tlb.h>
947d99948SChristophe Leroy
radix__flush_hugetlb_page(struct vm_area_struct * vma,unsigned long vmaddr)1047d99948SChristophe Leroy void radix__flush_hugetlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
1147d99948SChristophe Leroy {
1247d99948SChristophe Leroy int psize;
1347d99948SChristophe Leroy struct hstate *hstate = hstate_file(vma->vm_file);
1447d99948SChristophe Leroy
1547d99948SChristophe Leroy psize = hstate_get_psize(hstate);
1647d99948SChristophe Leroy radix__flush_tlb_page_psize(vma->vm_mm, vmaddr, psize);
1747d99948SChristophe Leroy }
1847d99948SChristophe Leroy
radix__local_flush_hugetlb_page(struct vm_area_struct * vma,unsigned long vmaddr)1947d99948SChristophe Leroy void radix__local_flush_hugetlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
2047d99948SChristophe Leroy {
2147d99948SChristophe Leroy int psize;
2247d99948SChristophe Leroy struct hstate *hstate = hstate_file(vma->vm_file);
2347d99948SChristophe Leroy
2447d99948SChristophe Leroy psize = hstate_get_psize(hstate);
2547d99948SChristophe Leroy radix__local_flush_tlb_page_psize(vma->vm_mm, vmaddr, psize);
2647d99948SChristophe Leroy }
2747d99948SChristophe Leroy
radix__flush_hugetlb_tlb_range(struct vm_area_struct * vma,unsigned long start,unsigned long end)2847d99948SChristophe Leroy void radix__flush_hugetlb_tlb_range(struct vm_area_struct *vma, unsigned long start,
2947d99948SChristophe Leroy unsigned long end)
3047d99948SChristophe Leroy {
3147d99948SChristophe Leroy int psize;
3247d99948SChristophe Leroy struct hstate *hstate = hstate_file(vma->vm_file);
3347d99948SChristophe Leroy
3447d99948SChristophe Leroy psize = hstate_get_psize(hstate);
35cec6515aSAneesh Kumar K.V /*
36cec6515aSAneesh Kumar K.V * Flush PWC even if we get PUD_SIZE hugetlb invalidate to keep this simpler.
37cec6515aSAneesh Kumar K.V */
38cec6515aSAneesh Kumar K.V if (end - start >= PUD_SIZE)
39cec6515aSAneesh Kumar K.V radix__flush_tlb_pwc_range_psize(vma->vm_mm, start, end, psize);
40cec6515aSAneesh Kumar K.V else
4147d99948SChristophe Leroy radix__flush_tlb_range_psize(vma->vm_mm, start, end, psize);
421af5a810SAlistair Popple mmu_notifier_arch_invalidate_secondary_tlbs(vma->vm_mm, start, end);
4347d99948SChristophe Leroy }
4447d99948SChristophe Leroy
radix__huge_ptep_modify_prot_commit(struct vm_area_struct * vma,unsigned long addr,pte_t * ptep,pte_t old_pte,pte_t pte)4547d99948SChristophe Leroy void radix__huge_ptep_modify_prot_commit(struct vm_area_struct *vma,
4647d99948SChristophe Leroy unsigned long addr, pte_t *ptep,
4747d99948SChristophe Leroy pte_t old_pte, pte_t pte)
4847d99948SChristophe Leroy {
4947d99948SChristophe Leroy struct mm_struct *mm = vma->vm_mm;
50*935d4f0cSRyan Roberts unsigned long psize = huge_page_size(hstate_vma(vma));
5147d99948SChristophe Leroy
5247d99948SChristophe Leroy /*
532a8a0f42SNicholas Piggin * POWER9 NMMU must flush the TLB after clearing the PTE before
542a8a0f42SNicholas Piggin * installing a PTE with more relaxed access permissions, see
552a8a0f42SNicholas Piggin * radix__ptep_set_access_flags.
5647d99948SChristophe Leroy */
572a8a0f42SNicholas Piggin if (!cpu_has_feature(CPU_FTR_ARCH_31) &&
582a8a0f42SNicholas Piggin is_pte_rw_upgrade(pte_val(old_pte), pte_val(pte)) &&
592a8a0f42SNicholas Piggin atomic_read(&mm->context.copros) > 0)
6047d99948SChristophe Leroy radix__flush_hugetlb_page(vma, addr);
6147d99948SChristophe Leroy
62*935d4f0cSRyan Roberts set_huge_pte_at(vma->vm_mm, addr, ptep, pte, psize);
6347d99948SChristophe Leroy }
64