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

[RFC v1 3/7] x86/emul: Separate out instruction completion


  • To: xen-devel@xxxxxxxxxxxxxxxxxxxx
  • From: Ross Lagerwall <ross.lagerwall@xxxxxxxxxx>
  • Date: Mon, 18 May 2026 14:14:00 +0100
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=citrix.com; dmarc=pass action=none header.from=citrix.com; dkim=pass header.d=citrix.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=IvpufiE6EX4IADgKhV1F40NPVtMT7lPinzez3cDqZ/k=; b=C9H0tTNEy5ArjqkzokC8lHlg5i9rgIvXKi4shMc+buSmeV4usg66B6pBEEs3VHgHOXJ+1XptSYcOB7f0po50pSpsOpM/tLtB0piCnxXlmLlMeZV5jSKbBTsqGIjVjCK0Ex39RQfIse+4AVJTbldo3/VckMcck5VaIzG4Fl6LUw6+5EcN7ZbYIO3RAo0be2qg8yVWaLR3ZyeUJfXZs989N4/UpwrmvewXRaKzAS89ZCcSx1dcEqOAmeZSO57RCErgxcoToG+aR1eUTRZuvFoxSFlP3Himlw4WvNMGZ1dUWboI12OLFPUijP9busW8D1Ioh4x3DX9EfC247eMAS/Dt+g==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=KsV39skMRHI6JNafJKHe2WpW2WvXfSPJo58c9633aMt2xqaV296InJ13wNYfvSu++LrH67Jx8KLW1LK61QtG0WH+KamG/A3oLUobFkYEuf2VrljD/eN4FbWDbyBFLpiqY8bXq7z9E0aDxMdBGZJFNMEodMiS+Mq/G4AF8R4VxEW5JFmvGKM/vFSwjg3EqVV3qeN5gluKT4bVxD/U2L5/raqzwogJUswTVTMSi+bo/YxNRkZGQ+nwB+3eg+ZS5maQik3Bj4v9s5NWkUg4yJzM+Z7ROowV85lBMNuYlredCTUGugsntQ+uuwza3E5NqikY7vA5jcYKGxAsXlqPQzy8eA==
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=citrix.com header.i="@citrix.com" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck"
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=citrix.com;
  • Cc: Ross Lagerwall <ross.lagerwall@xxxxxxxxxx>, Jan Beulich <jbeulich@xxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>, Teddy Astie <teddy.astie@xxxxxxxxxx>
  • Delivery-date: Mon, 18 May 2026 13:14:33 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

To support merging the emulated instruction and VMEXIT paths, split out
instruction completion from the core x86 emulation so it can be called
separately.

Signed-off-by: Ross Lagerwall <ross.lagerwall@xxxxxxxxxx>
---
 xen/arch/x86/x86_emulate/x86_emulate.c | 48 +++++++++++++++-----------
 xen/arch/x86/x86_emulate/x86_emulate.h |  3 ++
 2 files changed, 30 insertions(+), 21 deletions(-)

diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c 
b/xen/arch/x86/x86_emulate/x86_emulate.c
index 364e6c092ded..76fbebf96b4d 100644
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -320,7 +320,7 @@ do {                                                        
            \
     rc = ops->insn_fetch(ip, NULL, 0, ctxt);                            \
     if ( rc ) goto done;                                                \
     _regs.r(ip) = ip;                                                   \
-    singlestep = _regs.eflags & X86_EFLAGS_TF;                          \
+    ctxt->singlestep = _regs.eflags & X86_EFLAGS_TF;                    \
 } while (0)
 
 #define validate_far_branch(cs, ip) ({                                  \
@@ -337,7 +337,7 @@ do {                                                        
            \
         ({                                                              \
             validate_far_branch(cs, newip);                             \
             _regs.r(ip) = (newip);                                      \
-            singlestep = _regs.eflags & X86_EFLAGS_TF;                  \
+            ctxt->singlestep = _regs.eflags & X86_EFLAGS_TF;            \
         }),                                                             \
         ops->write_segment(x86_seg_cs, cs, ctxt)                        \
     )
@@ -1234,6 +1234,22 @@ int cf_check x86emul_unhandleable_rw(
     return X86EMUL_UNHANDLEABLE;
 }
 
+void x86_emulate_complete(struct x86_emulate_ctxt *ctxt, int rc)
+{
+    /* Zero the upper 32 bits of %rip if not in 64-bit mode. */
+    if ( !mode_64bit() )
+        ctxt->regs->r(ip) = (uint32_t)ctxt->regs->r(ip);
+
+    /* Should a singlestep #DB be raised? */
+    if ( rc == X86EMUL_OKAY && ctxt->singlestep && !ctxt->retire.mov_ss )
+    {
+        ctxt->retire.singlestep = true;
+        ctxt->retire.sti = false;
+    }
+
+    ctxt->regs->eflags &= ~X86_EFLAGS_RF;
+}
+
 /* Helper definitions. */
 #define op_bytes (state->op_bytes)
 #define ad_bytes (state->ad_bytes)
