diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2020-03-17 18:33:05 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2020-03-17 18:33:05 +0000 |
commit | d649689a8ecb2e276cc20d3af6d416e3c299cb17 (patch) | |
tree | 0e95f648151a0d24a2b44a07e2588d1f10809e96 /target | |
parent | cc818a2148c5f321bdeb8e5564bdb2914e824600 (diff) | |
parent | 32b9523ad5b44dea87792d5d8f71a87e8cc5803b (diff) |
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* Bugfixes all over the place
* get/set_uint cleanups (Felipe)
* Lock guard support (Stefan)
* MemoryRegion ownership cleanup (Philippe)
* AVX512 optimization for buffer_is_zero (Robert)
# gpg: Signature made Tue 17 Mar 2020 15:01:54 GMT
# gpg: using RSA key BFFBD25F78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full]
# gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [full]
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1
# Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83
* remotes/bonzini/tags/for-upstream: (62 commits)
hw/arm: Let devices own the MemoryRegion they create
hw/arm: Remove unnecessary memory_region_set_readonly() on ROM alias
hw/ppc/ppc405: Use memory_region_init_rom() with read-only regions
hw/arm/stm32: Use memory_region_init_rom() with read-only regions
hw/char: Let devices own the MemoryRegion they create
hw/riscv: Let devices own the MemoryRegion they create
hw/dma: Let devices own the MemoryRegion they create
hw/display: Let devices own the MemoryRegion they create
hw/core: Let devices own the MemoryRegion they create
scripts/cocci: Patch to let devices own their MemoryRegions
scripts/cocci: Patch to remove unnecessary memory_region_set_readonly()
scripts/cocci: Patch to detect potential use of memory_region_init_rom
hw/sparc: Use memory_region_init_rom() with read-only regions
hw/sh4: Use memory_region_init_rom() with read-only regions
hw/riscv: Use memory_region_init_rom() with read-only regions
hw/ppc: Use memory_region_init_rom() with read-only regions
hw/pci-host: Use memory_region_init_rom() with read-only regions
hw/net: Use memory_region_init_rom() with read-only regions
hw/m68k: Use memory_region_init_rom() with read-only regions
hw/display: Use memory_region_init_rom() with read-only regions
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target')
-rw-r--r-- | target/arm/cpu.c | 22 | ||||
-rw-r--r-- | target/i386/hax-posix.c | 33 | ||||
-rw-r--r-- | target/i386/hax-windows.c | 33 | ||||
-rw-r--r-- | target/i386/sev.c | 106 | ||||
-rw-r--r-- | target/i386/whp-dispatch.h | 9 | ||||
-rw-r--r-- | target/i386/whpx-all.c | 162 | ||||
-rw-r--r-- | target/s390x/ioinst.c | 2 |
7 files changed, 145 insertions, 222 deletions
diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 3623ecefbd..7fe367078c 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -1153,22 +1153,6 @@ static void arm_set_pmu(Object *obj, bool value, Error **errp) cpu->has_pmu = value; } -static void arm_get_init_svtor(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - ARMCPU *cpu = ARM_CPU(obj); - - visit_type_uint32(v, name, &cpu->init_svtor, errp); -} - -static void arm_set_init_svtor(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - ARMCPU *cpu = ARM_CPU(obj); - - visit_type_uint32(v, name, &cpu->init_svtor, errp); -} - unsigned int gt_cntfrq_period_ns(ARMCPU *cpu) { /* @@ -1288,9 +1272,9 @@ void arm_cpu_post_init(Object *obj) * a simple DEFINE_PROP_UINT32 for this because we want to permit * the property to be set after realize. */ - object_property_add(obj, "init-svtor", "uint32", - arm_get_init_svtor, arm_set_init_svtor, - NULL, NULL, &error_abort); + object_property_add_uint32_ptr(obj, "init-svtor", + &cpu->init_svtor, + OBJ_PROP_FLAG_READWRITE, &error_abort); } qdev_property_add_static(DEVICE(obj), &arm_cpu_cfgend_property); diff --git a/target/i386/hax-posix.c b/target/i386/hax-posix.c index a5426a6dac..3bad89f133 100644 --- a/target/i386/hax-posix.c +++ b/target/i386/hax-posix.c @@ -108,41 +108,12 @@ int hax_mod_version(struct hax_state *hax, struct hax_module_version *version) static char *hax_vm_devfs_string(int vm_id) { - char *name; - - if (vm_id > MAX_VM_ID) { - fprintf(stderr, "Too big VM id\n"); - return NULL; - } - -#define HAX_VM_DEVFS "/dev/hax_vm/vmxx" - name = g_strdup(HAX_VM_DEVFS); - if (!name) { - return NULL; - } - - snprintf(name, sizeof HAX_VM_DEVFS, "/dev/hax_vm/vm%02d", vm_id); - return name; + return g_strdup_printf("/dev/hax_vm/vm%02d", vm_id); } static char *hax_vcpu_devfs_string(int vm_id, int vcpu_id) { - char *name; - - if (vm_id > MAX_VM_ID || vcpu_id > MAX_VCPU_ID) { - fprintf(stderr, "Too big vm id %x or vcpu id %x\n", vm_id, vcpu_id); - return NULL; - } - -#define HAX_VCPU_DEVFS "/dev/hax_vmxx/vcpuxx" - name = g_strdup(HAX_VCPU_DEVFS); - if (!name) { - return NULL; - } - - snprintf(name, sizeof HAX_VCPU_DEVFS, "/dev/hax_vm%02d/vcpu%02d", - vm_id, vcpu_id); - return name; + return g_strdup_printf("/dev/hax_vm%02d/vcpu%02d", vm_id, vcpu_id); } int hax_host_create_vm(struct hax_state *hax, int *vmid) diff --git a/target/i386/hax-windows.c b/target/i386/hax-windows.c index 5729ad9b48..0ba488c468 100644 --- a/target/i386/hax-windows.c +++ b/target/i386/hax-windows.c @@ -185,41 +185,12 @@ int hax_mod_version(struct hax_state *hax, struct hax_module_version *version) static char *hax_vm_devfs_string(int vm_id) { - char *name; - - if (vm_id > MAX_VM_ID) { - fprintf(stderr, "Too big VM id\n"); - return NULL; - } - -#define HAX_VM_DEVFS "\\\\.\\hax_vmxx" - name = g_strdup(HAX_VM_DEVFS); - if (!name) { - return NULL; - } - - snprintf(name, sizeof HAX_VM_DEVFS, "\\\\.\\hax_vm%02d", vm_id); - return name; + return g_strdup_printf("/dev/hax_vm/vm%02d", vm_id); } static char *hax_vcpu_devfs_string(int vm_id, int vcpu_id) { - char *name; - - if (vm_id > MAX_VM_ID || vcpu_id > MAX_VCPU_ID) { - fprintf(stderr, "Too big vm id %x or vcpu id %x\n", vm_id, vcpu_id); - return NULL; - } - -#define HAX_VCPU_DEVFS "\\\\.\\hax_vmxx_vcpuxx" - name = g_strdup(HAX_VCPU_DEVFS); - if (!name) { - return NULL; - } - - snprintf(name, sizeof HAX_VCPU_DEVFS, "\\\\.\\hax_vm%02d_vcpu%02d", - vm_id, vcpu_id); - return name; + return g_strdup_printf("/dev/hax_vm%02d/vcpu%02d", vm_id, vcpu_id); } int hax_host_create_vm(struct hax_state *hax, int *vmid) diff --git a/target/i386/sev.c b/target/i386/sev.c index 024bb24e51..846018a12d 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -267,109 +267,21 @@ qsev_guest_class_init(ObjectClass *oc, void *data) } static void -qsev_guest_set_handle(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - QSevGuestInfo *sev = QSEV_GUEST_INFO(obj); - uint32_t value; - - visit_type_uint32(v, name, &value, errp); - sev->handle = value; -} - -static void -qsev_guest_set_policy(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - QSevGuestInfo *sev = QSEV_GUEST_INFO(obj); - uint32_t value; - - visit_type_uint32(v, name, &value, errp); - sev->policy = value; -} - -static void -qsev_guest_set_cbitpos(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - QSevGuestInfo *sev = QSEV_GUEST_INFO(obj); - uint32_t value; - - visit_type_uint32(v, name, &value, errp); - sev->cbitpos = value; -} - -static void -qsev_guest_set_reduced_phys_bits(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - QSevGuestInfo *sev = QSEV_GUEST_INFO(obj); - uint32_t value; - - visit_type_uint32(v, name, &value, errp); - sev->reduced_phys_bits = value; -} - -static void -qsev_guest_get_policy(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - uint32_t value; - QSevGuestInfo *sev = QSEV_GUEST_INFO(obj); - - value = sev->policy; - visit_type_uint32(v, name, &value, errp); -} - -static void -qsev_guest_get_handle(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - uint32_t value; - QSevGuestInfo *sev = QSEV_GUEST_INFO(obj); - - value = sev->handle; - visit_type_uint32(v, name, &value, errp); -} - -static void -qsev_guest_get_cbitpos(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - uint32_t value; - QSevGuestInfo *sev = QSEV_GUEST_INFO(obj); - - value = sev->cbitpos; - visit_type_uint32(v, name, &value, errp); -} - -static void -qsev_guest_get_reduced_phys_bits(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - uint32_t value; - QSevGuestInfo *sev = QSEV_GUEST_INFO(obj); - - value = sev->reduced_phys_bits; - visit_type_uint32(v, name, &value, errp); -} - -static void qsev_guest_init(Object *obj) { QSevGuestInfo *sev = QSEV_GUEST_INFO(obj); sev->sev_device = g_strdup(DEFAULT_SEV_DEVICE); sev->policy = DEFAULT_GUEST_POLICY; - object_property_add(obj, "policy", "uint32", qsev_guest_get_policy, - qsev_guest_set_policy, NULL, NULL, NULL); - object_property_add(obj, "handle", "uint32", qsev_guest_get_handle, - qsev_guest_set_handle, NULL, NULL, NULL); - object_property_add(obj, "cbitpos", "uint32", qsev_guest_get_cbitpos, - qsev_guest_set_cbitpos, NULL, NULL, NULL); - object_property_add(obj, "reduced-phys-bits", "uint32", - qsev_guest_get_reduced_phys_bits, - qsev_guest_set_reduced_phys_bits, NULL, NULL, NULL); + object_property_add_uint32_ptr(obj, "policy", &sev->policy, + OBJ_PROP_FLAG_READWRITE, NULL); + object_property_add_uint32_ptr(obj, "handle", &sev->handle, + OBJ_PROP_FLAG_READWRITE, NULL); + object_property_add_uint32_ptr(obj, "cbitpos", &sev->cbitpos, + OBJ_PROP_FLAG_READWRITE, NULL); + object_property_add_uint32_ptr(obj, "reduced-phys-bits", + &sev->reduced_phys_bits, + OBJ_PROP_FLAG_READWRITE, NULL); } /* sev guest info */ diff --git a/target/i386/whp-dispatch.h b/target/i386/whp-dispatch.h index 87d049ceab..e4695c349f 100644 --- a/target/i386/whp-dispatch.h +++ b/target/i386/whp-dispatch.h @@ -23,6 +23,12 @@ 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)) \ +/* + * These are supplemental functions that may not be present + * on all versions and are not critical for basic functionality. + */ +#define LIST_WINHVPLATFORM_FUNCTIONS_SUPPLEMENTAL(X) \ + X(HRESULT, WHvSuspendPartitionTime, (WHV_PARTITION_HANDLE Partition)) \ #define LIST_WINHVEMULATION_FUNCTIONS(X) \ X(HRESULT, WHvEmulatorCreateEmulator, (const WHV_EMULATOR_CALLBACKS* Callbacks, WHV_EMULATOR_HANDLE* Emulator)) \ @@ -40,10 +46,12 @@ /* Define function typedef */ LIST_WINHVPLATFORM_FUNCTIONS(WHP_DEFINE_TYPE) LIST_WINHVEMULATION_FUNCTIONS(WHP_DEFINE_TYPE) +LIST_WINHVPLATFORM_FUNCTIONS_SUPPLEMENTAL(WHP_DEFINE_TYPE) struct WHPDispatch { LIST_WINHVPLATFORM_FUNCTIONS(WHP_DECLARE_MEMBER) LIST_WINHVEMULATION_FUNCTIONS(WHP_DECLARE_MEMBER) + LIST_WINHVPLATFORM_FUNCTIONS_SUPPLEMENTAL(WHP_DECLARE_MEMBER) }; extern struct WHPDispatch whp_dispatch; @@ -53,6 +61,7 @@ bool init_whp_dispatch(void); typedef enum WHPFunctionList { WINHV_PLATFORM_FNS_DEFAULT, WINHV_EMULATION_FNS_DEFAULT, + WINHV_PLATFORM_FNS_SUPPLEMENTAL } WHPFunctionList; #endif /* WHP_DISPATCH_H */ diff --git a/target/i386/whpx-all.c b/target/i386/whpx-all.c index 683d49d217..c78baac6df 100644 --- a/target/i386/whpx-all.c +++ b/target/i386/whpx-all.c @@ -114,7 +114,6 @@ static const WHV_REGISTER_NAME whpx_register_names[] = { WHvX64RegisterXmmControlStatus, /* X64 MSRs */ - WHvX64RegisterTsc, WHvX64RegisterEfer, #ifdef TARGET_X86_64 WHvX64RegisterKernelGsBase, @@ -215,7 +214,44 @@ static SegmentCache whpx_seg_h2q(const WHV_X64_SEGMENT_REGISTER *hs) return qs; } -static void whpx_set_registers(CPUState *cpu) +static int whpx_set_tsc(CPUState *cpu) +{ + struct CPUX86State *env = (CPUArchState *)(cpu->env_ptr); + WHV_REGISTER_NAME tsc_reg = WHvX64RegisterTsc; + WHV_REGISTER_VALUE tsc_val; + HRESULT hr; + struct whpx_state *whpx = &whpx_global; + + /* + * Suspend the partition prior to setting the TSC to reduce the variance + * in TSC across vCPUs. When the first vCPU runs post suspend, the + * partition is automatically resumed. + */ + if (whp_dispatch.WHvSuspendPartitionTime) { + + /* + * Unable to suspend partition while setting TSC is not a fatal + * error. It just increases the likelihood of TSC variance between + * vCPUs and some guest OS are able to handle that just fine. + */ + hr = whp_dispatch.WHvSuspendPartitionTime(whpx->partition); + if (FAILED(hr)) { + warn_report("WHPX: Failed to suspend partition, hr=%08lx", hr); + } + } + + tsc_val.Reg64 = env->tsc; + hr = whp_dispatch.WHvSetVirtualProcessorRegisters( + whpx->partition, cpu->cpu_index, &tsc_reg, 1, &tsc_val); + if (FAILED(hr)) { + error_report("WHPX: Failed to set TSC, hr=%08lx", hr); + return -1; + } + + return 0; +} + +static void whpx_set_registers(CPUState *cpu, int level) { struct whpx_state *whpx = &whpx_global; struct whpx_vcpu *vcpu = get_whpx_vcpu(cpu); @@ -230,6 +266,14 @@ static void whpx_set_registers(CPUState *cpu) assert(cpu_is_stopped(cpu) || qemu_cpu_is_self(cpu)); + /* + * Following MSRs have side effects on the guest or are too heavy for + * runtime. Limit them to full state update. + */ + if (level >= WHPX_SET_RESET_STATE) { + whpx_set_tsc(cpu); + } + memset(&vcxt, 0, sizeof(struct whpx_register_set)); v86 = (env->eflags & VM_MASK); @@ -330,8 +374,6 @@ static void whpx_set_registers(CPUState *cpu) idx += 1; /* MSRs */ - assert(whpx_register_names[idx] == WHvX64RegisterTsc); - vcxt.values[idx++].Reg64 = env->tsc; assert(whpx_register_names[idx] == WHvX64RegisterEfer); vcxt.values[idx++].Reg64 = env->efer; #ifdef TARGET_X86_64 @@ -379,6 +421,25 @@ static void whpx_set_registers(CPUState *cpu) return; } +static int whpx_get_tsc(CPUState *cpu) +{ + struct CPUX86State *env = (CPUArchState *)(cpu->env_ptr); + WHV_REGISTER_NAME tsc_reg = WHvX64RegisterTsc; + WHV_REGISTER_VALUE tsc_val; + HRESULT hr; + struct whpx_state *whpx = &whpx_global; + + hr = whp_dispatch.WHvGetVirtualProcessorRegisters( + whpx->partition, cpu->cpu_index, &tsc_reg, 1, &tsc_val); + if (FAILED(hr)) { + error_report("WHPX: Failed to get TSC, hr=%08lx", hr); + return -1; + } + + env->tsc = tsc_val.Reg64; + return 0; +} + static void whpx_get_registers(CPUState *cpu) { struct whpx_state *whpx = &whpx_global; @@ -394,6 +455,11 @@ static void whpx_get_registers(CPUState *cpu) assert(cpu_is_stopped(cpu) || qemu_cpu_is_self(cpu)); + if (!env->tsc_valid) { + whpx_get_tsc(cpu); + env->tsc_valid = !runstate_is_running(); + } + hr = whp_dispatch.WHvGetVirtualProcessorRegisters( whpx->partition, cpu->cpu_index, whpx_register_names, @@ -492,8 +558,6 @@ static void whpx_get_registers(CPUState *cpu) idx += 1; /* MSRs */ - assert(whpx_register_names[idx] == WHvX64RegisterTsc); - env->tsc = vcxt.values[idx++].Reg64; assert(whpx_register_names[idx] == WHvX64RegisterEfer); env->efer = vcxt.values[idx++].Reg64; #ifdef TARGET_X86_64 @@ -841,9 +905,8 @@ static void whpx_vcpu_process_async_events(CPUState *cpu) if ((cpu->interrupt_request & CPU_INTERRUPT_INIT) && !(env->hflags & HF_SMM_MASK)) { - + whpx_cpu_synchronize_state(cpu); do_cpu_init(x86_cpu); - cpu->vcpu_dirty = true; vcpu->interruptable = true; } @@ -859,17 +922,13 @@ static void whpx_vcpu_process_async_events(CPUState *cpu) } if (cpu->interrupt_request & CPU_INTERRUPT_SIPI) { - if (!cpu->vcpu_dirty) { - whpx_get_registers(cpu); - } + whpx_cpu_synchronize_state(cpu); do_cpu_sipi(x86_cpu); } if (cpu->interrupt_request & CPU_INTERRUPT_TPR) { cpu->interrupt_request &= ~CPU_INTERRUPT_TPR; - if (!cpu->vcpu_dirty) { - whpx_get_registers(cpu); - } + whpx_cpu_synchronize_state(cpu); apic_handle_tpr_access_report(x86_cpu->apic_state, env->eip, env->tpr_access_type); } @@ -896,7 +955,7 @@ static int whpx_vcpu_run(CPUState *cpu) do { if (cpu->vcpu_dirty) { - whpx_set_registers(cpu); + whpx_set_registers(cpu, WHPX_SET_RUNTIME_STATE); cpu->vcpu_dirty = false; } @@ -980,38 +1039,32 @@ static int whpx_vcpu_run(CPUState *cpu) WHV_REGISTER_VALUE reg_values[5]; WHV_REGISTER_NAME reg_names[5]; UINT32 reg_count = 5; - UINT64 rip, rax, rcx, rdx, rbx; + UINT64 cpuid_fn, rip = 0, rax = 0, rcx = 0, rdx = 0, rbx = 0; + X86CPU *x86_cpu = X86_CPU(cpu); + CPUX86State *env = &x86_cpu->env; memset(reg_values, 0, sizeof(reg_values)); rip = vcpu->exit_ctx.VpContext.Rip + vcpu->exit_ctx.VpContext.InstructionLength; - switch (vcpu->exit_ctx.CpuidAccess.Rax) { - case 1: - rax = vcpu->exit_ctx.CpuidAccess.DefaultResultRax; - /* Advertise that we are running on a hypervisor */ - rcx = - vcpu->exit_ctx.CpuidAccess.DefaultResultRcx | - CPUID_EXT_HYPERVISOR; - - rdx = vcpu->exit_ctx.CpuidAccess.DefaultResultRdx; - rbx = vcpu->exit_ctx.CpuidAccess.DefaultResultRbx; - break; + cpuid_fn = vcpu->exit_ctx.CpuidAccess.Rax; + + /* + * Ideally, these should be supplied to the hypervisor during VCPU + * initialization and it should be able to satisfy this request. + * But, currently, WHPX doesn't support setting CPUID values in the + * hypervisor once the partition has been setup, which is too late + * since VCPUs are realized later. For now, use the values from + * QEMU to satisfy these requests, until WHPX adds support for + * being able to set these values in the hypervisor at runtime. + */ + cpu_x86_cpuid(env, cpuid_fn, 0, (UINT32 *)&rax, (UINT32 *)&rbx, + (UINT32 *)&rcx, (UINT32 *)&rdx); + switch (cpuid_fn) { case 0x80000001: - rax = vcpu->exit_ctx.CpuidAccess.DefaultResultRax; /* Remove any support of OSVW */ - rcx = - vcpu->exit_ctx.CpuidAccess.DefaultResultRcx & - ~CPUID_EXT3_OSVW; - - rdx = vcpu->exit_ctx.CpuidAccess.DefaultResultRdx; - rbx = vcpu->exit_ctx.CpuidAccess.DefaultResultRbx; + rcx &= ~CPUID_EXT3_OSVW; break; - default: - rax = vcpu->exit_ctx.CpuidAccess.DefaultResultRax; - rcx = vcpu->exit_ctx.CpuidAccess.DefaultResultRcx; - rdx = vcpu->exit_ctx.CpuidAccess.DefaultResultRdx; - rbx = vcpu->exit_ctx.CpuidAccess.DefaultResultRbx; } reg_names[0] = WHvX64RegisterRip; @@ -1067,21 +1120,23 @@ static int whpx_vcpu_run(CPUState *cpu) static void do_whpx_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg) { - whpx_get_registers(cpu); - cpu->vcpu_dirty = true; + if (!cpu->vcpu_dirty) { + whpx_get_registers(cpu); + cpu->vcpu_dirty = true; + } } static void do_whpx_cpu_synchronize_post_reset(CPUState *cpu, run_on_cpu_data arg) { - whpx_set_registers(cpu); + whpx_set_registers(cpu, WHPX_SET_RESET_STATE); cpu->vcpu_dirty = false; } static void do_whpx_cpu_synchronize_post_init(CPUState *cpu, run_on_cpu_data arg) { - whpx_set_registers(cpu); + whpx_set_registers(cpu, WHPX_SET_FULL_STATE); cpu->vcpu_dirty = false; } @@ -1123,6 +1178,15 @@ void whpx_cpu_synchronize_pre_loadvm(CPUState *cpu) static Error *whpx_migration_blocker; +static void whpx_cpu_update_state(void *opaque, int running, RunState state) +{ + CPUX86State *env = opaque; + + if (running) { + env->tsc_valid = false; + } +} + int whpx_init_vcpu(CPUState *cpu) { HRESULT hr; @@ -1178,6 +1242,7 @@ int whpx_init_vcpu(CPUState *cpu) cpu->vcpu_dirty = true; cpu->hax_vcpu = (struct hax_vcpu_state *)vcpu; + qemu_add_vm_change_state_handler(whpx_cpu_update_state, cpu->env_ptr); return 0; } @@ -1367,6 +1432,10 @@ static bool load_whp_dispatch_fns(HMODULE *handle, #define WINHV_PLATFORM_DLL "WinHvPlatform.dll" #define WINHV_EMULATION_DLL "WinHvEmulation.dll" + #define WHP_LOAD_FIELD_OPTIONAL(return_type, function_name, signature) \ + whp_dispatch.function_name = \ + (function_name ## _t)GetProcAddress(hLib, #function_name); \ + #define WHP_LOAD_FIELD(return_type, function_name, signature) \ whp_dispatch.function_name = \ (function_name ## _t)GetProcAddress(hLib, #function_name); \ @@ -1394,6 +1463,11 @@ static bool load_whp_dispatch_fns(HMODULE *handle, WHP_LOAD_LIB(WINHV_EMULATION_DLL, hLib) LIST_WINHVEMULATION_FUNCTIONS(WHP_LOAD_FIELD) break; + + case WINHV_PLATFORM_FNS_SUPPLEMENTAL: + WHP_LOAD_LIB(WINHV_PLATFORM_DLL, hLib) + LIST_WINHVPLATFORM_FUNCTIONS_SUPPLEMENTAL(WHP_LOAD_FIELD_OPTIONAL) + break; } *handle = hLib; @@ -1554,6 +1628,8 @@ bool init_whp_dispatch(void) goto error; } + assert(load_whp_dispatch_fns(&hWinHvPlatform, + WINHV_PLATFORM_FNS_SUPPLEMENTAL)); whp_dispatch_initialized = true; return true; diff --git a/target/s390x/ioinst.c b/target/s390x/ioinst.c index c437a1d8c6..0e840cc579 100644 --- a/target/s390x/ioinst.c +++ b/target/s390x/ioinst.c @@ -347,7 +347,7 @@ typedef struct ChscResp { uint16_t len; uint16_t code; uint32_t param; - char data[0]; + char data[]; } QEMU_PACKED ChscResp; #define CHSC_MIN_RESP_LEN 0x0008 |