Index: /trunk/include/VBox/vmm/gim.h
===================================================================
--- /trunk/include/VBox/vmm/gim.h	(revision 72468)
+++ /trunk/include/VBox/vmm/gim.h	(revision 72469)
@@ -189,4 +189,5 @@
 VMM_INT_DECL(bool)          GIMAreHypercallsEnabled(PVMCPU pVCpu);
 VMM_INT_DECL(VBOXSTRICTRC)  GIMHypercall(PVMCPU pVCpu, PCPUMCTX pCtx);
+VMM_INT_DECL(VBOXSTRICTRC)  GIMHypercallEx(PVMCPU pVCpu, PCPUMCTX pCtx, unsigned uDisOpcode, uint8_t cbInstr);
 VMM_INT_DECL(VBOXSTRICTRC)  GIMExecHypercallInstr(PVMCPU pVCpu, PCPUMCTX pCtx, uint8_t *pcbInstr);
 VMM_INT_DECL(VBOXSTRICTRC)  GIMXcptUD(PVMCPU pVCpu, PCPUMCTX pCtx, PDISCPUSTATE pDis, uint8_t *pcbInstr);
@@ -194,4 +195,6 @@
 VMM_INT_DECL(VBOXSTRICTRC)  GIMReadMsr(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t *puValue);
 VMM_INT_DECL(VBOXSTRICTRC)  GIMWriteMsr(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t uValue, uint64_t uRawValue);
+VMM_INT_DECL(int)           GIMQueryHypercallOpcodeBytes(PVM pVM, void *pvBuf, size_t cbBuf,
+                                                         size_t *pcbWritten, uint16_t *puDisOpcode);
 /** @} */
 
Index: /trunk/include/VBox/vmm/vmm.h
===================================================================
--- /trunk/include/VBox/vmm/vmm.h	(revision 72468)
+++ /trunk/include/VBox/vmm/vmm.h	(revision 72469)
@@ -286,5 +286,4 @@
 VMM_INT_DECL(bool)          VMMIsInRing3Call(PVMCPU pVCpu);
 VMM_INT_DECL(void)          VMMTrashVolatileXMMRegs(void);
