Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 30 Aug 2014 18:35:16 +0000 (UTC)
From:      Neel Natu <neel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r270855 - head/usr.sbin/bhyve
Message-ID:  <201408301835.s7UIZGti084704@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201408301835.s7UIZGti084704>