mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-15 08:14:15 +08:00
x86/boot/compressed/64: Add IDT Infrastructure
Add code needed to setup an IDT in the early pre-decompression boot-code. The IDT is loaded first in startup_64, which is after EfiExitBootServices() has been called, and later reloaded when the kernel image has been relocated to the end of the decompression area. This allows to setup different IDT handlers before and after the relocation. Signed-off-by: Joerg Roedel <jroedel@suse.de> Signed-off-by: Borislav Petkov <bp@suse.de> Link: https://lkml.kernel.org/r/20200907131613.12703-14-joro@8bytes.org
This commit is contained in:
parent
6ba0efa460
commit
64e682638e
@ -85,6 +85,7 @@ vmlinux-objs-$(CONFIG_EARLY_PRINTK) += $(obj)/early_serial_console.o
|
||||
vmlinux-objs-$(CONFIG_RANDOMIZE_BASE) += $(obj)/kaslr.o
|
||||
ifdef CONFIG_X86_64
|
||||
vmlinux-objs-$(CONFIG_RANDOMIZE_BASE) += $(obj)/kaslr_64.o
|
||||
vmlinux-objs-y += $(obj)/idt_64.o $(obj)/idt_handlers_64.o
|
||||
vmlinux-objs-y += $(obj)/mem_encrypt.o
|
||||
vmlinux-objs-y += $(obj)/pgtable_64.o
|
||||
endif
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <asm/processor-flags.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/bootparam.h>
|
||||
#include <asm/desc_defs.h>
|
||||
#include "pgtable.h"
|
||||
|
||||
/*
|
||||
@ -410,6 +411,10 @@ SYM_CODE_START(startup_64)
|
||||
|
||||
.Lon_kernel_cs:
|
||||
|
||||
pushq %rsi
|
||||
call load_stage1_idt
|
||||
popq %rsi
|
||||
|
||||
/*
|
||||
* paging_prepare() sets up the trampoline and checks if we need to
|
||||
* enable 5-level paging.
|
||||
@ -537,6 +542,13 @@ SYM_FUNC_START_LOCAL_NOALIGN(.Lrelocated)
|
||||
shrq $3, %rcx
|
||||
rep stosq
|
||||
|
||||
/*
|
||||
* Load stage2 IDT
|
||||
*/
|
||||
pushq %rsi
|
||||
call load_stage2_idt
|
||||
popq %rsi
|
||||
|
||||
/*
|
||||
* Do the extraction, and jump to the new kernel..
|
||||
*/
|
||||
@ -690,10 +702,21 @@ SYM_DATA_START_LOCAL(gdt)
|
||||
.quad 0x0000000000000000 /* TS continued */
|
||||
SYM_DATA_END_LABEL(gdt, SYM_L_LOCAL, gdt_end)
|
||||
|
||||
SYM_DATA_START(boot_idt_desc)
|
||||
.word boot_idt_end - boot_idt - 1
|
||||
.quad 0
|
||||
SYM_DATA_END(boot_idt_desc)
|
||||
.balign 8
|
||||
SYM_DATA_START(boot_idt)
|
||||
.rept BOOT_IDT_ENTRIES
|
||||
.quad 0
|
||||
.quad 0
|
||||
.endr
|
||||
SYM_DATA_END_LABEL(boot_idt, SYM_L_GLOBAL, boot_idt_end)
|
||||
|
||||
#ifdef CONFIG_EFI_STUB
|
||||
SYM_DATA(image_offset, .long 0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_EFI_MIXED
|
||||
SYM_DATA_LOCAL(efi32_boot_args, .long 0, 0, 0)
|
||||
SYM_DATA(efi_is64, .byte 1)
|
||||
|
44
arch/x86/boot/compressed/idt_64.c
Normal file
44
arch/x86/boot/compressed/idt_64.c
Normal file
@ -0,0 +1,44 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
#include <asm/trap_pf.h>
|
||||
#include <asm/segment.h>
|
||||
#include <asm/trapnr.h>
|
||||
#include "misc.h"
|
||||
|
||||
static void set_idt_entry(int vector, void (*handler)(void))
|
||||
{
|
||||
unsigned long address = (unsigned long)handler;
|
||||
gate_desc entry;
|
||||
|
||||
memset(&entry, 0, sizeof(entry));
|
||||
|
||||
entry.offset_low = (u16)(address & 0xffff);
|
||||
entry.segment = __KERNEL_CS;
|
||||
entry.bits.type = GATE_TRAP;
|
||||
entry.bits.p = 1;
|
||||
entry.offset_middle = (u16)((address >> 16) & 0xffff);
|
||||
entry.offset_high = (u32)(address >> 32);
|
||||
|
||||
memcpy(&boot_idt[vector], &entry, sizeof(entry));
|
||||
}
|
||||
|
||||
/* Have this here so we don't need to include <asm/desc.h> */
|
||||
static void load_boot_idt(const struct desc_ptr *dtr)
|
||||
{
|
||||
asm volatile("lidt %0"::"m" (*dtr));
|
||||
}
|
||||
|
||||
/* Setup IDT before kernel jumping to .Lrelocated */
|
||||
void load_stage1_idt(void)
|
||||
{
|
||||
boot_idt_desc.address = (unsigned long)boot_idt;
|
||||
|
||||
load_boot_idt(&boot_idt_desc);
|
||||
}
|
||||
|
||||
/* Setup IDT after kernel jumping to .Lrelocated */
|
||||
void load_stage2_idt(void)
|
||||
{
|
||||
boot_idt_desc.address = (unsigned long)boot_idt;
|
||||
|
||||
load_boot_idt(&boot_idt_desc);
|
||||
}
|
70
arch/x86/boot/compressed/idt_handlers_64.S
Normal file
70
arch/x86/boot/compressed/idt_handlers_64.S
Normal file
@ -0,0 +1,70 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Early IDT handler entry points
|
||||
*
|
||||
* Copyright (C) 2019 SUSE
|
||||
*
|
||||
* Author: Joerg Roedel <jroedel@suse.de>
|
||||
*/
|
||||
|
||||
#include <asm/segment.h>
|
||||
|
||||
/* For ORIG_RAX */
|
||||
#include "../../entry/calling.h"
|
||||
|
||||
.macro EXCEPTION_HANDLER name function error_code=0
|
||||
SYM_FUNC_START(\name)
|
||||
|
||||
/* Build pt_regs */
|
||||
.if \error_code == 0
|
||||
pushq $0
|
||||
.endif
|
||||
|
||||
pushq %rdi
|
||||
pushq %rsi
|
||||
pushq %rdx
|
||||
pushq %rcx
|
||||
pushq %rax
|
||||
pushq %r8
|
||||
pushq %r9
|
||||
pushq %r10
|
||||
pushq %r11
|
||||
pushq %rbx
|
||||
pushq %rbp
|
||||
pushq %r12
|
||||
pushq %r13
|
||||
pushq %r14
|
||||
pushq %r15
|
||||
|
||||
/* Call handler with pt_regs */
|
||||
movq %rsp, %rdi
|
||||
/* Error code is second parameter */
|
||||
movq ORIG_RAX(%rsp), %rsi
|
||||
call \function
|
||||
|
||||
/* Restore regs */
|
||||
popq %r15
|
||||
popq %r14
|
||||
popq %r13
|
||||
popq %r12
|
||||
popq %rbp
|
||||
popq %rbx
|
||||
popq %r11
|
||||
popq %r10
|
||||
popq %r9
|
||||
popq %r8
|
||||
popq %rax
|
||||
popq %rcx
|
||||
popq %rdx
|
||||
popq %rsi
|
||||
popq %rdi
|
||||
|
||||
/* Remove error code and return */
|
||||
addq $8, %rsp
|
||||
|
||||
iretq
|
||||
SYM_FUNC_END(\name)
|
||||
.endm
|
||||
|
||||
.text
|
||||
.code64
|
@ -23,6 +23,7 @@
|
||||
#include <asm/page.h>
|
||||
#include <asm/boot.h>
|
||||
#include <asm/bootparam.h>
|
||||
#include <asm/desc_defs.h>
|
||||
|
||||
#define BOOT_CTYPE_H
|
||||
#include <linux/acpi.h>
|
||||
@ -133,4 +134,8 @@ int count_immovable_mem_regions(void);
|
||||
static inline int count_immovable_mem_regions(void) { return 0; }
|
||||
#endif
|
||||
|
||||
/* idt_64.c */
|
||||
extern gate_desc boot_idt[BOOT_IDT_ENTRIES];
|
||||
extern struct desc_ptr boot_idt_desc;
|
||||
|
||||
#endif /* BOOT_COMPRESSED_MISC_H */
|
||||
|
@ -109,6 +109,9 @@ struct desc_ptr {
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
/* Boot IDT definitions */
|
||||
#define BOOT_IDT_ENTRIES 32
|
||||
|
||||
/* Access rights as returned by LAR */
|
||||
#define AR_TYPE_RODATA (0 * (1 << 9))
|
||||
#define AR_TYPE_RWDATA (1 * (1 << 9))
|
||||
|
Loading…
Reference in New Issue
Block a user