diff options
author | Joerg Roedel <jroedel@suse.de> | 2020-09-07 16:15:25 +0300 |
---|---|---|
committer | Borislav Petkov <bp@suse.de> | 2020-09-07 20:45:26 +0300 |
commit | 69add17a7c1992593a7cf775a66e0256ad4b3ef8 (patch) | |
tree | 74d7dd41c4f9fc80d5bfd12498b6ac6029d3bfd7 /arch/x86/boot/compressed/ident_map_64.c | |
parent | 597cfe48212a3f110ab0f918bf59791f453e65b7 (diff) | |
download | linux-69add17a7c1992593a7cf775a66e0256ad4b3ef8.tar.xz |
x86/boot/compressed/64: Unmap GHCB page before booting the kernel
Force a page-fault on any further accesses to the GHCB page when they
shouldn't happen anymore. This will catch any bugs where a #VC exception
is raised even though none is expected anymore.
Signed-off-by: Joerg Roedel <jroedel@suse.de>
Signed-off-by: Borislav Petkov <bp@suse.de>
Link: https://lkml.kernel.org/r/20200907131613.12703-25-joro@8bytes.org
Diffstat (limited to 'arch/x86/boot/compressed/ident_map_64.c')
-rw-r--r-- | arch/x86/boot/compressed/ident_map_64.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/arch/x86/boot/compressed/ident_map_64.c b/arch/x86/boot/compressed/ident_map_64.c index 05742f641a06..063a60edcf99 100644 --- a/arch/x86/boot/compressed/ident_map_64.c +++ b/arch/x86/boot/compressed/ident_map_64.c @@ -298,6 +298,11 @@ int set_page_encrypted(unsigned long address) return set_clr_page_flags(&mapping_info, address, _PAGE_ENC, 0); } +int set_page_non_present(unsigned long address) +{ + return set_clr_page_flags(&mapping_info, address, 0, _PAGE_PRESENT); +} + static void do_pf_error(const char *msg, unsigned long error_code, unsigned long address, unsigned long ip) { @@ -316,8 +321,14 @@ static void do_pf_error(const char *msg, unsigned long error_code, void do_boot_page_fault(struct pt_regs *regs, unsigned long error_code) { - unsigned long address = native_read_cr2() & PMD_MASK; - unsigned long end = address + PMD_SIZE; + unsigned long address = native_read_cr2(); + unsigned long end; + bool ghcb_fault; + + ghcb_fault = sev_es_check_ghcb_fault(address); + + address &= PMD_MASK; + end = address + PMD_SIZE; /* * Check for unexpected error codes. Unexpected are: @@ -327,6 +338,8 @@ void do_boot_page_fault(struct pt_regs *regs, unsigned long error_code) */ if (error_code & (X86_PF_PROT | X86_PF_USER | X86_PF_RSVD)) do_pf_error("Unexpected page-fault:", error_code, address, regs->ip); + else if (ghcb_fault) + do_pf_error("Page-fault on GHCB page:", error_code, address, regs->ip); /* * Error code is sane - now identity map the 2M region around |