aboutsummaryrefslogtreecommitdiff
path: root/target/i386
diff options
context:
space:
mode:
Diffstat (limited to 'target/i386')
-rw-r--r--target/i386/hax-all.c2
-rw-r--r--target/i386/hax-mem.c1
-rw-r--r--target/i386/hax-windows.c1
-rw-r--r--target/i386/hvf/hvf.c2
-rw-r--r--target/i386/hvf/x86_task.c3
-rw-r--r--target/i386/kvm.c3
-rw-r--r--target/i386/whpx-all.c262
7 files changed, 180 insertions, 94 deletions
diff --git a/target/i386/hax-all.c b/target/i386/hax-all.c
index cad7531406..d2e512856b 100644
--- a/target/i386/hax-all.c
+++ b/target/i386/hax-all.c
@@ -26,8 +26,6 @@
#include "qemu/osdep.h"
#include "cpu.h"
#include "exec/address-spaces.h"
-#include "exec/exec-all.h"
-#include "exec/ioport.h"
#include "qemu-common.h"
#include "hax-i386.h"
diff --git a/target/i386/hax-mem.c b/target/i386/hax-mem.c
index f46e85544d..5c37e94caa 100644
--- a/target/i386/hax-mem.c
+++ b/target/i386/hax-mem.c
@@ -11,7 +11,6 @@
#include "qemu/osdep.h"
#include "cpu.h"
#include "exec/address-spaces.h"
-#include "exec/exec-all.h"
#include "qemu/error-report.h"
#include "target/i386/hax-i386.h"
diff --git a/target/i386/hax-windows.c b/target/i386/hax-windows.c
index b1ac737ae4..5729ad9b48 100644
--- a/target/i386/hax-windows.c
+++ b/target/i386/hax-windows.c
@@ -12,7 +12,6 @@
#include "qemu/osdep.h"
#include "cpu.h"
-#include "exec/exec-all.h"
#include "hax-i386.h"
/*
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
index c36753954b..df69e6d0a7 100644
--- a/target/i386/hvf/hvf.c
+++ b/target/i386/hvf/hvf.c
@@ -65,8 +65,6 @@
#include <Hypervisor/hv_vmx.h>
#include "exec/address-spaces.h"
-#include "exec/exec-all.h"
-#include "exec/ioport.h"
#include "hw/i386/apic_internal.h"
#include "hw/boards.h"
#include "qemu/main-loop.h"
diff --git a/target/i386/hvf/x86_task.c b/target/i386/hvf/x86_task.c
index 4abf3db25e..7099335e89 100644
--- a/target/i386/hvf/x86_task.c
+++ b/target/i386/hvf/x86_task.c
@@ -26,9 +26,6 @@
#include <Hypervisor/hv.h>
#include <Hypervisor/hv_vmx.h>
-#include "exec/address-spaces.h"
-#include "exec/exec-all.h"
-#include "exec/ioport.h"
#include "hw/i386/apic_internal.h"
#include "hw/boards.h"
#include "qemu/main-loop.h"
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index 6511329d11..44f70733e7 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -40,7 +40,6 @@
#include "hw/i386/intel_iommu.h"
#include "hw/i386/x86-iommu.h"
-#include "exec/ioport.h"
#include "hw/pci/pci.h"
#include "hw/pci/msi.h"
#include "hw/pci/msix.h"
@@ -387,7 +386,7 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function,
ret &= ~(1U << KVM_FEATURE_PV_UNHALT);
}
} else if (function == KVM_CPUID_FEATURES && reg == R_EDX) {
- ret |= 1U << KVM_HINTS_DEDICATED;
+ ret |= 1U << KVM_HINTS_REALTIME;
found = 1;
}
diff --git a/target/i386/whpx-all.c b/target/i386/whpx-all.c
index 58435178a4..6b42096698 100644
--- a/target/i386/whpx-all.c
+++ b/target/i386/whpx-all.c
@@ -11,7 +11,6 @@
#include "qemu/osdep.h"
#include "cpu.h"
#include "exec/address-spaces.h"
-#include "exec/exec-all.h"
#include "exec/ioport.h"
#include "qemu-common.h"
#include "strings.h"
@@ -25,6 +24,7 @@
#include "qemu/queue.h"
#include "qapi/error.h"
#include "migration/blocker.h"
+#include "whp-dispatch.h"
#include <WinHvPlatform.h>
#include <WinHvEmulation.h>
@@ -160,8 +160,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;
/*
@@ -220,24 +223,31 @@ static void whpx_set_registers(CPUState *cpu)
struct whpx_vcpu *vcpu = get_whpx_vcpu(cpu);
struct CPUX86State *env = (CPUArchState *)(cpu->env_ptr);
X86CPU *x86_cpu = X86_CPU(cpu);
- struct whpx_register_set vcxt = {0};
+ struct whpx_register_set vcxt;
HRESULT hr;
- int idx = 0;
+ int idx;
+ int idx_next;
int i;
int v86, r86;
assert(cpu_is_stopped(cpu) || qemu_cpu_is_self(cpu));
+ memset(&vcxt, 0, sizeof(struct whpx_register_set));
+
v86 = (env->eflags & VM_MASK);
r86 = !(env->cr[0] & CR0_PE_MASK);
vcpu->tpr = cpu_get_apic_tpr(x86_cpu->apic_state);
vcpu->apic_base = cpu_get_apic_base(x86_cpu->apic_state);
+ idx = 0;
+
/* Indexes for first 16 registers match between HV and QEMU definitions */
- for (idx = 0; idx < CPU_NB_REGS64; idx += 1) {
- vcxt.values[idx].Reg64 = env->regs[idx];
+ idx_next = 16;
+ for (idx = 0; idx < CPU_NB_REGS; idx += 1) {
+ vcxt.values[idx].Reg64 = (uint64_t)env->regs[idx];
}
+ idx = idx_next;
/* Same goes for RIP and RFLAGS */
assert(whpx_register_names[idx] == WHvX64RegisterRip);
@@ -284,10 +294,12 @@ static void whpx_set_registers(CPUState *cpu)
/* 16 XMM registers */
assert(whpx_register_names[idx] == WHvX64RegisterXmm0);
- for (i = 0; i < 16; i += 1, idx += 1) {
+ idx_next = idx + 16;
+ for (i = 0; i < sizeof(env->xmm_regs) / sizeof(ZMMReg); i += 1, idx += 1) {
vcxt.values[idx].Reg128.Low64 = env->xmm_regs[i].ZMM_Q(0);
vcxt.values[idx].Reg128.High64 = env->xmm_regs[i].ZMM_Q(1);
}
+ idx = idx_next;
/* 8 FP registers */
assert(whpx_register_names[idx] == WHvX64RegisterFpMmx0);
@@ -355,10 +367,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",
@@ -377,24 +390,30 @@ static void whpx_get_registers(CPUState *cpu)
struct whpx_register_set vcxt;
uint64_t tpr, apic_base;
HRESULT hr;
- int idx = 0;
+ int idx;
+ int idx_next;
int i;
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);
}
+ idx = 0;
+
/* Indexes for first 16 registers match between HV and QEMU definitions */
- for (idx = 0; idx < CPU_NB_REGS64; idx += 1) {
+ idx_next = 16;
+ for (idx = 0; idx < CPU_NB_REGS; idx += 1) {
env->regs[idx] = vcxt.values[idx].Reg64;
}
+ idx = idx_next;
/* Same goes for RIP and RFLAGS */
assert(whpx_register_names[idx] == WHvX64RegisterRip);
@@ -441,10 +460,12 @@ static void whpx_get_registers(CPUState *cpu)
/* 16 XMM registers */
assert(whpx_register_names[idx] == WHvX64RegisterXmm0);
- for (i = 0; i < 16; i += 1, idx += 1) {
+ idx_next = idx + 16;
+ for (i = 0; i < sizeof(env->xmm_regs) / sizeof(ZMMReg); i += 1, idx += 1) {
env->xmm_regs[i].ZMM_Q(0) = vcxt.values[idx].Reg128.Low64;
env->xmm_regs[i].ZMM_Q(1) = vcxt.values[idx].Reg128.High64;
}
+ idx = idx_next;
/* 8 FP registers */
assert(whpx_register_names[idx] == WHvX64RegisterFpMmx0);
@@ -545,9 +566,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);
@@ -566,9 +588,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);
@@ -595,8 +618,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 {
@@ -621,16 +644,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;
}
@@ -644,16 +669,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;
}
@@ -687,11 +714,14 @@ static void whpx_vcpu_pre_run(CPUState *cpu)
X86CPU *x86_cpu = X86_CPU(cpu);
int irq;
uint8_t tpr;
- WHV_X64_PENDING_INTERRUPTION_REGISTER new_int = {0};
+ WHV_X64_PENDING_INTERRUPTION_REGISTER new_int;
UINT32 reg_count = 0;
- WHV_REGISTER_VALUE reg_values[3] = {0};
+ WHV_REGISTER_VALUE reg_values[3];
WHV_REGISTER_NAME reg_names[3];
+ memset(&new_int, 0, sizeof(new_int));
+ memset(reg_values, 0, sizeof(reg_values));
+
qemu_mutex_lock_iothread();
/* Inject NMI */
@@ -768,8 +798,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);
@@ -877,8 +908,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,"
@@ -912,11 +944,13 @@ static int whpx_vcpu_run(CPUState *cpu)
break;
case WHvRunVpExitReasonX64Cpuid: {
- WHV_REGISTER_VALUE reg_values[5] = {0};
+ WHV_REGISTER_VALUE reg_values[5];
WHV_REGISTER_NAME reg_names[5];
UINT32 reg_count = 5;
UINT64 rip, rax, rcx, rdx, rbx;
+ memset(reg_values, 0, sizeof(reg_values));
+
rip = vcpu->exit_ctx.VpContext.Rip +
vcpu->exit_ctx.VpContext.InstructionLength;
switch (vcpu->exit_ctx.CpuidAccess.Rax) {
@@ -949,11 +983,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,"
@@ -1065,8 +1099,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;
}
}
@@ -1078,7 +1112,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);
@@ -1086,11 +1122,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;
}
@@ -1131,8 +1168,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;
}
@@ -1140,7 +1177,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);
}
/*
@@ -1166,24 +1204,24 @@ 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)) {
error_report("WHPX: Failed to %s GPA range '%s' PA:%p, Size:%p bytes,"
" Host:%p, hr=%08lx",
(add ? "MAP" : "UNMAP"), name,
- (void *)start_pa, (void *)size, host_va, hr);
+ (void *)(uintptr_t)start_pa, (void *)size, host_va, hr);
}
}
@@ -1214,8 +1252,8 @@ static void whpx_process_section(MemoryRegionSection *section, int add)
host_va = (uintptr_t)memory_region_get_ram_ptr(mr)
+ section->offset_within_region + delta;
- whpx_update_mapping(start_pa, size, (void *)host_va, add,
- memory_region_is_rom(mr), mr->name);
+ whpx_update_mapping(start_pa, size, (void *)(uintptr_t)host_va, add,
+ memory_region_is_rom(mr), mr->name);
}
static void whpx_region_add(MemoryListener *listener,
@@ -1290,18 +1328,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;
@@ -1310,10 +1354,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,"
@@ -1324,10 +1369,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"
@@ -1337,11 +1383,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);
@@ -1349,7 +1395,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;
@@ -1366,7 +1412,7 @@ static int whpx_accel_init(MachineState *ms)
error:
if (NULL != whpx->partition) {
- WHvDeletePartition(whpx->partition);
+ whp_dispatch.WHvDeletePartition(whpx->partition);
whpx->partition = NULL;
}
@@ -1398,4 +1444,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);