Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1310527 > unrolled thread

[PATCH V2 4/5] x86/mcheck/AMD: Fix LVT offset configuration for thresholding

Started byAravind Gopalakrishnan <Aravind.Gopalakrishnan@amd.com>
First post2016-01-16 00:50 +0100
Last post2016-01-16 11:50 +0100
Articles 3 — 2 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  [PATCH V2 4/5] x86/mcheck/AMD: Fix LVT offset configuration for thresholding Aravind Gopalakrishnan <Aravind.Gopalakrishnan@amd.com> - 2016-01-16 00:50 +0100
    Re: [PATCH V2 4/5] x86/mcheck/AMD: Fix LVT offset configuration for  thresholding Borislav Petkov <bp@alien8.de> - 2016-01-16 11:40 +0100
    Re: [PATCH V2 4/5] x86/mcheck/AMD: Fix LVT offset configuration for  thresholding Borislav Petkov <bp@alien8.de> - 2016-01-16 11:50 +0100

#1310527 — [PATCH V2 4/5] x86/mcheck/AMD: Fix LVT offset configuration for thresholding

FromAravind Gopalakrishnan <Aravind.Gopalakrishnan@amd.com>
Date2016-01-16 00:50 +0100
Subject[PATCH V2 4/5] x86/mcheck/AMD: Fix LVT offset configuration for thresholding
Message-ID<qRmhY-4D4-3@gated-at.bofh.it>
For processor families with  SMCA feature, the LVT offset
for threshold interrupts is configured only in MSR 0xC0000410
and not in each per bank MISC register as was done in earlier
families.

Fixing the code here to obtain the LVT offset from the correct
MSR for those families which have SMCA feature enabled.

Signed-off-by: Aravind Gopalakrishnan <Aravind.Gopalakrishnan@amd.com>
---
 arch/x86/kernel/cpu/mcheck/mce_amd.c | 34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c
index e650fdc..29a7688 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_amd.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c
@@ -49,6 +49,15 @@
 #define DEF_LVT_OFF		0x2
 #define DEF_INT_TYPE_APIC	0x2
 
+/*
+ * SMCA settings:
+ * The following defines provide masks or bit positions of
+ * MSRs that are applicable only to SMCA enabled processors
+ */
+
+/* Threshold LVT offset is at MSR0xC0000410[15:12] */
+#define SMCA_THR_LVT_OFF	0xF000
+
 static const char * const th_names[] = {
 	"load_store",
 	"insn_fetch",
@@ -143,6 +152,15 @@ static int lvt_off_valid(struct threshold_block *b, int apic, u32 lo, u32 hi)
 	}
 
 	if (apic != msr) {
+		/*
+		 * For SMCA enabled processors, LVT offset is programmed at
+		 * different MSR and BIOS provides the value.
+		 * The original field where LVT offset was set is Reserved.
+		 * So, return early here.
+		 */
+		if (mce_flags.smca)
+			return 0;
+
 		pr_err(FW_BUG "cpu %d, invalid threshold interrupt offset %d "
 		       "for bank %d, block %d (MSR%08X=0x%x%08x)\n",
 		       b->cpu, apic, b->bank, b->block, b->address, hi, lo);
@@ -301,7 +319,21 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c)
 				goto init;
 
 			b.interrupt_enable = 1;
