Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 16 Apr 2012 19:31:44 +0000 (UTC)
From:      Jung-uk Kim <jkim@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r234350 - head/sys/i386/i386
Message-ID:  <201204161931.q3GJViWg047155@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jkim
Date: Mon Apr 16 19:31:44 2012
New Revision: 234350
URL: http://svn.freebsd.org/changeset/base/234350

Log:
  - When interrupt is not requested for VM86 call, make a fake exit point and
  push the address onto stack as we do for INTn emulation.  This avoids stack
  underflow when we encounter RETF instruction in VM86 mode.  Lack of this
  exit point actually caused page fault in VM86 mode with VESA module when we
  resume from suspend state[1].
  - Remove unnecessary CLI and STI instructions from BIOS interrupt emulation.
  INTn and IRET must be able to emulate the flag correctly.
  
  Reported by:	gavin [1]
  Tested by:	gavin (early revision)
  MFC after:	3 days

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

Modified: head/sys/i386/i386/vm86.c
==============================================================================
--- head/sys/i386/i386/vm86.c	Mon Apr 16 18:29:12 2012	(r234349)
+++ head/sys/i386/i386/vm86.c	Mon Apr 16 19:31:44 2012	(r234350)
@@ -512,22 +512,27 @@ full:
 void
 vm86_prepcall(struct vm86frame *vmf)
 {
-	uintptr_t addr[] = { 0xA00, 0x1000 };	/* code, stack */
-	u_char intcall[] = {
-		CLI, INTn, 0x00, STI, HLT
-	};
 	struct vm86_kernel *vm86;
+	uint32_t *stack;
+	uint8_t *code;
 
+	code = (void *)0xa00;
+	stack = (void *)(0x1000 - 2);	/* keep aligned */
 	if ((vmf->vmf_trapno & PAGE_MASK) <= 0xff) {
 		/* interrupt call requested */
-		intcall[2] = (u_char)(vmf->vmf_trapno & 0xff);
-		memcpy((void *)addr[0], (void *)intcall, sizeof(intcall));
-		vmf->vmf_ip = addr[0];
+		code[0] = INTn;
+		code[1] = vmf->vmf_trapno & 0xff;
+		code[2] = HLT;
+		vmf->vmf_ip = (uintptr_t)code;
 		vmf->vmf_cs = 0;
+	} else {
+		code[0] = HLT;
+		stack--;
+		stack[0] = MAKE_VEC(0, (uintptr_t)code);
 	}
-	vmf->vmf_sp = addr[1] - 2;              /* keep aligned */
-	vmf->kernel_fs = vmf->kernel_es = vmf->kernel_ds = 0;
+	vmf->vmf_sp = (uintptr_t)stack;
 	vmf->vmf_ss = 0;
+	vmf->kernel_fs = vmf->kernel_es = vmf->kernel_ds = 0;
 	vmf->vmf_eflags = PSL_VIF | PSL_VM | PSL_USER;
 
 	vm86 = &PCPU_GET(curpcb)->pcb_ext->ext_vm86;



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