-VMM_INT_DECL(int)           VMMPatchHypercall(PVM pVM, void *pvBuf, size_t cbBuf, size_t *pcbWritten);
 
 
Index: /trunk/src/VBox/VMM/VMMAll/GIMAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/GIMAll.cpp	(revision 72468)
+++ /trunk/src/VBox/VMM/VMMAll/GIMAll.cpp	(revision 72469)
@@ -133,4 +133,54 @@
 
 /**
+ * Same as GIMHypercall, except with disassembler opcode and instruction length.
+ *
+ * This is the interface used by IEM.
+ *
+ * @returns Strict VBox status code.
+ * @retval  VINF_SUCCESS if the hypercall succeeded (even if its operation
+ *          failed).
+ * @retval  VINF_GIM_HYPERCALL_CONTINUING continue hypercall without updating
+ *          RIP.
+ * @retval  VINF_GIM_R3_HYPERCALL re-start the hypercall from ring-3.
+ * @retval  VERR_GIM_HYPERCALL_ACCESS_DENIED CPL is insufficient.
+ * @retval  VERR_GIM_HYPERCALLS_NOT_AVAILABLE hypercalls unavailable.
+ * @retval  VERR_GIM_NOT_ENABLED GIM is not enabled (shouldn't really happen)
+ * @retval  VERR_GIM_HYPERCALL_MEMORY_READ_FAILED hypercall failed while reading
+ *          memory.
+ * @retval  VERR_GIM_HYPERCALL_MEMORY_WRITE_FAILED hypercall failed while
+ *          writing memory.
+ * @retval  VERR_GIM_INVALID_HYPERCALL_INSTR if uDisOpcode is the wrong one; raise \#UD.
+ *
+ * @param   pVCpu       The cross context virtual CPU structure.
+ * @param   pCtx        Pointer to the guest-CPU context.
+ * @param   uDisOpcode  The disassembler opcode.
+ * @param   cbInstr     The instruction length.
+ *
+ * @remarks The caller of this function needs to advance RIP as required.
+ * @thread  EMT.
+ */
+VMM_INT_DECL(VBOXSTRICTRC) GIMHypercallEx(PVMCPU pVCpu, PCPUMCTX pCtx, unsigned uDisOpcode, uint8_t cbInstr)
+{
+    PVM pVM = pVCpu->CTX_SUFF(pVM);
+    VMCPU_ASSERT_EMT(pVCpu);
+
+    if (RT_UNLIKELY(!GIMIsEnabled(pVM)))
+        return VERR_GIM_NOT_ENABLED;
+
+    switch (pVM->gim.s.enmProviderId)
+    {
+        case GIMPROVIDERID_HYPERV:
+            return gimHvHypercallEx(pVCpu, pCtx, uDisOpcode, cbInstr);
+
+        case GIMPROVIDERID_KVM:
+            return gimKvmHypercallEx(pVCpu, pCtx, uDisOpcode, cbInstr);
+
+        default:
+            AssertMsgFailedReturn(("enmProviderId=%u\n", pVM->gim.s.enmProviderId), VERR_GIM_HYPERCALLS_NOT_AVAILABLE);
+    }
+}
+
+
+/**
  * Disassembles the instruction at RIP and if it's a hypercall
  * instruction, performs the hypercall.
@@ -163,8 +213,8 @@
         {
             case GIMPROVIDERID_HYPERV:
-                return gimHvExecHypercallInstr(pVCpu, pCtx, &Dis);
+                return gimHvHypercallEx(pVCpu, pCtx, Dis.pCurInstr->uOpcode, Dis.cbInstr);
 
             case GIMPROVIDERID_KVM:
-                return gimKvmExecHypercallInstr(pVCpu, pCtx, &Dis);
+                return gimKvmHypercallEx(pVCpu, pCtx, Dis.pCurInstr->uOpcode, Dis.cbInstr);
 
             default:
@@ -352,2 +402,57 @@
 }
 
+
+/**
+ * Queries the opcode bytes for a native hypercall.
+ *
+ * @returns VBox status code.
+ * @param   pVM         The cross context VM structure.
+ * @param   pvBuf       The destination buffer.
+ * @param   cbBuf       The size of the buffer.
+ * @param   pcbWritten  Where to return the number of bytes written.  This is
+ *                      reliably updated only on successful return.  Optional.
+ * @param   puDisOpcode Where to return the disassembler opcode.  Optional.
+ */
+VMM_INT_DECL(int) GIMQueryHypercallOpcodeBytes(PVM pVM, void *pvBuf, size_t cbBuf, size_t *pcbWritten, uint16_t *puDisOpcode)
+{
+    AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
+
+    CPUMCPUVENDOR  enmHostCpu = CPUMGetHostCpuVendor(pVM);
+    uint8_t const *pbSrc;
+    size_t         cbSrc;
+    switch (enmHostCpu)
+    {
+        case CPUMCPUVENDOR_AMD:
+        {
+            if (puDisOpcode)
+                *puDisOpcode = OP_VMMCALL;
+            static uint8_t const s_abHypercall[] = { 0x0F, 0x01, 0xD9 };   /* VMMCALL */
+            pbSrc = s_abHypercall;
+            cbSrc = sizeof(s_abHypercall);
+            break;
+        }
+
+        case CPUMCPUVENDOR_INTEL:
+        case CPUMCPUVENDOR_VIA:
+        {
+            if (puDisOpcode)
+                *puDisOpcode = OP_VMCALL;
+            static uint8_t const s_abHypercall[] = { 0x0F, 0x01, 0xC1 };   /* VMCALL */
+            pbSrc = s_abHypercall;
+            cbSrc = sizeof(s_abHypercall);
+            break;
+        }
+
+        default:
+            AssertMsgFailedReturn(("%d\n", enmHostCpu), VERR_UNSUPPORTED_CPU);
+    }
+    if (RT_LIKELY(cbBuf >= cbSrc))
+    {
+        memcpy(pvBuf, pbSrc, cbSrc);
+        if (pcbWritten)
+            *pcbWritten = cbSrc;
+        return VINF_SUCCESS;
+    }
+    return VERR_BUFFER_OVERFLOW;
+}
+
Index: /trunk/src/VBox/VMM/VMMAll/GIMAllHv.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/GIMAllHv.cpp	(revision 72468)
+++ /trunk/src/VBox/VMM/VMMAll/GIMAllHv.cpp	(revision 72469)
@@ -1381,34 +1381,33 @@
 
 /**
- * Checks the currently disassembled instruction and executes the hypercall if
- * it's a hypercall instruction.
+ * Checks the instruction and executes the hypercall if it's a valid hypercall
+ * instruction.
+ *
+ * This interface is used by \#UD handlers and IEM.
  *
  * @returns Strict VBox status code.
  * @param   pVCpu       The cross context virtual CPU structure.
  * @param   pCtx        Pointer to the guest-CPU context.
- * @param   pDis        Pointer to the disassembled instruction state at RIP.
+ * @param   uDisOpcode  The disassembler opcode.
+ * @param   cbInstr     The instruction length.
  *
  * @thread  EMT(pVCpu).
- *
- * @todo    Make this function static when @bugref{7270#c168} is addressed.
- */
-VMM_INT_DECL(VBOXSTRICTRC) gimHvExecHypercallInstr(PVMCPU pVCpu, PCPUMCTX pCtx, PDISCPUSTATE pDis)
+ */
+VMM_INT_DECL(VBOXSTRICTRC) gimHvHypercallEx(PVMCPU pVCpu, PCPUMCTX pCtx, unsigned uDisOpcode, uint8_t cbInstr)
 {
     Assert(pVCpu);
     Assert(pCtx);
-    Assert(pDis);
     VMCPU_ASSERT_EMT(pVCpu);
 
     PVM pVM = pVCpu->CTX_SUFF(pVM);
-    CPUMCPUVENDOR const enmGuestCpuVendor = CPUMGetGuestCpuVendor(pVM);
-    if (   (   pDis->pCurInstr->uOpcode == OP_VMCALL
+    CPUMCPUVENDOR const enmGuestCpuVendor = (CPUMCPUVENDOR)pVM->cpum.ro.GuestFeatures.enmCpuVendor;
+    if (   (   uDisOpcode == OP_VMCALL
             && (   enmGuestCpuVendor == CPUMCPUVENDOR_INTEL
                 || enmGuestCpuVendor == CPUMCPUVENDOR_VIA))
-        || (   pDis->pCurInstr->uOpcode == OP_VMMCALL
+        || (   uDisOpcode == OP_VMMCALL
             && enmGuestCpuVendor == CPUMCPUVENDOR_AMD))
-    {
         return gimHvHypercall(pVCpu, pCtx);
-    }
-
+
+    RT_NOREF_PV(cbInstr);
     return VERR_GIM_INVALID_HYPERCALL_INSTR;
 }
@@ -1460,5 +1459,5 @@
             if (pcbInstr)
                 *pcbInstr = (uint8_t)cbInstr;
-            return gimHvExecHypercallInstr(pVCpu, pCtx, &Dis);
+            return gimHvHypercallEx(pVCpu, pCtx, Dis.pCurInstr->uOpcode, Dis.cbInstr);
         }
 
@@ -1467,5 +1466,5 @@
     }
 
-    return gimHvExecHypercallInstr(pVCpu, pCtx, pDis);
+    return gimHvHypercallEx(pVCpu, pCtx, pDis->pCurInstr->uOpcode, pDis->cbInstr);
 }
 
