Skip to content

Commit

Permalink
WHPX: register for unrecognized MSR exits
Browse files Browse the repository at this point in the history
Some variations of Linux kernels end up accessing MSR's that the Windows
Hypervisor doesn't implement which causes a GP to be returned to the guest.
This fix registers QEMU for unimplemented MSR access and globally returns 0 on
reads and ignores writes. This behavior is allows the Linux kernel to probe the
MSR with a write/read/check sequence it does often without failing the access.

Signed-off-by: Justin Terry (VM) <juterry@microsoft.com>
Message-Id: <20180605221500.21674-2-juterry@microsoft.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
  • Loading branch information
jterry75 authored and bonzini committed Jun 28, 2018
1 parent e1753a7 commit e7ca549
Showing 1 changed file with 38 additions and 3 deletions.
41 changes: 38 additions & 3 deletions target/i386/whpx-all.c
Expand Up @@ -932,6 +932,7 @@ static int whpx_vcpu_run(CPUState *cpu)

case WHvRunVpExitReasonX64InterruptWindow:
vcpu->window_registered = 0;
ret = 0;
break;

case WHvRunVpExitReasonX64Halt:
Expand All @@ -943,6 +944,40 @@ static int whpx_vcpu_run(CPUState *cpu)
ret = 1;
break;

case WHvRunVpExitReasonX64MsrAccess: {
WHV_REGISTER_VALUE reg_values[3] = {0};
WHV_REGISTER_NAME reg_names[3];
UINT32 reg_count;

reg_names[0] = WHvX64RegisterRip;
reg_names[1] = WHvX64RegisterRax;
reg_names[2] = WHvX64RegisterRdx;

reg_values[0].Reg64 =
vcpu->exit_ctx.VpContext.Rip +
vcpu->exit_ctx.VpContext.InstructionLength;

/*
* For all unsupported MSR access we:
* ignore writes
* return 0 on read.
*/
reg_count = vcpu->exit_ctx.MsrAccess.AccessInfo.IsWrite ?
1 : 3;

hr = whp_dispatch.WHvSetVirtualProcessorRegisters(
whpx->partition,
cpu->cpu_index,
reg_names, reg_count,
reg_values);

if (FAILED(hr)) {
error_report("WHPX: Failed to set MsrAccess state "
" registers, hr=%08lx", hr);
}
ret = 0;
break;
}
case WHvRunVpExitReasonX64Cpuid: {
WHV_REGISTER_VALUE reg_values[5];
WHV_REGISTER_NAME reg_names[5];
Expand Down Expand Up @@ -1010,7 +1045,6 @@ static int whpx_vcpu_run(CPUState *cpu)
case WHvRunVpExitReasonUnrecoverableException:
case WHvRunVpExitReasonInvalidVpRegisterValue:
case WHvRunVpExitReasonUnsupportedFeature:
case WHvRunVpExitReasonX64MsrAccess:
case WHvRunVpExitReasonException:
default:
error_report("WHPX: Unexpected VP exit code %d",
Expand Down Expand Up @@ -1378,6 +1412,7 @@ static int whpx_accel_init(MachineState *ms)
}

memset(&prop, 0, sizeof(WHV_PARTITION_PROPERTY));
prop.ExtendedVmExits.X64MsrExit = 1;
prop.ExtendedVmExits.X64CpuidExit = 1;
hr = whp_dispatch.WHvSetPartitionProperty(
whpx->partition,
Expand All @@ -1386,8 +1421,8 @@ static int whpx_accel_init(MachineState *ms)
sizeof(WHV_PARTITION_PROPERTY));

if (FAILED(hr)) {
error_report("WHPX: Failed to enable partition extended X64CpuidExit"
" hr=%08lx", hr);
error_report("WHPX: Failed to enable partition extended X64MsrExit and"
" X64CpuidExit hr=%08lx", hr);
ret = -EINVAL;
goto error;
}
Expand Down

0 comments on commit e7ca549

Please sign in to comment.