Pmap ops: perm->settings
[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 int unmap_segment(pgdir_t pgdir, uintptr_t va, size_t size);
47
48 typedef int (*kpte_cb_t)(kpte_t *kpte, uintptr_t kva, int pml_shift,
49                         bool visited_subs, void *arg);
50 int pml_for_each(kpte_t *pml, uintptr_t start, size_t len, kpte_cb_t callback,
51                  void *arg);
52 /* Helpers for PML for-each walks */
53 static inline bool pte_is_final(pte_t pte, int pml_shift)
54 {
55         return (pml_shift == PML1_SHIFT) || pte_is_jumbo(pte);
56 }
57
58 static inline bool pte_is_intermediate(pte_t pte, int pml_shift)
59 {
60         return !pte_is_final(pte, pml_shift);
61 }
62
63 /* Helper: gets the kpte_t pointer which is the base of the PML4 from pgdir */
64 static kpte_t *pgdir_get_kpt(pgdir_t pgdir)
65 {
66         return pgdir.kpte;
67 }
68
69 /* Helper: returns true if we do not need to walk the page table any further.
70  *
71  * The caller may or may not know if a jumbo is desired.  pml_shift determines
72  * which layer we are at in the page walk, and flags contains the target level
73  * we're looking for, like a jumbo or a default.
74  *
75  * Regardless of the desired target, if we find a jumbo page, we're also done.
76  */
77 static bool walk_is_complete(kpte_t *kpte, int pml_shift, int flags)
78 {
79         if ((pml_shift == (flags & PG_WALK_SHIFT_MASK)) || (*kpte & PTE_PS))
80                 return TRUE;
81         return FALSE;
82 }
83
84 /* PTE_ADDR should only be used on a PTE that has a physical address of the next
85  * PML inside.  i.e., not a final PTE in the page table walk. */
86 static kpte_t *kpte2pml(kpte_t kpte)
87 {
88         return (kpte_t*)KADDR(PTE_ADDR(kpte));
89 }
90
91 static kpte_t *__pml_walk(kpte_t *pml, uintptr_t va, int flags, int pml_shift)
92 {
93         kpte_t *kpte;
94         epte_t *epte;
95         void *new_pml_kva;
96
97         kpte = &pml[PMLx(va, pml_shift)];
98         epte = kpte_to_epte(kpte);
99         if (walk_is_complete(kpte, pml_shift, flags))
100                 return kpte;
101         if (!kpte_is_present(kpte)) {
102                 if (!(flags & PG_WALK_CREATE))
103                         return NULL;
104                 new_pml_kva = get_cont_pages(1, KMALLOC_WAIT);
105                 memset(new_pml_kva, 0, PGSIZE * 2);
106                 /* Might want better error handling (we're probably out of memory) */
107                 if (!new_pml_kva)
108                         return NULL;
109                 /* We insert the new PT into the PML with U and W perms.  Permissions on
110                  * page table walks are anded together (if any of them are !User, the
111                  * translation is !User).  We put the perms on the last entry, not the
112                  * intermediates. */
113                 *kpte = PADDR(new_pml_kva) | PTE_P | PTE_U | PTE_W;
114                 /* The physaddr of the new_pml is one page higher than the KPT page.  A
115                  * few other things:
116                  * - for the same reason that we have U and X set on all intermediate
117                  * PTEs, we now set R, X, and W for the EPTE.
118                  * - All EPTEs have U perms
119                  * - We can't use epte_write since we're workin on intermediate PTEs,
120                  * and they don't have the memory type set. */
121                 *epte = (PADDR(new_pml_kva) + PGSIZE) | EPTE_R | EPTE_X | EPTE_W;
122         }
123         return __pml_walk(kpte2pml(*kpte), va, flags, pml_shift - BITS_PER_PML);
124 }
125
126 /* Returns a pointer to the page table entry corresponding to va.  Flags has
127  * some options and selects which level of the page table we're happy with
128  * stopping at.  Normally, this is PML1 for a normal page (e.g. flags =
129  * PML1_SHIFT), but could be for a jumbo page (PML3 or PML2 entry).
130  *
131  * Flags also controls whether or not intermediate page tables are created or
132  * not.  This is useful for when we are checking whether or not a mapping
133  * exists, but aren't interested in creating intermediate tables that will not
134  * get filled.  When we want to create intermediate pages (i.e. we're looking
135  * for the PTE to insert a page), pass in PG_WALK_CREATE with flags.
136  *
137  * Returns 0 on error or absence of a PTE for va. */
138 kpte_t *pml_walk(kpte_t *pml, uintptr_t va, int flags)
139 {
140         return __pml_walk(pml, va, flags, PML4_SHIFT);
141 }
142
143 /* Helper: determines how much va needs to be advanced until it is aligned to
144  * pml_shift. */
145 static uintptr_t amt_til_aligned(uintptr_t va, int pml_shift)
146 {
147         /* find the lower bits of va, subtract them from the shift to see what we
148          * would need to add to get to the shift.  va might be aligned already, and
149          * we subtracted 0, so we mask off the top part again. */
150         return ((1UL << pml_shift) - (va & ((1UL << pml_shift) - 1))) &
151                ((1UL << pml_shift) - 1);
152 }
153
154 /* Helper: determines how much of size we can take, in chunks of pml_shift */
155 static uintptr_t amt_of_aligned_bytes(uintptr_t size, int pml_shift)
156 {
157         /* creates a mask all 1s from MSB down to (including) shift */
158         return (~((1UL << pml_shift) - 1)) & size;
159 }
160
161 /* Helper: Advance kpte, given old_pte.  Will do pml walks when necessary. */
162 static kpte_t *get_next_pte(kpte_t *old_pte, kpte_t *pgdir, uintptr_t va,
163                             int flags)
164 {
165         /* PTEs (undereferenced) are addresses within page tables.  so long as we
166          * stay inside the PML, we can just advance via pointer arithmetic.  if we
167          * advance old_pte and it points to the beginning of a page (offset == 0),
168          * we've looped outside of our original PML, and need to get a new one. */
169         old_pte++;
170         if (!PGOFF(old_pte))
171                 return pml_walk(pgdir, va, flags);
172         return old_pte;
173 }
174
175 /* Helper: maps pages from va to pa for size bytes, all for a given page size */
176 static void map_my_pages(kpte_t *pgdir, uintptr_t va, size_t size,
177                          physaddr_t pa, int perm, int pml_shift)
178 {
179         /* set to trigger a pml walk on the first get_next */
180         kpte_t *kpte = (kpte_t*)PGSIZE - 1;
181         size_t pgsize = 1UL << pml_shift;
182
183         for (size_t i = 0; i < size; i += pgsize, va += pgsize,
184              pa += pgsize) {
185                 kpte = get_next_pte(kpte, pgdir, va, PG_WALK_CREATE | pml_shift);
186                 assert(kpte);
187                 *kpte = PTE_ADDR(pa) | perm |
188                         (pml_shift != PML1_SHIFT ? PTE_PS : 0);
189                 printd("Wrote *kpte %p, for va %p to pa %p tried to cover %p\n",
190                        *kpte, va, pa, amt_mapped);
191         }
192 }
193
194 /* Maps all pages possible from va->pa, up to size, preferring to use pages of
195  * type pml_shift (size == (1 << shift)).  Assumes that it is possible to map va
196  * to pa at the given shift. */
197 static uintptr_t __map_segment(kpte_t *pgdir, uintptr_t va, size_t size,
198                                physaddr_t pa, int perm, int pml_shift)
199 {
200         printd("__map_segment, va %p, size %p, pa %p, shift %d\n", va, size,
201                pa, pml_shift);
202         uintptr_t amt_to_submap, amt_to_map, amt_mapped = 0;
203
204         amt_to_submap = amt_til_aligned(va, pml_shift);
205         amt_to_submap = MIN(amt_to_submap, size);
206         if (amt_to_submap) {
207                 amt_mapped = __map_segment(pgdir, va, amt_to_submap, pa, perm,
208                                            pml_shift - BITS_PER_PML);
209                 va += amt_mapped;
210                 pa += amt_mapped;
211                 size -= amt_mapped;
212         }
213         /* Now we're either aligned and ready to map, or size == 0 */
214         amt_to_map = amt_of_aligned_bytes(size, pml_shift);
215         if (amt_to_map) {
216                 map_my_pages(pgdir, va, amt_to_map, pa, perm, pml_shift);
217                 va += amt_to_map;
218                 pa += amt_to_map;
219                 size -= amt_to_map;
220                 amt_mapped += amt_to_map;
221         }
222         /* Map whatever is left over */
223         if (size)
224                 amt_mapped += __map_segment(pgdir, va, size, pa, perm,
225                                             pml_shift - BITS_PER_PML);
226         return amt_mapped;
227 }
228
229 /* Returns the maximum pml shift possible between a va->pa mapping.  It is the
230  * number of least-significant bits the two addresses have in common.  For
231  * instance, if the two pages are 0x456000 and 0x156000, this returns 20.  For
232  * regular pages, it will be at least 12 (every page ends in 0x000).
233  *
234  * The max pml shift possible for an va->pa mapping is determined by the
235  * least bit that differs between va and pa.
236  *
237  * We can optimize this a bit, since we know the first 12 bits are the same, and
238  * we won't go higher than max_pml_shift. */
239 static int max_possible_shift(uintptr_t va, uintptr_t pa)
240 {
241         int shift = 0;
242         if (va == pa)
243                 return sizeof(uintptr_t) * 8;
244         while ((va & 1) == (pa & 1)) {
245                 va >>= 1;
246                 pa >>= 1;
247                 shift++;
248         }
249         return shift;
250 }
251
252 /* Map [va, va+size) of virtual (linear) address space to physical [pa, pa+size)
253  * in the page table rooted at pgdir.  Size is a multiple of PGSIZE.  Use
254  * permission bits perm for the entries.  Set pml_shift to the shift of the
255  * largest page size you're willing to use.
256  *
257  * Doesn't handle having pages currently mapped yet, and while supporting that
258  * is relatively easy, doing an insertion of small pages into an existing jumbo
259  * would be trickier.  Might have the vmem region code deal with this.
260  *
261  * Don't use this to set the PAT flag on jumbo pages in perm, unless you are
262  * absolultely sure you won't map regular pages.  */
263 void map_segment(pgdir_t pgdir, uintptr_t va, size_t size, physaddr_t pa,
264                  int perm, int pml_shift)
265 {
266         int max_shift_possible;
267         if (PGOFF(va) || PGOFF(pa) || PGOFF(size))
268                 panic("Asked to map with bad alignment.  va %p, pa %p, size %p\n", va,
269                       pa, size);
270         /* Given the max_page_size, try and use larger pages.  We'll figure out the
271          * largest possible jumbo page, up to whatever we were asked for. */
272         if (pml_shift != PGSHIFT) {
273                 max_shift_possible = max_possible_shift(va, pa);
274                 max_shift_possible = MIN(max_shift_possible,
275                                          arch_max_jumbo_page_shift());
276                 /* Assumes we were given a proper PML shift 12, 21, 30, etc */
277                 while (pml_shift > max_shift_possible)
278                         pml_shift -= BITS_PER_PML;
279         }
280         assert((pml_shift == PML1_SHIFT) ||
281                (pml_shift == PML2_SHIFT) ||
282                (pml_shift == PML3_SHIFT));
283         __map_segment(pgdir_get_kpt(pgdir), va, size, pa, perm, pml_shift);
284 }
285
286 /* For every PTE in [start, start + len), call callback(kpte, shift,
287  * etc), including the not present PTEs.  pml_shift is the shift/size of pml.
288  *
289  * This will recurse down into sub PMLs, and perform the CB in a
290  * depth-first-search.  The CB will be told which level of the paging it is at,
291  * via 'shift'.
292  *
293  * The CB will also run on intermediate PTEs: meaning, PTEs that point to page
294  * tables (and not (jumbo) pages) will be executed.  If the CB returns anything
295  * other than 0, we'll abort and propagate that back out from for_each. */
296 static int __pml_for_each(kpte_t *pml,  uintptr_t start, size_t len,
297                           kpte_cb_t callback, void *arg, int pml_shift)
298 {
299         int ret;
300         bool visited_all_subs;
301         kpte_t *kpte_s, *kpte_e, *kpte_i;
302         uintptr_t kva, pgsize = 1UL << pml_shift;
303
304         if (!len)
305                 return 0;
306         kpte_s = &pml[PMLx(start, pml_shift)];
307         /* Later, we'll loop up to and including kpte_e.  Since start + len might
308          * not be page aligned, we'll need to include the final kpte.  If it is
309          * aligned, we don't want to visit, so we subtract one so that the aligned
310          * case maps to the index below its normal kpte. */
311         kpte_e = &pml[PMLx(start + len - 1, pml_shift)];
312         /* tracks the virt addr kpte_i works on, rounded for this PML */
313         kva = ROUNDDOWN(start, pgsize);
314         printd("PFE, start %p PMLx(S) %d, end-inc %p PMLx(E) %d shift %d, kva %p\n",
315                start, PMLx(start, pml_shift), start + len - 1,
316                PMLx(start + len - 1, pml_shift), pml_shift, kva);
317         for (kpte_i = kpte_s; kpte_i <= kpte_e; kpte_i++, kva += pgsize) {
318                 visited_all_subs = FALSE;
319                 /* Complete only on the last level (PML1_SHIFT) or on a jumbo */
320                 if (kpte_is_present(kpte_i) &&
321                     (!walk_is_complete(kpte_i, pml_shift, PML1_SHIFT))) {
322                         /* only pass truncated end points (e.g. start may not be page
323                          * aligned) when we're on the first (or last) item.  For the middle
324                          * entries, we want the subpmls to process the full range they are
325                          * responsible for: [kva, kva + pgsize). */
326                         uintptr_t sub_start = MAX(kva, start);
327                         size_t sub_len = MIN(start + len, kva + pgsize) - sub_start;
328                         ret = __pml_for_each(kpte2pml(*kpte_i), sub_start, sub_len,
329                                              callback, arg, pml_shift - BITS_PER_PML);
330                         if (ret)
331                                 return ret;
332                         /* based on sub_{start,end}, we can tell if our sub visited all of
333                          * its PTES. */
334                         if ((sub_start == kva) && (sub_len == pgsize))
335                                 visited_all_subs = TRUE;
336                 }
337                 if ((ret = callback(kpte_i, kva, pml_shift, visited_all_subs, arg)))
338                         return ret;
339         }
340         return 0;
341 }
342
343 int pml_for_each(kpte_t *pml, uintptr_t start, size_t len, kpte_cb_t callback,
344                  void *arg)
345 {
346         return __pml_for_each(pml, start, len, callback, arg, PML4_SHIFT);
347 }
348
349 /* Unmaps [va, va + size) from pgdir, freeing any intermediate page tables.
350  * This does not free the actual memory pointed to by the page tables, nor does
351  * it flush the TLB. */
352 int unmap_segment(pgdir_t pgdir, uintptr_t va, size_t size)
353 {
354         int pt_free_cb(kpte_t *kpte, uintptr_t kva, int shift, bool visited_subs,
355                        void *data)
356         {
357                 if (!kpte_is_present(kpte))
358                         return 0;
359                 if (pte_is_final(kpte, shift)) {
360                         *kpte = 0;
361                         return 0;
362                 }
363                 /* If we haven't visited all of our subs, we might still have some
364                  * mappings hanging off this page table. */
365                 if (!visited_subs) {
366                         kpte_t *kpte_i = kpte2pml(*kpte);       /* first kpte == pml */
367                         /* make sure we have no PTEs in use */
368                         for (int i = 0; i < NPTENTRIES; i++, kpte_i++) {
369                                 if (*kpte_i)
370                                         return 0;
371                         }
372                 }
373                 free_cont_pages(KADDR(PTE_ADDR(*kpte)), 1);
374                 *kpte = 0;
375                 return 0;
376         }
377         /* Don't accidentally unmap the boot mappings */
378         assert((va < KERNBASE) && (va + size < KERNBASE));
379         return pml_for_each(pgdir_get_kpt(pgdir), va, size, pt_free_cb, 0);
380 }
381
382 /* Older interface for page table walks - will return the PTE corresponding to
383  * VA.  If create is 1, it'll create intermediate tables.  This can return jumbo
384  * PTEs, but only if they already exist.  Otherwise, (with create), it'll walk
385  * to the lowest PML.  If the walk fails due to a lack of intermediate tables or
386  * memory, this returns 0 (subject to change based on pte_t). */
387 pte_t pgdir_walk(pgdir_t pgdir, const void *va, int create)
388 {
389         pte_t ret;
390         int flags = PML1_SHIFT;
391         if (create == 1)
392                 flags |= PG_WALK_CREATE;
393         return pml_walk(pgdir_get_kpt(pgdir), (uintptr_t)va, flags);
394 }
395
396 static int pml_perm_walk(kpte_t *pml, const void *va, int pml_shift)
397 {
398         kpte_t *kpte;
399         int perms_here;
400
401         kpte = &pml[PMLx(va, pml_shift)];
402         if (!kpte_is_present(kpte))
403                 return 0;
404         perms_here = *kpte & PTE_PERM;
405         if (walk_is_complete(kpte, pml_shift, PML1_SHIFT))
406                 return perms_here;
407         return pml_perm_walk(kpte2pml(*kpte), va, pml_shift - BITS_PER_PML) &
408                perms_here;
409 }
410
411 /* Returns the effective permissions for PTE_U, PTE_W, and PTE_P on a given
412  * virtual address.  Note we need to consider the composition of every PTE in
413  * the page table walk (we bit-and all of them together) */
414 int get_va_perms(pgdir_t pgdir, const void *va)
415 {
416         return pml_perm_walk(pgdir_get_kpt(pgdir), va, PML4_SHIFT);
417 }
418
419 #define check_sym_va(sym, addr)                                                \
420 ({                                                                             \
421         if ((sym) != (addr))                                                       \
422                 printk("Error: " #sym " is %p, should be " #addr "\n", sym);           \
423 })
424
425 static void check_syms_va(void)
426 {
427         /* Make sure our symbols are up to date (see arch/ros/mmu64.h) */
428         check_sym_va(KERN_LOAD_ADDR, 0xffffffffc0000000);
429         check_sym_va(LAPIC_BASE,     0xffffffffbff00000);
430         check_sym_va(IOAPIC_BASE,    0xffffffffbfe00000);
431         check_sym_va(VPT_TOP,        0xffffff0000000000);
432         check_sym_va(VPT,            0xfffffe8000000000);
433         check_sym_va(KERN_VMAP_TOP,  0xfffffe8000000000);
434         check_sym_va(KERNBASE,       0xffff800000000000);
435         check_sym_va(ULIM,           0x0000800000000000);
436         check_sym_va(UVPT,           0x00007f8000000000);
437         check_sym_va(UINFO,          0x00007f7fffe00000);
438         check_sym_va(UWLIM,          0x00007f7fffe00000);
439         check_sym_va(UDATA,          0x00007f7fffc00000);
440         check_sym_va(UGDATA,         0x00007f7fffbff000);
441         check_sym_va(UMAPTOP,        0x00007f7fffbff000);
442         check_sym_va(USTACKTOP,      0x00007f7fffbff000);
443         check_sym_va(BRK_END,        0x0000400000000000);
444 }
445
446 /* Initializes anything related to virtual memory.  Paging is already on, but we
447  * have a slimmed down page table. */
448 void vm_init(void)
449 {
450         int max_jumbo_shift;
451         kpte_t *boot_kpt = KADDR(get_boot_pml4());
452
453         boot_cr3 = get_boot_pml4();
454         boot_pgdir.kpte = boot_kpt;
455         boot_pgdir.eptp = 0;
456         gdt = KADDR(get_gdt64());
457
458         /* We need to limit our mappings on machines that don't support 1GB pages */
459         max_jumbo_shift = arch_max_jumbo_page_shift();
460         check_syms_va();
461         /* KERNBASE mapping: we already have 512 GB complete (one full PML3_REACH).
462          * It's okay if we have extra, just need to make sure we reach max_paddr. */
463         if (KERNBASE + PML3_REACH < (uintptr_t)KADDR(max_paddr)) {
464                 map_segment(boot_pgdir, KERNBASE + PML3_REACH,
465                             max_paddr - PML3_REACH, 0x0 + PML3_REACH,
466                             PTE_W | PTE_G, max_jumbo_shift);
467         }
468         /* For the LAPIC and IOAPIC, we use PAT (but not *the* PAT flag) to make
469          * these type UC */
470         map_segment(boot_pgdir, LAPIC_BASE, APIC_SIZE, LAPIC_PBASE,
471                     PTE_PCD | PTE_PWT | PTE_KERN_RW | PTE_G, max_jumbo_shift);
472         map_segment(boot_pgdir, IOAPIC_BASE, APIC_SIZE, IOAPIC_PBASE,
473                     PTE_PCD | PTE_PWT | PTE_KERN_RW | PTE_G, max_jumbo_shift);
474         /* VPT mapping: recursive PTE inserted at the VPT spot */
475         boot_kpt[PML4(VPT)] = PADDR(boot_kpt) | PTE_W | PTE_P;
476         /* same for UVPT, accessible by userspace (RO). */
477         boot_kpt[PML4(UVPT)] = PADDR(boot_kpt) | PTE_U | PTE_P;
478         /* set up core0s now (mostly for debugging) */
479         setup_default_mtrrs(0);
480         /* Our current gdt_pd (gdt64desc) is pointing to a physical address for the
481          * GDT.  We need to switch over to pointing to one with a virtual address,
482          * so we can later unmap the low memory */
483         gdt_pd = (pseudodesc_t) {sizeof(segdesc_t) * SEG_COUNT - 1,
484                                  (uintptr_t)gdt};
485         asm volatile("lgdt %0" : : "m"(gdt_pd));
486 }
487
488 void x86_cleanup_bootmem(void)
489 {
490         /* the boot page tables weren't alloc'd the same as other pages, so we'll
491          * need to do some hackery to 'free' them.  This doesn't actually free
492          * anything - it just unmaps but leave 2 KPTs (4 pages) sitting around. */
493         //unmap_segment(boot_pgdir, 0, PML3_PTE_REACH); // want to do this
494         boot_pgdir.kpte[0] = 0;
495         tlbflush();
496 }
497
498 /* Walks len bytes from start, executing 'callback' on every PTE, passing it a
499  * specific VA and whatever arg is passed in.  Note, this cannot handle jumbo
500  * pages.
501  *
502  * This is just a clumsy wrapper around the more powerful pml_for_each, which
503  * can handle jumbo and intermediate pages. */
504 int env_user_mem_walk(struct proc *p, void *start, size_t len,
505                       mem_walk_callback_t callback, void *arg)
506 {
507         struct tramp_package {
508                 struct proc *p;
509                 mem_walk_callback_t cb;
510                 void *cb_arg;
511         };
512         int trampoline_cb(kpte_t *kpte, uintptr_t kva, int shift, bool visited_subs,
513                           void *data)
514         {
515                 struct tramp_package *tp = (struct tramp_package*)data;
516                 assert(tp->cb);
517                 /* memwalk CBs don't know how to handle intermediates or jumbos */
518                 if (shift != PML1_SHIFT)
519                         return 0;
520                 return tp->cb(tp->p, kpte, (void*)kva, tp->cb_arg);
521         }
522
523         struct tramp_package local_tp;
524         local_tp.p = p;
525         local_tp.cb = callback;
526         local_tp.cb_arg = arg;
527         return pml_for_each(pgdir_get_kpt(p->env_pgdir), (uintptr_t)start, len,
528                            trampoline_cb, &local_tp);
529 }
530
531 /* Frees (decrefs) all pages of the process's page table, including the page
532  * directory.  Does not free the memory that is actually mapped. */
533 void env_pagetable_free(struct proc *p)
534 {
535         unmap_segment(p->env_pgdir, 0, UVPT - 0);
536         /* the page directory is not a PTE, so it never was freed */
537         free_cont_pages(pgdir_get_kpt(p->env_pgdir), 1);
538         tlbflush();
539 }
540
541 /* Remove the inner page tables along va's walk.  The internals are more
542  * powerful.  We'll eventually want better arch-indep VM functions. */
543 error_t pagetable_remove(pgdir_t pgdir, void *va)
544 {
545         return unmap_segment(pgdir, (uintptr_t)va, PGSIZE);
546 }
547
548 void page_check(void)
549 {
550 }
551
552 /* Sets up the page directory, based on boot_copy.
553  *
554  * For x86, to support VMs, all processes will have an EPT and a KPT.  Ideally,
555  * we'd use the same actual PT for both, but we can't thanks to the EPT design.
556  * Although they are not the same actual PT, they have the same contents.
557  *
558  * The KPT-EPT invariant is that the KPT and EPT hold the same mappings from
559  * [0,UVPT), so long as some lock is held.  Right now, the lock is the pte_lock,
560  * but it could be a finer-grained lock (e.g. on lower level PTs) in the future.
561  *
562  * Part of the reason for the invariant is so that a pgdir walk on the process's
563  * address space will get the 'same' PTE for both the KPT and the EPT.  For
564  * instance, if a page is present in the KPT, a pte is present and points to the
565  * same physical page in the EPT.  Likewise, both the KPT and EPT agree on jumbo
566  * mappings.
567  *
568  * I went with UVPT for the upper limit of equality btw the KPT and EPT for a
569  * couple reasons: I wanted something static (technically the physaddr width is
570  * runtime dependent), and we'll never actually PF high enough for it to make a
571  * difference.  Plus, the UVPT is something that would need to be changed for
572  * the EPT too, if we supported it at all.
573  *
574  * Each page table page is actually two contiguous pages.  The lower is the KPT.
575  * The upper is the EPT.  Order-1 page allocs are a little harder, but the
576  * tradeoff is simplicity in all of the pm code.  Given a KPTE, we can find an
577  * EPTE with no hassle.  Note that this two-page business is a tax on *all*
578  * processes, which is less than awesome.
579  *
580  * Another note is that the boot page tables are *not* double-pages.  The EPT
581  * won't cover those spaces (e.g. kernbase mapping), so it's not necessary, and
582  * it's a pain in the ass to get it to work (can't align to 2*PGSIZE without
583  * grub complaining, and we might run into issues with freeing memory in the
584  * data segment). */
585 int arch_pgdir_setup(pgdir_t boot_copy, pgdir_t *new_pd)
586 {
587         kpte_t *kpt = get_cont_pages(1, KMALLOC_WAIT);
588         memcpy(kpt, boot_copy.kpte, PGSIZE);
589         epte_t *ept = kpte_to_epte(kpt);
590         memset(ept, 0, PGSIZE);
591
592         /* VPT and UVPT map the proc's page table, with different permissions. */
593         kpt[PML4(VPT)]  = PTE(LA2PPN(PADDR(kpt)), PTE_KERN_RW);
594         kpt[PML4(UVPT)] = PTE(LA2PPN(PADDR(kpt)), PTE_USER_RO);
595
596         new_pd->kpte = kpt;
597         new_pd->eptp = construct_eptp(PADDR(ept));
598         return 0;
599 }
600
601 physaddr_t arch_pgdir_get_cr3(pgdir_t pd)
602 {
603         return PADDR(pd.kpte);
604 }
605
606 void arch_pgdir_clear(pgdir_t *pd)
607 {
608         pd->kpte = 0;
609         pd->eptp = 0;
610 }
611
612 /* Returns the page shift of the largest jumbo supported */
613 int arch_max_jumbo_page_shift(void)
614 {
615         uint32_t edx;
616         cpuid(0x80000001, 0x0, 0, 0, 0, &edx);
617         return edx & (1 << 26) ? PML3_SHIFT : PML2_SHIFT;
618 }
619
620 /* Debugging */
621 static int print_pte(kpte_t *kpte, uintptr_t kva, int shift, bool visited_subs,
622                      void *data)
623 {
624         if (kpte_is_unmapped(kpte))
625                 return 0;
626         switch (shift) {
627                 case (PML1_SHIFT):
628                         printk("\t");
629                         /* fall-through */
630                 case (PML2_SHIFT):
631                         printk("\t");
632                         /* fall-through */
633                 case (PML3_SHIFT):
634                         printk("\t");
635         }
636         printk("KVA: %p, PTE val %p, shift %d, visit %d%s\n", kva, *kpte, shift,
637                visited_subs, (*kpte & PTE_PS ? " (jumbo)" : ""));
638         return 0;
639 }
640
641 void debug_print_pgdir(kpte_t *pgdir)
642 {
643         if (! pgdir)
644                 pgdir = KADDR(rcr3());
645         printk("Printing the entire page table set for %p, DFS\n", pgdir);
646         /* Need to be careful we avoid VPT/UVPT, o/w we'll recurse */
647         pml_for_each(pgdir, 0, UVPT, print_pte, 0);
648         if (arch_max_jumbo_page_shift() < PML3_SHIFT)
649                 printk("(skipping kernbase mapping - too many entries)\n");
650         else
651                 pml_for_each(pgdir, KERNBASE, VPT - KERNBASE, print_pte, 0);
652         pml_for_each(pgdir, VPT_TOP, MAX_VADDR - VPT_TOP, print_pte, 0);
653 }
654
655 /* Debug helper - makes sure the KPT == EPT for [0, UVPT) */
656 int debug_check_kpt_ept(void)
657 {
658         int db_cb(kpte_t *kpte, uintptr_t kva, int shift, bool visited_subs,
659                   void *data)
660         {
661                 epte_t *epte = kpte_to_epte(kpte);
662                 char *reason;
663                 int pa_offset = 0;
664
665                 if (kpte_is_present(kpte) != epte_is_present(epte)) {
666                         reason = "present bit";
667                         goto fail;
668                 }
669                 if (kpte_is_mapped(kpte) != epte_is_mapped(epte)) {
670                         reason = "mapped or not";
671                         goto fail;
672                 }
673                 if (kpte_is_jumbo(kpte) != epte_is_jumbo(epte)) {
674                         reason = "jumbo";
675                         goto fail;
676                 }
677                 /* Intermediate PTEs have the EPTE pointing to PADDR + PGSIZE */
678                 if (pte_is_present(kpte) && pte_is_intermediate(kpte, shift))
679                         pa_offset = PGSIZE;
680                 if (kpte_get_paddr(kpte) + pa_offset != epte_get_paddr(epte)) {
681                         reason = "paddr";
682                         goto fail;
683                 }
684                 if ((kpte_get_settings(kpte) & PTE_PERM) !=
685                     (epte_get_settings(epte) & PTE_PERM)) {
686                         reason = "permissions";
687                         goto fail;
688                 }
689                 return 0;
690
691 fail:
692                 panic("kpte %p (%p) epte %p (%p) kva %p shift %d: %s",
693                        kpte, *kpte, epte, *epte, kva, shift, reason);
694                 return -1;
695         }
696         return pml_for_each(current->env_pgdir.kpte, 0, UVPT - 0, db_cb, 0);
697 }