x86/head/64: Move early exception dispatch to C code
authorJoerg Roedel <jroedel@suse.de>
Mon, 7 Sep 2020 13:15:36 +0000 (15:15 +0200)
committerBorislav Petkov <bp@suse.de>
Mon, 7 Sep 2020 20:49:18 +0000 (22:49 +0200)
Move the assembly coded dispatch between page-faults and all other
exceptions to C code to make it easier to maintain and extend.

Also change the return-type of early_make_pgtable() to bool and make it
static.

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

index b836138ce852308643173a738b3f3bee2a5474d7..7b8f2127de37f5dffc1c1c5b9aed62723da535fb 100644 (file)
@@ -28,7 +28,7 @@
 #include <asm-generic/pgtable_uffd.h>
 
 extern pgd_t early_top_pgt[PTRS_PER_PGD];
-int __init __early_make_pgtable(unsigned long address, pmdval_t pmd);
+bool __init __early_make_pgtable(unsigned long address, pmdval_t pmd);
 
 void ptdump_walk_pgd_level(struct seq_file *m, struct mm_struct *mm);
 void ptdump_walk_pgd_level_debugfs(struct seq_file *m, struct mm_struct *mm,
index 4b3ca5ade2fd41ee83a5612e8f51dd536a03aef2..7d7a064af6ff4d38237bdc6585a11f972f96dd22 100644 (file)
@@ -39,6 +39,8 @@ void vsmp_init(void);
 static inline void vsmp_init(void) { }
 #endif
 
+struct pt_regs;
+
 void setup_bios_corruption_check(void);
 void early_platform_quirks(void);
 
@@ -49,8 +51,8 @@ extern void i386_reserve_resources(void);
 extern unsigned long __startup_64(unsigned long physaddr, struct boot_params *bp);
 extern unsigned long __startup_secondary_64(void);
 extern void startup_64_setup_env(unsigned long physbase);
-extern int early_make_pgtable(unsigned long address);
 extern void early_setup_idt(void);
+extern void __init do_early_exception(struct pt_regs *regs, int trapnr);
 
 #ifdef CONFIG_X86_INTEL_MID
 extern void x86_intel_mid_early_setup(void);
index 7bfd5c27c7735ddf7831816868ef719b7d1fe194..4282dac694c383ff1d0ca3030e9cf0e89e4cb68e 100644 (file)
@@ -38,6 +38,8 @@
 #include <asm/fixmap.h>
 #include <asm/realmode.h>
 #include <asm/desc.h>
+#include <asm/extable.h>
+#include <asm/trapnr.h>
 
 /*
  * Manage page tables very early on.
@@ -317,7 +319,7 @@ static void __init reset_early_page_tables(void)
 }
 
 /* Create a new PMD entry */
-int __init __early_make_pgtable(unsigned long address, pmdval_t pmd)
+bool __init __early_make_pgtable(unsigned long address, pmdval_t pmd)
 {
        unsigned long physaddr = address - __PAGE_OFFSET;
        pgdval_t pgd, *pgd_p;
@@ -327,7 +329,7 @@ int __init __early_make_pgtable(unsigned long address, pmdval_t pmd)
 
        /* Invalid address or early pgt is done ?  */
        if (physaddr >= MAXMEM || read_cr3_pa() != __pa_nodebug(early_top_pgt))
-               return -1;
+               return false;
 
 again:
        pgd_p = &early_top_pgt[pgd_index(address)].pgd;
@@ -384,10 +386,10 @@ again:
        }
        pmd_p[pmd_index(address)] = pmd;
 
-       return 0;
+       return true;
 }
 
-int __init early_make_pgtable(unsigned long address)
+static bool __init early_make_pgtable(unsigned long address)
 {
        unsigned long physaddr = address - __PAGE_OFFSET;
        pmdval_t pmd;
@@ -397,6 +399,15 @@ int __init early_make_pgtable(unsigned long address)
        return __early_make_pgtable(address, pmd);
 }
 
+void __init do_early_exception(struct pt_regs *regs, int trapnr)
+{
+       if (trapnr == X86_TRAP_PF &&
+           early_make_pgtable(native_read_cr2()))
+               return;
+
+       early_fixup_exception(regs, trapnr);
+}
+
 /* Don't add a printk in there. printk relies on the PDA which is not initialized 
    yet. */
 static void __init clear_bss(void)
index 1de09b58e57848aee64a0b063145594901a74851..3b40ec44a67d786583c564bae01fccdc3d2f6446 100644 (file)
@@ -341,18 +341,9 @@ SYM_CODE_START_LOCAL(early_idt_handler_common)
        pushq %r15                              /* pt_regs->r15 */
        UNWIND_HINT_REGS
 
-       cmpq $14,%rsi           /* Page fault? */
-       jnz 10f
-       GET_CR2_INTO(%rdi)      /* can clobber %rax if pv */
-       call early_make_pgtable
-       andl %eax,%eax
-       jz 20f                  /* All good */
-
-10:
        movq %rsp,%rdi          /* RDI = pt_regs; RSI is already trapnr */
-       call early_fixup_exception
+       call do_early_exception
 
-20:
        decl early_recursion_flag(%rip)
        jmp restore_regs_and_return_to_kernel
 SYM_CODE_END(early_idt_handler_common)