[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] x86/emul: Simplfy L{ES,DS,SS,FS,GS} handling



%ss, %fs and %gs can be calculated by directly masking the opcode.  %es and
%ds cant, but the calculation isn't hard.

Use seg rather than dst.val for storing the calculated segment, which is
appropriately typed.  The mode_64() check can be repositioned and simplified
to drop the ext check.  Replace opencoding of X86EMUL_OKAY.

Finally, introduce assertions each time we calculate a user segment to load
(rather than using constants) which don't have other validity checks.  This
includes the POP %sreg case.

Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
CC: Jan Beulich <JBeulich@xxxxxxxx>
---
 xen/arch/x86/x86_emulate/x86_emulate.c | 40 +++++++++++++++-------------------
 1 file changed, 18 insertions(+), 22 deletions(-)

diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c 
b/xen/arch/x86/x86_emulate/x86_emulate.c
index 1b5becf..2fb99e9 100644
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -2765,6 +2765,7 @@ x86_emulate(
         if ( mode_64bit() && (op_bytes == 4) )
             op_bytes = 8;
         seg = (b >> 3) & 7;
+        ASSERT(is_x86_user_segment(seg));
         if ( (rc = read_ulong(x86_seg_ss, sp_post_inc(op_bytes), &dst.val,
                               op_bytes, ctxt, ops)) != X86EMUL_OKAY ||
              (rc = load_seg(seg, dst.val, 0, NULL, ctxt, ops)) != X86EMUL_OKAY 
)
@@ -3393,25 +3394,32 @@ x86_emulate(
         _regs.eip = dst.val;
         break;
 
-    case 0xc4: /* les */ {
+    case 0xc4: /* les */
+    case 0xc5: /* lds */
+    {
         unsigned long sel;
-        dst.val = x86_seg_es;
-    les: /* dst.val identifies the segment */
-        generate_exception_if(mode_64bit() && !ext, EXC_UD);
+
+        generate_exception_if(mode_64bit(), EXC_UD);
+        seg = (b & 1) * 3; /* es = 0, ds = 3 */
+        goto les;
+
+    case X86EMUL_OPC(0x0f, 0xb2): /* lss */
+    case X86EMUL_OPC(0x0f, 0xb4): /* lfs */
+    case X86EMUL_OPC(0x0f, 0xb5): /* lgs */
+        seg = b & 7;
+
+    les:
         generate_exception_if(src.type != OP_MEM, EXC_UD);
         if ( (rc = read_ulong(src.mem.seg, src.mem.off + src.bytes,
-                              &sel, 2, ctxt, ops)) != 0 )
+                              &sel, 2, ctxt, ops)) != X86EMUL_OKAY )
             goto done;
-        if ( (rc = load_seg(dst.val, sel, 0, NULL, ctxt, ops)) != 0 )
+        ASSERT(is_x86_user_segment(seg));
+        if ( (rc = load_seg(seg, sel, 0, NULL, ctxt, ops)) != X86EMUL_OKAY )
             goto done;
         dst.val = src.val;
         break;
     }
 
-    case 0xc5: /* lds */
-        dst.val = x86_seg_ds;
-        goto les;
-
     case 0xc8: /* enter imm16,imm8 */ {
         uint8_t depth = imm2 & 31;
         int i;
@@ -5228,22 +5236,10 @@ x86_emulate(
         }
         break;
 
-    case X86EMUL_OPC(0x0f, 0xb2): /* lss */
-        dst.val = x86_seg_ss;
-        goto les;
-
     case X86EMUL_OPC(0x0f, 0xb3): btr: /* btr */
         emulate_2op_SrcV_nobyte("btr", src, dst, _regs.eflags);
         break;
 
-    case X86EMUL_OPC(0x0f, 0xb4): /* lfs */
-        dst.val = x86_seg_fs;
-        goto les;
-
-    case X86EMUL_OPC(0x0f, 0xb5): /* lgs */
-        dst.val = x86_seg_gs;
-        goto les;
-
     case X86EMUL_OPC(0x0f, 0xb6): /* movzx rm8,r{16,32,64} */
         /* Recompute DstReg as we may have decoded AH/BH/CH/DH. */
         dst.reg   = decode_register(modrm_reg, &_regs, 0);
-- 
2.1.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.