mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-08-13 13:56:19 +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;
|
||||
|
||||
switch (leaf) {
|
||||
|
||||
case 0x06U:
|
||||
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);
|
||||
entry->ecx &= ~CPUID_ECX_HCFC;
|
||||
/* Always hide package level HWP controls and HWP interrupt*/
|
||||
entry->eax &= ~(CPUID_EAX_HWP_CTL | CPUID_EAX_HWP_PLR | CPUID_EAX_HWP_N);
|
||||
break;
|
||||
|
||||
case 0x07U:
|
||||
@ -548,6 +547,15 @@ int32_t set_vcpuid_entries(struct acrn_vm *vm)
|
||||
/* MONITOR/MWAIT */
|
||||
case 0x05U:
|
||||
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:
|
||||
init_vcpuid_entry(i, 0U, CPUID_CHECK_SUBLEAF, &entry);
|
||||
if (entry.eax != 0U) {
|
||||
|
@ -79,6 +79,13 @@ static uint32_t emulated_guest_msrs[NUM_EMULATED_MSRS] = {
|
||||
|
||||
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] */
|
||||
#ifdef CONFIG_NVMX_ENABLED
|
||||
LIST_OF_VMX_MSRS,
|
||||
@ -260,28 +267,19 @@ static const uint32_t unsupported_msrs[] = {
|
||||
MSR_IA32_PL3_SSP,
|
||||
MSR_IA32_INTERRUPT_SSP_TABLE_ADDR,
|
||||
|
||||
/* HWP disabled:
|
||||
* CPUID.06H.EAX[7]
|
||||
* CPUID.06H.EAX[9]
|
||||
* CPUID.06H:EAX[10]
|
||||
*/
|
||||
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]
|
||||
/*
|
||||
* HWP package ctrl disabled:
|
||||
* CPUID.06H.EAX[11] (MSR_IA32_HWP_REQUEST_PKG)
|
||||
* CPUID.06H.EAX[22] (MSR_IA32_HWP_CTL)
|
||||
*/
|
||||
MSR_IA32_HWP_REQUEST_PKG,
|
||||
/* Hardware Coordination Feedback Capability disabled:
|
||||
* CPUID.06H:ECX[0]
|
||||
MSR_IA32_HWP_CTL,
|
||||
|
||||
/*
|
||||
* HWP interrupt disabled:
|
||||
* CPUID.06H.EAX[8]
|
||||
*/
|
||||
MSR_IA32_MPERF,
|
||||
MSR_IA32_APERF,
|
||||
MSR_IA32_HWP_INTERRUPT,
|
||||
};
|
||||
|
||||
/* 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:
|
||||
{
|
||||
v = get_perf_status();
|
||||
if (is_vhwp_configured(vcpu->vm)) {
|
||||
v = msr_read(msr);
|
||||
} else {
|
||||
v = get_perf_status();
|
||||
}
|
||||
break;
|
||||
}
|
||||
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);
|
||||
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:
|
||||
{
|
||||
/*
|
||||
@ -1059,6 +1075,48 @@ int32_t wrmsr_vmexit_handler(struct acrn_vcpu *vcpu)
|
||||
vcpu_set_guest_msr(vcpu, MSR_IA32_PERF_CTL, v);
|
||||
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:
|
||||
{
|
||||
err = write_pat_msr(vcpu, v);
|
||||
|
@ -84,6 +84,8 @@
|
||||
#define CPUID_EAX_HWP_EPP (1U<<10U)
|
||||
/* CPUID.06H:EAX.HWP_Package_Level_Request */
|
||||
#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 */
|
||||
#define CPUID_ECX_HCFC (1U<<0U)
|
||||
/* CPUID.07H:EBX.FSGSBASE*/
|
||||
|
@ -175,7 +175,7 @@ enum reset_mode;
|
||||
#define SECURE_WORLD 1
|
||||
|
||||
#define NUM_WORLD_MSRS 2U
|
||||
#define NUM_COMMON_MSRS 25U
|
||||
#define NUM_COMMON_MSRS 31U
|
||||
|
||||
#ifdef CONFIG_VCAT_ENABLED
|
||||
#define NUM_CAT_L2_MSRS MAX_CACHE_CLOS_NUM_ENTRIES
|
||||
|
@ -294,6 +294,7 @@
|
||||
#define MSR_IA32_HWP_INTERRUPT 0x00000773U
|
||||
#define MSR_IA32_HWP_REQUEST 0x00000774U
|
||||
#define MSR_IA32_HWP_PECI_REQUEST_INFO 0x00000775U
|
||||
#define MSR_IA32_HWP_CTL 0x00000776U
|
||||
#define MSR_IA32_HWP_STATUS 0x00000777U
|
||||
|
||||
#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_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 */
|
||||
|
Loading…
Reference in New Issue
Block a user