Message ID | 20200211135256.24617-51-joro@8bytes.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Linux as SEV-ES Guest Support | expand |
> On Feb 11, 2020, at 5:53 AM, Joerg Roedel <joro@8bytes.org> wrote: > > From: Tom Lendacky <thomas.lendacky@amd.com> > > Implement a handler for #VC exceptions caused by VMMCALL instructions. > This patch is only a starting point, VMMCALL emulation under SEV-ES > needs further hypervisor-specific changes to provide additional state. > How about we just don’t do VMMCALL if we’re a SEV-ES guest? Otherwise we add thousands of cycles of extra latency for no good reason.
On Tue, Feb 11, 2020 at 04:14:53PM -0800, Andy Lutomirski wrote: > > How about we just don’t do VMMCALL if we’re a SEV-ES guest? Otherwise > we add thousands of cycles of extra latency for no good reason. True, but I left that as a future optimization for now, given the size the patch-set already has. The idea is to add an abstraction around VMMCALL for the support code of the various hypervisors and just do a VMGEXIT in that wrapper when in an SEV-ES guest. But again, that is a separate patch-set. Regards, Joerg
diff --git a/arch/x86/kernel/sev-es.c b/arch/x86/kernel/sev-es.c index 8f1e84da6fa6..6bd2cae7eb9c 100644 --- a/arch/x86/kernel/sev-es.c +++ b/arch/x86/kernel/sev-es.c @@ -341,6 +341,26 @@ static enum es_result handle_mwait(struct ghcb *ghcb, struct es_em_ctxt *ctxt) return ghcb_hv_call(ghcb, ctxt, SVM_EXIT_MWAIT, 0, 0); } +static enum es_result handle_vmmcall(struct ghcb *ghcb, + struct es_em_ctxt *ctxt) +{ + enum es_result ret; + + ghcb_set_rax(ghcb, ctxt->regs->ax); + ghcb_set_cpl(ghcb, user_mode(ctxt->regs) ? 3 : 0); + + ret = ghcb_hv_call(ghcb, ctxt, SVM_EXIT_VMMCALL, 0, 0); + if (ret != ES_OK) + return ret; + + if (!ghcb_is_valid_rax(ghcb)) + return ES_VMM_ERROR; + + ctxt->regs->ax = ghcb->save.rax; + + return ES_OK; +} + static enum es_result handle_vc_exception(struct es_em_ctxt *ctxt, struct ghcb *ghcb, unsigned long exit_code, @@ -374,6 +394,9 @@ static enum es_result handle_vc_exception(struct es_em_ctxt *ctxt, case SVM_EXIT_MSR: result = handle_msr(ghcb, ctxt); break; + case SVM_EXIT_VMMCALL: + result = handle_vmmcall(ghcb, ctxt); + break; case SVM_EXIT_WBINVD: result = handle_wbinvd(ghcb, ctxt); break;