summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorMichael Shalayeff <mickey@cvs.openbsd.org>2003-05-02 21:07:51 +0000
committerMichael Shalayeff <mickey@cvs.openbsd.org>2003-05-02 21:07:51 +0000
commit9ac64af7926d77ca1bc84977a4249c91059065ca (patch)
tree0a9d578f0b0bf1bbfe67673feacc082c00dbc24c /sys/arch
parenta308b37fbda7c0e311d0dde3871c5bd212495871 (diff)
when flipping the code descriptors also update cs in the
tss and not only in the frame since we might be returning that way too. add a heuristic for detecting an exec protection fault: iff we get a read protection fault (which we normally never get due to our segments being always readable) we assume that it was an exec protection indeed and go to page fault routine which will decide the rest for us (including sending a signal should that be needed). problem found by drahn@ and testing by many ppl.
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/i386/i386/pmap.c9
-rw-r--r--sys/arch/i386/i386/trap.c10
-rw-r--r--sys/arch/i386/include/pcb.h3
-rw-r--r--sys/arch/i386/include/tss.h4
4 files changed, 15 insertions, 11 deletions
diff --git a/sys/arch/i386/i386/pmap.c b/sys/arch/i386/i386/pmap.c
index 1fc27e278a0..341f2d72c39 100644
--- a/sys/arch/i386/i386/pmap.c
+++ b/sys/arch/i386/i386/pmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.c,v 1.68 2003/04/17 03:56:20 drahn Exp $ */
+/* $OpenBSD: pmap.c,v 1.69 2003/05/02 21:07:47 mickey Exp $ */
/* $NetBSD: pmap.c,v 1.91 2000/06/02 17:46:37 thorpej Exp $ */
/*
@@ -579,17 +579,20 @@ pmap_nxstack_account(struct pmap *pmap, vaddr_t va,
va < VM_MAXUSER_ADDRESS && va >= 0x40000000) {
struct trapframe *tf = curproc->p_md.md_regs;
struct vm_map *map = &curproc->p_vmspace->vm_map;
+ struct pcb *pcb = &curproc->p_addr->u_pcb;
if (npte & PG_X && !(opte & PG_X)) {
if (++pmap->pm_nxpages == 1 &&
pmap == vm_map_pmap(map)) {
- tf->tf_cs = GSEL(GUCODE1_SEL, SEL_UPL);
+ pcb->pcb_cs = tf->tf_cs =
+ GSEL(GUCODE1_SEL, SEL_UPL);
pmap_update_pg(va);
}
} else {
if (!--pmap->pm_nxpages &&
pmap == vm_map_pmap(map)) {
- tf->tf_cs = GSEL(GUCODE_SEL, SEL_UPL);
+ pcb->pcb_cs = tf->tf_cs =
+ GSEL(GUCODE_SEL, SEL_UPL);
pmap_update_pg(va);
}
}
diff --git a/sys/arch/i386/i386/trap.c b/sys/arch/i386/i386/trap.c
index 8827ecd6a1d..68c6f74eac5 100644
--- a/sys/arch/i386/i386/trap.c
+++ b/sys/arch/i386/i386/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.53 2003/01/16 04:15:17 art Exp $ */
+/* $OpenBSD: trap.c,v 1.54 2003/05/02 21:07:48 mickey Exp $ */
/* $NetBSD: trap.c,v 1.95 1996/05/05 06:50:02 mycroft Exp $ */
/*-
@@ -325,9 +325,9 @@ trap(frame)
goto out;
}
#endif
- sv.sival_int = rcr2();
- trapsignal(p, SIGSEGV, vftype, SEGV_MAPERR, sv);
- goto out;
+ if (ftype == VM_PROT_READ)
+ ftype |= VM_PROT_EXECUTE;
+ goto page_fault;
case T_TSSFLT|T_USER:
sv.sival_int = frame.tf_eip;
@@ -411,7 +411,7 @@ trap(frame)
goto we_re_toast;
#endif
/* FALLTHROUGH */
-
+ page_fault:
case T_PAGEFLT|T_USER: { /* page fault */
vaddr_t va, fa;
struct vmspace *vm = p->p_vmspace;
diff --git a/sys/arch/i386/include/pcb.h b/sys/arch/i386/include/pcb.h
index 18d135096cc..889bdc95397 100644
--- a/sys/arch/i386/include/pcb.h
+++ b/sys/arch/i386/include/pcb.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcb.h,v 1.7 2001/03/24 18:11:48 millert Exp $ */
+/* $OpenBSD: pcb.h,v 1.8 2003/05/02 21:07:50 mickey Exp $ */
/* $NetBSD: pcb.h,v 1.21 1996/01/08 13:51:42 mycroft Exp $ */
/*-
@@ -61,6 +61,7 @@ struct pcb {
#define pcb_cr3 pcb_tss.tss_cr3
#define pcb_esp pcb_tss.tss_esp
#define pcb_ebp pcb_tss.tss_ebp
+#define pcb_cs pcb_tss.tss_cs
#define pcb_fs pcb_tss.tss_fs
#define pcb_gs pcb_tss.tss_gs
#define pcb_ldt_sel pcb_tss.tss_ldt
diff --git a/sys/arch/i386/include/tss.h b/sys/arch/i386/include/tss.h
index 2ca42328a0d..5d47b1160f7 100644
--- a/sys/arch/i386/include/tss.h
+++ b/sys/arch/i386/include/tss.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tss.h,v 1.4 2000/08/05 22:07:33 niklas Exp $ */
+/* $OpenBSD: tss.h,v 1.5 2003/05/02 21:07:50 mickey Exp $ */
/* $NetBSD: tss.h,v 1.6 1995/10/11 04:20:28 mycroft Exp $ */
/*-
@@ -66,7 +66,7 @@ struct i386tss {
int __tss_esi;
int __tss_edi;
int __tss_es;
- int __tss_cs;
+ int tss_cs;
int __tss_ss;
int __tss_ds;
int tss_fs; /* saved segment register */