• Linus Torvalds's avatar
    Merge tag 'x86-apic-2023-04-24' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip · de10553f
    Linus Torvalds authored
    Pull x86 APIC updates from Thomas Gleixner:
    
     - Fix the incorrect handling of atomic offset updates in
       reserve_eilvt_offset()
    
       The check for the return value of atomic_cmpxchg() is not compared
       against the old value, it is compared against the new value, which
       makes it two round on success.
    
       Convert it to atomic_try_cmpxchg() which does the right thing.
    
     - Handle IO/APIC less systems correctly
    
       When IO/APIC is not advertised by ACPI then the computation of the
       lower bound for dynamically allocated interrupts like MSI goes wrong.
    
       This lower bound is used to exclude the IO/APIC legacy GSI space as
       that must stay reserved for the legacy interrupts.
    
       In case that the system, e.g. VM, does not advertise an IO/APIC the
       lower bound stays at 0.
    
       0 is an invalid interrupt number except for the legacy timer
       interrupt on x86. The return value is unchecked in the core code, so
       it ends up to allocate interrupt number 0 which is subsequently
       considered to be invalid by the caller, e.g. the MSI allocation code.
    
       A similar problem was already cured for device tree based systems
       years ago, but that missed - or did not envision - the zero IO/APIC
       case.
    
       Consolidate the zero check and return the provided "from" argument to
       the core code call site, which is guaranteed to be greater than 0.
    
     - Simplify the X2APIC cluster CPU mask logic for CPU hotplug
    
       Per cluster CPU masks are required for X2APIC in cluster mode to
       determine the correct cluster for a target CPU when calculating the
       destination for IPIs
    
       These masks are established when CPUs are borught up. The first CPU
       in a cluster must allocate a new cluster CPU mask. As this happens
       during the early startup of a CPU, where memory allocations cannot be
       done, the mask has to be allocated by the control CPU.
    
       The current implementation allocates a clustermask just in case and
       if the to be brought up CPU is the first in a cluster the CPU takes
       over this allocation from a global pointer.
    
       This works nicely in the fully serialized CPU bringup scenario which
       is used today, but would fail completely for parallel bringup of
       CPUs.
    
       The cluster association of a CPU can be computed from the APIC ID
       which is enumerated by ACPI/MADT.
    
       So the cluster CPU masks can be preallocated and associated upfront
       and the upcoming CPUs just need to set their corresponding bit.
    
       Aside of preparing for parallel bringup this is a valuable
       simplification on its own.
    
     - Remove global variables which control the early startup of secondary
       CPUs on 64-bit
    
       The only information which is needed by a starting CPU is the Linux
       CPU number. The CPU number allows it to retrieve the rest of the
       required data from already existing per CPU storage.
    
       So instead of initial_stack, early_gdt_desciptor and initial_gs
       provide a new variable smpboot_control which contains the Linux CPU
       number for now. The starting CPU can retrieve and compute all
       required information for startup from there.
    
       Aside of being a cleanup, this is also preparing for parallel CPU
       bringup, where starting CPUs will look up their Linux CPU number via
       the APIC ID, when smpboot_control has the corresponding control bit
       set.
    
     - Make cc_vendor globally accesible
    
       Subsequent parallel bringup changes require access to cc_vendor
       because confidental computing platforms need special treatment in the
       early startup phase vs. CPUID and APCI ID readouts.
    
       The change makes cc_vendor global and provides stub accessors in case
       that CONFIG_ARCH_HAS_CC_PLATFORM is not set.
    
       This was merged from the x86/cc branch in anticipation of further
       parallel bringup commits which require access to cc_vendor. Due to
       late discoveries of fundamental issue with those patches these
       commits never happened.
    
       The merge commit is unfortunately in the middle of the APIC commits
       so unraveling it would have required a rebase or revert. As the
       parallel bringup seems to be well on its way for 6.5 this would be
       just pointless churn. As the commit does not contain any functional
       change it's not a risk to keep it.
    
    * tag 'x86-apic-2023-04-24' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
      x86/ioapic: Don't return 0 from arch_dynirq_lower_bound()
      x86/apic: Fix atomic update of offset in reserve_eilvt_offset()
      x86/coco: Export cc_vendor
      x86/smpboot: Reference count on smpboot_setup_warm_reset_vector()
      x86/smpboot: Remove initial_gs
      x86/smpboot: Remove early_gdt_descr on 64-bit
      x86/smpboot: Remove initial_stack on 64-bit
      x86/apic/x2apic: Allow CPU cluster_mask to be populated in parallel
    de10553f
core.c 3.51 KB