From owner-freebsd-emulation@FreeBSD.ORG Mon Jan 22 16:52:28 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 27BDC16A469; Mon, 22 Jan 2007 16:52:28 +0000 (UTC) (envelope-from tijl@ulyssis.org) Received: from thumbler.kulnet.kuleuven.ac.be (thumbler.kulnet.kuleuven.ac.be [134.58.240.45]) by mx1.freebsd.org (Postfix) with ESMTP id B14A013C44C; Mon, 22 Jan 2007 16:52:27 +0000 (UTC) (envelope-from tijl@ulyssis.org) Received: from localhost (localhost [127.0.0.1]) by thumbler.kulnet.kuleuven.ac.be (Postfix) with ESMTP id A83E21382B5; Mon, 22 Jan 2007 17:52:26 +0100 (CET) Received: from smtps01 (octavianus.kulnet.kuleuven.ac.be [134.58.240.71]) by thumbler.kulnet.kuleuven.ac.be (Postfix) with ESMTP id A5572137C97; Mon, 22 Jan 2007 17:52:25 +0100 (CET) Received: from kalimero.kotnet.org (kalimero.kotnet.org [10.4.16.222]) by smtps01 (Postfix) with ESMTP id E1CAE2E68CC; Mon, 22 Jan 2007 17:52:24 +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 l0MGqMkc018492; Mon, 22 Jan 2007 17:52:23 +0100 (CET) (envelope-from tijl@ulyssis.org) From: Tijl Coosemans To: freebsd-emulation@freebsd.org Date: Mon, 22 Jan 2007 17:52:19 +0100 User-Agent: KMail/1.9.5 References: <790a9fff0701211041j1176d00gd6dd75d0989cf4ec@mail.gmail.com> <200701220001.22404.tijl@ulyssis.org> <20070122081810.GA42976@stud.fit.vutbr.cz> In-Reply-To: <20070122081810.GA42976@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: <200701221752.21628.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: Mon, 22 Jan 2007 16:52:28 -0000 On Monday 22 January 2007 09:18, Divacky Roman wrote: > On Mon, Jan 22, 2007 at 12:01:19AM +0100, Tijl Coosemans wrote: > > On Sunday 21 January 2007 19:54, Divacky Roman wrote: > > > On Sun, Jan 21, 2007 at 12:41:02PM -0600, Scot Hetzel wrote: > > > > Divacky Roman asked me to update my sources to the latest P4 > > > > patches and run the tls_test program. Below are the results: > > > > > > > > hp010 / # ./tls_test > > > > > > > > doing 1st set_thread_area(): > > > > ====> got GDT selector: 0x0 --- TEST PASSED. > > > > > > > > reading first byte of [0x00000000] TLS: > > > > ====> 123 --- TEST PASSED. > > > > > > > > doing 2nd set_thread_area(): > > > > ====> got GDT selector: 0x4 --- TEST PASSED. > > > > context-switching once ... > > > > > > > > reading first byte of 4K [0x0804aca0] TLS: > > > > Segmentation fault (core dumped) > > > > > > this means that we are able to set up the TLS for the very first > > > time but not any other time. > > > > > > can someone explain this? > > > > > > the tls_test program is at > > > > > > www.stud.fit.vutbr.cz/~xdivac02/tls_test.c > > > > I don't have an amd64 box, so I can only guess, but I think it's your > > test that's bugged and not your tls implementation. > > > > Your test uses FS and your tls implementation uses GS and while they > > each point to the same GDT entry they don't end up pointing to the > > same addresses because your tls implementation doesn't touch the GDT > > entry at all. It simply (and correctly as far as I can tell) changes > > the upper 32 bits of GS (using wrmsr). > > yeah, I thought about this as well and we might test it but > > 1) why the first test succeeds? Segment registers have a hidden part that contains base address and limit (and some more flags I guess). When you load a value into a segment register, this hidden part is updated with the info contained in the descriptor (entry in GDT/LDT). On amd64 the base address of FS and GS (in this hidden part) can also be changed directly using the wrmsr instruction. The first test requests base address 0x00000000. set_thread_area sets GS.base (in hidden part) to 0x00000000 and returns 4 as descriptor entry number. This is the user data segment descriptor, which base address is also 0x00000000 (I think). So when you next load 4<<3|3 in FS, FS.base also ends up being 0x00000000 and the test succeeds. The second test requests a different base address. GS.base is set to this address, but when you then load 4<<3|3 into FS, FS.base ends up with 0x00000000 and so your second read test fails (NULL pointer dereference). > 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 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.