From 192581fb368c74307ab89506af03aeb997a9c50a Mon Sep 17 00:00:00 2001
From: Luming Yu <luming.yu@intel.com>
Date: Fri, 29 Sep 2017 22:08:33 +0800
Subject: [PATCH v1 5/9] early pt: basic addr pair filter support 

(addr0 && addr1)

Signed-off-by: Luming Yu <luming.yu@intel.com>
---
 arch/x86/events/intel/early_pt.c | 45 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/arch/x86/events/intel/early_pt.c b/arch/x86/events/intel/early_pt.c
index 36b80b1..5335458 100644
--- a/arch/x86/events/intel/early_pt.c
+++ b/arch/x86/events/intel/early_pt.c
@@ -56,6 +56,9 @@ static unsigned cyc_thresh_mask = 0;
 static unsigned mtc_freq_mask = 0;
 static unsigned addr_range_num = 0;
 
+static unsigned long pt_addr0_start = 0, pt_addr0_end = 0;
+static unsigned long pt_addr1_start = 0, pt_addr1_end = 0;
+
 static int early_pt_buffer_init(int cpu)
 {
 	u64	pt_buffer;
@@ -180,6 +183,20 @@ static int start_early_pt(void *arg)
 	val |= RTIT_CTL_OS;
 	val |= RTIT_CTL_USR;
 
+	{
+		int num = addr_range_num;
+		if (num-- && pt_addr0_start && (pt_addr0_start <= pt_addr0_end)) {
+			val |= ((u64) 0x1 << ADDR0_SHIFT);
+			wrmsrl_safe(MSR_IA32_RTIT_ADDR0_A, pt_addr0_start);
+			wrmsrl_safe(MSR_IA32_RTIT_ADDR0_B, pt_addr0_end);
+		}
+		if (num-- && pt_addr1_start && (pt_addr1_start <= pt_addr1_end)) {
+			val |= ((u64) 0x1 << ADDR1_SHIFT);
+			wrmsrl_safe(MSR_IA32_RTIT_ADDR1_A, pt_addr1_start);
+			wrmsrl_safe(MSR_IA32_RTIT_ADDR1_B, pt_addr1_end);
+		}
+	}
+
 	if (wrmsrl_safe(MSR_IA32_RTIT_CTL, val) < 0) {
 		pr_info("early_pt start failed on cpu[%d]\n", cpu);
 		__this_cpu_write(early_pt_running, false);
@@ -356,3 +373,31 @@ static int __init early_pt_buf_len_setup(char *str)
 	return 0;
 }
 early_param("early_pt_buf_len", early_pt_buf_len_setup);
+
+static int __init early_pt_addr0_start_setup(char *arg)
+{
+	sscanf(arg, "%lx", &pt_addr0_start);
+	pr_info("pt_addr0_start = %lx\n", pt_addr0_start);
+	return 0;
+}
+early_param("early_pt_addr0_start", early_pt_addr0_start_setup);
+static int __init early_pt_addr0_end_setup(char *arg)
+{
+	sscanf(arg, "%lx", &pt_addr0_end);
+	pr_info("pt_addr0_end = %lx\n", pt_addr0_end);
+	return 0;
+}
+early_param("early_pt_addr0_end", early_pt_addr0_end_setup);
+
+static int __init early_pt_addr1_start_setup(char *arg)
+{
+	sscanf(arg, "%lu", &pt_addr1_start);
+	return 0;
+}
+early_param("early_pt_addr1_start", early_pt_addr1_start_setup);
+static int __init early_pt_addr1_end_setup(char *arg)
+{
+	sscanf(arg, "%lu", &pt_addr1_end);
+	return 0;
+}
+early_param("early_pt_addr1_end", early_pt_addr1_end_setup);
-- 
2.7.5

