1/*	$NetBSD: linux_machdep.c,v 1.51 2021/09/07 11:43:04 riastradh Exp $ */
2
3/*-
4 * Copyright (c) 1995, 2000, 2001 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Frank van der Linden and Emmanuel Dreyfus.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
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.
18 *
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.
30 */
31
32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: linux_machdep.c,v 1.51 2021/09/07 11:43:04 riastradh Exp $");
34
35#include <sys/param.h>
36#include <sys/systm.h>
37#include <sys/signalvar.h>
38#include <sys/kernel.h>
39#include <sys/proc.h>
40#include <sys/buf.h>
41#include <sys/reboot.h>
42#include <sys/conf.h>
43#include <sys/exec.h>
44#include <sys/file.h>
45#include <sys/callout.h>
46#include <sys/mbuf.h>
47#include <sys/msgbuf.h>
48#include <sys/mount.h>
49#include <sys/vnode.h>
50#include <sys/device.h>
51#include <sys/syscallargs.h>
52#include <sys/filedesc.h>
53#include <sys/exec_elf.h>
54#include <sys/disklabel.h>
55#include <sys/ioctl.h>
56#include <miscfs/specfs/specdev.h>
57
58#include <compat/linux/common/linux_types.h>
59#include <compat/linux/common/linux_signal.h>
60#include <compat/linux/common/linux_util.h>
61#include <compat/linux/common/linux_ioctl.h>
62#include <compat/linux/common/linux_hdio.h>
63#include <compat/linux/common/linux_exec.h>
64#include <compat/linux/common/linux_machdep.h>
65
66#include <compat/linux/linux_syscallargs.h>
67
68#include <sys/cpu.h>
69#include <machine/fpu.h>
70#include <machine/psl.h>
71#include <machine/pcb.h>
72#include <machine/vmparam.h>
73
74/*
75 * To see whether wscons is configured (for virtual console ioctl calls).
76 */
77#if defined(_KERNEL_OPT)
78#include "wsdisplay.h"
79#endif
80#if (NWSDISPLAY > 0)
81#include <dev/wscons/wsconsio.h>
82#include <dev/wscons/wsdisplay_usl_io.h>
83#endif
84
85/*
86 * Set set up registers on exec.
87 */
88void
89linux_setregs(struct lwp *l, struct exec_package *pack, vaddr_t stack)
90{
91	setregs(l, pack, stack);
92}
93
94/*
95 * Send an interrupt to process.
96 *
97 * Adapted from arch/powerpc/powerpc/sig_machdep.c:sendsig and
98 * compat/linux/arch/i386/linux_machdep.c:linux_sendsig
99 *
100 * XXX Does not work well yet with RT signals
101 *
102 */
103
104void
105linux_sendsig(const ksiginfo_t *ksi, const sigset_t *mask)
106{
107	const int sig = ksi->ksi_signo;
108	struct lwp *l = curlwp;
109	struct proc *p = l->l_proc;
110	struct trapframe *tf;
111	sig_t catcher = SIGACTION(p, sig).sa_handler;
112	struct linux_sigregs frame;
113	struct linux_pt_regs linux_regs;
114	struct linux_sigcontext sc;
115	register_t fp;
116	int onstack, error;
117	int i;
118
119	tf = trapframe(l);
120
121	/*
122	 * Do we need to jump onto the signal stack?
123	 */
124	onstack =
125	    (l->l_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 &&
126	    (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0;
127
128	/*
129	 * Signal stack is broken (see at the end of linux_sigreturn), so we do
130	 * not use it yet. XXX fix this.
131	 */
132	onstack=0;
133
134	/*
135	 * Allocate space for the signal handler context.
136	 */
137	if (onstack) {
138		fp = (register_t)
139		    ((char *)l->l_sigstk.ss_sp +
140		    l->l_sigstk.ss_size);
141	} else {
142		fp = tf->tf_fixreg[1];
143	}
144#ifdef DEBUG_LINUX
145	printf("fp at start of linux_sendsig = %x\n", fp);
146#endif
147	fp -= sizeof(struct linux_sigregs);
148	fp &= ~0xf;
149
150	/*
151	 * Prepare a sigcontext for later.
152	 */
153	memset(&sc, 0, sizeof sc);
154	sc.lsignal = (int)native_to_linux_signo[sig];
155	sc.lhandler = (unsigned long)catcher;
156	native_to_linux_old_extra_sigset(&sc.lmask, &sc._unused[3], mask);
157	sc.lregs = (struct linux_pt_regs*)fp;
158
159	/*
160	 * Setup the signal stack frame as Linux does it in
161	 * arch/ppc/kernel/signal.c:setup_frame()
162	 *
163	 * Save register context.
164	 */
165	memset(&linux_regs, 0, sizeof(linux_regs));
166	for (i = 0; i < 32; i++)
167		linux_regs.lgpr[i] = tf->tf_fixreg[i];
168	linux_regs.lnip = tf->tf_srr0;
169	linux_regs.lmsr = tf->tf_srr1 & PSL_USERSRR1;
170	linux_regs.lorig_gpr3 = tf->tf_fixreg[3]; /* XXX Is that right? */
171	linux_regs.lctr = tf->tf_ctr;
172	linux_regs.llink = tf->tf_lr;
173	linux_regs.lxer = tf->tf_xer;
174	linux_regs.lccr = tf->tf_cr;
175	linux_regs.lmq = 0;  			/* Unused, 601 only */
176	linux_regs.ltrap = tf->tf_exc;
177	linux_regs.ldar = tf->tf_dar;
178	linux_regs.ldsisr = tf->tf_dsisr;
179	linux_regs.lresult = 0;
180
181	memset(&frame, 0, sizeof(frame));
182	memcpy(&frame.lgp_regs, &linux_regs, sizeof(linux_regs));
183
184#ifdef PPC_HAVE_FPU
185	fpu_save(l);
186#endif
187	memcpy(&frame.lfp_regs, curpcb->pcb_fpu.fpreg, sizeof(frame.lfp_regs));
188
189	/*
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.
192	 */
193	frame.ltramp[0] = 0x38997777; /* li r0, 0x7777 */
194	frame.ltramp[1] = 0x44000002; /* sc */
195
196	/*
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.
202	 */
203	sendsig_reset(l, sig);
204	mutex_exit(p->p_lock);
205	error = copyout(&frame, (void *)fp, sizeof (frame) - LINUX_ABIGAP);
206
207	if (error != 0) {
208		/*
209		 * Process has trashed its stack; give it an illegal
210		 * instruction to halt it in its tracks.
211		 */
212		mutex_enter(p->p_lock);
213		sigexit(l, SIGILL);
214		/* NOTREACHED */
215	}
216
217	/*
218	 * Add a sigcontext on the stack
219	 */
220	fp -= sizeof(struct linux_sigcontext);
221	error = copyout(&sc, (void *)fp, sizeof (struct linux_sigcontext));
222	mutex_enter(p->p_lock);
223
224	if (error != 0) {
225		/*
226		 * Process has trashed its stack; give it an illegal
227		 * instruction to halt it in its tracks.
228		 */
229		sigexit(l, SIGILL);
230		/* NOTREACHED */
231	}
232
233	/*
234	 * Set the registers according to how the Linux process expects them.
235	 * "Mind the gap" Linux expects a gap here.
236	 */
237	tf->tf_fixreg[1] = fp - LINUX__SIGNAL_FRAMESIZE;
238	tf->tf_lr = (int)catcher;
239	tf->tf_fixreg[3] = (int)native_to_linux_signo[sig];
240	tf->tf_fixreg[4] = fp;
241	tf->tf_srr0 = (int)p->p_sigctx.ps_sigcode;
242
243#ifdef DEBUG_LINUX
244	printf("fp at end of linux_sendsig = %x\n", fp);
245#endif
246	/*
247	 * Remember that we're now on the signal stack.
248	 */
249	if (onstack)
250		l->l_sigstk.ss_flags |= SS_ONSTACK;
251#ifdef DEBUG_LINUX
252	printf("linux_sendsig: exiting. fp=0x%lx\n",(long)fp);
253#endif
254}
255
256/*
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
264 * a machine fault.
265 *
266 * XXX not tested
267 */
268int
269linux_sys_rt_sigreturn(struct lwp *l, const struct linux_sys_rt_sigreturn_args *uap, register_t *retval)
270{
271	/* {
272		syscallarg(struct linux_rt_sigframe *) sfp;
273	} */
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;
279	sigset_t mask;
280	int i;
281
282	/*
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.
286	 */
287	scp = SCARG(uap, sfp);
288
289	/*
290	 * Get the context from user stack
291	 */
292	if (copyin((void *)scp, &sigframe, sizeof(*scp)))
293		return (EFAULT);
294
295	/*
296	 *  Restore register context.
297	 */
298	if (copyin((void *)sigframe.luc.luc_context.lregs,
299		   &sregs, sizeof(sregs)))
300		return (EFAULT);
301	lregs = (struct linux_pt_regs *)&sregs.lgp_regs;
302
303	tf = trapframe(l);
304#ifdef DEBUG_LINUX
305	printf("linux_sys_rt_sigreturn: trapframe=0x%lx scp=0x%lx\n",
306	    (unsigned long)tf, (unsigned long)scp);
307#endif
308
309	if (!PSL_USEROK_P(lregs->lmsr))
310		return (EINVAL);
311
312	for (i = 0; i < 32; i++)
313		tf->tf_fixreg[i] = lregs->lgpr[i];
314	tf->tf_lr = lregs->llink;
315	tf->tf_cr = lregs->lccr;
316	tf->tf_xer = lregs->lxer;
317	tf->tf_ctr = lregs->lctr;
318	tf->tf_srr0 = lregs->lnip;
319	tf->tf_srr1 = lregs->lmsr;
320
321	/*
322	 * Make sure the fpu state is discarded
323	 */
324#ifdef PPC_HAVE_FPU
325	fpu_discard(l);
326#endif
327
328	memcpy(curpcb->pcb_fpu.fpreg, (void *)&sregs.lfp_regs,
329	       sizeof(curpcb->pcb_fpu.fpreg));
330
331	fpu_mark_used(l);
332
333	mutex_enter(p->p_lock);
334
335	/*
336	 * Restore signal stack.
337	 *
338	 * XXX cannot find the onstack information in Linux sig context.
339	 * Is signal stack really supported on Linux?
340	 *
341	 * It seems to be supported in libc6...
342	 */
343	/* if (sc.sc_onstack & SS_ONSTACK)
344		l->l_sigstk.ss_flags |= SS_ONSTACK;
345	else */
346		l->l_sigstk.ss_flags &= ~SS_ONSTACK;
347
348	/*
349	 * Grab the signal mask
350	 */
351	linux_to_native_sigset(&mask, &sigframe.luc.luc_sigmask);
352	(void) sigprocmask1(l, SIG_SETMASK, &mask, 0);
353
354	mutex_exit(p->p_lock);
355
356	return (EJUSTRETURN);
357}
358
359
360/*
361 * The following needs code review for potential security issues
362 */
363int
364linux_sys_sigreturn(struct lwp *l, const struct linux_sys_sigreturn_args *uap, register_t *retval)
365{
366	/* {
367		syscallarg(struct linux_sigcontext *) scp;
368	} */
369	struct proc *p = l->l_proc;
370	struct linux_sigcontext *scp, context;
371	struct linux_sigregs sregs;
372	struct linux_pt_regs *lregs;
373	struct trapframe *tf;
374	sigset_t mask;
375	int i;
376
377	/*
378	 * The trampoline code hands us the context.
379	 * It is unsafe to keep track of it ourselves, in the event that a
380	 * program jumps out of a signal handler.
381	 */
382	scp = SCARG(uap, scp);
383
384	/*
385	 * Get the context from user stack
386	 */
387	if (copyin(scp, &context, sizeof(*scp)))
388		return (EFAULT);
389
390	/*
391	 *  Restore register context.
392	 */
393	if (copyin((void *)context.lregs, &sregs, sizeof(sregs)))
394		return (EFAULT);
395	lregs = (struct linux_pt_regs *)&sregs.lgp_regs;
396
397	tf = trapframe(l);
398#ifdef DEBUG_LINUX
399	printf("linux_sys_sigreturn: trapframe=0x%lx scp=0x%lx\n",
400	    (unsigned long)tf, (unsigned long)scp);
401#endif
402
403	if (!PSL_USEROK_P(lregs->lmsr))
404		return (EINVAL);
405
406	for (i = 0; i < 32; i++)
407		tf->tf_fixreg[i] = lregs->lgpr[i];
408	tf->tf_lr = lregs->llink;
409	tf->tf_cr = lregs->lccr;
410	tf->tf_xer = lregs->lxer;
411	tf->tf_ctr = lregs->lctr;
412	tf->tf_srr0 = lregs->lnip;
413	tf->tf_srr1 = lregs->lmsr;
414
415	/*
416	 * Make sure the fpu state is discarded
417	 */
418#ifdef PPC_HAVE_FPU
419	fpu_discard(l);
420#endif
421
422	memcpy(curpcb->pcb_fpu.fpreg, (void *)&sregs.lfp_regs,
423	       sizeof(curpcb->pcb_fpu.fpreg));
424
425	fpu_mark_used(l);
426
427	mutex_enter(p->p_lock);
428
429	/*
430	 * Restore signal stack.
431	 *
432	 * XXX cannot find the onstack information in Linux sig context.
433	 * Is signal stack really supported on Linux?
434	 */
435#if 0
436	if (sc.sc_onstack & SS_ONSTACK)
437		l->l_sigstk.ss_flags |= SS_ONSTACK;
438	else
439#endif
440		l->l_sigstk.ss_flags &= ~SS_ONSTACK;
441
442	/* Restore signal mask. */
443	linux_old_extra_to_native_sigset(&mask, &context.lmask,
444	    &context._unused[3]);
445	(void) sigprocmask1(l, SIG_SETMASK, &mask, 0);
446
447	mutex_exit(p->p_lock);
448
449	return (EJUSTRETURN);
450}
451
452/*
453 * major device numbers remapping
454 */
455dev_t
456linux_fakedev(dev_t dev, int raw)
457{
458	/* XXX write me */
459	return dev;
460}
461
462/*
463 * We come here in a last attempt to satisfy a Linux ioctl() call
464 */
465int
466linux_machdepioctl(struct lwp *l, const struct linux_sys_ioctl_args *uap, register_t *retval)
467{
468	/* {
469		syscallarg(int) fd;
470		syscallarg(u_long) com;
471		syscallarg(void *) data;
472	} */
473	struct sys_ioctl_args bia;
474	u_long com;
475
476	SCARG(&bia, fd) = SCARG(uap, fd);
477	SCARG(&bia, data) = SCARG(uap, data);
478	com = SCARG(uap, com);
479
480	switch (com) {
481	default:
482		printf("linux_machdepioctl: invalid ioctl %08lx\n", com);
483		return EINVAL;
484	}
485	SCARG(&bia, com) = com;
486	/* XXX NJWLWP */
487	return sys_ioctl(curlwp, &bia, retval);
488}
489
490/*
491 * wrapper linux_sys_new_uname() -> linux_sys_uname()
492 */
493int
494linux_sys_new_uname(struct lwp *l, const struct linux_sys_new_uname_args *uap, register_t *retval)
495{
496	return linux_sys_uname(l, (const void *)uap, retval);
497}
498
499/*
500 * wrapper linux_sys_new_select() -> linux_sys_select()
501 */
502int
503linux_sys_new_select(struct lwp *l, const struct linux_sys_new_select_args *uap, register_t *retval)
504{
505	return linux_sys_select(l, (const void *)uap, retval);
506}
507
508int
509linux_usertrap(struct lwp *l, vaddr_t trapaddr, void *arg)
510{
511	return 0;
512}
513