@@ -1265,8 +1281,6 @@ x86_emulate(
     uint8_t b, d, *opc = NULL;
     unsigned int first_byte = 0, elem_bytes, insn_bytes = 0;
     uint64_t op_mask = ~0ULL;
-    bool singlestep = (_regs.eflags & X86_EFLAGS_TF) &&
-           !is_branch_step(ctxt, ops);
     bool sfence = false, fault_suppression = false;
     struct operand src = { .reg = PTR_POISON };
     struct operand dst = { .reg = PTR_POISON };
@@ -1280,6 +1294,9 @@ x86_emulate(
 
     init_context(ctxt);
 
+    ctxt->singlestep = (_regs.eflags & X86_EFLAGS_TF) &&
+           !is_branch_step(ctxt, ops);
+
     generate_exception_if((mode_vif() &&
                            (_regs.eflags & X86_EFLAGS_VIF) &&
                            (_regs.eflags & X86_EFLAGS_VIP)),
@@ -2064,7 +2081,7 @@ x86_emulate(
             goto done;
 
         _regs.r(ip) = imm1;
-        singlestep = _regs.eflags & X86_EFLAGS_TF;
+        ctxt->singlestep = _regs.eflags & X86_EFLAGS_TF;
         break;
 
 #ifndef X86EMUL_NO_FPU
@@ -3103,7 +3120,7 @@ x86_emulate(
          * Their only mitigation is to use a task gate for handling
          * #DB (or to not use enable EFER.SCE to start with).
          */
-        singlestep = _regs.eflags & X86_EFLAGS_TF;
+        ctxt->singlestep = _regs.eflags & X86_EFLAGS_TF;
         break;
 
     case X86EMUL_OPC(0x0f, 0x06): /* clts */
@@ -3189,7 +3206,7 @@ x86_emulate(
                                       ctxt)) != X86EMUL_OKAY )
             goto done;
 
-        singlestep = _regs.eflags & X86_EFLAGS_TF;
+        ctxt->singlestep = _regs.eflags & X86_EFLAGS_TF;
         break;
 
     case X86EMUL_OPC(0x0f, 0x08): /* invd */
@@ -3918,7 +3935,7 @@ x86_emulate(
             /* In particular mode_64bit() needs to return true from here on. */
             ctxt->addr_size = ctxt->sp_size = 64;
 
-        singlestep = _regs.eflags & X86_EFLAGS_TF;
+        ctxt->singlestep = _regs.eflags & X86_EFLAGS_TF;
         break;
 
     case X86EMUL_OPC(0x0f, 0x35): /* sysexit */
@@ -3958,7 +3975,7 @@ x86_emulate(
         _regs.r(ip) = op_bytes == 8 ? _regs.r(dx) : _regs.edx;
         _regs.r(sp) = op_bytes == 8 ? _regs.r(cx) : _regs.ecx;
 
-        singlestep = _regs.eflags & X86_EFLAGS_TF;
+        ctxt->singlestep = _regs.eflags & X86_EFLAGS_TF;
         break;
 
     case X86EMUL_OPC(0x0f, 0x40) ... X86EMUL_OPC(0x0f, 0x4f): /* cmovcc */
@@ -8347,17 +8364,6 @@ x86_emulate(
     put_fpu(fpu_type, false, state, ctxt, ops);
     fpu_type = X86EMUL_FPU_none;
 
-    /* Zero the upper 32 bits of %rip if not in 64-bit mode. */
-    if ( !mode_64bit() )
-        _regs.r(ip) = (uint32_t)_regs.r(ip);
-
-    /* Should a singlestep #DB be raised? */
-    if ( rc == X86EMUL_OKAY && singlestep && !ctxt->retire.mov_ss )
-    {
-        ctxt->retire.singlestep = true;
-        ctxt->retire.sti = false;
-    }
-
     if ( rc != X86EMUL_DONE )
         *ctxt->regs = _regs;
     else
@@ -8366,7 +8372,7 @@ x86_emulate(
         rc = X86EMUL_OKAY;
     }
 
-    ctxt->regs->eflags &= ~X86_EFLAGS_RF;
+    x86_emulate_complete(ctxt, rc);
 
  done:
     put_fpu(fpu_type, insn_bytes > 0 && dst.type == OP_MEM, state, ctxt, ops);
diff --git a/xen/arch/x86/x86_emulate/x86_emulate.h 
b/xen/arch/x86/x86_emulate/x86_emulate.h
index 0fd20747dc43..17bf14455cf3 100644
--- a/xen/arch/x86/x86_emulate/x86_emulate.h
+++ b/xen/arch/x86/x86_emulate/x86_emulate.h
@@ -594,6 +594,7 @@ struct x86_emulate_ctxt
     } retire;
 
     bool event_pending;
+    bool singlestep;
     struct x86_event event;
 };
 
@@ -680,6 +681,8 @@ x86_emulate(
     struct x86_emulate_ctxt *ctxt,
     const struct x86_emulate_ops *ops);
 
+void x86_emulate_complete(struct x86_emulate_ctxt *ctxt, int rc);
+
 #ifndef NDEBUG
 /*
  * In debug builds, wrap x86_emulate() with some assertions about its expected
-- 
2.53.0




 


Rackspace

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