xen/53e47d6b-x86_emulate-properly-do-IP-updates-and-other-side-effects.patch
Charles Arnold 3e51b51ba9 - bnc#883112 - Xen Panic during boot "System without CMOS RTC must
be booted from EFI"
  53dba447-x86-ACPI-allow-CMOS-RTC-use-even-when-ACPI-says-there-is-none.patch
- Upstream patches from Jan
  53d7b781-x86-cpu-undo-BIOS-CPUID-max_leaf-limit-earlier.patch
  53df71c7-lz4-check-for-underruns.patch
  53df727b-x86-HVM-extend-LAPIC-shortcuts-around-P2M-lookups.patch
  53e47d6b-x86_emulate-properly-do-IP-updates-and-other-side-effects.patch

- Update to Xen Version 4.4.1-rc2
  xen-4.4.1-testing-src.tar.bz2
- Dropped 60 upstream patches and xen-4.4.0-testing-src.tar.bz2

- bnc#820873 - The "long" option doesn't work with "xl list"
  53d124e7-fix-list_domain_details-check-config-data-length-0.patch

- bnc#888996 - Package 'xen-tool' contains 'SuSE' spelling in a
  filename and/or SPEC file
  Renamed README.SuSE -> README.SUSE
  Modified files: xen.spec, boot.local.xenU, init.pciback
  xend-config.patch, xend-vif-route-ifup.patch

- bnc#882673 - Dom0 memory should enforce a minimum memory size
  (e.g. dom0_mem=min:512M)
  xen.spec (Mike Latimer)

OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=324
2014-08-15 14:33:16 +00:00

379 lines
15 KiB
Diff

