Re: [RFC] KVM: x86: emulate movdqa

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

 



On Sun, Jan 8, 2012 at 10:32 AM, Avi Kivity <avi@xxxxxxxxxx> wrote:
> On 01/07/2012 12:26 PM, Stefan Hajnoczi wrote:
>>
>> movdqa %xmm0,(%rdi)
>>
>> This patch adds movdqa to the emulator but does not implement #GP when
>> the memory operand is unaligned to 16 bytes.  I'm not sure whether
>> alignment checking can be implemented as an opcode .flag or if it needs
>> to be done in em_movdqa().
>
> It should actually be automatic when the Sse flag is present, since it's
> the norm for almost all SSE instructions.  There should be a .flag to
> override it for movdqu.

When writing a kvm-unit-test for movdqa I found that alignment
checking happens before the page fault (makes sense).  That means
misalignment is detected by the CPU while still in guest mode.  The
emulator never sees the instruction because #GP is raised and handled
in the guest.

I also didn't see other instances of alignment checking in the
emulator (e.g. eflags AC).  I guess the same situation applies there.

Can you think of a case where we need to perform alignment checking in
the emulator?

>> A more fundamental question: why do we have to emulate this guest
>> userspace SSE instruction in the first place?  This host machine lacks
>> EPT but can't we service the page fault and then retry execution inside
>> the guest?
>
> Not when the target is mmio - there is no possible mapping.  With your
> patch, is there a kvm_mmio trace right after the movdqa emulation?

You are right.  These instructions are accessing the VGA area at 0xa0000.

>> +static int em_movdqa(struct x86_emulate_ctxt *ctxt)
>> +{
>> +     /* TODO alignment */
>> +     memcpy(&ctxt->dst.vec_val, &ctxt->src.vec_val, ctxt->op_bytes);
>> +     return X86EMUL_CONTINUE;
>> +}
>
> em_mov() should be adjusted to work here.

Ok.

>> +
>>  static int em_movdqu(struct x86_emulate_ctxt *ctxt)
>>  {
>>       memcpy(&ctxt->dst.vec_val, &ctxt->src.vec_val, ctxt->op_bytes);
>> @@ -3115,7 +3122,7 @@ static struct opcode group11[] = {
>>  };
>>
>>  static struct gprefix pfx_0f_6f_0f_7f = {
>> -     N, N, N, I(Sse, em_movdqu),
>> +     N, I(Sse, em_movdqa), N, I(Sse, em_movdqu),
>>  };
>>
>
> Need the Mov flag too (I see it's missing for movdqu as well); otherwise
> the emulator will RMW the destination.

The Mov is already given by the GP() group prefix.

Stefan
--
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


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux