[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: |
Paolo Bonzini |
Subject: |
Re: [Qemu-devel] [PATCH v3 2/3] WHPX: dynamically load WHP libraries |
Date: |
Wed, 6 Jun 2018 15:41:01 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.7.0 |
On 05/06/2018 01:06, Justin Terry (VM) wrote:
> 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?
My mistake, I'll add it.
Paolo
> 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
>