-			new	= (high & MASK_LVTOFF_HI) >> 20;
+
+			if (mce_flags.smca) {
+				u32 smca_low = 0, smca_high = 0;
+
+				/* Gather LVT offset for thresholding */
+				if (rdmsr_safe(MSR_CU_DEF_ERR,
+					       &smca_low,
+					       &smca_high))
+					break;
+
+				new = (smca_low & SMCA_THR_LVT_OFF) >> 12;
+			} else {
+				new	= (high & MASK_LVTOFF_HI) >> 20;
+			}
+
 			offset  = setup_APIC_mce_threshold(offset, new);
 
 			if ((offset == new) &&
-- 
2.7.0

[toc] | [next] | [standalone]


#1310920 — Re: [PATCH V2 4/5] x86/mcheck/AMD: Fix LVT offset configuration for thresholding

FromBorislav Petkov <bp@alien8.de>
Date2016-01-16 11:40 +0100
SubjectRe: [PATCH V2 4/5] x86/mcheck/AMD: Fix LVT offset configuration for thresholding
Message-ID<qRwqZ-36E-1@gated-at.bofh.it>
In reply to#1310527
On Fri, Jan 15, 2016 at 05:50:35PM -0600, Aravind Gopalakrishnan wrote:
> For processor families with  SMCA feature, the LVT offset
> for threshold interrupts is configured only in MSR 0xC0000410
> and not in each per bank MISC register as was done in earlier
> families.
> 
> Fixing the code here to obtain the LVT offset from the correct
> MSR for those families which have SMCA feature enabled.
> 
> Signed-off-by: Aravind Gopalakrishnan <Aravind.Gopalakrishnan@amd.com>
> ---
>  arch/x86/kernel/cpu/mcheck/mce_amd.c | 34 +++++++++++++++++++++++++++++++++-
>  1 file changed, 33 insertions(+), 1 deletion(-)

Did a small cleanup ontop:

---
From: Borislav Petkov <bp@suse.de>
Subject: [PATCH] x86/mce/AMD: Carve out threshold block preparation

mce_amd_feature_init() was getting pretty fat, carve out the
threshold_block setup into a separate function on order to simplify
flow and make it more understandable.

No functionality change.

Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: Aravind Gopalakrishnan <Aravind.Gopalakrishnan@amd.com>
---
 arch/x86/kernel/cpu/mcheck/mce_amd.c | 88 ++++++++++++++++++++----------------
 1 file changed, 50 insertions(+), 38 deletions(-)

diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c
index b9739b9b9341..57c7b296d1c5 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_amd.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c
@@ -267,14 +267,60 @@ static void deferred_error_interrupt_enable(struct cpuinfo_x86 *c)
 	wrmsr(MSR_CU_DEF_ERR, low, high);
 }
 
