summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--payloads/libpayload/arch/x86/Kconfig17
-rw-r--r--payloads/libpayload/arch/x86/exception.c18
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)