Skip to content

Commit

Permalink
x86/head/64: Move early exception dispatch to C code
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Joerg Roedel authored and Borislav Petkov committed Sep 7, 2020
1 parent 097ee5b commit 4b47cdb
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 16 deletions.
2 changes: 1 addition & 1 deletion arch/x86/include/asm/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 3 additions & 1 deletion arch/x86/include/asm/setup.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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);
Expand Down
19 changes: 15 additions & 4 deletions arch/x86/kernel/head64.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -384,10 +386,10 @@ int __init __early_make_pgtable(unsigned long address, pmdval_t pmd)
}
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;
Expand All @@ -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)
Expand Down
11 changes: 1 addition & 10 deletions arch/x86/kernel/head_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 4b47cdb

Please sign in to comment.