From nobody Fri Dec 19 07:41:19 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 69702C0015E for ; Mon, 24 Jul 2023 13:38:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231823AbjGXNie (ORCPT ); Mon, 24 Jul 2023 09:38:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37424 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231738AbjGXNhz (ORCPT ); Mon, 24 Jul 2023 09:37:55 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1D70E213E for ; Mon, 24 Jul 2023 06:36:30 -0700 (PDT) Message-ID: <20230724132047.554355840@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1690205711; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=u1MBAiZCltHmWzuaN06FA6y4i5aqgal/njyPH8pNWsw=; b=u9kgxt8SOBounsX3W7OIiLnRFhv3i25Y2kpEWL/veN4l+tSBaQ/APwQdgMMBK6wBDqypOH 0ibngDw1lcb/EqdfCfXK4lVgqQmhb7uLfewv/XZuLmI7u2SRFCsKI24f9s/r4m2sud2cht 5Y69rknWEkW4SDcKh+QHMbV+467JeRd8kUDZ8qsc+mtWlylAQjR/JRiNrRbJdL5qPFGEAu no+51QdXU2f6NhcjkGj4KMxXFzb+xsOcdaf34eiI4Ci053O//HGW+08KKXmamdXQXonWvQ 7/UvO45itPBejqF5nGUnDY0IjtUKJob+HuBplmD26vtWduWNFPGXjRkPGn+kew== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1690205711; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=u1MBAiZCltHmWzuaN06FA6y4i5aqgal/njyPH8pNWsw=; b=eA/edTzH+XyteYt7cDp/D6iynyMj8pju/Xb3PmjQNy0fXdzELBYW2tSIzNSHjD5d5ujCWT u2yXkPTA0MBiY2AQ== From: Thomas Gleixner To: LKML Cc: x86@kernel.org, Andrew Cooper , Tom Lendacky , Paolo Bonzini , Wei Liu , Arjan van de Ven , Juergen Gross , Michael Kelley , Peter Keresztes Schmidt , "Peter Zijlstra (Intel)" Subject: [patch V2 50/58] x86/apic: Provide common init infrastructure References: <20230724131206.500814398@linutronix.de> MIME-Version: 1.0 Date: Mon, 24 Jul 2023 15:35:10 +0200 (CEST) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In preparation for converting the hotpath APIC callbacks to static keys, provide common initialization inforastructure. Lift apic_install_drivers() from probe_64.c and convert all places which switch the apic instance by storing the pointer to use apic_install_driver() as a first step. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) --- arch/x86/include/asm/apic.h | 2 + arch/x86/kernel/apic/Makefile | 2 - arch/x86/kernel/apic/apic.c | 31 ----------------------- arch/x86/kernel/apic/apic_flat_64.c | 6 ---- arch/x86/kernel/apic/bigsmp_32.c | 6 +--- arch/x86/kernel/apic/init.c | 47 +++++++++++++++++++++++++++++++= +++++ arch/x86/kernel/apic/probe_32.c | 5 +-- arch/x86/kernel/apic/probe_64.c | 13 --------- arch/x86/xen/apic.c | 10 ++----- 9 files changed, 59 insertions(+), 63 deletions(-) --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -344,6 +344,8 @@ extern int lapic_can_unplug_cpu(void); =20 #ifdef CONFIG_X86_LOCAL_APIC =20 +void __init apic_install_driver(struct apic *driver); + static inline u32 apic_read(u32 reg) { return apic->read(reg); --- a/arch/x86/kernel/apic/Makefile +++ b/arch/x86/kernel/apic/Makefile @@ -7,7 +7,7 @@ # In particualr, smp_apic_timer_interrupt() is called in random places. KCOV_INSTRUMENT :=3D n =20 -obj-$(CONFIG_X86_LOCAL_APIC) +=3D apic.o apic_common.o apic_noop.o ipi.o v= ector.o +obj-$(CONFIG_X86_LOCAL_APIC) +=3D apic.o apic_common.o apic_noop.o ipi.o v= ector.o init.o obj-y +=3D hw_nmi.o =20 obj-$(CONFIG_X86_IO_APIC) +=3D io_apic.o --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -236,8 +236,7 @@ static int modern_apic(void) */ static void __init apic_disable(void) { - pr_info("APIC: switched to apic NOOP\n"); - apic =3D &apic_noop; + apic_install_driver(&apic_noop); } =20 void native_apic_icr_write(u32 low, u32 id) @@ -2486,34 +2485,6 @@ u32 x86_msi_msg_get_destid(struct msi_ms } EXPORT_SYMBOL_GPL(x86_msi_msg_get_destid); =20 -#ifdef CONFIG_X86_64 -void __init acpi_wake_cpu_handler_update(wakeup_cpu_handler handler) -{ - struct apic **drv; - - for (drv =3D __apicdrivers; drv < __apicdrivers_end; drv++) - (*drv)->wakeup_secondary_cpu_64 =3D handler; -} -#endif - -/* - * Override the generic EOI implementation with an optimized version. - * Only called during early boot when only one CPU is active and with - * interrupts disabled, so we know this does not race with actual APIC dri= ver - * use. - */ -void __init apic_set_eoi_cb(void (*eoi)(void)) -{ - struct apic **drv; - - for (drv =3D __apicdrivers; drv < __apicdrivers_end; drv++) { - /* Should happen once for each apic */ - WARN_ON((*drv)->eoi =3D=3D eoi); - (*drv)->native_eoi =3D (*drv)->eoi; - (*drv)->eoi =3D eoi; - } -} - static void __init apic_bsp_up_setup(void) { #ifdef CONFIG_X86_64 --- a/arch/x86/kernel/apic/apic_flat_64.c +++ b/arch/x86/kernel/apic/apic_flat_64.c @@ -143,11 +143,7 @@ static int physflat_acpi_madt_oem_check( =20 static int physflat_probe(void) { - if (apic =3D=3D &apic_physflat || num_possible_cpus() > 8 || - jailhouse_paravirt()) - return 1; - - return 0; + return apic =3D=3D &apic_physflat || num_possible_cpus() > 8 || jailhouse= _paravirt(); } =20 static struct apic apic_physflat __ro_after_init =3D { --- a/arch/x86/kernel/apic/bigsmp_32.c +++ b/arch/x86/kernel/apic/bigsmp_32.c @@ -119,10 +119,8 @@ bool __init apic_bigsmp_possible(bool cm =20 void __init apic_bigsmp_force(void) { - if (apic !=3D &apic_bigsmp) { - apic =3D &apic_bigsmp; - pr_info("Overriding APIC driver with bigsmp\n"); - } + if (apic !=3D &apic_bigsmp) + apic_install_driver(&apic_bigsmp); } =20 apic_driver(apic_bigsmp); --- /dev/null +++ b/arch/x86/kernel/apic/init.c @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0-only +#define pr_fmt(fmt) "APIC: " fmt + +#include + +#include "local.h" + +void __init apic_install_driver(struct apic *driver) +{ + if (apic =3D=3D driver) + return; + + apic =3D driver; + + if (IS_ENABLED(CONFIG_X86_X2APIC) && apic->x2apic_set_max_apicid) + apic->max_apic_id =3D x2apic_max_apicid; + + pr_info("Switched APIC routing to: %s\n", driver->name); +} + +#ifdef CONFIG_X86_64 +void __init acpi_wake_cpu_handler_update(wakeup_cpu_handler handler) +{ + struct apic **drv; + + for (drv =3D __apicdrivers; drv < __apicdrivers_end; drv++) + (*drv)->wakeup_secondary_cpu_64 =3D handler; +} +#endif + +/* + * Override the generic EOI implementation with an optimized version. + * Only called during early boot when only one CPU is active and with + * interrupts disabled, so we know this does not race with actual APIC dri= ver + * use. + */ +void __init apic_set_eoi_cb(void (*eoi)(void)) +{ + struct apic **drv; + + for (drv =3D __apicdrivers; drv < __apicdrivers_end; drv++) { + /* Should happen once for each apic */ + WARN_ON((*drv)->eoi =3D=3D eoi); + (*drv)->native_eoi =3D (*drv)->eoi; + (*drv)->eoi =3D eoi; + } +} --- a/arch/x86/kernel/apic/probe_32.c +++ b/arch/x86/kernel/apic/probe_32.c @@ -82,7 +82,7 @@ static int __init parse_apic(char *arg) =20 for (drv =3D __apicdrivers; drv < __apicdrivers_end; drv++) { if (!strcmp((*drv)->name, arg)) { - apic =3D *drv; + apic_install_driver(*drv); cmdline_apic =3D 1; return 0; } @@ -129,7 +129,7 @@ void __init x86_32_probe_apic(void) =20 for (drv =3D __apicdrivers; drv < __apicdrivers_end; drv++) { if ((*drv)->probe()) { - apic =3D *drv; + apic_install_driver(*drv); break; } } @@ -137,5 +137,4 @@ void __init x86_32_probe_apic(void) if (drv =3D=3D __apicdrivers_end) panic("Didn't find an APIC driver"); } - printk(KERN_INFO "Using APIC driver %s\n", apic->name); } --- a/arch/x86/kernel/apic/probe_64.c +++ b/arch/x86/kernel/apic/probe_64.c @@ -13,19 +13,6 @@ =20 #include "local.h" =20 -static __init void apic_install_driver(struct apic *driver) -{ - if (apic =3D=3D driver) - return; - - apic =3D driver; - - if (IS_ENABLED(CONFIG_X86_X2APIC) && apic->x2apic_set_max_apicid) - apic->max_apic_id =3D x2apic_max_apicid; - - pr_info("Switched APIC routing to %s:\n", apic->name); -} - /* Select the appropriate APIC driver */ void __init x86_64_probe_apic(void) { --- a/arch/x86/xen/apic.c +++ b/arch/x86/xen/apic.c @@ -160,20 +160,16 @@ static struct apic xen_pv_apic =3D { =20 static void __init xen_apic_check(void) { - if (apic =3D=3D &xen_pv_apic) - return; - - pr_info("Switched APIC routing from %s to %s.\n", apic->name, - xen_pv_apic.name); - apic =3D &xen_pv_apic; + apic_install_driver(&xen_pv_apic); } + void __init xen_init_apic(void) { x86_apic_ops.io_apic_read =3D xen_io_apic_read; /* On PV guests the APIC CPUID bit is disabled so none of the * routines end up executing. */ if (!xen_initial_domain()) - apic =3D &xen_pv_apic; + apic_install_driver(&xen_pv_apic); =20 x86_platform.apic_post_init =3D xen_apic_check; }