[VMXASSIST] Fix mishandling of segment registers on entry into VM86_PROTECTED mode.
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Thu, 9 Nov 2006 14:00:40 +0000 (14:00 +0000)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Thu, 9 Nov 2006 14:00:40 +0000 (14:00 +0000)
commit21b5e9be6acce19ff8aa22e55a0ddc69d7b19750
treea97acc346e99e9572fa7422e2265b43245ea3441
parentd857ed522cd3e7f3a978c85b01d5ba7feaec999c
[VMXASSIST] Fix mishandling of segment registers on entry into VM86_PROTECTED mode.

The bug occurs when the guest is entering protected mode and reaches
the far jump to set up the 32-bit segment registers for the virtual
VMENTER we're about to perform. vmxassist, in protected_mode(), looks
at the segment registers, which might be 16-bit segments or might be
32-bit segment selectors at this stage (depending on whether the OS
has reloaded them since entering protected mode); and it tries to load
the segments from the GDT.  Unconditionally.  Even if the segment
register still actually contains a real mode 16-bit segment.  Whoops.

vmxassist already has code to detect 16-bit segments that survived
unmodified from a transition into and out of protected mode, and to
save and restore those appropriately.  It does this using
"saved_rm_regs", which get cleared on entry to protected mode, and
then set to the old segment value if we fail to set a given 32-bit
segment correctly.

The fix is to save the 16-bit segments *always*, on entry to protected
mode when %CR0(PE) is first set; and to clear the saved 16-bit segment
and set the 32-bit variant in oldctx whenever a 32-bit segment
descriptor is set during the transition to 32-bit CS.  Then, when we
finally do the VMENTER, we will set up the VMCS from only the 32-bit
segments, clearing the VMCS entries for segments that have not been
assigned valid 32-bit segments yet.

Tested on various RHEL-5 boot.isos, including ones which worked before
and ones which triggered the bug; all now boot correctly.

Signed-off-by: Stephen Tweedie <sct@redhat.com>
tools/firmware/vmxassist/vm86.c