Index: /trunk/src/VBox/VMM/VMMAll/GIMAllKvm.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/GIMAllKvm.cpp	(revision 72468)
+++ /trunk/src/VBox/VMM/VMMAll/GIMAllKvm.cpp	(revision 72469)
@@ -351,21 +351,21 @@
 
 /**
- * Checks the currently disassembled instruction and executes the hypercall if
- * it's a hypercall instruction.
+ * Checks the instruction and executes the hypercall if it's a valid hypercall
+ * instruction.
+ *
+ * This interface is used by \#UD handlers and IEM.
  *
  * @returns Strict VBox status code.
  * @param   pVCpu       The cross context virtual CPU structure.
  * @param   pCtx        Pointer to the guest-CPU context.
- * @param   pDis        Pointer to the disassembled instruction state at RIP.
+ * @param   uDisOpcode  The disassembler opcode.
+ * @param   cbInstr     The instruction length.
  *
  * @thread  EMT(pVCpu).
- *
- * @todo    Make this function static when @bugref{7270#c168} is addressed.
- */
-VMM_INT_DECL(VBOXSTRICTRC) gimKvmExecHypercallInstr(PVMCPU pVCpu, PCPUMCTX pCtx, PDISCPUSTATE pDis)
+ */
+VMM_INT_DECL(VBOXSTRICTRC) gimKvmHypercallEx(PVMCPU pVCpu, PCPUMCTX pCtx, unsigned uDisOpcode, uint8_t cbInstr)
 {
     Assert(pVCpu);
     Assert(pCtx);
-    Assert(pDis);
     VMCPU_ASSERT_EMT(pVCpu);
 
@@ -378,6 +378,6 @@
      * will not require disassembly (when coming from HM).
      */
-    if (   pDis->pCurInstr->uOpcode == OP_VMCALL
-        || pDis->pCurInstr->uOpcode == OP_VMMCALL)
+    if (   uDisOpcode == OP_VMCALL
+        || uDisOpcode == OP_VMMCALL)
     {
         /*
@@ -399,20 +399,13 @@
             PVM      pVM  = pVCpu->CTX_SUFF(pVM);
             PCGIMKVM pKvm = &pVM->gim.s.u.Kvm;
-            if (   pDis->pCurInstr->uOpcode != pKvm->uOpCodeNative
-                && !VM_IS_RAW_MODE_ENABLED(pVM))
+            if (   uDisOpcode != pKvm->uOpcodeNative
+                && !VM_IS_RAW_MODE_ENABLED(pVM)
+                && cbInstr == sizeof(pKvm->abOpcodeNative) )
             {
                 /** @todo r=ramshankar: we probably should be doing this in an
                  *        EMT rendezvous. */
-                uint8_t abHypercall[3];
-                size_t  cbWritten = 0;
-                int rc = VMMPatchHypercall(pVM, &abHypercall, sizeof(abHypercall), &cbWritten);
+                /** @todo Add stats for patching. */
+                int rc = PGMPhysSimpleWriteGCPtr(pVCpu, pCtx->rip, pKvm->abOpcodeNative, sizeof(pKvm->abOpcodeNative));
                 AssertRC(rc);
-                Assert(sizeof(abHypercall) == pDis->cbInstr);
-                Assert(sizeof(abHypercall) == cbWritten);
-
-                rc = PGMPhysSimpleWriteGCPtr(pVCpu, pCtx->rip, &abHypercall, sizeof(abHypercall));
-                AssertRC(rc);
-
-                /** @todo Add stats for patching. */
             }
         }
