remove all PG_G global page mappings from the kernel when running on
authormlarkin <mlarkin@openbsd.org>
Sun, 7 Jan 2018 19:56:19 +0000 (19:56 +0000)
committermlarkin <mlarkin@openbsd.org>
Sun, 7 Jan 2018 19:56:19 +0000 (19:56 +0000)
Intel CPUs. Part of an ongoing set of commits to mitigate the Intel
"meltdown" CVE. This diff does not confer any immunity to that
vulnerability - subsequent commits are still needed and are being
worked on presently.

ok guenther, deraadt

sys/arch/amd64/amd64/locore.S
sys/arch/amd64/amd64/locore0.S
sys/arch/amd64/amd64/pmap.c
sys/arch/amd64/include/pte.h

index 2b85fc6..6e00ce3 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: locore.S,v 1.92 2018/01/06 22:03:12 guenther Exp $    */
+/*     $OpenBSD: locore.S,v 1.93 2018/01/07 19:56:19 mlarkin Exp $     */
 /*     $NetBSD: locore.S,v 1.13 2004/03/25 18:33:17 drochner Exp $     */
 
 /*
@@ -175,6 +175,7 @@ _C_LABEL(lapic_isr):
        .globl  _C_LABEL(biosbasemem)
        .globl  _C_LABEL(bootapiver)
        .globl  _C_LABEL(pg_nx)
+       .globl  _C_LABEL(pg_g_kern)
 _C_LABEL(cpu_id):      .long   0       # saved from `cpuid' instruction
 _C_LABEL(cpu_feature): .long   0       # feature flags from 'cpuid'
                                        #   instruction
@@ -207,6 +208,9 @@ _C_LABEL(biosextmem):       .long   0       # extended memory reported by BIOS
 _C_LABEL(biosextmem):  .long   REALEXTMEM
 #endif
 _C_LABEL(pg_nx):       .quad   0       # NX PTE bit (if CPU supports)
+_C_LABEL(pg_g_kern):   .quad   0       # 0x100 if global pages should be used
+                                       # in kernel mappings, 0 otherwise (for
+                                       # Intel)
 
 #define        _RELOC(x)       ((x) - KERNBASE)
 #define        RELOC(x)        _RELOC(_C_LABEL(x))
index aacda66..50f0c7e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: locore0.S,v 1.5 2017/10/14 21:42:17 mlarkin Exp $     */
+/*     $OpenBSD: locore0.S,v 1.6 2018/01/07 19:56:19 mlarkin Exp $     */
 /*     $NetBSD: locore.S,v 1.13 2004/03/25 18:33:17 drochner Exp $     */
 
 /*
@@ -204,6 +204,27 @@ bi_size_ok:
        movl    %ecx,8(%ebp)
        movl    $0,  12(%ebp)
 
+       /*
+        * Determine if CPU is Intel. Intel CPUs cannot use PG_G (global
+        * pages) in kernel mappings. If CPU is not Intel, this is safe.
+        * Cache the result in pg_g_kern - 0 if not supported or PG_G (0x100)
+        * if supported.
+        *
+        * This treatment is required for the meltdown CVE mitigation.
+        */
+       cmpl    $0x756e6547, %ebx       # "Genu"
+       jne     not_intel
+       cmpl    $0x6c65746e, %ecx       # "ntel"
+       jne     not_intel
+       cmpl    $0x49656e69, %edx       # "ineI"
+       jne     not_intel
+
+       jmp     pg_g_check_finished
+
+not_intel:
+       movl    $PG_G, RELOC(pg_g_kern)
+
+pg_g_check_finished:
        movl    $1,%eax
        cpuid
        movl    %eax,RELOC(cpu_id)
@@ -470,7 +491,8 @@ map_tables:
        leal    (PROC0_DMP2_OFF)(%esi), %ebx
        xorl    %eax, %eax
        movl    $(NDML2_ENTRIES * NPDPG), %ecx
-1:     orl     $(PG_V|PG_KW|PG_PS|PG_G), %eax
+1:     orl     $(PG_V|PG_KW|PG_PS), %eax
+       orl     RELOC(pg_g_kern), %eax
        cmpl    $__kernel_base_phys, %eax
        jl      store_pte
        cmpl    $__kernel_end_phys, %eax
index 85598ee..bb7ba39 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: pmap.c,v 1.107 2018/01/07 05:35:10 mlarkin Exp $      */
+/*     $OpenBSD: pmap.c,v 1.108 2018/01/07 19:56:19 mlarkin Exp $      */
 /*     $NetBSD: pmap.c,v 1.3 2003/05/08 18:13:13 thorpej Exp $ */
 
 /*
@@ -513,7 +513,7 @@ pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot)
 
        /* special 1:1 mappings in the first 2MB must not be global */
        if (va >= (vaddr_t)NBPD_L2)
-               npte |= PG_G;
+               npte |= pg_g_kern;
 
        if (!(prot & PROT_EXEC))
                npte |= pg_nx;
@@ -655,7 +655,7 @@ pmap_bootstrap(paddr_t first_avail, paddr_t max_pa)
             kva += PAGE_SIZE) {
                p1i = pl1_i(kva);
                if (pmap_valid_entry(PTE_BASE[p1i]))
-                       PTE_BASE[p1i] |= PG_G;
+                       PTE_BASE[p1i] |= pg_g_kern;
        }
 
        /*
@@ -680,7 +680,7 @@ pmap_bootstrap(paddr_t first_avail, paddr_t max_pa)
                va = PMAP_DIRECT_MAP(pdp);
 
                *((pd_entry_t *)va) = ((paddr_t)i << L2_SHIFT);
-               *((pd_entry_t *)va) |= PG_RW | PG_V | PG_PS | PG_G | PG_U |
+               *((pd_entry_t *)va) |= PG_RW | PG_V | PG_PS | pg_g_kern | PG_U |
                    PG_M | pg_nx;
        }
 
@@ -2155,7 +2155,7 @@ enter_now:
        else if (va < VM_MAX_ADDRESS)
                npte |= (PG_u | PG_RW); /* XXXCDC: no longer needed? */
        if (pmap == pmap_kernel())
-               npte |= PG_G;
+               npte |= pg_g_kern;
 
        ptes[pl1_i(va)] = npte;         /* zap! */
 
index 8aa59ae..397ec75 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: pte.h,v 1.13 2015/11/09 00:49:33 mlarkin Exp $        */
+/*     $OpenBSD: pte.h,v 1.14 2018/01/07 19:56:19 mlarkin Exp $        */
 /*     $NetBSD: pte.h,v 1.1 2003/04/26 18:39:47 fvdl Exp $     */
 
 /*
@@ -158,6 +158,7 @@ typedef u_int64_t pt_entry_t;               /* PTE */
 
 #ifdef _KERNEL
 extern pt_entry_t pg_nx;       /* NX pte bit */
+extern pt_entry_t pg_g_kern;   /* PG_G if glbl mappings can be used in kern */
 #endif /* _KERNEL */
 
 #endif /* _MACHINE_PTE_H_ */