| @@ -1,519 +1,513 @@ | | | @@ -1,519 +1,513 @@ |
1 | /* $NetBSD: linux_machdep.c,v 1.50 2014/11/09 17:48:07 maxv Exp $ */ | | 1 | /* $NetBSD: linux_machdep.c,v 1.51 2020/09/03 14:26:31 thorpej Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 1998 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 1998 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Eric Haszlakiewicz. | | 8 | * by Eric Haszlakiewicz. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
15 | * 2. Redistributions in binary form must reproduce the above copyright | | 15 | * 2. Redistributions in binary form must reproduce the above copyright |
16 | * notice, this list of conditions and the following disclaimer in the | | 16 | * notice, this list of conditions and the following disclaimer in the |
17 | * documentation and/or other materials provided with the distribution. | | 17 | * documentation and/or other materials provided with the distribution. |
18 | * | | 18 | * |
19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | | 19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | | 20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | | 21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | | 22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
29 | * POSSIBILITY OF SUCH DAMAGE. | | 29 | * POSSIBILITY OF SUCH DAMAGE. |
30 | * | | 30 | * |
31 | * Based on sys/arch/i386/i386/linux_machdep.c: | | 31 | * Based on sys/arch/i386/i386/linux_machdep.c: |
32 | * linux_machdep.c,v 1.42 1998/09/11 12:50:06 mycroft Exp | | 32 | * linux_machdep.c,v 1.42 1998/09/11 12:50:06 mycroft Exp |
33 | * written by Frank van der Linden | | 33 | * written by Frank van der Linden |
34 | * | | 34 | * |
35 | */ | | 35 | */ |
36 | | | 36 | |
37 | #include <sys/cdefs.h> | | 37 | #include <sys/cdefs.h> |
38 | __KERNEL_RCSID(0, "$NetBSD: linux_machdep.c,v 1.50 2014/11/09 17:48:07 maxv Exp $"); | | 38 | __KERNEL_RCSID(0, "$NetBSD: linux_machdep.c,v 1.51 2020/09/03 14:26:31 thorpej Exp $"); |
39 | | | 39 | |
40 | #include <sys/param.h> | | 40 | #include <sys/param.h> |
41 | #include <sys/systm.h> | | 41 | #include <sys/systm.h> |
42 | #include <sys/signalvar.h> | | 42 | #include <sys/signalvar.h> |
43 | #include <sys/kernel.h> | | 43 | #include <sys/kernel.h> |
44 | #include <sys/proc.h> | | 44 | #include <sys/proc.h> |
45 | #include <sys/buf.h> | | 45 | #include <sys/buf.h> |
46 | #include <sys/reboot.h> | | 46 | #include <sys/reboot.h> |
47 | #include <sys/conf.h> | | 47 | #include <sys/conf.h> |
48 | #include <sys/exec.h> | | 48 | #include <sys/exec.h> |
49 | #include <sys/file.h> | | 49 | #include <sys/file.h> |
50 | #include <sys/callout.h> | | 50 | #include <sys/callout.h> |
51 | #include <sys/mbuf.h> | | 51 | #include <sys/mbuf.h> |
52 | #include <sys/msgbuf.h> | | 52 | #include <sys/msgbuf.h> |
53 | #include <sys/mount.h> | | 53 | #include <sys/mount.h> |
54 | #include <sys/vnode.h> | | 54 | #include <sys/vnode.h> |
55 | #include <sys/device.h> | | 55 | #include <sys/device.h> |
56 | #include <sys/syscallargs.h> | | 56 | #include <sys/syscallargs.h> |
57 | #include <sys/filedesc.h> | | 57 | #include <sys/filedesc.h> |
58 | #include <sys/exec_elf.h> | | 58 | #include <sys/exec_elf.h> |
59 | #include <sys/ioctl.h> | | 59 | #include <sys/ioctl.h> |
60 | #include <sys/kauth.h> | | 60 | #include <sys/kauth.h> |
61 | | | 61 | |
62 | #include <uvm/uvm_extern.h> | | 62 | #include <uvm/uvm_extern.h> |
63 | | | 63 | |
64 | #include <compat/linux/common/linux_types.h> | | 64 | #include <compat/linux/common/linux_types.h> |
65 | #include <compat/linux/common/linux_signal.h> | | 65 | #include <compat/linux/common/linux_signal.h> |
66 | #include <compat/linux/common/linux_siginfo.h> | | 66 | #include <compat/linux/common/linux_siginfo.h> |
67 | #include <compat/linux/common/linux_util.h> | | 67 | #include <compat/linux/common/linux_util.h> |
68 | #include <compat/linux/common/linux_ioctl.h> | | 68 | #include <compat/linux/common/linux_ioctl.h> |
69 | #include <compat/linux/common/linux_exec.h> | | 69 | #include <compat/linux/common/linux_exec.h> |
70 | #include <compat/linux/common/linux_machdep.h> | | 70 | #include <compat/linux/common/linux_machdep.h> |
71 | #include <compat/linux/common/linux_emuldata.h> | | 71 | #include <compat/linux/common/linux_emuldata.h> |
72 | | | 72 | |
73 | #include <compat/linux/linux_syscallargs.h> | | 73 | #include <compat/linux/linux_syscallargs.h> |
74 | | | 74 | |
75 | #include <machine/alpha.h> | | 75 | #include <machine/alpha.h> |
76 | #include <machine/reg.h> | | 76 | #include <machine/reg.h> |
77 | | | 77 | |
78 | #if defined(_KERNEL_OPT) | | 78 | #if defined(_KERNEL_OPT) |
79 | #include "wsdisplay.h" | | 79 | #include "wsdisplay.h" |
80 | #endif | | 80 | #endif |
81 | #if (NWSDISPLAY >0) | | 81 | #if (NWSDISPLAY >0) |
82 | #include <dev/wscons/wsdisplay_usl_io.h> | | 82 | #include <dev/wscons/wsdisplay_usl_io.h> |
83 | #endif | | 83 | #endif |
84 | #ifdef DEBUG | | 84 | #ifdef DEBUG |
85 | #include <machine/sigdebug.h> | | 85 | #include <machine/sigdebug.h> |
86 | #endif | | 86 | #endif |
87 | | | 87 | |
88 | /* | | 88 | /* |
89 | * Deal with some alpha-specific things in the Linux emulation code. | | 89 | * Deal with some alpha-specific things in the Linux emulation code. |
90 | */ | | 90 | */ |
91 | | | 91 | |
92 | void | | 92 | void |
93 | linux_setregs(struct lwp *l, struct exec_package *epp, vaddr_t stack) | | 93 | linux_setregs(struct lwp *l, struct exec_package *epp, vaddr_t stack) |
94 | { | | 94 | { |
95 | #ifdef DEBUG | | 95 | #ifdef DEBUG |
96 | struct trapframe *tfp = l->l_md.md_tf; | | 96 | struct trapframe *tfp = l->l_md.md_tf; |
97 | #endif | | 97 | #endif |
98 | | | 98 | |
99 | setregs(l, epp, stack); | | 99 | setregs(l, epp, stack); |
100 | #ifdef DEBUG | | 100 | #ifdef DEBUG |
101 | /* | | 101 | /* |
102 | * Linux has registers set to zero on entry; for DEBUG kernels | | 102 | * Linux has registers set to zero on entry; for DEBUG kernels |
103 | * the alpha setregs() fills registers with 0xbabefacedeadbeef. | | 103 | * the alpha setregs() fills registers with 0xbabefacedeadbeef. |
104 | */ | | 104 | */ |
105 | memset(tfp->tf_regs, 0, FRAME_SIZE * sizeof tfp->tf_regs[0]); | | 105 | memset(tfp->tf_regs, 0, FRAME_SIZE * sizeof tfp->tf_regs[0]); |
106 | #endif | | 106 | #endif |
107 | } | | 107 | } |
108 | | | 108 | |
109 | void | | 109 | void |
110 | setup_linux_rt_sigframe(struct trapframe *tf, const ksiginfo_t *ksi, | | 110 | setup_linux_rt_sigframe(struct trapframe *tf, const ksiginfo_t *ksi, |
111 | const sigset_t *mask) | | 111 | const sigset_t *mask) |
112 | { | | 112 | { |
113 | struct lwp *l = curlwp; | | 113 | struct lwp *l = curlwp; |
114 | struct proc *p = l->l_proc; | | 114 | struct proc *p = l->l_proc; |
115 | struct linux_rt_sigframe *sfp, sigframe; | | 115 | struct linux_rt_sigframe *sfp, sigframe; |
116 | int onstack, error; | | 116 | int onstack, error; |
117 | int fsize, rndfsize; | | 117 | int fsize, rndfsize; |
118 | int sig = ksi->ksi_signo; | | 118 | int sig = ksi->ksi_signo; |
119 | extern char linux_rt_sigcode[], linux_rt_esigcode[]; | | 119 | extern char linux_rt_sigcode[], linux_rt_esigcode[]; |
120 | | | 120 | |
121 | /* Do we need to jump onto the signal stack? */ | | 121 | /* Do we need to jump onto the signal stack? */ |
122 | onstack = (l->l_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 && | | 122 | onstack = (l->l_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 && |
123 | (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0; | | 123 | (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0; |
124 | | | 124 | |
125 | /* Allocate space for the signal handler context. */ | | 125 | /* Allocate space for the signal handler context. */ |
126 | fsize = sizeof(struct linux_rt_sigframe); | | 126 | fsize = sizeof(struct linux_rt_sigframe); |
127 | rndfsize = ((fsize + 15) / 16) * 16; | | 127 | rndfsize = ((fsize + 15) / 16) * 16; |
128 | | | 128 | |
129 | if (onstack) | | 129 | if (onstack) |
130 | sfp = (struct linux_rt_sigframe *) | | 130 | sfp = (struct linux_rt_sigframe *) |
131 | ((char *)l->l_sigstk.ss_sp + l->l_sigstk.ss_size); | | 131 | ((char *)l->l_sigstk.ss_sp + l->l_sigstk.ss_size); |
132 | else | | 132 | else |
133 | sfp = (struct linux_rt_sigframe *)(alpha_pal_rdusp()); | | 133 | sfp = (struct linux_rt_sigframe *)(alpha_pal_rdusp()); |
134 | sfp = (struct linux_rt_sigframe *)((char *)sfp - rndfsize); | | 134 | sfp = (struct linux_rt_sigframe *)((char *)sfp - rndfsize); |
135 | | | 135 | |
136 | #ifdef DEBUG | | 136 | #ifdef DEBUG |
137 | if ((sigdebug & SDB_KSTACK) && (p->p_pid == sigpid)) | | 137 | if ((sigdebug & SDB_KSTACK) && (p->p_pid == sigpid)) |
138 | printf("linux_sendsig(%d): sig %d ssp %p usp %p\n", p->p_pid, | | 138 | printf("linux_sendsig(%d): sig %d ssp %p usp %p\n", p->p_pid, |
139 | sig, &onstack, sfp); | | 139 | sig, &onstack, sfp); |
140 | #endif /* DEBUG */ | | 140 | #endif /* DEBUG */ |
141 | | | 141 | |
142 | /* | | 142 | /* |
143 | * Build the signal context to be used by sigreturn. | | 143 | * Build the signal context to be used by sigreturn. |
144 | */ | | 144 | */ |
145 | memset(&sigframe.uc, 0, sizeof(struct linux_ucontext)); | | 145 | memset(&sigframe.uc, 0, sizeof(struct linux_ucontext)); |
146 | sigframe.uc.uc_mcontext.sc_onstack = onstack; | | 146 | sigframe.uc.uc_mcontext.sc_onstack = onstack; |
147 | | | 147 | |
148 | /* Setup potentially partial signal mask in sc_mask. */ | | 148 | /* Setup potentially partial signal mask in sc_mask. */ |
149 | /* But get all of it in uc_sigmask */ | | 149 | /* But get all of it in uc_sigmask */ |
150 | native_to_linux_old_sigset(&sigframe.uc.uc_mcontext.sc_mask, mask); | | 150 | native_to_linux_old_sigset(&sigframe.uc.uc_mcontext.sc_mask, mask); |
151 | native_to_linux_sigset(&sigframe.uc.uc_sigmask, mask); | | 151 | native_to_linux_sigset(&sigframe.uc.uc_sigmask, mask); |
152 | | | 152 | |
153 | sigframe.uc.uc_mcontext.sc_pc = tf->tf_regs[FRAME_PC]; | | 153 | sigframe.uc.uc_mcontext.sc_pc = tf->tf_regs[FRAME_PC]; |
154 | sigframe.uc.uc_mcontext.sc_ps = ALPHA_PSL_USERMODE; | | 154 | sigframe.uc.uc_mcontext.sc_ps = ALPHA_PSL_USERMODE; |
155 | frametoreg(tf, (struct reg *)sigframe.uc.uc_mcontext.sc_regs); | | 155 | frametoreg(tf, (struct reg *)sigframe.uc.uc_mcontext.sc_regs); |
156 | sigframe.uc.uc_mcontext.sc_regs[R_SP] = alpha_pal_rdusp(); | | 156 | sigframe.uc.uc_mcontext.sc_regs[R_SP] = alpha_pal_rdusp(); |
157 | | | 157 | |
158 | fpu_load(); | | 158 | fpu_load(); |
159 | alpha_pal_wrfen(1); | | 159 | alpha_pal_wrfen(1); |
160 | sigframe.uc.uc_mcontext.sc_fpcr = alpha_read_fpcr(); | | 160 | sigframe.uc.uc_mcontext.sc_fpcr = alpha_read_fpcr(); |
161 | sigframe.uc.uc_mcontext.sc_fp_control = alpha_read_fp_c(l); | | 161 | sigframe.uc.uc_mcontext.sc_fp_control = alpha_read_fp_c(l); |
162 | alpha_pal_wrfen(0); | | 162 | alpha_pal_wrfen(0); |
163 | | | 163 | |
164 | sigframe.uc.uc_mcontext.sc_traparg_a0 = tf->tf_regs[FRAME_A0]; | | 164 | sigframe.uc.uc_mcontext.sc_traparg_a0 = tf->tf_regs[FRAME_A0]; |
165 | sigframe.uc.uc_mcontext.sc_traparg_a1 = tf->tf_regs[FRAME_A1]; | | 165 | sigframe.uc.uc_mcontext.sc_traparg_a1 = tf->tf_regs[FRAME_A1]; |
166 | sigframe.uc.uc_mcontext.sc_traparg_a2 = tf->tf_regs[FRAME_A2]; | | 166 | sigframe.uc.uc_mcontext.sc_traparg_a2 = tf->tf_regs[FRAME_A2]; |
167 | native_to_linux_siginfo(&sigframe.info, &ksi->ksi_info); | | 167 | native_to_linux_siginfo(&sigframe.info, &ksi->ksi_info); |
168 | sendsig_reset(l, sig); | | 168 | sendsig_reset(l, sig); |
169 | mutex_exit(p->p_lock); | | 169 | mutex_exit(p->p_lock); |
170 | error = copyout((void *)&sigframe, (void *)sfp, fsize); | | 170 | error = copyout((void *)&sigframe, (void *)sfp, fsize); |
171 | mutex_enter(p->p_lock); | | 171 | mutex_enter(p->p_lock); |
172 | | | 172 | |
173 | if (error != 0) { | | 173 | if (error != 0) { |
174 | #ifdef DEBUG | | 174 | #ifdef DEBUG |
175 | if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) | | 175 | if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) |
176 | printf("sendsig(%d): copyout failed on sig %d\n", | | 176 | printf("sendsig(%d): copyout failed on sig %d\n", |
177 | p->p_pid, sig); | | 177 | p->p_pid, sig); |
178 | #endif | | 178 | #endif |
179 | /* | | 179 | /* |
180 | * Process has trashed its stack; give it an illegal | | 180 | * Process has trashed its stack; give it an illegal |
181 | * instruction to halt it in its tracks. | | 181 | * instruction to halt it in its tracks. |
182 | */ | | 182 | */ |
183 | sigexit(l, SIGILL); | | 183 | sigexit(l, SIGILL); |
184 | /* NOTREACHED */ | | 184 | /* NOTREACHED */ |
185 | } | | 185 | } |
186 | | | 186 | |
187 | /* Pass pointers to siginfo and ucontext in the regs */ | | 187 | /* Pass pointers to siginfo and ucontext in the regs */ |
188 | tf->tf_regs[FRAME_A1] = (unsigned long)&sfp->info; | | 188 | tf->tf_regs[FRAME_A1] = (unsigned long)&sfp->info; |
189 | tf->tf_regs[FRAME_A2] = (unsigned long)&sfp->uc; | | 189 | tf->tf_regs[FRAME_A2] = (unsigned long)&sfp->uc; |
190 | | | 190 | |
191 | /* Address of trampoline code. End up at this PC after mi_switch */ | | 191 | /* Address of trampoline code. End up at this PC after mi_switch */ |
192 | tf->tf_regs[FRAME_PC] = | | 192 | tf->tf_regs[FRAME_PC] = |
193 | (u_int64_t)(p->p_psstrp - (linux_rt_esigcode - linux_rt_sigcode)); | | 193 | (u_int64_t)(p->p_psstrp - (linux_rt_esigcode - linux_rt_sigcode)); |
194 | | | 194 | |
195 | /* Adjust the stack */ | | 195 | /* Adjust the stack */ |
196 | alpha_pal_wrusp((unsigned long)sfp); | | 196 | alpha_pal_wrusp((unsigned long)sfp); |
197 | | | 197 | |
198 | /* Remember that we're now on the signal stack. */ | | 198 | /* Remember that we're now on the signal stack. */ |
199 | if (onstack) | | 199 | if (onstack) |
200 | l->l_sigstk.ss_flags |= SS_ONSTACK; | | 200 | l->l_sigstk.ss_flags |= SS_ONSTACK; |
201 | } | | 201 | } |
202 | | | 202 | |
203 | void setup_linux_sigframe(struct trapframe *tf, const ksiginfo_t *ksi, | | 203 | void setup_linux_sigframe(struct trapframe *tf, const ksiginfo_t *ksi, |
204 | const sigset_t *mask) | | 204 | const sigset_t *mask) |
205 | { | | 205 | { |
206 | struct lwp *l = curlwp; | | 206 | struct lwp *l = curlwp; |
207 | struct proc *p = l->l_proc; | | 207 | struct proc *p = l->l_proc; |
208 | struct linux_sigframe *sfp, sigframe; | | 208 | struct linux_sigframe *sfp, sigframe; |
209 | int onstack, error; | | 209 | int onstack, error; |
210 | int fsize, rndfsize; | | 210 | int fsize, rndfsize; |
211 | int sig = ksi->ksi_signo; | | 211 | int sig = ksi->ksi_signo; |
212 | extern char linux_sigcode[], linux_esigcode[]; | | 212 | extern char linux_sigcode[], linux_esigcode[]; |
213 | | | 213 | |
214 | /* Do we need to jump onto the signal stack? */ | | 214 | /* Do we need to jump onto the signal stack? */ |
215 | onstack = (l->l_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 && | | 215 | onstack = (l->l_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 && |
216 | (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0; | | 216 | (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0; |
217 | | | 217 | |
218 | /* Allocate space for the signal handler context. */ | | 218 | /* Allocate space for the signal handler context. */ |
219 | fsize = sizeof(struct linux_sigframe); | | 219 | fsize = sizeof(struct linux_sigframe); |
220 | rndfsize = ((fsize + 15) / 16) * 16; | | 220 | rndfsize = ((fsize + 15) / 16) * 16; |
221 | | | 221 | |
222 | if (onstack) | | 222 | if (onstack) |
223 | sfp = (struct linux_sigframe *) | | 223 | sfp = (struct linux_sigframe *) |
224 | ((char *)l->l_sigstk.ss_sp + l->l_sigstk.ss_size); | | 224 | ((char *)l->l_sigstk.ss_sp + l->l_sigstk.ss_size); |
225 | else | | 225 | else |
226 | sfp = (struct linux_sigframe *)(alpha_pal_rdusp()); | | 226 | sfp = (struct linux_sigframe *)(alpha_pal_rdusp()); |
227 | sfp = (struct linux_sigframe *)((char *)sfp - rndfsize); | | 227 | sfp = (struct linux_sigframe *)((char *)sfp - rndfsize); |
228 | | | 228 | |
229 | #ifdef DEBUG | | 229 | #ifdef DEBUG |
230 | if ((sigdebug & SDB_KSTACK) && (p->p_pid == sigpid)) | | 230 | if ((sigdebug & SDB_KSTACK) && (p->p_pid == sigpid)) |
231 | printf("linux_sendsig(%d): sig %d ssp %p usp %p\n", p->p_pid, | | 231 | printf("linux_sendsig(%d): sig %d ssp %p usp %p\n", p->p_pid, |
232 | sig, &onstack, sfp); | | 232 | sig, &onstack, sfp); |
233 | #endif /* DEBUG */ | | 233 | #endif /* DEBUG */ |
234 | | | 234 | |
235 | /* | | 235 | /* |
236 | * Build the signal context to be used by sigreturn. | | 236 | * Build the signal context to be used by sigreturn. |
237 | */ | | 237 | */ |
238 | memset(&sigframe.sf_sc, 0, sizeof(struct linux_sigcontext)); | | 238 | memset(&sigframe.sf_sc, 0, sizeof(struct linux_sigcontext)); |
239 | sigframe.sf_sc.sc_onstack = onstack; | | 239 | sigframe.sf_sc.sc_onstack = onstack; |
240 | native_to_linux_old_sigset(&sigframe.sf_sc.sc_mask, mask); | | 240 | native_to_linux_old_sigset(&sigframe.sf_sc.sc_mask, mask); |
241 | sigframe.sf_sc.sc_pc = tf->tf_regs[FRAME_PC]; | | 241 | sigframe.sf_sc.sc_pc = tf->tf_regs[FRAME_PC]; |
242 | sigframe.sf_sc.sc_ps = ALPHA_PSL_USERMODE; | | 242 | sigframe.sf_sc.sc_ps = ALPHA_PSL_USERMODE; |
243 | frametoreg(tf, (struct reg *)sigframe.sf_sc.sc_regs); | | 243 | frametoreg(tf, (struct reg *)sigframe.sf_sc.sc_regs); |
244 | sigframe.sf_sc.sc_regs[R_SP] = alpha_pal_rdusp(); | | 244 | sigframe.sf_sc.sc_regs[R_SP] = alpha_pal_rdusp(); |
245 | | | 245 | |
246 | if (l == fpcurlwp) { | | 246 | if (fpu_valid_p(l)) { |
247 | struct pcb *pcb = lwp_getpcb(l); | | 247 | struct pcb *pcb = lwp_getpcb(l); |
248 | | | 248 | |
249 | alpha_pal_wrfen(1); | | 249 | fpu_save(l); |
250 | savefpstate(&pcb->pcb_fp); | | | |
251 | alpha_pal_wrfen(0); | | | |
252 | sigframe.sf_sc.sc_fpcr = pcb->pcb_fp.fpr_cr; | | 250 | sigframe.sf_sc.sc_fpcr = pcb->pcb_fp.fpr_cr; |
253 | fpcurlwp = NULL; | | | |
254 | } | | 251 | } |
255 | /* XXX ownedfp ? etc...? */ | | 252 | /* XXX ownedfp ? etc...? */ |
256 | | | 253 | |
257 | sigframe.sf_sc.sc_traparg_a0 = tf->tf_regs[FRAME_A0]; | | 254 | sigframe.sf_sc.sc_traparg_a0 = tf->tf_regs[FRAME_A0]; |
258 | sigframe.sf_sc.sc_traparg_a1 = tf->tf_regs[FRAME_A1]; | | 255 | sigframe.sf_sc.sc_traparg_a1 = tf->tf_regs[FRAME_A1]; |
259 | sigframe.sf_sc.sc_traparg_a2 = tf->tf_regs[FRAME_A2]; | | 256 | sigframe.sf_sc.sc_traparg_a2 = tf->tf_regs[FRAME_A2]; |
260 | | | 257 | |
261 | sendsig_reset(l, sig); | | 258 | sendsig_reset(l, sig); |
262 | mutex_exit(p->p_lock); | | 259 | mutex_exit(p->p_lock); |
263 | error = copyout((void *)&sigframe, (void *)sfp, fsize); | | 260 | error = copyout((void *)&sigframe, (void *)sfp, fsize); |
264 | mutex_enter(p->p_lock); | | 261 | mutex_enter(p->p_lock); |
265 | | | 262 | |
266 | if (error != 0) { | | 263 | if (error != 0) { |
267 | #ifdef DEBUG | | 264 | #ifdef DEBUG |
268 | if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) | | 265 | if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) |
269 | printf("sendsig(%d): copyout failed on sig %d\n", | | 266 | printf("sendsig(%d): copyout failed on sig %d\n", |
270 | p->p_pid, sig); | | 267 | p->p_pid, sig); |
271 | #endif | | 268 | #endif |
272 | /* | | 269 | /* |
273 | * Process has trashed its stack; give it an illegal | | 270 | * Process has trashed its stack; give it an illegal |
274 | * instruction to halt it in its tracks. | | 271 | * instruction to halt it in its tracks. |
275 | */ | | 272 | */ |
276 | sigexit(l, SIGILL); | | 273 | sigexit(l, SIGILL); |
277 | /* NOTREACHED */ | | 274 | /* NOTREACHED */ |
278 | } | | 275 | } |
279 | | | 276 | |
280 | /* Pass pointers to sigcontext in the regs */ | | 277 | /* Pass pointers to sigcontext in the regs */ |
281 | tf->tf_regs[FRAME_A1] = 0; | | 278 | tf->tf_regs[FRAME_A1] = 0; |
282 | tf->tf_regs[FRAME_A2] = (unsigned long)&sfp->sf_sc; | | 279 | tf->tf_regs[FRAME_A2] = (unsigned long)&sfp->sf_sc; |
283 | | | 280 | |
284 | /* Address of trampoline code. End up at this PC after mi_switch */ | | 281 | /* Address of trampoline code. End up at this PC after mi_switch */ |
285 | tf->tf_regs[FRAME_PC] = | | 282 | tf->tf_regs[FRAME_PC] = |
286 | (u_int64_t)(p->p_psstrp - (linux_esigcode - linux_sigcode)); | | 283 | (u_int64_t)(p->p_psstrp - (linux_esigcode - linux_sigcode)); |
287 | | | 284 | |
288 | /* Adjust the stack */ | | 285 | /* Adjust the stack */ |
289 | alpha_pal_wrusp((unsigned long)sfp); | | 286 | alpha_pal_wrusp((unsigned long)sfp); |
290 | | | 287 | |
291 | /* Remember that we're now on the signal stack. */ | | 288 | /* Remember that we're now on the signal stack. */ |
292 | if (onstack) | | 289 | if (onstack) |
293 | l->l_sigstk.ss_flags |= SS_ONSTACK; | | 290 | l->l_sigstk.ss_flags |= SS_ONSTACK; |
294 | } | | 291 | } |
295 | | | 292 | |
296 | /* | | 293 | /* |
297 | * Send an interrupt to process. | | 294 | * Send an interrupt to process. |
298 | * | | 295 | * |
299 | * Stack is set up to allow sigcode stored | | 296 | * Stack is set up to allow sigcode stored |
300 | * in u. to call routine, followed by kcall | | 297 | * in u. to call routine, followed by kcall |
301 | * to sigreturn routine below. After sigreturn | | 298 | * to sigreturn routine below. After sigreturn |
302 | * resets the signal mask, the stack, and the | | 299 | * resets the signal mask, the stack, and the |
303 | * frame pointer, it returns to the user | | 300 | * frame pointer, it returns to the user |
304 | * specified pc, psl. | | 301 | * specified pc, psl. |
305 | */ | | 302 | */ |
306 | void | | 303 | void |
307 | linux_sendsig(const ksiginfo_t *ksi, const sigset_t *mask) | | 304 | linux_sendsig(const ksiginfo_t *ksi, const sigset_t *mask) |
308 | { | | 305 | { |
309 | struct lwp *l = curlwp; | | 306 | struct lwp *l = curlwp; |
310 | struct proc *p = l->l_proc; | | 307 | struct proc *p = l->l_proc; |
311 | struct trapframe *tf = l->l_md.md_tf; | | 308 | struct trapframe *tf = l->l_md.md_tf; |
312 | const int sig = ksi->ksi_signo; | | 309 | const int sig = ksi->ksi_signo; |
313 | sig_t catcher = SIGACTION(p, sig).sa_handler; | | 310 | sig_t catcher = SIGACTION(p, sig).sa_handler; |
314 | #ifdef notyet | | 311 | #ifdef notyet |
315 | struct linux_emuldata *edp; | | 312 | struct linux_emuldata *edp; |
316 | | | 313 | |
317 | /* Setup the signal frame (and part of the trapframe) */ | | 314 | /* Setup the signal frame (and part of the trapframe) */ |
318 | /*OLD: if (p->p_sigacts->ps_siginfo & sigmask(sig))*/ | | 315 | /*OLD: if (p->p_sigacts->ps_siginfo & sigmask(sig))*/ |
319 | /* XXX XAX this is broken now. need someplace to store what | | 316 | /* XXX XAX this is broken now. need someplace to store what |
320 | XXX XAX kind of signal handler a signal has.*/ | | 317 | XXX XAX kind of signal handler a signal has.*/ |
321 | #if 0 | | 318 | #if 0 |
322 | edp = (struct linux_emuldata *)p->p_emuldata; | | 319 | edp = (struct linux_emuldata *)p->p_emuldata; |
323 | #else | | 320 | #else |
324 | edp = 0; | | 321 | edp = 0; |
325 | #endif | | 322 | #endif |
326 | if (edp && sigismember(&edp->ps_siginfo, sig)) | | 323 | if (edp && sigismember(&edp->ps_siginfo, sig)) |
327 | setup_linux_rt_sigframe(tf, ksi, mask); | | 324 | setup_linux_rt_sigframe(tf, ksi, mask); |
328 | else | | 325 | else |
329 | #endif /* notyet */ | | 326 | #endif /* notyet */ |
330 | setup_linux_sigframe(tf, ksi, mask); | | 327 | setup_linux_sigframe(tf, ksi, mask); |
331 | | | 328 | |
332 | /* Signal handler for trampoline code */ | | 329 | /* Signal handler for trampoline code */ |
333 | tf->tf_regs[FRAME_T12] = (u_int64_t)catcher; | | 330 | tf->tf_regs[FRAME_T12] = (u_int64_t)catcher; |
334 | tf->tf_regs[FRAME_A0] = native_to_linux_signo[sig]; | | 331 | tf->tf_regs[FRAME_A0] = native_to_linux_signo[sig]; |
335 | | | 332 | |
336 | /* | | 333 | /* |
337 | * Linux has a custom restorer option. To support it we would | | 334 | * Linux has a custom restorer option. To support it we would |
338 | * need to store an array of restorers and a sigcode block | | 335 | * need to store an array of restorers and a sigcode block |
339 | * which knew to use it. Doesn't seem worth the trouble. | | 336 | * which knew to use it. Doesn't seem worth the trouble. |
340 | * -erh | | 337 | * -erh |
341 | */ | | 338 | */ |
342 | | | 339 | |
343 | #ifdef DEBUG | | 340 | #ifdef DEBUG |
344 | if (sigdebug & SDB_FOLLOW) | | 341 | if (sigdebug & SDB_FOLLOW) |
345 | printf("sendsig(%d): pc %lx, catcher %lx\n", l->l_proc->p_pid, | | 342 | printf("sendsig(%d): pc %lx, catcher %lx\n", l->l_proc->p_pid, |
346 | tf->tf_regs[FRAME_PC], tf->tf_regs[FRAME_A3]); | | 343 | tf->tf_regs[FRAME_PC], tf->tf_regs[FRAME_A3]); |
347 | if ((sigdebug & SDB_KSTACK) && l->l_proc->p_pid == sigpid) | | 344 | if ((sigdebug & SDB_KSTACK) && l->l_proc->p_pid == sigpid) |
348 | printf("sendsig(%d): sig %d returns\n", l->l_proc->p_pid, sig); | | 345 | printf("sendsig(%d): sig %d returns\n", l->l_proc->p_pid, sig); |
349 | #endif | | 346 | #endif |
350 | } | | 347 | } |
351 | | | 348 | |
352 | /* | | 349 | /* |
353 | * System call to cleanup state after a signal | | 350 | * System call to cleanup state after a signal |
354 | * has been taken. Reset signal mask and | | 351 | * has been taken. Reset signal mask and |
355 | * stack state from context left by sendsig (above). | | 352 | * stack state from context left by sendsig (above). |
356 | * Return to previous pc as specified by context | | 353 | * Return to previous pc as specified by context |
357 | * left by sendsig. | | 354 | * left by sendsig. |
358 | * Linux real-time signals use a different sigframe, | | 355 | * Linux real-time signals use a different sigframe, |
359 | * but the sigcontext is the same. | | 356 | * but the sigcontext is the same. |
360 | */ | | 357 | */ |
361 | | | 358 | |
362 | int | | 359 | int |
363 | linux_restore_sigcontext(struct lwp *l, struct linux_sigcontext context, | | 360 | linux_restore_sigcontext(struct lwp *l, struct linux_sigcontext context, |
364 | sigset_t *mask) | | 361 | sigset_t *mask) |
365 | { | | 362 | { |
366 | struct proc *p = l->l_proc; | | 363 | struct proc *p = l->l_proc; |
367 | struct pcb *pcb; | | 364 | struct pcb *pcb; |
368 | | | 365 | |
369 | /* | | 366 | /* |
370 | * Linux doesn't (yet) have alternate signal stacks. | | 367 | * Linux doesn't (yet) have alternate signal stacks. |
371 | * However, the OSF/1 sigcontext which they use has | | 368 | * However, the OSF/1 sigcontext which they use has |
372 | * an onstack member. This could be needed in the future. | | 369 | * an onstack member. This could be needed in the future. |
373 | */ | | 370 | */ |
374 | mutex_enter(p->p_lock); | | 371 | mutex_enter(p->p_lock); |
375 | if (context.sc_onstack & LINUX_SA_ONSTACK) | | 372 | if (context.sc_onstack & LINUX_SA_ONSTACK) |
376 | l->l_sigstk.ss_flags |= SS_ONSTACK; | | 373 | l->l_sigstk.ss_flags |= SS_ONSTACK; |
377 | else | | 374 | else |
378 | l->l_sigstk.ss_flags &= ~SS_ONSTACK; | | 375 | l->l_sigstk.ss_flags &= ~SS_ONSTACK; |
379 | | | 376 | |
380 | /* Reset the signal mask */ | | 377 | /* Reset the signal mask */ |
381 | (void) sigprocmask1(l, SIG_SETMASK, mask, 0); | | 378 | (void) sigprocmask1(l, SIG_SETMASK, mask, 0); |
382 | mutex_exit(p->p_lock); | | 379 | mutex_exit(p->p_lock); |
383 | | | 380 | |
384 | /* | | 381 | /* |
385 | * Check for security violations. | | 382 | * Check for security violations. |
386 | * Linux doesn't allow any changes to the PSL. | | 383 | * Linux doesn't allow any changes to the PSL. |
387 | */ | | 384 | */ |
388 | if (context.sc_ps != ALPHA_PSL_USERMODE) | | 385 | if (context.sc_ps != ALPHA_PSL_USERMODE) |
389 | return(EINVAL); | | 386 | return(EINVAL); |
390 | | | 387 | |
391 | l->l_md.md_tf->tf_regs[FRAME_PC] = context.sc_pc; | | 388 | l->l_md.md_tf->tf_regs[FRAME_PC] = context.sc_pc; |
392 | l->l_md.md_tf->tf_regs[FRAME_PS] = context.sc_ps; | | 389 | l->l_md.md_tf->tf_regs[FRAME_PS] = context.sc_ps; |
393 | | | 390 | |
394 | regtoframe((struct reg *)context.sc_regs, l->l_md.md_tf); | | 391 | regtoframe((struct reg *)context.sc_regs, l->l_md.md_tf); |
395 | alpha_pal_wrusp(context.sc_regs[R_SP]); | | 392 | alpha_pal_wrusp(context.sc_regs[R_SP]); |
396 | | | 393 | |
397 | if (l == fpcurlwp) | | | |
398 | fpcurlwp = NULL; | | | |
399 | | | | |
400 | /* Restore fp regs and fpr_cr */ | | 394 | /* Restore fp regs and fpr_cr */ |
401 | pcb = lwp_getpcb(l); | | 395 | pcb = lwp_getpcb(l); |
402 | memcpy(&pcb->pcb_fp, (struct fpreg *)context.sc_fpregs, | | 396 | memcpy(&pcb->pcb_fp, (struct fpreg *)context.sc_fpregs, |
403 | sizeof(struct fpreg)); | | 397 | sizeof(struct fpreg)); |
404 | /* XXX sc_ownedfp ? */ | | 398 | /* XXX sc_ownedfp ? */ |
405 | /* XXX sc_fp_control ? */ | | 399 | /* XXX sc_fp_control ? */ |
406 | | | 400 | |
407 | #ifdef DEBUG | | 401 | #ifdef DEBUG |
408 | if (sigdebug & SDB_FOLLOW) | | 402 | if (sigdebug & SDB_FOLLOW) |
409 | printf("linux_rt_sigreturn(%d): returns\n", p->p_pid); | | 403 | printf("linux_rt_sigreturn(%d): returns\n", p->p_pid); |
410 | #endif | | 404 | #endif |
411 | return (EJUSTRETURN); | | 405 | return (EJUSTRETURN); |
412 | } | | 406 | } |
413 | | | 407 | |
414 | int | | 408 | int |
415 | linux_sys_rt_sigreturn(struct lwp *l, const struct linux_sys_rt_sigreturn_args *uap, register_t *retval) | | 409 | linux_sys_rt_sigreturn(struct lwp *l, const struct linux_sys_rt_sigreturn_args *uap, register_t *retval) |
416 | { | | 410 | { |
417 | /* { | | 411 | /* { |
418 | syscallarg(struct linux_rt_sigframe *) sfp; | | 412 | syscallarg(struct linux_rt_sigframe *) sfp; |
419 | } */ | | 413 | } */ |
420 | struct linux_rt_sigframe *sfp, sigframe; | | 414 | struct linux_rt_sigframe *sfp, sigframe; |
421 | sigset_t mask; | | 415 | sigset_t mask; |
422 | | | 416 | |
423 | /* | | 417 | /* |
424 | * The trampoline code hands us the context. | | 418 | * The trampoline code hands us the context. |
425 | * It is unsafe to keep track of it ourselves, in the event that a | | 419 | * It is unsafe to keep track of it ourselves, in the event that a |
426 | * program jumps out of a signal handler. | | 420 | * program jumps out of a signal handler. |
427 | */ | | 421 | */ |
428 | | | 422 | |
429 | sfp = SCARG(uap, sfp); | | 423 | sfp = SCARG(uap, sfp); |
430 | | | 424 | |
431 | if (ALIGN(sfp) != (u_int64_t)sfp) | | 425 | if (ALIGN(sfp) != (u_int64_t)sfp) |
432 | return(EINVAL); | | 426 | return(EINVAL); |
433 | | | 427 | |
434 | /* | | 428 | /* |
435 | * Fetch the frame structure. | | 429 | * Fetch the frame structure. |
436 | */ | | 430 | */ |
437 | if (copyin((void *)sfp, &sigframe, | | 431 | if (copyin((void *)sfp, &sigframe, |
438 | sizeof(struct linux_rt_sigframe)) != 0) | | 432 | sizeof(struct linux_rt_sigframe)) != 0) |
439 | return (EFAULT); | | 433 | return (EFAULT); |
440 | | | 434 | |
441 | /* Grab the signal mask */ | | 435 | /* Grab the signal mask */ |
442 | linux_to_native_sigset(&mask, &sigframe.uc.uc_sigmask); | | 436 | linux_to_native_sigset(&mask, &sigframe.uc.uc_sigmask); |
443 | | | 437 | |
444 | return(linux_restore_sigcontext(l, sigframe.uc.uc_mcontext, &mask)); | | 438 | return(linux_restore_sigcontext(l, sigframe.uc.uc_mcontext, &mask)); |
445 | } | | 439 | } |
446 | | | 440 | |
447 | | | 441 | |
448 | int | | 442 | int |
449 | linux_sys_sigreturn(struct lwp *l, const struct linux_sys_sigreturn_args *uap, register_t *retval) | | 443 | linux_sys_sigreturn(struct lwp *l, const struct linux_sys_sigreturn_args *uap, register_t *retval) |
450 | { | | 444 | { |
451 | /* { | | 445 | /* { |
452 | syscallarg(struct linux_sigframe *) sfp; | | 446 | syscallarg(struct linux_sigframe *) sfp; |
453 | } */ | | 447 | } */ |
454 | struct linux_sigframe *sfp, frame; | | 448 | struct linux_sigframe *sfp, frame; |
455 | sigset_t mask; | | 449 | sigset_t mask; |
456 | | | 450 | |
457 | /* | | 451 | /* |
458 | * The trampoline code hands us the context. | | 452 | * The trampoline code hands us the context. |
459 | * It is unsafe to keep track of it ourselves, in the event that a | | 453 | * It is unsafe to keep track of it ourselves, in the event that a |
460 | * program jumps out of a signal handler. | | 454 | * program jumps out of a signal handler. |
461 | */ | | 455 | */ |
462 | | | 456 | |
463 | sfp = SCARG(uap, sfp); | | 457 | sfp = SCARG(uap, sfp); |
464 | if (ALIGN(sfp) != (u_int64_t)sfp) | | 458 | if (ALIGN(sfp) != (u_int64_t)sfp) |
465 | return(EINVAL); | | 459 | return(EINVAL); |
466 | | | 460 | |
467 | /* | | 461 | /* |
468 | * Fetch the frame structure. | | 462 | * Fetch the frame structure. |
469 | */ | | 463 | */ |
470 | if (copyin((void *)sfp, &frame, sizeof(struct linux_sigframe)) != 0) | | 464 | if (copyin((void *)sfp, &frame, sizeof(struct linux_sigframe)) != 0) |
471 | return(EFAULT); | | 465 | return(EFAULT); |
472 | | | 466 | |
473 | /* Grab the signal mask. */ | | 467 | /* Grab the signal mask. */ |
474 | /* XXX use frame.extramask */ | | 468 | /* XXX use frame.extramask */ |
475 | linux_old_to_native_sigset(&mask, frame.sf_sc.sc_mask); | | 469 | linux_old_to_native_sigset(&mask, frame.sf_sc.sc_mask); |
476 | | | 470 | |
477 | return(linux_restore_sigcontext(l, frame.sf_sc, &mask)); | | 471 | return(linux_restore_sigcontext(l, frame.sf_sc, &mask)); |
478 | } | | 472 | } |
479 | | | 473 | |
480 | /* | | 474 | /* |
481 | * We come here in a last attempt to satisfy a Linux ioctl() call | | 475 | * We come here in a last attempt to satisfy a Linux ioctl() call |
482 | */ | | 476 | */ |
483 | /* XXX XAX update this, add maps, etc... */ | | 477 | /* XXX XAX update this, add maps, etc... */ |
484 | int | | 478 | int |
485 | linux_machdepioctl(struct lwp *l, const struct linux_sys_ioctl_args *uap, register_t *retval) | | 479 | linux_machdepioctl(struct lwp *l, const struct linux_sys_ioctl_args *uap, register_t *retval) |
486 | { | | 480 | { |
487 | /* { | | 481 | /* { |
488 | syscallarg(int) fd; | | 482 | syscallarg(int) fd; |
489 | syscallarg(u_long) com; | | 483 | syscallarg(u_long) com; |
490 | syscallarg(void *) data; | | 484 | syscallarg(void *) data; |
491 | } */ | | 485 | } */ |
492 | struct sys_ioctl_args bia; | | 486 | struct sys_ioctl_args bia; |
493 | u_long com; | | 487 | u_long com; |
494 | | | 488 | |
495 | SCARG(&bia, fd) = SCARG(uap, fd); | | 489 | SCARG(&bia, fd) = SCARG(uap, fd); |
496 | SCARG(&bia, data) = SCARG(uap, data); | | 490 | SCARG(&bia, data) = SCARG(uap, data); |
497 | com = SCARG(uap, com); | | 491 | com = SCARG(uap, com); |
498 | | | 492 | |
499 | switch (com) { | | 493 | switch (com) { |
500 | default: | | 494 | default: |
501 | printf("linux_machdepioctl: invalid ioctl %08lx\n", com); | | 495 | printf("linux_machdepioctl: invalid ioctl %08lx\n", com); |
502 | return EINVAL; | | 496 | return EINVAL; |
503 | } | | 497 | } |
504 | SCARG(&bia, com) = com; | | 498 | SCARG(&bia, com) = com; |
505 | return sys_ioctl(l, &bia, retval); | | 499 | return sys_ioctl(l, &bia, retval); |
506 | } | | 500 | } |
507 | | | 501 | |
508 | /* XXX XAX fix this */ | | 502 | /* XXX XAX fix this */ |
509 | dev_t | | 503 | dev_t |
510 | linux_fakedev(dev_t dev, int raw) | | 504 | linux_fakedev(dev_t dev, int raw) |
511 | { | | 505 | { |
512 | return dev; | | 506 | return dev; |
513 | } | | 507 | } |
514 | | | 508 | |
515 | int | | 509 | int |
516 | linux_usertrap(struct lwp *l, vaddr_t trapaddr, void *arg) | | 510 | linux_usertrap(struct lwp *l, vaddr_t trapaddr, void *arg) |
517 | { | | 511 | { |
518 | return 0; | | 512 | return 0; |
519 | } | | 513 | } |