[PATCH v3 2/2] x86/mce/AMD: Carve out SMCA bank configuration

2017-04-25 Thread Yazen Ghannam
From: Yazen Ghannam 

Scalable MCA systems have a new MCA_CONFIG register that we use to
configure each bank. We currently use this when we set up thresholding.
However, this is logically separate.

Group all SMCA-related initialization into a single, separate function.
This includes setting MCA_CONFIG and gathering SMCA bank info.

Signed-off-by: Yazen Ghannam 
---
Link:
https://lkml.kernel.org/r/1491326672-48298-2-git-send-email-yazen.ghan...@amd.com

v2->v3:
- Pass in CPU to smca_configure().

v1->v2:
- Merge get_smca_bank_info() and set_smca_config() into smca_configure().

 arch/x86/kernel/cpu/mcheck/mce_amd.c | 76 ++--
 1 file changed, 38 insertions(+), 38 deletions(-)

diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c 
b/arch/x86/kernel/cpu/mcheck/mce_amd.c
index e6e507d..f97bc60 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_amd.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c
@@ -164,17 +164,48 @@ static void default_deferred_error_interrupt(void)
 }
 void (*deferred_error_int_vector)(void) = default_deferred_error_interrupt;
 
-static void get_smca_bank_info(unsigned int bank)
+static void smca_configure(unsigned int bank, unsigned int cpu)
 {
-   unsigned int i, hwid_mcatype, cpu = smp_processor_id();
+   unsigned int i, hwid_mcatype;
struct smca_hwid *s_hwid;
-   u32 high, instance_id;
+   u32 high, low;
+   u32 smca_config = MSR_AMD64_SMCA_MCx_CONFIG(bank);
+
+   /* Set appropriate bits in MCA_CONFIG */
+   if (!rdmsr_safe(smca_config, , )) {
+   /*
+* 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.)
+*/
+   high |= BIT(0);
+
+   /*
+* SMCA sets the Deferred Error Interrupt type per bank.
+*
+* MCA_CONFIG[DeferredIntTypeSupported] is bit 5, and tells us
+* if the DeferredIntType bit field is available.
+*
+* MCA_CONFIG[DeferredIntType] is bits [38:37] ([6:5] in the
+* high portion of the MSR). OS should set this to 0x1 to enable
+* APIC based interrupt. First, check that no interrupt has been
+* set.
+*/
+   if ((low & BIT(5)) && !((high >> 5) & 0x3))
+   high |= BIT(5);
+
+   wrmsr(smca_config, low, high);
+   }
 
/* Collect bank_info using CPU 0 for now. */
if (cpu)
return;
 
-   if (rdmsr_safe_on_cpu(cpu, MSR_AMD64_SMCA_MCx_IPID(bank), _id, 
)) {
+   if (rdmsr_safe_on_cpu(cpu, MSR_AMD64_SMCA_MCx_IPID(bank), , )) 
{
pr_warn("Failed to read MCA_IPID for bank %d\n", bank);
return;
}
@@ -191,7 +222,7 @@ static void get_smca_bank_info(unsigned int bank)
 smca_get_name(s_hwid->bank_type));
 
smca_banks[bank].hwid = s_hwid;
-   smca_banks[bank].id = instance_id;
+   smca_banks[bank].id = low;
smca_banks[bank].sysfs_id = s_hwid->count++;
break;
}
@@ -433,7 +464,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;
+   u32 smca_low, smca_high;
struct threshold_block b;
int new;
 
@@ -457,37 +488,6 @@ prepare_threshold_block(unsigned int bank, unsigned int 
block, u32 addr,
goto set_offset;
}
 