@@ -473,5 +466,5 @@
             if (pcbInstr)
                 *pcbInstr = (uint8_t)cbInstr;
-            return gimKvmExecHypercallInstr(pVCpu, pCtx, &Dis);
+            return gimKvmHypercallEx(pVCpu, pCtx, Dis.pCurInstr->uOpcode, Dis.cbInstr);
         }
 
@@ -480,5 +473,5 @@
     }
 
-    return gimKvmExecHypercallInstr(pVCpu, pCtx, pDis);
-}
-
+    return gimKvmHypercallEx(pVCpu, pCtx, pDis->pCurInstr->uOpcode, pDis->cbInstr);
+}
+
Index: /trunk/src/VBox/VMM/VMMAll/IEMAllCImplSvmInstr.cpp.h
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IEMAllCImplSvmInstr.cpp.h	(revision 72468)
+++ /trunk/src/VBox/VMM/VMMAll/IEMAllCImplSvmInstr.cpp.h	(revision 72469)
@@ -1092,9 +1092,10 @@
  * Common code for iemCImpl_vmmcall and iemCImpl_vmcall (latter in IEMAllCImplVmxInstr.cpp.h).
  */
-IEM_CIMPL_DEF_0(iemCImpl_Hypercall)
+IEM_CIMPL_DEF_1(iemCImpl_Hypercall, uint16_t, uDisOpcode)
 {
     if (EMAreHypercallInstructionsEnabled(pVCpu))
     {
-        VBOXSTRICTRC rcStrict = GIMHypercall(pVCpu, IEM_GET_CTX(pVCpu));
+        NOREF(uDisOpcode);
+        VBOXSTRICTRC rcStrict = GIMHypercallEx(pVCpu, IEM_GET_CTX(pVCpu), uDisOpcode, cbInstr);
         if (RT_SUCCESS(rcStrict))
         {
@@ -1145,5 +1146,5 @@
 
     /* Join forces with vmcall. */
-    return IEM_CIMPL_CALL_0(iemCImpl_Hypercall);
+    return IEM_CIMPL_CALL_1(iemCImpl_Hypercall, OP_VMMCALL);
 }
 
Index: /trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h	(revision 72468)
+++ /trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h	(revision 72469)
@@ -25,5 +25,5 @@
 
     /* Join forces with vmmcall. */
-    return IEM_CIMPL_CALL_0(iemCImpl_Hypercall);
+    return IEM_CIMPL_CALL_1(iemCImpl_Hypercall, OP_VMCALL);
 }
 
Index: /trunk/src/VBox/VMM/VMMAll/VMMAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/VMMAll.cpp	(revision 72468)
+++ /trunk/src/VBox/VMM/VMMAll/VMMAll.cpp	(revision 72469)
@@ -396,54 +396,2 @@
 }
 
