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

Re: [PATCH] Use direct hypercall instead of hypercall page


  • To: Owen Smith <owen.smith@xxxxxxxxxx>, win-pv-devel@xxxxxxxxxxxxxxxxxxxx
  • From: Tu Dinh <ngoc-tu.dinh@xxxxxxxxxx>
  • Date: Fri, 24 Apr 2026 13:52:43 +0200
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=vates.tech header.i="@vates.tech" header.h="From:Subject:Date:Message-ID:To:MIME-Version:Content-Type:In-Reply-To:References:Feedback-ID"
  • Delivery-date: Fri, 24 Apr 2026 11:52:54 +0000
  • Feedback-id: default:8631fc262581453bbf619ec5b2062170:Sweego
  • List-id: Developer list for the Windows PV Drivers subproject <win-pv-devel.lists.xenproject.org>

On 24/04/2026 11:17, Owen Smith wrote:
> XSA-466 "Xen hypercall page unsafe against speculative attacks"
> recommends that OSes avoid using the hypercall page, since that breaks
> the use of return thunks and CET IBT.
> 
> While Windows doesn't support return thunks or CET IBT, the current
> hypercall code uses a naked indirect call to call into the hypercall
> page. This call is not protected by Windows CFG, and cannot be patched
> by Windows's Retpoline implementation.
> 
> Convert the hypercall code to detect CPU vendor and use the appropriate
> hypercall instructions.
> 
> Ported from xenbus 2635e7c08ee8df3e3c1be427926a53fe1b345c96
> by Tu Dinh <ngoc-tu.dinh@xxxxxxxxxx>
> 
> Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx>

Reviewed-by: Tu Dinh <ngoc-tu.dinh@xxxxxxxxxx>

Thanks,

