aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-ia64/mmu_context.h
diff options
context:
space:
mode:
authorTony Luck <tony.luck@intel.com>2008-08-01 13:13:32 -0400
committerTony Luck <tony.luck@intel.com>2008-08-01 13:21:21 -0400
commit7f30491ccd28627742e37899453ae20e3da8e18f (patch)
tree7291c0a26ed3a31acf9542857af3981d278f5de8 /include/asm-ia64/mmu_context.h
parent94ad374a0751f40d25e22e036c37f7263569d24c (diff)
[IA64] Move include/asm-ia64 to arch/ia64/include/asm
After moving the the include files there were a few clean-ups: 1) Some files used #include <asm-ia64/xyz.h>, changed to <asm/xyz.h> 2) Some comments alerted maintainers to look at various header files to make matching updates if certain code were to be changed. Updated these comments to use the new include paths. 3) Some header files mentioned their own names in initial comments. Just deleted these self references. Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'include/asm-ia64/mmu_context.h')
-rw-r--r--include/asm-ia64/mmu_context.h198
1 files changed, 0 insertions, 198 deletions
diff --git a/include/asm-ia64/mmu_context.h b/include/asm-ia64/mmu_context.h
deleted file mode 100644
index 040bc87db930..000000000000
--- a/include/asm-ia64/mmu_context.h
+++ /dev/null
@@ -1,198 +0,0 @@
1#ifndef _ASM_IA64_MMU_CONTEXT_H
2#define _ASM_IA64_MMU_CONTEXT_H
3
4/*
5 * Copyright (C) 1998-2002 Hewlett-Packard Co
6 * David Mosberger-Tang <davidm@hpl.hp.com>
7 */
8
9/*
10 * Routines to manage the allocation of task context numbers. Task context
11 * numbers are used to reduce or eliminate the need to perform TLB flushes
12 * due to context switches. Context numbers are implemented using ia-64
13 * region ids. Since the IA-64 TLB does not consider the region number when
14 * performing a TLB lookup, we need to assign a unique region id to each
15 * region in a process. We use the least significant three bits in aregion
16 * id for this purpose.
17 */
18
19#define IA64_REGION_ID_KERNEL 0 /* the kernel's region id (tlb.c depends on this being 0) */
20
21#define ia64_rid(ctx,addr) (((ctx) << 3) | (addr >> 61))
22
23# include <asm/page.h>
24# ifndef __ASSEMBLY__
25
26#include <linux/compiler.h>
27#include <linux/percpu.h>
28#include <linux/sched.h>
29#include <linux/spinlock.h>
30
31#include <asm/processor.h>
32#include <asm-generic/mm_hooks.h>
33
34struct ia64_ctx {
35 spinlock_t lock;
36 unsigned int next; /* next context number to use */
37 unsigned int limit; /* available free range */
38 unsigned int max_ctx; /* max. context value supported by all CPUs */
39 /* call wrap_mmu_context when next >= max */
40 unsigned long *bitmap; /* bitmap size is max_ctx+1 */
41 unsigned long *flushmap;/* pending rid to be flushed */
42};
43
44extern struct ia64_ctx ia64_ctx;
45DECLARE_PER_CPU(u8, ia64_need_tlb_flush);
46
47extern void mmu_context_init (void);
48extern void wrap_mmu_context (struct mm_struct *mm);
49
50static inline void
51enter_lazy_tlb (struct mm_struct *mm, struct task_struct *tsk)
52{
53}
54
55/*
56 * When the context counter wraps around all TLBs need to be flushed because
57 * an old context number might have been reused. This is signalled by the
58 * ia64_need_tlb_flush per-CPU variable, which is checked in the routine
59 * below. Called by activate_mm(). <efocht@ess.nec.de>
60 */
61static inline void
62delayed_tlb_flush (void)
63{
64 extern void local_flush_tlb_all (void);
65 unsigned long flags;
66
67 if (unlikely(__ia64_per_cpu_var(ia64_need_tlb_flush))) {
68 spin_lock_irqsave(&ia64_ctx.lock, flags);
69 if (__ia64_per_cpu_var(ia64_need_tlb_flush)) {
70 local_flush_tlb_all();
71 __ia64_per_cpu_var(ia64_need_tlb_flush) = 0;
72 }
73 spin_unlock_irqrestore(&ia64_ctx.lock, flags);
74 }
75}
76
77static inline nv_mm_context_t
78get_mmu_context (struct mm_struct *mm)
79{
80 unsigned long flags;
81 nv_mm_context_t context = mm->context;
82
83 if (likely(context))
84 goto out;
85
86 spin_lock_irqsave(&ia64_ctx.lock, flags);
87 /* re-check, now that we've got the lock: */
88 context = mm->context;
89 if (context == 0) {
90 cpus_clear(mm->cpu_vm_mask);
91 if (ia64_ctx.next >= ia64_ctx.limit) {
92 ia64_ctx.next = find_next_zero_bit(ia64_ctx.bitmap,
93 ia64_ctx.max_ctx, ia64_ctx.next);
94 ia64_ctx.limit = find_next_bit(ia64_ctx.bitmap,
95 ia64_ctx.max_ctx, ia64_ctx.next);
96 if (ia64_ctx.next >= ia64_ctx.max_ctx)
97 wrap_mmu_context(mm);
98 }
99 mm->context = context = ia64_ctx.next++;
100 __set_bit(context, ia64_ctx.bitmap);
101 }
102 spin_unlock_irqrestore(&ia64_ctx.lock, flags);
103out:
104 /*
105 * Ensure we're not starting to use "context" before any old
106 * uses of it are gone from our TLB.
107 */
108 delayed_tlb_flush();
109
110 return context;
111}
112
113/*
114 * Initialize context number to some sane value. MM is guaranteed to be a
115 * brand-new address-space, so no TLB flushing is needed, ever.
116 */
117static inline int
118init_new_context (struct task_struct *p, struct mm_struct *mm)
119{
120 mm->context = 0;
121 return 0;
122}
123
124static inline void
125destroy_context (struct mm_struct *mm)
126{
127 /* Nothing to do. */
128}
129
130static inline void
131reload_context (nv_mm_context_t context)
132{
133 unsigned long rid;
134 unsigned long rid_incr = 0;
135 unsigned long rr0, rr1, rr2, rr3, rr4, old_rr4;
136
137 old_rr4 = ia64_get_rr(RGN_BASE(RGN_HPAGE));
138 rid = context << 3; /* make space for encoding the region number */
139 rid_incr = 1 << 8;
140
141 /* encode the region id, preferred page size, and VHPT enable bit: */
142 rr0 = (rid << 8) | (PAGE_SHIFT << 2) | 1;
143 rr1 = rr0 + 1*rid_incr;
144 rr2 = rr0 + 2*rid_incr;
145 rr3 = rr0 + 3*rid_incr;
146 rr4 = rr0 + 4*rid_incr;
147#ifdef CONFIG_HUGETLB_PAGE
148 rr4 = (rr4 & (~(0xfcUL))) | (old_rr4 & 0xfc);
149
150# if RGN_HPAGE != 4
151# error "reload_context assumes RGN_HPAGE is 4"
152# endif
153#endif
154
155 ia64_set_rr0_to_rr4(rr0, rr1, rr2, rr3, rr4);
156 ia64_srlz_i(); /* srlz.i implies srlz.d */
157}
158
159/*
160 * Must be called with preemption off
161 */
162static inline void
163activate_context (struct mm_struct *mm)
164{
165 nv_mm_context_t context;
166
167 do {
168 context = get_mmu_context(mm);
169 if (!cpu_isset(smp_processor_id(), mm->cpu_vm_mask))
170 cpu_set(smp_processor_id(), mm->cpu_vm_mask);
171 reload_context(context);
172 /*
173 * in the unlikely event of a TLB-flush by another thread,
174 * redo the load.
175 */
176 } while (unlikely(context != mm->context));
177}
178
179#define deactivate_mm(tsk,mm) do { } while (0)
180
181/*
182 * Switch from address space PREV to address space NEXT.
183 */
184static inline void
185activate_mm (struct mm_struct *prev, struct mm_struct *next)
186{
187 /*
188 * We may get interrupts here, but that's OK because interrupt
189 * handlers cannot touch user-space.
190 */
191 ia64_set_kr(IA64_KR_PT_BASE, __pa(next->pgd));
192 activate_context(next);
193}
194
195#define switch_mm(prev_mm,next_mm,next_task) activate_mm(prev_mm, next_mm)
196
197# endif /* ! __ASSEMBLY__ */
198#endif /* _ASM_IA64_MMU_CONTEXT_H */