]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
x86/irq: Add x86_non_ir_cpumask
authorDavid Woodhouse <dwmw@amazon.co.uk>
Fri, 2 Oct 2020 15:12:30 +0000 (16:12 +0100)
committerDavid Woodhouse <dwmw@amazon.co.uk>
Wed, 7 Oct 2020 10:28:36 +0000 (11:28 +0100)
This is the mask of CPUs which have ever been online and to which IRQs
can be delivered without interrupt remapping.

Offline CPUs listed in (e.g.) the MADT are not included, because there
may be more than NR_CPUS of those, and populating the cpuid_to_apicid[]
array with the first NR_CPUS might mean that it doesn't have space for
the ones which are *actually* brought online later.

Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
arch/x86/include/asm/mpspec.h
arch/x86/kernel/apic/apic.c

index 25ee8ca0a1f28391341e7efde5d4cce13537650e..b2090be5b4443219c039bf6650654079caebe124 100644 (file)
@@ -141,5 +141,6 @@ static inline void physid_set_mask_of_physid(int physid, physid_mask_t *map)
 #define PHYSID_MASK_NONE       { {[0 ... PHYSID_ARRAY_SIZE-1] = 0UL} }
 
 extern physid_mask_t phys_cpu_present_map;
+extern cpumask_t x86_non_ir_cpumask;
 
 #endif /* _ASM_X86_MPSPEC_H */
index ba24a343c1f246e0d10fa133046372b3980225fe..db410cb009358146f31b5ba0bbb4e50fdb9e3487 100644 (file)
@@ -103,6 +103,14 @@ EXPORT_EARLY_PER_CPU_SYMBOL(x86_cpu_to_apicid);
 EXPORT_EARLY_PER_CPU_SYMBOL(x86_bios_cpu_apicid);
 EXPORT_EARLY_PER_CPU_SYMBOL(x86_cpu_to_acpiid);
 
+/*
+ * Mask of CPUs which can be targeted by non-remapped interrupts.
+ * By default, all CPUs can be reached. Only x2apic makes it
+ * possible for that to be untrue, and the x2apic initialisation
+ * code path will clear this and populate it accordingly.
+ */
+cpumask_t x86_non_ir_cpumask = { CPU_BITS_ALL };
+
 #ifdef CONFIG_X86_32
 
 /*
@@ -1838,6 +1846,7 @@ static __init void x2apic_enable(void)
 static __init void try_to_enable_x2apic(int remap_mode)
 {
        u32 apic_limit = 255;
+       int i;
 
        if (x2apic_state == X2APIC_DISABLED)
                return;
@@ -1872,6 +1881,13 @@ static __init void try_to_enable_x2apic(int remap_mode)
                x2apic_phys = 1;
        }
 
+       /* Build the affinity mask for interrupts that can't be remapped. */
+       cpumask_clear(&x86_non_ir_cpumask);
+       for (i = num_possible_cpus() - 1; i >= 0; i--) {
+               if (cpu_physical_id(i) <= apic_limit)
+                       cpumask_set_cpu(i, &x86_non_ir_cpumask);
+       }
+
        x2apic_enable();
 }
 
@@ -2485,6 +2501,9 @@ int generic_processor_info(int apicid, int version)
        set_cpu_present(cpu, true);
        num_processors++;
 
+       if (apicid < (msi_ext_dest_id ? 32768 : 256))
+               cpumask_set_cpu(cpu, &x86_non_ir_cpumask);
+
        return cpu;
 }