]> git.baikalelectronics.ru Git - kernel.git/commit
KVM: x86: Fix zero iterations REP-string
authorNadav Amit <namit@cs.technion.ac.il>
Tue, 28 Apr 2015 10:06:01 +0000 (13:06 +0300)
committerPaolo Bonzini <pbonzini@redhat.com>
Tue, 19 May 2015 18:52:36 +0000 (20:52 +0200)
commit0859a017ceec4ea9f71f4661adec68b20d30a3a0
tree88b926274e851fc4919468fdd24a30ca52086b2f
parente67d842cb9379a2c12b1688bb1e916f58884682d
KVM: x86: Fix zero iterations REP-string

When a REP-string is executed in 64-bit mode with an address-size prefix,
ECX/EDI/ESI are used as counter and pointers. When ECX is initially zero, Intel
CPUs clear the high 32-bits of RCX, and recent Intel CPUs update the high bits
of the pointers in MOVS/STOS. This behavior is specific to Intel according to
few experiments.

As one may guess, this is an undocumented behavior. Yet, it is observable in
the guest, since at least VMX traps REP-INS/OUTS even when ECX=0. Note that
VMware appears to get it right.  The behavior can be observed using the
following code:

 #include <stdio.h>

 #define LOW_MASK (0xffffffff00000000ull)
 #define ALL_MASK (0xffffffffffffffffull)
 #define TEST(opcode) \
do { \
asm volatile(".byte 0xf2 \n\t .byte 0x67 \n\t .byte " opcode "\n\t" \
: "=S"(s), "=c"(c), "=D"(d)  \
: "S"(ALL_MASK), "c"(LOW_MASK), "D"(ALL_MASK)); \
printf("opcode %s rcx=%llx rsi=%llx rdi=%llx\n", \
opcode, c, s, d); \
} while(0)

void main()
{
unsigned long long s, d, c;
iopl(3);
TEST("0x6c");
TEST("0x6d");
TEST("0x6e");
TEST("0x6f");
TEST("0xa4");
TEST("0xa5");
TEST("0xa6");
TEST("0xa7");
TEST("0xaa");
TEST("0xab");
TEST("0xae");
TEST("0xaf");
}

Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/emulate.c