diff options
-rw-r--r-- | sys/amd64/amd64/cpu_switch.S | 14 | ||||
-rw-r--r-- | sys/amd64/amd64/genassym.c | 4 | ||||
-rw-r--r-- | sys/amd64/amd64/machdep.c | 10 | ||||
-rw-r--r-- | sys/amd64/amd64/swtch.s | 14 | ||||
-rw-r--r-- | sys/amd64/amd64/trap.c | 21 | ||||
-rw-r--r-- | sys/amd64/include/md_var.h | 4 | ||||
-rw-r--r-- | sys/amd64/include/pcb.h | 6 | ||||
-rw-r--r-- | sys/amd64/include/reg.h | 14 | ||||
-rw-r--r-- | sys/i386/i386/genassym.c | 4 | ||||
-rw-r--r-- | sys/i386/i386/machdep.c | 10 | ||||
-rw-r--r-- | sys/i386/i386/swtch.s | 14 | ||||
-rw-r--r-- | sys/i386/i386/trap.c | 21 | ||||
-rw-r--r-- | sys/i386/include/md_var.h | 4 | ||||
-rw-r--r-- | sys/i386/include/pcb.h | 6 | ||||
-rw-r--r-- | sys/i386/include/reg.h | 14 | ||||
-rw-r--r-- | sys/kern/subr_trap.c | 21 |
16 files changed, 163 insertions, 18 deletions
diff --git a/sys/amd64/amd64/cpu_switch.S b/sys/amd64/amd64/cpu_switch.S index 094e75b..923d694 100644 --- a/sys/amd64/amd64/cpu_switch.S +++ b/sys/amd64/amd64/cpu_switch.S @@ -33,7 +33,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: swtch.s,v 1.50 1997/05/29 05:11:11 peter Exp $ + * $Id: swtch.s,v 1.51 1997/05/31 09:27:29 peter Exp $ */ #include "npx.h" @@ -336,6 +336,8 @@ ENTRY(cpu_switch) movl %ebp,PCB_EBP(%ecx) movl %esi,PCB_ESI(%ecx) movl %edi,PCB_EDI(%ecx) + movl %fs,PCB_FS(%ecx) + movl %gs,PCB_GS(%ecx) #ifdef SMP movl _mp_lock, %eax @@ -562,6 +564,14 @@ swtch_com: 2: #endif + /* This must be done after loading the user LDT. */ + .globl cpu_switch_load_fs +cpu_switch_load_fs: + movl PCB_FS(%edx),%fs + .globl cpu_switch_load_gs +cpu_switch_load_gs: + movl PCB_GS(%edx),%gs + sti ret @@ -592,6 +602,8 @@ ENTRY(savectx) movl %ebp,PCB_EBP(%ecx) movl %esi,PCB_ESI(%ecx) movl %edi,PCB_EDI(%ecx) + movl %fs,PCB_FS(%ecx) + movl %gs,PCB_GS(%ecx) #if NNPX > 0 /* diff --git a/sys/amd64/amd64/genassym.c b/sys/amd64/amd64/genassym.c index 18ecadc..d9473cf 100644 --- a/sys/amd64/amd64/genassym.c +++ b/sys/amd64/amd64/genassym.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)genassym.c 5.11 (Berkeley) 5/10/91 - * $Id: genassym.c,v 1.45 1997/04/26 11:45:06 peter Exp $ + * $Id: genassym.c,v 1.46 1997/05/10 08:01:13 bde Exp $ */ #include <stdio.h> @@ -127,6 +127,8 @@ main() printf("#define\tPCB_EIP %p\n", &pcb->pcb_eip); printf("#define\tTSS_ESP0 %p\n", &tss->tss_esp0); printf("#define\tPCB_USERLDT %p\n", &pcb->pcb_ldt); + printf("#define\tPCB_FS %p\n", &pcb->pcb_fs); + printf("#define\tPCB_GS %p\n", &pcb->pcb_gs); #ifdef SMP printf("#define\tPCB_MPNEST %p\n", &pcb->pcb_mpnest); #endif diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index 186541c..b59d92e 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 - * $Id: machdep.c,v 1.245 1997/05/26 18:40:45 fsmp Exp $ + * $Id: machdep.c,v 1.246 1997/06/02 08:19:03 dfr Exp $ */ #include "npx.h" @@ -1516,6 +1516,7 @@ fill_regs(p, regs) struct proc *p; struct reg *regs; { + struct pcb *pcb; struct trapframe *tp; tp = p->p_md.md_regs; @@ -1533,6 +1534,9 @@ fill_regs(p, regs) regs->r_eflags = tp->tf_eflags; regs->r_esp = tp->tf_esp; regs->r_ss = tp->tf_ss; + pcb = &p->p_addr->u_pcb; + regs->r_fs = pcb->pcb_fs; + regs->r_gs = pcb->pcb_gs; return (0); } @@ -1541,6 +1545,7 @@ set_regs(p, regs) struct proc *p; struct reg *regs; { + struct pcb *pcb; struct trapframe *tp; tp = p->p_md.md_regs; @@ -1561,6 +1566,9 @@ set_regs(p, regs) tp->tf_eflags = regs->r_eflags; tp->tf_esp = regs->r_esp; tp->tf_ss = regs->r_ss; + pcb = &p->p_addr->u_pcb; + pcb->pcb_fs = regs->r_fs; + pcb->pcb_gs = regs->r_gs; return (0); } diff --git a/sys/amd64/amd64/swtch.s b/sys/amd64/amd64/swtch.s index 094e75b..923d694 100644 --- a/sys/amd64/amd64/swtch.s +++ b/sys/amd64/amd64/swtch.s @@ -33,7 +33,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: swtch.s,v 1.50 1997/05/29 05:11:11 peter Exp $ + * $Id: swtch.s,v 1.51 1997/05/31 09:27:29 peter Exp $ */ #include "npx.h" @@ -336,6 +336,8 @@ ENTRY(cpu_switch) movl %ebp,PCB_EBP(%ecx) movl %esi,PCB_ESI(%ecx) movl %edi,PCB_EDI(%ecx) + movl %fs,PCB_FS(%ecx) + movl %gs,PCB_GS(%ecx) #ifdef SMP movl _mp_lock, %eax @@ -562,6 +564,14 @@ swtch_com: 2: #endif + /* This must be done after loading the user LDT. */ + .globl cpu_switch_load_fs +cpu_switch_load_fs: + movl PCB_FS(%edx),%fs + .globl cpu_switch_load_gs +cpu_switch_load_gs: + movl PCB_GS(%edx),%gs + sti ret @@ -592,6 +602,8 @@ ENTRY(savectx) movl %ebp,PCB_EBP(%ecx) movl %esi,PCB_ESI(%ecx) movl %edi,PCB_EDI(%ecx) + movl %fs,PCB_FS(%ecx) + movl %gs,PCB_GS(%ecx) #if NNPX > 0 /* diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c index f73c4f2..89dd34f 100644 --- a/sys/amd64/amd64/trap.c +++ b/sys/amd64/amd64/trap.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 - * $Id: trap.c,v 1.97 1997/05/31 09:27:29 peter Exp $ + * $Id: trap.c,v 1.98 1997/06/02 08:19:03 dfr Exp $ */ /* @@ -352,6 +352,25 @@ trap(frame) } while (0) if (intr_nesting_level == 0) { + /* + * Invalid %fs's and %gs's can be created using + * procfs or PT_SETREGS or by invalidating the + * underlying LDT entry. This causes a fault + * in kernel mode when the kernel attempts to + * switch contexts. Lose the bad context + * (XXX) so that we can continue, and generate + * a signal. + */ + if (frame.tf_eip == (int)cpu_switch_load_fs) { + curpcb->pcb_fs = 0; + psignal(p, SIGBUS); + return; + } + if (frame.tf_eip == (int)cpu_switch_load_gs) { + curpcb->pcb_gs = 0; + psignal(p, SIGBUS); + return; + } MAYBE_DORETI_FAULT(doreti_iret, doreti_iret_fault); MAYBE_DORETI_FAULT(doreti_popl_ds, diff --git a/sys/amd64/include/md_var.h b/sys/amd64/include/md_var.h index 307257c..a7e7856 100644 --- a/sys/amd64/include/md_var.h +++ b/sys/amd64/include/md_var.h @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: md_var.h,v 1.12 1997/02/22 09:34:49 peter Exp $ + * $Id: md_var.h,v 1.13 1997/03/22 18:53:08 kato Exp $ */ #ifndef _MACHINE_MD_VAR_H_ @@ -57,6 +57,8 @@ struct reg; void bcopyb __P((const void *from, void *to, size_t len)); void cpu_reset __P((void)); void cpu_halt __P((void)); +void cpu_switch_load_fs __P((void)) __asm(__STRING(cpu_switch_load_fs)); +void cpu_switch_load_gs __P((void)) __asm(__STRING(cpu_switch_load_gs)); void doreti_iret __P((void)) __asm(__STRING(doreti_iret)); void doreti_iret_fault __P((void)) __asm(__STRING(doreti_iret_fault)); void doreti_popl_ds __P((void)) __asm(__STRING(doreti_popl_ds)); diff --git a/sys/amd64/include/pcb.h b/sys/amd64/include/pcb.h index 1cbca02..c93ed87 100644 --- a/sys/amd64/include/pcb.h +++ b/sys/amd64/include/pcb.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)pcb.h 5.10 (Berkeley) 5/12/91 - * $Id: pcb.h,v 1.20 1997/04/26 11:45:39 peter Exp $ + * $Id: pcb.h,v 1.21 1997/05/07 19:49:32 peter Exp $ */ #ifndef _I386_PCB_H_ @@ -64,7 +64,9 @@ struct pcb { #define FP_SOFTFP 0x01 /* process using software fltng pnt emulator */ caddr_t pcb_onfault; /* copyin/out fault recovery */ u_long pcb_mpnest; - u_long __pcb_spare[7]; /* adjust to avoid core dump size changes */ + int pcb_fs; + int pcb_gs; + u_long __pcb_spare[5]; /* adjust to avoid core dump size changes */ #if 0 /* some day we may switch between procs that have their own i386tss */ struct i386tss pcb_tss; u_char pcb_iomap[NPORT/sizeof(u_char)]; /* i/o port bitmap */ diff --git a/sys/amd64/include/reg.h b/sys/amd64/include/reg.h index c896fe5..5d36f27 100644 --- a/sys/amd64/include/reg.h +++ b/sys/amd64/include/reg.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)reg.h 5.5 (Berkeley) 1/18/91 - * $Id: reg.h,v 1.13 1997/02/22 09:35:07 peter Exp $ + * $Id: reg.h,v 1.14 1997/06/07 00:49:45 bde Exp $ */ #ifndef _MACHINE_REG_H_ @@ -69,6 +69,16 @@ #define tSS (16) /* + * Indices for registers in `struct regs' only. + * + * Some registers live in the pcb and are only in an "array" with the + * other registers in application interfaces that copy all the registers + * to or from a `struct regs'. + */ +#define tFS (17) +#define tGS (18) + +/* * Register set accessible via /proc/$pid/regs and PT_{SET,GET}REGS. */ struct reg { @@ -89,6 +99,8 @@ struct reg { unsigned int r_eflags; unsigned int r_esp; unsigned int r_ss; + unsigned int r_fs; + unsigned int r_gs; }; /* diff --git a/sys/i386/i386/genassym.c b/sys/i386/i386/genassym.c index 18ecadc..d9473cf 100644 --- a/sys/i386/i386/genassym.c +++ b/sys/i386/i386/genassym.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)genassym.c 5.11 (Berkeley) 5/10/91 - * $Id: genassym.c,v 1.45 1997/04/26 11:45:06 peter Exp $ + * $Id: genassym.c,v 1.46 1997/05/10 08:01:13 bde Exp $ */ #include <stdio.h> @@ -127,6 +127,8 @@ main() printf("#define\tPCB_EIP %p\n", &pcb->pcb_eip); printf("#define\tTSS_ESP0 %p\n", &tss->tss_esp0); printf("#define\tPCB_USERLDT %p\n", &pcb->pcb_ldt); + printf("#define\tPCB_FS %p\n", &pcb->pcb_fs); + printf("#define\tPCB_GS %p\n", &pcb->pcb_gs); #ifdef SMP printf("#define\tPCB_MPNEST %p\n", &pcb->pcb_mpnest); #endif diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index 186541c..b59d92e 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 - * $Id: machdep.c,v 1.245 1997/05/26 18:40:45 fsmp Exp $ + * $Id: machdep.c,v 1.246 1997/06/02 08:19:03 dfr Exp $ */ #include "npx.h" @@ -1516,6 +1516,7 @@ fill_regs(p, regs) struct proc *p; struct reg *regs; { + struct pcb *pcb; struct trapframe *tp; tp = p->p_md.md_regs; @@ -1533,6 +1534,9 @@ fill_regs(p, regs) regs->r_eflags = tp->tf_eflags; regs->r_esp = tp->tf_esp; regs->r_ss = tp->tf_ss; + pcb = &p->p_addr->u_pcb; + regs->r_fs = pcb->pcb_fs; + regs->r_gs = pcb->pcb_gs; return (0); } @@ -1541,6 +1545,7 @@ set_regs(p, regs) struct proc *p; struct reg *regs; { + struct pcb *pcb; struct trapframe *tp; tp = p->p_md.md_regs; @@ -1561,6 +1566,9 @@ set_regs(p, regs) tp->tf_eflags = regs->r_eflags; tp->tf_esp = regs->r_esp; tp->tf_ss = regs->r_ss; + pcb = &p->p_addr->u_pcb; + pcb->pcb_fs = regs->r_fs; + pcb->pcb_gs = regs->r_gs; return (0); } diff --git a/sys/i386/i386/swtch.s b/sys/i386/i386/swtch.s index 094e75b..923d694 100644 --- a/sys/i386/i386/swtch.s +++ b/sys/i386/i386/swtch.s @@ -33,7 +33,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: swtch.s,v 1.50 1997/05/29 05:11:11 peter Exp $ + * $Id: swtch.s,v 1.51 1997/05/31 09:27:29 peter Exp $ */ #include "npx.h" @@ -336,6 +336,8 @@ ENTRY(cpu_switch) movl %ebp,PCB_EBP(%ecx) movl %esi,PCB_ESI(%ecx) movl %edi,PCB_EDI(%ecx) + movl %fs,PCB_FS(%ecx) + movl %gs,PCB_GS(%ecx) #ifdef SMP movl _mp_lock, %eax @@ -562,6 +564,14 @@ swtch_com: 2: #endif + /* This must be done after loading the user LDT. */ + .globl cpu_switch_load_fs +cpu_switch_load_fs: + movl PCB_FS(%edx),%fs + .globl cpu_switch_load_gs +cpu_switch_load_gs: + movl PCB_GS(%edx),%gs + sti ret @@ -592,6 +602,8 @@ ENTRY(savectx) movl %ebp,PCB_EBP(%ecx) movl %esi,PCB_ESI(%ecx) movl %edi,PCB_EDI(%ecx) + movl %fs,PCB_FS(%ecx) + movl %gs,PCB_GS(%ecx) #if NNPX > 0 /* diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c index f73c4f2..89dd34f 100644 --- a/sys/i386/i386/trap.c +++ b/sys/i386/i386/trap.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 - * $Id: trap.c,v 1.97 1997/05/31 09:27:29 peter Exp $ + * $Id: trap.c,v 1.98 1997/06/02 08:19:03 dfr Exp $ */ /* @@ -352,6 +352,25 @@ trap(frame) } while (0) if (intr_nesting_level == 0) { + /* + * Invalid %fs's and %gs's can be created using + * procfs or PT_SETREGS or by invalidating the + * underlying LDT entry. This causes a fault + * in kernel mode when the kernel attempts to + * switch contexts. Lose the bad context + * (XXX) so that we can continue, and generate + * a signal. + */ + if (frame.tf_eip == (int)cpu_switch_load_fs) { + curpcb->pcb_fs = 0; + psignal(p, SIGBUS); + return; + } + if (frame.tf_eip == (int)cpu_switch_load_gs) { + curpcb->pcb_gs = 0; + psignal(p, SIGBUS); + return; + } MAYBE_DORETI_FAULT(doreti_iret, doreti_iret_fault); MAYBE_DORETI_FAULT(doreti_popl_ds, diff --git a/sys/i386/include/md_var.h b/sys/i386/include/md_var.h index 307257c..a7e7856 100644 --- a/sys/i386/include/md_var.h +++ b/sys/i386/include/md_var.h @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: md_var.h,v 1.12 1997/02/22 09:34:49 peter Exp $ + * $Id: md_var.h,v 1.13 1997/03/22 18:53:08 kato Exp $ */ #ifndef _MACHINE_MD_VAR_H_ @@ -57,6 +57,8 @@ struct reg; void bcopyb __P((const void *from, void *to, size_t len)); void cpu_reset __P((void)); void cpu_halt __P((void)); +void cpu_switch_load_fs __P((void)) __asm(__STRING(cpu_switch_load_fs)); +void cpu_switch_load_gs __P((void)) __asm(__STRING(cpu_switch_load_gs)); void doreti_iret __P((void)) __asm(__STRING(doreti_iret)); void doreti_iret_fault __P((void)) __asm(__STRING(doreti_iret_fault)); void doreti_popl_ds __P((void)) __asm(__STRING(doreti_popl_ds)); diff --git a/sys/i386/include/pcb.h b/sys/i386/include/pcb.h index 1cbca02..c93ed87 100644 --- a/sys/i386/include/pcb.h +++ b/sys/i386/include/pcb.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)pcb.h 5.10 (Berkeley) 5/12/91 - * $Id: pcb.h,v 1.20 1997/04/26 11:45:39 peter Exp $ + * $Id: pcb.h,v 1.21 1997/05/07 19:49:32 peter Exp $ */ #ifndef _I386_PCB_H_ @@ -64,7 +64,9 @@ struct pcb { #define FP_SOFTFP 0x01 /* process using software fltng pnt emulator */ caddr_t pcb_onfault; /* copyin/out fault recovery */ u_long pcb_mpnest; - u_long __pcb_spare[7]; /* adjust to avoid core dump size changes */ + int pcb_fs; + int pcb_gs; + u_long __pcb_spare[5]; /* adjust to avoid core dump size changes */ #if 0 /* some day we may switch between procs that have their own i386tss */ struct i386tss pcb_tss; u_char pcb_iomap[NPORT/sizeof(u_char)]; /* i/o port bitmap */ diff --git a/sys/i386/include/reg.h b/sys/i386/include/reg.h index c896fe5..5d36f27 100644 --- a/sys/i386/include/reg.h +++ b/sys/i386/include/reg.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)reg.h 5.5 (Berkeley) 1/18/91 - * $Id: reg.h,v 1.13 1997/02/22 09:35:07 peter Exp $ + * $Id: reg.h,v 1.14 1997/06/07 00:49:45 bde Exp $ */ #ifndef _MACHINE_REG_H_ @@ -69,6 +69,16 @@ #define tSS (16) /* + * Indices for registers in `struct regs' only. + * + * Some registers live in the pcb and are only in an "array" with the + * other registers in application interfaces that copy all the registers + * to or from a `struct regs'. + */ +#define tFS (17) +#define tGS (18) + +/* * Register set accessible via /proc/$pid/regs and PT_{SET,GET}REGS. */ struct reg { @@ -89,6 +99,8 @@ struct reg { unsigned int r_eflags; unsigned int r_esp; unsigned int r_ss; + unsigned int r_fs; + unsigned int r_gs; }; /* diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c index f73c4f2..89dd34f 100644 --- a/sys/kern/subr_trap.c +++ b/sys/kern/subr_trap.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 - * $Id: trap.c,v 1.97 1997/05/31 09:27:29 peter Exp $ + * $Id: trap.c,v 1.98 1997/06/02 08:19:03 dfr Exp $ */ /* @@ -352,6 +352,25 @@ trap(frame) } while (0) if (intr_nesting_level == 0) { + /* + * Invalid %fs's and %gs's can be created using + * procfs or PT_SETREGS or by invalidating the + * underlying LDT entry. This causes a fault + * in kernel mode when the kernel attempts to + * switch contexts. Lose the bad context + * (XXX) so that we can continue, and generate + * a signal. + */ + if (frame.tf_eip == (int)cpu_switch_load_fs) { + curpcb->pcb_fs = 0; + psignal(p, SIGBUS); + return; + } + if (frame.tf_eip == (int)cpu_switch_load_gs) { + curpcb->pcb_gs = 0; + psignal(p, SIGBUS); + return; + } MAYBE_DORETI_FAULT(doreti_iret, doreti_iret_fault); MAYBE_DORETI_FAULT(doreti_popl_ds, |