linux/arch/riscv/include/asm/tlbflush.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-only */
   2/*
   3 * Copyright (C) 2009 Chen Liqin <liqin.chen@sunplusct.com>
   4 * Copyright (C) 2012 Regents of the University of California
   5 */
   6
   7#ifndef _ASM_RISCV_TLBFLUSH_H
   8#define _ASM_RISCV_TLBFLUSH_H
   9
  10#include <linux/mm_types.h>
  11#include <asm/smp.h>
  12
  13/*
  14 * Flush entire local TLB.  'sfence.vma' implicitly fences with the instruction
  15 * cache as well, so a 'fence.i' is not necessary.
  16 */
  17static inline void local_flush_tlb_all(void)
  18{
  19        __asm__ __volatile__ ("sfence.vma" : : : "memory");
  20}
  21
  22/* Flush one page from local TLB */
  23static inline void local_flush_tlb_page(unsigned long addr)
  24{
  25        __asm__ __volatile__ ("sfence.vma %0" : : "r" (addr) : "memory");
  26}
  27
  28#ifndef CONFIG_SMP
  29
  30#define flush_tlb_all() local_flush_tlb_all()
  31#define flush_tlb_page(vma, addr) local_flush_tlb_page(addr)
  32
  33static inline void flush_tlb_range(struct vm_area_struct *vma,
  34                unsigned long start, unsigned long end)
  35{
  36        local_flush_tlb_all();
  37}
  38
  39#define flush_tlb_mm(mm) flush_tlb_all()
  40
  41#else /* CONFIG_SMP */
  42
  43#include <asm/sbi.h>
  44
  45static inline void remote_sfence_vma(struct cpumask *cmask, unsigned long start,
  46                                     unsigned long size)
  47{
  48        struct cpumask hmask;
  49
  50        cpumask_clear(&hmask);
  51        riscv_cpuid_to_hartid_mask(cmask, &hmask);
  52        sbi_remote_sfence_vma(hmask.bits, start, size);
  53}
  54
  55#define flush_tlb_all() sbi_remote_sfence_vma(NULL, 0, -1)
  56#define flush_tlb_page(vma, addr) flush_tlb_range(vma, addr, 0)
  57#define flush_tlb_range(vma, start, end) \
  58        remote_sfence_vma(mm_cpumask((vma)->vm_mm), start, (end) - (start))
  59#define flush_tlb_mm(mm) \
  60        remote_sfence_vma(mm_cpumask(mm), 0, -1)
  61
  62#endif /* CONFIG_SMP */
  63
  64/* Flush a range of kernel pages */
  65static inline void flush_tlb_kernel_range(unsigned long start,
  66        unsigned long end)
  67{
  68        flush_tlb_all();
  69}
  70
  71#endif /* _ASM_RISCV_TLBFLUSH_H */
  72