]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
x86/apic/32: Sanitize logical APIC ID handling
authorThomas Gleixner <tglx@linutronix.de>
Tue, 8 Aug 2023 22:03:53 +0000 (15:03 -0700)
committerDave Hansen <dave.hansen@linux.intel.com>
Wed, 9 Aug 2023 18:58:23 +0000 (11:58 -0700)
apic::x86_32_early_logical_apicid() is yet another historical joke.

It is used to preset the x86_cpu_to_logical_apicid per CPU variable during
APIC enumeration with:

  - 1 shifted left by the CPU number
  - the physical APIC ID in case of bigsmp

The latter is hillarious because bigsmp uses physical destination mode
which never can use the logical APIC ID.

It gets even worse. As bigsmp can be enforced late in the boot process the
probe function overwrites the per CPU variable which is never used for this
APIC type once again.

Remove that gunk and store 1 << cpunr unconditionally if and only if the
CPU number is less than 8, because the default logical destination mode
only allows up to 8 CPUs.

This is just an intermediate step before removing the per CPU insanity
completely. Stay tuned.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Tested-by: Michael Kelley <mikelley@microsoft.com>
Tested-by: Sohil Mehta <sohil.mehta@intel.com>
Tested-by: Juergen Gross <jgross@suse.com> # Xen PV (dom0 and unpriv. guest)
arch/x86/include/asm/apic.h
arch/x86/kernel/apic/apic.c
arch/x86/kernel/apic/apic_noop.c
arch/x86/kernel/apic/bigsmp_32.c
arch/x86/kernel/apic/probe_32.c

index 098d193f93fb9500f7992dc358ad2149c004f7b5..daef6812141f0de15ededcd6d197d9575eb687e5 100644 (file)
@@ -315,19 +315,6 @@ struct apic {
        /* wakeup secondary CPU using 64-bit wakeup point */
        int     (*wakeup_secondary_cpu_64)(int apicid, unsigned long start_eip);
 
-#ifdef CONFIG_X86_32
-       /*
-        * Called very early during boot from get_smp_config().  It should
-        * return the logical apicid.  x86_[bios]_cpu_to_apicid is
-        * initialized before this function is called.
-        *
-        * If logical apicid can't be determined that early, the function
-        * may return BAD_APICID.  Logical apicid will be configured after
-        * init_apic_ldr() while bringing up CPUs.  Note that NUMA affinity
-        * won't be applied properly during early boot in this case.
-        */
-       int (*x86_32_early_logical_apicid)(int cpu);
-#endif
        char    *name;
 };
 
index 6eee777ca73cb628227fba1309f8a8ecf84b629b..89f2a7e5a9f57412ab6d9ac72178ce681fb531e7 100644 (file)
@@ -2435,8 +2435,8 @@ static void cpu_update_apic(int cpu, int apicid)
        early_per_cpu(x86_cpu_to_apicid, cpu) = apicid;
 #endif
 #ifdef CONFIG_X86_32
-       early_per_cpu(x86_cpu_to_logical_apicid, cpu) =
-               apic->x86_32_early_logical_apicid(cpu);
+       if (cpu < 8)
+               early_per_cpu(x86_cpu_to_logical_apicid, cpu) = 1U << cpu;
 #endif
        set_cpu_possible(cpu, true);
        physid_set(apicid, phys_cpu_present_map);
index c0c3b6bf79b5d74cefa79e6d230e446295537a52..ccd74e8016fc7383ea0665542d3308bec8752289 100644 (file)
@@ -80,13 +80,6 @@ static void noop_apic_write(u32 reg, u32 val)
        WARN_ON_ONCE(boot_cpu_has(X86_FEATURE_APIC) && !apic_is_disabled);
 }
 
-#ifdef CONFIG_X86_32
-static int noop_x86_32_early_logical_apicid(int cpu)
-{
-       return BAD_APICID;
-}
-#endif
-
 struct apic apic_noop __ro_after_init = {
        .name                           = "noop",
        .probe                          = noop_probe,
@@ -130,8 +123,4 @@ struct apic apic_noop __ro_after_init = {
        .icr_write                      = noop_apic_icr_write,
        .wait_icr_idle                  = noop_apic_wait_icr_idle,
        .safe_wait_icr_idle             = noop_safe_apic_wait_icr_idle,
-
-#ifdef CONFIG_X86_32
-       .x86_32_early_logical_apicid    = noop_x86_32_early_logical_apicid,
-#endif
 };
index 6f4bd71e97ec4dcd06e55133f542c5a2b30b70d4..b649048c2019894c79a8bbe1ff2080de06de9359 100644 (file)
@@ -28,12 +28,6 @@ static bool bigsmp_check_apicid_used(physid_mask_t *map, int apicid)
        return false;
 }
 
-static int bigsmp_early_logical_apicid(int cpu)
-{
-       /* on bigsmp, logical apicid is the same as physical */
-       return early_per_cpu(x86_cpu_to_apicid, cpu);
-}
-
 /*
  * bigsmp enables physical destination mode
  * and doesn't use LDR and DFR
@@ -154,27 +148,15 @@ static struct apic apic_bigsmp __ro_after_init = {
        .icr_write                      = native_apic_icr_write,
        .wait_icr_idle                  = native_apic_wait_icr_idle,
        .safe_wait_icr_idle             = native_safe_apic_wait_icr_idle,
-
-       .x86_32_early_logical_apicid    = bigsmp_early_logical_apicid,
 };
 
 void __init generic_bigsmp_probe(void)
 {
-       unsigned int cpu;
-
        if (!probe_bigsmp())
                return;
 
        apic = &apic_bigsmp;
 
-       for_each_possible_cpu(cpu) {
-               if (early_per_cpu(x86_cpu_to_logical_apicid,
-                                 cpu) == BAD_APICID)
-                       continue;
-               early_per_cpu(x86_cpu_to_logical_apicid, cpu) =
-                       bigsmp_early_logical_apicid(cpu);
-       }
-
        pr_info("Overriding APIC driver with %s\n", apic_bigsmp.name);
 }
 
index baa8b141eba143dceb1cb7140f61f22b64553e57..3ee0211b0c291bf913cc6bc139cb9ad084b89d86 100644 (file)
 
 #include "local.h"
 
-static int default_x86_32_early_logical_apicid(int cpu)
-{
-       return 1 << cpu;
-}
-
 static void setup_apic_flat_routing(void)
 {
 #ifdef CONFIG_X86_IO_APIC
@@ -101,8 +96,6 @@ static struct apic apic_default __ro_after_init = {
        .icr_write                      = native_apic_icr_write,
        .wait_icr_idle                  = native_apic_wait_icr_idle,
        .safe_wait_icr_idle             = native_safe_apic_wait_icr_idle,
-
-       .x86_32_early_logical_apicid    = default_x86_32_early_logical_apicid,
 };
 
 apic_driver(apic_default);