On Jun 4, 2014, at 7:34 PM, Paolo Bonzini <[email protected]> wrote:
> Il 04/06/2014 16:44, Alexander Graf ha scritto:
>>
>>
>>> Obviously, if you really like the current behavior better you can
>>> always reject whatever patch I'll come up with, but I'd like to at
>>> least try and see what it would look like :)
>>
>> I think it's perfectly fine to leave mwait always implemented as NOP -
>> it's valid behavior.
>>
>> As for the CPUID exposure, that should be a pure QEMU thing. If
>> overriding CPUID bits the kernel mask tells us doesn't work today, we
>> should just make it possible :).
>
> That should be the purpose of KVM_GET_EMULATED_CPUID, so MWAIT could be added
> in __do_cpuid_ent_emulated. However, the corresponding QEMU patches were
> never included. Borislav, can you refresh them?
Regardless to the whole discussion of what the guest is informed about, I think
it might be better to implement mwait and monitor correctly according to the
spec and let the instructions to be fully emulated.
Both mwait and monitor may encounter exceptions (#GP, #PF, regardless of #UD),
so this behaviour should be correct.
If you want me, I’ll send my version which looks something like:
static int em_monitor(struct x86_emulate_ctxt *ctxt)
{
int rc;
struct segmented_address addr;
u64 rcx = reg_read(ctxt, VCPU_REGS_RCX);
u64 rax = reg_read(ctxt, VCPU_REGS_RAX);
u8 byte;
rc = check_mwait_supported(ctxt);
if (rc != X86EMUL_CONTINUE)
return rc;
if (ctxt->mode != X86EMUL_MODE_PROT64)
rcx = (u32)rcx;
if (rcx != 0)
return emulate_gp(ctxt, 0);
addr.seg = seg_override(ctxt);
addr.ea = ctxt->ad_bytes == 8 ? rax : (u32)rax;
rc = segmented_read(ctxt, addr, &byte, 1);
if (rc != X86EMUL_CONTINUE)
return rc;
return X86EMUL_CONTINUE;
}
static int em_mwait(struct x86_emulate_ctxt *ctxt)
{
u64 rcx = reg_read(ctxt, VCPU_REGS_RCX);
int rc = check_mwait_supported(ctxt);
if (rc != X86EMUL_CONTINUE)
return rc;
if (ctxt->mode != X86EMUL_MODE_PROT64)
rcx = (u32)rcx;
if ((rcx & ~(u64)1) != 0)
return emulate_gp(ctxt, 0);
if (rcx & 1) {
/* Interrupt as break event */
u32 ebx, ecx, edx, eax;
eax = 5;
ecx = 0;
ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx);
if (!(ecx & 1))
return emulate_gp(ctxt, 0);
}
return X86EMUL_CONTINUE;
}
signature.asc
Description: Message signed with OpenPGP using GPGMail
