diff options
author | Chen Yucong <slaoub@gmail.com> | 2014-11-01 11:23:32 +0100 |
---|---|---|
committer | Borislav Petkov <bp@suse.de> | 2014-11-01 11:28:23 +0100 |
commit | 8dcf32ea220d87ca517e164de85d336480c9d172 (patch) | |
tree | 4d74594c26f1a6145197ca196142f563a735a0b7 | |
parent | a3a529d104ec5149fb9a667dce988635941be1ed (diff) | |
download | op-kernel-dev-8dcf32ea220d87ca517e164de85d336480c9d172.zip op-kernel-dev-8dcf32ea220d87ca517e164de85d336480c9d172.tar.gz |
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>
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce_amd.c | 17 |
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 6606523..f1c3769 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); } } } |