Now that we expose AccessFrequencyRegs, expose HV_X64_MSR_APIC_FREQUENCY as well for the case when the Hyper-V LAPIC is not used.
If the Hyper-V LAPIC is used, this will be handled by the hypervisor instead of the VMM, hence gating it on !whpx_irqchip_in_kernel(). Signed-off-by: Mohamed Mediouni <[email protected]> --- target/i386/whpx/whpx-all.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c index da2ba36060..69a3c42ba0 100644 --- a/target/i386/whpx/whpx-all.c +++ b/target/i386/whpx/whpx-all.c @@ -45,6 +45,8 @@ #include <winhvplatform.h> #define HYPERV_APIC_BUS_FREQUENCY (200000000ULL) +/* for kernel-irqchip=off */ +#define HV_X64_MSR_APIC_FREQUENCY 0x40000023 static const WHV_REGISTER_NAME whpx_register_names[] = { @@ -1787,6 +1789,7 @@ int whpx_vcpu_run(CPUState *cpu) WHV_REGISTER_VALUE reg_values[3] = {0}; WHV_REGISTER_NAME reg_names[3]; UINT32 reg_count; + bool is_known_msr = 0; reg_names[0] = WHvX64RegisterRip; reg_names[1] = WHvX64RegisterRax; @@ -1796,6 +1799,12 @@ int whpx_vcpu_run(CPUState *cpu) vcpu->exit_ctx.VpContext.Rip + vcpu->exit_ctx.VpContext.InstructionLength; + if (vcpu->exit_ctx.MsrAccess.MsrNumber == HV_X64_MSR_APIC_FREQUENCY + && !vcpu->exit_ctx.MsrAccess.AccessInfo.IsWrite + && !whpx_irqchip_in_kernel()) { + is_known_msr = 1; + reg_values[1].Reg32 = (uint32_t)X86_CPU(cpu)->env.apic_bus_freq; + } /* * For all unsupported MSR access we: * ignore writes @@ -1804,8 +1813,10 @@ int whpx_vcpu_run(CPUState *cpu) reg_count = vcpu->exit_ctx.MsrAccess.AccessInfo.IsWrite ? 1 : 3; - warn_report("WHPX: Unsupported MSR access (0x%x), IsWrite=%i", + if (!is_known_msr) { + warn_report("WHPX: Unsupported MSR access (0x%x), IsWrite=%i", vcpu->exit_ctx.MsrAccess.MsrNumber, vcpu->exit_ctx.MsrAccess.AccessInfo.IsWrite); + } hr = whp_dispatch.WHvSetVirtualProcessorRegisters( whpx->partition, @@ -1973,6 +1984,10 @@ int whpx_init_vcpu(CPUState *cpu) } } + /* When not using the Hyper-V APIC, the frequency is 1 GHz */ + if (!whpx_irqchip_in_kernel()) { + env->apic_bus_freq = 1000000000; + } vcpu->interruptable = true; cpu->vcpu_dirty = true; @@ -2186,7 +2201,6 @@ int whpx_accel_init(AccelState *as, MachineState *ms) synthetic_features.Bank0.Hv1 = 1; synthetic_features.Bank0.AccessPartitionReferenceCounter = 1; synthetic_features.Bank0.AccessPartitionReferenceTsc = 1; - /* if kernel-irqchip=off, HV_X64_MSR_APIC_FREQUENCY = 0. */ synthetic_features.Bank0.AccessFrequencyRegs = 1; synthetic_features.Bank0.AccessVpIndex = 1; synthetic_features.Bank0.AccessHypercallRegs = 1; -- 2.50.1 (Apple Git-155)
