]> xenbits.xensource.com Git - xen.git/commitdiff
x86/HVM: don't retain emulated insn cache when exiting back to guest
authorJan Beulich <jbeulich@suse.com>
Wed, 6 Dec 2017 11:50:23 +0000 (12:50 +0100)
committerJan Beulich <jbeulich@suse.com>
Wed, 6 Dec 2017 11:50:23 +0000 (12:50 +0100)
vio->mmio_retry is being set when a repeated string insn is being split
up. In that case we'll exit to the guest, expecting immediate re-entry.
Interruptions, however, may be serviced by the guest before re-entry
from the repeated string insn. Any emulation needed in the course of
handling the interruption must not fetch from the internally maintained
cache.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Paul Durrant <paul.durrant@citrix.com>
xen/arch/x86/hvm/emulate.c

index b8c94c926d5caa4bee6127d57d90371fec3cb448..c9fae88dd3e2d082f80d4b8b270b8bdfd91445e9 100644 (file)
@@ -2110,20 +2110,22 @@ static int _hvm_emulate_one(struct hvm_emulate_ctxt *hvmemul_ctxt,
 
     vio->mmio_retry = 0;
 
-    rc = x86_emulate(&hvmemul_ctxt->ctxt, ops);
-
-    if ( rc == X86EMUL_OKAY && vio->mmio_retry )
-        rc = X86EMUL_RETRY;
-    if ( rc != X86EMUL_RETRY )
+    switch ( rc = x86_emulate(&hvmemul_ctxt->ctxt, ops) )
     {
+    case X86EMUL_OKAY:
+        if ( vio->mmio_retry )
+            rc = X86EMUL_RETRY;
+        /* fall through */
+    default:
         vio->mmio_cache_count = 0;
         vio->mmio_insn_bytes = 0;
-    }
-    else
-    {
+        break;
+
+    case X86EMUL_RETRY:
         BUILD_BUG_ON(sizeof(vio->mmio_insn) < sizeof(hvmemul_ctxt->insn_buf));
         vio->mmio_insn_bytes = hvmemul_ctxt->insn_buf_bytes;
         memcpy(vio->mmio_insn, hvmemul_ctxt->insn_buf, vio->mmio_insn_bytes);
+        break;
     }
 
     if ( hvmemul_ctxt->ctxt.retire.singlestep )