diff options
-rw-r--r-- | arch/x86/kernel/cpu/perf_event_amd_ibs.c | 27 |
1 files changed, 14 insertions, 13 deletions
diff --git a/arch/x86/kernel/cpu/perf_event_amd_ibs.c b/arch/x86/kernel/cpu/perf_event_amd_ibs.c index 8ff74d439041..c8f69bea6624 100644 --- a/arch/x86/kernel/cpu/perf_event_amd_ibs.c +++ b/arch/x86/kernel/cpu/perf_event_amd_ibs.c | |||
@@ -386,7 +386,21 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs) | |||
386 | if (!(*buf++ & perf_ibs->valid_mask)) | 386 | if (!(*buf++ & perf_ibs->valid_mask)) |
387 | return 0; | 387 | return 0; |
388 | 388 | ||
389 | /* | ||
390 | * Emulate IbsOpCurCnt in MSRC001_1033 (IbsOpCtl), not | ||
391 | * supported in all cpus. As this triggered an interrupt, we | ||
392 | * set the current count to the max count. | ||
393 | */ | ||
394 | config = ibs_data.regs[0]; | ||
395 | if (perf_ibs == &perf_ibs_op && !(ibs_caps & IBS_CAPS_RDWROPCNT)) { | ||
396 | config &= ~IBS_OP_CUR_CNT; | ||
397 | config |= (config & IBS_OP_MAX_CNT) << 36; | ||
398 | } | ||
399 | |||
400 | perf_ibs_event_update(perf_ibs, event, config); | ||
389 | perf_sample_data_init(&data, 0); | 401 | perf_sample_data_init(&data, 0); |
402 | data.period = event->hw.last_period; | ||
403 | |||
390 | if (event->attr.sample_type & PERF_SAMPLE_RAW) { | 404 | if (event->attr.sample_type & PERF_SAMPLE_RAW) { |
391 | ibs_data.caps = ibs_caps; | 405 | ibs_data.caps = ibs_caps; |
392 | size = 1; | 406 | size = 1; |
@@ -405,19 +419,6 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs) | |||
405 | 419 | ||
406 | regs = *iregs; /* XXX: update ip from ibs sample */ | 420 | regs = *iregs; /* XXX: update ip from ibs sample */ |
407 | 421 | ||
408 | /* | ||
409 | * Emulate IbsOpCurCnt in MSRC001_1033 (IbsOpCtl), not | ||
410 | * supported in all cpus. As this triggered an interrupt, we | ||
411 | * set the current count to the max count. | ||
412 | */ | ||
413 | config = ibs_data.regs[0]; | ||
414 | if (perf_ibs == &perf_ibs_op && !(ibs_caps & IBS_CAPS_RDWROPCNT)) { | ||
415 | config &= ~IBS_OP_CUR_CNT; | ||
416 | config |= (config & IBS_OP_MAX_CNT) << 36; | ||
417 | } | ||
418 | |||
419 | perf_ibs_event_update(perf_ibs, event, config); | ||
420 | |||
421 | overflow = perf_ibs_set_period(perf_ibs, hwc, &config); | 422 | overflow = perf_ibs_set_period(perf_ibs, hwc, &config); |
422 | reenable = !(overflow && perf_event_overflow(event, &data, ®s)); | 423 | reenable = !(overflow && perf_event_overflow(event, &data, ®s)); |
423 | config = (config >> 4) | (reenable ? perf_ibs->enable_mask : 0); | 424 | config = (config >> 4) | (reenable ? perf_ibs->enable_mask : 0); |