Source-Changes-HG archive

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

[src/netbsd-6]: src/sys/arch Pull up the following revisions(s) (requested by...



details:   https://anonhg.NetBSD.org/src/rev/b67846a30e7f
branches:  netbsd-6
changeset: 773876:b67846a30e7f
user:      sborrill <sborrill%NetBSD.org@localhost>
date:      Mon Mar 05 20:18:01 2012 +0000

description:
Pull up the following revisions(s) (requested by bouyer in ticket #80):
        sys/arch/xen/x86/x86_xpmap.c:   revision 1.42
        sys/arch/x86/include/specialreg.h:      revision 1.56
        sys/arch/amd64/amd64/machdep.c: revision 1.179
        sys/arch/i386/i386/locore.S:    revision 1.97
        sys/arch/i386/i386/machdep.c:   revision 1.723 via patch
        sys/arch/x86/include/cpu.h:     revision 1.49

Fix possible FPU registers corruption on context switches.
Fix type of pointers passed to some hypercalls.

diffstat:

 sys/arch/amd64/amd64/machdep.c    |  66 +++++++++++++++++++++-----------------
 sys/arch/i386/i386/locore.S       |  18 +++++++---
 sys/arch/i386/i386/machdep.c      |  41 ++++++++++++++++++-----
 sys/arch/x86/include/cpu.h        |   3 +-
 sys/arch/x86/include/specialreg.h |   4 +-
 sys/arch/xen/x86/x86_xpmap.c      |  20 ++++-------
 6 files changed, 92 insertions(+), 60 deletions(-)

diffs (truncated from 366 to 300 lines):

diff -r ceca4d025978 -r b67846a30e7f sys/arch/amd64/amd64/machdep.c
--- a/sys/arch/amd64/amd64/machdep.c    Mon Mar 05 19:16:57 2012 +0000
+++ b/sys/arch/amd64/amd64/machdep.c    Mon Mar 05 20:18:01 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: machdep.c,v 1.175.2.1 2012/02/23 18:37:12 riz Exp $    */
+/*     $NetBSD: machdep.c,v 1.175.2.2 2012/03/05 20:18:01 sborrill Exp $       */
 
 /*-
  * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011
@@ -111,7 +111,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.175.2.1 2012/02/23 18:37:12 riz Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.175.2.2 2012/03/05 20:18:01 sborrill Exp $");
 
 /* #define XENDEBUG_LOW  */
 
@@ -414,23 +414,53 @@
 void hypervisor_callback(void);
 void failsafe_callback(void);
 void x86_64_switch_context(struct pcb *);
+void x86_64_tls_switch(struct lwp *);
 
 void
 x86_64_switch_context(struct pcb *new)
 {
-       struct cpu_info *ci;
-       ci = curcpu();
        HYPERVISOR_stack_switch(GSEL(GDATA_SEL, SEL_KPL), new->pcb_rsp0);
        struct physdev_op physop;
        physop.cmd = PHYSDEVOP_SET_IOPL;
        physop.u.set_iopl.iopl = new->pcb_iopl;
        HYPERVISOR_physdev_op(&physop);
-       if (new->pcb_fpcpu != ci) {
+}
+
+void
+x86_64_tls_switch(struct lwp *l)
+{
+       struct cpu_info *ci = curcpu();
+       struct pcb *pcb = lwp_getpcb(l);
+       struct trapframe *tf = l->l_md.md_regs;
+
+       /*
+        * Raise the IPL to IPL_HIGH.
+        * FPU IPIs can alter the LWP's saved cr0.  Dropping the priority
+        * is deferred until mi_switch(), when cpu_switchto() returns.
+        */
+       (void)splhigh();
+       /*
+        * If our floating point registers are on a different CPU,
+        * set CR0_TS so we'll trap rather than reuse bogus state.
+        */
+       if (l != ci->ci_fpcurlwp) {
                HYPERVISOR_fpu_taskswitch(1);
        }
+
+       /* Update TLS segment pointers */
+       if (pcb->pcb_flags & PCB_COMPAT32) {
+               update_descriptor(&curcpu()->ci_gdt[GUFS_SEL], &pcb->pcb_fs);
+               update_descriptor(&curcpu()->ci_gdt[GUGS_SEL], &pcb->pcb_gs);
+               setfs(tf->tf_fs);
+               HYPERVISOR_set_segment_base(SEGBASE_GS_USER_SEL, tf->tf_gs);
+       } else {
+               setfs(0);
+               HYPERVISOR_set_segment_base(SEGBASE_GS_USER_SEL, 0);
+               HYPERVISOR_set_segment_base(SEGBASE_FS, pcb->pcb_fs);
+               HYPERVISOR_set_segment_base(SEGBASE_GS_USER, pcb->pcb_gs);
+       }
 }
-
-#endif
+#endif /* XEN */
 
 /*
  * Set up proc0's TSS and LDT.
@@ -2297,28 +2327,6 @@
        }
 }
 
-#ifdef XEN
-void x86_64_tls_switch(struct lwp *);
-
-void
-x86_64_tls_switch(struct lwp *l)
-{
-       struct pcb *pcb = lwp_getpcb(l);
-       struct trapframe *tf = l->l_md.md_regs;
-
-       if (pcb->pcb_flags & PCB_COMPAT32) {
-               update_descriptor(&curcpu()->ci_gdt[GUFS_SEL], &pcb->pcb_fs);
-               update_descriptor(&curcpu()->ci_gdt[GUGS_SEL], &pcb->pcb_gs);
-               setfs(tf->tf_fs);
-               HYPERVISOR_set_segment_base(SEGBASE_GS_USER_SEL, tf->tf_gs);
-       } else {
-               setfs(0);
-               HYPERVISOR_set_segment_base(SEGBASE_GS_USER_SEL, 0);
-               HYPERVISOR_set_segment_base(SEGBASE_FS, pcb->pcb_fs);
-               HYPERVISOR_set_segment_base(SEGBASE_GS_USER, pcb->pcb_gs);
-       }
-}
-#endif
 
 #ifdef __HAVE_DIRECT_MAP
 bool
diff -r ceca4d025978 -r b67846a30e7f sys/arch/i386/i386/locore.S
--- a/sys/arch/i386/i386/locore.S       Mon Mar 05 19:16:57 2012 +0000
+++ b/sys/arch/i386/i386/locore.S       Mon Mar 05 20:18:01 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: locore.S,v 1.95 2011/03/18 15:18:16 joerg Exp $        */
+/*     $NetBSD: locore.S,v 1.95.10.1 2012/03/05 20:18:01 sborrill Exp $        */
 
 /*
  * Copyright-o-rama!
@@ -129,7 +129,7 @@
  */
 
 #include <machine/asm.h>
-__KERNEL_RCSID(0, "$NetBSD: locore.S,v 1.95 2011/03/18 15:18:16 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: locore.S,v 1.95.10.1 2012/03/05 20:18:01 sborrill Exp $");
 
 #include "opt_compat_oldboot.h"
 #include "opt_ddb.h"
@@ -999,15 +999,17 @@
        pushl   %edi
        call    _C_LABEL(i386_switch_context)
        addl    $4,%esp
-#else /* XEN */
+#else /* !XEN */
        /* Switch ring0 esp */
        movl    PCB_ESP0(%ebx),%eax
        movl    %eax,CPUVAR(ESP0)
+#endif /* !XEN */
 
        /* Don't bother with the rest if switching to a system process. */
        testl   $LW_SYSTEM,L_FLAG(%edi)
        jnz     4f
 
+#ifndef XEN
        /* Restore thread-private %fs/%gs descriptors. */
        movl    CPUVAR(GDT),%ecx
        movl    PCB_FSD(%ebx), %eax
@@ -1018,7 +1020,7 @@
        movl    PCB_GSD+4(%ebx), %edx
        movl    %eax, (GUGS_SEL*8)(%ecx)
        movl    %edx, (GUGS_SEL*8+4)(%ecx)
-#endif /* XEN */
+#endif /* !XEN */
 
        /* Switch I/O bitmap */
        movl    PCB_IOMAP(%ebx),%eax
@@ -1038,7 +1040,11 @@
         * is deferred until mi_switch(), when cpu_switchto() returns.
         */
 2:
-#ifndef XEN
+#ifdef XEN
+       pushl   %edi
+       call    _C_LABEL(i386_tls_switch)
+       addl    $4,%esp
+#else /* !XEN */
        movl    $IPL_HIGH,CPUVAR(ILEVEL)
        movl    PCB_CR0(%ebx),%ecx              /* has CR0_TS clear */
        movl    %cr0,%edx
@@ -1055,7 +1061,7 @@
 3:     cmpl    %edx,%ecx
        je      4f
        movl    %ecx,%cr0
-#endif /* XEN */
+#endif /* !XEN */
 
        /* Return to the new LWP, returning 'oldlwp' in %eax. */
 4:     movl    %esi,%eax
diff -r ceca4d025978 -r b67846a30e7f sys/arch/i386/i386/machdep.c
--- a/sys/arch/i386/i386/machdep.c      Mon Mar 05 19:16:57 2012 +0000
+++ b/sys/arch/i386/i386/machdep.c      Mon Mar 05 20:18:01 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: machdep.c,v 1.717.2.3 2012/02/27 20:29:36 riz Exp $    */
+/*     $NetBSD: machdep.c,v 1.717.2.4 2012/03/05 20:18:02 sborrill Exp $       */
 
 /*-
  * Copyright (c) 1996, 1997, 1998, 2000, 2004, 2006, 2008, 2009
@@ -67,7 +67,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.717.2.3 2012/02/27 20:29:36 riz Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.717.2.4 2012/03/05 20:18:02 sborrill Exp $");
 
 #include "opt_beep.h"
 #include "opt_compat_ibcs2.h"
@@ -530,9 +530,12 @@
 /* Shim for curcpu() until %fs is ready */
 extern struct cpu_info * (*xpq_cpu)(void);
 
+/* used in assembly */
+void i386_switch_context(lwp_t *);
+void i386_tls_switch(lwp_t *);
+
 /*
  * Switch context:
- * - honor CR0_TS in saved CR0 and request DNA exception on FPU use
  * - switch stack pointer for user->kernel transition
  */
 void
@@ -544,12 +547,35 @@
 
        pcb = lwp_getpcb(l);
        ci = curcpu();
-       if (pcb->pcb_fpcpu != ci) {
+
+       HYPERVISOR_stack_switch(GSEL(GDATA_SEL, SEL_KPL), pcb->pcb_esp0);
+
+       physop.cmd = PHYSDEVOP_SET_IOPL;
+       physop.u.set_iopl.iopl = pcb->pcb_iopl;
+       HYPERVISOR_physdev_op(&physop);
+}
+
+void
+i386_tls_switch(lwp_t *l)
+{
+       struct cpu_info *ci = curcpu();
+       struct pcb *pcb = lwp_getpcb(l);
+       /*
+         * Raise the IPL to IPL_HIGH.
+        * FPU IPIs can alter the LWP's saved cr0.  Dropping the priority
+        * is deferred until mi_switch(), when cpu_switchto() returns.
+        */
+       (void)splhigh();
+
+        /*
+        * If our floating point registers are on a different CPU,
+        * set CR0_TS so we'll trap rather than reuse bogus state.
+        */
+
+       if (l != ci->ci_fpcurlwp) {
                HYPERVISOR_fpu_taskswitch(1);
        }
 
-       HYPERVISOR_stack_switch(GSEL(GDATA_SEL, SEL_KPL), pcb->pcb_esp0);
-
        /* Update TLS segment pointers */
        update_descriptor(&ci->ci_gdt[GUFS_SEL],
                          (union descriptor *) &pcb->pcb_fsd);
@@ -562,9 +588,6 @@
                xpq_cpu = x86_curcpu;
        }
 
-       physop.cmd = PHYSDEVOP_SET_IOPL;
-       physop.u.set_iopl.iopl = pcb->pcb_iopl;
-       HYPERVISOR_physdev_op(&physop);
 }
 #endif /* XEN */
 
diff -r ceca4d025978 -r b67846a30e7f sys/arch/x86/include/cpu.h
--- a/sys/arch/x86/include/cpu.h        Mon Mar 05 19:16:57 2012 +0000
+++ b/sys/arch/x86/include/cpu.h        Mon Mar 05 20:18:01 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cpu.h,v 1.47.2.1 2012/02/22 18:56:47 riz Exp $ */
+/*     $NetBSD: cpu.h,v 1.47.2.2 2012/03/05 20:18:02 sborrill Exp $    */
 
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
@@ -404,7 +404,6 @@
 void   lgdt(struct region_descriptor *);
 #ifdef XEN
 void   lgdt_finish(void);
-void   i386_switch_context(lwp_t *);
 #endif
 
 struct pcb;
diff -r ceca4d025978 -r b67846a30e7f sys/arch/x86/include/specialreg.h
--- a/sys/arch/x86/include/specialreg.h Mon Mar 05 19:16:57 2012 +0000
+++ b/sys/arch/x86/include/specialreg.h Mon Mar 05 20:18:01 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: specialreg.h,v 1.55 2011/12/15 09:38:21 abs Exp $      */
+/*     $NetBSD: specialreg.h,v 1.55.2.1 2012/03/05 20:18:03 sborrill Exp $     */
 
 /*-
  * Copyright (c) 1991 The Regents of the University of California.
@@ -307,7 +307,7 @@
 /* Blacklists of CPUID flags - used to mask certain features */
 #ifdef XEN
 /* Not on Xen */
-#define CPUID_FEAT_BLACKLIST    (CPUID_PGE|CPUID_PSE|CPUID_MTRR|CPUID_FXSR)
+#define CPUID_FEAT_BLACKLIST    (CPUID_PGE|CPUID_PSE|CPUID_MTRR)
 #else
 #define CPUID_FEAT_BLACKLIST    0
 #endif /* XEN */
diff -r ceca4d025978 -r b67846a30e7f sys/arch/xen/x86/x86_xpmap.c
--- a/sys/arch/xen/x86/x86_xpmap.c      Mon Mar 05 19:16:57 2012 +0000
+++ b/sys/arch/xen/x86/x86_xpmap.c      Mon Mar 05 20:18:01 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: x86_xpmap.c,v 1.38.2.2 2012/02/23 21:17:25 riz Exp $   */
+/*     $NetBSD: x86_xpmap.c,v 1.38.2.3 2012/03/05 20:18:03 sborrill Exp $      */
 
 /*
  * Copyright (c) 2006 Mathieu Ropert <mro%adviseo.fr@localhost>
@@ -69,7 +69,7 @@



Home | Main Index | Thread Index | Old Index