From owner-freebsd-emulation@FreeBSD.ORG Tue Jan 23 00:01:55 2007 Return-Path: X-Original-To: freebsd-emulation@freebsd.org Delivered-To: freebsd-emulation@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 7FC8B16A400; Tue, 23 Jan 2007 00:01:55 +0000 (UTC) (envelope-from tijl@ulyssis.org) Received: from nibbel.kulnet.kuleuven.ac.be (nibbel.kulnet.kuleuven.ac.be [134.58.240.41]) by mx1.freebsd.org (Postfix) with ESMTP id 15C3713C469; Tue, 23 Jan 2007 00:01:54 +0000 (UTC) (envelope-from tijl@ulyssis.org) Received: from localhost (localhost [127.0.0.1]) by nibbel.kulnet.kuleuven.ac.be (Postfix) with ESMTP id A6C304D2C9; Tue, 23 Jan 2007 01:01:53 +0100 (CET) Received: from smtp02.kuleuven.be (lepidus.kulnet.kuleuven.ac.be [134.58.240.72]) by nibbel.kulnet.kuleuven.ac.be (Postfix) with ESMTP id 027D74D0A6; Tue, 23 Jan 2007 01:01:53 +0100 (CET) Received: from kalimero.kotnet.org (kalimero.kotnet.org [10.4.16.222]) by smtp02.kuleuven.be (Postfix) with ESMTP id B158E2CAA72; Tue, 23 Jan 2007 01:01:52 +0100 (CET) Received: from kalimero.kotnet.org (kalimero.kotnet.org [127.0.0.1]) by kalimero.kotnet.org (8.13.8/8.13.8) with ESMTP id l0N01q6h042164; Tue, 23 Jan 2007 01:01:52 +0100 (CET) (envelope-from tijl@ulyssis.org) From: Tijl Coosemans To: freebsd-emulation@freebsd.org Date: Tue, 23 Jan 2007 01:01:49 +0100 User-Agent: KMail/1.9.5 References: <790a9fff0701211041j1176d00gd6dd75d0989cf4ec@mail.gmail.com> <200701221752.21628.tijl@ulyssis.org> <20070122212624.GA49466@stud.fit.vutbr.cz> In-Reply-To: <20070122212624.GA49466@stud.fit.vutbr.cz> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200701230101.51580.tijl@ulyssis.org> X-Virus-Scanned: by KULeuven Antivirus Cluster Cc: jkim@freebsd.org Subject: Re: linuxolator: tls_test results amd64 X-BeenThere: freebsd-emulation@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Development of Emulators of other operating systems List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Jan 2007 00:01:55 -0000 On Monday 22 January 2007 22:26, Divacky Roman wrote: > > > 2) why real apps (ie. using %gs) show the very same behaviour (first > > > program works then it doesnt) > > > > Hmm, can you point me to the source of such a program? I would expect > > programs that use glibc to always fail. Glibc expects set_thread_area > > to setup a GDT entry and return the entry number. Then glibc loads > > that entry number into GS which sets up GS.base. Because of this, I > > would expect GS.base to always end up being 0x00000000 just as FS.base > > above. > > > > Wine on Linux does the same. It calls set_thread_area and loads the > > returned entry number in FS. (On Windows, FS is used for tls.) > > > > The reason setting GS.base directly with a wrmsr works on FreeBSD is > > because i386 user land code doesn't write to GS. i386_set_gsbase > > what do you mean by "writing to GS" ? mov something, %gs Linux glibc does this after calling set_thread_area, which loads the base address in the GDT entry into GS.base, overwriting the GS.base previously setup using wrmsr. FreeBSD libc/libpthread don't do this. > > already sets up GS on i386, so the compatibility code on amd64 can > > use the wrmsr trick and leave GS itself and the descriptor it points > > to untouched. As far as I understand things, this won't work for > > linux32 compatibility on amd64. > > lookin at the code it looks like: > > i386_set_gsbase = sysarch(I386_SET_GSBASE, &addr); > > and sysarch for that looks like: > wrmsr(MSR_KGSBASE, i386base); > pcb->pcb_gsbase = i386base; > > where is the setting up of the GS? I dont get it... GS.base is what matters for address calculations. In the i386 version, this is set by setting up a GDT entry and loading the entry's index into GS. In the amd64 version, which you gave above, GS.base is set directly. (Actuallyn the code above sets a copy of GS.base. When switching between user and kernel mode, a swapgs instruction swaps kernel GS.base and user GS.base) > overall you are saying that to support linux32 tls we have to > > 1) load an unused segment with proper values > 2) return the number of the segment from the set_thread_syscall > 3) make the automatic loading/unloading of that segment to happen on > every context switch (just like its done for segment 3 on i386) > > do I get it right? 1) Yes, but the amd64 code has no GDT entry reserved for this right now it seems, so you have to add one. I don't really know how that's done, but what I would try (if I had the time) is to add an entry to the gdt_segs array in sys/amd64/amd64/machdep.c, say at index 6 and then adjust the defines and NGDT in sys/amd64/include/segments.h. 2) Just as you do now. Set the entry number and do a copyout. The syscall returns 0 on success. FYI, the glibc code that uses this syscall is in glibc-2.3.6/nptl/sysdeps/i386/tls.h:185:TLS_INIT_TP 3) Yes. You'll have to add a field to the pcb to store a copy of the descriptor. And then adjust the context switch code. After that, the amd64 version of set_thread_area becomes virtually the same as the i386 version. Setup a descriptor and copy it to the pcb and GDT. Most of this is copy/paste work I guess. The tricky part is to figure out what to copy and where to paste it. This should get basic tls working I think. The actual set_thread_area is a bit more complicated. It has 3 GDT entries available and when called with -1 as the entry number, it will select an unused entry. I don't know if there are programs that use all 3 (some tests maybe?). The only program I know that uses 2 is wine.