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_inuse
- pte_clear
- pte_reuse
- pmd_none
- pmd_bad
- pmd_present
- pmd_inuse
- pmd_inuse
- pmd_clear
- pmd_reuse
- pgd_none
- pgd_bad
- pgd_present
- pgd_inuse
- 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 int pte_inuse(pte_t *ptep) { return mem_map[MAP_NR(ptep)].reserved || mem_map[MAP_NR(ptep)].count != 1; }
292 extern inline void pte_clear(pte_t *ptep) { pte_val(*ptep) = 0; }
293 extern inline void pte_reuse(pte_t * ptep)
294 {
295 if (!mem_map[MAP_NR(ptep)].reserved)
296 mem_map[MAP_NR(ptep)].count++;
297 }
298
299 extern inline int pmd_none(pmd_t pmd) { return !pmd_val(pmd); }
300 extern inline int pmd_bad(pmd_t pmd) { return (pmd_val(pmd) & ~PAGE_MASK) != _PAGE_TABLE || pmd_val(pmd) > high_memory; }
301 extern inline int pmd_present(pmd_t pmd) { return pmd_val(pmd) & _PAGE_PRESENT; }
302 #ifdef USE_PENTIUM_MM
303 extern inline int pmd_inuse(pmd_t *pmdp) { return (pmd_val(*pmdp) & _PAGE_4M) != 0; }
304 #else
305 extern inline int pmd_inuse(pmd_t *pmdp) { return 0; }
306 #endif
307 extern inline void pmd_clear(pmd_t * pmdp) { pmd_val(*pmdp) = 0; }
308 extern inline void pmd_reuse(pmd_t * pmdp) { }
309
310
311
312
313
314
315 extern inline int pgd_none(pgd_t pgd) { return 0; }
316 extern inline int pgd_bad(pgd_t pgd) { return 0; }
317 extern inline int pgd_present(pgd_t pgd) { return 1; }
318 extern inline int pgd_inuse(pgd_t * pgdp) { return mem_map[MAP_NR(pgdp)].reserved; }
319 extern inline void pgd_clear(pgd_t * pgdp) { }
320
321
322
323
324
325 extern inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_USER; }
326 extern inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; }
327 extern inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_USER; }
328 extern inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
329 extern inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
330
331 extern inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_RW; return pte; }
332 extern inline pte_t pte_rdprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_USER; return pte; }
333 extern inline pte_t pte_exprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_USER; return pte; }
334 extern inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~_PAGE_DIRTY; return pte; }
335 extern inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
336 extern inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_RW; return pte; }
337 extern inline pte_t pte_mkread(pte_t pte) { pte_val(pte) |= _PAGE_USER; return pte; }
338 extern inline pte_t pte_mkexec(pte_t pte) { pte_val(pte) |= _PAGE_USER; return pte; }
339 extern inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_DIRTY; return pte; }
340 extern inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; return pte; }
341
342
343
344
345
346 extern inline pte_t mk_pte(unsigned long page, pgprot_t pgprot)
347 { pte_t pte; pte_val(pte) = page | pgprot_val(pgprot); return pte; }
348
349 extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
350 { pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
351
352 extern inline unsigned long pte_page(pte_t pte)
353 { return pte_val(pte) & PAGE_MASK; }
354
355 extern inline unsigned long pmd_page(pmd_t pmd)
356 { return pmd_val(pmd) & PAGE_MASK; }
357
358
359 extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
360 {
361 return mm->pgd + (address >> PGDIR_SHIFT);
362 }
363
364
365 extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
366 {
367 return (pmd_t *) dir;
368 }
369
370
371 extern inline pte_t * pte_offset(pmd_t * dir, unsigned long address)
372 {
373 return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
374 }
375
376
377
378
379
380
381 extern inline void pte_free_kernel(pte_t * pte)
382 {
383 mem_map[MAP_NR(pte)].reserved = 0;
384 free_page((unsigned long) pte);
385 }
386
387 extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address)
388 {
389 address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
390 if (pmd_none(*pmd)) {
391 pte_t * page = (pte_t *) get_free_page(GFP_KERNEL);
392 if (pmd_none(*pmd)) {
393 if (page) {
394 pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) page;
395 mem_map[MAP_NR(page)].reserved = 1;
396 return page + address;
397 }
398 pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
399 return NULL;
400 }
401 free_page((unsigned long) page);
402 }
403 if (pmd_bad(*pmd)) {
404 printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
405 pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
406 return NULL;
407 }
408 return (pte_t *) pmd_page(*pmd) + address;
409 }
410
411
412
413
414
415 extern inline void pmd_free_kernel(pmd_t * pmd)
416 {
417 pmd_val(*pmd) = 0;
418 }
419
420 extern inline pmd_t * pmd_alloc_kernel(pgd_t * pgd, unsigned long address)
421 {
422 return (pmd_t *) pgd;
423 }
424
425 extern inline void pte_free(pte_t * pte)
426 {
427 free_page((unsigned long) pte);
428 }
429
430 extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address)
431 {
432 address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
433 if (pmd_none(*pmd)) {
434 pte_t * page = (pte_t *) get_free_page(GFP_KERNEL);
435 if (pmd_none(*pmd)) {
436 if (page) {
437 pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) page;
438 return page + address;
439 }
440 pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
441 return NULL;
442 }
443 free_page((unsigned long) page);
444 }
445 if (pmd_bad(*pmd)) {
446 printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
447 pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
448 return NULL;
449 }
450 return (pte_t *) pmd_page(*pmd) + address;
451 }
452
453
454
455
456
457 extern inline void pmd_free(pmd_t * pmd)
458 {
459 pmd_val(*pmd) = 0;
460 }
461
462 extern inline pmd_t * pmd_alloc(pgd_t * pgd, unsigned long address)
463 {
464 return (pmd_t *) pgd;
465 }
466
467 extern inline void pgd_free(pgd_t * pgd)
468 {
469 free_page((unsigned long) pgd);
470 }
471
472 extern inline pgd_t * pgd_alloc(void)
473 {
474 return (pgd_t *) get_free_page(GFP_KERNEL);
475 }
476
477 extern pgd_t swapper_pg_dir[1024];
478
479
480
481
482
483 extern inline void update_mmu_cache(struct vm_area_struct * vma,
484 unsigned long address, pte_t pte)
485 {
486 }
487
488 #define SWP_TYPE(entry) (((entry) >> 1) & 0x7f)
489 #define SWP_OFFSET(entry) ((entry) >> 8)
490 #define SWP_ENTRY(type,offset) (((type) << 1) | ((offset) << 8))
491
492 #endif