x86/of: Fix a bug in x86 arch OF support
cover x86/of: Fix a bug in x86 arch OF support
Hi Sebastian Andrzej Siewior, Rob, Thomas, Ingo, Boris, Andy, Dave & all [email protected] maintainers,
I sent this patch 3 times but for some reasons, never got any response or attention from anybody so far. Hence, resending with a cover letter to explain the rationale behind it in detail & to justify the need to add this fix. Also, hoping to get some feedback in-case i am mistaken in my understanding which might be the reason why i never got any response.
Background (baseline understanding - pls correct if mistaken anywhere):
References [1], [2] & [6]
For SMP systems, Intel defines three (logically four) interrupt modes during boot/init time while BIOS/bootloader boots & switches to linux kernel.
1. PIC mode - Legacy 8259 PIC interrupt controller.
2. Virtual wire mode via Local APIC - uses local APIC as virtual wire
3. Virtual wire mode via I/O APIC - uses I/O APIC as virtual wire
4. Symmetric I/O mode - final one used by linux for SMP systems.
BIOS/bootloaders are supposed to boot in either #1 or #2 or #3 and then switch to #4 in linux for SMP systems.
For our platform, we use #2.
Detection of which interrupt mode the system is booting in is made by using below global variable in apic.c
int pic_mode __ro_after_init;
Here pic_mode = 1 means #1 (PIC mode) above.
And pic_mode = 0 means #2 or #3 (basically virtual wire mode via apic).
And apic.c while doing setup_local_APIC() uses below code [3]:
value = apic_read(APIC_LVT0) & APIC_LVT_MASKED;
if (!cpu && (pic_mode || !value || skip_ioapic_setup)) {
value = APIC_DM_EXTINT;
apic_printk(APIC_VERBOSE, "enabled ExtINT on CPU#%d\n", cpu);
} else {
value = APIC_DM_EXTINT | APIC_LVT_MASKED;
apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n", cpu);
}
apic_write(APIC_LVT0, value);What i understand from above is that if at this point of time, as long as it is cpu0 & pic_mode=1, it will set delivery mode to ExtINT (causes the processor to respond to the interrupt as if the interrupt originated in an externally connected (8259A-compatible) interrupt controller) and enables/ unmask the interrupts.
pic_mode is presently set/populated/initialized at only two places:
1. In mpparse.c [4]
2. In devicetree.c [7]
For #1 MPPARSE Kconfig definition is as below:
config X86_MPPARSE
bool "Enable MPS table" if ACPI
default y
depends on X86_LOCAL_APIC
help
For old smp systems that do not have proper acpi support. Newer systems (esp with 64bit cpus) with acpi support, MADT and DSDT will override it
As seen above, if ACPI is not enabled, then mpparse by default is always enabled. Presently, there is no way to disable MPPARSE (if ACPI is not enabled). This to me appears to be another bug which needs fixing. As per theory, MPPARSE was to support MPS spec [1] as a temporary solution to support SMP systems until a final ACPI standard was added. But now if ACPI is not enabled, it will rely on MPPARSE driver to read MP floating pointer structure's IMCRP Bit 7 of MP feature info byte 2 [5] to figure out if it supports PIC mode or virtual wire mode and initialize pic_mode variable accordingly. If ACPI is enabled, the ACPI code overrides it by using the MADT table spec'ed in ACPI spec [2].
For #2 devicetree.c presently hardcodes pic_mode = 1 (PIC Mode). There is no support to configure virtual wire mode via devicetree path for OF based systems.
Now we have a platform which is OF based & does not use legacy 8259 PIC interrupt controller. Non ACPI compliant as well as non MPPARSE compliant.
For such platforms, it appears to me that hardcoding pic_mode = 1 (PIC Mode) and giving no other choice to choose virtual wire mode is a bug for OF based x86 platforms.
Just like mpparse relies on IMCRP bit 7 of MP feature info byte2 [5] to select pic_mode to PIC mode or virtual wire mode. arch/x86/kernel/devicetree.c should also provide some similar configurability to choose interrupt delivery mode & not hardcode it to PIC mode.
This patch is to fix above explained bug in x86/of support for interrupt delivery mode configuration. Please let me know if you find any mistake in above understanding or if you have a alternative better suggestion to solve it or if you find anything odd here in our platform/system. TIA.
The patch is baselined on below git tree:git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/core
[1] https://pdos.csail.mit.edu/6.828/2008/readings/ia32/MPspec.pdf
[2] https://uefi.org/sites/default/files/resources/ACPI_6_3_final_Jan30.pdf
[3] https://elixir.bootlin.com/linux/v6.1-rc5/source/arch/x86/kernel/apic/apic.c#L1691
[4] https://elixir.bootlin.com/linux/v6.1-rc5/source/arch/x86/kernel/mpparse.c#L517
[5] https://www.manualslib.com/manual/77733/Intel-Multiprocessor.html?page=40#manual
[6] https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html
[7] https://elixir.bootlin.com/linux/v6.1-rc5/source/arch/x86/kernel/devicetree.c#L170
Rahul Tanwar (1):
x86/of: Add support for boot time interrupt mode config
arch/x86/kernel/devicetree.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
Signature · 1 line
2.17.1
PATCH RESEND 1/1 x86/of: Add support for boot time interrupt mode config
Presently, init/boot time interrupt delivery mode is enumerated only for ACPI enabled systems by parsing MADT table or for older systems by parsing MP table. But for OF based x86 systems, it is assumed & fixed to legacy PIC mode.
Add support for configuration of init time interrupt delivery mode for x86 OF based systems by introducing a new optional boolean property 'intel,no-imcr' for interrupt-controller node of local APIC. This property emulates IMCRP Bit 7 of MP feature info byte 2 of MP floating pointer structure.
Defaults to legacy PIC mode if absent. Configures it to virtual wire compatibility mode if present.
--- arch/x86/kernel/devicetree.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
arch/x86/kernel/devicetree.c +8 -1
@@ -167,7 +167,14 @@ static void __init dtb_lapic_setup(void)return ; } smp_found_config =1 ; - pic_mode =1 ; +if (of_property_read_bool (dn,"intel,no-imcr" )) { +pr_info (" Virtual Wire compatibility mode.\n" ); + pic_mode =0 ; + }else { +pr_info (" IMCR and PIC compatibility mode.\n" ); + pic_mode =1 ; + } +register_lapic_address (lapic_addr); }
Signature · 1 line
2.17.1
Re: [PATCH RESEND 1/1] x86/of: Add support for boot time interrupt mode config
Quoted 13 lines · Rahul Tanwar
Presently, init/boot time interrupt delivery mode is enumerated only for ACPI enabled systems by parsing MADT table or for older systems by parsing MP table. But for OF based x86 systems, it is assumed & fixed to legacy PIC mode.
Add support for configuration of init time interrupt delivery mode for x86 OF based systems by introducing a new optional boolean property 'intel,no-imcr' for interrupt-controller node of local APIC. This property emulates IMCRP Bit 7 of MP feature info byte 2 of MP floating pointer structure.
Defaults to legacy PIC mode if absent. Configures it to virtual wire compatibility mode if present.
...
arch/x86/kernel/devicetree.c static void __init dtb_lapic_setup(void) · line 170
Quoted 1 line
arch/x86/kernel/devicetree.c +1
-0+if (of_property_read_bool (dn,"intel,no-imcr" )) {
I can't find this property in the Documentation/devicetree/bindings.
Moreover, I prefer to see positive one, something like:
intel,virtual-wire-bla-bla-bla
Please consult with DT people on how properly name it.
Quoted 6 lines
arch/x86/kernel/devicetree.c +6
-0+pr_info (" Virtual Wire compatibility mode.\n" ); + pic_mode =0 ; + }else { +pr_info (" IMCR and PIC compatibility mode.\n" ); + pic_mode =1 ; + }
Signature · 2 lines
With Best Regards, Andy Shevchenko
Re: [PATCH RESEND 1/1] x86/of: Add support for boot time interrupt mode config
Hi Andy,
Thanks for response.
Quoted 22 lines · Andy Shevchenko
This email was sent from outside of MaxLinear.
Quoted 13 lines · Rahul Tanwar
Presently, init/boot time interrupt delivery mode is enumerated only for ACPI enabled systems by parsing MADT table or for older systems by parsing MP table. But for OF based x86 systems, it is assumed & fixed to legacy PIC mode.
Add support for configuration of init time interrupt delivery mode for x86 OF based systems by introducing a new optional boolean property 'intel,no-imcr' for interrupt-controller node of local APIC. This property emulates IMCRP Bit 7 of MP feature info byte 2 of MP floating pointer structure.
Defaults to legacy PIC mode if absent. Configures it to virtual wire compatibility mode if present.
...
Quoted 1 line
+ if (
of_property_read_bool(dn, "intel,no-imcr")) {
Quoted 7 lines
I can't find this property in the
Documentation/devicetree/bindings.Moreover, I prefer to see positive one, something like:
intel,virtual-wire-bla-bla-bla
Please consult with DT people on how properly name it.
Yes, agree. Need to add it in bindings doc after finalizing the property name. I chose "intel,no-imcr" to have a direct correlation with the MPS spec defined data field for the same purpose. It reads below bit in mpparse code to detect PIC mode or virtual wire mode.
Bit 7: IMCRP. When the IMCR presence bit is set, the IMCR is present and PIC Mode is implemented; otherwise, Virtual Wire Mode is implemented.
Please refer [1]
[1] https://www.manualslib.com/manual/77733/Intel
Multiprocessor.html?page=40#manual
Regards,
Rahul
Quoted 14 lines
arch/x86/kernel/devicetree.c static void __init dtb_lapic_setup(void) · line 176
Quoted 7 lines
arch/x86/kernel/devicetree.c +6
-0+pr_info (" Virtual Wire compatibility mode.\n" ); + pic_mode =0 ; + }else { +pr_info (" IMCR and PIC compatibility mode.\n" ); + pic_mode =1 ; + }--
With Best Regards,
Andy Shevchenko
Re: [PATCH RESEND 1/1] x86/of: Add support for boot time interrupt mode config
Quoted 2 lines · Rahul Tanwar
Quoted 1 line · Andy Shevchenko
On Mon, Nov 14, 2022 at 05:20:06PM +0800, Rahul Tanwar wrote:
...
Quoted 6 lines
Quoted 6 lines
Quoted 1 line
+ if (
of_property_read_bool(dn, "intel,no-imcr")) {I can't find this property in the
Documentation/devicetree/bindings.Moreover, I prefer to see positive one, something like:
Quoted 8 lines
Quoted 3 lines
intel,virtual-wire-bla-bla-bla
Please consult with DT people on how properly name it.
Yes, agree. Need to add it in bindings doc after finalizing the property name. I chose "intel,no-imcr" to have a direct correlation with the MPS spec defined data field for the same purpose.
The problems with it are:
- it's negative
- it's too cryptic to one who doesn't know area well enough
Quoted 10 lines
It reads below bit in
mpparse code to detect PIC mode or virtual wire mode.Bit 7: IMCRP. When the IMCR presence bit is set, the IMCR is present and PIC Mode is implemented; otherwise, Virtual Wire Mode is implemented.
Please refer [1]
[1] https://www.manualslib.com/manual/77733/Intel
Multiprocessor.html?page=40#manual
This is good reference for DT people to suggest you a better name.
Signature · 2 lines
With Best Regards, Andy Shevchenko