diff --git a/hypervisor/arch/x86/guest/vcpuid.c b/hypervisor/arch/x86/guest/vcpuid.c index 42666e071..1c6eb615d 100644 --- a/hypervisor/arch/x86/guest/vcpuid.c +++ b/hypervisor/arch/x86/guest/vcpuid.c @@ -395,8 +395,14 @@ int32_t set_vcpuid_entries(struct acrn_vm *vm) result = set_vcpuid_sgx(vm); break; /* These features are disabled */ - /* PMU is not supported */ + /* PMU is not supported except for core partition VM, like RTVM */ case 0x0aU: + if (is_lapic_pt_configured(vm)) { + init_vcpuid_entry(i, 0U, 0U, &entry); + result = set_vcpuid_entry(vm, &entry); + } + break; + /* Intel RDT */ case 0x0fU: case 0x10U: diff --git a/hypervisor/arch/x86/guest/vmcs.c b/hypervisor/arch/x86/guest/vmcs.c index 10fb0f404..228587f01 100644 --- a/hypervisor/arch/x86/guest/vmcs.c +++ b/hypervisor/arch/x86/guest/vmcs.c @@ -305,9 +305,12 @@ static void init_exec_ctrl(struct acrn_vcpu *vcpu) value32 &= ~VMX_PROCBASED_CTLS_INVLPG; /* - * Enable VM_EXIT for rdpmc execution. + * Enable VM_EXIT for rdpmc execution except core partition VM, like RTVM */ - value32 |= VMX_PROCBASED_CTLS_RDPMC; + if (!is_lapic_pt_configured(vcpu->vm)) { + value32 |= VMX_PROCBASED_CTLS_RDPMC; + } + vcpu->arch.proc_vm_exec_ctrls = value32; exec_vmwrite32(VMX_PROC_VM_EXEC_CONTROLS, value32); pr_dbg("VMX_PROC_VM_EXEC_CONTROLS: 0x%x ", value32); diff --git a/hypervisor/arch/x86/guest/vmsr.c b/hypervisor/arch/x86/guest/vmsr.c index 679922654..d0fcd1eb7 100644 --- a/hypervisor/arch/x86/guest/vmsr.c +++ b/hypervisor/arch/x86/guest/vmsr.c @@ -96,6 +96,41 @@ static const uint32_t mtrr_msrs[] = { MSR_IA32_MTRR_FIX4K_F8000 }; +/* Performance Counters and Events: CPUID.0AH.EAX[15:8] */ +static const uint32_t pmc_msrs[] = { + MSR_IA32_PMC0, + MSR_IA32_PMC1, + MSR_IA32_PMC2, + MSR_IA32_PMC3, + MSR_IA32_PMC4, + MSR_IA32_PMC5, + MSR_IA32_PMC6, + MSR_IA32_PMC7, + MSR_IA32_PERFEVTSEL0, + MSR_IA32_PERFEVTSEL1, + MSR_IA32_PERFEVTSEL2, + MSR_IA32_PERFEVTSEL3, + MSR_IA32_A_PMC0, + MSR_IA32_A_PMC1, + MSR_IA32_A_PMC2, + MSR_IA32_A_PMC3, + MSR_IA32_A_PMC4, + MSR_IA32_A_PMC5, + MSR_IA32_A_PMC6, + MSR_IA32_A_PMC7, + /* CPUID.0AH.EAX[7:0] */ + MSR_IA32_FIXED_CTR_CTL, + MSR_IA32_PERF_GLOBAL_STATUS, + MSR_IA32_PERF_GLOBAL_CTRL, + MSR_IA32_PERF_GLOBAL_OVF_CTRL, + MSR_IA32_PERF_GLOBAL_STATUS_SET, + MSR_IA32_PERF_GLOBAL_INUSE, + /* CPUID.0AH.EDX[4:0] */ + MSR_IA32_FIXED_CTR0, + MSR_IA32_FIXED_CTR1, + MSR_IA32_FIXED_CTR2 +}; + /* Following MSRs are intercepted, but it throws GPs for any guest accesses */ static const uint32_t unsupported_msrs[] = { /* Variable MTRRs are not supported */ @@ -134,39 +169,6 @@ static const uint32_t unsupported_msrs[] = { MSR_SGXOWNEREPOCH0, MSR_SGXOWNEREPOCH1, - /* Performance Counters and Events: CPUID.0AH.EAX[15:8] */ - MSR_IA32_PMC0, - MSR_IA32_PMC1, - MSR_IA32_PMC2, - MSR_IA32_PMC3, - MSR_IA32_PMC4, - MSR_IA32_PMC5, - MSR_IA32_PMC6, - MSR_IA32_PMC7, - MSR_IA32_PERFEVTSEL0, - MSR_IA32_PERFEVTSEL1, - MSR_IA32_PERFEVTSEL2, - MSR_IA32_PERFEVTSEL3, - MSR_IA32_A_PMC0, - MSR_IA32_A_PMC1, - MSR_IA32_A_PMC2, - MSR_IA32_A_PMC3, - MSR_IA32_A_PMC4, - MSR_IA32_A_PMC5, - MSR_IA32_A_PMC6, - MSR_IA32_A_PMC7, - /* CPUID.0AH.EAX[7:0] */ - MSR_IA32_FIXED_CTR_CTL, - MSR_IA32_PERF_GLOBAL_STATUS, - MSR_IA32_PERF_GLOBAL_CTRL, - MSR_IA32_PERF_GLOBAL_OVF_CTRL, - MSR_IA32_PERF_GLOBAL_STATUS_SET, - MSR_IA32_PERF_GLOBAL_INUSE, - /* CPUID.0AH.EDX[4:0] */ - MSR_IA32_FIXED_CTR0, - MSR_IA32_FIXED_CTR1, - MSR_IA32_FIXED_CTR2, - /* QOS Configuration disabled: CPUID.10H.ECX[2] */ MSR_IA32_L3_QOS_CFG, MSR_IA32_L2_QOS_CFG, @@ -367,6 +369,13 @@ void init_msr_emulation(struct acrn_vcpu *vcpu) enable_msr_interception(msr_bitmap, mtrr_msrs[i], INTERCEPT_READ_WRITE); } + /* for core partition VM (like RTVM), passthrou PMC MSRs for performance profiling/tuning; hide to other VMs */ + if (!is_lapic_pt_configured(vcpu->vm)) { + for (i = 0U; i < ARRAY_SIZE(pmc_msrs); i++) { + enable_msr_interception(msr_bitmap, pmc_msrs[i], INTERCEPT_READ_WRITE); + } + } + intercept_x2apic_msrs(msr_bitmap, INTERCEPT_READ_WRITE); for (i = 0U; i < ARRAY_SIZE(unsupported_msrs); i++) {