Skip site navigation (1)Skip section navigation (2)
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>