diff options
author | Michael Shalayeff <mickey@cvs.openbsd.org> | 2004-02-23 08:32:37 +0000 |
---|---|---|
committer | Michael Shalayeff <mickey@cvs.openbsd.org> | 2004-02-23 08:32:37 +0000 |
commit | 275222c05e633e180ac7dc89572ff77c018eb8b6 (patch) | |
tree | 663aaeb11275b433893e9c3d546a3d688d24ed33 | |
parent | 44c8c435873ec61b5ce0f10cd3d6ab136be6b737 (diff) |
get use of NX; partially from netbsd; passes the regress; deraadt@ ok
-rw-r--r-- | sys/arch/amd64/amd64/cpu.c | 5 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/locore.S | 7 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/pmap.c | 36 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/trap.c | 7 | ||||
-rw-r--r-- | sys/arch/amd64/include/pmap.h | 3 | ||||
-rw-r--r-- | sys/arch/amd64/include/pte.h | 6 |
6 files changed, 43 insertions, 21 deletions
diff --git a/sys/arch/amd64/amd64/cpu.c b/sys/arch/amd64/amd64/cpu.c index d58a8acb3ce..ee181c1938a 100644 --- a/sys/arch/amd64/amd64/cpu.c +++ b/sys/arch/amd64/amd64/cpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.c,v 1.1 2004/01/28 01:39:38 mickey Exp $ */ +/* $OpenBSD: cpu.c,v 1.2 2004/02/23 08:32:36 mickey Exp $ */ /* $NetBSD: cpu.c,v 1.1 2003/04/26 18:39:26 fvdl Exp $ */ /*- @@ -696,4 +696,7 @@ cpu_init_msrs(struct cpu_info *ci) wrmsr(MSR_FSBASE, 0); wrmsr(MSR_GSBASE, (u_int64_t)ci); wrmsr(MSR_KERNELGSBASE, 0); + + if (cpu_feature & CPUID_NXE) + wrmsr(MSR_EFER, rdmsr(MSR_EFER) | EFER_NXE); } diff --git a/sys/arch/amd64/amd64/locore.S b/sys/arch/amd64/amd64/locore.S index 2d328dc7d51..b680bd86f36 100644 --- a/sys/arch/amd64/amd64/locore.S +++ b/sys/arch/amd64/amd64/locore.S @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.S,v 1.6 2004/02/23 01:19:52 tom Exp $ */ +/* $OpenBSD: locore.S,v 1.7 2004/02/23 08:32:36 mickey Exp $ */ /* $NetBSD: locore.S,v 1.2 2003/04/26 19:34:45 fvdl Exp $ */ /* @@ -320,6 +320,11 @@ start: movw $0x1234,0x472 # warm boot movl %eax,RELOC(cpu_id) movl %edx,RELOC(cpu_feature) + movl $0x80000001, %eax + cpuid + andl $CPUID_NXE, %edx /* other bits may clash */ + orl %edx, RELOC(cpu_feature) + /* Brand ID is bits 0-7 of %ebx */ andl $255,%ebx movl %ebx,RELOC(cpu_brand_id) diff --git a/sys/arch/amd64/amd64/pmap.c b/sys/arch/amd64/amd64/pmap.c index e933e8855a2..30c65946713 100644 --- a/sys/arch/amd64/amd64/pmap.c +++ b/sys/arch/amd64/amd64/pmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.c,v 1.2 2004/02/09 22:41:14 mickey Exp $ */ +/* $OpenBSD: pmap.c,v 1.3 2004/02/23 08:32:36 mickey Exp $ */ /* $NetBSD: pmap.c,v 1.3 2003/05/08 18:13:13 thorpej Exp $ */ /* @@ -779,6 +779,8 @@ pmap_kenter_pa(va, pa, prot) npte = pa | ((prot & VM_PROT_WRITE) ? PG_RW : PG_RO) | PG_V | pmap_pg_g; + if ((cpu_feature & CPUID_NXE) && !(prot & VM_PROT_EXECUTE)) + npte |= PG_NX; opte = pmap_pte_set(pte, npte); /* zap! */ #ifdef LARGEPAGES /* XXX For now... */ @@ -866,6 +868,7 @@ pmap_bootstrap(kva_start) pt_entry_t *pte; int i; unsigned long p1i; + pt_entry_t pg_nx = (cpu_feature & CPUID_NXE? PG_NX : 0); /* * define the voundaries of the managed kernel virtual address @@ -880,13 +883,14 @@ pmap_bootstrap(kva_start) * we can jam into a i386 PTE. */ - protection_codes[VM_PROT_NONE] = 0; /* --- */ + protection_codes[VM_PROT_NONE] = pg_nx; /* --- */ protection_codes[VM_PROT_EXECUTE] = PG_RO; /* --x */ - protection_codes[VM_PROT_READ] = PG_RO; /* -r- */ + protection_codes[VM_PROT_READ] = PG_RO | pg_nx; /* -r- */ protection_codes[VM_PROT_READ|VM_PROT_EXECUTE] = PG_RO; /* -rx */ - protection_codes[VM_PROT_WRITE] = PG_RW; /* w-- */ + protection_codes[VM_PROT_WRITE] = PG_RW | pg_nx; /* w-- */ protection_codes[VM_PROT_WRITE|VM_PROT_EXECUTE] = PG_RW;/* w-x */ - protection_codes[VM_PROT_WRITE|VM_PROT_READ] = PG_RW; /* wr- */ + protection_codes[VM_PROT_WRITE|VM_PROT_READ] = PG_RW | pg_nx; + /* wr- */ protection_codes[VM_PROT_ALL] = PG_RW; /* wrx */ /* @@ -2199,7 +2203,7 @@ pmap_extract(pmap, va, pap) #ifdef LARGEPAGES if (pde & PG_PS) { if (pap != NULL) - *pap = (pde & PG_LGFRAME) | (va & ~PG_LGFRAME); + *pap = (pde & PG_LGFRAME) | (va & 0x1fffff); return (TRUE); } #endif @@ -2207,7 +2211,7 @@ pmap_extract(pmap, va, pap) if (__predict_true((pte & PG_V) != 0)) { if (pap != NULL) - *pap = (pte & PG_FRAME) | (va & ~PG_FRAME); + *pap = (pte & PG_FRAME) | (va & 0xfff); return (TRUE); } @@ -2937,7 +2941,7 @@ pmap_write_protect(pmap, sva, eva, prot) vaddr_t sva, eva; vm_prot_t prot; { - pt_entry_t *ptes, *spte, *epte; + pt_entry_t nx, opte, *ptes, *spte, *epte; pd_entry_t **pdes; vaddr_t blockend; int32_t cpumask = 0; @@ -2948,6 +2952,10 @@ pmap_write_protect(pmap, sva, eva, prot) sva &= PG_FRAME; eva &= PG_FRAME; + nx = 0; + if ((cpu_feature & CPUID_NXE) && !(prot & VM_PROT_EXECUTE)) + nx = PG_NX; + for (/* null */ ; sva < eva ; sva = blockend) { blockend = (sva & L2_FRAME) + NBPD_L2; @@ -2972,8 +2980,7 @@ pmap_write_protect(pmap, sva, eva, prot) continue; #ifdef DIAGNOSTIC - if (sva >= VM_MAXUSER_ADDRESS && - sva < VM_MAX_ADDRESS) + if (sva >= VM_MAXUSER_ADDRESS && sva < VM_MAX_ADDRESS) panic("pmap_write_protect: PTE space"); #endif @@ -2981,11 +2988,14 @@ pmap_write_protect(pmap, sva, eva, prot) epte = &ptes[pl1_i(blockend)]; for (/*null */; spte < epte ; spte++) { - if ((*spte & (PG_RW|PG_V)) == (PG_RW|PG_V)) { - pmap_pte_clearbits(spte, PG_RW); + if (!(*spte & PG_V)) + continue; + opte = *spte; + pmap_pte_clearbits(spte, PG_RW); + pmap_pte_setbits(spte, nx); + if (opte != *spte) pmap_tlb_shootdown(pmap, ptob(spte - ptes), *spte, &cpumask); - } } } diff --git a/sys/arch/amd64/amd64/trap.c b/sys/arch/amd64/amd64/trap.c index f543c8c843c..91bb63f9afa 100644 --- a/sys/arch/amd64/amd64/trap.c +++ b/sys/arch/amd64/amd64/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.2 2004/02/20 22:35:12 deraadt Exp $ */ +/* $OpenBSD: trap.c,v 1.3 2004/02/23 08:32:36 mickey Exp $ */ /* $NetBSD: trap.c,v 1.2 2003/05/04 23:51:56 fvdl Exp $ */ /*- @@ -428,6 +428,8 @@ faultcommon: map = &vm->vm_map; if (frame.tf_err & PGEX_W) ftype = VM_PROT_WRITE; + else if (frame.tf_err & PGEX_I) + ftype = VM_PROT_EXECUTE; else ftype = VM_PROT_READ; @@ -460,7 +462,8 @@ faultcommon: /* Fault the original page in. */ onfault = pcb->pcb_onfault; pcb->pcb_onfault = NULL; - error = uvm_fault(map, va, 0, ftype); + error = uvm_fault(map, va, frame.tf_err & PGEX_P? + VM_FAULT_PROTECT : VM_FAULT_INVALID, ftype); pcb->pcb_onfault = onfault; if (error == 0) { if (nss > (u_long)vm->vm_ssize) diff --git a/sys/arch/amd64/include/pmap.h b/sys/arch/amd64/include/pmap.h index a9366187930..bc21c685339 100644 --- a/sys/arch/amd64/include/pmap.h +++ b/sys/arch/amd64/include/pmap.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.h,v 1.1 2004/01/28 01:39:39 mickey Exp $ */ +/* $OpenBSD: pmap.h,v 1.2 2004/02/23 08:32:36 mickey Exp $ */ /* $NetBSD: pmap.h,v 1.1 2003/04/26 18:39:46 fvdl Exp $ */ /* @@ -572,6 +572,7 @@ kvtopte(vaddr_t va) #define pmap_pte_set(p, n) x86_atomic_testset_u64(p, n) #define pmap_pte_clearbits(p, b) x86_atomic_clearbits_u64(p, b) +#define pmap_pte_setbits(p, b) x86_atomic_setbits_u64(p, b) #define pmap_cpu_has_pg_n() (1) #define pmap_cpu_has_invlpg (1) diff --git a/sys/arch/amd64/include/pte.h b/sys/arch/amd64/include/pte.h index 842c49c4b8d..bc262c0d93e 100644 --- a/sys/arch/amd64/include/pte.h +++ b/sys/arch/amd64/include/pte.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pte.h,v 1.3 2004/02/07 17:00:15 miod Exp $ */ +/* $OpenBSD: pte.h,v 1.4 2004/02/23 08:32:36 mickey Exp $ */ /* $NetBSD: pte.h,v 1.1 2003/04/26 18:39:47 fvdl Exp $ */ /* @@ -115,9 +115,9 @@ typedef u_int64_t pt_entry_t; /* PTE */ #define PG_AVAIL2 0x0000000000000400UL #define PG_AVAIL3 0x0000000000000800UL #define PG_NX 0x8000000000000000UL /* non-executable */ -#define PG_FRAME 0xfffffffffffff000UL +#define PG_FRAME 0x000ffffffffff000UL -#define PG_LGFRAME 0xffffffffffc00000UL /* large (2M) page frame mask */ +#define PG_LGFRAME 0x000fffffffc00000UL /* large (2M) page frame mask */ /* * short forms of protection codes |