[U-Boot] [PATCH] x86: Force 32-bit jumps in interrupt handlers

Depending upon the compiler used, IRQ entries could vary in sizes. With GCC 5.x, the code generator will use short jumps for some IRQ entries but near jumps for others. For example, GCC 5.4.0 generates the following:
$ objdump -d interrupt.o <snip> 00000207 <irq_18>: 207: 6a 12 push $0x12 209: eb 85 jmp 190 <irq_common_entry>
0000020b <irq_19>: 20b: 6a 13 push $0x13 20d: eb 81 jmp 190 <irq_common_entry>
0000020f <irq_20>: 20f: 6a 14 push $0x14 211: e9 7a ff ff ff jmp 190 <irq_common_entry>
00000216 <irq_21>: 216: 6a 15 push $0x15 218: e9 73 ff ff ff jmp 190 <irq_common_entry>
This causes a problem in cpu_init_interrupts(), because the IDT setup assumed same sizes for all IRQ entries. GCC 4.x always generated 32-bit jumps, so this previously was not a problem.
The fix is to force 32-bit near jumps for all entries within the inline assembly. This works for GCC 5.x, and 4.x was already using that form of jumping.
Signed-off-by: Jason Tang tang@jtang.org --- arch/x86/cpu/i386/interrupt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/cpu/i386/interrupt.c b/arch/x86/cpu/i386/interrupt.c index a058303..ba576fe 100644 --- a/arch/x86/cpu/i386/interrupt.c +++ b/arch/x86/cpu/i386/interrupt.c @@ -28,7 +28,7 @@ DECLARE_GLOBAL_DATA_PTR; ".type irq_"#x", @function\n" \ "irq_"#x":\n" \ "pushl $"#x"\n" \ - "jmp irq_common_entry\n" + "jmp.d32 irq_common_entry\n"
static char *exceptions[] = { "Divide Error",

On Fri, Feb 10, 2017 at 10:54 AM, J. Tang tang@jtang.org wrote:
Depending upon the compiler used, IRQ entries could vary in sizes. With GCC 5.x, the code generator will use short jumps for some IRQ entries but near jumps for others. For example, GCC 5.4.0 generates the following:
$ objdump -d interrupt.o
<snip> 00000207 <irq_18>: 207: 6a 12 push $0x12 209: eb 85 jmp 190 <irq_common_entry>
0000020b <irq_19>: 20b: 6a 13 push $0x13 20d: eb 81 jmp 190 <irq_common_entry>
0000020f <irq_20>: 20f: 6a 14 push $0x14 211: e9 7a ff ff ff jmp 190 <irq_common_entry>
00000216 <irq_21>: 216: 6a 15 push $0x15 218: e9 73 ff ff ff jmp 190 <irq_common_entry>
This causes a problem in cpu_init_interrupts(), because the IDT setup assumed same sizes for all IRQ entries. GCC 4.x always generated 32-bit jumps, so this previously was not a problem.
The fix is to force 32-bit near jumps for all entries within the inline assembly. This works for GCC 5.x, and 4.x was already using that form of jumping.
Signed-off-by: Jason Tang tang@jtang.org
arch/x86/cpu/i386/interrupt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com

On Fri, Feb 10, 2017 at 11:46 AM, Bin Meng bmeng.cn@gmail.com wrote:
On Fri, Feb 10, 2017 at 10:54 AM, J. Tang tang@jtang.org wrote:
Depending upon the compiler used, IRQ entries could vary in sizes. With GCC 5.x, the code generator will use short jumps for some IRQ entries but near jumps for others. For example, GCC 5.4.0 generates the following:
$ objdump -d interrupt.o
<snip> 00000207 <irq_18>: 207: 6a 12 push $0x12 209: eb 85 jmp 190 <irq_common_entry>
0000020b <irq_19>: 20b: 6a 13 push $0x13 20d: eb 81 jmp 190 <irq_common_entry>
0000020f <irq_20>: 20f: 6a 14 push $0x14 211: e9 7a ff ff ff jmp 190 <irq_common_entry>
00000216 <irq_21>: 216: 6a 15 push $0x15 218: e9 73 ff ff ff jmp 190 <irq_common_entry>
This causes a problem in cpu_init_interrupts(), because the IDT setup assumed same sizes for all IRQ entries. GCC 4.x always generated 32-bit jumps, so this previously was not a problem.
The fix is to force 32-bit near jumps for all entries within the inline assembly. This works for GCC 5.x, and 4.x was already using that form of jumping.
Signed-off-by: Jason Tang tang@jtang.org
arch/x86/cpu/i386/interrupt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com
applied to u-boot-x86, thanks!
participants (2)
-
Bin Meng
-
J. Tang