+static int
+prepare_threshold_block(unsigned int bank, unsigned int block, u32 addr,
+			int offset, u32 misc_high)
+{
+	unsigned int cpu = smp_processor_id();
+	struct threshold_block b;
+	int new;
+
+	if (!block)
+		per_cpu(bank_map, cpu) |= (1 << bank);
+
+	memset(&b, 0, sizeof(b));
+	b.cpu			= cpu;
+	b.bank			= bank;
+	b.block			= block;
+	b.address		= addr;
+	b.interrupt_capable	= lvt_interrupt_supported(bank, misc_high);
+
+	if (!b.interrupt_capable)
+		goto done;
+
+	b.interrupt_enable = 1;
+
+	if (mce_flags.smca) {
+		u32 smca_low = 0, smca_high = 0;
+
+		/* 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;
+	} else {
+		new = (misc_high & MASK_LVTOFF_HI) >> 20;
+	}
+
+	offset = setup_APIC_mce_threshold(offset, new);
+
+	if ((offset == new) &&
+	    (mce_threshold_vector != amd_threshold_interrupt))
+		mce_threshold_vector = amd_threshold_interrupt;
+
+done:
+	mce_threshold_block_init(&b, offset);
+
+out:
+	return offset;
+}
+
 /* cpu init entry point, called from mce.c with preempt off */
 void mce_amd_feature_init(struct cpuinfo_x86 *c)
 {
-	struct threshold_block b;
-	unsigned int cpu = smp_processor_id();
 	u32 low = 0, high = 0, address = 0;
 	unsigned int bank, block;
-	int offset = -1, new;
+	int offset = -1;
 
 	for (bank = 0; bank < mca_cfg.banks; ++bank) {
 		for (block = 0; block < NR_BLOCKS; ++block) {
@@ -299,41 +345,7 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c)
 			     (high & MASK_LOCKED_HI))
 				continue;
 
-			if (!block)
-				per_cpu(bank_map, cpu) |= (1 << bank);
-
-			memset(&b, 0, sizeof(b));
-			b.cpu			= cpu;
-			b.bank			= bank;
-			b.block			= block;
-			b.address		= address;
-			b.interrupt_capable	= lvt_interrupt_supported(bank, high);
-
-			if (!b.interrupt_capable)
-				goto init;
-
-			b.interrupt_enable = 1;
-
-			if (mce_flags.smca) {
-				u32 smca_low = 0, smca_high = 0;
-
-				/* Gather LVT offset for thresholding */
-				if (rdmsr_safe(MSR_CU_DEF_ERR, &smca_low, &smca_high))
-					break;
-
-				new = (smca_low & SMCA_THR_LVT_OFF) >> 12;
-			} else {
-				new = (high & MASK_LVTOFF_HI) >> 20;
-			}
-
-			offset  = setup_APIC_mce_threshold(offset, new);
-
-			if ((offset == new) &&
-			    (mce_threshold_vector != amd_threshold_interrupt))
-				mce_threshold_vector = amd_threshold_interrupt;
-
-init:
-			mce_threshold_block_init(&b, offset);
+			offset = prepare_threshold_block(bank, block, address, offset, high);
 		}
 	}
 
-- 
2.3.5

-- 
Regards/Gruss,
    Boris.

ECO tip #101: Trim your mails when you reply.

[toc] | [prev] | [next] | [standalone]


#1310922 — Re: [PATCH V2 4/5] x86/mcheck/AMD: Fix LVT offset configuration for thresholding

FromBorislav Petkov <bp@alien8.de>
Date2016-01-16 11:50 +0100
SubjectRe: [PATCH V2 4/5] x86/mcheck/AMD: Fix LVT offset configuration for thresholding
Message-ID<qRwAF-3aT-17@gated-at.bofh.it>
In reply to#1310527
On Fri, Jan 15, 2016 at 05:50:35PM -0600, Aravind Gopalakrishnan wrote:
> For processor families with  SMCA feature, the LVT offset
> for threshold interrupts is configured only in MSR 0xC0000410
> and not in each per bank MISC register as was done in earlier
> families.
> 
> Fixing the code here to obtain the LVT offset from the correct
> MSR for those families which have SMCA feature enabled.
> 
> Signed-off-by: Aravind Gopalakrishnan <Aravind.Gopalakrishnan@amd.com>
> ---
>  arch/x86/kernel/cpu/mcheck/mce_amd.c | 34 +++++++++++++++++++++++++++++++++-
>  1 file changed, 33 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c
> index e650fdc..29a7688 100644
> --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c
> +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c
> @@ -49,6 +49,15 @@
>  #define DEF_LVT_OFF		0x2
>  #define DEF_INT_TYPE_APIC	0x2
>  
> +/*
> + * SMCA settings:
> + * The following defines provide masks or bit positions of
> + * MSRs that are applicable only to SMCA enabled processors
> + */
> +
> +/* Threshold LVT offset is at MSR0xC0000410[15:12] */
> +#define SMCA_THR_LVT_OFF	0xF000
> +
>  static const char * const th_names[] = {
>  	"load_store",
>  	"insn_fetch",
> @@ -143,6 +152,15 @@ static int lvt_off_valid(struct threshold_block *b, int apic, u32 lo, u32 hi)
>  	}
>  
>  	if (apic != msr) {
> +		/*
> +		 * For SMCA enabled processors, LVT offset is programmed at
> +		 * different MSR and BIOS provides the value.
> +		 * The original field where LVT offset was set is Reserved.
> +		 * So, return early here.
> +		 */
> +		if (mce_flags.smca)
> +			return 0;
> +
>  		pr_err(FW_BUG "cpu %d, invalid threshold interrupt offset %d "
>  		       "for bank %d, block %d (MSR%08X=0x%x%08x)\n",
>  		       b->cpu, apic, b->bank, b->block, b->address, hi, lo);
> @@ -301,7 +319,21 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c)
>  				goto init;
>  
>  			b.interrupt_enable = 1;
> -			new	= (high & MASK_LVTOFF_HI) >> 20;
> +
> +			if (mce_flags.smca) {
> +				u32 smca_low = 0, smca_high = 0;

Those variables don't need to be initialized to 0 since you're reading
into them right afterwards.

I fixed that up.



> +
> +				/* Gather LVT offset for thresholding */
> +				if (rdmsr_safe(MSR_CU_DEF_ERR,
> +					       &smca_low,
> +					       &smca_high))
> +					break;
> +

-- 
Regards/Gruss,
    Boris.

ECO tip #101: Trim your mails when you reply.

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web