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 <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
Andrew Cooper committed 2018-02-05 18:17:22 +00:00
1 parent d28953581b
commit a91b2ec337
1 file changed
+8 -1
+8 -1
View File
@@ -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)) )
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.