Ulrich Weigand wrote:
>
> Hello,
>
> just a quick question: Kevin, you said you've already planned the use
> of a different address space in the monitor; I was wondering how you
> intend to perform the actual PDBR switch.
>
> AFAIK there's only two ways to do it: either by placing the code that
> performs the switch into a page mapped to the same linear address in
> both spaces, or else using a task switch that reloads the PDBR.
>
> The first method is ugly as we need to force a particular linear address
> inside the Linux address space, but the second method is somewhat ugly
> as well as we need to load the GDT *before* the task switch, so that
> the TSS descriptor is available, but then after the task switch, the
> linear base address of the GDT will have changed :-/
>
> What do you think?
Yes, these are some good comments. I've been down this road
and found the same. There are some hacky ways I was thinking
of, for utilizing tasking, but getting back to host context
is worse since you don't have the same room to play.
The simplist way is to have a host<->monitor shim which
sits within a single page of memory. The address in
the host world is just the linear address where insmod
places your module code. When you're in the guest and
you want to get back to the host, you make a quick
switch of that page mapping to make it the same physical
address as in the host, invalidate the TLB entry for it,
then jump to it. (remember the differences in CS base
values though!)
A similar process happens in reverse. After you've made
the transition, you have to restore the page mapping back to the
way the guest wants it. During normal operation in the guest,
the page of shim code does not exist in the linear addressing
world, or at least it doesn't need to.
I call this the "worm hole" technique. That one page (it could
be more but you shouldn't need it) is the nexus between the
host linear world and the guest linear world. You open it
up, make your quantum jump into the next world, then close
the worm hole behind you.
-Kevin