From 342d29eea8c16f2ccce42d78598c57cfd9eff54e Mon Sep 17 00:00:00 2001 From: Min Lim Date: Wed, 30 Jan 2019 13:58:08 -0800 Subject: [PATCH] profiling: fix the system freeze issue when running profiling tool The msr load/restore during vmexit/vmentry is enabled in HV by default. The profiling has assumption that it's only user for this feature, which could overwrite of HV default setting. This fix combine the msr load list for vmexit when profiling. Tracked-On: #2422 Signed-off-by: Min Lim --- hypervisor/debug/profiling.c | 35 ++++++++++--------- hypervisor/include/debug/profiling_internal.h | 16 ++++----- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/hypervisor/debug/profiling.c b/hypervisor/debug/profiling.c index 1517b08de..41afff600 100644 --- a/hypervisor/debug/profiling.c +++ b/hypervisor/debug/profiling.c @@ -90,6 +90,7 @@ static void profiling_enable_pmu(void) uint32_t lvt_perf_ctr; uint32_t i; uint32_t group_id; + uint32_t size; struct profiling_msr_op *msrop = NULL; struct sep_state *ss = &get_cpu_var(profiling_info.sep_state); @@ -112,19 +113,20 @@ static void profiling_enable_pmu(void) __func__, MSR_IA32_EXT_APIC_LVT_PMI, lvt_perf_ctr); if (ss->guest_debugctl_value != 0U) { - /* Set the VM Exit MSR Load in VMCS */ + /* Merge the msr vmexit loading list with HV */ if (ss->vmexit_msr_cnt == 0) { - ss->vmexit_msr_cnt = 1; - ss->vmexit_msr_list[0].msr_idx - = MSR_IA32_DEBUGCTL; - ss->vmexit_msr_list[0].msr_data - = ss->guest_debugctl_value & - VALID_DEBUGCTL_BIT_MASK; + struct acrn_vcpu *vcpu = get_ever_run_vcpu(get_cpu_id()); - exec_vmwrite64(VMX_EXIT_MSR_LOAD_ADDR_FULL, - hva2hpa(ss->vmexit_msr_list)); - exec_vmwrite(VMX_EXIT_MSR_LOAD_COUNT, - (uint64_t)ss->vmexit_msr_cnt); + size = sizeof(struct msr_store_entry) * MAX_HV_MSR_LIST_NUM; + (void)memcpy_s(ss->vmexit_msr_list, size, vcpu->arch.msr_area.host, size); + ss->vmexit_msr_cnt = MAX_HV_MSR_LIST_NUM; + + ss->vmexit_msr_list[MAX_HV_MSR_LIST_NUM].msr_num = MSR_IA32_DEBUGCTL; + ss->vmexit_msr_list[MAX_HV_MSR_LIST_NUM].value = ss->guest_debugctl_value & VALID_DEBUGCTL_BIT_MASK; + ss->vmexit_msr_cnt++; + + exec_vmwrite64(VMX_EXIT_MSR_LOAD_ADDR_FULL, hva2hpa(ss->vmexit_msr_list)); + exec_vmwrite32(VMX_EXIT_MSR_LOAD_COUNT, ss->vmexit_msr_cnt); } /* VMCS GUEST field */ @@ -171,11 +173,12 @@ static void profiling_disable_pmu(void) __func__, get_cpu_id()); if (ss != NULL) { - if (ss->vmexit_msr_cnt == 1) { - /* Set the VM Exit MSR Load in VMCS */ - exec_vmwrite(VMX_EXIT_MSR_LOAD_COUNT, 0x0U); - exec_vmwrite64(VMX_GUEST_IA32_DEBUGCTL_FULL, - ss->saved_debugctl_value); + if (ss->vmexit_msr_cnt != 0) { + /* Restore the msr exit loading list of HV */ + struct acrn_vcpu *vcpu = get_ever_run_vcpu(get_cpu_id()); + + exec_vmwrite64(VMX_EXIT_MSR_LOAD_ADDR_FULL, hva2hpa(vcpu->arch.msr_area.host)); + exec_vmwrite32(VMX_EXIT_MSR_LOAD_COUNT, MAX_HV_MSR_LIST_NUM); ss->vmexit_msr_cnt = 0; } diff --git a/hypervisor/include/debug/profiling_internal.h b/hypervisor/include/debug/profiling_internal.h index 33d00e29f..bc5e052d1 100644 --- a/hypervisor/include/debug/profiling_internal.h +++ b/hypervisor/include/debug/profiling_internal.h @@ -9,7 +9,11 @@ #ifdef PROFILING_ON -#define MAX_MSR_LIST_NUM 15U +#include + +#define MAX_MSR_LIST_NUM 15U +#define MAX_PROFILING_MSR_STORE_NUM 1 +#define MAX_HV_MSR_LIST_NUM (MSR_AREA_COUNT) #define MAX_GROUP_NUM 1U #define COLLECT_PROFILE_DATA 0 @@ -158,12 +162,6 @@ struct profiling_vmsw_config { struct profiling_msr_op exit_list[MAX_MSR_LIST_NUM]; }; -struct vmexit_msr { - uint32_t msr_idx; - uint32_t reserved; - uint64_t msr_data; -}; - struct guest_vm_info { uint64_t vmenter_tsc; uint64_t vmexit_tsc; @@ -216,8 +214,8 @@ struct sep_state { uint32_t frozen_delayed; uint32_t nofrozen_pmi; - struct vmexit_msr vmexit_msr_list[MAX_MSR_LIST_NUM]; - int32_t vmexit_msr_cnt; + struct msr_store_entry vmexit_msr_list[MAX_PROFILING_MSR_STORE_NUM + MAX_HV_MSR_LIST_NUM]; + uint32_t vmexit_msr_cnt; uint64_t guest_debugctl_value; uint64_t saved_debugctl_value; } __aligned(8);