summaryrefslogtreecommitdiff
path: root/sys/arch/i386/i386/linux_machdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/i386/i386/linux_machdep.c')
-rw-r--r--sys/arch/i386/i386/linux_machdep.c90
1 files changed, 46 insertions, 44 deletions
diff --git a/sys/arch/i386/i386/linux_machdep.c b/sys/arch/i386/i386/linux_machdep.c
index b38e48cf9ed..b01926463ab 100644
--- a/sys/arch/i386/i386/linux_machdep.c
+++ b/sys/arch/i386/i386/linux_machdep.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: linux_machdep.c,v 1.3 1996/03/11 11:16:48 mickey Exp $ */
-/* $NetBSD: linux_machdep.c,v 1.24 1996/01/04 22:21:57 jtc Exp $ */
+/* $OpenBSD: linux_machdep.c,v 1.4 1996/04/17 05:18:53 mickey Exp $ */
+/* $NetBSD: linux_machdep.c,v 1.26 1996/04/11 07:47:45 mycroft Exp $ */
/*
* Copyright (c) 1995 Frank van der Linden
@@ -66,6 +66,7 @@
#include <machine/segments.h>
#include <machine/specialreg.h>
#include <machine/sysarch.h>
+#include <machine/vm86.h>
#include <machine/linux_machdep.h>
/*
@@ -134,6 +135,8 @@ linux_sendsig(catcher, sig, mask, code)
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);
+ tf->tf_eflags &= ~PSL_VM;
} else
#endif
{
@@ -141,20 +144,20 @@ linux_sendsig(catcher, sig, mask, code)
__asm("movl %%fs,%w0" : "=r" (frame.sf_sc.sc_fs));
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;
- frame.sf_sc.sc_ebx = tf->tf_ebx;
- frame.sf_sc.sc_edx = tf->tf_edx;
- frame.sf_sc.sc_ecx = tf->tf_ecx;
- frame.sf_sc.sc_eax = tf->tf_eax;
- frame.sf_sc.sc_eip = tf->tf_eip;
- frame.sf_sc.sc_cs = tf->tf_cs;
- 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;
+ frame.sf_sc.sc_ebx = tf->tf_ebx;
+ frame.sf_sc.sc_edx = tf->tf_edx;
+ frame.sf_sc.sc_ecx = tf->tf_ecx;
+ frame.sf_sc.sc_eax = tf->tf_eax;
+ frame.sf_sc.sc_eip = tf->tf_eip;
+ frame.sf_sc.sc_cs = tf->tf_cs;
frame.sf_sc.sc_esp_at_signal = tf->tf_esp;
- frame.sf_sc.sc_ss = tf->tf_ss;
- frame.sf_sc.sc_err = tf->tf_err;
+ frame.sf_sc.sc_ss = tf->tf_ss;
+ frame.sf_sc.sc_err = tf->tf_err;
frame.sf_sc.sc_trapno = tf->tf_trapno;
if (copyout(&frame, fp, sizeof(frame)) != 0) {
@@ -169,15 +172,12 @@ linux_sendsig(catcher, sig, mask, code)
/*
* Build context to run handler in.
*/
- tf->tf_esp = (int)fp;
+ tf->tf_es = GSEL(GUDATA_SEL, SEL_UPL);
+ tf->tf_ds = GSEL(GUDATA_SEL, SEL_UPL);
tf->tf_eip = (int)(((char *)PS_STRINGS) -
(linux_esigcode - linux_sigcode));
-#ifdef VM86
- tf->tf_eflags &= ~PSL_VM;
-#endif
tf->tf_cs = GSEL(GUCODE_SEL, SEL_UPL);
- tf->tf_ds = GSEL(GUDATA_SEL, SEL_UPL);
- tf->tf_es = GSEL(GUDATA_SEL, SEL_UPL);
+ tf->tf_esp = (int)fp;
tf->tf_ss = GSEL(GUDATA_SEL, SEL_UPL);
}
@@ -215,16 +215,6 @@ linux_sys_sigreturn(p, v, retval)
return (EFAULT);
/*
- * Check for security violations.
- */
- if (((context.sc_eflags ^ tf->tf_eflags) & PSL_USERSTATIC) != 0 ||
- !USERMODE(context.sc_cs, context.sc_eflags))
- return (EINVAL);
-
- p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
- p->p_sigmask = context.sc_mask & ~sigcantmask;
-
- /*
* Restore signal context.
*/
#ifdef VM86
@@ -233,25 +223,39 @@ linux_sys_sigreturn(p, v, retval)
tf->tf_vm86_fs = context.sc_fs;
tf->tf_vm86_es = context.sc_es;
tf->tf_vm86_ds = context.sc_ds;
+ set_vflags(p, context.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 (((context.sc_eflags ^ tf->tf_eflags) & PSL_USERSTATIC) != 0 ||
+ !USERMODE(context.sc_cs, context.sc_eflags))
+ return (EINVAL);
+
/* %fs and %gs were restored by the trampoline. */
tf->tf_es = context.sc_es;
tf->tf_ds = context.sc_ds;
+ tf->tf_eflags = context.sc_eflags;
}
- tf->tf_edi = context.sc_edi;
- tf->tf_esi = context.sc_esi;
- tf->tf_ebp = context.sc_ebp;
- tf->tf_ebx = context.sc_ebx;
- tf->tf_edx = context.sc_edx;
- tf->tf_ecx = context.sc_ecx;
- tf->tf_eax = context.sc_eax;
- tf->tf_eip = context.sc_eip;
- tf->tf_cs = context.sc_cs;
- tf->tf_eflags = context.sc_eflags;
- tf->tf_esp = context.sc_esp_at_signal;
- tf->tf_ss = context.sc_ss;
+ tf->tf_edi = context.sc_edi;
+ tf->tf_esi = context.sc_esi;
+ tf->tf_ebp = context.sc_ebp;
+ tf->tf_ebx = context.sc_ebx;
+ tf->tf_edx = context.sc_edx;
+ tf->tf_ecx = context.sc_ecx;
+ tf->tf_eax = context.sc_eax;
+ tf->tf_eip = context.sc_eip;
+ tf->tf_cs = context.sc_cs;
+ tf->tf_esp = context.sc_esp_at_signal;
+ tf->tf_ss = context.sc_ss;
+
+ p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
+ p->p_sigmask = context.sc_mask & ~sigcantmask;
return (EJUSTRETURN);
}
@@ -503,9 +507,7 @@ linux_machdepioctl(p, v, retval)
break;
#endif
default:
-#ifdef DIAGNOSTIC
printf("linux_machdepioctl: invalid ioctl %08x\n", com);
-#endif
return EINVAL;
}
SCARG(&bia, com) = com;