diff options
-rw-r--r-- | arch/x86_64/kernel/mce_amd.c | 40 |
1 files changed, 25 insertions, 15 deletions
diff --git a/arch/x86_64/kernel/mce_amd.c b/arch/x86_64/kernel/mce_amd.c index 93c707257637..cd8dbe57b33a 100644 --- a/arch/x86_64/kernel/mce_amd.c +++ b/arch/x86_64/kernel/mce_amd.c | |||
@@ -37,6 +37,8 @@ | |||
37 | #define THRESHOLD_MAX 0xFFF | 37 | #define THRESHOLD_MAX 0xFFF |
38 | #define INT_TYPE_APIC 0x00020000 | 38 | #define INT_TYPE_APIC 0x00020000 |
39 | #define MASK_VALID_HI 0x80000000 | 39 | #define MASK_VALID_HI 0x80000000 |
40 | #define MASK_CNTP_HI 0x40000000 | ||
41 | #define MASK_LOCKED_HI 0x20000000 | ||
40 | #define MASK_LVTOFF_HI 0x00F00000 | 42 | #define MASK_LVTOFF_HI 0x00F00000 |
41 | #define MASK_COUNT_EN_HI 0x00080000 | 43 | #define MASK_COUNT_EN_HI 0x00080000 |
42 | #define MASK_INT_TYPE_HI 0x00060000 | 44 | #define MASK_INT_TYPE_HI 0x00060000 |
@@ -122,14 +124,17 @@ void __cpuinit mce_amd_feature_init(struct cpuinfo_x86 *c) | |||
122 | for (block = 0; block < NR_BLOCKS; ++block) { | 124 | for (block = 0; block < NR_BLOCKS; ++block) { |
123 | if (block == 0) | 125 | if (block == 0) |
124 | address = MSR_IA32_MC0_MISC + bank * 4; | 126 | address = MSR_IA32_MC0_MISC + bank * 4; |
125 | else if (block == 1) | 127 | else if (block == 1) { |
126 | address = MCG_XBLK_ADDR | 128 | address = (low & MASK_BLKPTR_LO) >> 21; |
127 | + ((low & MASK_BLKPTR_LO) >> 21); | 129 | if (!address) |
130 | break; | ||
131 | address += MCG_XBLK_ADDR; | ||
132 | } | ||
128 | else | 133 | else |
129 | ++address; | 134 | ++address; |
130 | 135 | ||
131 | if (rdmsr_safe(address, &low, &high)) | 136 | if (rdmsr_safe(address, &low, &high)) |
132 | continue; | 137 | break; |
133 | 138 | ||
134 | if (!(high & MASK_VALID_HI)) { | 139 | if (!(high & MASK_VALID_HI)) { |
135 | if (block) | 140 | if (block) |
@@ -138,8 +143,8 @@ void __cpuinit mce_amd_feature_init(struct cpuinfo_x86 *c) | |||
138 | break; | 143 | break; |
139 | } | 144 | } |
140 | 145 | ||
141 | if (!(high & MASK_VALID_HI >> 1) || | 146 | if (!(high & MASK_CNTP_HI) || |
142 | (high & MASK_VALID_HI >> 2)) | 147 | (high & MASK_LOCKED_HI)) |
143 | continue; | 148 | continue; |
144 | 149 | ||
145 | if (!block) | 150 | if (!block) |
@@ -187,17 +192,22 @@ asmlinkage void mce_threshold_interrupt(void) | |||
187 | 192 | ||
188 | /* assume first bank caused it */ | 193 | /* assume first bank caused it */ |
189 | for (bank = 0; bank < NR_BANKS; ++bank) { | 194 | for (bank = 0; bank < NR_BANKS; ++bank) { |
195 | if (!(per_cpu(bank_map, m.cpu) & (1 << bank))) | ||
196 | continue; | ||
190 | for (block = 0; block < NR_BLOCKS; ++block) { | 197 | for (block = 0; block < NR_BLOCKS; ++block) { |
191 | if (block == 0) | 198 | if (block == 0) |
192 | address = MSR_IA32_MC0_MISC + bank * 4; | 199 | address = MSR_IA32_MC0_MISC + bank * 4; |
193 | else if (block == 1) | 200 | else if (block == 1) { |
194 | address = MCG_XBLK_ADDR | 201 | address = (low & MASK_BLKPTR_LO) >> 21; |
195 | + ((low & MASK_BLKPTR_LO) >> 21); | 202 | if (!address) |
203 | break; | ||
204 | address += MCG_XBLK_ADDR; | ||
205 | } | ||
196 | else | 206 | else |
197 | ++address; | 207 | ++address; |
198 | 208 | ||
199 | if (rdmsr_safe(address, &low, &high)) | 209 | if (rdmsr_safe(address, &low, &high)) |
200 | continue; | 210 | break; |
201 | 211 | ||
202 | if (!(high & MASK_VALID_HI)) { | 212 | if (!(high & MASK_VALID_HI)) { |
203 | if (block) | 213 | if (block) |
@@ -206,8 +216,8 @@ asmlinkage void mce_threshold_interrupt(void) | |||
206 | break; | 216 | break; |
207 | } | 217 | } |
208 | 218 | ||
209 | if (!(high & MASK_VALID_HI >> 1) || | 219 | if (!(high & MASK_CNTP_HI) || |
210 | (high & MASK_VALID_HI >> 2)) | 220 | (high & MASK_LOCKED_HI)) |
211 | continue; | 221 | continue; |
212 | 222 | ||
213 | if (high & MASK_OVERFLOW_HI) { | 223 | if (high & MASK_OVERFLOW_HI) { |
@@ -385,7 +395,7 @@ static __cpuinit int allocate_threshold_blocks(unsigned int cpu, | |||
385 | return 0; | 395 | return 0; |
386 | 396 | ||
387 | if (rdmsr_safe(address, &low, &high)) | 397 | if (rdmsr_safe(address, &low, &high)) |
388 | goto recurse; | 398 | return 0; |
389 | 399 | ||
390 | if (!(high & MASK_VALID_HI)) { | 400 | if (!(high & MASK_VALID_HI)) { |
391 | if (block) | 401 | if (block) |
@@ -394,8 +404,8 @@ static __cpuinit int allocate_threshold_blocks(unsigned int cpu, | |||
394 | return 0; | 404 | return 0; |
395 | } | 405 | } |
396 | 406 | ||
397 | if (!(high & MASK_VALID_HI >> 1) || | 407 | if (!(high & MASK_CNTP_HI) || |
398 | (high & MASK_VALID_HI >> 2)) | 408 | (high & MASK_LOCKED_HI)) |
399 | goto recurse; | 409 | goto recurse; |
400 | 410 | ||
401 | b = kzalloc(sizeof(struct threshold_block), GFP_KERNEL); | 411 | b = kzalloc(sizeof(struct threshold_block), GFP_KERNEL); |