From mboxrd@z Thu Jan 1 00:00:00 1970 From: Andrew Cooper Subject: Re: [PATCH] x86_emulate: properly do IP updates and other side effects on success Date: Thu, 7 Aug 2014 12:40:42 +0100 Message-ID: <53E365BA.8010801@citrix.com> References: <53E35543020000780002A09C@mail.emea.novell.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="===============0686798464874905975==" Return-path: Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1XFM3s-0006Zj-Bf for xen-devel@lists.xenproject.org; Thu, 07 Aug 2014 11:40:48 +0000 In-Reply-To: <53E35543020000780002A09C@mail.emea.novell.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: Jan Beulich , xen-devel Cc: Keir Fraser List-Id: xen-devel@lists.xenproject.org --===============0686798464874905975== Content-Type: multipart/alternative; boundary="------------020603030204030301050208" --------------020603030204030301050208 Content-Type: text/plain; charset="ISO-8859-1" Content-Transfer-Encoding: 7bit On 07/08/14 09:30, Jan Beulich wrote: > The two MMX/SSE/AVX code blocks failed to update IP properly, and these > as well as get_reg_refix(), which "manually" updated IP so far, failed > to do the TF and RF processing needed at the end of successfully > emulated instructions. > > Reported-by: Andrei LUTAS > Signed-off-by: Jan Beulich > Tested-by: Razvan Cojocaru Reviewed-by: Andrew Cooper > > --- a/xen/arch/x86/x86_emulate/x86_emulate.c > +++ b/xen/arch/x86/x86_emulate/x86_emulate.c > @@ -720,29 +720,26 @@ do{ uint8_t stub[] = { _bytes, 0xc3 }; > put_fpu(&fic); \ > } while (0) > > -static unsigned long __get_rep_prefix( > - struct cpu_user_regs *int_regs, > - struct cpu_user_regs *ext_regs, > +static unsigned long _get_rep_prefix( > + const struct cpu_user_regs *int_regs, > int ad_bytes) > { > - unsigned long ecx = ((ad_bytes == 2) ? (uint16_t)int_regs->ecx : > - (ad_bytes == 4) ? (uint32_t)int_regs->ecx : > - int_regs->ecx); > - > - /* Skip the instruction if no repetitions are required. */ > - if ( ecx == 0 ) > - ext_regs->eip = int_regs->eip; > - > - return ecx; > + return (ad_bytes == 2) ? (uint16_t)int_regs->ecx : > + (ad_bytes == 4) ? (uint32_t)int_regs->ecx : > + int_regs->ecx; > } > > #define get_rep_prefix() ({ \ > unsigned long max_reps = 1; \ > if ( rep_prefix() ) \ > - max_reps = __get_rep_prefix(&_regs, ctxt->regs, ad_bytes); \ > + max_reps = _get_rep_prefix(&_regs, ad_bytes); \ > if ( max_reps == 0 ) \ > - goto done; \ > - max_reps; \ > + { \ > + /* Skip the instruction if no repetitions are required. */ \ > + dst.type = OP_NONE; \ > + goto writeback; \ > + } \ > + max_reps; \ > }) > > static void __put_rep_prefix( > @@ -3921,7 +3918,8 @@ x86_emulate( > if ( !rc && (b & 1) && (ea.type == OP_MEM) ) > rc = ops->write(ea.mem.seg, ea.mem.off, mmvalp, > ea.bytes, ctxt); > - goto done; > + dst.type = OP_NONE; > + break; > } > > case 0x20: /* mov cr,reg */ > @@ -4188,7 +4186,8 @@ x86_emulate( > if ( !rc && (b != 0x6f) && (ea.type == OP_MEM) ) > rc = ops->write(ea.mem.seg, ea.mem.off, mmvalp, > ea.bytes, ctxt); > - goto done; > + dst.type = OP_NONE; > + break; > } > > case 0x80 ... 0x8f: /* jcc (near) */ { > > > > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xen.org > http://lists.xen.org/xen-devel --------------020603030204030301050208 Content-Type: text/html; charset="ISO-8859-1" Content-Transfer-Encoding: 7bit
On 07/08/14 09:30, Jan Beulich wrote:
The two MMX/SSE/AVX code blocks failed to update IP properly, and these
as well as get_reg_refix(), which "manually" updated IP so far, failed
to do the TF and RF processing needed at the end of successfully
emulated instructions.

Reported-by: Andrei LUTAS <vlutas@bitdefender.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Tested-by: Razvan Cojocaru <rcojocaru@bitdefender.com>

Reviewed-by: Andrew Cooper <andrew.cooper@citrix.com>


--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -720,29 +720,26 @@ do{ uint8_t stub[] = { _bytes, 0xc3 };  
     put_fpu(&fic);                                                      \
 } while (0)
 
-static unsigned long __get_rep_prefix(
-    struct cpu_user_regs *int_regs,
-    struct cpu_user_regs *ext_regs,
+static unsigned long _get_rep_prefix(
+    const struct cpu_user_regs *int_regs,
     int ad_bytes)
 {
-    unsigned long ecx = ((ad_bytes == 2) ? (uint16_t)int_regs->ecx :
-                         (ad_bytes == 4) ? (uint32_t)int_regs->ecx :
-                         int_regs->ecx);
-
-    /* Skip the instruction if no repetitions are required. */
-    if ( ecx == 0 )
-        ext_regs->eip = int_regs->eip;
-
-    return ecx;
+    return (ad_bytes == 2) ? (uint16_t)int_regs->ecx :
+           (ad_bytes == 4) ? (uint32_t)int_regs->ecx :
+           int_regs->ecx;
 }
 
 #define get_rep_prefix() ({                                             \
     unsigned long max_reps = 1;                                         \
     if ( rep_prefix() )                                                 \
-        max_reps = __get_rep_prefix(&_regs, ctxt->regs, ad_bytes);      \
+        max_reps = _get_rep_prefix(&_regs, ad_bytes);                   \
     if ( max_reps == 0 )                                                \
-        goto done;                                                      \
-   max_reps;                                                            \
+    {                                                                   \
+        /* Skip the instruction if no repetitions are required. */      \
+        dst.type = OP_NONE;                                             \
+        goto writeback;                                                 \
+    }                                                                   \
+    max_reps;                                                           \
 })
 
 static void __put_rep_prefix(
@@ -3921,7 +3918,8 @@ x86_emulate(
         if ( !rc && (b & 1) && (ea.type == OP_MEM) )
             rc = ops->write(ea.mem.seg, ea.mem.off, mmvalp,
                             ea.bytes, ctxt);
-        goto done;
+        dst.type = OP_NONE;
+        break;
     }
 
     case 0x20: /* mov cr,reg */
@@ -4188,7 +4186,8 @@ x86_emulate(
         if ( !rc && (b != 0x6f) && (ea.type == OP_MEM) )
             rc = ops->write(ea.mem.seg, ea.mem.off, mmvalp,
                             ea.bytes, ctxt);
-        goto done;
+        dst.type = OP_NONE;
+        break;
     }
 
     case 0x80 ... 0x8f: /* jcc (near) */ {





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

--------------020603030204030301050208-- --===============0686798464874905975== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel --===============0686798464874905975==--