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

[Xen-devel] [PATCH RFC V2 1/6] xen: Emulate with no writes


  • To: xen-devel@xxxxxxxxxxxxx
  • From: Razvan Cojocaru <rcojocaru@xxxxxxxxxxxxxxx>
  • Date: Fri, 11 Jul 2014 18:43:33 +0300
  • Cc: andrew.cooper3@xxxxxxxxxx, mdontu@xxxxxxxxxxxxxxx, tim@xxxxxxx, Razvan Cojocaru <rcojocaru@xxxxxxxxxxxxxxx>, JBeulich@xxxxxxxx
  • Comment: DomainKeys? See http://domainkeys.sourceforge.net/
  • Delivery-date: Fri, 11 Jul 2014 15:43:58 +0000
  • Domainkey-signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=bitdefender.com; b=MVREByGtnQ2FsZO+iOvfRGrxaeDIyjf7OdPfW7KTpIgAzO5GcdyGb0dZyntTT7O791dLRzhDTRVfsrLc+cATdh66Ue/dp67t7yZj57bmHkTUB0Mmu+yaW0N68PeVTOQbES9Gq4+5eD+CDvQ8GZh40f1DoUzOE0Z7ToKwtKwYb+46pvAZjaM7TVuwYE6MsSZmFJKAtGP/kxYt+BNzF1H4ojAeC3NQRL1urAFeX2DcI+0DXZjmMrJmTMk7N3SOmoz4GjEfXZHI9wJHzB8xxh/ryUMf9Obn+ZDdxgKXNfW5X6qVuC8suTJYPJTUodvBS/MaRiHioQeX4rmxwosB2yckBA==; h=Received:Received:Received:Received:From:To:Cc:Subject:Date:Message-Id:X-Mailer:X-BitDefender-Scanner:X-BitDefender-Spam:X-BitDefender-SpamStamp:X-BitDefender-CF-Stamp;
  • List-id: Xen developer discussion <xen-devel.lists.xen.org>

Added support for emulating an instruction with no memory writes.
Additionally, introduced hvm_emulate_one_full(), which acts upon all
possible return values from the hvm_emulate_one() functions (RETRY,
EXCEPTION, UNHANDLEABLE).

Changes since V1:
 - Removed the Linux code that computes the length of an instruction.
 - Unused function parameters are no longer marked.
 - Refactored the code to eliminate redundancy.
 - Made the exception passed on to the guest by hvm_emulate_one_full()
   configurable.

Signed-off-by: Razvan Cojocaru <rcojocaru@xxxxxxxxxxxxxxx>
---
 xen/arch/x86/hvm/emulate.c        |   73 +++++++++++++++++++++++++++++++++++--
 xen/include/asm-x86/hvm/emulate.h |    5 +++
 2 files changed, 75 insertions(+), 3 deletions(-)

diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c
index eac159f..114a77a 100644
--- a/xen/arch/x86/hvm/emulate.c
+++ b/xen/arch/x86/hvm/emulate.c
@@ -688,6 +688,17 @@ static int hvmemul_write(
     return X86EMUL_OKAY;
 }
 
