a custom kernel for over 20 years.
testing mlarkin@
ok deraadt@ phessler@ jca@ matthieu@
-# $OpenBSD: Makefile,v 1.10 2016/03/30 06:38:41 jmc Exp $
+# $OpenBSD: Makefile,v 1.11 2018/07/09 19:20:29 guenther Exp $
# $NetBSD: Makefile,v 1.1 1996/02/21 02:45:47 jtk Exp $
MAN+= i386_get_fsbase.2 i386_get_gsbase.2 \
- i386_iopl.2 i386_vm86.2
+ i386_iopl.2
MANSUBDIR=i386
.if ${MACHINE} == "i386"
NOPIC=
SRCS+= i386_iopl.c \
i386_get_fsbase.c i386_get_gsbase.c \
- i386_set_fsbase.c i386_set_gsbase.c \
- i386_vm86.c
+ i386_set_fsbase.c i386_set_gsbase.c
.include <bsd.lib.mk>
.else
NOPROG=
+++ /dev/null
-.\" $OpenBSD: i386_vm86.2,v 1.13 2015/09/10 17:55:21 schwarze Exp $
-.\" $NetBSD: i386_vm86.2,v 1.1 1996/02/21 00:21:52 jtk Exp $
-.\"
-.\" Copyright (c) 1996 The NetBSD Foundation, Inc.
-.\" All rights reserved.
-.\"
-.\" This code is derived from software contributed to The NetBSD Foundation
-.\" by John Kohl.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
-.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
-.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-.\" POSSIBILITY OF SUCH DAMAGE.
-.\"
-.\" from: @(#)fork.2 6.5 (Berkeley) 3/10/91
-.\"
-.Dd $Mdocdate: September 10 2015 $
-.Dt I386_VM86 2 i386
-.Os
-.Sh NAME
-.Nm i386_vm86
-.Nd set virtual 8086 processor registers and mode
-.Sh SYNOPSIS
-.In sys/types.h
-.In signal.h
-.In machine/segments.h
-.In machine/sysarch.h
-.In machine/vm86.h
-.Ft int
-.Fn i386_vm86 "struct vm86_struct *vmcp"
-.Sh DESCRIPTION
-.Fn i386_vm86
-will set the process into virtual 8086 mode using the registers and
-selectors specified by the context pointed to by
-.Ar vmcp .
-The processor registers are set from
-.Ar vmcp->substr.regs ,
-and the emulated processor type from
-.Ar vmcp->substr.ss_cpu_type .
-.Pp
-The kernel keeps a pointer to the context, and uses the tables stored at
-.Ar vmcp->int_byuser
-and
-.Ar vmcp->int21_byuser
-for fast virtual interrupt handling.
-If the
-.Ar n Ns Li th
-bit is clear in the first of
-these arrays, then the kernel may directly emulate the real-mode x86 INT
-.Ar n
-instruction handling.
-If the
-.Ar n Ns Li th
-bit is set, then the process is
-delivered a signal when an INT instruction is executed.
-.Pp
-Since MS-DOS puts many DOS functions onto interrupt 21, it is handled
-specially: the
-.Ar k Ns Li th
-bit in the
-.Ar vmcp->int21_byuser
-array is checked when INT
-.Ar 21
-is requested and the
-.Ar ah
-register is
-.Ar k .
-.Pp
-.Sy Note:
-Code using the
-.Fn i386_vm86
-function must be compiled using
-.Cm -li386 .
-.Sh RETURN VALUES
-This routine does not normally return: 32-bit mode will be restored by
-the delivery of a signal to the process.
-In case of an error in setting
-the VM86 mode, a value of \-1 is returned and the global variable
-.Va errno
-is set to indicate the error.
-.Sh ERRORS
-.Fn i386_vm86
-will fail if:
-.Bl -tag -width [EINVAL]
-.It Bq Er EFAULT
-The state at
-.Ar vmcp
-was not readable to the user process.
-.El
-.Sh REFERENCES
-.Rs
-.%A Intel
-.%T i386 Microprocessor Programmer's Reference Manual
-.Re
+++ /dev/null
-/* $OpenBSD: i386_vm86.c,v 1.7 2016/02/01 19:58:44 jca Exp $ */
-/* $NetBSD: i386_vm86.c,v 1.1 1996/02/21 00:21:56 jtk Exp $ */
-
-/*-
- * Copyright (c) 1996 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by John Kohl.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/types.h>
-#include <machine/signal.h>
-#include <machine/segments.h>
-#include <machine/sysarch.h>
-#include <machine/vm86.h>
-
-int
-i386_vm86(struct vm86_struct *vmcp)
-{
-
- return sysarch(I386_VM86, vmcp);
-}
-
-/* $OpenBSD: psl.h,v 1.4 2011/03/23 16:54:34 pirofti Exp $ */
+/* $OpenBSD: psl.h,v 1.5 2018/07/09 19:20:29 guenther Exp $ */
/* $NetBSD: psl.h,v 1.1 2003/02/26 21:26:11 fvdl Exp $ */
/*-
#define PSL_MBZ 0xffc08028 /* must be zero bits */
#define PSL_USERSET (PSL_MBO | PSL_I)
-#ifdef VM86
-#define PSL_USERSTATIC (PSL_MBO | PSL_MBZ | PSL_I | PSL_IOPL | PSL_NT | PSL_VIF | PSL_VIP)
-#else
#define PSL_USERSTATIC (PSL_MBO | PSL_MBZ | PSL_I | PSL_IOPL | PSL_NT | PSL_VM | PSL_VIF | PSL_VIP)
-#endif
#define PSL_USER (PSL_C | PSL_MBO | PSL_PF | PSL_AF | PSL_Z | PSL_N | PSL_V)
/*
-# $OpenBSD: GENERIC,v 1.831 2018/07/05 11:54:43 patrick Exp $
+# $OpenBSD: GENERIC,v 1.832 2018/07/09 19:20:29 guenther Exp $
#
# For further information on compiling OpenBSD kernels, see the config(8)
# man page.
option USER_PCICONF # user-space PCI configuration
-#option VM86 # Virtual 8086 emulation
option KVM86 # Kernel Virtual 8086 emulation
option APERTURE # in-kernel aperture driver for XFree86
option MTRR # CPU memory range attributes control
-# $OpenBSD: files.i386,v 1.238 2018/07/01 15:52:12 kettenis Exp $
+# $OpenBSD: files.i386,v 1.239 2018/07/09 19:20:29 guenther Exp $
#
# new style config file for i386 architecture
#
# Compatibility modules
#
-# VM86 mode
-file arch/i386/i386/vm86.c vm86
-
# VM86 in kernel
file arch/i386/i386/kvm86.c kvm86
file arch/i386/i386/kvm86call.S kvm86
-/* $OpenBSD: locore.s,v 1.189 2018/06/22 13:21:14 bluhm Exp $ */
+/* $OpenBSD: locore.s,v 1.190 2018/07/09 19:20:29 guenther Exp $ */
/* $NetBSD: locore.s,v 1.145 1996/05/03 19:41:19 christos Exp $ */
/*-
#define CLEAR_ASTPENDING(cpreg) \
movl $0,P_MD_ASTPENDING(cpreg)
-#ifdef VM86
-#define SAVE_VM86 \
- testl $PSL_VM,TRF_EFLAGS(%ebp) ; \
- jz 102f ; \
- movl TRF_VM86_ES(%ebp),%eax ; \
- movl %eax,IRF_VM86_ES(%esp) ; \
- movl TRF_VM86_DS(%ebp),%eax ; \
- movl %eax,IRF_VM86_DS(%esp) ; \
- movl TRF_VM86_FS(%ebp),%eax ; \
- movl %eax,IRF_VM86_FS(%esp) ; \
- movl TRF_VM86_GS(%ebp),%eax ; \
- movl %eax,IRF_VM86_GS(%esp) ; \
- 102:
-
-#define RESTORE_VM86 \
- testl $PSL_VM,TRF_EFLAGS(%ebp) ; \
- jz 101f ; \
- movl TRF_VM86_ES(%esp),%eax ; \
- movl %eax,TRF_VM86_ES(%ebp) ; \
- movl TRF_VM86_DS(%esp),%eax ; \
- movl %eax,TRF_VM86_DS(%ebp) ; \
- movl TRF_VM86_FS(%esp),%eax ; \
- movl %eax,TRF_VM86_FS(%ebp) ; \
- movl TRF_VM86_GS(%esp),%eax ; \
- movl %eax,TRF_VM86_GS(%ebp) ; \
- 101:
-
-#else
-
-#define SAVE_VM86 ;
-#define RESTORE_VM86 ;
-
-#endif /* VM86 */
-
/*
* These are used on interrupt or trap entry or exit.
*/
movl TRF_ERR(%ebp),%eax ; \
movl %eax,IRF_ERR(%esp) ; \
movl TRF_TRAPNO(%ebp),%eax ; \
- movl %eax,IRF_TRAPNO(%esp) ; \
- SAVE_VM86
+ movl %eax,IRF_TRAPNO(%esp)
#define INTR_ENABLE_U_PLUS_K \
movl $GSEL(GCPU_SEL, SEL_KPL),%eax ; \
CHECK_ASTPENDING(%ecx)
je 1f
testb $SEL_RPL,TF_CS(%esp)
-#ifdef VM86
- jnz 5f
- testl $PSL_VM,TF_EFLAGS(%esp)
-#endif
jz 1f
5: CLEAR_ASTPENDING(%ecx)
sti
movl %eax,TRF__DEADBEEF(%ebp)
movl TRF__KERN_ESP(%esp),%eax
movl %eax,TRF__KERN_ESP(%ebp)
- RESTORE_VM86
movl TRF_FS(%esp),%eax
movl %eax,TRF_FS(%ebp)
movl TRF_EAX(%esp),%eax
-/* $OpenBSD: machdep.c,v 1.618 2018/06/22 13:21:14 bluhm Exp $ */
+/* $OpenBSD: machdep.c,v 1.619 2018/07/09 19:20:29 guenther Exp $ */
/* $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $ */
/*-
#include <ddb/db_extern.h>
#endif
-#ifdef VM86
-#include <machine/vm86.h>
-#endif
-
#include "isa.h"
#include "isadma.h"
#include "npx.h"
frame.sf_sc.sc_err = tf->tf_err;
frame.sf_sc.sc_trapno = tf->tf_trapno;
frame.sf_sc.sc_mask = mask;
-#ifdef VM86
- if (tf->tf_eflags & PSL_VM) {
- frame.sf_sc.sc_gs = tf->tf_vm86_gs;
- frame.sf_sc.sc_fs = tf->tf_vm86_fs;
- frame.sf_sc.sc_es = tf->tf_vm86_es;
- frame.sf_sc.sc_ds = tf->tf_vm86_ds;
- frame.sf_sc.sc_eflags = get_vflags(p);
- } else
-#endif
- {
- frame.sf_sc.sc_fs = tf->tf_fs;
- frame.sf_sc.sc_gs = tf->tf_gs;
- frame.sf_sc.sc_es = tf->tf_es;
- frame.sf_sc.sc_ds = tf->tf_ds;
- frame.sf_sc.sc_eflags = tf->tf_eflags;
- }
+ frame.sf_sc.sc_fs = tf->tf_fs;
+ frame.sf_sc.sc_gs = tf->tf_gs;
+ frame.sf_sc.sc_es = tf->tf_es;
+ frame.sf_sc.sc_ds = tf->tf_ds;
+ frame.sf_sc.sc_eflags = tf->tf_eflags;
frame.sf_sc.sc_edi = tf->tf_edi;
frame.sf_sc.sc_esi = tf->tf_esi;
frame.sf_sc.sc_ebp = tf->tf_ebp;
if (psp->ps_siginfo & sigmask(sig)) {
frame.sf_sip = &fp->sf_si;
initsiginfo(&frame.sf_si, sig, code, type, val);
-#ifdef VM86
- if (sig == SIGURG) /* VM86 userland trap */
- frame.sf_si.si_trapno = code;
-#endif
}
/* XXX don't copyout siginfo if not needed? */
/*
* Restore signal ksc.
*/
-#ifdef VM86
- if (ksc.sc_eflags & PSL_VM) {
- tf->tf_vm86_gs = ksc.sc_gs;
- tf->tf_vm86_fs = ksc.sc_fs;
- tf->tf_vm86_es = ksc.sc_es;
- tf->tf_vm86_ds = ksc.sc_ds;
- set_vflags(p, ksc.sc_eflags);
- } else
-#endif
- {
- /*
- * Check for security violations. If we're returning to
- * protected mode, the CPU will validate the segment registers
- * automatically and generate a trap on violations. We handle
- * the trap, rather than doing all of the checking here.
- */
- if (((ksc.sc_eflags ^ tf->tf_eflags) & PSL_USERSTATIC) != 0 ||
- !USERMODE(ksc.sc_cs, ksc.sc_eflags))
- return (EINVAL);
-
- tf->tf_fs = ksc.sc_fs;
- tf->tf_gs = ksc.sc_gs;
- tf->tf_es = ksc.sc_es;
- tf->tf_ds = ksc.sc_ds;
- tf->tf_eflags = ksc.sc_eflags;
- }
+ /*
+ * Check for security violations. If we're returning to
+ * protected mode, the CPU will validate the segment registers
+ * automatically and generate a trap on violations. We handle
+ * the trap, rather than doing all of the checking here.
+ */
+ if (((ksc.sc_eflags ^ tf->tf_eflags) & PSL_USERSTATIC) != 0 ||
+ !USERMODE(ksc.sc_cs, ksc.sc_eflags))
+ return (EINVAL);
+
+ tf->tf_fs = ksc.sc_fs;
+ tf->tf_gs = ksc.sc_gs;
+ tf->tf_es = ksc.sc_es;
+ tf->tf_ds = ksc.sc_ds;
+ tf->tf_eflags = ksc.sc_eflags;
tf->tf_edi = ksc.sc_edi;
tf->tf_esi = ksc.sc_esi;
tf->tf_ebp = ksc.sc_ebp;
-/* $OpenBSD: process_machdep.c,v 1.28 2013/05/08 15:36:30 tedu Exp $ */
+/* $OpenBSD: process_machdep.c,v 1.29 2018/07/09 19:20:29 guenther Exp $ */
/* $NetBSD: process_machdep.c,v 1.22 1996/05/03 19:42:25 christos Exp $ */
/*
#include <machine/reg.h>
#include <machine/segments.h>
-#ifdef VM86
-#include <machine/vm86.h>
-#endif
-
#include "npx.h"
static __inline struct trapframe *process_frame(struct proc *);
{
struct trapframe *tf = process_frame(p);
-#ifdef VM86
- if (tf->tf_eflags & PSL_VM) {
- regs->r_gs = tf->tf_vm86_gs & 0xffff;
- regs->r_fs = tf->tf_vm86_fs & 0xffff;
- regs->r_es = tf->tf_vm86_es & 0xffff;
- regs->r_ds = tf->tf_vm86_ds & 0xffff;
- regs->r_eflags = get_vflags(p);
- } else
-#endif
- {
- regs->r_gs = tf->tf_gs & 0xffff;
- regs->r_fs = tf->tf_fs & 0xffff;
- regs->r_es = tf->tf_es & 0xffff;
- regs->r_ds = tf->tf_ds & 0xffff;
- regs->r_eflags = tf->tf_eflags;
- }
+ regs->r_gs = tf->tf_gs & 0xffff;
+ regs->r_fs = tf->tf_fs & 0xffff;
+ regs->r_es = tf->tf_es & 0xffff;
+ regs->r_ds = tf->tf_ds & 0xffff;
+ regs->r_eflags = tf->tf_eflags;
regs->r_edi = tf->tf_edi;
regs->r_esi = tf->tf_esi;
regs->r_ebp = tf->tf_ebp;
{
struct trapframe *tf = process_frame(p);
-#ifdef VM86
- if (tf->tf_eflags & PSL_VM) {
- tf->tf_vm86_gs = regs->r_gs & 0xffff;
- tf->tf_vm86_fs = regs->r_fs & 0xffff;
- tf->tf_vm86_es = regs->r_es & 0xffff;
- tf->tf_vm86_ds = regs->r_ds & 0xffff;
- set_vflags(p, regs->r_eflags);
- } else
-#endif
- {
- /*
- * Check for security violations.
- */
- if (((regs->r_eflags ^ tf->tf_eflags) & PSL_USERSTATIC) != 0 ||
- !USERMODE(regs->r_cs, regs->r_eflags))
- return (EINVAL);
-
- tf->tf_gs = regs->r_gs & 0xffff;
- tf->tf_fs = regs->r_fs & 0xffff;
- tf->tf_es = regs->r_es & 0xffff;
- tf->tf_ds = regs->r_ds & 0xffff;
- tf->tf_eflags = regs->r_eflags;
- }
+ /*
+ * Check for security violations.
+ */
+ if (((regs->r_eflags ^ tf->tf_eflags) & PSL_USERSTATIC) != 0 ||
+ !USERMODE(regs->r_cs, regs->r_eflags))
+ return (EINVAL);
+
+ tf->tf_gs = regs->r_gs & 0xffff;
+ tf->tf_fs = regs->r_fs & 0xffff;
+ tf->tf_es = regs->r_es & 0xffff;
+ tf->tf_ds = regs->r_ds & 0xffff;
+ tf->tf_eflags = regs->r_eflags;
tf->tf_edi = regs->r_edi;
tf->tf_esi = regs->r_esi;
tf->tf_ebp = regs->r_ebp;
-/* $OpenBSD: sys_machdep.c,v 1.39 2018/02/19 08:59:52 mpi Exp $ */
+/* $OpenBSD: sys_machdep.c,v 1.40 2018/07/09 19:20:29 guenther Exp $ */
/* $NetBSD: sys_machdep.c,v 1.28 1996/05/03 19:42:29 christos Exp $ */
/*-
#include <machine/reg.h>
#include <machine/sysarch.h>
-#ifdef VM86
-#include <machine/vm86.h>
-#endif
-
extern struct vm_map *kernel_map;
int i386_iopl(struct proc *, void *, register_t *);
error = i386_iopl(p, SCARG(uap, parms), retval);
break;
-#ifdef VM86
- case I386_VM86:
- error = i386_vm86(p, SCARG(uap, parms), retval);
- break;
-#endif
-
case I386_GET_FSBASE:
{
uint32_t base = i386_get_threadbase(p, TSEG_FS);
-/* $OpenBSD: trap.c,v 1.137 2018/04/12 17:13:43 deraadt Exp $ */
+/* $OpenBSD: trap.c,v 1.138 2018/07/09 19:20:30 guenther Exp $ */
/* $NetBSD: trap.c,v 1.95 1996/05/05 06:50:02 mycroft Exp $ */
/*-
case T_PROTFLT|T_USER: /* protection fault */
KERNEL_LOCK();
-#ifdef VM86
- if (frame->tf_eflags & PSL_VM) {
- vm86_gpfault(p, type & ~T_USER);
- KERNEL_UNLOCK();
- goto out;
- }
-#endif
+
/* If pmap_exec_fixup does something, let's retry the trap. */
if (pmap_exec_fixup(&p->p_vmspace->vm_map, frame,
&p->p_addr->u_pcb)) {
params = (caddr_t)frame->tf_esp + sizeof(int);
-#ifdef VM86
- /*
- * VM86 mode application found our syscall trap gate by accident; let
- * it get a SIGSYS and have the VM86 handler in the process take care
- * of it.
- */
- if (frame->tf_eflags & PSL_VM)
- code = -1;
- else
-#endif
-
switch (code) {
case SYS_syscall:
/*
+++ /dev/null
-/* $OpenBSD: vm86.c,v 1.24 2017/12/30 20:46:59 guenther Exp $ */
-/* $NetBSD: vm86.c,v 1.15 1996/05/03 19:42:33 christos Exp $ */
-
-/*-
- * Copyright (c) 1996 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by John T. Kohl and Charles M. Hannum.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/signalvar.h>
-#include <sys/kernel.h>
-#include <sys/proc.h>
-#include <sys/user.h>
-#include <sys/exec.h>
-#include <sys/buf.h>
-#include <sys/reboot.h>
-#include <sys/conf.h>
-#include <sys/malloc.h>
-#include <sys/mbuf.h>
-#include <sys/msgbuf.h>
-#include <sys/mount.h>
-#include <sys/vnode.h>
-#include <sys/device.h>
-#include <sys/sysctl.h>
-#include <sys/syscallargs.h>
-#ifdef SYSVMSG
-#include <sys/msg.h>
-#endif
-#ifdef SYSVSEM
-#include <sys/sem.h>
-#endif
-#ifdef SYSVSHM
-#include <sys/shm.h>
-#endif
-
-#include <sys/ktrace.h>
-#include <machine/sysarch.h>
-#include <machine/vm86.h>
-
-static void fast_intxx(struct proc *, int);
-static __inline int is_bitset(int, caddr_t);
-
-#define CS(tf) (*(u_short *)&tf->tf_cs)
-#define IP(tf) (*(u_short *)&tf->tf_eip)
-#define SS(tf) (*(u_short *)&tf->tf_ss)
-#define SP(tf) (*(u_short *)&tf->tf_esp)
-
-
-#define putword(base, ptr, val) \
-__asm__ volatile( \
- "decw %w0\n\t" \
- "movb %h2,0(%1,%0)\n\t" \
- "decw %w0\n\t" \
- "movb %b2,0(%1,%0)" \
- : "=r" (ptr) \
- : "r" (base), "q" (val), "0" (ptr))
-
-#define putdword(base, ptr, val) \
-__asm__ volatile( \
- "rorl $16,%2\n\t" \
- "decw %w0\n\t" \
- "movb %h2,0(%1,%0)\n\t" \
- "decw %w0\n\t" \
- "movb %b2,0(%1,%0)\n\t" \
- "rorl $16,%2\n\t" \
- "decw %w0\n\t" \
- "movb %h2,0(%1,%0)\n\t" \
- "decw %w0\n\t" \
- "movb %b2,0(%1,%0)" \
- : "=r" (ptr) \
- : "r" (base), "q" (val), "0" (ptr))
-
-#define getbyte(base, ptr) \
-({ unsigned long __res; \
-__asm__ volatile( \
- "movb 0(%1,%0),%b2\n\t" \
- "incw %w0" \
- : "=r" (ptr), "=r" (base), "=q" (__res) \
- : "0" (ptr), "1" (base), "2" (0)); \
-__res; })
-
-#define getword(base, ptr) \
-({ unsigned long __res; \
-__asm__ volatile( \
- "movb 0(%1,%0),%b2\n\t" \
- "incw %w0\n\t" \
- "movb 0(%1,%0),%h2\n\t" \
- "incw %w0" \
- : "=r" (ptr), "=r" (base), "=q" (__res) \
- : "0" (ptr), "1" (base), "2" (0)); \
-__res; })
-
-#define getdword(base, ptr) \
-({ unsigned long __res; \
-__asm__ volatile( \
- "movb 0(%1,%0),%b2\n\t" \
- "incw %w0\n\t" \
- "movb 0(%1,%0),%h2\n\t" \
- "incw %w0\n\t" \
- "rorl $16,%2\n\t" \
- "movb 0(%1,%0),%b2\n\t" \
- "incw %w0\n\t" \
- "movb 0(%1,%0),%h2\n\t" \
- "incw %w0\n\t" \
- "rorl $16,%2" \
- : "=r" (ptr), "=r" (base), "=q" (__res) \
- : "0" (ptr), "1" (base)); \
-__res; })
-
-
-static __inline int
-is_bitset(int nr, caddr_t bitmap)
-{
- u_int byte; /* bt instruction doesn't do
- bytes--it examines ints! */
- bitmap += nr / NBBY;
- nr = nr % NBBY;
- copyin(bitmap, &byte, sizeof(u_char));
-
- __asm__ volatile("btl %2,%1\n\tsbbl %0,%0"
- :"=r" (nr)
- :"r" (byte),"r" (nr));
- return (nr);
-}
-
-
-#define V86_AH(regs) (((u_char *)&((regs)->tf_eax))[1])
-#define V86_AL(regs) (((u_char *)&((regs)->tf_eax))[0])
-
-static void
-fast_intxx(struct proc *p, int intrno)
-{
- struct trapframe *tf = p->p_md.md_regs;
- /*
- * handle certain interrupts directly by pushing the interrupt
- * frame and resetting registers, but only if user said that's ok
- * (i.e. not revectored.) Otherwise bump to 32-bit user handler.
- */
- struct vm86_struct *u_vm86p;
- struct { u_short ip, cs; } ihand;
-
- u_long ss, sp;
-
- /*
- * Note: u_vm86p points to user-space, we only compute offsets
- * and don't deref it. is_revectored() above does copyin() to
- * get stuff from it
- */
- u_vm86p = (struct vm86_struct *)p->p_addr->u_pcb.vm86_userp;
-
- /*
- * If user requested special handling, return to user space with
- * indication of which INT was requested.
- */
- if (is_bitset(intrno, &u_vm86p->int_byuser[0]))
- goto vector;
-
- /*
- * If it's interrupt 0x21 (special in the DOS world) and the
- * sub-command (in AH) was requested for special handling,
- * return to user mode.
- */
- if (intrno == 0x21 && is_bitset(V86_AH(tf), &u_vm86p->int21_byuser[0]))
- goto vector;
-
- /*
- * Fetch intr handler info from "real-mode" IDT based at addr 0 in
- * the user address space.
- */
- if (copyin((caddr_t)(intrno * sizeof(ihand)), &ihand, sizeof(ihand)))
- goto bad;
-
- /*
- * Otherwise, push flags, cs, eip, and jump to handler to
- * simulate direct INT call.
- */
- ss = SS(tf) << 4;
- sp = SP(tf);
-
- putword(ss, sp, get_vflags_short(p));
- putword(ss, sp, CS(tf));
- putword(ss, sp, IP(tf));
- SP(tf) = sp;
-
- IP(tf) = ihand.ip;
- CS(tf) = ihand.cs;
-
- return;
-
-vector:
- vm86_return(p, VM86_MAKEVAL(VM86_INTx, intrno));
- return;
-
-bad:
- vm86_return(p, VM86_UNKNOWN);
- return;
-}
-
-void
-vm86_return(struct proc *p, int retval)
-{
- union sigval sv;
-
- /*
- * We can't set the virtual flags in our real trap frame,
- * since it's used to jump to the signal handler. Instead we
- * let sendsig() pull in the vm86_eflags bits.
- */
- if (p->p_sigmask & sigmask(SIGURG)) {
-#ifdef DIAGNOSTIC
- printf("pid %d killed on VM86 protocol screwup (SIGURG blocked)\n",
- p->p_p->ps_pid);
-#endif
- sigexit(p, SIGILL);
- /* NOTREACHED */
- }
- sv.sival_int = 0;
- trapsignal(p, SIGURG, retval, 0, sv);
-}
-
-#define CLI 0xFA
-#define STI 0xFB
-#define INTxx 0xCD
-#define INTO 0xCE
-#define IRET 0xCF
-#define OPSIZ 0x66
-#define INT3 0xCC /* Actually the process gets 32-bit IDT to handle it */
-#define LOCK 0xF0
-#define PUSHF 0x9C
-#define POPF 0x9D
-
-/*
- * Handle a GP fault that occurred while in VM86 mode. Things that are easy
- * to handle here are done here (much more efficient than trapping to 32-bit
- * handler code and then having it restart VM86 mode).
- */
-void
-vm86_gpfault(struct proc *p, int type)
-{
- struct trapframe *tf = p->p_md.md_regs;
- union sigval sv;
-
- /*
- * we want to fetch some stuff from the current user virtual
- * address space for checking. remember that the frame's
- * segment selectors are real-mode style selectors.
- */
- u_long cs, ip, ss, sp;
- u_char tmpbyte;
- int trace;
-
- cs = CS(tf) << 4;
- ip = IP(tf);
- ss = SS(tf) << 4;
- sp = SP(tf);
-
- trace = tf->tf_eflags & PSL_T;
-
- /*
- * For most of these, we must set all the registers before calling
- * macros/functions which might do a vm86_return.
- */
- tmpbyte = getbyte(cs, ip);
- IP(tf) = ip;
- switch (tmpbyte) {
- case CLI:
- /* simulate handling of IF */
- clr_vif(p);
- break;
-
- case STI:
- /* simulate handling of IF.
- * XXX the i386 enables interrupts one instruction later.
- * code here is wrong, but much simpler than doing it Right.
- */
- set_vif(p);
- break;
-
- case INTxx:
- /* try fast intxx, or return to 32bit mode to handle it. */
- tmpbyte = getbyte(cs, ip);
- IP(tf) = ip;
- fast_intxx(p, tmpbyte);
- break;
-
- case INTO:
- if (tf->tf_eflags & PSL_V)
- fast_intxx(p, 4);
- break;
-
- case PUSHF:
- putword(ss, sp, get_vflags_short(p));
- SP(tf) = sp;
- break;
-
- case IRET:
- IP(tf) = getword(ss, sp);
- CS(tf) = getword(ss, sp);
- case POPF:
- set_vflags_short(p, getword(ss, sp));
- SP(tf) = sp;
- break;
-
- case OPSIZ:
- tmpbyte = getbyte(cs, ip);
- IP(tf) = ip;
- switch (tmpbyte) {
- case PUSHF:
- putdword(ss, sp, get_vflags(p) & ~PSL_VM);
- SP(tf) = sp;
- break;
-
- case IRET:
- IP(tf) = getdword(ss, sp);
- CS(tf) = getdword(ss, sp);
- case POPF:
- set_vflags(p, getdword(ss, sp) | PSL_VM);
- SP(tf) = sp;
- break;
-
- default:
- IP(tf) -= 2;
- goto bad;
- }
- break;
-
- case LOCK:
- default:
- IP(tf) -= 1;
- goto bad;
- }
-
- if (trace && tf->tf_eflags & PSL_VM) {
- sv.sival_int = 0;
- trapsignal(p, SIGTRAP, T_TRCTRAP, TRAP_TRACE, sv);
- }
- return;
-
-bad:
- vm86_return(p, VM86_UNKNOWN);
- return;
-}
-
-int
-i386_vm86(struct proc *p, char *args, register_t *retval)
-{
- struct trapframe *tf = p->p_md.md_regs;
- struct pcb *pcb = &p->p_addr->u_pcb;
- struct vm86_kern vm86s;
- int error;
-
- error = copyin(args, &vm86s, sizeof(vm86s));
- if (error)
- return (error);
-
- pcb->vm86_userp = (void *)args;
-
- /*
- * Keep mask of flags we simulate to simulate a particular type of
- * processor.
- */
- switch (vm86s.ss_cpu_type) {
- case VCPU_086:
- case VCPU_186:
- case VCPU_286:
- pcb->vm86_flagmask = PSL_ID|PSL_AC|PSL_NT|PSL_IOPL;
- break;
- case VCPU_386:
- pcb->vm86_flagmask = PSL_ID|PSL_AC;
- break;
- case VCPU_486:
- pcb->vm86_flagmask = PSL_ID;
- break;
- case VCPU_586:
- pcb->vm86_flagmask = 0;
- break;
- default:
- return (EINVAL);
- }
-
-#define DOVREG(reg) tf->tf_vm86_##reg = (u_short) vm86s.regs.vmsc.sc_##reg
-#define DOREG(reg) tf->tf_##reg = (u_short) vm86s.regs.vmsc.sc_##reg
-
- DOVREG(ds);
- DOVREG(es);
- DOVREG(fs);
- DOVREG(gs);
- DOREG(edi);
- DOREG(esi);
- DOREG(ebp);
- DOREG(eax);
- DOREG(ebx);
- DOREG(ecx);
- DOREG(edx);
- DOREG(eip);
- DOREG(cs);
- DOREG(esp);
- DOREG(ss);
-
-#undef DOVREG
-#undef DOREG
-
- /* Going into vm86 mode jumps off the signal stack. */
- p->p_sigstk.ss_flags &= ~SS_ONSTACK;
-
- set_vflags(p, vm86s.regs.vmsc.sc_eflags | PSL_VM);
-
- return (EJUSTRETURN);
-}
-/* $OpenBSD: cpu.h,v 1.163 2018/06/22 13:21:14 bluhm Exp $ */
+/* $OpenBSD: cpu.h,v 1.164 2018/07/09 19:20:30 guenther Exp $ */
/* $NetBSD: cpu.h,v 1.35 1996/05/05 19:29:26 christos Exp $ */
/*-
void mp_setperf_init(void);
#endif
-#ifdef VM86
-/* vm86.c */
-void vm86_gpfault(struct proc *, int);
-#endif /* VM86 */
-
int cpu_paenable(void *);
#endif /* _KERNEL */
-/* $OpenBSD: psl.h,v 1.20 2013/05/16 19:26:04 kettenis Exp $ */
+/* $OpenBSD: psl.h,v 1.21 2018/07/09 19:20:30 guenther Exp $ */
/* $NetBSD: psl.h,v 1.30 1996/05/13 01:28:05 mycroft Exp $ */
/*-
#define PSL_MBZ 0xffc08028 /* must be zero bits */
#define PSL_USERSET (PSL_MBO | PSL_I)
-#ifdef VM86
-#define PSL_USERSTATIC (PSL_MBO | PSL_MBZ | PSL_I | PSL_IOPL | PSL_NT | PSL_VIF | PSL_VIP)
-#else
#define PSL_USERSTATIC (PSL_MBO | PSL_MBZ | PSL_I | PSL_IOPL | PSL_NT | PSL_VM | PSL_VIF | PSL_VIP)
-#endif
#ifdef _KERNEL
#include <machine/intr.h>
-/* $OpenBSD: segments.h,v 1.25 2018/06/22 13:21:14 bluhm Exp $ */
+/* $OpenBSD: segments.h,v 1.26 2018/07/09 19:20:30 guenther Exp $ */
/* $NetBSD: segments.h,v 1.23 1996/02/01 22:31:03 mycroft Exp $ */
/*-
#define GSEL(s,r) (((s) << 3) | r) /* a global selector */
#define LSEL(s,r) (((s) << 3) | r | SEL_LDT) /* a local selector */
-#ifdef VM86
-#define USERMODE(c, f) (ISPL(c) == SEL_UPL || ((f) & PSL_VM) != 0)
-#define KERNELMODE(c, f) (ISPL(c) == SEL_KPL && ((f) & PSL_VM) == 0)
-#else
#define USERMODE(c, f) (ISPL(c) == SEL_UPL)
#define KERNELMODE(c, f) (ISPL(c) == SEL_KPL)
-#endif
#ifndef _LOCORE
+++ /dev/null
-/* $OpenBSD: vm86.h,v 1.10 2011/06/25 19:20:41 jsg Exp $ */
-/* $NetBSD: vm86.h,v 1.8 1996/05/03 19:26:32 christos Exp $ */
-
-#undef VM86_USE_VIF
-
-/*-
- * Copyright (c) 1996 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by John T. Kohl and Charles M. Hannum.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#define SETFLAGS(targ, new, newmask) (targ) = ((targ) & ~(newmask)) | ((new) & (newmask))
-
-#define VM86_TYPE(x) ((x) & 0xff)
-#define VM86_ARG(x) (((x) & 0xff00) >> 8)
-#define VM86_MAKEVAL(type,arg) ((type) | (((arg) & 0xff) << 8))
-#define VM86_STI 0
-#define VM86_INTx 1
-#define VM86_SIGNAL 2
-#define VM86_UNKNOWN 3
-
-#define VM86_REALFLAGS (~PSL_USERSTATIC)
-#define VM86_VIRTFLAGS (PSL_USERSTATIC & ~(PSL_MBO | PSL_MBZ))
-
-struct vm86_regs {
- struct sigcontext vmsc;
-};
-
-struct vm86_kern { /* kernel uses this stuff */
- struct vm86_regs regs;
- unsigned long ss_cpu_type;
-};
-#define cpu_type substr.ss_cpu_type
-
-/*
- * Kernel keeps copy of user-mode address of this, but doesn't copy it in.
- */
-struct vm86_struct {
- struct vm86_kern substr;
- unsigned long screen_bitmap; /* not used/supported (yet) */
- unsigned long flags; /* not used/supported (yet) */
- unsigned char int_byuser[32]; /* 256 bits each: pass control to user */
- unsigned char int21_byuser[32]; /* otherwise, handle directly */
-};
-
-#define VCPU_086 0
-#define VCPU_186 1
-#define VCPU_286 2
-#define VCPU_386 3
-#define VCPU_486 4
-#define VCPU_586 5
-
-#ifdef _KERNEL
-int i386_vm86(struct proc *, char *, register_t *);
-void vm86_gpfault(struct proc *, int);
-void vm86_return(struct proc *, int);
-static __inline void clr_vif(struct proc *);
-static __inline void set_vif(struct proc *);
-static __inline void set_vflags(struct proc *, int);
-static __inline int get_vflags(struct proc *);
-static __inline void set_vflags_short(struct proc *, int);
-static __inline int get_vflags_short(struct proc *);
-
-static __inline void
-clr_vif(p)
- struct proc *p;
-{
- struct pcb *pcb = &p->p_addr->u_pcb;
-
-#ifndef VM86_USE_VIF
- pcb->vm86_eflags &= ~PSL_I;
-#else
- pcb->vm86_eflags &= ~PSL_VIF;
-#endif
-}
-
-static __inline void
-set_vif(struct proc *p)
-{
- struct pcb *pcb = &p->p_addr->u_pcb;
-
-#ifndef VM86_USE_VIF
- pcb->vm86_eflags |= PSL_I;
- if ((pcb->vm86_eflags & (PSL_I|PSL_VIP)) == (PSL_I|PSL_VIP))
-#else
- pcb->vm86_eflags |= PSL_VIF;
- if ((pcb->vm86_eflags & (PSL_VIF|PSL_VIP)) == (PSL_VIF|PSL_VIP))
-#endif
- vm86_return(p, VM86_STI);
-}
-
-static __inline void
-set_vflags(struct proc *p, int flags)
-{
- struct trapframe *tf = p->p_md.md_regs;
- struct pcb *pcb = &p->p_addr->u_pcb;
-
- flags &= ~pcb->vm86_flagmask;
- SETFLAGS(pcb->vm86_eflags, flags, VM86_VIRTFLAGS);
- SETFLAGS(tf->tf_eflags, flags, VM86_REALFLAGS);
-#ifndef VM86_USE_VIF
- if ((pcb->vm86_eflags & (PSL_I|PSL_VIP)) == (PSL_I|PSL_VIP))
-#else
- if ((pcb->vm86_eflags & (PSL_VIF|PSL_VIP)) == (PSL_VIF|PSL_VIP))
-#endif
- vm86_return(p, VM86_STI);
-}
-
-static __inline int
-get_vflags(struct proc *p)
-{
- struct trapframe *tf = p->p_md.md_regs;
- struct pcb *pcb = &p->p_addr->u_pcb;
- int flags = PSL_MBO;
-
- SETFLAGS(flags, pcb->vm86_eflags, VM86_VIRTFLAGS);
- SETFLAGS(flags, tf->tf_eflags, VM86_REALFLAGS);
- return (flags);
-}
-
-static __inline void
-set_vflags_short(struct proc *p, int flags)
-{
- struct trapframe *tf = p->p_md.md_regs;
- struct pcb *pcb = &p->p_addr->u_pcb;
-
- flags &= ~pcb->vm86_flagmask;
- SETFLAGS(pcb->vm86_eflags, flags, VM86_VIRTFLAGS & 0xffff);
- SETFLAGS(tf->tf_eflags, flags, VM86_REALFLAGS & 0xffff);
-#ifndef VM86_USE_VIF
- if ((pcb->vm86_eflags & (PSL_I|PSL_VIP)) == (PSL_I|PSL_VIP))
- vm86_return(p, VM86_STI);
-#endif
-}
-
-static __inline int
-get_vflags_short(struct proc *p)
-{
- struct trapframe *tf = p->p_md.md_regs;
- struct pcb *pcb = &p->p_addr->u_pcb;
- int flags = PSL_MBO;
-
- SETFLAGS(flags, pcb->vm86_eflags, VM86_VIRTFLAGS & 0xffff);
- SETFLAGS(flags, tf->tf_eflags, VM86_REALFLAGS & 0xffff);
- return (flags);
-}
-#else
-int i386_vm86(struct vm86_struct *vmcp);
-#endif
-/* $OpenBSD: icu.s,v 1.34 2018/04/11 15:44:08 bluhm Exp $ */
+/* $OpenBSD: icu.s,v 1.35 2018/07/09 19:20:30 guenther Exp $ */
/* $NetBSD: icu.s,v 1.45 1996/01/07 03:59:34 mycroft Exp $ */
/*-
movl %ebx,CPL
je 3f
testb $SEL_RPL,TF_CS(%esp)
-#ifdef VM86
- jnz 4f
- testl $PSL_VM,TF_EFLAGS(%esp)
-#endif
jz 3f
4: CLEAR_ASTPENDING(%ecx)
sti