From 95c3baa7ee4b5dd88be242a814c7fbe0c238c5e1 Mon Sep 17 00:00:00 2001 From: msmith Date: Tue, 18 Aug 1998 07:47:12 +0000 Subject: Presently there is only one `currentldt' variable for all cpus in a SMP system. Unexpected things could happen if each cpu has a different ldt setting and one cpu tries to use value of currentldt set by another cpu. The fix is to move currentldt to the per-cpu area. It includes patches I filed in PR i386/6219 which are also user ldt related. PR: i386/7591, i386/6219 Submitted by: Luoqi Chen --- sys/amd64/amd64/genassym.c | 6 +++++- sys/amd64/amd64/machdep.c | 22 ++++++++++++++++------ sys/amd64/amd64/mp_machdep.c | 6 +++++- sys/amd64/amd64/mptable.c | 6 +++++- sys/amd64/amd64/sys_machdep.c | 4 ++-- sys/amd64/amd64/vm_machdep.c | 8 +++++--- sys/amd64/include/mptable.h | 6 +++++- sys/amd64/include/pcpu.h | 5 ++++- sys/i386/i386/genassym.c | 6 +++++- sys/i386/i386/globals.s | 8 +++++++- sys/i386/i386/machdep.c | 22 ++++++++++++++++------ sys/i386/i386/mp_machdep.c | 6 +++++- sys/i386/i386/mptable.c | 6 +++++- sys/i386/i386/sys_machdep.c | 4 ++-- sys/i386/i386/vm_machdep.c | 8 +++++--- sys/i386/include/globaldata.h | 5 ++++- sys/i386/include/mptable.h | 6 +++++- sys/i386/include/pcpu.h | 5 ++++- sys/kern/subr_smp.c | 6 +++++- 19 files changed, 110 insertions(+), 35 deletions(-) diff --git a/sys/amd64/amd64/genassym.c b/sys/amd64/amd64/genassym.c index d545c08..cf931cc 100644 --- a/sys/amd64/amd64/genassym.c +++ b/sys/amd64/amd64/genassym.c @@ -34,10 +34,11 @@ * SUCH DAMAGE. * * from: @(#)genassym.c 5.11 (Berkeley) 5/10/91 - * $Id: genassym.c,v 1.58 1998/05/28 09:29:55 phk Exp $ + * $Id: genassym.c,v 1.59 1998/07/11 12:17:07 bde Exp $ */ #include "opt_vm86.h" +#include "opt_user_ldt.h" #include @@ -204,6 +205,9 @@ main() printf("#define\tGD_PRIVATE_TSS %#x\n", OS(globaldata, private_tss)); printf("#define\tGD_MY_TR %#x\n", OS(globaldata, my_tr)); #endif +#ifdef USER_LDT + printf("#define\tGD_CURRENTLDT %#x\n", OS(globaldata, currentldt)); +#endif #ifdef SMP printf("#define\tGD_CPUID %#x\n", OS(globaldata, cpuid)); printf("#define\tGD_CPU_LOCKID %#x\n", OS(globaldata, cpu_lockid)); diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index c991f91..f0db465 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.302 1998/06/30 21:25:58 phk Exp $ + * $Id: machdep.c,v 1.303 1998/07/11 07:45:30 bde Exp $ */ #include "apm.h" @@ -801,14 +801,15 @@ setregs(p, entry, stack) u_long stack; { struct trapframe *regs = p->p_md.md_regs; - -#ifdef USER_LDT struct pcb *pcb = &p->p_addr->u_pcb; +#ifdef USER_LDT /* was i386_user_cleanup() in NetBSD */ if (pcb->pcb_ldt) { - if (pcb == curpcb) - lldt(GSEL(GUSERLDT_SEL, SEL_KPL)); + if (pcb == curpcb) { + lldt(_default_ldt); + currentldt = _default_ldt; + } kmem_free(kernel_map, (vm_offset_t)pcb->pcb_ldt, pcb->pcb_ldt_len * sizeof(union descriptor)); pcb->pcb_ldt_len = (int)pcb->pcb_ldt = 0; @@ -824,6 +825,14 @@ setregs(p, entry, stack) regs->tf_es = _udatasel; regs->tf_cs = _ucodesel; + /* reset %fs and %gs as well */ + pcb->pcb_fs = _udatasel; + pcb->pcb_gs = _udatasel; + if (pcb == curpcb) { + __asm("mov %0,%%fs" : : "r" (_udatasel)); + __asm("mov %0,%%gs" : : "r" (_udatasel)); + } + /* * Initialize the math emulator (if any) for the current process. * Actually, just clear the bit that says that the emulator has @@ -881,7 +890,6 @@ SYSCTL_INT(_machdep, CPU_WALLCLOCK, wall_cmos_clock, * Initialize segments & interrupt table */ -int currentldt; int _default_ldt; #ifdef SMP union descriptor gdt[NGDT + NCPU]; /* global descriptor table */ @@ -1248,7 +1256,9 @@ init386(first) _default_ldt = GSEL(GLDT_SEL, SEL_KPL); lldt(_default_ldt); +#ifdef USER_LDT currentldt = _default_ldt; +#endif #ifdef DDB kdb_init(); diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c index 8052740..d36835d 100644 --- a/sys/amd64/amd64/mp_machdep.c +++ b/sys/amd64/amd64/mp_machdep.c @@ -22,12 +22,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.76 1998/05/17 22:12:08 tegge Exp $ + * $Id: mp_machdep.c,v 1.77 1998/08/16 00:41:40 bde Exp $ */ #include "opt_smp.h" #include "opt_vm86.h" #include "opt_cpu.h" +#include "opt_user_ldt.h" #ifdef SMP #include @@ -466,6 +467,9 @@ init_secondary(void) lgdt(&r_gdt); /* does magic intra-segment return */ lidt(&r_idt); lldt(_default_ldt); +#ifdef USER_LDT + currentldt = _default_ldt; +#endif my_tr = NGDT + cpuid; gsel_tss = GSEL(my_tr, SEL_KPL); diff --git a/sys/amd64/amd64/mptable.c b/sys/amd64/amd64/mptable.c index 8052740..d36835d 100644 --- a/sys/amd64/amd64/mptable.c +++ b/sys/amd64/amd64/mptable.c @@ -22,12 +22,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.76 1998/05/17 22:12:08 tegge Exp $ + * $Id: mp_machdep.c,v 1.77 1998/08/16 00:41:40 bde Exp $ */ #include "opt_smp.h" #include "opt_vm86.h" #include "opt_cpu.h" +#include "opt_user_ldt.h" #ifdef SMP #include @@ -466,6 +467,9 @@ init_secondary(void) lgdt(&r_gdt); /* does magic intra-segment return */ lidt(&r_idt); lldt(_default_ldt); +#ifdef USER_LDT + currentldt = _default_ldt; +#endif my_tr = NGDT + cpuid; gsel_tss = GSEL(my_tr, SEL_KPL); diff --git a/sys/amd64/amd64/sys_machdep.c b/sys/amd64/amd64/sys_machdep.c index bd3dab7..573052e 100644 --- a/sys/amd64/amd64/sys_machdep.c +++ b/sys/amd64/amd64/sys_machdep.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)sys_machdep.c 5.5 (Berkeley) 1/19/91 - * $Id: sys_machdep.c,v 1.34 1998/03/23 19:52:34 jlemon Exp $ + * $Id: sys_machdep.c,v 1.35 1998/07/28 03:29:32 jlemon Exp $ * */ @@ -64,8 +64,8 @@ -void set_user_ldt __P((struct pcb *pcb)); #ifdef USER_LDT +void set_user_ldt __P((struct pcb *pcb)); static int i386_get_ldt __P((struct proc *, char *)); static int i386_set_ldt __P((struct proc *, char *)); #endif diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c index 9c8b1f5..cf16f53 100644 --- a/sys/amd64/amd64/vm_machdep.c +++ b/sys/amd64/amd64/vm_machdep.c @@ -38,7 +38,7 @@ * * from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91 * Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$ - * $Id: vm_machdep.c,v 1.107 1998/05/17 22:12:11 tegge Exp $ + * $Id: vm_machdep.c,v 1.108 1998/05/19 00:00:10 tegge Exp $ */ #include "npx.h" @@ -710,8 +710,10 @@ cpu_exit(p) #endif #ifdef USER_LDT if (pcb->pcb_ldt != 0) { - if (pcb == curpcb) - lldt(GSEL(GUSERLDT_SEL, SEL_KPL)); + if (pcb == curpcb) { + lldt(_default_ldt); + currentldt = _default_ldt; + } kmem_free(kernel_map, (vm_offset_t)pcb->pcb_ldt, pcb->pcb_ldt_len * sizeof(union descriptor)); pcb->pcb_ldt_len = (int)pcb->pcb_ldt = 0; diff --git a/sys/amd64/include/mptable.h b/sys/amd64/include/mptable.h index 8052740..d36835d 100644 --- a/sys/amd64/include/mptable.h +++ b/sys/amd64/include/mptable.h @@ -22,12 +22,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.76 1998/05/17 22:12:08 tegge Exp $ + * $Id: mp_machdep.c,v 1.77 1998/08/16 00:41:40 bde Exp $ */ #include "opt_smp.h" #include "opt_vm86.h" #include "opt_cpu.h" +#include "opt_user_ldt.h" #ifdef SMP #include @@ -466,6 +467,9 @@ init_secondary(void) lgdt(&r_gdt); /* does magic intra-segment return */ lidt(&r_idt); lldt(_default_ldt); +#ifdef USER_LDT + currentldt = _default_ldt; +#endif my_tr = NGDT + cpuid; gsel_tss = GSEL(my_tr, SEL_KPL); diff --git a/sys/amd64/include/pcpu.h b/sys/amd64/include/pcpu.h index c6c5a17..e182d0a 100644 --- a/sys/amd64/include/pcpu.h +++ b/sys/amd64/include/pcpu.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: globaldata.h,v 1.4 1998/05/17 23:08:02 tegge Exp $ + * $Id: globaldata.h,v 1.5 1998/05/28 09:30:02 phk Exp $ */ /* @@ -49,6 +49,9 @@ struct globaldata { u_int private_tss; u_int my_tr; #endif +#ifdef USER_LDT + int currentldt; +#endif #ifdef SMP u_int cpuid; u_int cpu_lockid; diff --git a/sys/i386/i386/genassym.c b/sys/i386/i386/genassym.c index d545c08..cf931cc 100644 --- a/sys/i386/i386/genassym.c +++ b/sys/i386/i386/genassym.c @@ -34,10 +34,11 @@ * SUCH DAMAGE. * * from: @(#)genassym.c 5.11 (Berkeley) 5/10/91 - * $Id: genassym.c,v 1.58 1998/05/28 09:29:55 phk Exp $ + * $Id: genassym.c,v 1.59 1998/07/11 12:17:07 bde Exp $ */ #include "opt_vm86.h" +#include "opt_user_ldt.h" #include @@ -204,6 +205,9 @@ main() printf("#define\tGD_PRIVATE_TSS %#x\n", OS(globaldata, private_tss)); printf("#define\tGD_MY_TR %#x\n", OS(globaldata, my_tr)); #endif +#ifdef USER_LDT + printf("#define\tGD_CURRENTLDT %#x\n", OS(globaldata, currentldt)); +#endif #ifdef SMP printf("#define\tGD_CPUID %#x\n", OS(globaldata, cpuid)); printf("#define\tGD_CPU_LOCKID %#x\n", OS(globaldata, cpu_lockid)); diff --git a/sys/i386/i386/globals.s b/sys/i386/i386/globals.s index a9783a9..a1c2ce5 100644 --- a/sys/i386/i386/globals.s +++ b/sys/i386/i386/globals.s @@ -23,10 +23,11 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: globals.s,v 1.5 1998/05/28 09:29:56 phk Exp $ + * $Id: globals.s,v 1.6 1998/06/21 14:45:00 bde Exp $ */ #include "opt_vm86.h" +#include "opt_user_ldt.h" #ifndef SMP #include @@ -84,6 +85,11 @@ globaldata: .set _my_tr,globaldata + GD_MY_TR #endif +#ifdef USER_LDT + .globl _currentldt + .set _currentldt,globaldata + GD_CURRENTLDT +#endif + #ifdef SMP /* * The BSP version of these get setup in locore.s and pmap.c, while diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index c991f91..f0db465 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.302 1998/06/30 21:25:58 phk Exp $ + * $Id: machdep.c,v 1.303 1998/07/11 07:45:30 bde Exp $ */ #include "apm.h" @@ -801,14 +801,15 @@ setregs(p, entry, stack) u_long stack; { struct trapframe *regs = p->p_md.md_regs; - -#ifdef USER_LDT struct pcb *pcb = &p->p_addr->u_pcb; +#ifdef USER_LDT /* was i386_user_cleanup() in NetBSD */ if (pcb->pcb_ldt) { - if (pcb == curpcb) - lldt(GSEL(GUSERLDT_SEL, SEL_KPL)); + if (pcb == curpcb) { + lldt(_default_ldt); + currentldt = _default_ldt; + } kmem_free(kernel_map, (vm_offset_t)pcb->pcb_ldt, pcb->pcb_ldt_len * sizeof(union descriptor)); pcb->pcb_ldt_len = (int)pcb->pcb_ldt = 0; @@ -824,6 +825,14 @@ setregs(p, entry, stack) regs->tf_es = _udatasel; regs->tf_cs = _ucodesel; + /* reset %fs and %gs as well */ + pcb->pcb_fs = _udatasel; + pcb->pcb_gs = _udatasel; + if (pcb == curpcb) { + __asm("mov %0,%%fs" : : "r" (_udatasel)); + __asm("mov %0,%%gs" : : "r" (_udatasel)); + } + /* * Initialize the math emulator (if any) for the current process. * Actually, just clear the bit that says that the emulator has @@ -881,7 +890,6 @@ SYSCTL_INT(_machdep, CPU_WALLCLOCK, wall_cmos_clock, * Initialize segments & interrupt table */ -int currentldt; int _default_ldt; #ifdef SMP union descriptor gdt[NGDT + NCPU]; /* global descriptor table */ @@ -1248,7 +1256,9 @@ init386(first) _default_ldt = GSEL(GLDT_SEL, SEL_KPL); lldt(_default_ldt); +#ifdef USER_LDT currentldt = _default_ldt; +#endif #ifdef DDB kdb_init(); diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c index 8052740..d36835d 100644 --- a/sys/i386/i386/mp_machdep.c +++ b/sys/i386/i386/mp_machdep.c @@ -22,12 +22,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.76 1998/05/17 22:12:08 tegge Exp $ + * $Id: mp_machdep.c,v 1.77 1998/08/16 00:41:40 bde Exp $ */ #include "opt_smp.h" #include "opt_vm86.h" #include "opt_cpu.h" +#include "opt_user_ldt.h" #ifdef SMP #include @@ -466,6 +467,9 @@ init_secondary(void) lgdt(&r_gdt); /* does magic intra-segment return */ lidt(&r_idt); lldt(_default_ldt); +#ifdef USER_LDT + currentldt = _default_ldt; +#endif my_tr = NGDT + cpuid; gsel_tss = GSEL(my_tr, SEL_KPL); diff --git a/sys/i386/i386/mptable.c b/sys/i386/i386/mptable.c index 8052740..d36835d 100644 --- a/sys/i386/i386/mptable.c +++ b/sys/i386/i386/mptable.c @@ -22,12 +22,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.76 1998/05/17 22:12:08 tegge Exp $ + * $Id: mp_machdep.c,v 1.77 1998/08/16 00:41:40 bde Exp $ */ #include "opt_smp.h" #include "opt_vm86.h" #include "opt_cpu.h" +#include "opt_user_ldt.h" #ifdef SMP #include @@ -466,6 +467,9 @@ init_secondary(void) lgdt(&r_gdt); /* does magic intra-segment return */ lidt(&r_idt); lldt(_default_ldt); +#ifdef USER_LDT + currentldt = _default_ldt; +#endif my_tr = NGDT + cpuid; gsel_tss = GSEL(my_tr, SEL_KPL); diff --git a/sys/i386/i386/sys_machdep.c b/sys/i386/i386/sys_machdep.c index bd3dab7..573052e 100644 --- a/sys/i386/i386/sys_machdep.c +++ b/sys/i386/i386/sys_machdep.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)sys_machdep.c 5.5 (Berkeley) 1/19/91 - * $Id: sys_machdep.c,v 1.34 1998/03/23 19:52:34 jlemon Exp $ + * $Id: sys_machdep.c,v 1.35 1998/07/28 03:29:32 jlemon Exp $ * */ @@ -64,8 +64,8 @@ -void set_user_ldt __P((struct pcb *pcb)); #ifdef USER_LDT +void set_user_ldt __P((struct pcb *pcb)); static int i386_get_ldt __P((struct proc *, char *)); static int i386_set_ldt __P((struct proc *, char *)); #endif diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c index 9c8b1f5..cf16f53 100644 --- a/sys/i386/i386/vm_machdep.c +++ b/sys/i386/i386/vm_machdep.c @@ -38,7 +38,7 @@ * * from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91 * Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$ - * $Id: vm_machdep.c,v 1.107 1998/05/17 22:12:11 tegge Exp $ + * $Id: vm_machdep.c,v 1.108 1998/05/19 00:00:10 tegge Exp $ */ #include "npx.h" @@ -710,8 +710,10 @@ cpu_exit(p) #endif #ifdef USER_LDT if (pcb->pcb_ldt != 0) { - if (pcb == curpcb) - lldt(GSEL(GUSERLDT_SEL, SEL_KPL)); + if (pcb == curpcb) { + lldt(_default_ldt); + currentldt = _default_ldt; + } kmem_free(kernel_map, (vm_offset_t)pcb->pcb_ldt, pcb->pcb_ldt_len * sizeof(union descriptor)); pcb->pcb_ldt_len = (int)pcb->pcb_ldt = 0; diff --git a/sys/i386/include/globaldata.h b/sys/i386/include/globaldata.h index c6c5a17..e182d0a 100644 --- a/sys/i386/include/globaldata.h +++ b/sys/i386/include/globaldata.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: globaldata.h,v 1.4 1998/05/17 23:08:02 tegge Exp $ + * $Id: globaldata.h,v 1.5 1998/05/28 09:30:02 phk Exp $ */ /* @@ -49,6 +49,9 @@ struct globaldata { u_int private_tss; u_int my_tr; #endif +#ifdef USER_LDT + int currentldt; +#endif #ifdef SMP u_int cpuid; u_int cpu_lockid; diff --git a/sys/i386/include/mptable.h b/sys/i386/include/mptable.h index 8052740..d36835d 100644 --- a/sys/i386/include/mptable.h +++ b/sys/i386/include/mptable.h @@ -22,12 +22,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.76 1998/05/17 22:12:08 tegge Exp $ + * $Id: mp_machdep.c,v 1.77 1998/08/16 00:41:40 bde Exp $ */ #include "opt_smp.h" #include "opt_vm86.h" #include "opt_cpu.h" +#include "opt_user_ldt.h" #ifdef SMP #include @@ -466,6 +467,9 @@ init_secondary(void) lgdt(&r_gdt); /* does magic intra-segment return */ lidt(&r_idt); lldt(_default_ldt); +#ifdef USER_LDT + currentldt = _default_ldt; +#endif my_tr = NGDT + cpuid; gsel_tss = GSEL(my_tr, SEL_KPL); diff --git a/sys/i386/include/pcpu.h b/sys/i386/include/pcpu.h index c6c5a17..e182d0a 100644 --- a/sys/i386/include/pcpu.h +++ b/sys/i386/include/pcpu.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: globaldata.h,v 1.4 1998/05/17 23:08:02 tegge Exp $ + * $Id: globaldata.h,v 1.5 1998/05/28 09:30:02 phk Exp $ */ /* @@ -49,6 +49,9 @@ struct globaldata { u_int private_tss; u_int my_tr; #endif +#ifdef USER_LDT + int currentldt; +#endif #ifdef SMP u_int cpuid; u_int cpu_lockid; diff --git a/sys/kern/subr_smp.c b/sys/kern/subr_smp.c index 8052740..d36835d 100644 --- a/sys/kern/subr_smp.c +++ b/sys/kern/subr_smp.c @@ -22,12 +22,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.76 1998/05/17 22:12:08 tegge Exp $ + * $Id: mp_machdep.c,v 1.77 1998/08/16 00:41:40 bde Exp $ */ #include "opt_smp.h" #include "opt_vm86.h" #include "opt_cpu.h" +#include "opt_user_ldt.h" #ifdef SMP #include @@ -466,6 +467,9 @@ init_secondary(void) lgdt(&r_gdt); /* does magic intra-segment return */ lidt(&r_idt); lldt(_default_ldt); +#ifdef USER_LDT + currentldt = _default_ldt; +#endif my_tr = NGDT + cpuid; gsel_tss = GSEL(my_tr, SEL_KPL); -- cgit v1.1