// SPDX-License-Identifier: GPL-2.0-or-later1/*2* This file contains the routines for flushing entries from the3* TLB and MMU hash table.4*5* Derived from arch/ppc64/mm/init.c:6* Copyright (C) 1995-1996 Gary Thomas ([email protected])7*8* Modifications by Paul Mackerras (PowerMac) ([email protected])9* and Cort Dougan (PReP) ([email protected])10* Copyright (C) 1996 Paul Mackerras11*12* Derived from "arch/i386/mm/init.c"13* Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds14*15* Dave Engebretsen <[email protected]>16* Rework for PPC64 port.17*/1819#include <linux/kernel.h>20#include <linux/mm.h>21#include <linux/percpu.h>22#include <linux/hardirq.h>23#include <asm/tlbflush.h>24#include <asm/tlb.h>25#include <asm/bug.h>26#include <asm/pte-walk.h>272829#include <trace/events/thp.h>3031DEFINE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);3233/*34* A linux PTE was changed and the corresponding hash table entry35* neesd to be flushed. This function will either perform the flush36* immediately or will batch it up if the current CPU has an active37* batch on it.38*/39void hpte_need_flush(struct mm_struct *mm, unsigned long addr,40pte_t *ptep, unsigned long pte, int huge)41{42unsigned long vpn;43struct ppc64_tlb_batch *batch = &get_cpu_var(ppc64_tlb_batch);44unsigned long vsid;45unsigned int psize;46int ssize;47real_pte_t rpte;48int i, offset;4950i = batch->index;5152/*53* Get page size (maybe move back to caller).54*55* NOTE: when using special 64K mappings in 4K environment like56* for SPEs, we obtain the page size from the slice, which thus57* must still exist (and thus the VMA not reused) at the time58* of this call59*/60if (huge) {61#ifdef CONFIG_HUGETLB_PAGE62psize = get_slice_psize(mm, addr);63/* Mask the address for the correct page size */64addr &= ~((1UL << mmu_psize_defs[psize].shift) - 1);65if (unlikely(psize == MMU_PAGE_16G))66offset = PTRS_PER_PUD;67else68offset = PTRS_PER_PMD;69#else70BUG();71psize = pte_pagesize_index(mm, addr, pte); /* shutup gcc */72#endif73} else {74psize = pte_pagesize_index(mm, addr, pte);75/*76* Mask the address for the standard page size. If we77* have a 64k page kernel, but the hardware does not78* support 64k pages, this might be different from the79* hardware page size encoded in the slice table.80*/81addr &= PAGE_MASK;82offset = PTRS_PER_PTE;83}848586/* Build full vaddr */87if (!is_kernel_addr(addr)) {88ssize = user_segment_size(addr);89vsid = get_user_vsid(&mm->context, addr, ssize);90} else {91vsid = get_kernel_vsid(addr, mmu_kernel_ssize);92ssize = mmu_kernel_ssize;93}94WARN_ON(vsid == 0);95vpn = hpt_vpn(addr, vsid, ssize);96rpte = __real_pte(__pte(pte), ptep, offset);9798/*99* Check if we have an active batch on this CPU. If not, just100* flush now and return.101*/102if (!batch->active) {103flush_hash_page(vpn, rpte, psize, ssize, mm_is_thread_local(mm));104put_cpu_var(ppc64_tlb_batch);105return;106}107108/*109* This can happen when we are in the middle of a TLB batch and110* we encounter memory pressure (eg copy_page_range when it tries111* to allocate a new pte). If we have to reclaim memory and end112* up scanning and resetting referenced bits then our batch context113* will change mid stream.114*115* We also need to ensure only one page size is present in a given116* batch117*/118if (i != 0 && (mm != batch->mm || batch->psize != psize ||119batch->ssize != ssize)) {120__flush_tlb_pending(batch);121i = 0;122}123if (i == 0) {124batch->mm = mm;125batch->psize = psize;126batch->ssize = ssize;127}128batch->pte[i] = rpte;129batch->vpn[i] = vpn;130batch->index = ++i;131if (i >= PPC64_TLB_BATCH_NR)132__flush_tlb_pending(batch);133put_cpu_var(ppc64_tlb_batch);134}135136/*137* This function is called when terminating an mmu batch or when a batch138* is full. It will perform the flush of all the entries currently stored139* in a batch.140*141* Must be called from within some kind of spinlock/non-preempt region...142*/143void __flush_tlb_pending(struct ppc64_tlb_batch *batch)144{145int i, local;146147i = batch->index;148local = mm_is_thread_local(batch->mm);149if (i == 1)150flush_hash_page(batch->vpn[0], batch->pte[0],151batch->psize, batch->ssize, local);152else153flush_hash_range(i, local);154batch->index = 0;155}156157void hash__tlb_flush(struct mmu_gather *tlb)158{159struct ppc64_tlb_batch *tlbbatch = &get_cpu_var(ppc64_tlb_batch);160161/*162* If there's a TLB batch pending, then we must flush it because the163* pages are going to be freed and we really don't want to have a CPU164* access a freed page because it has a stale TLB165*/166if (tlbbatch->index)167__flush_tlb_pending(tlbbatch);168169put_cpu_var(ppc64_tlb_batch);170}171172/**173* __flush_hash_table_range - Flush all HPTEs for a given address range174* from the hash table (and the TLB). But keeps175* the linux PTEs intact.176*177* @start : starting address178* @end : ending address (not included in the flush)179*180* This function is mostly to be used by some IO hotplug code in order181* to remove all hash entries from a given address range used to map IO182* space on a removed PCI-PCI bidge without tearing down the full mapping183* since 64K pages may overlap with other bridges when using 64K pages184* with 4K HW pages on IO space.185*186* Because of that usage pattern, it is implemented for small size rather187* than speed.188*/189void __flush_hash_table_range(unsigned long start, unsigned long end)190{191int hugepage_shift;192unsigned long flags;193194start = ALIGN_DOWN(start, PAGE_SIZE);195end = ALIGN(end, PAGE_SIZE);196197198/*199* Note: Normally, we should only ever use a batch within a200* PTE locked section. This violates the rule, but will work201* since we don't actually modify the PTEs, we just flush the202* hash while leaving the PTEs intact (including their reference203* to being hashed). This is not the most performance oriented204* way to do things but is fine for our needs here.205*/206local_irq_save(flags);207arch_enter_lazy_mmu_mode();208for (; start < end; start += PAGE_SIZE) {209pte_t *ptep = find_init_mm_pte(start, &hugepage_shift);210unsigned long pte;211212if (ptep == NULL)213continue;214pte = pte_val(*ptep);215if (!(pte & H_PAGE_HASHPTE))216continue;217hpte_need_flush(&init_mm, start, ptep, pte, hugepage_shift);218}219arch_leave_lazy_mmu_mode();220local_irq_restore(flags);221}222223void flush_hash_table_pmd_range(struct mm_struct *mm, pmd_t *pmd, unsigned long addr)224{225pte_t *pte;226pte_t *start_pte;227unsigned long flags;228229addr = ALIGN_DOWN(addr, PMD_SIZE);230/*231* Note: Normally, we should only ever use a batch within a232* PTE locked section. This violates the rule, but will work233* since we don't actually modify the PTEs, we just flush the234* hash while leaving the PTEs intact (including their reference235* to being hashed). This is not the most performance oriented236* way to do things but is fine for our needs here.237*/238local_irq_save(flags);239arch_enter_lazy_mmu_mode();240start_pte = pte_offset_map(pmd, addr);241if (!start_pte)242goto out;243for (pte = start_pte; pte < start_pte + PTRS_PER_PTE; pte++) {244unsigned long pteval = pte_val(*pte);245if (pteval & H_PAGE_HASHPTE)246hpte_need_flush(mm, addr, pte, pteval, 0);247addr += PAGE_SIZE;248}249pte_unmap(start_pte);250out:251arch_leave_lazy_mmu_mode();252local_irq_restore(flags);253}254255256