Checks the hvm EFER.SVME bit to make sure the EFER.SVME bit it high before allowing nested SVM intercepts to be handled successfully. On SVME being low, it generates a #UD as per the AMD APM vol2 15.4.
Reported-by: Andrew Cooper <andrew.coop...@citrix.com> Signed-off-by: Brian Woods <brian.wo...@amd.com> --- xen/arch/x86/hvm/svm/svm.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index 2e62b9bb6d..2d0a82ae77 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -2587,6 +2587,35 @@ void svm_vmexit_handler(struct cpu_user_regs *regs) eventinj.fields.vector) ) vmcb->eventinj = eventinj; + /* + * Making sure SVME is enabled see AMD APM vol2 section 15.4 + * Nested Xen needs VMMCALL to boot. It hasn't set SVME by the time + * it uses it, therefore it isn't checked + */ + switch ( exit_reason ) + { + case VMEXIT_VMRUN: + case VMEXIT_VMLOAD: + case VMEXIT_VMSAVE: + case VMEXIT_CLGI: + case VMEXIT_INVLPGA: + if ( !(nestedhvm_enabled(v->domain) && + nsvm_efer_svm_enabled(v)) ) + { + gdprintk(XENLOG_ERR, "nestedhvm nested/SVME disabled, injecting #UD\n"); + hvm_inject_hw_exception(TRAP_invalid_op, X86_EVENT_NO_EC); + goto out; + } + case VMEXIT_STGI: + case VMEXIT_SKINIT: + if ( !nestedhvm_enabled(v->domain) ) + { + gdprintk(XENLOG_ERR, "nestedhvm nested disabled, injecting #UD\n"); + hvm_inject_hw_exception(TRAP_invalid_op, X86_EVENT_NO_EC); + goto out; + } + } + switch ( exit_reason ) { case VMEXIT_INTR: -- 2.11.0 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel