| From 70d914f274c9684b8a26cd0bdfcceac72f9b0ed3 Mon Sep 17 00:00:00 2001 |
| From: Jan Beulich <jbeulich@suse.com> |
| Date: Tue, 29 Oct 2019 10:34:19 +0100 |
| Subject: [PATCH] x86/apic/32: Avoid bogus LDR warnings |
| |
| commit fe6f85ca121e9c74e7490fe66b0c5aae38e332c3 upstream. |
| |
| The removal of the LDR initialization in the bigsmp_32 APIC code unearthed |
| a problem in setup_local_APIC(). |
| |
| The code checks unconditionally for a mismatch of the logical APIC id by |
| comparing the early APIC id which was initialized in get_smp_config() with |
| the actual LDR value in the APIC. |
| |
| Due to the removal of the bogus LDR initialization the check now can |
| trigger on bigsmp_32 APIC systems emitting a warning for every booting |
| CPU. This is of course a false positive because the APIC is not using |
| logical destination mode. |
| |
| Restrict the check and the possibly resulting fixup to systems which are |
| actually using the APIC in logical destination mode. |
| |
| [ tglx: Massaged changelog and added Cc stable ] |
| |
| Fixes: bae3a8d3308 ("x86/apic: Do not initialize LDR and DFR for bigsmp") |
| Signed-off-by: Jan Beulich <jbeulich@suse.com> |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| Cc: stable@vger.kernel.org |
| Link: https://lkml.kernel.org/r/666d8f91-b5a8-1afd-7add-821e72a35f03@suse.com |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c |
| index a18d6dd934e5..142e7cfa8a3c 100644 |
| --- a/arch/x86/kernel/apic/apic.c |
| +++ b/arch/x86/kernel/apic/apic.c |
| @@ -1540,9 +1540,6 @@ static void setup_local_APIC(void) |
| { |
| int cpu = smp_processor_id(); |
| unsigned int value; |
| -#ifdef CONFIG_X86_32 |
| - int logical_apicid, ldr_apicid; |
| -#endif |
| |
| |
| if (disable_apic) { |
| @@ -1583,16 +1580,21 @@ static void setup_local_APIC(void) |
| apic->init_apic_ldr(); |
| |
| #ifdef CONFIG_X86_32 |
| - /* |
| - * APIC LDR is initialized. If logical_apicid mapping was |
| - * initialized during get_smp_config(), make sure it matches the |
| - * actual value. |
| - */ |
| - logical_apicid = early_per_cpu(x86_cpu_to_logical_apicid, cpu); |
| - ldr_apicid = GET_APIC_LOGICAL_ID(apic_read(APIC_LDR)); |
| - WARN_ON(logical_apicid != BAD_APICID && logical_apicid != ldr_apicid); |
| - /* always use the value from LDR */ |
| - early_per_cpu(x86_cpu_to_logical_apicid, cpu) = ldr_apicid; |
| + if (apic->dest_logical) { |
| + int logical_apicid, ldr_apicid; |
| + |
| + /* |
| + * APIC LDR is initialized. If logical_apicid mapping was |
| + * initialized during get_smp_config(), make sure it matches |
| + * the actual value. |
| + */ |
| + logical_apicid = early_per_cpu(x86_cpu_to_logical_apicid, cpu); |
| + ldr_apicid = GET_APIC_LOGICAL_ID(apic_read(APIC_LDR)); |
| + if (logical_apicid != BAD_APICID) |
| + WARN_ON(logical_apicid != ldr_apicid); |
| + /* Always use the value from LDR. */ |
| + early_per_cpu(x86_cpu_to_logical_apicid, cpu) = ldr_apicid; |
| + } |
| #endif |
| |
| /* |
| -- |
| 2.7.4 |
| |