mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-07-31 23:38:24 +00:00
profiling: split profiling_vmexit_handler into two functions
This patch fixes incorrect vm_id captured when sampling PMU data. Currently, the vm_id gets attributed to ACRN hypervisor, rather than actual guest vm_id. The issue is identified that the existing code captures the guest vm info after vmexit_hander function is completed, in which the profiling module points its context to VMM. When the vmexit happens by PMI, the guest context should be captured so that the attribution to proper guest vm can happen. This change will also allow to capture more accurate TSC when vmexit happens. Tracked-On: #2043 Signed-off-by: Min Lim <min.yeol.lim@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
302494cb80
commit
9e917057e9
@ -70,6 +70,8 @@ void vcpu_thread(struct acrn_vcpu *vcpu)
|
||||
|
||||
vcpu->arch.nrexits++;
|
||||
|
||||
profiling_pre_vmexit_handler(vcpu);
|
||||
|
||||
CPU_IRQ_ENABLE();
|
||||
/* Dispatch handler */
|
||||
ret = vmexit_handler(vcpu);
|
||||
@ -83,6 +85,6 @@ void vcpu_thread(struct acrn_vcpu *vcpu)
|
||||
|
||||
TRACE_2L(TRACE_VM_EXIT, basic_exit_reason, vcpu_get_rip(vcpu));
|
||||
|
||||
profiling_vmexit_handler(vcpu, basic_exit_reason);
|
||||
profiling_post_vmexit_handler(vcpu);
|
||||
} while (1);
|
||||
}
|
||||
|
@ -1305,15 +1305,18 @@ void profiling_vmenter_handler(__unused struct acrn_vcpu *vcpu)
|
||||
/*
|
||||
* Save the VCPU info on vmexit
|
||||
*/
|
||||
void profiling_vmexit_handler(struct acrn_vcpu *vcpu, uint64_t exit_reason)
|
||||
void profiling_pre_vmexit_handler(struct acrn_vcpu *vcpu)
|
||||
{
|
||||
per_cpu(profiling_info.sep_state, vcpu->pcpu_id).total_vmexit_count++;
|
||||
uint64_t exit_reason = 0UL;
|
||||
|
||||
exit_reason = vcpu->arch.exit_reason & 0xFFFFUL;
|
||||
|
||||
if ((get_cpu_var(profiling_info.sep_state).pmu_state == PMU_RUNNING) ||
|
||||
(get_cpu_var(profiling_info.soc_state) == SW_RUNNING)) {
|
||||
|
||||
get_cpu_var(profiling_info.vm_info).vmexit_tsc = rdtsc();
|
||||
get_cpu_var(profiling_info.vm_info).vmexit_reason = exit_reason;
|
||||
get_cpu_var(profiling_info.vm_info).vmexit_reason
|
||||
= exit_reason;
|
||||
if (exit_reason == VMX_EXIT_REASON_EXTERNAL_INTERRUPT) {
|
||||
get_cpu_var(profiling_info.vm_info).external_vector
|
||||
= (int32_t)(exec_vmread(VMX_EXIT_INT_INFO) & 0xFFUL);
|
||||
@ -1330,6 +1333,18 @@ void profiling_vmexit_handler(struct acrn_vcpu *vcpu, uint64_t exit_reason)
|
||||
= exec_vmread64(VMX_GUEST_CS_SEL);
|
||||
|
||||
get_cpu_var(profiling_info.vm_info).guest_vm_id = (int32_t)vcpu->vm->vm_id;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate vmexit data
|
||||
*/
|
||||
void profiling_post_vmexit_handler(struct acrn_vcpu *vcpu)
|
||||
{
|
||||
per_cpu(profiling_info.sep_state, vcpu->pcpu_id).total_vmexit_count++;
|
||||
|
||||
if ((get_cpu_var(profiling_info.sep_state).pmu_state == PMU_RUNNING) ||
|
||||
(get_cpu_var(profiling_info.soc_state) == SW_RUNNING)) {
|
||||
|
||||
/* Generate vmswitch sample */
|
||||
if (((sep_collection_switch &
|
||||
@ -1343,7 +1358,7 @@ void profiling_vmexit_handler(struct acrn_vcpu *vcpu, uint64_t exit_reason)
|
||||
get_cpu_var(profiling_info.vm_switch_trace).vm_exit_tsc
|
||||
= get_cpu_var(profiling_info.vm_info).vmexit_tsc;
|
||||
get_cpu_var(profiling_info.vm_switch_trace).vm_exit_reason
|
||||
= exit_reason;
|
||||
= get_cpu_var(profiling_info.vm_info).vmexit_reason;
|
||||
|
||||
if ((sep_collection_switch &
|
||||
(1UL << (uint64_t)VM_SWITCH_TRACING)) > 0UL) {
|
||||
|
@ -12,7 +12,8 @@
|
||||
#endif
|
||||
|
||||
void profiling_vmenter_handler(struct acrn_vcpu *vcpu);
|
||||
void profiling_vmexit_handler(struct acrn_vcpu *vcpu, uint64_t exit_reason);
|
||||
void profiling_pre_vmexit_handler(struct acrn_vcpu *vcpu);
|
||||
void profiling_post_vmexit_handler(struct acrn_vcpu *vcpu);
|
||||
void profiling_setup(void);
|
||||
|
||||
#endif /* PROFILING_H */
|
||||
|
@ -7,5 +7,6 @@
|
||||
#include <hypervisor.h>
|
||||
|
||||
void profiling_vmenter_handler(__unused struct acrn_vcpu *vcpu) {}
|
||||
void profiling_vmexit_handler(__unused struct acrn_vcpu *vcpu, __unused uint64_t exit_reason) {}
|
||||
void profiling_pre_vmexit_handler(__unused struct acrn_vcpu *vcpu) {}
|
||||
void profiling_post_vmexit_handler(__unused struct acrn_vcpu *vcpu) {}
|
||||
void profiling_setup(void) {}
|
||||
|
Loading…
Reference in New Issue
Block a user