Module Name: src Committed By: bouyer Date: Fri Mar 2 16:43:31 UTC 2012
Modified Files: src/sys/arch/amd64/amd64: machdep.c src/sys/arch/i386/i386: locore.S machdep.c src/sys/arch/x86/include: cpu.h Log Message: Follow locore.S and move FPU handling from x86_64_switch_context() to x86_64_tls_switch(); raise IPL to IPL_HIGH in x86_64_switch_context() and test ci_fpcurlwp to decide to disable FPU or not. Change the Xen i386 context switch code to be like the amd64 one. To generate a diff of this commit: cvs rdiff -u -r1.178 -r1.179 src/sys/arch/amd64/amd64/machdep.c cvs rdiff -u -r1.96 -r1.97 src/sys/arch/i386/i386/locore.S cvs rdiff -u -r1.722 -r1.723 src/sys/arch/i386/i386/machdep.c cvs rdiff -u -r1.48 -r1.49 src/sys/arch/x86/include/cpu.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/amd64/amd64/machdep.c diff -u src/sys/arch/amd64/amd64/machdep.c:1.178 src/sys/arch/amd64/amd64/machdep.c:1.179 --- src/sys/arch/amd64/amd64/machdep.c:1.178 Thu Feb 23 14:45:54 2012 +++ src/sys/arch/amd64/amd64/machdep.c Fri Mar 2 16:43:30 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.178 2012/02/23 14:45:54 chs Exp $ */ +/* $NetBSD: machdep.c,v 1.179 2012/03/02 16:43:30 bouyer 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.178 2012/02/23 14:45:54 chs Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.179 2012/03/02 16:43:30 bouyer Exp $"); /* #define XENDEBUG_LOW */ @@ -407,23 +407,53 @@ cpu_startup(void) 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); } -} -#endif + /* 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 /* XEN */ /* * Set up proc0's TSS and LDT. @@ -2257,28 +2287,6 @@ cpu_fsgs_reload(struct lwp *l, int fssel } } -#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 Index: src/sys/arch/i386/i386/locore.S diff -u src/sys/arch/i386/i386/locore.S:1.96 src/sys/arch/i386/i386/locore.S:1.97 --- src/sys/arch/i386/i386/locore.S:1.96 Fri Feb 24 08:06:07 2012 +++ src/sys/arch/i386/i386/locore.S Fri Mar 2 16:43:31 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.96 2012/02/24 08:06:07 cherry Exp $ */ +/* $NetBSD: locore.S,v 1.97 2012/03/02 16:43:31 bouyer Exp $ */ /* * Copyright-o-rama! @@ -129,7 +129,7 @@ */ #include <machine/asm.h> -__KERNEL_RCSID(0, "$NetBSD: locore.S,v 1.96 2012/02/24 08:06:07 cherry Exp $"); +__KERNEL_RCSID(0, "$NetBSD: locore.S,v 1.97 2012/03/02 16:43:31 bouyer Exp $"); #include "opt_compat_oldboot.h" #include "opt_ddb.h" @@ -1013,15 +1013,17 @@ ENTRY(cpu_switchto) 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 @@ -1032,7 +1034,7 @@ ENTRY(cpu_switchto) 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 @@ -1052,7 +1054,11 @@ ENTRY(cpu_switchto) * 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 @@ -1069,7 +1075,7 @@ ENTRY(cpu_switchto) 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 Index: src/sys/arch/i386/i386/machdep.c diff -u src/sys/arch/i386/i386/machdep.c:1.722 src/sys/arch/i386/i386/machdep.c:1.723 --- src/sys/arch/i386/i386/machdep.c:1.722 Mon Feb 27 19:52:59 2012 +++ src/sys/arch/i386/i386/machdep.c Fri Mar 2 16:43:31 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.722 2012/02/27 19:52:59 bouyer Exp $ */ +/* $NetBSD: machdep.c,v 1.723 2012/03/02 16:43:31 bouyer 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.722 2012/02/27 19:52:59 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.723 2012/03/02 16:43:31 bouyer Exp $"); #include "opt_beep.h" #include "opt_compat_ibcs2.h" @@ -525,9 +525,12 @@ i386_proc0_tss_ldt_init(void) } #ifdef XEN +/* 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 @@ -539,21 +542,41 @@ i386_switch_context(lwp_t *l) pcb = lwp_getpcb(l); ci = curcpu(); - if (pcb->pcb_fpcpu != ci) { - HYPERVISOR_fpu_taskswitch(1); - } 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); + } + /* Update TLS segment pointers */ update_descriptor(&ci->ci_gdt[GUFS_SEL], (union descriptor *) &pcb->pcb_fsd); update_descriptor(&ci->ci_gdt[GUGS_SEL], (union descriptor *) &pcb->pcb_gsd); - physop.cmd = PHYSDEVOP_SET_IOPL; - physop.u.set_iopl.iopl = pcb->pcb_iopl; - HYPERVISOR_physdev_op(&physop); } #endif /* XEN */ Index: src/sys/arch/x86/include/cpu.h diff -u src/sys/arch/x86/include/cpu.h:1.48 src/sys/arch/x86/include/cpu.h:1.49 --- src/sys/arch/x86/include/cpu.h:1.48 Fri Feb 17 18:40:18 2012 +++ src/sys/arch/x86/include/cpu.h Fri Mar 2 16:43:31 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.h,v 1.48 2012/02/17 18:40:18 bouyer Exp $ */ +/* $NetBSD: cpu.h,v 1.49 2012/03/02 16:43:31 bouyer Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. @@ -404,7 +404,6 @@ struct region_descriptor; void lgdt(struct region_descriptor *); #ifdef XEN void lgdt_finish(void); -void i386_switch_context(lwp_t *); #endif struct pcb;