Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Add %fs/%gs to trap frame and save/restore them on



details:   https://anonhg.NetBSD.org/src/rev/c879b19d5841
branches:  trunk
changeset: 511321:c879b19d5841
user:      sommerfeld <sommerfeld%NetBSD.org@localhost>
date:      Sun Jun 17 21:01:32 2001 +0000

description:
Add %fs/%gs to trap frame and save/restore them on
trap/interrupt/syscall entry from userspace.

Remove special-case "by hand" validation of fs/gs register values as
well as special handling of them in various signal handling paths.

Now, like %ds and %es, they are validated by the hardware on return to
userland.

This paves the way for the use of %fs for per-cpu data on
multiprocessor systems, and fixes an otherwise difficult-to-fix
interaction between threads/clone(2) and USER_LDT.

Discussed in advance with Frank van der Linden.

diffstat:

 sys/arch/i386/i386/compat_13_machdep.c     |   5 +-
 sys/arch/i386/i386/db_interface.c          |   4 +-
 sys/arch/i386/i386/db_trace.c              |   6 ++-
 sys/arch/i386/i386/genassym.cf             |  13 +------
 sys/arch/i386/i386/ibcs2_machdep.c         |  10 ++--
 sys/arch/i386/i386/ibcs2_sigcode.s         |   6 +--
 sys/arch/i386/i386/ipkdb_glue.c            |  10 ++--
 sys/arch/i386/i386/kgdb_machdep.c          |   4 +-
 sys/arch/i386/i386/linux_sigcode.s         |  22 +----------
 sys/arch/i386/i386/locore.s                |  57 ++++++++++++-----------------
 sys/arch/i386/i386/machdep.c               |  14 +++---
 sys/arch/i386/i386/process_machdep.c       |  23 ++---------
 sys/arch/i386/i386/svr4_machdep.c          |   6 +-
 sys/arch/i386/i386/svr4_sigcode.s          |  12 +-----
 sys/arch/i386/i386/sys_machdep.c           |  18 +--------
 sys/arch/i386/i386/trap.c                  |  17 ++++++++-
 sys/arch/i386/include/db_machdep.h         |   4 +-
 sys/arch/i386/include/frame.h              |   6 ++-
 sys/arch/i386/include/pcb.h                |   4 +-
 sys/compat/linux/arch/i386/linux_machdep.c |   6 +-
 20 files changed, 97 insertions(+), 150 deletions(-)

diffs (truncated from 685 to 300 lines):

diff -r 33fd19362ab4 -r c879b19d5841 sys/arch/i386/i386/compat_13_machdep.c
--- a/sys/arch/i386/i386/compat_13_machdep.c    Sun Jun 17 19:54:47 2001 +0000
+++ b/sys/arch/i386/i386/compat_13_machdep.c    Sun Jun 17 21:01:32 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: compat_13_machdep.c,v 1.5 2000/12/22 22:58:53 jdolecek Exp $   */
+/*     $NetBSD: compat_13_machdep.c,v 1.6 2001/06/17 21:01:32 sommerfeld Exp $ */
 
 /*-
  * Copyright (c) 1996, 1997, 1998, 2000 The NetBSD Foundation, Inc.
@@ -97,7 +97,8 @@
                    !USERMODE(context.sc_cs, context.sc_eflags))
                        return (EINVAL);
 
-               /* %fs and %gs were restored by the trampoline. */
+               tf->tf_gs = context.sc_gs;
+               tf->tf_fs = context.sc_fs;              
                tf->tf_es = context.sc_es;
                tf->tf_ds = context.sc_ds;
                tf->tf_eflags = context.sc_eflags;
