Thu Sep 3 14:26:31 2020 UTC ()
The conversion of FPU tracking to PCU rendered the fpcurlwp variable
unmaintained, which broke FP status info in the COMPAT_LINUX sigcontext.
Use the new API, which will at least be closer to correct.


(thorpej)
diff -r1.50 -r1.51 src/sys/compat/linux/arch/alpha/linux_machdep.c

cvs diff -r1.50 -r1.51 src/sys/compat/linux/arch/alpha/linux_machdep.c (switch to unified diff)

--- src/sys/compat/linux/arch/alpha/linux_machdep.c 2014/11/09 17:48:07 1.50
+++ src/sys/compat/linux/arch/alpha/linux_machdep.c 2020/09/03 14:26:31 1.51
@@ -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
92void 92void
93linux_setregs(struct lwp *l, struct exec_package *epp, vaddr_t stack) 93linux_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
109void 109void
110setup_linux_rt_sigframe(struct trapframe *tf, const ksiginfo_t *ksi, 110setup_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
203void setup_linux_sigframe(struct trapframe *tf, const ksiginfo_t *ksi, 203void 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 */
306void 303void
307linux_sendsig(const ksiginfo_t *ksi, const sigset_t *mask) 304linux_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
362int 359int
363linux_restore_sigcontext(struct lwp *l, struct linux_sigcontext context, 360linux_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
414int 408int
415linux_sys_rt_sigreturn(struct lwp *l, const struct linux_sys_rt_sigreturn_args *uap, register_t *retval) 409linux_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
448int 442int
449linux_sys_sigreturn(struct lwp *l, const struct linux_sys_sigreturn_args *uap, register_t *retval) 443linux_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... */
484int 478int
485linux_machdepioctl(struct lwp *l, const struct linux_sys_ioctl_args *uap, register_t *retval) 479linux_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 */
509dev_t 503dev_t
510linux_fakedev(dev_t dev, int raw) 504linux_fakedev(dev_t dev, int raw)
511{ 505{
512 return dev; 506 return dev;
513} 507}
514 508
515int 509int
516linux_usertrap(struct lwp *l, vaddr_t trapaddr, void *arg) 510linux_usertrap(struct lwp *l, vaddr_t trapaddr, void *arg)
517{ 511{
518 return 0; 512 return 0;
519} 513}