On 08/11/2010 07:20 AM, Avi Kivity wrote:
On 08/11/2010 07:04 AM, Avi Kivity wrote:
This is 32-bit code, yet from the trace:
qemu-system-x86-4321 [001] 150.002276: kvm_exit: reason
EXCEPTION_NMI rip 0x1a
qemu-system-x86-4321 [001] 150.002277: kvm_page_fault: address
d4dc error_code f
The address is trimmed, so kvm thinks we're in real mode! The '0f
00' is just leftover bytes from the instruction.
We'll need earlier traces to find how the mixup happened.
I think I have it:
static int load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
struct x86_emulate_ops *ops,
u16 selector, int seg)
{
struct desc_struct seg_desc;
u8 dpl, rpl, cpl;
unsigned err_vec = GP_VECTOR;
u32 err_code = 0;
bool null_selector = !(selector & ~0x3); /* 0000-0003 are null */
int ret;
memset(&seg_desc, 0, sizeof seg_desc);
if ((seg <= VCPU_SREG_GS && ctxt->mode == X86EMUL_MODE_VM86)
|| ctxt->mode == X86EMUL_MODE_REAL) {
/* set real mode segment descriptor */
set_desc_base(&seg_desc, selector << 4);
set_desc_limit(&seg_desc, 0xffff);
seg_desc.type = 3;
seg_desc.p = 1;
seg_desc.s = 1;
goto load;
}
seg_desc is not initialized, so seg_desc.d gets a random value. This
selects 32-bit or 16-bit mode, and explains the confusion. Likely the
other case as well.
It is initialized, I even quoted the memset(). So the problem is
somewhere else, we'll need more traces to find out.
--
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html