aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRobert Richter <robert.richter@amd.com>2010-10-25 10:03:37 -0400
committerIngo Molnar <mingo@elte.hu>2010-10-25 12:59:43 -0400
commitbbaff08dca3c34d0fb6b4c4051354184e33e3df8 (patch)
tree3b08ed3ec89d079b634664bf131a0fbaa7868bca /arch
parent7203a0494084541575bac6dfc4e153f9e28869b8 (diff)
mce, amd: Add helper functions to setup APIC
This patch reworks and cleans up mce_amd_feature_init() by introducing helper functions to setup and check the LVT offset. It also fixes line endings in pr_err() calls. Signed-off-by: Robert Richter <robert.richter@amd.com> Acked-by: Borislav Petkov <borislav.petkov@amd.com> LKML-Reference: <1288015419-29543-4-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_amd.c67
1 files changed, 38 insertions, 29 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c
index eb771b9fc0cb..e316684f9ed7 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_amd.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c
@@ -31,8 +31,6 @@
31#include <asm/mce.h> 31#include <asm/mce.h>
32#include <asm/msr.h> 32#include <asm/msr.h>
33 33
34#define PFX "mce_threshold: "
35#define VERSION "version 1.1.1"
36#define NR_BANKS 6 34#define NR_BANKS 6
37#define NR_BLOCKS 9 35#define NR_BLOCKS 9
38#define THRESHOLD_MAX 0xFFF 36#define THRESHOLD_MAX 0xFFF
@@ -88,6 +86,27 @@ struct thresh_restart {
88 u16 old_limit; 86 u16 old_limit;
89}; 87};
90 88
89static int lvt_off_valid(struct threshold_block *b, int apic, u32 lo, u32 hi)
90{
91 int msr = (hi & MASK_LVTOFF_HI) >> 20;
92
93 if (apic < 0) {
94 pr_err(FW_BUG "cpu %d, failed to setup threshold interrupt "
95 "for bank %d, block %d (MSR%08X=0x%x%08x)\n", b->cpu,
96 b->bank, b->block, b->address, hi, lo);
97 return 0;
98 }
99
100 if (apic != msr) {
101 pr_err(FW_BUG "cpu %d, invalid threshold interrupt offset %d "
102 "for bank %d, block %d (MSR%08X=0x%x%08x)\n",
103 b->cpu, apic, b->bank, b->block, b->address, hi, lo);
104 return 0;
105 }
106
107 return 1;
108};
109
91/* must be called with correct cpu affinity */ 110/* must be called with correct cpu affinity */
92/* Called via smp_call_function_single() */ 111/* Called via smp_call_function_single() */
93static void threshold_restart_bank(void *_tr) 112static void threshold_restart_bank(void *_tr)
@@ -113,9 +132,11 @@ static void threshold_restart_bank(void *_tr)
113 } 132 }
114 133
115 if (tr->set_lvt_off) { 134 if (tr->set_lvt_off) {
116 /* set new lvt offset */ 135 if (lvt_off_valid(tr->b, tr->lvt_off, lo, hi)) {
117 hi &= ~MASK_LVTOFF_HI; 136 /* set new lvt offset */
118 hi |= tr->lvt_off << 20; 137 hi &= ~MASK_LVTOFF_HI;
138 hi |= tr->lvt_off << 20;
139 }
119 } 140 }
120 141
121 tr->b->interrupt_enable ? 142 tr->b->interrupt_enable ?
@@ -138,6 +159,15 @@ static void mce_threshold_block_init(struct threshold_block *b, int offset)
138 threshold_restart_bank(&tr); 159 threshold_restart_bank(&tr);
139}; 160};
140 161
162static int setup_APIC_mce(int reserved, int new)
163{
164 if (reserved < 0 && !setup_APIC_eilvt(new, THRESHOLD_APIC_VECTOR,
165 APIC_EILVT_MSG_FIX, 0))
166 return new;
167
168 return reserved;
169}
170
141/* cpu init entry point, called from mce.c with preempt off */ 171/* cpu init entry point, called from mce.c with preempt off */
142void mce_amd_feature_init(struct cpuinfo_x86 *c) 172void mce_amd_feature_init(struct cpuinfo_x86 *c)
143{ 173{
@@ -145,8 +175,7 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c)
145 unsigned int cpu = smp_processor_id(); 175 unsigned int cpu = smp_processor_id();
146 u32 low = 0, high = 0, address = 0; 176 u32 low = 0, high = 0, address = 0;
147 unsigned int bank, block; 177 unsigned int bank, block;
148 int lvt_off = -1; 178 int offset = -1;
149 u8 offset;
150 179
151 for (bank = 0; bank < NR_BANKS; ++bank) { 180 for (bank = 0; bank < NR_BANKS; ++bank) {
152 for (block = 0; block < NR_BLOCKS; ++block) { 181 for (block = 0; block < NR_BLOCKS; ++block) {
@@ -177,28 +206,8 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c)
177 if (shared_bank[bank] && c->cpu_core_id) 206 if (shared_bank[bank] && c->cpu_core_id)
178 break; 207 break;
179#endif 208#endif
180 offset = (high & MASK_LVTOFF_HI) >> 20; 209 offset = setup_APIC_mce(offset,
181 if (lvt_off < 0) { 210 (high & MASK_LVTOFF_HI) >> 20);
182 if (setup_APIC_eilvt(offset,
183 THRESHOLD_APIC_VECTOR,
184 APIC_EILVT_MSG_FIX, 0)) {
185 pr_err(FW_BUG "cpu %d, failed to "
186 "setup threshold interrupt "
187 "for bank %d, block %d "
188 "(MSR%08X=0x%x%08x)",
189 smp_processor_id(), bank, block,
190 address, high, low);
191 continue;
192 }
193 lvt_off = offset;
194 } else if (lvt_off != offset) {
195 pr_err(FW_BUG "cpu %d, invalid threshold "
196 "interrupt offset %d for bank %d,"
197 "block %d (MSR%08X=0x%x%08x)",
198 smp_processor_id(), lvt_off, bank,
199 block, address, high, low);
200 continue;
201 }
202 211
203 memset(&b, 0, sizeof(b)); 212 memset(&b, 0, sizeof(b));
204 b.cpu = cpu; 213 b.cpu = cpu;