Skip to content

Commit 3af1e41

Browse files
KAGA-KOKOhansendc
authored andcommitted
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 <[email protected]> Signed-off-by: Dave Hansen <[email protected]> Acked-by: Peter Zijlstra (Intel) <[email protected]> Tested-by: Michael Kelley <[email protected]> Tested-by: Sohil Mehta <[email protected]> Tested-by: Juergen Gross <[email protected]> # Xen PV (dom0 and unpriv. guest)
1 parent 0fa0757 commit 3af1e41

File tree

9 files changed

+59
-63
lines changed

9 files changed

+59
-63
lines changed

arch/x86/include/asm/apic.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,8 @@ extern int lapic_can_unplug_cpu(void);
344344

345345
#ifdef CONFIG_X86_LOCAL_APIC
346346

347+
void __init apic_install_driver(struct apic *driver);
348+
347349
static inline u32 apic_read(u32 reg)
348350
{
349351
return apic->read(reg);

arch/x86/kernel/apic/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
# In particualr, smp_apic_timer_interrupt() is called in random places.
88
KCOV_INSTRUMENT := n
99

10-
obj-$(CONFIG_X86_LOCAL_APIC) += apic.o apic_common.o apic_noop.o ipi.o vector.o
10+
obj-$(CONFIG_X86_LOCAL_APIC) += apic.o apic_common.o apic_noop.o ipi.o vector.o init.o
1111
obj-y += hw_nmi.o
1212

1313
obj-$(CONFIG_X86_IO_APIC) += io_apic.o

arch/x86/kernel/apic/apic.c

Lines changed: 1 addition & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -236,8 +236,7 @@ static int modern_apic(void)
236236
*/
237237
static void __init apic_disable(void)
238238
{
239-
pr_info("APIC: switched to apic NOOP\n");
240-
apic = &apic_noop;
239+
apic_install_driver(&apic_noop);
241240
}
242241

243242
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)
24862485
}
24872486
EXPORT_SYMBOL_GPL(x86_msi_msg_get_destid);
24882487

