diff options
author | Joerg Roedel <jroedel@suse.de> | 2020-09-07 16:16:11 +0300 |
---|---|---|
committer | Borislav Petkov <bp@suse.de> | 2020-09-09 19:02:35 +0300 |
commit | 4ca68e023b11e4d5908bf9ee326fab01111d77d5 (patch) | |
tree | 874f57bbc6627e3f64668d2845051e1ea03cc15f /arch/x86/kernel/sev-es.c | |
parent | 094794f59720d7e877a1eeb372ecedeed6b441ab (diff) | |
download | linux-4ca68e023b11e4d5908bf9ee326fab01111d77d5.tar.xz |
x86/sev-es: Handle NMI State
When running under SEV-ES, the kernel has to tell the hypervisor when to
open the NMI window again after an NMI was injected. This is done with
an NMI-complete message to the hypervisor.
Add code to the kernel's NMI handler to send this message right at the
beginning of do_nmi(). This always allows nesting NMIs.
[ bp: Mark __sev_es_nmi_complete() noinstr:
vmlinux.o: warning: objtool: exc_nmi()+0x17: call to __sev_es_nmi_complete()
leaves .noinstr.text section
While at it, use __pa_nodebug() for the same reason due to
CONFIG_DEBUG_VIRTUAL=y:
vmlinux.o: warning: objtool: __sev_es_nmi_complete()+0xd9: call to __phys_addr()
leaves .noinstr.text section ]
Signed-off-by: Joerg Roedel <jroedel@suse.de>
Signed-off-by: Borislav Petkov <bp@suse.de>
Link: https://lkml.kernel.org/r/20200907131613.12703-71-joro@8bytes.org
Diffstat (limited to 'arch/x86/kernel/sev-es.c')
-rw-r--r-- | arch/x86/kernel/sev-es.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/arch/x86/kernel/sev-es.c b/arch/x86/kernel/sev-es.c index d1bcd0dca583..b6518e96dedb 100644 --- a/arch/x86/kernel/sev-es.c +++ b/arch/x86/kernel/sev-es.c @@ -408,6 +408,24 @@ static bool vc_slow_virt_to_phys(struct ghcb *ghcb, struct es_em_ctxt *ctxt, /* Include code shared with pre-decompression boot stage */ #include "sev-es-shared.c" +void noinstr __sev_es_nmi_complete(void) +{ + struct ghcb_state state; + struct ghcb *ghcb; + + ghcb = sev_es_get_ghcb(&state); + + vc_ghcb_invalidate(ghcb); + ghcb_set_sw_exit_code(ghcb, SVM_VMGEXIT_NMI_COMPLETE); + ghcb_set_sw_exit_info_1(ghcb, 0); + ghcb_set_sw_exit_info_2(ghcb, 0); + + sev_es_wr_ghcb_msr(__pa_nodebug(ghcb)); + VMGEXIT(); + + sev_es_put_ghcb(&state); +} + static u64 get_jump_table_addr(void) { struct ghcb_state state; |