Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP1:GA
xen.4507
5810a9cc-x86-emul-Correct-decoding-of-SReg3-ope...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 5810a9cc-x86-emul-Correct-decoding-of-SReg3-operands.patch of Package xen.4507
# Commit 0888d36bb23f7365ce12b03127fd0fb2661ec90e # Date 2016-10-26 14:04:12 +0100 # Author Andrew Cooper <andrew.cooper3@citrix.com> # Committer Andrew Cooper <andrew.cooper3@citrix.com> x86/emul: Correct the decoding of SReg3 operands REX.R is ignored when considering segment register operands, and needs masking out first. While fixing this, reorder the user segments in x86_segment to match SReg3 encoding. This avoids needing a translation table between hardware ordering and Xen's ordering. Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> Reviewed-by: Jan Beulich <jbeulich@suse.com> # Commit a62511bf14971ff581212decbbf57fc11b967840 # Date 2016-10-31 08:57:47 +0100 # Author Jan Beulich <jbeulich@suse.com> # Committer Jan Beulich <jbeulich@suse.com> VMX: fix realmode emulation SReg handling Commit 0888d36bb2 ("x86/emul: Correct the decoding of SReg3 operands") overlooked three places where x86_seg_cs was assumed to be zero. Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com> --- a/tools/tests/x86_emulator/x86_emulate.c +++ b/tools/tests/x86_emulator/x86_emulate.c @@ -13,6 +13,16 @@ typedef bool bool_t; #define BUG() abort() #define ASSERT assert +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) +/* Force a compilation error if condition is true */ +#define BUILD_BUG_ON(cond) ({ _Static_assert(!(cond), "!(" #cond ")"); }) +#define BUILD_BUG_ON_ZERO(cond) \ + sizeof(struct { _Static_assert(!(cond), "!(" #cond ")"); }) +#else +#define BUILD_BUG_ON_ZERO(cond) sizeof(struct { int:-!!(cond); }) +#define BUILD_BUG_ON(cond) ((void)BUILD_BUG_ON_ZERO(cond)) +#endif + #define cpu_has_amd_erratum(nr) 0 #define mark_regs_dirty(r) ((void)(r)) --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -1400,23 +1400,6 @@ decode_register( return p; } -#define decode_segment_failed x86_seg_tr -static enum x86_segment -decode_segment(uint8_t modrm_reg) -{ - switch ( modrm_reg ) - { - case 0: return x86_seg_es; - case 1: return x86_seg_cs; - case 2: return x86_seg_ss; - case 3: return x86_seg_ds; - case 4: return x86_seg_fs; - case 5: return x86_seg_gs; - default: break; - } - return decode_segment_failed; -} - int x86_emulate( struct x86_emulate_ctxt *ctxt, @@ -2324,8 +2307,8 @@ x86_emulate( case 0x8c: /* mov Sreg,r/m */ { struct segment_register reg; - enum x86_segment seg = decode_segment(modrm_reg); - generate_exception_if(seg == decode_segment_failed, EXC_UD, -1); + enum x86_segment seg = modrm_reg & 7; /* REX.R is ignored. */ + generate_exception_if(!is_x86_user_segment(seg), EXC_UD, -1); fail_if(ops->read_segment == NULL); if ( (rc = ops->read_segment(seg, ®, ctxt)) != 0 ) goto done; @@ -2336,9 +2319,9 @@ x86_emulate( } case 0x8e: /* mov r/m,Sreg */ { - enum x86_segment seg = decode_segment(modrm_reg); - generate_exception_if(seg == decode_segment_failed, EXC_UD, -1); - generate_exception_if(seg == x86_seg_cs, EXC_UD, -1); + enum x86_segment seg = modrm_reg & 7; /* REX.R is ignored. */ + generate_exception_if(!is_x86_user_segment(seg) || + seg == x86_seg_cs, EXC_UD, -1); if ( (rc = load_seg(seg, src.val, 0, NULL, ctxt, ops)) != 0 ) goto done; if ( seg == x86_seg_ss ) @@ -4629,3 +4612,14 @@ x86_emulate( cannot_emulate: return X86EMUL_UNHANDLEABLE; } + +static inline void build_assertions(void) +{ + /* Check the values against SReg3 encoding in opcode/ModRM bytes. */ + BUILD_BUG_ON(x86_seg_es != 0); + BUILD_BUG_ON(x86_seg_cs != 1); + BUILD_BUG_ON(x86_seg_ss != 2); + BUILD_BUG_ON(x86_seg_ds != 3); + BUILD_BUG_ON(x86_seg_fs != 4); + BUILD_BUG_ON(x86_seg_gs != 5); +} --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -1198,21 +1198,23 @@ static void vmx_update_guest_cr(struct v enum x86_segment s; struct segment_register reg[x86_seg_tr + 1]; + BUILD_BUG_ON(x86_seg_tr != x86_seg_gs + 1); + /* Entering or leaving real mode: adjust the segment registers. * Need to read them all either way, as realmode reads can update * the saved values we'll use when returning to prot mode. */ - for ( s = x86_seg_cs ; s <= x86_seg_tr ; s++ ) + for ( s = 0; s < ARRAY_SIZE(reg); s++ ) vmx_get_segment_register(v, s, ®[s]); v->arch.hvm_vmx.vmx_realmode = realmode; if ( realmode ) { - for ( s = x86_seg_cs ; s <= x86_seg_tr ; s++ ) + for ( s = 0; s < ARRAY_SIZE(reg); s++ ) vmx_set_segment_register(v, s, ®[s]); } else { - for ( s = x86_seg_cs ; s <= x86_seg_tr ; s++ ) + for ( s = 0; s < ARRAY_SIZE(reg); s++ ) if ( !(v->arch.hvm_vmx.vm86_segment_mask & (1<<s)) ) vmx_set_segment_register( v, s, &v->arch.hvm_vmx.vm86_saved_seg[s]); --- a/xen/arch/x86/x86_emulate/x86_emulate.h +++ b/xen/arch/x86/x86_emulate/x86_emulate.h @@ -28,11 +28,11 @@ struct x86_emulate_ctxt; /* Comprehensive enumeration of x86 segment registers. */ enum x86_segment { - /* General purpose. */ + /* General purpose. Matches the SReg3 encoding in opcode/ModRM bytes. */ + x86_seg_es, x86_seg_cs, x86_seg_ss, x86_seg_ds, - x86_seg_es, x86_seg_fs, x86_seg_gs, /* System. */
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor