|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] x86_emulate: Always truncate %eip out of long mode
_regs.eip needs to be truncated after having size added to it, or bad
situations can occur. e.g. emulating an instruction which crosses the 4GB
boundary causes _regs.eip to become invalid (have some of the upper 32 bits
set), and fail vmentry checks when returning back to the guest.
The comment /* real hardware doesn't truncate */ seems to appear in c/s
ddef8e16 "Tweak x86 emulator interface." without any justification.
I have not been able to find any information to prove or disprove the claim,
but emulating oneself into a vmentry failure is definitely the wrong thing to
do.
Trucate the instruction pointer at 32 or 16 bits, according to %cs.D.
Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
CC: Jan Beulich <JBeulich@xxxxxxxx>
v2: Use def_ad_bytes, to allow truncating to 16 bits for a 16bit code segment.
---
xen/arch/x86/x86_emulate/x86_emulate.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c
b/xen/arch/x86/x86_emulate/x86_emulate.c
index f1454ce..03e7aab 100644
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -570,8 +570,10 @@ do{ asm volatile (
\
/* Fetch next part of the instruction being emulated. */
#define insn_fetch_bytes(_size) \
({ unsigned long _x = 0, _eip = _regs.eip; \
- if ( !mode_64bit() ) _eip = (uint32_t)_eip; /* ignore upper dword */ \
- _regs.eip += (_size); /* real hardware doesn't truncate */ \
+ _regs.eip += (_size); \
+ if ( !mode_64bit() ) { /* Truncate eip to def_ad_bytes (2 or 4). */ \
+ _eip &= ~((1UL << (def_ad_bytes * 8)) - 1); \
+ _regs.eip &= ~((1UL << (def_ad_bytes * 8)) - 1); }; \
generate_exception_if((uint8_t)(_regs.eip - \
ctxt->regs->eip) > MAX_INST_LEN, \
EXC_GP, 0); \
--
2.1.4
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |