0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/mm.h>
0009 #include <linux/cpu.h>
0010 #include <linux/sched/mm.h>
0011
0012 #include <asm/mmu_context.h>
0013 #include <asm/pgalloc.h>
0014
0015 #if defined(CONFIG_PPC32)
0016 static inline void switch_mm_pgdir(struct task_struct *tsk,
0017 struct mm_struct *mm)
0018 {
0019
0020 tsk->thread.pgdir = mm->pgd;
0021 #ifdef CONFIG_PPC_BOOK3S_32
0022 tsk->thread.sr0 = mm->context.sr0;
0023 #endif
0024 #if defined(CONFIG_BOOKE_OR_40x) && defined(CONFIG_PPC_KUAP)
0025 tsk->thread.pid = mm->context.id;
0026 #endif
0027 }
0028 #elif defined(CONFIG_PPC_BOOK3E_64)
0029 static inline void switch_mm_pgdir(struct task_struct *tsk,
0030 struct mm_struct *mm)
0031 {
0032
0033 get_paca()->pgd = mm->pgd;
0034 #ifdef CONFIG_PPC_KUAP
0035 tsk->thread.pid = mm->context.id;
0036 #endif
0037 }
0038 #else
0039 static inline void switch_mm_pgdir(struct task_struct *tsk,
0040 struct mm_struct *mm) { }
0041 #endif
0042
0043 void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
0044 struct task_struct *tsk)
0045 {
0046 bool new_on_cpu = false;
0047
0048
0049 if (!cpumask_test_cpu(smp_processor_id(), mm_cpumask(next))) {
0050 cpumask_set_cpu(smp_processor_id(), mm_cpumask(next));
0051 inc_mm_active_cpus(next);
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076 smp_mb();
0077
0078 new_on_cpu = true;
0079 }
0080
0081
0082 switch_mm_pgdir(tsk, next);
0083
0084
0085 if (prev == next)
0086 return;
0087
0088
0089
0090
0091
0092 if (cpu_has_feature(CPU_FTR_ALTIVEC))
0093 asm volatile (PPC_DSSALL);
0094
0095 if (!new_on_cpu)
0096 membarrier_arch_switch_mm(prev, next, tsk);
0097
0098
0099
0100
0101
0102 switch_mmu_context(prev, next, tsk);
0103 }
0104
0105 #ifndef CONFIG_PPC_BOOK3S_64
0106 void arch_exit_mmap(struct mm_struct *mm)
0107 {
0108 void *frag = pte_frag_get(&mm->context);
0109
0110 if (frag)
0111 pte_frag_destroy(frag);
0112 }
0113 #endif