Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'x86-apic-2022-12-10' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 apic update from Thomas Gleixner:
"A set of changes for the x86 APIC code:

- Handle the case where x2APIC is enabled and locked by the BIOS on a
kernel with CONFIG_X86_X2APIC=n gracefully.

Instead of a panic which does not make it to the graphical console
during very early boot, simply disable the local APIC completely
and boot with the PIC and very limited functionality, which allows
to diagnose the issue

- Convert x86 APIC device tree bindings to YAML

- Extend x86 APIC device tree bindings to configure interrupt
delivery mode and handle this in during init. This allows to boot
with device tree on platforms which lack a legacy PIC"

* tag 'x86-apic-2022-12-10' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/of: Add support for boot time interrupt delivery mode configuration
x86/of: Replace printk(KERN_LVL) with pr_lvl()
dt-bindings: x86: apic: Introduce new optional bool property for lapic
dt-bindings: x86: apic: Convert Intel's APIC bindings to YAML schema
x86/of: Remove unused early_init_dt_add_memory_arch()
x86/apic: Handle no CONFIG_X86_X2APIC on systems with x2APIC enabled by BIOS

+152 -43
-26
Documentation/devicetree/bindings/interrupt-controller/intel,ce4100-ioapic.txt
··· 1 - Interrupt chips 2 - --------------- 3 - 4 - * Intel I/O Advanced Programmable Interrupt Controller (IO APIC) 5 - 6 - Required properties: 7 - -------------------- 8 - compatible = "intel,ce4100-ioapic"; 9 - #interrupt-cells = <2>; 10 - 11 - Device's interrupt property: 12 - 13 - interrupts = <P S>; 14 - 15 - The first number (P) represents the interrupt pin which is wired to the 16 - IO APIC. The second number (S) represents the sense of interrupt which 17 - should be configured and can be one of: 18 - 0 - Edge Rising 19 - 1 - Level Low 20 - 2 - Level High 21 - 3 - Edge Falling 22 - 23 - * Local APIC 24 - Required property: 25 - 26 - compatible = "intel,ce4100-lapic";
+60
Documentation/devicetree/bindings/interrupt-controller/intel,ce4100-ioapic.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: "http://devicetree.org/schemas/interrupt-controller/intel,ce4100-ioapic.yaml#" 5 + $schema: "http://devicetree.org/meta-schemas/core.yaml#" 6 + 7 + title: Intel I/O Advanced Programmable Interrupt Controller (IO APIC) 8 + 9 + maintainers: 10 + - Rahul Tanwar <rtanwar@maxlinear.com> 11 + 12 + description: | 13 + Intel's Advanced Programmable Interrupt Controller (APIC) is a 14 + family of interrupt controllers. The APIC is a split 15 + architecture design, with a local component (LAPIC) integrated 16 + into the processor itself and an external I/O APIC. Local APIC 17 + (lapic) receives interrupts from the processor's interrupt pins, 18 + from internal sources and from an external I/O APIC (ioapic). 19 + And it sends these to the processor core for handling. 20 + See [1] Chapter 8 for more details. 21 + 22 + Many of the Intel's generic devices like hpet, ioapic, lapic have 23 + the ce4100 name in their compatible property names because they 24 + first appeared in CE4100 SoC. 25 + 26 + This schema defines bindings for I/O APIC interrupt controller. 27 + 28 + [1] https://pdos.csail.mit.edu/6.828/2008/readings/ia32/IA32-3A.pdf 29 + 30 + properties: 31 + compatible: 32 + const: intel,ce4100-ioapic 33 + 34 + reg: 35 + maxItems: 1 36 + 37 + interrupt-controller: true 38 + 39 + '#interrupt-cells': 40 + const: 2 41 + 42 + interrupts: 43 + maxItems: 1 44 + 45 + required: 46 + - compatible 47 + - reg 48 + - interrupt-controller 49 + - '#interrupt-cells' 50 + 51 + additionalProperties: false 52 + 53 + examples: 54 + - | 55 + ioapic1: interrupt-controller@fec00000 { 56 + compatible = "intel,ce4100-ioapic"; 57 + reg = <0xfec00000 0x1000>; 58 + interrupt-controller; 59 + #interrupt-cells = <2>; 60 + };
+71
Documentation/devicetree/bindings/interrupt-controller/intel,ce4100-lapic.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: "http://devicetree.org/schemas/interrupt-controller/intel,ce4100-lapic.yaml#" 5 + $schema: "http://devicetree.org/meta-schemas/core.yaml#" 6 + 7 + title: Intel Local Advanced Programmable Interrupt Controller (LAPIC) 8 + 9 + maintainers: 10 + - Rahul Tanwar <rtanwar@maxlinear.com> 11 + 12 + description: | 13 + Intel's Advanced Programmable Interrupt Controller (APIC) is a 14 + family of interrupt controllers. The APIC is a split 15 + architecture design, with a local component (LAPIC) integrated 16 + into the processor itself and an external I/O APIC. Local APIC 17 + (lapic) receives interrupts from the processor's interrupt pins, 18 + from internal sources and from an external I/O APIC (ioapic). 19 + And it sends these to the processor core for handling. 20 + See [1] Chapter 8 for more details. 21 + 22 + Many of the Intel's generic devices like hpet, ioapic, lapic have 23 + the ce4100 name in their compatible property names because they 24 + first appeared in CE4100 SoC. 25 + 26 + This schema defines bindings for local APIC interrupt controller. 27 + 28 + [1] https://pdos.csail.mit.edu/6.828/2008/readings/ia32/IA32-3A.pdf 29 + 30 + properties: 31 + compatible: 32 + const: intel,ce4100-lapic 33 + 34 + reg: 35 + maxItems: 1 36 + 37 + interrupt-controller: true 38 + 39 + '#interrupt-cells': 40 + const: 2 41 + 42 + intel,virtual-wire-mode: 43 + description: Intel defines a few possible interrupt delivery 44 + modes. With respect to boot/init time, mainly two interrupt 45 + delivery modes are possible. 46 + PIC Mode - Legacy external 8259 compliant PIC interrupt controller. 47 + Virtual Wire Mode - use lapic as virtual wire interrupt delivery mode. 48 + For ACPI or MPS spec compliant systems, it is figured out by some read 49 + only bit field/s available in their respective defined data structures. 50 + For OF based systems, it is by default set to PIC mode. 51 + But if this optional boolean property is set, then the interrupt delivery 52 + mode is configured to virtual wire compatibility mode. 53 + type: boolean 54 + 55 + required: 56 + - compatible 57 + - reg 58 + - interrupt-controller 59 + - '#interrupt-cells' 60 + 61 + additionalProperties: false 62 + 63 + examples: 64 + - | 65 + lapic0: interrupt-controller@fee00000 { 66 + compatible = "intel,ce4100-lapic"; 67 + reg = <0xfee00000 0x1000>; 68 + interrupt-controller; 69 + #interrupt-cells = <2>; 70 + intel,virtual-wire-mode; 71 + };
+2 -2
arch/x86/Kconfig
··· 463 463 464 464 Some Intel systems circa 2022 and later are locked into x2APIC mode 465 465 and can not fall back to the legacy APIC modes if SGX or TDX are 466 - enabled in the BIOS. They will be unable to boot without enabling 467 - this option. 466 + enabled in the BIOS. They will boot with very reduced functionality 467 + without enabling this option. 468 468 469 469 If you don't know what to do here, say N. 470 470
+1 -2
arch/x86/include/asm/apic.h
··· 249 249 extern int x2apic_mode; 250 250 extern int x2apic_phys; 251 251 extern void __init x2apic_set_max_apicid(u32 apicid); 252 - extern void __init check_x2apic(void); 253 252 extern void x2apic_setup(void); 254 253 static inline int x2apic_enabled(void) 255 254 { ··· 257 258 258 259 #define x2apic_supported() (boot_cpu_has(X86_FEATURE_X2APIC)) 259 260 #else /* !CONFIG_X86_X2APIC */ 260 - static inline void check_x2apic(void) { } 261 261 static inline void x2apic_setup(void) { } 262 262 static inline int x2apic_enabled(void) { return 0; } 263 263 264 264 #define x2apic_mode (0) 265 265 #define x2apic_supported() (0) 266 266 #endif /* !CONFIG_X86_X2APIC */ 267 + extern void __init check_x2apic(void); 267 268 268 269 struct irq_data; 269 270
+8 -5
arch/x86/kernel/apic/apic.c
··· 1931 1931 } 1932 1932 } 1933 1933 #else /* CONFIG_X86_X2APIC */ 1934 - static int __init validate_x2apic(void) 1934 + void __init check_x2apic(void) 1935 1935 { 1936 1936 if (!apic_is_x2apic_enabled()) 1937 - return 0; 1937 + return; 1938 1938 /* 1939 - * Checkme: Can we simply turn off x2apic here instead of panic? 1939 + * Checkme: Can we simply turn off x2APIC here instead of disabling the APIC? 1940 1940 */ 1941 - panic("BIOS has enabled x2apic but kernel doesn't support x2apic, please disable x2apic in BIOS.\n"); 1941 + pr_err("Kernel does not support x2APIC, please recompile with CONFIG_X86_X2APIC.\n"); 1942 + pr_err("Disabling APIC, expect reduced performance and functionality.\n"); 1943 + 1944 + disable_apic = 1; 1945 + setup_clear_cpu_cap(X86_FEATURE_APIC); 1942 1946 } 1943 - early_initcall(validate_x2apic); 1944 1947 1945 1948 static inline void try_to_enable_x2apic(int remap_mode) { } 1946 1949 static inline void __x2apic_enable(void) { }
+10 -8
arch/x86/kernel/devicetree.c
··· 31 31 32 32 int __initdata of_ioapic; 33 33 34 - void __init early_init_dt_add_memory_arch(u64 base, u64 size) 35 - { 36 - BUG(); 37 - } 38 - 39 34 void __init add_dtb(u64 data) 40 35 { 41 36 initial_dtb = data + offsetof(struct setup_data, data); ··· 162 167 return; 163 168 } 164 169 smp_found_config = 1; 165 - pic_mode = 1; 170 + if (of_property_read_bool(dn, "intel,virtual-wire-mode")) { 171 + pr_info("Virtual Wire compatibility mode.\n"); 172 + pic_mode = 0; 173 + } else { 174 + pr_info("IMCR and PIC compatibility mode.\n"); 175 + pic_mode = 1; 176 + } 177 + 166 178 register_lapic_address(lapic_addr); 167 179 } 168 180 ··· 250 248 251 249 ret = of_address_to_resource(dn, 0, &r); 252 250 if (ret) { 253 - printk(KERN_ERR "Can't obtain address from device node %pOF.\n", dn); 251 + pr_err("Can't obtain address from device node %pOF.\n", dn); 254 252 return; 255 253 } 256 254 mp_register_ioapic(++ioapic_id, r.start, gsi_top, &cfg); ··· 267 265 of_ioapic = 1; 268 266 return; 269 267 } 270 - printk(KERN_ERR "Error: No information about IO-APIC in OF.\n"); 268 + pr_err("Error: No information about IO-APIC in OF.\n"); 271 269 } 272 270 #else 273 271 static void __init dtb_ioapic_setup(void) {}