Date: Wed, 10 Oct 2007 17:11:13 +0300 From: Mihai =?utf-8?q?Don=C8=9Bu?= <mihai.dontu@gmail.com> To: Tijl Coosemans <tijl@ulyssis.org> Cc: freebsd-emulation@freebsd.org, freebsd-questions@freebsd.org, Jung-uk Kim <jkim@freebsd.org> Subject: Re: amd64_set_gsbase() Message-ID: <200710101711.14386.mihai.dontu@gmail.com> In-Reply-To: <200710101533.06287.tijl@ulyssis.org> References: <200710082135.58099.mihai.dontu@gmail.com> <200710090348.52036.mihai.dontu@gmail.com> <200710101533.06287.tijl@ulyssis.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Wednesday 10 October 2007, Tijl Coosemans wrote: > On Tuesday 09 October 2007 02:48:51 Mihai Donțu wrote: > > I have *one* more question: maybe I don't fully understand the hole > > BASE thing, but since the FreeBSD kernel does not preserve %gs and > > %fs, what is the purpose of amd64_set_XXbase()? > > The %fs, %gs registers and fsbase and gsbase MSRs are separate > registers. When you write %gs:offset, you actually get (gsbase+offset), > so the actual value of %gs doesn't matter. > > There are two ways to set gsbase. One is by using the privileged > instruction wrmsr to set gsbase directly (full 64bit base address), > which is what amd64_set_gsbase() exposes to userland. The other is by > loading a descriptor selector in %gs in which case gsbase will be set > to the base address (only 32bit base address) of a descriptor entry in > either the GDT or LDT. Invaluable info. Thanks! :) > To get back to what you are trying to do, because %gs isn't preserved, > I think you should avoid writing to it and instead strictly use > amd64_set_gsbase(). But from what you've written, I'm guessing you're > already doing this, so the next thing to try is to create threads with > PTHREAD_SCOPE_SYSTEM or use libthr instead of libpthread, because if > I'm not mistaken, PTHREAD_SCOPE_PROCESS in libpthread doesn't preserve > gsbase either. Well, I'm am not setting (loading) %gs, I *only* do amd64_set_gsbase() and expect that *all* instructions such as: mov %gs:0x10,%rax to be valid (not segfault). I don't really care what the value of %gs is as long as *all* the instructions as the above work and access the memory specified in amd64_set_gsbase( addr ). I was under the (wrong) impression that the value of %gs is important, that's why I wanted it preserved, but if you say: > [...] When you write %gs:offset, you actually get (gsbase+offset), > so the actual value of %gs doesn't matter. then I don't care if %gs' value gets lost over context switches as long as mov %gs:0x10,%rax and other such instructions, work. However, it turns out that amd64_set_gsbase() is not enough :( Either: a) someone *does* set %gs (and is not me); b) the 'gsbase' gets lost; The thing is I've ported my emulator to Linux and there I use modify_ldt() and then some __asm__ voodoo to load %gs, because (quote from man): - "ARCH_SET_GS is disabled in some kernels." - "Context switches for 64-bit segment bases are rather expensive. It may be a faster alternative to set a 32-bit base using a segment selector by setting up an LDT with modify_ldt(2) [...]" Anyhoo, I'll try to use 'libthr' and see if this helps. Thanks, again! -- Mihai Donțu
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200710101711.14386.mihai.dontu>