mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
x86emul: ignore VEX.W for BMI{1,2} insns in 32-bit mode
While result values and other status flags are unaffected as long as we can ignore the case of registers having their upper 32 bits non-zero outside of 64-bit mode, EFLAGS.SF may obtain a wrong value when we mistakenly re-execute the original insn with VEX.W set. Note that guest the memory access, if any, is correctly carried out as 32-bit regardless of VEX.W. The emulator-local memory operand will be accessed as a 64-bit quantity, but it is pre-initialised to zero so no internal state can leak. Fixes:771daacd19("x86emul: support BMI1 insns") Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com> master commit:1179d51dcbmaster date: 2024-11-14 13:00:57 +0100
This commit is contained in:
1 parent
5c05c4a2b2
commit
8eed56995d
2 files changed
+28
No files matched your search
@@ -1948,6 +1948,30 @@ int main(int argc, char **argv)
|
||||
if ( (rc != X86EMUL_OKAY) || regs.ecx != 0xfedcba90 ||
|
||||
(regs.eflags & 0xf6b) != 0x202 || !check_eip(blsr) )
|
||||
goto fail;
|
||||
|
||||
#ifdef __x86_64__
|
||||
/* Re-test with VEX.W set while emulating 32-bit mode. */
|
||||
ctxt.lma = 0;
|
||||
ctxt.addr_size = 32;
|
||||
ctxt.sp_size = 32;
|
||||
|
||||
memcpy(instr, blsr, blsr_end - blsr);
|
||||
instr[2] |= 0x80;
|
||||
regs.rip = (unsigned long)&instr[0];
|
||||
regs.eflags = EFLAGS_ALWAYS_SET | X86_EFLAGS_OF | X86_EFLAGS_ZF | \
|
||||
X86_EFLAGS_CF;
|
||||
rc = x86_emulate(&ctxt, &emulops);
|
||||
if ( (rc != X86EMUL_OKAY) || regs.ecx != 0xfedcba90 ||
|
||||
(regs.eflags & (EFLAGS_MASK & ~(X86_EFLAGS_AF | X86_EFLAGS_PF))) !=
|
||||
(EFLAGS_ALWAYS_SET | X86_EFLAGS_SF) ||
|
||||
(regs.rip != (unsigned long)&instr[blsr_end - blsr]) )
|
||||
goto fail;
|
||||
|
||||
ctxt.lma = 1;
|
||||
ctxt.addr_size = 64;
|
||||
ctxt.sp_size = 64;
|
||||
#endif
|
||||
|
||||
printf("okay\n");
|
||||
}
|
||||
else
|
||||
|
||||
@@ -6984,6 +6984,8 @@ x86_emulate(
|
||||
*pvex = vex;
|
||||
pvex->b = 1;
|
||||
pvex->r = 1;
|
||||
if ( !mode_64bit() )
|
||||
pvex->w = 0;
|
||||
pvex->reg = 0xf; /* rAX */
|
||||
buf[3] = b;
|
||||
buf[4] = 0x09; /* reg=rCX r/m=(%rCX) */
|
||||
@@ -7018,6 +7020,8 @@ x86_emulate(
|
||||
*pvex = vex;
|
||||
pvex->b = 1;
|
||||
pvex->r = 1;
|
||||
if ( !mode_64bit() )
|
||||
pvex->w = 0;
|
||||
pvex->reg = 0xf; /* rAX */
|
||||
buf[3] = b;
|
||||
buf[4] = (modrm & 0x38) | 0x01; /* r/m=(%rCX) */
|
||||
|
||||