-
-/**
- * Patches the instructions necessary for making a hypercall to the hypervisor.
- * Used by GIM.
- *
- * @returns VBox status code.
- * @param   pVM         The cross context VM structure.
- * @param   pvBuf       The buffer in the hypercall page(s) to be patched.
- * @param   cbBuf       The size of the buffer.
- * @param   pcbWritten  Where to store the number of bytes patched. This
- *                      is reliably updated only when this function returns
- *                      VINF_SUCCESS.
- */
-VMM_INT_DECL(int) VMMPatchHypercall(PVM pVM, void *pvBuf, size_t cbBuf, size_t *pcbWritten)
-{
-    AssertReturn(pvBuf, VERR_INVALID_POINTER);
-    AssertReturn(pcbWritten, VERR_INVALID_POINTER);
-
-    CPUMCPUVENDOR enmHostCpu = CPUMGetHostCpuVendor(pVM);
-    switch (enmHostCpu)
-    {
-        case CPUMCPUVENDOR_AMD:
-        {
-            uint8_t abHypercall[] = { 0x0F, 0x01, 0xD9 };   /* VMMCALL */
-            if (RT_LIKELY(cbBuf >= sizeof(abHypercall)))
-            {
-                memcpy(pvBuf, abHypercall, sizeof(abHypercall));
-                *pcbWritten = sizeof(abHypercall);
-                return VINF_SUCCESS;
-            }
-            return VERR_BUFFER_OVERFLOW;
-        }
-
-        case CPUMCPUVENDOR_INTEL:
-        case CPUMCPUVENDOR_VIA:
-        {
-            uint8_t abHypercall[] = { 0x0F, 0x01, 0xC1 };   /* VMCALL */
-            if (RT_LIKELY(cbBuf >= sizeof(abHypercall)))
-            {
-                memcpy(pvBuf, abHypercall, sizeof(abHypercall));
-                *pcbWritten = sizeof(abHypercall);
-                return VINF_SUCCESS;
-            }
-            return VERR_BUFFER_OVERFLOW;
-        }
-
-        default:
-            AssertFailed();
-            return VERR_UNSUPPORTED_CPU;
-    }
-}
-
Index: /trunk/src/VBox/VMM/VMMR3/GIMHv.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/GIMHv.cpp	(revision 72468)
+++ /trunk/src/VBox/VMM/VMMR3/GIMHv.cpp	(revision 72469)
@@ -1521,10 +1521,10 @@
      * Patch the hypercall-page.
      */
-    size_t cbWritten = 0;
-    int rc = VMMPatchHypercall(pVM, pvHypercallPage, PAGE_SIZE, &cbWritten);
+    size_t cbHypercall = 0;
+    int rc = GIMQueryHypercallOpcodeBytes(pVM, pvHypercallPage, PAGE_SIZE, &cbHypercall, NULL /*puDisOpcode*/);
     if (   RT_SUCCESS(rc)
-        && cbWritten < PAGE_SIZE)
-    {
-        uint8_t *pbLast = (uint8_t *)pvHypercallPage + cbWritten;
+        && cbHypercall < PAGE_SIZE)
+    {
+        uint8_t *pbLast = (uint8_t *)pvHypercallPage + cbHypercall;
         *pbLast = 0xc3;  /* RET */
 
@@ -1543,5 +1543,5 @@
         if (rc == VINF_SUCCESS)
             rc = VERR_GIM_OPERATION_FAILED;
-        LogRel(("GIM: HyperV: VMMPatchHypercall failed. rc=%Rrc cbWritten=%u\n", rc, cbWritten));
+        LogRel(("GIM: HyperV: VMMPatchHypercall failed. rc=%Rrc cbHypercall=%u\n", rc, cbHypercall));
     }
 
Index: /trunk/src/VBox/VMM/VMMR3/GIMKvm.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/GIMKvm.cpp	(revision 72468)
+++ /trunk/src/VBox/VMM/VMMR3/GIMKvm.cpp	(revision 72469)
@@ -158,23 +158,14 @@
     /*
      * Setup hypercall and #UD handling.
+     * Note! We always need to trap VMCALL/VMMCALL hypercall using #UDs for raw-mode VMs.
      */
     for (VMCPUID i = 0; i < pVM->cCpus; i++)
         EMSetHypercallInstructionsEnabled(&pVM->aCpus[i], true);
 
