summaryrefslogtreecommitdiff
path: root/arch/x86/kernel/cpu/mcheck/mce_amd.c
diff options
context:
space:
mode:
authorChen Yucong <slaoub@gmail.com>2014-11-01 11:23:32 +0100
committerBorislav Petkov <bp@suse.de>2014-11-01 11:28:23 +0100
commit8dcf32ea220d87ca517e164de85d336480c9d172 (patch)
tree4d74594c26f1a6145197ca196142f563a735a0b7 /arch/x86/kernel/cpu/mcheck/mce_amd.c
parenta3a529d104ec5149fb9a667dce988635941be1ed (diff)
x86, MCE, AMD: Assign interrupt handler only when bank supports it
There are some AMD CPU models which have thresholding banks but which cannot generate a thresholding interrupt. This is denoted by the bit MCi_MISC[IntP]. Make sure to check that bit before assigning the thresholding interrupt handler. Signed-off-by: Chen Yucong <slaoub@gmail.com> [ Boris: save an indentation level and rewrite commit message. ] Link: http://lkml.kernel.org/r/1412662128.28440.18.camel@debian Signed-off-by: Borislav Petkov <bp@suse.de>
Diffstat (limited to 'arch/x86/kernel/cpu/mcheck/mce_amd.c')
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_amd.c17
1 files changed, 10 insertions, 7 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c
index 6606523ff1c1..f1c3769bbd64 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_amd.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c
@@ -212,7 +212,7 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c)
unsigned int cpu = smp_processor_id();
u32 low = 0, high = 0, address = 0;
unsigned int bank, block;
- int offset = -1;
+ int offset = -1, new;
for (bank = 0; bank < mca_cfg.banks; ++bank) {
for (block = 0; block < NR_BLOCKS; ++block) {
@@ -247,15 +247,18 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c)
b.address = address;
b.interrupt_capable = lvt_interrupt_supported(bank, high);
- if (b.interrupt_capable) {
- int new = (high & MASK_LVTOFF_HI) >> 20;
- offset = setup_APIC_mce(offset, new);
- }
+ if (!b.interrupt_capable)
+ goto init;
- mce_threshold_block_init(&b, offset);
+ new = (high & MASK_LVTOFF_HI) >> 20;
+ offset = setup_APIC_mce(offset, new);
- if (mce_threshold_vector != amd_threshold_interrupt)
+ if ((offset == new) &&
+ (mce_threshold_vector != amd_threshold_interrupt))
mce_threshold_vector = amd_threshold_interrupt;
+
+init:
+ mce_threshold_block_init(&b, offset);
}
}
}