diff options
-rw-r--r-- | payloads/libpayload/arch/x86/Kconfig | 17 | ||||
-rw-r--r-- | payloads/libpayload/arch/x86/exception.c | 18 |
2 files changed, 32 insertions, 3 deletions
diff --git a/payloads/libpayload/arch/x86/Kconfig b/payloads/libpayload/arch/x86/Kconfig index cbb21cbc14..129ff5f682 100644 --- a/payloads/libpayload/arch/x86/Kconfig +++ b/payloads/libpayload/arch/x86/Kconfig @@ -37,4 +37,21 @@ config ARCH_SPECIFIC_OPTIONS # dummy config ENABLE_APIC bool "Enables the Local APIC" +choice + prompt "Interrupt Handling" + default LOG_UNKNOWN_INTERRUPTS if ENABLE_APIC + default DIE_ON_UNKNOWN_INTERRUPT + +config IGNORE_UNKNOWN_INTERRUPTS + bool "Ignore unknown user defined interrupts" + +config LOG_UNKNOWN_INTERRUPTS + bool "Logs unknown user defined interrupts to the console" + +config DIE_ON_UNKNOWN_INTERRUPT + bool "Die if an unknown user defined interrupt is encountered" + +endchoice + + endif diff --git a/payloads/libpayload/arch/x86/exception.c b/payloads/libpayload/arch/x86/exception.c index 1fa1304f62..983a9f3bd2 100644 --- a/payloads/libpayload/arch/x86/exception.c +++ b/payloads/libpayload/arch/x86/exception.c @@ -171,9 +171,14 @@ void exception_dispatch(void) if (handlers[vec]) { handlers[vec](vec); - if (IS_ENABLED(CONFIG_LP_ENABLE_APIC)) - apic_eoi(vec); - return; + goto success; + } else if (vec >= EXC_COUNT + && IS_ENABLED(CONFIG_LP_IGNORE_UNKNOWN_INTERRUPTS)) { + goto success; + } else if (vec >= EXC_COUNT + && IS_ENABLED(CONFIG_LP_LOG_UNKNOWN_INTERRUPTS)) { + printf("Ignoring interrupt vector %u\n", vec); + goto success; } die_if(vec >= EXC_COUNT || !names[vec], "Bad exception vector %u\n", @@ -181,7 +186,14 @@ void exception_dispatch(void) dump_exception_state(); dump_stack(exception_state->regs.esp, 512); + /* We don't call apic_eoi because we don't want to ack the interrupt and + allow another interrupt to wake the processor. */ halt(); + return; + +success: + if (IS_ENABLED(CONFIG_LP_ENABLE_APIC)) + apic_eoi(vec); } void exception_init(void) |