[PATCH 0/7] x86/ras: RAS queue

classic Classic list List threaded Threaded
15 messages Options
Reply | Threaded
Open this post in threaded view
|

[PATCH 0/7] x86/ras: RAS queue

Borislav Petkov-3
From: Borislav Petkov <[hidden email]>

Hi,

here's the last pile that got ready. It is mostly SMCA enablement for
future AMD F17h CPUs so the remaining families shouldn't be affected.
Initial testing on what I have here looks ok, randconfigs pass too.

All is ontop of tip:ras/core.

Thanks.

Borislav Petkov (1):
  x86/mce/AMD: Save an indentation level in prepare_threshold_block()

Yazen Ghannam (6):
  x86/mce/AMD: Log Deferred Errors using SMCA MCA_DE{STAT,ADDR}
    registers
  x86/mce/AMD: Disable LogDeferredInMcaStat for SMCA systems
  x86/cpu: Add detection of AMD RAS Capabilities
  x86/mce: Update AMD mcheck init to use cpu_has() facilities
  EDAC, mce_amd: Detect SMCA using X86_FEATURE_SMCA
  x86/RAS: Add SMCA support to AMD Error Injector

 arch/x86/include/asm/cpufeature.h    |  1 +
 arch/x86/include/asm/cpufeatures.h   |  7 ++-
 arch/x86/include/asm/mce.h           |  4 ++
 arch/x86/kernel/cpu/common.c         | 10 ++--
 arch/x86/kernel/cpu/mcheck/mce.c     |  8 ++--
 arch/x86/kernel/cpu/mcheck/mce_amd.c | 92 ++++++++++++++++++++++++------------
 arch/x86/ras/mce_amd_inj.c           | 31 +++++++++---
 drivers/edac/mce_amd.c               |  9 ++--
 8 files changed, 112 insertions(+), 50 deletions(-)

--
2.7.3

Reply | Threaded
Open this post in threaded view
|

[PATCH 3/7] x86/mce/AMD: Save an indentation level in prepare_threshold_block()

Borislav Petkov-3
From: Borislav Petkov <[hidden email]>

Do the !SMCA work first and then save us an indentation level for the
SMCA code.

No functionality change.

Signed-off-by: Borislav Petkov <[hidden email]>
Cc: Aravind Gopalakrishnan <[hidden email]>
Cc: Tony Luck <[hidden email]>
Cc: linux-edac <[hidden email]>
Cc: x86-ml <[hidden email]>
Cc: Yazen Ghannam <[hidden email]>
---
 arch/x86/kernel/cpu/mcheck/mce_amd.c | 78 ++++++++++++++++++------------------
 1 file changed, 38 insertions(+), 40 deletions(-)

diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c
index 527ddae3017b..10b0661651e0 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_amd.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c
@@ -343,6 +343,7 @@ prepare_threshold_block(unsigned int bank, unsigned int block, u32 addr,
  int offset, u32 misc_high)
 {
  unsigned int cpu = smp_processor_id();
+ u32 smca_low, smca_high, smca_addr;
  struct threshold_block b;
  int new;
 
@@ -361,52 +362,49 @@ prepare_threshold_block(unsigned int bank, unsigned int block, u32 addr,
 
  b.interrupt_enable = 1;
 
- if (mce_flags.smca) {
- u32 smca_low, smca_high;
- u32 smca_addr = MSR_AMD64_SMCA_MCx_CONFIG(bank);
-
- if (!rdmsr_safe(smca_addr, &smca_low, &smca_high)) {
- /*
- * OS is required to set the MCAX bit to acknowledge
- * that it is now using the new MSR ranges and new
- * registers under each bank. It also means that the OS
- * will configure deferred errors in the new MCx_CONFIG
- * register. If the bit is not set, uncorrectable errors
- * will cause a system panic.
- *
- * MCA_CONFIG[MCAX] is bit 32 (0 in the high portion of
- * the MSR.)
- */
- smca_high |= BIT(0);
+ if (!mce_flags.smca) {
+ new = (misc_high & MASK_LVTOFF_HI) >> 20;
+ goto set_offset;
+ }
 
- /*
- * SMCA logs Deferred Error information in
- * MCA_DE{STAT,ADDR} registers with the option of
- * additionally logging to MCA_{STATUS,ADDR} if
- * MCA_CONFIG[LogDeferredInMcaStat] is set.
- *
- * This bit is usually set by BIOS to retain the old
- * behavior for OSes that don't use the new registers.
- * Linux supports the new registers so let's disable
- * that additional logging here.
- *
- * MCA_CONFIG[LogDeferredInMcaStat] is bit 34 (bit 2 in
- * the high portion of the MSR).
- */
- smca_high &= ~BIT(2);
+ smca_addr = MSR_AMD64_SMCA_MCx_CONFIG(bank);
 
- wrmsr(smca_addr, smca_low, smca_high);
- }
+ if (!rdmsr_safe(smca_addr, &smca_low, &smca_high)) {
+ /*
+ * OS is required to set the MCAX bit to acknowledge that it is
+ * now using the new MSR ranges and new registers under each
+ * bank. It also means that the OS will configure deferred
+ * errors in the new MCx_CONFIG register. If the bit is not set,
+ * uncorrectable errors will cause a system panic.
+ *
+ * MCA_CONFIG[MCAX] is bit 32 (0 in the high portion of the MSR.)
+ */
+ smca_high |= BIT(0);
 
- /* Gather LVT offset for thresholding: */
- if (rdmsr_safe(MSR_CU_DEF_ERR, &smca_low, &smca_high))
- goto out;
+ /*
+ * SMCA logs Deferred Error information in MCA_DE{STAT,ADDR}
+ * registers with the option of additionally logging to
+ * MCA_{STATUS,ADDR} if MCA_CONFIG[LogDeferredInMcaStat] is set.
+ *
+ * This bit is usually set by BIOS to retain the old behavior
+ * for OSes that don't use the new registers. Linux supports the
+ * new registers so let's disable that additional logging here.
+ *
+ * MCA_CONFIG[LogDeferredInMcaStat] is bit 34 (bit 2 in the high
+ * portion of the MSR).
+ */
+ smca_high &= ~BIT(2);
 
- new = (smca_low & SMCA_THR_LVT_OFF) >> 12;
- } else {
- new = (misc_high & MASK_LVTOFF_HI) >> 20;
+ wrmsr(smca_addr, smca_low, smca_high);
  }
 
+ /* Gather LVT offset for thresholding: */
+ if (rdmsr_safe(MSR_CU_DEF_ERR, &smca_low, &smca_high))
+ goto out;
+
+ new = (smca_low & SMCA_THR_LVT_OFF) >> 12;
+
+set_offset:
  offset = setup_APIC_mce_threshold(offset, new);
 
  if ((offset == new) && (mce_threshold_vector != amd_threshold_interrupt))
--
2.7.3

Reply | Threaded
Open this post in threaded view
|

[PATCH 2/7] x86/mce/AMD: Disable LogDeferredInMcaStat for SMCA systems

Borislav Petkov-3
In reply to this post by Borislav Petkov-3
From: Yazen Ghannam <[hidden email]>

Disable Deferred Error logging in MCA_{STATUS,ADDR} additionally for
SMCA systems as this information will retrieved from MCA_DE{STAT,ADDR}
on those systems.

Signed-off-by: Yazen Ghannam <[hidden email]>
Cc: Aravind Gopalakrishnan <[hidden email]>
Cc: Tony Luck <[hidden email]>
Cc: linux-edac <[hidden email]>
Cc: x86-ml <[hidden email]>
Link: http://lkml.kernel.org/r/1462377407-1446-3-git-send-email-Yazen.Ghannam@...
[ Simplify, drop SMCA_MCAX_EN_OFF define too. ]
Signed-off-by: Borislav Petkov <[hidden email]>
---
 arch/x86/kernel/cpu/mcheck/mce_amd.c | 38 +++++++++++++++++++++++++++---------
 1 file changed, 29 insertions(+), 9 deletions(-)

diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c
index d1b1e62f7cb9..527ddae3017b 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_amd.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c
@@ -54,14 +54,6 @@
 /* Threshold LVT offset is at MSR0xC0000410[15:12] */
 #define SMCA_THR_LVT_OFF 0xF000
 
-/*
- * OS is required to set the MCAX bit to acknowledge that it is now using the
- * new MSR ranges and new registers under each bank. It also means that the OS
- * will configure deferred errors in the new MCx_CONFIG register. If the bit is
- * not set, uncorrectable errors will cause a system panic.
- */
-#define SMCA_MCAX_EN_OFF 0x1
-
 static const char * const th_names[] = {
  "load_store",
  "insn_fetch",
@@ -374,7 +366,35 @@ prepare_threshold_block(unsigned int bank, unsigned int block, u32 addr,
  u32 smca_addr = MSR_AMD64_SMCA_MCx_CONFIG(bank);
 
  if (!rdmsr_safe(smca_addr, &smca_low, &smca_high)) {
- smca_high |= SMCA_MCAX_EN_OFF;
+ /*
+ * OS is required to set the MCAX bit to acknowledge
+ * that it is now using the new MSR ranges and new
+ * registers under each bank. It also means that the OS
+ * will configure deferred errors in the new MCx_CONFIG
+ * register. If the bit is not set, uncorrectable errors
+ * will cause a system panic.
+ *
+ * MCA_CONFIG[MCAX] is bit 32 (0 in the high portion of
+ * the MSR.)
+ */
+ smca_high |= BIT(0);
+
+ /*
+ * SMCA logs Deferred Error information in
+ * MCA_DE{STAT,ADDR} registers with the option of
+ * additionally logging to MCA_{STATUS,ADDR} if
+ * MCA_CONFIG[LogDeferredInMcaStat] is set.
+ *
+ * This bit is usually set by BIOS to retain the old
+ * behavior for OSes that don't use the new registers.
+ * Linux supports the new registers so let's disable
+ * that additional logging here.
+ *
+ * MCA_CONFIG[LogDeferredInMcaStat] is bit 34 (bit 2 in
+ * the high portion of the MSR).
+ */
+ smca_high &= ~BIT(2);
+
  wrmsr(smca_addr, smca_low, smca_high);
  }
 
--
2.7.3

Reply | Threaded
Open this post in threaded view
|

[PATCH 7/7] x86/RAS: Add SMCA support to AMD Error Injector

Borislav Petkov-3
In reply to this post by Borislav Petkov-3
From: Yazen Ghannam <[hidden email]>

Use SMCA MSRs when writing to MCA_{STATUS,ADDR,MISC} and
MCA_DE{STAT,ADDR} when injecting Deferred Errors on SMCA platforms.

Signed-off-by: Yazen Ghannam <[hidden email]>
Cc: Aravind Gopalakrishnan <[hidden email]>
Cc: Tony Luck <[hidden email]>
Cc: linux-edac <[hidden email]>
Cc: x86-ml <[hidden email]>
Link: http://lkml.kernel.org/r/1462914639-29513-6-git-send-email-Yazen.Ghannam@...
Signed-off-by: Borislav Petkov <[hidden email]>
---
 arch/x86/ras/mce_amd_inj.c | 31 +++++++++++++++++++++++++------
 1 file changed, 25 insertions(+), 6 deletions(-)

diff --git a/arch/x86/ras/mce_amd_inj.c b/arch/x86/ras/mce_amd_inj.c
index 9e02dcaef683..e69f4701a076 100644
--- a/arch/x86/ras/mce_amd_inj.c
+++ b/arch/x86/ras/mce_amd_inj.c
@@ -290,14 +290,33 @@ static void do_inject(void)
  wrmsr_on_cpu(cpu, MSR_IA32_MCG_STATUS,
      (u32)mcg_status, (u32)(mcg_status >> 32));
 
- wrmsr_on_cpu(cpu, MSR_IA32_MCx_STATUS(b),
-     (u32)i_mce.status, (u32)(i_mce.status >> 32));
+ if (boot_cpu_has(X86_FEATURE_SMCA)) {
+ if (inj_type == DFR_INT_INJ) {
+ wrmsr_on_cpu(cpu, MSR_AMD64_SMCA_MCx_DESTAT(b),
+     (u32)i_mce.status, (u32)(i_mce.status >> 32));
+
+ wrmsr_on_cpu(cpu, MSR_AMD64_SMCA_MCx_DEADDR(b),
+     (u32)i_mce.addr, (u32)(i_mce.addr >> 32));
+ } else {
+ wrmsr_on_cpu(cpu, MSR_AMD64_SMCA_MCx_STATUS(b),
+     (u32)i_mce.status, (u32)(i_mce.status >> 32));
+
+ wrmsr_on_cpu(cpu, MSR_AMD64_SMCA_MCx_ADDR(b),
+     (u32)i_mce.addr, (u32)(i_mce.addr >> 32));
+ }
+
+ wrmsr_on_cpu(cpu, MSR_AMD64_SMCA_MCx_MISC(b),
+     (u32)i_mce.misc, (u32)(i_mce.misc >> 32));
+ } else {
+ wrmsr_on_cpu(cpu, MSR_IA32_MCx_STATUS(b),
+     (u32)i_mce.status, (u32)(i_mce.status >> 32));
 
- wrmsr_on_cpu(cpu, MSR_IA32_MCx_ADDR(b),
-     (u32)i_mce.addr, (u32)(i_mce.addr >> 32));
+ wrmsr_on_cpu(cpu, MSR_IA32_MCx_ADDR(b),
+     (u32)i_mce.addr, (u32)(i_mce.addr >> 32));
 
- wrmsr_on_cpu(cpu, MSR_IA32_MCx_MISC(b),
-     (u32)i_mce.misc, (u32)(i_mce.misc >> 32));
+ wrmsr_on_cpu(cpu, MSR_IA32_MCx_MISC(b),
+     (u32)i_mce.misc, (u32)(i_mce.misc >> 32));
+ }
 
  toggle_hw_mce_inject(cpu, false);
 
--
2.7.3

Reply | Threaded
Open this post in threaded view
|

[PATCH 5/7] x86/mce: Update AMD mcheck init to use cpu_has() facilities

Borislav Petkov-3
In reply to this post by Borislav Petkov-3
From: Yazen Ghannam <[hidden email]>

Use cpu_has() facilities to find available RAS features rather than
directly reading CPUID 0x80000007_EBX.

Signed-off-by: Yazen Ghannam <[hidden email]>
Cc: Tony Luck <[hidden email]>
Cc: linux-edac <[hidden email]>
Cc: x86-ml <[hidden email]>
Link: http://lkml.kernel.org/r/1462914639-29513-4-git-send-email-Yazen.Ghannam@...
[ Use the struct cpuinfo_x86 ptr instead. ]
Signed-off-by: Borislav Petkov <[hidden email]>
---
 arch/x86/kernel/cpu/mcheck/mce.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index aeda44684758..92e5e37d97bf 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -1683,11 +1683,9 @@ static void __mcheck_cpu_init_vendor(struct cpuinfo_x86 *c)
  break;
 
  case X86_VENDOR_AMD: {
- u32 ebx = cpuid_ebx(0x80000007);
-
- mce_flags.overflow_recov = !!(ebx & BIT(0));
- mce_flags.succor = !!(ebx & BIT(1));
- mce_flags.smca = !!(ebx & BIT(3));
+ mce_flags.overflow_recov = !!cpu_has(c, X86_FEATURE_OVERFLOW_RECOV);
+ mce_flags.succor = !!cpu_has(c, X86_FEATURE_SUCCOR);
+ mce_flags.smca = !!cpu_has(c, X86_FEATURE_SMCA);
 
  /*
  * Install proper ops for Scalable MCA enabled processors
--
2.7.3

Reply | Threaded
Open this post in threaded view
|

[PATCH 6/7] EDAC, mce_amd: Detect SMCA using X86_FEATURE_SMCA

Borislav Petkov-3
In reply to this post by Borislav Petkov-3
From: Yazen Ghannam <[hidden email]>

Use X86_FEATURE_SMCA when detecting if SMCA is available instead of
directly using CPUID 0x80000007_EBX.

Signed-off-by: Yazen Ghannam <[hidden email]>
Cc: <[hidden email]>
Cc: Tony Luck <[hidden email]>
Cc: linux-edac <[hidden email]>
Link: http://lkml.kernel.org/r/1462914639-29513-5-git-send-email-Yazen.Ghannam@...
Signed-off-by: Borislav Petkov <[hidden email]>
---
 drivers/edac/mce_amd.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/edac/mce_amd.c b/drivers/edac/mce_amd.c
index 49768c08ac07..9b6800a79c7f 100644
--- a/drivers/edac/mce_amd.c
+++ b/drivers/edac/mce_amd.c
@@ -1052,7 +1052,6 @@ int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
  struct mce *m = (struct mce *)data;
  struct cpuinfo_x86 *c = &cpu_data(m->extcpu);
  int ecc;
- u32 ebx = cpuid_ebx(0x80000007);
 
  if (amd_filter_mce(m))
  return NOTIFY_STOP;
@@ -1075,7 +1074,7 @@ int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
  ((m->status & MCI_STATUS_DEFERRED) ? "Deferred" : "-"),
  ((m->status & MCI_STATUS_POISON)   ? "Poison"   : "-"));
 
- if (!!(ebx & BIT(3))) {
+ if (boot_cpu_has(X86_FEATURE_SMCA)) {
  u32 low, high;
  u32 addr = MSR_AMD64_SMCA_MCx_CONFIG(m->bank);
 
@@ -1094,7 +1093,7 @@ int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
  if (m->status & MCI_STATUS_ADDRV)
  pr_emerg(HW_ERR "MC%d Error Address: 0x%016llx\n", m->bank, m->addr);
 
- if (!!(ebx & BIT(3))) {
+ if (boot_cpu_has(X86_FEATURE_SMCA)) {
  decode_smca_errors(m);
  goto err_code;
  }
@@ -1149,7 +1148,6 @@ static struct notifier_block amd_mce_dec_nb = {
 static int __init mce_amd_init(void)
 {
  struct cpuinfo_x86 *c = &boot_cpu_data;
- u32 ebx;
 
  if (c->x86_vendor != X86_VENDOR_AMD)
  return -ENODEV;
@@ -1205,9 +1203,8 @@ static int __init mce_amd_init(void)
  break;
 
  case 0x17:
- ebx = cpuid_ebx(0x80000007);
  xec_mask = 0x3f;
- if (!(ebx & BIT(3))) {
+ if (!boot_cpu_has(X86_FEATURE_SMCA)) {
  printk(KERN_WARNING "Decoding supported only on Scalable MCA processors.\n");
  goto err_out;
  }
--
2.7.3

Reply | Threaded
Open this post in threaded view
|

[PATCH 4/7] x86/cpu: Add detection of AMD RAS Capabilities

Borislav Petkov-3
In reply to this post by Borislav Petkov-3
From: Yazen Ghannam <[hidden email]>

Add a new CPUID leaf to hold the contents of CPUID 0x80000007_EBX (RasCap).

Define bits that are currently in use:
Bit 0: McaOverflowRecov
Bit 1: SUCCOR
Bit 3: ScalableMca

Signed-off-by: Yazen Ghannam <[hidden email]>
Cc: Tony Luck <[hidden email]>
Cc: linux-edac <[hidden email]>
Cc: x86-ml <[hidden email]>
Link: http://lkml.kernel.org/r/1462914639-29513-3-git-send-email-Yazen.Ghannam@...
[ Shorten comment. ]
Signed-off-by: Borislav Petkov <[hidden email]>
---
 arch/x86/include/asm/cpufeature.h  |  1 +
 arch/x86/include/asm/cpufeatures.h |  7 ++++++-
 arch/x86/kernel/cpu/common.c       | 10 +++++++---
 3 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 3636ec06c887..53ac9bbf2064 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -27,6 +27,7 @@ enum cpuid_leafs
  CPUID_6_EAX,
  CPUID_8000_000A_EDX,
  CPUID_7_ECX,
+ CPUID_8000_0007_EBX,
 };
 
 #ifdef CONFIG_X86_FEATURE_NAMES
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index 8f9afefd2dc5..d4e5018e9a44 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -12,7 +12,7 @@
 /*
  * Defines x86 CPU feature bits
  */
-#define NCAPINTS 17 /* N 32-bit words worth of info */
+#define NCAPINTS 18 /* N 32-bit words worth of info */
 #define NBUGINTS 1 /* N 32-bit bug flags */
 
 /*
@@ -280,6 +280,11 @@
 #define X86_FEATURE_PKU (16*32+ 3) /* Protection Keys for Userspace */
 #define X86_FEATURE_OSPKE (16*32+ 4) /* OS Protection Keys Enable */
 
+/* AMD-defined CPU features, CPUID level 0x80000007 (ebx), word 17 */
+#define X86_FEATURE_OVERFLOW_RECOV (17*32+0) /* MCA overflow recovery support */
+#define X86_FEATURE_SUCCOR (17*32+1) /* Uncorrectable error containment and recovery */
+#define X86_FEATURE_SMCA (17*32+3) /* Scalable MCA */
+
 /*
  * BUG word(s)
  */
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 8394b3d1f94f..dbc6f066e231 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -717,6 +717,13 @@ void get_cpu_cap(struct cpuinfo_x86 *c)
  }
  }
 
+ if (c->extended_cpuid_level >= 0x80000007) {
+ cpuid(0x80000007, &eax, &ebx, &ecx, &edx);
+
+ c->x86_capability[CPUID_8000_0007_EBX] = ebx;
+ c->x86_power = edx;
+ }
+
  if (c->extended_cpuid_level >= 0x80000008) {
  cpuid(0x80000008, &eax, &ebx, &ecx, &edx);
 
@@ -729,9 +736,6 @@ void get_cpu_cap(struct cpuinfo_x86 *c)
  c->x86_phys_bits = 36;
 #endif
 
- if (c->extended_cpuid_level >= 0x80000007)
- c->x86_power = cpuid_edx(0x80000007);
-
  if (c->extended_cpuid_level >= 0x8000000a)
  c->x86_capability[CPUID_8000_000A_EDX] = cpuid_edx(0x8000000a);
 
--
2.7.3

Reply | Threaded
Open this post in threaded view
|

[PATCH 1/7] x86/mce/AMD: Log Deferred Errors using SMCA MCA_DE{STAT,ADDR} registers

Borislav Petkov-3
In reply to this post by Borislav Petkov-3
From: Yazen Ghannam <[hidden email]>

Scalable MCA provides new registers for all banks for logging deferred
errors: MCA_DESTAT and MCA_DEADDR. Deferred errors are always logged to
these registers.

Update the AMD deferred error handler to use these registers, if
available.

Signed-off-by: Yazen Ghannam <[hidden email]>
Cc: Aravind Gopalakrishnan <[hidden email]>
Cc: linux-edac <[hidden email]>
Cc: Tony Luck <[hidden email]>
Cc: x86-ml <[hidden email]>
Link: http://lkml.kernel.org/r/1462377407-1446-2-git-send-email-Yazen.Ghannam@...
[ Sanity-check __log_error() args, massage a bit. ]
Signed-off-by: Borislav Petkov <[hidden email]>
---
 arch/x86/include/asm/mce.h           |  4 ++++
 arch/x86/kernel/cpu/mcheck/mce_amd.c | 32 ++++++++++++++++++++++++--------
 2 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h
index 53ab69704771..8bf766ef0e18 100644
--- a/arch/x86/include/asm/mce.h
+++ b/arch/x86/include/asm/mce.h
@@ -110,6 +110,8 @@
 #define MSR_AMD64_SMCA_MC0_MISC0 0xc0002003
 #define MSR_AMD64_SMCA_MC0_CONFIG 0xc0002004
 #define MSR_AMD64_SMCA_MC0_IPID 0xc0002005
+#define MSR_AMD64_SMCA_MC0_DESTAT 0xc0002008
+#define MSR_AMD64_SMCA_MC0_DEADDR 0xc0002009
 #define MSR_AMD64_SMCA_MC0_MISC1 0xc000200a
 #define MSR_AMD64_SMCA_MCx_CTL(x) (MSR_AMD64_SMCA_MC0_CTL + 0x10*(x))
 #define MSR_AMD64_SMCA_MCx_STATUS(x) (MSR_AMD64_SMCA_MC0_STATUS + 0x10*(x))
@@ -117,6 +119,8 @@
 #define MSR_AMD64_SMCA_MCx_MISC(x) (MSR_AMD64_SMCA_MC0_MISC0 + 0x10*(x))
 #define MSR_AMD64_SMCA_MCx_CONFIG(x) (MSR_AMD64_SMCA_MC0_CONFIG + 0x10*(x))
 #define MSR_AMD64_SMCA_MCx_IPID(x) (MSR_AMD64_SMCA_MC0_IPID + 0x10*(x))
+#define MSR_AMD64_SMCA_MCx_DESTAT(x) (MSR_AMD64_SMCA_MC0_DESTAT + 0x10*(x))
+#define MSR_AMD64_SMCA_MCx_DEADDR(x) (MSR_AMD64_SMCA_MC0_DEADDR + 0x10*(x))
 #define MSR_AMD64_SMCA_MCx_MISCy(x, y) ((MSR_AMD64_SMCA_MC0_MISC1 + y) + (0x10*(x)))
 
 /*
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c
index c594680c36f2..d1b1e62f7cb9 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_amd.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c
@@ -430,12 +430,23 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c)
  deferred_error_interrupt_enable(c);
 }
 
-static void __log_error(unsigned int bank, bool threshold_err, u64 misc)
+static void
+__log_error(unsigned int bank, bool deferred_err, bool threshold_err, u64 misc)
 {
+ u32 msr_status = msr_ops.status(bank);
+ u32 msr_addr = msr_ops.addr(bank);
  struct mce m;
  u64 status;
 
- rdmsrl(msr_ops.status(bank), status);
+ WARN_ON_ONCE(deferred_err && threshold_err);
+
+ if (deferred_err && mce_flags.smca) {
+ msr_status = MSR_AMD64_SMCA_MCx_DESTAT(bank);
+ msr_addr = MSR_AMD64_SMCA_MCx_DEADDR(bank);
+ }
+
+ rdmsrl(msr_status, status);
+
  if (!(status & MCI_STATUS_VAL))
  return;
 
@@ -448,10 +459,11 @@ static void __log_error(unsigned int bank, bool threshold_err, u64 misc)
  m.misc = misc;
 
  if (m.status & MCI_STATUS_ADDRV)
- rdmsrl(msr_ops.addr(bank), m.addr);
+ rdmsrl(msr_addr, m.addr);
 
  mce_log(&m);
- wrmsrl(msr_ops.status(bank), 0);
+
+ wrmsrl(msr_status, 0);
 }
 
 static inline void __smp_deferred_error_interrupt(void)
@@ -479,17 +491,21 @@ asmlinkage __visible void smp_trace_deferred_error_interrupt(void)
 /* APIC interrupt handler for deferred errors */
 static void amd_deferred_error_interrupt(void)
 {
- u64 status;
  unsigned int bank;
+ u32 msr_status;
+ u64 status;
 
  for (bank = 0; bank < mca_cfg.banks; ++bank) {
- rdmsrl(msr_ops.status(bank), status);
+ msr_status = (mce_flags.smca) ? MSR_AMD64_SMCA_MCx_DESTAT(bank)
+      : msr_ops.status(bank);
+
+ rdmsrl(msr_status, status);
 
  if (!(status & MCI_STATUS_VAL) ||
     !(status & MCI_STATUS_DEFERRED))
  continue;
 
- __log_error(bank, false, 0);
+ __log_error(bank, true, false, 0);
  break;
  }
 }
@@ -544,7 +560,7 @@ static void amd_threshold_interrupt(void)
  return;
 
 log:
- __log_error(bank, true, ((u64)high << 32) | low);
+ __log_error(bank, false, true, ((u64)high << 32) | low);
 }
 
 /*
--
2.7.3

Reply | Threaded
Open this post in threaded view
|

[tip:ras/core] x86/mce/AMD: Log Deferred Errors using SMCA MCA_DE{STAT,ADDR} registers

tip-bot for Peter Zijlstra
Commit-ID:  34102009580a047c02b21f089f7fc7f65e605887
Gitweb:     http://git.kernel.org/tip/34102009580a047c02b21f089f7fc7f65e605887
Author:     Yazen Ghannam <[hidden email]>
AuthorDate: Wed, 11 May 2016 14:58:23 +0200
Committer:  Ingo Molnar <[hidden email]>
CommitDate: Thu, 12 May 2016 09:08:19 +0200

x86/mce/AMD: Log Deferred Errors using SMCA MCA_DE{STAT,ADDR} registers

Scalable MCA provides new registers for all banks for logging deferred
errors: MCA_DESTAT and MCA_DEADDR. Deferred errors are always logged to
these registers.

Update the AMD deferred error handler to use these registers, if
available.

Signed-off-by: Yazen Ghannam <[hidden email]>
[ Sanity-check __log_error() args, massage a bit. ]
Signed-off-by: Borislav Petkov <[hidden email]>
Cc: Andy Lutomirski <[hidden email]>
Cc: Aravind Gopalakrishnan <[hidden email]>
Cc: Borislav Petkov <[hidden email]>
Cc: Brian Gerst <[hidden email]>
Cc: Denys Vlasenko <[hidden email]>
Cc: H. Peter Anvin <[hidden email]>
Cc: Linus Torvalds <[hidden email]>
Cc: Peter Zijlstra <[hidden email]>
Cc: Thomas Gleixner <[hidden email]>
Cc: Tony Luck <[hidden email]>
Cc: linux-edac <[hidden email]>
Link: http://lkml.kernel.org/r/1462971509-3856-2-git-send-email-bp@...
Signed-off-by: Ingo Molnar <[hidden email]>
---
 arch/x86/include/asm/mce.h           |  4 ++++
 arch/x86/kernel/cpu/mcheck/mce_amd.c | 32 ++++++++++++++++++++++++--------
 2 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h
index 53ab697..8bf766e 100644
--- a/arch/x86/include/asm/mce.h
+++ b/arch/x86/include/asm/mce.h
@@ -110,6 +110,8 @@
 #define MSR_AMD64_SMCA_MC0_MISC0 0xc0002003
 #define MSR_AMD64_SMCA_MC0_CONFIG 0xc0002004
 #define MSR_AMD64_SMCA_MC0_IPID 0xc0002005
+#define MSR_AMD64_SMCA_MC0_DESTAT 0xc0002008
+#define MSR_AMD64_SMCA_MC0_DEADDR 0xc0002009
 #define MSR_AMD64_SMCA_MC0_MISC1 0xc000200a
 #define MSR_AMD64_SMCA_MCx_CTL(x) (MSR_AMD64_SMCA_MC0_CTL + 0x10*(x))
 #define MSR_AMD64_SMCA_MCx_STATUS(x) (MSR_AMD64_SMCA_MC0_STATUS + 0x10*(x))
@@ -117,6 +119,8 @@
 #define MSR_AMD64_SMCA_MCx_MISC(x) (MSR_AMD64_SMCA_MC0_MISC0 + 0x10*(x))
 #define MSR_AMD64_SMCA_MCx_CONFIG(x) (MSR_AMD64_SMCA_MC0_CONFIG + 0x10*(x))
 #define MSR_AMD64_SMCA_MCx_IPID(x) (MSR_AMD64_SMCA_MC0_IPID + 0x10*(x))
+#define MSR_AMD64_SMCA_MCx_DESTAT(x) (MSR_AMD64_SMCA_MC0_DESTAT + 0x10*(x))
+#define MSR_AMD64_SMCA_MCx_DEADDR(x) (MSR_AMD64_SMCA_MC0_DEADDR + 0x10*(x))
 #define MSR_AMD64_SMCA_MCx_MISCy(x, y) ((MSR_AMD64_SMCA_MC0_MISC1 + y) + (0x10*(x)))
 
 /*
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c
index c594680..d1b1e62 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_amd.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c
@@ -430,12 +430,23 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c)
  deferred_error_interrupt_enable(c);
 }
 
-static void __log_error(unsigned int bank, bool threshold_err, u64 misc)
+static void
+__log_error(unsigned int bank, bool deferred_err, bool threshold_err, u64 misc)
 {
+ u32 msr_status = msr_ops.status(bank);
+ u32 msr_addr = msr_ops.addr(bank);
  struct mce m;
  u64 status;
 
- rdmsrl(msr_ops.status(bank), status);
+ WARN_ON_ONCE(deferred_err && threshold_err);
+
+ if (deferred_err && mce_flags.smca) {
+ msr_status = MSR_AMD64_SMCA_MCx_DESTAT(bank);
+ msr_addr = MSR_AMD64_SMCA_MCx_DEADDR(bank);
+ }
+
+ rdmsrl(msr_status, status);
+
  if (!(status & MCI_STATUS_VAL))
  return;
 
@@ -448,10 +459,11 @@ static void __log_error(unsigned int bank, bool threshold_err, u64 misc)
  m.misc = misc;
 
  if (m.status & MCI_STATUS_ADDRV)
- rdmsrl(msr_ops.addr(bank), m.addr);
+ rdmsrl(msr_addr, m.addr);
 
  mce_log(&m);
- wrmsrl(msr_ops.status(bank), 0);
+
+ wrmsrl(msr_status, 0);
 }
 
 static inline void __smp_deferred_error_interrupt(void)
@@ -479,17 +491,21 @@ asmlinkage __visible void smp_trace_deferred_error_interrupt(void)
 /* APIC interrupt handler for deferred errors */
 static void amd_deferred_error_interrupt(void)
 {
- u64 status;
  unsigned int bank;
+ u32 msr_status;
+ u64 status;
 
  for (bank = 0; bank < mca_cfg.banks; ++bank) {
- rdmsrl(msr_ops.status(bank), status);
+ msr_status = (mce_flags.smca) ? MSR_AMD64_SMCA_MCx_DESTAT(bank)
+      : msr_ops.status(bank);
+
+ rdmsrl(msr_status, status);
 
  if (!(status & MCI_STATUS_VAL) ||
     !(status & MCI_STATUS_DEFERRED))
  continue;
 
- __log_error(bank, false, 0);
+ __log_error(bank, true, false, 0);
  break;
  }
 }
@@ -544,7 +560,7 @@ static void amd_threshold_interrupt(void)
  return;
 
 log:
- __log_error(bank, true, ((u64)high << 32) | low);
+ __log_error(bank, false, true, ((u64)high << 32) | low);
 }
 
 /*
Reply | Threaded
Open this post in threaded view
|

[tip:ras/core] x86/mce/AMD: Disable LogDeferredInMcaStat for SMCA systems

tip-bot for Peter Zijlstra
In reply to this post by Borislav Petkov-3
Commit-ID:  32544f060326bffa60dade49ce4595652df4d3ab
Gitweb:     http://git.kernel.org/tip/32544f060326bffa60dade49ce4595652df4d3ab
Author:     Yazen Ghannam <[hidden email]>
AuthorDate: Wed, 11 May 2016 14:58:24 +0200
Committer:  Ingo Molnar <[hidden email]>
CommitDate: Thu, 12 May 2016 09:08:20 +0200

x86/mce/AMD: Disable LogDeferredInMcaStat for SMCA systems

Disable Deferred Error logging in MCA_{STATUS,ADDR} additionally for
SMCA systems as this information will retrieved from MCA_DE{STAT,ADDR}
on those systems.

Signed-off-by: Yazen Ghannam <[hidden email]>
[ Simplify, drop SMCA_MCAX_EN_OFF define too. ]
Signed-off-by: Borislav Petkov <[hidden email]>
Cc: Andy Lutomirski <[hidden email]>
Cc: Aravind Gopalakrishnan <[hidden email]>
Cc: Borislav Petkov <[hidden email]>
Cc: Brian Gerst <[hidden email]>
Cc: Denys Vlasenko <[hidden email]>
Cc: H. Peter Anvin <[hidden email]>
Cc: Linus Torvalds <[hidden email]>
Cc: Peter Zijlstra <[hidden email]>
Cc: Thomas Gleixner <[hidden email]>
Cc: Tony Luck <[hidden email]>
Cc: linux-edac <[hidden email]>
Link: http://lkml.kernel.org/r/1462971509-3856-3-git-send-email-bp@...
Signed-off-by: Ingo Molnar <[hidden email]>
---
 arch/x86/kernel/cpu/mcheck/mce_amd.c | 38 +++++++++++++++++++++++++++---------
 1 file changed, 29 insertions(+), 9 deletions(-)

diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c
index d1b1e62..527ddae 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_amd.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c
@@ -54,14 +54,6 @@
 /* Threshold LVT offset is at MSR0xC0000410[15:12] */
 #define SMCA_THR_LVT_OFF 0xF000
 
-/*
- * OS is required to set the MCAX bit to acknowledge that it is now using the
- * new MSR ranges and new registers under each bank. It also means that the OS
- * will configure deferred errors in the new MCx_CONFIG register. If the bit is
- * not set, uncorrectable errors will cause a system panic.
- */
-#define SMCA_MCAX_EN_OFF 0x1
-
 static const char * const th_names[] = {
  "load_store",
  "insn_fetch",
@@ -374,7 +366,35 @@ prepare_threshold_block(unsigned int bank, unsigned int block, u32 addr,
  u32 smca_addr = MSR_AMD64_SMCA_MCx_CONFIG(bank);
 
  if (!rdmsr_safe(smca_addr, &smca_low, &smca_high)) {
- smca_high |= SMCA_MCAX_EN_OFF;
+ /*
+ * OS is required to set the MCAX bit to acknowledge
+ * that it is now using the new MSR ranges and new
+ * registers under each bank. It also means that the OS
+ * will configure deferred errors in the new MCx_CONFIG
+ * register. If the bit is not set, uncorrectable errors
+ * will cause a system panic.
+ *
+ * MCA_CONFIG[MCAX] is bit 32 (0 in the high portion of
+ * the MSR.)
+ */
+ smca_high |= BIT(0);
+
+ /*
+ * SMCA logs Deferred Error information in
+ * MCA_DE{STAT,ADDR} registers with the option of
+ * additionally logging to MCA_{STATUS,ADDR} if
+ * MCA_CONFIG[LogDeferredInMcaStat] is set.
+ *
+ * This bit is usually set by BIOS to retain the old
+ * behavior for OSes that don't use the new registers.
+ * Linux supports the new registers so let's disable
+ * that additional logging here.
+ *
+ * MCA_CONFIG[LogDeferredInMcaStat] is bit 34 (bit 2 in
+ * the high portion of the MSR).
+ */
+ smca_high &= ~BIT(2);
+
  wrmsr(smca_addr, smca_low, smca_high);
  }
 
Reply | Threaded
Open this post in threaded view
|

[tip:ras/core] x86/mce/AMD: Save an indentation level in prepare_threshold_block()

tip-bot for Peter Zijlstra
In reply to this post by Borislav Petkov-3
Commit-ID:  e128b4f4833cc1e0ce46dfb978763b260f166188
Gitweb:     http://git.kernel.org/tip/e128b4f4833cc1e0ce46dfb978763b260f166188
Author:     Borislav Petkov <[hidden email]>
AuthorDate: Wed, 11 May 2016 14:58:25 +0200
Committer:  Ingo Molnar <[hidden email]>
CommitDate: Thu, 12 May 2016 09:08:21 +0200

x86/mce/AMD: Save an indentation level in prepare_threshold_block()

Do the !SMCA work first and then save us an indentation level for the
SMCA code.

No functionality change.

Signed-off-by: Borislav Petkov <[hidden email]>
Cc: Andy Lutomirski <[hidden email]>
Cc: Aravind Gopalakrishnan <[hidden email]>
Cc: Borislav Petkov <[hidden email]>
Cc: Brian Gerst <[hidden email]>
Cc: Denys Vlasenko <[hidden email]>
Cc: H. Peter Anvin <[hidden email]>
Cc: Linus Torvalds <[hidden email]>
Cc: Peter Zijlstra <[hidden email]>
Cc: Thomas Gleixner <[hidden email]>
Cc: Tony Luck <[hidden email]>
Cc: Yazen Ghannam <[hidden email]>
Cc: linux-edac <[hidden email]>
Link: http://lkml.kernel.org/r/1462971509-3856-4-git-send-email-bp@...
Signed-off-by: Ingo Molnar <[hidden email]>
---
 arch/x86/kernel/cpu/mcheck/mce_amd.c | 78 ++++++++++++++++++------------------
 1 file changed, 38 insertions(+), 40 deletions(-)

diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c
index 527ddae..10b0661 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_amd.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c
@@ -343,6 +343,7 @@ prepare_threshold_block(unsigned int bank, unsigned int block, u32 addr,
  int offset, u32 misc_high)
 {
  unsigned int cpu = smp_processor_id();
+ u32 smca_low, smca_high, smca_addr;
  struct threshold_block b;
  int new;
 
@@ -361,52 +362,49 @@ prepare_threshold_block(unsigned int bank, unsigned int block, u32 addr,
 
  b.interrupt_enable = 1;
 
- if (mce_flags.smca) {
- u32 smca_low, smca_high;
- u32 smca_addr = MSR_AMD64_SMCA_MCx_CONFIG(bank);
-
- if (!rdmsr_safe(smca_addr, &smca_low, &smca_high)) {
- /*
- * OS is required to set the MCAX bit to acknowledge
- * that it is now using the new MSR ranges and new
- * registers under each bank. It also means that the OS
- * will configure deferred errors in the new MCx_CONFIG
- * register. If the bit is not set, uncorrectable errors
- * will cause a system panic.
- *
- * MCA_CONFIG[MCAX] is bit 32 (0 in the high portion of
- * the MSR.)
- */
- smca_high |= BIT(0);
+ if (!mce_flags.smca) {
+ new = (misc_high & MASK_LVTOFF_HI) >> 20;
+ goto set_offset;
+ }
 
- /*
- * SMCA logs Deferred Error information in
- * MCA_DE{STAT,ADDR} registers with the option of
- * additionally logging to MCA_{STATUS,ADDR} if
- * MCA_CONFIG[LogDeferredInMcaStat] is set.
- *
- * This bit is usually set by BIOS to retain the old
- * behavior for OSes that don't use the new registers.
- * Linux supports the new registers so let's disable
- * that additional logging here.
- *
- * MCA_CONFIG[LogDeferredInMcaStat] is bit 34 (bit 2 in
- * the high portion of the MSR).
- */
- smca_high &= ~BIT(2);
+ smca_addr = MSR_AMD64_SMCA_MCx_CONFIG(bank);
 
- wrmsr(smca_addr, smca_low, smca_high);
- }
+ if (!rdmsr_safe(smca_addr, &smca_low, &smca_high)) {
+ /*
+ * OS is required to set the MCAX bit to acknowledge that it is
+ * now using the new MSR ranges and new registers under each
+ * bank. It also means that the OS will configure deferred
+ * errors in the new MCx_CONFIG register. If the bit is not set,
+ * uncorrectable errors will cause a system panic.
+ *
+ * MCA_CONFIG[MCAX] is bit 32 (0 in the high portion of the MSR.)
+ */
+ smca_high |= BIT(0);
 
- /* Gather LVT offset for thresholding: */
- if (rdmsr_safe(MSR_CU_DEF_ERR, &smca_low, &smca_high))
- goto out;
+ /*
+ * SMCA logs Deferred Error information in MCA_DE{STAT,ADDR}
+ * registers with the option of additionally logging to
+ * MCA_{STATUS,ADDR} if MCA_CONFIG[LogDeferredInMcaStat] is set.
+ *
+ * This bit is usually set by BIOS to retain the old behavior
+ * for OSes that don't use the new registers. Linux supports the
+ * new registers so let's disable that additional logging here.
+ *
+ * MCA_CONFIG[LogDeferredInMcaStat] is bit 34 (bit 2 in the high
+ * portion of the MSR).
+ */
+ smca_high &= ~BIT(2);
 
- new = (smca_low & SMCA_THR_LVT_OFF) >> 12;
- } else {
- new = (misc_high & MASK_LVTOFF_HI) >> 20;
+ wrmsr(smca_addr, smca_low, smca_high);
  }
 
+ /* Gather LVT offset for thresholding: */
+ if (rdmsr_safe(MSR_CU_DEF_ERR, &smca_low, &smca_high))
+ goto out;
+
+ new = (smca_low & SMCA_THR_LVT_OFF) >> 12;
+
+set_offset:
  offset = setup_APIC_mce_threshold(offset, new);
 
  if ((offset == new) && (mce_threshold_vector != amd_threshold_interrupt))
Reply | Threaded
Open this post in threaded view
|

[tip:ras/core] x86/cpu: Add detection of AMD RAS Capabilities

tip-bot for Peter Zijlstra
In reply to this post by Borislav Petkov-3
Commit-ID:  71faad43060d3d2040583635fbf7d1bdb3d04118
Gitweb:     http://git.kernel.org/tip/71faad43060d3d2040583635fbf7d1bdb3d04118
Author:     Yazen Ghannam <[hidden email]>
AuthorDate: Wed, 11 May 2016 14:58:26 +0200
Committer:  Ingo Molnar <[hidden email]>
CommitDate: Thu, 12 May 2016 09:08:22 +0200

x86/cpu: Add detection of AMD RAS Capabilities

Add a new CPUID leaf to hold the contents of CPUID 0x80000007_EBX (RasCap).

Define bits that are currently in use:

 Bit 0: McaOverflowRecov
 Bit 1: SUCCOR
 Bit 3: ScalableMca

Signed-off-by: Yazen Ghannam <[hidden email]>
[ Shorten comment. ]
Signed-off-by: Borislav Petkov <[hidden email]>
Cc: Andy Lutomirski <[hidden email]>
Cc: Borislav Petkov <[hidden email]>
Cc: Brian Gerst <[hidden email]>
Cc: Denys Vlasenko <[hidden email]>
Cc: H. Peter Anvin <[hidden email]>
Cc: Linus Torvalds <[hidden email]>
Cc: Peter Zijlstra <[hidden email]>
Cc: Thomas Gleixner <[hidden email]>
Cc: Tony Luck <[hidden email]>
Cc: linux-edac <[hidden email]>
Link: http://lkml.kernel.org/r/1462971509-3856-5-git-send-email-bp@...
Signed-off-by: Ingo Molnar <[hidden email]>
---
 arch/x86/include/asm/cpufeature.h  |  1 +
 arch/x86/include/asm/cpufeatures.h |  7 ++++++-
 arch/x86/kernel/cpu/common.c       | 10 +++++++---
 3 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 3636ec0..53ac9bb 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -27,6 +27,7 @@ enum cpuid_leafs
  CPUID_6_EAX,
  CPUID_8000_000A_EDX,
  CPUID_7_ECX,
+ CPUID_8000_0007_EBX,
 };
 
 #ifdef CONFIG_X86_FEATURE_NAMES
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index 8f9afef..d4e5018 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -12,7 +12,7 @@
 /*
  * Defines x86 CPU feature bits
  */
-#define NCAPINTS 17 /* N 32-bit words worth of info */
+#define NCAPINTS 18 /* N 32-bit words worth of info */
 #define NBUGINTS 1 /* N 32-bit bug flags */
 
 /*
@@ -280,6 +280,11 @@
 #define X86_FEATURE_PKU (16*32+ 3) /* Protection Keys for Userspace */
 #define X86_FEATURE_OSPKE (16*32+ 4) /* OS Protection Keys Enable */
 
+/* AMD-defined CPU features, CPUID level 0x80000007 (ebx), word 17 */
+#define X86_FEATURE_OVERFLOW_RECOV (17*32+0) /* MCA overflow recovery support */
+#define X86_FEATURE_SUCCOR (17*32+1) /* Uncorrectable error containment and recovery */
+#define X86_FEATURE_SMCA (17*32+3) /* Scalable MCA */
+
 /*
  * BUG word(s)
  */
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 8394b3d..dbc6f06 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -717,6 +717,13 @@ void get_cpu_cap(struct cpuinfo_x86 *c)
  }
  }
 
+ if (c->extended_cpuid_level >= 0x80000007) {
+ cpuid(0x80000007, &eax, &ebx, &ecx, &edx);
+
+ c->x86_capability[CPUID_8000_0007_EBX] = ebx;
+ c->x86_power = edx;
+ }
+
  if (c->extended_cpuid_level >= 0x80000008) {
  cpuid(0x80000008, &eax, &ebx, &ecx, &edx);
 
@@ -729,9 +736,6 @@ void get_cpu_cap(struct cpuinfo_x86 *c)
  c->x86_phys_bits = 36;
 #endif
 
- if (c->extended_cpuid_level >= 0x80000007)
- c->x86_power = cpuid_edx(0x80000007);
-
  if (c->extended_cpuid_level >= 0x8000000a)
  c->x86_capability[CPUID_8000_000A_EDX] = cpuid_edx(0x8000000a);
 
Reply | Threaded
Open this post in threaded view
|

[tip:ras/core] x86/mce: Update AMD mcheck init to use cpu_has() facilities

tip-bot for Peter Zijlstra
In reply to this post by Borislav Petkov-3
Commit-ID:  14cddfd5308b0880abd6e58b6660f5cc8e8020f9
Gitweb:     http://git.kernel.org/tip/14cddfd5308b0880abd6e58b6660f5cc8e8020f9
Author:     Yazen Ghannam <[hidden email]>
AuthorDate: Wed, 11 May 2016 14:58:27 +0200
Committer:  Ingo Molnar <[hidden email]>
CommitDate: Thu, 12 May 2016 09:08:22 +0200

x86/mce: Update AMD mcheck init to use cpu_has() facilities

Use cpu_has() facilities to find available RAS features rather than
directly reading CPUID 0x80000007_EBX.

Signed-off-by: Yazen Ghannam <[hidden email]>
[ Use the struct cpuinfo_x86 ptr instead. ]
Signed-off-by: Borislav Petkov <[hidden email]>
Cc: Andy Lutomirski <[hidden email]>
Cc: Borislav Petkov <[hidden email]>
Cc: Brian Gerst <[hidden email]>
Cc: Denys Vlasenko <[hidden email]>
Cc: H. Peter Anvin <[hidden email]>
Cc: Linus Torvalds <[hidden email]>
Cc: Peter Zijlstra <[hidden email]>
Cc: Thomas Gleixner <[hidden email]>
Cc: Tony Luck <[hidden email]>
Cc: linux-edac <[hidden email]>
Link: http://lkml.kernel.org/r/1462971509-3856-6-git-send-email-bp@...
Signed-off-by: Ingo Molnar <[hidden email]>
---
 arch/x86/kernel/cpu/mcheck/mce.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index aeda446..92e5e37 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -1683,11 +1683,9 @@ static void __mcheck_cpu_init_vendor(struct cpuinfo_x86 *c)
  break;
 
  case X86_VENDOR_AMD: {
- u32 ebx = cpuid_ebx(0x80000007);
-
- mce_flags.overflow_recov = !!(ebx & BIT(0));
- mce_flags.succor = !!(ebx & BIT(1));
- mce_flags.smca = !!(ebx & BIT(3));
+ mce_flags.overflow_recov = !!cpu_has(c, X86_FEATURE_OVERFLOW_RECOV);
+ mce_flags.succor = !!cpu_has(c, X86_FEATURE_SUCCOR);
+ mce_flags.smca = !!cpu_has(c, X86_FEATURE_SMCA);
 
  /*
  * Install proper ops for Scalable MCA enabled processors
Reply | Threaded
Open this post in threaded view
|

[tip:ras/core] EDAC, mce_amd: Detect SMCA using X86_FEATURE_SMCA

tip-bot for Peter Zijlstra
In reply to this post by Borislav Petkov-3
Commit-ID:  a348ed83d9efe8c11ecc85c15d7329825b97431e
Gitweb:     http://git.kernel.org/tip/a348ed83d9efe8c11ecc85c15d7329825b97431e
Author:     Yazen Ghannam <[hidden email]>
AuthorDate: Wed, 11 May 2016 14:58:28 +0200
Committer:  Ingo Molnar <[hidden email]>
CommitDate: Thu, 12 May 2016 09:08:23 +0200

EDAC, mce_amd: Detect SMCA using X86_FEATURE_SMCA

Use X86_FEATURE_SMCA when detecting if SMCA is available instead of
directly using CPUID 0x80000007_EBX.

Signed-off-by: Yazen Ghannam <[hidden email]>
Signed-off-by: Borislav Petkov <[hidden email]>
Cc: Andy Lutomirski <[hidden email]>
Cc: Borislav Petkov <[hidden email]>
Cc: Brian Gerst <[hidden email]>
Cc: Denys Vlasenko <[hidden email]>
Cc: H. Peter Anvin <[hidden email]>
Cc: Linus Torvalds <[hidden email]>
Cc: Peter Zijlstra <[hidden email]>
Cc: Thomas Gleixner <[hidden email]>
Cc: Tony Luck <[hidden email]>
Cc: linux-edac <[hidden email]>
Link: http://lkml.kernel.org/r/1462971509-3856-7-git-send-email-bp@...
Signed-off-by: Ingo Molnar <[hidden email]>
---
 drivers/edac/mce_amd.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/edac/mce_amd.c b/drivers/edac/mce_amd.c
index 49768c0..9b6800a 100644
--- a/drivers/edac/mce_amd.c
+++ b/drivers/edac/mce_amd.c
@@ -1052,7 +1052,6 @@ int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
  struct mce *m = (struct mce *)data;
  struct cpuinfo_x86 *c = &cpu_data(m->extcpu);
  int ecc;
- u32 ebx = cpuid_ebx(0x80000007);
 
  if (amd_filter_mce(m))
  return NOTIFY_STOP;
@@ -1075,7 +1074,7 @@ int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
  ((m->status & MCI_STATUS_DEFERRED) ? "Deferred" : "-"),
  ((m->status & MCI_STATUS_POISON)   ? "Poison"   : "-"));
 
- if (!!(ebx & BIT(3))) {
+ if (boot_cpu_has(X86_FEATURE_SMCA)) {
  u32 low, high;
  u32 addr = MSR_AMD64_SMCA_MCx_CONFIG(m->bank);
 
@@ -1094,7 +1093,7 @@ int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
  if (m->status & MCI_STATUS_ADDRV)
  pr_emerg(HW_ERR "MC%d Error Address: 0x%016llx\n", m->bank, m->addr);
 
- if (!!(ebx & BIT(3))) {
+ if (boot_cpu_has(X86_FEATURE_SMCA)) {
  decode_smca_errors(m);
  goto err_code;
  }
@@ -1149,7 +1148,6 @@ static struct notifier_block amd_mce_dec_nb = {
 static int __init mce_amd_init(void)
 {
  struct cpuinfo_x86 *c = &boot_cpu_data;
- u32 ebx;
 
  if (c->x86_vendor != X86_VENDOR_AMD)
  return -ENODEV;
@@ -1205,9 +1203,8 @@ static int __init mce_amd_init(void)
  break;
 
  case 0x17:
- ebx = cpuid_ebx(0x80000007);
  xec_mask = 0x3f;
- if (!(ebx & BIT(3))) {
+ if (!boot_cpu_has(X86_FEATURE_SMCA)) {
  printk(KERN_WARNING "Decoding supported only on Scalable MCA processors.\n");
  goto err_out;
  }
Reply | Threaded
Open this post in threaded view
|

[tip:ras/core] x86/RAS: Add SMCA support to AMD Error Injector

tip-bot for Peter Zijlstra
In reply to this post by Borislav Petkov-3
Commit-ID:  754a92305980b1fecffe033dd3fdc49c37f8e4b0
Gitweb:     http://git.kernel.org/tip/754a92305980b1fecffe033dd3fdc49c37f8e4b0
Author:     Yazen Ghannam <[hidden email]>
AuthorDate: Wed, 11 May 2016 14:58:29 +0200
Committer:  Ingo Molnar <[hidden email]>
CommitDate: Thu, 12 May 2016 09:08:23 +0200

x86/RAS: Add SMCA support to AMD Error Injector

Use SMCA MSRs when writing to MCA_{STATUS,ADDR,MISC} and
MCA_DE{STAT,ADDR} when injecting Deferred Errors on SMCA platforms.

Signed-off-by: Yazen Ghannam <[hidden email]>
Signed-off-by: Borislav Petkov <[hidden email]>
Cc: Andy Lutomirski <[hidden email]>
Cc: Aravind Gopalakrishnan <[hidden email]>
Cc: Borislav Petkov <[hidden email]>
Cc: Brian Gerst <[hidden email]>
Cc: Denys Vlasenko <[hidden email]>
Cc: H. Peter Anvin <[hidden email]>
Cc: Linus Torvalds <[hidden email]>
Cc: Peter Zijlstra <[hidden email]>
Cc: Thomas Gleixner <[hidden email]>
Cc: Tony Luck <[hidden email]>
Cc: linux-edac <[hidden email]>
Link: http://lkml.kernel.org/r/1462971509-3856-8-git-send-email-bp@...
Signed-off-by: Ingo Molnar <[hidden email]>
---
 arch/x86/ras/mce_amd_inj.c | 31 +++++++++++++++++++++++++------
 1 file changed, 25 insertions(+), 6 deletions(-)

diff --git a/arch/x86/ras/mce_amd_inj.c b/arch/x86/ras/mce_amd_inj.c
index 9e02dca..e69f470 100644
--- a/arch/x86/ras/mce_amd_inj.c
+++ b/arch/x86/ras/mce_amd_inj.c
@@ -290,14 +290,33 @@ static void do_inject(void)
  wrmsr_on_cpu(cpu, MSR_IA32_MCG_STATUS,
      (u32)mcg_status, (u32)(mcg_status >> 32));
 
- wrmsr_on_cpu(cpu, MSR_IA32_MCx_STATUS(b),
-     (u32)i_mce.status, (u32)(i_mce.status >> 32));
+ if (boot_cpu_has(X86_FEATURE_SMCA)) {
+ if (inj_type == DFR_INT_INJ) {
+ wrmsr_on_cpu(cpu, MSR_AMD64_SMCA_MCx_DESTAT(b),
+     (u32)i_mce.status, (u32)(i_mce.status >> 32));
+
+ wrmsr_on_cpu(cpu, MSR_AMD64_SMCA_MCx_DEADDR(b),
+     (u32)i_mce.addr, (u32)(i_mce.addr >> 32));
+ } else {
+ wrmsr_on_cpu(cpu, MSR_AMD64_SMCA_MCx_STATUS(b),
+     (u32)i_mce.status, (u32)(i_mce.status >> 32));
+
+ wrmsr_on_cpu(cpu, MSR_AMD64_SMCA_MCx_ADDR(b),
+     (u32)i_mce.addr, (u32)(i_mce.addr >> 32));
+ }
+
+ wrmsr_on_cpu(cpu, MSR_AMD64_SMCA_MCx_MISC(b),
+     (u32)i_mce.misc, (u32)(i_mce.misc >> 32));
+ } else {
+ wrmsr_on_cpu(cpu, MSR_IA32_MCx_STATUS(b),
+     (u32)i_mce.status, (u32)(i_mce.status >> 32));
 
- wrmsr_on_cpu(cpu, MSR_IA32_MCx_ADDR(b),
-     (u32)i_mce.addr, (u32)(i_mce.addr >> 32));
+ wrmsr_on_cpu(cpu, MSR_IA32_MCx_ADDR(b),
+     (u32)i_mce.addr, (u32)(i_mce.addr >> 32));
 
- wrmsr_on_cpu(cpu, MSR_IA32_MCx_MISC(b),
-     (u32)i_mce.misc, (u32)(i_mce.misc >> 32));
+ wrmsr_on_cpu(cpu, MSR_IA32_MCx_MISC(b),
+     (u32)i_mce.misc, (u32)(i_mce.misc >> 32));
+ }
 
  toggle_hw_mce_inject(cpu, false);