| From e503f9e4b092e2349a9477a333543de8f3c7f5d9 Mon Sep 17 00:00:00 2001 |
| From: Youquan Song <youquan.song@intel.com> |
| Date: Fri, 22 Apr 2011 00:22:43 +0800 |
| Subject: x86, apic: Fix spurious error interrupts triggering on all non-boot APs |
| |
| From: Youquan Song <youquan.song@intel.com> |
| |
| commit e503f9e4b092e2349a9477a333543de8f3c7f5d9 upstream. |
| |
| This patch fixes a bug reported by a customer, who found |
| that many unreasonable error interrupts reported on all |
| non-boot CPUs (APs) during the system boot stage. |
| |
| According to Chapter 10 of Intel Software Developer Manual |
| Volume 3A, Local APIC may signal an illegal vector error when |
| an LVT entry is set as an illegal vector value (0~15) under |
| FIXED delivery mode (bits 8-11 is 0), regardless of whether |
| the mask bit is set or an interrupt actually happen. These |
| errors are seen as error interrupts. |
| |
| The initial value of thermal LVT entries on all APs always reads |
| 0x10000 because APs are woken up by BSP issuing INIT-SIPI-SIPI |
| sequence to them and LVT registers are reset to 0s except for |
| the mask bits which are set to 1s when APs receive INIT IPI. |
| |
| When the BIOS takes over the thermal throttling interrupt, |
| the LVT thermal deliver mode should be SMI and it is required |
| from the kernel to keep AP's LVT thermal monitoring register |
| programmed as such as well. |
| |
| This issue happens when BIOS does not take over thermal throttling |
| interrupt, AP's LVT thermal monitor register will be restored to |
| 0x10000 which means vector 0 and fixed deliver mode, so all APs will |
| signal illegal vector error interrupts. |
| |
| This patch check if interrupt delivery mode is not fixed mode before |
| restoring AP's LVT thermal monitor register. |
| |
| Signed-off-by: Youquan Song <youquan.song@intel.com> |
| Acked-by: Suresh Siddha <suresh.b.siddha@intel.com> |
| Acked-by: Yong Wang <yong.y.wang@intel.com> |
| Cc: hpa@linux.intel.com |
| Cc: joe@perches.com |
| Cc: jbaron@redhat.com |
| Cc: trenn@suse.de |
| Cc: kent.liu@intel.com |
| Cc: chaohong.guo@intel.com |
| Link: http://lkml.kernel.org/r/1303402963-17738-1-git-send-email-youquan.song@intel.com |
| Signed-off-by: Ingo Molnar <mingo@elte.hu> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| arch/x86/include/asm/apicdef.h | 1 + |
| arch/x86/kernel/cpu/mcheck/therm_throt.c | 12 +++++++----- |
| 2 files changed, 8 insertions(+), 5 deletions(-) |
| |
| --- a/arch/x86/include/asm/apicdef.h |
| +++ b/arch/x86/include/asm/apicdef.h |
| @@ -78,6 +78,7 @@ |
| #define APIC_DEST_LOGICAL 0x00800 |
| #define APIC_DEST_PHYSICAL 0x00000 |
| #define APIC_DM_FIXED 0x00000 |
| +#define APIC_DM_FIXED_MASK 0x00700 |
| #define APIC_DM_LOWEST 0x00100 |
| #define APIC_DM_SMI 0x00200 |
| #define APIC_DM_REMRD 0x00300 |
| --- a/arch/x86/kernel/cpu/mcheck/therm_throt.c |
| +++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c |
| @@ -293,18 +293,20 @@ void intel_init_thermal(struct cpuinfo_x |
| */ |
| rdmsr(MSR_IA32_MISC_ENABLE, l, h); |
| |
| + h = lvtthmr_init; |
| /* |
| * The initial value of thermal LVT entries on all APs always reads |
| * 0x10000 because APs are woken up by BSP issuing INIT-SIPI-SIPI |
| * sequence to them and LVT registers are reset to 0s except for |
| * the mask bits which are set to 1s when APs receive INIT IPI. |
| - * Always restore the value that BIOS has programmed on AP based on |
| - * BSP's info we saved since BIOS is always setting the same value |
| - * for all threads/cores |
| + * If BIOS takes over the thermal interrupt and sets its interrupt |
| + * delivery mode to SMI (not fixed), it restores the value that the |
| + * BIOS has programmed on AP based on BSP's info we saved since BIOS |
| + * is always setting the same value for all threads/cores. |
| */ |
| - apic_write(APIC_LVTTHMR, lvtthmr_init); |
| + if ((h & APIC_DM_FIXED_MASK) != APIC_DM_FIXED) |
| + apic_write(APIC_LVTTHMR, lvtthmr_init); |
| |
| - h = lvtthmr_init; |
| |
| if ((l & MSR_IA32_MISC_ENABLE_TM1) && (h & APIC_DM_SMI)) { |
| printk(KERN_DEBUG |