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

[xen stable-4.13] x86emul: fix SYSENTER/SYSCALL switching into 64-bit mode



commit ac4955c74b2dd8cc81d455c424f680041180c063
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Fri Mar 5 15:45:54 2021 +0100
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Fri Mar 5 15:45:54 2021 +0100

    x86emul: fix SYSENTER/SYSCALL switching into 64-bit mode
    
    When invoked by compat mode, mode_64bit() will be false at the start of
    emulation. The logic after complete_insn, however, needs to consider the
    mode switched into, in particular to avoid truncating RIP.
    
    Inspired by / paralleling and extending Linux commit 943dea8af21b ("KVM:
    x86: Update emulator context mode if SYSENTER xfers to 64-bit mode").
    
    While there, tighten a related assertion in x86_emulate_wrapper() - we
    want to be sure to not switch into an impossible mode when the code gets
    built for 32-bit only (as is possible for the test harness).
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxxx>
    master commit: f3e1eb2f0234c955243a915d69ebd84f26eec130
    master date: 2021-02-11 17:53:10 +0100
---
 xen/arch/x86/x86_emulate/x86_emulate.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c 
b/xen/arch/x86/x86_emulate/x86_emulate.c
index a6f67c6a56..a4e0341b25 100644
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -5926,6 +5926,10 @@ x86_emulate(
              (rc = ops->write_segment(x86_seg_ss, &sreg, ctxt)) )
             goto done;
 
+        if ( ctxt->lma )
+            /* In particular mode_64bit() needs to return true from here on. */
+            ctxt->addr_size = ctxt->sp_size = 64;
+
         /*
          * SYSCALL (unlike most instructions) evaluates its singlestep action
          * based on the resulting EFLAGS.TF, not the starting EFLAGS.TF.
@@ -6595,6 +6599,10 @@ x86_emulate(
             goto done;
         _regs.r(sp) = ctxt->lma ? msr_val : (uint32_t)msr_val;
 
+        if ( ctxt->lma )
+            /* In particular mode_64bit() needs to return true from here on. */
+            ctxt->addr_size = ctxt->sp_size = 64;
+
         singlestep = _regs.eflags & X86_EFLAGS_TF;
         break;
 
@@ -11195,8 +11203,12 @@ int x86_emulate_wrapper(
     unsigned long orig_ip = ctxt->regs->r(ip);
     int rc;
 
+#ifdef __x86_64__
     if ( mode_64bit() )
         ASSERT(ctxt->lma);
+#else
+    ASSERT(!ctxt->lma && !mode_64bit());
+#endif
 
     rc = x86_emulate(ctxt, ops);
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13



 


Rackspace

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