[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH] x86_emulate: Always truncate %eip out of long mode
On 06/01/16 15:44, Jan Beulich wrote: > Ping? Sorry - this is still on my todo list, but I have more urgent work currently. ~Andrew > >>>> On 15.12.15 at 09:53, <JBeulich@xxxxxxxx> wrote: >>>>> On 10.12.15 at 21:03, <andrew.cooper3@xxxxxxxxxx> wrote: >>> --- 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); }; \ >> Did you test this? The ~ seems quite wrong, and this would also >> cause undefined behavior in 32-bit compilation of the emulator >> test... Anyway, how about the following replacement patch, >> along the lines of what I think I had described in reply to the first >> variant of the patch? >> >> Jan >> >> x86emul: fix rIP handling >> >> Deal with rIP just like with any other register: Truncate to designated >> width upon entry, and write back the zero-extended 32-bit value when >> emulating 32-bit code, and leave the upper 48 bits unchanged for 16-bit >> code. >> >> Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> >> >> --- a/xen/arch/x86/x86_emulate/x86_emulate.c >> +++ b/xen/arch/x86/x86_emulate/x86_emulate.c >> @@ -570,7 +570,6 @@ 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 */ \ >> generate_exception_if((uint8_t)(_regs.eip - \ >> ctxt->regs->eip) > MAX_INST_LEN, \ >> @@ -1481,6 +1480,10 @@ x86_emulate( >> #endif >> } >> >> + /* Truncate rIP to def_ad_bytes (2 or 4) if necessary. */ >> + if ( def_ad_bytes < sizeof(_regs.eip) ) >> + _regs.eip &= (1UL << (def_ad_bytes * 8)) - 1; >> + >> /* Prefix bytes. */ >> for ( ; ; ) >> { >> @@ -3793,6 +3796,21 @@ x86_emulate( >> >> /* Commit shadow register state. */ >> _regs.eflags &= ~EFLG_RF; >> + switch ( __builtin_expect(def_ad_bytes, sizeof(_regs.eip)) ) >> + { >> + uint16_t ip; >> + >> + case 2: >> + ip = _regs.eip; >> + _regs.eip = ctxt->regs->eip; >> + *(uint16_t *)&_regs.eip = ip; >> + break; >> +#ifdef __x86_64__ >> + case 4: >> + _regs.rip = _regs._eip; >> + break; >> +#endif >> + } >> *ctxt->regs = _regs; >> >> done: > > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |