This source file includes following definitions.
- invalidate_mm
- invalidate_page
- invalidate_range
- invalidate_current_task
- invalidate_mm
- invalidate_page
- invalidate_range
- invalidate_mm
- invalidate_page
- invalidate_range
- pte_none
- pte_present
- pte_clear
- pmd_none
- pmd_bad
- pmd_present
- pmd_clear
- pgd_none
- pgd_bad
- pgd_present
- pgd_clear
- pte_read
- pte_write
- pte_exec
- pte_dirty
- pte_young
- pte_wrprotect
- pte_rdprotect
- pte_exprotect
- pte_mkclean
- pte_mkold
- pte_mkwrite
- pte_mkread
- pte_mkexec
- pte_mkdirty
- pte_mkyoung
- mk_pte
- pte_modify
- pte_page
- pmd_page
- pgd_offset
- pmd_offset
- pte_offset
- pte_free_kernel
- pte_alloc_kernel
- pmd_free_kernel
- pmd_alloc_kernel
- pte_free
- pte_alloc
- pmd_free
- pmd_alloc
- pgd_free
- pgd_alloc
- update_mmu_cache
1 #ifndef _I386_PGTABLE_H
2 #define _I386_PGTABLE_H
3
4 #include <linux/config.h>
5
6
7
8
9
10 #define USE_PENTIUM_MM 1
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 #define __invalidate() \
36 __asm__ __volatile__("movl %%cr3,%%eax\n\tmovl %%eax,%%cr3": : :"ax")
37
38 #ifdef CONFIG_M386
39 #define __invalidate_one(addr) invalidate()
40 #else
41 #define __invalidate_one(addr) \
42 __asm__ __volatile__("invlpg %0": :"m" (*(char *) addr))
43 #endif
44
45 #ifndef __SMP__
46
47 #define invalidate() __invalidate()
48 #define invalidate_all() __invalidate()
49
50 static inline void invalidate_mm(struct mm_struct *mm)
51 {
52 if (mm == current->mm)
53 __invalidate();
54 }
55
56 static inline void invalidate_page(struct vm_area_struct *vma,
57 unsigned long addr)
58 {
59 if (vma->vm_mm == current->mm)
60 __invalidate_one(addr);
61 }
62
63 static inline void invalidate_range(struct mm_struct *mm,
64 unsigned long start, unsigned long end)
65 {
66 if (mm == current->mm)
67 __invalidate();
68 }
69
70 #else
71
72
73
74
75
76
77 #include <asm/smp.h>
78
79 #define local_invalidate() \
80 __invalidate()
81
82
83 #undef CLEVER_SMP_INVALIDATE
84 #ifdef CLEVER_SMP_INVALIDATE
85
86
87
88
89
90
91
92
93
94
95
96
97 static inline void invalidate_current_task(void)
98 {
99 if (current->mm->count == 1)
100 local_invalidate();
101 else
102 smp_invalidate();
103 }
104
105 #define invalidate() invalidate_current_task()
106
107 #define invalidate_all() smp_invalidate()
108
109 static inline void invalidate_mm(struct mm_struct * mm)
110 {
111 if (mm == current->mm && mm->count == 1)
112 local_invalidate();
113 else
114 smp_invalidate();
115 }
116
117 static inline void invalidate_page(struct vm_area_struct * vma,
118 unsigned long va)
119 {
120 if (vma->vm_mm == current->mm && current->mm->count == 1)
121 __invalidate_one(va);
122 else
123 smp_invalidate();
124 }
125
126 static inline void invalidate_range(struct mm_struct * mm,
127 unsigned long start, unsigned long end)
128 {
129 invalidate_mm(mm);
130 }
131
132
133 #else
134
135 #define invalidate() \
136 smp_invalidate()
137
138 #define invalidate_all() invalidate()
139
140 static inline void invalidate_mm(struct mm_struct *mm)
141 {
142 invalidate();
143 }
144
145 static inline void invalidate_page(struct vm_area_struct *vma,
146 unsigned long addr)
147 {
148 invalidate();
149 }
150
151 static inline void invalidate_range(struct mm_struct *mm,
152 unsigned long start, unsigned long end)
153 {
154 invalidate();
155 }
156 #endif
157 #endif
158
159
160
161
162
163
164 #define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval))
165
166
167 #define PMD_SHIFT 22
168 #define PMD_SIZE (1UL << PMD_SHIFT)
169 #define PMD_MASK (~(PMD_SIZE-1))
170
171
172 #define PGDIR_SHIFT 22
173 #define PGDIR_SIZE (1UL << PGDIR_SHIFT)
174 #define PGDIR_MASK (~(PGDIR_SIZE-1))
175
176
177
178
179
180 #define PTRS_PER_PTE 1024
181 #define PTRS_PER_PMD 1
182 #define PTRS_PER_PGD 1024
183
184
185
186
187
188
189
190
191 #define VMALLOC_OFFSET (8*1024*1024)
192 #define VMALLOC_START ((high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
193 #define VMALLOC_VMADDR(x) (TASK_SIZE + (unsigned long)(x))
194
195
196
197
198
199
200
201
202 #define _PAGE_PRESENT 0x001
203 #define _PAGE_RW 0x002
204 #define _PAGE_USER 0x004
205 #define _PAGE_PCD 0x010
206 #define _PAGE_ACCESSED 0x020
207 #define _PAGE_DIRTY 0x040
208 #define _PAGE_4M 0x080
209
210 #define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
211 #define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
212
213 #define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
214 #define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
215 #define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
216 #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
217 #define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
218
219
220
221
222
223 #define __P000 PAGE_NONE
224 #define __P001 PAGE_READONLY
225 #define __P010 PAGE_COPY
226 #define __P011 PAGE_COPY
227 #define __P100 PAGE_READONLY
228 #define __P101 PAGE_READONLY
229 #define __P110 PAGE_COPY
230 #define __P111 PAGE_COPY
231
232 #define __S000 PAGE_NONE
233 #define __S001 PAGE_READONLY
234 #define __S010 PAGE_SHARED
235 #define __S011 PAGE_SHARED
236 #define __S100 PAGE_READONLY
237 #define __S101 PAGE_READONLY
238 #define __S110 PAGE_SHARED
239 #define __S111 PAGE_SHARED
240
241
242
243
244
245
246 #undef TEST_VERIFY_AREA
247
248
249 extern unsigned long pg0[1024];
250
251 extern unsigned long empty_zero_page[1024];
252
253
254
255
256
257
258
259
260 extern pte_t __bad_page(void);
261 extern pte_t * __bad_pagetable(void);
262
263 #define BAD_PAGETABLE __bad_pagetable()
264 #define BAD_PAGE __bad_page()
265 #define ZERO_PAGE ((unsigned long) empty_zero_page)
266
267
268 #define BITS_PER_PTR (8*sizeof(unsigned long))
269
270
271 #define PTR_MASK (~(sizeof(void*)-1))
272
273
274
275 #define SIZEOF_PTR_LOG2 2
276
277
278 #define PAGE_PTR(address) \
279 ((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
280
281
282 #define SET_PAGE_DIR(tsk,pgdir) \
283 do { \
284 (tsk)->tss.cr3 = (unsigned long) (pgdir); \
285 if ((tsk) == current) \
286 __asm__ __volatile__("movl %0,%%cr3": :"a" ((tsk)->tss.cr3)); \
287 } while (0)
288
289 extern inline int pte_none(pte_t pte) { return !pte_val(pte); }
290 extern inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_PRESENT; }
291 extern inline void pte_clear(pte_t *ptep) { pte_val(*ptep) = 0; }
292
293 extern inline int pmd_none(pmd_t pmd) { return !pmd_val(pmd); }
294 extern inline int pmd_bad(pmd_t pmd) { return (pmd_val(pmd) & ~PAGE_MASK) != _PAGE_TABLE || pmd_val(pmd) > high_memory; }
295 extern inline int pmd_present(pmd_t pmd) { return pmd_val(pmd) & _PAGE_PRESENT; }
296 extern inline void pmd_clear(pmd_t * pmdp) { pmd_val(*pmdp) = 0; }
297
298
299
300
301
302
303 extern inline int pgd_none(pgd_t pgd) { return 0; }
304 extern inline int pgd_bad(pgd_t pgd) { return 0; }
305 extern inline int pgd_present(pgd_t pgd) { return 1; }
306 extern inline void pgd_clear(pgd_t * pgdp) { }
307
308
309
310
311
312 extern inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_USER; }
313 extern inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; }
314 extern inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_USER; }
315 extern inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
316 extern inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
317
318 extern inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_RW; return pte; }
319 extern inline pte_t pte_rdprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_USER; return pte; }
320 extern inline pte_t pte_exprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_USER; return pte; }
321 extern inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~_PAGE_DIRTY; return pte; }
322 extern inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
323 extern inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_RW; return pte; }
324 extern inline pte_t pte_mkread(pte_t pte) { pte_val(pte) |= _PAGE_USER; return pte; }
325 extern inline pte_t pte_mkexec(pte_t pte) { pte_val(pte) |= _PAGE_USER; return pte; }
326 extern inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_DIRTY; return pte; }
327 extern inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; return pte; }
328
329
330
331
332
333 extern inline pte_t mk_pte(unsigned long page, pgprot_t pgprot)
334 { pte_t pte; pte_val(pte) = page | pgprot_val(pgprot); return pte; }
335
336 extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
337 { pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
338
339 extern inline unsigned long pte_page(pte_t pte)
340 { return pte_val(pte) & PAGE_MASK; }
341
342 extern inline unsigned long pmd_page(pmd_t pmd)
343 { return pmd_val(pmd) & PAGE_MASK; }
344
345
346 extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
347 {
348 return mm->pgd + (address >> PGDIR_SHIFT);
349 }
350
351
352 extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
353 {
354 return (pmd_t *) dir;
355 }
356
357
358 extern inline pte_t * pte_offset(pmd_t * dir, unsigned long address)
359 {
360 return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
361 }
362
363
364
365
366
367
368 extern inline void pte_free_kernel(pte_t * pte)
369 {
370 free_page((unsigned long) pte);
371 }
372
373 extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address)
374 {
375 address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
376 if (pmd_none(*pmd)) {
377 pte_t * page = (pte_t *) get_free_page(GFP_KERNEL);
378 if (pmd_none(*pmd)) {
379 if (page) {
380 pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) page;
381 return page + address;
382 }
383 pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
384 return NULL;
385 }
386 free_page((unsigned long) page);
387 }
388 if (pmd_bad(*pmd)) {
389 printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
390 pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
391 return NULL;
392 }
393 return (pte_t *) pmd_page(*pmd) + address;
394 }
395
396
397
398
399
400 extern inline void pmd_free_kernel(pmd_t * pmd)
401 {
402 pmd_val(*pmd) = 0;
403 }
404
405 extern inline pmd_t * pmd_alloc_kernel(pgd_t * pgd, unsigned long address)
406 {
407 return (pmd_t *) pgd;
408 }
409
410 extern inline void pte_free(pte_t * pte)
411 {
412 free_page((unsigned long) pte);
413 }
414
415 extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address)
416 {
417 address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
418 if (pmd_none(*pmd)) {
419 pte_t * page = (pte_t *) get_free_page(GFP_KERNEL);
420 if (pmd_none(*pmd)) {
421 if (page) {
422 pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) page;
423 return page + address;
424 }
425 pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
426 return NULL;
427 }
428 free_page((unsigned long) page);
429 }
430 if (pmd_bad(*pmd)) {
431 printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
432 pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
433 return NULL;
434 }
435 return (pte_t *) pmd_page(*pmd) + address;
436 }
437
438
439
440
441
442 extern inline void pmd_free(pmd_t * pmd)
443 {
444 pmd_val(*pmd) = 0;
445 }
446
447 extern inline pmd_t * pmd_alloc(pgd_t * pgd, unsigned long address)
448 {
449 return (pmd_t *) pgd;
450 }
451
452 extern inline void pgd_free(pgd_t * pgd)
453 {
454 free_page((unsigned long) pgd);
455 }
456
457 extern inline pgd_t * pgd_alloc(void)
458 {
459 return (pgd_t *) get_free_page(GFP_KERNEL);
460 }
461
462 extern pgd_t swapper_pg_dir[1024];
463
464
465
466
467
468 extern inline void update_mmu_cache(struct vm_area_struct * vma,
469 unsigned long address, pte_t pte)
470 {
471 }
472
473 #define SWP_TYPE(entry) (((entry) >> 1) & 0x7f)
474 #define SWP_OFFSET(entry) ((entry) >> 8)
475 #define SWP_ENTRY(type,offset) (((type) << 1) | ((offset) << 8))
476
477 #endif