Browse Source

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 <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>
Jesse Larrew 10 years ago
parent
commit
f77ac507f8
1 changed files with 4 additions and 10 deletions
  1. 4 10
      arch/x86/kernel/cpu/mcheck/mce.c

+ 4 - 10
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 &&
 		 if (c->x86 == 0x15 &&
 		     (c->x86_model >= 0x10 && c->x86_model <= 0x1f)) {
 		     (c->x86_model >= 0x10 && c->x86_model <= 0x1f)) {
 			 int i;
 			 int i;
-			 u64 val, hwcr;
+			 u64 hwcr;
 			 bool need_toggle;
 			 bool need_toggle;
 			 u32 msrs[] = {
 			 u32 msrs[] = {
 				0x00000413, /* MC4_MISC0 */
 				0x00000413, /* MC4_MISC0 */
@@ -1556,15 +1556,9 @@ static int __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c)
 			 if (need_toggle)
 			 if (need_toggle)
 				 wrmsrl(MSR_K7_HWCR, hwcr | BIT(18));
 				 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 */
 			 /* restore old settings */
 			 if (need_toggle)
 			 if (need_toggle)