Message ID | cd54bc0e-9e7b-42bb-ea60-8d4578a59cac@suse.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | x86emul: correct LFS et al handling for 64-bit mode | expand |
On 11/12/2019 09:28, Jan Beulich wrote: > AMD and friends explicitly specify that 64-bit operands aren't possible > for these insns. Nevertheless REX.W isn't fully ignored: It still > cancels a possible operand size override (0x66). Intel otoh explicitly > provides for 64-bit operands on the respective insn page of the SDM. > > Signed-off-by: Jan Beulich <jbeulich@suse.com> It is definitely more than just these. Near jumps have per-vendor behaviour on how long the instruction is, whereas far jump/calls are in the same category as these by the looks of things. ~Andrew > > --- a/xen/arch/x86/x86_emulate/x86_emulate.c > +++ b/xen/arch/x86/x86_emulate/x86_emulate.c > @@ -2640,6 +2640,15 @@ x86_decode_twobyte( > } > break; > > + case 0xb2: /* lss */ > + case 0xb4: /* lfs */ > + case 0xb5: /* lgs */ > + /* REX.W ignored on a vendor-dependent basis. */ > + if ( op_bytes == 8 && > + (ctxt->cpuid->x86_vendor & (X86_VENDOR_AMD | X86_VENDOR_HYGON)) ) > + op_bytes = 4; > + break; > + > case 0xb8: /* jmpe / popcnt */ > if ( rep_prefix() ) > ctxt->opcode |= MASK_INSR(vex.pfx, X86EMUL_OPC_PFX_MASK);
On 11.12.2019 21:57, Andrew Cooper wrote: > On 11/12/2019 09:28, Jan Beulich wrote: >> AMD and friends explicitly specify that 64-bit operands aren't possible >> for these insns. Nevertheless REX.W isn't fully ignored: It still >> cancels a possible operand size override (0x66). Intel otoh explicitly >> provides for 64-bit operands on the respective insn page of the SDM. >> >> Signed-off-by: Jan Beulich <jbeulich@suse.com> > > It is definitely more than just these. Near jumps have per-vendor > behaviour on how long the instruction is, whereas far jump/calls are in > the same category as these by the looks of things. But you don't expect me to fold all of these into one patch, do you? We have _some_ vendor dependent behavior already, and I'm slowly adding to it. Our far call/jmp support is rather incomplete in other ways anyway. (As an aside, I'm trying to do the binutils side of some of these before wanting to do the emulator parts. I'm only about to get to the far call/jmp issues there, as reported by you in bug 24546.) I'd appreciate if you could clarify what exactly your reply means for the patch at hand. Jan
On 12/12/2019 10:11, Jan Beulich wrote: > On 11.12.2019 21:57, Andrew Cooper wrote: >> On 11/12/2019 09:28, Jan Beulich wrote: >>> AMD and friends explicitly specify that 64-bit operands aren't possible >>> for these insns. Nevertheless REX.W isn't fully ignored: It still >>> cancels a possible operand size override (0x66). Intel otoh explicitly >>> provides for 64-bit operands on the respective insn page of the SDM. >>> >>> Signed-off-by: Jan Beulich <jbeulich@suse.com> >> It is definitely more than just these. Near jumps have per-vendor >> behaviour on how long the instruction is, whereas far jump/calls are in >> the same category as these by the looks of things. > But you don't expect me to fold all of these into one patch, do > you? short jmp certainly not, but far jmp/call is just two extra case statements in this new code block, no? > We have _some_ vendor dependent behavior already, and I'm > slowly adding to it. Our far call/jmp support is rather > incomplete in other ways anyway. There is different truncation behaviour for %rip which needs altering, but that is a separate area of code. Anything else? ~Andrew
On 12.12.2019 12:37, Andrew Cooper wrote: > On 12/12/2019 10:11, Jan Beulich wrote: >> On 11.12.2019 21:57, Andrew Cooper wrote: >>> On 11/12/2019 09:28, Jan Beulich wrote: >>>> AMD and friends explicitly specify that 64-bit operands aren't possible >>>> for these insns. Nevertheless REX.W isn't fully ignored: It still >>>> cancels a possible operand size override (0x66). Intel otoh explicitly >>>> provides for 64-bit operands on the respective insn page of the SDM. >>>> >>>> Signed-off-by: Jan Beulich <jbeulich@suse.com> >>> It is definitely more than just these. Near jumps have per-vendor >>> behaviour on how long the instruction is, whereas far jump/calls are in >>> the same category as these by the looks of things. >> But you don't expect me to fold all of these into one patch, do >> you? > > short jmp certainly not, but far jmp/call is just two extra case > statements in this new code block, no? Not exactly (the other change would need to be in x86_decode_onebyte() and depend on ModRM.reg), but yes, I can do this. Yet then it would feel odd to not also deal with the near counterparts at the same time. Which in turn would make is desirable to also deal with near RET as well. At which point we're about to also discuss CALL/JMP with displacement operands and Jcc. >> We have _some_ vendor dependent behavior already, and I'm >> slowly adding to it. Our far call/jmp support is rather >> incomplete in other ways anyway. > > There is different truncation behaviour for %rip which needs altering, > but that is a separate area of code. Anything else? protmode_load_seg() and MOVSXD already have vendor dependent code, if that was your question. For things needing doing see above plus LOOP, J[ER]CXZ, SYSENTER, and SYSEXIT as far as I'm currently aware. Jan
On 12/12/2019 13:05, Jan Beulich wrote: > On 12.12.2019 12:37, Andrew Cooper wrote: >> On 12/12/2019 10:11, Jan Beulich wrote: >>> On 11.12.2019 21:57, Andrew Cooper wrote: >>>> On 11/12/2019 09:28, Jan Beulich wrote: >>>>> AMD and friends explicitly specify that 64-bit operands aren't possible >>>>> for these insns. Nevertheless REX.W isn't fully ignored: It still >>>>> cancels a possible operand size override (0x66). Intel otoh explicitly >>>>> provides for 64-bit operands on the respective insn page of the SDM. >>>>> >>>>> Signed-off-by: Jan Beulich <jbeulich@suse.com> >>>> It is definitely more than just these. Near jumps have per-vendor >>>> behaviour on how long the instruction is, whereas far jump/calls are in >>>> the same category as these by the looks of things. >>> But you don't expect me to fold all of these into one patch, do >>> you? >> short jmp certainly not, but far jmp/call is just two extra case >> statements in this new code block, no? > Not exactly (the other change would need to be in > x86_decode_onebyte() and depend on ModRM.reg), but yes, I can > do this. Yet then it would feel odd to not also deal with the > near counterparts at the same time. Which in turn would make > is desirable to also deal with near RET as well. At which > point we're about to also discuss CALL/JMP with displacement > operands and Jcc. > >>> We have _some_ vendor dependent behavior already, and I'm >>> slowly adding to it. Our far call/jmp support is rather >>> incomplete in other ways anyway. >> There is different truncation behaviour for %rip which needs altering, >> but that is a separate area of code. Anything else? > protmode_load_seg() and MOVSXD already have vendor dependent > code, if that was your question. I was actually just asking about far jmp/call. If you're sure that far jmp/call is more complicated than just tweaking this patch, then fine. Acked-by: Andrew Cooper <andrew.cooper3@citrix.com> > For things needing doing see > above plus LOOP, J[ER]CXZ, SYSENTER, and SYSEXIT as far as I'm > currently aware. SYSCALL and SYSRET as well. The way they handle MSR_STAR is vendor specific, as well as #UD conditions. I've just noticed that I've still got an XSA-204 followup patch still outstanding from 2016... ~Andrew
On 12.12.2019 15:20, Andrew Cooper wrote: > On 12/12/2019 13:05, Jan Beulich wrote: >> On 12.12.2019 12:37, Andrew Cooper wrote: >>> On 12/12/2019 10:11, Jan Beulich wrote: >>>> On 11.12.2019 21:57, Andrew Cooper wrote: >>>>> On 11/12/2019 09:28, Jan Beulich wrote: >>>>>> AMD and friends explicitly specify that 64-bit operands aren't possible >>>>>> for these insns. Nevertheless REX.W isn't fully ignored: It still >>>>>> cancels a possible operand size override (0x66). Intel otoh explicitly >>>>>> provides for 64-bit operands on the respective insn page of the SDM. >>>>>> >>>>>> Signed-off-by: Jan Beulich <jbeulich@suse.com> >>>>> It is definitely more than just these. Near jumps have per-vendor >>>>> behaviour on how long the instruction is, whereas far jump/calls are in >>>>> the same category as these by the looks of things. >>>> But you don't expect me to fold all of these into one patch, do >>>> you? >>> short jmp certainly not, but far jmp/call is just two extra case >>> statements in this new code block, no? >> Not exactly (the other change would need to be in >> x86_decode_onebyte() and depend on ModRM.reg), but yes, I can >> do this. Yet then it would feel odd to not also deal with the >> near counterparts at the same time. Which in turn would make >> is desirable to also deal with near RET as well. At which >> point we're about to also discuss CALL/JMP with displacement >> operands and Jcc. >> >>>> We have _some_ vendor dependent behavior already, and I'm >>>> slowly adding to it. Our far call/jmp support is rather >>>> incomplete in other ways anyway. >>> There is different truncation behaviour for %rip which needs altering, >>> but that is a separate area of code. Anything else? >> protmode_load_seg() and MOVSXD already have vendor dependent >> code, if that was your question. > > I was actually just asking about far jmp/call. > > If you're sure that far jmp/call is more complicated than just tweaking > this patch, then fine. Acked-by: Andrew Cooper <andrew.cooper3@citrix.com> Thanks much. I'll see to put together the far branch counterpart soon. Perhaps I can also do the near branch parts then. >> For things needing doing see >> above plus LOOP, J[ER]CXZ, SYSENTER, and SYSEXIT as far as I'm >> currently aware. > > SYSCALL and SYSRET as well. The way they handle MSR_STAR is vendor > specific, as well as #UD conditions. > > I've just noticed that I've still got an XSA-204 followup patch still > outstanding from 2016... Oh. Looking forward to see it. Jan
--- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -2640,6 +2640,15 @@ x86_decode_twobyte( } break; + case 0xb2: /* lss */ + case 0xb4: /* lfs */ + case 0xb5: /* lgs */ + /* REX.W ignored on a vendor-dependent basis. */ + if ( op_bytes == 8 && + (ctxt->cpuid->x86_vendor & (X86_VENDOR_AMD | X86_VENDOR_HYGON)) ) + op_bytes = 4; + break; + case 0xb8: /* jmpe / popcnt */ if ( rep_prefix() ) ctxt->opcode |= MASK_INSR(vex.pfx, X86EMUL_OPC_PFX_MASK);
AMD and friends explicitly specify that 64-bit operands aren't possible for these insns. Nevertheless REX.W isn't fully ignored: It still cancels a possible operand size override (0x66). Intel otoh explicitly provides for 64-bit operands on the respective insn page of the SDM. Signed-off-by: Jan Beulich <jbeulich@suse.com>