1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef __PARISC_MMU_CONTEXT_H
3 #define __PARISC_MMU_CONTEXT_H
4 
5 #include <linux/mm.h>
6 #include <linux/sched.h>
7 #include <linux/atomic.h>
8 #include <asm-generic/mm_hooks.h>
9 
10 static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
11 {
12 }
13 
14 /* on PA-RISC, we actually have enough contexts to justify an allocator
15  * for them.  prumpf */
16 
17 extern unsigned long alloc_sid(void);
18 extern void free_sid(unsigned long);
19 
20 static inline int
21 init_new_context(struct task_struct *tsk, struct mm_struct *mm)
22 {
23 	BUG_ON(atomic_read(&mm->mm_users) != 1);
24 
25 	mm->context = alloc_sid();
26 	return 0;
27 }
28 
29 static inline void
30 destroy_context(struct mm_struct *mm)
31 {
32 	free_sid(mm->context);
33 	mm->context = 0;
34 }
35 
36 static inline unsigned long __space_to_prot(mm_context_t context)
37 {
38 #if SPACEID_SHIFT == 0
39 	return context << 1;
40 #else
41 	return context >> (SPACEID_SHIFT - 1);
42 #endif
43 }
44 
45 static inline void load_context(mm_context_t context)
46 {
47 	mtsp(context, 3);
48 	mtctl(__space_to_prot(context), 8);
49 }
50 
51 static inline void switch_mm_irqs_off(struct mm_struct *prev,
52 		struct mm_struct *next, struct task_struct *tsk)
53 {
54 	if (prev != next) {
55 		mtctl(__pa(next->pgd), 25);
56 		load_context(next->context);
57 	}
58 }
59 
60 static inline void switch_mm(struct mm_struct *prev,
61 		struct mm_struct *next, struct task_struct *tsk)
62 {
63 	unsigned long flags;
64 
65 	if (prev == next)
66 		return;
67 
68 	local_irq_save(flags);
69 	switch_mm_irqs_off(prev, next, tsk);
70 	local_irq_restore(flags);
71 }
72 #define switch_mm_irqs_off switch_mm_irqs_off
73 
74 #define deactivate_mm(tsk,mm)	do { } while (0)
75 
76 static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next)
77 {
78 	/*
79 	 * Activate_mm is our one chance to allocate a space id
80 	 * for a new mm created in the exec path. There's also
81 	 * some lazy tlb stuff, which is currently dead code, but
82 	 * we only allocate a space id if one hasn't been allocated
83 	 * already, so we should be OK.
84 	 */
85 
86 	BUG_ON(next == &init_mm); /* Should never happen */
87 
88 	if (next->context == 0)
89 	    next->context = alloc_sid();
90 
91 	switch_mm(prev,next,current);
92 }
93 #endif
94