x86/apic: Fix the saving and restoring of lapic vectors during suspend/resume
authorJuergen Gross <jgross@suse.com>
Mon, 23 Nov 2015 10:59:24 +0000 (11:59 +0100)
committerIngo Molnar <mingo@kernel.org>
Tue, 24 Nov 2015 08:18:33 +0000 (09:18 +0100)
Saving and restoring lapic vectors in lapic_suspend() and
lapic_resume() is not consistent: the thmr vector saving is
guarded by a different config option than the restore part. The
cmci vector isn't handled at all.

Those inconsistencies are not very critical, as the missing cmci
vector will be set via mce resume handling, the wrong config
option used for restoring the thmr vector can't be configured
differently than the one which should be used.

Nevertheless correct the thmr vector restore and add cmci vector
handling.

Signed-off-by: Juergen Gross <jgross@suse.com>
Acked-by: Borislav Petkov <bp@suse.de>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1448276364-31334-1-git-send-email-jgross@suse.com
[ Minor code edits. ]
Signed-off-by: Ingo Molnar <mingo@kernel.org>
arch/x86/kernel/apic/apic.c

index 2f69e3b..8d7df74 100644 (file)
@@ -2270,6 +2270,7 @@ static struct {
        unsigned int apic_tmict;
        unsigned int apic_tdcr;
        unsigned int apic_thmr;
        unsigned int apic_tmict;
        unsigned int apic_tdcr;
        unsigned int apic_thmr;
+       unsigned int apic_cmci;
 } apic_pm_state;
 
 static int lapic_suspend(void)
 } apic_pm_state;
 
 static int lapic_suspend(void)
@@ -2299,6 +2300,10 @@ static int lapic_suspend(void)
        if (maxlvt >= 5)
                apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR);
 #endif
        if (maxlvt >= 5)
                apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR);
 #endif
+#ifdef CONFIG_X86_MCE_INTEL
+       if (maxlvt >= 6)
+               apic_pm_state.apic_cmci = apic_read(APIC_LVTCMCI);
+#endif
 
        local_irq_save(flags);
        disable_local_APIC();
 
        local_irq_save(flags);
        disable_local_APIC();
@@ -2355,9 +2360,13 @@ static void lapic_resume(void)
        apic_write(APIC_SPIV, apic_pm_state.apic_spiv);
        apic_write(APIC_LVT0, apic_pm_state.apic_lvt0);
        apic_write(APIC_LVT1, apic_pm_state.apic_lvt1);
        apic_write(APIC_SPIV, apic_pm_state.apic_spiv);
        apic_write(APIC_LVT0, apic_pm_state.apic_lvt0);
        apic_write(APIC_LVT1, apic_pm_state.apic_lvt1);
-#if defined(CONFIG_X86_MCE_INTEL)
+#ifdef CONFIG_X86_THERMAL_VECTOR
        if (maxlvt >= 5)
                apic_write(APIC_LVTTHMR, apic_pm_state.apic_thmr);
        if (maxlvt >= 5)
                apic_write(APIC_LVTTHMR, apic_pm_state.apic_thmr);
+#endif
+#ifdef CONFIG_X86_MCE_INTEL
+       if (maxlvt >= 6)
+               apic_write(APIC_LVTCMCI, apic_pm_state.apic_cmci);
 #endif
        if (maxlvt >= 4)
                apic_write(APIC_LVTPC, apic_pm_state.apic_lvtpc);
 #endif
        if (maxlvt >= 4)
                apic_write(APIC_LVTPC, apic_pm_state.apic_lvtpc);