2489-
#ifdef CONFIG_X86_64
2490-
void __init acpi_wake_cpu_handler_update(wakeup_cpu_handler handler)
2491-
{
2492-
struct apic **drv;
2493-
2494-
for (drv = __apicdrivers; drv < __apicdrivers_end; drv++)
2495-
(*drv)->wakeup_secondary_cpu_64 = handler;
2496-
}
2497-
#endif
2498-
2499-
/*
2500-
* Override the generic EOI implementation with an optimized version.
2501-
* Only called during early boot when only one CPU is active and with
2502-
* interrupts disabled, so we know this does not race with actual APIC driver
2503-
* use.
2504-
*/
2505-
void __init apic_set_eoi_cb(void (*eoi)(void))
2506-
{
2507-
struct apic **drv;
2508-
2509-
for (drv = __apicdrivers; drv < __apicdrivers_end; drv++) {
2510-
/* Should happen once for each apic */
2511-
WARN_ON((*drv)->eoi == eoi);
2512-
(*drv)->native_eoi = (*drv)->eoi;
2513-
(*drv)->eoi = eoi;
2514-
}
2515-
}
2516-
25172488
static void __init apic_bsp_up_setup(void)
25182489
{
25192490
#ifdef CONFIG_X86_64

arch/x86/kernel/apic/apic_flat_64.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,7 @@ static int physflat_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
143143

144144
static int physflat_probe(void)
145145
{
146-
if (apic == &apic_physflat || num_possible_cpus() > 8 ||
147-
jailhouse_paravirt())
148-
return 1;
149-
150-
return 0;
146+
return apic == &apic_physflat || num_possible_cpus() > 8 || jailhouse_paravirt();
151147
}
152148

153149
static struct apic apic_physflat __ro_after_init = {

arch/x86/kernel/apic/bigsmp_32.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,8 @@ bool __init apic_bigsmp_possible(bool cmdline_override)
119119

120120
void __init apic_bigsmp_force(void)
121121
{
122-
if (apic != &apic_bigsmp) {
123-
apic = &apic_bigsmp;
124-
pr_info("Overriding APIC driver with bigsmp\n");
125-
}
122+
if (apic != &apic_bigsmp)
123+
apic_install_driver(&apic_bigsmp);
126124
}
127125

128126
apic_driver(apic_bigsmp);

arch/x86/kernel/apic/init.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
#define pr_fmt(fmt) "APIC: " fmt
3+
4+
#include <asm/apic.h>
5+
6+
#include "local.h"
7+
8+
void __init apic_install_driver(struct apic *driver)
9+
{
10+
if (apic == driver)
11+
return;
12+
13+
apic = driver;
14+
15+
if (IS_ENABLED(CONFIG_X86_X2APIC) && apic->x2apic_set_max_apicid)
16+
apic->max_apic_id = x2apic_max_apicid;
17+
18+
pr_info("Switched APIC routing to: %s\n", driver->name);
19+
}
20+
21+
#ifdef CONFIG_X86_64
22+
void __init acpi_wake_cpu_handler_update(wakeup_cpu_handler handler)
23+
{
24+
struct apic **drv;
25+
26+
for (drv = __apicdrivers; drv < __apicdrivers_end; drv++)
27+
(*drv)->wakeup_secondary_cpu_64 = handler;
28+
}
29+
#endif
30+
31+
/*
32+
* Override the generic EOI implementation with an optimized version.
33+
* Only called during early boot when only one CPU is active and with
34+
* interrupts disabled, so we know this does not race with actual APIC driver
35+
* use.
36+
*/
37+
void __init apic_set_eoi_cb(void (*eoi)(void))
38+
{
39+
struct apic **drv;
40+
41+
for (drv = __apicdrivers; drv < __apicdrivers_end; drv++) {
42+
/* Should happen once for each apic */
43+
WARN_ON((*drv)->eoi == eoi);
44+
(*drv)->native_eoi = (*drv)->eoi;
45+
(*drv)->eoi = eoi;
46+
}
47+
}

arch/x86/kernel/apic/probe_32.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ static int __init parse_apic(char *arg)
8282

8383
for (drv = __apicdrivers; drv < __apicdrivers_end; drv++) {
8484
if (!strcmp((*drv)->name, arg)) {
85-
apic = *drv;
85+
apic_install_driver(*drv);
8686
cmdline_apic = 1;
8787
return 0;
8888
}
@@ -129,13 +129,12 @@ void __init x86_32_probe_apic(void)
129129

130130
for (drv = __apicdrivers; drv < __apicdrivers_end; drv++) {
131131
if ((*drv)->probe()) {
132-
apic = *drv;
132+
apic_install_driver(*drv);
133133
break;
134134
}
135135
}
136136
/* Not visible without early console */
137137
if (drv == __apicdrivers_end)
138138
panic("Didn't find an APIC driver");
139139
}
140-
printk(KERN_INFO "Using APIC driver %s\n", apic->name);
141140
}

arch/x86/kernel/apic/probe_64.c

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,6 @@
1313

1414
#include "local.h"
1515

16-
static __init void apic_install_driver(struct apic *driver)
17-
{
18-
if (apic == driver)
19-
return;
20-
21-
apic = driver;
22-
23-
if (IS_ENABLED(CONFIG_X86_X2APIC) && apic->x2apic_set_max_apicid)
24-
apic->max_apic_id = x2apic_max_apicid;
25-
26-
pr_info("Switched APIC routing to %s:\n", apic->name);
27-
}
28-
2916
/* Select the appropriate APIC driver */
3017
void __init x86_64_probe_apic(void)
3118
{

arch/x86/xen/apic.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -160,20 +160,16 @@ static struct apic xen_pv_apic = {
160160

161161
static void __init xen_apic_check(void)
162162
{
163-
if (apic == &xen_pv_apic)
164-
return;
165-
166-
pr_info("Switched APIC routing from %s to %s.\n", apic->name,
167-
xen_pv_apic.name);
168-
apic = &xen_pv_apic;
163+
apic_install_driver(&xen_pv_apic);
169164
}
165+
170166
void __init xen_init_apic(void)
171167
{
172168
x86_apic_ops.io_apic_read = xen_io_apic_read;
173169
/* On PV guests the APIC CPUID bit is disabled so none of the
174170
* routines end up executing. */
175171
if (!xen_initial_domain())
176-
apic = &xen_pv_apic;
172+
apic_install_driver(&xen_pv_apic);
177173

178174
x86_platform.apic_post_init = xen_apic_check;
179175
}

0 commit comments

Comments
 (0)