diff options
author | Jesse Larrew <[email protected]> | 2015-03-13 11:03:39 -0500 |
---|---|---|
committer | Ingo Molnar <[email protected]> | 2015-03-23 10:16:43 +0100 |
commit | f77ac507f893fc00c1b9ea0076f3c9e664b0f9ab (patch) | |
tree | 746da99d0fb1efe66fc2061f34d51dfb71a3a51f | |
parent | fa45a45ca34891614789e68dfbf7ce344c9013ac (diff) |
x86/mce: Use safe MSR accesses for AMD quirk
Certain MSRs are only relevant to a kernel in host mode, and kvm had
chosen not to implement these MSRs at all for guests. If a guest kernel
ever tried to access these MSRs, the result was a general protection
fault.
KVM will be separately patched to return 0 when these MSRs are read,
and this patch ensures that MSR accesses are tolerant of exceptions.
Signed-off-by: Jesse Larrew <[email protected]>
[ Drop {} braces around loop ]
Signed-off-by: Borislav Petkov <[email protected]>
Reviewed-by: Joel Schopp <[email protected]>
Acked-by: Tony Luck <[email protected]>
Cc: H. Peter Anvin <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: [email protected]
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce.c | 14 |
1 files changed, 4 insertions, 10 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index d760931a4546..196a1e34fe39 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c @@ -1541,7 +1541,7 @@ static int __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c) if (c->x86 == 0x15 && (c->x86_model >= 0x10 && c->x86_model <= 0x1f)) { int i; - u64 val, hwcr; + u64 hwcr; bool need_toggle; u32 msrs[] = { 0x00000413, /* MC4_MISC0 */ @@ -1556,15 +1556,9 @@ static int __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c) if (need_toggle) wrmsrl(MSR_K7_HWCR, hwcr | BIT(18)); - for (i = 0; i < ARRAY_SIZE(msrs); i++) { - rdmsrl(msrs[i], val); - - /* CntP bit set? */ - if (val & BIT_64(62)) { - val &= ~BIT_64(62); - wrmsrl(msrs[i], val); - } - } + /* Clear CntP bit safely */ + for (i = 0; i < ARRAY_SIZE(msrs); i++) + msr_clear_bit(msrs[i], 62); /* restore old settings */ if (need_toggle) |