diff options
| -rw-r--r-- | arch/x86/kernel/cpu/perf_event.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index ed6310183efb..6d75b9145b13 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
| @@ -381,6 +381,20 @@ static void release_pmc_hardware(void) {} | |||
| 381 | 381 | ||
| 382 | #endif | 382 | #endif |
| 383 | 383 | ||
| 384 | static bool check_hw_exists(void) | ||
| 385 | { | ||
| 386 | u64 val, val_new = 0; | ||
| 387 | int ret = 0; | ||
| 388 | |||
| 389 | val = 0xabcdUL; | ||
| 390 | ret |= checking_wrmsrl(x86_pmu.perfctr, val); | ||
| 391 | ret |= rdmsrl_safe(x86_pmu.perfctr, &val_new); | ||
| 392 | if (ret || val != val_new) | ||
| 393 | return false; | ||
| 394 | |||
| 395 | return true; | ||
| 396 | } | ||
| 397 | |||
| 384 | static void reserve_ds_buffers(void); | 398 | static void reserve_ds_buffers(void); |
| 385 | static void release_ds_buffers(void); | 399 | static void release_ds_buffers(void); |
| 386 | 400 | ||
| @@ -1372,6 +1386,12 @@ void __init init_hw_perf_events(void) | |||
| 1372 | 1386 | ||
| 1373 | pmu_check_apic(); | 1387 | pmu_check_apic(); |
| 1374 | 1388 | ||
| 1389 | /* sanity check that the hardware exists or is emulated */ | ||
| 1390 | if (!check_hw_exists()) { | ||
| 1391 | pr_cont("Broken PMU hardware detected, software events only.\n"); | ||
| 1392 | return; | ||
| 1393 | } | ||
| 1394 | |||
| 1375 | pr_cont("%s PMU driver.\n", x86_pmu.name); | 1395 | pr_cont("%s PMU driver.\n", x86_pmu.name); |
| 1376 | 1396 | ||
| 1377 | if (x86_pmu.quirks) | 1397 | if (x86_pmu.quirks) |
