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 /* The container for function call overrides */ 9 struct apic_override __x86_apic_override __initdata; 10 11 #define apply_override(__cb) \ 12 if (__x86_apic_override.__cb) \ 13 apic->__cb = __x86_apic_override.__cb 14 15 static __init void restore_override_callbacks(void) 16 { 17 apply_override(eoi); 18 apply_override(native_eoi); 19 apply_override(write); 20 apply_override(read); 21 apply_override(send_IPI); 22 apply_override(send_IPI_mask); 23 apply_override(send_IPI_mask_allbutself); 24 apply_override(send_IPI_allbutself); 25 apply_override(send_IPI_all); 26 apply_override(send_IPI_self); 27 apply_override(icr_read); 28 apply_override(icr_write); 29 apply_override(wakeup_secondary_cpu); 30 apply_override(wakeup_secondary_cpu_64); 31 } 32 33 void __init apic_setup_apic_calls(void) 34 { 35 /* Ensure that the default APIC has native_eoi populated */ 36 apic->native_eoi = apic->eoi; 37 } 38 39 void __init apic_install_driver(struct apic *driver) 40 { 41 if (apic == driver) 42 return; 43 44 apic = driver; 45 46 if (IS_ENABLED(CONFIG_X86_X2APIC) && apic->x2apic_set_max_apicid) 47 apic->max_apic_id = x2apic_max_apicid; 48 49 /* Copy the original eoi() callback as KVM/HyperV might overwrite it */ 50 if (!apic->native_eoi) 51 apic->native_eoi = apic->eoi; 52 53 /* Apply any already installed callback overrides */ 54 restore_override_callbacks(); 55 56 pr_info("Switched APIC routing to: %s\n", driver->name); 57 } 58