[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v5 4/9] xen/x86: populate PVHv2 Dom0 physical memory map



At 05:41 -0700 on 26 Jan (1485409318), Jan Beulich wrote:
> >>> On 19.01.17 at 18:29, <roger.pau@xxxxxxxxxx> wrote:
> > +/* Size of the VM86 TSS for virtual 8086 mode to use. */
> > +#define HVM_VM86_TSS_SIZE   128
> 
> I continue to be puzzled by this value. Why 128? I think this really
> needs to be clarified in the comment.

I was asked on IRC to do some archaeology / explain myself about this,
so here goes.

First, the _intended_ mechanism for "real mode" guests on older VMX
hardware is to run them in virtual 8086 mode inside the guest as much
as possible, and emulate whenever we can't do that.

This is managed with some state in v->arch.hvm_vmx:
 - vmx_realmode, set when the guest thinks it's in real mode. 
 - vmx_emulate, to force emulation rather than VMENTER
   We set this when we have exceptions to inject, as the VMX hardware
   would try to inject them in 32-bit protected mode.
 - vm86_segment_mask, a bitmask of segments that can't be fudged
   to run in virtual 8086 mode.

When vmx_realmode is set, vmx_do_vmentry() DTRT: it bails out into the
emulator if either vmx_emulate or any bit in vm86_segment_mask is set;
otherwise it calls vmx_enter_realmode() to adjust %rflags and enters
the guest in virtual 8086 mode.

The reason we need a TSS at all is for handling software interrupts.
Virtual 8086 mode has two ways to handle software interrupts: stay in
virtual 8086 mode and vector via the table @0x0, or raise #GP in 32-bit
protected mode.  We want the first of those, so that a guest in 'real mode'
can make BIOS calls.

The CPU uses a bitmap in the TSS to decide which method to use; we
need all the bits in that bitmap to be clear.  In my SDM (April 2016)
this is section 20.3.3 "Class 3 -- Software Interrupt Handling in
Virtual-8086 Mode", table 20-2, method 5.

---

So far so good, and AIUI the system works -- or at least it did in
December 2008 when it was put in (8d4638d1), because emulating every
instruction made Windows boot times so slow that we would definitely
have noticed.

But looking at it now, I'm not convinced of exactly how.  The magic
bitmap in the TSS is at [I/O Map Base Address] - 32, and the I/O map
base address itself lives at offset 100.  A zero'd TSS should mean an
I/O map at 0, and an interrupt redirection bitmap at -32, which would
plausibly work if the TSS were 256 bytes (matching the limit set in
Xen).  Perhaps it's only working because the 128 bytes following the
TSS in hvmloader happen to be zeros too?

I also don't remember why the TSS is 128 rather than 104 bytes.  The
SDM claims that the TSS must be larger than 104 bytes "when accessing
the I/O permission bit map or interrupt redirection bit map."
(7.2.2. "TSS Descriptor") but I suspect that just means that the
generated address of the bitmap must lie inside the limit.

In any case, the limit set in vmx_set_segment_register() should surely
match the size of the actual TSS!

I haven't got the time or hardware to test this right now, but could
maybe look at it next week unless anyone else wants to play with it.

Cheers,

Tim.

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.