summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Shalayeff <mickey@cvs.openbsd.org>2004-02-23 08:32:37 +0000
committerMichael Shalayeff <mickey@cvs.openbsd.org>2004-02-23 08:32:37 +0000
commit275222c05e633e180ac7dc89572ff77c018eb8b6 (patch)
tree663aaeb11275b433893e9c3d546a3d688d24ed33
parent44c8c435873ec61b5ce0f10cd3d6ab136be6b737 (diff)
get use of NX; partially from netbsd; passes the regress; deraadt@ ok
-rw-r--r--sys/arch/amd64/amd64/cpu.c5
-rw-r--r--sys/arch/amd64/amd64/locore.S7
-rw-r--r--sys/arch/amd64/amd64/pmap.c36
-rw-r--r--sys/arch/amd64/amd64/trap.c7
-rw-r--r--sys/arch/amd64/include/pmap.h3
-rw-r--r--sys/arch/amd64/include/pte.h6
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