All of lore.kernel.org
 help / color / mirror / Atom feed
From: Razvan Cojocaru <rcojocaru@bitdefender.com>
To: Andrew Cooper <andrew.cooper3@citrix.com>,
	Andrei LUTAS <vlutas@bitdefender.com>,
	Jan Beulich <JBeulich@suse.com>
Cc: keir@xen.org, "xen-devel@lists.xen.org" <xen-devel@lists.xen.org>
Subject: Re: Possible problem emulating movntq, movss
Date: Wed, 06 Aug 2014 14:22:59 +0300	[thread overview]
Message-ID: <53E21013.1060705@bitdefender.com> (raw)
In-Reply-To: <53E20BF1.7060503@citrix.com>

On 08/06/2014 02:05 PM, Andrew Cooper wrote:
> On 06/08/2014 11:47, Andrei LUTAS wrote:
>> Hello there,
>>
>> On 8/6/2014 12:54 PM, Jan Beulich wrote:
>>>>>> On 06.08.14 at 10:57, <rcojocaru@bitdefender.com> wrote:
>>>> We found that our HVM guests froze when trying to emulate movntq
>>>> instructions. The solution seems to be to replace "goto done;" with
>>>> "break;" at line 4191 (when handling "case 0x7f:") in
>>>> xen/arch/x86/x86_emulate/x86_emulate.c. Otherwise the writeback part
>>>> doesn't happen.
>>>>
>>>> If you're happy with the fix I can prepare a patch, otherwise please
>>>> let
>>>> me know if we're missing something.
>>> No, that doesn't look right: There's nothing left to be written back at
>>> that point (registers get updated with the instruction executed via the
>>> on-stack stub, and memory gets written with immediately preceding
>>> ops->write(). So without you being more specific about _what_ you
>>> see going wrong I don't think I can give further advice.
>> Except for maybe the instruction pointer? That doesn't seem to be updated
>> anywhereexcept during the write-back phase (or maybe I'm missing the
>> spot).
>> The problem is that the guest gets stuck with the instruction pointer
>> pointing to the sameinstruction (in our particular case it is
>> "MOVDQU xmm0, xmmword ptr [rdx + rcx - 0x10]"),entering in an infinite
>> loop (EPT violation - emulate), since the IP doesn't seem to be updated.
>>>
>>> Furthermore what you write is kind of inconsistent: For one, opcode
>>> 0x7f is movq/movdq[au] rather than movntdq (admitted they're
>>> being handled by the same code block, but you ought to be rather
>>> precise here). And then the subject of your mail mentions movss, but
>>> the body doesn't at all - is that because you mean the same would
>>> apply to that other similar code block?
>> A quick look reveals that 0x0f 0x2b/0x28/0x29/0x10/0x11 and 0x0f
>> 0xe7/0x6f/0x7f
>> encodings are all affected. While other places may be affected too,
>> these two
>> encoding sets seem to be the only ones where "goto done;" is used
>> unconditionally instead of a "break;" - all otheruses of "goto done;" are
>> made when an error is encountered.
>>
>>>
>>> As to Andrew asking for added tests: movq, movdqu, and vmovdqu
>>> are all being tested with both operation directions (covering one of
>>> the two code blocks in question), and the set of tests for movsd,
>>> movaps, vmovsd, and vmovaps should be sufficient to cover the
>>> other of the two code blocks too.
>>>
>>> Jan
>> Best regards,
>> Andrei.
> 
> It would appear that for some instructions, these movxxx included, the
> test harness does not verify that the instruction pointer has been
> suitably updated.
> 
> It is plausible that this is a real bug and the unit tests are
> erroneously passing.  I would suggest starting by adding instruction
> pointer checks to the test harness first to confirm whether there is a bug.

Quick and dirty test:

655     printf("%-40s", "Testing movdqu %xmm2,(%ecx)...");
656     if ( stack_exec && cpu_has_sse2 )
657     {
658         extern const unsigned char movdqu_to_mem[];
659
660         asm volatile ( "pcmpeqb %%xmm2, %%xmm2\n"
661                        ".pushsection .test, \"a\", @progbits\n"
662                        "movdqu_to_mem: movdqu %%xmm2, (%0)\n"
663                        ".popsection" :: "c" (NULL) );
664
665         memcpy(instr, movdqu_to_mem, 15);
666         memset(res, 0x55, 64);
667         memset(res + 8, 0xff, 16);
668         regs.eip    = (unsigned long)&instr[0];
669         regs.ecx    = (unsigned long)res;
670         rc = x86_emulate(&ctxt, &emulops);
671         if ( (rc != X86EMUL_OKAY) || memcmp(res, res + 8, 32) )
672             goto fail;
673
674         if ( regs.eip == (unsigned long)&instr[0] )
675             printf("eip has NOT been updated!\n");
676         else
677             printf("okay\n");
678     }
679     else
680         printf("skipped\n");

Output:

Testing movdqu %xmm2,(%ecx)...          eip has NOT been updated!


Thanks,
Razvan Cojocaru

  reply	other threads:[~2014-08-06 11:22 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-08-06  8:57 Possible problem emulating movntq, movss Razvan Cojocaru
2014-08-06  9:22 ` Andrew Cooper
2014-08-06  9:54 ` Jan Beulich
2014-08-06 10:39   ` Razvan Cojocaru
2014-08-06 10:47   ` Andrei LUTAS
2014-08-06 11:05     ` Andrew Cooper
2014-08-06 11:22       ` Razvan Cojocaru [this message]
2014-08-06 12:16     ` Jan Beulich
2014-08-06 12:50       ` Jan Beulich
2014-08-07  8:09         ` Razvan Cojocaru
2014-08-06 12:29     ` Jan Beulich

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=53E21013.1060705@bitdefender.com \
    --to=rcojocaru@bitdefender.com \
    --cc=JBeulich@suse.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=keir@xen.org \
    --cc=vlutas@bitdefender.com \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.