Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/i386/i386 If we fault on the iret during return to ...



details:   https://anonhg.NetBSD.org/src/rev/d6feba961143
branches:  trunk
changeset: 750678:d6feba961143
user:      dsl <dsl%NetBSD.org@localhost>
date:      Sun Jan 10 15:37:36 2010 +0000

description:
If we fault on the iret during return to userspace, see if we need to
do a lazy update of %cs to make the stack executable.
If a change is made, just retry the failing sequence.
Signal handlers as gcc nested local functions now work!

diffstat:

 sys/arch/i386/i386/trap.c |  13 ++++++++++---
 1 files changed, 10 insertions(+), 3 deletions(-)

diffs (41 lines):

diff -r 2a616cf64edc -r d6feba961143 sys/arch/i386/i386/trap.c
--- a/sys/arch/i386/i386/trap.c Sun Jan 10 15:21:36 2010 +0000
+++ b/sys/arch/i386/i386/trap.c Sun Jan 10 15:37:36 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: trap.c,v 1.251 2010/01/10 15:21:36 dsl Exp $   */
+/*     $NetBSD: trap.c,v 1.252 2010/01/10 15:37:36 dsl Exp $   */
 
 /*-
  * Copyright (c) 1998, 2000, 2005, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -68,7 +68,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.251 2010/01/10 15:21:36 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.252 2010/01/10 15:37:36 dsl Exp $");
 
 #include "opt_ddb.h"
 #include "opt_kgdb.h"
@@ -423,6 +423,11 @@
                         * the kernel address of the iret.
                         * We must copy the registers next to the userspace
                         * return address so we have a frame for md_regs.
+                        *
+                        * Also, we might have faulted trying to execute the
+                        * trampoline for a local (nested) signal handler.
+                        * If we change the %cs (eg to include the stack)
+                        * just return the return to user.
                         */
                        vframe = (void *)((int *)frame + 3);
                        if (KERNELMODE(vframe->tf_cs, vframe->tf_eflags))
@@ -431,7 +436,9 @@
                            offsetof(struct trapframe, tf_eip));
                        l->l_md.md_regs = vframe;
                        ksi.ksi_addr = (void *)vframe->tf_eip;
-                       (*p->p_emul->e_trapsignal)(l, &ksi);
+                       if (!pmap_exec_fixup(&p->p_vmspace->vm_map, vframe,
+                           lwp_getpcb(l)))
+                               (*p->p_emul->e_trapsignal)(l, &ksi);
                        trap_return_iret(vframe);
                        /* NOTREACHED */
                case 0x8e:



Home | Main Index | Thread Index | Old Index