From owner-freebsd-bugs Wed Aug 12 11:00:10 1998 Return-Path: Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id LAA08241 for freebsd-bugs-outgoing; Wed, 12 Aug 1998 11:00:10 -0700 (PDT) (envelope-from owner-freebsd-bugs@FreeBSD.ORG) Received: from freefall.freebsd.org (freefall.FreeBSD.ORG [204.216.27.21]) by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id LAA08147 for ; Wed, 12 Aug 1998 11:00:03 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.8.8/8.8.5) id LAA27305; Wed, 12 Aug 1998 11:00:00 -0700 (PDT) Received: from chen.ml.org (luoqi.watermarkgroup.com [207.202.73.170]) by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id KAA06650 for ; Wed, 12 Aug 1998 10:50:35 -0700 (PDT) (envelope-from luoqi@chen.ml.org) Received: (from luoqi@localhost) by sabrina.chen.ml.org (8.9.1/8.9.1) id NAA02965; Wed, 12 Aug 1998 13:31:42 -0400 (EDT) (envelope-from luoqi) Message-Id: <199808121731.NAA02965@sabrina.chen.ml.org> Date: Wed, 12 Aug 1998 13:31:42 -0400 (EDT) From: Luoqi Chen Reply-To: luoqi@chen.ml.org To: FreeBSD-gnats-submit@FreeBSD.ORG X-Send-Pr-Version: 3.2 Subject: i386/7591: Move `currentldt' to per-cpu area (for wine to work on SMP) Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org >Number: 7591 >Category: i386 >Synopsis: `currentldt' should be in per-cpu area on SMP >Confidential: no >Severity: serious >Priority: high >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Wed Aug 12 11:00:00 PDT 1998 >Last-Modified: >Originator: Luoqi Chen >Organization: >Release: FreeBSD 3.0-CURRENT i386 >Environment: 3.0-CURRENT SMP kernel with USER_LDT option. >Description: 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. >How-To-Repeat: Run wine on a SMP machine with SMP kernel. >Fix: 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. Index: sys/i386/i386/genassym.c =================================================================== RCS file: /fun/cvs/src/sys/i386/i386/genassym.c,v retrieving revision 1.59 diff -u -r1.59 genassym.c --- genassym.c 1998/07/11 12:17:07 1.59 +++ genassym.c 1998/08/11 22:26:13 @@ -38,6 +38,7 @@ */ #include "opt_vm86.h" +#include "opt_user_ldt.h" #include @@ -203,6 +204,9 @@ printf("#define\tGD_COMMON_TSSD %#x\n", OS(globaldata, common_tssd)); 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)); Index: sys/i386/i386/globals.s =================================================================== RCS file: /fun/cvs/src/sys/i386/i386/globals.s,v retrieving revision 1.6 diff -u -r1.6 globals.s --- globals.s 1998/06/21 14:45:00 1.6 +++ globals.s 1998/08/11 22:26:42 @@ -27,6 +27,7 @@ */ #include "opt_vm86.h" +#include "opt_user_ldt.h" #ifndef SMP #include @@ -82,6 +83,11 @@ .set _common_tssd,globaldata + GD_COMMON_TSSD .set _private_tss,globaldata + GD_PRIVATE_TSS .set _my_tr,globaldata + GD_MY_TR +#endif + +#ifdef USER_LDT + .globl _currentldt + .set _currentldt,globaldata + GD_CURRENTLDT #endif #ifdef SMP Index: sys/i386/i386/machdep.c =================================================================== RCS file: /fun/cvs/src/sys/i386/i386/machdep.c,v retrieving revision 1.303 diff -u -r1.303 machdep.c --- machdep.c 1998/07/11 07:45:30 1.303 +++ machdep.c 1998/08/11 22:35:23 @@ -801,14 +801,15 @@ 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 @@ 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 @@ * Initialize segments & interrupt table */ -int currentldt; int _default_ldt; #ifdef SMP union descriptor gdt[NGDT + NCPU]; /* global descriptor table */ @@ -1248,7 +1256,9 @@ _default_ldt = GSEL(GLDT_SEL, SEL_KPL); lldt(_default_ldt); +#ifdef USER_LDT currentldt = _default_ldt; +#endif #ifdef DDB kdb_init(); Index: sys/i386/i386/mp_machdep.c =================================================================== RCS file: /fun/cvs/src/sys/i386/i386/mp_machdep.c,v retrieving revision 1.76 diff -u -r1.76 mp_machdep.c --- mp_machdep.c 1998/05/17 22:12:08 1.76 +++ mp_machdep.c 1998/08/11 22:25:26 @@ -28,6 +28,7 @@ #include "opt_smp.h" #include "opt_vm86.h" #include "opt_cpu.h" +#include "opt_user_ldt.h" #ifdef SMP #include @@ -466,6 +467,9 @@ 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); Index: sys/i386/i386/sys_machdep.c =================================================================== RCS file: /fun/cvs/src/sys/i386/i386/sys_machdep.c,v retrieving revision 1.35 diff -u -r1.35 sys_machdep.c --- sys_machdep.c 1998/07/28 03:29:32 1.35 +++ sys_machdep.c 1998/08/11 22:32:03 @@ -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 Index: sys/i386/i386/vm_machdep.c =================================================================== RCS file: /fun/cvs/src/sys/i386/i386/vm_machdep.c,v retrieving revision 1.108 diff -u -r1.108 vm_machdep.c --- vm_machdep.c 1998/05/19 00:00:10 1.108 +++ vm_machdep.c 1998/07/04 03:05:13 @@ -710,8 +710,10 @@ #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; Index: sys/i386/include/globaldata.h =================================================================== RCS file: /fun/cvs/src/sys/i386/include/globaldata.h,v retrieving revision 1.5 diff -u -r1.5 globaldata.h --- globaldata.h 1998/05/28 09:30:02 1.5 +++ globaldata.h 1998/08/11 22:15:54 @@ -49,6 +49,9 @@ u_int private_tss; u_int my_tr; #endif +#ifdef USER_LDT + int currentldt; +#endif #ifdef SMP u_int cpuid; u_int cpu_lockid; >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message