-   smca_addr = MSR_AMD64_SMCA_MCx_CONFIG(bank);
-
-   if (!rdmsr_safe(smca_addr, _low, _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);
-
-   /*
-* SMCA sets the Deferred Error Interrupt type per bank.
-*
-* MCA_CONFIG[DeferredIntTypeSupported] is bit 5, and tells us
-* if the DeferredIntType 

[PATCH v3 2/2] x86/mce/AMD: Carve out SMCA bank configuration

2017-04-25 Thread Yazen Ghannam
From: Yazen Ghannam 

Scalable MCA systems have a new MCA_CONFIG register that we use to
configure each bank. We currently use this when we set up thresholding.
However, this is logically separate.

Group all SMCA-related initialization into a single, separate function.
This includes setting MCA_CONFIG and gathering SMCA bank info.

Signed-off-by: Yazen Ghannam 
---
Link:
https://lkml.kernel.org/r/1491326672-48298-2-git-send-email-yazen.ghan...@amd.com

v2->v3:
- Pass in CPU to smca_configure().

v1->v2:
- Merge get_smca_bank_info() and set_smca_config() into smca_configure().

 arch/x86/kernel/cpu/mcheck/mce_amd.c | 76 ++--
 1 file changed, 38 insertions(+), 38 deletions(-)

diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c 
b/arch/x86/kernel/cpu/mcheck/mce_amd.c
index e6e507d..f97bc60 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_amd.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c
@@ -164,17 +164,48 @@ static void default_deferred_error_interrupt(void)
 }
 void (*deferred_error_int_vector)(void) = default_deferred_error_interrupt;
 
-static void get_smca_bank_info(unsigned int bank)
+static void smca_configure(unsigned int bank, unsigned int cpu)
 {
-   unsigned int i, hwid_mcatype, cpu = smp_processor_id();
+   unsigned int i, hwid_mcatype;
struct smca_hwid *s_hwid;
-   u32 high, instance_id;
+   u32 high, low;
+   u32 smca_config = MSR_AMD64_SMCA_MCx_CONFIG(bank);
+
+   /* Set appropriate bits in MCA_CONFIG */
+   if (!rdmsr_safe(smca_config, , )) {
+   /*
+* 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.)
+*/
+   high |= BIT(0);
+
+   /*
+* SMCA sets the Deferred Error Interrupt type per bank.
+*
+* MCA_CONFIG[DeferredIntTypeSupported] is bit 5, and tells us
+* if the DeferredIntType bit field is available.
+*
+* MCA_CONFIG[DeferredIntType] is bits [38:37] ([6:5] in the
+* high portion of the MSR). OS should set this to 0x1 to enable
+* APIC based interrupt. First, check that no interrupt has been
+* set.
+*/
+   if ((low & BIT(5)) && !((high >> 5) & 0x3))
+   high |= BIT(5);
+
+   wrmsr(smca_config, low, high);
+   }
 
/* Collect bank_info using CPU 0 for now. */
if (cpu)
return;
 
-   if (rdmsr_safe_on_cpu(cpu, MSR_AMD64_SMCA_MCx_IPID(bank), _id, 
)) {
+   if (rdmsr_safe_on_cpu(cpu, MSR_AMD64_SMCA_MCx_IPID(bank), , )) 
{
pr_warn("Failed to read MCA_IPID for bank %d\n", bank);
return;
}
@@ -191,7 +222,7 @@ static void get_smca_bank_info(unsigned int bank)
 smca_get_name(s_hwid->bank_type));
 
smca_banks[bank].hwid = s_hwid;
-   smca_banks[bank].id = instance_id;
+   smca_banks[bank].id = low;
smca_banks[bank].sysfs_id = s_hwid->count++;
break;
}
@@ -433,7 +464,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;
+   u32 smca_low, smca_high;
struct threshold_block b;
int new;
 
@@ -457,37 +488,6 @@ prepare_threshold_block(unsigned int bank, unsigned int 
block, u32 addr,
goto set_offset;
}
 
-   smca_addr = MSR_AMD64_SMCA_MCx_CONFIG(bank);
-
-   if (!rdmsr_safe(smca_addr, _low, _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);
-
-   /*
-* SMCA sets the Deferred Error Interrupt type per bank.
-*
-* MCA_CONFIG[DeferredIntTypeSupported] is bit 5, and tells us
-* if the DeferredIntType bit field is available.
-*
-