diff options
Diffstat (limited to 'arch/x86/kernel/cpu/perf_event.c')
-rw-r--r-- | arch/x86/kernel/cpu/perf_event.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 915b876edd1e..4a3374e61a93 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
@@ -208,12 +208,14 @@ static bool check_hw_exists(void) | |||
208 | } | 208 | } |
209 | 209 | ||
210 | /* | 210 | /* |
211 | * Now write a value and read it back to see if it matches, | 211 | * Read the current value, change it and read it back to see if it |
212 | * this is needed to detect certain hardware emulators (qemu/kvm) | 212 | * matches, this is needed to detect certain hardware emulators |
213 | * that don't trap on the MSR access and always return 0s. | 213 | * (qemu/kvm) that don't trap on the MSR access and always return 0s. |
214 | */ | 214 | */ |
215 | val = 0xabcdUL; | ||
216 | reg = x86_pmu_event_addr(0); | 215 | reg = x86_pmu_event_addr(0); |
216 | if (rdmsrl_safe(reg, &val)) | ||
217 | goto msr_fail; | ||
218 | val ^= 0xffffUL; | ||
217 | ret = wrmsrl_safe(reg, val); | 219 | ret = wrmsrl_safe(reg, val); |
218 | ret |= rdmsrl_safe(reg, &val_new); | 220 | ret |= rdmsrl_safe(reg, &val_new); |
219 | if (ret || val != val_new) | 221 | if (ret || val != val_new) |
@@ -338,6 +340,9 @@ int x86_setup_perfctr(struct perf_event *event) | |||
338 | /* BTS is currently only allowed for user-mode. */ | 340 | /* BTS is currently only allowed for user-mode. */ |
339 | if (!attr->exclude_kernel) | 341 | if (!attr->exclude_kernel) |
340 | return -EOPNOTSUPP; | 342 | return -EOPNOTSUPP; |
343 | |||
344 | if (!attr->exclude_guest) | ||
345 | return -EOPNOTSUPP; | ||
341 | } | 346 | } |
342 | 347 | ||
343 | hwc->config |= config; | 348 | hwc->config |= config; |
@@ -380,6 +385,9 @@ int x86_pmu_hw_config(struct perf_event *event) | |||
380 | if (event->attr.precise_ip) { | 385 | if (event->attr.precise_ip) { |
381 | int precise = 0; | 386 | int precise = 0; |
382 | 387 | ||
388 | if (!event->attr.exclude_guest) | ||
389 | return -EOPNOTSUPP; | ||
390 | |||
383 | /* Support for constant skid */ | 391 | /* Support for constant skid */ |
384 | if (x86_pmu.pebs_active && !x86_pmu.pebs_broken) { | 392 | if (x86_pmu.pebs_active && !x86_pmu.pebs_broken) { |
385 | precise++; | 393 | precise++; |