// SPDX-License-Identifier: GPL-2.0-only1/*2* Hexagon Virtual Machine TLB functions3*4* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.5*/67/*8* The Hexagon Virtual Machine conceals the real workings of9* the TLB, but there are one or two functions that need to10* be instantiated for it, differently from a native build.11*/12#include <linux/mm.h>13#include <linux/sched.h>14#include <asm/page.h>15#include <asm/hexagon_vm.h>16#include <asm/tlbflush.h>1718/*19* Initial VM implementation has only one map active at a time, with20* TLB purgings on changes. So either we're nuking the current map,21* or it's a no-op. This operation is messy on true SMPs where other22* processors must be induced to flush the copies in their local TLBs,23* but Hexagon thread-based virtual processors share the same MMU.24*/25void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,26unsigned long end)27{28struct mm_struct *mm = vma->vm_mm;2930if (mm->context.ptbase == current->active_mm->context.ptbase)31__vmclrmap((void *)start, end - start);32}3334/*35* Flush a page from the kernel virtual map - used by highmem36*/37void flush_tlb_one(unsigned long vaddr)38{39__vmclrmap((void *)vaddr, PAGE_SIZE);40}4142/*43* Flush all TLBs across all CPUs, virtual or real.44* A single Hexagon core has 6 thread contexts but45* only one TLB.46*/47void tlb_flush_all(void)48{49/* should probably use that fixaddr end or whateve label */50__vmclrmap(0, 0xffff0000);51}5253/*54* Flush TLB entries associated with a given mm_struct mapping.55*/56void flush_tlb_mm(struct mm_struct *mm)57{58/* Current Virtual Machine has only one map active at a time */59if (current->active_mm->context.ptbase == mm->context.ptbase)60tlb_flush_all();61}6263/*64* Flush TLB state associated with a page of a vma.65*/66void flush_tlb_page(struct vm_area_struct *vma, unsigned long vaddr)67{68struct mm_struct *mm = vma->vm_mm;6970if (mm->context.ptbase == current->active_mm->context.ptbase)71__vmclrmap((void *)vaddr, PAGE_SIZE);72}7374/*75* Flush TLB entries associated with a kernel address range.76* Like flush range, but without the check on the vma->vm_mm.77*/78void flush_tlb_kernel_range(unsigned long start, unsigned long end)79{80__vmclrmap((void *)start, end - start);81}828384