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);