qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH v3 2/3] WHPX: dynamically load WHP libraries


From: Justin Terry (VM)
Subject: Re: [Qemu-devel] [PATCH v3 2/3] WHPX: dynamically load WHP libraries
Date: Mon, 4 Jun 2018 23:06:20 +0000

Paolo - I saw that this merged with commit: 
327fccb288976f95808efa968082fc9d4a9ced84 but it seems to be missing 
whp-dispatch.h so now the build is failing. Any idea how this file failed to 
get included?

Thanks,
Justin

> -----Original Message-----
> From: address@hidden <address@hidden>
> Sent: Friday, May 25, 2018 7:02 AM
> To: address@hidden
> Cc: Lucian Petrut <address@hidden>; apilotti
> <address@hidden>; Justin Terry (VM)
> <address@hidden>
> Subject: [PATCH v3 2/3] WHPX: dynamically load WHP libraries
> 
> From: Lucian Petrut <address@hidden>
> 
> We're currently linking against import libraries of the WHP DLLs.
> 
> By dynamically loading the libraries, we ensure that QEMU will work on
> previous Windows versions, where the WHP DLLs will be missing (assuming
> that WHP is not requested).
> 
> Also, we're simplifying the build process, as we no longer require the import
> libraries.
> 
> Signed-off-by: Alessandro Pilotti <address@hidden>
> Signed-off-by: Justin Terry (VM) <address@hidden>
> Signed-off-by: Lucian Petrut <address@hidden>
> ---
>  configure                  |  15 +--
>  target/i386/whp-dispatch.h |  56 ++++++++++++
>  target/i386/whpx-all.c     | 222 ++++++++++++++++++++++++++++++--------
> -------
>  3 files changed, 206 insertions(+), 87 deletions(-)  create mode 100644
> target/i386/whp-dispatch.h
> 
> diff --git a/configure b/configure
> index a8498ab..99b4a28 100755
> --- a/configure
> +++ b/configure
> @@ -2524,20 +2524,7 @@ fi
>  ##########################################
>  # Windows Hypervisor Platform accelerator (WHPX) check  if test "$whpx" !=
> "no" ; then
> -    cat > $TMPC << EOF
> -#include <windows.h>
> -#include <WinHvPlatform.h>
> -#include <WinHvEmulation.h>
> -int main(void) {
> -    WHV_CAPABILITY whpx_cap;
> -    UINT32 writtenSize;
> -    WHvGetCapability(WHvCapabilityCodeFeatures, &whpx_cap,
> sizeof(whpx_cap),
> -                     &writtenSize);
> -    return 0;
> -}
> -EOF
> -    if compile_prog "" "-lWinHvPlatform -lWinHvEmulation" ; then
> -        libs_softmmu="$libs_softmmu -lWinHvPlatform -lWinHvEmulation"
> +    if check_include "WinHvPlatform.h" && check_include
> + "WinHvEmulation.h"; then
>          whpx="yes"
>      else
>          if test "$whpx" = "yes"; then
> diff --git a/target/i386/whp-dispatch.h b/target/i386/whp-dispatch.h new file
> mode 100644 index 0000000..d8d3485
> --- /dev/null
> +++ b/target/i386/whp-dispatch.h
> @@ -0,0 +1,56 @@
> +#include "windows.h"
> +#include <stdbool.h>
> +
> +#include <WinHvPlatform.h>
> +#include <WinHvEmulation.h>
> +
> +#ifndef WHP_DISPATCH_H
> +#define WHP_DISPATCH_H
> +
> +
> +#define LIST_WINHVPLATFORM_FUNCTIONS(X) \
> +  X(HRESULT, WHvGetCapability, (WHV_CAPABILITY_CODE CapabilityCode,
> +VOID* CapabilityBuffer, UINT32 CapabilityBufferSizeInBytes, UINT32*
> +WrittenSizeInBytes)) \
> +  X(HRESULT, WHvCreatePartition, (WHV_PARTITION_HANDLE* Partition)) \
> +  X(HRESULT, WHvSetupPartition, (WHV_PARTITION_HANDLE Partition)) \
> +  X(HRESULT, WHvDeletePartition, (WHV_PARTITION_HANDLE Partition)) \
> +  X(HRESULT, WHvGetPartitionProperty, (WHV_PARTITION_HANDLE
> Partition,
> +WHV_PARTITION_PROPERTY_CODE PropertyCode, VOID* PropertyBuffer,
> UINT32
> +PropertyBufferSizeInBytes, UINT32* WrittenSizeInBytes)) \
> +  X(HRESULT, WHvSetPartitionProperty, (WHV_PARTITION_HANDLE
> Partition,
> +WHV_PARTITION_PROPERTY_CODE PropertyCode, const VOID*
> PropertyBuffer,
> +UINT32 PropertyBufferSizeInBytes)) \
> +  X(HRESULT, WHvMapGpaRange, (WHV_PARTITION_HANDLE Partition,
> VOID*
> +SourceAddress, WHV_GUEST_PHYSICAL_ADDRESS GuestAddress, UINT64
> +SizeInBytes, WHV_MAP_GPA_RANGE_FLAGS Flags)) \
> +  X(HRESULT, WHvUnmapGpaRange, (WHV_PARTITION_HANDLE Partition,
> +WHV_GUEST_PHYSICAL_ADDRESS GuestAddress, UINT64 SizeInBytes)) \
> +  X(HRESULT, WHvTranslateGva, (WHV_PARTITION_HANDLE Partition,
> UINT32
> +VpIndex, WHV_GUEST_VIRTUAL_ADDRESS Gva,
> WHV_TRANSLATE_GVA_FLAGS
> +TranslateFlags, WHV_TRANSLATE_GVA_RESULT* TranslationResult,
> +WHV_GUEST_PHYSICAL_ADDRESS* Gpa)) \
> +  X(HRESULT, WHvCreateVirtualProcessor, (WHV_PARTITION_HANDLE
> +Partition, UINT32 VpIndex, UINT32 Flags)) \
> +  X(HRESULT, WHvDeleteVirtualProcessor, (WHV_PARTITION_HANDLE
> +Partition, UINT32 VpIndex)) \
> +  X(HRESULT, WHvRunVirtualProcessor, (WHV_PARTITION_HANDLE
> Partition,
> +UINT32 VpIndex, VOID* ExitContext, UINT32 ExitContextSizeInBytes)) \
> +  X(HRESULT, WHvCancelRunVirtualProcessor, (WHV_PARTITION_HANDLE
> +Partition, UINT32 VpIndex, UINT32 Flags)) \
> +  X(HRESULT, WHvGetVirtualProcessorRegisters,
> (WHV_PARTITION_HANDLE
> +Partition, UINT32 VpIndex, const WHV_REGISTER_NAME* RegisterNames,
> +UINT32 RegisterCount, WHV_REGISTER_VALUE* RegisterValues)) \
> +  X(HRESULT, WHvSetVirtualProcessorRegisters, (WHV_PARTITION_HANDLE
> +Partition, UINT32 VpIndex, const WHV_REGISTER_NAME* RegisterNames,
> +UINT32 RegisterCount, const WHV_REGISTER_VALUE* RegisterValues)) \
> +
> +
> +#define LIST_WINHVEMULATION_FUNCTIONS(X) \
> +  X(HRESULT, WHvEmulatorCreateEmulator, (const
> WHV_EMULATOR_CALLBACKS*
> +Callbacks, WHV_EMULATOR_HANDLE* Emulator)) \
> +  X(HRESULT, WHvEmulatorDestroyEmulator, (WHV_EMULATOR_HANDLE
> +Emulator)) \
> +  X(HRESULT, WHvEmulatorTryIoEmulation, (WHV_EMULATOR_HANDLE
> Emulator,
> +VOID* Context, const WHV_VP_EXIT_CONTEXT* VpContext, const
> +WHV_X64_IO_PORT_ACCESS_CONTEXT* IoInstructionContext,
> +WHV_EMULATOR_STATUS* EmulatorReturnStatus)) \
> +  X(HRESULT, WHvEmulatorTryMmioEmulation, (WHV_EMULATOR_HANDLE
> +Emulator, VOID* Context, const WHV_VP_EXIT_CONTEXT* VpContext,
> const
> +WHV_MEMORY_ACCESS_CONTEXT* MmioInstructionContext,
> WHV_EMULATOR_STATUS*
> +EmulatorReturnStatus)) \
> +
> +
> +#define WHP_DEFINE_TYPE(return_type, function_name, signature) \
> +    typedef return_type (WINAPI *function_name ## _t) signature;
> +
> +#define WHP_DECLARE_MEMBER(return_type, function_name, signature)
> \
> +    function_name ## _t function_name;
> +
> +/* Define function typedef */
> +LIST_WINHVPLATFORM_FUNCTIONS(WHP_DEFINE_TYPE)
> +LIST_WINHVEMULATION_FUNCTIONS(WHP_DEFINE_TYPE)
> +
> +struct WHPDispatch {
> +    LIST_WINHVPLATFORM_FUNCTIONS(WHP_DECLARE_MEMBER)
> +    LIST_WINHVEMULATION_FUNCTIONS(WHP_DECLARE_MEMBER)
> +};
> +
> +extern struct WHPDispatch whp_dispatch;
> +
> +bool init_whp_dispatch(void);
> +
> +
> +#endif /* WHP_DISPATCH_H */
> diff --git a/target/i386/whpx-all.c b/target/i386/whpx-all.c index
> ffc083e..280e2bc 100644
> --- a/target/i386/whpx-all.c
> +++ b/target/i386/whpx-all.c
> @@ -25,6 +25,7 @@
>  #include "qemu/queue.h"
>  #include "qapi/error.h"
>  #include "migration/blocker.h"
> +#include "whp-dispatch.h"
> 
>  #include <WinHvPlatform.h>
>  #include <WinHvEmulation.h>
> @@ -162,8 +163,11 @@ struct whpx_vcpu {
>  };
> 
>  static bool whpx_allowed;
> +static bool whp_dispatch_initialized;
> +static HMODULE hWinHvPlatform, hWinHvEmulation;
> 
>  struct whpx_state whpx_global;
> +struct WHPDispatch whp_dispatch;
> 
> 
>  /*
> @@ -357,10 +361,11 @@ static void whpx_set_registers(CPUState *cpu)
> 
>      assert(idx == RTL_NUMBER_OF(whpx_register_names));
> 
> -    hr = WHvSetVirtualProcessorRegisters(whpx->partition, cpu->cpu_index,
> -                                         whpx_register_names,
> -                                         RTL_NUMBER_OF(whpx_register_names),
> -                                         &vcxt.values[0]);
> +    hr = whp_dispatch.WHvSetVirtualProcessorRegisters(
> +        whpx->partition, cpu->cpu_index,
> +        whpx_register_names,
> +        RTL_NUMBER_OF(whpx_register_names),
> +        &vcxt.values[0]);
> 
>      if (FAILED(hr)) {
>          error_report("WHPX: Failed to set virtual processor context, 
> hr=%08lx",
> @@ -384,10 +389,11 @@ static void whpx_get_registers(CPUState *cpu)
> 
>      assert(cpu_is_stopped(cpu) || qemu_cpu_is_self(cpu));
> 
> -    hr = WHvGetVirtualProcessorRegisters(whpx->partition, cpu->cpu_index,
> -                                         whpx_register_names,
> -                                         RTL_NUMBER_OF(whpx_register_names),
> -                                         &vcxt.values[0]);
> +    hr = whp_dispatch.WHvGetVirtualProcessorRegisters(
> +        whpx->partition, cpu->cpu_index,
> +        whpx_register_names,
> +        RTL_NUMBER_OF(whpx_register_names),
> +        &vcxt.values[0]);
>      if (FAILED(hr)) {
>          error_report("WHPX: Failed to get virtual processor context, 
> hr=%08lx",
>                       hr);
> @@ -547,9 +553,10 @@ static HRESULT CALLBACK
> whpx_emu_getreg_callback(
>      struct whpx_state *whpx = &whpx_global;
>      CPUState *cpu = (CPUState *)ctx;
> 
> -    hr = WHvGetVirtualProcessorRegisters(whpx->partition, cpu->cpu_index,
> -                                         RegisterNames, RegisterCount,
> -                                         RegisterValues);
> +    hr = whp_dispatch.WHvGetVirtualProcessorRegisters(
> +        whpx->partition, cpu->cpu_index,
> +        RegisterNames, RegisterCount,
> +        RegisterValues);
>      if (FAILED(hr)) {
>          error_report("WHPX: Failed to get virtual processor registers,"
>                       " hr=%08lx", hr);
> @@ -568,9 +575,10 @@ static HRESULT CALLBACK
> whpx_emu_setreg_callback(
>      struct whpx_state *whpx = &whpx_global;
>      CPUState *cpu = (CPUState *)ctx;
> 
> -    hr = WHvSetVirtualProcessorRegisters(whpx->partition, cpu->cpu_index,
> -                                         RegisterNames, RegisterCount,
> -                                         RegisterValues);
> +    hr = whp_dispatch.WHvSetVirtualProcessorRegisters(
> +        whpx->partition, cpu->cpu_index,
> +        RegisterNames, RegisterCount,
> +        RegisterValues);
>      if (FAILED(hr)) {
>          error_report("WHPX: Failed to set virtual processor registers,"
>                       " hr=%08lx", hr);
> @@ -597,8 +605,8 @@ static HRESULT CALLBACK
> whpx_emu_translate_callback(
>      CPUState *cpu = (CPUState *)ctx;
>      WHV_TRANSLATE_GVA_RESULT res;
> 
> -    hr = WHvTranslateGva(whpx->partition, cpu->cpu_index,
> -                         Gva, TranslateFlags, &res, Gpa);
> +    hr = whp_dispatch.WHvTranslateGva(whpx->partition, cpu->cpu_index,
> +                                      Gva, TranslateFlags, &res, Gpa);
>      if (FAILED(hr)) {
>          error_report("WHPX: Failed to translate GVA, hr=%08lx", hr);
>      } else {
> @@ -623,16 +631,18 @@ static int whpx_handle_mmio(CPUState *cpu,
> WHV_MEMORY_ACCESS_CONTEXT *ctx)
>      struct whpx_vcpu *vcpu = get_whpx_vcpu(cpu);
>      WHV_EMULATOR_STATUS emu_status;
> 
> -    hr = WHvEmulatorTryMmioEmulation(vcpu->emulator, cpu,
> -                                     &vcpu->exit_ctx.VpContext, ctx,
> -                                     &emu_status);
> +    hr = whp_dispatch.WHvEmulatorTryMmioEmulation(
> +        vcpu->emulator, cpu,
> +        &vcpu->exit_ctx.VpContext, ctx,
> +        &emu_status);
>      if (FAILED(hr)) {
>          error_report("WHPX: Failed to parse MMIO access, hr=%08lx", hr);
>          return -1;
>      }
> 
>      if (!emu_status.EmulationSuccessful) {
> -        error_report("WHPX: Failed to emulate MMIO access");
> +        error_report("WHPX: Failed to emulate MMIO access with"
> +                     " EmulatorReturnStatus: %u", emu_status.AsUINT32);
>          return -1;
>      }
> 
> @@ -646,16 +656,18 @@ static int whpx_handle_portio(CPUState *cpu,
>      struct whpx_vcpu *vcpu = get_whpx_vcpu(cpu);
>      WHV_EMULATOR_STATUS emu_status;
> 
> -    hr = WHvEmulatorTryIoEmulation(vcpu->emulator, cpu,
> -                                   &vcpu->exit_ctx.VpContext, ctx,
> -                                   &emu_status);
> +    hr = whp_dispatch.WHvEmulatorTryIoEmulation(
> +        vcpu->emulator, cpu,
> +        &vcpu->exit_ctx.VpContext, ctx,
> +        &emu_status);
>      if (FAILED(hr)) {
>          error_report("WHPX: Failed to parse PortIO access, hr=%08lx", hr);
>          return -1;
>      }
> 
>      if (!emu_status.EmulationSuccessful) {
> -        error_report("WHPX: Failed to emulate PortMMIO access");
> +        error_report("WHPX: Failed to emulate PortIO access with"
> +                     " EmulatorReturnStatus: %u", emu_status.AsUINT32);
>          return -1;
>      }
> 
> @@ -770,8 +782,9 @@ static void whpx_vcpu_pre_run(CPUState *cpu)
>      qemu_mutex_unlock_iothread();
> 
>      if (reg_count) {
> -        hr = WHvSetVirtualProcessorRegisters(whpx->partition, cpu-
> >cpu_index,
> -                                             reg_names, reg_count, 
> reg_values);
> +        hr = whp_dispatch.WHvSetVirtualProcessorRegisters(
> +            whpx->partition, cpu->cpu_index,
> +            reg_names, reg_count, reg_values);
>          if (FAILED(hr)) {
>              error_report("WHPX: Failed to set interrupt state registers,"
>                           " hr=%08lx", hr); @@ -879,8 +892,9 @@ static int
> whpx_vcpu_run(CPUState *cpu)
>              whpx_vcpu_kick(cpu);
>          }
> 
> -        hr = WHvRunVirtualProcessor(whpx->partition, cpu->cpu_index,
> -                                    &vcpu->exit_ctx, sizeof(vcpu->exit_ctx));
> +        hr = whp_dispatch.WHvRunVirtualProcessor(
> +            whpx->partition, cpu->cpu_index,
> +            &vcpu->exit_ctx, sizeof(vcpu->exit_ctx));
> 
>          if (FAILED(hr)) {
>              error_report("WHPX: Failed to exec a virtual processor,"
> @@ -951,11 +965,11 @@ static int whpx_vcpu_run(CPUState *cpu)
>              reg_values[3].Reg64 = rdx;
>              reg_values[4].Reg64 = rbx;
> 
> -            hr = WHvSetVirtualProcessorRegisters(whpx->partition,
> -                                                 cpu->cpu_index,
> -                                                 reg_names,
> -                                                 reg_count,
> -                                                 reg_values);
> +            hr = whp_dispatch.WHvSetVirtualProcessorRegisters(
> +                whpx->partition, cpu->cpu_index,
> +                reg_names,
> +                reg_count,
> +                reg_values);
> 
>              if (FAILED(hr)) {
>                  error_report("WHPX: Failed to set CpuidAccess state 
> registers,"
> @@ -1067,8 +1081,8 @@ int whpx_init_vcpu(CPUState *cpu)
>          (void)migrate_add_blocker(whpx_migration_blocker, &local_error);
>          if (local_error) {
>              error_report_err(local_error);
> -            error_free(whpx_migration_blocker);
>              migrate_del_blocker(whpx_migration_blocker);
> +            error_free(whpx_migration_blocker);
>              return -EINVAL;
>          }
>      }
> @@ -1080,7 +1094,9 @@ int whpx_init_vcpu(CPUState *cpu)
>          return -ENOMEM;
>      }
> 
> -    hr = WHvEmulatorCreateEmulator(&whpx_emu_callbacks, &vcpu-
> >emulator);
> +    hr = whp_dispatch.WHvEmulatorCreateEmulator(
> +        &whpx_emu_callbacks,
> +        &vcpu->emulator);
>      if (FAILED(hr)) {
>          error_report("WHPX: Failed to setup instruction completion support,"
>                       " hr=%08lx", hr);
> @@ -1088,11 +1104,12 @@ int whpx_init_vcpu(CPUState *cpu)
>          return -EINVAL;
>      }
> 
> -    hr = WHvCreateVirtualProcessor(whpx->partition, cpu->cpu_index, 0);
> +    hr = whp_dispatch.WHvCreateVirtualProcessor(
> +        whpx->partition, cpu->cpu_index, 0);
>      if (FAILED(hr)) {
>          error_report("WHPX: Failed to create a virtual processor,"
>                       " hr=%08lx", hr);
> -        WHvEmulatorDestroyEmulator(vcpu->emulator);
> +        whp_dispatch.WHvEmulatorDestroyEmulator(vcpu->emulator);
>          g_free(vcpu);
>          return -EINVAL;
>      }
> @@ -1133,8 +1150,8 @@ void whpx_destroy_vcpu(CPUState *cpu)
>      struct whpx_state *whpx = &whpx_global;
>      struct whpx_vcpu *vcpu = get_whpx_vcpu(cpu);
> 
> -    WHvDeleteVirtualProcessor(whpx->partition, cpu->cpu_index);
> -    WHvEmulatorDestroyEmulator(vcpu->emulator);
> +    whp_dispatch.WHvDeleteVirtualProcessor(whpx->partition, cpu-
> >cpu_index);
> +    whp_dispatch.WHvEmulatorDestroyEmulator(vcpu->emulator);
>      g_free(cpu->hax_vcpu);
>      return;
>  }
> @@ -1142,7 +1159,8 @@ void whpx_destroy_vcpu(CPUState *cpu)  void
> whpx_vcpu_kick(CPUState *cpu)  {
>      struct whpx_state *whpx = &whpx_global;
> -    WHvCancelRunVirtualProcessor(whpx->partition, cpu->cpu_index, 0);
> +    whp_dispatch.WHvCancelRunVirtualProcessor(
> +        whpx->partition, cpu->cpu_index, 0);
>  }
> 
>  /*
> @@ -1168,17 +1186,17 @@ static void whpx_update_mapping(hwaddr
> start_pa, ram_addr_t size,
>      */
> 
>      if (add) {
> -        hr = WHvMapGpaRange(whpx->partition,
> -                            host_va,
> -                            start_pa,
> -                            size,
> -                            (WHvMapGpaRangeFlagRead |
> -                             WHvMapGpaRangeFlagExecute |
> -                             (rom ? 0 : WHvMapGpaRangeFlagWrite)));
> +        hr = whp_dispatch.WHvMapGpaRange(whpx->partition,
> +                                         host_va,
> +                                         start_pa,
> +                                         size,
> +                                         (WHvMapGpaRangeFlagRead |
> +                                          WHvMapGpaRangeFlagExecute |
> +                                          (rom ? 0 :
> + WHvMapGpaRangeFlagWrite)));
>      } else {
> -        hr = WHvUnmapGpaRange(whpx->partition,
> -                              start_pa,
> -                              size);
> +        hr = whp_dispatch.WHvUnmapGpaRange(whpx->partition,
> +                                           start_pa,
> +                                           size);
>      }
> 
>      if (FAILED(hr)) {
> @@ -1292,18 +1310,24 @@ static int whpx_accel_init(MachineState *ms)
> 
>      whpx = &whpx_global;
> 
> +    if (!init_whp_dispatch()) {
> +        ret = -ENOSYS;
> +        goto error;
> +    }
> +
>      memset(whpx, 0, sizeof(struct whpx_state));
>      whpx->mem_quota = ms->ram_size;
> 
> -    hr = WHvGetCapability(WHvCapabilityCodeHypervisorPresent,
> &whpx_cap,
> -                          sizeof(whpx_cap), &whpx_cap_size);
> +    hr = whp_dispatch.WHvGetCapability(
> +        WHvCapabilityCodeHypervisorPresent, &whpx_cap,
> +        sizeof(whpx_cap), &whpx_cap_size);
>      if (FAILED(hr) || !whpx_cap.HypervisorPresent) {
>          error_report("WHPX: No accelerator found, hr=%08lx", hr);
>          ret = -ENOSPC;
>          goto error;
>      }
> 
> -    hr = WHvCreatePartition(&whpx->partition);
> +    hr = whp_dispatch.WHvCreatePartition(&whpx->partition);
>      if (FAILED(hr)) {
>          error_report("WHPX: Failed to create partition, hr=%08lx", hr);
>          ret = -EINVAL;
> @@ -1312,10 +1336,11 @@ static int whpx_accel_init(MachineState *ms)
> 
>      memset(&prop, 0, sizeof(WHV_PARTITION_PROPERTY));
>      prop.ProcessorCount = smp_cpus;
> -    hr = WHvSetPartitionProperty(whpx->partition,
> -                                 WHvPartitionPropertyCodeProcessorCount,
> -                                 &prop,
> -                                 sizeof(WHV_PARTITION_PROPERTY));
> +    hr = whp_dispatch.WHvSetPartitionProperty(
> +        whpx->partition,
> +        WHvPartitionPropertyCodeProcessorCount,
> +        &prop,
> +        sizeof(WHV_PARTITION_PROPERTY));
> 
>      if (FAILED(hr)) {
>          error_report("WHPX: Failed to set partition core count to %d,"
> @@ -1326,10 +1351,11 @@ static int whpx_accel_init(MachineState *ms)
> 
>      memset(&prop, 0, sizeof(WHV_PARTITION_PROPERTY));
>      prop.ExtendedVmExits.X64CpuidExit = 1;
> -    hr = WHvSetPartitionProperty(whpx->partition,
> -                                 WHvPartitionPropertyCodeExtendedVmExits,
> -                                 &prop,
> -                                 sizeof(WHV_PARTITION_PROPERTY));
> +    hr = whp_dispatch.WHvSetPartitionProperty(
> +        whpx->partition,
> +        WHvPartitionPropertyCodeExtendedVmExits,
> +        &prop,
> +        sizeof(WHV_PARTITION_PROPERTY));
> 
>      if (FAILED(hr)) {
>          error_report("WHPX: Failed to enable partition extended X64CpuidExit"
> @@ -1339,11 +1365,11 @@ static int whpx_accel_init(MachineState *ms)
>      }
> 
>      UINT32 cpuidExitList[] = {1};
> -    hr = WHvSetPartitionProperty(whpx->partition,
> -                                 WHvPartitionPropertyCodeCpuidExitList,
> -                                 cpuidExitList,
> -                                 RTL_NUMBER_OF(cpuidExitList) * 
> sizeof(UINT32));
> -
> +    hr = whp_dispatch.WHvSetPartitionProperty(
> +        whpx->partition,
> +        WHvPartitionPropertyCodeCpuidExitList,
> +        cpuidExitList,
> +        RTL_NUMBER_OF(cpuidExitList) * sizeof(UINT32));
>      if (FAILED(hr)) {
>          error_report("WHPX: Failed to set partition CpuidExitList hr=%08lx",
>                       hr);
> @@ -1360,11 +1386,11 @@ static int whpx_accel_init(MachineState *ms)
>      cpuidResultList[0].Ebx = signature[0];
>      cpuidResultList[0].Ecx = signature[1];
>      cpuidResultList[0].Edx = signature[2];
> -    hr = WHvSetPartitionProperty(whpx->partition,
> -                                 WHvPartitionPropertyCodeCpuidResultList,
> -                                 cpuidResultList,
> -                                 RTL_NUMBER_OF(cpuidResultList) *
> -                                    sizeof(WHV_X64_CPUID_RESULT));
> +    hr = whp_dispatch.WHvSetPartitionProperty(
> +        whpx->partition,
> +        WHvPartitionPropertyCodeCpuidResultList,
> +        cpuidResultList,
> +        RTL_NUMBER_OF(cpuidResultList) *
> sizeof(WHV_X64_CPUID_RESULT));
>      if (FAILED(hr)) {
>          error_report("WHPX: Failed to set partition CpuidResultList 
> hr=%08lx",
>                       hr);
> @@ -1372,7 +1398,7 @@ static int whpx_accel_init(MachineState *ms)
>          goto error;
>      }
> 
> -    hr = WHvSetupPartition(whpx->partition);
> +    hr = whp_dispatch.WHvSetupPartition(whpx->partition);
>      if (FAILED(hr)) {
>          error_report("WHPX: Failed to setup partition, hr=%08lx", hr);
>          ret = -EINVAL;
> @@ -1389,7 +1415,7 @@ static int whpx_accel_init(MachineState *ms)
>    error:
> 
>      if (NULL != whpx->partition) {
> -        WHvDeletePartition(whpx->partition);
> +        whp_dispatch.WHvDeletePartition(whpx->partition);
>          whpx->partition = NULL;
>      }
> 
> @@ -1421,4 +1447,54 @@ static void whpx_type_init(void)
>      type_register_static(&whpx_accel_type);
>  }
> 
> +bool init_whp_dispatch(void)
> +{
> +    const char *lib_name;
> +    HMODULE hLib;
> +
> +    if (whp_dispatch_initialized) {
> +        return true;
> +    }
> +
> +    #define WHP_LOAD_FIELD(return_type, function_name, signature) \
> +        whp_dispatch.function_name = \
> +            (function_name ## _t)GetProcAddress(hLib, #function_name); \
> +        if (!whp_dispatch.function_name) { \
> +            error_report("Could not load function %s from library %s.", \
> +                         #function_name, lib_name); \
> +            goto error; \
> +        } \
> +
> +    lib_name = "WinHvPlatform.dll";
> +    hWinHvPlatform = LoadLibrary(lib_name);
> +    if (!hWinHvPlatform) {
> +        error_report("Could not load library %s.", lib_name);
> +        goto error;
> +    }
> +    hLib = hWinHvPlatform;
> +    LIST_WINHVPLATFORM_FUNCTIONS(WHP_LOAD_FIELD)
> +
> +    lib_name = "WinHvEmulation.dll";
> +    hWinHvEmulation = LoadLibrary(lib_name);
> +    if (!hWinHvEmulation) {
> +        error_report("Could not load library %s.", lib_name);
> +        goto error;
> +    }
> +    hLib = hWinHvEmulation;
> +    LIST_WINHVEMULATION_FUNCTIONS(WHP_LOAD_FIELD)
> +
> +    whp_dispatch_initialized = true;
> +    return true;
> +
> +    error:
> +
> +    if (hWinHvPlatform) {
> +        FreeLibrary(hWinHvPlatform);
> +    }
> +    if (hWinHvEmulation) {
> +        FreeLibrary(hWinHvEmulation);
> +    }
> +    return false;
> +}
> +
>  type_init(whpx_type_init);
> --
> 2.7.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]