diff -r 33fd19362ab4 -r c879b19d5841 sys/arch/i386/i386/db_interface.c
--- a/sys/arch/i386/i386/db_interface.c Sun Jun 17 19:54:47 2001 +0000
+++ b/sys/arch/i386/i386/db_interface.c Sun Jun 17 21:01:32 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: db_interface.c,v 1.30 2000/06/29 08:44:51 mrg Exp $    */
+/*     $NetBSD: db_interface.c,v 1.31 2001/06/17 21:01:32 sommerfeld Exp $     */
 
 /* 
  * Mach Operating System
@@ -121,6 +121,8 @@
        db_active--;
        splx(s);
 
+       regs->tf_gs     = ddb_regs.tf_gs;
+       regs->tf_fs     = ddb_regs.tf_fs;
        regs->tf_es     = ddb_regs.tf_es;
        regs->tf_ds     = ddb_regs.tf_ds;
        regs->tf_edi    = ddb_regs.tf_edi;
diff -r 33fd19362ab4 -r c879b19d5841 sys/arch/i386/i386/db_trace.c
--- a/sys/arch/i386/i386/db_trace.c     Sun Jun 17 19:54:47 2001 +0000
+++ b/sys/arch/i386/i386/db_trace.c     Sun Jun 17 21:01:32 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: db_trace.c,v 1.29 2001/01/18 10:54:27 jdolecek Exp $   */
+/*     $NetBSD: db_trace.c,v 1.30 2001/06/17 21:01:32 sommerfeld Exp $ */
 
 /* 
  * Mach Operating System
@@ -43,8 +43,10 @@
  * Machine register set.
  */
 const struct db_variable db_regs[] = {
+       { "ds",         (long *)&ddb_regs.tf_ds,     FCN_NULL },
        { "es",         (long *)&ddb_regs.tf_es,     FCN_NULL },
-       { "ds",         (long *)&ddb_regs.tf_ds,     FCN_NULL },
+       { "fs",         (long *)&ddb_regs.tf_fs,     FCN_NULL },
+       { "gs",         (long *)&ddb_regs.tf_gs,     FCN_NULL },
        { "edi",        (long *)&ddb_regs.tf_edi,    FCN_NULL },
        { "esi",        (long *)&ddb_regs.tf_esi,    FCN_NULL },
        { "ebp",        (long *)&ddb_regs.tf_ebp,    FCN_NULL },
diff -r 33fd19362ab4 -r c879b19d5841 sys/arch/i386/i386/genassym.cf
--- a/sys/arch/i386/i386/genassym.cf    Sun Jun 17 19:54:47 2001 +0000
+++ b/sys/arch/i386/i386/genassym.cf    Sun Jun 17 21:01:32 2001 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: genassym.cf,v 1.27 2001/05/26 17:46:12 sommerfeld Exp $
+#      $NetBSD: genassym.cf,v 1.28 2001/06/17 21:01:32 sommerfeld Exp $
 
 #
 # Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -168,8 +168,6 @@
 define PCB_CR3                 offsetof(struct pcb, pcb_cr3)
 define PCB_EBP                 offsetof(struct pcb, pcb_ebp)
 define PCB_ESP                 offsetof(struct pcb, pcb_esp)
-define PCB_FS                  offsetof(struct pcb, pcb_fs)
-define PCB_GS                  offsetof(struct pcb, pcb_gs)
 define PCB_CR0                 offsetof(struct pcb, pcb_cr0)
 define PCB_LDT_SEL             offsetof(struct pcb, pcb_ldt_sel)
 define PCB_ONFAULT             offsetof(struct pcb, pcb_onfault)
@@ -184,24 +182,15 @@
 
 define SIGF_HANDLER            offsetof(struct sigframe, sf_handler)
 define SIGF_SC                 offsetof(struct sigframe, sf_sc)
-define SC_FS                   offsetof(struct sigcontext, sc_fs)
-define SC_GS                   offsetof(struct sigcontext, sc_gs)
-define SC_EFLAGS               offsetof(struct sigcontext, sc_eflags)
 
 ifdef COMPAT_SVR4
 define SVR4_SIGF_HANDLER       offsetof(struct svr4_sigframe, sf_handler)
 define SVR4_SIGF_UC            offsetof(struct svr4_sigframe, sf_uc)
-define SVR4_UC_FS              offsetof(struct svr4_ucontext, uc_mcontext.greg[SVR4_X86_FS])
-define SVR4_UC_GS              offsetof(struct svr4_ucontext, uc_mcontext.greg[SVR4_X86_GS])
-define SVR4_UC_EFLAGS          offsetof(struct svr4_ucontext, uc_mcontext.greg[SVR4_X86_EFL])
 endif
 
 ifdef COMPAT_LINUX
 define LINUX_SIGF_HANDLER      offsetof(struct linux_sigframe, sf_handler)
 define LINUX_SIGF_SC           offsetof(struct linux_sigframe, sf_sc)
-define LINUX_SC_FS             offsetof(struct linux_sigcontext, sc_fs)
-define LINUX_SC_GS             offsetof(struct linux_sigcontext, sc_gs)
-define LINUX_SC_EFLAGS         offsetof(struct linux_sigcontext, sc_eflags)
 endif
 
 ifdef COMPAT_FREEBSD
diff -r 33fd19362ab4 -r c879b19d5841 sys/arch/i386/i386/ibcs2_machdep.c
--- a/sys/arch/i386/i386/ibcs2_machdep.c        Sun Jun 17 19:54:47 2001 +0000
+++ b/sys/arch/i386/i386/ibcs2_machdep.c        Sun Jun 17 21:01:32 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ibcs2_machdep.c,v 1.14 2001/05/30 12:28:43 mrg Exp $   */
+/*     $NetBSD: ibcs2_machdep.c,v 1.15 2001/06/17 21:01:33 sommerfeld Exp $    */
 
 /*-
  * Copyright (c) 1997, 2000 The NetBSD Foundation, Inc.
@@ -136,8 +136,8 @@
        } else
 #endif
        {
-               __asm("movl %%gs,%w0" : "=r" (frame.sf_sc.sc_gs));
-               __asm("movl %%fs,%w0" : "=r" (frame.sf_sc.sc_fs));
+               frame.sf_sc.sc_gs = tf->tf_gs;
+               frame.sf_sc.sc_fs = tf->tf_fs;
                frame.sf_sc.sc_es = tf->tf_es;
                frame.sf_sc.sc_ds = tf->tf_ds;
                frame.sf_sc.sc_eflags = tf->tf_eflags;
@@ -174,8 +174,8 @@
        /*
         * Build context to run handler in.
         */
-       __asm("movl %w0,%%gs" : : "r" (GSEL(GUDATA_SEL, SEL_UPL)));
-       __asm("movl %w0,%%fs" : : "r" (GSEL(GUDATA_SEL, SEL_UPL)));
+       tf->tf_gs = GSEL(GUDATA_SEL, SEL_UPL);
+       tf->tf_fs = GSEL(GUDATA_SEL, SEL_UPL);  
        tf->tf_es = GSEL(GUDATA_SEL, SEL_UPL);
        tf->tf_ds = GSEL(GUDATA_SEL, SEL_UPL);
        tf->tf_eip = (int)p->p_sigctx.ps_sigcode;
diff -r 33fd19362ab4 -r c879b19d5841 sys/arch/i386/i386/ibcs2_sigcode.s
--- a/sys/arch/i386/i386/ibcs2_sigcode.s        Sun Jun 17 19:54:47 2001 +0000
+++ b/sys/arch/i386/i386/ibcs2_sigcode.s        Sun Jun 17 21:01:32 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ibcs2_sigcode.s,v 1.3 2001/05/30 12:28:43 mrg Exp $    */
+/*     $NetBSD: ibcs2_sigcode.s,v 1.4 2001/06/17 21:01:33 sommerfeld Exp $     */
 
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -88,10 +88,6 @@
        call    SIGF_HANDLER(%esp)
        leal    SIGF_SC(%esp),%eax      # scp (the call may have clobbered the
                                        # copy at SIGF_SCP(%esp))
-       movl    SC_FS(%eax),%ecx
-       movl    SC_GS(%eax),%edx
-       movl    %cx,%fs
-       movl    %dx,%gs
        pushl   %eax
        pushl   %eax                    # junk to fake return address
        movl    $IBCS2_SYS_sigreturn,%eax
diff -r 33fd19362ab4 -r c879b19d5841 sys/arch/i386/i386/ipkdb_glue.c
--- a/sys/arch/i386/i386/ipkdb_glue.c   Sun Jun 17 19:54:47 2001 +0000
+++ b/sys/arch/i386/i386/ipkdb_glue.c   Sun Jun 17 21:01:32 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ipkdb_glue.c,v 1.1 2000/03/22 20:58:27 ws Exp $        */
+/*     $NetBSD: ipkdb_glue.c,v 1.2 2001/06/17 21:01:33 sommerfeld Exp $        */
 
 /*
  * Copyright (C) 2000 Wolfgang Solfrank.
@@ -99,8 +99,8 @@
        ipkdbregs[SS] = 0x10;
        ipkdbregs[DS] = frame.tf_ds;
        ipkdbregs[ES] = frame.tf_es;
-       __asm ("movl %%fs,%0; movl %%gs,%1"
-              : "=r"(ipkdbregs[FS]), "=r"(ipkdbregs[GS]));
+       ipkdbregs[FS] = frame.tf_fs;
+       ipkdbregs[GS] = frame.tf_gs;
 
        switch ((ipkdb_mode = ipkdbcmds())) {
        case IPKDB_CMD_EXIT:
@@ -123,8 +123,8 @@
        frame.tf_cs = ipkdbregs[CS];
        frame.tf_ds = ipkdbregs[DS];
        frame.tf_es = ipkdbregs[ES];
-       __asm __volatile ("movl %0,%%fs; movl %1,%%gs"
-                         :: "r"(ipkdbregs[FS]), "r"(ipkdbregs[GS]));
+       frame.tf_fs = ipkdbregs[FS];
+       frame.tf_gs = ipkdbregs[GS];
 
        return 1;
 }
diff -r 33fd19362ab4 -r c879b19d5841 sys/arch/i386/i386/kgdb_machdep.c
--- a/sys/arch/i386/i386/kgdb_machdep.c Sun Jun 17 19:54:47 2001 +0000
+++ b/sys/arch/i386/i386/kgdb_machdep.c Sun Jun 17 21:01:32 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kgdb_machdep.c,v 1.10 2000/11/14 22:55:05 thorpej Exp $        */
+/*     $NetBSD: kgdb_machdep.c,v 1.11 2001/06/17 21:01:33 sommerfeld Exp $     */
 
 /*-
  * Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -191,6 +191,8 @@
        gdb_regs[10] = regs->tf_cs;
        gdb_regs[12] = regs->tf_ds;
        gdb_regs[13] = regs->tf_es;
+       gdb_regs[14] = regs->tf_fs;
+       gdb_regs[15] = regs->tf_gs;
 
        if (KERNELMODE(regs->tf_cs, regs->tf_eflags)) {
                /*
diff -r 33fd19362ab4 -r c879b19d5841 sys/arch/i386/i386/linux_sigcode.s
--- a/sys/arch/i386/i386/linux_sigcode.s        Sun Jun 17 19:54:47 2001 +0000
+++ b/sys/arch/i386/i386/linux_sigcode.s        Sun Jun 17 21:01:32 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: linux_sigcode.s,v 1.3 2001/05/30 12:28:43 mrg Exp $    */
+/*     $NetBSD: linux_sigcode.s,v 1.4 2001/06/17 21:01:33 sommerfeld Exp $     */
 
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -95,15 +95,7 @@
        call    LINUX_SIGF_HANDLER(%esp)
        leal    LINUX_SIGF_SC(%esp),%ebx # scp (the call may have clobbered the
                                        # copy at SIGF_SCP(%esp))
-#ifdef VM86
-       testl   $PSL_VM,LINUX_SC_EFLAGS(%ebx)
-       jnz     1f
-#endif
-       movl    LINUX_SC_FS(%ebx),%ecx
-       movl    LINUX_SC_GS(%ebx),%edx
-       movl    %cx,%fs
-       movl    %dx,%gs
-1:     pushl   %eax                    # junk to fake return address
+       pushl   %eax                    # junk to fake return address
        movl    $LINUX_SYS_sigreturn,%eax
        int     $0x80                   # enter kernel with args on stack
        movl    $LINUX_SYS_exit,%eax
@@ -116,15 +108,7 @@
        call    LINUX_SIGF_HANDLER(%esp)
        leal    LINUX_SIGF_SC(%esp),%ebx # scp (the call may have clobbered the
                                        # copy at SIGF_SCP(%esp))
-#ifdef VM86
-       testl   $PSL_VM,LINUX_SC_EFLAGS(%ebx)
-       jnz     1f
-#endif
-       movl    LINUX_SC_FS(%ebx),%ecx
-       movl    LINUX_SC_GS(%ebx),%edx
-       movl    %cx,%fs
-       movl    %dx,%gs
-1:     pushl   %eax                    # junk to fake return address
+       pushl   %eax                    # junk to fake return address
        movl    $LINUX_SYS_rt_sigreturn,%eax
        int     $0x80                   # enter kernel with args on stack
        movl    $LINUX_SYS_exit,%eax
diff -r 33fd19362ab4 -r c879b19d5841 sys/arch/i386/i386/locore.s
--- a/sys/arch/i386/i386/locore.s       Sun Jun 17 19:54:47 2001 +0000
+++ b/sys/arch/i386/i386/locore.s       Sun Jun 17 21:01:32 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: locore.s,v 1.241 2001/06/11 22:56:26 perry Exp $       */
+/*     $NetBSD: locore.s,v 1.242 2001/06/17 21:01:33 sommerfeld Exp $  */
 
 /*-
  * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@@ -162,8 +162,15 @@
        pushl   %ds             ; \
        pushl   %es             ; \
        movl    %ax,%ds         ; \
-       movl    %ax,%es
+       movl    %ax,%es         ; \
+       pushl   %fs             ; \
+       pushl   %gs             ; \
+       movl    %ax,%fs         ; \
+       movl    %ax,%gs         ; \
+
 #define        INTRFASTEXIT \
+       popl    %gs             ; \
+       popl    %fs             ; \
        popl    %es             ; \
        popl    %ds             ; \
        popl    %edi            ; \
@@ -320,6 +327,10 @@
        pushl   $PSL_MBO
        popfl
 
+       /* Clear segment registers; always null in proc0. */
+       xorl    %eax,%eax
+       movl    %ax,%fs
+       movl    %ax,%gs
        /* Find out our CPU type. */
 
 try386:        /* Try to toggle alignment check flag; does not exist on 386. */
@@ -672,11 +683,6 @@
        call    _C_LABEL(init386)       # wire 386 chip for unix operation
        addl    $4,%esp
 
-       /* Clear segment registers; always null in proc0. */
-       xorl    %ecx,%ecx
-       movl    %cx,%fs
-       movl    %cx,%gs
-
 #ifdef SAFARI_FIFO_HACK
        movb    $5,%al
        movw    $0x37b,%dx
@@ -726,15 +732,7 @@
        call    SIGF_HANDLER(%esp)
        leal    SIGF_SC(%esp),%eax      # scp (the call may have clobbered the
                                        # copy at SIGF_SCP(%esp))
-#ifdef VM86
-       testl   $PSL_VM,SC_EFLAGS(%eax)
-       jnz     1f



Home | Main Index | Thread Index | Old Index