1 /* $NetBSD: linux_machdep.c,v 1.39 2008/04/28 20:23:43 martin Exp $ */
4 * Copyright (c) 1995, 2000, 2001 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Frank van der Linden and Emmanuel Dreyfus.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
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
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
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
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
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: linux_machdep.c,v 1.39 2008/04/28 20:23:43 martin Exp $");
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/signalvar.h>
38 #include <sys/kernel.h>
41 #include <sys/reboot.h>
45 #include <sys/callout.h>
46 #include <sys/malloc.h>
48 #include <sys/msgbuf.h>
49 #include <sys/mount.h>
50 #include <sys/vnode.h>
51 #include <sys/device.h>
52 #include <sys/syscallargs.h>
53 #include <sys/filedesc.h>
54 #include <sys/exec_elf.h>
55 #include <sys/disklabel.h>
56 #include <sys/ioctl.h>
57 #include <miscfs/specfs/specdev.h>
59 #include <compat/linux/common/linux_types.h>
60 #include <compat/linux/common/linux_signal.h>
61 #include <compat/linux/common/linux_util.h>
62 #include <compat/linux/common/linux_ioctl.h>
63 #include <compat/linux/common/linux_hdio.h>
64 #include <compat/linux/common/linux_exec.h>
65 #include <compat/linux/common/linux_machdep.h>
67 #include <compat/linux/linux_syscallargs.h>
70 #include <machine/fpu.h>
71 #include <machine/psl.h>
72 #include <machine/reg.h>
73 #include <machine/vmparam.h>
76 * To see whether wscons is configured (for virtual console ioctl calls).
78 #if defined(_KERNEL_OPT)
79 #include "wsdisplay.h"
82 #include <dev/wscons/wsconsio.h>
83 #include <dev/wscons/wsdisplay_usl_io.h>
87 * Set set up registers on exec.
88 * XXX not used at the moment since in sys/kern/exec_conf, LINUX_COMPAT
89 * entry uses NetBSD's native setregs instead of linux_setregs
92 linux_setregs(struct lwp
*l
, struct exec_package
*pack
, u_long stack
)
94 setregs(l
, pack
, stack
);
98 * Send an interrupt to process.
100 * Adapted from arch/powerpc/powerpc/sig_machdep.c:sendsig and
101 * compat/linux/arch/i386/linux_machdep.c:linux_sendsig
103 * XXX Does not work well yet with RT signals
108 linux_sendsig(const ksiginfo_t
*ksi
, const sigset_t
*mask
)
110 const int sig
= ksi
->ksi_signo
;
111 struct lwp
*l
= curlwp
;
112 struct proc
*p
= l
->l_proc
;
113 struct trapframe
*tf
;
114 sig_t catcher
= SIGACTION(p
, sig
).sa_handler
;
115 struct linux_sigregs frame
;
116 struct linux_pt_regs linux_regs
;
117 struct linux_sigcontext sc
;
125 * Do we need to jump onto the signal stack?
128 (l
->l_sigstk
.ss_flags
& (SS_DISABLE
| SS_ONSTACK
)) == 0 &&
129 (SIGACTION(p
, sig
).sa_flags
& SA_ONSTACK
) != 0;
132 * Signal stack is broken (see at the end of linux_sigreturn), so we do
133 * not use it yet. XXX fix this.
138 * Allocate space for the signal handler context.
142 ((char *)l
->l_sigstk
.ss_sp
+
143 l
->l_sigstk
.ss_size
);
148 printf("fp at start of linux_sendsig = %x\n", fp
);
150 fp
-= sizeof(struct linux_sigregs
);
154 * Prepare a sigcontext for later.
156 memset(&sc
, 0, sizeof sc
);
157 sc
.lsignal
= (int)native_to_linux_signo
[sig
];
158 sc
.lhandler
= (unsigned long)catcher
;
159 native_to_linux_old_extra_sigset(&sc
.lmask
, &sc
._unused
[3], mask
);
160 sc
.lregs
= (struct linux_pt_regs
*)fp
;
163 * Setup the signal stack frame as Linux does it in
164 * arch/ppc/kernel/signal.c:setup_frame()
166 * Save register context.
168 for (i
= 0; i
< 32; i
++)
169 linux_regs
.lgpr
[i
] = tf
->fixreg
[i
];
170 linux_regs
.lnip
= tf
->srr0
;
171 linux_regs
.lmsr
= tf
->srr1
& PSL_USERSRR1
;
172 linux_regs
.lorig_gpr3
= tf
->fixreg
[3]; /* XXX Is that right? */
173 linux_regs
.lctr
= tf
->ctr
;
174 linux_regs
.llink
= tf
->lr
;
175 linux_regs
.lxer
= tf
->xer
;
176 linux_regs
.lccr
= tf
->cr
;
177 linux_regs
.lmq
= 0; /* Unused, 601 only */
178 linux_regs
.ltrap
= tf
->exc
;
179 linux_regs
.ldar
= tf
->dar
;
180 linux_regs
.ldsisr
= tf
->dsisr
;
181 linux_regs
.lresult
= 0;
183 memset(&frame
, 0, sizeof(frame
));
184 memcpy(&frame
.lgp_regs
, &linux_regs
, sizeof(linux_regs
));
186 save_fpu_lwp(curlwp
, FPU_SAVE
);
187 memcpy(&frame
.lfp_regs
, curpcb
->pcb_fpu
.fpreg
, sizeof(frame
.lfp_regs
));
190 * Copy Linux's signal trampoline on the user stack It should not
191 * be used, but Linux binaries might expect it to be there.
193 frame
.ltramp
[0] = 0x38997777; /* li r0, 0x7777 */
194 frame
.ltramp
[1] = 0x44000002; /* sc */
197 * Move it to the user stack
198 * There is a little trick here, about the LINUX_ABIGAP: the
199 * linux_sigreg structure has a 56 int gap to support rs6000/xcoff
200 * binaries. But the Linux kernel seems to do without it, and it
201 * just skip it when building the stack frame. Hence the LINUX_ABIGAP.
203 sendsig_reset(l
, sig
);
204 mutex_exit(p
->p_lock
);
205 error
= copyout(&frame
, (void *)fp
, sizeof (frame
) - LINUX_ABIGAP
);
209 * Process has trashed its stack; give it an illegal
210 * instruction to halt it in its tracks.
212 mutex_enter(p
->p_lock
);
218 * Add a sigcontext on the stack
220 fp
-= sizeof(struct linux_sigcontext
);
221 error
= copyout(&sc
, (void *)fp
, sizeof (struct linux_sigcontext
));
222 mutex_enter(p
->p_lock
);
226 * Process has trashed its stack; give it an illegal
227 * instruction to halt it in its tracks.
234 * Set the registers according to how the Linux process expects them.
235 * "Mind the gap" Linux expects a gap here.
237 tf
->fixreg
[1] = fp
- LINUX__SIGNAL_FRAMESIZE
;
238 tf
->lr
= (int)catcher
;
239 tf
->fixreg
[3] = (int)native_to_linux_signo
[sig
];
241 tf
->srr0
= (int)p
->p_sigctx
.ps_sigcode
;
244 printf("fp at end of linux_sendsig = %x\n", fp
);
247 * Remember that we're now on the signal stack.
250 l
->l_sigstk
.ss_flags
|= SS_ONSTACK
;
252 printf("linux_sendsig: exitting. fp=0x%lx\n",(long)fp
);
257 * System call to cleanup state after a signal
258 * has been taken. Reset signal mask and
259 * stack state from context left by sendsig (above).
260 * Return to previous pc and psl as specified by
261 * context left by sendsig. Check carefully to
262 * make sure that the user has not modified the
263 * psl to gain improper privileges or to cause
269 linux_sys_rt_sigreturn(struct lwp
*l
, const struct linux_sys_rt_sigreturn_args
*uap
, register_t
*retval
)
272 syscallarg(struct linux_rt_sigframe *) sfp;
274 struct proc
*p
= l
->l_proc
;
275 struct linux_rt_sigframe
*scp
, sigframe
;
276 struct linux_sigregs sregs
;
277 struct linux_pt_regs
*lregs
;
278 struct trapframe
*tf
;
283 * The trampoline code hands us the context.
284 * It is unsafe to keep track of it ourselves, in the event that a
285 * program jumps out of a signal handler.
287 scp
= SCARG(uap
, sfp
);
290 * Get the context from user stack
292 if (copyin((void *)scp
, &sigframe
, sizeof(*scp
)))
296 * Restore register context.
298 if (copyin((void *)sigframe
.luc
.luc_context
.lregs
,
299 &sregs
, sizeof(sregs
)))
301 lregs
= (struct linux_pt_regs
*)&sregs
.lgp_regs
;
305 (unsigned long)tf
, (unsigned long)scp
);
308 if (!PSL_USEROK_P(lregs
->lmsr
))
311 for (i
= 0; i
< 32; i
++)
312 tf
->fixreg
[i
] = lregs
->lgpr
[i
];
313 tf
->lr
= lregs
->llink
;
314 tf
->cr
= lregs
->lccr
;
315 tf
->xer
= lregs
->lxer
;
316 tf
->ctr
= lregs
->lctr
;
317 tf
->srr0
= lregs
->lnip
;
318 tf
->srr1
= lregs
->lmsr
;
321 * Make sure the fpu state is discarded
323 save_fpu_lwp(curlwp
, FPU_DISCARD
);
325 memcpy(curpcb
->pcb_fpu
.fpreg
, (void *)&sregs
.lfp_regs
,
326 sizeof(curpcb
->pcb_fpu
.fpreg
));
328 mutex_enter(p
->p_lock
);
331 * Restore signal stack.
333 * XXX cannot find the onstack information in Linux sig context.
334 * Is signal stack really supported on Linux?
336 * It seems to be supported in libc6...
338 /* if (sc.sc_onstack & SS_ONSTACK)
339 l->l_sigstk.ss_flags |= SS_ONSTACK;
341 l
->l_sigstk
.ss_flags
&= ~SS_ONSTACK
;
344 * Grab the signal mask
346 linux_to_native_sigset(&mask
, &sigframe
.luc
.luc_sigmask
);
347 (void) sigprocmask1(l
, SIG_SETMASK
, &mask
, 0);
349 mutex_exit(p
->p_lock
);
351 return (EJUSTRETURN
);
356 * The following needs code review for potential security issues
359 linux_sys_sigreturn(struct lwp
*l
, const struct linux_sys_sigreturn_args
*uap
, register_t
*retval
)
362 syscallarg(struct linux_sigcontext *) scp;
364 struct proc
*p
= l
->l_proc
;
365 struct linux_sigcontext
*scp
, context
;
366 struct linux_sigregs sregs
;
367 struct linux_pt_regs
*lregs
;
368 struct trapframe
*tf
;
373 * The trampoline code hands us the context.
374 * It is unsafe to keep track of it ourselves, in the event that a
375 * program jumps out of a signal handler.
377 scp
= SCARG(uap
, scp
);
380 * Get the context from user stack
382 if (copyin(scp
, &context
, sizeof(*scp
)))
386 * Restore register context.
388 if (copyin((void *)context
.lregs
, &sregs
, sizeof(sregs
)))
390 lregs
= (struct linux_pt_regs
*)&sregs
.lgp_regs
;
394 printf("linux_sys_sigreturn: trapframe=0x%lx scp=0x%lx\n",
395 (unsigned long)tf
, (unsigned long)scp
);
398 if (!PSL_USEROK_P(lregs
->lmsr
))
401 for (i
= 0; i
< 32; i
++)
402 tf
->fixreg
[i
] = lregs
->lgpr
[i
];
403 tf
->lr
= lregs
->llink
;
404 tf
->cr
= lregs
->lccr
;
405 tf
->xer
= lregs
->lxer
;
406 tf
->ctr
= lregs
->lctr
;
407 tf
->srr0
= lregs
->lnip
;
408 tf
->srr1
= lregs
->lmsr
;
411 * Make sure the fpu state is discarded
413 save_fpu_lwp(curlwp
, FPU_DISCARD
);
415 memcpy(curpcb
->pcb_fpu
.fpreg
, (void *)&sregs
.lfp_regs
,
416 sizeof(curpcb
->pcb_fpu
.fpreg
));
418 mutex_enter(p
->p_lock
);
421 * Restore signal stack.
423 * XXX cannot find the onstack information in Linux sig context.
424 * Is signal stack really supported on Linux?
427 if (sc
.sc_onstack
& SS_ONSTACK
)
428 l
->l_sigstk
.ss_flags
|= SS_ONSTACK
;
431 l
->l_sigstk
.ss_flags
&= ~SS_ONSTACK
;
433 /* Restore signal mask. */
434 linux_old_extra_to_native_sigset(&mask
, &context
.lmask
,
435 &context
._unused
[3]);
436 (void) sigprocmask1(l
, SIG_SETMASK
, &mask
, 0);
438 mutex_exit(p
->p_lock
);
440 return (EJUSTRETURN
);
446 linux_sys_modify_ldt(struct proc
*p
, void *v
, register_t
*retval
)
449 * This syscall is not implemented in Linux/PowerPC: we should not
453 printf("linux_sys_modify_ldt: should not be here.\n");
460 * major device numbers remapping
463 linux_fakedev(dev_t dev
, int raw
)
470 * We come here in a last attempt to satisfy a Linux ioctl() call
473 linux_machdepioctl(struct lwp
*l
, const struct linux_sys_ioctl_args
*uap
, register_t
*retval
)
477 syscallarg(u_long) com;
478 syscallarg(void *) data;
480 struct sys_ioctl_args bia
;
483 SCARG(&bia
, fd
) = SCARG(uap
, fd
);
484 SCARG(&bia
, data
) = SCARG(uap
, data
);
485 com
= SCARG(uap
, com
);
489 printf("linux_machdepioctl: invalid ioctl %08lx\n", com
);
492 SCARG(&bia
, com
) = com
;
494 return sys_ioctl(curlwp
, &bia
, retval
);
498 * Set I/O permissions for a process. Just set the maximum level
499 * right away (ignoring the argument), otherwise we would have
500 * to rely on I/O permission maps, which are not implemented.
503 linux_sys_iopl(struct lwp
*l
, const void *v
, register_t
*retval
)
506 * This syscall is not implemented in Linux/PowerPC: we should not be here
509 printf("linux_sys_iopl: should not be here.\n");
516 * See above. If a root process tries to set access to an I/O port,
517 * just let it have the whole range.
520 linux_sys_ioperm(struct lwp
*l
, const struct linux_sys_ioperm_args
*uap
, register_t
*retval
)
523 * This syscall is not implemented in Linux/PowerPC: we should not be here
526 printf("linux_sys_ioperm: should not be here.\n");
532 * wrapper linux_sys_new_uname() -> linux_sys_uname()
535 linux_sys_new_uname(struct lwp
*l
, const struct linux_sys_new_uname_args
*uap
, register_t
*retval
)
537 return linux_sys_uname(l
, (const void *)uap
, retval
);
541 * wrapper linux_sys_new_select() -> linux_sys_select()
544 linux_sys_new_select(struct lwp
*l
, const struct linux_sys_new_select_args
*uap
, register_t
*retval
)
546 return linux_sys_select(l
, (const void *)uap
, retval
);
550 linux_usertrap(struct lwp
*l
, vaddr_t trapaddr
, void *arg
)