x86/head/64: Install a CPU bringup IDT
authorJoerg Roedel <jroedel@suse.de>
Mon, 7 Sep 2020 13:15:34 +0000 (15:15 +0200)
committerBorislav Petkov <bp@suse.de>
Mon, 7 Sep 2020 20:18:38 +0000 (22:18 +0200)
commitf5963ba7a45fc6ff298a34976064354be437e1d8
tree3a390e287e24f87c73a2caf0e26970b84e7b1c82
parent3add38cb96a1ae7d152db69ab4329e809c2af2d4
x86/head/64: Install a CPU bringup IDT

Add a separate bringup IDT for the CPU bringup code that will be used
until the kernel switches to the idt_table. There are two reasons for a
separate IDT:

1) When the idt_table is set up and the secondary CPUs are
   booted, it contains entries (e.g. IST entries) which
   require certain CPU state to be set up. This includes a
   working TSS (for IST), MSR_GS_BASE (for stack protector) or
   CR4.FSGSBASE (for paranoid_entry) path. By using a
   dedicated IDT for early boot this state need not to be set
   up early.

2) The idt_table is static to idt.c, so any function
   using/modifying must be in idt.c too. That means that all
   compiler driven instrumentation like tracing or KASAN is
   also active in this code. But during early CPU bringup the
   environment is not set up for this instrumentation to work
   correctly.

To avoid all of these hassles and make early exception handling robust,
use a dedicated bringup IDT.

The IDT is loaded two times, first on the boot CPU while the kernel is
still running on direct mapped addresses, and again later after the
switch to kernel addresses has happened. The second IDT load happens on
the boot and secondary CPUs.

Signed-off-by: Joerg Roedel <jroedel@suse.de>
Signed-off-by: Borislav Petkov <bp@suse.de>
Link: https://lkml.kernel.org/r/20200907131613.12703-34-joro@8bytes.org
arch/x86/include/asm/setup.h
arch/x86/kernel/head64.c
arch/x86/kernel/head_64.S