Skip to content

x86-apic-2023-04-24

tagged this 24 Apr 17:10
 - 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.
Assets 2
Loading