diff options
| -rw-r--r-- | arch/x86/include/asm/perf_event.h | 19 | ||||
| -rw-r--r-- | arch/x86/oprofile/op_model_amd.c | 22 |
2 files changed, 29 insertions, 12 deletions
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h index 6e742cc4251b..550e26b1dbb3 100644 --- a/arch/x86/include/asm/perf_event.h +++ b/arch/x86/include/asm/perf_event.h | |||
| @@ -111,17 +111,18 @@ union cpuid10_edx { | |||
| 111 | #define X86_PMC_IDX_FIXED_BTS (X86_PMC_IDX_FIXED + 16) | 111 | #define X86_PMC_IDX_FIXED_BTS (X86_PMC_IDX_FIXED + 16) |
| 112 | 112 | ||
| 113 | /* IbsFetchCtl bits/masks */ | 113 | /* IbsFetchCtl bits/masks */ |
| 114 | #define IBS_FETCH_RAND_EN (1ULL<<57) | 114 | #define IBS_FETCH_RAND_EN (1ULL<<57) |
| 115 | #define IBS_FETCH_VAL (1ULL<<49) | 115 | #define IBS_FETCH_VAL (1ULL<<49) |
| 116 | #define IBS_FETCH_ENABLE (1ULL<<48) | 116 | #define IBS_FETCH_ENABLE (1ULL<<48) |
| 117 | #define IBS_FETCH_CNT 0xFFFF0000ULL | 117 | #define IBS_FETCH_CNT 0xFFFF0000ULL |
| 118 | #define IBS_FETCH_MAX_CNT 0x0000FFFFULL | 118 | #define IBS_FETCH_MAX_CNT 0x0000FFFFULL |
| 119 | 119 | ||
| 120 | /* IbsOpCtl bits */ | 120 | /* IbsOpCtl bits */ |
| 121 | #define IBS_OP_CNT_CTL (1ULL<<19) | 121 | #define IBS_OP_CNT_CTL (1ULL<<19) |
| 122 | #define IBS_OP_VAL (1ULL<<18) | 122 | #define IBS_OP_VAL (1ULL<<18) |
| 123 | #define IBS_OP_ENABLE (1ULL<<17) | 123 | #define IBS_OP_ENABLE (1ULL<<17) |
| 124 | #define IBS_OP_MAX_CNT 0x0000FFFFULL | 124 | #define IBS_OP_MAX_CNT 0x0000FFFFULL |
| 125 | #define IBS_OP_MAX_CNT_EXT 0x007FFFFFULL /* not a register bit mask */ | ||
| 125 | 126 | ||
| 126 | #ifdef CONFIG_PERF_EVENTS | 127 | #ifdef CONFIG_PERF_EVENTS |
| 127 | extern void init_hw_perf_events(void); | 128 | extern void init_hw_perf_events(void); |
diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c index 9de33fa9531a..65f0a1eb6b86 100644 --- a/arch/x86/oprofile/op_model_amd.c +++ b/arch/x86/oprofile/op_model_amd.c | |||
| @@ -83,6 +83,7 @@ static struct ibs_state ibs_state; | |||
| 83 | #define IBS_CAPS_RDWROPCNT (1U<<3) | 83 | #define IBS_CAPS_RDWROPCNT (1U<<3) |
| 84 | #define IBS_CAPS_OPCNT (1U<<4) | 84 | #define IBS_CAPS_OPCNT (1U<<4) |
| 85 | #define IBS_CAPS_BRNTRGT (1U<<5) | 85 | #define IBS_CAPS_BRNTRGT (1U<<5) |
| 86 | #define IBS_CAPS_OPCNTEXT (1U<<6) | ||
| 86 | 87 | ||
| 87 | #define IBS_CAPS_DEFAULT (IBS_CAPS_AVAIL \ | 88 | #define IBS_CAPS_DEFAULT (IBS_CAPS_AVAIL \ |
| 88 | | IBS_CAPS_FETCHSAM \ | 89 | | IBS_CAPS_FETCHSAM \ |
| @@ -246,8 +247,16 @@ static inline void op_amd_start_ibs(void) | |||
| 246 | 247 | ||
| 247 | memset(&ibs_state, 0, sizeof(ibs_state)); | 248 | memset(&ibs_state, 0, sizeof(ibs_state)); |
| 248 | 249 | ||
| 250 | /* | ||
| 251 | * Note: Since the max count settings may out of range we | ||
| 252 | * write back the actual used values so that userland can read | ||
| 253 | * it. | ||
| 254 | */ | ||
| 255 | |||
| 249 | if (ibs_config.fetch_enabled) { | 256 | if (ibs_config.fetch_enabled) { |
| 250 | val = (ibs_config.max_cnt_fetch >> 4) & IBS_FETCH_MAX_CNT; | 257 | val = ibs_config.max_cnt_fetch >> 4; |
| 258 | val = min(val, IBS_FETCH_MAX_CNT); | ||
| 259 | ibs_config.max_cnt_fetch = val << 4; | ||
| 251 | val |= ibs_config.rand_en ? IBS_FETCH_RAND_EN : 0; | 260 | val |= ibs_config.rand_en ? IBS_FETCH_RAND_EN : 0; |
| 252 | val |= IBS_FETCH_ENABLE; | 261 | val |= IBS_FETCH_ENABLE; |
| 253 | wrmsrl(MSR_AMD64_IBSFETCHCTL, val); | 262 | wrmsrl(MSR_AMD64_IBSFETCHCTL, val); |
| @@ -261,6 +270,7 @@ static inline void op_amd_start_ibs(void) | |||
| 261 | * op_amd_randomize_ibs_op() for details. | 270 | * op_amd_randomize_ibs_op() for details. |
| 262 | */ | 271 | */ |
| 263 | val = clamp(val, 0x0081ULL, 0xFF80ULL); | 272 | val = clamp(val, 0x0081ULL, 0xFF80ULL); |
| 273 | ibs_config.max_cnt_op = val << 4; | ||
| 264 | } else { | 274 | } else { |
| 265 | /* | 275 | /* |
| 266 | * The start value is randomized with a | 276 | * The start value is randomized with a |
| @@ -268,9 +278,15 @@ static inline void op_amd_start_ibs(void) | |||
| 268 | * with the half of the randomized range. Also | 278 | * with the half of the randomized range. Also |
| 269 | * avoid underflows. | 279 | * avoid underflows. |
| 270 | */ | 280 | */ |
| 271 | val = min(val + IBS_RANDOM_MAXCNT_OFFSET, | 281 | val += IBS_RANDOM_MAXCNT_OFFSET; |
| 272 | IBS_OP_MAX_CNT); | 282 | if (ibs_caps & IBS_CAPS_OPCNTEXT) |
| 283 | val = min(val, IBS_OP_MAX_CNT_EXT); | ||
| 284 | else | ||
| 285 | val = min(val, IBS_OP_MAX_CNT); | ||
| 286 | ibs_config.max_cnt_op = | ||
| 287 | (val - IBS_RANDOM_MAXCNT_OFFSET) << 4; | ||
| 273 | } | 288 | } |
| 289 | val = ((val & ~IBS_OP_MAX_CNT) << 4) | (val & IBS_OP_MAX_CNT); | ||
| 274 | val |= ibs_config.dispatched_ops ? IBS_OP_CNT_CTL : 0; | 290 | val |= ibs_config.dispatched_ops ? IBS_OP_CNT_CTL : 0; |
| 275 | val |= IBS_OP_ENABLE; | 291 | val |= IBS_OP_ENABLE; |
| 276 | ibs_state.ibs_op_ctl = val; | 292 | ibs_state.ibs_op_ctl = val; |
