linux/arch/x86
Andre Przywara bffd5fc260 x86/perf: Fix virtualization sanity check
In check_hw_exists() we try to detect non-emulated MSR accesses
by writing an arbitrary value into one of the PMU registers
and check if it's value after a readout is still the same.
This algorithm silently assumes that the register does not contain
the magic value already, which is wrong in at least one situation.

Fix the algorithm to really do a read-modify-write cycle. This fixes
a warning under Xen under some circumstances on AMD family 10h CPUs.

The reasons in more details actually sound like a story from
Believe It or Not!:

First you need an AMD family 10h/12h CPU. These do not reset the
PERF_CTR registers on a reboot.
Now you boot bare metal Linux, which goes successfully through this
check, but leaves the magic value of 0xabcd in the register. You
don't use the performance counters, but do a reboot (warm reset).
Then you choose to boot Xen. The check will be triggered with a
recent Linux kernel as Dom0 again, trying to write 0xabcd into the
MSR. Xen silently drops the write (expected), but the subsequent read
will return the value in the register, which just happens to be the
expected magic value. Thus the test misleadingly succeeds, leaving
the kernel in the belief that the PMU is available. This will trigger
the following message:

[    0.020294] ------------[ cut here ]------------
[    0.020311] WARNING: at arch/x86/xen/enlighten.c:730 xen_apic_write+0x15/0x17()
[    0.020318] Hardware name: empty
[    0.020323] Modules linked in:
[    0.020334] Pid: 1, comm: swapper/0 Not tainted 3.3.8 #7
[    0.020340] Call Trace:
[    0.020354]  [<ffffffff81050379>] warn_slowpath_common+0x80/0x98
[    0.020369]  [<ffffffff810503a6>] warn_slowpath_null+0x15/0x17
[    0.020378]  [<ffffffff810034df>] xen_apic_write+0x15/0x17
[    0.020392]  [<ffffffff8101cb2b>] perf_events_lapic_init+0x2e/0x30
[    0.020410]  [<ffffffff81ee4dd0>] init_hw_perf_events+0x250/0x407
[    0.020419]  [<ffffffff81ee4b80>] ? check_bugs+0x2d/0x2d
[    0.020430]  [<ffffffff81002181>] do_one_initcall+0x7a/0x131
[    0.020444]  [<ffffffff81edbbf9>] kernel_init+0x91/0x15d
[    0.020456]  [<ffffffff817caaa4>] kernel_thread_helper+0x4/0x10
[    0.020471]  [<ffffffff817c347c>] ? retint_restore_args+0x5/0x6
[    0.020481]  [<ffffffff817caaa0>] ? gs_change+0x13/0x13
[    0.020500] ---[ end trace a7919e7f17c0a725 ]---

The new code will change every of the 16 low bits read from the
register and tries to write and read-back that modified number
from the MSR.

Signed-off-by: Andre Przywara <andre.przywara@amd.com>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Avi Kivity <avi@redhat.com>
Link: http://lkml.kernel.org/r/1349797115-28346-2-git-send-email-andre.przywara@amd.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
2012-10-24 08:53:13 +02:00
..
boot x86, boot: Explicitly include autoconf.h for hostprogs 2012-10-14 12:41:28 -07:00
configs x86/Kconfig: Turn off DEBUG_NX_TEST module in defconfigs 2012-09-05 10:43:12 +02:00
crypto crypto: aesni - fix XTS mode on x86-32, add wrapper function for asmlinkage aesni_enc() 2012-10-18 14:01:33 -07:00
ia32 Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal 2012-10-10 12:02:25 +09:00
include Merge commit 'v3.7-rc1' into stable/for-linus-3.7 2012-10-19 15:19:19 -04:00
kernel x86/perf: Fix virtualization sanity check 2012-10-24 08:53:13 +02:00
kvm KVM: apic: fix LDR calculation in x2apic mode 2012-10-22 18:03:27 +02:00
lguest virtio: remove CONFIG_VIRTIO_RING 2012-09-28 15:05:15 +09:30
lib UAPI: x86: Fix insn_sanity build failure after UAPI split 2012-10-02 18:01:56 +01:00
math-emu x86: Rename trap_no to trap_nr in thread_struct 2012-03-13 06:24:09 +01:00
mm readahead: fault retry breaks mmap file read random detection 2012-10-09 16:22:47 +09:00
net x86: bpf_jit_comp: add XOR instruction for BPF JIT 2012-09-24 16:54:35 -04:00
oprofile oprofile, x86: Fix wrapping bug in op_x86_get_ctrl() 2012-10-15 14:38:24 +02:00
pci PCI changes for the 3.7 merge window: 2012-10-01 12:05:36 -07:00
platform efi: Fix the ACPI BGRT driver for images located in EFI boot services memory 2012-09-29 12:21:03 -07:00
power x86, kvm: Call restore_sched_clock_state() only after %gs is initialized 2012-04-02 13:53:00 +02:00
realmode x86, suspend: Correct the restore of CR4, EFER; skip computing EFLAGS.ID 2012-10-02 08:42:31 +02:00
syscalls Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal 2012-10-10 12:02:25 +09:00
tools UAPI: x86: Fix the test_get_len tool 2012-10-02 18:01:56 +01:00
um Merge branch 'modules-next' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux 2012-10-14 13:39:34 -07:00
vdso time: Convert x86_64 to using new update_vsyscall 2012-09-24 12:38:09 -04:00
video x86: Use vga_default_device() when determining whether an fb is primary 2012-04-24 09:50:17 +01:00
xen Merge commit 'v3.7-rc1' into stable/for-linus-3.7 2012-10-19 15:19:19 -04:00
.gitignore x86/kprobes: Add arch/x86/tools/insn_sanity to .gitignore 2012-01-16 08:21:59 +01:00
Kbuild x86, realmode: realmode.bin infrastructure 2012-05-08 11:41:48 -07:00
Kconfig Merge branch 'modules-next' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux 2012-10-14 13:39:34 -07:00
Kconfig.cpu x86/Kconfig: Clean up Kconfig defaults 2012-09-13 17:45:33 +02:00
Kconfig.debug x86/tlb: add tlb_flushall_shift knob into debugfs 2012-06-27 19:29:10 -07:00
Makefile kbuild: Fix accidental revert in commit fe04ddf 2012-10-15 13:01:05 -07:00
Makefile_32.cpu
Makefile.um um: fix linker script generation 2012-04-09 13:59:00 -04:00