hv: expose PEBS capability and MSR as PMU_PT flag

Requirement: in CPU partition VM (RTVM), vtune or perf can be used to
sample hotspot code path to tune the RT performance, It need support
PMU/PEBS (Processor Event Based Sampling). Intel TCC asks for it, too.

It exposes PEBS related capabilities/features and MSRs to CPU
partition VM, like RTVM. PEBS is a part of PMU. Also PEBS needs
DS (Debug Store) feature to support. So DS is exposed too.

Limitation: current it just support PEBS feature in VM level, when CPU
traps to HV, the performance counter will stop. Perf global control
MSR is used to do this work. So, the counters shall be close to native.

Tracked-On: #6966
Acked-by: Anthony Xu <anthony.xu@intel.com>
Signed-off-by: Minggui Cao <minggui.cao@intel.com>
This commit is contained in:
Minggui Cao 2021-12-13 15:16:14 +08:00 committed by acrnsi-robot
parent 299c56bb68
commit b3bd153180
4 changed files with 31 additions and 18 deletions

View File

@ -558,7 +558,7 @@ int32_t set_vcpuid_entries(struct acrn_vm *vm)
/* These features are disabled */
/* PMU is not supported except for core partition VM, like RTVM */
case 0x0aU:
if (is_lapic_pt_configured(vm)) {
if (is_pmu_pt_configured(vm)) {
init_vcpuid_entry(i, 0U, 0U, &entry);
result = set_vcpuid_entry(vm, &entry);
}
@ -625,15 +625,9 @@ static void guest_cpuid_01h(struct acrn_vcpu *vcpu, uint32_t *eax, uint32_t *ebx
*edx &= ~CPUID_EDX_MTRR;
}
/* mask Debug Store feature */
*ecx &= ~(CPUID_ECX_DTES64 | CPUID_ECX_DS_CPL);
/* mask Safer Mode Extension */
*ecx &= ~CPUID_ECX_SMX;
/* mask PDCM: Perfmon and Debug Capability */
*ecx &= ~CPUID_ECX_PDCM;
/* mask SDBG for silicon debug */
*ecx &= ~CPUID_ECX_SDBG;
@ -693,8 +687,17 @@ static void guest_cpuid_01h(struct acrn_vcpu *vcpu, uint32_t *eax, uint32_t *ebx
*edx &= ~CPUID_EDX_FXSR;
}
/* mask Debug Store feature */
*edx &= ~CPUID_EDX_DTES;
/* DS/PEBS is not supported except for core partition VM, like RTVM */
if (!is_pmu_pt_configured(vcpu->vm)) {
/* mask Debug Store feature */
*ecx &= ~(CPUID_ECX_DTES64 | CPUID_ECX_DS_CPL);
/* mask PDCM: Perfmon and Debug Capability */
*ecx &= ~CPUID_ECX_PDCM;
/* mask Debug Store feature */
*edx &= ~CPUID_EDX_DTES;
}
}
static void guest_cpuid_0bh(struct acrn_vcpu *vcpu, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)

View File

@ -307,7 +307,7 @@ static void init_exec_ctrl(struct acrn_vcpu *vcpu)
/*
* Enable VM_EXIT for rdpmc execution except core partition VM, like RTVM
*/
if (!is_lapic_pt_configured(vcpu->vm)) {
if (!is_pmu_pt_configured(vcpu->vm)) {
value32 |= VMX_PROCBASED_CTLS_RDPMC;
}

View File

@ -148,7 +148,13 @@ static const uint32_t pmc_msrs[] = {
/* CPUID.0AH.EDX[4:0] */
MSR_IA32_FIXED_CTR0,
MSR_IA32_FIXED_CTR1,
MSR_IA32_FIXED_CTR2
MSR_IA32_FIXED_CTR2,
/* Performance Monitoring: CPUID.01H.ECX[15] X86_FEATURE_PDCM */
MSR_IA32_PERF_CAPABILITIES,
/* Debug Store disabled: CPUID.01H.EDX[21] X86_FEATURE_DTES */
MSR_IA32_DS_AREA,
};
/* Following MSRs are intercepted, but it throws GPs for any guest accesses */
@ -223,12 +229,6 @@ static const uint32_t unsupported_msrs[] = {
/* Silicon Debug Feature: CPUID.01H.ECX[11] (X86_FEATURE_SDBG) */
MSR_IA32_DEBUG_INTERFACE,
/* Performance Monitoring: CPUID.01H.ECX[15] X86_FEATURE_PDCM */
MSR_IA32_PERF_CAPABILITIES,
/* Debug Store disabled: CPUID.01H.EDX[21] X86_FEATURE_DTES */
MSR_IA32_DS_AREA,
/* Machine Check Exception: CPUID.01H.EDX[5] (X86_FEATURE_MCE) */
MSR_IA32_MCG_CAP,
MSR_IA32_MCG_STATUS,
@ -331,6 +331,15 @@ static void prepare_auto_msr_area(struct acrn_vcpu *vcpu)
{
vcpu->arch.msr_area.count = 0U;
/* in HV, disable perf/PMC counting, just count in guest VM */
if (is_pmu_pt_configured(vcpu->vm)) {
vcpu->arch.msr_area.guest[MSR_AREA_PERF_CTRL].msr_index = MSR_IA32_PERF_GLOBAL_CTRL;
vcpu->arch.msr_area.guest[MSR_AREA_PERF_CTRL].value = 0;
vcpu->arch.msr_area.host[MSR_AREA_PERF_CTRL].msr_index = MSR_IA32_PERF_GLOBAL_CTRL;
vcpu->arch.msr_area.host[MSR_AREA_PERF_CTRL].value = 0;
vcpu->arch.msr_area.count++;
}
if (is_platform_rdt_capable()) {
struct acrn_vm_config *cfg = get_vm_config(vcpu->vm->vm_id);
uint16_t vcpu_clos;
@ -472,7 +481,7 @@ void init_msr_emulation(struct acrn_vcpu *vcpu)
}
/* for core partition VM (like RTVM), passthrou PMC MSRs for performance profiling/tuning; hide to other VMs */
if (!is_lapic_pt_configured(vcpu->vm)) {
if (!is_pmu_pt_configured(vcpu->vm)) {
for (i = 0U; i < ARRAY_SIZE(pmc_msrs); i++) {
enable_msr_interception(msr_bitmap, pmc_msrs[i], INTERCEPT_READ_WRITE);
}

View File

@ -214,6 +214,7 @@ struct msr_store_entry {
enum {
MSR_AREA_IA32_PQR_ASSOC = 0,
MSR_AREA_PERF_CTRL,
MSR_AREA_COUNT,
};