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

[Xen-changelog] [xen master] x86/hvm: Correct the emulated interaction of invlpg with segments



commit a373db28eaa1e9011db00cc6359b8ee1112c80e0
Author:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
AuthorDate: Fri Apr 22 09:44:53 2016 +0100
Commit:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Tue May 10 18:08:55 2016 +0100

    x86/hvm: Correct the emulated interaction of invlpg with segments
    
    The `invlpg` instruction is documented to take a memory address, and is not
    documented to suffer faults from segmentation violations.  It is also
    explicitly documented to be a NOP when issued on a non-canonical address.
    
    Experimentally, and subsequently confirmed by both Intel and AMD, the
    instruction does take into account segment bases, but will happily 
invalidate
    a TLB entry for a mapping beyond the segment limit.
    
    The emulation logic will currently raise #GP/#SS faults for segment limit
    violations, or non-canonical addresses, which doesn't match hardware's
    behaviour.  Instead, squash exceptions generated by
    hvmemul_virtual_to_linear() and proceed with invalidation.
    
    Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
    Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
    Reviewed-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
    Release-acked-by: Wei Liu <wei.liu2@xxxxxxxxxx>
---
 xen/arch/x86/hvm/emulate.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c
index ee5cf1f..e6316be 100644
--- a/xen/arch/x86/hvm/emulate.c
+++ b/xen/arch/x86/hvm/emulate.c
@@ -1608,7 +1608,22 @@ static int hvmemul_invlpg(
     rc = hvmemul_virtual_to_linear(
         seg, offset, 1, &reps, hvm_access_none, hvmemul_ctxt, &addr);
 
-    if ( rc == X86EMUL_OKAY )
+    if ( rc == X86EMUL_EXCEPTION )
+    {
+        /*
+         * `invlpg` takes segment bases into account, but is not subject to
+         * faults from segment type/limit checks, and is specified as a NOP
+         * when issued on non-canonical addresses.
+         *
+         * hvmemul_virtual_to_linear() raises exceptions for type/limit
+         * violations, so squash them.
+         */
+        hvmemul_ctxt->exn_pending = 0;
+        hvmemul_ctxt->trap = (struct hvm_trap){};
+        rc = X86EMUL_OKAY;
+    }
+
+    if ( rc == X86EMUL_OKAY && is_canonical_address(addr) )
         hvm_funcs.invlpg_intercept(addr);
 
     return rc;
--
generated by git-patchbot for /home/xen/git/xen.git#master

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

 


Rackspace

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