x86/sev-es: Setup an early #VC handler
Setup an early handler for #VC exceptions. There is no GHCB mapped yet, so just re-use the vc_no_ghcb_handler(). It can only handle CPUID exit-codes, but that should be enough to get the kernel through verify_cpu() and __startup_64() until it runs on virtual addresses. Signed-off-by: Joerg Roedel <jroedel@suse.de> Signed-off-by: Borislav Petkov <bp@suse.de> [ boot failure Error: kernel_ident_mapping_init() failed. ] Reported-by: kernel test robot <lkp@intel.com> Link: https://lkml.kernel.org/r/20200908123517.GA3764@8bytes.org
This commit is contained in:
parent
f980f9c31a
commit
74d8d9d531
@ -73,4 +73,7 @@ static inline u64 lower_bits(u64 val, unsigned int bits)
|
||||
return (val & mask);
|
||||
}
|
||||
|
||||
/* Early IDT entry points for #VC handler */
|
||||
extern void vc_no_ghcb(void);
|
||||
|
||||
#endif
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include <asm/desc.h>
|
||||
#include <asm/extable.h>
|
||||
#include <asm/trapnr.h>
|
||||
#include <asm/sev-es.h>
|
||||
|
||||
/*
|
||||
* Manage page tables very early on.
|
||||
@ -540,12 +541,34 @@ static struct desc_ptr bringup_idt_descr = {
|
||||
.address = 0, /* Set at runtime */
|
||||
};
|
||||
|
||||
static void set_bringup_idt_handler(gate_desc *idt, int n, void *handler)
|
||||
{
|
||||
#ifdef CONFIG_AMD_MEM_ENCRYPT
|
||||
struct idt_data data;
|
||||
gate_desc desc;
|
||||
|
||||
init_idt_data(&data, n, handler);
|
||||
idt_init_desc(&desc, &data);
|
||||
native_write_idt_entry(idt, n, &desc);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* This runs while still in the direct mapping */
|
||||
static void startup_64_load_idt(unsigned long physbase)
|
||||
{
|
||||
struct desc_ptr *desc = fixup_pointer(&bringup_idt_descr, physbase);
|
||||
gate_desc *idt = fixup_pointer(bringup_idt_table, physbase);
|
||||
|
||||
desc->address = (unsigned long)fixup_pointer(bringup_idt_table, physbase);
|
||||
|
||||
if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT)) {
|
||||
void *handler;
|
||||
|
||||
/* VMM Communication Exception */
|
||||
handler = fixup_pointer(vc_no_ghcb, physbase);
|
||||
set_bringup_idt_handler(idt, X86_TRAP_VC, handler);
|
||||
}
|
||||
|
||||
desc->address = (unsigned long)idt;
|
||||
native_load_idt(desc);
|
||||
}
|
||||
|
||||
|
@ -348,6 +348,36 @@ SYM_CODE_START_LOCAL(early_idt_handler_common)
|
||||
jmp restore_regs_and_return_to_kernel
|
||||
SYM_CODE_END(early_idt_handler_common)
|
||||
|
||||
#ifdef CONFIG_AMD_MEM_ENCRYPT
|
||||
/*
|
||||
* VC Exception handler used during very early boot. The
|
||||
* early_idt_handler_array can't be used because it returns via the
|
||||
* paravirtualized INTERRUPT_RETURN and pv-ops don't work that early.
|
||||
*
|
||||
* This handler will end up in the .init.text section and not be
|
||||
* available to boot secondary CPUs.
|
||||
*/
|
||||
SYM_CODE_START_NOALIGN(vc_no_ghcb)
|
||||
UNWIND_HINT_IRET_REGS offset=8
|
||||
|
||||
/* Build pt_regs */
|
||||
PUSH_AND_CLEAR_REGS
|
||||
|
||||
/* Call C handler */
|
||||
movq %rsp, %rdi
|
||||
movq ORIG_RAX(%rsp), %rsi
|
||||
call do_vc_no_ghcb
|
||||
|
||||
/* Unwind pt_regs */
|
||||
POP_REGS
|
||||
|
||||
/* Remove Error Code */
|
||||
addq $8, %rsp
|
||||
|
||||
/* Pure iret required here - don't use INTERRUPT_RETURN */
|
||||
iretq
|
||||
SYM_CODE_END(vc_no_ghcb)
|
||||
#endif
|
||||
|
||||
#define SYM_DATA_START_PAGE_ALIGNED(name) \
|
||||
SYM_START(name, SYM_L_GLOBAL, .balign PAGE_SIZE)
|
||||
|
Loading…
x
Reference in New Issue
Block a user