Re: [REGRESSION]: x86/idt: Move early IDT setup out of 32-bit asm

From: Thomas Gleixner
Date: Mon Oct 16 2017 - 06:26:03 EST


Matthew,

On Sat, 14 Oct 2017, tedheadster wrote:

> I bisected a bug to commit 87e81786b13b267c4355e0d23e33c7e4c08fa63f.
> On first generation i486 processors it immediately resets the system
> after the "Booting the kernel" message.

Duh. Took me a while to understand whats going on. The patch below should
fix that issue.

Thanks,

tglx

8<------------------

Subject: x86/idt: Initialize early IDT before cr4_init_shadow()
From: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
Date: Mon, 16 Oct 2017 12:12:16 +0200

Moving the early IDT setup out of assembly code breaks the boot on first
generation 486 systems.

The reason is that the call to setup of these handlers was added after the
call to cr4_init_shadow().

cr4_init_shadow() tries to read CR4 which is not available on those
systems. The accessor function uses a extable fixup to handle the resulting
fault. As the IDT is not set up yet, the cr4 read exception causes an
instantaneous reboot for obvious reasons.

Call idt_setup_early_handler() before cr4_init_shadow() so IDT is set up
before the first exception hits.

Fixes: 87e81786b13b ("x86/idt: Move early IDT setup out of 32-bit asm")
Reported-by: Matthew Whitehead <whiteheadm@xxxxxxx>
Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx>

---
arch/x86/kernel/head32.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

--- a/arch/x86/kernel/head32.c
+++ b/arch/x86/kernel/head32.c
@@ -30,10 +30,11 @@ static void __init i386_default_early_se

asmlinkage __visible void __init i386_start_kernel(void)
{
- cr4_init_shadow();
-
+ /* Make sure IDT is set up before any exception happens */
idt_setup_early_handler();

+ cr4_init_shadow();
+
sanitize_boot_params(&boot_params);

x86_early_init_platform_quirks();