x86/mce: Use safe MSR accesses for AMD quirk
authorJesse Larrew <jesse.larrew@amd.com>
Fri, 13 Mar 2015 16:03:39 +0000 (11:03 -0500)
committerIngo Molnar <mingo@kernel.org>
Mon, 23 Mar 2015 09:16:43 +0000 (10:16 +0100)
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 <jesse.larrew@amd.com>
[ Drop {} braces around loop ]
Signed-off-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Joel Schopp <joel.schopp@amd.com>
Acked-by: Tony Luck <tony.luck@intel.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-edac@vger.kernel.org
Link: http://lkml.kernel.org/r/1426262619-5016-1-git-send-email-jesse.larrew@amd.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
arch/x86/kernel/cpu/mcheck/mce.c

index d760931a4546e677e4a9df41f34db9448704e26b..196a1e34fe39a16e2333abb79b1aa80175682d2e 100644 (file)
@@ -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)