mirror of https://github.com/xemu-project/xemu.git
WHPX: support for xcr0
Support for xcr0 to be able to enable xsave/xrstor. This by itself is not sufficient to enable xsave/xrstor. WHPX XSAVE API's also needs to be hooked up. Signed-off-by: Sunil Muthuswamy <sunilmut@microsoft.com> Message-Id: <MW2PR2101MB1116F07C07A26FD7A7ED8DCFC0780@MW2PR2101MB1116.namprd21.prod.outlook.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
13220a46e2
commit
b6b3da9998
|
@ -246,9 +246,15 @@ static bool whpx_allowed;
|
||||||
static bool whp_dispatch_initialized;
|
static bool whp_dispatch_initialized;
|
||||||
static HMODULE hWinHvPlatform, hWinHvEmulation;
|
static HMODULE hWinHvPlatform, hWinHvEmulation;
|
||||||
static uint32_t max_vcpu_index;
|
static uint32_t max_vcpu_index;
|
||||||
|
static WHV_PROCESSOR_XSAVE_FEATURES whpx_xsave_cap;
|
||||||
|
|
||||||
struct whpx_state whpx_global;
|
struct whpx_state whpx_global;
|
||||||
struct WHPDispatch whp_dispatch;
|
struct WHPDispatch whp_dispatch;
|
||||||
|
|
||||||
|
static bool whpx_has_xsave(void)
|
||||||
|
{
|
||||||
|
return whpx_xsave_cap.XsaveSupport;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* VP support
|
* VP support
|
||||||
|
@ -300,6 +306,28 @@ static SegmentCache whpx_seg_h2q(const WHV_X64_SEGMENT_REGISTER *hs)
|
||||||
return qs;
|
return qs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* X64 Extended Control Registers */
|
||||||
|
static void whpx_set_xcrs(CPUState *cpu)
|
||||||
|
{
|
||||||
|
CPUX86State *env = cpu->env_ptr;
|
||||||
|
HRESULT hr;
|
||||||
|
struct whpx_state *whpx = &whpx_global;
|
||||||
|
WHV_REGISTER_VALUE xcr0;
|
||||||
|
WHV_REGISTER_NAME xcr0_name = WHvX64RegisterXCr0;
|
||||||
|
|
||||||
|
if (!whpx_has_xsave()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only xcr0 is supported by the hypervisor currently */
|
||||||
|
xcr0.Reg64 = env->xcr0;
|
||||||
|
hr = whp_dispatch.WHvSetVirtualProcessorRegisters(
|
||||||
|
whpx->partition, cpu->cpu_index, &xcr0_name, 1, &xcr0);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
error_report("WHPX: Failed to set register xcr0, hr=%08lx", hr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int whpx_set_tsc(CPUState *cpu)
|
static int whpx_set_tsc(CPUState *cpu)
|
||||||
{
|
{
|
||||||
CPUX86State *env = cpu->env_ptr;
|
CPUX86State *env = cpu->env_ptr;
|
||||||
|
@ -435,6 +463,12 @@ static void whpx_set_registers(CPUState *cpu, int level)
|
||||||
|
|
||||||
/* 8 Debug Registers - Skipped */
|
/* 8 Debug Registers - Skipped */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extended control registers needs to be handled separately depending
|
||||||
|
* on whether xsave is supported/enabled or not.
|
||||||
|
*/
|
||||||
|
whpx_set_xcrs(cpu);
|
||||||
|
|
||||||
/* 16 XMM registers */
|
/* 16 XMM registers */
|
||||||
assert(whpx_register_names[idx] == WHvX64RegisterXmm0);
|
assert(whpx_register_names[idx] == WHvX64RegisterXmm0);
|
||||||
idx_next = idx + 16;
|
idx_next = idx + 16;
|
||||||
|
@ -541,6 +575,30 @@ static int whpx_get_tsc(CPUState *cpu)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* X64 Extended Control Registers */
|
||||||
|
static void whpx_get_xcrs(CPUState *cpu)
|
||||||
|
{
|
||||||
|
CPUX86State *env = cpu->env_ptr;
|
||||||
|
HRESULT hr;
|
||||||
|
struct whpx_state *whpx = &whpx_global;
|
||||||
|
WHV_REGISTER_VALUE xcr0;
|
||||||
|
WHV_REGISTER_NAME xcr0_name = WHvX64RegisterXCr0;
|
||||||
|
|
||||||
|
if (!whpx_has_xsave()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only xcr0 is supported by the hypervisor currently */
|
||||||
|
hr = whp_dispatch.WHvGetVirtualProcessorRegisters(
|
||||||
|
whpx->partition, cpu->cpu_index, &xcr0_name, 1, &xcr0);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
error_report("WHPX: Failed to get register xcr0, hr=%08lx", hr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
env->xcr0 = xcr0.Reg64;
|
||||||
|
}
|
||||||
|
|
||||||
static void whpx_get_registers(CPUState *cpu)
|
static void whpx_get_registers(CPUState *cpu)
|
||||||
{
|
{
|
||||||
struct whpx_state *whpx = &whpx_global;
|
struct whpx_state *whpx = &whpx_global;
|
||||||
|
@ -634,6 +692,12 @@ static void whpx_get_registers(CPUState *cpu)
|
||||||
|
|
||||||
/* 8 Debug Registers - Skipped */
|
/* 8 Debug Registers - Skipped */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extended control registers needs to be handled separately depending
|
||||||
|
* on whether xsave is supported/enabled or not.
|
||||||
|
*/
|
||||||
|
whpx_get_xcrs(cpu);
|
||||||
|
|
||||||
/* 16 XMM registers */
|
/* 16 XMM registers */
|
||||||
assert(whpx_register_names[idx] == WHvX64RegisterXmm0);
|
assert(whpx_register_names[idx] == WHvX64RegisterXmm0);
|
||||||
idx_next = idx + 16;
|
idx_next = idx + 16;
|
||||||
|
@ -2513,6 +2577,29 @@ static int whpx_accel_init(MachineState *ms)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Query the XSAVE capability of the partition. Any error here is not
|
||||||
|
* considered fatal.
|
||||||
|
*/
|
||||||
|
hr = whp_dispatch.WHvGetPartitionProperty(
|
||||||
|
whpx->partition,
|
||||||
|
WHvPartitionPropertyCodeProcessorXsaveFeatures,
|
||||||
|
&whpx_xsave_cap,
|
||||||
|
sizeof(whpx_xsave_cap),
|
||||||
|
&whpx_cap_size);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Windows version which don't support this property will return with the
|
||||||
|
* specific error code.
|
||||||
|
*/
|
||||||
|
if (FAILED(hr) && hr != WHV_E_UNKNOWN_PROPERTY) {
|
||||||
|
error_report("WHPX: Failed to query XSAVE capability, hr=%08lx", hr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!whpx_has_xsave()) {
|
||||||
|
printf("WHPX: Partition is not XSAVE capable\n");
|
||||||
|
}
|
||||||
|
|
||||||
memset(&prop, 0, sizeof(WHV_PARTITION_PROPERTY));
|
memset(&prop, 0, sizeof(WHV_PARTITION_PROPERTY));
|
||||||
prop.ProcessorCount = ms->smp.cpus;
|
prop.ProcessorCount = ms->smp.cpus;
|
||||||
hr = whp_dispatch.WHvSetPartitionProperty(
|
hr = whp_dispatch.WHvSetPartitionProperty(
|
||||||
|
|
|
@ -48,6 +48,9 @@ void whpx_apic_get(DeviceState *s);
|
||||||
|
|
||||||
#define WHV_E_UNKNOWN_CAPABILITY 0x80370300L
|
#define WHV_E_UNKNOWN_CAPABILITY 0x80370300L
|
||||||
|
|
||||||
|
/* This should eventually come from the Windows SDK */
|
||||||
|
#define WHV_E_UNKNOWN_PROPERTY 0x80370302
|
||||||
|
|
||||||
#define LIST_WINHVPLATFORM_FUNCTIONS(X) \
|
#define LIST_WINHVPLATFORM_FUNCTIONS(X) \
|
||||||
X(HRESULT, WHvGetCapability, (WHV_CAPABILITY_CODE CapabilityCode, VOID* CapabilityBuffer, UINT32 CapabilityBufferSizeInBytes, UINT32* WrittenSizeInBytes)) \
|
X(HRESULT, WHvGetCapability, (WHV_CAPABILITY_CODE CapabilityCode, VOID* CapabilityBuffer, UINT32 CapabilityBufferSizeInBytes, UINT32* WrittenSizeInBytes)) \
|
||||||
X(HRESULT, WHvCreatePartition, (WHV_PARTITION_HANDLE* Partition)) \
|
X(HRESULT, WHvCreatePartition, (WHV_PARTITION_HANDLE* Partition)) \
|
||||||
|
|
Loading…
Reference in New Issue