From nobody Sun Feb 8 19:43:18 2026 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 DEC51C0015E for ; Wed, 9 Aug 2023 20:36:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234663AbjHIUgf (ORCPT ); Wed, 9 Aug 2023 16:36:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54438 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234519AbjHIUgR (ORCPT ); Wed, 9 Aug 2023 16:36:17 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 01694211B; Wed, 9 Aug 2023 13:36:10 -0700 (PDT) Date: Wed, 09 Aug 2023 20:36:08 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1691613368; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=bimBVY8RdmfT0LAkUV4jrKBGiIhXO+0jFslavpxZtLs=; b=JhYPAI3B6XoED6OHEFgOYbd3MJNhNYzfyQSJ+MOs5V1QzxYyCUg8bsboUYgWzwx+ddtgXR UE2HbuVnIwEOE12bGjAANKKGolb5NbOaQoU4YKjyaYNbeoawAW1nz7EaHtzoR5QRHsPX5a +ShLBVOqkNn1DT4pXHfm9cMcUxk13KfwQ3ippoP9cykt2y6N39AZ7aVDvBlvXeYsby/x3q FcMWGjCqTnk/71MVoVYo8zh+oKBTtlVZ6CEr/nE9S4DUDXebL3mDmEj4nWQloTcGMmax59 9TOewUSDQnaEknZlZ22s26S4BEf+7pO8xw4GZqQpsICod5MXilxGnXM/DbY8Yg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1691613368; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=bimBVY8RdmfT0LAkUV4jrKBGiIhXO+0jFslavpxZtLs=; b=2LS0jn0TRpUNKHLikt0+qmqL+Jsg21MaLH7JxpGT4fE0V/XU2hHBxOISCIkS6PObxjtdDA nTRoEikxOe5WyGCQ== From: "tip-bot2 for Thomas Gleixner" Sender: tip-bot2@linutronix.de Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: x86/apic] x86/apic: Provide common init infrastructure Cc: Thomas Gleixner , Dave Hansen , "Peter Zijlstra (Intel)" , Michael Kelley , Sohil Mehta , Juergen Gross , x86@kernel.org, linux-kernel@vger.kernel.org MIME-Version: 1.0 Message-ID: <169161336811.27769.16060148631353900017.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The following commit has been merged into the x86/apic branch of tip: Commit-ID: 3af1e415e4d43128b72af615b346b832694377d3 Gitweb: https://git.kernel.org/tip/3af1e415e4d43128b72af615b346b8326= 94377d3 Author: Thomas Gleixner AuthorDate: Tue, 08 Aug 2023 15:04:18 -07:00 Committer: Dave Hansen CommitterDate: Wed, 09 Aug 2023 11:58:34 -07:00 x86/apic: Provide common init infrastructure In preparation for converting the hotpath APIC callbacks to static keys, provide common initialization infrastructure. 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 Signed-off-by: Dave Hansen Acked-by: Peter Zijlstra (Intel) Tested-by: Michael Kelley Tested-by: Sohil Mehta Tested-by: Juergen Gross # Xen PV (dom0 and unpriv. guest) --- 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(-) create mode 100644 arch/x86/kernel/apic/init.c diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index 5d98c4b..90814ec 100644 --- 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); diff --git a/arch/x86/kernel/apic/Makefile b/arch/x86/kernel/apic/Makefile index a6fcaf1..2ee867d 100644 --- 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 diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index b8b801e..55f2b96 100644 --- 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_msg *msg, bool= extid) } 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 diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/api= c_flat_64.c index 5ce1b37..032a84e 100644 --- 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(char *oem_id, = char *oem_table_id) =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 { diff --git a/arch/x86/kernel/apic/bigsmp_32.c b/arch/x86/kernel/apic/bigsmp= _32.c index 23c29a0..0e5535a 100644 --- 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 cmdline_override) =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); diff --git a/arch/x86/kernel/apic/init.c b/arch/x86/kernel/apic/init.c new file mode 100644 index 0000000..25cf39b --- /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; + } +} diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_3= 2.c index 3671cc1..9a06df6 100644 --- 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); } diff --git a/arch/x86/kernel/apic/probe_64.c b/arch/x86/kernel/apic/probe_6= 4.c index a12a379..ecdf0c4 100644 --- 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) { diff --git a/arch/x86/xen/apic.c b/arch/x86/xen/apic.c index 804a26b..1838aef 100644 --- 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; }