Enable the NX bit and use it in the PAE pmap code. PAE is still disabled
authorkettenis <kettenis@openbsd.org>
Fri, 24 Apr 2015 12:52:38 +0000 (12:52 +0000)
committerkettenis <kettenis@openbsd.org>
Fri, 24 Apr 2015 12:52:38 +0000 (12:52 +0000)
while we're chasing at least one remaining bug.

ok mlarkin@, deraadt@

sys/arch/i386/i386/locore.s
sys/arch/i386/i386/mptramp.s
sys/arch/i386/i386/pmapae.c
sys/arch/i386/i386/trap.c

index 7413d2b..bb8a1d3 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: locore.s,v 1.154 2015/04/19 06:27:17 sf Exp $ */
+/*     $OpenBSD: locore.s,v 1.155 2015/04/24 12:52:38 kettenis Exp $   */
 /*     $NetBSD: locore.s,v 1.145 1996/05/03 19:41:19 christos Exp $    */
 
 /*-
@@ -1669,7 +1669,7 @@ ENTRY(i686_pagezero)
 ENTRY(cpu_paenable)
        movl    $-1, %eax
        testl   $CPUID_PAE, _C_LABEL(cpu_feature)
-       jz      1f
+       jz      2f
 
        pushl   %esi
        pushl   %edi
@@ -1682,9 +1682,28 @@ ENTRY(cpu_paenable)
        cld
        rep
        movsl
+
        movl    %cr4, %eax
        orl     $CR4_PAE, %eax
        movl    %eax, %cr4      /* BANG!!! */
+
+       movl    $MSR_EFER,%ecx
+       rdmsr
+       movl    %edx, %edi              # %edx is needed by wrmsr below
+
+       # Check if we need to enable NXE
+       movl    $0x80000001, %eax
+       cpuid
+       andl    $CPUID_NXE, %edx
+       xorl    %eax,%eax
+       testl   %edx, %edx
+       jz      1f
+       orl     $EFER_NXE, %eax
+1:
+       movl    %edi, %edx              # Restore saved %edx
+       movl    $MSR_EFER,%ecx
+       wrmsr
+
        movl    12(%esp), %eax
        subl    $KERNBASE, %eax
        movl    %eax, %cr3      /* reload real PDPT */
@@ -1694,7 +1713,7 @@ ENTRY(cpu_paenable)
        xorl    %eax, %eax
        popl    %edi
        popl    %esi
-1:
+2:
        ret
 
 /*
index 02efc76..a6e80b8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: mptramp.s,v 1.15 2015/04/12 18:37:53 mlarkin Exp $    */
+/*     $OpenBSD: mptramp.s,v 1.16 2015/04/24 12:52:38 kettenis Exp $   */
 
 /*-
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -167,6 +167,24 @@ _TRMP_LABEL(mp_startup)
        movl    %cr4,%eax
        orl     $CR4_PAE,%eax
        movl    %eax, %cr4
+       
+       movl    $MSR_EFER,%ecx
+       rdmsr
+       movl    %edx, %edi              # %edx is needed by wrmsr below
+
+       # Check if we need to enable NXE
+       movl    $0x80000001, %eax
+       cpuid
+       andl    $CPUID_NXE, %edx
+       xorl    %eax,%eax
+       testl   %edx, %edx
+       jz      1f
+       orl     $EFER_NXE, %eax
+1:
+       movl    %edi, %edx              # Restore saved %edx
+       movl    $MSR_EFER,%ecx
+       wrmsr
+
 nopae:
 #endif
        movl    %cr0,%eax               # get control word
index 98812f7..af13312 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: pmapae.c,v 1.33 2015/04/22 06:26:23 mlarkin Exp $     */
+/*     $OpenBSD: pmapae.c,v 1.34 2015/04/24 12:52:38 kettenis Exp $    */
 
 /*
  * Copyright (c) 2006-2008 Michael Shalayeff
@@ -423,6 +423,7 @@ typedef u_int64_t pt_entry_t;               /* PTE */
 
 extern u_int32_t protection_codes[];   /* maps MI prot to i386 prot code */
 extern boolean_t pmap_initialized;     /* pmap_init done yet? */
+pt_entry_t pg_nx;
 
 /*
  * MULTIPROCESSOR: special VA's/ PTE's are actually allocated inside a
@@ -595,6 +596,8 @@ pmap_bootstrap_pae()
        }
 
        cpu_pae = 1;
+       if (ecpu_feature & CPUID_NXE)
+               pg_nx = (1ULL << 63);
 
        va = (vaddr_t)kpm->pm_pdir;
        kpm->pm_pdidx[0] = (va + 0*NBPG - KERNBASE) | PG_V;
@@ -1313,7 +1316,7 @@ pmap_write_protect_pae(struct pmap *pmap, vaddr_t sva, vaddr_t eva,
 {
        pt_entry_t *ptes, *spte, *epte, npte, opte;
        vaddr_t blockend;
-       u_int32_t md_prot;
+       u_int64_t md_prot;
        vaddr_t va;
        int shootall = 0;
 
@@ -1349,6 +1352,8 @@ pmap_write_protect_pae(struct pmap *pmap, vaddr_t sva, vaddr_t eva,
                        continue;
 
                md_prot = protection_codes[prot];
+               if (!(prot & PROT_EXEC))
+                       md_prot |= pg_nx;
                if (va < VM_MAXUSER_ADDRESS)
                        md_prot |= PG_u;
                else if (va < VM_MAX_ADDRESS)
@@ -1604,6 +1609,8 @@ enter_now:
         */
 
        npte = pa | protection_codes[prot] | PG_V;
+       if (!(prot & PROT_EXEC))
+               npte |= pg_nx;
        pmap_exec_account(pmap, va, opte, npte);
        if (wired)
                npte |= PG_W;
index e277cdf..9843a2b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: trap.c,v 1.121 2015/04/18 05:14:05 guenther Exp $     */
+/*     $OpenBSD: trap.c,v 1.122 2015/04/24 12:52:38 kettenis Exp $     */
 /*     $NetBSD: trap.c,v 1.95 1996/05/05 06:50:02 mycroft Exp $        */
 
 /*-
@@ -140,6 +140,8 @@ trap(struct trapframe *frame)
        if (frame->tf_err & PGEX_W) {
                vftype = PROT_WRITE;
                ftype = PROT_READ | PROT_WRITE;
+       } else if (frame->tf_err & PGEX_I) {
+               ftype = vftype = PROT_EXEC;
        } else
                ftype = vftype = PROT_READ;