diff options
-rw-r--r-- | arch/x86/include/asm/msr-index.h | 1 | ||||
-rw-r--r-- | arch/x86/oprofile/op_model_amd.c | 26 |
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 | ||
60 | struct ibs_state { | 61 | struct 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 | ||
64 | static struct ibs_config ibs_config; | 67 | static 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; |