[PATCH 1/2] hv: pass-thru PMU registers when no PROFILING_ON

Min He min.he at intel.com
Fri Feb 15 01:42:03 UTC 2019


In debug version, when disabling PROFILING, we will pass-thru the
PMU registers to allow perf tool to be run in UOS directly.
Also, a PMI interrupt handler is registered to send the PMI interrupts
to the UOS through VLAPIC.

Signed-off-by: Min He <min.he at intel.com>
---
 hypervisor/arch/x86/guest/vcpuid.c |  2 ++
 hypervisor/arch/x86/guest/vmsr.c   |  2 ++
 hypervisor/debug/hypercall.c       |  8 +++++++
 hypervisor/debug/profiling.c       | 35 ++++++++++++++++++++++++++++++
 4 files changed, 47 insertions(+)

diff --git a/hypervisor/arch/x86/guest/vcpuid.c b/hypervisor/arch/x86/guest/vcpuid.c
index db38242b..e20d2f35 100644
--- a/hypervisor/arch/x86/guest/vcpuid.c
+++ b/hypervisor/arch/x86/guest/vcpuid.c
@@ -230,8 +230,10 @@ int32_t set_vcpuid_entries(struct acrn_vm *vm)
 				break;
 
 			/* These features are disabled */
+#ifdef PROFILING_ON
 			/* PMU is not supported */
 			case 0x0aU:
+#endif /* PROFILING_ON */
 			/* Intel RDT */
 			case 0x0fU:
 			case 0x10U:
diff --git a/hypervisor/arch/x86/guest/vmsr.c b/hypervisor/arch/x86/guest/vmsr.c
index 873c36bc..bdc629bc 100644
--- a/hypervisor/arch/x86/guest/vmsr.c
+++ b/hypervisor/arch/x86/guest/vmsr.c
@@ -114,6 +114,7 @@ static const uint32_t unsupported_msrs[NUM_UNSUPPORTED_MSRS] = {
 	MSR_SGXOWNEREPOCH0,
 	MSR_SGXOWNEREPOCH1,
 
+#ifdef PROFILING_ON
 	/* Performance Counters and Events: CPUID.0AH.EAX[15:8] */
 	MSR_IA32_PMC0,
 	MSR_IA32_PMC1,
@@ -146,6 +147,7 @@ static const uint32_t unsupported_msrs[NUM_UNSUPPORTED_MSRS] = {
 	MSR_IA32_FIXED_CTR0,
 	MSR_IA32_FIXED_CTR1,
 	MSR_IA32_FIXED_CTR2,
+#endif /* PROFILING_ON */
 
 	/* QOS Configuration disabled: CPUID.10H.ECX[2] */
 	MSR_IA32_L3_QOS_CFG,
diff --git a/hypervisor/debug/hypercall.c b/hypervisor/debug/hypercall.c
index f20f43d3..32e90ce2 100644
--- a/hypervisor/debug/hypercall.c
+++ b/hypervisor/debug/hypercall.c
@@ -61,6 +61,14 @@ static int32_t hcall_profiling_ops(struct acrn_vm *vm, uint64_t cmd, uint64_t pa
 	}
  	return ret;
 }
+
+#else
+
+static int32_t hcall_profiling_ops(__unused struct acrn_vm *vm, __unused uint64_t cmd, __unused uint64_t param)
+{
+	return -EPERM;
+}
+
 #endif /* PROFILING_ON */
 
 /**
diff --git a/hypervisor/debug/profiling.c b/hypervisor/debug/profiling.c
index 41afff60..3f261966 100644
--- a/hypervisor/debug/profiling.c
+++ b/hypervisor/debug/profiling.c
@@ -1455,4 +1455,39 @@ void profiling_setup(void)
 	dev_dbg(ACRN_DBG_PROFILING, "%s: exiting", __func__);
 }
 
+#else
+
+#include <hypervisor.h>
+
+void profiling_vmenter_handler(__unused struct acrn_vcpu *vcpu) {}
+void profiling_pre_vmexit_handler(__unused struct acrn_vcpu *vcpu) {}
+void profiling_post_vmexit_handler(__unused struct acrn_vcpu *vcpu) {}
+
+static void pmu_passthru_pmi_handler(__unused uint32_t irq, __unused void *data)
+{
+	struct acrn_vcpu *vcpu = get_ever_run_vcpu(get_cpu_id());
+
+	msr_write(MSR_IA32_EXT_APIC_LVT_PMI, VECTOR_PMI|LAPIC_LVT_MASK);
+	vlapic_set_local_intr(vcpu->vm, vcpu->vcpu_id, APIC_LVT_PMC);
+	msr_write(MSR_IA32_EXT_APIC_LVT_PMI, VECTOR_PMI);
+}
+
+void profiling_setup(void)
+{
+	uint16_t cpu;
+	int32_t retval;
+
+	cpu = get_cpu_id();
+	if (cpu == BOOT_CPU_ID){
+		retval = request_irq(PMI_IRQ,
+				pmu_passthru_pmi_handler, NULL, IRQF_NONE);
+		if (retval < 0) {
+			pr_err("Failed to add PMI isr");
+			return;
+		}
+	}
+
+	msr_write(MSR_IA32_EXT_APIC_LVT_PMI, VECTOR_PMI);
+}
+
 #endif
-- 
2.17.0



More information about the intel-gvt-dev mailing list