linux/arch/nds32/include/asm/mmu_context.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2// Copyright (C) 2005-2017 Andes Technology Corporation
   3
   4#ifndef __ASM_NDS32_MMU_CONTEXT_H
   5#define __ASM_NDS32_MMU_CONTEXT_H
   6
   7#include <linux/spinlock.h>
   8#include <asm/tlbflush.h>
   9#include <asm/proc-fns.h>
  10#include <asm-generic/mm_hooks.h>
  11
  12#define init_new_context init_new_context
  13static inline int
  14init_new_context(struct task_struct *tsk, struct mm_struct *mm)
  15{
  16        mm->context.id = 0;
  17        return 0;
  18}
  19
  20#define CID_BITS        9
  21extern spinlock_t cid_lock;
  22extern unsigned int cpu_last_cid;
  23
  24static inline void __new_context(struct mm_struct *mm)
  25{
  26        unsigned int cid;
  27        unsigned long flags;
  28
  29        spin_lock_irqsave(&cid_lock, flags);
  30        cid = cpu_last_cid;
  31        cpu_last_cid += 1 << TLB_MISC_offCID;
  32        if (cpu_last_cid == 0)
  33                cpu_last_cid = 1 << TLB_MISC_offCID << CID_BITS;
  34
  35        if ((cid & TLB_MISC_mskCID) == 0)
  36                flush_tlb_all();
  37        spin_unlock_irqrestore(&cid_lock, flags);
  38
  39        mm->context.id = cid;
  40}
  41
  42static inline void check_context(struct mm_struct *mm)
  43{
  44        if (unlikely
  45            ((mm->context.id ^ cpu_last_cid) >> TLB_MISC_offCID >> CID_BITS))
  46                __new_context(mm);
  47}
  48
  49static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
  50                             struct task_struct *tsk)
  51{
  52        unsigned int cpu = smp_processor_id();
  53
  54        if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next)) || prev != next) {
  55                check_context(next);
  56                cpu_switch_mm(next);
  57        }
  58}
  59
  60#include <asm-generic/mmu_context.h>
  61
  62#endif
  63