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

[Xen-devel] [PATCH] x86: properly handle LOCK prefix in privileged PV opcode emulation



- include LOCK prefix presence in calculation of which CR/DR is being
  targeted by moves to/from these registers
- fail any other opcodes when beingused with lock prefix

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>

Index: 2007-01-08/xen/arch/x86/traps.c
===================================================================
--- 2007-01-08.orig/xen/arch/x86/traps.c        2006-12-18 17:53:52.000000000 
+0100
+++ 2007-01-08/xen/arch/x86/traps.c     2006-12-18 17:55:26.000000000 +0100
@@ -1121,7 +1121,7 @@ static int emulate_privileged_op(struct 
 {
     struct vcpu *v = current;
     unsigned long *reg, eip = regs->eip, res;
-    u8 opcode, modrm_reg = 0, modrm_rm = 0, rep_prefix = 0, rex = 0;
+    u8 opcode, modrm_reg = 0, modrm_rm = 0, rep_prefix = 0, lock = 0, rex = 0;
     enum { lm_seg_none, lm_seg_fs, lm_seg_gs } lm_ovr = lm_seg_none;
     unsigned int port, i, data_sel, ar, data, rc;
     unsigned int op_bytes, op_default, ad_bytes, ad_default;
@@ -1184,6 +1184,7 @@ static int emulate_privileged_op(struct 
             data_sel = regs->ss;
             continue;
         case 0xf0: /* LOCK */
+            lock = 1;
             continue;
         case 0xf2: /* REPNE/REPNZ */
         case 0xf3: /* REP/REPE/REPZ */
@@ -1210,6 +1211,9 @@ static int emulate_privileged_op(struct 
     if ( opcode == 0x0f )
         goto twobyte_opcode;
     
+    if ( lock )
+        goto fail;
+
     /* Input/Output String instructions. */
     if ( (opcode >= 0x6c) && (opcode <= 0x6f) )
     {
@@ -1472,6 +1476,8 @@ static int emulate_privileged_op(struct 
 
     /* Privileged (ring 0) instructions. */
     opcode = insn_fetch(u8, code_base, eip, code_limit);
+    if ( lock && (opcode & ~3) != 0x20 )
+        goto fail;
     switch ( opcode )
     {
     case 0x06: /* CLTS */
@@ -1490,7 +1496,7 @@ static int emulate_privileged_op(struct 
 
     case 0x20: /* MOV CR?,<reg> */
         opcode = insn_fetch(u8, code_base, eip, code_limit);
-        modrm_reg |= (opcode >> 3) & 7;
+        modrm_reg += ((opcode >> 3) & 7) + (lock << 3);
         modrm_rm  |= (opcode >> 0) & 7;
         reg = decode_register(modrm_rm, regs, 0);
         switch ( modrm_reg )
@@ -1530,7 +1536,7 @@ static int emulate_privileged_op(struct 
 
     case 0x21: /* MOV DR?,<reg> */
         opcode = insn_fetch(u8, code_base, eip, code_limit);
-        modrm_reg |= (opcode >> 3) & 7;
+        modrm_reg += ((opcode >> 3) & 7) + (lock << 3);
         modrm_rm  |= (opcode >> 0) & 7;
         reg = decode_register(modrm_rm, regs, 0);
         if ( (res = do_get_debugreg(modrm_reg)) > (unsigned long)-256 )
@@ -1540,7 +1546,7 @@ static int emulate_privileged_op(struct 
 
     case 0x22: /* MOV <reg>,CR? */
         opcode = insn_fetch(u8, code_base, eip, code_limit);
-        modrm_reg |= (opcode >> 3) & 7;
+        modrm_reg += ((opcode >> 3) & 7) + (lock << 3);
         modrm_rm  |= (opcode >> 0) & 7;
         reg = decode_register(modrm_rm, regs, 0);
         switch ( modrm_reg )
@@ -1588,7 +1594,7 @@ static int emulate_privileged_op(struct 
 
     case 0x23: /* MOV <reg>,DR? */
         opcode = insn_fetch(u8, code_base, eip, code_limit);
-        modrm_reg |= (opcode >> 3) & 7;
+        modrm_reg += ((opcode >> 3) & 7) + (lock << 3);
         modrm_rm  |= (opcode >> 0) & 7;
         reg = decode_register(modrm_rm, regs, 0);
         if ( do_set_debugreg(modrm_reg, *reg) != 0 )



_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

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