From a91b2ec337a45d5d98e5a4387aa6563bc5cdc4c9 Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Fri, 2 Feb 2018 16:10:17 +0000 Subject: [PATCH] x86/emul: Fix the emulation of invlpga The instruction requires EFER.SVME set to be usable in the first place. Furthermore, the emulation doesn't handle ASIDs, so avoid giving the impression that they work. Permit ASID 0 which is reserved for non-root mode (in which case the instruction is identical to invlpg), but raise #UD for any other ASID. Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich --- xen/arch/x86/x86_emulate/x86_emulate.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c index bc8fa1d1b1..d192280c4d 100644 --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -5120,8 +5120,15 @@ x86_emulate( break; case 0xdf: /* invlpga */ - generate_exception_if(!in_protmode(ctxt, ops), EXC_UD); + fail_if(!ops->read_msr); + if ( (rc = ops->read_msr(MSR_EFER, + &msr_val, ctxt)) != X86EMUL_OKAY ) + goto done; + /* Finding SVME set implies vcpu_has_svm(). */ + generate_exception_if(!(msr_val & EFER_SVME) || + !in_protmode(ctxt, ops), EXC_UD); generate_exception_if(!mode_ring0(), EXC_GP, 0); + generate_exception_if(_regs.ecx, EXC_UD); /* TODO: Support ASIDs. */ fail_if(ops->invlpg == NULL); if ( (rc = ops->invlpg(x86_seg_none, truncate_ea(_regs.r(ax)), ctxt)) ) -- 2.39.5