Date: Thu, 19 Apr 2012 20:11:43 +0000 (UTC) From: Jung-uk Kim <jkim@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r234467 - stable/9/sys/i386/i386 Message-ID: <201204192011.q3JKBhku005384@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jkim Date: Thu Apr 19 20:11:43 2012 New Revision: 234467 URL: http://svn.freebsd.org/changeset/base/234467 Log: MFC: r234350 - 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. - Remove unnecessary CLI and STI instructions from BIOS interrupt emulation. INTn and IRET must be able to emulate the flag correctly. Modified: stable/9/sys/i386/i386/vm86.c Directory Properties: stable/9/sys/ (props changed) Modified: stable/9/sys/i386/i386/vm86.c ============================================================================== --- stable/9/sys/i386/i386/vm86.c Thu Apr 19 18:03:24 2012 (r234466) +++ stable/9/sys/i386/i386/vm86.c Thu Apr 19 20:11:43 2012 (r234467) @@ -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?201204192011.q3JKBhku005384>