-    if (ASMIsAmdCpu())
-    {
-        pKvm->fTrapXcptUD   = true;
-        pKvm->uOpCodeNative = OP_VMMCALL;
-    }
-    else
-    {
-        Assert(ASMIsIntelCpu() || ASMIsViaCentaurCpu());
-        pKvm->fTrapXcptUD   = false;
-        pKvm->uOpCodeNative = OP_VMCALL;
-    }
-
-    /* We always need to trap VMCALL/VMMCALL hypercall using #UDs for raw-mode VMs. */
-    if (VM_IS_RAW_MODE_ENABLED(pVM))
-        pKvm->fTrapXcptUD = true;
+    size_t cbHypercall = 0;
+    rc = GIMQueryHypercallOpcodeBytes(pVM, pKvm->abOpcodeNative, sizeof(pKvm->abOpcodeNative), &cbHypercall, &pKvm->uOpcodeNative);
+    AssertLogRelRCReturn(rc, rc);
+    AssertLogRelReturn(cbHypercall == sizeof(pKvm->abOpcodeNative), VERR_GIM_IPE_1);
+    pKvm->fTrapXcptUD = pKvm->uOpcodeNative != OP_VMCALL || VM_IS_RAW_MODE_ENABLED(pVM);
 
     return VINF_SUCCESS;
Index: /trunk/src/VBox/VMM/include/GIMHvInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/GIMHvInternal.h	(revision 72468)
+++ /trunk/src/VBox/VMM/include/GIMHvInternal.h	(revision 72469)
@@ -1368,5 +1368,5 @@
 VMM_INT_DECL(VBOXSTRICTRC)      gimHvXcptUD(PVMCPU pVCpu, PCPUMCTX pCtx, PDISCPUSTATE pDis, uint8_t *pcbInstr);
 VMM_INT_DECL(VBOXSTRICTRC)      gimHvHypercall(PVMCPU pVCpu, PCPUMCTX pCtx);
-VMM_INT_DECL(VBOXSTRICTRC)      gimHvExecHypercallInstr(PVMCPU pVCpu, PCPUMCTX pCtx, PDISCPUSTATE pDis);
+VMM_INT_DECL(VBOXSTRICTRC)      gimHvHypercallEx(PVMCPU pVCpu, PCPUMCTX pCtx, unsigned uDisOpcode, uint8_t cbInstr);
 VMM_INT_DECL(VBOXSTRICTRC)      gimHvReadMsr(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t *puValue);
 VMM_INT_DECL(VBOXSTRICTRC)      gimHvWriteMsr(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t uRawValue);
Index: /trunk/src/VBox/VMM/include/GIMKvmInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/GIMKvmInternal.h	(revision 72468)
+++ /trunk/src/VBox/VMM/include/GIMKvmInternal.h	(revision 72469)
@@ -200,5 +200,9 @@
     bool                        fTrapXcptUD;
     /** Disassembler opcode of hypercall instruction native for this host CPU. */
-    uint16_t                    uOpCodeNative;
+    uint16_t                    uOpcodeNative;
+    /** Native hypercall opcode bytes.  Use for replacing. */
+    uint8_t                     abOpcodeNative[3];
+    /** Alignment padding. */
+    uint8_t                     abPadding[5];
     /** The TSC frequency (in HZ) reported to the guest. */
     uint64_t                    cTscTicksPerSecond;
@@ -266,5 +270,5 @@
 VMM_INT_DECL(bool)              gimKvmShouldTrapXcptUD(PVMCPU pVCpu);
 VMM_INT_DECL(VBOXSTRICTRC)      gimKvmXcptUD(PVMCPU pVCpu, PCPUMCTX pCtx, PDISCPUSTATE pDis, uint8_t *pcbInstr);
-VMM_INT_DECL(VBOXSTRICTRC)      gimKvmExecHypercallInstr(PVMCPU pVCpu, PCPUMCTX pCtx, PDISCPUSTATE pDis);
+VMM_INT_DECL(VBOXSTRICTRC)      gimKvmHypercallEx(PVMCPU pVCpu, PCPUMCTX pCtx, unsigned uDisOpcode, uint8_t cbInstr);
 
 
