Skip to content

Commit

Permalink
profiling: fix the system freeze issue when running profiling
Browse files Browse the repository at this point in the history
 tool

The msr load/restore during vmexit/vmenty 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 combines the msr load list for vmexit when profiling.

Tracked-On: #2422
Signed-off-by: Min Lim <min.yeol.lim@intel.com>
  • Loading branch information
mlim19 authored and wenlingz committed Jan 30, 2019
1 parent b963bd5 commit 1de5feb
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 18 deletions.
28 changes: 18 additions & 10 deletions hypervisor/debug/profiling.c
Expand Up @@ -112,18 +112,25 @@ 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
struct acrn_vcpu *vcpu = get_ever_run_vcpu(get_cpu_id());

ss->vmexit_msr_cnt = 1 + MSR_AREA_COUNT;
ss->vmexit_msr_list[0].msr_num
= MSR_IA32_DEBUGCTL;
ss->vmexit_msr_list[0].msr_data
ss->vmexit_msr_list[0].value
= ss->guest_debugctl_value &
VALID_DEBUGCTL_BIT_MASK;

for (i = 0; i < MSR_AREA_COUNT; i++) {
ss->vmexit_msr_list[i + 1].msr_num = vcpu->arch.msr_area.host[i].msr_num;
ss->vmexit_msr_list[i + 1].value = vcpu->arch.msr_area.host[i].value;
}

exec_vmwrite64(VMX_EXIT_MSR_LOAD_ADDR_FULL,
hva2hpa(ss->vmexit_msr_list));
exec_vmwrite(VMX_EXIT_MSR_LOAD_COUNT,
exec_vmwrite32(VMX_EXIT_MSR_LOAD_COUNT,
(uint64_t)ss->vmexit_msr_cnt);
}

Expand Down Expand Up @@ -171,11 +178,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, (uint64_t)vcpu->arch.msr_area.host);
exec_vmwrite32(VMX_EXIT_MSR_LOAD_COUNT, MSR_AREA_COUNT);

ss->vmexit_msr_cnt = 0;
}
Expand Down
14 changes: 6 additions & 8 deletions hypervisor/include/debug/profiling_internal.h
Expand Up @@ -9,7 +9,11 @@

#ifdef PROFILING_ON

#define MAX_MSR_LIST_NUM 15U
#include <vcpu.h>

#define MAX_MSR_LIST_NUM 15U
#define MAX_PROFILING_MSR_LIST_NUM (MAX_MSR_LIST_NUM)
#define MAX_HV_MSR_LIST_NUM (MSR_AREA_COUNT)
#define MAX_GROUP_NUM 1U

#define COLLECT_PROFILE_DATA 0
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -210,7 +208,7 @@ struct sep_state {
uint32_t frozen_delayed;
uint32_t nofrozen_pmi;

struct vmexit_msr vmexit_msr_list[MAX_MSR_LIST_NUM];
struct msr_store_entry vmexit_msr_list[MAX_PROFILING_MSR_LIST_NUM + MAX_HV_MSR_LIST_NUM];
int32_t vmexit_msr_cnt;
uint64_t guest_debugctl_value;
uint64_t saved_debugctl_value;
Expand Down

0 comments on commit 1de5feb

Please sign in to comment.