Author: neel
Date: Sat Aug 30 18:35:16 2014
New Revision: 270855
URL: http://svnweb.freebsd.org/changeset/base/270855

Log:
  Set the 'inst_length' to '0' early on before any error conditions are detected
  in the emulation of the task switch. If any exceptions are triggered then the
  guest %rip should point to instruction that caused the task switch as opposed
  to the one after it.

Modified:
  head/usr.sbin/bhyve/task_switch.c

Modified: head/usr.sbin/bhyve/task_switch.c
==============================================================================
--- head/usr.sbin/bhyve/task_switch.c   Sat Aug 30 18:01:45 2014        
(r270854)
+++ head/usr.sbin/bhyve/task_switch.c   Sat Aug 30 18:35:16 2014        
(r270855)
@@ -725,6 +725,21 @@ vmexit_task_switch(struct vmctx *ctx, st
        assert(paging->cpu_mode == CPU_MODE_PROTECTED);
 
        /*
+        * Calculate the %eip to store in the old TSS before modifying the
+        * 'inst_length'.
+        */
+       eip = vmexit->rip + vmexit->inst_length;
+
+       /*
+        * Set the 'inst_length' to '0'.
+        *
+        * If an exception is triggered during emulation of the task switch
+        * then the exception handler should return to the instruction that
+        * caused the task switch as opposed to the subsequent instruction.
+        */
+       vmexit->inst_length = 0;
+
+       /*
         * Section 4.6, "Access Rights" in Intel SDM Vol 3.
         * The following page table accesses are implicitly supervisor mode:
         * - accesses to GDT or LDT to load segment descriptors
@@ -839,7 +854,6 @@ vmexit_task_switch(struct vmctx *ctx, st
        }
 
        /* Save processor state in old TSS */
-       eip = vmexit->rip + vmexit->inst_length;
        tss32_save(ctx, vcpu, task_switch, eip, &oldtss, ot_iov);
 
        /*
@@ -870,7 +884,7 @@ vmexit_task_switch(struct vmctx *ctx, st
         * the saved instruction pointer will belong to the new task.
         */
        vmexit->rip = newtss.tss_eip;
-       vmexit->inst_length = 0;
+       assert(vmexit->inst_length == 0);
 
        /* Load processor state from new TSS */
        error = tss32_restore(ctx, vcpu, task_switch, ot_sel, &newtss, nt_iov);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to