# Commit 3af450fd2d9403f208d3ac6459716f027b8597ad
# Date 2014-08-08 09:34:03 +0200
# Author Jan Beulich <jbeulich@suse.com>
# Committer Jan Beulich <jbeulich@suse.com>
x86_emulate: properly do IP updates and other side effects on success
The two MMX/SSE/AVX code blocks failed to update IP properly, and these
as well as get_reg_refix(), which "manually" updated IP so far, failed
to do the TF and RF processing needed at the end of successfully
emulated instructions.
Fix the test utility at once to check IP is properly getting updated,
and while at it macroize the respective code quite a bit, hopefully
making it easier to add further tests when the need arises.
Reported-by: Andrei LUTAS <vlutas@bitdefender.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Tested-by: Razvan Cojocaru <rcojocaru@bitdefender.com>
Reviewed-by: Andrew Cooper <andrew.cooper@citrix.com>
--- a/tools/tests/x86_emulator/test_x86_emulator.c
+++ b/tools/tests/x86_emulator/test_x86_emulator.c
@@ -597,23 +597,32 @@ int main(int argc, char **argv)
printf("skipped\n");
#endif
+#define decl_insn(which) extern const unsigned char which[], which##_len[]
+#define put_insn(which, insn) ".pushsection .test, \"ax\", @progbits\n" \
+ #which ": " insn "\n" \
+ ".equ " #which "_len, .-" #which "\n" \
+ ".popsection"
+#define set_insn(which) (regs.eip = (unsigned long)memcpy(instr, which, \
+ (unsigned long)which##_len))
+#define check_eip(which) (regs.eip == (unsigned long)instr + \
+ (unsigned long)which##_len)
+
printf("%-40s", "Testing movq %mm3,(%ecx)...");
if ( stack_exec && cpu_has_mmx )
{
- extern const unsigned char movq_to_mem[];
+ decl_insn(movq_to_mem);
asm volatile ( "pcmpeqb %%mm3, %%mm3\n"
- ".pushsection .test, \"a\", @progbits\n"
- "movq_to_mem: movq %%mm3, (%0)\n"
- ".popsection" :: "c" (NULL) );
+ put_insn(movq_to_mem, "movq %%mm3, (%0)")
+ :: "c" (NULL) );
- memcpy(instr, movq_to_mem, 15);
+ set_insn(movq_to_mem);
memset(res, 0x33, 64);
memset(res + 8, 0xff, 8);
- regs.eip = (unsigned long)&instr[0];
regs.ecx = (unsigned long)res;
rc = x86_emulate(&ctxt, &emulops);
- if ( (rc != X86EMUL_OKAY) || memcmp(res, res + 8, 32) )
+ if ( (rc != X86EMUL_OKAY) || memcmp(res, res + 8, 32) ||
+ !check_eip(movq_to_mem) )
goto fail;
printf("okay\n");
}
@@ -623,19 +632,17 @@ int main(int argc, char **argv)
printf("%-40s", "Testing movq (%edx),%mm5...");
if ( stack_exec && cpu_has_mmx )
{
- extern const unsigned char movq_from_mem[];
+ decl_insn(movq_from_mem);
asm volatile ( "pcmpgtb %%mm5, %%mm5\n"
- ".pushsection .test, \"a\", @progbits\n"
- "movq_from_mem: movq (%0), %%mm5\n"
- ".popsection" :: "d" (NULL) );
+ put_insn(movq_from_mem, "movq (%0), %%mm5")
+ :: "d" (NULL) );
- memcpy(instr, movq_from_mem, 15);
- regs.eip = (unsigned long)&instr[0];
+ set_insn(movq_from_mem);
regs.ecx = 0;
regs.edx = (unsigned long)res;
rc = x86_emulate(&ctxt, &emulops);
- if ( rc != X86EMUL_OKAY )
+ if ( rc != X86EMUL_OKAY || !check_eip(movq_from_mem) )
goto fail;
asm ( "pcmpeqb %%mm3, %%mm3\n\t"
"pcmpeqb %%mm5, %%mm3\n\t"
@@ -650,20 +657,19 @@ int main(int argc, char **argv)
printf("%-40s", "Testing movdqu %xmm2,(%ecx)...");
if ( stack_exec && cpu_has_sse2 )
{
- extern const unsigned char movdqu_to_mem[];
+ decl_insn(movdqu_to_mem);
asm volatile ( "pcmpeqb %%xmm2, %%xmm2\n"
- ".pushsection .test, \"a\", @progbits\n"
- "movdqu_to_mem: movdqu %%xmm2, (%0)\n"
- ".popsection" :: "c" (NULL) );
+ put_insn(movdqu_to_mem, "movdqu %%xmm2, (%0)")
+ :: "c" (NULL) );
- memcpy(instr, movdqu_to_mem, 15);
+ set_insn(movdqu_to_mem);
memset(res, 0x55, 64);
memset(res + 8, 0xff, 16);
- regs.eip = (unsigned long)&instr[0];
regs.ecx = (unsigned long)res;
rc = x86_emulate(&ctxt, &emulops);
- if ( (rc != X86EMUL_OKAY) || memcmp(res, res + 8, 32) )
+ if ( (rc != X86EMUL_OKAY) || memcmp(res, res + 8, 32) ||
+ !check_eip(movdqu_to_mem) )
goto fail;
printf("okay\n");
}
@@ -673,19 +679,17 @@ int main(int argc, char **argv)
printf("%-40s", "Testing movdqu (%edx),%xmm4...");
if ( stack_exec && cpu_has_sse2 )
{
- extern const unsigned char movdqu_from_mem[];
+ decl_insn(movdqu_from_mem);
asm volatile ( "pcmpgtb %%xmm4, %%xmm4\n"
- ".pushsection .test, \"a\", @progbits\n"
- "movdqu_from_mem: movdqu (%0), %%xmm4\n"
- ".popsection" :: "d" (NULL) );
+ put_insn(movdqu_from_mem, "movdqu (%0), %%xmm4")
+ :: "d" (NULL) );
- memcpy(instr, movdqu_from_mem, 15);
- regs.eip = (unsigned long)&instr[0];
+ set_insn(movdqu_from_mem);
regs.ecx = 0;
regs.edx = (unsigned long)res;
rc = x86_emulate(&ctxt, &emulops);
- if ( rc != X86EMUL_OKAY )
+ if ( rc != X86EMUL_OKAY || !check_eip(movdqu_from_mem) )
goto fail;
asm ( "pcmpeqb %%xmm2, %%xmm2\n\t"
"pcmpeqb %%xmm4, %%xmm2\n\t"
@@ -700,21 +704,20 @@ int main(int argc, char **argv)
printf("%-40s", "Testing vmovdqu %ymm2,(%ecx)...");
if ( stack_exec && cpu_has_avx )
{
- extern const unsigned char vmovdqu_to_mem[];
+ decl_insn(vmovdqu_to_mem);
asm volatile ( "vpcmpeqb %%xmm2, %%xmm2, %%xmm2\n"
- ".pushsection .test, \"a\", @progbits\n"
- "vmovdqu_to_mem: vmovdqu %%ymm2, (%0)\n"
- ".popsection" :: "c" (NULL) );
+ put_insn(vmovdqu_to_mem, "vmovdqu %%ymm2, (%0)")
+ :: "c" (NULL) );
- memcpy(instr, vmovdqu_to_mem, 15);
+ set_insn(vmovdqu_to_mem);
memset(res, 0x55, 128);
memset(res + 16, 0xff, 16);
memset(res + 20, 0x00, 16);
- regs.eip = (unsigned long)&instr[0];
regs.ecx = (unsigned long)res;
rc = x86_emulate(&ctxt, &emulops);
- if ( (rc != X86EMUL_OKAY) || memcmp(res, res + 16, 64) )
+ if ( (rc != X86EMUL_OKAY) || memcmp(res, res + 16, 64) ||
+ !check_eip(vmovdqu_to_mem) )
goto fail;
printf("okay\n");
}
@@ -724,7 +727,7 @@ int main(int argc, char **argv)
printf("%-40s", "Testing vmovdqu (%edx),%ymm4...");
if ( stack_exec && cpu_has_avx )
{
- extern const unsigned char vmovdqu_from_mem[];
+ decl_insn(vmovdqu_from_mem);
#if 0 /* Don't use AVX2 instructions for now */
asm volatile ( "vpcmpgtb %%ymm4, %%ymm4, %%ymm4\n"
@@ -732,17 +735,15 @@ int main(int argc, char **argv)
asm volatile ( "vpcmpgtb %%xmm4, %%xmm4, %%xmm4\n\t"
"vinsertf128 $1, %%xmm4, %%ymm4, %%ymm4\n"
#endif
- ".pushsection .test, \"a\", @progbits\n"
- "vmovdqu_from_mem: vmovdqu (%0), %%ymm4\n"
- ".popsection" :: "d" (NULL) );
+ put_insn(vmovdqu_from_mem, "vmovdqu (%0), %%ymm4")
+ :: "d" (NULL) );
- memcpy(instr, vmovdqu_from_mem, 15);
+ set_insn(vmovdqu_from_mem);
memset(res + 4, 0xff, 16);
- regs.eip = (unsigned long)&instr[0];
regs.ecx = 0;
regs.edx = (unsigned long)res;
rc = x86_emulate(&ctxt, &emulops);
- if ( rc != X86EMUL_OKAY )
+ if ( rc != X86EMUL_OKAY || !check_eip(vmovdqu_from_mem) )
goto fail;
#if 0 /* Don't use AVX2 instructions for now */
asm ( "vpcmpeqb %%ymm2, %%ymm2, %%ymm2\n\t"
@@ -769,20 +770,19 @@ int main(int argc, char **argv)
memset(res + 10, 0x66, 8);
if ( stack_exec && cpu_has_sse2 )
{
- extern const unsigned char movsd_to_mem[];
+ decl_insn(movsd_to_mem);
asm volatile ( "movlpd %0, %%xmm5\n\t"
"movhpd %0, %%xmm5\n"
- ".pushsection .test, \"a\", @progbits\n"
- "movsd_to_mem: movsd %%xmm5, (%1)\n"
- ".popsection" :: "m" (res[10]), "c" (NULL) );
+ put_insn(movsd_to_mem, "movsd %%xmm5, (%1)")
+ :: "m" (res[10]), "c" (NULL) );
- memcpy(instr, movsd_to_mem, 15);
- regs.eip = (unsigned long)&instr[0];
+ set_insn(movsd_to_mem);
regs.ecx = (unsigned long)(res + 2);
regs.edx = 0;
rc = x86_emulate(&ctxt, &emulops);
- if ( (rc != X86EMUL_OKAY) || memcmp(res, res + 8, 32) )
+ if ( (rc != X86EMUL_OKAY) || memcmp(res, res + 8, 32) ||
+ !check_eip(movsd_to_mem) )
goto fail;
printf("okay\n");
}
@@ -795,19 +795,17 @@ int main(int argc, char **argv)
printf("%-40s", "Testing movaps (%edx),%xmm7...");
if ( stack_exec && cpu_has_sse )
{
- extern const unsigned char movaps_from_mem[];
+ decl_insn(movaps_from_mem);
asm volatile ( "xorps %%xmm7, %%xmm7\n"
- ".pushsection .test, \"a\", @progbits\n"
- "movaps_from_mem: movaps (%0), %%xmm7\n"
- ".popsection" :: "d" (NULL) );
+ put_insn(movaps_from_mem, "movaps (%0), %%xmm7")
+ :: "d" (NULL) );
- memcpy(instr, movaps_from_mem, 15);
- regs.eip = (unsigned long)&instr[0];
+ set_insn(movaps_from_mem);
regs.ecx = 0;
regs.edx = (unsigned long)res;
rc = x86_emulate(&ctxt, &emulops);
- if ( rc != X86EMUL_OKAY )
+ if ( rc != X86EMUL_OKAY || !check_eip(movaps_from_mem) )
goto fail;
asm ( "cmpeqps %1, %%xmm7\n\t"
"movmskps %%xmm7, %0" : "=r" (rc) : "m" (res[8]) );
@@ -823,19 +821,18 @@ int main(int argc, char **argv)
memset(res + 10, 0x77, 8);
if ( stack_exec && cpu_has_avx )
{
- extern const unsigned char vmovsd_to_mem[];
+ decl_insn(vmovsd_to_mem);
asm volatile ( "vbroadcastsd %0, %%ymm5\n"
- ".pushsection .test, \"a\", @progbits\n"
- "vmovsd_to_mem: vmovsd %%xmm5, (%1)\n"
- ".popsection" :: "m" (res[10]), "c" (NULL) );
+ put_insn(vmovsd_to_mem, "vmovsd %%xmm5, (%1)")
+ :: "m" (res[10]), "c" (NULL) );
- memcpy(instr, vmovsd_to_mem, 15);
- regs.eip = (unsigned long)&instr[0];
+ set_insn(vmovsd_to_mem);
regs.ecx = (unsigned long)(res + 2);
regs.edx = 0;
rc = x86_emulate(&ctxt, &emulops);
- if ( (rc != X86EMUL_OKAY) || memcmp(res, res + 8, 32) )
+ if ( (rc != X86EMUL_OKAY) || memcmp(res, res + 8, 32) ||
+ !check_eip(vmovsd_to_mem) )
goto fail;
printf("okay\n");
}
@@ -848,19 +845,17 @@ int main(int argc, char **argv)
printf("%-40s", "Testing vmovaps (%edx),%ymm7...");
if ( stack_exec && cpu_has_avx )
{
- extern const unsigned char vmovaps_from_mem[];
+ decl_insn(vmovaps_from_mem);
asm volatile ( "vxorps %%ymm7, %%ymm7, %%ymm7\n"
- ".pushsection .test, \"a\", @progbits\n"
- "vmovaps_from_mem: vmovaps (%0), %%ymm7\n"
- ".popsection" :: "d" (NULL) );
+ put_insn(vmovaps_from_mem, "vmovaps (%0), %%ymm7")
+ :: "d" (NULL) );
- memcpy(instr, vmovaps_from_mem, 15);
- regs.eip = (unsigned long)&instr[0];
+ set_insn(vmovaps_from_mem);
regs.ecx = 0;
regs.edx = (unsigned long)res;
rc = x86_emulate(&ctxt, &emulops);
- if ( rc != X86EMUL_OKAY )
+ if ( rc != X86EMUL_OKAY || !check_eip(vmovaps_from_mem) )
goto fail;
asm ( "vcmpeqps %1, %%ymm7, %%ymm0\n\t"
"vmovmskps %%ymm0, %0" : "=r" (rc) : "m" (res[8]) );
@@ -871,6 +866,11 @@ int main(int argc, char **argv)
else
printf("skipped\n");
+#undef decl_insn
+#undef put_insn
+#undef set_insn
+#undef check_eip
+
for ( j = 1; j <= 2; j++ )
{
#if defined(__i386__)
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -720,29 +720,26 @@ do{ uint8_t stub[] = { _bytes, 0xc3 };
put_fpu(&fic); \
} while (0)
-static unsigned long __get_rep_prefix(
- struct cpu_user_regs *int_regs,
- struct cpu_user_regs *ext_regs,
+static unsigned long _get_rep_prefix(
+ const struct cpu_user_regs *int_regs,
int ad_bytes)
{
- unsigned long ecx = ((ad_bytes == 2) ? (uint16_t)int_regs->ecx :
- (ad_bytes == 4) ? (uint32_t)int_regs->ecx :
- int_regs->ecx);
-
- /* Skip the instruction if no repetitions are required. */
- if ( ecx == 0 )
- ext_regs->eip = int_regs->eip;
-
- return ecx;
+ return (ad_bytes == 2) ? (uint16_t)int_regs->ecx :
+ (ad_bytes == 4) ? (uint32_t)int_regs->ecx :
+ int_regs->ecx;
}
#define get_rep_prefix() ({ \
unsigned long max_reps = 1; \
if ( rep_prefix() ) \
- max_reps = __get_rep_prefix(&_regs, ctxt->regs, ad_bytes); \
+ max_reps = _get_rep_prefix(&_regs, ad_bytes); \
if ( max_reps == 0 ) \
- goto done; \
- max_reps; \
+ { \
+ /* Skip the instruction if no repetitions are required. */ \
+ dst.type = OP_NONE; \
+ goto writeback; \
+ } \
+ max_reps; \
})
static void __put_rep_prefix(
@@ -3921,7 +3918,8 @@ x86_emulate(
if ( !rc && (b & 1) && (ea.type == OP_MEM) )
rc = ops->write(ea.mem.seg, ea.mem.off, mmvalp,
ea.bytes, ctxt);
- goto done;
+ dst.type = OP_NONE;
+ break;
}
case 0x20: /* mov cr,reg */
@@ -4188,7 +4186,8 @@ x86_emulate(
if ( !rc && (b != 0x6f) && (ea.type == OP_MEM) )
rc = ops->write(ea.mem.seg, ea.mem.off, mmvalp,
ea.bytes, ctxt);
- goto done;
+ dst.type = OP_NONE;
+ break;
}
case 0x80 ... 0x8f: /* jcc (near) */ {