diff --git a/hypervisor/arch/x86/guest/vcpuid.c b/hypervisor/arch/x86/guest/vcpuid.c index 11acd8647..1b688d13b 100644 --- a/hypervisor/arch/x86/guest/vcpuid.c +++ b/hypervisor/arch/x86/guest/vcpuid.c @@ -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) { diff --git a/hypervisor/arch/x86/guest/vmsr.c b/hypervisor/arch/x86/guest/vmsr.c index 809c52ebe..715b29735 100644 --- a/hypervisor/arch/x86/guest/vmsr.c +++ b/hypervisor/arch/x86/guest/vmsr.c @@ -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); diff --git a/hypervisor/include/arch/x86/asm/cpuid.h b/hypervisor/include/arch/x86/asm/cpuid.h index e178e3305..022ac5850 100644 --- a/hypervisor/include/arch/x86/asm/cpuid.h +++ b/hypervisor/include/arch/x86/asm/cpuid.h @@ -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*/ diff --git a/hypervisor/include/arch/x86/asm/guest/vcpu.h b/hypervisor/include/arch/x86/asm/guest/vcpu.h index 825f4a672..01b661bc7 100644 --- a/hypervisor/include/arch/x86/asm/guest/vcpu.h +++ b/hypervisor/include/arch/x86/asm/guest/vcpu.h @@ -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 diff --git a/hypervisor/include/arch/x86/asm/msr.h b/hypervisor/include/arch/x86/asm/msr.h index dbb43254c..b2e56ec5f 100644 --- a/hypervisor/include/arch/x86/asm/msr.h +++ b/hypervisor/include/arch/x86/asm/msr.h @@ -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 */