More minor IPI work.
[dragonfly/vkernel-mp.git] / sys / platform / vkernel / i386 / exception.c
blob9f5983f96a17808f5fefb76338753dff2199ef36
2 /*
3 * Copyright (c) 2006 The DragonFly Project. All rights reserved.
4 *
5 * This code is derived from software contributed to The DragonFly Project
6 * by Matthew Dillon <dillon@backplane.com>
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 * 3. Neither the name of The DragonFly Project nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific, prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
30 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
35 * $DragonFly: src/sys/platform/vkernel/i386/exception.c,v 1.6 2007/06/17 16:46:15 dillon Exp $
38 #include "opt_ddb.h"
39 #include <sys/types.h>
40 #include <sys/systm.h>
41 #include <sys/reboot.h>
42 #include <sys/kernel.h>
43 #include <sys/kthread.h>
44 #include <sys/reboot.h>
45 #include <ddb/ddb.h>
47 #include <sys/thread2.h>
49 #include <machine/trap.h>
50 #include <machine/md_var.h>
51 #include <machine/segments.h>
53 #include <err.h>
54 #include <signal.h>
55 #include <unistd.h>
57 int _ucodesel = LSEL(LUCODE_SEL, SEL_UPL);
58 int _udatasel = LSEL(LUDATA_SEL, SEL_UPL);
60 static void exc_segfault(int signo, siginfo_t *info, void *ctx);
61 #ifdef DDB
62 static void exc_debugger(int signo, siginfo_t *info, void *ctx);
63 #endif
65 /* signal shutdown thread misc. */
67 static void sigshutdown_daemon( void );
68 static struct thread *sigshutdown_thread;
69 static struct kproc_desc sigshut_kp = {
70 "sigshutdown", sigshutdown_daemon, &sigshutdown_thread
73 static
74 void
75 ipi(int nada, siginfo_t *info, void *ctxp)
77 struct globaldata *gd = mycpu;
79 kprintf("ipi\n");
80 ++mycpu->gd_intr_nesting_level;
81 if (IN_CRITICAL_SECT(curthread)) {
82 kprintf("JAT: ipi in critical section\n");
83 gd->gd_reqflags &= RQF_IPIQ;
84 lwkt_process_ipiq();
85 } else {
86 kprintf("JAT: ipi NOT in critical section\n");
87 curthread->td_pri += TDPRI_CRIT;
88 lwkt_process_ipiq();
89 curthread->td_pri -= TDPRI_CRIT;
91 --mycpu->gd_intr_nesting_level;
95 void
96 init_exceptions(void)
98 struct sigaction sa;
100 bzero(&sa, sizeof(sa));
101 sa.sa_sigaction = exc_segfault;
102 sa.sa_flags |= SA_SIGINFO;
103 sigemptyset(&sa.sa_mask);
104 sigaction(SIGSEGV, &sa, NULL);
105 sigaction(SIGTRAP, &sa, NULL);
107 #ifdef DDB
108 sa.sa_sigaction = exc_debugger;
109 sigaction(SIGQUIT, &sa, NULL);
110 #endif
112 sa.sa_sigaction = ipi;
113 if (sigaction(SIGUSR1, &sa, NULL) != 0)
115 warn("ipi handler setup failed");
116 panic("IPI setup failed");
119 bzero(&sa, sizeof(sa));
120 sigemptyset(&sa.sa_mask);
121 sa.sa_flags |= SA_MAILBOX | SA_NODEFER;
122 sa.sa_mailbox = &mdcpu->gd_shutdown;
123 sigaction(SIGTERM, &sa, NULL);
127 * This function handles a segmentation fault.
129 * XXX We assume that trapframe is a subset of ucontext. It is as of
130 * this writing.
132 static void
133 exc_segfault(int signo, siginfo_t *info, void *ctxp)
135 ucontext_t *ctx = ctxp;
137 #if 0
138 kprintf("CAUGHT SEGFAULT EIP %08x ERR %08x TRAPNO %d err %d\n",
139 ctx->uc_mcontext.mc_eip,
140 ctx->uc_mcontext.mc_err,
141 ctx->uc_mcontext.mc_trapno & 0xFFFF,
142 ctx->uc_mcontext.mc_trapno >> 16);
143 #endif
144 kern_trap((struct trapframe *)&ctx->uc_mcontext.mc_gs);
145 splz();
149 * This function runs in a thread dedicated to external shutdown signals.
151 * Currently, when a vkernel recieves a SIGTERM, either the VKERNEL init(8)
152 * is signaled with SIGUSR2, or the VKERNEL simply shuts down, preventing
153 * fsck's when the VKERNEL is restarted.
155 static void
156 sigshutdown_daemon( void )
158 while (mdcpu->gd_shutdown == 0) {
159 tsleep(&mdcpu->gd_shutdown, 0, "sswait", 0);
161 mdcpu->gd_shutdown = 0;
162 kprintf("Caught SIGTERM from host system. Shutting down...\n");
163 if (initproc != NULL) {
164 ksignal(initproc, SIGUSR2);
166 else {
167 reboot(RB_POWEROFF);
170 SYSINIT(sigshutdown, SI_BOOT2_PROC0, SI_ORDER_ANY,
171 kproc_start, &sigshut_kp);
173 #ifdef DDB
175 static void
176 exc_debugger(int signo, siginfo_t *info, void *ctx)
178 Debugger("interrupt from console");
181 #endif