> ---
>   src/xencrsh/amd64/hypercall.asm | 109 ++++++++++++------
>   src/xencrsh/hvm.c               | 120 +-------------------
>   src/xencrsh/hypercall.h         |   6 +-
>   src/xencrsh/hypercall_stub.c    | 191 +++++++++++++++++++++++++++++++-
>   src/xencrsh/i386/hypercall.asm  | 119 +++++++++++++-------
>   5 files changed, 342 insertions(+), 203 deletions(-)
> 
> diff --git a/src/xencrsh/amd64/hypercall.asm b/src/xencrsh/amd64/hypercall.asm
> index 1ceda85..de430e7 100644
> --- a/src/xencrsh/amd64/hypercall.asm
> +++ b/src/xencrsh/amd64/hypercall.asm
> @@ -1,41 +1,78 @@
> -                page    ,132
> -                title   Hypercall Gates
> +                        page    ,132
> +                        title   Hypercall Thunks
>   
> -                .code
> +                        .code
>   
> -                extrn   Hypercall:qword
> +                        ; uintptr_t __stdcall hypercall2_vmcall(
> +                        ;     uint32_t    ord,
> +                        ;     uintptr_t   arg1,
> +                        ;     uintptr_t   arg2);
> +                        public hypercall2_vmcall
> +hypercall2_vmcall       proc
> +                        push    rdi
> +                        push    rsi
> +                        mov     eax, ecx                            ; ord
> +                        mov     rdi, rdx                            ; arg1
> +                        mov     rsi, r8                             ; arg2
> +                        vmcall
> +                        pop     rsi
> +                        pop     rdi
> +                        ret
> +hypercall2_vmcall       endp
>   
> -                ; uintptr_t __stdcall asm___hypercall2(uint32_t ord, 
> uintptr_t arg1, uintptr_t arg2);
> -                public asm___hypercall2
> -asm___hypercall2 proc
> -             push rdi
> -             push rsi
> -             mov rdi, rdx                            ; arg1
> -             mov rax, qword ptr [Hypercall]
> -             shl rcx, 5                              ; ord
> -             add rax, rcx
> -             mov rsi, r8                             ; arg2
> -             call rax
> -             pop rsi
> -             pop rdi
> -             ret
> -asm___hypercall2 endp
> +                        ; uintptr_t __stdcall hypercall2_vmmcall(
> +                        ;     uint32_t    ord,
> +                        ;     uintptr_t   arg1,
> +                        ;     uintptr_t   arg2);
> +                        public hypercall2_vmmcall
> +hypercall2_vmmcall      proc
> +                        push    rdi
> +                        push    rsi
> +                        mov     eax, ecx                            ; ord
> +                        mov     rdi, rdx                            ; arg1
> +                        mov     rsi, r8                             ; arg2
> +                        vmmcall
> +                        pop     rsi
> +                        pop     rdi
> +                        ret
> +hypercall2_vmmcall      endp
>   
> -                ; uintptr_t __stdcall asm___hypercall3(uint32_t ord, 
> uintptr_t arg1, uintptr_t arg2, uintptr_t arg3);
> -                public asm___hypercall3
> -asm___hypercall3 proc
> -             push rdi
> -             push rsi
> -             mov rdi, rdx                            ; arg1
> -             mov rax, qword ptr [Hypercall]
> -             shl rcx, 5                              ; ord
> -             add rax, rcx
> -             mov rsi, r8                             ; arg2
> -             mov rdx, r9                             ; arg3
> -             call rax
> -             pop rsi
> -             pop rdi
> -             ret
> -asm___hypercall3 endp
> +                        ; uintptr_t __stdcall hypercall3_vmcall(
> +                        ;     uint32_t    ord,
> +                        ;     uintptr_t   arg1,
> +                        ;     uintptr_t   arg2,
> +                        ;     uintptr_t   arg3);
> +                        public hypercall3_vmcall
> +hypercall3_vmcall       proc
> +                        push    rdi
> +                        push    rsi
> +                        mov     eax, ecx                            ; ord
> +                        mov     rdi, rdx                            ; arg1
> +                        mov     rsi, r8                             ; arg2
> +                        mov     rdx, r9                             ; arg3
> +                        vmcall
> +                        pop     rsi
> +                        pop     rdi
> +                        ret
> +hypercall3_vmcall       endp
>   
> -                end
> +                        ; uintptr_t __stdcall hypercall3_vmmcall(
> +                        ;     uint32_t    ord,
> +                        ;     uintptr_t   arg1,
> +                        ;     uintptr_t   arg2,
> +                        ;     uintptr_t   arg3);
> +                        public hypercall3_vmmcall
> +hypercall3_vmmcall      proc
> +                        push    rdi
> +                        push    rsi
> +                        mov     eax, ecx                            ; ord
> +                        mov     rdi, rdx                            ; arg1
> +                        mov     rsi, r8                             ; arg2
> +                        mov     rdx, r9                             ; arg3
> +                        vmmcall
> +                        pop     rsi
> +                        pop     rdi
> +                        ret
> +hypercall3_vmmcall      endp
> +
> +                        end
> diff --git a/src/xencrsh/hvm.c b/src/xencrsh/hvm.c
> index 04da4e3..82230ef 100644
> --- a/src/xencrsh/hvm.c
> +++ b/src/xencrsh/hvm.c
> @@ -50,22 +50,6 @@
>   #include "log.h"
>   #include "assert.h"
>   
> -#define MAXIMUM_HYPERCALL_PFN_COUNT 2
> -
> -#pragma code_seg("hypercall")
> -__declspec(allocate("hypercall"))
> -static UCHAR    __HypercallSection[(MAXIMUM_HYPERCALL_PFN_COUNT + 1) * 
> PAGE_SIZE];
> -
> -#define XEN_SIGNATURE   "XenVMMXenVMM"
> -
> -static ULONG            __BaseLeaf = 0x40000000;
> -static USHORT           __MajorVersion;
> -static USHORT           __MinorVersion;
> -static PFN_NUMBER       __Pfn[MAXIMUM_HYPERCALL_PFN_COUNT];
> -static ULONG            __PfnCount;
> -
> -PHYPERCALL_GATE         Hypercall;
> -
>   //#pragma code_seg("sharedinfo")
>   //__declspec(allocate("sharedinfo"))
>   //static UCHAR    __SharedInfoSection[(1 + 1) * PAGE_SIZE];
> @@ -95,102 +79,6 @@ fail:
>       return Status;
>   }
>   
> -static FORCEINLINE VOID
> -CpuId(
> -    IN  ULONG   Leaf,
> -    OUT PULONG  EAX OPTIONAL,
> -    OUT PULONG  EBX OPTIONAL,
> -    OUT PULONG  ECX OPTIONAL,
> -    OUT PULONG  EDX OPTIONAL
> -    )
> -{
> -    int         Value[4] = {0};
> -
> -    __cpuid(Value, Leaf);
> -
> -    if (EAX)
> -        *EAX = (ULONG)Value[0];
> -
> -    if (EBX)
> -        *EBX = (ULONG)Value[1];
> -
> -    if (ECX)
> -        *ECX = (ULONG)Value[2];
> -
> -    if (EDX)
> -        *EDX = (ULONG)Value[3];
> -}
> -
> -static FORCEINLINE NTSTATUS
> -__InitHypercallPage()
> -{
> -    ULONG       eax = 'DEAD';
> -    ULONG       ebx = 'DEAD';
> -    ULONG       ecx = 'DEAD';
> -    ULONG       edx = 'DEAD';
> -    ULONG_PTR   Index;
> -    ULONG       HypercallMsr;
> -
> -    NTSTATUS    Status;
> -
> -    Status = STATUS_UNSUCCESSFUL;
> -    for (;;) {
> -        CHAR Signature[13] = { 0 };
> -
> -        CpuId(__BaseLeaf, &eax, &ebx, &ecx, &edx);
> -        *((PULONG)(Signature + 0)) = ebx;
> -        *((PULONG)(Signature + 4)) = ecx;
> -        *((PULONG)(Signature + 8)) = edx;
> -
> -        if (strcmp(Signature, XEN_SIGNATURE) == 0 &&
> -            eax >= __BaseLeaf + 2)
> -            break;
> -
> -        __BaseLeaf += 0x100;
> -
> -        if (__BaseLeaf > 0x40000100)
> -            goto fail1;
> -    }
> -
> -    CpuId(__BaseLeaf + 1, &eax, NULL, NULL, NULL);
> -    __MajorVersion = (USHORT)(eax >> 16);
> -    __MinorVersion = (USHORT)(eax & 0xFFFF);
> -
> -    LogVerbose("XEN %d.%d\n", __MajorVersion, __MinorVersion);
> -    LogVerbose("INTERFACE 0x%08x\n", __XEN_INTERFACE_VERSION__);
> -
> -    if ((ULONG_PTR)__HypercallSection & (PAGE_SIZE - 1))
> -        Hypercall = (PVOID)(((ULONG_PTR)__HypercallSection + PAGE_SIZE - 1) 
> & ~(PAGE_SIZE - 1));
> -    else
> -        Hypercall = (PVOID)__HypercallSection;
> -
> -    ASSERT3U(((ULONG_PTR)Hypercall & (PAGE_SIZE - 1)), ==, 0);
> -
> -    for (Index = 0; Index < MAXIMUM_HYPERCALL_PFN_COUNT; Index++) {
> -        PHYSICAL_ADDRESS    PhysicalAddress;
> -
> -        PhysicalAddress = MmGetPhysicalAddress((PUCHAR)Hypercall + (Index << 
> PAGE_SHIFT));
> -        __Pfn[Index] = (PFN_NUMBER)(PhysicalAddress.QuadPart >> PAGE_SHIFT);
> -    }
> -
> -    CpuId(__BaseLeaf + 2, &eax, &ebx, NULL, NULL);
> -    __PfnCount = eax;
> -    ASSERT(__PfnCount <= MAXIMUM_HYPERCALL_PFN_COUNT);
> -    HypercallMsr = ebx;
> -
> -    for (Index = 0; Index < __PfnCount; Index++) {
> -        LogVerbose("HypercallPfn[%d]: %p\n", Index, (PVOID)__Pfn[Index]);
> -        __writemsr(HypercallMsr, (ULONG64)__Pfn[Index] << PAGE_SHIFT);
> -    }
> -
> -    return STATUS_SUCCESS;
> -
> -fail1:
> -    LogError("fail1 (%08x)", Status);
> -
> -    return Status;
> -}
> -
>   //static NTSTATUS
>   //__InitSharedInfo()
>   //{
> @@ -235,7 +123,7 @@ HvmInitialize()
>   {
>       NTSTATUS    Status;
>   
> -    Status = __InitHypercallPage();
> +    Status = HypercallInitialize();
>       if (!NT_SUCCESS(Status))
>           goto fail;
>   
> @@ -258,12 +146,6 @@ fail:
>   VOID
>   HvmTerminate()
>   {
> -    ULONG Index;
> -
> -    Hypercall = NULL;
> -    for (Index = 0; Index < MAXIMUM_HYPERCALL_PFN_COUNT; ++Index) {
> -        __Pfn[Index] = 0;
> -    }
>       //SharedInfo = NULL;
>   }
>   
> diff --git a/src/xencrsh/hypercall.h b/src/xencrsh/hypercall.h
> index 762ecf8..6b055fa 100644
> --- a/src/xencrsh/hypercall.h
> +++ b/src/xencrsh/hypercall.h
> @@ -35,8 +35,10 @@
>   
>   #include "driver.h"
>   
> -typedef UCHAR           HYPERCALL_GATE[32];
> -typedef HYPERCALL_GATE  *PHYPERCALL_GATE;
> +extern NTSTATUS
> +HypercallInitialize(
> +    VOID
> +    );
>   
>   extern ULONG_PTR
>   ___Hypercall2(
> diff --git a/src/xencrsh/hypercall_stub.c b/src/xencrsh/hypercall_stub.c
> index 1741850..5183f58 100644
> --- a/src/xencrsh/hypercall_stub.c
> +++ b/src/xencrsh/hypercall_stub.c
> @@ -32,16 +32,164 @@
>   
>   #include <wdm.h>
>   #include <xenvbd-storport.h>
> -
> +#include <intrin.h>
>   
>   #include <xen-version.h>
>   #include <xen\xen-compat.h>
>            
>   #include <xen-types.h>
>   
> +#include "log.h"
> +#include "assert.h"
> +
>   #include "hypercall.h"
>   
> -extern uintptr_t __stdcall asm___hypercall2(uint32_t ord, uintptr_t arg1, 
> uintptr_t arg2);
> +typedef enum _HYPERCALL_INSTRUCTION {
> +    HYPERCALL_INSTRUCTION_UNKNOWN,
> +    HYPERCALL_INSTRUCTION_VMCALL,
> +    HYPERCALL_INSTRUCTION_VMMCALL,
> +} HYPERCALL_INSTRUCTION;
> +
> +typedef struct _CPU_VENDOR_DATA {
> +    ULONG                   EBX;
> +    ULONG                   ECX;
> +    ULONG                   EDX;
> +    HYPERCALL_INSTRUCTION   Instruction;
> +} CPU_VENDOR_DATA;
> +
> +static const CPU_VENDOR_DATA    HypercallVendorData[] = {
> +    // Note that the vendor data goes EBX-ECX-EDX
> +    {
> +        // "GenuineIntel"
> +        0x756E6547, 0x6C65746E, 0x49656E69,
> +        HYPERCALL_INSTRUCTION_VMCALL
> +    },
> +    {
> +        // "AuthenticAMD"
> +        0x68747541, 0x444D4163, 0x69746E65,
> +        HYPERCALL_INSTRUCTION_VMMCALL
> +    },
> +    {
> +        // "CentaurHauls"
> +        0x746E6543, 0x736C7561, 0x48727561,
> +        HYPERCALL_INSTRUCTION_VMCALL
> +    },
> +    {
> +        // "  Shanghai  "
> +        0x68532020, 0x20206961, 0x68676E61,
> +        HYPERCALL_INSTRUCTION_VMCALL
> +    },
> +    {
> +        // "HygonGenuine"
> +        0x6F677948, 0x656E6975, 0x6E65476E,
> +        HYPERCALL_INSTRUCTION_VMMCALL
> +    },
> +};
> +
> +static HYPERCALL_INSTRUCTION    HypercallInstruction
> +    = HYPERCALL_INSTRUCTION_UNKNOWN;
> +
> +static FORCEINLINE VOID
> +__CpuId(
> +    IN  ULONG   Leaf,
> +    OUT PULONG  EAX OPTIONAL,
> +    OUT PULONG  EBX OPTIONAL,
> +    OUT PULONG  ECX OPTIONAL,
> +    OUT PULONG  EDX OPTIONAL
> +    )
> +{
> +    int         Value[4] = {0};
> +
> +    __cpuid(Value, Leaf);
> +
> +    if (EAX)
> +        *EAX = (ULONG)Value[0];
> +
> +    if (EBX)
> +        *EBX = (ULONG)Value[1];
> +
> +    if (ECX)
> +        *ECX = (ULONG)Value[2];
> +
> +    if (EDX)
> +        *EDX = (ULONG)Value[3];
> +}
> +
> +NTSTATUS
> +HypercallInitialize(
> +    VOID
> +    )
> +{
> +    ULONG                   XenBaseLeaf = 0x40000000;
> +    ULONG                   EAX = 'DEAD';
> +    ULONG                   EBX = 'DEAD';
> +    ULONG                   ECX = 'DEAD';
> +    ULONG                   EDX = 'DEAD';
> +    HYPERCALL_INSTRUCTION   Instruction = HYPERCALL_INSTRUCTION_UNKNOWN;
> +    ULONG                   Index;
> +
> +    for (;;) {
> +        CHAR    Signature[13] = {0};
> +
> +        __CpuId(XenBaseLeaf, &EAX, &EBX, &ECX, &EDX);
> +        *((PULONG)(Signature + 0)) = EBX;
> +        *((PULONG)(Signature + 4)) = ECX;
> +        *((PULONG)(Signature + 8)) = EDX;
> +
> +        if (strcmp(Signature, "XenVMMXenVMM") == 0 &&
> +            EAX >= XenBaseLeaf + 2)
> +            break;
> +
> +        XenBaseLeaf += 0x100;
> +
> +        if (XenBaseLeaf > 0x40000100) {
> +            LogVerbose("XEN: BASE CPUID LEAF NOT FOUND\n");
> +            return STATUS_NOT_SUPPORTED;
> +        }
> +    }
> +
> +    LogVerbose("XEN: BASE CPUID LEAF @ %08x\n",
> +               XenBaseLeaf);
> +
> +    __CpuId(0, &EAX, &EBX, &ECX, &EDX);
> +    for (Index = 0; Index < ARRAYSIZE(HypercallVendorData); Index++) {
> +        const CPU_VENDOR_DATA   *CurrentData = &HypercallVendorData[Index];
> +
> +        if (EBX == CurrentData->EBX &&
> +            ECX == CurrentData->ECX &&
> +            EDX == CurrentData->EDX) {
> +            Instruction = CurrentData->Instruction;
> +            break;
> +        }
> +    }
> +
> +    if (Instruction == HYPERCALL_INSTRUCTION_UNKNOWN) {
> +        LogVerbose("XEN: CANNOT DETECT HYPERCALL INSTRUCTION\n");
> +        return STATUS_NOT_SUPPORTED;
> +    }
> +
> +    HypercallInstruction = Instruction;
> +    return STATUS_SUCCESS;
> +}
> +
> +extern uintptr_t __stdcall hypercall2_vmcall(
> +    uint32_t    ord,
> +    uintptr_t   arg1,
> +    uintptr_t   arg2);
> +extern uintptr_t __stdcall hypercall2_vmmcall(
> +    uint32_t    ord,
> +    uintptr_t   arg1,
> +    uintptr_t   arg2);
> +extern uintptr_t __stdcall hypercall3_vmcall(
> +    uint32_t    ord,
> +    uintptr_t   arg1,
> +    uintptr_t   arg2,
> +    uintptr_t   arg3);
> +extern uintptr_t __stdcall hypercall3_vmmcall(
> +    uint32_t    ord,
> +    uintptr_t   arg1,
> +    uintptr_t   arg2,
> +    uintptr_t   arg3);
>   
>   ULONG_PTR
>   ___Hypercall2(
> @@ -50,10 +198,24 @@ ___Hypercall2(
>       ULONG_PTR   Argument2
>       )
>   {
> -    return asm___hypercall2(Ordinal, Argument1, Argument2);
> -}
> +    ULONG_PTR   Value;
>   
> -extern uintptr_t __stdcall asm___hypercall3(uint32_t ord, uintptr_t arg1, 
> uintptr_t arg2, uintptr_t arg3);
> +    switch (HypercallInstruction) {
> +    case HYPERCALL_INSTRUCTION_VMCALL:
> +        Value = hypercall2_vmcall(Ordinal, Argument1, Argument2);
> +        break;
> +
> +    case HYPERCALL_INSTRUCTION_VMMCALL:
> +        Value = hypercall2_vmmcall(Ordinal, Argument1, Argument2);
> +        break;
> +
> +    default:
> +        Value = 0;
> +        BUG("NO HYPERCALL INSTRUCTION");
> +    }
> +
> +    return Value;
> +}
>   
>   ULONG_PTR
>   ___Hypercall3(
> @@ -63,5 +225,22 @@ ___Hypercall3(
>       ULONG_PTR   Argument3
>       )
>   {
> -    return asm___hypercall3(Ordinal, Argument1, Argument2, Argument3);
> +    ULONG_PTR   Value;
> +
> +    switch (HypercallInstruction) {
> +    case HYPERCALL_INSTRUCTION_VMCALL:
> +        Value = hypercall3_vmcall(Ordinal, Argument1, Argument2, Argument3);
> +        break;
> +
> +    case HYPERCALL_INSTRUCTION_VMMCALL:
> +        Value = hypercall3_vmmcall(Ordinal, Argument1, Argument2, Argument3);
> +        break;
> +
> +    default:
> +        Value = 0;
> +        BUG("NO HYPERCALL INSTRUCTION");
> +    }
> +
> +    return Value;
> +
>   }
> diff --git a/src/xencrsh/i386/hypercall.asm b/src/xencrsh/i386/hypercall.asm
> index 51094be..be68db3 100644
> --- a/src/xencrsh/i386/hypercall.asm
> +++ b/src/xencrsh/i386/hypercall.asm
> @@ -1,45 +1,84 @@
> -                page    ,132
> -                title   Hypercall Gates
> +                        page    ,132
> +                        title   Hypercall Thunks
>   
> -                .686p
> -                .model  FLAT
> -                .code
> +                        .686p
> +                        .model  FLAT
> +                        .code
>   
> -                extrn   _Hypercall:dword
> +                        ; uintptr_t __stdcall hypercall2_vmcall(
> +                        ;     uint32_t    ord,
> +                        ;     uintptr_t   arg1,
> +                        ;     uintptr_t   arg2);
> +                        public _hypercall2_vmcall@12
> +_hypercall2_vmcall@12   proc
> +                        push    ebp
> +                        mov     ebp, esp
> +                        push    ebx
> +                        mov     eax, [ebp + 08h]                ; ord
> +                        mov     ebx, [ebp + 0ch]                ; arg1
> +                        mov     ecx, [ebp + 10h]                ; arg2
> +                        vmcall
> +                        pop     ebx
> +                        leave
> +                        ret     0Ch
> +_hypercall2_vmcall@12   endp
>   
> -                ; uintptr_t __stdcall asm___hypercall2(uint32_t ord, 
> uintptr_t arg1, uintptr_t arg2);
> -                public _asm___hypercall2@12
> -_asm___hypercall2@12 proc
> -                push    ebp
> -                mov     ebp, esp
> -                push    ebx
> -                mov     eax, [ebp + 08h]                ; ord
> -                mov     ebx, [ebp + 0ch]                ; arg1
> -                mov     ecx, [ebp + 10h]                ; arg2
> -                shl     eax, 5
> -                add     eax, dword ptr [_Hypercall]
> -                call    eax
> -                pop     ebx
> -                leave
> -                ret     0Ch
> -_asm___hypercall2@12 endp
> +                        ; uintptr_t __stdcall hypercall2_vmmcall(
> +                        ;     uint32_t    ord,
> +                        ;     uintptr_t   arg1,
> +                        ;     uintptr_t   arg2);
> +                        public _hypercall2_vmmcall@12
> +_hypercall2_vmmcall@12  proc
> +                        push    ebp
> +                        mov     ebp, esp
> +                        push    ebx
> +                        mov     eax, [ebp + 08h]                ; ord
> +                        mov     ebx, [ebp + 0ch]                ; arg1
> +                        mov     ecx, [ebp + 10h]                ; arg2
> +                        vmmcall
> +                        pop     ebx
> +                        leave
> +                        ret     0Ch
> +_hypercall2_vmmcall@12  endp
>   
> -                ; uintptr_t __stdcall asm___hypercall3(uint32_t ord, 
> uintptr_t arg1, uintptr_t arg2, uintptr_t arg3);
> -                public _asm___hypercall3@16
> -_asm___hypercall3@16 proc
> -                push    ebp
> -                mov     ebp, esp
> -                push    ebx
> -                mov     eax, [ebp + 08h]                ; ord
> -                mov     ebx, [ebp + 0ch]                ; arg1
> -                mov     ecx, [ebp + 10h]                ; arg2
> -                mov     edx, [ebp + 14h]                ; arg3
> -                shl     eax, 5
> -                add     eax, dword ptr [_Hypercall]
> -                call    eax
> -                pop     ebx
> -                leave
> -                ret     10h
> -_asm___hypercall3@16 endp
> +                        ; uintptr_t __stdcall hypercall3_vmcall(
> +                        ;     uint32_t    ord,
> +                        ;     uintptr_t   arg1,
> +                        ;     uintptr_t   arg2,
> +                        ;     uintptr_t   arg3);
> +                        public _hypercall3_vmcall@16
> +_hypercall3_vmcall@16   proc
> +                        push    ebp
> +                        mov     ebp, esp
> +                        push    ebx
> +                        mov     eax, [ebp + 08h]                ; ord
> +                        mov     ebx, [ebp + 0ch]                ; arg1
> +                        mov     ecx, [ebp + 10h]                ; arg2
> +                        mov     edx, [ebp + 14h]                ; arg3
> +                        vmcall
> +                        pop     ebx
> +                        leave
> +                        ret     10h
> +_hypercall3_vmcall@16   endp
>   
> -                end
> +                        ; uintptr_t __stdcall hypercall3_vmmcall(
> +                        ;     uint32_t    ord,
> +                        ;     uintptr_t   arg1,
> +                        ;     uintptr_t   arg2,
> +                        ;     uintptr_t   arg3);
> +                        public _hypercall3_vmmcall@16
> +_hypercall3_vmmcall@16  proc
> +                        push    ebp
> +                        mov     ebp, esp
> +                        push    ebx
> +                        mov     eax, [ebp + 08h]                ; ord
> +                        mov     ebx, [ebp + 0ch]                ; arg1
> +                        mov     ecx, [ebp + 10h]                ; arg2
> +                        mov     edx, [ebp + 14h]                ; arg3
> +                        vmmcall
> +                        pop     ebx
> +                        leave
> +                        ret     10h
> +_hypercall3_vmmcall@16  endp
> +
> +                        end



--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech

 


Rackspace

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