diff options
-rw-r--r-- | arch/x86/oprofile/op_model_amd.c | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c index d5e9dab71bec..9d4509736772 100644 --- a/arch/x86/oprofile/op_model_amd.c +++ b/arch/x86/oprofile/op_model_amd.c | |||
@@ -48,7 +48,7 @@ static unsigned long reset_value[NUM_VIRT_COUNTERS]; | |||
48 | 48 | ||
49 | static u32 ibs_caps; | 49 | static u32 ibs_caps; |
50 | 50 | ||
51 | struct op_ibs_config { | 51 | struct ibs_config { |
52 | unsigned long op_enabled; | 52 | unsigned long op_enabled; |
53 | unsigned long fetch_enabled; | 53 | unsigned long fetch_enabled; |
54 | unsigned long max_cnt_fetch; | 54 | unsigned long max_cnt_fetch; |
@@ -57,8 +57,12 @@ struct op_ibs_config { | |||
57 | unsigned long dispatched_ops; | 57 | unsigned long dispatched_ops; |
58 | }; | 58 | }; |
59 | 59 | ||
60 | static struct op_ibs_config ibs_config; | 60 | struct ibs_state { |
61 | static u64 ibs_op_ctl; | 61 | u64 ibs_op_ctl; |
62 | }; | ||
63 | |||
64 | static struct ibs_config ibs_config; | ||
65 | static struct ibs_state ibs_state; | ||
62 | 66 | ||
63 | /* | 67 | /* |
64 | * IBS cpuid feature detection | 68 | * IBS cpuid feature detection |
@@ -219,7 +223,7 @@ op_amd_handle_ibs(struct pt_regs * const regs, | |||
219 | oprofile_write_commit(&entry); | 223 | oprofile_write_commit(&entry); |
220 | 224 | ||
221 | /* reenable the IRQ */ | 225 | /* reenable the IRQ */ |
222 | ctl = op_amd_randomize_ibs_op(ibs_op_ctl); | 226 | ctl = op_amd_randomize_ibs_op(ibs_state.ibs_op_ctl); |
223 | wrmsrl(MSR_AMD64_IBSOPCTL, ctl); | 227 | wrmsrl(MSR_AMD64_IBSOPCTL, ctl); |
224 | } | 228 | } |
225 | } | 229 | } |
@@ -232,6 +236,8 @@ static inline void op_amd_start_ibs(void) | |||
232 | if (!ibs_caps) | 236 | if (!ibs_caps) |
233 | return; | 237 | return; |
234 | 238 | ||
239 | memset(&ibs_state, 0, sizeof(ibs_state)); | ||
240 | |||
235 | if (ibs_config.fetch_enabled) { | 241 | if (ibs_config.fetch_enabled) { |
236 | val = (ibs_config.max_cnt_fetch >> 4) & IBS_FETCH_MAX_CNT; | 242 | val = (ibs_config.max_cnt_fetch >> 4) & IBS_FETCH_MAX_CNT; |
237 | val |= ibs_config.rand_en ? IBS_FETCH_RAND_EN : 0; | 243 | val |= ibs_config.rand_en ? IBS_FETCH_RAND_EN : 0; |
@@ -240,13 +246,13 @@ static inline void op_amd_start_ibs(void) | |||
240 | } | 246 | } |
241 | 247 | ||
242 | if (ibs_config.op_enabled) { | 248 | if (ibs_config.op_enabled) { |
243 | ibs_op_ctl = ibs_config.max_cnt_op >> 4; | 249 | val = ibs_config.max_cnt_op >> 4; |
244 | if (!(ibs_caps & IBS_CAPS_RDWROPCNT)) { | 250 | if (!(ibs_caps & IBS_CAPS_RDWROPCNT)) { |
245 | /* | 251 | /* |
246 | * IbsOpCurCnt not supported. See | 252 | * IbsOpCurCnt not supported. See |
247 | * op_amd_randomize_ibs_op() for details. | 253 | * op_amd_randomize_ibs_op() for details. |
248 | */ | 254 | */ |
249 | ibs_op_ctl = clamp(ibs_op_ctl, 0x0081ULL, 0xFF80ULL); | 255 | val = clamp(val, 0x0081ULL, 0xFF80ULL); |
250 | } else { | 256 | } else { |
251 | /* | 257 | /* |
252 | * The start value is randomized with a | 258 | * The start value is randomized with a |
@@ -254,12 +260,13 @@ static inline void op_amd_start_ibs(void) | |||
254 | * with the half of the randomized range. Also | 260 | * with the half of the randomized range. Also |
255 | * avoid underflows. | 261 | * avoid underflows. |
256 | */ | 262 | */ |
257 | ibs_op_ctl = min(ibs_op_ctl + IBS_RANDOM_MAXCNT_OFFSET, | 263 | val = min(val + IBS_RANDOM_MAXCNT_OFFSET, |
258 | IBS_OP_MAX_CNT); | 264 | IBS_OP_MAX_CNT); |
259 | } | 265 | } |
260 | ibs_op_ctl |= ibs_config.dispatched_ops ? IBS_OP_CNT_CTL : 0; | 266 | val |= ibs_config.dispatched_ops ? IBS_OP_CNT_CTL : 0; |
261 | ibs_op_ctl |= IBS_OP_ENABLE; | 267 | val |= IBS_OP_ENABLE; |
262 | val = op_amd_randomize_ibs_op(ibs_op_ctl); | 268 | ibs_state.ibs_op_ctl = val; |
269 | val = op_amd_randomize_ibs_op(ibs_state.ibs_op_ctl); | ||
263 | wrmsrl(MSR_AMD64_IBSOPCTL, val); | 270 | wrmsrl(MSR_AMD64_IBSOPCTL, val); |
264 | } | 271 | } |
265 | } | 272 | } |