Skip to content

Commit f6a9f8a

Browse files
joergroedelsuryasaimadhu
authored andcommitted
x86/paravirt: Allow hypervisor-specific VMMCALL handling under SEV-ES
Add two new paravirt callbacks to provide hypervisor-specific processor state in the GHCB and to copy state from the hypervisor back to the processor. Signed-off-by: Joerg Roedel <jroedel@suse.de> Signed-off-by: Borislav Petkov <bp@suse.de> Link: https://lkml.kernel.org/r/20200907131613.12703-63-joro@8bytes.org
1 parent cb1ad3e commit f6a9f8a

2 files changed

Lines changed: 27 additions & 1 deletion

File tree

arch/x86/include/asm/x86_init.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44

55
#include <asm/bootparam.h>
66

7+
struct ghcb;
78
struct mpc_bus;
89
struct mpc_cpu;
10+
struct pt_regs;
911
struct mpc_table;
1012
struct cpuinfo_x86;
1113

@@ -236,10 +238,22 @@ struct x86_legacy_features {
236238
/**
237239
* struct x86_hyper_runtime - x86 hypervisor specific runtime callbacks
238240
*
239-
* @pin_vcpu: pin current vcpu to specified physical cpu (run rarely)
241+
* @pin_vcpu: pin current vcpu to specified physical
242+
* cpu (run rarely)
243+
* @sev_es_hcall_prepare: Load additional hypervisor-specific
244+
* state into the GHCB when doing a VMMCALL under
245+
* SEV-ES. Called from the #VC exception handler.
246+
* @sev_es_hcall_finish: Copies state from the GHCB back into the
247+
* processor (or pt_regs). Also runs checks on the
248+
* state returned from the hypervisor after a
249+
* VMMCALL under SEV-ES. Needs to return 'false'
250+
* if the checks fail. Called from the #VC
251+
* exception handler.
240252
*/
241253
struct x86_hyper_runtime {
242254
void (*pin_vcpu)(int cpu);
255+
void (*sev_es_hcall_prepare)(struct ghcb *ghcb, struct pt_regs *regs);
256+
bool (*sev_es_hcall_finish)(struct ghcb *ghcb, struct pt_regs *regs);
243257
};
244258

245259
/**

arch/x86/kernel/sev-es.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -897,6 +897,9 @@ static enum es_result vc_handle_vmmcall(struct ghcb *ghcb,
897897
ghcb_set_rax(ghcb, ctxt->regs->ax);
898898
ghcb_set_cpl(ghcb, user_mode(ctxt->regs) ? 3 : 0);
899899

900+
if (x86_platform.hyper.sev_es_hcall_prepare)
901+
x86_platform.hyper.sev_es_hcall_prepare(ghcb, ctxt->regs);
902+
900903
ret = sev_es_ghcb_hv_call(ghcb, ctxt, SVM_EXIT_VMMCALL, 0, 0);
901904
if (ret != ES_OK)
902905
return ret;
@@ -906,6 +909,15 @@ static enum es_result vc_handle_vmmcall(struct ghcb *ghcb,
906909

907910
ctxt->regs->ax = ghcb->save.rax;
908911

912+
/*
913+
* Call sev_es_hcall_finish() after regs->ax is already set.
914+
* This allows the hypervisor handler to overwrite it again if
915+
* necessary.
916+
*/
917+
if (x86_platform.hyper.sev_es_hcall_finish &&
918+
!x86_platform.hyper.sev_es_hcall_finish(ghcb, ctxt->regs))
919+
return ES_VMM_ERROR;
920+
909921
return ES_OK;
910922
}
911923

0 commit comments

Comments
 (0)