svn commit: r305612 - head/sys/i386/i386

Bruce Evans bde at FreeBSD.org
Thu Sep 8 14:43:40 UTC 2016


Author: bde
Date: Thu Sep  8 14:43:39 2016
New Revision: 305612
URL: https://svnweb.freebsd.org/changeset/base/305612

Log:
  Fix single-stepping of instructions emulated by vm86.
  
  In vm86.c, fix 2 (rarely used) cases where the return code lost the
  single-step indicator.  While here, fix 2 misspellings of PSL_T as
  PSL_TF (TF is the CPU manufacturer's spelling, but we use T).
  
  In trap.c, turn T_PROTFLT and T_STKFLT into T_TRCTRAP if
  vm86_emulate() asked for this (it does this when the instruction is
  being traced and was successully emulated).  In the kernel case, we
  used to deliver the trap as SIGTRAP to the process, where it always
  terminated the process; now we deliver the trap as T_TRCTRAP to kdb,
  where it normally gives single-stepping.  In the user case, the only
  difference is that we now clear PSL_T and initialize ucode properly.
  
  Reviewed by:	kib

Modified:
  head/sys/i386/i386/trap.c
  head/sys/i386/i386/vm86.c

Modified: head/sys/i386/i386/trap.c
==============================================================================
--- head/sys/i386/i386/trap.c	Thu Sep  8 14:04:04 2016	(r305611)
+++ head/sys/i386/i386/trap.c	Thu Sep  8 14:43:39 2016	(r305612)
@@ -335,6 +335,7 @@ trap(struct trapframe *frame)
 					goto out;
 			}
 #endif
+user_trctrap_out:
 			frame->tf_eflags &= ~PSL_T;
 			i = SIGTRAP;
 			ucode = (type == T_TRCTRAP ? TRAP_TRACE : TRAP_BRKPT);
@@ -360,6 +361,10 @@ trap(struct trapframe *frame)
 		case T_STKFLT:		/* stack fault */
 			if (frame->tf_eflags & PSL_VM) {
 				i = vm86_emulate((struct vm86frame *)frame);
+				if (i == SIGTRAP) {
+					type = T_TRCTRAP;
+					goto user_trctrap_out;
+				}
 				if (i == 0)
 					goto user;
 				break;
@@ -566,6 +571,10 @@ trap(struct trapframe *frame)
 		case T_STKFLT:		/* stack fault */
 			if (frame->tf_eflags & PSL_VM) {
 				i = vm86_emulate((struct vm86frame *)frame);
+				if (i == SIGTRAP) {
+					type = T_TRCTRAP;
+					goto kernel_trctrap;
+				}
 				if (i != 0)
 					/*
 					 * returns to original process
@@ -654,6 +663,7 @@ trap(struct trapframe *frame)
 			break;
 
 		case T_TRCTRAP:	 /* trace trap */
+kernel_trctrap:
 			if (frame->tf_eip == (int)IDTVEC(lcall_syscall)) {
 				/*
 				 * We've just entered system mode via the

Modified: head/sys/i386/i386/vm86.c
==============================================================================
--- head/sys/i386/i386/vm86.c	Thu Sep  8 14:04:04 2016	(r305611)
+++ head/sys/i386/i386/vm86.c	Thu Sep  8 14:43:39 2016	(r305612)
@@ -171,7 +171,7 @@ vm86_emulate(vmf)
 					PUSHL((vmf->vmf_eflags & PUSH_MASK)
 					    | PSL_IOPL, vmf);
 				vmf->vmf_ip += inc_ip;
-				return (0);
+				return (retcode);
 
 			case POPF:
 				temp_flags = POPL(vmf) & POP_MASK;
@@ -185,7 +185,7 @@ vm86_emulate(vmf)
 				} else {
 					vmf->vmf_eflags &= ~PSL_VIF;
 				}
-				return (0);
+				return (retcode);
 			}
 			break;
 
@@ -203,7 +203,7 @@ vm86_emulate(vmf)
 		case INTn:
 			break;
 
-		/* VME if trying to set PSL_TF, or PSL_I when VIP is set */
+		/* VME if trying to set PSL_T, or PSL_I when VIP is set */
 		case POPF:
 			temp_flags = POP(vmf) & POP_MASK;
 			vmf->vmf_flags = (vmf->vmf_flags & ~POP_MASK)
@@ -218,7 +218,7 @@ vm86_emulate(vmf)
 			}
 			return (retcode);
 
-		/* VME if trying to set PSL_TF, or PSL_I when VIP is set */
+		/* VME if trying to set PSL_T, or PSL_I when VIP is set */
 		case IRET:
 			vmf->vmf_ip = POP(vmf);
 			vmf->vmf_cs = POP(vmf);


More information about the svn-src-head mailing list