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; |
