a82c6f0c9d1531583a0b36dbc1aaaf3470107ed6
[akaros.git] / kern / arch / x86 / pmap64.c
1 /* Copyright (c) 2013 The Regents of the University of California
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * See LICENSE for details.
4  *
5  * 64 bit virtual memory / address space management (and a touch of pmem).
6  *
7  * TODO:
8  * - better testing: check my helper funcs, a variety of inserts/segments remove
9  * it all, etc (esp with jumbos).  check permissions and the existence of
10  * mappings.
11  * - mapping segments doesn't support having a PTE already present
12  * - mtrrs break big machines
13  * - jumbo pages are only supported at the VM layer, not PM (a jumbo is 2^9
14  * little pages, for example)
15  * - usermemwalk and freeing might need some help (in higher layers of the
16  * kernel). */
17
18 #include <arch/x86.h>
19 #include <arch/arch.h>
20 #include <arch/mmu.h>
21 #include <arch/apic.h>
22 #include <error.h>
23 #include <sys/queue.h>
24 #include <atomic.h>
25 #include <string.h>
26 #include <assert.h>
27 #include <pmap.h>
28 #include <kclock.h>
29 #include <env.h>
30 #include <stdio.h>
31 #include <kmalloc.h>
32 #include <page_alloc.h>
33
34 extern char boot_pml4[], gdt64[], gdt64desc[];
35 pgdir_t boot_pgdir;
36 physaddr_t boot_cr3;
37 segdesc_t *gdt;
38 pseudodesc_t gdt_pd;
39
40 #define PG_WALK_SHIFT_MASK              0x00ff          /* first byte = target shift */
41 #define PG_WALK_CREATE                  0x0100
42
43 kpte_t *pml_walk(kpte_t *pml, uintptr_t va, int flags);
44 void map_segment(pgdir_t pgdir, uintptr_t va, size_t size, physaddr_t pa,
45                  int perm, int pml_shift);
46 typedef int (*kpte_cb_t)(kpte_t *kpte, uintptr_t kva, int pml_shift,
47                         bool visited_subs, void *arg);
48 int pml_for_each(kpte_t *pml, uintptr_t start, size_t len, kpte_cb_t callback,
49                  void *arg);
50 int unmap_segment(pgdir_t pgdir, uintptr_t va, size_t size);
51
52 /* Helper: gets the kpte_t pointer which is the base of the PML4 from pgdir */
53 static kpte_t *pgdir_get_kpt(pgdir_t pgdir)
54 {
55         return pgdir.kpte;
56 }
57
58 /* Helper: returns true if we do not need to walk the page table any further.
59  *
60  * The caller may or may not know if a jumbo is desired.  pml_shift determines
61  * which layer we are at in the page walk, and flags contains the target level
62  * we're looking for, like a jumbo or a default.
63  *
64  * Regardless of the desired target, if we find a jumbo page, we're also done.
65  */
66 static bool walk_is_complete(kpte_t *kpte, int pml_shift, int flags)
67 {
68         if ((pml_shift == (flags & PG_WALK_SHIFT_MASK)) || (*kpte & PTE_PS))
69                 return TRUE;
70         return FALSE;
71 }
72
73 /* PTE_ADDR should only be used on a PTE that has a physical address of the next
74  * PML inside.  i.e., not a final PTE in the page table walk. */
75 static kpte_t *kpte2pml(kpte_t kpte)
76 {
77         return (kpte_t*)KADDR(PTE_ADDR(kpte));
78 }
79
80 static kpte_t *__pml_walk(kpte_t *pml, uintptr_t va, int flags, int pml_shift)
81 {
82         kpte_t *kpte;
83         void *new_pml_kva;
84
85         kpte = &pml[PMLx(va, pml_shift)];
86         if (walk_is_complete(kpte, pml_shift, flags))
87                 return kpte;
88         if (!(*kpte & PTE_P)) {
89                 if (!(flags & PG_WALK_CREATE))
90                         return NULL;
91                 new_pml_kva = kpage_zalloc_addr();
92                 /* Might want better error handling (we're probably out of memory) */
93                 if (!new_pml_kva)
94                         return NULL;
95                 /* We insert the new PT into the PML with U and W perms.  Permissions on
96                  * page table walks are anded together (if any of them are !User, the
97                  * translation is !User).  We put the perms on the last entry, not the
98                  * intermediates. */
99                 *kpte = PADDR(new_pml_kva) | PTE_P | PTE_U | PTE_W;
100         }
101         return __pml_walk(kpte2pml(*kpte), va, flags, pml_shift - BITS_PER_PML);
102 }
103
104 /* Returns a pointer to the page table entry corresponding to va.  Flags has
105  * some options and selects which level of the page table we're happy with
106  * stopping at.  Normally, this is PML1 for a normal page (e.g. flags =
107  * PML1_SHIFT), but could be for a jumbo page (PML3 or PML2 entry).
108  *
109  * Flags also controls whether or not intermediate page tables are created or
110  * not.  This is useful for when we are checking whether or not a mapping
111  * exists, but aren't interested in creating intermediate tables that will not
112  * get filled.  When we want to create intermediate pages (i.e. we're looking
113  * for the PTE to insert a page), pass in PG_WALK_CREATE with flags.
114  *
115  * Returns 0 on error or absence of a PTE for va. */
116 kpte_t *pml_walk(kpte_t *pml, uintptr_t va, int flags)
117 {
118         return __pml_walk(pml, va, flags, PML4_SHIFT);
119 }
120
121 /* Helper: determines how much va needs to be advanced until it is aligned to
122  * pml_shift. */
123 static uintptr_t amt_til_aligned(uintptr_t va, int pml_shift)
124 {
125         /* find the lower bits of va, subtract them from the shift to see what we
126          * would need to add to get to the shift.  va might be aligned already, and
127          * we subtracted 0, so we mask off the top part again. */
128         return ((1UL << pml_shift) - (va & ((1UL << pml_shift) - 1))) &
129                ((1UL << pml_shift) - 1);
130 }
131
132 /* Helper: determines how much of size we can take, in chunks of pml_shift */
133 static uintptr_t amt_of_aligned_bytes(uintptr_t size, int pml_shift)
134 {
135         /* creates a mask all 1s from MSB down to (including) shift */
136         return (~((1UL << pml_shift) - 1)) & size;
137 }
138
139 /* Helper: Advance kpte, given old_pte.  Will do pml walks when necessary. */
140 static kpte_t *get_next_pte(kpte_t *old_pte, kpte_t *pgdir, uintptr_t va,
141                             int flags)
142 {
143         /* PTEs (undereferenced) are addresses within page tables.  so long as we
144          * stay inside the PML, we can just advance via pointer arithmetic.  if we
145          * advance old_pte and it points to the beginning of a page (offset == 0),
146          * we've looped outside of our original PML, and need to get a new one. */
147         old_pte++;
148         if (!PGOFF(old_pte))
149                 return pml_walk(pgdir, va, flags);
150         return old_pte;
151 }
152
153 /* Helper: maps pages from va to pa for size bytes, all for a given page size */
154 static void map_my_pages(kpte_t *pgdir, uintptr_t va, size_t size,
155                          physaddr_t pa, int perm, int pml_shift)
156 {
157         /* set to trigger a pml walk on the first get_next */
158         kpte_t *kpte = (kpte_t*)PGSIZE - 1;
159         size_t pgsize = 1UL << pml_shift;
160
161         for (size_t i = 0; i < size; i += pgsize, va += pgsize,
162              pa += pgsize) {
163                 kpte = get_next_pte(kpte, pgdir, va, PG_WALK_CREATE | pml_shift);
164                 assert(kpte);
165                 *kpte = PTE_ADDR(pa) | PTE_P | perm |
166                         (pml_shift != PML1_SHIFT ? PTE_PS : 0);
167                 printd("Wrote *kpte %p, for va %p to pa %p tried to cover %p\n",
168                        *kpte, va, pa, amt_mapped);
169         }
170 }
171
172 /* Maps all pages possible from va->pa, up to size, preferring to use pages of
173  * type pml_shift (size == (1 << shift)).  Assumes that it is possible to map va
174  * to pa at the given shift. */
175 static uintptr_t __map_segment(kpte_t *pgdir, uintptr_t va, size_t size,
176                                physaddr_t pa, int perm, int pml_shift)
177 {
178         printd("__map_segment, va %p, size %p, pa %p, shift %d\n", va, size,
179                pa, pml_shift);
180         uintptr_t amt_to_submap, amt_to_map, amt_mapped = 0;
181
182         amt_to_submap = amt_til_aligned(va, pml_shift);
183         amt_to_submap = MIN(amt_to_submap, size);
184         if (amt_to_submap) {
185                 amt_mapped = __map_segment(pgdir, va, amt_to_submap, pa, perm,
186                                            pml_shift - BITS_PER_PML);
187                 va += amt_mapped;
188                 pa += amt_mapped;
189                 size -= amt_mapped;
190         }
191         /* Now we're either aligned and ready to map, or size == 0 */
192         amt_to_map = amt_of_aligned_bytes(size, pml_shift);
193         if (amt_to_map) {
194                 map_my_pages(pgdir, va, amt_to_map, pa, perm, pml_shift);
195                 va += amt_to_map;
196                 pa += amt_to_map;
197                 size -= amt_to_map;
198                 amt_mapped += amt_to_map;
199         }
200         /* Map whatever is left over */
201         if (size)
202                 amt_mapped += __map_segment(pgdir, va, size, pa, perm,
203                                             pml_shift - BITS_PER_PML);
204         return amt_mapped;
205 }
206
207 /* Returns the maximum pml shift possible between a va->pa mapping.  It is the
208  * number of least-significant bits the two addresses have in common.  For
209  * instance, if the two pages are 0x456000 and 0x156000, this returns 20.  For
210  * regular pages, it will be at least 12 (every page ends in 0x000).
211  *
212  * The max pml shift possible for an va->pa mapping is determined by the
213  * least bit that differs between va and pa.
214  *
215  * We can optimize this a bit, since we know the first 12 bits are the same, and
216  * we won't go higher than max_pml_shift. */
217 static int max_possible_shift(uintptr_t va, uintptr_t pa)
218 {
219         int shift = 0;
220         if (va == pa)
221                 return sizeof(uintptr_t) * 8;
222         while ((va & 1) == (pa & 1)) {
223                 va >>= 1;
224                 pa >>= 1;
225                 shift++;
226         }
227         return shift;
228 }
229
230 /* Map [va, va+size) of virtual (linear) address space to physical [pa, pa+size)
231  * in the page table rooted at pgdir.  Size is a multiple of PGSIZE.  Use
232  * permission bits perm|PTE_P for the entries.  Set pml_shift to the shift of
233  * the largest page size you're willing to use.
234  *
235  * Doesn't handle having pages currently mapped yet, and while supporting that
236  * is relatively easy, doing an insertion of small pages into an existing jumbo
237  * would be trickier.  Might have the vmem region code deal with this.
238  *
239  * Don't use this to set the PAT flag on jumbo pages in perm, unless you are
240  * absolultely sure you won't map regular pages.  */
241 void map_segment(pgdir_t pgdir, uintptr_t va, size_t size, physaddr_t pa,
242                  int perm, int pml_shift)
243 {
244         int max_shift_possible;
245         if (PGOFF(va) || PGOFF(pa) || PGOFF(size))
246                 panic("Asked to map with bad alignment.  va %p, pa %p, size %p\n", va,
247                       pa, size);
248         /* Given the max_page_size, try and use larger pages.  We'll figure out the
249          * largest possible jumbo page, up to whatever we were asked for. */
250         if (pml_shift != PGSHIFT) {
251                 max_shift_possible = max_possible_shift(va, pa);
252                 /* arch-specific limitation (can't have jumbos beyond PML3) */
253                 max_shift_possible = MIN(max_shift_possible, PML3_SHIFT);
254                 /* Assumes we were given a proper PML shift 12, 21, 30, etc */
255                 while (pml_shift > max_shift_possible)
256                         pml_shift -= BITS_PER_PML;
257         }
258         assert((pml_shift == PML1_SHIFT) ||
259                (pml_shift == PML2_SHIFT) ||
260                (pml_shift == PML3_SHIFT));
261         __map_segment(pgdir_get_kpt(pgdir), va, size, pa, perm, pml_shift);
262 }
263
264 /* For every PTE in [start, start + len), call callback(kpte, shift,
265  * etc), including the not present PTEs.  pml_shift is the shift/size of pml.
266  *
267  * This will recurse down into sub PMLs, and perform the CB in a
268  * depth-first-search.  The CB will be told which level of the paging it is at,
269  * via 'shift'.
270  *
271  * The CB will also run on intermediate PTEs: meaning, PTEs that point to page
272  * tables (and not (jumbo) pages) will be executed.  If the CB returns anything
273  * other than 0, we'll abort and propagate that back out from for_each. */
274 static int __pml_for_each(kpte_t *pml,  uintptr_t start, size_t len,
275                           kpte_cb_t callback, void *arg, int pml_shift)
276 {
277         int ret;
278         bool visited_all_subs;
279         kpte_t *kpte_s, *kpte_e, *kpte_i;
280         uintptr_t kva, pgsize = 1UL << pml_shift;
281
282         if (!len)
283                 return 0;
284         kpte_s = &pml[PMLx(start, pml_shift)];
285         /* Later, we'll loop up to and including kpte_e.  Since start + len might
286          * not be page aligned, we'll need to include the final kpte.  If it is
287          * aligned, we don't want to visit, so we subtract one so that the aligned
288          * case maps to the index below its normal kpte. */
289         kpte_e = &pml[PMLx(start + len - 1, pml_shift)];
290         /* tracks the virt addr kpte_i works on, rounded for this PML */
291         kva = ROUNDDOWN(start, pgsize);
292         printd("PFE, start %p PMLx(S) %d, end-inc %p PMLx(E) %d shift %d, kva %p\n",
293                start, PMLx(start, pml_shift), start + len - 1,
294                PMLx(start + len - 1, pml_shift), pml_shift, kva);
295         for (kpte_i = kpte_s; kpte_i <= kpte_e; kpte_i++, kva += pgsize) {
296                 visited_all_subs = FALSE;
297                 /* Complete only on the last level (PML1_SHIFT) or on a jumbo */
298                 if ((*kpte_i & PTE_P) &&
299                     (!walk_is_complete(kpte_i, pml_shift, PML1_SHIFT))) {
300                         /* only pass truncated end points (e.g. start may not be page
301                          * aligned) when we're on the first (or last) item.  For the middle
302                          * entries, we want the subpmls to process the full range they are
303                          * responsible for: [kva, kva + pgsize). */
304                         uintptr_t sub_start = MAX(kva, start);
305                         size_t sub_len = MIN(start + len, kva + pgsize) - sub_start;
306                         ret = __pml_for_each(kpte2pml(*kpte_i), sub_start, sub_len,
307                                              callback, arg, pml_shift - BITS_PER_PML);
308                         if (ret)
309                                 return ret;
310                         /* based on sub_{start,end}, we can tell if our sub visited all of
311                          * its PTES. */
312                         if ((sub_start == kva) && (sub_len == pgsize))
313                                 visited_all_subs = TRUE;
314                 }
315                 if ((ret = callback(kpte_i, kva, pml_shift, visited_all_subs, arg)))
316                         return ret;
317         }
318         return 0;
319 }
320
321 int pml_for_each(kpte_t *pml, uintptr_t start, size_t len, kpte_cb_t callback,
322                  void *arg)
323 {
324         return __pml_for_each(pml, start, len, callback, arg, PML4_SHIFT);
325 }
326
327 /* Unmaps [va, va + size) from pgdir, freeing any intermediate page tables.
328  * This does not free the actual memory pointed to by the page tables, nor does
329  * it flush the TLB. */
330 int unmap_segment(pgdir_t pgdir, uintptr_t va, size_t size)
331 {
332         int pt_free_cb(kpte_t *kpte, uintptr_t kva, int shift, bool visited_subs,
333                        void *data)
334         {
335                 if (!(*kpte & PTE_P))
336                         return 0;
337                 if ((shift == PML1_SHIFT) || (*kpte & PTE_PS)) {
338                         *kpte = 0;
339                         return 0;
340                 }
341                 /* If we haven't visited all of our subs, we might still have some
342                  * mappings hanging our this page table. */
343                 if (!visited_subs) {
344                         kpte_t *kpte_i = kpte2pml(*kpte);       /* first kpte == pml */
345                         /* make sure we have no PTEs in use */
346                         for (int i = 0; i < NPTENTRIES; i++, kpte_i++) {
347                                 if (*kpte_i)
348                                         return 0;
349                         }
350                 }
351                 page_decref(ppn2page(LA2PPN(*kpte)));
352                 *kpte = 0;
353                 return 0;
354         }
355
356         return pml_for_each(pgdir_get_kpt(pgdir), va, size, pt_free_cb, 0);
357 }
358
359 /* Older interface for page table walks - will return the PTE corresponding to
360  * VA.  If create is 1, it'll create intermediate tables.  This can return jumbo
361  * PTEs, but only if they already exist.  Otherwise, (with create), it'll walk
362  * to the lowest PML.  If the walk fails due to a lack of intermediate tables or
363  * memory, this returns 0 (subject to change based on pte_t). */
364 pte_t pgdir_walk(pgdir_t pgdir, const void *va, int create)
365 {
366         pte_t ret;
367         int flags = PML1_SHIFT;
368         if (create == 1)
369                 flags |= PG_WALK_CREATE;
370         ret.kpte = pml_walk(pgdir_get_kpt(pgdir), (uintptr_t)va, flags);
371         /* TODO: (EPT) walk the EPT */
372         ret.epte = 0;
373         return ret;
374 }
375
376 static int pml_perm_walk(kpte_t *pml, const void *va, int pml_shift)
377 {
378         kpte_t *kpte;
379         int perms_here;
380
381         kpte = &pml[PMLx(va, pml_shift)];
382         if (!(*kpte & PTE_P))
383                 return 0;
384         perms_here = *kpte & (PTE_PERM | PTE_P);
385         if (walk_is_complete(kpte, pml_shift, PML1_SHIFT))
386                 return perms_here;
387         return pml_perm_walk(kpte2pml(*kpte), va, pml_shift - BITS_PER_PML) &
388                perms_here;
389 }
390
391 /* Returns the effective permissions for PTE_U, PTE_W, and PTE_P on a given
392  * virtual address.  Note we need to consider the composition of every PTE in
393  * the page table walk (we bit-and all of them together) */
394 int get_va_perms(pgdir_t pgdir, const void *va)
395 {
396         return pml_perm_walk(pgdir_get_kpt(pgdir), va, PML4_SHIFT);
397 }
398
399 #define check_sym_va(sym, addr)                                                \
400 ({                                                                             \
401         if ((sym) != (addr))                                                       \
402                 printk("Error: " #sym " is %p, should be " #addr "\n", sym);           \
403 })
404
405 static void check_syms_va(void)
406 {
407         /* Make sure our symbols are up to date (see arch/ros/mmu64.h) */
408         check_sym_va(KERN_LOAD_ADDR, 0xffffffffc0000000);
409         check_sym_va(LAPIC_BASE,     0xffffffffbff00000);
410         check_sym_va(IOAPIC_BASE,    0xffffffffbfe00000);
411         check_sym_va(VPT_TOP,        0xffffff0000000000);
412         check_sym_va(VPT,            0xfffffe8000000000);
413         check_sym_va(KERN_VMAP_TOP,  0xfffffe8000000000);
414         check_sym_va(KERNBASE,       0xffff800000000000);
415         check_sym_va(ULIM,           0x0000800000000000);
416         check_sym_va(UVPT,           0x00007f8000000000);
417         check_sym_va(UINFO,          0x00007f7fffe00000);
418         check_sym_va(UWLIM,          0x00007f7fffe00000);
419         check_sym_va(UDATA,          0x00007f7fffc00000);
420         check_sym_va(UGDATA,         0x00007f7fffbff000);
421         check_sym_va(UMAPTOP,        0x00007f7fffbff000);
422         check_sym_va(USTACKTOP,      0x00007f7fffbff000);
423         check_sym_va(BRK_END,        0x0000400000000000);
424 }
425
426 /* Initializes anything related to virtual memory.  Paging is already on, but we
427  * have a slimmed down page table. */
428 void vm_init(void)
429 {
430         int max_jumbo_shift;
431         kpte_t *boot_kpt = KADDR(get_boot_pml4());
432
433         boot_cr3 = get_boot_pml4();
434         boot_pgdir.kpte = boot_kpt;
435         boot_pgdir.epte = 0;
436         gdt = KADDR(get_gdt64());
437
438         /* We need to limit our mappings on machines that don't support 1GB pages */
439         max_jumbo_shift = arch_max_jumbo_page_shift();
440         check_syms_va();
441         /* KERNBASE mapping: we already have 512 GB complete (one full PML3_REACH).
442          * It's okay if we have extra, just need to make sure we reach max_paddr. */
443         if (KERNBASE + PML3_REACH < (uintptr_t)KADDR(max_paddr)) {
444                 map_segment(boot_pgdir, KERNBASE + PML3_REACH,
445                             max_paddr - PML3_REACH, 0x0 + PML3_REACH,
446                             PTE_W | PTE_G, max_jumbo_shift);
447         }
448         /* For the LAPIC and IOAPIC, we use PAT (but not *the* PAT flag) to make
449          * these type UC */
450         map_segment(boot_pgdir, LAPIC_BASE, APIC_SIZE, LAPIC_PBASE,
451                     PTE_PCD | PTE_PWT | PTE_W | PTE_G, max_jumbo_shift);
452         map_segment(boot_pgdir, IOAPIC_BASE, APIC_SIZE, IOAPIC_PBASE,
453                     PTE_PCD | PTE_PWT | PTE_W | PTE_G, max_jumbo_shift);
454         /* VPT mapping: recursive PTE inserted at the VPT spot */
455         boot_kpt[PML4(VPT)] = PADDR(boot_kpt) | PTE_W | PTE_P;
456         /* same for UVPT, accessible by userspace (RO). */
457         boot_kpt[PML4(UVPT)] = PADDR(boot_kpt) | PTE_U | PTE_P;
458         /* set up core0s now (mostly for debugging) */
459         setup_default_mtrrs(0);
460         /* Our current gdt_pd (gdt64desc) is pointing to a physical address for the
461          * GDT.  We need to switch over to pointing to one with a virtual address,
462          * so we can later unmap the low memory */
463         gdt_pd = (pseudodesc_t) {sizeof(segdesc_t) * SEG_COUNT - 1,
464                                  (uintptr_t)gdt};
465         asm volatile("lgdt %0" : : "m"(gdt_pd));
466 }
467
468 void x86_cleanup_bootmem(void)
469 {
470         unmap_segment(boot_pgdir, 0, PML3_PTE_REACH);
471         tlbflush();
472 }
473
474 /* Walks len bytes from start, executing 'callback' on every PTE, passing it a
475  * specific VA and whatever arg is passed in.  Note, this cannot handle jumbo
476  * pages.
477  *
478  * This is just a clumsy wrapper around the more powerful pml_for_each, which
479  * can handle jumbo and intermediate pages. */
480 int env_user_mem_walk(struct proc *p, void *start, size_t len,
481                       mem_walk_callback_t callback, void *arg)
482 {
483         struct tramp_package {
484                 struct proc *p;
485                 mem_walk_callback_t cb;
486                 void *cb_arg;
487         };
488         int trampoline_cb(kpte_t *kpte, uintptr_t kva, int shift, bool visited_subs,
489                           void *data)
490         {
491                 struct tramp_package *tp = (struct tramp_package*)data;
492                 pte_t half_pte = {.kpte = kpte, .epte = 0};
493                 assert(tp->cb);
494                 /* memwalk CBs don't know how to handle intermediates or jumbos */
495                 if (shift != PML1_SHIFT)
496                         return 0;
497                 return tp->cb(tp->p, half_pte, (void*)kva, tp->cb_arg);
498         }
499
500         int ret;
501         struct tramp_package local_tp;
502         local_tp.p = p;
503         local_tp.cb = callback;
504         local_tp.cb_arg = arg;
505         /* Walking both in parallel and making a joint PTE is a pain.  instead, we
506          * walk one at a time, each with only a half_pte.  Most all of the pmap_ops
507          * need to deal with a getting half PTE.  Ideally, we'd combine the two
508          * walks and then know that we always have a kpte. */
509         ret = pml_for_each(pgdir_get_kpt(p->env_pgdir), (uintptr_t)start, len,
510                            trampoline_cb, &local_tp);
511         /* TODO: walk the EPT, combine with ret */
512         return ret;
513 }
514
515 /* Frees (decrefs) all pages of the process's page table, including the page
516  * directory.  Does not free the memory that is actually mapped. */
517 void env_pagetable_free(struct proc *p)
518 {
519         /* callback: given an intermediate kpte (not a final one), removes the page
520          * table the PTE points to */
521         int pt_free_cb(kpte_t *kpte, uintptr_t kva, int shift, bool visited_subs,
522                        void *data)
523         {
524                 if (!(*kpte & PTE_P))
525                         return 0;
526                 if ((shift == PML1_SHIFT) || (*kpte & PTE_PS))
527                         return 0;
528                 page_decref(ppn2page(LA2PPN(*kpte)));
529                 return 0;
530         }
531                 
532         assert(p->env_cr3 != rcr3());
533         pml_for_each(pgdir_get_kpt(p->env_pgdir), 0, UVPT, pt_free_cb, 0);
534         /* the page directory is not a PTE, so it never was freed */
535         page_decref(pa2page(p->env_cr3));
536         tlbflush();
537 }
538
539 /* Remove the inner page tables along va's walk.  The internals are more
540  * powerful.  We'll eventually want better arch-indep VM functions. */
541 error_t pagetable_remove(pgdir_t pgdir, void *va)
542 {
543         return unmap_segment(pgdir, (uintptr_t)va, PGSIZE);
544 }
545
546 void page_check(void)
547 {
548 }
549
550 int arch_pgdir_setup(pgdir_t boot_copy, pgdir_t *new_pd)
551 {
552         kpte_t *kpt = kpage_alloc_addr();
553         if (!kpt)
554                 return -ENOMEM;
555         memcpy(kpt, boot_copy.kpte, PGSIZE);
556
557         /* VPT and UVPT map the proc's page table, with different permissions. */
558         kpt[PML4(VPT)]  = PTE(LA2PPN(PADDR(kpt)), PTE_P | PTE_KERN_RW);
559         kpt[PML4(UVPT)] = PTE(LA2PPN(PADDR(kpt)), PTE_P | PTE_USER_RO);
560
561         new_pd->kpte = kpt;
562         /* Processes do not have EPTs by default, only once they are VMMs */
563         new_pd->epte = 0;
564         return 0;
565 }
566
567 physaddr_t arch_pgdir_get_cr3(pgdir_t pd)
568 {
569         return PADDR(pd.kpte);
570 }
571
572 void arch_pgdir_clear(pgdir_t *pd)
573 {
574         pd->kpte = 0;
575         pd->epte = 0;
576 }
577
578 /* Returns the page shift of the largest jumbo supported */
579 int arch_max_jumbo_page_shift(void)
580 {
581         uint32_t edx;
582         cpuid(0x80000001, 0x0, 0, 0, 0, &edx);
583         return edx & (1 << 26) ? PML3_SHIFT : PML2_SHIFT;
584 }
585
586 /* Debugging */
587 static int print_pte(kpte_t *kpte, uintptr_t kva, int shift, bool visited_subs,
588                      void *data)
589 {
590         if (!(*kpte & PTE_P))
591                 return 0;
592         switch (shift) {
593                 case (PML1_SHIFT):
594                         printk("\t");
595                         /* fall-through */
596                 case (PML2_SHIFT):
597                         printk("\t");
598                         /* fall-through */
599                 case (PML3_SHIFT):
600                         printk("\t");
601         }
602         printk("KVA: %p, PTE val %p, shift %d, visit %d%s\n", kva, *kpte, shift,
603                visited_subs, (*kpte & PTE_PS ? " (jumbo)" : ""));
604         return 0;
605 }
606
607 void debug_print_pgdir(kpte_t *pgdir)
608 {
609         if (! pgdir)
610                 pgdir = KADDR(rcr3());
611         printk("Printing the entire page table set for %p, DFS\n", pgdir);
612         /* Need to be careful we avoid VPT/UVPT, o/w we'll recurse */
613         pml_for_each(pgdir, 0, UVPT, print_pte, 0);
614         if (arch_max_jumbo_page_shift() < PML3_SHIFT)
615                 printk("(skipping kernbase mapping - too many entries)\n");
616         else
617                 pml_for_each(pgdir, KERNBASE, VPT - KERNBASE, print_pte, 0);
618         pml_for_each(pgdir, VPT_TOP, MAX_VADDR - VPT_TOP, print_pte, 0);
619 }