Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.2-rc6 137 lines 3.4 kB view raw
1/* SPDX-License-Identifier: GPL-2.0 */ 2// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. 3 4#ifndef __ASM_CSKY_MMU_CONTEXT_H 5#define __ASM_CSKY_MMU_CONTEXT_H 6 7#include <asm-generic/mm_hooks.h> 8#include <asm/setup.h> 9#include <asm/page.h> 10#include <asm/cacheflush.h> 11#include <asm/tlbflush.h> 12 13#include <linux/errno.h> 14#include <linux/sched.h> 15#include <abi/ckmmu.h> 16 17#define TLBMISS_HANDLER_SETUP_PGD(pgd) \ 18 setup_pgd(__pa(pgd), false) 19#define TLBMISS_HANDLER_SETUP_PGD_KERNEL(pgd) \ 20 setup_pgd(__pa(pgd), true) 21 22#define cpu_context(cpu, mm) ((mm)->context.asid[cpu]) 23#define cpu_asid(cpu, mm) (cpu_context((cpu), (mm)) & ASID_MASK) 24#define asid_cache(cpu) (cpu_data[cpu].asid_cache) 25 26#define ASID_FIRST_VERSION (1 << CONFIG_CPU_ASID_BITS) 27#define ASID_INC 0x1 28#define ASID_MASK (ASID_FIRST_VERSION - 1) 29#define ASID_VERSION_MASK ~ASID_MASK 30 31#define destroy_context(mm) do {} while (0) 32#define enter_lazy_tlb(mm, tsk) do {} while (0) 33#define deactivate_mm(tsk, mm) do {} while (0) 34 35/* 36 * All unused by hardware upper bits will be considered 37 * as a software asid extension. 38 */ 39static inline void 40get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) 41{ 42 unsigned long asid = asid_cache(cpu); 43 44 asid += ASID_INC; 45 if (!(asid & ASID_MASK)) { 46 flush_tlb_all(); /* start new asid cycle */ 47 if (!asid) /* fix version if needed */ 48 asid = ASID_FIRST_VERSION; 49 } 50 cpu_context(cpu, mm) = asid_cache(cpu) = asid; 51} 52 53/* 54 * Initialize the context related info for a new mm_struct 55 * instance. 56 */ 57static inline int 58init_new_context(struct task_struct *tsk, struct mm_struct *mm) 59{ 60 int i; 61 62 for_each_online_cpu(i) 63 cpu_context(i, mm) = 0; 64 return 0; 65} 66 67static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, 68 struct task_struct *tsk) 69{ 70 unsigned int cpu = smp_processor_id(); 71 unsigned long flags; 72 73 local_irq_save(flags); 74 /* Check if our ASID is of an older version and thus invalid */ 75 if ((cpu_context(cpu, next) ^ asid_cache(cpu)) & ASID_VERSION_MASK) 76 get_new_mmu_context(next, cpu); 77 write_mmu_entryhi(cpu_asid(cpu, next)); 78 TLBMISS_HANDLER_SETUP_PGD(next->pgd); 79 80 /* 81 * Mark current->active_mm as not "active" anymore. 82 * We don't want to mislead possible IPI tlb flush routines. 83 */ 84 cpumask_clear_cpu(cpu, mm_cpumask(prev)); 85 cpumask_set_cpu(cpu, mm_cpumask(next)); 86 87 local_irq_restore(flags); 88} 89 90/* 91 * After we have set current->mm to a new value, this activates 92 * the context for the new mm so we see the new mappings. 93 */ 94static inline void 95activate_mm(struct mm_struct *prev, struct mm_struct *next) 96{ 97 unsigned long flags; 98 int cpu = smp_processor_id(); 99 100 local_irq_save(flags); 101 102 /* Unconditionally get a new ASID. */ 103 get_new_mmu_context(next, cpu); 104 105 write_mmu_entryhi(cpu_asid(cpu, next)); 106 TLBMISS_HANDLER_SETUP_PGD(next->pgd); 107 108 /* mark mmu ownership change */ 109 cpumask_clear_cpu(cpu, mm_cpumask(prev)); 110 cpumask_set_cpu(cpu, mm_cpumask(next)); 111 112 local_irq_restore(flags); 113} 114 115/* 116 * If mm is currently active_mm, we can't really drop it. Instead, 117 * we will get a new one for it. 118 */ 119static inline void 120drop_mmu_context(struct mm_struct *mm, unsigned int cpu) 121{ 122 unsigned long flags; 123 124 local_irq_save(flags); 125 126 if (cpumask_test_cpu(cpu, mm_cpumask(mm))) { 127 get_new_mmu_context(mm, cpu); 128 write_mmu_entryhi(cpu_asid(cpu, mm)); 129 } else { 130 /* will get a new context next time */ 131 cpu_context(cpu, mm) = 0; 132 } 133 134 local_irq_restore(flags); 135} 136 137#endif /* __ASM_CSKY_MMU_CONTEXT_H */