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

[Xen-changelog] [xen master] x86/PV: avoid indirect call/thunk in I/O emulation



commit 0091daa9d911995327ef92c3ce663c3c569c8c6e
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Mon Feb 19 13:59:37 2018 +0100
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Mon Feb 19 13:59:37 2018 +0100

    x86/PV: avoid indirect call/thunk in I/O emulation
    
    The stub is within reach from the .text section, so there's no point
    using an indirect call here. This has the added benefit of there no
    longer being two sufficiently different approaches, breaking one of
    which people may not even notice.
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Acked-by: Andrew Cooper <andrew.cooper3@xxxxxxxxx>
---
 xen/arch/x86/pv/emul-priv-op.c | 39 +++++++++++++--------------------------
 1 file changed, 13 insertions(+), 26 deletions(-)

diff --git a/xen/arch/x86/pv/emul-priv-op.c b/xen/arch/x86/pv/emul-priv-op.c
index 21ecfc8..17aaf97 100644
--- a/xen/arch/x86/pv/emul-priv-op.c
+++ b/xen/arch/x86/pv/emul-priv-op.c
@@ -73,55 +73,42 @@ void (*pv_post_outb_hook)(unsigned int port, u8 value);
 
 typedef void io_emul_stub_t(struct cpu_user_regs *);
 
-void __x86_indirect_thunk_rcx(void);
-
 static io_emul_stub_t *io_emul_stub_setup(struct priv_op_ctxt *ctxt, u8 opcode,
                                           unsigned int port, unsigned int 
bytes)
 {
     struct stubs *this_stubs = &this_cpu(stubs);
     unsigned long stub_va = this_stubs->addr + STUB_BUF_SIZE / 2;
+    long disp;
     bool use_quirk_stub = false;
 
     if ( !ctxt->io_emul_stub )
         ctxt->io_emul_stub =
             map_domain_page(_mfn(this_stubs->mfn)) + (stub_va & ~PAGE_MASK);
 
-    /* movq $host_to_guest_gpr_switch,%rcx */
-    ctxt->io_emul_stub[0] = 0x48;
-    ctxt->io_emul_stub[1] = 0xb9;
-    *(void **)&ctxt->io_emul_stub[2] = (void *)host_to_guest_gpr_switch;
-
-#ifdef CONFIG_INDIRECT_THUNK
-    /* callq __x86_indirect_thunk_rcx */
-    ctxt->io_emul_stub[10] = 0xe8;
-    *(int32_t *)&ctxt->io_emul_stub[11] =
-        (long)__x86_indirect_thunk_rcx - (stub_va + 11 + 4);
-#else
-    /* callq *%rcx */
-    ctxt->io_emul_stub[10] = 0xff;
-    ctxt->io_emul_stub[11] = 0xd1;
-    /* TODO: untangle ideal_nops from init/livepatch Kconfig options. */
-    memcpy(&ctxt->io_emul_stub[12], "\x0f\x1f\x00", 3); /* P6_NOP3 */
-#endif
+    /* call host_to_guest_gpr_switch */
+    ctxt->io_emul_stub[0] = 0xe8;
+    disp = (long)host_to_guest_gpr_switch - (stub_va + 5);
+    BUG_ON((int32_t)disp != disp);
+    *(int32_t *)&ctxt->io_emul_stub[1] = disp;
 
     if ( unlikely(ioemul_handle_quirk) )
-        use_quirk_stub = ioemul_handle_quirk(opcode, &ctxt->io_emul_stub[15],
+        use_quirk_stub = ioemul_handle_quirk(opcode, &ctxt->io_emul_stub[5],
                                              ctxt->ctxt.regs);
 
     if ( !use_quirk_stub )
     {
         /* data16 or nop */
-        ctxt->io_emul_stub[15] = (bytes != 2) ? 0x90 : 0x66;
+        ctxt->io_emul_stub[5] = (bytes != 2) ? 0x90 : 0x66;
         /* <io-access opcode> */
-        ctxt->io_emul_stub[16] = opcode;
+        ctxt->io_emul_stub[6] = opcode;
         /* imm8 or nop */
-        ctxt->io_emul_stub[17] = !(opcode & 8) ? port : 0x90;
+        ctxt->io_emul_stub[7] = !(opcode & 8) ? port : 0x90;
         /* ret (jumps to guest_to_host_gpr_switch) */
-        ctxt->io_emul_stub[18] = 0xc3;
+        ctxt->io_emul_stub[8] = 0xc3;
     }
 
-    BUILD_BUG_ON(STUB_BUF_SIZE / 2 < MAX(19, /* Default emul stub */
-                                         15 + IOEMUL_QUIRK_STUB_BYTES));
+    BUILD_BUG_ON(STUB_BUF_SIZE / 2 < MAX(9, /* Default emul stub */
+                                         5 + IOEMUL_QUIRK_STUB_BYTES));
 
     /* Handy function-typed pointer to the stub. */
     return (void *)stub_va;
--
generated by git-patchbot for /home/xen/git/xen.git#master

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog

 


Rackspace

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