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>