From f9072c166bd102c44e9a9b653473f346dd9c5a1b Mon Sep 17 00:00:00 2001 From: Michael LeMay Date: Wed, 29 Jul 2015 07:00:54 -0700 Subject: [PATCH] x86: Add missing clobber list in interrupt.h The SET_INTERRUPT_HANDLER macro defines and registers an interrupt handler. It outputs a trampoline for the interrupt handler using a block of inline assembly, and the address of that trampoline is what is actually placed in the IDT. That trampoline invokes the main body of the interrupt handler. This patch adds a missing clobber list to the inline assembly block. It simply lists the caller-saved registers defined by the cdecl calling convention: EAX, ECX, and EDX. This is necessary, because the inline assembly block invokes idt_set_intr_gate_desc using a call instruction at the time the function containing the SET_INTERRUPT_HANDLER instance is executed. The idt_set_intr_gate_desc function is free to clobber EAX, ECX, and EDX according to cdecl. A Clang-generated implementation of idt_set_intr_gate_desc did in fact clobber those registers, resulting in incorrect operation of the code following an instance of SET_INTERRUPT_HANDLER. The change in this patch informs the compiler that those registers may be clobbered so that it can adjust the code that it outputs around the inline assembly block accordingly. --- cpu/x86/init/common/interrupt.h | 1 + 1 file changed, 1 insertion(+) diff --git a/cpu/x86/init/common/interrupt.h b/cpu/x86/init/common/interrupt.h index 3310dad02..498a766fc 100644 --- a/cpu/x86/init/common/interrupt.h +++ b/cpu/x86/init/common/interrupt.h @@ -92,6 +92,7 @@ struct interrupt_context { " iret\n\t" \ "skip_trampoline%=:\n\t" \ :: "g" (num), "i" (idt_set_intr_gate_desc), "i" (handler) \ + : "eax", "ecx", "edx" \ ); \ } while (0)