From e37b86ed2c5aa9cae9f5c3c1c5489348323ee481 Mon Sep 17 00:00:00 2001
From: Luming Yu <luming.yu@intel.com>
Date: Fri, 29 Sep 2017 22:12:59 +0800
Subject: [PATCH v1 9/9] early pt: early start intel processor trace in early boot

enable intel PT to trace kernel boot && runtime 

Signed-off-by: Luming Yu <luming.yu@intel.com>
---
 arch/x86/events/intel/early_pt.c | 19 +++++++++++++------
 arch/x86/kernel/smpboot.c        |  2 ++
 init/main.c                      |  2 ++
 3 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/arch/x86/events/intel/early_pt.c b/arch/x86/events/intel/early_pt.c
index 95225d6..253aa3d 100644
--- a/arch/x86/events/intel/early_pt.c
+++ b/arch/x86/events/intel/early_pt.c
@@ -140,11 +140,13 @@ static int early_pt_cpuid_caps(void)
 	}
 	return 0;
 }
-static int start_early_pt(void *arg)
+int start_early_pt(void *arg)
 {
 	u64 val, oldval;
 	int cpu;
 
+	if (__this_cpu_read(early_pt_running))
+		return 0;
 
 	if (rdmsrl_safe(MSR_IA32_RTIT_CTL, &val) < 0) {
 		pr_info("start_early_pt: failed\n");
@@ -220,6 +222,7 @@ static int start_early_pt(void *arg)
 	__this_cpu_write(early_pt_running, true);
 	return 0;
 }
+EXPORT_SYMBOL(start_early_pt);
 
 static void start_pt_no_return(void *arg)
 {
@@ -229,20 +232,24 @@ static void start_pt_no_return(void *arg)
 
 static struct miscdevice early_pt_miscdev;
 
-static int early_pt_init(void)
+int early_pt_init(void)
 {
 	int err;
 
 	if (!early_pt_enabled)
 		return 0;
-	err = early_pt_cpuid_caps();
-	if (err < 0) {
-		pr_info("early_pt_init: no feature available\n");
-		return err;
+	if (!__this_cpu_read(early_pt_running)) {
+		err = early_pt_cpuid_caps();
+		if (err < 0) {
+			pr_info("early_pt_init: no feature available\n");
+			return err;
+		}
 	}
 	on_each_cpu(start_pt_no_return, NULL, 0);
 	return 0;
 }
+EXPORT_SYMBOL(early_pt_init);
+
 static int late_pt_init(void)
 {
 	int err;
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 54b9e89..fd366ed 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -220,6 +220,7 @@ static void smp_callin(void)
 
 static int cpu0_logical_apicid;
 static int enable_start_cpu0;
+extern int start_early_pt(void *);
 /*
  * Activate a secondary processor.
  */
@@ -231,6 +232,7 @@ static void notrace start_secondary(void *unused)
 	 * most necessary things.
 	 */
 	cpu_init();
+	start_early_pt(NULL);
 	x86_cpuinit.early_percpu_clock_init();
 	preempt_disable();
 	smp_callin();
diff --git a/init/main.c b/init/main.c
index c0c7cf0..7792e54 100644
--- a/init/main.c
+++ b/init/main.c
@@ -506,6 +506,7 @@ static void __init mm_init(void)
 	ioremap_huge_init();
 }
 
+extern int early_pt_init(void);
 asmlinkage __visible void __init start_kernel(void)
 {
 	char *command_line;
@@ -567,6 +568,7 @@ asmlinkage __visible void __init start_kernel(void)
 	trap_init();
 	mm_init();
 
+	early_pt_init();
 	ftrace_init();
 
 	/* trace_printk can be enabled here */
-- 
2.7.5