+static int hvmemul_write_dummy(
+    enum x86_segment seg,
+    unsigned long offset,
+    void *p_data,
+    unsigned int bytes,
+    struct x86_emulate_ctxt *ctxt)
+{
+    /* discarding the write */
+    return X86EMUL_OKAY;
+}
+
 static int hvmemul_cmpxchg(
     enum x86_segment seg,
     unsigned long offset,
@@ -1138,8 +1149,8 @@ static const struct x86_emulate_ops hvm_emulate_ops = {
     .invlpg        = hvmemul_invlpg
 };
 
-int hvm_emulate_one(
-    struct hvm_emulate_ctxt *hvmemul_ctxt)
+static int hvm_emulate_one_with_ops(struct hvm_emulate_ctxt *hvmemul_ctxt,
+    const struct x86_emulate_ops *ops)
 {
     struct cpu_user_regs *regs = hvmemul_ctxt->ctxt.regs;
     struct vcpu *curr = current;
@@ -1191,7 +1202,7 @@ int hvm_emulate_one(
     vio->mmio_retrying = vio->mmio_retry;
     vio->mmio_retry = 0;
 
-    rc = x86_emulate(&hvmemul_ctxt->ctxt, &hvm_emulate_ops);
+    rc = x86_emulate(&hvmemul_ctxt->ctxt, ops);
 
     if ( rc == X86EMUL_OKAY && vio->mmio_retry )
         rc = X86EMUL_RETRY;
@@ -1239,6 +1250,62 @@ int hvm_emulate_one(
     return X86EMUL_OKAY;
 }
 
+int hvm_emulate_one(
+    struct hvm_emulate_ctxt *hvmemul_ctxt)
+{
+    return hvm_emulate_one_with_ops(hvmemul_ctxt, &hvm_emulate_ops);
+}
+
+int hvm_emulate_one_no_write(
+    struct hvm_emulate_ctxt *hvmemul_ctxt)
+{
+    struct x86_emulate_ops local_ops = hvm_emulate_ops;
+    local_ops.write = hvmemul_write_dummy;
+
+    return hvm_emulate_one_with_ops(hvmemul_ctxt, &local_ops);
+}
+
+void hvm_emulate_one_full(bool_t nowrite,
+    unsigned int unhandleable_trapnr,
+    int unhandleable_errcode)
+{
+    struct hvm_emulate_ctxt ctx[1] = {};
+    int rc = X86EMUL_RETRY;
+
+    hvm_emulate_prepare(ctx, guest_cpu_user_regs());
+
+    while ( rc == X86EMUL_RETRY )
+    {
+        if ( nowrite )
+            rc = hvm_emulate_one_no_write(ctx);
+        else
+            rc = hvm_emulate_one(ctx);
+    }
+
+    switch ( rc )
+    {
+    case X86EMUL_UNHANDLEABLE:
+        gdprintk(XENLOG_DEBUG, "Emulation failed @ %04x:%lx: "
+               "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
+               hvmemul_get_seg_reg(x86_seg_cs, ctx)->sel,
+               ctx->insn_buf_eip,
+               ctx->insn_buf[0], ctx->insn_buf[1],
+               ctx->insn_buf[2], ctx->insn_buf[3],
+               ctx->insn_buf[4], ctx->insn_buf[5],
+               ctx->insn_buf[6], ctx->insn_buf[7],
+               ctx->insn_buf[8], ctx->insn_buf[9]);
+        hvm_inject_hw_exception(unhandleable_trapnr, unhandleable_errcode);
+        break;
+    case X86EMUL_EXCEPTION:
+        if ( ctx->exn_pending )
+            hvm_inject_hw_exception(ctx->exn_vector, ctx->exn_error_code);
+        /* fall through */
+    default:
+        hvm_emulate_writeback(ctx);
+        break;
+    }
+}
+
 void hvm_emulate_prepare(
     struct hvm_emulate_ctxt *hvmemul_ctxt,
     struct cpu_user_regs *regs)
diff --git a/xen/include/asm-x86/hvm/emulate.h 
b/xen/include/asm-x86/hvm/emulate.h
index 00a06cc..d68b485 100644
--- a/xen/include/asm-x86/hvm/emulate.h
+++ b/xen/include/asm-x86/hvm/emulate.h
@@ -37,6 +37,11 @@ struct hvm_emulate_ctxt {
 
 int hvm_emulate_one(
     struct hvm_emulate_ctxt *hvmemul_ctxt);
+int hvm_emulate_one_no_write(
+    struct hvm_emulate_ctxt *hvmemul_ctxt);
+void hvm_emulate_one_full(bool_t nowrite,
+    unsigned int unhandleable_trapnr,
+    int unhandleable_errcode);
 void hvm_emulate_prepare(
     struct hvm_emulate_ctxt *hvmemul_ctxt,
     struct cpu_user_regs *regs);
-- 
1.7.9.5


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


 


Rackspace

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