aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/msr-index.h1
-rw-r--r--arch/x86/oprofile/op_model_amd.c26
2 files changed, 21 insertions, 6 deletions
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 986f7790fdb2..91ba8e6b630a 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -121,6 +121,7 @@
121#define MSR_AMD64_IBSDCLINAD 0xc0011038 121#define MSR_AMD64_IBSDCLINAD 0xc0011038
122#define MSR_AMD64_IBSDCPHYSAD 0xc0011039 122#define MSR_AMD64_IBSDCPHYSAD 0xc0011039
123#define MSR_AMD64_IBSCTL 0xc001103a 123#define MSR_AMD64_IBSCTL 0xc001103a
124#define MSR_AMD64_IBSBRTARGET 0xc001103b
124 125
125/* Fam 10h MSRs */ 126/* Fam 10h MSRs */
126#define MSR_FAM10H_MMIO_CONF_BASE 0xc0010058 127#define MSR_FAM10H_MMIO_CONF_BASE 0xc0010058
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;