x86: Use global PTEs for kernel mappings
authorBarret Rhoden <brho@cs.berkeley.edu>
Sun, 27 Nov 2016 17:55:44 +0000 (12:55 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Tue, 29 Nov 2016 16:27:40 +0000 (11:27 -0500)
The KERNBASE and kernel-load-addr mappings, built in ASM, were not using
global PTEs.  That's been broken since at least the x86_64 port.  The
rest of the KERNBASE mapping, set up in vm_init(), was using the global
entries, but the lower 512 GB (i.e., most of the RAM) was ignored.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/arch/x86/cpuinfo.c
kern/arch/x86/entry64.S
kern/arch/x86/pmap64.c

index d72cb17..0bbed99 100644 (file)
@@ -206,7 +206,7 @@ void show_mapping(pgdir_t pgdir, uintptr_t start, size_t size)
        page_t *page;
        uintptr_t i;
 
-       printk("   %sVirtual    %sPhysical  Ps Dr Ac CD WT U W P EPTE\n",
+       printk("   %sVirtual    %sPhysical  Ps Dr Ac CD WT U W P EPTE\n",
               BIT_SPACING, BIT_SPACING);
        printk("-------------------------------------------------%s\n", BIT_DASHES);
        for(i = 0; i < size; i += PGSIZE, start += PGSIZE) {
@@ -222,11 +222,12 @@ void show_mapping(pgdir_t pgdir, uintptr_t start, size_t size)
                         * UVPT mapping requires the U to see interior pages (but have W
                         * off). */
                        perm = get_va_perms(pgdir, (void*)start);
-                       printk("%p  %1d  %1d  %1d  %1d  %1d  %1d %1d %1d 0x%llx\n",
+                       printk("%p  %1d  %1d  %1d  %1d %1d  %1d  %1d %1d %1d 0x%llx\n",
                               pte_get_paddr(pte),
                               pte_is_jumbo(pte),
                               pte_is_dirty(pte),
                               pte_is_accessed(pte),
+                              (pte_print(pte) & PTE_G) / PTE_G,
                               (pte_print(pte) & __PTE_PCD) / __PTE_PCD,
                               (pte_print(pte) & __PTE_PWT) / __PTE_PWT,
                               (perm & PTE_U) / PTE_U,
index 65141c9..eeed1fc 100644 (file)
@@ -115,7 +115,7 @@ fill_jpml3:
 1:
        movl    %ecx, %eax
        shll    $30, %eax                                       # lower part of PTE ADDR
-       orl             $(PTE_P | PTE_W | PTE_PS), %eax
+       orl             $(PTE_P | PTE_W | PTE_PS | PTE_G), %eax
        movl    %eax, (%edi, %esi, 8)
        movl    %ecx, %eax
        shrl    $2, %eax                                        # upper part of PTE ADDR
@@ -245,7 +245,7 @@ fill_jpml2:
 1:
        movl    %ecx, %eax
        shll    $21, %eax                                       # lower part of PTE ADDR
-       orl             $(PTE_P | PTE_W | PTE_PS), %eax
+       orl             $(PTE_P | PTE_W | PTE_PS | PTE_G), %eax
        movl    %eax, (%edi, %esi, 8)
        movl    %ecx, %eax
        shrl    $11, %eax                                       # upper part of PTE ADDR
@@ -264,7 +264,7 @@ fill_jpml2:
 insert_pml3:
        shrl    $7, %esi        # want to shift vaddr >> 39
        andl    $0x1ff, %esi
-       orl             $(PTE_P | PTE_W), %edi
+       orl             $(PTE_P | PTE_W | PTE_G), %edi
        movl    %edi, (%ecx, %esi, 8)
        movl    $0x0, 4(%ecx, %esi, 8)  # being clever, i know upper bits are 0
        ret
@@ -278,7 +278,7 @@ insert_pml2:
        shrl    $30, %edx
        orl             %edx, %esi
        andl    $0x1ff, %esi
-       orl             $(PTE_P | PTE_W), %edi
+       orl             $(PTE_P | PTE_W | PTE_G), %edi
        movl    %edi, (%ecx, %esi, 8)
        movl    $0x0, 4(%ecx, %esi, 8)  # being clever, i know upper bits are 0
        ret
index 4fd7ae7..e5b149d 100644 (file)
@@ -491,7 +491,7 @@ void x86_cleanup_bootmem(void)
         * anything - it just unmaps but leave 2 KPTs (4 pages) sitting around. */
        //unmap_segment(boot_pgdir, 0, PML3_PTE_REACH); // want to do this
        boot_pgdir.kpte[0] = 0;
-       tlbflush();
+       tlb_flush_global();
 }
 
 /* Walks len bytes from start, executing 'callback' on every PTE, passing it a