mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-08-14 14:25:14 +00:00
hv: emulate cpuids and MSRs for VHWP
Changes made by this patch includes: 1. Emulate HWP and pstate MSRs/CPUIDs. Those are exposed to guest when the GUEST_FLAG_VHWP is set: - CPUID[6].EAX[7,9,10]: MSR_IA32_PM_ENABLE(enabled by hv, always read 1), MSR_IA32_HWP_CAPABILITIES, MSR_IA32_HWP_REQUEST, MSR_IA32_HWP_STATUS, - CPUID[6].ECX[0]: MSR_IA32_MPERF, MSR_IA32_APERF - MSR_IA32_PERF_STATUS(read as base frequency when not owning pCPU) - MSR_IA32_PERF_CTL(ignore writes) 2. Always hide HWP interrupt and package control MSRs/CPUIDs: - CPUID[6].EAX[8]: MSR_IA32_HWP_INTERRUPT(currently ACRN is not able to deliver thermal LVT virtual interrupt to guests) - CPUID[6].EAX[11,22]: MSR_IA32_HWP_REQUEST_PKG, MSR_IA32_HWP_CTL Tracked-On: #8414 Signed-off-by: Wu Zhou <wu.zhou@intel.com> Reviewed-by: Junjie Mao <junjie.mao@intel.com>
This commit is contained in:
parent
2edf141047
commit
c5d019b836
@ -115,11 +115,10 @@ static void init_vcpuid_entry(uint32_t leaf, uint32_t subleaf,
|
|||||||
entry->flags = flags;
|
entry->flags = flags;
|
||||||
|
|
||||||
switch (leaf) {
|
switch (leaf) {
|
||||||
|
|
||||||
case 0x06U:
|
case 0x06U:
|
||||||
cpuid_subleaf(leaf, subleaf, &entry->eax, &entry->ebx, &entry->ecx, &entry->edx);
|
cpuid_subleaf(leaf, subleaf, &entry->eax, &entry->ebx, &entry->ecx, &entry->edx);
|
||||||
entry->eax &= ~(CPUID_EAX_HWP | CPUID_EAX_HWP_N | CPUID_EAX_HWP_AW | CPUID_EAX_HWP_EPP | CPUID_EAX_HWP_PLR);
|
/* Always hide package level HWP controls and HWP interrupt*/
|
||||||
entry->ecx &= ~CPUID_ECX_HCFC;
|
entry->eax &= ~(CPUID_EAX_HWP_CTL | CPUID_EAX_HWP_PLR | CPUID_EAX_HWP_N);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x07U:
|
case 0x07U:
|
||||||
@ -548,6 +547,15 @@ int32_t set_vcpuid_entries(struct acrn_vm *vm)
|
|||||||
/* MONITOR/MWAIT */
|
/* MONITOR/MWAIT */
|
||||||
case 0x05U:
|
case 0x05U:
|
||||||
break;
|
break;
|
||||||
|
case 0x06U:
|
||||||
|
init_vcpuid_entry(i, 0U, CPUID_CHECK_SUBLEAF, &entry);
|
||||||
|
/* For VMs without vhwp, HWP and HCFC are always hidden. */
|
||||||
|
if (!is_vhwp_configured(vm)) {
|
||||||
|
entry.eax &= ~(CPUID_EAX_HWP | CPUID_EAX_HWP_AW | CPUID_EAX_HWP_EPP);
|
||||||
|
entry.ecx &= ~CPUID_ECX_HCFC;
|
||||||
|
}
|
||||||
|
result = set_vcpuid_entry(vm, &entry);
|
||||||
|
break;
|
||||||
case 0x07U:
|
case 0x07U:
|
||||||
init_vcpuid_entry(i, 0U, CPUID_CHECK_SUBLEAF, &entry);
|
init_vcpuid_entry(i, 0U, CPUID_CHECK_SUBLEAF, &entry);
|
||||||
if (entry.eax != 0U) {
|
if (entry.eax != 0U) {
|
||||||
|
@ -79,6 +79,13 @@ static uint32_t emulated_guest_msrs[NUM_EMULATED_MSRS] = {
|
|||||||
|
|
||||||
MSR_PLATFORM_INFO,
|
MSR_PLATFORM_INFO,
|
||||||
|
|
||||||
|
MSR_IA32_PM_ENABLE,
|
||||||
|
MSR_IA32_HWP_CAPABILITIES,
|
||||||
|
MSR_IA32_HWP_REQUEST,
|
||||||
|
MSR_IA32_HWP_STATUS,
|
||||||
|
MSR_IA32_MPERF,
|
||||||
|
MSR_IA32_APERF,
|
||||||
|
|
||||||
/* VMX: CPUID.01H.ECX[5] */
|
/* VMX: CPUID.01H.ECX[5] */
|
||||||
#ifdef CONFIG_NVMX_ENABLED
|
#ifdef CONFIG_NVMX_ENABLED
|
||||||
LIST_OF_VMX_MSRS,
|
LIST_OF_VMX_MSRS,
|
||||||
@ -260,28 +267,19 @@ static const uint32_t unsupported_msrs[] = {
|
|||||||
MSR_IA32_PL3_SSP,
|
MSR_IA32_PL3_SSP,
|
||||||
MSR_IA32_INTERRUPT_SSP_TABLE_ADDR,
|
MSR_IA32_INTERRUPT_SSP_TABLE_ADDR,
|
||||||
|
|
||||||
/* HWP disabled:
|
/*
|
||||||
* CPUID.06H.EAX[7]
|
* HWP package ctrl disabled:
|
||||||
* CPUID.06H.EAX[9]
|
* CPUID.06H.EAX[11] (MSR_IA32_HWP_REQUEST_PKG)
|
||||||
* CPUID.06H:EAX[10]
|
* CPUID.06H.EAX[22] (MSR_IA32_HWP_CTL)
|
||||||
*/
|
|
||||||
MSR_IA32_PM_ENABLE,
|
|
||||||
MSR_IA32_HWP_CAPABILITIES,
|
|
||||||
MSR_IA32_HWP_REQUEST,
|
|
||||||
MSR_IA32_HWP_STATUS,
|
|
||||||
/* HWP_Notification disabled:
|
|
||||||
* CPUID.06H:EAX[8]
|
|
||||||
*/
|
|
||||||
MSR_IA32_HWP_INTERRUPT,
|
|
||||||
/* HWP_package_level disabled:
|
|
||||||
* CPUID.06H:EAX[11]
|
|
||||||
*/
|
*/
|
||||||
MSR_IA32_HWP_REQUEST_PKG,
|
MSR_IA32_HWP_REQUEST_PKG,
|
||||||
/* Hardware Coordination Feedback Capability disabled:
|
MSR_IA32_HWP_CTL,
|
||||||
* CPUID.06H:ECX[0]
|
|
||||||
|
/*
|
||||||
|
* HWP interrupt disabled:
|
||||||
|
* CPUID.06H.EAX[8]
|
||||||
*/
|
*/
|
||||||
MSR_IA32_MPERF,
|
MSR_IA32_HWP_INTERRUPT,
|
||||||
MSR_IA32_APERF,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* emulated_guest_msrs[] shares same indexes with array vcpu->arch->guest_msrs[] */
|
/* emulated_guest_msrs[] shares same indexes with array vcpu->arch->guest_msrs[] */
|
||||||
@ -672,7 +670,11 @@ int32_t rdmsr_vmexit_handler(struct acrn_vcpu *vcpu)
|
|||||||
}
|
}
|
||||||
case MSR_IA32_PERF_STATUS:
|
case MSR_IA32_PERF_STATUS:
|
||||||
{
|
{
|
||||||
|
if (is_vhwp_configured(vcpu->vm)) {
|
||||||
|
v = msr_read(msr);
|
||||||
|
} else {
|
||||||
v = get_perf_status();
|
v = get_perf_status();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MSR_IA32_PERF_CTL:
|
case MSR_IA32_PERF_CTL:
|
||||||
@ -680,6 +682,20 @@ int32_t rdmsr_vmexit_handler(struct acrn_vcpu *vcpu)
|
|||||||
v = vcpu_get_guest_msr(vcpu, MSR_IA32_PERF_CTL);
|
v = vcpu_get_guest_msr(vcpu, MSR_IA32_PERF_CTL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case MSR_IA32_PM_ENABLE:
|
||||||
|
case MSR_IA32_HWP_CAPABILITIES:
|
||||||
|
case MSR_IA32_HWP_REQUEST:
|
||||||
|
case MSR_IA32_HWP_STATUS:
|
||||||
|
case MSR_IA32_MPERF:
|
||||||
|
case MSR_IA32_APERF:
|
||||||
|
{
|
||||||
|
if (is_vhwp_configured(vcpu->vm)) {
|
||||||
|
v = msr_read(msr);
|
||||||
|
} else {
|
||||||
|
err = -EACCES;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case MSR_IA32_PAT:
|
case MSR_IA32_PAT:
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -1059,6 +1075,48 @@ int32_t wrmsr_vmexit_handler(struct acrn_vcpu *vcpu)
|
|||||||
vcpu_set_guest_msr(vcpu, MSR_IA32_PERF_CTL, v);
|
vcpu_set_guest_msr(vcpu, MSR_IA32_PERF_CTL, v);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case MSR_IA32_PM_ENABLE:
|
||||||
|
{
|
||||||
|
if (!is_vhwp_configured(vcpu->vm)) {
|
||||||
|
err = -EACCES;
|
||||||
|
}
|
||||||
|
/* Set by HV. Writing from guests will have no effect */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MSR_IA32_HWP_CAPABILITIES:
|
||||||
|
{
|
||||||
|
/* RO */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MSR_IA32_HWP_REQUEST:
|
||||||
|
{
|
||||||
|
if (is_vhwp_configured(vcpu->vm) &&
|
||||||
|
((v & (MSR_IA32_HWP_REQUEST_RSV_BITS | MSR_IA32_HWP_REQUEST_PKG_CTL)) == 0)) {
|
||||||
|
msr_write(msr, v);
|
||||||
|
} else {
|
||||||
|
err = -EACCES;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MSR_IA32_HWP_STATUS:
|
||||||
|
{
|
||||||
|
if (is_vhwp_configured(vcpu->vm) && ((v & MSR_IA32_HWP_STATUS_RSV_BITS) == 0)) {
|
||||||
|
msr_write(msr, v);
|
||||||
|
} else {
|
||||||
|
err = -EACCES;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MSR_IA32_MPERF:
|
||||||
|
case MSR_IA32_APERF:
|
||||||
|
{
|
||||||
|
if (is_vhwp_configured(vcpu->vm)) {
|
||||||
|
msr_write(msr, v);
|
||||||
|
} else {
|
||||||
|
err = -EACCES;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case MSR_IA32_PAT:
|
case MSR_IA32_PAT:
|
||||||
{
|
{
|
||||||
err = write_pat_msr(vcpu, v);
|
err = write_pat_msr(vcpu, v);
|
||||||
|
@ -84,6 +84,8 @@
|
|||||||
#define CPUID_EAX_HWP_EPP (1U<<10U)
|
#define CPUID_EAX_HWP_EPP (1U<<10U)
|
||||||
/* CPUID.06H:EAX.HWP_Package_Level_Request */
|
/* CPUID.06H:EAX.HWP_Package_Level_Request */
|
||||||
#define CPUID_EAX_HWP_PLR (1U<<11U)
|
#define CPUID_EAX_HWP_PLR (1U<<11U)
|
||||||
|
/* CPUID.06H:EAX.HWP_control */
|
||||||
|
#define CPUID_EAX_HWP_CTL (1U<<22U)
|
||||||
/* CPUID.06H:ECX.Hardware_Coordination_Feedback_Capability */
|
/* CPUID.06H:ECX.Hardware_Coordination_Feedback_Capability */
|
||||||
#define CPUID_ECX_HCFC (1U<<0U)
|
#define CPUID_ECX_HCFC (1U<<0U)
|
||||||
/* CPUID.07H:EBX.FSGSBASE*/
|
/* CPUID.07H:EBX.FSGSBASE*/
|
||||||
|
@ -175,7 +175,7 @@ enum reset_mode;
|
|||||||
#define SECURE_WORLD 1
|
#define SECURE_WORLD 1
|
||||||
|
|
||||||
#define NUM_WORLD_MSRS 2U
|
#define NUM_WORLD_MSRS 2U
|
||||||
#define NUM_COMMON_MSRS 25U
|
#define NUM_COMMON_MSRS 31U
|
||||||
|
|
||||||
#ifdef CONFIG_VCAT_ENABLED
|
#ifdef CONFIG_VCAT_ENABLED
|
||||||
#define NUM_CAT_L2_MSRS MAX_CACHE_CLOS_NUM_ENTRIES
|
#define NUM_CAT_L2_MSRS MAX_CACHE_CLOS_NUM_ENTRIES
|
||||||
|
@ -294,6 +294,7 @@
|
|||||||
#define MSR_IA32_HWP_INTERRUPT 0x00000773U
|
#define MSR_IA32_HWP_INTERRUPT 0x00000773U
|
||||||
#define MSR_IA32_HWP_REQUEST 0x00000774U
|
#define MSR_IA32_HWP_REQUEST 0x00000774U
|
||||||
#define MSR_IA32_HWP_PECI_REQUEST_INFO 0x00000775U
|
#define MSR_IA32_HWP_PECI_REQUEST_INFO 0x00000775U
|
||||||
|
#define MSR_IA32_HWP_CTL 0x00000776U
|
||||||
#define MSR_IA32_HWP_STATUS 0x00000777U
|
#define MSR_IA32_HWP_STATUS 0x00000777U
|
||||||
|
|
||||||
#define MSR_IA32_EXT_XAPICID 0x00000802U
|
#define MSR_IA32_EXT_XAPICID 0x00000802U
|
||||||
@ -679,4 +680,8 @@ void update_msr_bitmap_x2apic_passthru(struct acrn_vcpu *vcpu);
|
|||||||
#define MSR_PLATFORM_INFO_MIN_OPERATING_RATIO_MASK (0x00ff000000000000UL) /* 55:48 */
|
#define MSR_PLATFORM_INFO_MIN_OPERATING_RATIO_MASK (0x00ff000000000000UL) /* 55:48 */
|
||||||
#define MSR_PLATFORM_INFO_SAMPLE_PART (1UL << 27U)
|
#define MSR_PLATFORM_INFO_SAMPLE_PART (1UL << 27U)
|
||||||
|
|
||||||
|
#define MSR_IA32_HWP_STATUS_RSV_BITS (~0x3DUL)
|
||||||
|
#define MSR_IA32_HWP_REQUEST_RSV_BITS (0x7FFF80000000000UL)
|
||||||
|
#define MSR_IA32_HWP_REQUEST_PKG_CTL (1UL << 42U)
|
||||||
|
|
||||||
#endif /* MSR_H */
|
#endif /* MSR_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user