[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH for-4.7] x86/hvm: Correct emulation of invlpg instruction



`invlpg` and `invlpga` are specified to be NOPs when issued on non-canonical
addresses.

These instructions are not normally intercepted.  They are however intercepted
for HVM guests running in shadow paging mode.  AMD hardware lacking decode
hardware assistance uses the general instruction emulator to handle the
interception.

Alter hvmemul_invlpg() to swallow the #GP exception resulting from a
non-canonical address, rather than reporting it back to the guest.

Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
CC: Jan Beulich <JBeulich@xxxxxxxx>
CC: Wei Liu <wei.liu2@xxxxxxxxxx>

Note: Ideally this should be caught in the instruction emulator itself, but it
is the hvmemul_virtual_to_linear() which completes the memory calculation
including a possible non-zero %fs/%gs base.
---
 xen/arch/x86/hvm/emulate.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c
index cc0b841..897724e 100644
--- a/xen/arch/x86/hvm/emulate.c
+++ b/xen/arch/x86/hvm/emulate.c
@@ -1598,8 +1598,27 @@ static int hvmemul_invlpg(
     rc = hvmemul_virtual_to_linear(
         seg, offset, 1, &reps, hvm_access_none, hvmemul_ctxt, &addr);
 
-    if ( rc == X86EMUL_OKAY )
+    switch ( rc )
+    {
+    case X86EMUL_OKAY:
         hvm_funcs.invlpg_intercept(addr);
+        break;
+
+    case X86EMUL_EXCEPTION:
+        ASSERT(hvmemul_ctxt->trap.vector == TRAP_gp_fault);
+        /*
+         * `invlpg` and `invlpga` are specified to be NOPs when issued on a
+         * non-canonical address.  hvmemul_virtual_to_linear() latches a #GP
+         * which is the useful behaviour for most of its callers.
+         *
+         * Clear the pending exception to match avoid delivering a #GP fault
+         * to the guest.
+         */
+        hvmemul_ctxt->exn_pending = 0;
+        hvmemul_ctxt->trap = (struct hvm_trap){};
+        rc = X86EMUL_OKAY;
+        break;
+    }
 
     return rc;
 }
-- 
2.1.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.