> A second solution is to modify the sequence above so we
> load the descriptor cache with an appropriate value, but
> mark the descriptor table entry thereafter as inaccessible.
> Accesses to the table by instructions will cause an exception,
> at which point the monitor can emulate the instruction.
>
> mon_gdt[GS_index] = GS.cache
> reload GS
> mon_gdt[GS_index] = inaccessible
> ...
> IRET
>
> Now instructions like "MOV GS, AX" will be virtualized. Since
> we can determine when there is no longer any conditions of
> inconsistency between segment descriptor cache and descriptor
> table entry, the monitor can re-evaluate when to return to
> execution of ring3 guest code by way of the first sequence.
> Thereafter, the native CPU segment register loading mechanisms will
> work without intervention. It's worth pointing out, that
> multiple segment registers may use the same table entry.
> For instance, DS/ES/FS/GS may all use the same entry. So
> instructions which reload them will get virtualized as
> a side effect.
That's (nearly) our current implementation. But the cache is a set
of free entries in GDT, what's bad for two reasons:
* Segment Selectors have other values than guest OS expects
* May be that there aren't (enough) free entries in GDT
But think that could be changed easily while you are changing guest
(ring 3) <-> monitor (ring 0) switching. Have to enhance the virtual
guest structures by a number of descriptor entries (one per selector)...
jens