aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/oprofile
diff options
context:
space:
mode:
authorRobert Richter <robert.richter@amd.com>2010-09-21 09:49:31 -0400
committerRobert Richter <robert.richter@amd.com>2010-10-15 06:50:42 -0400
commit25da6950475becb35d7a3bb3b5fbdc715a76887e (patch)
treece77e751ee711b08ddc5fd3cc6e159a093676b5b /arch/x86/oprofile
parent53b39e9480ef8a286cef9899c455a979acd0eed9 (diff)
oprofile, x86: Add support for IBS branch target address reporting
This patch adds support for IBS branch target address reporting. A new MSR (MSRC001_103B IBS Branch Target Address) has been added that provides the logical address in canonical form for the branch target. The size of the IBS sample that is transferred to the userland has been increased. For backward compatibility, the userland daemon must explicit enable the feature by writing to the oprofilefs file ibs_op/branch_target After enabling branch target address reporting, the userland daemon must handle the extended size of the IBS sample. Signed-off-by: Robert Richter <robert.richter@amd.com>
Diffstat (limited to 'arch/x86/oprofile')
-rw-r--r--arch/x86/oprofile/op_model_amd.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c
index 9d4509736772..9de33fa9531a 100644
--- a/arch/x86/oprofile/op_model_amd.c
+++ b/arch/x86/oprofile/op_model_amd.c
@@ -55,10 +55,13 @@ struct ibs_config {
55 unsigned long max_cnt_op; 55 unsigned long max_cnt_op;
56 unsigned long rand_en; 56 unsigned long rand_en;
57 unsigned long dispatched_ops; 57 unsigned long dispatched_ops;
58 unsigned long branch_target;
58}; 59};
59 60
60struct ibs_state { 61struct ibs_state {
61 u64 ibs_op_ctl; 62 u64 ibs_op_ctl;
63 int branch_target;
64 unsigned long sample_size;
62}; 65};
63 66
64static struct ibs_config ibs_config; 67static struct ibs_config ibs_config;
@@ -79,6 +82,7 @@ static struct ibs_state ibs_state;
79#define IBS_CAPS_OPSAM (1U<<2) 82#define IBS_CAPS_OPSAM (1U<<2)
80#define IBS_CAPS_RDWROPCNT (1U<<3) 83#define IBS_CAPS_RDWROPCNT (1U<<3)
81#define IBS_CAPS_OPCNT (1U<<4) 84#define IBS_CAPS_OPCNT (1U<<4)
85#define IBS_CAPS_BRNTRGT (1U<<5)
82 86
83#define IBS_CAPS_DEFAULT (IBS_CAPS_AVAIL \ 87#define IBS_CAPS_DEFAULT (IBS_CAPS_AVAIL \
84 | IBS_CAPS_FETCHSAM \ 88 | IBS_CAPS_FETCHSAM \
@@ -207,8 +211,8 @@ op_amd_handle_ibs(struct pt_regs * const regs,
207 rdmsrl(MSR_AMD64_IBSOPCTL, ctl); 211 rdmsrl(MSR_AMD64_IBSOPCTL, ctl);
208 if (ctl & IBS_OP_VAL) { 212 if (ctl & IBS_OP_VAL) {
209 rdmsrl(MSR_AMD64_IBSOPRIP, val); 213 rdmsrl(MSR_AMD64_IBSOPRIP, val);
210 oprofile_write_reserve(&entry, regs, val, 214 oprofile_write_reserve(&entry, regs, val, IBS_OP_CODE,
211 IBS_OP_CODE, IBS_OP_SIZE); 215 ibs_state.sample_size);
212 oprofile_add_data64(&entry, val); 216 oprofile_add_data64(&entry, val);
213 rdmsrl(MSR_AMD64_IBSOPDATA, val); 217 rdmsrl(MSR_AMD64_IBSOPDATA, val);
214 oprofile_add_data64(&entry, val); 218 oprofile_add_data64(&entry, val);
@@ -220,6 +224,10 @@ op_amd_handle_ibs(struct pt_regs * const regs,
220 oprofile_add_data64(&entry, val); 224 oprofile_add_data64(&entry, val);
221 rdmsrl(MSR_AMD64_IBSDCPHYSAD, val); 225 rdmsrl(MSR_AMD64_IBSDCPHYSAD, val);
222 oprofile_add_data64(&entry, val); 226 oprofile_add_data64(&entry, val);
227 if (ibs_state.branch_target) {
228 rdmsrl(MSR_AMD64_IBSBRTARGET, val);
229 oprofile_add_data(&entry, (unsigned long)val);
230 }
223 oprofile_write_commit(&entry); 231 oprofile_write_commit(&entry);
224 232
225 /* reenable the IRQ */ 233 /* reenable the IRQ */
@@ -266,6 +274,11 @@ static inline void op_amd_start_ibs(void)
266 val |= ibs_config.dispatched_ops ? IBS_OP_CNT_CTL : 0; 274 val |= ibs_config.dispatched_ops ? IBS_OP_CNT_CTL : 0;
267 val |= IBS_OP_ENABLE; 275 val |= IBS_OP_ENABLE;
268 ibs_state.ibs_op_ctl = val; 276 ibs_state.ibs_op_ctl = val;
277 ibs_state.sample_size = IBS_OP_SIZE;
278 if (ibs_config.branch_target) {
279 ibs_state.branch_target = 1;
280 ibs_state.sample_size++;
281 }
269 val = op_amd_randomize_ibs_op(ibs_state.ibs_op_ctl); 282 val = op_amd_randomize_ibs_op(ibs_state.ibs_op_ctl);
270 wrmsrl(MSR_AMD64_IBSOPCTL, val); 283 wrmsrl(MSR_AMD64_IBSOPCTL, val);
271 } 284 }
@@ -540,11 +553,9 @@ static int setup_ibs_files(struct super_block *sb, struct dentry *root)
540 /* model specific files */ 553 /* model specific files */
541 554
542 /* setup some reasonable defaults */ 555 /* setup some reasonable defaults */
556 memset(&ibs_config, 0, sizeof(ibs_config));
543 ibs_config.max_cnt_fetch = 250000; 557 ibs_config.max_cnt_fetch = 250000;
544 ibs_config.fetch_enabled = 0;
545 ibs_config.max_cnt_op = 250000; 558 ibs_config.max_cnt_op = 250000;
546 ibs_config.op_enabled = 0;
547 ibs_config.dispatched_ops = 0;
548 559
549 if (ibs_caps & IBS_CAPS_FETCHSAM) { 560 if (ibs_caps & IBS_CAPS_FETCHSAM) {
550 dir = oprofilefs_mkdir(sb, root, "ibs_fetch"); 561 dir = oprofilefs_mkdir(sb, root, "ibs_fetch");
@@ -565,6 +576,9 @@ static int setup_ibs_files(struct super_block *sb, struct dentry *root)
565 if (ibs_caps & IBS_CAPS_OPCNT) 576 if (ibs_caps & IBS_CAPS_OPCNT)
566 oprofilefs_create_ulong(sb, dir, "dispatched_ops", 577 oprofilefs_create_ulong(sb, dir, "dispatched_ops",
567 &ibs_config.dispatched_ops); 578 &ibs_config.dispatched_ops);
579 if (ibs_caps & IBS_CAPS_BRNTRGT)
580 oprofilefs_create_ulong(sb, dir, "branch_target",
581 &ibs_config.branch_target);
568 } 582 }
569 583
570 return 0; 584 return 0;