diff options
author | Renato Botelho <renato@netgate.com> | 2016-01-13 17:56:30 -0200 |
---|---|---|
committer | Renato Botelho <renato@netgate.com> | 2016-01-13 17:56:30 -0200 |
commit | 3e0bf52f358eb969d165c4b1e54942ee94cf2c8d (patch) | |
tree | 440bb9907871a5bc578d65b32f0c4aa339096175 /sys | |
parent | 4b4ac714f11471e43f18410bcc86da8f9dc3b88c (diff) | |
parent | e357bdb742b2696dcb81404917b6247f9e840232 (diff) | |
download | FreeBSD-src-3e0bf52f358eb969d165c4b1e54942ee94cf2c8d.zip FreeBSD-src-3e0bf52f358eb969d165c4b1e54942ee94cf2c8d.tar.gz |
Merge remote-tracking branch 'origin/stable/10' into devel
Diffstat (limited to 'sys')
220 files changed, 24501 insertions, 3357 deletions
diff --git a/sys/amd64/amd64/elf_machdep.c b/sys/amd64/amd64/elf_machdep.c index f9ba30d..d961f09 100644 --- a/sys/amd64/amd64/elf_machdep.c +++ b/sys/amd64/amd64/elf_machdep.c @@ -82,6 +82,7 @@ struct sysentvec elf64_freebsd_sysvec = { .sv_shared_page_base = SHAREDPAGE, .sv_shared_page_len = PAGE_SIZE, .sv_schedtail = NULL, + .sv_thread_detach = NULL, }; INIT_SYSENTVEC(elf64_sysvec, &elf64_freebsd_sysvec); diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index fb1c0d9..03334f1 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -384,10 +384,6 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) /* Align to 16 bytes. */ sfp = (struct sigframe *)((unsigned long)sp & ~0xFul); - /* Translate the signal if appropriate. */ - if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) - sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; - /* Build the argument list for the signal handler. */ regs->tf_rdi = sig; /* arg 1 in %rdi */ regs->tf_rdx = (register_t)&sfp->sf_uc; /* arg 3 in %rdx */ diff --git a/sys/amd64/ia32/ia32_signal.c b/sys/amd64/ia32/ia32_signal.c index da01647..9831013 100644 --- a/sys/amd64/ia32/ia32_signal.c +++ b/sys/amd64/ia32/ia32_signal.c @@ -360,10 +360,6 @@ ia32_osendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) } else fp = (struct ia32_sigframe3 *)regs->tf_rsp - 1; - /* Translate the signal if appropriate. */ - if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) - sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; - /* Build the argument list for the signal handler. */ sf.sf_signum = sig; sf.sf_scp = (register_t)&fp->sf_siginfo.si_sc; @@ -498,10 +494,6 @@ freebsd4_ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) sfp = (struct ia32_sigframe4 *)regs->tf_rsp - 1; PROC_UNLOCK(p); - /* Translate the signal if appropriate. */ - if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) - sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; - /* Build the argument list for the signal handler. */ sf.sf_signum = sig; sf.sf_ucontext = (register_t)&sfp->sf_uc; @@ -643,10 +635,6 @@ ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) sfp = (struct ia32_sigframe *)((uintptr_t)sp & ~0xF); PROC_UNLOCK(p); - /* Translate the signal if appropriate. */ - if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) - sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; - /* Build the argument list for the signal handler. */ sf.sf_signum = sig; sf.sf_ucontext = (register_t)&sfp->sf_uc; diff --git a/sys/amd64/linux/Makefile b/sys/amd64/linux/Makefile new file mode 100644 index 0000000..c8899e6 --- /dev/null +++ b/sys/amd64/linux/Makefile @@ -0,0 +1,17 @@ +# Makefile for syscall tables +# +# $FreeBSD$ + +all: + @echo "make sysent only" + +sysent: linux_sysent.c linux_syscall.h linux_proto.h linux_syscalls.c linux_systrace_args.c + +linux_sysent.c linux_syscall.h linux_proto.h linux_syscalls.c linux_systrace_args.c: \ + ../../kern/makesyscalls.sh syscalls.master syscalls.conf + -mv -f linux_sysent.c linux_sysent.c.bak + -mv -f linux_syscall.h linux_syscall.h.bak + -mv -f linux_proto.h linux_proto.h.bak + -mv -f linux_syscalls.c linux_syscalls.c.bak + -mv -f linux_systrace_args.c linux_systrace_args.c.bak + sh ../../kern/makesyscalls.sh syscalls.master syscalls.conf diff --git a/sys/amd64/linux/linux.h b/sys/amd64/linux/linux.h new file mode 100644 index 0000000..c4fe9ae --- /dev/null +++ b/sys/amd64/linux/linux.h @@ -0,0 +1,549 @@ +/*- + * Copyright (c) 2013 Dmitry Chagin + * Copyright (c) 1994-1996 Søren Schmidt + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _AMD64_LINUX_H_ +#define _AMD64_LINUX_H_ + +#include <compat/linux/linux.h> +#include <amd64/linux/linux_syscall.h> + +/* + * debugging support + */ +extern u_char linux_debug_map[]; +#define ldebug(name) isclr(linux_debug_map, LINUX_SYS_linux_ ## name) +#define ARGS(nm, fmt) "linux(%ld/%ld): "#nm"("fmt")\n", \ + (long)td->td_proc->p_pid, (long)td->td_tid +#define LMSG(fmt) "linux(%ld/%ld): "fmt"\n", \ + (long)td->td_proc->p_pid, (long)td->td_tid +#define LINUX_DTRACE linuxulator + +#define PTRIN(v) (void *)(v) +#define PTROUT(v) (uintptr_t)(v) + +#define CP(src,dst,fld) do { (dst).fld = (src).fld; } while (0) +#define CP2(src,dst,sfld,dfld) do { (dst).dfld = (src).sfld; } while (0) +#define PTRIN_CP(src,dst,fld) \ + do { (dst).fld = PTRIN((src).fld); } while (0) + +/* + * Provide a separate set of types for the Linux types. + */ +typedef int32_t l_int; +typedef int64_t l_long; +typedef int16_t l_short; +typedef uint32_t l_uint; +typedef uint64_t l_ulong; +typedef uint16_t l_ushort; + +typedef l_ulong l_uintptr_t; +typedef l_long l_clock_t; +typedef l_int l_daddr_t; +typedef l_ulong l_dev_t; +typedef l_uint l_gid_t; +typedef l_uint l_uid_t; +typedef l_ulong l_ino_t; +typedef l_int l_key_t; +typedef l_long l_loff_t; +typedef l_uint l_mode_t; +typedef l_long l_off_t; +typedef l_int l_pid_t; +typedef l_ulong l_size_t; +typedef l_long l_ssize_t; +typedef l_long l_suseconds_t; +typedef l_long l_time_t; +typedef l_int l_timer_t; +typedef l_int l_mqd_t; +typedef l_size_t l_socklen_t; +typedef l_ulong l_fd_mask; + +typedef struct { + l_int val[2]; +} l_fsid_t; + +typedef struct { + l_time_t tv_sec; + l_suseconds_t tv_usec; +} l_timeval; + +#define l_fd_set fd_set + +/* + * Miscellaneous + */ +#define LINUX_NAME_MAX 255 +#define LINUX_CTL_MAXNAME 10 + +#define LINUX_AT_COUNT 19 /* Count of used aux entry types. */ + +struct l___sysctl_args +{ + l_uintptr_t name; + l_int nlen; + l_uintptr_t oldval; + l_uintptr_t oldlenp; + l_uintptr_t newval; + l_size_t newlen; + l_ulong __spare[4]; +}; + +/* Scheduling policies */ +#define LINUX_SCHED_OTHER 0 +#define LINUX_SCHED_FIFO 1 +#define LINUX_SCHED_RR 2 + +/* Resource limits */ +#define LINUX_RLIMIT_CPU 0 +#define LINUX_RLIMIT_FSIZE 1 +#define LINUX_RLIMIT_DATA 2 +#define LINUX_RLIMIT_STACK 3 +#define LINUX_RLIMIT_CORE 4 +#define LINUX_RLIMIT_RSS 5 +#define LINUX_RLIMIT_NPROC 6 +#define LINUX_RLIMIT_NOFILE 7 +#define LINUX_RLIMIT_MEMLOCK 8 +#define LINUX_RLIMIT_AS 9 /* Address space limit */ + +#define LINUX_RLIM_NLIMITS 10 + +struct l_rlimit { + l_ulong rlim_cur; + l_ulong rlim_max; +}; + +/* mmap options */ +#define LINUX_MAP_SHARED 0x0001 +#define LINUX_MAP_PRIVATE 0x0002 +#define LINUX_MAP_FIXED 0x0010 +#define LINUX_MAP_ANON 0x0020 +#define LINUX_MAP_GROWSDOWN 0x0100 + +/* + * stat family of syscalls + */ +struct l_timespec { + l_time_t tv_sec; + l_long tv_nsec; +}; + +struct l_newstat { + l_dev_t st_dev; + l_ino_t st_ino; + l_ulong st_nlink; + l_uint st_mode; + l_uid_t st_uid; + l_gid_t st_gid; + l_uint __st_pad1; + l_dev_t st_rdev; + l_off_t st_size; + l_long st_blksize; + l_long st_blocks; + struct l_timespec st_atim; + struct l_timespec st_mtim; + struct l_timespec st_ctim; + l_long __unused1; + l_long __unused2; + l_long __unused3; +}; + +/* sigaction flags */ +#define LINUX_SA_NOCLDSTOP 0x00000001 +#define LINUX_SA_NOCLDWAIT 0x00000002 +#define LINUX_SA_SIGINFO 0x00000004 +#define LINUX_SA_RESTORER 0x04000000 +#define LINUX_SA_ONSTACK 0x08000000 +#define LINUX_SA_RESTART 0x10000000 +#define LINUX_SA_INTERRUPT 0x20000000 +#define LINUX_SA_NOMASK 0x40000000 +#define LINUX_SA_ONESHOT 0x80000000 + +/* sigprocmask actions */ +#define LINUX_SIG_BLOCK 0 +#define LINUX_SIG_UNBLOCK 1 +#define LINUX_SIG_SETMASK 2 + +/* sigaltstack */ +#define LINUX_MINSIGSTKSZ 2048 + +typedef void (*l_handler_t)(l_int); + +typedef struct { + l_handler_t lsa_handler; + l_ulong lsa_flags; + l_uintptr_t lsa_restorer; + l_sigset_t lsa_mask; +} l_sigaction_t; + +typedef struct { + l_uintptr_t ss_sp; + l_int ss_flags; + l_size_t ss_size; +} l_stack_t; + +struct l_fpstate { + u_int16_t cwd; + u_int16_t swd; + u_int16_t twd; + u_int16_t fop; + u_int64_t rip; + u_int64_t rdp; + u_int32_t mxcsr; + u_int32_t mxcsr_mask; + u_int32_t st_space[32]; + u_int32_t xmm_space[64]; + u_int32_t reserved2[24]; +}; + +struct l_sigcontext { + l_ulong sc_r8; + l_ulong sc_r9; + l_ulong sc_r10; + l_ulong sc_r11; + l_ulong sc_r12; + l_ulong sc_r13; + l_ulong sc_r14; + l_ulong sc_r15; + l_ulong sc_rdi; + l_ulong sc_rsi; + l_ulong sc_rbp; + l_ulong sc_rbx; + l_ulong sc_rdx; + l_ulong sc_rax; + l_ulong sc_rcx; + l_ulong sc_rsp; + l_ulong sc_rip; + l_ulong sc_rflags; + l_ushort sc_cs; + l_ushort sc_gs; + l_ushort sc_fs; + l_ushort sc___pad0; + l_ulong sc_err; + l_ulong sc_trapno; + l_sigset_t sc_mask; + l_ulong sc_cr2; + struct l_fpstate *sc_fpstate; + l_ulong sc_reserved1[8]; +}; + +struct l_ucontext { + l_ulong uc_flags; + l_uintptr_t uc_link; + l_stack_t uc_stack; + struct l_sigcontext uc_mcontext; + l_sigset_t uc_sigmask; +}; + +#define LINUX_SI_PREAMBLE_SIZE (4 * sizeof(int)) +#define LINUX_SI_MAX_SIZE 128 +#define LINUX_SI_PAD_SIZE ((LINUX_SI_MAX_SIZE - \ + LINUX_SI_PREAMBLE_SIZE) / sizeof(l_int)) +typedef union l_sigval { + l_int sival_int; + l_uintptr_t sival_ptr; +} l_sigval_t; + +typedef struct l_siginfo { + l_int lsi_signo; + l_int lsi_errno; + l_int lsi_code; + union { + l_int _pad[LINUX_SI_PAD_SIZE]; + + struct { + l_pid_t _pid; + l_uid_t _uid; + } _kill; + + struct { + l_timer_t _tid; + l_int _overrun; + char _pad[sizeof(l_uid_t) - sizeof(int)]; + union l_sigval _sigval; + l_uint _sys_private; + } _timer; + + struct { + l_pid_t _pid; /* sender's pid */ + l_uid_t _uid; /* sender's uid */ + union l_sigval _sigval; + } _rt; + + struct { + l_pid_t _pid; /* which child */ + l_uid_t _uid; /* sender's uid */ + l_int _status; /* exit code */ + l_clock_t _utime; + l_clock_t _stime; + } _sigchld; + + struct { + l_uintptr_t _addr; /* Faulting insn/memory ref. */ + } _sigfault; + + struct { + l_long _band; /* POLL_IN,POLL_OUT,POLL_MSG */ + l_int _fd; + } _sigpoll; + } _sifields; +} l_siginfo_t; + +#define lsi_pid _sifields._kill._pid +#define lsi_uid _sifields._kill._uid +#define lsi_tid _sifields._timer._tid +#define lsi_overrun _sifields._timer._overrun +#define lsi_sys_private _sifields._timer._sys_private +#define lsi_status _sifields._sigchld._status +#define lsi_utime _sifields._sigchld._utime +#define lsi_stime _sifields._sigchld._stime +#define lsi_value _sifields._rt._sigval +#define lsi_int _sifields._rt._sigval.sival_int +#define lsi_ptr _sifields._rt._sigval.sival_ptr +#define lsi_addr _sifields._sigfault._addr +#define lsi_band _sifields._sigpoll._band +#define lsi_fd _sifields._sigpoll._fd + +/* + * We make the stack look like Linux expects it when calling a signal + * handler, but use the BSD way of calling the handler and sigreturn(). + * This means that we need to pass the pointer to the handler too. + * It is appended to the frame to not interfere with the rest of it. + */ + +struct l_rt_sigframe { + struct l_ucontext sf_sc; + struct l_siginfo sf_si; + l_handler_t sf_handler; +}; + +/* + * mount flags + */ +#define LINUX_MS_RDONLY 0x0001 +#define LINUX_MS_NOSUID 0x0002 +#define LINUX_MS_NODEV 0x0004 +#define LINUX_MS_NOEXEC 0x0008 +#define LINUX_MS_REMOUNT 0x0020 + +/* + * SystemV IPC defines + */ +#define LINUX_IPC_RMID 0 +#define LINUX_IPC_SET 1 +#define LINUX_IPC_STAT 2 +#define LINUX_IPC_INFO 3 + +#define LINUX_SHM_LOCK 11 +#define LINUX_SHM_UNLOCK 12 +#define LINUX_SHM_STAT 13 +#define LINUX_SHM_INFO 14 + +#define LINUX_SHM_RDONLY 0x1000 +#define LINUX_SHM_RND 0x2000 +#define LINUX_SHM_REMAP 0x4000 + +/* semctl commands */ +#define LINUX_GETPID 11 +#define LINUX_GETVAL 12 +#define LINUX_GETALL 13 +#define LINUX_GETNCNT 14 +#define LINUX_GETZCNT 15 +#define LINUX_SETVAL 16 +#define LINUX_SETALL 17 +#define LINUX_SEM_STAT 18 +#define LINUX_SEM_INFO 19 + +union l_semun { + l_int val; + l_uintptr_t buf; + l_uintptr_t array; + l_uintptr_t __buf; + l_uintptr_t __pad; +}; + +struct l_ipc_perm { + l_key_t key; + l_uid_t uid; + l_gid_t gid; + l_uid_t cuid; + l_gid_t cgid; + l_ushort mode; + l_ushort seq; +}; + +/* + * Socket defines + */ + +#define LINUX_SOL_SOCKET 1 +#define LINUX_SOL_IP 0 +#define LINUX_SOL_IPX 256 +#define LINUX_SOL_AX25 257 +#define LINUX_SOL_TCP 6 +#define LINUX_SOL_UDP 17 + +#define LINUX_SO_DEBUG 1 +#define LINUX_SO_REUSEADDR 2 +#define LINUX_SO_TYPE 3 +#define LINUX_SO_ERROR 4 +#define LINUX_SO_DONTROUTE 5 +#define LINUX_SO_BROADCAST 6 +#define LINUX_SO_SNDBUF 7 +#define LINUX_SO_RCVBUF 8 +#define LINUX_SO_KEEPALIVE 9 +#define LINUX_SO_OOBINLINE 10 +#define LINUX_SO_NO_CHECK 11 +#define LINUX_SO_PRIORITY 12 +#define LINUX_SO_LINGER 13 +#define LINUX_SO_PASSCRED 16 +#define LINUX_SO_PEERCRED 17 +#define LINUX_SO_RCVLOWAT 18 +#define LINUX_SO_SNDLOWAT 19 +#define LINUX_SO_RCVTIMEO 20 +#define LINUX_SO_SNDTIMEO 21 +#define LINUX_SO_TIMESTAMP 29 +#define LINUX_SO_ACCEPTCONN 30 + +#define LINUX_IP_TOS 1 +#define LINUX_IP_TTL 2 +#define LINUX_IP_HDRINCL 3 +#define LINUX_IP_OPTIONS 4 + +#define LINUX_IP_MULTICAST_IF 32 +#define LINUX_IP_MULTICAST_TTL 33 +#define LINUX_IP_MULTICAST_LOOP 34 +#define LINUX_IP_ADD_MEMBERSHIP 35 +#define LINUX_IP_DROP_MEMBERSHIP 36 + +struct l_sockaddr { + l_ushort sa_family; + char sa_data[14]; +}; + +struct l_ifmap { + l_ulong mem_start; + l_ulong mem_end; + l_ushort base_addr; + u_char irq; + u_char dma; + u_char port; +} __packed; + +#define LINUX_IFHWADDRLEN 6 +#define LINUX_IFNAMSIZ 16 + +struct l_ifreq { + union { + char ifrn_name[LINUX_IFNAMSIZ]; + } ifr_ifrn; + + union { + struct l_sockaddr ifru_addr; + struct l_sockaddr ifru_dstaddr; + struct l_sockaddr ifru_broadaddr; + struct l_sockaddr ifru_netmask; + struct l_sockaddr ifru_hwaddr; + l_short ifru_flags[1]; + l_int ifru_metric; + l_int ifru_mtu; + struct l_ifmap ifru_map; + char ifru_slave[LINUX_IFNAMSIZ]; + l_uintptr_t ifru_data; + } ifr_ifru; +} __packed; + +#define ifr_name ifr_ifrn.ifrn_name /* Interface name */ +#define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */ + +struct l_ifconf { + int ifc_len; + union { + l_uintptr_t ifcu_buf; + l_uintptr_t ifcu_req; + } ifc_ifcu; +}; + +#define ifc_buf ifc_ifcu.ifcu_buf +#define ifc_req ifc_ifcu.ifcu_req + +/* + * poll() + */ +#define LINUX_POLLIN 0x0001 +#define LINUX_POLLPRI 0x0002 +#define LINUX_POLLOUT 0x0004 +#define LINUX_POLLERR 0x0008 +#define LINUX_POLLHUP 0x0010 +#define LINUX_POLLNVAL 0x0020 +#define LINUX_POLLRDNORM 0x0040 +#define LINUX_POLLRDBAND 0x0080 +#define LINUX_POLLWRNORM 0x0100 +#define LINUX_POLLWRBAND 0x0200 +#define LINUX_POLLMSG 0x0400 + +struct l_pollfd { + l_int fd; + l_short events; + l_short revents; +}; + + +#define LINUX_CLONE_VM 0x00000100 +#define LINUX_CLONE_FS 0x00000200 +#define LINUX_CLONE_FILES 0x00000400 +#define LINUX_CLONE_SIGHAND 0x00000800 +#define LINUX_CLONE_PID 0x00001000 /* No longer exist in Linux */ +#define LINUX_CLONE_VFORK 0x00004000 +#define LINUX_CLONE_PARENT 0x00008000 +#define LINUX_CLONE_THREAD 0x00010000 +#define LINUX_CLONE_SETTLS 0x00080000 +#define LINUX_CLONE_PARENT_SETTID 0x00100000 +#define LINUX_CLONE_CHILD_CLEARTID 0x00200000 +#define LINUX_CLONE_CHILD_SETTID 0x01000000 + +#define LINUX_ARCH_SET_GS 0x1001 +#define LINUX_ARCH_SET_FS 0x1002 +#define LINUX_ARCH_GET_GS 0x1003 +#define LINUX_ARCH_GET_FS 0x1004 + +#define linux_copyout_rusage(r, u) copyout(r, u, sizeof(*r)) + +/* robust futexes */ +struct linux_robust_list { + l_uintptr_t next; +}; + +struct linux_robust_list_head { + struct linux_robust_list list; + l_long futex_offset; + l_uintptr_t pending_list; +}; + +#endif /* !_AMD64_LINUX_H_ */ diff --git a/sys/amd64/linux/linux_dummy.c b/sys/amd64/linux/linux_dummy.c new file mode 100644 index 0000000..96cf8d9 --- /dev/null +++ b/sys/amd64/linux/linux_dummy.c @@ -0,0 +1,141 @@ +/*- + * Copyright (c) 2013 Dmitry Chagin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include "opt_compat.h" +#include "opt_kdtrace.h" + +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/sdt.h> +#include <sys/systm.h> +#include <sys/proc.h> + +#include <amd64/linux/linux.h> +#include <amd64/linux/linux_proto.h> +#include <compat/linux/linux_dtrace.h> +#include <compat/linux/linux_util.h> + +/* DTrace init */ +LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE); + +DUMMY(mincore); +DUMMY(sendfile); +DUMMY(ptrace); +DUMMY(syslog); +DUMMY(setfsuid); +DUMMY(setfsgid); +DUMMY(sysfs); +DUMMY(vhangup); +DUMMY(pivot_root); +DUMMY(adjtimex); +DUMMY(swapoff); +DUMMY(create_module); +DUMMY(init_module); +DUMMY(delete_module); +DUMMY(get_kernel_syms); +DUMMY(query_module); +DUMMY(quotactl); +DUMMY(nfsservctl); +DUMMY(getpmsg); +DUMMY(putpmsg); +DUMMY(afs_syscall); +DUMMY(tuxcall); +DUMMY(security); +DUMMY(set_thread_area); +DUMMY(lookup_dcookie); +DUMMY(epoll_ctl_old); +DUMMY(epoll_wait_old); +DUMMY(remap_file_pages); +DUMMY(semtimedop); +DUMMY(mbind); +DUMMY(get_mempolicy); +DUMMY(set_mempolicy); +DUMMY(mq_open); +DUMMY(mq_unlink); +DUMMY(mq_timedsend); +DUMMY(mq_timedreceive); +DUMMY(mq_notify); +DUMMY(mq_getsetattr); +DUMMY(kexec_load); +DUMMY(add_key); +DUMMY(request_key); +DUMMY(keyctl); +DUMMY(ioprio_set); +DUMMY(ioprio_get); +DUMMY(inotify_init); +DUMMY(inotify_add_watch); +DUMMY(inotify_rm_watch); +DUMMY(migrate_pages); +DUMMY(unshare); +DUMMY(splice); +DUMMY(tee); +DUMMY(sync_file_range); +DUMMY(vmsplice); +DUMMY(move_pages); +DUMMY(signalfd); +DUMMY(timerfd); +DUMMY(timerfd_settime); +DUMMY(timerfd_gettime); +DUMMY(signalfd4); +DUMMY(inotify_init1); +DUMMY(preadv); +DUMMY(pwritev); +DUMMY(rt_tsigqueueinfo); +DUMMY(perf_event_open); +DUMMY(fanotify_init); +DUMMY(fanotify_mark); +DUMMY(name_to_handle_at); +DUMMY(open_by_handle_at); +DUMMY(clock_adjtime); +DUMMY(setns); +DUMMY(process_vm_readv); +DUMMY(process_vm_writev); +DUMMY(kcmp); +DUMMY(finit_module); + +#define DUMMY_XATTR(s) \ +int \ +linux_ ## s ## xattr( \ + struct thread *td, struct linux_ ## s ## xattr_args *arg) \ +{ \ + \ + return (ENOATTR); \ +} +DUMMY_XATTR(set); +DUMMY_XATTR(lset); +DUMMY_XATTR(fset); +DUMMY_XATTR(get); +DUMMY_XATTR(lget); +DUMMY_XATTR(fget); +DUMMY_XATTR(list); +DUMMY_XATTR(llist); +DUMMY_XATTR(flist); +DUMMY_XATTR(remove); +DUMMY_XATTR(lremove); +DUMMY_XATTR(fremove); diff --git a/sys/amd64/linux/linux_genassym.c b/sys/amd64/linux/linux_genassym.c new file mode 100644 index 0000000..0edb6a0 --- /dev/null +++ b/sys/amd64/linux/linux_genassym.c @@ -0,0 +1,15 @@ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/assym.h> +#include <sys/systm.h> + +#include <amd64/linux/linux.h> +#include <compat/linux/linux_mib.h> + +ASSYM(LINUX_RT_SIGF_HANDLER, offsetof(struct l_rt_sigframe, sf_handler)); +ASSYM(LINUX_RT_SIGF_UC, offsetof(struct l_rt_sigframe, sf_sc)); +ASSYM(LINUX_RT_SIGF_SC, offsetof(struct l_ucontext, uc_mcontext)); +ASSYM(LINUX_VERSION_CODE, LINUX_VERSION_CODE); +ASSYM(LINUX_SC_RSP, offsetof(struct l_sigcontext, sc_rsp)); diff --git a/sys/amd64/linux/linux_ipc64.h b/sys/amd64/linux/linux_ipc64.h new file mode 100644 index 0000000..913fc1a --- /dev/null +++ b/sys/amd64/linux/linux_ipc64.h @@ -0,0 +1,142 @@ +/*- + * Copyright (c) 2002 Maxim Sobolev <sobomax@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _AMD64_LINUX_LINUX_IPC64_H_ +#define _AMD64_LINUX_LINUX_IPC64_H_ + +/* + * The ipc64_perm structure for i386 architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 32-bit mode_t and seq + * - 2 miscellaneous 32-bit values + */ + +struct l_ipc64_perm +{ + l_key_t key; + l_uid_t uid; + l_gid_t gid; + l_uid_t cuid; + l_gid_t cgid; + l_mode_t mode; + l_ushort __pad1; + l_ushort seq; + l_ushort __pad2; + l_ulong __unused1; + l_ulong __unused2; +}; + +/* + * The msqid64_ds structure for i386 architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 64-bit time_t to solve y2038 problem + * - 2 miscellaneous 32-bit values + */ + +struct l_msqid64_ds { + struct l_ipc64_perm msg_perm; + l_time_t msg_stime; /* last msgsnd time */ + l_ulong __unused1; + l_time_t msg_rtime; /* last msgrcv time */ + l_ulong __unused2; + l_time_t msg_ctime; /* last change time */ + l_ulong __unused3; + l_ulong msg_cbytes; /* current number of bytes on queue */ + l_ulong msg_qnum; /* number of messages in queue */ + l_ulong msg_qbytes; /* max number of bytes on queue */ + l_pid_t msg_lspid; /* pid of last msgsnd */ + l_pid_t msg_lrpid; /* last receive pid */ + l_ulong __unused4; + l_ulong __unused5; +}; + +/* + * The semid64_ds structure for i386 architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 64-bit time_t to solve y2038 problem + * - 2 miscellaneous 32-bit values + */ + +struct l_semid64_ds { + struct l_ipc64_perm sem_perm; /* permissions */ + l_time_t sem_otime; /* last semop time */ + l_ulong __unused1; + l_time_t sem_ctime; /* last change time */ + l_ulong __unused2; + l_ulong sem_nsems; /* no. of semaphores in array */ + l_ulong __unused3; + l_ulong __unused4; +}; + +/* + * The shmid64_ds structure for i386 architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 64-bit time_t to solve y2038 problem + * - 2 miscellaneous 32-bit values + */ + +struct l_shmid64_ds { + struct l_ipc64_perm shm_perm; /* operation perms */ + l_size_t shm_segsz; /* size of segment (bytes) */ + l_time_t shm_atime; /* last attach time */ + l_time_t shm_dtime; /* last detach time */ + l_time_t shm_ctime; /* last change time */ + l_pid_t shm_cpid; /* pid of creator */ + l_pid_t shm_lpid; /* pid of last operator */ + l_ulong shm_nattch; /* no. of current attaches */ + l_ulong __unused4; + l_ulong __unused5; +}; + +struct l_shminfo64 { + l_ulong shmmax; + l_ulong shmmin; + l_ulong shmmni; + l_ulong shmseg; + l_ulong shmall; + l_ulong __unused1; + l_ulong __unused2; + l_ulong __unused3; + l_ulong __unused4; +}; + +#endif /* !_AMD64_LINUX_LINUX_IPC64_H_ */ diff --git a/sys/amd64/linux/linux_locore.s b/sys/amd64/linux/linux_locore.s new file mode 100644 index 0000000..5dcc09a --- /dev/null +++ b/sys/amd64/linux/linux_locore.s @@ -0,0 +1,76 @@ +/* $FreeBSD$ */ + +#include "linux_assym.h" /* system definitions */ +#include <machine/asmacros.h> /* miscellaneous asm macros */ + +#include <amd64/linux/linux_syscall.h> /* system call numbers */ + + .data + + .globl linux_platform +linux_platform: + .asciz "x86_64" + + + .text +/* + * To avoid excess stack frame the signal trampoline code emulates + * the 'call' instruction. + */ +NON_GPROF_ENTRY(linux_rt_sigcode) + movq %rsp, %rbx /* preserve sigframe */ + call .getip +.getip: + popq %rax + add $.startrtsigcode-.getip, %rax /* ret address */ + pushq %rax + jmp *LINUX_RT_SIGF_HANDLER(%rbx) +.startrtsigcode: + movq $LINUX_SYS_linux_rt_sigreturn,%rax /* linux_rt_sigreturn() */ + syscall /* enter kernel with args */ + hlt +0: jmp 0b + +NON_GPROF_ENTRY(__vdso_clock_gettime) + movq $LINUX_SYS_linux_clock_gettime,%rax + syscall + ret +.weak clock_gettime +.set clock_gettime, __vdso_clock_gettime + +NON_GPROF_ENTRY(__vdso_time) + movq $LINUX_SYS_linux_time,%rax + syscall + ret +.weak time +.set time, __vdso_time + +NON_GPROF_ENTRY(__vdso_gettimeofday) + movq $LINUX_SYS_gettimeofday,%rax + syscall + ret +.weak gettimeofday +.set gettimeofday, __vdso_gettimeofday + +NON_GPROF_ENTRY(__vdso_getcpu) + movq $-38,%rax /* not implemented */ + ret +.weak getcpu +.set getcpu, __vdso_getcpu + +#if 0 + .section .note.Linux, "a",@note + .long 2f - 1f /* namesz */ + .balign 4 + .long 4f - 3f /* descsz */ + .long 0 +1: + .asciz "Linux" +2: + .balign 4 +3: + .long LINUX_VERSION_CODE +4: + .balign 4 + .previous +#endif diff --git a/sys/amd64/linux/linux_machdep.c b/sys/amd64/linux/linux_machdep.c new file mode 100644 index 0000000..d6174e6 --- /dev/null +++ b/sys/amd64/linux/linux_machdep.c @@ -0,0 +1,433 @@ +/*- + * Copyright (c) 2013 Dmitry Chagin + * Copyright (c) 2004 Tim J. Robbins + * Copyright (c) 2002 Doug Rabson + * Copyright (c) 2000 Marcel Moolenaar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/systm.h> +#include <sys/capability.h> +#include <sys/dirent.h> +#include <sys/file.h> +#include <sys/fcntl.h> +#include <sys/filedesc.h> +#include <sys/clock.h> +#include <sys/imgact.h> +#include <sys/ktr.h> +#include <sys/limits.h> +#include <sys/lock.h> +#include <sys/malloc.h> +#include <sys/mman.h> +#include <sys/mutex.h> +#include <sys/priv.h> +#include <sys/proc.h> +#include <sys/resource.h> +#include <sys/resourcevar.h> +#include <sys/sched.h> +#include <sys/syscallsubr.h> +#include <sys/sysproto.h> +#include <sys/vnode.h> +#include <sys/unistd.h> +#include <sys/wait.h> + +#include <security/mac/mac_framework.h> + +#include <ufs/ufs/extattr.h> +#include <ufs/ufs/quota.h> +#include <ufs/ufs/ufsmount.h> + +#include <machine/frame.h> +#include <machine/md_var.h> +#include <machine/pcb.h> +#include <machine/psl.h> +#include <machine/segments.h> +#include <machine/specialreg.h> + +#include <vm/vm.h> +#include <vm/pmap.h> +#include <vm/vm_extern.h> +#include <vm/vm_kern.h> +#include <vm/vm_map.h> + +#include <amd64/linux/linux.h> +#include <amd64/linux/linux_proto.h> +#include <compat/linux/linux_ipc.h> +#include <compat/linux/linux_file.h> +#include <compat/linux/linux_misc.h> +#include <compat/linux/linux_signal.h> +#include <compat/linux/linux_util.h> +#include <compat/linux/linux_emul.h> + + +int +linux_execve(struct thread *td, struct linux_execve_args *args) +{ + struct image_args eargs; + char *path; + int error; + + LCONVPATHEXIST(td, args->path, &path); + + LINUX_CTR(execve); + + error = exec_copyin_args(&eargs, path, UIO_SYSSPACE, args->argp, + args->envp); + free(path, M_TEMP); + if (error == 0) + error = linux_common_execve(td, &eargs); + return (error); +} + +int +linux_set_upcall_kse(struct thread *td, register_t stack) +{ + + if (stack) + td->td_frame->tf_rsp = stack; + + /* + * The newly created Linux thread returns + * to the user space by the same path that a parent do. + */ + td->td_frame->tf_rax = 0; + return (0); +} + +#define STACK_SIZE (2 * 1024 * 1024) +#define GUARD_SIZE (4 * PAGE_SIZE) + +int +linux_mmap2(struct thread *td, struct linux_mmap2_args *args) +{ + struct proc *p = td->td_proc; + struct mmap_args /* { + caddr_t addr; + size_t len; + int prot; + int flags; + int fd; + long pad; + off_t pos; + } */ bsd_args; + int error; + struct file *fp; + cap_rights_t rights; + + LINUX_CTR6(mmap2, "0x%lx, %ld, %ld, 0x%08lx, %ld, 0x%lx", + args->addr, args->len, args->prot, + args->flags, args->fd, args->pgoff); + + error = 0; + bsd_args.flags = 0; + fp = NULL; + + /* + * Linux mmap(2): + * You must specify exactly one of MAP_SHARED and MAP_PRIVATE + */ + if (! ((args->flags & LINUX_MAP_SHARED) ^ + (args->flags & LINUX_MAP_PRIVATE))) + return (EINVAL); + + if (args->flags & LINUX_MAP_SHARED) + bsd_args.flags |= MAP_SHARED; + if (args->flags & LINUX_MAP_PRIVATE) + bsd_args.flags |= MAP_PRIVATE; + if (args->flags & LINUX_MAP_FIXED) + bsd_args.flags |= MAP_FIXED; + if (args->flags & LINUX_MAP_ANON) + bsd_args.flags |= MAP_ANON; + else + bsd_args.flags |= MAP_NOSYNC; + if (args->flags & LINUX_MAP_GROWSDOWN) + bsd_args.flags |= MAP_STACK; + + /* + * PROT_READ, PROT_WRITE, or PROT_EXEC implies PROT_READ and PROT_EXEC + * on Linux/i386. We do this to ensure maximum compatibility. + * Linux/ia64 does the same in i386 emulation mode. + */ + bsd_args.prot = args->prot; + if (bsd_args.prot & (PROT_READ | PROT_WRITE | PROT_EXEC)) + bsd_args.prot |= PROT_READ | PROT_EXEC; + + /* Linux does not check file descriptor when MAP_ANONYMOUS is set. */ + bsd_args.fd = (bsd_args.flags & MAP_ANON) ? -1 : args->fd; + if (bsd_args.fd != -1) { + /* + * Linux follows Solaris mmap(2) description: + * The file descriptor fildes is opened with + * read permission, regardless of the + * protection options specified. + */ + + error = fget(td, bsd_args.fd, + cap_rights_init(&rights, CAP_MMAP), &fp); + if (error != 0 ) + return (error); + if (fp->f_type != DTYPE_VNODE) { + fdrop(fp, td); + return (EINVAL); + } + + /* Linux mmap() just fails for O_WRONLY files */ + if (!(fp->f_flag & FREAD)) { + fdrop(fp, td); + return (EACCES); + } + + fdrop(fp, td); + } + + if (args->flags & LINUX_MAP_GROWSDOWN) { + /* + * The Linux MAP_GROWSDOWN option does not limit auto + * growth of the region. Linux mmap with this option + * takes as addr the inital BOS, and as len, the initial + * region size. It can then grow down from addr without + * limit. However, Linux threads has an implicit internal + * limit to stack size of STACK_SIZE. Its just not + * enforced explicitly in Linux. But, here we impose + * a limit of (STACK_SIZE - GUARD_SIZE) on the stack + * region, since we can do this with our mmap. + * + * Our mmap with MAP_STACK takes addr as the maximum + * downsize limit on BOS, and as len the max size of + * the region. It then maps the top SGROWSIZ bytes, + * and auto grows the region down, up to the limit + * in addr. + * + * If we don't use the MAP_STACK option, the effect + * of this code is to allocate a stack region of a + * fixed size of (STACK_SIZE - GUARD_SIZE). + */ + + if ((caddr_t)PTRIN(args->addr) + args->len > + p->p_vmspace->vm_maxsaddr) { + /* + * Some Linux apps will attempt to mmap + * thread stacks near the top of their + * address space. If their TOS is greater + * than vm_maxsaddr, vm_map_growstack() + * will confuse the thread stack with the + * process stack and deliver a SEGV if they + * attempt to grow the thread stack past their + * current stacksize rlimit. To avoid this, + * adjust vm_maxsaddr upwards to reflect + * the current stacksize rlimit rather + * than the maximum possible stacksize. + * It would be better to adjust the + * mmap'ed region, but some apps do not check + * mmap's return value. + */ + PROC_LOCK(p); + p->p_vmspace->vm_maxsaddr = (char *)USRSTACK - + lim_cur(p, RLIMIT_STACK); + PROC_UNLOCK(p); + } + + /* + * This gives us our maximum stack size and a new BOS. + * If we're using VM_STACK, then mmap will just map + * the top SGROWSIZ bytes, and let the stack grow down + * to the limit at BOS. If we're not using VM_STACK + * we map the full stack, since we don't have a way + * to autogrow it. + */ + if (args->len > STACK_SIZE - GUARD_SIZE) { + bsd_args.addr = (caddr_t)PTRIN(args->addr); + bsd_args.len = args->len; + } else { + bsd_args.addr = (caddr_t)PTRIN(args->addr) - + (STACK_SIZE - GUARD_SIZE - args->len); + bsd_args.len = STACK_SIZE - GUARD_SIZE; + } + } else { + bsd_args.addr = (caddr_t)PTRIN(args->addr); + bsd_args.len = args->len; + } + bsd_args.pos = (off_t)args->pgoff; + + error = sys_mmap(td, &bsd_args); + + LINUX_CTR2(mmap2, "return: %d (%p)", + error, td->td_retval[0]); + return (error); +} + +int +linux_mprotect(struct thread *td, struct linux_mprotect_args *uap) +{ + struct mprotect_args bsd_args; + + LINUX_CTR(mprotect); + + bsd_args.addr = uap->addr; + bsd_args.len = uap->len; + bsd_args.prot = uap->prot; + if (bsd_args.prot & (PROT_READ | PROT_WRITE | PROT_EXEC)) + bsd_args.prot |= PROT_READ | PROT_EXEC; + return (sys_mprotect(td, &bsd_args)); +} + +int +linux_iopl(struct thread *td, struct linux_iopl_args *args) +{ + int error; + + LINUX_CTR(iopl); + + if (args->level > 3) + return (EINVAL); + if ((error = priv_check(td, PRIV_IO)) != 0) + return (error); + if ((error = securelevel_gt(td->td_ucred, 0)) != 0) + return (error); + td->td_frame->tf_rflags = (td->td_frame->tf_rflags & ~PSL_IOPL) | + (args->level * (PSL_IOPL / 3)); + + return (0); +} + +int +linux_rt_sigsuspend(struct thread *td, struct linux_rt_sigsuspend_args *uap) +{ + l_sigset_t lmask; + sigset_t sigmask; + int error; + + LINUX_CTR2(rt_sigsuspend, "%p, %ld", + uap->newset, uap->sigsetsize); + + if (uap->sigsetsize != sizeof(l_sigset_t)) + return (EINVAL); + + error = copyin(uap->newset, &lmask, sizeof(l_sigset_t)); + if (error) + return (error); + + linux_to_bsd_sigset(&lmask, &sigmask); + return (kern_sigsuspend(td, sigmask)); +} + +int +linux_pause(struct thread *td, struct linux_pause_args *args) +{ + struct proc *p = td->td_proc; + sigset_t sigmask; + + LINUX_CTR(pause); + + PROC_LOCK(p); + sigmask = td->td_sigmask; + PROC_UNLOCK(p); + return (kern_sigsuspend(td, sigmask)); +} + +int +linux_sigaltstack(struct thread *td, struct linux_sigaltstack_args *uap) +{ + stack_t ss, oss; + l_stack_t lss; + int error; + + LINUX_CTR2(sigaltstack, "%p, %p", uap->uss, uap->uoss); + + if (uap->uss != NULL) { + error = copyin(uap->uss, &lss, sizeof(l_stack_t)); + if (error) + return (error); + + ss.ss_sp = PTRIN(lss.ss_sp); + ss.ss_size = lss.ss_size; + ss.ss_flags = linux_to_bsd_sigaltstack(lss.ss_flags); + } + error = kern_sigaltstack(td, (uap->uss != NULL) ? &ss : NULL, + (uap->uoss != NULL) ? &oss : NULL); + if (!error && uap->uoss != NULL) { + lss.ss_sp = PTROUT(oss.ss_sp); + lss.ss_size = oss.ss_size; + lss.ss_flags = bsd_to_linux_sigaltstack(oss.ss_flags); + error = copyout(&lss, uap->uoss, sizeof(l_stack_t)); + } + + return (error); +} + +/* XXX do all */ +int +linux_arch_prctl(struct thread *td, struct linux_arch_prctl_args *args) +{ + int error; + struct pcb *pcb; + + LINUX_CTR2(arch_prctl, "0x%x, %p", args->code, args->addr); + + error = ENOTSUP; + pcb = td->td_pcb; + + switch (args->code) { + case LINUX_ARCH_GET_GS: + error = copyout(&pcb->pcb_gsbase, (unsigned long *)args->addr, + sizeof(args->addr)); + break; + case LINUX_ARCH_SET_GS: + if (args->addr >= VM_MAXUSER_ADDRESS) + return(EPERM); + break; + case LINUX_ARCH_GET_FS: + error = copyout(&pcb->pcb_fsbase, (unsigned long *)args->addr, + sizeof(args->addr)); + break; + case LINUX_ARCH_SET_FS: + error = linux_set_cloned_tls(td, (void *)args->addr); + break; + default: + error = EINVAL; + } + return (error); +} + +int +linux_set_cloned_tls(struct thread *td, void *desc) +{ + struct pcb *pcb; + + if ((uint64_t)desc >= VM_MAXUSER_ADDRESS) + return (EPERM); + + pcb = td->td_pcb; + pcb->pcb_fsbase = (register_t)desc; + td->td_frame->tf_fs = _ufssel; + + return (0); +} diff --git a/sys/amd64/linux/linux_proto.h b/sys/amd64/linux/linux_proto.h new file mode 100644 index 0000000..eedd423 --- /dev/null +++ b/sys/amd64/linux/linux_proto.h @@ -0,0 +1,1663 @@ +/* + * System call prototypes. + * + * DO NOT EDIT-- this file is automatically generated. + * $FreeBSD$ + * created from FreeBSD: stable/10/sys/amd64/linux/syscalls.master 293592 2016-01-09 17:54:37Z dchagin + */ + +#ifndef _LINUX_SYSPROTO_H_ +#define _LINUX_SYSPROTO_H_ + +#include <sys/signal.h> +#include <sys/acl.h> +#include <sys/cpuset.h> +#include <sys/_ffcounter.h> +#include <sys/_semaphore.h> +#include <sys/ucontext.h> +#include <sys/wait.h> + +#include <bsm/audit_kevents.h> + +struct proc; + +struct thread; + +#define PAD_(t) (sizeof(register_t) <= sizeof(t) ? \ + 0 : sizeof(register_t) - sizeof(t)) + +#if BYTE_ORDER == LITTLE_ENDIAN +#define PADL_(t) 0 +#define PADR_(t) PAD_(t) +#else +#define PADL_(t) PAD_(t) +#define PADR_(t) 0 +#endif + +#define nosys linux_nosys +struct linux_open_args { + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; + char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)]; + char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)]; +}; +struct linux_newstat_args { + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; + char buf_l_[PADL_(struct l_newstat *)]; struct l_newstat * buf; char buf_r_[PADR_(struct l_newstat *)]; +}; +struct linux_newfstat_args { + char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)]; + char buf_l_[PADL_(struct l_newstat *)]; struct l_newstat * buf; char buf_r_[PADR_(struct l_newstat *)]; +}; +struct linux_newlstat_args { + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; + char buf_l_[PADL_(struct l_newstat *)]; struct l_newstat * buf; char buf_r_[PADR_(struct l_newstat *)]; +}; +struct linux_lseek_args { + char fdes_l_[PADL_(l_uint)]; l_uint fdes; char fdes_r_[PADR_(l_uint)]; + char off_l_[PADL_(l_off_t)]; l_off_t off; char off_r_[PADR_(l_off_t)]; + char whence_l_[PADL_(l_int)]; l_int whence; char whence_r_[PADR_(l_int)]; +}; +struct linux_mmap2_args { + char addr_l_[PADL_(l_ulong)]; l_ulong addr; char addr_r_[PADR_(l_ulong)]; + char len_l_[PADL_(l_ulong)]; l_ulong len; char len_r_[PADR_(l_ulong)]; + char prot_l_[PADL_(l_ulong)]; l_ulong prot; char prot_r_[PADR_(l_ulong)]; + char flags_l_[PADL_(l_ulong)]; l_ulong flags; char flags_r_[PADR_(l_ulong)]; + char fd_l_[PADL_(l_ulong)]; l_ulong fd; char fd_r_[PADR_(l_ulong)]; + char pgoff_l_[PADL_(l_ulong)]; l_ulong pgoff; char pgoff_r_[PADR_(l_ulong)]; +}; +struct linux_mprotect_args { + char addr_l_[PADL_(caddr_t)]; caddr_t addr; char addr_r_[PADR_(caddr_t)]; + char len_l_[PADL_(int)]; int len; char len_r_[PADR_(int)]; + char prot_l_[PADL_(int)]; int prot; char prot_r_[PADR_(int)]; +}; +struct linux_brk_args { + char dsend_l_[PADL_(l_ulong)]; l_ulong dsend; char dsend_r_[PADR_(l_ulong)]; +}; +struct linux_rt_sigaction_args { + char sig_l_[PADL_(l_int)]; l_int sig; char sig_r_[PADR_(l_int)]; + char act_l_[PADL_(l_sigaction_t *)]; l_sigaction_t * act; char act_r_[PADR_(l_sigaction_t *)]; + char oact_l_[PADL_(l_sigaction_t *)]; l_sigaction_t * oact; char oact_r_[PADR_(l_sigaction_t *)]; + char sigsetsize_l_[PADL_(l_size_t)]; l_size_t sigsetsize; char sigsetsize_r_[PADR_(l_size_t)]; +}; +struct linux_rt_sigprocmask_args { + char how_l_[PADL_(l_int)]; l_int how; char how_r_[PADR_(l_int)]; + char mask_l_[PADL_(l_sigset_t *)]; l_sigset_t * mask; char mask_r_[PADR_(l_sigset_t *)]; + char omask_l_[PADL_(l_sigset_t *)]; l_sigset_t * omask; char omask_r_[PADR_(l_sigset_t *)]; + char sigsetsize_l_[PADL_(l_size_t)]; l_size_t sigsetsize; char sigsetsize_r_[PADR_(l_size_t)]; +}; +struct linux_rt_sigreturn_args { + char ucp_l_[PADL_(struct l_ucontext *)]; struct l_ucontext * ucp; char ucp_r_[PADR_(struct l_ucontext *)]; +}; +struct linux_ioctl_args { + char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)]; + char cmd_l_[PADL_(l_uint)]; l_uint cmd; char cmd_r_[PADR_(l_uint)]; + char arg_l_[PADL_(uintptr_t)]; uintptr_t arg; char arg_r_[PADR_(uintptr_t)]; +}; +struct linux_pread_args { + char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)]; + char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)]; + char nbyte_l_[PADL_(l_size_t)]; l_size_t nbyte; char nbyte_r_[PADR_(l_size_t)]; + char offset_l_[PADL_(l_loff_t)]; l_loff_t offset; char offset_r_[PADR_(l_loff_t)]; +}; +struct linux_pwrite_args { + char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)]; + char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)]; + char nbyte_l_[PADL_(l_size_t)]; l_size_t nbyte; char nbyte_r_[PADR_(l_size_t)]; + char offset_l_[PADL_(l_loff_t)]; l_loff_t offset; char offset_r_[PADR_(l_loff_t)]; +}; +struct linux_access_args { + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; + char amode_l_[PADL_(l_int)]; l_int amode; char amode_r_[PADR_(l_int)]; +}; +struct linux_pipe_args { + char pipefds_l_[PADL_(l_ulong *)]; l_ulong * pipefds; char pipefds_r_[PADR_(l_ulong *)]; +}; +struct linux_select_args { + char nfds_l_[PADL_(l_int)]; l_int nfds; char nfds_r_[PADR_(l_int)]; + char readfds_l_[PADL_(l_fd_set *)]; l_fd_set * readfds; char readfds_r_[PADR_(l_fd_set *)]; + char writefds_l_[PADL_(l_fd_set *)]; l_fd_set * writefds; char writefds_r_[PADR_(l_fd_set *)]; + char exceptfds_l_[PADL_(l_fd_set *)]; l_fd_set * exceptfds; char exceptfds_r_[PADR_(l_fd_set *)]; + char timeout_l_[PADL_(struct l_timeval *)]; struct l_timeval * timeout; char timeout_r_[PADR_(struct l_timeval *)]; +}; +struct linux_mremap_args { + char addr_l_[PADL_(l_ulong)]; l_ulong addr; char addr_r_[PADR_(l_ulong)]; + char old_len_l_[PADL_(l_ulong)]; l_ulong old_len; char old_len_r_[PADR_(l_ulong)]; + char new_len_l_[PADL_(l_ulong)]; l_ulong new_len; char new_len_r_[PADR_(l_ulong)]; + char flags_l_[PADL_(l_ulong)]; l_ulong flags; char flags_r_[PADR_(l_ulong)]; + char new_addr_l_[PADL_(l_ulong)]; l_ulong new_addr; char new_addr_r_[PADR_(l_ulong)]; +}; +struct linux_msync_args { + char addr_l_[PADL_(l_ulong)]; l_ulong addr; char addr_r_[PADR_(l_ulong)]; + char len_l_[PADL_(l_size_t)]; l_size_t len; char len_r_[PADR_(l_size_t)]; + char fl_l_[PADL_(l_int)]; l_int fl; char fl_r_[PADR_(l_int)]; +}; +struct linux_mincore_args { + char start_l_[PADL_(l_ulong)]; l_ulong start; char start_r_[PADR_(l_ulong)]; + char len_l_[PADL_(l_size_t)]; l_size_t len; char len_r_[PADR_(l_size_t)]; + char vec_l_[PADL_(u_char *)]; u_char * vec; char vec_r_[PADR_(u_char *)]; +}; +struct linux_shmget_args { + char key_l_[PADL_(l_key_t)]; l_key_t key; char key_r_[PADR_(l_key_t)]; + char size_l_[PADL_(l_size_t)]; l_size_t size; char size_r_[PADR_(l_size_t)]; + char shmflg_l_[PADL_(l_int)]; l_int shmflg; char shmflg_r_[PADR_(l_int)]; +}; +struct linux_shmat_args { + char shmid_l_[PADL_(l_int)]; l_int shmid; char shmid_r_[PADR_(l_int)]; + char shmaddr_l_[PADL_(char *)]; char * shmaddr; char shmaddr_r_[PADR_(char *)]; + char shmflg_l_[PADL_(l_int)]; l_int shmflg; char shmflg_r_[PADR_(l_int)]; +}; +struct linux_shmctl_args { + char shmid_l_[PADL_(l_int)]; l_int shmid; char shmid_r_[PADR_(l_int)]; + char cmd_l_[PADL_(l_int)]; l_int cmd; char cmd_r_[PADR_(l_int)]; + char buf_l_[PADL_(struct l_shmid_ds *)]; struct l_shmid_ds * buf; char buf_r_[PADR_(struct l_shmid_ds *)]; +}; +struct linux_pause_args { + register_t dummy; +}; +struct linux_nanosleep_args { + char rqtp_l_[PADL_(const struct l_timespec *)]; const struct l_timespec * rqtp; char rqtp_r_[PADR_(const struct l_timespec *)]; + char rmtp_l_[PADL_(struct l_timespec *)]; struct l_timespec * rmtp; char rmtp_r_[PADR_(struct l_timespec *)]; +}; +struct linux_getitimer_args { + char which_l_[PADL_(l_int)]; l_int which; char which_r_[PADR_(l_int)]; + char itv_l_[PADL_(struct l_itimerval *)]; struct l_itimerval * itv; char itv_r_[PADR_(struct l_itimerval *)]; +}; +struct linux_alarm_args { + char secs_l_[PADL_(l_uint)]; l_uint secs; char secs_r_[PADR_(l_uint)]; +}; +struct linux_setitimer_args { + char which_l_[PADL_(l_int)]; l_int which; char which_r_[PADR_(l_int)]; + char itv_l_[PADL_(struct l_itimerval *)]; struct l_itimerval * itv; char itv_r_[PADR_(struct l_itimerval *)]; + char oitv_l_[PADL_(struct l_itimerval *)]; struct l_itimerval * oitv; char oitv_r_[PADR_(struct l_itimerval *)]; +}; +struct linux_getpid_args { + register_t dummy; +}; +struct linux_sendfile_args { + char out_l_[PADL_(int)]; int out; char out_r_[PADR_(int)]; + char in_l_[PADL_(int)]; int in; char in_r_[PADR_(int)]; + char offset_l_[PADL_(l_long *)]; l_long * offset; char offset_r_[PADR_(l_long *)]; + char count_l_[PADL_(l_size_t)]; l_size_t count; char count_r_[PADR_(l_size_t)]; +}; +struct linux_socket_args { + char domain_l_[PADL_(l_int)]; l_int domain; char domain_r_[PADR_(l_int)]; + char type_l_[PADL_(l_int)]; l_int type; char type_r_[PADR_(l_int)]; + char protocol_l_[PADL_(l_int)]; l_int protocol; char protocol_r_[PADR_(l_int)]; +}; +struct linux_connect_args { + char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)]; + char name_l_[PADL_(l_uintptr_t)]; l_uintptr_t name; char name_r_[PADR_(l_uintptr_t)]; + char namelen_l_[PADL_(l_int)]; l_int namelen; char namelen_r_[PADR_(l_int)]; +}; +struct linux_accept_args { + char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)]; + char addr_l_[PADL_(l_uintptr_t)]; l_uintptr_t addr; char addr_r_[PADR_(l_uintptr_t)]; + char namelen_l_[PADL_(l_uintptr_t)]; l_uintptr_t namelen; char namelen_r_[PADR_(l_uintptr_t)]; +}; +struct linux_sendto_args { + char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)]; + char msg_l_[PADL_(l_uintptr_t)]; l_uintptr_t msg; char msg_r_[PADR_(l_uintptr_t)]; + char len_l_[PADL_(l_int)]; l_int len; char len_r_[PADR_(l_int)]; + char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)]; + char to_l_[PADL_(l_uintptr_t)]; l_uintptr_t to; char to_r_[PADR_(l_uintptr_t)]; + char tolen_l_[PADL_(l_int)]; l_int tolen; char tolen_r_[PADR_(l_int)]; +}; +struct linux_recvfrom_args { + char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)]; + char buf_l_[PADL_(l_uintptr_t)]; l_uintptr_t buf; char buf_r_[PADR_(l_uintptr_t)]; + char len_l_[PADL_(l_size_t)]; l_size_t len; char len_r_[PADR_(l_size_t)]; + char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)]; + char from_l_[PADL_(l_uintptr_t)]; l_uintptr_t from; char from_r_[PADR_(l_uintptr_t)]; + char fromlen_l_[PADL_(l_uintptr_t)]; l_uintptr_t fromlen; char fromlen_r_[PADR_(l_uintptr_t)]; +}; +struct linux_sendmsg_args { + char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)]; + char msg_l_[PADL_(l_uintptr_t)]; l_uintptr_t msg; char msg_r_[PADR_(l_uintptr_t)]; + char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)]; +}; +struct linux_recvmsg_args { + char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)]; + char msg_l_[PADL_(l_uintptr_t)]; l_uintptr_t msg; char msg_r_[PADR_(l_uintptr_t)]; + char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)]; +}; +struct linux_shutdown_args { + char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)]; + char how_l_[PADL_(l_int)]; l_int how; char how_r_[PADR_(l_int)]; +}; +struct linux_bind_args { + char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)]; + char name_l_[PADL_(l_uintptr_t)]; l_uintptr_t name; char name_r_[PADR_(l_uintptr_t)]; + char namelen_l_[PADL_(l_int)]; l_int namelen; char namelen_r_[PADR_(l_int)]; +}; +struct linux_listen_args { + char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)]; + char backlog_l_[PADL_(l_int)]; l_int backlog; char backlog_r_[PADR_(l_int)]; +}; +struct linux_getsockname_args { + char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)]; + char addr_l_[PADL_(l_uintptr_t)]; l_uintptr_t addr; char addr_r_[PADR_(l_uintptr_t)]; + char namelen_l_[PADL_(l_uintptr_t)]; l_uintptr_t namelen; char namelen_r_[PADR_(l_uintptr_t)]; +}; +struct linux_getpeername_args { + char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)]; + char addr_l_[PADL_(l_uintptr_t)]; l_uintptr_t addr; char addr_r_[PADR_(l_uintptr_t)]; + char namelen_l_[PADL_(l_uintptr_t)]; l_uintptr_t namelen; char namelen_r_[PADR_(l_uintptr_t)]; +}; +struct linux_socketpair_args { + char domain_l_[PADL_(l_int)]; l_int domain; char domain_r_[PADR_(l_int)]; + char type_l_[PADL_(l_int)]; l_int type; char type_r_[PADR_(l_int)]; + char protocol_l_[PADL_(l_int)]; l_int protocol; char protocol_r_[PADR_(l_int)]; + char rsv_l_[PADL_(l_uintptr_t)]; l_uintptr_t rsv; char rsv_r_[PADR_(l_uintptr_t)]; +}; +struct linux_setsockopt_args { + char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)]; + char level_l_[PADL_(l_int)]; l_int level; char level_r_[PADR_(l_int)]; + char optname_l_[PADL_(l_int)]; l_int optname; char optname_r_[PADR_(l_int)]; + char optval_l_[PADL_(l_uintptr_t)]; l_uintptr_t optval; char optval_r_[PADR_(l_uintptr_t)]; + char optlen_l_[PADL_(l_int)]; l_int optlen; char optlen_r_[PADR_(l_int)]; +}; +struct linux_getsockopt_args { + char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)]; + char level_l_[PADL_(l_int)]; l_int level; char level_r_[PADR_(l_int)]; + char optname_l_[PADL_(l_int)]; l_int optname; char optname_r_[PADR_(l_int)]; + char optval_l_[PADL_(l_uintptr_t)]; l_uintptr_t optval; char optval_r_[PADR_(l_uintptr_t)]; + char optlen_l_[PADL_(l_uintptr_t)]; l_uintptr_t optlen; char optlen_r_[PADR_(l_uintptr_t)]; +}; +struct linux_clone_args { + char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)]; + char stack_l_[PADL_(void *)]; void * stack; char stack_r_[PADR_(void *)]; + char parent_tidptr_l_[PADL_(void *)]; void * parent_tidptr; char parent_tidptr_r_[PADR_(void *)]; + char child_tidptr_l_[PADL_(void *)]; void * child_tidptr; char child_tidptr_r_[PADR_(void *)]; + char tls_l_[PADL_(void *)]; void * tls; char tls_r_[PADR_(void *)]; +}; +struct linux_fork_args { + register_t dummy; +}; +struct linux_vfork_args { + register_t dummy; +}; +struct linux_execve_args { + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; + char argp_l_[PADL_(char **)]; char ** argp; char argp_r_[PADR_(char **)]; + char envp_l_[PADL_(char **)]; char ** envp; char envp_r_[PADR_(char **)]; +}; +struct linux_exit_args { + char rval_l_[PADL_(int)]; int rval; char rval_r_[PADR_(int)]; +}; +struct linux_wait4_args { + char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)]; + char status_l_[PADL_(l_int *)]; l_int * status; char status_r_[PADR_(l_int *)]; + char options_l_[PADL_(l_int)]; l_int options; char options_r_[PADR_(l_int)]; + char rusage_l_[PADL_(struct rusage *)]; struct rusage * rusage; char rusage_r_[PADR_(struct rusage *)]; +}; +struct linux_kill_args { + char pid_l_[PADL_(l_int)]; l_int pid; char pid_r_[PADR_(l_int)]; + char signum_l_[PADL_(l_int)]; l_int signum; char signum_r_[PADR_(l_int)]; +}; +struct linux_newuname_args { + char buf_l_[PADL_(struct l_new_utsname *)]; struct l_new_utsname * buf; char buf_r_[PADR_(struct l_new_utsname *)]; +}; +struct linux_semget_args { + char key_l_[PADL_(l_key_t)]; l_key_t key; char key_r_[PADR_(l_key_t)]; + char nsems_l_[PADL_(l_int)]; l_int nsems; char nsems_r_[PADR_(l_int)]; + char semflg_l_[PADL_(l_int)]; l_int semflg; char semflg_r_[PADR_(l_int)]; +}; +struct linux_semop_args { + char semid_l_[PADL_(l_int)]; l_int semid; char semid_r_[PADR_(l_int)]; + char tsops_l_[PADL_(struct l_sembuf *)]; struct l_sembuf * tsops; char tsops_r_[PADR_(struct l_sembuf *)]; + char nsops_l_[PADL_(l_uint)]; l_uint nsops; char nsops_r_[PADR_(l_uint)]; +}; +struct linux_semctl_args { + char semid_l_[PADL_(l_int)]; l_int semid; char semid_r_[PADR_(l_int)]; + char semnum_l_[PADL_(l_int)]; l_int semnum; char semnum_r_[PADR_(l_int)]; + char cmd_l_[PADL_(l_int)]; l_int cmd; char cmd_r_[PADR_(l_int)]; + char arg_l_[PADL_(union l_semun)]; union l_semun arg; char arg_r_[PADR_(union l_semun)]; +}; +struct linux_shmdt_args { + char shmaddr_l_[PADL_(char *)]; char * shmaddr; char shmaddr_r_[PADR_(char *)]; +}; +struct linux_msgget_args { + char key_l_[PADL_(l_key_t)]; l_key_t key; char key_r_[PADR_(l_key_t)]; + char msgflg_l_[PADL_(l_int)]; l_int msgflg; char msgflg_r_[PADR_(l_int)]; +}; +struct linux_msgsnd_args { + char msqid_l_[PADL_(l_int)]; l_int msqid; char msqid_r_[PADR_(l_int)]; + char msgp_l_[PADL_(struct l_msgbuf *)]; struct l_msgbuf * msgp; char msgp_r_[PADR_(struct l_msgbuf *)]; + char msgsz_l_[PADL_(l_size_t)]; l_size_t msgsz; char msgsz_r_[PADR_(l_size_t)]; + char msgflg_l_[PADL_(l_int)]; l_int msgflg; char msgflg_r_[PADR_(l_int)]; +}; +struct linux_msgrcv_args { + char msqid_l_[PADL_(l_int)]; l_int msqid; char msqid_r_[PADR_(l_int)]; + char msgp_l_[PADL_(struct l_msgbuf *)]; struct l_msgbuf * msgp; char msgp_r_[PADR_(struct l_msgbuf *)]; + char msgsz_l_[PADL_(l_size_t)]; l_size_t msgsz; char msgsz_r_[PADR_(l_size_t)]; + char msgtyp_l_[PADL_(l_long)]; l_long msgtyp; char msgtyp_r_[PADR_(l_long)]; + char msgflg_l_[PADL_(l_int)]; l_int msgflg; char msgflg_r_[PADR_(l_int)]; +}; +struct linux_msgctl_args { + char msqid_l_[PADL_(l_int)]; l_int msqid; char msqid_r_[PADR_(l_int)]; + char cmd_l_[PADL_(l_int)]; l_int cmd; char cmd_r_[PADR_(l_int)]; + char buf_l_[PADL_(struct l_msqid_ds *)]; struct l_msqid_ds * buf; char buf_r_[PADR_(struct l_msqid_ds *)]; +}; +struct linux_fcntl_args { + char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)]; + char cmd_l_[PADL_(l_uint)]; l_uint cmd; char cmd_r_[PADR_(l_uint)]; + char arg_l_[PADL_(l_ulong)]; l_ulong arg; char arg_r_[PADR_(l_ulong)]; +}; +struct linux_fdatasync_args { + char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)]; +}; +struct linux_truncate_args { + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; + char length_l_[PADL_(l_ulong)]; l_ulong length; char length_r_[PADR_(l_ulong)]; +}; +struct linux_ftruncate_args { + char fd_l_[PADL_(l_int)]; l_int fd; char fd_r_[PADR_(l_int)]; + char length_l_[PADL_(l_long)]; l_long length; char length_r_[PADR_(l_long)]; +}; +struct linux_getdents_args { + char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)]; + char dent_l_[PADL_(void *)]; void * dent; char dent_r_[PADR_(void *)]; + char count_l_[PADL_(l_uint)]; l_uint count; char count_r_[PADR_(l_uint)]; +}; +struct linux_getcwd_args { + char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)]; + char bufsize_l_[PADL_(l_ulong)]; l_ulong bufsize; char bufsize_r_[PADR_(l_ulong)]; +}; +struct linux_chdir_args { + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; +}; +struct linux_rename_args { + char from_l_[PADL_(char *)]; char * from; char from_r_[PADR_(char *)]; + char to_l_[PADL_(char *)]; char * to; char to_r_[PADR_(char *)]; +}; +struct linux_mkdir_args { + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; + char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)]; +}; +struct linux_rmdir_args { + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; +}; +struct linux_creat_args { + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; + char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)]; +}; +struct linux_link_args { + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; + char to_l_[PADL_(char *)]; char * to; char to_r_[PADR_(char *)]; +}; +struct linux_unlink_args { + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; +}; +struct linux_symlink_args { + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; + char to_l_[PADL_(char *)]; char * to; char to_r_[PADR_(char *)]; +}; +struct linux_readlink_args { + char name_l_[PADL_(char *)]; char * name; char name_r_[PADR_(char *)]; + char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)]; + char count_l_[PADL_(l_int)]; l_int count; char count_r_[PADR_(l_int)]; +}; +struct linux_chmod_args { + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; + char mode_l_[PADL_(l_mode_t)]; l_mode_t mode; char mode_r_[PADR_(l_mode_t)]; +}; +struct linux_chown_args { + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; + char uid_l_[PADL_(l_uid_t)]; l_uid_t uid; char uid_r_[PADR_(l_uid_t)]; + char gid_l_[PADL_(l_gid_t)]; l_gid_t gid; char gid_r_[PADR_(l_gid_t)]; +}; +struct linux_lchown_args { + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; + char uid_l_[PADL_(l_uid_t)]; l_uid_t uid; char uid_r_[PADR_(l_uid_t)]; + char gid_l_[PADL_(l_gid_t)]; l_gid_t gid; char gid_r_[PADR_(l_gid_t)]; +}; +struct linux_getrlimit_args { + char resource_l_[PADL_(l_uint)]; l_uint resource; char resource_r_[PADR_(l_uint)]; + char rlim_l_[PADL_(struct l_rlimit *)]; struct l_rlimit * rlim; char rlim_r_[PADR_(struct l_rlimit *)]; +}; +struct linux_sysinfo_args { + char info_l_[PADL_(struct l_sysinfo *)]; struct l_sysinfo * info; char info_r_[PADR_(struct l_sysinfo *)]; +}; +struct linux_times_args { + char buf_l_[PADL_(struct l_times_argv *)]; struct l_times_argv * buf; char buf_r_[PADR_(struct l_times_argv *)]; +}; +struct linux_ptrace_args { + char req_l_[PADL_(l_long)]; l_long req; char req_r_[PADR_(l_long)]; + char pid_l_[PADL_(l_long)]; l_long pid; char pid_r_[PADR_(l_long)]; + char addr_l_[PADL_(l_long)]; l_long addr; char addr_r_[PADR_(l_long)]; + char data_l_[PADL_(l_long)]; l_long data; char data_r_[PADR_(l_long)]; +}; +struct linux_getuid_args { + register_t dummy; +}; +struct linux_syslog_args { + char type_l_[PADL_(l_int)]; l_int type; char type_r_[PADR_(l_int)]; + char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)]; + char len_l_[PADL_(l_int)]; l_int len; char len_r_[PADR_(l_int)]; +}; +struct linux_getgid_args { + register_t dummy; +}; +struct linux_getppid_args { + register_t dummy; +}; +struct linux_getgroups_args { + char gidsetsize_l_[PADL_(l_int)]; l_int gidsetsize; char gidsetsize_r_[PADR_(l_int)]; + char grouplist_l_[PADL_(l_gid_t *)]; l_gid_t * grouplist; char grouplist_r_[PADR_(l_gid_t *)]; +}; +struct linux_setgroups_args { + char gidsetsize_l_[PADL_(l_int)]; l_int gidsetsize; char gidsetsize_r_[PADR_(l_int)]; + char grouplist_l_[PADL_(l_gid_t *)]; l_gid_t * grouplist; char grouplist_r_[PADR_(l_gid_t *)]; +}; +struct linux_setfsuid_args { + char uid_l_[PADL_(l_uid_t)]; l_uid_t uid; char uid_r_[PADR_(l_uid_t)]; +}; +struct linux_setfsgid_args { + char gid_l_[PADL_(l_gid_t)]; l_gid_t gid; char gid_r_[PADR_(l_gid_t)]; +}; +struct linux_getsid_args { + char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)]; +}; +struct linux_capget_args { + char hdrp_l_[PADL_(struct l_user_cap_header *)]; struct l_user_cap_header * hdrp; char hdrp_r_[PADR_(struct l_user_cap_header *)]; + char datap_l_[PADL_(struct l_user_cap_data *)]; struct l_user_cap_data * datap; char datap_r_[PADR_(struct l_user_cap_data *)]; +}; +struct linux_capset_args { + char hdrp_l_[PADL_(struct l_user_cap_header *)]; struct l_user_cap_header * hdrp; char hdrp_r_[PADR_(struct l_user_cap_header *)]; + char datap_l_[PADL_(struct l_user_cap_data *)]; struct l_user_cap_data * datap; char datap_r_[PADR_(struct l_user_cap_data *)]; +}; +struct linux_rt_sigpending_args { + char set_l_[PADL_(l_sigset_t *)]; l_sigset_t * set; char set_r_[PADR_(l_sigset_t *)]; + char sigsetsize_l_[PADL_(l_size_t)]; l_size_t sigsetsize; char sigsetsize_r_[PADR_(l_size_t)]; +}; +struct linux_rt_sigtimedwait_args { + char mask_l_[PADL_(l_sigset_t *)]; l_sigset_t * mask; char mask_r_[PADR_(l_sigset_t *)]; + char ptr_l_[PADL_(l_siginfo_t *)]; l_siginfo_t * ptr; char ptr_r_[PADR_(l_siginfo_t *)]; + char timeout_l_[PADL_(struct l_timeval *)]; struct l_timeval * timeout; char timeout_r_[PADR_(struct l_timeval *)]; + char sigsetsize_l_[PADL_(l_size_t)]; l_size_t sigsetsize; char sigsetsize_r_[PADR_(l_size_t)]; +}; +struct linux_rt_sigqueueinfo_args { + char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)]; + char sig_l_[PADL_(l_int)]; l_int sig; char sig_r_[PADR_(l_int)]; + char info_l_[PADL_(l_siginfo_t *)]; l_siginfo_t * info; char info_r_[PADR_(l_siginfo_t *)]; +}; +struct linux_rt_sigsuspend_args { + char newset_l_[PADL_(l_sigset_t *)]; l_sigset_t * newset; char newset_r_[PADR_(l_sigset_t *)]; + char sigsetsize_l_[PADL_(l_size_t)]; l_size_t sigsetsize; char sigsetsize_r_[PADR_(l_size_t)]; +}; +struct linux_sigaltstack_args { + char uss_l_[PADL_(l_stack_t *)]; l_stack_t * uss; char uss_r_[PADR_(l_stack_t *)]; + char uoss_l_[PADL_(l_stack_t *)]; l_stack_t * uoss; char uoss_r_[PADR_(l_stack_t *)]; +}; +struct linux_utime_args { + char fname_l_[PADL_(char *)]; char * fname; char fname_r_[PADR_(char *)]; + char times_l_[PADL_(struct l_utimbuf *)]; struct l_utimbuf * times; char times_r_[PADR_(struct l_utimbuf *)]; +}; +struct linux_mknod_args { + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; + char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)]; + char dev_l_[PADL_(l_dev_t)]; l_dev_t dev; char dev_r_[PADR_(l_dev_t)]; +}; +struct linux_personality_args { + char per_l_[PADL_(l_ulong)]; l_ulong per; char per_r_[PADR_(l_ulong)]; +}; +struct linux_ustat_args { + char dev_l_[PADL_(l_dev_t)]; l_dev_t dev; char dev_r_[PADR_(l_dev_t)]; + char ubuf_l_[PADL_(struct l_ustat *)]; struct l_ustat * ubuf; char ubuf_r_[PADR_(struct l_ustat *)]; +}; +struct linux_statfs_args { + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; + char buf_l_[PADL_(struct l_statfs_buf *)]; struct l_statfs_buf * buf; char buf_r_[PADR_(struct l_statfs_buf *)]; +}; +struct linux_fstatfs_args { + char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)]; + char buf_l_[PADL_(struct l_statfs_buf *)]; struct l_statfs_buf * buf; char buf_r_[PADR_(struct l_statfs_buf *)]; +}; +struct linux_sysfs_args { + char option_l_[PADL_(l_int)]; l_int option; char option_r_[PADR_(l_int)]; + char arg1_l_[PADL_(l_ulong)]; l_ulong arg1; char arg1_r_[PADR_(l_ulong)]; + char arg2_l_[PADL_(l_ulong)]; l_ulong arg2; char arg2_r_[PADR_(l_ulong)]; +}; +struct linux_getpriority_args { + char which_l_[PADL_(int)]; int which; char which_r_[PADR_(int)]; + char who_l_[PADL_(int)]; int who; char who_r_[PADR_(int)]; +}; +struct linux_sched_setparam_args { + char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)]; + char param_l_[PADL_(struct l_sched_param *)]; struct l_sched_param * param; char param_r_[PADR_(struct l_sched_param *)]; +}; +struct linux_sched_getparam_args { + char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)]; + char param_l_[PADL_(struct l_sched_param *)]; struct l_sched_param * param; char param_r_[PADR_(struct l_sched_param *)]; +}; +struct linux_sched_setscheduler_args { + char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)]; + char policy_l_[PADL_(l_int)]; l_int policy; char policy_r_[PADR_(l_int)]; + char param_l_[PADL_(struct l_sched_param *)]; struct l_sched_param * param; char param_r_[PADR_(struct l_sched_param *)]; +}; +struct linux_sched_getscheduler_args { + char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)]; +}; +struct linux_sched_get_priority_max_args { + char policy_l_[PADL_(l_int)]; l_int policy; char policy_r_[PADR_(l_int)]; +}; +struct linux_sched_get_priority_min_args { + char policy_l_[PADL_(l_int)]; l_int policy; char policy_r_[PADR_(l_int)]; +}; +struct linux_sched_rr_get_interval_args { + char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)]; + char interval_l_[PADL_(struct l_timespec *)]; struct l_timespec * interval; char interval_r_[PADR_(struct l_timespec *)]; +}; +struct linux_vhangup_args { + register_t dummy; +}; +struct linux_pivot_root_args { + register_t dummy; +}; +struct linux_sysctl_args { + char args_l_[PADL_(struct l___sysctl_args *)]; struct l___sysctl_args * args; char args_r_[PADR_(struct l___sysctl_args *)]; +}; +struct linux_prctl_args { + char option_l_[PADL_(l_int)]; l_int option; char option_r_[PADR_(l_int)]; + char arg2_l_[PADL_(l_uintptr_t)]; l_uintptr_t arg2; char arg2_r_[PADR_(l_uintptr_t)]; + char arg3_l_[PADL_(l_uintptr_t)]; l_uintptr_t arg3; char arg3_r_[PADR_(l_uintptr_t)]; + char arg4_l_[PADL_(l_uintptr_t)]; l_uintptr_t arg4; char arg4_r_[PADR_(l_uintptr_t)]; + char arg5_l_[PADL_(l_uintptr_t)]; l_uintptr_t arg5; char arg5_r_[PADR_(l_uintptr_t)]; +}; +struct linux_arch_prctl_args { + char code_l_[PADL_(l_int)]; l_int code; char code_r_[PADR_(l_int)]; + char addr_l_[PADL_(l_ulong)]; l_ulong addr; char addr_r_[PADR_(l_ulong)]; +}; +struct linux_adjtimex_args { + register_t dummy; +}; +struct linux_setrlimit_args { + char resource_l_[PADL_(l_uint)]; l_uint resource; char resource_r_[PADR_(l_uint)]; + char rlim_l_[PADL_(struct l_rlimit *)]; struct l_rlimit * rlim; char rlim_r_[PADR_(struct l_rlimit *)]; +}; +struct linux_mount_args { + char specialfile_l_[PADL_(char *)]; char * specialfile; char specialfile_r_[PADR_(char *)]; + char dir_l_[PADL_(char *)]; char * dir; char dir_r_[PADR_(char *)]; + char filesystemtype_l_[PADL_(char *)]; char * filesystemtype; char filesystemtype_r_[PADR_(char *)]; + char rwflag_l_[PADL_(l_ulong)]; l_ulong rwflag; char rwflag_r_[PADR_(l_ulong)]; + char data_l_[PADL_(void *)]; void * data; char data_r_[PADR_(void *)]; +}; +struct linux_umount_args { + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; + char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)]; +}; +struct linux_swapoff_args { + register_t dummy; +}; +struct linux_reboot_args { + char magic1_l_[PADL_(l_int)]; l_int magic1; char magic1_r_[PADR_(l_int)]; + char magic2_l_[PADL_(l_int)]; l_int magic2; char magic2_r_[PADR_(l_int)]; + char cmd_l_[PADL_(l_uint)]; l_uint cmd; char cmd_r_[PADR_(l_uint)]; + char arg_l_[PADL_(void *)]; void * arg; char arg_r_[PADR_(void *)]; +}; +struct linux_sethostname_args { + char hostname_l_[PADL_(char *)]; char * hostname; char hostname_r_[PADR_(char *)]; + char len_l_[PADL_(l_uint)]; l_uint len; char len_r_[PADR_(l_uint)]; +}; +struct linux_setdomainname_args { + char name_l_[PADL_(char *)]; char * name; char name_r_[PADR_(char *)]; + char len_l_[PADL_(l_int)]; l_int len; char len_r_[PADR_(l_int)]; +}; +struct linux_iopl_args { + char level_l_[PADL_(l_uint)]; l_uint level; char level_r_[PADR_(l_uint)]; +}; +struct linux_create_module_args { + register_t dummy; +}; +struct linux_init_module_args { + register_t dummy; +}; +struct linux_delete_module_args { + register_t dummy; +}; +struct linux_get_kernel_syms_args { + register_t dummy; +}; +struct linux_query_module_args { + register_t dummy; +}; +struct linux_quotactl_args { + register_t dummy; +}; +struct linux_nfsservctl_args { + register_t dummy; +}; +struct linux_getpmsg_args { + register_t dummy; +}; +struct linux_putpmsg_args { + register_t dummy; +}; +struct linux_afs_syscall_args { + register_t dummy; +}; +struct linux_tuxcall_args { + register_t dummy; +}; +struct linux_security_args { + register_t dummy; +}; +struct linux_gettid_args { + register_t dummy; +}; +struct linux_setxattr_args { + register_t dummy; +}; +struct linux_lsetxattr_args { + register_t dummy; +}; +struct linux_fsetxattr_args { + register_t dummy; +}; +struct linux_getxattr_args { + register_t dummy; +}; +struct linux_lgetxattr_args { + register_t dummy; +}; +struct linux_fgetxattr_args { + register_t dummy; +}; +struct linux_listxattr_args { + register_t dummy; +}; +struct linux_llistxattr_args { + register_t dummy; +}; +struct linux_flistxattr_args { + register_t dummy; +}; +struct linux_removexattr_args { + register_t dummy; +}; +struct linux_lremovexattr_args { + register_t dummy; +}; +struct linux_fremovexattr_args { + register_t dummy; +}; +struct linux_tkill_args { + char tid_l_[PADL_(int)]; int tid; char tid_r_[PADR_(int)]; + char sig_l_[PADL_(int)]; int sig; char sig_r_[PADR_(int)]; +}; +struct linux_time_args { + char tm_l_[PADL_(l_time_t *)]; l_time_t * tm; char tm_r_[PADR_(l_time_t *)]; +}; +struct linux_sys_futex_args { + char uaddr_l_[PADL_(void *)]; void * uaddr; char uaddr_r_[PADR_(void *)]; + char op_l_[PADL_(int)]; int op; char op_r_[PADR_(int)]; + char val_l_[PADL_(int)]; int val; char val_r_[PADR_(int)]; + char timeout_l_[PADL_(struct l_timespec *)]; struct l_timespec * timeout; char timeout_r_[PADR_(struct l_timespec *)]; + char uaddr2_l_[PADL_(void *)]; void * uaddr2; char uaddr2_r_[PADR_(void *)]; + char val3_l_[PADL_(int)]; int val3; char val3_r_[PADR_(int)]; +}; +struct linux_sched_setaffinity_args { + char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)]; + char len_l_[PADL_(l_uint)]; l_uint len; char len_r_[PADR_(l_uint)]; + char user_mask_ptr_l_[PADL_(l_ulong *)]; l_ulong * user_mask_ptr; char user_mask_ptr_r_[PADR_(l_ulong *)]; +}; +struct linux_sched_getaffinity_args { + char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)]; + char len_l_[PADL_(l_uint)]; l_uint len; char len_r_[PADR_(l_uint)]; + char user_mask_ptr_l_[PADL_(l_ulong *)]; l_ulong * user_mask_ptr; char user_mask_ptr_r_[PADR_(l_ulong *)]; +}; +struct linux_set_thread_area_args { + register_t dummy; +}; +struct linux_lookup_dcookie_args { + register_t dummy; +}; +struct linux_epoll_create_args { + char size_l_[PADL_(l_int)]; l_int size; char size_r_[PADR_(l_int)]; +}; +struct linux_epoll_ctl_old_args { + register_t dummy; +}; +struct linux_epoll_wait_old_args { + register_t dummy; +}; +struct linux_remap_file_pages_args { + register_t dummy; +}; +struct linux_getdents64_args { + char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)]; + char dirent_l_[PADL_(void *)]; void * dirent; char dirent_r_[PADR_(void *)]; + char count_l_[PADL_(l_uint)]; l_uint count; char count_r_[PADR_(l_uint)]; +}; +struct linux_set_tid_address_args { + char tidptr_l_[PADL_(int *)]; int * tidptr; char tidptr_r_[PADR_(int *)]; +}; +struct linux_semtimedop_args { + register_t dummy; +}; +struct linux_fadvise64_args { + char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; + char offset_l_[PADL_(l_loff_t)]; l_loff_t offset; char offset_r_[PADR_(l_loff_t)]; + char len_l_[PADL_(l_size_t)]; l_size_t len; char len_r_[PADR_(l_size_t)]; + char advice_l_[PADL_(int)]; int advice; char advice_r_[PADR_(int)]; +}; +struct linux_timer_create_args { + char clock_id_l_[PADL_(clockid_t)]; clockid_t clock_id; char clock_id_r_[PADR_(clockid_t)]; + char evp_l_[PADL_(struct sigevent *)]; struct sigevent * evp; char evp_r_[PADR_(struct sigevent *)]; + char timerid_l_[PADL_(l_timer_t *)]; l_timer_t * timerid; char timerid_r_[PADR_(l_timer_t *)]; +}; +struct linux_timer_settime_args { + char timerid_l_[PADL_(l_timer_t)]; l_timer_t timerid; char timerid_r_[PADR_(l_timer_t)]; + char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)]; + char new_l_[PADL_(const struct itimerspec *)]; const struct itimerspec * new; char new_r_[PADR_(const struct itimerspec *)]; + char old_l_[PADL_(struct itimerspec *)]; struct itimerspec * old; char old_r_[PADR_(struct itimerspec *)]; +}; +struct linux_timer_gettime_args { + char timerid_l_[PADL_(l_timer_t)]; l_timer_t timerid; char timerid_r_[PADR_(l_timer_t)]; + char setting_l_[PADL_(struct itimerspec *)]; struct itimerspec * setting; char setting_r_[PADR_(struct itimerspec *)]; +}; +struct linux_timer_getoverrun_args { + char timerid_l_[PADL_(l_timer_t)]; l_timer_t timerid; char timerid_r_[PADR_(l_timer_t)]; +}; +struct linux_timer_delete_args { + char timerid_l_[PADL_(l_timer_t)]; l_timer_t timerid; char timerid_r_[PADR_(l_timer_t)]; +}; +struct linux_clock_settime_args { + char which_l_[PADL_(clockid_t)]; clockid_t which; char which_r_[PADR_(clockid_t)]; + char tp_l_[PADL_(struct l_timespec *)]; struct l_timespec * tp; char tp_r_[PADR_(struct l_timespec *)]; +}; +struct linux_clock_gettime_args { + char which_l_[PADL_(clockid_t)]; clockid_t which; char which_r_[PADR_(clockid_t)]; + char tp_l_[PADL_(struct l_timespec *)]; struct l_timespec * tp; char tp_r_[PADR_(struct l_timespec *)]; +}; +struct linux_clock_getres_args { + char which_l_[PADL_(clockid_t)]; clockid_t which; char which_r_[PADR_(clockid_t)]; + char tp_l_[PADL_(struct l_timespec *)]; struct l_timespec * tp; char tp_r_[PADR_(struct l_timespec *)]; +}; +struct linux_clock_nanosleep_args { + char which_l_[PADL_(clockid_t)]; clockid_t which; char which_r_[PADR_(clockid_t)]; + char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)]; + char rqtp_l_[PADL_(struct l_timespec *)]; struct l_timespec * rqtp; char rqtp_r_[PADR_(struct l_timespec *)]; + char rmtp_l_[PADL_(struct l_timespec *)]; struct l_timespec * rmtp; char rmtp_r_[PADR_(struct l_timespec *)]; +}; +struct linux_exit_group_args { + char error_code_l_[PADL_(int)]; int error_code; char error_code_r_[PADR_(int)]; +}; +struct linux_epoll_wait_args { + char epfd_l_[PADL_(l_int)]; l_int epfd; char epfd_r_[PADR_(l_int)]; + char events_l_[PADL_(struct epoll_event *)]; struct epoll_event * events; char events_r_[PADR_(struct epoll_event *)]; + char maxevents_l_[PADL_(l_int)]; l_int maxevents; char maxevents_r_[PADR_(l_int)]; + char timeout_l_[PADL_(l_int)]; l_int timeout; char timeout_r_[PADR_(l_int)]; +}; +struct linux_epoll_ctl_args { + char epfd_l_[PADL_(l_int)]; l_int epfd; char epfd_r_[PADR_(l_int)]; + char op_l_[PADL_(l_int)]; l_int op; char op_r_[PADR_(l_int)]; + char fd_l_[PADL_(l_int)]; l_int fd; char fd_r_[PADR_(l_int)]; + char event_l_[PADL_(struct epoll_event *)]; struct epoll_event * event; char event_r_[PADR_(struct epoll_event *)]; +}; +struct linux_tgkill_args { + char tgid_l_[PADL_(int)]; int tgid; char tgid_r_[PADR_(int)]; + char pid_l_[PADL_(int)]; int pid; char pid_r_[PADR_(int)]; + char sig_l_[PADL_(int)]; int sig; char sig_r_[PADR_(int)]; +}; +struct linux_utimes_args { + char fname_l_[PADL_(char *)]; char * fname; char fname_r_[PADR_(char *)]; + char tptr_l_[PADL_(struct l_timeval *)]; struct l_timeval * tptr; char tptr_r_[PADR_(struct l_timeval *)]; +}; +struct linux_mbind_args { + register_t dummy; +}; +struct linux_set_mempolicy_args { + register_t dummy; +}; +struct linux_get_mempolicy_args { + register_t dummy; +}; +struct linux_mq_open_args { + register_t dummy; +}; +struct linux_mq_unlink_args { + register_t dummy; +}; +struct linux_mq_timedsend_args { + register_t dummy; +}; +struct linux_mq_timedreceive_args { + register_t dummy; +}; +struct linux_mq_notify_args { + register_t dummy; +}; +struct linux_mq_getsetattr_args { + register_t dummy; +}; +struct linux_kexec_load_args { + register_t dummy; +}; +struct linux_waitid_args { + char idtype_l_[PADL_(int)]; int idtype; char idtype_r_[PADR_(int)]; + char id_l_[PADL_(l_pid_t)]; l_pid_t id; char id_r_[PADR_(l_pid_t)]; + char info_l_[PADL_(l_siginfo_t *)]; l_siginfo_t * info; char info_r_[PADR_(l_siginfo_t *)]; + char options_l_[PADL_(int)]; int options; char options_r_[PADR_(int)]; + char rusage_l_[PADL_(struct rusage *)]; struct rusage * rusage; char rusage_r_[PADR_(struct rusage *)]; +}; +struct linux_add_key_args { + register_t dummy; +}; +struct linux_request_key_args { + register_t dummy; +}; +struct linux_keyctl_args { + register_t dummy; +}; +struct linux_ioprio_set_args { + register_t dummy; +}; +struct linux_ioprio_get_args { + register_t dummy; +}; +struct linux_inotify_init_args { + register_t dummy; +}; +struct linux_inotify_add_watch_args { + register_t dummy; +}; +struct linux_inotify_rm_watch_args { + register_t dummy; +}; +struct linux_migrate_pages_args { + register_t dummy; +}; +struct linux_openat_args { + char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)]; + char filename_l_[PADL_(const char *)]; const char * filename; char filename_r_[PADR_(const char *)]; + char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)]; + char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)]; +}; +struct linux_mkdirat_args { + char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)]; + char pathname_l_[PADL_(const char *)]; const char * pathname; char pathname_r_[PADR_(const char *)]; + char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)]; +}; +struct linux_mknodat_args { + char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)]; + char filename_l_[PADL_(const char *)]; const char * filename; char filename_r_[PADR_(const char *)]; + char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)]; + char dev_l_[PADL_(l_uint)]; l_uint dev; char dev_r_[PADR_(l_uint)]; +}; +struct linux_fchownat_args { + char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)]; + char filename_l_[PADL_(const char *)]; const char * filename; char filename_r_[PADR_(const char *)]; + char uid_l_[PADL_(l_uid_t)]; l_uid_t uid; char uid_r_[PADR_(l_uid_t)]; + char gid_l_[PADL_(l_gid_t)]; l_gid_t gid; char gid_r_[PADR_(l_gid_t)]; + char flag_l_[PADL_(l_int)]; l_int flag; char flag_r_[PADR_(l_int)]; +}; +struct linux_futimesat_args { + char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)]; + char filename_l_[PADL_(char *)]; char * filename; char filename_r_[PADR_(char *)]; + char utimes_l_[PADL_(struct l_timeval *)]; struct l_timeval * utimes; char utimes_r_[PADR_(struct l_timeval *)]; +}; +struct linux_newfstatat_args { + char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)]; + char pathname_l_[PADL_(char *)]; char * pathname; char pathname_r_[PADR_(char *)]; + char statbuf_l_[PADL_(struct l_stat64 *)]; struct l_stat64 * statbuf; char statbuf_r_[PADR_(struct l_stat64 *)]; + char flag_l_[PADL_(l_int)]; l_int flag; char flag_r_[PADR_(l_int)]; +}; +struct linux_unlinkat_args { + char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)]; + char pathname_l_[PADL_(const char *)]; const char * pathname; char pathname_r_[PADR_(const char *)]; + char flag_l_[PADL_(l_int)]; l_int flag; char flag_r_[PADR_(l_int)]; +}; +struct linux_renameat_args { + char olddfd_l_[PADL_(l_int)]; l_int olddfd; char olddfd_r_[PADR_(l_int)]; + char oldname_l_[PADL_(const char *)]; const char * oldname; char oldname_r_[PADR_(const char *)]; + char newdfd_l_[PADL_(l_int)]; l_int newdfd; char newdfd_r_[PADR_(l_int)]; + char newname_l_[PADL_(const char *)]; const char * newname; char newname_r_[PADR_(const char *)]; +}; +struct linux_linkat_args { + char olddfd_l_[PADL_(l_int)]; l_int olddfd; char olddfd_r_[PADR_(l_int)]; + char oldname_l_[PADL_(const char *)]; const char * oldname; char oldname_r_[PADR_(const char *)]; + char newdfd_l_[PADL_(l_int)]; l_int newdfd; char newdfd_r_[PADR_(l_int)]; + char newname_l_[PADL_(const char *)]; const char * newname; char newname_r_[PADR_(const char *)]; + char flag_l_[PADL_(l_int)]; l_int flag; char flag_r_[PADR_(l_int)]; +}; +struct linux_symlinkat_args { + char oldname_l_[PADL_(const char *)]; const char * oldname; char oldname_r_[PADR_(const char *)]; + char newdfd_l_[PADL_(l_int)]; l_int newdfd; char newdfd_r_[PADR_(l_int)]; + char newname_l_[PADL_(const char *)]; const char * newname; char newname_r_[PADR_(const char *)]; +}; +struct linux_readlinkat_args { + char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)]; + char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)]; + char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)]; + char bufsiz_l_[PADL_(l_int)]; l_int bufsiz; char bufsiz_r_[PADR_(l_int)]; +}; +struct linux_fchmodat_args { + char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)]; + char filename_l_[PADL_(const char *)]; const char * filename; char filename_r_[PADR_(const char *)]; + char mode_l_[PADL_(l_mode_t)]; l_mode_t mode; char mode_r_[PADR_(l_mode_t)]; +}; +struct linux_faccessat_args { + char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)]; + char filename_l_[PADL_(const char *)]; const char * filename; char filename_r_[PADR_(const char *)]; + char amode_l_[PADL_(l_int)]; l_int amode; char amode_r_[PADR_(l_int)]; +}; +struct linux_pselect6_args { + char nfds_l_[PADL_(l_int)]; l_int nfds; char nfds_r_[PADR_(l_int)]; + char readfds_l_[PADL_(l_fd_set *)]; l_fd_set * readfds; char readfds_r_[PADR_(l_fd_set *)]; + char writefds_l_[PADL_(l_fd_set *)]; l_fd_set * writefds; char writefds_r_[PADR_(l_fd_set *)]; + char exceptfds_l_[PADL_(l_fd_set *)]; l_fd_set * exceptfds; char exceptfds_r_[PADR_(l_fd_set *)]; + char tsp_l_[PADL_(struct l_timespec *)]; struct l_timespec * tsp; char tsp_r_[PADR_(struct l_timespec *)]; + char sig_l_[PADL_(l_uintptr_t *)]; l_uintptr_t * sig; char sig_r_[PADR_(l_uintptr_t *)]; +}; +struct linux_ppoll_args { + char fds_l_[PADL_(struct pollfd *)]; struct pollfd * fds; char fds_r_[PADR_(struct pollfd *)]; + char nfds_l_[PADL_(uint32_t)]; uint32_t nfds; char nfds_r_[PADR_(uint32_t)]; + char tsp_l_[PADL_(struct l_timespec *)]; struct l_timespec * tsp; char tsp_r_[PADR_(struct l_timespec *)]; + char sset_l_[PADL_(l_sigset_t *)]; l_sigset_t * sset; char sset_r_[PADR_(l_sigset_t *)]; + char ssize_l_[PADL_(l_size_t)]; l_size_t ssize; char ssize_r_[PADR_(l_size_t)]; +}; +struct linux_unshare_args { + register_t dummy; +}; +struct linux_set_robust_list_args { + char head_l_[PADL_(struct linux_robust_list_head *)]; struct linux_robust_list_head * head; char head_r_[PADR_(struct linux_robust_list_head *)]; + char len_l_[PADL_(l_size_t)]; l_size_t len; char len_r_[PADR_(l_size_t)]; +}; +struct linux_get_robust_list_args { + char pid_l_[PADL_(l_int)]; l_int pid; char pid_r_[PADR_(l_int)]; + char head_l_[PADL_(struct linux_robust_list_head *)]; struct linux_robust_list_head * head; char head_r_[PADR_(struct linux_robust_list_head *)]; + char len_l_[PADL_(l_size_t *)]; l_size_t * len; char len_r_[PADR_(l_size_t *)]; +}; +struct linux_splice_args { + register_t dummy; +}; +struct linux_tee_args { + register_t dummy; +}; +struct linux_sync_file_range_args { + register_t dummy; +}; +struct linux_vmsplice_args { + register_t dummy; +}; +struct linux_move_pages_args { + register_t dummy; +}; +struct linux_utimensat_args { + char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)]; + char pathname_l_[PADL_(const char *)]; const char * pathname; char pathname_r_[PADR_(const char *)]; + char times_l_[PADL_(const struct l_timespec *)]; const struct l_timespec * times; char times_r_[PADR_(const struct l_timespec *)]; + char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)]; +}; +struct linux_epoll_pwait_args { + char epfd_l_[PADL_(l_int)]; l_int epfd; char epfd_r_[PADR_(l_int)]; + char events_l_[PADL_(struct epoll_event *)]; struct epoll_event * events; char events_r_[PADR_(struct epoll_event *)]; + char maxevents_l_[PADL_(l_int)]; l_int maxevents; char maxevents_r_[PADR_(l_int)]; + char timeout_l_[PADL_(l_int)]; l_int timeout; char timeout_r_[PADR_(l_int)]; + char mask_l_[PADL_(l_sigset_t *)]; l_sigset_t * mask; char mask_r_[PADR_(l_sigset_t *)]; +}; +struct linux_signalfd_args { + register_t dummy; +}; +struct linux_timerfd_args { + register_t dummy; +}; +struct linux_eventfd_args { + char initval_l_[PADL_(l_uint)]; l_uint initval; char initval_r_[PADR_(l_uint)]; +}; +struct linux_fallocate_args { + char fd_l_[PADL_(l_int)]; l_int fd; char fd_r_[PADR_(l_int)]; + char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)]; + char offset_l_[PADL_(l_loff_t)]; l_loff_t offset; char offset_r_[PADR_(l_loff_t)]; + char len_l_[PADL_(l_loff_t)]; l_loff_t len; char len_r_[PADR_(l_loff_t)]; +}; +struct linux_timerfd_settime_args { + register_t dummy; +}; +struct linux_timerfd_gettime_args { + register_t dummy; +}; +struct linux_accept4_args { + char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)]; + char addr_l_[PADL_(l_uintptr_t)]; l_uintptr_t addr; char addr_r_[PADR_(l_uintptr_t)]; + char namelen_l_[PADL_(l_uintptr_t)]; l_uintptr_t namelen; char namelen_r_[PADR_(l_uintptr_t)]; + char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)]; +}; +struct linux_signalfd4_args { + register_t dummy; +}; +struct linux_eventfd2_args { + char initval_l_[PADL_(l_uint)]; l_uint initval; char initval_r_[PADR_(l_uint)]; + char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)]; +}; +struct linux_epoll_create1_args { + char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)]; +}; +struct linux_dup3_args { + char oldfd_l_[PADL_(l_int)]; l_int oldfd; char oldfd_r_[PADR_(l_int)]; + char newfd_l_[PADL_(l_int)]; l_int newfd; char newfd_r_[PADR_(l_int)]; + char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)]; +}; +struct linux_pipe2_args { + char pipefds_l_[PADL_(l_int *)]; l_int * pipefds; char pipefds_r_[PADR_(l_int *)]; + char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)]; +}; +struct linux_inotify_init1_args { + register_t dummy; +}; +struct linux_preadv_args { + register_t dummy; +}; +struct linux_pwritev_args { + register_t dummy; +}; +struct linux_rt_tsigqueueinfo_args { + register_t dummy; +}; +struct linux_perf_event_open_args { + register_t dummy; +}; +struct linux_recvmmsg_args { + char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)]; + char msg_l_[PADL_(struct l_mmsghdr *)]; struct l_mmsghdr * msg; char msg_r_[PADR_(struct l_mmsghdr *)]; + char vlen_l_[PADL_(l_uint)]; l_uint vlen; char vlen_r_[PADR_(l_uint)]; + char flags_l_[PADL_(l_uint)]; l_uint flags; char flags_r_[PADR_(l_uint)]; + char timeout_l_[PADL_(struct l_timespec *)]; struct l_timespec * timeout; char timeout_r_[PADR_(struct l_timespec *)]; +}; +struct linux_fanotify_init_args { + register_t dummy; +}; +struct linux_fanotify_mark_args { + register_t dummy; +}; +struct linux_prlimit64_args { + char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)]; + char resource_l_[PADL_(l_uint)]; l_uint resource; char resource_r_[PADR_(l_uint)]; + char new_l_[PADL_(struct rlimit *)]; struct rlimit * new; char new_r_[PADR_(struct rlimit *)]; + char old_l_[PADL_(struct rlimit *)]; struct rlimit * old; char old_r_[PADR_(struct rlimit *)]; +}; +struct linux_name_to_handle_at_args { + register_t dummy; +}; +struct linux_open_by_handle_at_args { + register_t dummy; +}; +struct linux_clock_adjtime_args { + register_t dummy; +}; +struct linux_syncfs_args { + char fd_l_[PADL_(l_int)]; l_int fd; char fd_r_[PADR_(l_int)]; +}; +struct linux_sendmmsg_args { + char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)]; + char msg_l_[PADL_(struct l_mmsghdr *)]; struct l_mmsghdr * msg; char msg_r_[PADR_(struct l_mmsghdr *)]; + char vlen_l_[PADL_(l_uint)]; l_uint vlen; char vlen_r_[PADR_(l_uint)]; + char flags_l_[PADL_(l_uint)]; l_uint flags; char flags_r_[PADR_(l_uint)]; +}; +struct linux_setns_args { + register_t dummy; +}; +struct linux_process_vm_readv_args { + register_t dummy; +}; +struct linux_process_vm_writev_args { + register_t dummy; +}; +struct linux_kcmp_args { + register_t dummy; +}; +struct linux_finit_module_args { + register_t dummy; +}; +#define nosys linux_nosys +int linux_open(struct thread *, struct linux_open_args *); +int linux_newstat(struct thread *, struct linux_newstat_args *); +int linux_newfstat(struct thread *, struct linux_newfstat_args *); +int linux_newlstat(struct thread *, struct linux_newlstat_args *); +int linux_lseek(struct thread *, struct linux_lseek_args *); +int linux_mmap2(struct thread *, struct linux_mmap2_args *); +int linux_mprotect(struct thread *, struct linux_mprotect_args *); +int linux_brk(struct thread *, struct linux_brk_args *); +int linux_rt_sigaction(struct thread *, struct linux_rt_sigaction_args *); +int linux_rt_sigprocmask(struct thread *, struct linux_rt_sigprocmask_args *); +int linux_rt_sigreturn(struct thread *, struct linux_rt_sigreturn_args *); +int linux_ioctl(struct thread *, struct linux_ioctl_args *); +int linux_pread(struct thread *, struct linux_pread_args *); +int linux_pwrite(struct thread *, struct linux_pwrite_args *); +int linux_access(struct thread *, struct linux_access_args *); +int linux_pipe(struct thread *, struct linux_pipe_args *); +int linux_select(struct thread *, struct linux_select_args *); +int linux_mremap(struct thread *, struct linux_mremap_args *); +int linux_msync(struct thread *, struct linux_msync_args *); +int linux_mincore(struct thread *, struct linux_mincore_args *); +int linux_shmget(struct thread *, struct linux_shmget_args *); +int linux_shmat(struct thread *, struct linux_shmat_args *); +int linux_shmctl(struct thread *, struct linux_shmctl_args *); +int linux_pause(struct thread *, struct linux_pause_args *); +int linux_nanosleep(struct thread *, struct linux_nanosleep_args *); +int linux_getitimer(struct thread *, struct linux_getitimer_args *); +int linux_alarm(struct thread *, struct linux_alarm_args *); +int linux_setitimer(struct thread *, struct linux_setitimer_args *); +int linux_getpid(struct thread *, struct linux_getpid_args *); +int linux_sendfile(struct thread *, struct linux_sendfile_args *); +int linux_socket(struct thread *, struct linux_socket_args *); +int linux_connect(struct thread *, struct linux_connect_args *); +int linux_accept(struct thread *, struct linux_accept_args *); +int linux_sendto(struct thread *, struct linux_sendto_args *); +int linux_recvfrom(struct thread *, struct linux_recvfrom_args *); +int linux_sendmsg(struct thread *, struct linux_sendmsg_args *); +int linux_recvmsg(struct thread *, struct linux_recvmsg_args *); +int linux_shutdown(struct thread *, struct linux_shutdown_args *); +int linux_bind(struct thread *, struct linux_bind_args *); +int linux_listen(struct thread *, struct linux_listen_args *); +int linux_getsockname(struct thread *, struct linux_getsockname_args *); +int linux_getpeername(struct thread *, struct linux_getpeername_args *); +int linux_socketpair(struct thread *, struct linux_socketpair_args *); +int linux_setsockopt(struct thread *, struct linux_setsockopt_args *); +int linux_getsockopt(struct thread *, struct linux_getsockopt_args *); +int linux_clone(struct thread *, struct linux_clone_args *); +int linux_fork(struct thread *, struct linux_fork_args *); +int linux_vfork(struct thread *, struct linux_vfork_args *); +int linux_execve(struct thread *, struct linux_execve_args *); +int linux_exit(struct thread *, struct linux_exit_args *); +int linux_wait4(struct thread *, struct linux_wait4_args *); +int linux_kill(struct thread *, struct linux_kill_args *); +int linux_newuname(struct thread *, struct linux_newuname_args *); +int linux_semget(struct thread *, struct linux_semget_args *); +int linux_semop(struct thread *, struct linux_semop_args *); +int linux_semctl(struct thread *, struct linux_semctl_args *); +int linux_shmdt(struct thread *, struct linux_shmdt_args *); +int linux_msgget(struct thread *, struct linux_msgget_args *); +int linux_msgsnd(struct thread *, struct linux_msgsnd_args *); +int linux_msgrcv(struct thread *, struct linux_msgrcv_args *); +int linux_msgctl(struct thread *, struct linux_msgctl_args *); +int linux_fcntl(struct thread *, struct linux_fcntl_args *); +int linux_fdatasync(struct thread *, struct linux_fdatasync_args *); +int linux_truncate(struct thread *, struct linux_truncate_args *); +int linux_ftruncate(struct thread *, struct linux_ftruncate_args *); +int linux_getdents(struct thread *, struct linux_getdents_args *); +int linux_getcwd(struct thread *, struct linux_getcwd_args *); +int linux_chdir(struct thread *, struct linux_chdir_args *); +int linux_rename(struct thread *, struct linux_rename_args *); +int linux_mkdir(struct thread *, struct linux_mkdir_args *); +int linux_rmdir(struct thread *, struct linux_rmdir_args *); +int linux_creat(struct thread *, struct linux_creat_args *); +int linux_link(struct thread *, struct linux_link_args *); +int linux_unlink(struct thread *, struct linux_unlink_args *); +int linux_symlink(struct thread *, struct linux_symlink_args *); +int linux_readlink(struct thread *, struct linux_readlink_args *); +int linux_chmod(struct thread *, struct linux_chmod_args *); +int linux_chown(struct thread *, struct linux_chown_args *); +int linux_lchown(struct thread *, struct linux_lchown_args *); +int linux_getrlimit(struct thread *, struct linux_getrlimit_args *); +int linux_sysinfo(struct thread *, struct linux_sysinfo_args *); +int linux_times(struct thread *, struct linux_times_args *); +int linux_ptrace(struct thread *, struct linux_ptrace_args *); +int linux_getuid(struct thread *, struct linux_getuid_args *); +int linux_syslog(struct thread *, struct linux_syslog_args *); +int linux_getgid(struct thread *, struct linux_getgid_args *); +int linux_getppid(struct thread *, struct linux_getppid_args *); +int linux_getgroups(struct thread *, struct linux_getgroups_args *); +int linux_setgroups(struct thread *, struct linux_setgroups_args *); +int linux_setfsuid(struct thread *, struct linux_setfsuid_args *); +int linux_setfsgid(struct thread *, struct linux_setfsgid_args *); +int linux_getsid(struct thread *, struct linux_getsid_args *); +int linux_capget(struct thread *, struct linux_capget_args *); +int linux_capset(struct thread *, struct linux_capset_args *); +int linux_rt_sigpending(struct thread *, struct linux_rt_sigpending_args *); +int linux_rt_sigtimedwait(struct thread *, struct linux_rt_sigtimedwait_args *); +int linux_rt_sigqueueinfo(struct thread *, struct linux_rt_sigqueueinfo_args *); +int linux_rt_sigsuspend(struct thread *, struct linux_rt_sigsuspend_args *); +int linux_sigaltstack(struct thread *, struct linux_sigaltstack_args *); +int linux_utime(struct thread *, struct linux_utime_args *); +int linux_mknod(struct thread *, struct linux_mknod_args *); +int linux_personality(struct thread *, struct linux_personality_args *); +int linux_ustat(struct thread *, struct linux_ustat_args *); +int linux_statfs(struct thread *, struct linux_statfs_args *); +int linux_fstatfs(struct thread *, struct linux_fstatfs_args *); +int linux_sysfs(struct thread *, struct linux_sysfs_args *); +int linux_getpriority(struct thread *, struct linux_getpriority_args *); +int linux_sched_setparam(struct thread *, struct linux_sched_setparam_args *); +int linux_sched_getparam(struct thread *, struct linux_sched_getparam_args *); +int linux_sched_setscheduler(struct thread *, struct linux_sched_setscheduler_args *); +int linux_sched_getscheduler(struct thread *, struct linux_sched_getscheduler_args *); +int linux_sched_get_priority_max(struct thread *, struct linux_sched_get_priority_max_args *); +int linux_sched_get_priority_min(struct thread *, struct linux_sched_get_priority_min_args *); +int linux_sched_rr_get_interval(struct thread *, struct linux_sched_rr_get_interval_args *); +int linux_vhangup(struct thread *, struct linux_vhangup_args *); +int linux_pivot_root(struct thread *, struct linux_pivot_root_args *); +int linux_sysctl(struct thread *, struct linux_sysctl_args *); +int linux_prctl(struct thread *, struct linux_prctl_args *); +int linux_arch_prctl(struct thread *, struct linux_arch_prctl_args *); +int linux_adjtimex(struct thread *, struct linux_adjtimex_args *); +int linux_setrlimit(struct thread *, struct linux_setrlimit_args *); +int linux_mount(struct thread *, struct linux_mount_args *); +int linux_umount(struct thread *, struct linux_umount_args *); +int linux_swapoff(struct thread *, struct linux_swapoff_args *); +int linux_reboot(struct thread *, struct linux_reboot_args *); +int linux_sethostname(struct thread *, struct linux_sethostname_args *); +int linux_setdomainname(struct thread *, struct linux_setdomainname_args *); +int linux_iopl(struct thread *, struct linux_iopl_args *); +int linux_create_module(struct thread *, struct linux_create_module_args *); +int linux_init_module(struct thread *, struct linux_init_module_args *); +int linux_delete_module(struct thread *, struct linux_delete_module_args *); +int linux_get_kernel_syms(struct thread *, struct linux_get_kernel_syms_args *); +int linux_query_module(struct thread *, struct linux_query_module_args *); +int linux_quotactl(struct thread *, struct linux_quotactl_args *); +int linux_nfsservctl(struct thread *, struct linux_nfsservctl_args *); +int linux_getpmsg(struct thread *, struct linux_getpmsg_args *); +int linux_putpmsg(struct thread *, struct linux_putpmsg_args *); +int linux_afs_syscall(struct thread *, struct linux_afs_syscall_args *); +int linux_tuxcall(struct thread *, struct linux_tuxcall_args *); +int linux_security(struct thread *, struct linux_security_args *); +int linux_gettid(struct thread *, struct linux_gettid_args *); +int linux_setxattr(struct thread *, struct linux_setxattr_args *); +int linux_lsetxattr(struct thread *, struct linux_lsetxattr_args *); +int linux_fsetxattr(struct thread *, struct linux_fsetxattr_args *); +int linux_getxattr(struct thread *, struct linux_getxattr_args *); +int linux_lgetxattr(struct thread *, struct linux_lgetxattr_args *); +int linux_fgetxattr(struct thread *, struct linux_fgetxattr_args *); +int linux_listxattr(struct thread *, struct linux_listxattr_args *); +int linux_llistxattr(struct thread *, struct linux_llistxattr_args *); +int linux_flistxattr(struct thread *, struct linux_flistxattr_args *); +int linux_removexattr(struct thread *, struct linux_removexattr_args *); +int linux_lremovexattr(struct thread *, struct linux_lremovexattr_args *); +int linux_fremovexattr(struct thread *, struct linux_fremovexattr_args *); +int linux_tkill(struct thread *, struct linux_tkill_args *); +int linux_time(struct thread *, struct linux_time_args *); +int linux_sys_futex(struct thread *, struct linux_sys_futex_args *); +int linux_sched_setaffinity(struct thread *, struct linux_sched_setaffinity_args *); +int linux_sched_getaffinity(struct thread *, struct linux_sched_getaffinity_args *); +int linux_set_thread_area(struct thread *, struct linux_set_thread_area_args *); +int linux_lookup_dcookie(struct thread *, struct linux_lookup_dcookie_args *); +int linux_epoll_create(struct thread *, struct linux_epoll_create_args *); +int linux_epoll_ctl_old(struct thread *, struct linux_epoll_ctl_old_args *); +int linux_epoll_wait_old(struct thread *, struct linux_epoll_wait_old_args *); +int linux_remap_file_pages(struct thread *, struct linux_remap_file_pages_args *); +int linux_getdents64(struct thread *, struct linux_getdents64_args *); +int linux_set_tid_address(struct thread *, struct linux_set_tid_address_args *); +int linux_semtimedop(struct thread *, struct linux_semtimedop_args *); +int linux_fadvise64(struct thread *, struct linux_fadvise64_args *); +int linux_timer_create(struct thread *, struct linux_timer_create_args *); +int linux_timer_settime(struct thread *, struct linux_timer_settime_args *); +int linux_timer_gettime(struct thread *, struct linux_timer_gettime_args *); +int linux_timer_getoverrun(struct thread *, struct linux_timer_getoverrun_args *); +int linux_timer_delete(struct thread *, struct linux_timer_delete_args *); +int linux_clock_settime(struct thread *, struct linux_clock_settime_args *); +int linux_clock_gettime(struct thread *, struct linux_clock_gettime_args *); +int linux_clock_getres(struct thread *, struct linux_clock_getres_args *); +int linux_clock_nanosleep(struct thread *, struct linux_clock_nanosleep_args *); +int linux_exit_group(struct thread *, struct linux_exit_group_args *); +int linux_epoll_wait(struct thread *, struct linux_epoll_wait_args *); +int linux_epoll_ctl(struct thread *, struct linux_epoll_ctl_args *); +int linux_tgkill(struct thread *, struct linux_tgkill_args *); +int linux_utimes(struct thread *, struct linux_utimes_args *); +int linux_mbind(struct thread *, struct linux_mbind_args *); +int linux_set_mempolicy(struct thread *, struct linux_set_mempolicy_args *); +int linux_get_mempolicy(struct thread *, struct linux_get_mempolicy_args *); +int linux_mq_open(struct thread *, struct linux_mq_open_args *); +int linux_mq_unlink(struct thread *, struct linux_mq_unlink_args *); +int linux_mq_timedsend(struct thread *, struct linux_mq_timedsend_args *); +int linux_mq_timedreceive(struct thread *, struct linux_mq_timedreceive_args *); +int linux_mq_notify(struct thread *, struct linux_mq_notify_args *); +int linux_mq_getsetattr(struct thread *, struct linux_mq_getsetattr_args *); +int linux_kexec_load(struct thread *, struct linux_kexec_load_args *); +int linux_waitid(struct thread *, struct linux_waitid_args *); +int linux_add_key(struct thread *, struct linux_add_key_args *); +int linux_request_key(struct thread *, struct linux_request_key_args *); +int linux_keyctl(struct thread *, struct linux_keyctl_args *); +int linux_ioprio_set(struct thread *, struct linux_ioprio_set_args *); +int linux_ioprio_get(struct thread *, struct linux_ioprio_get_args *); +int linux_inotify_init(struct thread *, struct linux_inotify_init_args *); +int linux_inotify_add_watch(struct thread *, struct linux_inotify_add_watch_args *); +int linux_inotify_rm_watch(struct thread *, struct linux_inotify_rm_watch_args *); +int linux_migrate_pages(struct thread *, struct linux_migrate_pages_args *); +int linux_openat(struct thread *, struct linux_openat_args *); +int linux_mkdirat(struct thread *, struct linux_mkdirat_args *); +int linux_mknodat(struct thread *, struct linux_mknodat_args *); +int linux_fchownat(struct thread *, struct linux_fchownat_args *); +int linux_futimesat(struct thread *, struct linux_futimesat_args *); +int linux_newfstatat(struct thread *, struct linux_newfstatat_args *); +int linux_unlinkat(struct thread *, struct linux_unlinkat_args *); +int linux_renameat(struct thread *, struct linux_renameat_args *); +int linux_linkat(struct thread *, struct linux_linkat_args *); +int linux_symlinkat(struct thread *, struct linux_symlinkat_args *); +int linux_readlinkat(struct thread *, struct linux_readlinkat_args *); +int linux_fchmodat(struct thread *, struct linux_fchmodat_args *); +int linux_faccessat(struct thread *, struct linux_faccessat_args *); +int linux_pselect6(struct thread *, struct linux_pselect6_args *); +int linux_ppoll(struct thread *, struct linux_ppoll_args *); +int linux_unshare(struct thread *, struct linux_unshare_args *); +int linux_set_robust_list(struct thread *, struct linux_set_robust_list_args *); +int linux_get_robust_list(struct thread *, struct linux_get_robust_list_args *); +int linux_splice(struct thread *, struct linux_splice_args *); +int linux_tee(struct thread *, struct linux_tee_args *); +int linux_sync_file_range(struct thread *, struct linux_sync_file_range_args *); +int linux_vmsplice(struct thread *, struct linux_vmsplice_args *); +int linux_move_pages(struct thread *, struct linux_move_pages_args *); +int linux_utimensat(struct thread *, struct linux_utimensat_args *); +int linux_epoll_pwait(struct thread *, struct linux_epoll_pwait_args *); +int linux_signalfd(struct thread *, struct linux_signalfd_args *); +int linux_timerfd(struct thread *, struct linux_timerfd_args *); +int linux_eventfd(struct thread *, struct linux_eventfd_args *); +int linux_fallocate(struct thread *, struct linux_fallocate_args *); +int linux_timerfd_settime(struct thread *, struct linux_timerfd_settime_args *); +int linux_timerfd_gettime(struct thread *, struct linux_timerfd_gettime_args *); +int linux_accept4(struct thread *, struct linux_accept4_args *); +int linux_signalfd4(struct thread *, struct linux_signalfd4_args *); +int linux_eventfd2(struct thread *, struct linux_eventfd2_args *); +int linux_epoll_create1(struct thread *, struct linux_epoll_create1_args *); +int linux_dup3(struct thread *, struct linux_dup3_args *); +int linux_pipe2(struct thread *, struct linux_pipe2_args *); +int linux_inotify_init1(struct thread *, struct linux_inotify_init1_args *); +int linux_preadv(struct thread *, struct linux_preadv_args *); +int linux_pwritev(struct thread *, struct linux_pwritev_args *); +int linux_rt_tsigqueueinfo(struct thread *, struct linux_rt_tsigqueueinfo_args *); +int linux_perf_event_open(struct thread *, struct linux_perf_event_open_args *); +int linux_recvmmsg(struct thread *, struct linux_recvmmsg_args *); +int linux_fanotify_init(struct thread *, struct linux_fanotify_init_args *); +int linux_fanotify_mark(struct thread *, struct linux_fanotify_mark_args *); +int linux_prlimit64(struct thread *, struct linux_prlimit64_args *); +int linux_name_to_handle_at(struct thread *, struct linux_name_to_handle_at_args *); +int linux_open_by_handle_at(struct thread *, struct linux_open_by_handle_at_args *); +int linux_clock_adjtime(struct thread *, struct linux_clock_adjtime_args *); +int linux_syncfs(struct thread *, struct linux_syncfs_args *); +int linux_sendmmsg(struct thread *, struct linux_sendmmsg_args *); +int linux_setns(struct thread *, struct linux_setns_args *); +int linux_process_vm_readv(struct thread *, struct linux_process_vm_readv_args *); +int linux_process_vm_writev(struct thread *, struct linux_process_vm_writev_args *); +int linux_kcmp(struct thread *, struct linux_kcmp_args *); +int linux_finit_module(struct thread *, struct linux_finit_module_args *); + +#ifdef COMPAT_43 + +#define nosys linux_nosys + +#endif /* COMPAT_43 */ + + +#ifdef COMPAT_FREEBSD4 + +#define nosys linux_nosys + +#endif /* COMPAT_FREEBSD4 */ + + +#ifdef COMPAT_FREEBSD6 + +#define nosys linux_nosys + +#endif /* COMPAT_FREEBSD6 */ + + +#ifdef COMPAT_FREEBSD7 + +#define nosys linux_nosys + +#endif /* COMPAT_FREEBSD7 */ + +#define LINUX_SYS_AUE_linux_open AUE_OPEN_RWTC +#define LINUX_SYS_AUE_linux_newstat AUE_STAT +#define LINUX_SYS_AUE_linux_newfstat AUE_FSTAT +#define LINUX_SYS_AUE_linux_newlstat AUE_LSTAT +#define LINUX_SYS_AUE_linux_lseek AUE_LSEEK +#define LINUX_SYS_AUE_linux_mmap2 AUE_MMAP +#define LINUX_SYS_AUE_linux_mprotect AUE_MPROTECT +#define LINUX_SYS_AUE_linux_brk AUE_NULL +#define LINUX_SYS_AUE_linux_rt_sigaction AUE_NULL +#define LINUX_SYS_AUE_linux_rt_sigprocmask AUE_NULL +#define LINUX_SYS_AUE_linux_rt_sigreturn AUE_NULL +#define LINUX_SYS_AUE_linux_ioctl AUE_IOCTL +#define LINUX_SYS_AUE_linux_pread AUE_PREAD +#define LINUX_SYS_AUE_linux_pwrite AUE_PWRITE +#define LINUX_SYS_AUE_linux_access AUE_ACCESS +#define LINUX_SYS_AUE_linux_pipe AUE_PIPE +#define LINUX_SYS_AUE_linux_select AUE_SELECT +#define LINUX_SYS_AUE_linux_mremap AUE_NULL +#define LINUX_SYS_AUE_linux_msync AUE_MSYNC +#define LINUX_SYS_AUE_linux_mincore AUE_MINCORE +#define LINUX_SYS_AUE_linux_shmget AUE_NULL +#define LINUX_SYS_AUE_linux_shmat AUE_NULL +#define LINUX_SYS_AUE_linux_shmctl AUE_NULL +#define LINUX_SYS_AUE_linux_pause AUE_NULL +#define LINUX_SYS_AUE_linux_nanosleep AUE_NULL +#define LINUX_SYS_AUE_linux_getitimer AUE_GETITIMER +#define LINUX_SYS_AUE_linux_alarm AUE_NULL +#define LINUX_SYS_AUE_linux_setitimer AUE_SETITIMER +#define LINUX_SYS_AUE_linux_getpid AUE_GETPID +#define LINUX_SYS_AUE_linux_sendfile AUE_SENDFILE +#define LINUX_SYS_AUE_linux_socket AUE_SOCKET +#define LINUX_SYS_AUE_linux_connect AUE_CONNECT +#define LINUX_SYS_AUE_linux_accept AUE_ACCEPT +#define LINUX_SYS_AUE_linux_sendto AUE_SENDTO +#define LINUX_SYS_AUE_linux_recvfrom AUE_RECVFROM +#define LINUX_SYS_AUE_linux_sendmsg AUE_SENDMSG +#define LINUX_SYS_AUE_linux_recvmsg AUE_RECVMSG +#define LINUX_SYS_AUE_linux_shutdown AUE_NULL +#define LINUX_SYS_AUE_linux_bind AUE_BIND +#define LINUX_SYS_AUE_linux_listen AUE_LISTEN +#define LINUX_SYS_AUE_linux_getsockname AUE_GETSOCKNAME +#define LINUX_SYS_AUE_linux_getpeername AUE_GETPEERNAME +#define LINUX_SYS_AUE_linux_socketpair AUE_SOCKETPAIR +#define LINUX_SYS_AUE_linux_setsockopt AUE_SETSOCKOPT +#define LINUX_SYS_AUE_linux_getsockopt AUE_GETSOCKOPT +#define LINUX_SYS_AUE_linux_clone AUE_RFORK +#define LINUX_SYS_AUE_linux_fork AUE_FORK +#define LINUX_SYS_AUE_linux_vfork AUE_VFORK +#define LINUX_SYS_AUE_linux_execve AUE_EXECVE +#define LINUX_SYS_AUE_linux_exit AUE_EXIT +#define LINUX_SYS_AUE_linux_wait4 AUE_WAIT4 +#define LINUX_SYS_AUE_linux_kill AUE_KILL +#define LINUX_SYS_AUE_linux_newuname AUE_NULL +#define LINUX_SYS_AUE_linux_semget AUE_NULL +#define LINUX_SYS_AUE_linux_semop AUE_NULL +#define LINUX_SYS_AUE_linux_semctl AUE_NULL +#define LINUX_SYS_AUE_linux_shmdt AUE_NULL +#define LINUX_SYS_AUE_linux_msgget AUE_NULL +#define LINUX_SYS_AUE_linux_msgsnd AUE_NULL +#define LINUX_SYS_AUE_linux_msgrcv AUE_NULL +#define LINUX_SYS_AUE_linux_msgctl AUE_NULL +#define LINUX_SYS_AUE_linux_fcntl AUE_FCNTL +#define LINUX_SYS_AUE_linux_fdatasync AUE_NULL +#define LINUX_SYS_AUE_linux_truncate AUE_TRUNCATE +#define LINUX_SYS_AUE_linux_ftruncate AUE_FTRUNCATE +#define LINUX_SYS_AUE_linux_getdents AUE_GETDIRENTRIES +#define LINUX_SYS_AUE_linux_getcwd AUE_GETCWD +#define LINUX_SYS_AUE_linux_chdir AUE_CHDIR +#define LINUX_SYS_AUE_linux_rename AUE_RENAME +#define LINUX_SYS_AUE_linux_mkdir AUE_MKDIR +#define LINUX_SYS_AUE_linux_rmdir AUE_RMDIR +#define LINUX_SYS_AUE_linux_creat AUE_CREAT +#define LINUX_SYS_AUE_linux_link AUE_LINK +#define LINUX_SYS_AUE_linux_unlink AUE_UNLINK +#define LINUX_SYS_AUE_linux_symlink AUE_SYMLINK +#define LINUX_SYS_AUE_linux_readlink AUE_READLINK +#define LINUX_SYS_AUE_linux_chmod AUE_CHMOD +#define LINUX_SYS_AUE_linux_chown AUE_LCHOWN +#define LINUX_SYS_AUE_linux_lchown AUE_LCHOWN +#define LINUX_SYS_AUE_linux_getrlimit AUE_GETRLIMIT +#define LINUX_SYS_AUE_linux_sysinfo AUE_NULL +#define LINUX_SYS_AUE_linux_times AUE_NULL +#define LINUX_SYS_AUE_linux_ptrace AUE_PTRACE +#define LINUX_SYS_AUE_linux_getuid AUE_GETUID +#define LINUX_SYS_AUE_linux_syslog AUE_NULL +#define LINUX_SYS_AUE_linux_getgid AUE_GETGID +#define LINUX_SYS_AUE_linux_getppid AUE_GETPPID +#define LINUX_SYS_AUE_linux_getgroups AUE_GETGROUPS +#define LINUX_SYS_AUE_linux_setgroups AUE_SETGROUPS +#define LINUX_SYS_AUE_linux_setfsuid AUE_SETFSUID +#define LINUX_SYS_AUE_linux_setfsgid AUE_SETFSGID +#define LINUX_SYS_AUE_linux_getsid AUE_GETSID +#define LINUX_SYS_AUE_linux_capget AUE_CAPGET +#define LINUX_SYS_AUE_linux_capset AUE_CAPSET +#define LINUX_SYS_AUE_linux_rt_sigpending AUE_NULL +#define LINUX_SYS_AUE_linux_rt_sigtimedwait AUE_NULL +#define LINUX_SYS_AUE_linux_rt_sigqueueinfo AUE_NULL +#define LINUX_SYS_AUE_linux_rt_sigsuspend AUE_NULL +#define LINUX_SYS_AUE_linux_sigaltstack AUE_NULL +#define LINUX_SYS_AUE_linux_utime AUE_UTIME +#define LINUX_SYS_AUE_linux_mknod AUE_MKNOD +#define LINUX_SYS_AUE_linux_personality AUE_PERSONALITY +#define LINUX_SYS_AUE_linux_ustat AUE_NULL +#define LINUX_SYS_AUE_linux_statfs AUE_STATFS +#define LINUX_SYS_AUE_linux_fstatfs AUE_FSTATFS +#define LINUX_SYS_AUE_linux_sysfs AUE_NULL +#define LINUX_SYS_AUE_linux_getpriority AUE_GETPRIORITY +#define LINUX_SYS_AUE_linux_sched_setparam AUE_SCHED_SETPARAM +#define LINUX_SYS_AUE_linux_sched_getparam AUE_SCHED_GETPARAM +#define LINUX_SYS_AUE_linux_sched_setscheduler AUE_SCHED_SETSCHEDULER +#define LINUX_SYS_AUE_linux_sched_getscheduler AUE_SCHED_GETSCHEDULER +#define LINUX_SYS_AUE_linux_sched_get_priority_max AUE_SCHED_GET_PRIORITY_MAX +#define LINUX_SYS_AUE_linux_sched_get_priority_min AUE_SCHED_GET_PRIORITY_MIN +#define LINUX_SYS_AUE_linux_sched_rr_get_interval AUE_SCHED_RR_GET_INTERVAL +#define LINUX_SYS_AUE_linux_vhangup AUE_NULL +#define LINUX_SYS_AUE_linux_pivot_root AUE_PIVOT_ROOT +#define LINUX_SYS_AUE_linux_sysctl AUE_SYSCTL +#define LINUX_SYS_AUE_linux_prctl AUE_PRCTL +#define LINUX_SYS_AUE_linux_arch_prctl AUE_PRCTL +#define LINUX_SYS_AUE_linux_adjtimex AUE_ADJTIME +#define LINUX_SYS_AUE_linux_setrlimit AUE_SETRLIMIT +#define LINUX_SYS_AUE_linux_mount AUE_MOUNT +#define LINUX_SYS_AUE_linux_umount AUE_UMOUNT +#define LINUX_SYS_AUE_linux_swapoff AUE_SWAPOFF +#define LINUX_SYS_AUE_linux_reboot AUE_REBOOT +#define LINUX_SYS_AUE_linux_sethostname AUE_SYSCTL +#define LINUX_SYS_AUE_linux_setdomainname AUE_SYSCTL +#define LINUX_SYS_AUE_linux_iopl AUE_NULL +#define LINUX_SYS_AUE_linux_create_module AUE_NULL +#define LINUX_SYS_AUE_linux_init_module AUE_NULL +#define LINUX_SYS_AUE_linux_delete_module AUE_NULL +#define LINUX_SYS_AUE_linux_get_kernel_syms AUE_NULL +#define LINUX_SYS_AUE_linux_query_module AUE_NULL +#define LINUX_SYS_AUE_linux_quotactl AUE_QUOTACTL +#define LINUX_SYS_AUE_linux_nfsservctl AUE_NULL +#define LINUX_SYS_AUE_linux_getpmsg AUE_GETPMSG +#define LINUX_SYS_AUE_linux_putpmsg AUE_PUTPMSG +#define LINUX_SYS_AUE_linux_afs_syscall AUE_NULL +#define LINUX_SYS_AUE_linux_tuxcall AUE_NULL +#define LINUX_SYS_AUE_linux_security AUE_NULL +#define LINUX_SYS_AUE_linux_gettid AUE_NULL +#define LINUX_SYS_AUE_linux_setxattr AUE_NULL +#define LINUX_SYS_AUE_linux_lsetxattr AUE_NULL +#define LINUX_SYS_AUE_linux_fsetxattr AUE_NULL +#define LINUX_SYS_AUE_linux_getxattr AUE_NULL +#define LINUX_SYS_AUE_linux_lgetxattr AUE_NULL +#define LINUX_SYS_AUE_linux_fgetxattr AUE_NULL +#define LINUX_SYS_AUE_linux_listxattr AUE_NULL +#define LINUX_SYS_AUE_linux_llistxattr AUE_NULL +#define LINUX_SYS_AUE_linux_flistxattr AUE_NULL +#define LINUX_SYS_AUE_linux_removexattr AUE_NULL +#define LINUX_SYS_AUE_linux_lremovexattr AUE_NULL +#define LINUX_SYS_AUE_linux_fremovexattr AUE_NULL +#define LINUX_SYS_AUE_linux_tkill AUE_NULL +#define LINUX_SYS_AUE_linux_time AUE_NULL +#define LINUX_SYS_AUE_linux_sys_futex AUE_NULL +#define LINUX_SYS_AUE_linux_sched_setaffinity AUE_NULL +#define LINUX_SYS_AUE_linux_sched_getaffinity AUE_NULL +#define LINUX_SYS_AUE_linux_set_thread_area AUE_NULL +#define LINUX_SYS_AUE_linux_lookup_dcookie AUE_NULL +#define LINUX_SYS_AUE_linux_epoll_create AUE_NULL +#define LINUX_SYS_AUE_linux_epoll_ctl_old AUE_NULL +#define LINUX_SYS_AUE_linux_epoll_wait_old AUE_NULL +#define LINUX_SYS_AUE_linux_remap_file_pages AUE_NULL +#define LINUX_SYS_AUE_linux_getdents64 AUE_GETDIRENTRIES +#define LINUX_SYS_AUE_linux_set_tid_address AUE_NULL +#define LINUX_SYS_AUE_linux_semtimedop AUE_NULL +#define LINUX_SYS_AUE_linux_fadvise64 AUE_NULL +#define LINUX_SYS_AUE_linux_timer_create AUE_NULL +#define LINUX_SYS_AUE_linux_timer_settime AUE_NULL +#define LINUX_SYS_AUE_linux_timer_gettime AUE_NULL +#define LINUX_SYS_AUE_linux_timer_getoverrun AUE_NULL +#define LINUX_SYS_AUE_linux_timer_delete AUE_NULL +#define LINUX_SYS_AUE_linux_clock_settime AUE_CLOCK_SETTIME +#define LINUX_SYS_AUE_linux_clock_gettime AUE_NULL +#define LINUX_SYS_AUE_linux_clock_getres AUE_NULL +#define LINUX_SYS_AUE_linux_clock_nanosleep AUE_NULL +#define LINUX_SYS_AUE_linux_exit_group AUE_EXIT +#define LINUX_SYS_AUE_linux_epoll_wait AUE_NULL +#define LINUX_SYS_AUE_linux_epoll_ctl AUE_NULL +#define LINUX_SYS_AUE_linux_tgkill AUE_NULL +#define LINUX_SYS_AUE_linux_utimes AUE_UTIMES +#define LINUX_SYS_AUE_linux_mbind AUE_NULL +#define LINUX_SYS_AUE_linux_set_mempolicy AUE_NULL +#define LINUX_SYS_AUE_linux_get_mempolicy AUE_NULL +#define LINUX_SYS_AUE_linux_mq_open AUE_NULL +#define LINUX_SYS_AUE_linux_mq_unlink AUE_NULL +#define LINUX_SYS_AUE_linux_mq_timedsend AUE_NULL +#define LINUX_SYS_AUE_linux_mq_timedreceive AUE_NULL +#define LINUX_SYS_AUE_linux_mq_notify AUE_NULL +#define LINUX_SYS_AUE_linux_mq_getsetattr AUE_NULL +#define LINUX_SYS_AUE_linux_kexec_load AUE_NULL +#define LINUX_SYS_AUE_linux_waitid AUE_WAIT6 +#define LINUX_SYS_AUE_linux_add_key AUE_NULL +#define LINUX_SYS_AUE_linux_request_key AUE_NULL +#define LINUX_SYS_AUE_linux_keyctl AUE_NULL +#define LINUX_SYS_AUE_linux_ioprio_set AUE_NULL +#define LINUX_SYS_AUE_linux_ioprio_get AUE_NULL +#define LINUX_SYS_AUE_linux_inotify_init AUE_NULL +#define LINUX_SYS_AUE_linux_inotify_add_watch AUE_NULL +#define LINUX_SYS_AUE_linux_inotify_rm_watch AUE_NULL +#define LINUX_SYS_AUE_linux_migrate_pages AUE_NULL +#define LINUX_SYS_AUE_linux_openat AUE_OPEN_RWTC +#define LINUX_SYS_AUE_linux_mkdirat AUE_MKDIRAT +#define LINUX_SYS_AUE_linux_mknodat AUE_MKNODAT +#define LINUX_SYS_AUE_linux_fchownat AUE_FCHOWNAT +#define LINUX_SYS_AUE_linux_futimesat AUE_FUTIMESAT +#define LINUX_SYS_AUE_linux_newfstatat AUE_FSTATAT +#define LINUX_SYS_AUE_linux_unlinkat AUE_UNLINKAT +#define LINUX_SYS_AUE_linux_renameat AUE_RENAMEAT +#define LINUX_SYS_AUE_linux_linkat AUE_LINKAT +#define LINUX_SYS_AUE_linux_symlinkat AUE_SYMLINKAT +#define LINUX_SYS_AUE_linux_readlinkat AUE_READLINKAT +#define LINUX_SYS_AUE_linux_fchmodat AUE_FCHMODAT +#define LINUX_SYS_AUE_linux_faccessat AUE_FACCESSAT +#define LINUX_SYS_AUE_linux_pselect6 AUE_SELECT +#define LINUX_SYS_AUE_linux_ppoll AUE_POLL +#define LINUX_SYS_AUE_linux_unshare AUE_NULL +#define LINUX_SYS_AUE_linux_set_robust_list AUE_NULL +#define LINUX_SYS_AUE_linux_get_robust_list AUE_NULL +#define LINUX_SYS_AUE_linux_splice AUE_NULL +#define LINUX_SYS_AUE_linux_tee AUE_NULL +#define LINUX_SYS_AUE_linux_sync_file_range AUE_NULL +#define LINUX_SYS_AUE_linux_vmsplice AUE_NULL +#define LINUX_SYS_AUE_linux_move_pages AUE_NULL +#define LINUX_SYS_AUE_linux_utimensat AUE_FUTIMESAT +#define LINUX_SYS_AUE_linux_epoll_pwait AUE_NULL +#define LINUX_SYS_AUE_linux_signalfd AUE_NULL +#define LINUX_SYS_AUE_linux_timerfd AUE_NULL +#define LINUX_SYS_AUE_linux_eventfd AUE_NULL +#define LINUX_SYS_AUE_linux_fallocate AUE_NULL +#define LINUX_SYS_AUE_linux_timerfd_settime AUE_NULL +#define LINUX_SYS_AUE_linux_timerfd_gettime AUE_NULL +#define LINUX_SYS_AUE_linux_accept4 AUE_ACCEPT +#define LINUX_SYS_AUE_linux_signalfd4 AUE_NULL +#define LINUX_SYS_AUE_linux_eventfd2 AUE_NULL +#define LINUX_SYS_AUE_linux_epoll_create1 AUE_NULL +#define LINUX_SYS_AUE_linux_dup3 AUE_NULL +#define LINUX_SYS_AUE_linux_pipe2 AUE_NULL +#define LINUX_SYS_AUE_linux_inotify_init1 AUE_NULL +#define LINUX_SYS_AUE_linux_preadv AUE_NULL +#define LINUX_SYS_AUE_linux_pwritev AUE_NULL +#define LINUX_SYS_AUE_linux_rt_tsigqueueinfo AUE_NULL +#define LINUX_SYS_AUE_linux_perf_event_open AUE_NULL +#define LINUX_SYS_AUE_linux_recvmmsg AUE_NULL +#define LINUX_SYS_AUE_linux_fanotify_init AUE_NULL +#define LINUX_SYS_AUE_linux_fanotify_mark AUE_NULL +#define LINUX_SYS_AUE_linux_prlimit64 AUE_NULL +#define LINUX_SYS_AUE_linux_name_to_handle_at AUE_NULL +#define LINUX_SYS_AUE_linux_open_by_handle_at AUE_NULL +#define LINUX_SYS_AUE_linux_clock_adjtime AUE_NULL +#define LINUX_SYS_AUE_linux_syncfs AUE_SYNC +#define LINUX_SYS_AUE_linux_sendmmsg AUE_NULL +#define LINUX_SYS_AUE_linux_setns AUE_NULL +#define LINUX_SYS_AUE_linux_process_vm_readv AUE_NULL +#define LINUX_SYS_AUE_linux_process_vm_writev AUE_NULL +#define LINUX_SYS_AUE_linux_kcmp AUE_NULL +#define LINUX_SYS_AUE_linux_finit_module AUE_NULL + +#undef PAD_ +#undef PADL_ +#undef PADR_ + +#endif /* !_LINUX_SYSPROTO_H_ */ diff --git a/sys/amd64/linux/linux_support.s b/sys/amd64/linux/linux_support.s new file mode 100644 index 0000000..2a3ba1a --- /dev/null +++ b/sys/amd64/linux/linux_support.s @@ -0,0 +1,124 @@ +/*- + * Copyright (c) 2007 Konstantin Belousov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include "linux_assym.h" /* system definitions */ +#include <machine/asmacros.h> /* miscellaneous asm macros */ + +#include "assym.s" + +futex_fault: + movq $0,PCB_ONFAULT(%r8) + movl $-EFAULT,%eax + ret + +ENTRY(futex_xchgl) + movq PCPU(CURPCB),%r8 + movq $futex_fault,PCB_ONFAULT(%r8) + movq $VM_MAXUSER_ADDRESS-4,%rax + cmpq %rax,%rsi + ja futex_fault + xchgl %edi,(%rsi) + movl %edi,(%rdx) + xorl %eax,%eax + movq %rax,PCB_ONFAULT(%r8) + ret + +ENTRY(futex_addl) + movq PCPU(CURPCB),%r8 + movq $futex_fault,PCB_ONFAULT(%r8) + movq $VM_MAXUSER_ADDRESS-4,%rax + cmpq %rax,%rsi + ja futex_fault +#ifdef SMP + lock +#endif + xaddl %edi,(%rsi) + movl %edi,(%rdx) + xorl %eax,%eax + movq %rax,PCB_ONFAULT(%r8) + ret + +ENTRY(futex_orl) + movq PCPU(CURPCB),%r8 + movq $futex_fault,PCB_ONFAULT(%r8) + movq $VM_MAXUSER_ADDRESS-4,%rax + cmpq %rax,%rsi + ja futex_fault + movl (%rsi),%eax +1: movl %eax,%ecx + orl %edi,%ecx +#ifdef SMP + lock +#endif + cmpxchgl %ecx,(%rsi) + jnz 1b + movl %eax,(%rdx) + xorl %eax,%eax + movq %rax,PCB_ONFAULT(%r8) + ret + +ENTRY(futex_andl) + movq PCPU(CURPCB),%r8 + movq $futex_fault,PCB_ONFAULT(%r8) + movq $VM_MAXUSER_ADDRESS-4,%rax + cmpq %rax,%rsi + ja futex_fault + movl (%rsi),%eax +1: movl %eax,%ecx + andl %edi,%ecx +#ifdef SMP + lock +#endif + cmpxchgl %ecx,(%rsi) + jnz 1b + movl %eax,(%rdx) + xorl %eax,%eax + movq %rax,PCB_ONFAULT(%r8) + ret + +ENTRY(futex_xorl) + movq PCPU(CURPCB),%r8 + movq $futex_fault,PCB_ONFAULT(%r8) + movq $VM_MAXUSER_ADDRESS-4,%rax + cmpq %rax,%rsi + ja futex_fault + movl (%rsi),%eax +1: movl %eax,%ecx + xorl %edi,%ecx +#ifdef SMP + lock +#endif + cmpxchgl %ecx,(%rsi) + jnz 1b + movl %eax,(%rdx) + xorl %eax,%eax + movq %rax,PCB_ONFAULT(%r8) + ret diff --git a/sys/amd64/linux/linux_syscall.h b/sys/amd64/linux/linux_syscall.h new file mode 100644 index 0000000..c8d811a --- /dev/null +++ b/sys/amd64/linux/linux_syscall.h @@ -0,0 +1,310 @@ +/* + * System call numbers. + * + * DO NOT EDIT-- this file is automatically generated. + * $FreeBSD$ + * created from FreeBSD: stable/10/sys/amd64/linux/syscalls.master 293592 2016-01-09 17:54:37Z dchagin + */ + +#define LINUX_SYS_read 0 +#define LINUX_SYS_write 1 +#define LINUX_SYS_linux_open 2 +#define LINUX_SYS_close 3 +#define LINUX_SYS_linux_newstat 4 +#define LINUX_SYS_linux_newfstat 5 +#define LINUX_SYS_linux_newlstat 6 +#define LINUX_SYS_poll 7 +#define LINUX_SYS_linux_lseek 8 +#define LINUX_SYS_linux_mmap2 9 +#define LINUX_SYS_linux_mprotect 10 +#define LINUX_SYS_munmap 11 +#define LINUX_SYS_linux_brk 12 +#define LINUX_SYS_linux_rt_sigaction 13 +#define LINUX_SYS_linux_rt_sigprocmask 14 +#define LINUX_SYS_linux_rt_sigreturn 15 +#define LINUX_SYS_linux_ioctl 16 +#define LINUX_SYS_linux_pread 17 +#define LINUX_SYS_linux_pwrite 18 +#define LINUX_SYS_readv 19 +#define LINUX_SYS_writev 20 +#define LINUX_SYS_linux_access 21 +#define LINUX_SYS_linux_pipe 22 +#define LINUX_SYS_linux_select 23 +#define LINUX_SYS_sched_yield 24 +#define LINUX_SYS_linux_mremap 25 +#define LINUX_SYS_linux_msync 26 +#define LINUX_SYS_linux_mincore 27 +#define LINUX_SYS_madvise 28 +#define LINUX_SYS_linux_shmget 29 +#define LINUX_SYS_linux_shmat 30 +#define LINUX_SYS_linux_shmctl 31 +#define LINUX_SYS_dup 32 +#define LINUX_SYS_dup2 33 +#define LINUX_SYS_linux_pause 34 +#define LINUX_SYS_linux_nanosleep 35 +#define LINUX_SYS_linux_getitimer 36 +#define LINUX_SYS_linux_alarm 37 +#define LINUX_SYS_linux_setitimer 38 +#define LINUX_SYS_linux_getpid 39 +#define LINUX_SYS_linux_sendfile 40 +#define LINUX_SYS_linux_socket 41 +#define LINUX_SYS_linux_connect 42 +#define LINUX_SYS_linux_accept 43 +#define LINUX_SYS_linux_sendto 44 +#define LINUX_SYS_linux_recvfrom 45 +#define LINUX_SYS_linux_sendmsg 46 +#define LINUX_SYS_linux_recvmsg 47 +#define LINUX_SYS_linux_shutdown 48 +#define LINUX_SYS_linux_bind 49 +#define LINUX_SYS_linux_listen 50 +#define LINUX_SYS_linux_getsockname 51 +#define LINUX_SYS_linux_getpeername 52 +#define LINUX_SYS_linux_socketpair 53 +#define LINUX_SYS_linux_setsockopt 54 +#define LINUX_SYS_linux_getsockopt 55 +#define LINUX_SYS_linux_clone 56 +#define LINUX_SYS_linux_fork 57 +#define LINUX_SYS_linux_vfork 58 +#define LINUX_SYS_linux_execve 59 +#define LINUX_SYS_linux_exit 60 +#define LINUX_SYS_linux_wait4 61 +#define LINUX_SYS_linux_kill 62 +#define LINUX_SYS_linux_newuname 63 +#define LINUX_SYS_linux_semget 64 +#define LINUX_SYS_linux_semop 65 +#define LINUX_SYS_linux_semctl 66 +#define LINUX_SYS_linux_shmdt 67 +#define LINUX_SYS_linux_msgget 68 +#define LINUX_SYS_linux_msgsnd 69 +#define LINUX_SYS_linux_msgrcv 70 +#define LINUX_SYS_linux_msgctl 71 +#define LINUX_SYS_linux_fcntl 72 +#define LINUX_SYS_flock 73 +#define LINUX_SYS_fsync 74 +#define LINUX_SYS_linux_fdatasync 75 +#define LINUX_SYS_linux_truncate 76 +#define LINUX_SYS_linux_ftruncate 77 +#define LINUX_SYS_linux_getdents 78 +#define LINUX_SYS_linux_getcwd 79 +#define LINUX_SYS_linux_chdir 80 +#define LINUX_SYS_fchdir 81 +#define LINUX_SYS_linux_rename 82 +#define LINUX_SYS_linux_mkdir 83 +#define LINUX_SYS_linux_rmdir 84 +#define LINUX_SYS_linux_creat 85 +#define LINUX_SYS_linux_link 86 +#define LINUX_SYS_linux_unlink 87 +#define LINUX_SYS_linux_symlink 88 +#define LINUX_SYS_linux_readlink 89 +#define LINUX_SYS_linux_chmod 90 +#define LINUX_SYS_fchmod 91 +#define LINUX_SYS_linux_chown 92 +#define LINUX_SYS_fchown 93 +#define LINUX_SYS_linux_lchown 94 +#define LINUX_SYS_umask 95 +#define LINUX_SYS_gettimeofday 96 +#define LINUX_SYS_linux_getrlimit 97 +#define LINUX_SYS_getrusage 98 +#define LINUX_SYS_linux_sysinfo 99 +#define LINUX_SYS_linux_times 100 +#define LINUX_SYS_linux_ptrace 101 +#define LINUX_SYS_linux_getuid 102 +#define LINUX_SYS_linux_syslog 103 +#define LINUX_SYS_linux_getgid 104 +#define LINUX_SYS_setuid 105 +#define LINUX_SYS_setgid 106 +#define LINUX_SYS_geteuid 107 +#define LINUX_SYS_getegid 108 +#define LINUX_SYS_setpgid 109 +#define LINUX_SYS_linux_getppid 110 +#define LINUX_SYS_getpgrp 111 +#define LINUX_SYS_setsid 112 +#define LINUX_SYS_setreuid 113 +#define LINUX_SYS_setregid 114 +#define LINUX_SYS_linux_getgroups 115 +#define LINUX_SYS_linux_setgroups 116 +#define LINUX_SYS_setresuid 117 +#define LINUX_SYS_getresuid 118 +#define LINUX_SYS_setresgid 119 +#define LINUX_SYS_getresgid 120 +#define LINUX_SYS_getpgid 121 +#define LINUX_SYS_linux_setfsuid 122 +#define LINUX_SYS_linux_setfsgid 123 +#define LINUX_SYS_linux_getsid 124 +#define LINUX_SYS_linux_capget 125 +#define LINUX_SYS_linux_capset 126 +#define LINUX_SYS_linux_rt_sigpending 127 +#define LINUX_SYS_linux_rt_sigtimedwait 128 +#define LINUX_SYS_linux_rt_sigqueueinfo 129 +#define LINUX_SYS_linux_rt_sigsuspend 130 +#define LINUX_SYS_linux_sigaltstack 131 +#define LINUX_SYS_linux_utime 132 +#define LINUX_SYS_linux_mknod 133 +#define LINUX_SYS_linux_personality 135 +#define LINUX_SYS_linux_ustat 136 +#define LINUX_SYS_linux_statfs 137 +#define LINUX_SYS_linux_fstatfs 138 +#define LINUX_SYS_linux_sysfs 139 +#define LINUX_SYS_linux_getpriority 140 +#define LINUX_SYS_setpriority 141 +#define LINUX_SYS_linux_sched_setparam 142 +#define LINUX_SYS_linux_sched_getparam 143 +#define LINUX_SYS_linux_sched_setscheduler 144 +#define LINUX_SYS_linux_sched_getscheduler 145 +#define LINUX_SYS_linux_sched_get_priority_max 146 +#define LINUX_SYS_linux_sched_get_priority_min 147 +#define LINUX_SYS_linux_sched_rr_get_interval 148 +#define LINUX_SYS_mlock 149 +#define LINUX_SYS_munlock 150 +#define LINUX_SYS_mlockall 151 +#define LINUX_SYS_munlockall 152 +#define LINUX_SYS_linux_vhangup 153 +#define LINUX_SYS_linux_pivot_root 155 +#define LINUX_SYS_linux_sysctl 156 +#define LINUX_SYS_linux_prctl 157 +#define LINUX_SYS_linux_arch_prctl 158 +#define LINUX_SYS_linux_adjtimex 159 +#define LINUX_SYS_linux_setrlimit 160 +#define LINUX_SYS_chroot 161 +#define LINUX_SYS_sync 162 +#define LINUX_SYS_acct 163 +#define LINUX_SYS_settimeofday 164 +#define LINUX_SYS_linux_mount 165 +#define LINUX_SYS_linux_umount 166 +#define LINUX_SYS_swapon 167 +#define LINUX_SYS_linux_swapoff 168 +#define LINUX_SYS_linux_reboot 169 +#define LINUX_SYS_linux_sethostname 170 +#define LINUX_SYS_linux_setdomainname 171 +#define LINUX_SYS_linux_iopl 172 +#define LINUX_SYS_linux_create_module 174 +#define LINUX_SYS_linux_init_module 175 +#define LINUX_SYS_linux_delete_module 176 +#define LINUX_SYS_linux_get_kernel_syms 177 +#define LINUX_SYS_linux_query_module 178 +#define LINUX_SYS_linux_quotactl 179 +#define LINUX_SYS_linux_nfsservctl 180 +#define LINUX_SYS_linux_getpmsg 181 +#define LINUX_SYS_linux_putpmsg 182 +#define LINUX_SYS_linux_afs_syscall 183 +#define LINUX_SYS_linux_tuxcall 184 +#define LINUX_SYS_linux_security 185 +#define LINUX_SYS_linux_gettid 186 +#define LINUX_SYS_linux_setxattr 188 +#define LINUX_SYS_linux_lsetxattr 189 +#define LINUX_SYS_linux_fsetxattr 190 +#define LINUX_SYS_linux_getxattr 191 +#define LINUX_SYS_linux_lgetxattr 192 +#define LINUX_SYS_linux_fgetxattr 193 +#define LINUX_SYS_linux_listxattr 194 +#define LINUX_SYS_linux_llistxattr 195 +#define LINUX_SYS_linux_flistxattr 196 +#define LINUX_SYS_linux_removexattr 197 +#define LINUX_SYS_linux_lremovexattr 198 +#define LINUX_SYS_linux_fremovexattr 199 +#define LINUX_SYS_linux_tkill 200 +#define LINUX_SYS_linux_time 201 +#define LINUX_SYS_linux_sys_futex 202 +#define LINUX_SYS_linux_sched_setaffinity 203 +#define LINUX_SYS_linux_sched_getaffinity 204 +#define LINUX_SYS_linux_set_thread_area 205 +#define LINUX_SYS_linux_lookup_dcookie 212 +#define LINUX_SYS_linux_epoll_create 213 +#define LINUX_SYS_linux_epoll_ctl_old 214 +#define LINUX_SYS_linux_epoll_wait_old 215 +#define LINUX_SYS_linux_remap_file_pages 216 +#define LINUX_SYS_linux_getdents64 217 +#define LINUX_SYS_linux_set_tid_address 218 +#define LINUX_SYS_linux_semtimedop 220 +#define LINUX_SYS_linux_fadvise64 221 +#define LINUX_SYS_linux_timer_create 222 +#define LINUX_SYS_linux_timer_settime 223 +#define LINUX_SYS_linux_timer_gettime 224 +#define LINUX_SYS_linux_timer_getoverrun 225 +#define LINUX_SYS_linux_timer_delete 226 +#define LINUX_SYS_linux_clock_settime 227 +#define LINUX_SYS_linux_clock_gettime 228 +#define LINUX_SYS_linux_clock_getres 229 +#define LINUX_SYS_linux_clock_nanosleep 230 +#define LINUX_SYS_linux_exit_group 231 +#define LINUX_SYS_linux_epoll_wait 232 +#define LINUX_SYS_linux_epoll_ctl 233 +#define LINUX_SYS_linux_tgkill 234 +#define LINUX_SYS_linux_utimes 235 +#define LINUX_SYS_linux_mbind 237 +#define LINUX_SYS_linux_set_mempolicy 238 +#define LINUX_SYS_linux_get_mempolicy 239 +#define LINUX_SYS_linux_mq_open 240 +#define LINUX_SYS_linux_mq_unlink 241 +#define LINUX_SYS_linux_mq_timedsend 242 +#define LINUX_SYS_linux_mq_timedreceive 243 +#define LINUX_SYS_linux_mq_notify 244 +#define LINUX_SYS_linux_mq_getsetattr 245 +#define LINUX_SYS_linux_kexec_load 246 +#define LINUX_SYS_linux_waitid 247 +#define LINUX_SYS_linux_add_key 248 +#define LINUX_SYS_linux_request_key 249 +#define LINUX_SYS_linux_keyctl 250 +#define LINUX_SYS_linux_ioprio_set 251 +#define LINUX_SYS_linux_ioprio_get 252 +#define LINUX_SYS_linux_inotify_init 253 +#define LINUX_SYS_linux_inotify_add_watch 254 +#define LINUX_SYS_linux_inotify_rm_watch 255 +#define LINUX_SYS_linux_migrate_pages 256 +#define LINUX_SYS_linux_openat 257 +#define LINUX_SYS_linux_mkdirat 258 +#define LINUX_SYS_linux_mknodat 259 +#define LINUX_SYS_linux_fchownat 260 +#define LINUX_SYS_linux_futimesat 261 +#define LINUX_SYS_linux_newfstatat 262 +#define LINUX_SYS_linux_unlinkat 263 +#define LINUX_SYS_linux_renameat 264 +#define LINUX_SYS_linux_linkat 265 +#define LINUX_SYS_linux_symlinkat 266 +#define LINUX_SYS_linux_readlinkat 267 +#define LINUX_SYS_linux_fchmodat 268 +#define LINUX_SYS_linux_faccessat 269 +#define LINUX_SYS_linux_pselect6 270 +#define LINUX_SYS_linux_ppoll 271 +#define LINUX_SYS_linux_unshare 272 +#define LINUX_SYS_linux_set_robust_list 273 +#define LINUX_SYS_linux_get_robust_list 274 +#define LINUX_SYS_linux_splice 275 +#define LINUX_SYS_linux_tee 276 +#define LINUX_SYS_linux_sync_file_range 277 +#define LINUX_SYS_linux_vmsplice 278 +#define LINUX_SYS_linux_move_pages 279 +#define LINUX_SYS_linux_utimensat 280 +#define LINUX_SYS_linux_epoll_pwait 281 +#define LINUX_SYS_linux_signalfd 282 +#define LINUX_SYS_linux_timerfd 283 +#define LINUX_SYS_linux_eventfd 284 +#define LINUX_SYS_linux_fallocate 285 +#define LINUX_SYS_linux_timerfd_settime 286 +#define LINUX_SYS_linux_timerfd_gettime 287 +#define LINUX_SYS_linux_accept4 288 +#define LINUX_SYS_linux_signalfd4 289 +#define LINUX_SYS_linux_eventfd2 290 +#define LINUX_SYS_linux_epoll_create1 291 +#define LINUX_SYS_linux_dup3 292 +#define LINUX_SYS_linux_pipe2 293 +#define LINUX_SYS_linux_inotify_init1 294 +#define LINUX_SYS_linux_preadv 295 +#define LINUX_SYS_linux_pwritev 296 +#define LINUX_SYS_linux_rt_tsigqueueinfo 297 +#define LINUX_SYS_linux_perf_event_open 298 +#define LINUX_SYS_linux_recvmmsg 299 +#define LINUX_SYS_linux_fanotify_init 300 +#define LINUX_SYS_linux_fanotify_mark 301 +#define LINUX_SYS_linux_prlimit64 302 +#define LINUX_SYS_linux_name_to_handle_at 303 +#define LINUX_SYS_linux_open_by_handle_at 304 +#define LINUX_SYS_linux_clock_adjtime 305 +#define LINUX_SYS_linux_syncfs 306 +#define LINUX_SYS_linux_sendmmsg 307 +#define LINUX_SYS_linux_setns 308 +#define LINUX_SYS_linux_process_vm_readv 309 +#define LINUX_SYS_linux_process_vm_writev 310 +#define LINUX_SYS_linux_kcmp 311 +#define LINUX_SYS_linux_finit_module 312 +#define LINUX_SYS_MAXSYSCALL 314 diff --git a/sys/amd64/linux/linux_syscalls.c b/sys/amd64/linux/linux_syscalls.c new file mode 100644 index 0000000..5c1e1a2 --- /dev/null +++ b/sys/amd64/linux/linux_syscalls.c @@ -0,0 +1,325 @@ +/* + * System call names. + * + * DO NOT EDIT-- this file is automatically generated. + * $FreeBSD$ + * created from FreeBSD: stable/10/sys/amd64/linux/syscalls.master 293592 2016-01-09 17:54:37Z dchagin + */ + +const char *linux_syscallnames[] = { +#define nosys linux_nosys + "read", /* 0 = read */ + "write", /* 1 = write */ + "linux_open", /* 2 = linux_open */ + "close", /* 3 = close */ + "linux_newstat", /* 4 = linux_newstat */ + "linux_newfstat", /* 5 = linux_newfstat */ + "linux_newlstat", /* 6 = linux_newlstat */ + "poll", /* 7 = poll */ + "linux_lseek", /* 8 = linux_lseek */ + "linux_mmap2", /* 9 = linux_mmap2 */ + "linux_mprotect", /* 10 = linux_mprotect */ + "munmap", /* 11 = munmap */ + "linux_brk", /* 12 = linux_brk */ + "linux_rt_sigaction", /* 13 = linux_rt_sigaction */ + "linux_rt_sigprocmask", /* 14 = linux_rt_sigprocmask */ + "linux_rt_sigreturn", /* 15 = linux_rt_sigreturn */ + "linux_ioctl", /* 16 = linux_ioctl */ + "linux_pread", /* 17 = linux_pread */ + "linux_pwrite", /* 18 = linux_pwrite */ + "readv", /* 19 = readv */ + "writev", /* 20 = writev */ + "linux_access", /* 21 = linux_access */ + "linux_pipe", /* 22 = linux_pipe */ + "linux_select", /* 23 = linux_select */ + "sched_yield", /* 24 = sched_yield */ + "linux_mremap", /* 25 = linux_mremap */ + "linux_msync", /* 26 = linux_msync */ + "linux_mincore", /* 27 = linux_mincore */ + "madvise", /* 28 = madvise */ + "linux_shmget", /* 29 = linux_shmget */ + "linux_shmat", /* 30 = linux_shmat */ + "linux_shmctl", /* 31 = linux_shmctl */ + "dup", /* 32 = dup */ + "dup2", /* 33 = dup2 */ + "linux_pause", /* 34 = linux_pause */ + "linux_nanosleep", /* 35 = linux_nanosleep */ + "linux_getitimer", /* 36 = linux_getitimer */ + "linux_alarm", /* 37 = linux_alarm */ + "linux_setitimer", /* 38 = linux_setitimer */ + "linux_getpid", /* 39 = linux_getpid */ + "linux_sendfile", /* 40 = linux_sendfile */ + "linux_socket", /* 41 = linux_socket */ + "linux_connect", /* 42 = linux_connect */ + "linux_accept", /* 43 = linux_accept */ + "linux_sendto", /* 44 = linux_sendto */ + "linux_recvfrom", /* 45 = linux_recvfrom */ + "linux_sendmsg", /* 46 = linux_sendmsg */ + "linux_recvmsg", /* 47 = linux_recvmsg */ + "linux_shutdown", /* 48 = linux_shutdown */ + "linux_bind", /* 49 = linux_bind */ + "linux_listen", /* 50 = linux_listen */ + "linux_getsockname", /* 51 = linux_getsockname */ + "linux_getpeername", /* 52 = linux_getpeername */ + "linux_socketpair", /* 53 = linux_socketpair */ + "linux_setsockopt", /* 54 = linux_setsockopt */ + "linux_getsockopt", /* 55 = linux_getsockopt */ + "linux_clone", /* 56 = linux_clone */ + "linux_fork", /* 57 = linux_fork */ + "linux_vfork", /* 58 = linux_vfork */ + "linux_execve", /* 59 = linux_execve */ + "linux_exit", /* 60 = linux_exit */ + "linux_wait4", /* 61 = linux_wait4 */ + "linux_kill", /* 62 = linux_kill */ + "linux_newuname", /* 63 = linux_newuname */ + "linux_semget", /* 64 = linux_semget */ + "linux_semop", /* 65 = linux_semop */ + "linux_semctl", /* 66 = linux_semctl */ + "linux_shmdt", /* 67 = linux_shmdt */ + "linux_msgget", /* 68 = linux_msgget */ + "linux_msgsnd", /* 69 = linux_msgsnd */ + "linux_msgrcv", /* 70 = linux_msgrcv */ + "linux_msgctl", /* 71 = linux_msgctl */ + "linux_fcntl", /* 72 = linux_fcntl */ + "flock", /* 73 = flock */ + "fsync", /* 74 = fsync */ + "linux_fdatasync", /* 75 = linux_fdatasync */ + "linux_truncate", /* 76 = linux_truncate */ + "linux_ftruncate", /* 77 = linux_ftruncate */ + "linux_getdents", /* 78 = linux_getdents */ + "linux_getcwd", /* 79 = linux_getcwd */ + "linux_chdir", /* 80 = linux_chdir */ + "fchdir", /* 81 = fchdir */ + "linux_rename", /* 82 = linux_rename */ + "linux_mkdir", /* 83 = linux_mkdir */ + "linux_rmdir", /* 84 = linux_rmdir */ + "linux_creat", /* 85 = linux_creat */ + "linux_link", /* 86 = linux_link */ + "linux_unlink", /* 87 = linux_unlink */ + "linux_symlink", /* 88 = linux_symlink */ + "linux_readlink", /* 89 = linux_readlink */ + "linux_chmod", /* 90 = linux_chmod */ + "fchmod", /* 91 = fchmod */ + "linux_chown", /* 92 = linux_chown */ + "fchown", /* 93 = fchown */ + "linux_lchown", /* 94 = linux_lchown */ + "umask", /* 95 = umask */ + "gettimeofday", /* 96 = gettimeofday */ + "linux_getrlimit", /* 97 = linux_getrlimit */ + "getrusage", /* 98 = getrusage */ + "linux_sysinfo", /* 99 = linux_sysinfo */ + "linux_times", /* 100 = linux_times */ + "linux_ptrace", /* 101 = linux_ptrace */ + "linux_getuid", /* 102 = linux_getuid */ + "linux_syslog", /* 103 = linux_syslog */ + "linux_getgid", /* 104 = linux_getgid */ + "setuid", /* 105 = setuid */ + "setgid", /* 106 = setgid */ + "geteuid", /* 107 = geteuid */ + "getegid", /* 108 = getegid */ + "setpgid", /* 109 = setpgid */ + "linux_getppid", /* 110 = linux_getppid */ + "getpgrp", /* 111 = getpgrp */ + "setsid", /* 112 = setsid */ + "setreuid", /* 113 = setreuid */ + "setregid", /* 114 = setregid */ + "linux_getgroups", /* 115 = linux_getgroups */ + "linux_setgroups", /* 116 = linux_setgroups */ + "setresuid", /* 117 = setresuid */ + "getresuid", /* 118 = getresuid */ + "setresgid", /* 119 = setresgid */ + "getresgid", /* 120 = getresgid */ + "getpgid", /* 121 = getpgid */ + "linux_setfsuid", /* 122 = linux_setfsuid */ + "linux_setfsgid", /* 123 = linux_setfsgid */ + "linux_getsid", /* 124 = linux_getsid */ + "linux_capget", /* 125 = linux_capget */ + "linux_capset", /* 126 = linux_capset */ + "linux_rt_sigpending", /* 127 = linux_rt_sigpending */ + "linux_rt_sigtimedwait", /* 128 = linux_rt_sigtimedwait */ + "linux_rt_sigqueueinfo", /* 129 = linux_rt_sigqueueinfo */ + "linux_rt_sigsuspend", /* 130 = linux_rt_sigsuspend */ + "linux_sigaltstack", /* 131 = linux_sigaltstack */ + "linux_utime", /* 132 = linux_utime */ + "linux_mknod", /* 133 = linux_mknod */ + "#134", /* 134 = uselib */ + "linux_personality", /* 135 = linux_personality */ + "linux_ustat", /* 136 = linux_ustat */ + "linux_statfs", /* 137 = linux_statfs */ + "linux_fstatfs", /* 138 = linux_fstatfs */ + "linux_sysfs", /* 139 = linux_sysfs */ + "linux_getpriority", /* 140 = linux_getpriority */ + "setpriority", /* 141 = setpriority */ + "linux_sched_setparam", /* 142 = linux_sched_setparam */ + "linux_sched_getparam", /* 143 = linux_sched_getparam */ + "linux_sched_setscheduler", /* 144 = linux_sched_setscheduler */ + "linux_sched_getscheduler", /* 145 = linux_sched_getscheduler */ + "linux_sched_get_priority_max", /* 146 = linux_sched_get_priority_max */ + "linux_sched_get_priority_min", /* 147 = linux_sched_get_priority_min */ + "linux_sched_rr_get_interval", /* 148 = linux_sched_rr_get_interval */ + "mlock", /* 149 = mlock */ + "munlock", /* 150 = munlock */ + "mlockall", /* 151 = mlockall */ + "munlockall", /* 152 = munlockall */ + "linux_vhangup", /* 153 = linux_vhangup */ + "#154", /* 154 = modify_ldt */ + "linux_pivot_root", /* 155 = linux_pivot_root */ + "linux_sysctl", /* 156 = linux_sysctl */ + "linux_prctl", /* 157 = linux_prctl */ + "linux_arch_prctl", /* 158 = linux_arch_prctl */ + "linux_adjtimex", /* 159 = linux_adjtimex */ + "linux_setrlimit", /* 160 = linux_setrlimit */ + "chroot", /* 161 = chroot */ + "sync", /* 162 = sync */ + "acct", /* 163 = acct */ + "settimeofday", /* 164 = settimeofday */ + "linux_mount", /* 165 = linux_mount */ + "linux_umount", /* 166 = linux_umount */ + "swapon", /* 167 = swapon */ + "linux_swapoff", /* 168 = linux_swapoff */ + "linux_reboot", /* 169 = linux_reboot */ + "linux_sethostname", /* 170 = linux_sethostname */ + "linux_setdomainname", /* 171 = linux_setdomainname */ + "linux_iopl", /* 172 = linux_iopl */ + "#173", /* 173 = ioperm */ + "linux_create_module", /* 174 = linux_create_module */ + "linux_init_module", /* 175 = linux_init_module */ + "linux_delete_module", /* 176 = linux_delete_module */ + "linux_get_kernel_syms", /* 177 = linux_get_kernel_syms */ + "linux_query_module", /* 178 = linux_query_module */ + "linux_quotactl", /* 179 = linux_quotactl */ + "linux_nfsservctl", /* 180 = linux_nfsservctl */ + "linux_getpmsg", /* 181 = linux_getpmsg */ + "linux_putpmsg", /* 182 = linux_putpmsg */ + "linux_afs_syscall", /* 183 = linux_afs_syscall */ + "linux_tuxcall", /* 184 = linux_tuxcall */ + "linux_security", /* 185 = linux_security */ + "linux_gettid", /* 186 = linux_gettid */ + "#187", /* 187 = linux_readahead */ + "linux_setxattr", /* 188 = linux_setxattr */ + "linux_lsetxattr", /* 189 = linux_lsetxattr */ + "linux_fsetxattr", /* 190 = linux_fsetxattr */ + "linux_getxattr", /* 191 = linux_getxattr */ + "linux_lgetxattr", /* 192 = linux_lgetxattr */ + "linux_fgetxattr", /* 193 = linux_fgetxattr */ + "linux_listxattr", /* 194 = linux_listxattr */ + "linux_llistxattr", /* 195 = linux_llistxattr */ + "linux_flistxattr", /* 196 = linux_flistxattr */ + "linux_removexattr", /* 197 = linux_removexattr */ + "linux_lremovexattr", /* 198 = linux_lremovexattr */ + "linux_fremovexattr", /* 199 = linux_fremovexattr */ + "linux_tkill", /* 200 = linux_tkill */ + "linux_time", /* 201 = linux_time */ + "linux_sys_futex", /* 202 = linux_sys_futex */ + "linux_sched_setaffinity", /* 203 = linux_sched_setaffinity */ + "linux_sched_getaffinity", /* 204 = linux_sched_getaffinity */ + "linux_set_thread_area", /* 205 = linux_set_thread_area */ + "#206", /* 206 = linux_io_setup */ + "#207", /* 207 = linux_io_destroy */ + "#208", /* 208 = linux_io_getevents */ + "#209", /* 209 = inux_io_submit */ + "#210", /* 210 = linux_io_cancel */ + "#211", /* 211 = linux_get_thread_area */ + "linux_lookup_dcookie", /* 212 = linux_lookup_dcookie */ + "linux_epoll_create", /* 213 = linux_epoll_create */ + "linux_epoll_ctl_old", /* 214 = linux_epoll_ctl_old */ + "linux_epoll_wait_old", /* 215 = linux_epoll_wait_old */ + "linux_remap_file_pages", /* 216 = linux_remap_file_pages */ + "linux_getdents64", /* 217 = linux_getdents64 */ + "linux_set_tid_address", /* 218 = linux_set_tid_address */ + "#219", /* 219 = restart_syscall */ + "linux_semtimedop", /* 220 = linux_semtimedop */ + "linux_fadvise64", /* 221 = linux_fadvise64 */ + "linux_timer_create", /* 222 = linux_timer_create */ + "linux_timer_settime", /* 223 = linux_timer_settime */ + "linux_timer_gettime", /* 224 = linux_timer_gettime */ + "linux_timer_getoverrun", /* 225 = linux_timer_getoverrun */ + "linux_timer_delete", /* 226 = linux_timer_delete */ + "linux_clock_settime", /* 227 = linux_clock_settime */ + "linux_clock_gettime", /* 228 = linux_clock_gettime */ + "linux_clock_getres", /* 229 = linux_clock_getres */ + "linux_clock_nanosleep", /* 230 = linux_clock_nanosleep */ + "linux_exit_group", /* 231 = linux_exit_group */ + "linux_epoll_wait", /* 232 = linux_epoll_wait */ + "linux_epoll_ctl", /* 233 = linux_epoll_ctl */ + "linux_tgkill", /* 234 = linux_tgkill */ + "linux_utimes", /* 235 = linux_utimes */ + "#236", /* 236 = vserver */ + "linux_mbind", /* 237 = linux_mbind */ + "linux_set_mempolicy", /* 238 = linux_set_mempolicy */ + "linux_get_mempolicy", /* 239 = linux_get_mempolicy */ + "linux_mq_open", /* 240 = linux_mq_open */ + "linux_mq_unlink", /* 241 = linux_mq_unlink */ + "linux_mq_timedsend", /* 242 = linux_mq_timedsend */ + "linux_mq_timedreceive", /* 243 = linux_mq_timedreceive */ + "linux_mq_notify", /* 244 = linux_mq_notify */ + "linux_mq_getsetattr", /* 245 = linux_mq_getsetattr */ + "linux_kexec_load", /* 246 = linux_kexec_load */ + "linux_waitid", /* 247 = linux_waitid */ + "linux_add_key", /* 248 = linux_add_key */ + "linux_request_key", /* 249 = linux_request_key */ + "linux_keyctl", /* 250 = linux_keyctl */ + "linux_ioprio_set", /* 251 = linux_ioprio_set */ + "linux_ioprio_get", /* 252 = linux_ioprio_get */ + "linux_inotify_init", /* 253 = linux_inotify_init */ + "linux_inotify_add_watch", /* 254 = linux_inotify_add_watch */ + "linux_inotify_rm_watch", /* 255 = linux_inotify_rm_watch */ + "linux_migrate_pages", /* 256 = linux_migrate_pages */ + "linux_openat", /* 257 = linux_openat */ + "linux_mkdirat", /* 258 = linux_mkdirat */ + "linux_mknodat", /* 259 = linux_mknodat */ + "linux_fchownat", /* 260 = linux_fchownat */ + "linux_futimesat", /* 261 = linux_futimesat */ + "linux_newfstatat", /* 262 = linux_newfstatat */ + "linux_unlinkat", /* 263 = linux_unlinkat */ + "linux_renameat", /* 264 = linux_renameat */ + "linux_linkat", /* 265 = linux_linkat */ + "linux_symlinkat", /* 266 = linux_symlinkat */ + "linux_readlinkat", /* 267 = linux_readlinkat */ + "linux_fchmodat", /* 268 = linux_fchmodat */ + "linux_faccessat", /* 269 = linux_faccessat */ + "linux_pselect6", /* 270 = linux_pselect6 */ + "linux_ppoll", /* 271 = linux_ppoll */ + "linux_unshare", /* 272 = linux_unshare */ + "linux_set_robust_list", /* 273 = linux_set_robust_list */ + "linux_get_robust_list", /* 274 = linux_get_robust_list */ + "linux_splice", /* 275 = linux_splice */ + "linux_tee", /* 276 = linux_tee */ + "linux_sync_file_range", /* 277 = linux_sync_file_range */ + "linux_vmsplice", /* 278 = linux_vmsplice */ + "linux_move_pages", /* 279 = linux_move_pages */ + "linux_utimensat", /* 280 = linux_utimensat */ + "linux_epoll_pwait", /* 281 = linux_epoll_pwait */ + "linux_signalfd", /* 282 = linux_signalfd */ + "linux_timerfd", /* 283 = linux_timerfd */ + "linux_eventfd", /* 284 = linux_eventfd */ + "linux_fallocate", /* 285 = linux_fallocate */ + "linux_timerfd_settime", /* 286 = linux_timerfd_settime */ + "linux_timerfd_gettime", /* 287 = linux_timerfd_gettime */ + "linux_accept4", /* 288 = linux_accept4 */ + "linux_signalfd4", /* 289 = linux_signalfd4 */ + "linux_eventfd2", /* 290 = linux_eventfd2 */ + "linux_epoll_create1", /* 291 = linux_epoll_create1 */ + "linux_dup3", /* 292 = linux_dup3 */ + "linux_pipe2", /* 293 = linux_pipe2 */ + "linux_inotify_init1", /* 294 = linux_inotify_init1 */ + "linux_preadv", /* 295 = linux_preadv */ + "linux_pwritev", /* 296 = linux_pwritev */ + "linux_rt_tsigqueueinfo", /* 297 = linux_rt_tsigqueueinfo */ + "linux_perf_event_open", /* 298 = linux_perf_event_open */ + "linux_recvmmsg", /* 299 = linux_recvmmsg */ + "linux_fanotify_init", /* 300 = linux_fanotify_init */ + "linux_fanotify_mark", /* 301 = linux_fanotify_mark */ + "linux_prlimit64", /* 302 = linux_prlimit64 */ + "linux_name_to_handle_at", /* 303 = linux_name_to_handle_at */ + "linux_open_by_handle_at", /* 304 = linux_open_by_handle_at */ + "linux_clock_adjtime", /* 305 = linux_clock_adjtime */ + "linux_syncfs", /* 306 = linux_syncfs */ + "linux_sendmmsg", /* 307 = linux_sendmmsg */ + "linux_setns", /* 308 = linux_setns */ + "linux_process_vm_readv", /* 309 = linux_process_vm_readv */ + "linux_process_vm_writev", /* 310 = linux_process_vm_writev */ + "linux_kcmp", /* 311 = linux_kcmp */ + "linux_finit_module", /* 312 = linux_finit_module */ + "#313", /* 313 = nosys */ +}; diff --git a/sys/amd64/linux/linux_sysent.c b/sys/amd64/linux/linux_sysent.c new file mode 100644 index 0000000..97a15cc --- /dev/null +++ b/sys/amd64/linux/linux_sysent.c @@ -0,0 +1,335 @@ +/* + * System call switch table. + * + * DO NOT EDIT-- this file is automatically generated. + * $FreeBSD$ + * created from FreeBSD: stable/10/sys/amd64/linux/syscalls.master 293592 2016-01-09 17:54:37Z dchagin + */ + +#include <sys/param.h> +#include <sys/sysent.h> +#include <sys/sysproto.h> +#include <compat/linux/linux_sysproto.h> +#include <amd64/linux/linux.h> +#include <amd64/linux/linux_proto.h> + +#define AS(name) (sizeof(struct name) / sizeof(register_t)) + +/* The casts are bogus but will do for now. */ +struct sysent linux_sysent[] = { +#define nosys linux_nosys + { AS(read_args), (sy_call_t *)sys_read, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 0 = read */ + { AS(write_args), (sy_call_t *)sys_write, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 1 = write */ + { AS(linux_open_args), (sy_call_t *)linux_open, AUE_OPEN_RWTC, NULL, 0, 0, 0, SY_THR_STATIC }, /* 2 = linux_open */ + { AS(close_args), (sy_call_t *)sys_close, AUE_CLOSE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 3 = close */ + { AS(linux_newstat_args), (sy_call_t *)linux_newstat, AUE_STAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 4 = linux_newstat */ + { AS(linux_newfstat_args), (sy_call_t *)linux_newfstat, AUE_FSTAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 5 = linux_newfstat */ + { AS(linux_newlstat_args), (sy_call_t *)linux_newlstat, AUE_LSTAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 6 = linux_newlstat */ + { AS(poll_args), (sy_call_t *)sys_poll, AUE_POLL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 7 = poll */ + { AS(linux_lseek_args), (sy_call_t *)linux_lseek, AUE_LSEEK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 8 = linux_lseek */ + { AS(linux_mmap2_args), (sy_call_t *)linux_mmap2, AUE_MMAP, NULL, 0, 0, 0, SY_THR_STATIC }, /* 9 = linux_mmap2 */ + { AS(linux_mprotect_args), (sy_call_t *)linux_mprotect, AUE_MPROTECT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 10 = linux_mprotect */ + { AS(munmap_args), (sy_call_t *)sys_munmap, AUE_MUNMAP, NULL, 0, 0, 0, SY_THR_STATIC }, /* 11 = munmap */ + { AS(linux_brk_args), (sy_call_t *)linux_brk, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 12 = linux_brk */ + { AS(linux_rt_sigaction_args), (sy_call_t *)linux_rt_sigaction, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 13 = linux_rt_sigaction */ + { AS(linux_rt_sigprocmask_args), (sy_call_t *)linux_rt_sigprocmask, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 14 = linux_rt_sigprocmask */ + { AS(linux_rt_sigreturn_args), (sy_call_t *)linux_rt_sigreturn, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 15 = linux_rt_sigreturn */ + { AS(linux_ioctl_args), (sy_call_t *)linux_ioctl, AUE_IOCTL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 16 = linux_ioctl */ + { AS(linux_pread_args), (sy_call_t *)linux_pread, AUE_PREAD, NULL, 0, 0, 0, SY_THR_STATIC }, /* 17 = linux_pread */ + { AS(linux_pwrite_args), (sy_call_t *)linux_pwrite, AUE_PWRITE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 18 = linux_pwrite */ + { AS(readv_args), (sy_call_t *)sys_readv, AUE_READV, NULL, 0, 0, 0, SY_THR_STATIC }, /* 19 = readv */ + { AS(writev_args), (sy_call_t *)sys_writev, AUE_WRITEV, NULL, 0, 0, 0, SY_THR_STATIC }, /* 20 = writev */ + { AS(linux_access_args), (sy_call_t *)linux_access, AUE_ACCESS, NULL, 0, 0, 0, SY_THR_STATIC }, /* 21 = linux_access */ + { AS(linux_pipe_args), (sy_call_t *)linux_pipe, AUE_PIPE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 22 = linux_pipe */ + { AS(linux_select_args), (sy_call_t *)linux_select, AUE_SELECT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 23 = linux_select */ + { 0, (sy_call_t *)sys_sched_yield, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 24 = sched_yield */ + { AS(linux_mremap_args), (sy_call_t *)linux_mremap, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 25 = linux_mremap */ + { AS(linux_msync_args), (sy_call_t *)linux_msync, AUE_MSYNC, NULL, 0, 0, 0, SY_THR_STATIC }, /* 26 = linux_msync */ + { AS(linux_mincore_args), (sy_call_t *)linux_mincore, AUE_MINCORE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 27 = linux_mincore */ + { AS(madvise_args), (sy_call_t *)sys_madvise, AUE_MADVISE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 28 = madvise */ + { AS(linux_shmget_args), (sy_call_t *)linux_shmget, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 29 = linux_shmget */ + { AS(linux_shmat_args), (sy_call_t *)linux_shmat, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 30 = linux_shmat */ + { AS(linux_shmctl_args), (sy_call_t *)linux_shmctl, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 31 = linux_shmctl */ + { AS(dup_args), (sy_call_t *)sys_dup, AUE_DUP, NULL, 0, 0, 0, SY_THR_STATIC }, /* 32 = dup */ + { AS(dup2_args), (sy_call_t *)sys_dup2, AUE_DUP2, NULL, 0, 0, 0, SY_THR_STATIC }, /* 33 = dup2 */ + { 0, (sy_call_t *)linux_pause, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 34 = linux_pause */ + { AS(linux_nanosleep_args), (sy_call_t *)linux_nanosleep, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 35 = linux_nanosleep */ + { AS(linux_getitimer_args), (sy_call_t *)linux_getitimer, AUE_GETITIMER, NULL, 0, 0, 0, SY_THR_STATIC }, /* 36 = linux_getitimer */ + { AS(linux_alarm_args), (sy_call_t *)linux_alarm, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 37 = linux_alarm */ + { AS(linux_setitimer_args), (sy_call_t *)linux_setitimer, AUE_SETITIMER, NULL, 0, 0, 0, SY_THR_STATIC }, /* 38 = linux_setitimer */ + { 0, (sy_call_t *)linux_getpid, AUE_GETPID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 39 = linux_getpid */ + { AS(linux_sendfile_args), (sy_call_t *)linux_sendfile, AUE_SENDFILE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 40 = linux_sendfile */ + { AS(linux_socket_args), (sy_call_t *)linux_socket, AUE_SOCKET, NULL, 0, 0, 0, SY_THR_STATIC }, /* 41 = linux_socket */ + { AS(linux_connect_args), (sy_call_t *)linux_connect, AUE_CONNECT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 42 = linux_connect */ + { AS(linux_accept_args), (sy_call_t *)linux_accept, AUE_ACCEPT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 43 = linux_accept */ + { AS(linux_sendto_args), (sy_call_t *)linux_sendto, AUE_SENDTO, NULL, 0, 0, 0, SY_THR_STATIC }, /* 44 = linux_sendto */ + { AS(linux_recvfrom_args), (sy_call_t *)linux_recvfrom, AUE_RECVFROM, NULL, 0, 0, 0, SY_THR_STATIC }, /* 45 = linux_recvfrom */ + { AS(linux_sendmsg_args), (sy_call_t *)linux_sendmsg, AUE_SENDMSG, NULL, 0, 0, 0, SY_THR_STATIC }, /* 46 = linux_sendmsg */ + { AS(linux_recvmsg_args), (sy_call_t *)linux_recvmsg, AUE_RECVMSG, NULL, 0, 0, 0, SY_THR_STATIC }, /* 47 = linux_recvmsg */ + { AS(linux_shutdown_args), (sy_call_t *)linux_shutdown, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 48 = linux_shutdown */ + { AS(linux_bind_args), (sy_call_t *)linux_bind, AUE_BIND, NULL, 0, 0, 0, SY_THR_STATIC }, /* 49 = linux_bind */ + { AS(linux_listen_args), (sy_call_t *)linux_listen, AUE_LISTEN, NULL, 0, 0, 0, SY_THR_STATIC }, /* 50 = linux_listen */ + { AS(linux_getsockname_args), (sy_call_t *)linux_getsockname, AUE_GETSOCKNAME, NULL, 0, 0, 0, SY_THR_STATIC }, /* 51 = linux_getsockname */ + { AS(linux_getpeername_args), (sy_call_t *)linux_getpeername, AUE_GETPEERNAME, NULL, 0, 0, 0, SY_THR_STATIC }, /* 52 = linux_getpeername */ + { AS(linux_socketpair_args), (sy_call_t *)linux_socketpair, AUE_SOCKETPAIR, NULL, 0, 0, 0, SY_THR_STATIC }, /* 53 = linux_socketpair */ + { AS(linux_setsockopt_args), (sy_call_t *)linux_setsockopt, AUE_SETSOCKOPT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 54 = linux_setsockopt */ + { AS(linux_getsockopt_args), (sy_call_t *)linux_getsockopt, AUE_GETSOCKOPT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 55 = linux_getsockopt */ + { AS(linux_clone_args), (sy_call_t *)linux_clone, AUE_RFORK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 56 = linux_clone */ + { 0, (sy_call_t *)linux_fork, AUE_FORK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 57 = linux_fork */ + { 0, (sy_call_t *)linux_vfork, AUE_VFORK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 58 = linux_vfork */ + { AS(linux_execve_args), (sy_call_t *)linux_execve, AUE_EXECVE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 59 = linux_execve */ + { AS(linux_exit_args), (sy_call_t *)linux_exit, AUE_EXIT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 60 = linux_exit */ + { AS(linux_wait4_args), (sy_call_t *)linux_wait4, AUE_WAIT4, NULL, 0, 0, 0, SY_THR_STATIC }, /* 61 = linux_wait4 */ + { AS(linux_kill_args), (sy_call_t *)linux_kill, AUE_KILL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 62 = linux_kill */ + { AS(linux_newuname_args), (sy_call_t *)linux_newuname, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 63 = linux_newuname */ + { AS(linux_semget_args), (sy_call_t *)linux_semget, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 64 = linux_semget */ + { AS(linux_semop_args), (sy_call_t *)linux_semop, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 65 = linux_semop */ + { AS(linux_semctl_args), (sy_call_t *)linux_semctl, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 66 = linux_semctl */ + { AS(linux_shmdt_args), (sy_call_t *)linux_shmdt, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 67 = linux_shmdt */ + { AS(linux_msgget_args), (sy_call_t *)linux_msgget, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 68 = linux_msgget */ + { AS(linux_msgsnd_args), (sy_call_t *)linux_msgsnd, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 69 = linux_msgsnd */ + { AS(linux_msgrcv_args), (sy_call_t *)linux_msgrcv, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 70 = linux_msgrcv */ + { AS(linux_msgctl_args), (sy_call_t *)linux_msgctl, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 71 = linux_msgctl */ + { AS(linux_fcntl_args), (sy_call_t *)linux_fcntl, AUE_FCNTL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 72 = linux_fcntl */ + { AS(flock_args), (sy_call_t *)sys_flock, AUE_FLOCK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 73 = flock */ + { AS(fsync_args), (sy_call_t *)sys_fsync, AUE_FSYNC, NULL, 0, 0, 0, SY_THR_STATIC }, /* 74 = fsync */ + { AS(linux_fdatasync_args), (sy_call_t *)linux_fdatasync, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 75 = linux_fdatasync */ + { AS(linux_truncate_args), (sy_call_t *)linux_truncate, AUE_TRUNCATE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 76 = linux_truncate */ + { AS(linux_ftruncate_args), (sy_call_t *)linux_ftruncate, AUE_FTRUNCATE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 77 = linux_ftruncate */ + { AS(linux_getdents_args), (sy_call_t *)linux_getdents, AUE_GETDIRENTRIES, NULL, 0, 0, 0, SY_THR_STATIC }, /* 78 = linux_getdents */ + { AS(linux_getcwd_args), (sy_call_t *)linux_getcwd, AUE_GETCWD, NULL, 0, 0, 0, SY_THR_STATIC }, /* 79 = linux_getcwd */ + { AS(linux_chdir_args), (sy_call_t *)linux_chdir, AUE_CHDIR, NULL, 0, 0, 0, SY_THR_STATIC }, /* 80 = linux_chdir */ + { AS(fchdir_args), (sy_call_t *)sys_fchdir, AUE_FCHDIR, NULL, 0, 0, 0, SY_THR_STATIC }, /* 81 = fchdir */ + { AS(linux_rename_args), (sy_call_t *)linux_rename, AUE_RENAME, NULL, 0, 0, 0, SY_THR_STATIC }, /* 82 = linux_rename */ + { AS(linux_mkdir_args), (sy_call_t *)linux_mkdir, AUE_MKDIR, NULL, 0, 0, 0, SY_THR_STATIC }, /* 83 = linux_mkdir */ + { AS(linux_rmdir_args), (sy_call_t *)linux_rmdir, AUE_RMDIR, NULL, 0, 0, 0, SY_THR_STATIC }, /* 84 = linux_rmdir */ + { AS(linux_creat_args), (sy_call_t *)linux_creat, AUE_CREAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 85 = linux_creat */ + { AS(linux_link_args), (sy_call_t *)linux_link, AUE_LINK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 86 = linux_link */ + { AS(linux_unlink_args), (sy_call_t *)linux_unlink, AUE_UNLINK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 87 = linux_unlink */ + { AS(linux_symlink_args), (sy_call_t *)linux_symlink, AUE_SYMLINK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 88 = linux_symlink */ + { AS(linux_readlink_args), (sy_call_t *)linux_readlink, AUE_READLINK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 89 = linux_readlink */ + { AS(linux_chmod_args), (sy_call_t *)linux_chmod, AUE_CHMOD, NULL, 0, 0, 0, SY_THR_STATIC }, /* 90 = linux_chmod */ + { AS(fchmod_args), (sy_call_t *)sys_fchmod, AUE_FCHMOD, NULL, 0, 0, 0, SY_THR_STATIC }, /* 91 = fchmod */ + { AS(linux_chown_args), (sy_call_t *)linux_chown, AUE_LCHOWN, NULL, 0, 0, 0, SY_THR_STATIC }, /* 92 = linux_chown */ + { AS(fchown_args), (sy_call_t *)sys_fchown, AUE_FCHOWN, NULL, 0, 0, 0, SY_THR_STATIC }, /* 93 = fchown */ + { AS(linux_lchown_args), (sy_call_t *)linux_lchown, AUE_LCHOWN, NULL, 0, 0, 0, SY_THR_STATIC }, /* 94 = linux_lchown */ + { AS(umask_args), (sy_call_t *)sys_umask, AUE_UMASK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 95 = umask */ + { AS(gettimeofday_args), (sy_call_t *)sys_gettimeofday, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 96 = gettimeofday */ + { AS(linux_getrlimit_args), (sy_call_t *)linux_getrlimit, AUE_GETRLIMIT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 97 = linux_getrlimit */ + { AS(getrusage_args), (sy_call_t *)sys_getrusage, AUE_GETRUSAGE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 98 = getrusage */ + { AS(linux_sysinfo_args), (sy_call_t *)linux_sysinfo, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 99 = linux_sysinfo */ + { AS(linux_times_args), (sy_call_t *)linux_times, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 100 = linux_times */ + { AS(linux_ptrace_args), (sy_call_t *)linux_ptrace, AUE_PTRACE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 101 = linux_ptrace */ + { 0, (sy_call_t *)linux_getuid, AUE_GETUID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 102 = linux_getuid */ + { AS(linux_syslog_args), (sy_call_t *)linux_syslog, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 103 = linux_syslog */ + { 0, (sy_call_t *)linux_getgid, AUE_GETGID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 104 = linux_getgid */ + { AS(setuid_args), (sy_call_t *)sys_setuid, AUE_SETUID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 105 = setuid */ + { AS(setgid_args), (sy_call_t *)sys_setgid, AUE_SETGID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 106 = setgid */ + { 0, (sy_call_t *)sys_geteuid, AUE_GETEUID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 107 = geteuid */ + { 0, (sy_call_t *)sys_getegid, AUE_GETEGID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 108 = getegid */ + { AS(setpgid_args), (sy_call_t *)sys_setpgid, AUE_SETPGRP, NULL, 0, 0, 0, SY_THR_STATIC }, /* 109 = setpgid */ + { 0, (sy_call_t *)linux_getppid, AUE_GETPPID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 110 = linux_getppid */ + { 0, (sy_call_t *)sys_getpgrp, AUE_GETPGRP, NULL, 0, 0, 0, SY_THR_STATIC }, /* 111 = getpgrp */ + { 0, (sy_call_t *)sys_setsid, AUE_SETSID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 112 = setsid */ + { AS(setreuid_args), (sy_call_t *)sys_setreuid, AUE_SETREUID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 113 = setreuid */ + { AS(setregid_args), (sy_call_t *)sys_setregid, AUE_SETREGID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 114 = setregid */ + { AS(linux_getgroups_args), (sy_call_t *)linux_getgroups, AUE_GETGROUPS, NULL, 0, 0, 0, SY_THR_STATIC }, /* 115 = linux_getgroups */ + { AS(linux_setgroups_args), (sy_call_t *)linux_setgroups, AUE_SETGROUPS, NULL, 0, 0, 0, SY_THR_STATIC }, /* 116 = linux_setgroups */ + { AS(setresuid_args), (sy_call_t *)sys_setresuid, AUE_SETRESUID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 117 = setresuid */ + { AS(getresuid_args), (sy_call_t *)sys_getresuid, AUE_GETRESUID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 118 = getresuid */ + { AS(setresgid_args), (sy_call_t *)sys_setresgid, AUE_SETRESGID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 119 = setresgid */ + { AS(getresgid_args), (sy_call_t *)sys_getresgid, AUE_GETRESGID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 120 = getresgid */ + { AS(getpgid_args), (sy_call_t *)sys_getpgid, AUE_GETPGID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 121 = getpgid */ + { AS(linux_setfsuid_args), (sy_call_t *)linux_setfsuid, AUE_SETFSUID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 122 = linux_setfsuid */ + { AS(linux_setfsgid_args), (sy_call_t *)linux_setfsgid, AUE_SETFSGID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 123 = linux_setfsgid */ + { AS(linux_getsid_args), (sy_call_t *)linux_getsid, AUE_GETSID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 124 = linux_getsid */ + { AS(linux_capget_args), (sy_call_t *)linux_capget, AUE_CAPGET, NULL, 0, 0, 0, SY_THR_STATIC }, /* 125 = linux_capget */ + { AS(linux_capset_args), (sy_call_t *)linux_capset, AUE_CAPSET, NULL, 0, 0, 0, SY_THR_STATIC }, /* 126 = linux_capset */ + { AS(linux_rt_sigpending_args), (sy_call_t *)linux_rt_sigpending, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 127 = linux_rt_sigpending */ + { AS(linux_rt_sigtimedwait_args), (sy_call_t *)linux_rt_sigtimedwait, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 128 = linux_rt_sigtimedwait */ + { AS(linux_rt_sigqueueinfo_args), (sy_call_t *)linux_rt_sigqueueinfo, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 129 = linux_rt_sigqueueinfo */ + { AS(linux_rt_sigsuspend_args), (sy_call_t *)linux_rt_sigsuspend, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 130 = linux_rt_sigsuspend */ + { AS(linux_sigaltstack_args), (sy_call_t *)linux_sigaltstack, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 131 = linux_sigaltstack */ + { AS(linux_utime_args), (sy_call_t *)linux_utime, AUE_UTIME, NULL, 0, 0, 0, SY_THR_STATIC }, /* 132 = linux_utime */ + { AS(linux_mknod_args), (sy_call_t *)linux_mknod, AUE_MKNOD, NULL, 0, 0, 0, SY_THR_STATIC }, /* 133 = linux_mknod */ + { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 134 = uselib */ + { AS(linux_personality_args), (sy_call_t *)linux_personality, AUE_PERSONALITY, NULL, 0, 0, 0, SY_THR_STATIC }, /* 135 = linux_personality */ + { AS(linux_ustat_args), (sy_call_t *)linux_ustat, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 136 = linux_ustat */ + { AS(linux_statfs_args), (sy_call_t *)linux_statfs, AUE_STATFS, NULL, 0, 0, 0, SY_THR_STATIC }, /* 137 = linux_statfs */ + { AS(linux_fstatfs_args), (sy_call_t *)linux_fstatfs, AUE_FSTATFS, NULL, 0, 0, 0, SY_THR_STATIC }, /* 138 = linux_fstatfs */ + { AS(linux_sysfs_args), (sy_call_t *)linux_sysfs, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 139 = linux_sysfs */ + { AS(linux_getpriority_args), (sy_call_t *)linux_getpriority, AUE_GETPRIORITY, NULL, 0, 0, 0, SY_THR_STATIC }, /* 140 = linux_getpriority */ + { AS(setpriority_args), (sy_call_t *)sys_setpriority, AUE_SETPRIORITY, NULL, 0, 0, 0, SY_THR_STATIC }, /* 141 = setpriority */ + { AS(linux_sched_setparam_args), (sy_call_t *)linux_sched_setparam, AUE_SCHED_SETPARAM, NULL, 0, 0, 0, SY_THR_STATIC }, /* 142 = linux_sched_setparam */ + { AS(linux_sched_getparam_args), (sy_call_t *)linux_sched_getparam, AUE_SCHED_GETPARAM, NULL, 0, 0, 0, SY_THR_STATIC }, /* 143 = linux_sched_getparam */ + { AS(linux_sched_setscheduler_args), (sy_call_t *)linux_sched_setscheduler, AUE_SCHED_SETSCHEDULER, NULL, 0, 0, 0, SY_THR_STATIC }, /* 144 = linux_sched_setscheduler */ + { AS(linux_sched_getscheduler_args), (sy_call_t *)linux_sched_getscheduler, AUE_SCHED_GETSCHEDULER, NULL, 0, 0, 0, SY_THR_STATIC }, /* 145 = linux_sched_getscheduler */ + { AS(linux_sched_get_priority_max_args), (sy_call_t *)linux_sched_get_priority_max, AUE_SCHED_GET_PRIORITY_MAX, NULL, 0, 0, 0, SY_THR_STATIC }, /* 146 = linux_sched_get_priority_max */ + { AS(linux_sched_get_priority_min_args), (sy_call_t *)linux_sched_get_priority_min, AUE_SCHED_GET_PRIORITY_MIN, NULL, 0, 0, 0, SY_THR_STATIC }, /* 147 = linux_sched_get_priority_min */ + { AS(linux_sched_rr_get_interval_args), (sy_call_t *)linux_sched_rr_get_interval, AUE_SCHED_RR_GET_INTERVAL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 148 = linux_sched_rr_get_interval */ + { AS(mlock_args), (sy_call_t *)sys_mlock, AUE_MLOCK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 149 = mlock */ + { AS(munlock_args), (sy_call_t *)sys_munlock, AUE_MUNLOCK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 150 = munlock */ + { AS(mlockall_args), (sy_call_t *)sys_mlockall, AUE_MLOCKALL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 151 = mlockall */ + { 0, (sy_call_t *)sys_munlockall, AUE_MUNLOCKALL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 152 = munlockall */ + { 0, (sy_call_t *)linux_vhangup, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 153 = linux_vhangup */ + { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 154 = modify_ldt */ + { 0, (sy_call_t *)linux_pivot_root, AUE_PIVOT_ROOT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 155 = linux_pivot_root */ + { AS(linux_sysctl_args), (sy_call_t *)linux_sysctl, AUE_SYSCTL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 156 = linux_sysctl */ + { AS(linux_prctl_args), (sy_call_t *)linux_prctl, AUE_PRCTL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 157 = linux_prctl */ + { AS(linux_arch_prctl_args), (sy_call_t *)linux_arch_prctl, AUE_PRCTL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 158 = linux_arch_prctl */ + { 0, (sy_call_t *)linux_adjtimex, AUE_ADJTIME, NULL, 0, 0, 0, SY_THR_STATIC }, /* 159 = linux_adjtimex */ + { AS(linux_setrlimit_args), (sy_call_t *)linux_setrlimit, AUE_SETRLIMIT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 160 = linux_setrlimit */ + { AS(chroot_args), (sy_call_t *)sys_chroot, AUE_CHROOT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 161 = chroot */ + { 0, (sy_call_t *)sys_sync, AUE_SYNC, NULL, 0, 0, 0, SY_THR_STATIC }, /* 162 = sync */ + { AS(acct_args), (sy_call_t *)sys_acct, AUE_ACCT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 163 = acct */ + { AS(settimeofday_args), (sy_call_t *)sys_settimeofday, AUE_SETTIMEOFDAY, NULL, 0, 0, 0, SY_THR_STATIC }, /* 164 = settimeofday */ + { AS(linux_mount_args), (sy_call_t *)linux_mount, AUE_MOUNT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 165 = linux_mount */ + { AS(linux_umount_args), (sy_call_t *)linux_umount, AUE_UMOUNT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 166 = linux_umount */ + { AS(swapon_args), (sy_call_t *)sys_swapon, AUE_SWAPON, NULL, 0, 0, 0, SY_THR_STATIC }, /* 167 = swapon */ + { 0, (sy_call_t *)linux_swapoff, AUE_SWAPOFF, NULL, 0, 0, 0, SY_THR_STATIC }, /* 168 = linux_swapoff */ + { AS(linux_reboot_args), (sy_call_t *)linux_reboot, AUE_REBOOT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 169 = linux_reboot */ + { AS(linux_sethostname_args), (sy_call_t *)linux_sethostname, AUE_SYSCTL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 170 = linux_sethostname */ + { AS(linux_setdomainname_args), (sy_call_t *)linux_setdomainname, AUE_SYSCTL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 171 = linux_setdomainname */ + { AS(linux_iopl_args), (sy_call_t *)linux_iopl, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 172 = linux_iopl */ + { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 173 = ioperm */ + { 0, (sy_call_t *)linux_create_module, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 174 = linux_create_module */ + { 0, (sy_call_t *)linux_init_module, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 175 = linux_init_module */ + { 0, (sy_call_t *)linux_delete_module, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 176 = linux_delete_module */ + { 0, (sy_call_t *)linux_get_kernel_syms, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 177 = linux_get_kernel_syms */ + { 0, (sy_call_t *)linux_query_module, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 178 = linux_query_module */ + { 0, (sy_call_t *)linux_quotactl, AUE_QUOTACTL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 179 = linux_quotactl */ + { 0, (sy_call_t *)linux_nfsservctl, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 180 = linux_nfsservctl */ + { 0, (sy_call_t *)linux_getpmsg, AUE_GETPMSG, NULL, 0, 0, 0, SY_THR_STATIC }, /* 181 = linux_getpmsg */ + { 0, (sy_call_t *)linux_putpmsg, AUE_PUTPMSG, NULL, 0, 0, 0, SY_THR_STATIC }, /* 182 = linux_putpmsg */ + { 0, (sy_call_t *)linux_afs_syscall, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 183 = linux_afs_syscall */ + { 0, (sy_call_t *)linux_tuxcall, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 184 = linux_tuxcall */ + { 0, (sy_call_t *)linux_security, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 185 = linux_security */ + { 0, (sy_call_t *)linux_gettid, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 186 = linux_gettid */ + { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 187 = linux_readahead */ + { 0, (sy_call_t *)linux_setxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 188 = linux_setxattr */ + { 0, (sy_call_t *)linux_lsetxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 189 = linux_lsetxattr */ + { 0, (sy_call_t *)linux_fsetxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 190 = linux_fsetxattr */ + { 0, (sy_call_t *)linux_getxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 191 = linux_getxattr */ + { 0, (sy_call_t *)linux_lgetxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 192 = linux_lgetxattr */ + { 0, (sy_call_t *)linux_fgetxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 193 = linux_fgetxattr */ + { 0, (sy_call_t *)linux_listxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 194 = linux_listxattr */ + { 0, (sy_call_t *)linux_llistxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 195 = linux_llistxattr */ + { 0, (sy_call_t *)linux_flistxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 196 = linux_flistxattr */ + { 0, (sy_call_t *)linux_removexattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 197 = linux_removexattr */ + { 0, (sy_call_t *)linux_lremovexattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 198 = linux_lremovexattr */ + { 0, (sy_call_t *)linux_fremovexattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 199 = linux_fremovexattr */ + { AS(linux_tkill_args), (sy_call_t *)linux_tkill, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 200 = linux_tkill */ + { AS(linux_time_args), (sy_call_t *)linux_time, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 201 = linux_time */ + { AS(linux_sys_futex_args), (sy_call_t *)linux_sys_futex, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 202 = linux_sys_futex */ + { AS(linux_sched_setaffinity_args), (sy_call_t *)linux_sched_setaffinity, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 203 = linux_sched_setaffinity */ + { AS(linux_sched_getaffinity_args), (sy_call_t *)linux_sched_getaffinity, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 204 = linux_sched_getaffinity */ + { 0, (sy_call_t *)linux_set_thread_area, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 205 = linux_set_thread_area */ + { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 206 = linux_io_setup */ + { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 207 = linux_io_destroy */ + { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 208 = linux_io_getevents */ + { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 209 = inux_io_submit */ + { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 210 = linux_io_cancel */ + { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 211 = linux_get_thread_area */ + { 0, (sy_call_t *)linux_lookup_dcookie, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 212 = linux_lookup_dcookie */ + { AS(linux_epoll_create_args), (sy_call_t *)linux_epoll_create, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 213 = linux_epoll_create */ + { 0, (sy_call_t *)linux_epoll_ctl_old, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 214 = linux_epoll_ctl_old */ + { 0, (sy_call_t *)linux_epoll_wait_old, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 215 = linux_epoll_wait_old */ + { 0, (sy_call_t *)linux_remap_file_pages, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 216 = linux_remap_file_pages */ + { AS(linux_getdents64_args), (sy_call_t *)linux_getdents64, AUE_GETDIRENTRIES, NULL, 0, 0, 0, SY_THR_STATIC }, /* 217 = linux_getdents64 */ + { AS(linux_set_tid_address_args), (sy_call_t *)linux_set_tid_address, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 218 = linux_set_tid_address */ + { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 219 = restart_syscall */ + { 0, (sy_call_t *)linux_semtimedop, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 220 = linux_semtimedop */ + { AS(linux_fadvise64_args), (sy_call_t *)linux_fadvise64, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 221 = linux_fadvise64 */ + { AS(linux_timer_create_args), (sy_call_t *)linux_timer_create, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 222 = linux_timer_create */ + { AS(linux_timer_settime_args), (sy_call_t *)linux_timer_settime, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 223 = linux_timer_settime */ + { AS(linux_timer_gettime_args), (sy_call_t *)linux_timer_gettime, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 224 = linux_timer_gettime */ + { AS(linux_timer_getoverrun_args), (sy_call_t *)linux_timer_getoverrun, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 225 = linux_timer_getoverrun */ + { AS(linux_timer_delete_args), (sy_call_t *)linux_timer_delete, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 226 = linux_timer_delete */ + { AS(linux_clock_settime_args), (sy_call_t *)linux_clock_settime, AUE_CLOCK_SETTIME, NULL, 0, 0, 0, SY_THR_STATIC }, /* 227 = linux_clock_settime */ + { AS(linux_clock_gettime_args), (sy_call_t *)linux_clock_gettime, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 228 = linux_clock_gettime */ + { AS(linux_clock_getres_args), (sy_call_t *)linux_clock_getres, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 229 = linux_clock_getres */ + { AS(linux_clock_nanosleep_args), (sy_call_t *)linux_clock_nanosleep, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 230 = linux_clock_nanosleep */ + { AS(linux_exit_group_args), (sy_call_t *)linux_exit_group, AUE_EXIT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 231 = linux_exit_group */ + { AS(linux_epoll_wait_args), (sy_call_t *)linux_epoll_wait, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 232 = linux_epoll_wait */ + { AS(linux_epoll_ctl_args), (sy_call_t *)linux_epoll_ctl, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 233 = linux_epoll_ctl */ + { AS(linux_tgkill_args), (sy_call_t *)linux_tgkill, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 234 = linux_tgkill */ + { AS(linux_utimes_args), (sy_call_t *)linux_utimes, AUE_UTIMES, NULL, 0, 0, 0, SY_THR_STATIC }, /* 235 = linux_utimes */ + { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 236 = vserver */ + { 0, (sy_call_t *)linux_mbind, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 237 = linux_mbind */ + { 0, (sy_call_t *)linux_set_mempolicy, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 238 = linux_set_mempolicy */ + { 0, (sy_call_t *)linux_get_mempolicy, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 239 = linux_get_mempolicy */ + { 0, (sy_call_t *)linux_mq_open, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 240 = linux_mq_open */ + { 0, (sy_call_t *)linux_mq_unlink, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 241 = linux_mq_unlink */ + { 0, (sy_call_t *)linux_mq_timedsend, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 242 = linux_mq_timedsend */ + { 0, (sy_call_t *)linux_mq_timedreceive, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 243 = linux_mq_timedreceive */ + { 0, (sy_call_t *)linux_mq_notify, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 244 = linux_mq_notify */ + { 0, (sy_call_t *)linux_mq_getsetattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 245 = linux_mq_getsetattr */ + { 0, (sy_call_t *)linux_kexec_load, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 246 = linux_kexec_load */ + { AS(linux_waitid_args), (sy_call_t *)linux_waitid, AUE_WAIT6, NULL, 0, 0, 0, SY_THR_STATIC }, /* 247 = linux_waitid */ + { 0, (sy_call_t *)linux_add_key, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 248 = linux_add_key */ + { 0, (sy_call_t *)linux_request_key, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 249 = linux_request_key */ + { 0, (sy_call_t *)linux_keyctl, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 250 = linux_keyctl */ + { 0, (sy_call_t *)linux_ioprio_set, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 251 = linux_ioprio_set */ + { 0, (sy_call_t *)linux_ioprio_get, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 252 = linux_ioprio_get */ + { 0, (sy_call_t *)linux_inotify_init, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 253 = linux_inotify_init */ + { 0, (sy_call_t *)linux_inotify_add_watch, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 254 = linux_inotify_add_watch */ + { 0, (sy_call_t *)linux_inotify_rm_watch, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 255 = linux_inotify_rm_watch */ + { 0, (sy_call_t *)linux_migrate_pages, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 256 = linux_migrate_pages */ + { AS(linux_openat_args), (sy_call_t *)linux_openat, AUE_OPEN_RWTC, NULL, 0, 0, 0, SY_THR_STATIC }, /* 257 = linux_openat */ + { AS(linux_mkdirat_args), (sy_call_t *)linux_mkdirat, AUE_MKDIRAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 258 = linux_mkdirat */ + { AS(linux_mknodat_args), (sy_call_t *)linux_mknodat, AUE_MKNODAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 259 = linux_mknodat */ + { AS(linux_fchownat_args), (sy_call_t *)linux_fchownat, AUE_FCHOWNAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 260 = linux_fchownat */ + { AS(linux_futimesat_args), (sy_call_t *)linux_futimesat, AUE_FUTIMESAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 261 = linux_futimesat */ + { AS(linux_newfstatat_args), (sy_call_t *)linux_newfstatat, AUE_FSTATAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 262 = linux_newfstatat */ + { AS(linux_unlinkat_args), (sy_call_t *)linux_unlinkat, AUE_UNLINKAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 263 = linux_unlinkat */ + { AS(linux_renameat_args), (sy_call_t *)linux_renameat, AUE_RENAMEAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 264 = linux_renameat */ + { AS(linux_linkat_args), (sy_call_t *)linux_linkat, AUE_LINKAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 265 = linux_linkat */ + { AS(linux_symlinkat_args), (sy_call_t *)linux_symlinkat, AUE_SYMLINKAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 266 = linux_symlinkat */ + { AS(linux_readlinkat_args), (sy_call_t *)linux_readlinkat, AUE_READLINKAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 267 = linux_readlinkat */ + { AS(linux_fchmodat_args), (sy_call_t *)linux_fchmodat, AUE_FCHMODAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 268 = linux_fchmodat */ + { AS(linux_faccessat_args), (sy_call_t *)linux_faccessat, AUE_FACCESSAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 269 = linux_faccessat */ + { AS(linux_pselect6_args), (sy_call_t *)linux_pselect6, AUE_SELECT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 270 = linux_pselect6 */ + { AS(linux_ppoll_args), (sy_call_t *)linux_ppoll, AUE_POLL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 271 = linux_ppoll */ + { 0, (sy_call_t *)linux_unshare, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 272 = linux_unshare */ + { AS(linux_set_robust_list_args), (sy_call_t *)linux_set_robust_list, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 273 = linux_set_robust_list */ + { AS(linux_get_robust_list_args), (sy_call_t *)linux_get_robust_list, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 274 = linux_get_robust_list */ + { 0, (sy_call_t *)linux_splice, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 275 = linux_splice */ + { 0, (sy_call_t *)linux_tee, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 276 = linux_tee */ + { 0, (sy_call_t *)linux_sync_file_range, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 277 = linux_sync_file_range */ + { 0, (sy_call_t *)linux_vmsplice, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 278 = linux_vmsplice */ + { 0, (sy_call_t *)linux_move_pages, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 279 = linux_move_pages */ + { AS(linux_utimensat_args), (sy_call_t *)linux_utimensat, AUE_FUTIMESAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 280 = linux_utimensat */ + { AS(linux_epoll_pwait_args), (sy_call_t *)linux_epoll_pwait, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 281 = linux_epoll_pwait */ + { 0, (sy_call_t *)linux_signalfd, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 282 = linux_signalfd */ + { 0, (sy_call_t *)linux_timerfd, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 283 = linux_timerfd */ + { AS(linux_eventfd_args), (sy_call_t *)linux_eventfd, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 284 = linux_eventfd */ + { AS(linux_fallocate_args), (sy_call_t *)linux_fallocate, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 285 = linux_fallocate */ + { 0, (sy_call_t *)linux_timerfd_settime, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 286 = linux_timerfd_settime */ + { 0, (sy_call_t *)linux_timerfd_gettime, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 287 = linux_timerfd_gettime */ + { AS(linux_accept4_args), (sy_call_t *)linux_accept4, AUE_ACCEPT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 288 = linux_accept4 */ + { 0, (sy_call_t *)linux_signalfd4, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 289 = linux_signalfd4 */ + { AS(linux_eventfd2_args), (sy_call_t *)linux_eventfd2, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 290 = linux_eventfd2 */ + { AS(linux_epoll_create1_args), (sy_call_t *)linux_epoll_create1, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 291 = linux_epoll_create1 */ + { AS(linux_dup3_args), (sy_call_t *)linux_dup3, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 292 = linux_dup3 */ + { AS(linux_pipe2_args), (sy_call_t *)linux_pipe2, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 293 = linux_pipe2 */ + { 0, (sy_call_t *)linux_inotify_init1, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 294 = linux_inotify_init1 */ + { 0, (sy_call_t *)linux_preadv, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 295 = linux_preadv */ + { 0, (sy_call_t *)linux_pwritev, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 296 = linux_pwritev */ + { 0, (sy_call_t *)linux_rt_tsigqueueinfo, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 297 = linux_rt_tsigqueueinfo */ + { 0, (sy_call_t *)linux_perf_event_open, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 298 = linux_perf_event_open */ + { AS(linux_recvmmsg_args), (sy_call_t *)linux_recvmmsg, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 299 = linux_recvmmsg */ + { 0, (sy_call_t *)linux_fanotify_init, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 300 = linux_fanotify_init */ + { 0, (sy_call_t *)linux_fanotify_mark, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 301 = linux_fanotify_mark */ + { AS(linux_prlimit64_args), (sy_call_t *)linux_prlimit64, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 302 = linux_prlimit64 */ + { 0, (sy_call_t *)linux_name_to_handle_at, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 303 = linux_name_to_handle_at */ + { 0, (sy_call_t *)linux_open_by_handle_at, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 304 = linux_open_by_handle_at */ + { 0, (sy_call_t *)linux_clock_adjtime, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 305 = linux_clock_adjtime */ + { AS(linux_syncfs_args), (sy_call_t *)linux_syncfs, AUE_SYNC, NULL, 0, 0, 0, SY_THR_STATIC }, /* 306 = linux_syncfs */ + { AS(linux_sendmmsg_args), (sy_call_t *)linux_sendmmsg, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 307 = linux_sendmmsg */ + { 0, (sy_call_t *)linux_setns, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 308 = linux_setns */ + { 0, (sy_call_t *)linux_process_vm_readv, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 309 = linux_process_vm_readv */ + { 0, (sy_call_t *)linux_process_vm_writev, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 310 = linux_process_vm_writev */ + { 0, (sy_call_t *)linux_kcmp, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 311 = linux_kcmp */ + { 0, (sy_call_t *)linux_finit_module, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 312 = linux_finit_module */ + { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 313 = nosys */ +}; diff --git a/sys/amd64/linux/linux_systrace_args.c b/sys/amd64/linux/linux_systrace_args.c new file mode 100644 index 0000000..529e768 --- /dev/null +++ b/sys/amd64/linux/linux_systrace_args.c @@ -0,0 +1,6885 @@ +/* + * System call argument to DTrace register array converstion. + * + * DO NOT EDIT-- this file is automatically generated. + * $FreeBSD$ + * This file is part of the DTrace syscall provider. + */ + +static void +systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) +{ + int64_t *iarg = (int64_t *) uarg; + switch (sysnum) { +#define nosys linux_nosys + /* read */ + case 0: { + struct read_args *p = params; + iarg[0] = p->fd; /* int */ + uarg[1] = (intptr_t) p->buf; /* char * */ + uarg[2] = p->nbyte; /* u_int */ + *n_args = 3; + break; + } + /* write */ + case 1: { + struct write_args *p = params; + iarg[0] = p->fd; /* int */ + uarg[1] = (intptr_t) p->buf; /* char * */ + uarg[2] = p->nbyte; /* u_int */ + *n_args = 3; + break; + } + /* linux_open */ + case 2: { + struct linux_open_args *p = params; + uarg[0] = (intptr_t) p->path; /* char * */ + iarg[1] = p->flags; /* l_int */ + iarg[2] = p->mode; /* l_int */ + *n_args = 3; + break; + } + /* close */ + case 3: { + struct close_args *p = params; + iarg[0] = p->fd; /* int */ + *n_args = 1; + break; + } + /* linux_newstat */ + case 4: { + struct linux_newstat_args *p = params; + uarg[0] = (intptr_t) p->path; /* char * */ + uarg[1] = (intptr_t) p->buf; /* struct l_newstat * */ + *n_args = 2; + break; + } + /* linux_newfstat */ + case 5: { + struct linux_newfstat_args *p = params; + iarg[0] = p->fd; /* l_uint */ + uarg[1] = (intptr_t) p->buf; /* struct l_newstat * */ + *n_args = 2; + break; + } + /* linux_newlstat */ + case 6: { + struct linux_newlstat_args *p = params; + uarg[0] = (intptr_t) p->path; /* char * */ + uarg[1] = (intptr_t) p->buf; /* struct l_newstat * */ + *n_args = 2; + break; + } + /* poll */ + case 7: { + struct poll_args *p = params; + iarg[0] = p->*; /* struct pollfd */ + uarg[1] = p->nfds; /* unsigned int */ + iarg[2] = p->timeout; /* int */ + *n_args = 3; + break; + } + /* linux_lseek */ + case 8: { + struct linux_lseek_args *p = params; + iarg[0] = p->fdes; /* l_uint */ + iarg[1] = p->off; /* l_off_t */ + iarg[2] = p->whence; /* l_int */ + *n_args = 3; + break; + } + /* linux_mmap2 */ + case 9: { + struct linux_mmap2_args *p = params; + iarg[0] = p->addr; /* l_ulong */ + iarg[1] = p->len; /* l_ulong */ + iarg[2] = p->prot; /* l_ulong */ + iarg[3] = p->flags; /* l_ulong */ + iarg[4] = p->fd; /* l_ulong */ + iarg[5] = p->pgoff; /* l_ulong */ + *n_args = 6; + break; + } + /* linux_mprotect */ + case 10: { + struct linux_mprotect_args *p = params; + uarg[0] = (intptr_t) p->addr; /* caddr_t */ + iarg[1] = p->len; /* int */ + iarg[2] = p->prot; /* int */ + *n_args = 3; + break; + } + /* munmap */ + case 11: { + struct munmap_args *p = params; + uarg[0] = (intptr_t) p->addr; /* caddr_t */ + iarg[1] = p->len; /* int */ + *n_args = 2; + break; + } + /* linux_brk */ + case 12: { + struct linux_brk_args *p = params; + iarg[0] = p->dsend; /* l_ulong */ + *n_args = 1; + break; + } + /* linux_rt_sigaction */ + case 13: { + struct linux_rt_sigaction_args *p = params; + iarg[0] = p->sig; /* l_int */ + uarg[1] = (intptr_t) p->act; /* l_sigaction_t * */ + uarg[2] = (intptr_t) p->oact; /* l_sigaction_t * */ + iarg[3] = p->sigsetsize; /* l_size_t */ + *n_args = 4; + break; + } + /* linux_rt_sigprocmask */ + case 14: { + struct linux_rt_sigprocmask_args *p = params; + iarg[0] = p->how; /* l_int */ + uarg[1] = (intptr_t) p->mask; /* l_sigset_t * */ + uarg[2] = (intptr_t) p->omask; /* l_sigset_t * */ + iarg[3] = p->sigsetsize; /* l_size_t */ + *n_args = 4; + break; + } + /* linux_rt_sigreturn */ + case 15: { + struct linux_rt_sigreturn_args *p = params; + uarg[0] = (intptr_t) p->ucp; /* struct l_ucontext * */ + *n_args = 1; + break; + } + /* linux_ioctl */ + case 16: { + struct linux_ioctl_args *p = params; + iarg[0] = p->fd; /* l_uint */ + iarg[1] = p->cmd; /* l_uint */ + uarg[2] = p->arg; /* uintptr_t */ + *n_args = 3; + break; + } + /* linux_pread */ + case 17: { + struct linux_pread_args *p = params; + iarg[0] = p->fd; /* l_uint */ + uarg[1] = (intptr_t) p->buf; /* char * */ + iarg[2] = p->nbyte; /* l_size_t */ + iarg[3] = p->offset; /* l_loff_t */ + *n_args = 4; + break; + } + /* linux_pwrite */ + case 18: { + struct linux_pwrite_args *p = params; + iarg[0] = p->fd; /* l_uint */ + uarg[1] = (intptr_t) p->buf; /* char * */ + iarg[2] = p->nbyte; /* l_size_t */ + iarg[3] = p->offset; /* l_loff_t */ + *n_args = 4; + break; + } + /* readv */ + case 19: { + struct readv_args *p = params; + iarg[0] = p->fd; /* int */ + uarg[1] = (intptr_t) p->iovp; /* struct iovec * */ + uarg[2] = p->iovcnt; /* u_int */ + *n_args = 3; + break; + } + /* writev */ + case 20: { + struct writev_args *p = params; + iarg[0] = p->fd; /* int */ + uarg[1] = (intptr_t) p->iovp; /* struct iovec * */ + uarg[2] = p->iovcnt; /* u_int */ + *n_args = 3; + break; + } + /* linux_access */ + case 21: { + struct linux_access_args *p = params; + uarg[0] = (intptr_t) p->path; /* char * */ + iarg[1] = p->amode; /* l_int */ + *n_args = 2; + break; + } + /* linux_pipe */ + case 22: { + struct linux_pipe_args *p = params; + uarg[0] = (intptr_t) p->pipefds; /* l_ulong * */ + *n_args = 1; + break; + } + /* linux_select */ + case 23: { + struct linux_select_args *p = params; + iarg[0] = p->nfds; /* l_int */ + uarg[1] = (intptr_t) p->readfds; /* l_fd_set * */ + uarg[2] = (intptr_t) p->writefds; /* l_fd_set * */ + uarg[3] = (intptr_t) p->exceptfds; /* l_fd_set * */ + uarg[4] = (intptr_t) p->timeout; /* struct l_timeval * */ + *n_args = 5; + break; + } + /* sched_yield */ + case 24: { + *n_args = 0; + break; + } + /* linux_mremap */ + case 25: { + struct linux_mremap_args *p = params; + iarg[0] = p->addr; /* l_ulong */ + iarg[1] = p->old_len; /* l_ulong */ + iarg[2] = p->new_len; /* l_ulong */ + iarg[3] = p->flags; /* l_ulong */ + iarg[4] = p->new_addr; /* l_ulong */ + *n_args = 5; + break; + } + /* linux_msync */ + case 26: { + struct linux_msync_args *p = params; + iarg[0] = p->addr; /* l_ulong */ + iarg[1] = p->len; /* l_size_t */ + iarg[2] = p->fl; /* l_int */ + *n_args = 3; + break; + } + /* linux_mincore */ + case 27: { + struct linux_mincore_args *p = params; + iarg[0] = p->start; /* l_ulong */ + iarg[1] = p->len; /* l_size_t */ + uarg[2] = (intptr_t) p->vec; /* u_char * */ + *n_args = 3; + break; + } + /* madvise */ + case 28: { + struct madvise_args *p = params; + uarg[0] = (intptr_t) p->addr; /* void * */ + uarg[1] = p->len; /* size_t */ + iarg[2] = p->behav; /* int */ + *n_args = 3; + break; + } + /* linux_shmget */ + case 29: { + struct linux_shmget_args *p = params; + iarg[0] = p->key; /* l_key_t */ + iarg[1] = p->size; /* l_size_t */ + iarg[2] = p->shmflg; /* l_int */ + *n_args = 3; + break; + } + /* linux_shmat */ + case 30: { + struct linux_shmat_args *p = params; + iarg[0] = p->shmid; /* l_int */ + uarg[1] = (intptr_t) p->shmaddr; /* char * */ + iarg[2] = p->shmflg; /* l_int */ + *n_args = 3; + break; + } + /* linux_shmctl */ + case 31: { + struct linux_shmctl_args *p = params; + iarg[0] = p->shmid; /* l_int */ + iarg[1] = p->cmd; /* l_int */ + uarg[2] = (intptr_t) p->buf; /* struct l_shmid_ds * */ + *n_args = 3; + break; + } + /* dup */ + case 32: { + struct dup_args *p = params; + uarg[0] = p->fd; /* u_int */ + *n_args = 1; + break; + } + /* dup2 */ + case 33: { + struct dup2_args *p = params; + uarg[0] = p->from; /* u_int */ + uarg[1] = p->to; /* u_int */ + *n_args = 2; + break; + } + /* linux_pause */ + case 34: { + *n_args = 0; + break; + } + /* linux_nanosleep */ + case 35: { + struct linux_nanosleep_args *p = params; + uarg[0] = (intptr_t) p->rqtp; /* const struct l_timespec * */ + uarg[1] = (intptr_t) p->rmtp; /* struct l_timespec * */ + *n_args = 2; + break; + } + /* linux_getitimer */ + case 36: { + struct linux_getitimer_args *p = params; + iarg[0] = p->which; /* l_int */ + uarg[1] = (intptr_t) p->itv; /* struct l_itimerval * */ + *n_args = 2; + break; + } + /* linux_alarm */ + case 37: { + struct linux_alarm_args *p = params; + iarg[0] = p->secs; /* l_uint */ + *n_args = 1; + break; + } + /* linux_setitimer */ + case 38: { + struct linux_setitimer_args *p = params; + iarg[0] = p->which; /* l_int */ + uarg[1] = (intptr_t) p->itv; /* struct l_itimerval * */ + uarg[2] = (intptr_t) p->oitv; /* struct l_itimerval * */ + *n_args = 3; + break; + } + /* linux_getpid */ + case 39: { + *n_args = 0; + break; + } + /* linux_sendfile */ + case 40: { + struct linux_sendfile_args *p = params; + iarg[0] = p->out; /* int */ + iarg[1] = p->in; /* int */ + uarg[2] = (intptr_t) p->offset; /* l_long * */ + iarg[3] = p->count; /* l_size_t */ + *n_args = 4; + break; + } + /* linux_socket */ + case 41: { + struct linux_socket_args *p = params; + iarg[0] = p->domain; /* l_int */ + iarg[1] = p->type; /* l_int */ + iarg[2] = p->protocol; /* l_int */ + *n_args = 3; + break; + } + /* linux_connect */ + case 42: { + struct linux_connect_args *p = params; + iarg[0] = p->s; /* l_int */ + iarg[1] = p->name; /* l_uintptr_t */ + iarg[2] = p->namelen; /* l_int */ + *n_args = 3; + break; + } + /* linux_accept */ + case 43: { + struct linux_accept_args *p = params; + iarg[0] = p->s; /* l_int */ + iarg[1] = p->addr; /* l_uintptr_t */ + iarg[2] = p->namelen; /* l_uintptr_t */ + *n_args = 3; + break; + } + /* linux_sendto */ + case 44: { + struct linux_sendto_args *p = params; + iarg[0] = p->s; /* l_int */ + iarg[1] = p->msg; /* l_uintptr_t */ + iarg[2] = p->len; /* l_int */ + iarg[3] = p->flags; /* l_int */ + iarg[4] = p->to; /* l_uintptr_t */ + iarg[5] = p->tolen; /* l_int */ + *n_args = 6; + break; + } + /* linux_recvfrom */ + case 45: { + struct linux_recvfrom_args *p = params; + iarg[0] = p->s; /* l_int */ + iarg[1] = p->buf; /* l_uintptr_t */ + iarg[2] = p->len; /* l_size_t */ + iarg[3] = p->flags; /* l_int */ + iarg[4] = p->from; /* l_uintptr_t */ + iarg[5] = p->fromlen; /* l_uintptr_t */ + *n_args = 6; + break; + } + /* linux_sendmsg */ + case 46: { + struct linux_sendmsg_args *p = params; + iarg[0] = p->s; /* l_int */ + iarg[1] = p->msg; /* l_uintptr_t */ + iarg[2] = p->flags; /* l_int */ + *n_args = 3; + break; + } + /* linux_recvmsg */ + case 47: { + struct linux_recvmsg_args *p = params; + iarg[0] = p->s; /* l_int */ + iarg[1] = p->msg; /* l_uintptr_t */ + iarg[2] = p->flags; /* l_int */ + *n_args = 3; + break; + } + /* linux_shutdown */ + case 48: { + struct linux_shutdown_args *p = params; + iarg[0] = p->s; /* l_int */ + iarg[1] = p->how; /* l_int */ + *n_args = 2; + break; + } + /* linux_bind */ + case 49: { + struct linux_bind_args *p = params; + iarg[0] = p->s; /* l_int */ + iarg[1] = p->name; /* l_uintptr_t */ + iarg[2] = p->namelen; /* l_int */ + *n_args = 3; + break; + } + /* linux_listen */ + case 50: { + struct linux_listen_args *p = params; + iarg[0] = p->s; /* l_int */ + iarg[1] = p->backlog; /* l_int */ + *n_args = 2; + break; + } + /* linux_getsockname */ + case 51: { + struct linux_getsockname_args *p = params; + iarg[0] = p->s; /* l_int */ + iarg[1] = p->addr; /* l_uintptr_t */ + iarg[2] = p->namelen; /* l_uintptr_t */ + *n_args = 3; + break; + } + /* linux_getpeername */ + case 52: { + struct linux_getpeername_args *p = params; + iarg[0] = p->s; /* l_int */ + iarg[1] = p->addr; /* l_uintptr_t */ + iarg[2] = p->namelen; /* l_uintptr_t */ + *n_args = 3; + break; + } + /* linux_socketpair */ + case 53: { + struct linux_socketpair_args *p = params; + iarg[0] = p->domain; /* l_int */ + iarg[1] = p->type; /* l_int */ + iarg[2] = p->protocol; /* l_int */ + iarg[3] = p->rsv; /* l_uintptr_t */ + *n_args = 4; + break; + } + /* linux_setsockopt */ + case 54: { + struct linux_setsockopt_args *p = params; + iarg[0] = p->s; /* l_int */ + iarg[1] = p->level; /* l_int */ + iarg[2] = p->optname; /* l_int */ + iarg[3] = p->optval; /* l_uintptr_t */ + iarg[4] = p->optlen; /* l_int */ + *n_args = 5; + break; + } + /* linux_getsockopt */ + case 55: { + struct linux_getsockopt_args *p = params; + iarg[0] = p->s; /* l_int */ + iarg[1] = p->level; /* l_int */ + iarg[2] = p->optname; /* l_int */ + iarg[3] = p->optval; /* l_uintptr_t */ + iarg[4] = p->optlen; /* l_uintptr_t */ + *n_args = 5; + break; + } + /* linux_clone */ + case 56: { + struct linux_clone_args *p = params; + iarg[0] = p->flags; /* l_int */ + uarg[1] = (intptr_t) p->stack; /* void * */ + uarg[2] = (intptr_t) p->parent_tidptr; /* void * */ + uarg[3] = (intptr_t) p->child_tidptr; /* void * */ + uarg[4] = (intptr_t) p->tls; /* void * */ + *n_args = 5; + break; + } + /* linux_fork */ + case 57: { + *n_args = 0; + break; + } + /* linux_vfork */ + case 58: { + *n_args = 0; + break; + } + /* linux_execve */ + case 59: { + struct linux_execve_args *p = params; + uarg[0] = (intptr_t) p->path; /* char * */ + uarg[1] = (intptr_t) p->argp; /* char ** */ + uarg[2] = (intptr_t) p->envp; /* char ** */ + *n_args = 3; + break; + } + /* linux_exit */ + case 60: { + struct linux_exit_args *p = params; + iarg[0] = p->rval; /* int */ + *n_args = 1; + break; + } + /* linux_wait4 */ + case 61: { + struct linux_wait4_args *p = params; + iarg[0] = p->pid; /* l_pid_t */ + uarg[1] = (intptr_t) p->status; /* l_int * */ + iarg[2] = p->options; /* l_int */ + uarg[3] = (intptr_t) p->rusage; /* struct rusage * */ + *n_args = 4; + break; + } + /* linux_kill */ + case 62: { + struct linux_kill_args *p = params; + iarg[0] = p->pid; /* l_int */ + iarg[1] = p->signum; /* l_int */ + *n_args = 2; + break; + } + /* linux_newuname */ + case 63: { + struct linux_newuname_args *p = params; + uarg[0] = (intptr_t) p->buf; /* struct l_new_utsname * */ + *n_args = 1; + break; + } + /* linux_semget */ + case 64: { + struct linux_semget_args *p = params; + iarg[0] = p->key; /* l_key_t */ + iarg[1] = p->nsems; /* l_int */ + iarg[2] = p->semflg; /* l_int */ + *n_args = 3; + break; + } + /* linux_semop */ + case 65: { + struct linux_semop_args *p = params; + iarg[0] = p->semid; /* l_int */ + uarg[1] = (intptr_t) p->tsops; /* struct l_sembuf * */ + iarg[2] = p->nsops; /* l_uint */ + *n_args = 3; + break; + } + /* linux_semctl */ + case 66: { + struct linux_semctl_args *p = params; + iarg[0] = p->semid; /* l_int */ + iarg[1] = p->semnum; /* l_int */ + iarg[2] = p->cmd; /* l_int */ + uarg[3] = p->arg; /* union l_semun */ + *n_args = 4; + break; + } + /* linux_shmdt */ + case 67: { + struct linux_shmdt_args *p = params; + uarg[0] = (intptr_t) p->shmaddr; /* char * */ + *n_args = 1; + break; + } + /* linux_msgget */ + case 68: { + struct linux_msgget_args *p = params; + iarg[0] = p->key; /* l_key_t */ + iarg[1] = p->msgflg; /* l_int */ + *n_args = 2; + break; + } + /* linux_msgsnd */ + case 69: { + struct linux_msgsnd_args *p = params; + iarg[0] = p->msqid; /* l_int */ + uarg[1] = (intptr_t) p->msgp; /* struct l_msgbuf * */ + iarg[2] = p->msgsz; /* l_size_t */ + iarg[3] = p->msgflg; /* l_int */ + *n_args = 4; + break; + } + /* linux_msgrcv */ + case 70: { + struct linux_msgrcv_args *p = params; + iarg[0] = p->msqid; /* l_int */ + uarg[1] = (intptr_t) p->msgp; /* struct l_msgbuf * */ + iarg[2] = p->msgsz; /* l_size_t */ + iarg[3] = p->msgtyp; /* l_long */ + iarg[4] = p->msgflg; /* l_int */ + *n_args = 5; + break; + } + /* linux_msgctl */ + case 71: { + struct linux_msgctl_args *p = params; + iarg[0] = p->msqid; /* l_int */ + iarg[1] = p->cmd; /* l_int */ + uarg[2] = (intptr_t) p->buf; /* struct l_msqid_ds * */ + *n_args = 3; + break; + } + /* linux_fcntl */ + case 72: { + struct linux_fcntl_args *p = params; + iarg[0] = p->fd; /* l_uint */ + iarg[1] = p->cmd; /* l_uint */ + iarg[2] = p->arg; /* l_ulong */ + *n_args = 3; + break; + } + /* flock */ + case 73: { + struct flock_args *p = params; + iarg[0] = p->fd; /* int */ + iarg[1] = p->how; /* int */ + *n_args = 2; + break; + } + /* fsync */ + case 74: { + struct fsync_args *p = params; + iarg[0] = p->fd; /* int */ + *n_args = 1; + break; + } + /* linux_fdatasync */ + case 75: { + struct linux_fdatasync_args *p = params; + iarg[0] = p->fd; /* l_uint */ + *n_args = 1; + break; + } + /* linux_truncate */ + case 76: { + struct linux_truncate_args *p = params; + uarg[0] = (intptr_t) p->path; /* char * */ + iarg[1] = p->length; /* l_ulong */ + *n_args = 2; + break; + } + /* linux_ftruncate */ + case 77: { + struct linux_ftruncate_args *p = params; + iarg[0] = p->fd; /* l_int */ + iarg[1] = p->length; /* l_long */ + *n_args = 2; + break; + } + /* linux_getdents */ + case 78: { + struct linux_getdents_args *p = params; + iarg[0] = p->fd; /* l_uint */ + uarg[1] = (intptr_t) p->dent; /* void * */ + iarg[2] = p->count; /* l_uint */ + *n_args = 3; + break; + } + /* linux_getcwd */ + case 79: { + struct linux_getcwd_args *p = params; + uarg[0] = (intptr_t) p->buf; /* char * */ + iarg[1] = p->bufsize; /* l_ulong */ + *n_args = 2; + break; + } + /* linux_chdir */ + case 80: { + struct linux_chdir_args *p = params; + uarg[0] = (intptr_t) p->path; /* char * */ + *n_args = 1; + break; + } + /* fchdir */ + case 81: { + struct fchdir_args *p = params; + iarg[0] = p->fd; /* int */ + *n_args = 1; + break; + } + /* linux_rename */ + case 82: { + struct linux_rename_args *p = params; + uarg[0] = (intptr_t) p->from; /* char * */ + uarg[1] = (intptr_t) p->to; /* char * */ + *n_args = 2; + break; + } + /* linux_mkdir */ + case 83: { + struct linux_mkdir_args *p = params; + uarg[0] = (intptr_t) p->path; /* char * */ + iarg[1] = p->mode; /* l_int */ + *n_args = 2; + break; + } + /* linux_rmdir */ + case 84: { + struct linux_rmdir_args *p = params; + uarg[0] = (intptr_t) p->path; /* char * */ + *n_args = 1; + break; + } + /* linux_creat */ + case 85: { + struct linux_creat_args *p = params; + uarg[0] = (intptr_t) p->path; /* char * */ + iarg[1] = p->mode; /* l_int */ + *n_args = 2; + break; + } + /* linux_link */ + case 86: { + struct linux_link_args *p = params; + uarg[0] = (intptr_t) p->path; /* char * */ + uarg[1] = (intptr_t) p->to; /* char * */ + *n_args = 2; + break; + } + /* linux_unlink */ + case 87: { + struct linux_unlink_args *p = params; + uarg[0] = (intptr_t) p->path; /* char * */ + *n_args = 1; + break; + } + /* linux_symlink */ + case 88: { + struct linux_symlink_args *p = params; + uarg[0] = (intptr_t) p->path; /* char * */ + uarg[1] = (intptr_t) p->to; /* char * */ + *n_args = 2; + break; + } + /* linux_readlink */ + case 89: { + struct linux_readlink_args *p = params; + uarg[0] = (intptr_t) p->name; /* char * */ + uarg[1] = (intptr_t) p->buf; /* char * */ + iarg[2] = p->count; /* l_int */ + *n_args = 3; + break; + } + /* linux_chmod */ + case 90: { + struct linux_chmod_args *p = params; + uarg[0] = (intptr_t) p->path; /* char * */ + iarg[1] = p->mode; /* l_mode_t */ + *n_args = 2; + break; + } + /* fchmod */ + case 91: { + struct fchmod_args *p = params; + iarg[0] = p->fd; /* int */ + iarg[1] = p->mode; /* int */ + *n_args = 2; + break; + } + /* linux_chown */ + case 92: { + struct linux_chown_args *p = params; + uarg[0] = (intptr_t) p->path; /* char * */ + iarg[1] = p->uid; /* l_uid_t */ + iarg[2] = p->gid; /* l_gid_t */ + *n_args = 3; + break; + } + /* fchown */ + case 93: { + struct fchown_args *p = params; + iarg[0] = p->fd; /* int */ + iarg[1] = p->uid; /* int */ + iarg[2] = p->gid; /* int */ + *n_args = 3; + break; + } + /* linux_lchown */ + case 94: { + struct linux_lchown_args *p = params; + uarg[0] = (intptr_t) p->path; /* char * */ + iarg[1] = p->uid; /* l_uid_t */ + iarg[2] = p->gid; /* l_gid_t */ + *n_args = 3; + break; + } + /* umask */ + case 95: { + struct umask_args *p = params; + iarg[0] = p->newmask; /* int */ + *n_args = 1; + break; + } + /* gettimeofday */ + case 96: { + struct gettimeofday_args *p = params; + uarg[0] = (intptr_t) p->tp; /* struct l_timeval * */ + uarg[1] = (intptr_t) p->tzp; /* struct timezone * */ + *n_args = 2; + break; + } + /* linux_getrlimit */ + case 97: { + struct linux_getrlimit_args *p = params; + iarg[0] = p->resource; /* l_uint */ + uarg[1] = (intptr_t) p->rlim; /* struct l_rlimit * */ + *n_args = 2; + break; + } + /* getrusage */ + case 98: { + struct getrusage_args *p = params; + iarg[0] = p->who; /* int */ + uarg[1] = (intptr_t) p->rusage; /* struct rusage * */ + *n_args = 2; + break; + } + /* linux_sysinfo */ + case 99: { + struct linux_sysinfo_args *p = params; + uarg[0] = (intptr_t) p->info; /* struct l_sysinfo * */ + *n_args = 1; + break; + } + /* linux_times */ + case 100: { + struct linux_times_args *p = params; + uarg[0] = (intptr_t) p->buf; /* struct l_times_argv * */ + *n_args = 1; + break; + } + /* linux_ptrace */ + case 101: { + struct linux_ptrace_args *p = params; + iarg[0] = p->req; /* l_long */ + iarg[1] = p->pid; /* l_long */ + iarg[2] = p->addr; /* l_long */ + iarg[3] = p->data; /* l_long */ + *n_args = 4; + break; + } + /* linux_getuid */ + case 102: { + *n_args = 0; + break; + } + /* linux_syslog */ + case 103: { + struct linux_syslog_args *p = params; + iarg[0] = p->type; /* l_int */ + uarg[1] = (intptr_t) p->buf; /* char * */ + iarg[2] = p->len; /* l_int */ + *n_args = 3; + break; + } + /* linux_getgid */ + case 104: { + *n_args = 0; + break; + } + /* setuid */ + case 105: { + struct setuid_args *p = params; + uarg[0] = p->uid; /* uid_t */ + *n_args = 1; + break; + } + /* setgid */ + case 106: { + struct setgid_args *p = params; + iarg[0] = p->gid; /* gid_t */ + *n_args = 1; + break; + } + /* geteuid */ + case 107: { + *n_args = 0; + break; + } + /* getegid */ + case 108: { + *n_args = 0; + break; + } + /* setpgid */ + case 109: { + struct setpgid_args *p = params; + iarg[0] = p->pid; /* int */ + iarg[1] = p->pgid; /* int */ + *n_args = 2; + break; + } + /* linux_getppid */ + case 110: { + *n_args = 0; + break; + } + /* getpgrp */ + case 111: { + *n_args = 0; + break; + } + /* setsid */ + case 112: { + *n_args = 0; + break; + } + /* setreuid */ + case 113: { + struct setreuid_args *p = params; + uarg[0] = p->ruid; /* uid_t */ + uarg[1] = p->euid; /* uid_t */ + *n_args = 2; + break; + } + /* setregid */ + case 114: { + struct setregid_args *p = params; + iarg[0] = p->rgid; /* gid_t */ + iarg[1] = p->egid; /* gid_t */ + *n_args = 2; + break; + } + /* linux_getgroups */ + case 115: { + struct linux_getgroups_args *p = params; + iarg[0] = p->gidsetsize; /* l_int */ + uarg[1] = (intptr_t) p->grouplist; /* l_gid_t * */ + *n_args = 2; + break; + } + /* linux_setgroups */ + case 116: { + struct linux_setgroups_args *p = params; + iarg[0] = p->gidsetsize; /* l_int */ + uarg[1] = (intptr_t) p->grouplist; /* l_gid_t * */ + *n_args = 2; + break; + } + /* setresuid */ + case 117: { + struct setresuid_args *p = params; + uarg[0] = p->ruid; /* uid_t */ + uarg[1] = p->euid; /* uid_t */ + uarg[2] = p->suid; /* uid_t */ + *n_args = 3; + break; + } + /* getresuid */ + case 118: { + struct getresuid_args *p = params; + uarg[0] = (intptr_t) p->ruid; /* uid_t * */ + uarg[1] = (intptr_t) p->euid; /* uid_t * */ + uarg[2] = (intptr_t) p->suid; /* uid_t * */ + *n_args = 3; + break; + } + /* setresgid */ + case 119: { + struct setresgid_args *p = params; + iarg[0] = p->rgid; /* gid_t */ + iarg[1] = p->egid; /* gid_t */ + iarg[2] = p->sgid; /* gid_t */ + *n_args = 3; + break; + } + /* getresgid */ + case 120: { + struct getresgid_args *p = params; + uarg[0] = (intptr_t) p->rgid; /* gid_t * */ + uarg[1] = (intptr_t) p->egid; /* gid_t * */ + uarg[2] = (intptr_t) p->sgid; /* gid_t * */ + *n_args = 3; + break; + } + /* getpgid */ + case 121: { + struct getpgid_args *p = params; + iarg[0] = p->pid; /* int */ + *n_args = 1; + break; + } + /* linux_setfsuid */ + case 122: { + struct linux_setfsuid_args *p = params; + iarg[0] = p->uid; /* l_uid_t */ + *n_args = 1; + break; + } + /* linux_setfsgid */ + case 123: { + struct linux_setfsgid_args *p = params; + iarg[0] = p->gid; /* l_gid_t */ + *n_args = 1; + break; + } + /* linux_getsid */ + case 124: { + struct linux_getsid_args *p = params; + iarg[0] = p->pid; /* l_pid_t */ + *n_args = 1; + break; + } + /* linux_capget */ + case 125: { + struct linux_capget_args *p = params; + uarg[0] = (intptr_t) p->hdrp; /* struct l_user_cap_header * */ + uarg[1] = (intptr_t) p->datap; /* struct l_user_cap_data * */ + *n_args = 2; + break; + } + /* linux_capset */ + case 126: { + struct linux_capset_args *p = params; + uarg[0] = (intptr_t) p->hdrp; /* struct l_user_cap_header * */ + uarg[1] = (intptr_t) p->datap; /* struct l_user_cap_data * */ + *n_args = 2; + break; + } + /* linux_rt_sigpending */ + case 127: { + struct linux_rt_sigpending_args *p = params; + uarg[0] = (intptr_t) p->set; /* l_sigset_t * */ + iarg[1] = p->sigsetsize; /* l_size_t */ + *n_args = 2; + break; + } + /* linux_rt_sigtimedwait */ + case 128: { + struct linux_rt_sigtimedwait_args *p = params; + uarg[0] = (intptr_t) p->mask; /* l_sigset_t * */ + uarg[1] = (intptr_t) p->ptr; /* l_siginfo_t * */ + uarg[2] = (intptr_t) p->timeout; /* struct l_timeval * */ + iarg[3] = p->sigsetsize; /* l_size_t */ + *n_args = 4; + break; + } + /* linux_rt_sigqueueinfo */ + case 129: { + struct linux_rt_sigqueueinfo_args *p = params; + iarg[0] = p->pid; /* l_pid_t */ + iarg[1] = p->sig; /* l_int */ + uarg[2] = (intptr_t) p->info; /* l_siginfo_t * */ + *n_args = 3; + break; + } + /* linux_rt_sigsuspend */ + case 130: { + struct linux_rt_sigsuspend_args *p = params; + uarg[0] = (intptr_t) p->newset; /* l_sigset_t * */ + iarg[1] = p->sigsetsize; /* l_size_t */ + *n_args = 2; + break; + } + /* linux_sigaltstack */ + case 131: { + struct linux_sigaltstack_args *p = params; + uarg[0] = (intptr_t) p->uss; /* l_stack_t * */ + uarg[1] = (intptr_t) p->uoss; /* l_stack_t * */ + *n_args = 2; + break; + } + /* linux_utime */ + case 132: { + struct linux_utime_args *p = params; + uarg[0] = (intptr_t) p->fname; /* char * */ + uarg[1] = (intptr_t) p->times; /* struct l_utimbuf * */ + *n_args = 2; + break; + } + /* linux_mknod */ + case 133: { + struct linux_mknod_args *p = params; + uarg[0] = (intptr_t) p->path; /* char * */ + iarg[1] = p->mode; /* l_int */ + iarg[2] = p->dev; /* l_dev_t */ + *n_args = 3; + break; + } + /* linux_personality */ + case 135: { + struct linux_personality_args *p = params; + iarg[0] = p->per; /* l_ulong */ + *n_args = 1; + break; + } + /* linux_ustat */ + case 136: { + struct linux_ustat_args *p = params; + iarg[0] = p->dev; /* l_dev_t */ + uarg[1] = (intptr_t) p->ubuf; /* struct l_ustat * */ + *n_args = 2; + break; + } + /* linux_statfs */ + case 137: { + struct linux_statfs_args *p = params; + uarg[0] = (intptr_t) p->path; /* char * */ + uarg[1] = (intptr_t) p->buf; /* struct l_statfs_buf * */ + *n_args = 2; + break; + } + /* linux_fstatfs */ + case 138: { + struct linux_fstatfs_args *p = params; + iarg[0] = p->fd; /* l_uint */ + uarg[1] = (intptr_t) p->buf; /* struct l_statfs_buf * */ + *n_args = 2; + break; + } + /* linux_sysfs */ + case 139: { + struct linux_sysfs_args *p = params; + iarg[0] = p->option; /* l_int */ + iarg[1] = p->arg1; /* l_ulong */ + iarg[2] = p->arg2; /* l_ulong */ + *n_args = 3; + break; + } + /* linux_getpriority */ + case 140: { + struct linux_getpriority_args *p = params; + iarg[0] = p->which; /* int */ + iarg[1] = p->who; /* int */ + *n_args = 2; + break; + } + /* setpriority */ + case 141: { + struct setpriority_args *p = params; + iarg[0] = p->which; /* int */ + iarg[1] = p->who; /* int */ + iarg[2] = p->prio; /* int */ + *n_args = 3; + break; + } + /* linux_sched_setparam */ + case 142: { + struct linux_sched_setparam_args *p = params; + iarg[0] = p->pid; /* l_pid_t */ + uarg[1] = (intptr_t) p->param; /* struct l_sched_param * */ + *n_args = 2; + break; + } + /* linux_sched_getparam */ + case 143: { + struct linux_sched_getparam_args *p = params; + iarg[0] = p->pid; /* l_pid_t */ + uarg[1] = (intptr_t) p->param; /* struct l_sched_param * */ + *n_args = 2; + break; + } + /* linux_sched_setscheduler */ + case 144: { + struct linux_sched_setscheduler_args *p = params; + iarg[0] = p->pid; /* l_pid_t */ + iarg[1] = p->policy; /* l_int */ + uarg[2] = (intptr_t) p->param; /* struct l_sched_param * */ + *n_args = 3; + break; + } + /* linux_sched_getscheduler */ + case 145: { + struct linux_sched_getscheduler_args *p = params; + iarg[0] = p->pid; /* l_pid_t */ + *n_args = 1; + break; + } + /* linux_sched_get_priority_max */ + case 146: { + struct linux_sched_get_priority_max_args *p = params; + iarg[0] = p->policy; /* l_int */ + *n_args = 1; + break; + } + /* linux_sched_get_priority_min */ + case 147: { + struct linux_sched_get_priority_min_args *p = params; + iarg[0] = p->policy; /* l_int */ + *n_args = 1; + break; + } + /* linux_sched_rr_get_interval */ + case 148: { + struct linux_sched_rr_get_interval_args *p = params; + iarg[0] = p->pid; /* l_pid_t */ + uarg[1] = (intptr_t) p->interval; /* struct l_timespec * */ + *n_args = 2; + break; + } + /* mlock */ + case 149: { + struct mlock_args *p = params; + uarg[0] = (intptr_t) p->addr; /* const void * */ + uarg[1] = p->len; /* size_t */ + *n_args = 2; + break; + } + /* munlock */ + case 150: { + struct munlock_args *p = params; + uarg[0] = (intptr_t) p->addr; /* const void * */ + uarg[1] = p->len; /* size_t */ + *n_args = 2; + break; + } + /* mlockall */ + case 151: { + struct mlockall_args *p = params; + iarg[0] = p->how; /* int */ + *n_args = 1; + break; + } + /* munlockall */ + case 152: { + *n_args = 0; + break; + } + /* linux_vhangup */ + case 153: { + *n_args = 0; + break; + } + /* linux_pivot_root */ + case 155: { + *n_args = 0; + break; + } + /* linux_sysctl */ + case 156: { + struct linux_sysctl_args *p = params; + uarg[0] = (intptr_t) p->args; /* struct l___sysctl_args * */ + *n_args = 1; + break; + } + /* linux_prctl */ + case 157: { + struct linux_prctl_args *p = params; + iarg[0] = p->option; /* l_int */ + iarg[1] = p->arg2; /* l_uintptr_t */ + iarg[2] = p->arg3; /* l_uintptr_t */ + iarg[3] = p->arg4; /* l_uintptr_t */ + iarg[4] = p->arg5; /* l_uintptr_t */ + *n_args = 5; + break; + } + /* linux_arch_prctl */ + case 158: { + struct linux_arch_prctl_args *p = params; + iarg[0] = p->code; /* l_int */ + iarg[1] = p->addr; /* l_ulong */ + *n_args = 2; + break; + } + /* linux_adjtimex */ + case 159: { + *n_args = 0; + break; + } + /* linux_setrlimit */ + case 160: { + struct linux_setrlimit_args *p = params; + iarg[0] = p->resource; /* l_uint */ + uarg[1] = (intptr_t) p->rlim; /* struct l_rlimit * */ + *n_args = 2; + break; + } + /* chroot */ + case 161: { + struct chroot_args *p = params; + uarg[0] = (intptr_t) p->path; /* char * */ + *n_args = 1; + break; + } + /* sync */ + case 162: { + *n_args = 0; + break; + } + /* acct */ + case 163: { + struct acct_args *p = params; + uarg[0] = (intptr_t) p->path; /* char * */ + *n_args = 1; + break; + } + /* settimeofday */ + case 164: { + struct settimeofday_args *p = params; + uarg[0] = (intptr_t) p->tp; /* struct l_timeval * */ + uarg[1] = (intptr_t) p->tzp; /* struct timezone * */ + *n_args = 2; + break; + } + /* linux_mount */ + case 165: { + struct linux_mount_args *p = params; + uarg[0] = (intptr_t) p->specialfile; /* char * */ + uarg[1] = (intptr_t) p->dir; /* char * */ + uarg[2] = (intptr_t) p->filesystemtype; /* char * */ + iarg[3] = p->rwflag; /* l_ulong */ + uarg[4] = (intptr_t) p->data; /* void * */ + *n_args = 5; + break; + } + /* linux_umount */ + case 166: { + struct linux_umount_args *p = params; + uarg[0] = (intptr_t) p->path; /* char * */ + iarg[1] = p->flags; /* l_int */ + *n_args = 2; + break; + } + /* swapon */ + case 167: { + struct swapon_args *p = params; + uarg[0] = (intptr_t) p->name; /* char * */ + *n_args = 1; + break; + } + /* linux_swapoff */ + case 168: { + *n_args = 0; + break; + } + /* linux_reboot */ + case 169: { + struct linux_reboot_args *p = params; + iarg[0] = p->magic1; /* l_int */ + iarg[1] = p->magic2; /* l_int */ + iarg[2] = p->cmd; /* l_uint */ + uarg[3] = (intptr_t) p->arg; /* void * */ + *n_args = 4; + break; + } + /* linux_sethostname */ + case 170: { + struct linux_sethostname_args *p = params; + uarg[0] = (intptr_t) p->hostname; /* char * */ + iarg[1] = p->len; /* l_uint */ + *n_args = 2; + break; + } + /* linux_setdomainname */ + case 171: { + struct linux_setdomainname_args *p = params; + uarg[0] = (intptr_t) p->name; /* char * */ + iarg[1] = p->len; /* l_int */ + *n_args = 2; + break; + } + /* linux_iopl */ + case 172: { + struct linux_iopl_args *p = params; + iarg[0] = p->level; /* l_uint */ + *n_args = 1; + break; + } + /* linux_create_module */ + case 174: { + *n_args = 0; + break; + } + /* linux_init_module */ + case 175: { + *n_args = 0; + break; + } + /* linux_delete_module */ + case 176: { + *n_args = 0; + break; + } + /* linux_get_kernel_syms */ + case 177: { + *n_args = 0; + break; + } + /* linux_query_module */ + case 178: { + *n_args = 0; + break; + } + /* linux_quotactl */ + case 179: { + *n_args = 0; + break; + } + /* linux_nfsservctl */ + case 180: { + *n_args = 0; + break; + } + /* linux_getpmsg */ + case 181: { + *n_args = 0; + break; + } + /* linux_putpmsg */ + case 182: { + *n_args = 0; + break; + } + /* linux_afs_syscall */ + case 183: { + *n_args = 0; + break; + } + /* linux_tuxcall */ + case 184: { + *n_args = 0; + break; + } + /* linux_security */ + case 185: { + *n_args = 0; + break; + } + /* linux_gettid */ + case 186: { + *n_args = 0; + break; + } + /* linux_setxattr */ + case 188: { + *n_args = 0; + break; + } + /* linux_lsetxattr */ + case 189: { + *n_args = 0; + break; + } + /* linux_fsetxattr */ + case 190: { + *n_args = 0; + break; + } + /* linux_getxattr */ + case 191: { + *n_args = 0; + break; + } + /* linux_lgetxattr */ + case 192: { + *n_args = 0; + break; + } + /* linux_fgetxattr */ + case 193: { + *n_args = 0; + break; + } + /* linux_listxattr */ + case 194: { + *n_args = 0; + break; + } + /* linux_llistxattr */ + case 195: { + *n_args = 0; + break; + } + /* linux_flistxattr */ + case 196: { + *n_args = 0; + break; + } + /* linux_removexattr */ + case 197: { + *n_args = 0; + break; + } + /* linux_lremovexattr */ + case 198: { + *n_args = 0; + break; + } + /* linux_fremovexattr */ + case 199: { + *n_args = 0; + break; + } + /* linux_tkill */ + case 200: { + struct linux_tkill_args *p = params; + iarg[0] = p->tid; /* int */ + iarg[1] = p->sig; /* int */ + *n_args = 2; + break; + } + /* linux_time */ + case 201: { + struct linux_time_args *p = params; + uarg[0] = (intptr_t) p->tm; /* l_time_t * */ + *n_args = 1; + break; + } + /* linux_sys_futex */ + case 202: { + struct linux_sys_futex_args *p = params; + uarg[0] = (intptr_t) p->uaddr; /* void * */ + iarg[1] = p->op; /* int */ + iarg[2] = p->val; /* int */ + uarg[3] = (intptr_t) p->timeout; /* struct l_timespec * */ + uarg[4] = (intptr_t) p->uaddr2; /* void * */ + iarg[5] = p->val3; /* int */ + *n_args = 6; + break; + } + /* linux_sched_setaffinity */ + case 203: { + struct linux_sched_setaffinity_args *p = params; + iarg[0] = p->pid; /* l_pid_t */ + iarg[1] = p->len; /* l_uint */ + uarg[2] = (intptr_t) p->user_mask_ptr; /* l_ulong * */ + *n_args = 3; + break; + } + /* linux_sched_getaffinity */ + case 204: { + struct linux_sched_getaffinity_args *p = params; + iarg[0] = p->pid; /* l_pid_t */ + iarg[1] = p->len; /* l_uint */ + uarg[2] = (intptr_t) p->user_mask_ptr; /* l_ulong * */ + *n_args = 3; + break; + } + /* linux_set_thread_area */ + case 205: { + *n_args = 0; + break; + } + /* linux_lookup_dcookie */ + case 212: { + *n_args = 0; + break; + } + /* linux_epoll_create */ + case 213: { + struct linux_epoll_create_args *p = params; + iarg[0] = p->size; /* l_int */ + *n_args = 1; + break; + } + /* linux_epoll_ctl_old */ + case 214: { + *n_args = 0; + break; + } + /* linux_epoll_wait_old */ + case 215: { + *n_args = 0; + break; + } + /* linux_remap_file_pages */ + case 216: { + *n_args = 0; + break; + } + /* linux_getdents64 */ + case 217: { + struct linux_getdents64_args *p = params; + iarg[0] = p->fd; /* l_uint */ + uarg[1] = (intptr_t) p->dirent; /* void * */ + iarg[2] = p->count; /* l_uint */ + *n_args = 3; + break; + } + /* linux_set_tid_address */ + case 218: { + struct linux_set_tid_address_args *p = params; + uarg[0] = (intptr_t) p->tidptr; /* int * */ + *n_args = 1; + break; + } + /* linux_semtimedop */ + case 220: { + *n_args = 0; + break; + } + /* linux_fadvise64 */ + case 221: { + struct linux_fadvise64_args *p = params; + iarg[0] = p->fd; /* int */ + iarg[1] = p->offset; /* l_loff_t */ + iarg[2] = p->len; /* l_size_t */ + iarg[3] = p->advice; /* int */ + *n_args = 4; + break; + } + /* linux_timer_create */ + case 222: { + struct linux_timer_create_args *p = params; + iarg[0] = p->clock_id; /* clockid_t */ + uarg[1] = (intptr_t) p->evp; /* struct sigevent * */ + uarg[2] = (intptr_t) p->timerid; /* l_timer_t * */ + *n_args = 3; + break; + } + /* linux_timer_settime */ + case 223: { + struct linux_timer_settime_args *p = params; + iarg[0] = p->timerid; /* l_timer_t */ + iarg[1] = p->flags; /* l_int */ + uarg[2] = (intptr_t) p->new; /* const struct itimerspec * */ + uarg[3] = (intptr_t) p->old; /* struct itimerspec * */ + *n_args = 4; + break; + } + /* linux_timer_gettime */ + case 224: { + struct linux_timer_gettime_args *p = params; + iarg[0] = p->timerid; /* l_timer_t */ + uarg[1] = (intptr_t) p->setting; /* struct itimerspec * */ + *n_args = 2; + break; + } + /* linux_timer_getoverrun */ + case 225: { + struct linux_timer_getoverrun_args *p = params; + iarg[0] = p->timerid; /* l_timer_t */ + *n_args = 1; + break; + } + /* linux_timer_delete */ + case 226: { + struct linux_timer_delete_args *p = params; + iarg[0] = p->timerid; /* l_timer_t */ + *n_args = 1; + break; + } + /* linux_clock_settime */ + case 227: { + struct linux_clock_settime_args *p = params; + iarg[0] = p->which; /* clockid_t */ + uarg[1] = (intptr_t) p->tp; /* struct l_timespec * */ + *n_args = 2; + break; + } + /* linux_clock_gettime */ + case 228: { + struct linux_clock_gettime_args *p = params; + iarg[0] = p->which; /* clockid_t */ + uarg[1] = (intptr_t) p->tp; /* struct l_timespec * */ + *n_args = 2; + break; + } + /* linux_clock_getres */ + case 229: { + struct linux_clock_getres_args *p = params; + iarg[0] = p->which; /* clockid_t */ + uarg[1] = (intptr_t) p->tp; /* struct l_timespec * */ + *n_args = 2; + break; + } + /* linux_clock_nanosleep */ + case 230: { + struct linux_clock_nanosleep_args *p = params; + iarg[0] = p->which; /* clockid_t */ + iarg[1] = p->flags; /* int */ + uarg[2] = (intptr_t) p->rqtp; /* struct l_timespec * */ + uarg[3] = (intptr_t) p->rmtp; /* struct l_timespec * */ + *n_args = 4; + break; + } + /* linux_exit_group */ + case 231: { + struct linux_exit_group_args *p = params; + iarg[0] = p->error_code; /* int */ + *n_args = 1; + break; + } + /* linux_epoll_wait */ + case 232: { + struct linux_epoll_wait_args *p = params; + iarg[0] = p->epfd; /* l_int */ + uarg[1] = (intptr_t) p->events; /* struct epoll_event * */ + iarg[2] = p->maxevents; /* l_int */ + iarg[3] = p->timeout; /* l_int */ + *n_args = 4; + break; + } + /* linux_epoll_ctl */ + case 233: { + struct linux_epoll_ctl_args *p = params; + iarg[0] = p->epfd; /* l_int */ + iarg[1] = p->op; /* l_int */ + iarg[2] = p->fd; /* l_int */ + uarg[3] = (intptr_t) p->event; /* struct epoll_event * */ + *n_args = 4; + break; + } + /* linux_tgkill */ + case 234: { + struct linux_tgkill_args *p = params; + iarg[0] = p->tgid; /* int */ + iarg[1] = p->pid; /* int */ + iarg[2] = p->sig; /* int */ + *n_args = 3; + break; + } + /* linux_utimes */ + case 235: { + struct linux_utimes_args *p = params; + uarg[0] = (intptr_t) p->fname; /* char * */ + uarg[1] = (intptr_t) p->tptr; /* struct l_timeval * */ + *n_args = 2; + break; + } + /* linux_mbind */ + case 237: { + *n_args = 0; + break; + } + /* linux_set_mempolicy */ + case 238: { + *n_args = 0; + break; + } + /* linux_get_mempolicy */ + case 239: { + *n_args = 0; + break; + } + /* linux_mq_open */ + case 240: { + *n_args = 0; + break; + } + /* linux_mq_unlink */ + case 241: { + *n_args = 0; + break; + } + /* linux_mq_timedsend */ + case 242: { + *n_args = 0; + break; + } + /* linux_mq_timedreceive */ + case 243: { + *n_args = 0; + break; + } + /* linux_mq_notify */ + case 244: { + *n_args = 0; + break; + } + /* linux_mq_getsetattr */ + case 245: { + *n_args = 0; + break; + } + /* linux_kexec_load */ + case 246: { + *n_args = 0; + break; + } + /* linux_waitid */ + case 247: { + struct linux_waitid_args *p = params; + iarg[0] = p->idtype; /* int */ + iarg[1] = p->id; /* l_pid_t */ + uarg[2] = (intptr_t) p->info; /* l_siginfo_t * */ + iarg[3] = p->options; /* int */ + uarg[4] = (intptr_t) p->rusage; /* struct rusage * */ + *n_args = 5; + break; + } + /* linux_add_key */ + case 248: { + *n_args = 0; + break; + } + /* linux_request_key */ + case 249: { + *n_args = 0; + break; + } + /* linux_keyctl */ + case 250: { + *n_args = 0; + break; + } + /* linux_ioprio_set */ + case 251: { + *n_args = 0; + break; + } + /* linux_ioprio_get */ + case 252: { + *n_args = 0; + break; + } + /* linux_inotify_init */ + case 253: { + *n_args = 0; + break; + } + /* linux_inotify_add_watch */ + case 254: { + *n_args = 0; + break; + } + /* linux_inotify_rm_watch */ + case 255: { + *n_args = 0; + break; + } + /* linux_migrate_pages */ + case 256: { + *n_args = 0; + break; + } + /* linux_openat */ + case 257: { + struct linux_openat_args *p = params; + iarg[0] = p->dfd; /* l_int */ + uarg[1] = (intptr_t) p->filename; /* const char * */ + iarg[2] = p->flags; /* l_int */ + iarg[3] = p->mode; /* l_int */ + *n_args = 4; + break; + } + /* linux_mkdirat */ + case 258: { + struct linux_mkdirat_args *p = params; + iarg[0] = p->dfd; /* l_int */ + uarg[1] = (intptr_t) p->pathname; /* const char * */ + iarg[2] = p->mode; /* l_int */ + *n_args = 3; + break; + } + /* linux_mknodat */ + case 259: { + struct linux_mknodat_args *p = params; + iarg[0] = p->dfd; /* l_int */ + uarg[1] = (intptr_t) p->filename; /* const char * */ + iarg[2] = p->mode; /* l_int */ + iarg[3] = p->dev; /* l_uint */ + *n_args = 4; + break; + } + /* linux_fchownat */ + case 260: { + struct linux_fchownat_args *p = params; + iarg[0] = p->dfd; /* l_int */ + uarg[1] = (intptr_t) p->filename; /* const char * */ + iarg[2] = p->uid; /* l_uid_t */ + iarg[3] = p->gid; /* l_gid_t */ + iarg[4] = p->flag; /* l_int */ + *n_args = 5; + break; + } + /* linux_futimesat */ + case 261: { + struct linux_futimesat_args *p = params; + iarg[0] = p->dfd; /* l_int */ + uarg[1] = (intptr_t) p->filename; /* char * */ + uarg[2] = (intptr_t) p->utimes; /* struct l_timeval * */ + *n_args = 3; + break; + } + /* linux_newfstatat */ + case 262: { + struct linux_newfstatat_args *p = params; + iarg[0] = p->dfd; /* l_int */ + uarg[1] = (intptr_t) p->pathname; /* char * */ + uarg[2] = (intptr_t) p->statbuf; /* struct l_stat64 * */ + iarg[3] = p->flag; /* l_int */ + *n_args = 4; + break; + } + /* linux_unlinkat */ + case 263: { + struct linux_unlinkat_args *p = params; + iarg[0] = p->dfd; /* l_int */ + uarg[1] = (intptr_t) p->pathname; /* const char * */ + iarg[2] = p->flag; /* l_int */ + *n_args = 3; + break; + } + /* linux_renameat */ + case 264: { + struct linux_renameat_args *p = params; + iarg[0] = p->olddfd; /* l_int */ + uarg[1] = (intptr_t) p->oldname; /* const char * */ + iarg[2] = p->newdfd; /* l_int */ + uarg[3] = (intptr_t) p->newname; /* const char * */ + *n_args = 4; + break; + } + /* linux_linkat */ + case 265: { + struct linux_linkat_args *p = params; + iarg[0] = p->olddfd; /* l_int */ + uarg[1] = (intptr_t) p->oldname; /* const char * */ + iarg[2] = p->newdfd; /* l_int */ + uarg[3] = (intptr_t) p->newname; /* const char * */ + iarg[4] = p->flag; /* l_int */ + *n_args = 5; + break; + } + /* linux_symlinkat */ + case 266: { + struct linux_symlinkat_args *p = params; + uarg[0] = (intptr_t) p->oldname; /* const char * */ + iarg[1] = p->newdfd; /* l_int */ + uarg[2] = (intptr_t) p->newname; /* const char * */ + *n_args = 3; + break; + } + /* linux_readlinkat */ + case 267: { + struct linux_readlinkat_args *p = params; + iarg[0] = p->dfd; /* l_int */ + uarg[1] = (intptr_t) p->path; /* const char * */ + uarg[2] = (intptr_t) p->buf; /* char * */ + iarg[3] = p->bufsiz; /* l_int */ + *n_args = 4; + break; + } + /* linux_fchmodat */ + case 268: { + struct linux_fchmodat_args *p = params; + iarg[0] = p->dfd; /* l_int */ + uarg[1] = (intptr_t) p->filename; /* const char * */ + iarg[2] = p->mode; /* l_mode_t */ + *n_args = 3; + break; + } + /* linux_faccessat */ + case 269: { + struct linux_faccessat_args *p = params; + iarg[0] = p->dfd; /* l_int */ + uarg[1] = (intptr_t) p->filename; /* const char * */ + iarg[2] = p->amode; /* l_int */ + *n_args = 3; + break; + } + /* linux_pselect6 */ + case 270: { + struct linux_pselect6_args *p = params; + iarg[0] = p->nfds; /* l_int */ + uarg[1] = (intptr_t) p->readfds; /* l_fd_set * */ + uarg[2] = (intptr_t) p->writefds; /* l_fd_set * */ + uarg[3] = (intptr_t) p->exceptfds; /* l_fd_set * */ + uarg[4] = (intptr_t) p->tsp; /* struct l_timespec * */ + uarg[5] = (intptr_t) p->sig; /* l_uintptr_t * */ + *n_args = 6; + break; + } + /* linux_ppoll */ + case 271: { + struct linux_ppoll_args *p = params; + uarg[0] = (intptr_t) p->fds; /* struct pollfd * */ + uarg[1] = p->nfds; /* uint32_t */ + uarg[2] = (intptr_t) p->tsp; /* struct l_timespec * */ + uarg[3] = (intptr_t) p->sset; /* l_sigset_t * */ + iarg[4] = p->ssize; /* l_size_t */ + *n_args = 5; + break; + } + /* linux_unshare */ + case 272: { + *n_args = 0; + break; + } + /* linux_set_robust_list */ + case 273: { + struct linux_set_robust_list_args *p = params; + uarg[0] = (intptr_t) p->head; /* struct linux_robust_list_head * */ + iarg[1] = p->len; /* l_size_t */ + *n_args = 2; + break; + } + /* linux_get_robust_list */ + case 274: { + struct linux_get_robust_list_args *p = params; + iarg[0] = p->pid; /* l_int */ + uarg[1] = (intptr_t) p->head; /* struct linux_robust_list_head * */ + uarg[2] = (intptr_t) p->len; /* l_size_t * */ + *n_args = 3; + break; + } + /* linux_splice */ + case 275: { + *n_args = 0; + break; + } + /* linux_tee */ + case 276: { + *n_args = 0; + break; + } + /* linux_sync_file_range */ + case 277: { + *n_args = 0; + break; + } + /* linux_vmsplice */ + case 278: { + *n_args = 0; + break; + } + /* linux_move_pages */ + case 279: { + *n_args = 0; + break; + } + /* linux_utimensat */ + case 280: { + struct linux_utimensat_args *p = params; + iarg[0] = p->dfd; /* l_int */ + uarg[1] = (intptr_t) p->pathname; /* const char * */ + uarg[2] = (intptr_t) p->times; /* const struct l_timespec * */ + iarg[3] = p->flags; /* l_int */ + *n_args = 4; + break; + } + /* linux_epoll_pwait */ + case 281: { + struct linux_epoll_pwait_args *p = params; + iarg[0] = p->epfd; /* l_int */ + uarg[1] = (intptr_t) p->events; /* struct epoll_event * */ + iarg[2] = p->maxevents; /* l_int */ + iarg[3] = p->timeout; /* l_int */ + uarg[4] = (intptr_t) p->mask; /* l_sigset_t * */ + *n_args = 5; + break; + } + /* linux_signalfd */ + case 282: { + *n_args = 0; + break; + } + /* linux_timerfd */ + case 283: { + *n_args = 0; + break; + } + /* linux_eventfd */ + case 284: { + struct linux_eventfd_args *p = params; + iarg[0] = p->initval; /* l_uint */ + *n_args = 1; + break; + } + /* linux_fallocate */ + case 285: { + struct linux_fallocate_args *p = params; + iarg[0] = p->fd; /* l_int */ + iarg[1] = p->mode; /* l_int */ + iarg[2] = p->offset; /* l_loff_t */ + iarg[3] = p->len; /* l_loff_t */ + *n_args = 4; + break; + } + /* linux_timerfd_settime */ + case 286: { + *n_args = 0; + break; + } + /* linux_timerfd_gettime */ + case 287: { + *n_args = 0; + break; + } + /* linux_accept4 */ + case 288: { + struct linux_accept4_args *p = params; + iarg[0] = p->s; /* l_int */ + iarg[1] = p->addr; /* l_uintptr_t */ + iarg[2] = p->namelen; /* l_uintptr_t */ + iarg[3] = p->flags; /* int */ + *n_args = 4; + break; + } + /* linux_signalfd4 */ + case 289: { + *n_args = 0; + break; + } + /* linux_eventfd2 */ + case 290: { + struct linux_eventfd2_args *p = params; + iarg[0] = p->initval; /* l_uint */ + iarg[1] = p->flags; /* l_int */ + *n_args = 2; + break; + } + /* linux_epoll_create1 */ + case 291: { + struct linux_epoll_create1_args *p = params; + iarg[0] = p->flags; /* l_int */ + *n_args = 1; + break; + } + /* linux_dup3 */ + case 292: { + struct linux_dup3_args *p = params; + iarg[0] = p->oldfd; /* l_int */ + iarg[1] = p->newfd; /* l_int */ + iarg[2] = p->flags; /* l_int */ + *n_args = 3; + break; + } + /* linux_pipe2 */ + case 293: { + struct linux_pipe2_args *p = params; + uarg[0] = (intptr_t) p->pipefds; /* l_int * */ + iarg[1] = p->flags; /* l_int */ + *n_args = 2; + break; + } + /* linux_inotify_init1 */ + case 294: { + *n_args = 0; + break; + } + /* linux_preadv */ + case 295: { + *n_args = 0; + break; + } + /* linux_pwritev */ + case 296: { + *n_args = 0; + break; + } + /* linux_rt_tsigqueueinfo */ + case 297: { + *n_args = 0; + break; + } + /* linux_perf_event_open */ + case 298: { + *n_args = 0; + break; + } + /* linux_recvmmsg */ + case 299: { + struct linux_recvmmsg_args *p = params; + iarg[0] = p->s; /* l_int */ + uarg[1] = (intptr_t) p->msg; /* struct l_mmsghdr * */ + iarg[2] = p->vlen; /* l_uint */ + iarg[3] = p->flags; /* l_uint */ + uarg[4] = (intptr_t) p->timeout; /* struct l_timespec * */ + *n_args = 5; + break; + } + /* linux_fanotify_init */ + case 300: { + *n_args = 0; + break; + } + /* linux_fanotify_mark */ + case 301: { + *n_args = 0; + break; + } + /* linux_prlimit64 */ + case 302: { + struct linux_prlimit64_args *p = params; + iarg[0] = p->pid; /* l_pid_t */ + iarg[1] = p->resource; /* l_uint */ + uarg[2] = (intptr_t) p->new; /* struct rlimit * */ + uarg[3] = (intptr_t) p->old; /* struct rlimit * */ + *n_args = 4; + break; + } + /* linux_name_to_handle_at */ + case 303: { + *n_args = 0; + break; + } + /* linux_open_by_handle_at */ + case 304: { + *n_args = 0; + break; + } + /* linux_clock_adjtime */ + case 305: { + *n_args = 0; + break; + } + /* linux_syncfs */ + case 306: { + struct linux_syncfs_args *p = params; + iarg[0] = p->fd; /* l_int */ + *n_args = 1; + break; + } + /* linux_sendmmsg */ + case 307: { + struct linux_sendmmsg_args *p = params; + iarg[0] = p->s; /* l_int */ + uarg[1] = (intptr_t) p->msg; /* struct l_mmsghdr * */ + iarg[2] = p->vlen; /* l_uint */ + iarg[3] = p->flags; /* l_uint */ + *n_args = 4; + break; + } + /* linux_setns */ + case 308: { + *n_args = 0; + break; + } + /* linux_process_vm_readv */ + case 309: { + *n_args = 0; + break; + } + /* linux_process_vm_writev */ + case 310: { + *n_args = 0; + break; + } + /* linux_kcmp */ + case 311: { + *n_args = 0; + break; + } + /* linux_finit_module */ + case 312: { + *n_args = 0; + break; + } + default: + *n_args = 0; + break; + }; +} +static void +systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) +{ + const char *p = NULL; + switch (sysnum) { +#define nosys linux_nosys + /* read */ + case 0: + switch(ndx) { + case 0: + p = "int"; + break; + case 1: + p = "char *"; + break; + case 2: + p = "u_int"; + break; + default: + break; + }; + break; + /* write */ + case 1: + switch(ndx) { + case 0: + p = "int"; + break; + case 1: + p = "char *"; + break; + case 2: + p = "u_int"; + break; + default: + break; + }; + break; + /* linux_open */ + case 2: + switch(ndx) { + case 0: + p = "char *"; + break; + case 1: + p = "l_int"; + break; + case 2: + p = "l_int"; + break; + default: + break; + }; + break; + /* close */ + case 3: + switch(ndx) { + case 0: + p = "int"; + break; + default: + break; + }; + break; + /* linux_newstat */ + case 4: + switch(ndx) { + case 0: + p = "char *"; + break; + case 1: + p = "struct l_newstat *"; + break; + default: + break; + }; + break; + /* linux_newfstat */ + case 5: + switch(ndx) { + case 0: + p = "l_uint"; + break; + case 1: + p = "struct l_newstat *"; + break; + default: + break; + }; + break; + /* linux_newlstat */ + case 6: + switch(ndx) { + case 0: + p = "char *"; + break; + case 1: + p = "struct l_newstat *"; + break; + default: + break; + }; + break; + /* poll */ + case 7: + switch(ndx) { + case 0: + p = "struct pollfd"; + break; + case 1: + p = "unsigned int"; + break; + case 2: + p = "int"; + break; + default: + break; + }; + break; + /* linux_lseek */ + case 8: + switch(ndx) { + case 0: + p = "l_uint"; + break; + case 1: + p = "l_off_t"; + break; + case 2: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_mmap2 */ + case 9: + switch(ndx) { + case 0: + p = "l_ulong"; + break; + case 1: + p = "l_ulong"; + break; + case 2: + p = "l_ulong"; + break; + case 3: + p = "l_ulong"; + break; + case 4: + p = "l_ulong"; + break; + case 5: + p = "l_ulong"; + break; + default: + break; + }; + break; + /* linux_mprotect */ + case 10: + switch(ndx) { + case 0: + p = "caddr_t"; + break; + case 1: + p = "int"; + break; + case 2: + p = "int"; + break; + default: + break; + }; + break; + /* munmap */ + case 11: + switch(ndx) { + case 0: + p = "caddr_t"; + break; + case 1: + p = "int"; + break; + default: + break; + }; + break; + /* linux_brk */ + case 12: + switch(ndx) { + case 0: + p = "l_ulong"; + break; + default: + break; + }; + break; + /* linux_rt_sigaction */ + case 13: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_sigaction_t *"; + break; + case 2: + p = "l_sigaction_t *"; + break; + case 3: + p = "l_size_t"; + break; + default: + break; + }; + break; + /* linux_rt_sigprocmask */ + case 14: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_sigset_t *"; + break; + case 2: + p = "l_sigset_t *"; + break; + case 3: + p = "l_size_t"; + break; + default: + break; + }; + break; + /* linux_rt_sigreturn */ + case 15: + switch(ndx) { + case 0: + p = "struct l_ucontext *"; + break; + default: + break; + }; + break; + /* linux_ioctl */ + case 16: + switch(ndx) { + case 0: + p = "l_uint"; + break; + case 1: + p = "l_uint"; + break; + case 2: + p = "uintptr_t"; + break; + default: + break; + }; + break; + /* linux_pread */ + case 17: + switch(ndx) { + case 0: + p = "l_uint"; + break; + case 1: + p = "char *"; + break; + case 2: + p = "l_size_t"; + break; + case 3: + p = "l_loff_t"; + break; + default: + break; + }; + break; + /* linux_pwrite */ + case 18: + switch(ndx) { + case 0: + p = "l_uint"; + break; + case 1: + p = "char *"; + break; + case 2: + p = "l_size_t"; + break; + case 3: + p = "l_loff_t"; + break; + default: + break; + }; + break; + /* readv */ + case 19: + switch(ndx) { + case 0: + p = "int"; + break; + case 1: + p = "struct iovec *"; + break; + case 2: + p = "u_int"; + break; + default: + break; + }; + break; + /* writev */ + case 20: + switch(ndx) { + case 0: + p = "int"; + break; + case 1: + p = "struct iovec *"; + break; + case 2: + p = "u_int"; + break; + default: + break; + }; + break; + /* linux_access */ + case 21: + switch(ndx) { + case 0: + p = "char *"; + break; + case 1: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_pipe */ + case 22: + switch(ndx) { + case 0: + p = "l_ulong *"; + break; + default: + break; + }; + break; + /* linux_select */ + case 23: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_fd_set *"; + break; + case 2: + p = "l_fd_set *"; + break; + case 3: + p = "l_fd_set *"; + break; + case 4: + p = "struct l_timeval *"; + break; + default: + break; + }; + break; + /* sched_yield */ + case 24: + break; + /* linux_mremap */ + case 25: + switch(ndx) { + case 0: + p = "l_ulong"; + break; + case 1: + p = "l_ulong"; + break; + case 2: + p = "l_ulong"; + break; + case 3: + p = "l_ulong"; + break; + case 4: + p = "l_ulong"; + break; + default: + break; + }; + break; + /* linux_msync */ + case 26: + switch(ndx) { + case 0: + p = "l_ulong"; + break; + case 1: + p = "l_size_t"; + break; + case 2: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_mincore */ + case 27: + switch(ndx) { + case 0: + p = "l_ulong"; + break; + case 1: + p = "l_size_t"; + break; + case 2: + p = "u_char *"; + break; + default: + break; + }; + break; + /* madvise */ + case 28: + switch(ndx) { + case 0: + p = "void *"; + break; + case 1: + p = "size_t"; + break; + case 2: + p = "int"; + break; + default: + break; + }; + break; + /* linux_shmget */ + case 29: + switch(ndx) { + case 0: + p = "l_key_t"; + break; + case 1: + p = "l_size_t"; + break; + case 2: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_shmat */ + case 30: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "char *"; + break; + case 2: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_shmctl */ + case 31: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_int"; + break; + case 2: + p = "struct l_shmid_ds *"; + break; + default: + break; + }; + break; + /* dup */ + case 32: + switch(ndx) { + case 0: + p = "u_int"; + break; + default: + break; + }; + break; + /* dup2 */ + case 33: + switch(ndx) { + case 0: + p = "u_int"; + break; + case 1: + p = "u_int"; + break; + default: + break; + }; + break; + /* linux_pause */ + case 34: + break; + /* linux_nanosleep */ + case 35: + switch(ndx) { + case 0: + p = "const struct l_timespec *"; + break; + case 1: + p = "struct l_timespec *"; + break; + default: + break; + }; + break; + /* linux_getitimer */ + case 36: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "struct l_itimerval *"; + break; + default: + break; + }; + break; + /* linux_alarm */ + case 37: + switch(ndx) { + case 0: + p = "l_uint"; + break; + default: + break; + }; + break; + /* linux_setitimer */ + case 38: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "struct l_itimerval *"; + break; + case 2: + p = "struct l_itimerval *"; + break; + default: + break; + }; + break; + /* linux_getpid */ + case 39: + break; + /* linux_sendfile */ + case 40: + switch(ndx) { + case 0: + p = "int"; + break; + case 1: + p = "int"; + break; + case 2: + p = "l_long *"; + break; + case 3: + p = "l_size_t"; + break; + default: + break; + }; + break; + /* linux_socket */ + case 41: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_int"; + break; + case 2: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_connect */ + case 42: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_uintptr_t"; + break; + case 2: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_accept */ + case 43: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_uintptr_t"; + break; + case 2: + p = "l_uintptr_t"; + break; + default: + break; + }; + break; + /* linux_sendto */ + case 44: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_uintptr_t"; + break; + case 2: + p = "l_int"; + break; + case 3: + p = "l_int"; + break; + case 4: + p = "l_uintptr_t"; + break; + case 5: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_recvfrom */ + case 45: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_uintptr_t"; + break; + case 2: + p = "l_size_t"; + break; + case 3: + p = "l_int"; + break; + case 4: + p = "l_uintptr_t"; + break; + case 5: + p = "l_uintptr_t"; + break; + default: + break; + }; + break; + /* linux_sendmsg */ + case 46: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_uintptr_t"; + break; + case 2: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_recvmsg */ + case 47: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_uintptr_t"; + break; + case 2: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_shutdown */ + case 48: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_bind */ + case 49: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_uintptr_t"; + break; + case 2: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_listen */ + case 50: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_getsockname */ + case 51: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_uintptr_t"; + break; + case 2: + p = "l_uintptr_t"; + break; + default: + break; + }; + break; + /* linux_getpeername */ + case 52: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_uintptr_t"; + break; + case 2: + p = "l_uintptr_t"; + break; + default: + break; + }; + break; + /* linux_socketpair */ + case 53: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_int"; + break; + case 2: + p = "l_int"; + break; + case 3: + p = "l_uintptr_t"; + break; + default: + break; + }; + break; + /* linux_setsockopt */ + case 54: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_int"; + break; + case 2: + p = "l_int"; + break; + case 3: + p = "l_uintptr_t"; + break; + case 4: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_getsockopt */ + case 55: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_int"; + break; + case 2: + p = "l_int"; + break; + case 3: + p = "l_uintptr_t"; + break; + case 4: + p = "l_uintptr_t"; + break; + default: + break; + }; + break; + /* linux_clone */ + case 56: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "void *"; + break; + case 2: + p = "void *"; + break; + case 3: + p = "void *"; + break; + case 4: + p = "void *"; + break; + default: + break; + }; + break; + /* linux_fork */ + case 57: + break; + /* linux_vfork */ + case 58: + break; + /* linux_execve */ + case 59: + switch(ndx) { + case 0: + p = "char *"; + break; + case 1: + p = "char **"; + break; + case 2: + p = "char **"; + break; + default: + break; + }; + break; + /* linux_exit */ + case 60: + switch(ndx) { + case 0: + p = "int"; + break; + default: + break; + }; + break; + /* linux_wait4 */ + case 61: + switch(ndx) { + case 0: + p = "l_pid_t"; + break; + case 1: + p = "l_int *"; + break; + case 2: + p = "l_int"; + break; + case 3: + p = "struct rusage *"; + break; + default: + break; + }; + break; + /* linux_kill */ + case 62: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_newuname */ + case 63: + switch(ndx) { + case 0: + p = "struct l_new_utsname *"; + break; + default: + break; + }; + break; + /* linux_semget */ + case 64: + switch(ndx) { + case 0: + p = "l_key_t"; + break; + case 1: + p = "l_int"; + break; + case 2: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_semop */ + case 65: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "struct l_sembuf *"; + break; + case 2: + p = "l_uint"; + break; + default: + break; + }; + break; + /* linux_semctl */ + case 66: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_int"; + break; + case 2: + p = "l_int"; + break; + case 3: + p = "union l_semun"; + break; + default: + break; + }; + break; + /* linux_shmdt */ + case 67: + switch(ndx) { + case 0: + p = "char *"; + break; + default: + break; + }; + break; + /* linux_msgget */ + case 68: + switch(ndx) { + case 0: + p = "l_key_t"; + break; + case 1: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_msgsnd */ + case 69: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "struct l_msgbuf *"; + break; + case 2: + p = "l_size_t"; + break; + case 3: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_msgrcv */ + case 70: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "struct l_msgbuf *"; + break; + case 2: + p = "l_size_t"; + break; + case 3: + p = "l_long"; + break; + case 4: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_msgctl */ + case 71: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_int"; + break; + case 2: + p = "struct l_msqid_ds *"; + break; + default: + break; + }; + break; + /* linux_fcntl */ + case 72: + switch(ndx) { + case 0: + p = "l_uint"; + break; + case 1: + p = "l_uint"; + break; + case 2: + p = "l_ulong"; + break; + default: + break; + }; + break; + /* flock */ + case 73: + switch(ndx) { + case 0: + p = "int"; + break; + case 1: + p = "int"; + break; + default: + break; + }; + break; + /* fsync */ + case 74: + switch(ndx) { + case 0: + p = "int"; + break; + default: + break; + }; + break; + /* linux_fdatasync */ + case 75: + switch(ndx) { + case 0: + p = "l_uint"; + break; + default: + break; + }; + break; + /* linux_truncate */ + case 76: + switch(ndx) { + case 0: + p = "char *"; + break; + case 1: + p = "l_ulong"; + break; + default: + break; + }; + break; + /* linux_ftruncate */ + case 77: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_long"; + break; + default: + break; + }; + break; + /* linux_getdents */ + case 78: + switch(ndx) { + case 0: + p = "l_uint"; + break; + case 1: + p = "void *"; + break; + case 2: + p = "l_uint"; + break; + default: + break; + }; + break; + /* linux_getcwd */ + case 79: + switch(ndx) { + case 0: + p = "char *"; + break; + case 1: + p = "l_ulong"; + break; + default: + break; + }; + break; + /* linux_chdir */ + case 80: + switch(ndx) { + case 0: + p = "char *"; + break; + default: + break; + }; + break; + /* fchdir */ + case 81: + switch(ndx) { + case 0: + p = "int"; + break; + default: + break; + }; + break; + /* linux_rename */ + case 82: + switch(ndx) { + case 0: + p = "char *"; + break; + case 1: + p = "char *"; + break; + default: + break; + }; + break; + /* linux_mkdir */ + case 83: + switch(ndx) { + case 0: + p = "char *"; + break; + case 1: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_rmdir */ + case 84: + switch(ndx) { + case 0: + p = "char *"; + break; + default: + break; + }; + break; + /* linux_creat */ + case 85: + switch(ndx) { + case 0: + p = "char *"; + break; + case 1: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_link */ + case 86: + switch(ndx) { + case 0: + p = "char *"; + break; + case 1: + p = "char *"; + break; + default: + break; + }; + break; + /* linux_unlink */ + case 87: + switch(ndx) { + case 0: + p = "char *"; + break; + default: + break; + }; + break; + /* linux_symlink */ + case 88: + switch(ndx) { + case 0: + p = "char *"; + break; + case 1: + p = "char *"; + break; + default: + break; + }; + break; + /* linux_readlink */ + case 89: + switch(ndx) { + case 0: + p = "char *"; + break; + case 1: + p = "char *"; + break; + case 2: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_chmod */ + case 90: + switch(ndx) { + case 0: + p = "char *"; + break; + case 1: + p = "l_mode_t"; + break; + default: + break; + }; + break; + /* fchmod */ + case 91: + switch(ndx) { + case 0: + p = "int"; + break; + case 1: + p = "int"; + break; + default: + break; + }; + break; + /* linux_chown */ + case 92: + switch(ndx) { + case 0: + p = "char *"; + break; + case 1: + p = "l_uid_t"; + break; + case 2: + p = "l_gid_t"; + break; + default: + break; + }; + break; + /* fchown */ + case 93: + switch(ndx) { + case 0: + p = "int"; + break; + case 1: + p = "int"; + break; + case 2: + p = "int"; + break; + default: + break; + }; + break; + /* linux_lchown */ + case 94: + switch(ndx) { + case 0: + p = "char *"; + break; + case 1: + p = "l_uid_t"; + break; + case 2: + p = "l_gid_t"; + break; + default: + break; + }; + break; + /* umask */ + case 95: + switch(ndx) { + case 0: + p = "int"; + break; + default: + break; + }; + break; + /* gettimeofday */ + case 96: + switch(ndx) { + case 0: + p = "struct l_timeval *"; + break; + case 1: + p = "struct timezone *"; + break; + default: + break; + }; + break; + /* linux_getrlimit */ + case 97: + switch(ndx) { + case 0: + p = "l_uint"; + break; + case 1: + p = "struct l_rlimit *"; + break; + default: + break; + }; + break; + /* getrusage */ + case 98: + switch(ndx) { + case 0: + p = "int"; + break; + case 1: + p = "struct rusage *"; + break; + default: + break; + }; + break; + /* linux_sysinfo */ + case 99: + switch(ndx) { + case 0: + p = "struct l_sysinfo *"; + break; + default: + break; + }; + break; + /* linux_times */ + case 100: + switch(ndx) { + case 0: + p = "struct l_times_argv *"; + break; + default: + break; + }; + break; + /* linux_ptrace */ + case 101: + switch(ndx) { + case 0: + p = "l_long"; + break; + case 1: + p = "l_long"; + break; + case 2: + p = "l_long"; + break; + case 3: + p = "l_long"; + break; + default: + break; + }; + break; + /* linux_getuid */ + case 102: + break; + /* linux_syslog */ + case 103: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "char *"; + break; + case 2: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_getgid */ + case 104: + break; + /* setuid */ + case 105: + switch(ndx) { + case 0: + p = "uid_t"; + break; + default: + break; + }; + break; + /* setgid */ + case 106: + switch(ndx) { + case 0: + p = "gid_t"; + break; + default: + break; + }; + break; + /* geteuid */ + case 107: + break; + /* getegid */ + case 108: + break; + /* setpgid */ + case 109: + switch(ndx) { + case 0: + p = "int"; + break; + case 1: + p = "int"; + break; + default: + break; + }; + break; + /* linux_getppid */ + case 110: + break; + /* getpgrp */ + case 111: + break; + /* setsid */ + case 112: + break; + /* setreuid */ + case 113: + switch(ndx) { + case 0: + p = "uid_t"; + break; + case 1: + p = "uid_t"; + break; + default: + break; + }; + break; + /* setregid */ + case 114: + switch(ndx) { + case 0: + p = "gid_t"; + break; + case 1: + p = "gid_t"; + break; + default: + break; + }; + break; + /* linux_getgroups */ + case 115: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_gid_t *"; + break; + default: + break; + }; + break; + /* linux_setgroups */ + case 116: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_gid_t *"; + break; + default: + break; + }; + break; + /* setresuid */ + case 117: + switch(ndx) { + case 0: + p = "uid_t"; + break; + case 1: + p = "uid_t"; + break; + case 2: + p = "uid_t"; + break; + default: + break; + }; + break; + /* getresuid */ + case 118: + switch(ndx) { + case 0: + p = "uid_t *"; + break; + case 1: + p = "uid_t *"; + break; + case 2: + p = "uid_t *"; + break; + default: + break; + }; + break; + /* setresgid */ + case 119: + switch(ndx) { + case 0: + p = "gid_t"; + break; + case 1: + p = "gid_t"; + break; + case 2: + p = "gid_t"; + break; + default: + break; + }; + break; + /* getresgid */ + case 120: + switch(ndx) { + case 0: + p = "gid_t *"; + break; + case 1: + p = "gid_t *"; + break; + case 2: + p = "gid_t *"; + break; + default: + break; + }; + break; + /* getpgid */ + case 121: + switch(ndx) { + case 0: + p = "int"; + break; + default: + break; + }; + break; + /* linux_setfsuid */ + case 122: + switch(ndx) { + case 0: + p = "l_uid_t"; + break; + default: + break; + }; + break; + /* linux_setfsgid */ + case 123: + switch(ndx) { + case 0: + p = "l_gid_t"; + break; + default: + break; + }; + break; + /* linux_getsid */ + case 124: + switch(ndx) { + case 0: + p = "l_pid_t"; + break; + default: + break; + }; + break; + /* linux_capget */ + case 125: + switch(ndx) { + case 0: + p = "struct l_user_cap_header *"; + break; + case 1: + p = "struct l_user_cap_data *"; + break; + default: + break; + }; + break; + /* linux_capset */ + case 126: + switch(ndx) { + case 0: + p = "struct l_user_cap_header *"; + break; + case 1: + p = "struct l_user_cap_data *"; + break; + default: + break; + }; + break; + /* linux_rt_sigpending */ + case 127: + switch(ndx) { + case 0: + p = "l_sigset_t *"; + break; + case 1: + p = "l_size_t"; + break; + default: + break; + }; + break; + /* linux_rt_sigtimedwait */ + case 128: + switch(ndx) { + case 0: + p = "l_sigset_t *"; + break; + case 1: + p = "l_siginfo_t *"; + break; + case 2: + p = "struct l_timeval *"; + break; + case 3: + p = "l_size_t"; + break; + default: + break; + }; + break; + /* linux_rt_sigqueueinfo */ + case 129: + switch(ndx) { + case 0: + p = "l_pid_t"; + break; + case 1: + p = "l_int"; + break; + case 2: + p = "l_siginfo_t *"; + break; + default: + break; + }; + break; + /* linux_rt_sigsuspend */ + case 130: + switch(ndx) { + case 0: + p = "l_sigset_t *"; + break; + case 1: + p = "l_size_t"; + break; + default: + break; + }; + break; + /* linux_sigaltstack */ + case 131: + switch(ndx) { + case 0: + p = "l_stack_t *"; + break; + case 1: + p = "l_stack_t *"; + break; + default: + break; + }; + break; + /* linux_utime */ + case 132: + switch(ndx) { + case 0: + p = "char *"; + break; + case 1: + p = "struct l_utimbuf *"; + break; + default: + break; + }; + break; + /* linux_mknod */ + case 133: + switch(ndx) { + case 0: + p = "char *"; + break; + case 1: + p = "l_int"; + break; + case 2: + p = "l_dev_t"; + break; + default: + break; + }; + break; + /* linux_personality */ + case 135: + switch(ndx) { + case 0: + p = "l_ulong"; + break; + default: + break; + }; + break; + /* linux_ustat */ + case 136: + switch(ndx) { + case 0: + p = "l_dev_t"; + break; + case 1: + p = "struct l_ustat *"; + break; + default: + break; + }; + break; + /* linux_statfs */ + case 137: + switch(ndx) { + case 0: + p = "char *"; + break; + case 1: + p = "struct l_statfs_buf *"; + break; + default: + break; + }; + break; + /* linux_fstatfs */ + case 138: + switch(ndx) { + case 0: + p = "l_uint"; + break; + case 1: + p = "struct l_statfs_buf *"; + break; + default: + break; + }; + break; + /* linux_sysfs */ + case 139: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_ulong"; + break; + case 2: + p = "l_ulong"; + break; + default: + break; + }; + break; + /* linux_getpriority */ + case 140: + switch(ndx) { + case 0: + p = "int"; + break; + case 1: + p = "int"; + break; + default: + break; + }; + break; + /* setpriority */ + case 141: + switch(ndx) { + case 0: + p = "int"; + break; + case 1: + p = "int"; + break; + case 2: + p = "int"; + break; + default: + break; + }; + break; + /* linux_sched_setparam */ + case 142: + switch(ndx) { + case 0: + p = "l_pid_t"; + break; + case 1: + p = "struct l_sched_param *"; + break; + default: + break; + }; + break; + /* linux_sched_getparam */ + case 143: + switch(ndx) { + case 0: + p = "l_pid_t"; + break; + case 1: + p = "struct l_sched_param *"; + break; + default: + break; + }; + break; + /* linux_sched_setscheduler */ + case 144: + switch(ndx) { + case 0: + p = "l_pid_t"; + break; + case 1: + p = "l_int"; + break; + case 2: + p = "struct l_sched_param *"; + break; + default: + break; + }; + break; + /* linux_sched_getscheduler */ + case 145: + switch(ndx) { + case 0: + p = "l_pid_t"; + break; + default: + break; + }; + break; + /* linux_sched_get_priority_max */ + case 146: + switch(ndx) { + case 0: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_sched_get_priority_min */ + case 147: + switch(ndx) { + case 0: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_sched_rr_get_interval */ + case 148: + switch(ndx) { + case 0: + p = "l_pid_t"; + break; + case 1: + p = "struct l_timespec *"; + break; + default: + break; + }; + break; + /* mlock */ + case 149: + switch(ndx) { + case 0: + p = "const void *"; + break; + case 1: + p = "size_t"; + break; + default: + break; + }; + break; + /* munlock */ + case 150: + switch(ndx) { + case 0: + p = "const void *"; + break; + case 1: + p = "size_t"; + break; + default: + break; + }; + break; + /* mlockall */ + case 151: + switch(ndx) { + case 0: + p = "int"; + break; + default: + break; + }; + break; + /* munlockall */ + case 152: + break; + /* linux_vhangup */ + case 153: + break; + /* linux_pivot_root */ + case 155: + break; + /* linux_sysctl */ + case 156: + switch(ndx) { + case 0: + p = "struct l___sysctl_args *"; + break; + default: + break; + }; + break; + /* linux_prctl */ + case 157: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_uintptr_t"; + break; + case 2: + p = "l_uintptr_t"; + break; + case 3: + p = "l_uintptr_t"; + break; + case 4: + p = "l_uintptr_t"; + break; + default: + break; + }; + break; + /* linux_arch_prctl */ + case 158: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_ulong"; + break; + default: + break; + }; + break; + /* linux_adjtimex */ + case 159: + break; + /* linux_setrlimit */ + case 160: + switch(ndx) { + case 0: + p = "l_uint"; + break; + case 1: + p = "struct l_rlimit *"; + break; + default: + break; + }; + break; + /* chroot */ + case 161: + switch(ndx) { + case 0: + p = "char *"; + break; + default: + break; + }; + break; + /* sync */ + case 162: + break; + /* acct */ + case 163: + switch(ndx) { + case 0: + p = "char *"; + break; + default: + break; + }; + break; + /* settimeofday */ + case 164: + switch(ndx) { + case 0: + p = "struct l_timeval *"; + break; + case 1: + p = "struct timezone *"; + break; + default: + break; + }; + break; + /* linux_mount */ + case 165: + switch(ndx) { + case 0: + p = "char *"; + break; + case 1: + p = "char *"; + break; + case 2: + p = "char *"; + break; + case 3: + p = "l_ulong"; + break; + case 4: + p = "void *"; + break; + default: + break; + }; + break; + /* linux_umount */ + case 166: + switch(ndx) { + case 0: + p = "char *"; + break; + case 1: + p = "l_int"; + break; + default: + break; + }; + break; + /* swapon */ + case 167: + switch(ndx) { + case 0: + p = "char *"; + break; + default: + break; + }; + break; + /* linux_swapoff */ + case 168: + break; + /* linux_reboot */ + case 169: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_int"; + break; + case 2: + p = "l_uint"; + break; + case 3: + p = "void *"; + break; + default: + break; + }; + break; + /* linux_sethostname */ + case 170: + switch(ndx) { + case 0: + p = "char *"; + break; + case 1: + p = "l_uint"; + break; + default: + break; + }; + break; + /* linux_setdomainname */ + case 171: + switch(ndx) { + case 0: + p = "char *"; + break; + case 1: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_iopl */ + case 172: + switch(ndx) { + case 0: + p = "l_uint"; + break; + default: + break; + }; + break; + /* linux_create_module */ + case 174: + break; + /* linux_init_module */ + case 175: + break; + /* linux_delete_module */ + case 176: + break; + /* linux_get_kernel_syms */ + case 177: + break; + /* linux_query_module */ + case 178: + break; + /* linux_quotactl */ + case 179: + break; + /* linux_nfsservctl */ + case 180: + break; + /* linux_getpmsg */ + case 181: + break; + /* linux_putpmsg */ + case 182: + break; + /* linux_afs_syscall */ + case 183: + break; + /* linux_tuxcall */ + case 184: + break; + /* linux_security */ + case 185: + break; + /* linux_gettid */ + case 186: + break; + /* linux_setxattr */ + case 188: + break; + /* linux_lsetxattr */ + case 189: + break; + /* linux_fsetxattr */ + case 190: + break; + /* linux_getxattr */ + case 191: + break; + /* linux_lgetxattr */ + case 192: + break; + /* linux_fgetxattr */ + case 193: + break; + /* linux_listxattr */ + case 194: + break; + /* linux_llistxattr */ + case 195: + break; + /* linux_flistxattr */ + case 196: + break; + /* linux_removexattr */ + case 197: + break; + /* linux_lremovexattr */ + case 198: + break; + /* linux_fremovexattr */ + case 199: + break; + /* linux_tkill */ + case 200: + switch(ndx) { + case 0: + p = "int"; + break; + case 1: + p = "int"; + break; + default: + break; + }; + break; + /* linux_time */ + case 201: + switch(ndx) { + case 0: + p = "l_time_t *"; + break; + default: + break; + }; + break; + /* linux_sys_futex */ + case 202: + switch(ndx) { + case 0: + p = "void *"; + break; + case 1: + p = "int"; + break; + case 2: + p = "int"; + break; + case 3: + p = "struct l_timespec *"; + break; + case 4: + p = "void *"; + break; + case 5: + p = "int"; + break; + default: + break; + }; + break; + /* linux_sched_setaffinity */ + case 203: + switch(ndx) { + case 0: + p = "l_pid_t"; + break; + case 1: + p = "l_uint"; + break; + case 2: + p = "l_ulong *"; + break; + default: + break; + }; + break; + /* linux_sched_getaffinity */ + case 204: + switch(ndx) { + case 0: + p = "l_pid_t"; + break; + case 1: + p = "l_uint"; + break; + case 2: + p = "l_ulong *"; + break; + default: + break; + }; + break; + /* linux_set_thread_area */ + case 205: + break; + /* linux_lookup_dcookie */ + case 212: + break; + /* linux_epoll_create */ + case 213: + switch(ndx) { + case 0: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_epoll_ctl_old */ + case 214: + break; + /* linux_epoll_wait_old */ + case 215: + break; + /* linux_remap_file_pages */ + case 216: + break; + /* linux_getdents64 */ + case 217: + switch(ndx) { + case 0: + p = "l_uint"; + break; + case 1: + p = "void *"; + break; + case 2: + p = "l_uint"; + break; + default: + break; + }; + break; + /* linux_set_tid_address */ + case 218: + switch(ndx) { + case 0: + p = "int *"; + break; + default: + break; + }; + break; + /* linux_semtimedop */ + case 220: + break; + /* linux_fadvise64 */ + case 221: + switch(ndx) { + case 0: + p = "int"; + break; + case 1: + p = "l_loff_t"; + break; + case 2: + p = "l_size_t"; + break; + case 3: + p = "int"; + break; + default: + break; + }; + break; + /* linux_timer_create */ + case 222: + switch(ndx) { + case 0: + p = "clockid_t"; + break; + case 1: + p = "struct sigevent *"; + break; + case 2: + p = "l_timer_t *"; + break; + default: + break; + }; + break; + /* linux_timer_settime */ + case 223: + switch(ndx) { + case 0: + p = "l_timer_t"; + break; + case 1: + p = "l_int"; + break; + case 2: + p = "const struct itimerspec *"; + break; + case 3: + p = "struct itimerspec *"; + break; + default: + break; + }; + break; + /* linux_timer_gettime */ + case 224: + switch(ndx) { + case 0: + p = "l_timer_t"; + break; + case 1: + p = "struct itimerspec *"; + break; + default: + break; + }; + break; + /* linux_timer_getoverrun */ + case 225: + switch(ndx) { + case 0: + p = "l_timer_t"; + break; + default: + break; + }; + break; + /* linux_timer_delete */ + case 226: + switch(ndx) { + case 0: + p = "l_timer_t"; + break; + default: + break; + }; + break; + /* linux_clock_settime */ + case 227: + switch(ndx) { + case 0: + p = "clockid_t"; + break; + case 1: + p = "struct l_timespec *"; + break; + default: + break; + }; + break; + /* linux_clock_gettime */ + case 228: + switch(ndx) { + case 0: + p = "clockid_t"; + break; + case 1: + p = "struct l_timespec *"; + break; + default: + break; + }; + break; + /* linux_clock_getres */ + case 229: + switch(ndx) { + case 0: + p = "clockid_t"; + break; + case 1: + p = "struct l_timespec *"; + break; + default: + break; + }; + break; + /* linux_clock_nanosleep */ + case 230: + switch(ndx) { + case 0: + p = "clockid_t"; + break; + case 1: + p = "int"; + break; + case 2: + p = "struct l_timespec *"; + break; + case 3: + p = "struct l_timespec *"; + break; + default: + break; + }; + break; + /* linux_exit_group */ + case 231: + switch(ndx) { + case 0: + p = "int"; + break; + default: + break; + }; + break; + /* linux_epoll_wait */ + case 232: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "struct epoll_event *"; + break; + case 2: + p = "l_int"; + break; + case 3: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_epoll_ctl */ + case 233: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_int"; + break; + case 2: + p = "l_int"; + break; + case 3: + p = "struct epoll_event *"; + break; + default: + break; + }; + break; + /* linux_tgkill */ + case 234: + switch(ndx) { + case 0: + p = "int"; + break; + case 1: + p = "int"; + break; + case 2: + p = "int"; + break; + default: + break; + }; + break; + /* linux_utimes */ + case 235: + switch(ndx) { + case 0: + p = "char *"; + break; + case 1: + p = "struct l_timeval *"; + break; + default: + break; + }; + break; + /* linux_mbind */ + case 237: + break; + /* linux_set_mempolicy */ + case 238: + break; + /* linux_get_mempolicy */ + case 239: + break; + /* linux_mq_open */ + case 240: + break; + /* linux_mq_unlink */ + case 241: + break; + /* linux_mq_timedsend */ + case 242: + break; + /* linux_mq_timedreceive */ + case 243: + break; + /* linux_mq_notify */ + case 244: + break; + /* linux_mq_getsetattr */ + case 245: + break; + /* linux_kexec_load */ + case 246: + break; + /* linux_waitid */ + case 247: + switch(ndx) { + case 0: + p = "int"; + break; + case 1: + p = "l_pid_t"; + break; + case 2: + p = "l_siginfo_t *"; + break; + case 3: + p = "int"; + break; + case 4: + p = "struct rusage *"; + break; + default: + break; + }; + break; + /* linux_add_key */ + case 248: + break; + /* linux_request_key */ + case 249: + break; + /* linux_keyctl */ + case 250: + break; + /* linux_ioprio_set */ + case 251: + break; + /* linux_ioprio_get */ + case 252: + break; + /* linux_inotify_init */ + case 253: + break; + /* linux_inotify_add_watch */ + case 254: + break; + /* linux_inotify_rm_watch */ + case 255: + break; + /* linux_migrate_pages */ + case 256: + break; + /* linux_openat */ + case 257: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "const char *"; + break; + case 2: + p = "l_int"; + break; + case 3: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_mkdirat */ + case 258: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "const char *"; + break; + case 2: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_mknodat */ + case 259: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "const char *"; + break; + case 2: + p = "l_int"; + break; + case 3: + p = "l_uint"; + break; + default: + break; + }; + break; + /* linux_fchownat */ + case 260: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "const char *"; + break; + case 2: + p = "l_uid_t"; + break; + case 3: + p = "l_gid_t"; + break; + case 4: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_futimesat */ + case 261: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "char *"; + break; + case 2: + p = "struct l_timeval *"; + break; + default: + break; + }; + break; + /* linux_newfstatat */ + case 262: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "char *"; + break; + case 2: + p = "struct l_stat64 *"; + break; + case 3: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_unlinkat */ + case 263: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "const char *"; + break; + case 2: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_renameat */ + case 264: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "const char *"; + break; + case 2: + p = "l_int"; + break; + case 3: + p = "const char *"; + break; + default: + break; + }; + break; + /* linux_linkat */ + case 265: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "const char *"; + break; + case 2: + p = "l_int"; + break; + case 3: + p = "const char *"; + break; + case 4: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_symlinkat */ + case 266: + switch(ndx) { + case 0: + p = "const char *"; + break; + case 1: + p = "l_int"; + break; + case 2: + p = "const char *"; + break; + default: + break; + }; + break; + /* linux_readlinkat */ + case 267: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "const char *"; + break; + case 2: + p = "char *"; + break; + case 3: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_fchmodat */ + case 268: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "const char *"; + break; + case 2: + p = "l_mode_t"; + break; + default: + break; + }; + break; + /* linux_faccessat */ + case 269: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "const char *"; + break; + case 2: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_pselect6 */ + case 270: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_fd_set *"; + break; + case 2: + p = "l_fd_set *"; + break; + case 3: + p = "l_fd_set *"; + break; + case 4: + p = "struct l_timespec *"; + break; + case 5: + p = "l_uintptr_t *"; + break; + default: + break; + }; + break; + /* linux_ppoll */ + case 271: + switch(ndx) { + case 0: + p = "struct pollfd *"; + break; + case 1: + p = "uint32_t"; + break; + case 2: + p = "struct l_timespec *"; + break; + case 3: + p = "l_sigset_t *"; + break; + case 4: + p = "l_size_t"; + break; + default: + break; + }; + break; + /* linux_unshare */ + case 272: + break; + /* linux_set_robust_list */ + case 273: + switch(ndx) { + case 0: + p = "struct linux_robust_list_head *"; + break; + case 1: + p = "l_size_t"; + break; + default: + break; + }; + break; + /* linux_get_robust_list */ + case 274: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "struct linux_robust_list_head *"; + break; + case 2: + p = "l_size_t *"; + break; + default: + break; + }; + break; + /* linux_splice */ + case 275: + break; + /* linux_tee */ + case 276: + break; + /* linux_sync_file_range */ + case 277: + break; + /* linux_vmsplice */ + case 278: + break; + /* linux_move_pages */ + case 279: + break; + /* linux_utimensat */ + case 280: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "const char *"; + break; + case 2: + p = "const struct l_timespec *"; + break; + case 3: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_epoll_pwait */ + case 281: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "struct epoll_event *"; + break; + case 2: + p = "l_int"; + break; + case 3: + p = "l_int"; + break; + case 4: + p = "l_sigset_t *"; + break; + default: + break; + }; + break; + /* linux_signalfd */ + case 282: + break; + /* linux_timerfd */ + case 283: + break; + /* linux_eventfd */ + case 284: + switch(ndx) { + case 0: + p = "l_uint"; + break; + default: + break; + }; + break; + /* linux_fallocate */ + case 285: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_int"; + break; + case 2: + p = "l_loff_t"; + break; + case 3: + p = "l_loff_t"; + break; + default: + break; + }; + break; + /* linux_timerfd_settime */ + case 286: + break; + /* linux_timerfd_gettime */ + case 287: + break; + /* linux_accept4 */ + case 288: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_uintptr_t"; + break; + case 2: + p = "l_uintptr_t"; + break; + case 3: + p = "int"; + break; + default: + break; + }; + break; + /* linux_signalfd4 */ + case 289: + break; + /* linux_eventfd2 */ + case 290: + switch(ndx) { + case 0: + p = "l_uint"; + break; + case 1: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_epoll_create1 */ + case 291: + switch(ndx) { + case 0: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_dup3 */ + case 292: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_int"; + break; + case 2: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_pipe2 */ + case 293: + switch(ndx) { + case 0: + p = "l_int *"; + break; + case 1: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_inotify_init1 */ + case 294: + break; + /* linux_preadv */ + case 295: + break; + /* linux_pwritev */ + case 296: + break; + /* linux_rt_tsigqueueinfo */ + case 297: + break; + /* linux_perf_event_open */ + case 298: + break; + /* linux_recvmmsg */ + case 299: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "struct l_mmsghdr *"; + break; + case 2: + p = "l_uint"; + break; + case 3: + p = "l_uint"; + break; + case 4: + p = "struct l_timespec *"; + break; + default: + break; + }; + break; + /* linux_fanotify_init */ + case 300: + break; + /* linux_fanotify_mark */ + case 301: + break; + /* linux_prlimit64 */ + case 302: + switch(ndx) { + case 0: + p = "l_pid_t"; + break; + case 1: + p = "l_uint"; + break; + case 2: + p = "struct rlimit *"; + break; + case 3: + p = "struct rlimit *"; + break; + default: + break; + }; + break; + /* linux_name_to_handle_at */ + case 303: + break; + /* linux_open_by_handle_at */ + case 304: + break; + /* linux_clock_adjtime */ + case 305: + break; + /* linux_syncfs */ + case 306: + switch(ndx) { + case 0: + p = "l_int"; + break; + default: + break; + }; + break; + /* linux_sendmmsg */ + case 307: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "struct l_mmsghdr *"; + break; + case 2: + p = "l_uint"; + break; + case 3: + p = "l_uint"; + break; + default: + break; + }; + break; + /* linux_setns */ + case 308: + break; + /* linux_process_vm_readv */ + case 309: + break; + /* linux_process_vm_writev */ + case 310: + break; + /* linux_kcmp */ + case 311: + break; + /* linux_finit_module */ + case 312: + break; + default: + break; + }; + if (p != NULL) + strlcpy(desc, p, descsz); +} +static void +systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) +{ + const char *p = NULL; + switch (sysnum) { +#define nosys linux_nosys + /* read */ + case 0: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* write */ + case 1: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_open */ + case 2: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* close */ + case 3: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_newstat */ + case 4: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_newfstat */ + case 5: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_newlstat */ + case 6: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* poll */ + case 7: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_lseek */ + case 8: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_mmap2 */ + case 9: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_mprotect */ + case 10: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* munmap */ + case 11: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_brk */ + case 12: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_rt_sigaction */ + case 13: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_rt_sigprocmask */ + case 14: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_rt_sigreturn */ + case 15: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_ioctl */ + case 16: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_pread */ + case 17: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_pwrite */ + case 18: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* readv */ + case 19: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* writev */ + case 20: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_access */ + case 21: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_pipe */ + case 22: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_select */ + case 23: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* sched_yield */ + case 24: + /* linux_mremap */ + case 25: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_msync */ + case 26: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_mincore */ + case 27: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* madvise */ + case 28: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_shmget */ + case 29: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_shmat */ + case 30: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_shmctl */ + case 31: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* dup */ + case 32: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* dup2 */ + case 33: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_pause */ + case 34: + /* linux_nanosleep */ + case 35: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_getitimer */ + case 36: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_alarm */ + case 37: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_setitimer */ + case 38: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_getpid */ + case 39: + /* linux_sendfile */ + case 40: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_socket */ + case 41: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_connect */ + case 42: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_accept */ + case 43: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_sendto */ + case 44: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_recvfrom */ + case 45: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_sendmsg */ + case 46: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_recvmsg */ + case 47: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_shutdown */ + case 48: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_bind */ + case 49: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_listen */ + case 50: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_getsockname */ + case 51: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_getpeername */ + case 52: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_socketpair */ + case 53: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_setsockopt */ + case 54: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_getsockopt */ + case 55: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_clone */ + case 56: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_fork */ + case 57: + /* linux_vfork */ + case 58: + /* linux_execve */ + case 59: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_exit */ + case 60: + if (ndx == 0 || ndx == 1) + p = "void"; + break; + /* linux_wait4 */ + case 61: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_kill */ + case 62: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_newuname */ + case 63: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_semget */ + case 64: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_semop */ + case 65: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_semctl */ + case 66: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_shmdt */ + case 67: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_msgget */ + case 68: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_msgsnd */ + case 69: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_msgrcv */ + case 70: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_msgctl */ + case 71: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_fcntl */ + case 72: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* flock */ + case 73: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* fsync */ + case 74: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_fdatasync */ + case 75: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_truncate */ + case 76: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_ftruncate */ + case 77: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_getdents */ + case 78: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_getcwd */ + case 79: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_chdir */ + case 80: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* fchdir */ + case 81: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_rename */ + case 82: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_mkdir */ + case 83: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_rmdir */ + case 84: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_creat */ + case 85: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_link */ + case 86: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_unlink */ + case 87: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_symlink */ + case 88: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_readlink */ + case 89: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_chmod */ + case 90: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* fchmod */ + case 91: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_chown */ + case 92: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* fchown */ + case 93: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_lchown */ + case 94: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* umask */ + case 95: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* gettimeofday */ + case 96: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_getrlimit */ + case 97: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* getrusage */ + case 98: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_sysinfo */ + case 99: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_times */ + case 100: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_ptrace */ + case 101: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_getuid */ + case 102: + /* linux_syslog */ + case 103: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_getgid */ + case 104: + /* setuid */ + case 105: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* setgid */ + case 106: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* geteuid */ + case 107: + /* getegid */ + case 108: + /* setpgid */ + case 109: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_getppid */ + case 110: + /* getpgrp */ + case 111: + /* setsid */ + case 112: + /* setreuid */ + case 113: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* setregid */ + case 114: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_getgroups */ + case 115: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_setgroups */ + case 116: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* setresuid */ + case 117: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* getresuid */ + case 118: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* setresgid */ + case 119: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* getresgid */ + case 120: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* getpgid */ + case 121: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_setfsuid */ + case 122: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_setfsgid */ + case 123: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_getsid */ + case 124: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_capget */ + case 125: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_capset */ + case 126: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_rt_sigpending */ + case 127: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_rt_sigtimedwait */ + case 128: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_rt_sigqueueinfo */ + case 129: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_rt_sigsuspend */ + case 130: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_sigaltstack */ + case 131: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_utime */ + case 132: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_mknod */ + case 133: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_personality */ + case 135: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_ustat */ + case 136: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_statfs */ + case 137: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_fstatfs */ + case 138: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_sysfs */ + case 139: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_getpriority */ + case 140: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* setpriority */ + case 141: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_sched_setparam */ + case 142: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_sched_getparam */ + case 143: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_sched_setscheduler */ + case 144: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_sched_getscheduler */ + case 145: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_sched_get_priority_max */ + case 146: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_sched_get_priority_min */ + case 147: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_sched_rr_get_interval */ + case 148: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* mlock */ + case 149: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* munlock */ + case 150: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* mlockall */ + case 151: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* munlockall */ + case 152: + /* linux_vhangup */ + case 153: + /* linux_pivot_root */ + case 155: + /* linux_sysctl */ + case 156: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_prctl */ + case 157: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_arch_prctl */ + case 158: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_adjtimex */ + case 159: + /* linux_setrlimit */ + case 160: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* chroot */ + case 161: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* sync */ + case 162: + /* acct */ + case 163: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* settimeofday */ + case 164: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_mount */ + case 165: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_umount */ + case 166: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* swapon */ + case 167: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_swapoff */ + case 168: + /* linux_reboot */ + case 169: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_sethostname */ + case 170: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_setdomainname */ + case 171: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_iopl */ + case 172: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_create_module */ + case 174: + /* linux_init_module */ + case 175: + /* linux_delete_module */ + case 176: + /* linux_get_kernel_syms */ + case 177: + /* linux_query_module */ + case 178: + /* linux_quotactl */ + case 179: + /* linux_nfsservctl */ + case 180: + /* linux_getpmsg */ + case 181: + /* linux_putpmsg */ + case 182: + /* linux_afs_syscall */ + case 183: + /* linux_tuxcall */ + case 184: + /* linux_security */ + case 185: + /* linux_gettid */ + case 186: + /* linux_setxattr */ + case 188: + /* linux_lsetxattr */ + case 189: + /* linux_fsetxattr */ + case 190: + /* linux_getxattr */ + case 191: + /* linux_lgetxattr */ + case 192: + /* linux_fgetxattr */ + case 193: + /* linux_listxattr */ + case 194: + /* linux_llistxattr */ + case 195: + /* linux_flistxattr */ + case 196: + /* linux_removexattr */ + case 197: + /* linux_lremovexattr */ + case 198: + /* linux_fremovexattr */ + case 199: + /* linux_tkill */ + case 200: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_time */ + case 201: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_sys_futex */ + case 202: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_sched_setaffinity */ + case 203: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_sched_getaffinity */ + case 204: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_set_thread_area */ + case 205: + /* linux_lookup_dcookie */ + case 212: + /* linux_epoll_create */ + case 213: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_epoll_ctl_old */ + case 214: + /* linux_epoll_wait_old */ + case 215: + /* linux_remap_file_pages */ + case 216: + /* linux_getdents64 */ + case 217: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_set_tid_address */ + case 218: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_semtimedop */ + case 220: + /* linux_fadvise64 */ + case 221: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_timer_create */ + case 222: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_timer_settime */ + case 223: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_timer_gettime */ + case 224: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_timer_getoverrun */ + case 225: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_timer_delete */ + case 226: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_clock_settime */ + case 227: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_clock_gettime */ + case 228: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_clock_getres */ + case 229: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_clock_nanosleep */ + case 230: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_exit_group */ + case 231: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_epoll_wait */ + case 232: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_epoll_ctl */ + case 233: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_tgkill */ + case 234: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_utimes */ + case 235: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_mbind */ + case 237: + /* linux_set_mempolicy */ + case 238: + /* linux_get_mempolicy */ + case 239: + /* linux_mq_open */ + case 240: + /* linux_mq_unlink */ + case 241: + /* linux_mq_timedsend */ + case 242: + /* linux_mq_timedreceive */ + case 243: + /* linux_mq_notify */ + case 244: + /* linux_mq_getsetattr */ + case 245: + /* linux_kexec_load */ + case 246: + /* linux_waitid */ + case 247: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_add_key */ + case 248: + /* linux_request_key */ + case 249: + /* linux_keyctl */ + case 250: + /* linux_ioprio_set */ + case 251: + /* linux_ioprio_get */ + case 252: + /* linux_inotify_init */ + case 253: + /* linux_inotify_add_watch */ + case 254: + /* linux_inotify_rm_watch */ + case 255: + /* linux_migrate_pages */ + case 256: + /* linux_openat */ + case 257: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_mkdirat */ + case 258: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_mknodat */ + case 259: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_fchownat */ + case 260: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_futimesat */ + case 261: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_newfstatat */ + case 262: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_unlinkat */ + case 263: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_renameat */ + case 264: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_linkat */ + case 265: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_symlinkat */ + case 266: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_readlinkat */ + case 267: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_fchmodat */ + case 268: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_faccessat */ + case 269: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_pselect6 */ + case 270: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_ppoll */ + case 271: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_unshare */ + case 272: + /* linux_set_robust_list */ + case 273: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_get_robust_list */ + case 274: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_splice */ + case 275: + /* linux_tee */ + case 276: + /* linux_sync_file_range */ + case 277: + /* linux_vmsplice */ + case 278: + /* linux_move_pages */ + case 279: + /* linux_utimensat */ + case 280: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_epoll_pwait */ + case 281: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_signalfd */ + case 282: + /* linux_timerfd */ + case 283: + /* linux_eventfd */ + case 284: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_fallocate */ + case 285: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_timerfd_settime */ + case 286: + /* linux_timerfd_gettime */ + case 287: + /* linux_accept4 */ + case 288: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_signalfd4 */ + case 289: + /* linux_eventfd2 */ + case 290: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_epoll_create1 */ + case 291: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_dup3 */ + case 292: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_pipe2 */ + case 293: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_inotify_init1 */ + case 294: + /* linux_preadv */ + case 295: + /* linux_pwritev */ + case 296: + /* linux_rt_tsigqueueinfo */ + case 297: + /* linux_perf_event_open */ + case 298: + /* linux_recvmmsg */ + case 299: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_fanotify_init */ + case 300: + /* linux_fanotify_mark */ + case 301: + /* linux_prlimit64 */ + case 302: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_name_to_handle_at */ + case 303: + /* linux_open_by_handle_at */ + case 304: + /* linux_clock_adjtime */ + case 305: + /* linux_syncfs */ + case 306: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_sendmmsg */ + case 307: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* linux_setns */ + case 308: + /* linux_process_vm_readv */ + case 309: + /* linux_process_vm_writev */ + case 310: + /* linux_kcmp */ + case 311: + /* linux_finit_module */ + case 312: + default: + break; + }; + if (p != NULL) + strlcpy(desc, p, descsz); +} diff --git a/sys/amd64/linux/linux_sysvec.c b/sys/amd64/linux/linux_sysvec.c new file mode 100644 index 0000000..37c1b69 --- /dev/null +++ b/sys/amd64/linux/linux_sysvec.c @@ -0,0 +1,946 @@ +/*- + * Copyright (c) 2013 Dmitry Chagin + * Copyright (c) 2004 Tim J. Robbins + * Copyright (c) 2003 Peter Wemm + * Copyright (c) 2002 Doug Rabson + * Copyright (c) 1998-1999 Andrew Gallatin + * Copyright (c) 1994-1996 Søren Schmidt + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include "opt_compat.h" + +#define __ELF_WORD_SIZE 64 + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/exec.h> +#include <sys/fcntl.h> +#include <sys/imgact.h> +#include <sys/imgact_elf.h> +#include <sys/kernel.h> +#include <sys/ktr.h> +#include <sys/lock.h> +#include <sys/malloc.h> +#include <sys/module.h> +#include <sys/mutex.h> +#include <sys/proc.h> +#include <sys/resourcevar.h> +#include <sys/signalvar.h> +#include <sys/sysctl.h> +#include <sys/syscallsubr.h> +#include <sys/sysent.h> +#include <sys/sysproto.h> +#include <sys/vnode.h> +#include <sys/eventhandler.h> + +#include <vm/vm.h> +#include <vm/pmap.h> +#include <vm/vm_extern.h> +#include <vm/vm_map.h> +#include <vm/vm_object.h> +#include <vm/vm_page.h> +#include <vm/vm_param.h> + +#include <machine/cpu.h> +#include <machine/md_var.h> +#include <machine/pcb.h> +#include <machine/specialreg.h> + +#include <amd64/linux/linux.h> +#include <amd64/linux/linux_proto.h> +#include <compat/linux/linux_emul.h> +#include <compat/linux/linux_futex.h> +#include <compat/linux/linux_ioctl.h> +#include <compat/linux/linux_mib.h> +#include <compat/linux/linux_misc.h> +#include <compat/linux/linux_signal.h> +#include <compat/linux/linux_sysproto.h> +#include <compat/linux/linux_util.h> +#include <compat/linux/linux_vdso.h> + +MODULE_VERSION(linux64, 1); + +#if BYTE_ORDER == LITTLE_ENDIAN +#define SHELLMAGIC 0x2123 /* #! */ +#else +#define SHELLMAGIC 0x2321 +#endif + +#if defined(DEBUG) +SYSCTL_PROC(_compat_linux, OID_AUTO, debug, + CTLTYPE_STRING | CTLFLAG_RW, + 0, 0, linux_sysctl_debug, "A", + "Linux 64 debugging control"); +#endif + +/* + * Allow the this functions to use the ldebug() facility + * even though they are not syscalls themselves. Map them + * to syscall 0. This is slightly less bogus than using + * ldebug(sigreturn). + */ +#define LINUX_SYS_linux_rt_sendsig 0 + +const char *linux_kplatform; +static int linux_szsigcode; +static vm_object_t linux_shared_page_obj; +static char *linux_shared_page_mapping; +extern char _binary_linux_locore_o_start; +extern char _binary_linux_locore_o_end; + +extern struct sysent linux_sysent[LINUX_SYS_MAXSYSCALL]; + +SET_DECLARE(linux_ioctl_handler_set, struct linux_ioctl_handler); + +static register_t * linux_copyout_strings(struct image_params *imgp); +static int elf_linux_fixup(register_t **stack_base, + struct image_params *iparams); +static boolean_t linux_trans_osrel(const Elf_Note *note, int32_t *osrel); +static void linux_vdso_install(void *param); +static void linux_vdso_deinstall(void *param); +static void linux_set_syscall_retval(struct thread *td, int error); +static int linux_fetch_syscall_args(struct thread *td, struct syscall_args *sa); +static void linux_exec_setregs(struct thread *td, struct image_params *imgp, + u_long stack); + +/* + * Linux syscalls return negative errno's, we do positive and map them + * Reference: + * FreeBSD: src/sys/sys/errno.h + * Linux: linux-2.6.17.8/include/asm-generic/errno-base.h + * linux-2.6.17.8/include/asm-generic/errno.h + */ +static int bsd_to_linux_errno[ELAST + 1] = { + -0, -1, -2, -3, -4, -5, -6, -7, -8, -9, + -10, -35, -12, -13, -14, -15, -16, -17, -18, -19, + -20, -21, -22, -23, -24, -25, -26, -27, -28, -29, + -30, -31, -32, -33, -34, -11,-115,-114, -88, -89, + -90, -91, -92, -93, -94, -95, -96, -97, -98, -99, + -100,-101,-102,-103,-104,-105,-106,-107,-108,-109, + -110,-111, -40, -36,-112,-113, -39, -11, -87,-122, + -116, -66, -6, -6, -6, -6, -6, -37, -38, -9, + -6, -6, -43, -42, -75,-125, -84, -95, -16, -74, + -72, -67, -71 +}; + +#define LINUX_T_UNKNOWN 255 +static int _bsd_to_linux_trapcode[] = { + LINUX_T_UNKNOWN, /* 0 */ + 6, /* 1 T_PRIVINFLT */ + LINUX_T_UNKNOWN, /* 2 */ + 3, /* 3 T_BPTFLT */ + LINUX_T_UNKNOWN, /* 4 */ + LINUX_T_UNKNOWN, /* 5 */ + 16, /* 6 T_ARITHTRAP */ + 254, /* 7 T_ASTFLT */ + LINUX_T_UNKNOWN, /* 8 */ + 13, /* 9 T_PROTFLT */ + 1, /* 10 T_TRCTRAP */ + LINUX_T_UNKNOWN, /* 11 */ + 14, /* 12 T_PAGEFLT */ + LINUX_T_UNKNOWN, /* 13 */ + 17, /* 14 T_ALIGNFLT */ + LINUX_T_UNKNOWN, /* 15 */ + LINUX_T_UNKNOWN, /* 16 */ + LINUX_T_UNKNOWN, /* 17 */ + 0, /* 18 T_DIVIDE */ + 2, /* 19 T_NMI */ + 4, /* 20 T_OFLOW */ + 5, /* 21 T_BOUND */ + 7, /* 22 T_DNA */ + 8, /* 23 T_DOUBLEFLT */ + 9, /* 24 T_FPOPFLT */ + 10, /* 25 T_TSSFLT */ + 11, /* 26 T_SEGNPFLT */ + 12, /* 27 T_STKFLT */ + 18, /* 28 T_MCHK */ + 19, /* 29 T_XMMFLT */ + 15 /* 30 T_RESERVED */ +}; +#define bsd_to_linux_trapcode(code) \ + ((code)<sizeof(_bsd_to_linux_trapcode)/sizeof(*_bsd_to_linux_trapcode)? \ + _bsd_to_linux_trapcode[(code)]: \ + LINUX_T_UNKNOWN) + +LINUX_VDSO_SYM_INTPTR(linux_rt_sigcode); +LINUX_VDSO_SYM_CHAR(linux_platform); + +/* + * If FreeBSD & Linux have a difference of opinion about what a trap + * means, deal with it here. + * + * MPSAFE + */ +static int +translate_traps(int signal, int trap_code) +{ + + if (signal != SIGBUS) + return signal; + switch (trap_code) { + case T_PROTFLT: + case T_TSSFLT: + case T_DOUBLEFLT: + case T_PAGEFLT: + return SIGSEGV; + default: + return signal; + } +} + +static int +linux_fetch_syscall_args(struct thread *td, struct syscall_args *sa) +{ + struct proc *p; + struct trapframe *frame; + + p = td->td_proc; + frame = td->td_frame; + + sa->args[0] = frame->tf_rdi; + sa->args[1] = frame->tf_rsi; + sa->args[2] = frame->tf_rdx; + sa->args[3] = frame->tf_rcx; + sa->args[4] = frame->tf_r8; + sa->args[5] = frame->tf_r9; + sa->code = frame->tf_rax; + + if (sa->code >= p->p_sysent->sv_size) + /* nosys */ + sa->callp = &p->p_sysent->sv_table[p->p_sysent->sv_size - 1]; + else + sa->callp = &p->p_sysent->sv_table[sa->code]; + sa->narg = sa->callp->sy_narg; + + td->td_retval[0] = 0; + return (0); +} + +static void +linux_set_syscall_retval(struct thread *td, int error) +{ + struct trapframe *frame = td->td_frame; + + /* + * On Linux only %rcx and %r11 values are not preserved across + * the syscall. + * So, do not clobber %rdx and %r10 + */ + td->td_retval[1] = frame->tf_rdx; + frame->tf_r10 = frame->tf_rcx; + + cpu_set_syscall_retval(td, error); + + /* Restore all registers. */ + set_pcb_flags(td->td_pcb, PCB_FULL_IRET); +} + +static int +elf_linux_fixup(register_t **stack_base, struct image_params *imgp) +{ + Elf_Auxargs *args; + Elf_Addr *base; + Elf_Addr *pos; + struct ps_strings *arginfo; + struct proc *p; + + p = imgp->proc; + arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings; + + KASSERT(curthread->td_proc == imgp->proc, + ("unsafe elf_linux_fixup(), should be curproc")); + base = (Elf64_Addr *)*stack_base; + args = (Elf64_Auxargs *)imgp->auxargs; + pos = base + (imgp->args->argc + imgp->args->envc + 2); + + AUXARGS_ENTRY(pos, LINUX_AT_SYSINFO_EHDR, + imgp->proc->p_sysent->sv_shared_page_base); + AUXARGS_ENTRY(pos, LINUX_AT_HWCAP, cpu_feature); + AUXARGS_ENTRY(pos, LINUX_AT_CLKTCK, stclohz); + AUXARGS_ENTRY(pos, AT_PHDR, args->phdr); + AUXARGS_ENTRY(pos, AT_PHENT, args->phent); + AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum); + AUXARGS_ENTRY(pos, AT_PAGESZ, args->pagesz); + AUXARGS_ENTRY(pos, AT_BASE, args->base); + AUXARGS_ENTRY(pos, AT_FLAGS, args->flags); + AUXARGS_ENTRY(pos, AT_ENTRY, args->entry); + AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_ucred->cr_ruid); + AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_ucred->cr_svuid); + AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_ucred->cr_rgid); + AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid); + AUXARGS_ENTRY(pos, LINUX_AT_SECURE, 0); + AUXARGS_ENTRY(pos, LINUX_AT_PLATFORM, PTROUT(linux_platform)); + AUXARGS_ENTRY(pos, LINUX_AT_RANDOM, imgp->canary); + if (imgp->execpathp != 0) + AUXARGS_ENTRY(pos, LINUX_AT_EXECFN, imgp->execpathp); + if (args->execfd != -1) + AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd); + AUXARGS_ENTRY(pos, AT_NULL, 0); + free(imgp->auxargs, M_TEMP); + imgp->auxargs = NULL; + + base--; + suword(base, (uint64_t)imgp->args->argc); + + *stack_base = (register_t *)base; + return (0); +} + +/* + * Copy strings out to the new process address space, constructing new arg + * and env vector tables. Return a pointer to the base so that it can be used + * as the initial stack pointer. + */ +static register_t * +linux_copyout_strings(struct image_params *imgp) +{ + int argc, envc; + char **vectp; + char *stringp, *destp; + register_t *stack_base; + struct ps_strings *arginfo; + char canary[LINUX_AT_RANDOM_LEN]; + size_t execpath_len; + struct proc *p; + + /* + * Calculate string base and vector table pointers. + */ + if (imgp->execpath != NULL && imgp->auxargs != NULL) + execpath_len = strlen(imgp->execpath) + 1; + else + execpath_len = 0; + + p = imgp->proc; + arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings; + destp = (caddr_t)arginfo - SPARE_USRSPACE - + roundup(sizeof(canary), sizeof(char *)) - + roundup(execpath_len, sizeof(char *)) - + roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *)); + + if (execpath_len != 0) { + imgp->execpathp = (uintptr_t)arginfo - execpath_len; + copyout(imgp->execpath, (void *)imgp->execpathp, execpath_len); + } + + /* + * Prepare the canary for SSP. + */ + arc4rand(canary, sizeof(canary), 0); + imgp->canary = (uintptr_t)arginfo - + roundup(execpath_len, sizeof(char *)) - + roundup(sizeof(canary), sizeof(char *)); + copyout(canary, (void *)imgp->canary, sizeof(canary)); + + /* + * If we have a valid auxargs ptr, prepare some room + * on the stack. + */ + if (imgp->auxargs) { + /* + * 'AT_COUNT*2' is size for the ELF Auxargs data. This is for + * lower compatibility. + */ + imgp->auxarg_size = (imgp->auxarg_size) ? imgp->auxarg_size : + (LINUX_AT_COUNT * 2); + + /* + * The '+ 2' is for the null pointers at the end of each of + * the arg and env vector sets,and imgp->auxarg_size is room + * for argument of Runtime loader. + */ + vectp = (char **)(destp - (imgp->args->argc + + imgp->args->envc + 2 + imgp->auxarg_size) * sizeof(char *)); + + } else { + /* + * The '+ 2' is for the null pointers at the end of each of + * the arg and env vector sets + */ + vectp = (char **)(destp - (imgp->args->argc + + imgp->args->envc + 2) * sizeof(char *)); + } + + /* + * vectp also becomes our initial stack base + */ + stack_base = (register_t *)vectp; + + stringp = imgp->args->begin_argv; + argc = imgp->args->argc; + envc = imgp->args->envc; + + /* + * Copy out strings - arguments and environment. + */ + copyout(stringp, destp, ARG_MAX - imgp->args->stringspace); + + /* + * Fill in "ps_strings" struct for ps, w, etc. + */ + suword(&arginfo->ps_argvstr, (long)(intptr_t)vectp); + suword(&arginfo->ps_nargvstr, argc); + + /* + * Fill in argument portion of vector table. + */ + for (; argc > 0; --argc) { + suword(vectp++, (long)(intptr_t)destp); + while (*stringp++ != 0) + destp++; + destp++; + } + + /* a null vector table pointer separates the argp's from the envp's */ + suword(vectp++, 0); + + suword(&arginfo->ps_envstr, (long)(intptr_t)vectp); + suword(&arginfo->ps_nenvstr, envc); + + /* + * Fill in environment portion of vector table. + */ + for (; envc > 0; --envc) { + suword(vectp++, (long)(intptr_t)destp); + while (*stringp++ != 0) + destp++; + destp++; + } + + /* end of vector table is a null pointer */ + suword(vectp, 0); + return (stack_base); +} + +/* + * Reset registers to default values on exec. + */ +static void +linux_exec_setregs(struct thread *td, struct image_params *imgp, u_long stack) +{ + struct trapframe *regs = td->td_frame; + struct pcb *pcb = td->td_pcb; + + mtx_lock(&dt_lock); + if (td->td_proc->p_md.md_ldt != NULL) + user_ldt_free(td); + else + mtx_unlock(&dt_lock); + + pcb->pcb_fsbase = 0; + pcb->pcb_gsbase = 0; + clear_pcb_flags(pcb, PCB_32BIT); + pcb->pcb_initial_fpucw = __LINUX_NPXCW__; + set_pcb_flags(pcb, PCB_FULL_IRET); + + bzero((char *)regs, sizeof(struct trapframe)); + regs->tf_rip = imgp->entry_addr; + regs->tf_rsp = stack; + regs->tf_rflags = PSL_USER | (regs->tf_rflags & PSL_T); + regs->tf_ss = _udatasel; + regs->tf_cs = _ucodesel; + regs->tf_ds = _udatasel; + regs->tf_es = _udatasel; + regs->tf_fs = _ufssel; + regs->tf_gs = _ugssel; + regs->tf_flags = TF_HASSEGS; + + /* + * Reset the hardware debug registers if they were in use. + * They won't have any meaning for the newly exec'd process. + */ + if (pcb->pcb_flags & PCB_DBREGS) { + pcb->pcb_dr0 = 0; + pcb->pcb_dr1 = 0; + pcb->pcb_dr2 = 0; + pcb->pcb_dr3 = 0; + pcb->pcb_dr6 = 0; + pcb->pcb_dr7 = 0; + if (pcb == curpcb) { + /* + * Clear the debug registers on the running + * CPU, otherwise they will end up affecting + * the next process we switch to. + */ + reset_dbregs(); + } + clear_pcb_flags(pcb, PCB_DBREGS); + } + + /* + * Drop the FP state if we hold it, so that the process gets a + * clean FP state if it uses the FPU again. + */ + fpstate_drop(td); +} + +/* + * Copied from amd64/amd64/machdep.c + * + * XXX fpu state need? don't think so + */ +int +linux_rt_sigreturn(struct thread *td, struct linux_rt_sigreturn_args *args) +{ + struct proc *p; + struct l_ucontext uc; + struct l_sigcontext *context; + struct trapframe *regs; + unsigned long rflags; + int error; + ksiginfo_t ksi; + + regs = td->td_frame; + error = copyin((void *)regs->tf_rbx, &uc, sizeof(uc)); + if (error != 0) + return (error); + + p = td->td_proc; + context = &uc.uc_mcontext; + rflags = context->sc_rflags; + + /* + * Don't allow users to change privileged or reserved flags. + */ + /* + * XXX do allow users to change the privileged flag PSL_RF. + * The cpu sets PSL_RF in tf_rflags for faults. Debuggers + * should sometimes set it there too. tf_rflags is kept in + * the signal context during signal handling and there is no + * other place to remember it, so the PSL_RF bit may be + * corrupted by the signal handler without us knowing. + * Corruption of the PSL_RF bit at worst causes one more or + * one less debugger trap, so allowing it is fairly harmless. + */ + +#define RFLAG_SECURE(ef, oef) ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0) + if (!RFLAG_SECURE(rflags & ~PSL_RF, regs->tf_rflags & ~PSL_RF)) { + printf("linux_rt_sigreturn: rflags = 0x%lx\n", rflags); + return (EINVAL); + } + + /* + * Don't allow users to load a valid privileged %cs. Let the + * hardware check for invalid selectors, excess privilege in + * other selectors, invalid %eip's and invalid %esp's. + */ +#define CS_SECURE(cs) (ISPL(cs) == SEL_UPL) + if (!CS_SECURE(context->sc_cs)) { + printf("linux_rt_sigreturn: cs = 0x%x\n", context->sc_cs); + ksiginfo_init_trap(&ksi); + ksi.ksi_signo = SIGBUS; + ksi.ksi_code = BUS_OBJERR; + ksi.ksi_trapno = T_PROTFLT; + ksi.ksi_addr = (void *)regs->tf_rip; + trapsignal(td, &ksi); + return (EINVAL); + } + + PROC_LOCK(p); + linux_to_bsd_sigset(&uc.uc_sigmask, &td->td_sigmask); + SIG_CANTMASK(td->td_sigmask); + signotify(td); + PROC_UNLOCK(p); + + regs->tf_rdi = context->sc_rdi; + regs->tf_rsi = context->sc_rsi; + regs->tf_rdx = context->sc_rdx; + regs->tf_rbp = context->sc_rbp; + regs->tf_rbx = context->sc_rbx; + regs->tf_rcx = context->sc_rcx; + regs->tf_rax = context->sc_rax; + regs->tf_rip = context->sc_rip; + regs->tf_rsp = context->sc_rsp; + regs->tf_r8 = context->sc_r8; + regs->tf_r9 = context->sc_r9; + regs->tf_r10 = context->sc_r10; + regs->tf_r11 = context->sc_r11; + regs->tf_r12 = context->sc_r12; + regs->tf_r13 = context->sc_r13; + regs->tf_r14 = context->sc_r14; + regs->tf_r15 = context->sc_r15; + regs->tf_cs = context->sc_cs; + regs->tf_err = context->sc_err; + regs->tf_rflags = rflags; + + set_pcb_flags(td->td_pcb, PCB_FULL_IRET); + return (EJUSTRETURN); +} + +/* + * copied from amd64/amd64/machdep.c + * + * Send an interrupt to process. + */ +static void +linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) +{ + struct l_rt_sigframe sf, *sfp; + struct proc *p; + struct thread *td; + struct sigacts *psp; + caddr_t sp; + struct trapframe *regs; + int sig, code; + int oonstack; + + td = curthread; + p = td->td_proc; + PROC_LOCK_ASSERT(p, MA_OWNED); + sig = ksi->ksi_signo; + psp = p->p_sigacts; + code = ksi->ksi_code; + mtx_assert(&psp->ps_mtx, MA_OWNED); + regs = td->td_frame; + oonstack = sigonstack(regs->tf_rsp); + + LINUX_CTR4(rt_sendsig, "%p, %d, %p, %u", + catcher, sig, mask, code); + + /* Allocate space for the signal handler context. */ + if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack && + SIGISMEMBER(psp->ps_sigonstack, sig)) { + sp = td->td_sigstk.ss_sp + td->td_sigstk.ss_size - + sizeof(struct l_rt_sigframe); + } else + sp = (caddr_t)regs->tf_rsp - sizeof(struct l_rt_sigframe) - 128; + /* Align to 16 bytes. */ + sfp = (struct l_rt_sigframe *)((unsigned long)sp & ~0xFul); + mtx_unlock(&psp->ps_mtx); + + /* Translate the signal. */ + sig = bsd_to_linux_signal(sig); + + /* Save user context. */ + bzero(&sf, sizeof(sf)); + bsd_to_linux_sigset(mask, &sf.sf_sc.uc_sigmask); + bsd_to_linux_sigset(mask, &sf.sf_sc.uc_mcontext.sc_mask); + + sf.sf_sc.uc_stack.ss_sp = PTROUT(td->td_sigstk.ss_sp); + sf.sf_sc.uc_stack.ss_size = td->td_sigstk.ss_size; + sf.sf_sc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK) + ? ((oonstack) ? LINUX_SS_ONSTACK : 0) : LINUX_SS_DISABLE; + PROC_UNLOCK(p); + + sf.sf_sc.uc_mcontext.sc_rdi = regs->tf_rdi; + sf.sf_sc.uc_mcontext.sc_rsi = regs->tf_rsi; + sf.sf_sc.uc_mcontext.sc_rdx = regs->tf_rdx; + sf.sf_sc.uc_mcontext.sc_rbp = regs->tf_rbp; + sf.sf_sc.uc_mcontext.sc_rbx = regs->tf_rbx; + sf.sf_sc.uc_mcontext.sc_rcx = regs->tf_rcx; + sf.sf_sc.uc_mcontext.sc_rax = regs->tf_rax; + sf.sf_sc.uc_mcontext.sc_rip = regs->tf_rip; + sf.sf_sc.uc_mcontext.sc_rsp = regs->tf_rsp; + sf.sf_sc.uc_mcontext.sc_r8 = regs->tf_r8; + sf.sf_sc.uc_mcontext.sc_r9 = regs->tf_r9; + sf.sf_sc.uc_mcontext.sc_r10 = regs->tf_r10; + sf.sf_sc.uc_mcontext.sc_r11 = regs->tf_r11; + sf.sf_sc.uc_mcontext.sc_r12 = regs->tf_r12; + sf.sf_sc.uc_mcontext.sc_r13 = regs->tf_r13; + sf.sf_sc.uc_mcontext.sc_r14 = regs->tf_r14; + sf.sf_sc.uc_mcontext.sc_r15 = regs->tf_r15; + sf.sf_sc.uc_mcontext.sc_cs = regs->tf_cs; + sf.sf_sc.uc_mcontext.sc_rflags = regs->tf_rflags; + sf.sf_sc.uc_mcontext.sc_err = regs->tf_err; + sf.sf_sc.uc_mcontext.sc_trapno = bsd_to_linux_trapcode(code); + sf.sf_sc.uc_mcontext.sc_cr2 = (register_t)ksi->ksi_addr; + + /* Build the argument list for the signal handler. */ + regs->tf_rdi = sig; /* arg 1 in %rdi */ + regs->tf_rax = 0; + regs->tf_rsi = (register_t)&sfp->sf_si; /* arg 2 in %rsi */ + regs->tf_rdx = (register_t)&sfp->sf_sc; /* arg 3 in %rdx */ + + sf.sf_handler = catcher; + /* Fill in POSIX parts */ + ksiginfo_to_lsiginfo(ksi, &sf.sf_si, sig); + + /* + * Copy the sigframe out to the user's stack. + */ + if (copyout(&sf, sfp, sizeof(*sfp)) != 0) { +#ifdef DEBUG + printf("process %ld has trashed its stack\n", (long)p->p_pid); +#endif + PROC_LOCK(p); + sigexit(td, SIGILL); + } + + regs->tf_rsp = (long)sfp; + regs->tf_rip = linux_rt_sigcode; + regs->tf_rflags &= ~(PSL_T | PSL_D); + regs->tf_cs = _ucodesel; + set_pcb_flags(td->td_pcb, PCB_FULL_IRET); + PROC_LOCK(p); + mtx_lock(&psp->ps_mtx); +} + +/* + * If a linux binary is exec'ing something, try this image activator + * first. We override standard shell script execution in order to + * be able to modify the interpreter path. We only do this if a linux + * binary is doing the exec, so we do not create an EXEC module for it. + */ +static int exec_linux_imgact_try(struct image_params *iparams); + +static int +exec_linux_imgact_try(struct image_params *imgp) +{ + const char *head = (const char *)imgp->image_header; + char *rpath; + int error = -1, len; + + /* + * The interpreter for shell scripts run from a linux binary needs + * to be located in /compat/linux if possible in order to recursively + * maintain linux path emulation. + */ + if (((const short *)head)[0] == SHELLMAGIC) { + /* + * Run our normal shell image activator. If it succeeds + * attempt to use the alternate path for the interpreter. + * If an alternate path is found, use our stringspace + * to store it. + */ + if ((error = exec_shell_imgact(imgp)) == 0) { + linux_emul_convpath(FIRST_THREAD_IN_PROC(imgp->proc), + imgp->interpreter_name, UIO_SYSSPACE, + &rpath, 0, AT_FDCWD); + if (rpath != NULL) { + len = strlen(rpath) + 1; + + if (len <= MAXSHELLCMDLEN) + memcpy(imgp->interpreter_name, + rpath, len); + free(rpath, M_TEMP); + } + } + } + return(error); +} + +struct sysentvec elf_linux_sysvec = { + .sv_size = LINUX_SYS_MAXSYSCALL, + .sv_table = linux_sysent, + .sv_mask = 0, + .sv_sigsize = 0, + .sv_sigtbl = NULL, + .sv_errsize = ELAST + 1, + .sv_errtbl = bsd_to_linux_errno, + .sv_transtrap = translate_traps, + .sv_fixup = elf_linux_fixup, + .sv_sendsig = linux_rt_sendsig, + .sv_sigcode = &_binary_linux_locore_o_start, + .sv_szsigcode = &linux_szsigcode, + .sv_prepsyscall = NULL, + .sv_name = "Linux ELF64", + .sv_coredump = elf64_coredump, + .sv_imgact_try = exec_linux_imgact_try, + .sv_minsigstksz = LINUX_MINSIGSTKSZ, + .sv_pagesize = PAGE_SIZE, + .sv_minuser = VM_MIN_ADDRESS, + .sv_maxuser = VM_MAXUSER_ADDRESS, + .sv_usrstack = USRSTACK, + .sv_psstrings = PS_STRINGS, + .sv_stackprot = VM_PROT_ALL, + .sv_copyout_strings = linux_copyout_strings, + .sv_setregs = linux_exec_setregs, + .sv_fixlimit = NULL, + .sv_maxssiz = NULL, + .sv_flags = SV_ABI_LINUX | SV_LP64 | SV_SHP, + .sv_set_syscall_retval = linux_set_syscall_retval, + .sv_fetch_syscall_args = linux_fetch_syscall_args, + .sv_syscallnames = NULL, + .sv_shared_page_base = SHAREDPAGE, + .sv_shared_page_len = PAGE_SIZE, + .sv_schedtail = linux_schedtail, + .sv_thread_detach = linux_thread_detach +}; + +static void +linux_vdso_install(void *param) +{ + + linux_szsigcode = (&_binary_linux_locore_o_end - + &_binary_linux_locore_o_start); + + if (linux_szsigcode > elf_linux_sysvec.sv_shared_page_len) + panic("Linux invalid vdso size\n"); + + __elfN(linux_vdso_fixup)(&elf_linux_sysvec); + + linux_shared_page_obj = __elfN(linux_shared_page_init) + (&linux_shared_page_mapping); + + __elfN(linux_vdso_reloc)(&elf_linux_sysvec, SHAREDPAGE); + + bcopy(elf_linux_sysvec.sv_sigcode, linux_shared_page_mapping, + linux_szsigcode); + elf_linux_sysvec.sv_shared_page_obj = linux_shared_page_obj; + + linux_kplatform = linux_shared_page_mapping + + (linux_platform - (caddr_t)SHAREDPAGE); +} +SYSINIT(elf_linux_vdso_init, SI_SUB_EXEC, SI_ORDER_ANY, + (sysinit_cfunc_t)linux_vdso_install, NULL); + +static void +linux_vdso_deinstall(void *param) +{ + + __elfN(linux_shared_page_fini)(linux_shared_page_obj); +}; +SYSUNINIT(elf_linux_vdso_uninit, SI_SUB_EXEC, SI_ORDER_FIRST, + (sysinit_cfunc_t)linux_vdso_deinstall, NULL); + +static char GNULINUX_ABI_VENDOR[] = "GNU"; +static int GNULINUX_ABI_DESC = 0; + +static boolean_t +linux_trans_osrel(const Elf_Note *note, int32_t *osrel) +{ + const Elf32_Word *desc; + uintptr_t p; + + p = (uintptr_t)(note + 1); + p += roundup2(note->n_namesz, sizeof(Elf32_Addr)); + + desc = (const Elf32_Word *)p; + if (desc[0] != GNULINUX_ABI_DESC) + return (FALSE); + + /* + * For linux we encode osrel as follows (see linux_mib.c): + * VVVMMMIII (version, major, minor), see linux_mib.c. + */ + *osrel = desc[1] * 1000000 + desc[2] * 1000 + desc[3]; + + return (TRUE); +} + +static Elf_Brandnote linux64_brandnote = { + .hdr.n_namesz = sizeof(GNULINUX_ABI_VENDOR), + .hdr.n_descsz = 16, + .hdr.n_type = 1, + .vendor = GNULINUX_ABI_VENDOR, + .flags = BN_TRANSLATE_OSREL, + .trans_osrel = linux_trans_osrel +}; + +static Elf64_Brandinfo linux_glibc2brand = { + .brand = ELFOSABI_LINUX, + .machine = EM_X86_64, + .compat_3_brand = "Linux", + .emul_path = "/compat/linux", + .interp_path = "/lib64/ld-linux-x86-64.so.2", + .sysvec = &elf_linux_sysvec, + .interp_newpath = NULL, + .brand_note = &linux64_brandnote, + .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE +}; + +static Elf64_Brandinfo linux_glibc2brandshort = { + .brand = ELFOSABI_LINUX, + .machine = EM_X86_64, + .compat_3_brand = "Linux", + .emul_path = "/compat/linux", + .interp_path = "/lib64/ld-linux.so.2", + .sysvec = &elf_linux_sysvec, + .interp_newpath = NULL, + .brand_note = &linux64_brandnote, + .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE +}; + +Elf64_Brandinfo *linux_brandlist[] = { + &linux_glibc2brand, + &linux_glibc2brandshort, + NULL +}; + +static int +linux64_elf_modevent(module_t mod, int type, void *data) +{ + Elf64_Brandinfo **brandinfo; + int error; + struct linux_ioctl_handler **lihp; + + error = 0; + + switch(type) { + case MOD_LOAD: + for (brandinfo = &linux_brandlist[0]; *brandinfo != NULL; + ++brandinfo) + if (elf64_insert_brand_entry(*brandinfo) < 0) + error = EINVAL; + if (error == 0) { + SET_FOREACH(lihp, linux_ioctl_handler_set) + linux_ioctl_register_handler(*lihp); + LIST_INIT(&futex_list); + mtx_init(&futex_mtx, "ftllk64", NULL, MTX_DEF); + stclohz = (stathz ? stathz : hz); + if (bootverbose) + printf("Linux x86-64 ELF exec handler installed\n"); + } else + printf("cannot insert Linux x86-64 ELF brand handler\n"); + break; + case MOD_UNLOAD: + for (brandinfo = &linux_brandlist[0]; *brandinfo != NULL; + ++brandinfo) + if (elf64_brand_inuse(*brandinfo)) + error = EBUSY; + if (error == 0) { + for (brandinfo = &linux_brandlist[0]; + *brandinfo != NULL; ++brandinfo) + if (elf64_remove_brand_entry(*brandinfo) < 0) + error = EINVAL; + } + if (error == 0) { + SET_FOREACH(lihp, linux_ioctl_handler_set) + linux_ioctl_unregister_handler(*lihp); + mtx_destroy(&futex_mtx); + if (bootverbose) + printf("Linux ELF exec handler removed\n"); + } else + printf("Could not deinstall ELF interpreter entry\n"); + break; + default: + return (EOPNOTSUPP); + } + return (error); +} + +static moduledata_t linux64_elf_mod = { + "linux64elf", + linux64_elf_modevent, + 0 +}; + +DECLARE_MODULE_TIED(linux64elf, linux64_elf_mod, SI_SUB_EXEC, SI_ORDER_ANY); +MODULE_DEPEND(linux64elf, linux_common, 1, 1, 1); diff --git a/sys/amd64/linux/linux_vdso.lds.s b/sys/amd64/linux/linux_vdso.lds.s new file mode 100644 index 0000000..94f0266 --- /dev/null +++ b/sys/amd64/linux/linux_vdso.lds.s @@ -0,0 +1,69 @@ +/* + * Linker script for 64-bit vDSO. + * Copied from Linux kernel arch/x86/vdso/vdso-layout.lds.S + * + * $FreeBSD$ + */ + +SECTIONS +{ + . = . + SIZEOF_HEADERS; + + .hash : { *(.hash) } :text + .gnu.hash : { *(.gnu.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + + .note : { *(.note.*) } :text :note + + .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr + .eh_frame : { KEEP (*(.eh_frame)) } :text + + .dynamic : { *(.dynamic) } :text :dynamic + + .rodata : { *(.rodata*) } :text + .data : { + *(.data*) + *(.sdata*) + *(.got.plt) *(.got) + *(.gnu.linkonce.d.*) + *(.bss*) + *(.dynbss*) + *(.gnu.linkonce.b.*) + } + + .altinstructions : { *(.altinstructions) } + .altinstr_replacement : { *(.altinstr_replacement) } + + . = ALIGN(0x100); + .text : { *(.test .text*) } :text =0x90909090 +} + +PHDRS +{ + text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */ + dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ + note PT_NOTE FLAGS(4); /* PF_R */ + eh_frame_hdr PT_GNU_EH_FRAME; +} + +VERSION +{ + LINUX_2.6 { + global: + time; + __vdso_time; + gettimeofday; + __vdso_gettimeofday; + getcpu; + __vdso_getcpu; + clock_gettime; + __vdso_clock_gettime; + linux_rt_sigcode; + linux_platform; + local: *; + }; +} diff --git a/sys/amd64/linux/syscalls.conf b/sys/amd64/linux/syscalls.conf new file mode 100644 index 0000000..29f3792 --- /dev/null +++ b/sys/amd64/linux/syscalls.conf @@ -0,0 +1,11 @@ +# $FreeBSD$ +sysnames="linux_syscalls.c" +sysproto="linux_proto.h" +sysproto_h=_LINUX_SYSPROTO_H_ +syshdr="linux_syscall.h" +syssw="linux_sysent.c" +sysmk="/dev/null" +syscallprefix="LINUX_SYS_" +switchname="linux_sysent" +namesname="linux_syscallnames" +systrace="linux_systrace_args.c" diff --git a/sys/amd64/linux/syscalls.master b/sys/amd64/linux/syscalls.master new file mode 100644 index 0000000..d840f88 --- /dev/null +++ b/sys/amd64/linux/syscalls.master @@ -0,0 +1,515 @@ + $FreeBSD$ + +; @(#)syscalls.master 8.1 (Berkeley) 7/19/93 +; System call name/number master file (or rather, slave, from LINUX). +; Processed to create linux_sysent.c, linux_proto.h and linux_syscall.h. + +; Columns: number audit type nargs name alt{name,tag,rtyp}/comments +; number system call number, must be in order +; audit the audit event associated with the system call +; A value of AUE_NULL means no auditing, but it also means that +; there is no audit event for the call at this time. For the +; case where the event exists, but we don't want auditing, the +; event should be #defined to AUE_NULL in audit_kevents.h. +; type one of STD, OBSOL, UNIMPL +; name psuedo-prototype of syscall routine +; If one of the following alts is different, then all appear: +; altname name of system call if different +; alttag name of args struct tag if different from [o]`name'"_args" +; altrtyp return type if not int (bogus - syscalls always return int) +; for UNIMPL/OBSOL, name continues with comments + +; types: +; STD always included +; OBSOL obsolete, not included in system, only specifies name +; UNIMPL not implemented, placeholder only + +#include <sys/param.h> +#include <sys/sysent.h> +#include <sys/sysproto.h> +#include <compat/linux/linux_sysproto.h> +#include <amd64/linux/linux.h> +#include <amd64/linux/linux_proto.h> + +; Isn't pretty, but there seems to be no other way to trap nosys +#define nosys linux_nosys + +; #ifdef's, etc. may be included, and are copied to the output files. + +0 AUE_NULL NOPROTO { int read(int fd, char *buf, \ + u_int nbyte); } +1 AUE_NULL NOPROTO { int write(int fd, char *buf, \ + u_int nbyte); } +2 AUE_OPEN_RWTC STD { int linux_open(char *path, l_int flags, \ + l_int mode); } +3 AUE_CLOSE NOPROTO { int close(int fd); } +4 AUE_STAT STD { int linux_newstat(char *path, \ + struct l_newstat *buf); } +5 AUE_FSTAT STD { int linux_newfstat(l_uint fd, \ + struct l_newstat *buf); } +6 AUE_LSTAT STD { int linux_newlstat(char *path, \ + struct l_newstat *buf); } +7 AUE_POLL NOPROTO { int poll(struct pollfd*, \ + unsigned int nfds, int timeout); } +8 AUE_LSEEK STD { int linux_lseek(l_uint fdes, l_off_t off, \ + l_int whence); } +9 AUE_MMAP STD { int linux_mmap2(l_ulong addr, l_ulong len, \ + l_ulong prot, l_ulong flags, l_ulong fd, \ + l_ulong pgoff); } +10 AUE_MPROTECT STD { int linux_mprotect(caddr_t addr, int len, \ + int prot); } +11 AUE_MUNMAP NOPROTO { int munmap(caddr_t addr, int len); } +12 AUE_NULL STD { int linux_brk(l_ulong dsend); } +13 AUE_NULL STD { int linux_rt_sigaction(l_int sig, \ + l_sigaction_t *act, l_sigaction_t *oact, \ + l_size_t sigsetsize); } +14 AUE_NULL STD { int linux_rt_sigprocmask(l_int how, \ + l_sigset_t *mask, l_sigset_t *omask, \ + l_size_t sigsetsize); } +15 AUE_NULL STD { int linux_rt_sigreturn( \ + struct l_ucontext *ucp); } +16 AUE_IOCTL STD { int linux_ioctl(l_uint fd, l_uint cmd, \ + uintptr_t arg); } +17 AUE_PREAD STD { int linux_pread(l_uint fd, char *buf, \ + l_size_t nbyte, l_loff_t offset); } +18 AUE_PWRITE STD { int linux_pwrite(l_uint fd, char *buf, \ + l_size_t nbyte, l_loff_t offset); } +19 AUE_READV NOPROTO { int readv(int fd, struct iovec *iovp, \ + u_int iovcnt); } +20 AUE_WRITEV NOPROTO { int writev(int fd, struct iovec *iovp, \ + u_int iovcnt); } +21 AUE_ACCESS STD { int linux_access(char *path, l_int amode); } +22 AUE_PIPE STD { int linux_pipe(l_ulong *pipefds); } +23 AUE_SELECT STD { int linux_select(l_int nfds, \ + l_fd_set *readfds, l_fd_set *writefds, \ + l_fd_set *exceptfds, \ + struct l_timeval *timeout); } +24 AUE_NULL NOPROTO { int sched_yield(void); } +25 AUE_NULL STD { int linux_mremap(l_ulong addr, \ + l_ulong old_len, l_ulong new_len, \ + l_ulong flags, l_ulong new_addr); } +26 AUE_MSYNC STD { int linux_msync(l_ulong addr, \ + l_size_t len, l_int fl); } +27 AUE_MINCORE STD { int linux_mincore(l_ulong start, \ + l_size_t len, u_char *vec); } +28 AUE_MADVISE NOPROTO { int madvise(void *addr, size_t len, \ + int behav); } +29 AUE_NULL STD { int linux_shmget(l_key_t key, l_size_t size, \ + l_int shmflg); } +30 AUE_NULL STD { int linux_shmat(l_int shmid, char *shmaddr, \ + l_int shmflg); } +31 AUE_NULL STD { int linux_shmctl(l_int shmid, l_int cmd, \ + struct l_shmid_ds *buf); } +32 AUE_DUP NOPROTO { int dup(u_int fd); } +33 AUE_DUP2 NOPROTO { int dup2(u_int from, u_int to); } +34 AUE_NULL STD { int linux_pause(void); } +35 AUE_NULL STD { int linux_nanosleep( \ + const struct l_timespec *rqtp, \ + struct l_timespec *rmtp); } +36 AUE_GETITIMER STD { int linux_getitimer(l_int which, \ + struct l_itimerval *itv); } +37 AUE_NULL STD { int linux_alarm(l_uint secs); } +38 AUE_SETITIMER STD { int linux_setitimer(l_int which, \ + struct l_itimerval *itv, \ + struct l_itimerval *oitv); } +39 AUE_GETPID STD { int linux_getpid(void); } +40 AUE_SENDFILE STD { int linux_sendfile(int out, int in, \ + l_long *offset, l_size_t count); } +41 AUE_SOCKET STD { int linux_socket(l_int domain, l_int type, \ + l_int protocol); } +42 AUE_CONNECT STD { int linux_connect(l_int s, l_uintptr_t name, \ + l_int namelen); } +43 AUE_ACCEPT STD { int linux_accept(l_int s, l_uintptr_t addr, \ + l_uintptr_t namelen); } +44 AUE_SENDTO STD { int linux_sendto(l_int s, l_uintptr_t msg, \ + l_int len, l_int flags, l_uintptr_t to, \ + l_int tolen); } +45 AUE_RECVFROM STD { int linux_recvfrom(l_int s, l_uintptr_t buf, \ + l_size_t len, l_int flags, l_uintptr_t from, \ + l_uintptr_t fromlen); } +46 AUE_SENDMSG STD { int linux_sendmsg(l_int s, l_uintptr_t msg, \ + l_int flags); } +47 AUE_RECVMSG STD { int linux_recvmsg(l_int s, l_uintptr_t msg, \ + l_int flags); } +48 AUE_NULL STD { int linux_shutdown(l_int s, l_int how); } +49 AUE_BIND STD { int linux_bind(l_int s, l_uintptr_t name, \ + l_int namelen); } +50 AUE_LISTEN STD { int linux_listen(l_int s, l_int backlog); } +51 AUE_GETSOCKNAME STD { int linux_getsockname(l_int s, \ + l_uintptr_t addr, l_uintptr_t namelen); } +52 AUE_GETPEERNAME STD { int linux_getpeername(l_int s, \ + l_uintptr_t addr, l_uintptr_t namelen); } +53 AUE_SOCKETPAIR STD { int linux_socketpair(l_int domain, \ + l_int type, l_int protocol, l_uintptr_t rsv); } +54 AUE_SETSOCKOPT STD { int linux_setsockopt(l_int s, l_int level, \ + l_int optname, l_uintptr_t optval, \ + l_int optlen); } +55 AUE_GETSOCKOPT STD { int linux_getsockopt(l_int s, l_int level, \ + l_int optname, l_uintptr_t optval, \ + l_uintptr_t optlen); } +56 AUE_RFORK STD { int linux_clone(l_int flags, void *stack, \ + void *parent_tidptr, void * child_tidptr, void *tls ); } +57 AUE_FORK STD { int linux_fork(void); } +58 AUE_VFORK STD { int linux_vfork(void); } +59 AUE_EXECVE STD { int linux_execve(char *path, char **argp, \ + char **envp); } +60 AUE_EXIT STD { void linux_exit(int rval); } +61 AUE_WAIT4 STD { int linux_wait4(l_pid_t pid, \ + l_int *status, l_int options, \ + struct rusage *rusage); } +62 AUE_KILL STD { int linux_kill(l_int pid, l_int signum); } +63 AUE_NULL STD { int linux_newuname( \ + struct l_new_utsname *buf); } +64 AUE_NULL STD { int linux_semget(l_key_t key, \ + l_int nsems, l_int semflg); } +65 AUE_NULL STD { int linux_semop(l_int semid, \ + struct l_sembuf *tsops, l_uint nsops); } +66 AUE_NULL STD { int linux_semctl(l_int semid, \ + l_int semnum, l_int cmd, union l_semun arg); } +67 AUE_NULL STD { int linux_shmdt(char *shmaddr); } +68 AUE_NULL STD { int linux_msgget(l_key_t key, l_int msgflg); } +69 AUE_NULL STD { int linux_msgsnd(l_int msqid, \ + struct l_msgbuf *msgp, l_size_t msgsz, \ + l_int msgflg); } +70 AUE_NULL STD { int linux_msgrcv(l_int msqid, \ + struct l_msgbuf *msgp, l_size_t msgsz, \ + l_long msgtyp, l_int msgflg); } +71 AUE_NULL STD { int linux_msgctl(l_int msqid, l_int cmd, \ + struct l_msqid_ds *buf); } +72 AUE_FCNTL STD { int linux_fcntl(l_uint fd, l_uint cmd, \ + l_ulong arg); } +73 AUE_FLOCK NOPROTO { int flock(int fd, int how); } +74 AUE_FSYNC NOPROTO { int fsync(int fd); } +75 AUE_NULL STD { int linux_fdatasync(l_uint fd); } +76 AUE_TRUNCATE STD { int linux_truncate(char *path, \ + l_ulong length); } +77 AUE_FTRUNCATE STD { int linux_ftruncate(l_int fd, l_long length); } +78 AUE_GETDIRENTRIES STD { int linux_getdents(l_uint fd, void *dent, \ + l_uint count); } +79 AUE_GETCWD STD { int linux_getcwd(char *buf, \ + l_ulong bufsize); } +80 AUE_CHDIR STD { int linux_chdir(char *path); } +81 AUE_FCHDIR NOPROTO { int fchdir(int fd); } +82 AUE_RENAME STD { int linux_rename(char *from, char *to); } +83 AUE_MKDIR STD { int linux_mkdir(char *path, l_int mode); } +84 AUE_RMDIR STD { int linux_rmdir(char *path); } +85 AUE_CREAT STD { int linux_creat(char *path, \ + l_int mode); } +86 AUE_LINK STD { int linux_link(char *path, char *to); } +87 AUE_UNLINK STD { int linux_unlink(char *path); } +88 AUE_SYMLINK STD { int linux_symlink(char *path, char *to); } +89 AUE_READLINK STD { int linux_readlink(char *name, char *buf, \ + l_int count); } +90 AUE_CHMOD STD { int linux_chmod(char *path, \ + l_mode_t mode); } +91 AUE_FCHMOD NOPROTO { int fchmod(int fd, int mode); } +92 AUE_LCHOWN STD { int linux_chown(char *path, \ + l_uid_t uid, l_gid_t gid); } +93 AUE_FCHOWN NOPROTO { int fchown(int fd, int uid, int gid); } +94 AUE_LCHOWN STD { int linux_lchown(char *path, l_uid_t uid, \ + l_gid_t gid); } +95 AUE_UMASK NOPROTO { int umask(int newmask); } +96 AUE_NULL NOPROTO { int gettimeofday(struct l_timeval *tp, \ + struct timezone *tzp); } +97 AUE_GETRLIMIT STD { int linux_getrlimit(l_uint resource, \ + struct l_rlimit *rlim); } +98 AUE_GETRUSAGE NOPROTO { int getrusage(int who, struct rusage *rusage); } +99 AUE_NULL STD { int linux_sysinfo(struct l_sysinfo *info); } +100 AUE_NULL STD { int linux_times(struct l_times_argv *buf); } +101 AUE_PTRACE STD { int linux_ptrace(l_long req, l_long pid, \ + l_long addr, l_long data); } +102 AUE_GETUID STD { int linux_getuid(void); } +103 AUE_NULL STD { int linux_syslog(l_int type, char *buf, \ + l_int len); } +104 AUE_GETGID STD { int linux_getgid(void); } +105 AUE_SETUID NOPROTO { int setuid(uid_t uid); } +106 AUE_SETGID NOPROTO { int setgid(gid_t gid); } +107 AUE_GETEUID NOPROTO { int geteuid(void); } +108 AUE_GETEGID NOPROTO { int getegid(void); } +109 AUE_SETPGRP NOPROTO { int setpgid(int pid, int pgid); } +110 AUE_GETPPID STD { int linux_getppid(void); } +111 AUE_GETPGRP NOPROTO { int getpgrp(void); } +112 AUE_SETSID NOPROTO { int setsid(void); } +113 AUE_SETREUID NOPROTO { int setreuid(uid_t ruid, uid_t euid); } +114 AUE_SETREGID NOPROTO { int setregid(gid_t rgid, gid_t egid); } +115 AUE_GETGROUPS STD { int linux_getgroups(l_int gidsetsize, \ + l_gid_t *grouplist); } +116 AUE_SETGROUPS STD { int linux_setgroups(l_int gidsetsize, \ + l_gid_t *grouplist); } +117 AUE_SETRESUID NOPROTO { int setresuid(uid_t ruid, uid_t euid, \ + uid_t suid); } +118 AUE_GETRESUID NOPROTO { int getresuid(uid_t *ruid, uid_t *euid, \ + uid_t *suid); } +119 AUE_SETRESGID NOPROTO { int setresgid(gid_t rgid, gid_t egid, \ + gid_t sgid); } +120 AUE_GETRESGID NOPROTO { int getresgid(gid_t *rgid, gid_t *egid, \ + gid_t *sgid); } +121 AUE_GETPGID NOPROTO { int getpgid(int pid); } +122 AUE_SETFSUID STD { int linux_setfsuid(l_uid_t uid); } +123 AUE_SETFSGID STD { int linux_setfsgid(l_gid_t gid); } +124 AUE_GETSID STD { int linux_getsid(l_pid_t pid); } +125 AUE_CAPGET STD { int linux_capget(struct l_user_cap_header *hdrp, \ + struct l_user_cap_data *datap); } +126 AUE_CAPSET STD { int linux_capset(struct l_user_cap_header *hdrp, \ + struct l_user_cap_data *datap); } +127 AUE_NULL STD { int linux_rt_sigpending(l_sigset_t *set, \ + l_size_t sigsetsize); } +128 AUE_NULL STD { int linux_rt_sigtimedwait(l_sigset_t *mask, \ + l_siginfo_t *ptr, \ + struct l_timeval *timeout, \ + l_size_t sigsetsize); } +129 AUE_NULL STD { int linux_rt_sigqueueinfo(l_pid_t pid, l_int sig, \ + l_siginfo_t *info); } +130 AUE_NULL STD { int linux_rt_sigsuspend( \ + l_sigset_t *newset, \ + l_size_t sigsetsize); } +131 AUE_NULL STD { int linux_sigaltstack(l_stack_t *uss, \ + l_stack_t *uoss); } +132 AUE_UTIME STD { int linux_utime(char *fname, \ + struct l_utimbuf *times); } +133 AUE_MKNOD STD { int linux_mknod(char *path, l_int mode, \ + l_dev_t dev); } +134 AUE_USELIB UNIMPL uselib +135 AUE_PERSONALITY STD { int linux_personality(l_ulong per); } +136 AUE_NULL STD { int linux_ustat(l_dev_t dev, \ + struct l_ustat *ubuf); } +137 AUE_STATFS STD { int linux_statfs(char *path, \ + struct l_statfs_buf *buf); } +138 AUE_FSTATFS STD { int linux_fstatfs(l_uint fd, \ + struct l_statfs_buf *buf); } +139 AUE_NULL STD { int linux_sysfs(l_int option, \ + l_ulong arg1, l_ulong arg2); } +140 AUE_GETPRIORITY STD { int linux_getpriority(int which, int who); } +141 AUE_SETPRIORITY NOPROTO { int setpriority(int which, int who, \ + int prio); } +142 AUE_SCHED_SETPARAM STD { int linux_sched_setparam(l_pid_t pid, \ + struct l_sched_param *param); } +143 AUE_SCHED_GETPARAM STD { int linux_sched_getparam(l_pid_t pid, \ + struct l_sched_param *param); } +144 AUE_SCHED_SETSCHEDULER STD { int linux_sched_setscheduler( \ + l_pid_t pid, l_int policy, \ + struct l_sched_param *param); } +145 AUE_SCHED_GETSCHEDULER STD { int linux_sched_getscheduler( \ + l_pid_t pid); } +146 AUE_SCHED_GET_PRIORITY_MAX STD { int linux_sched_get_priority_max( \ + l_int policy); } +147 AUE_SCHED_GET_PRIORITY_MIN STD { int linux_sched_get_priority_min( \ + l_int policy); } +148 AUE_SCHED_RR_GET_INTERVAL STD { int linux_sched_rr_get_interval(l_pid_t pid, \ + struct l_timespec *interval); } +149 AUE_MLOCK NOPROTO { int mlock(const void *addr, size_t len); } +150 AUE_MUNLOCK NOPROTO { int munlock(const void *addr, size_t len); } +151 AUE_MLOCKALL NOPROTO { int mlockall(int how); } +152 AUE_MUNLOCKALL NOPROTO { int munlockall(void); } +153 AUE_NULL STD { int linux_vhangup(void); } +154 AUE_NULL UNIMPL modify_ldt +155 AUE_PIVOT_ROOT STD { int linux_pivot_root(void); } +156 AUE_SYSCTL STD { int linux_sysctl( \ + struct l___sysctl_args *args); } +157 AUE_PRCTL STD { int linux_prctl(l_int option, l_uintptr_t arg2, \ + l_uintptr_t arg3, l_uintptr_t arg4, \ + l_uintptr_t arg5); } +158 AUE_PRCTL STD { int linux_arch_prctl(l_int code, l_ulong addr); } +159 AUE_ADJTIME STD { int linux_adjtimex(void); } +160 AUE_SETRLIMIT STD { int linux_setrlimit(l_uint resource, \ + struct l_rlimit *rlim); } +161 AUE_CHROOT NOPROTO { int chroot(char *path); } +162 AUE_SYNC NOPROTO { int sync(void); } +163 AUE_ACCT NOPROTO { int acct(char *path); } +164 AUE_SETTIMEOFDAY NOPROTO { int settimeofday(struct l_timeval *tp, struct timezone *tzp); } +165 AUE_MOUNT STD { int linux_mount(char *specialfile, \ + char *dir, char *filesystemtype, \ + l_ulong rwflag, void *data); } +166 AUE_UMOUNT STD { int linux_umount(char *path, l_int flags); } +167 AUE_SWAPON NOPROTO { int swapon(char *name); } +168 AUE_SWAPOFF STD { int linux_swapoff(void); } +169 AUE_REBOOT STD { int linux_reboot(l_int magic1, \ + l_int magic2, l_uint cmd, void *arg); } +170 AUE_SYSCTL STD { int linux_sethostname(char *hostname, \ + l_uint len); } +171 AUE_SYSCTL STD { int linux_setdomainname(char *name, \ + l_int len); } +172 AUE_NULL STD { int linux_iopl(l_uint level); } +173 AUE_NULL UNIMPL ioperm +174 AUE_NULL STD { int linux_create_module(void); } +175 AUE_NULL STD { int linux_init_module(void); } +176 AUE_NULL STD { int linux_delete_module(void); } +177 AUE_NULL STD { int linux_get_kernel_syms(void); } +178 AUE_NULL STD { int linux_query_module(void); } +179 AUE_QUOTACTL STD { int linux_quotactl(void); } +180 AUE_NULL STD { int linux_nfsservctl(void); } +181 AUE_GETPMSG STD { int linux_getpmsg(void); } +182 AUE_PUTPMSG STD { int linux_putpmsg(void); } +183 AUE_NULL STD { int linux_afs_syscall(void); } +184 AUE_NULL STD { int linux_tuxcall(void); } +185 AUE_NULL STD { int linux_security(void); } +186 AUE_NULL STD { int linux_gettid(void); } +187 AUE_NULL UNIMPL linux_readahead +188 AUE_NULL STD { int linux_setxattr(void); } +189 AUE_NULL STD { int linux_lsetxattr(void); } +190 AUE_NULL STD { int linux_fsetxattr(void); } +191 AUE_NULL STD { int linux_getxattr(void); } +192 AUE_NULL STD { int linux_lgetxattr(void); } +193 AUE_NULL STD { int linux_fgetxattr(void); } +194 AUE_NULL STD { int linux_listxattr(void); } +195 AUE_NULL STD { int linux_llistxattr(void); } +196 AUE_NULL STD { int linux_flistxattr(void); } +197 AUE_NULL STD { int linux_removexattr(void); } +198 AUE_NULL STD { int linux_lremovexattr(void); } +199 AUE_NULL STD { int linux_fremovexattr(void); } +200 AUE_NULL STD { int linux_tkill(int tid, int sig); } +201 AUE_NULL STD { int linux_time(l_time_t *tm); } +202 AUE_NULL STD { int linux_sys_futex(void *uaddr, int op, int val, \ + struct l_timespec *timeout, void *uaddr2, int val3); } +203 AUE_NULL STD { int linux_sched_setaffinity(l_pid_t pid, l_uint len, \ + l_ulong *user_mask_ptr); } +204 AUE_NULL STD { int linux_sched_getaffinity(l_pid_t pid, l_uint len, \ + l_ulong *user_mask_ptr); } +205 AUE_NULL STD { int linux_set_thread_area(void); } +206 AUE_NULL UNIMPL linux_io_setup +207 AUE_NULL UNIMPL linux_io_destroy +208 AUE_NULL UNIMPL linux_io_getevents +209 AUE_NULL UNIMPL inux_io_submit +210 AUE_NULL UNIMPL linux_io_cancel +211 AUE_NULL UNIMPL linux_get_thread_area +212 AUE_NULL STD { int linux_lookup_dcookie(void); } +213 AUE_NULL STD { int linux_epoll_create(l_int size); } +214 AUE_NULL STD { int linux_epoll_ctl_old(void); } +215 AUE_NULL STD { int linux_epoll_wait_old(void); } +216 AUE_NULL STD { int linux_remap_file_pages(void); } +217 AUE_GETDIRENTRIES STD { int linux_getdents64(l_uint fd, \ + void *dirent, l_uint count); } +218 AUE_NULL STD { int linux_set_tid_address(int *tidptr); } +219 AUE_NULL UNIMPL restart_syscall +220 AUE_NULL STD { int linux_semtimedop(void); } +221 AUE_NULL STD { int linux_fadvise64(int fd, l_loff_t offset, \ + l_size_t len, int advice); } +222 AUE_NULL STD { int linux_timer_create(clockid_t clock_id, \ + struct sigevent *evp, l_timer_t *timerid); } +223 AUE_NULL STD { int linux_timer_settime(l_timer_t timerid, l_int flags, \ + const struct itimerspec *new, struct itimerspec *old); } +224 AUE_NULL STD { int linux_timer_gettime(l_timer_t timerid, struct itimerspec *setting); } +225 AUE_NULL STD { int linux_timer_getoverrun(l_timer_t timerid); } +226 AUE_NULL STD { int linux_timer_delete(l_timer_t timerid); } +227 AUE_CLOCK_SETTIME STD { int linux_clock_settime(clockid_t which, struct l_timespec *tp); } +228 AUE_NULL STD { int linux_clock_gettime(clockid_t which, struct l_timespec *tp); } +229 AUE_NULL STD { int linux_clock_getres(clockid_t which, struct l_timespec *tp); } +230 AUE_NULL STD { int linux_clock_nanosleep(clockid_t which, int flags, \ + struct l_timespec *rqtp, struct l_timespec *rmtp); } +231 AUE_EXIT STD { int linux_exit_group(int error_code); } +232 AUE_NULL STD { int linux_epoll_wait(l_int epfd, struct epoll_event *events, \ + l_int maxevents, l_int timeout); } +233 AUE_NULL STD { int linux_epoll_ctl(l_int epfd, l_int op, l_int fd, \ + struct epoll_event *event); } +234 AUE_NULL STD { int linux_tgkill(int tgid, int pid, int sig); } +235 AUE_UTIMES STD { int linux_utimes(char *fname, \ + struct l_timeval *tptr); } +236 AUE_NULL UNIMPL vserver +237 AUE_NULL STD { int linux_mbind(void); } +238 AUE_NULL STD { int linux_set_mempolicy(void); } +239 AUE_NULL STD { int linux_get_mempolicy(void); } +240 AUE_NULL STD { int linux_mq_open(void); } +241 AUE_NULL STD { int linux_mq_unlink(void); } +242 AUE_NULL STD { int linux_mq_timedsend(void); } +243 AUE_NULL STD { int linux_mq_timedreceive(void); } +244 AUE_NULL STD { int linux_mq_notify(void); } +245 AUE_NULL STD { int linux_mq_getsetattr(void); } +246 AUE_NULL STD { int linux_kexec_load(void); } +247 AUE_WAIT6 STD { int linux_waitid(int idtype, l_pid_t id, \ + l_siginfo_t *info, int options, \ + struct rusage *rusage); } +248 AUE_NULL STD { int linux_add_key(void); } +249 AUE_NULL STD { int linux_request_key(void); } +250 AUE_NULL STD { int linux_keyctl(void); } +251 AUE_NULL STD { int linux_ioprio_set(void); } +252 AUE_NULL STD { int linux_ioprio_get(void); } +253 AUE_NULL STD { int linux_inotify_init(void); } +254 AUE_NULL STD { int linux_inotify_add_watch(void); } +255 AUE_NULL STD { int linux_inotify_rm_watch(void); } +256 AUE_NULL STD { int linux_migrate_pages(void); } +257 AUE_OPEN_RWTC STD { int linux_openat(l_int dfd, const char *filename, \ + l_int flags, l_int mode); } +258 AUE_MKDIRAT STD { int linux_mkdirat(l_int dfd, const char *pathname, \ + l_int mode); } +259 AUE_MKNODAT STD { int linux_mknodat(l_int dfd, const char *filename, \ + l_int mode, l_uint dev); } +260 AUE_FCHOWNAT STD { int linux_fchownat(l_int dfd, const char *filename, \ + l_uid_t uid, l_gid_t gid, l_int flag); } +261 AUE_FUTIMESAT STD { int linux_futimesat(l_int dfd, char *filename, \ + struct l_timeval *utimes); } +262 AUE_FSTATAT STD { int linux_newfstatat(l_int dfd, char *pathname, \ + struct l_stat64 *statbuf, l_int flag); } +263 AUE_UNLINKAT STD { int linux_unlinkat(l_int dfd, const char *pathname, \ + l_int flag); } +264 AUE_RENAMEAT STD { int linux_renameat(l_int olddfd, const char *oldname, \ + l_int newdfd, const char *newname); } +265 AUE_LINKAT STD { int linux_linkat(l_int olddfd, const char *oldname, \ + l_int newdfd, const char *newname, l_int flag); } +266 AUE_SYMLINKAT STD { int linux_symlinkat(const char *oldname, l_int newdfd, \ + const char *newname); } +267 AUE_READLINKAT STD { int linux_readlinkat(l_int dfd, const char *path, \ + char *buf, l_int bufsiz); } +268 AUE_FCHMODAT STD { int linux_fchmodat(l_int dfd, const char *filename, \ + l_mode_t mode); } +269 AUE_FACCESSAT STD { int linux_faccessat(l_int dfd, const char *filename, \ + l_int amode); } +270 AUE_SELECT STD { int linux_pselect6(l_int nfds, \ + l_fd_set *readfds, l_fd_set *writefds, l_fd_set *exceptfds, \ + struct l_timespec *tsp, l_uintptr_t *sig); } +271 AUE_POLL STD { int linux_ppoll(struct pollfd *fds, uint32_t nfds, \ + struct l_timespec *tsp, l_sigset_t *sset, l_size_t ssize); } +272 AUE_NULL STD { int linux_unshare(void); } +273 AUE_NULL STD { int linux_set_robust_list(struct linux_robust_list_head *head, \ + l_size_t len); } +274 AUE_NULL STD { int linux_get_robust_list(l_int pid, struct linux_robust_list_head *head, \ + l_size_t *len); } +275 AUE_NULL STD { int linux_splice(void); } +276 AUE_NULL STD { int linux_tee(void); } +277 AUE_NULL STD { int linux_sync_file_range(void); } +278 AUE_NULL STD { int linux_vmsplice(void); } +279 AUE_NULL STD { int linux_move_pages(void); } +280 AUE_FUTIMESAT STD { int linux_utimensat(l_int dfd, const char *pathname, \ + const struct l_timespec *times, l_int flags); } +281 AUE_NULL STD { int linux_epoll_pwait(l_int epfd, struct epoll_event *events, \ + l_int maxevents, l_int timeout, l_sigset_t *mask); } +282 AUE_NULL STD { int linux_signalfd(void); } +283 AUE_NULL STD { int linux_timerfd(void); } +284 AUE_NULL STD { int linux_eventfd(l_uint initval); } +285 AUE_NULL STD { int linux_fallocate(l_int fd, l_int mode, \ + l_loff_t offset, l_loff_t len); } +286 AUE_NULL STD { int linux_timerfd_settime(void); } +287 AUE_NULL STD { int linux_timerfd_gettime(void); } +288 AUE_ACCEPT STD { int linux_accept4(l_int s, l_uintptr_t addr, \ + l_uintptr_t namelen, int flags); } +289 AUE_NULL STD { int linux_signalfd4(void); } +290 AUE_NULL STD { int linux_eventfd2(l_uint initval, l_int flags); } +291 AUE_NULL STD { int linux_epoll_create1(l_int flags); } +292 AUE_NULL STD { int linux_dup3(l_int oldfd, \ + l_int newfd, l_int flags); } +293 AUE_NULL STD { int linux_pipe2(l_int *pipefds, l_int flags); } +294 AUE_NULL STD { int linux_inotify_init1(void); } +295 AUE_NULL STD { int linux_preadv(void); } +296 AUE_NULL STD { int linux_pwritev(void); } +297 AUE_NULL STD { int linux_rt_tsigqueueinfo(void); } +298 AUE_NULL STD { int linux_perf_event_open(void); } +299 AUE_NULL STD { int linux_recvmmsg(l_int s, \ + struct l_mmsghdr *msg, l_uint vlen, \ + l_uint flags, struct l_timespec *timeout); } +300 AUE_NULL STD { int linux_fanotify_init(void); } +301 AUE_NULL STD { int linux_fanotify_mark(void); } +302 AUE_NULL STD { int linux_prlimit64(l_pid_t pid, l_uint resource, \ + struct rlimit *new, struct rlimit *old); } +303 AUE_NULL STD { int linux_name_to_handle_at(void); } +304 AUE_NULL STD { int linux_open_by_handle_at(void); } +305 AUE_NULL STD { int linux_clock_adjtime(void); } +306 AUE_SYNC STD { int linux_syncfs(l_int fd); } +307 AUE_NULL STD { int linux_sendmmsg(l_int s, \ + struct l_mmsghdr *msg, l_uint vlen, \ + l_uint flags); } +308 AUE_NULL STD { int linux_setns(void); } +309 AUE_NULL STD { int linux_process_vm_readv(void); } +310 AUE_NULL STD { int linux_process_vm_writev(void); } +311 AUE_NULL STD { int linux_kcmp(void); } +312 AUE_NULL STD { int linux_finit_module(void); } +; please, keep this line at the end. +313 AUE_NULL UNIMPL nosys diff --git a/sys/amd64/linux32/linux.h b/sys/amd64/linux32/linux.h index 39c17c8..e3b9f11 100644 --- a/sys/amd64/linux32/linux.h +++ b/sys/amd64/linux32/linux.h @@ -33,6 +33,7 @@ #ifndef _AMD64_LINUX_H_ #define _AMD64_LINUX_H_ +#include <compat/linux/linux.h> #include <amd64/linux32/linux32_syscall.h> /* @@ -40,14 +41,12 @@ */ extern u_char linux_debug_map[]; #define ldebug(name) isclr(linux_debug_map, LINUX_SYS_linux_ ## name) -#define ARGS(nm, fmt) "linux(%ld): "#nm"("fmt")\n", (long)td->td_proc->p_pid -#define LMSG(fmt) "linux(%ld): "fmt"\n", (long)td->td_proc->p_pid +#define ARGS(nm, fmt) "linux(%ld/%ld): "#nm"("fmt")\n", \ + (long)td->td_proc->p_pid, (long)td->td_tid +#define LMSG(fmt) "linux(%ld/%ld): "fmt"\n", \ + (long)td->td_proc->p_pid, (long)td->td_tid #define LINUX_DTRACE linuxulator32 -#ifdef MALLOC_DECLARE -MALLOC_DECLARE(M_LINUX); -#endif - #define LINUX32_MAXUSER ((1ul << 32) - PAGE_SIZE) #define LINUX32_SHAREDPAGE (LINUX32_MAXUSER - PAGE_SIZE) #define LINUX32_USRSTACK LINUX32_SHAREDPAGE @@ -97,6 +96,7 @@ typedef l_uint l_uid_t; typedef l_ushort l_uid16_t; typedef l_int l_timer_t; typedef l_int l_mqd_t; +typedef l_ulong l_fd_mask; typedef struct { l_int val[2]; @@ -112,7 +112,7 @@ typedef struct { /* * Miscellaneous */ -#define LINUX_AT_COUNT 16 /* Count of used aux entry types. +#define LINUX_AT_COUNT 20 /* Count of used aux entry types. * Keep this synchronized with * elf_linux_fixup() code. */ @@ -260,49 +260,6 @@ struct l_statfs64 { l_int f_spare[6]; } __packed; -/* - * Signalling - */ -#define LINUX_SIGHUP 1 -#define LINUX_SIGINT 2 -#define LINUX_SIGQUIT 3 -#define LINUX_SIGILL 4 -#define LINUX_SIGTRAP 5 -#define LINUX_SIGABRT 6 -#define LINUX_SIGIOT LINUX_SIGABRT -#define LINUX_SIGBUS 7 -#define LINUX_SIGFPE 8 -#define LINUX_SIGKILL 9 -#define LINUX_SIGUSR1 10 -#define LINUX_SIGSEGV 11 -#define LINUX_SIGUSR2 12 -#define LINUX_SIGPIPE 13 -#define LINUX_SIGALRM 14 -#define LINUX_SIGTERM 15 -#define LINUX_SIGSTKFLT 16 -#define LINUX_SIGCHLD 17 -#define LINUX_SIGCONT 18 -#define LINUX_SIGSTOP 19 -#define LINUX_SIGTSTP 20 -#define LINUX_SIGTTIN 21 -#define LINUX_SIGTTOU 22 -#define LINUX_SIGURG 23 -#define LINUX_SIGXCPU 24 -#define LINUX_SIGXFSZ 25 -#define LINUX_SIGVTALRM 26 -#define LINUX_SIGPROF 27 -#define LINUX_SIGWINCH 28 -#define LINUX_SIGIO 29 -#define LINUX_SIGPOLL LINUX_SIGIO -#define LINUX_SIGPWR 30 -#define LINUX_SIGSYS 31 -#define LINUX_SIGRTMIN 32 - -#define LINUX_SIGTBLSZ 31 -#define LINUX_NSIG_WORDS 2 -#define LINUX_NBPW 32 -#define LINUX_NSIG (LINUX_NBPW * LINUX_NSIG_WORDS) - /* sigaction flags */ #define LINUX_SA_NOCLDSTOP 0x00000001 #define LINUX_SA_NOCLDWAIT 0x00000002 @@ -319,27 +276,13 @@ struct l_statfs64 { #define LINUX_SIG_UNBLOCK 1 #define LINUX_SIG_SETMASK 2 -/* sigset_t macros */ -#define LINUX_SIGEMPTYSET(set) (set).__bits[0] = (set).__bits[1] = 0 -#define LINUX_SIGISMEMBER(set, sig) SIGISMEMBER(set, sig) -#define LINUX_SIGADDSET(set, sig) SIGADDSET(set, sig) - /* sigaltstack */ #define LINUX_MINSIGSTKSZ 2048 -#define LINUX_SS_ONSTACK 1 -#define LINUX_SS_DISABLE 2 - -int linux_to_bsd_sigaltstack(int lsa); -int bsd_to_linux_sigaltstack(int bsa); typedef l_uintptr_t l_handler_t; typedef l_ulong l_osigset_t; typedef struct { - l_uint __bits[LINUX_NSIG_WORDS]; -} __packed l_sigset_t; - -typedef struct { l_handler_t lsa_handler; l_osigset_t lsa_mask; l_ulong lsa_flags; @@ -508,7 +451,7 @@ struct l_sigframe { l_int sf_sig; struct l_sigcontext sf_sc; struct l_fpstate sf_fpstate; - l_uint sf_extramask[LINUX_NSIG_WORDS-1]; + l_uint sf_extramask[1]; l_handler_t sf_handler; } __packed; @@ -521,50 +464,13 @@ struct l_rt_sigframe { l_handler_t sf_handler; } __packed; -extern struct sysentvec elf_linux_sysvec; - /* - * open/fcntl flags + * arch specific open/fcntl flags */ -#define LINUX_O_RDONLY 00000000 -#define LINUX_O_WRONLY 00000001 -#define LINUX_O_RDWR 00000002 -#define LINUX_O_ACCMODE 00000003 -#define LINUX_O_CREAT 00000100 -#define LINUX_O_EXCL 00000200 -#define LINUX_O_NOCTTY 00000400 -#define LINUX_O_TRUNC 00001000 -#define LINUX_O_APPEND 00002000 -#define LINUX_O_NONBLOCK 00004000 -#define LINUX_O_NDELAY LINUX_O_NONBLOCK -#define LINUX_O_SYNC 00010000 -#define LINUX_FASYNC 00020000 -#define LINUX_O_DIRECT 00040000 /* Direct disk access hint */ -#define LINUX_O_LARGEFILE 00100000 -#define LINUX_O_DIRECTORY 00200000 /* Must be a directory */ -#define LINUX_O_NOFOLLOW 00400000 /* Do not follow links */ -#define LINUX_O_NOATIME 01000000 -#define LINUX_O_CLOEXEC 02000000 - -#define LINUX_F_DUPFD 0 -#define LINUX_F_GETFD 1 -#define LINUX_F_SETFD 2 -#define LINUX_F_GETFL 3 -#define LINUX_F_SETFL 4 -#define LINUX_F_GETLK 5 -#define LINUX_F_SETLK 6 -#define LINUX_F_SETLKW 7 -#define LINUX_F_SETOWN 8 -#define LINUX_F_GETOWN 9 - #define LINUX_F_GETLK64 12 #define LINUX_F_SETLK64 13 #define LINUX_F_SETLKW64 14 -#define LINUX_F_RDLCK 0 -#define LINUX_F_WRLCK 1 -#define LINUX_F_UNLCK 2 - union l_semun { l_int val; l_uintptr_t buf; @@ -573,6 +479,16 @@ union l_semun { l_uintptr_t __pad; } __packed; +struct l_ipc_perm { + l_key_t key; + l_uid16_t uid; + l_gid16_t gid; + l_uid16_t cuid; + l_gid16_t cgid; + l_ushort mode; + l_ushort seq; +}; + /* * Socket defines */ @@ -609,22 +525,6 @@ struct l_sockaddr { char sa_data[14]; } __packed; -struct l_msghdr { - l_uintptr_t msg_name; - l_int msg_namelen; - l_uintptr_t msg_iov; - l_size_t msg_iovlen; - l_uintptr_t msg_control; - l_size_t msg_controllen; - l_uint msg_flags; -}; - -struct l_cmsghdr { - l_size_t cmsg_len; - l_int cmsg_level; - l_int cmsg_type; -}; - struct l_ifmap { l_ulong mem_start; l_ulong mem_end; @@ -778,6 +678,7 @@ struct l_iovec32 { int linux32_copyiniov(struct l_iovec32 *iovp32, l_ulong iovcnt, struct iovec **iovp, int error); +int linux_copyout_rusage(struct rusage *ru, void *uaddr); /* robust futexes */ struct linux_robust_list { diff --git a/sys/amd64/linux32/linux32_dummy.c b/sys/amd64/linux32/linux32_dummy.c index c36d519..de8b620 100644 --- a/sys/amd64/linux32/linux32_dummy.c +++ b/sys/amd64/linux32/linux32_dummy.c @@ -62,7 +62,6 @@ DUMMY(bdflush); DUMMY(sysfs); DUMMY(query_module); DUMMY(nfsservctl); -DUMMY(rt_sigqueueinfo); DUMMY(sendfile); DUMMY(setfsuid); DUMMY(setfsgid); @@ -70,9 +69,6 @@ DUMMY(pivot_root); DUMMY(mincore); DUMMY(ptrace); DUMMY(lookup_dcookie); -DUMMY(epoll_create); -DUMMY(epoll_ctl); -DUMMY(epoll_wait); DUMMY(remap_file_pages); DUMMY(fstatfs64); DUMMY(mbind); @@ -85,7 +81,6 @@ DUMMY(mq_timedreceive); DUMMY(mq_notify); DUMMY(mq_getsetattr); DUMMY(kexec_load); -DUMMY(waitid); /* linux 2.6.11: */ DUMMY(add_key); DUMMY(request_key); @@ -98,8 +93,6 @@ DUMMY(inotify_add_watch); DUMMY(inotify_rm_watch); /* linux 2.6.16: */ DUMMY(migrate_pages); -DUMMY(pselect6); -DUMMY(ppoll); DUMMY(unshare); /* linux 2.6.17: */ DUMMY(splice); @@ -110,22 +103,14 @@ DUMMY(vmsplice); DUMMY(move_pages); /* linux 2.6.19: */ DUMMY(getcpu); -DUMMY(epoll_pwait); /* linux 2.6.22: */ -DUMMY(utimensat); DUMMY(signalfd); DUMMY(timerfd_create); -DUMMY(eventfd); -/* linux 2.6.23: */ -DUMMY(fallocate); /* linux 2.6.25: */ DUMMY(timerfd_settime); DUMMY(timerfd_gettime); /* linux 2.6.27: */ DUMMY(signalfd4); -DUMMY(eventfd2); -DUMMY(epoll_create1); -DUMMY(dup3); DUMMY(inotify_init1); /* linux 2.6.30: */ DUMMY(preadv); @@ -134,17 +119,12 @@ DUMMY(pwritev); DUMMY(rt_tsigqueueinfo); DUMMY(perf_event_open); /* linux 2.6.33: */ -DUMMY(recvmmsg); DUMMY(fanotify_init); DUMMY(fanotify_mark); -/* linux 2.6.36: */ -DUMMY(prlimit64); /* later: */ DUMMY(name_to_handle_at); DUMMY(open_by_handle_at); DUMMY(clock_adjtime); -DUMMY(syncfs); -DUMMY(sendmmsg); DUMMY(setns); DUMMY(process_vm_readv); DUMMY(process_vm_writev); diff --git a/sys/amd64/linux32/linux32_genassym.c b/sys/amd64/linux32/linux32_genassym.c index a022fac..bc94139 100644 --- a/sys/amd64/linux32/linux32_genassym.c +++ b/sys/amd64/linux32/linux32_genassym.c @@ -3,12 +3,16 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/assym.h> +#include <sys/resource.h> #include <sys/systm.h> #include <amd64/linux32/linux.h> +#include <compat/linux/linux_mib.h> ASSYM(LINUX_SIGF_HANDLER, offsetof(struct l_sigframe, sf_handler)); ASSYM(LINUX_SIGF_SC, offsetof(struct l_sigframe, sf_sc)); ASSYM(LINUX_RT_SIGF_HANDLER, offsetof(struct l_rt_sigframe, sf_handler)); ASSYM(LINUX_RT_SIGF_UC, offsetof(struct l_rt_sigframe, sf_sc)); ASSYM(LINUX_RT_SIGF_SC, offsetof(struct l_ucontext, uc_mcontext)); +ASSYM(LINUX_VERSION_CODE, LINUX_VERSION_CODE); +ASSYM(LINUX_SC_ESP, offsetof(struct l_sigcontext, sc_esp)); diff --git a/sys/amd64/linux32/linux32_locore.s b/sys/amd64/linux32/linux32_locore.s index 36e1abf..4edbdf3 100644 --- a/sys/amd64/linux32/linux32_locore.s +++ b/sys/amd64/linux32/linux32_locore.s @@ -5,34 +5,152 @@ #include <amd64/linux32/linux32_syscall.h> /* system call numbers */ +.data + + .globl linux_platform +linux_platform: + .asciz "i686" + .text .code32 -NON_GPROF_ENTRY(linux_sigcode) - call *LINUX_SIGF_HANDLER(%esp) - leal LINUX_SIGF_SC(%esp),%ebx /* linux scp */ - movl %esp, %ebx /* pass sigframe */ - push %eax /* fake ret addr */ +/* + * To avoid excess stack frame the signal trampoline code emulates + * the 'call' instruction. + */ +NON_GPROF_ENTRY(linux32_sigcode) + movl %esp, %ebx /* preserve sigframe */ + call .getip0 +.getip0: + popl %eax + add $.startsigcode-.getip0, %eax /* ret address */ + push %eax + jmp *LINUX_SIGF_HANDLER(%ebx) +.startsigcode: + popl %eax movl $LINUX_SYS_linux_sigreturn,%eax /* linux_sigreturn() */ int $0x80 /* enter kernel with args */ +.endsigcode: 0: jmp 0b - ALIGN_TEXT -/* XXXXX */ -linux_rt_sigcode: - call *LINUX_RT_SIGF_HANDLER(%esp) + +NON_GPROF_ENTRY(linux32_rt_sigcode) leal LINUX_RT_SIGF_UC(%esp),%ebx /* linux ucp */ leal LINUX_RT_SIGF_SC(%ebx),%ecx /* linux sigcontext */ - push %eax /* fake ret addr */ + movl %esp, %edi + call .getip1 +.getip1: + popl %eax + add $.startrtsigcode-.getip1, %eax /* ret address */ + push %eax + jmp *LINUX_RT_SIGF_HANDLER(%edi) +.startrtsigcode: movl $LINUX_SYS_linux_rt_sigreturn,%eax /* linux_rt_sigreturn() */ int $0x80 /* enter kernel with args */ +.endrtsigcode: 0: jmp 0b - ALIGN_TEXT -/* XXXXX */ -linux_esigcode: - - .data - .globl linux_szsigcode, linux_sznonrtsigcode -linux_szsigcode: - .long linux_esigcode-linux_sigcode -linux_sznonrtsigcode: - .long linux_rt_sigcode-linux_sigcode + +NON_GPROF_ENTRY(linux32_vsyscall) +.startvsyscall: + int $0x80 + ret +.endvsyscall: + +#if 0 + .section .note.Linux, "a",@note + .long 2f - 1f /* namesz */ + .balign 4 + .long 4f - 3f /* descsz */ + .long 0 +1: + .asciz "Linux" +2: + .balign 4 +3: + .long LINUX_VERSION_CODE +4: + .balign 4 + .previous +#endif + +#define do_cfa_expr(offset) \ + .byte 0x0f; /* DW_CFA_def_cfa_expression */ \ + .uleb128 11f-10f; /* length */ \ +10: .byte 0x74; /* DW_OP_breg4 */ \ + .sleb128 offset; /* offset */ \ + .byte 0x06; /* DW_OP_deref */ \ +11: + + + /* CIE */ + .section .eh_frame,"a",@progbits +.LSTARTFRAMEDLSI1: + .long .LENDCIEDLSI1-.LSTARTCIEDLSI1 +.LSTARTCIEDLSI1: + .long 0 /* CIE ID */ + .byte 1 /* Version number */ + .string "zRS" /* NULL-terminated + * augmentation string + */ + .uleb128 1 /* Code alignment factor */ + .sleb128 -4 /* Data alignment factor */ + .byte 8 /* Return address + * register column + */ + .uleb128 1 /* Augmentation value length */ + .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */ + .byte 0 /* DW_CFA_nop */ + .align 4 +.LENDCIEDLSI1: + + /* FDE */ + .long .LENDFDEDLSI1-.LSTARTFDEDLSI1 /* Length FDE */ +.LSTARTFDEDLSI1: + .long .LSTARTFDEDLSI1-.LSTARTFRAMEDLSI1 /* CIE pointer */ + .long .startsigcode-. /* PC-relative start address */ + .long .endsigcode-.startsigcode + .uleb128 0 /* Augmentation */ + do_cfa_expr(LINUX_SIGF_SC-8) + .align 4 +.LENDFDEDLSI1: + + .long .LENDFDEDLSI2-.LSTARTFDEDLSI2 /* Length FDE */ +.LSTARTFDEDLSI2: + .long .LSTARTFDEDLSI2-.LSTARTFRAMEDLSI1 /* CIE pointer */ + .long .startrtsigcode-. /* PC-relative start address */ + .long .endrtsigcode-.startrtsigcode + .uleb128 0 /* Augmentation */ + do_cfa_expr(LINUX_RT_SIGF_SC-4+LINUX_SC_ESP) + .align 4 +.LENDFDEDLSI2: + .previous + + .section .eh_frame,"a",@progbits +.LSTARTFRAMEDLSI2: + .long .LENDCIEDLSI2-.LSTARTCIEDLSI2 +.LSTARTCIEDLSI2: + .long 0 /* CIE ID */ + .byte 1 /* Version number */ + .string "zR" /* NULL-terminated + * augmentation string + */ + .uleb128 1 /* Code alignment factor */ + .sleb128 -4 /* Data alignment factor */ + .byte 8 /* Return address register column */ + .uleb128 1 /* Augmentation value length */ + .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */ + .byte 0x0c /* DW_CFA_def_cfa */ + .uleb128 4 + .uleb128 4 + .byte 0x88 /* DW_CFA_offset, column 0x8 */ + .uleb128 1 + .align 4 +.LENDCIEDLSI2: + .long .LENDFDEDLSI3-.LSTARTFDEDLSI3 /* Length FDE */ +.LSTARTFDEDLSI3: + .long .LSTARTFDEDLSI3-.LSTARTFRAMEDLSI2 /* CIE pointer */ + .long .startvsyscall-. /* PC-relative start address */ + .long .endvsyscall-.startvsyscall + .uleb128 0 + .align 4 +.LENDFDEDLSI3: + .previous diff --git a/sys/amd64/linux32/linux32_machdep.c b/sys/amd64/linux32/linux32_machdep.c index 87a24fb..b38afb3 100644 --- a/sys/amd64/linux32/linux32_machdep.c +++ b/sys/amd64/linux32/linux32_machdep.c @@ -31,6 +31,8 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include "opt_compat.h" + #include <sys/param.h> #include <sys/kernel.h> #include <sys/systm.h> @@ -48,7 +50,6 @@ __FBSDID("$FreeBSD$"); #include <sys/proc.h> #include <sys/resource.h> #include <sys/resourcevar.h> -#include <sys/sched.h> #include <sys/syscallsubr.h> #include <sys/sysproto.h> #include <sys/unistd.h> @@ -73,6 +74,8 @@ __FBSDID("$FreeBSD$"); #include <compat/linux/linux_util.h> #include <compat/linux/linux_emul.h> +static void bsd_to_linux_rusage(struct rusage *ru, struct l_rusage *lru); + struct l_old_select_argv { l_int nfds; l_uintptr_t readfds; @@ -81,34 +84,10 @@ struct l_old_select_argv { l_uintptr_t timeout; } __packed; -int -linux_to_bsd_sigaltstack(int lsa) -{ - int bsa = 0; - - if (lsa & LINUX_SS_DISABLE) - bsa |= SS_DISABLE; - if (lsa & LINUX_SS_ONSTACK) - bsa |= SS_ONSTACK; - return (bsa); -} - static int linux_mmap_common(struct thread *td, l_uintptr_t addr, l_size_t len, l_int prot, l_int flags, l_int fd, l_loff_t pos); -int -bsd_to_linux_sigaltstack(int bsa) -{ - int lsa = 0; - - if (bsa & SS_DISABLE) - lsa |= LINUX_SS_DISABLE; - if (bsa & SS_ONSTACK) - lsa |= LINUX_SS_ONSTACK; - return (lsa); -} - static void bsd_to_linux_rusage(struct rusage *ru, struct l_rusage *lru) { @@ -134,10 +113,19 @@ bsd_to_linux_rusage(struct rusage *ru, struct l_rusage *lru) } int +linux_copyout_rusage(struct rusage *ru, void *uaddr) +{ + struct l_rusage lru; + + bsd_to_linux_rusage(ru, &lru); + + return (copyout(&lru, uaddr, sizeof(struct l_rusage))); +} + +int linux_execve(struct thread *td, struct linux_execve_args *args) { struct image_args eargs; - struct vmspace *oldvmspace; char *path; int error; @@ -148,26 +136,11 @@ linux_execve(struct thread *td, struct linux_execve_args *args) printf(ARGS(execve, "%s"), path); #endif - error = pre_execve(td, &oldvmspace); - if (error != 0) { - free(path, M_TEMP); - return (error); - } error = freebsd32_exec_copyin_args(&eargs, path, UIO_SYSSPACE, args->argp, args->envp); free(path, M_TEMP); if (error == 0) - error = kern_execve(td, &eargs, NULL); - if (error == 0) { - /* Linux process can execute FreeBSD one, do not attempt - * to create emuldata for such process using - * linux_proc_init, this leads to a panic on KASSERT - * because such process has p->p_emuldata == NULL. - */ - if (SV_PROC_ABI(td->td_proc) == SV_ABI_LINUX) - error = linux_proc_init(td, 0, 0); - } - post_execve(td, error, oldvmspace); + error = linux_common_execve(td, &eargs); return (error); } @@ -464,8 +437,14 @@ int linux_set_upcall_kse(struct thread *td, register_t stack) { - td->td_frame->tf_rsp = stack; + if (stack) + td->td_frame->tf_rsp = stack; + /* + * The newly created Linux thread returns + * to the user space by the same path that a parent do. + */ + td->td_frame->tf_rax = 0; return (0); } @@ -728,7 +707,7 @@ linux_sigaction(struct thread *td, struct linux_sigaction_args *args) act.lsa_flags = osa.lsa_flags; act.lsa_restorer = osa.lsa_restorer; LINUX_SIGEMPTYSET(act.lsa_mask); - act.lsa_mask.__bits[0] = osa.lsa_mask; + act.lsa_mask.__mask = osa.lsa_mask; } error = linux_do_sigaction(td, args->sig, args->nsa ? &act : NULL, @@ -738,7 +717,7 @@ linux_sigaction(struct thread *td, struct linux_sigaction_args *args) osa.lsa_handler = oact.lsa_handler; osa.lsa_flags = oact.lsa_flags; osa.lsa_restorer = oact.lsa_restorer; - osa.lsa_mask = oact.lsa_mask.__bits[0]; + osa.lsa_mask = oact.lsa_mask.__mask; error = copyout(&osa, args->osa, sizeof(l_osigaction_t)); } @@ -762,7 +741,7 @@ linux_sigsuspend(struct thread *td, struct linux_sigsuspend_args *args) #endif LINUX_SIGEMPTYSET(mask); - mask.__bits[0] = args->mask; + mask.__mask = args->mask; linux_to_bsd_sigset(&mask, &sigmask); return (kern_sigsuspend(td, sigmask)); } @@ -909,37 +888,18 @@ linux_settimeofday(struct thread *td, struct linux_settimeofday_args *uap) int linux_getrusage(struct thread *td, struct linux_getrusage_args *uap) { - struct l_rusage s32; struct rusage s; int error; error = kern_getrusage(td, uap->who, &s); if (error != 0) return (error); - if (uap->rusage != NULL) { - bsd_to_linux_rusage(&s, &s32); - error = copyout(&s32, uap->rusage, sizeof(s32)); - } + if (uap->rusage != NULL) + error = linux_copyout_rusage(&s, uap->rusage); return (error); } int -linux_sched_rr_get_interval(struct thread *td, - struct linux_sched_rr_get_interval_args *uap) -{ - struct timespec ts; - struct l_timespec ts32; - int error; - - error = kern_sched_rr_get_interval(td, uap->pid, &ts); - if (error != 0) - return (error); - ts32.tv_sec = ts.tv_sec; - ts32.tv_nsec = ts.tv_nsec; - return (copyout(&ts32, uap->interval, sizeof(ts32))); -} - -int linux_set_thread_area(struct thread *td, struct linux_set_thread_area_args *args) { @@ -1041,37 +1001,3 @@ linux_set_thread_area(struct thread *td, return (0); } - -int -linux_wait4(struct thread *td, struct linux_wait4_args *args) -{ - int error, options; - struct rusage ru, *rup; - struct l_rusage lru; - -#ifdef DEBUG - if (ldebug(wait4)) - printf(ARGS(wait4, "%d, %p, %d, %p"), - args->pid, (void *)args->status, args->options, - (void *)args->rusage); -#endif - - options = (args->options & (WNOHANG | WUNTRACED)); - /* WLINUXCLONE should be equal to __WCLONE, but we make sure */ - if (args->options & __WCLONE) - options |= WLINUXCLONE; - - if (args->rusage != NULL) - rup = &ru; - else - rup = NULL; - error = linux_common_wait(td, args->pid, args->status, options, rup); - if (error) - return (error); - if (args->rusage != NULL) { - bsd_to_linux_rusage(rup, &lru); - error = copyout(&lru, args->rusage, sizeof(lru)); - } - - return (error); -} diff --git a/sys/amd64/linux32/linux32_proto.h b/sys/amd64/linux32/linux32_proto.h index cdc5148..09c63c9 100644 --- a/sys/amd64/linux32/linux32_proto.h +++ b/sys/amd64/linux32/linux32_proto.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: stable/10/sys/amd64/linux32/syscalls.master 276810 2015-01-08 06:23:11Z dchagin + * created from FreeBSD: stable/10/sys/amd64/linux32/syscalls.master 293592 2016-01-09 17:54:37Z dchagin */ #ifndef _LINUX_SYSPROTO_H_ @@ -35,6 +35,9 @@ struct thread; #endif #define nosys linux_nosys +struct linux_exit_args { + char rval_l_[PADL_(int)]; int rval; char rval_r_[PADR_(int)]; +}; struct linux_fork_args { register_t dummy; }; @@ -475,6 +478,14 @@ struct linux_fdatasync_args { struct linux_sysctl_args { char args_l_[PADL_(struct l___sysctl_args *)]; struct l___sysctl_args * args; char args_r_[PADR_(struct l___sysctl_args *)]; }; +struct linux_sched_setparam_args { + char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)]; + char param_l_[PADL_(struct l_sched_param *)]; struct l_sched_param * param; char param_r_[PADR_(struct l_sched_param *)]; +}; +struct linux_sched_getparam_args { + char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)]; + char param_l_[PADL_(struct l_sched_param *)]; struct l_sched_param * param; char param_r_[PADR_(struct l_sched_param *)]; +}; struct linux_sched_setscheduler_args { char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)]; char policy_l_[PADL_(l_int)]; l_int policy; char policy_r_[PADR_(l_int)]; @@ -563,7 +574,9 @@ struct linux_rt_sigtimedwait_args { char sigsetsize_l_[PADL_(l_size_t)]; l_size_t sigsetsize; char sigsetsize_r_[PADR_(l_size_t)]; }; struct linux_rt_sigqueueinfo_args { - register_t dummy; + char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)]; + char sig_l_[PADL_(l_int)]; l_int sig; char sig_r_[PADR_(l_int)]; + char info_l_[PADL_(l_siginfo_t *)]; l_siginfo_t * info; char info_r_[PADR_(l_siginfo_t *)]; }; struct linux_rt_sigsuspend_args { char newset_l_[PADL_(l_sigset_t *)]; l_sigset_t * newset; char newset_r_[PADR_(l_sigset_t *)]; @@ -766,13 +779,19 @@ struct linux_lookup_dcookie_args { register_t dummy; }; struct linux_epoll_create_args { - register_t dummy; + char size_l_[PADL_(l_int)]; l_int size; char size_r_[PADR_(l_int)]; }; struct linux_epoll_ctl_args { - register_t dummy; + char epfd_l_[PADL_(l_int)]; l_int epfd; char epfd_r_[PADR_(l_int)]; + char op_l_[PADL_(l_int)]; l_int op; char op_r_[PADR_(l_int)]; + char fd_l_[PADL_(l_int)]; l_int fd; char fd_r_[PADR_(l_int)]; + char event_l_[PADL_(struct epoll_event *)]; struct epoll_event * event; char event_r_[PADR_(struct epoll_event *)]; }; struct linux_epoll_wait_args { - register_t dummy; + char epfd_l_[PADL_(l_int)]; l_int epfd; char epfd_r_[PADR_(l_int)]; + char events_l_[PADL_(struct epoll_event *)]; struct epoll_event * events; char events_r_[PADR_(struct epoll_event *)]; + char maxevents_l_[PADL_(l_int)]; l_int maxevents; char maxevents_r_[PADR_(l_int)]; + char timeout_l_[PADL_(l_int)]; l_int timeout; char timeout_r_[PADR_(l_int)]; }; struct linux_remap_file_pages_args { register_t dummy; @@ -873,7 +892,11 @@ struct linux_kexec_load_args { register_t dummy; }; struct linux_waitid_args { - register_t dummy; + char idtype_l_[PADL_(int)]; int idtype; char idtype_r_[PADR_(int)]; + char id_l_[PADL_(l_pid_t)]; l_pid_t id; char id_r_[PADR_(l_pid_t)]; + char info_l_[PADL_(l_siginfo_t *)]; l_siginfo_t * info; char info_r_[PADR_(l_siginfo_t *)]; + char options_l_[PADL_(int)]; int options; char options_r_[PADR_(int)]; + char rusage_l_[PADL_(struct l_rusage *)]; struct l_rusage * rusage; char rusage_r_[PADR_(struct l_rusage *)]; }; struct linux_add_key_args { register_t dummy; @@ -975,13 +998,21 @@ struct linux_faccessat_args { char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)]; char filename_l_[PADL_(const char *)]; const char * filename; char filename_r_[PADR_(const char *)]; char amode_l_[PADL_(l_int)]; l_int amode; char amode_r_[PADR_(l_int)]; - char flag_l_[PADL_(int)]; int flag; char flag_r_[PADR_(int)]; }; struct linux_pselect6_args { - register_t dummy; + char nfds_l_[PADL_(l_int)]; l_int nfds; char nfds_r_[PADR_(l_int)]; + char readfds_l_[PADL_(l_fd_set *)]; l_fd_set * readfds; char readfds_r_[PADR_(l_fd_set *)]; + char writefds_l_[PADL_(l_fd_set *)]; l_fd_set * writefds; char writefds_r_[PADR_(l_fd_set *)]; + char exceptfds_l_[PADL_(l_fd_set *)]; l_fd_set * exceptfds; char exceptfds_r_[PADR_(l_fd_set *)]; + char tsp_l_[PADL_(struct l_timespec *)]; struct l_timespec * tsp; char tsp_r_[PADR_(struct l_timespec *)]; + char sig_l_[PADL_(l_uintptr_t *)]; l_uintptr_t * sig; char sig_r_[PADR_(l_uintptr_t *)]; }; struct linux_ppoll_args { - register_t dummy; + char fds_l_[PADL_(struct pollfd *)]; struct pollfd * fds; char fds_r_[PADR_(struct pollfd *)]; + char nfds_l_[PADL_(uint32_t)]; uint32_t nfds; char nfds_r_[PADR_(uint32_t)]; + char tsp_l_[PADL_(struct l_timespec *)]; struct l_timespec * tsp; char tsp_r_[PADR_(struct l_timespec *)]; + char sset_l_[PADL_(l_sigset_t *)]; l_sigset_t * sset; char sset_r_[PADR_(l_sigset_t *)]; + char ssize_l_[PADL_(l_size_t)]; l_size_t ssize; char ssize_r_[PADR_(l_size_t)]; }; struct linux_unshare_args { register_t dummy; @@ -1014,10 +1045,17 @@ struct linux_getcpu_args { register_t dummy; }; struct linux_epoll_pwait_args { - register_t dummy; + char epfd_l_[PADL_(l_int)]; l_int epfd; char epfd_r_[PADR_(l_int)]; + char events_l_[PADL_(struct epoll_event *)]; struct epoll_event * events; char events_r_[PADR_(struct epoll_event *)]; + char maxevents_l_[PADL_(l_int)]; l_int maxevents; char maxevents_r_[PADR_(l_int)]; + char timeout_l_[PADL_(l_int)]; l_int timeout; char timeout_r_[PADR_(l_int)]; + char mask_l_[PADL_(l_sigset_t *)]; l_sigset_t * mask; char mask_r_[PADR_(l_sigset_t *)]; }; struct linux_utimensat_args { - register_t dummy; + char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)]; + char pathname_l_[PADL_(const char *)]; const char * pathname; char pathname_r_[PADR_(const char *)]; + char times_l_[PADL_(const struct l_timespec *)]; const struct l_timespec * times; char times_r_[PADR_(const struct l_timespec *)]; + char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)]; }; struct linux_signalfd_args { register_t dummy; @@ -1026,10 +1064,13 @@ struct linux_timerfd_create_args { register_t dummy; }; struct linux_eventfd_args { - register_t dummy; + char initval_l_[PADL_(l_uint)]; l_uint initval; char initval_r_[PADR_(l_uint)]; }; struct linux_fallocate_args { - register_t dummy; + char fd_l_[PADL_(l_int)]; l_int fd; char fd_r_[PADR_(l_int)]; + char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)]; + char offset_l_[PADL_(l_loff_t)]; l_loff_t offset; char offset_r_[PADR_(l_loff_t)]; + char len_l_[PADL_(l_loff_t)]; l_loff_t len; char len_r_[PADR_(l_loff_t)]; }; struct linux_timerfd_settime_args { register_t dummy; @@ -1041,13 +1082,16 @@ struct linux_signalfd4_args { register_t dummy; }; struct linux_eventfd2_args { - register_t dummy; + char initval_l_[PADL_(l_uint)]; l_uint initval; char initval_r_[PADR_(l_uint)]; + char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)]; }; struct linux_epoll_create1_args { - register_t dummy; + char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)]; }; struct linux_dup3_args { - register_t dummy; + char oldfd_l_[PADL_(l_int)]; l_int oldfd; char oldfd_r_[PADR_(l_int)]; + char newfd_l_[PADL_(l_int)]; l_int newfd; char newfd_r_[PADR_(l_int)]; + char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)]; }; struct linux_pipe2_args { char pipefds_l_[PADL_(l_int *)]; l_int * pipefds; char pipefds_r_[PADR_(l_int *)]; @@ -1069,7 +1113,11 @@ struct linux_perf_event_open_args { register_t dummy; }; struct linux_recvmmsg_args { - register_t dummy; + char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)]; + char msg_l_[PADL_(struct l_mmsghdr *)]; struct l_mmsghdr * msg; char msg_r_[PADR_(struct l_mmsghdr *)]; + char vlen_l_[PADL_(l_uint)]; l_uint vlen; char vlen_r_[PADR_(l_uint)]; + char flags_l_[PADL_(l_uint)]; l_uint flags; char flags_r_[PADR_(l_uint)]; + char timeout_l_[PADL_(struct l_timespec *)]; struct l_timespec * timeout; char timeout_r_[PADR_(struct l_timespec *)]; }; struct linux_fanotify_init_args { register_t dummy; @@ -1078,7 +1126,10 @@ struct linux_fanotify_mark_args { register_t dummy; }; struct linux_prlimit64_args { - register_t dummy; + char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)]; + char resource_l_[PADL_(l_uint)]; l_uint resource; char resource_r_[PADR_(l_uint)]; + char new_l_[PADL_(struct rlimit *)]; struct rlimit * new; char new_r_[PADR_(struct rlimit *)]; + char old_l_[PADL_(struct rlimit *)]; struct rlimit * old; char old_r_[PADR_(struct rlimit *)]; }; struct linux_name_to_handle_at_args { register_t dummy; @@ -1090,10 +1141,13 @@ struct linux_clock_adjtime_args { register_t dummy; }; struct linux_syncfs_args { - register_t dummy; + char fd_l_[PADL_(l_int)]; l_int fd; char fd_r_[PADR_(l_int)]; }; struct linux_sendmmsg_args { - register_t dummy; + char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)]; + char msg_l_[PADL_(struct l_mmsghdr *)]; struct l_mmsghdr * msg; char msg_r_[PADR_(struct l_mmsghdr *)]; + char vlen_l_[PADL_(l_uint)]; l_uint vlen; char vlen_r_[PADR_(l_uint)]; + char flags_l_[PADL_(l_uint)]; l_uint flags; char flags_r_[PADR_(l_uint)]; }; struct linux_setns_args { register_t dummy; @@ -1105,6 +1159,7 @@ struct linux_process_vm_writev_args { register_t dummy; }; #define nosys linux_nosys +int linux_exit(struct thread *, struct linux_exit_args *); int linux_fork(struct thread *, struct linux_fork_args *); int linux_open(struct thread *, struct linux_open_args *); int linux_waitpid(struct thread *, struct linux_waitpid_args *); @@ -1216,6 +1271,8 @@ int linux_writev(struct thread *, struct linux_writev_args *); int linux_getsid(struct thread *, struct linux_getsid_args *); int linux_fdatasync(struct thread *, struct linux_fdatasync_args *); int linux_sysctl(struct thread *, struct linux_sysctl_args *); +int linux_sched_setparam(struct thread *, struct linux_sched_setparam_args *); +int linux_sched_getparam(struct thread *, struct linux_sched_getparam_args *); int linux_sched_setscheduler(struct thread *, struct linux_sched_setscheduler_args *); int linux_sched_getscheduler(struct thread *, struct linux_sched_getscheduler_args *); int linux_sched_get_priority_max(struct thread *, struct linux_sched_get_priority_max_args *); @@ -1407,6 +1464,7 @@ int linux_process_vm_writev(struct thread *, struct linux_process_vm_writev_args #endif /* COMPAT_FREEBSD7 */ +#define LINUX_SYS_AUE_linux_exit AUE_EXIT #define LINUX_SYS_AUE_linux_fork AUE_FORK #define LINUX_SYS_AUE_linux_open AUE_OPEN_RWTC #define LINUX_SYS_AUE_linux_waitpid AUE_WAIT4 @@ -1518,6 +1576,8 @@ int linux_process_vm_writev(struct thread *, struct linux_process_vm_writev_args #define LINUX_SYS_AUE_linux_getsid AUE_GETSID #define LINUX_SYS_AUE_linux_fdatasync AUE_NULL #define LINUX_SYS_AUE_linux_sysctl AUE_SYSCTL +#define LINUX_SYS_AUE_linux_sched_setparam AUE_SCHED_SETPARAM +#define LINUX_SYS_AUE_linux_sched_getparam AUE_SCHED_GETPARAM #define LINUX_SYS_AUE_linux_sched_setscheduler AUE_SCHED_SETSCHEDULER #define LINUX_SYS_AUE_linux_sched_getscheduler AUE_SCHED_GETSCHEDULER #define LINUX_SYS_AUE_linux_sched_get_priority_max AUE_SCHED_GET_PRIORITY_MAX @@ -1617,7 +1677,7 @@ int linux_process_vm_writev(struct thread *, struct linux_process_vm_writev_args #define LINUX_SYS_AUE_linux_mq_notify AUE_NULL #define LINUX_SYS_AUE_linux_mq_getsetattr AUE_NULL #define LINUX_SYS_AUE_linux_kexec_load AUE_NULL -#define LINUX_SYS_AUE_linux_waitid AUE_NULL +#define LINUX_SYS_AUE_linux_waitid AUE_WAIT6 #define LINUX_SYS_AUE_linux_add_key AUE_NULL #define LINUX_SYS_AUE_linux_request_key AUE_NULL #define LINUX_SYS_AUE_linux_keyctl AUE_NULL @@ -1640,8 +1700,8 @@ int linux_process_vm_writev(struct thread *, struct linux_process_vm_writev_args #define LINUX_SYS_AUE_linux_readlinkat AUE_READLINKAT #define LINUX_SYS_AUE_linux_fchmodat AUE_FCHMODAT #define LINUX_SYS_AUE_linux_faccessat AUE_FACCESSAT -#define LINUX_SYS_AUE_linux_pselect6 AUE_NULL -#define LINUX_SYS_AUE_linux_ppoll AUE_NULL +#define LINUX_SYS_AUE_linux_pselect6 AUE_SELECT +#define LINUX_SYS_AUE_linux_ppoll AUE_POLL #define LINUX_SYS_AUE_linux_unshare AUE_NULL #define LINUX_SYS_AUE_linux_set_robust_list AUE_NULL #define LINUX_SYS_AUE_linux_get_robust_list AUE_NULL @@ -1652,7 +1712,7 @@ int linux_process_vm_writev(struct thread *, struct linux_process_vm_writev_args #define LINUX_SYS_AUE_linux_move_pages AUE_NULL #define LINUX_SYS_AUE_linux_getcpu AUE_NULL #define LINUX_SYS_AUE_linux_epoll_pwait AUE_NULL -#define LINUX_SYS_AUE_linux_utimensat AUE_NULL +#define LINUX_SYS_AUE_linux_utimensat AUE_FUTIMESAT #define LINUX_SYS_AUE_linux_signalfd AUE_NULL #define LINUX_SYS_AUE_linux_timerfd_create AUE_NULL #define LINUX_SYS_AUE_linux_eventfd AUE_NULL @@ -1676,7 +1736,7 @@ int linux_process_vm_writev(struct thread *, struct linux_process_vm_writev_args #define LINUX_SYS_AUE_linux_name_to_handle_at AUE_NULL #define LINUX_SYS_AUE_linux_open_by_handle_at AUE_NULL #define LINUX_SYS_AUE_linux_clock_adjtime AUE_NULL -#define LINUX_SYS_AUE_linux_syncfs AUE_NULL +#define LINUX_SYS_AUE_linux_syncfs AUE_SYNC #define LINUX_SYS_AUE_linux_sendmmsg AUE_NULL #define LINUX_SYS_AUE_linux_setns AUE_NULL #define LINUX_SYS_AUE_linux_process_vm_readv AUE_NULL diff --git a/sys/amd64/linux32/linux32_syscall.h b/sys/amd64/linux32/linux32_syscall.h index 716880d..e3424b4 100644 --- a/sys/amd64/linux32/linux32_syscall.h +++ b/sys/amd64/linux32/linux32_syscall.h @@ -3,10 +3,10 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: stable/10/sys/amd64/linux32/syscalls.master 276810 2015-01-08 06:23:11Z dchagin + * created from FreeBSD: stable/10/sys/amd64/linux32/syscalls.master 293592 2016-01-09 17:54:37Z dchagin */ -#define LINUX_SYS_exit 1 +#define LINUX_SYS_linux_exit 1 #define LINUX_SYS_linux_fork 2 #define LINUX_SYS_read 3 #define LINUX_SYS_write 4 @@ -143,8 +143,8 @@ #define LINUX_SYS_munlock 151 #define LINUX_SYS_mlockall 152 #define LINUX_SYS_munlockall 153 -#define LINUX_SYS_sched_setparam 154 -#define LINUX_SYS_sched_getparam 155 +#define LINUX_SYS_linux_sched_setparam 154 +#define LINUX_SYS_linux_sched_getparam 155 #define LINUX_SYS_linux_sched_setscheduler 156 #define LINUX_SYS_linux_sched_getscheduler 157 #define LINUX_SYS_sched_yield 158 @@ -321,4 +321,4 @@ #define LINUX_SYS_linux_setns 346 #define LINUX_SYS_linux_process_vm_readv 347 #define LINUX_SYS_linux_process_vm_writev 348 -#define LINUX_SYS_MAXSYSCALL 349 +#define LINUX_SYS_MAXSYSCALL 350 diff --git a/sys/amd64/linux32/linux32_syscalls.c b/sys/amd64/linux32/linux32_syscalls.c index 8fe356e..6d81d6b 100644 --- a/sys/amd64/linux32/linux32_syscalls.c +++ b/sys/amd64/linux32/linux32_syscalls.c @@ -3,13 +3,13 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: stable/10/sys/amd64/linux32/syscalls.master 276810 2015-01-08 06:23:11Z dchagin + * created from FreeBSD: stable/10/sys/amd64/linux32/syscalls.master 293592 2016-01-09 17:54:37Z dchagin */ const char *linux_syscallnames[] = { #define nosys linux_nosys "#0", /* 0 = setup */ - "exit", /* 1 = exit */ + "linux_exit", /* 1 = linux_exit */ "linux_fork", /* 2 = linux_fork */ "read", /* 3 = read */ "write", /* 4 = write */ @@ -162,8 +162,8 @@ const char *linux_syscallnames[] = { "munlock", /* 151 = munlock */ "mlockall", /* 152 = mlockall */ "munlockall", /* 153 = munlockall */ - "sched_setparam", /* 154 = sched_setparam */ - "sched_getparam", /* 155 = sched_getparam */ + "linux_sched_setparam", /* 154 = linux_sched_setparam */ + "linux_sched_getparam", /* 155 = linux_sched_getparam */ "linux_sched_setscheduler", /* 156 = linux_sched_setscheduler */ "linux_sched_getscheduler", /* 157 = linux_sched_getscheduler */ "sched_yield", /* 158 = sched_yield */ @@ -357,4 +357,5 @@ const char *linux_syscallnames[] = { "linux_setns", /* 346 = linux_setns */ "linux_process_vm_readv", /* 347 = linux_process_vm_readv */ "linux_process_vm_writev", /* 348 = linux_process_vm_writev */ + "#349", /* 349 = nosys */ }; diff --git a/sys/amd64/linux32/linux32_sysent.c b/sys/amd64/linux32/linux32_sysent.c index 80d9688..a4d3075 100644 --- a/sys/amd64/linux32/linux32_sysent.c +++ b/sys/amd64/linux32/linux32_sysent.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: stable/10/sys/amd64/linux32/syscalls.master 276810 2015-01-08 06:23:11Z dchagin + * created from FreeBSD: stable/10/sys/amd64/linux32/syscalls.master 293592 2016-01-09 17:54:37Z dchagin */ #include "opt_compat.h" @@ -20,7 +20,7 @@ struct sysent linux_sysent[] = { #define nosys linux_nosys { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 0 = setup */ - { AS(sys_exit_args), (sy_call_t *)sys_sys_exit, AUE_EXIT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 1 = exit */ + { AS(linux_exit_args), (sy_call_t *)linux_exit, AUE_EXIT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 1 = linux_exit */ { 0, (sy_call_t *)linux_fork, AUE_FORK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 2 = linux_fork */ { AS(read_args), (sy_call_t *)sys_read, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 3 = read */ { AS(write_args), (sy_call_t *)sys_write, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 4 = write */ @@ -173,8 +173,8 @@ struct sysent linux_sysent[] = { { AS(munlock_args), (sy_call_t *)sys_munlock, AUE_MUNLOCK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 151 = munlock */ { AS(mlockall_args), (sy_call_t *)sys_mlockall, AUE_MLOCKALL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 152 = mlockall */ { 0, (sy_call_t *)sys_munlockall, AUE_MUNLOCKALL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 153 = munlockall */ - { AS(sched_setparam_args), (sy_call_t *)sys_sched_setparam, AUE_SCHED_SETPARAM, NULL, 0, 0, 0, SY_THR_STATIC }, /* 154 = sched_setparam */ - { AS(sched_getparam_args), (sy_call_t *)sys_sched_getparam, AUE_SCHED_GETPARAM, NULL, 0, 0, 0, SY_THR_STATIC }, /* 155 = sched_getparam */ + { AS(linux_sched_setparam_args), (sy_call_t *)linux_sched_setparam, AUE_SCHED_SETPARAM, NULL, 0, 0, 0, SY_THR_STATIC }, /* 154 = linux_sched_setparam */ + { AS(linux_sched_getparam_args), (sy_call_t *)linux_sched_getparam, AUE_SCHED_GETPARAM, NULL, 0, 0, 0, SY_THR_STATIC }, /* 155 = linux_sched_getparam */ { AS(linux_sched_setscheduler_args), (sy_call_t *)linux_sched_setscheduler, AUE_SCHED_SETSCHEDULER, NULL, 0, 0, 0, SY_THR_STATIC }, /* 156 = linux_sched_setscheduler */ { AS(linux_sched_getscheduler_args), (sy_call_t *)linux_sched_getscheduler, AUE_SCHED_GETSCHEDULER, NULL, 0, 0, 0, SY_THR_STATIC }, /* 157 = linux_sched_getscheduler */ { 0, (sy_call_t *)sys_sched_yield, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 158 = sched_yield */ @@ -197,7 +197,7 @@ struct sysent linux_sysent[] = { { AS(linux_rt_sigprocmask_args), (sy_call_t *)linux_rt_sigprocmask, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 175 = linux_rt_sigprocmask */ { AS(linux_rt_sigpending_args), (sy_call_t *)linux_rt_sigpending, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 176 = linux_rt_sigpending */ { AS(linux_rt_sigtimedwait_args), (sy_call_t *)linux_rt_sigtimedwait, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 177 = linux_rt_sigtimedwait */ - { 0, (sy_call_t *)linux_rt_sigqueueinfo, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 178 = linux_rt_sigqueueinfo */ + { AS(linux_rt_sigqueueinfo_args), (sy_call_t *)linux_rt_sigqueueinfo, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 178 = linux_rt_sigqueueinfo */ { AS(linux_rt_sigsuspend_args), (sy_call_t *)linux_rt_sigsuspend, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 179 = linux_rt_sigsuspend */ { AS(linux_pread_args), (sy_call_t *)linux_pread, AUE_PREAD, NULL, 0, 0, 0, SY_THR_STATIC }, /* 180 = linux_pread */ { AS(linux_pwrite_args), (sy_call_t *)linux_pwrite, AUE_PWRITE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 181 = linux_pwrite */ @@ -273,9 +273,9 @@ struct sysent linux_sysent[] = { { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 251 = */ { AS(linux_exit_group_args), (sy_call_t *)linux_exit_group, AUE_EXIT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 252 = linux_exit_group */ { 0, (sy_call_t *)linux_lookup_dcookie, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 253 = linux_lookup_dcookie */ - { 0, (sy_call_t *)linux_epoll_create, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 254 = linux_epoll_create */ - { 0, (sy_call_t *)linux_epoll_ctl, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 255 = linux_epoll_ctl */ - { 0, (sy_call_t *)linux_epoll_wait, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 256 = linux_epoll_wait */ + { AS(linux_epoll_create_args), (sy_call_t *)linux_epoll_create, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 254 = linux_epoll_create */ + { AS(linux_epoll_ctl_args), (sy_call_t *)linux_epoll_ctl, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 255 = linux_epoll_ctl */ + { AS(linux_epoll_wait_args), (sy_call_t *)linux_epoll_wait, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 256 = linux_epoll_wait */ { 0, (sy_call_t *)linux_remap_file_pages, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 257 = linux_remap_file_pages */ { AS(linux_set_tid_address_args), (sy_call_t *)linux_set_tid_address, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 258 = linux_set_tid_address */ { AS(linux_timer_create_args), (sy_call_t *)linux_timer_create, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 259 = linux_timer_create */ @@ -303,7 +303,7 @@ struct sysent linux_sysent[] = { { 0, (sy_call_t *)linux_mq_notify, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 281 = linux_mq_notify */ { 0, (sy_call_t *)linux_mq_getsetattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 282 = linux_mq_getsetattr */ { 0, (sy_call_t *)linux_kexec_load, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 283 = linux_kexec_load */ - { 0, (sy_call_t *)linux_waitid, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 284 = linux_waitid */ + { AS(linux_waitid_args), (sy_call_t *)linux_waitid, AUE_WAIT6, NULL, 0, 0, 0, SY_THR_STATIC }, /* 284 = linux_waitid */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 285 = */ { 0, (sy_call_t *)linux_add_key, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 286 = linux_add_key */ { 0, (sy_call_t *)linux_request_key, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 287 = linux_request_key */ @@ -327,8 +327,8 @@ struct sysent linux_sysent[] = { { AS(linux_readlinkat_args), (sy_call_t *)linux_readlinkat, AUE_READLINKAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 305 = linux_readlinkat */ { AS(linux_fchmodat_args), (sy_call_t *)linux_fchmodat, AUE_FCHMODAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 306 = linux_fchmodat */ { AS(linux_faccessat_args), (sy_call_t *)linux_faccessat, AUE_FACCESSAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 307 = linux_faccessat */ - { 0, (sy_call_t *)linux_pselect6, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 308 = linux_pselect6 */ - { 0, (sy_call_t *)linux_ppoll, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 309 = linux_ppoll */ + { AS(linux_pselect6_args), (sy_call_t *)linux_pselect6, AUE_SELECT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 308 = linux_pselect6 */ + { AS(linux_ppoll_args), (sy_call_t *)linux_ppoll, AUE_POLL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 309 = linux_ppoll */ { 0, (sy_call_t *)linux_unshare, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 310 = linux_unshare */ { AS(linux_set_robust_list_args), (sy_call_t *)linux_set_robust_list, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 311 = linux_set_robust_list */ { AS(linux_get_robust_list_args), (sy_call_t *)linux_get_robust_list, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 312 = linux_get_robust_list */ @@ -338,34 +338,35 @@ struct sysent linux_sysent[] = { { 0, (sy_call_t *)linux_vmsplice, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 316 = linux_vmsplice */ { 0, (sy_call_t *)linux_move_pages, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 317 = linux_move_pages */ { 0, (sy_call_t *)linux_getcpu, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 318 = linux_getcpu */ - { 0, (sy_call_t *)linux_epoll_pwait, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 319 = linux_epoll_pwait */ - { 0, (sy_call_t *)linux_utimensat, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 320 = linux_utimensat */ + { AS(linux_epoll_pwait_args), (sy_call_t *)linux_epoll_pwait, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 319 = linux_epoll_pwait */ + { AS(linux_utimensat_args), (sy_call_t *)linux_utimensat, AUE_FUTIMESAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 320 = linux_utimensat */ { 0, (sy_call_t *)linux_signalfd, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 321 = linux_signalfd */ { 0, (sy_call_t *)linux_timerfd_create, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 322 = linux_timerfd_create */ - { 0, (sy_call_t *)linux_eventfd, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 323 = linux_eventfd */ - { 0, (sy_call_t *)linux_fallocate, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 324 = linux_fallocate */ + { AS(linux_eventfd_args), (sy_call_t *)linux_eventfd, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 323 = linux_eventfd */ + { AS(linux_fallocate_args), (sy_call_t *)linux_fallocate, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 324 = linux_fallocate */ { 0, (sy_call_t *)linux_timerfd_settime, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 325 = linux_timerfd_settime */ { 0, (sy_call_t *)linux_timerfd_gettime, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 326 = linux_timerfd_gettime */ { 0, (sy_call_t *)linux_signalfd4, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 327 = linux_signalfd4 */ - { 0, (sy_call_t *)linux_eventfd2, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 328 = linux_eventfd2 */ - { 0, (sy_call_t *)linux_epoll_create1, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 329 = linux_epoll_create1 */ - { 0, (sy_call_t *)linux_dup3, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 330 = linux_dup3 */ + { AS(linux_eventfd2_args), (sy_call_t *)linux_eventfd2, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 328 = linux_eventfd2 */ + { AS(linux_epoll_create1_args), (sy_call_t *)linux_epoll_create1, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 329 = linux_epoll_create1 */ + { AS(linux_dup3_args), (sy_call_t *)linux_dup3, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 330 = linux_dup3 */ { AS(linux_pipe2_args), (sy_call_t *)linux_pipe2, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 331 = linux_pipe2 */ { 0, (sy_call_t *)linux_inotify_init1, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 332 = linux_inotify_init1 */ { 0, (sy_call_t *)linux_preadv, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 333 = linux_preadv */ { 0, (sy_call_t *)linux_pwritev, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 334 = linux_pwritev */ { 0, (sy_call_t *)linux_rt_tsigqueueinfo, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 335 = linux_rt_tsigqueueinfo */ { 0, (sy_call_t *)linux_perf_event_open, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 336 = linux_perf_event_open */ - { 0, (sy_call_t *)linux_recvmmsg, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 337 = linux_recvmmsg */ + { AS(linux_recvmmsg_args), (sy_call_t *)linux_recvmmsg, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 337 = linux_recvmmsg */ { 0, (sy_call_t *)linux_fanotify_init, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 338 = linux_fanotify_init */ { 0, (sy_call_t *)linux_fanotify_mark, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 339 = linux_fanotify_mark */ - { 0, (sy_call_t *)linux_prlimit64, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 340 = linux_prlimit64 */ + { AS(linux_prlimit64_args), (sy_call_t *)linux_prlimit64, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 340 = linux_prlimit64 */ { 0, (sy_call_t *)linux_name_to_handle_at, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 341 = linux_name_to_handle_at */ { 0, (sy_call_t *)linux_open_by_handle_at, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 342 = linux_open_by_handle_at */ { 0, (sy_call_t *)linux_clock_adjtime, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 343 = linux_clock_adjtime */ - { 0, (sy_call_t *)linux_syncfs, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 344 = linux_syncfs */ - { 0, (sy_call_t *)linux_sendmmsg, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 345 = linux_sendmmsg */ + { AS(linux_syncfs_args), (sy_call_t *)linux_syncfs, AUE_SYNC, NULL, 0, 0, 0, SY_THR_STATIC }, /* 344 = linux_syncfs */ + { AS(linux_sendmmsg_args), (sy_call_t *)linux_sendmmsg, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 345 = linux_sendmmsg */ { 0, (sy_call_t *)linux_setns, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 346 = linux_setns */ { 0, (sy_call_t *)linux_process_vm_readv, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 347 = linux_process_vm_readv */ { 0, (sy_call_t *)linux_process_vm_writev, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 348 = linux_process_vm_writev */ + { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 349 = nosys */ }; diff --git a/sys/amd64/linux32/linux32_systrace_args.c b/sys/amd64/linux32/linux32_systrace_args.c index 2d563ac..b6ccd33 100644 --- a/sys/amd64/linux32/linux32_systrace_args.c +++ b/sys/amd64/linux32/linux32_systrace_args.c @@ -12,9 +12,9 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) int64_t *iarg = (int64_t *) uarg; switch (sysnum) { #define nosys linux_nosys - /* sys_exit */ + /* linux_exit */ case 1: { - struct sys_exit_args *p = params; + struct linux_exit_args *p = params; iarg[0] = p->rval; /* int */ *n_args = 1; break; @@ -1043,19 +1043,19 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) *n_args = 0; break; } - /* sched_setparam */ + /* linux_sched_setparam */ case 154: { - struct sched_setparam_args *p = params; - iarg[0] = p->pid; /* pid_t */ - uarg[1] = (intptr_t) p->param; /* const struct sched_param * */ + struct linux_sched_setparam_args *p = params; + iarg[0] = p->pid; /* l_pid_t */ + uarg[1] = (intptr_t) p->param; /* struct l_sched_param * */ *n_args = 2; break; } - /* sched_getparam */ + /* linux_sched_getparam */ case 155: { - struct sched_getparam_args *p = params; - iarg[0] = p->pid; /* pid_t */ - uarg[1] = (intptr_t) p->param; /* struct sched_param * */ + struct linux_sched_getparam_args *p = params; + iarg[0] = p->pid; /* l_pid_t */ + uarg[1] = (intptr_t) p->param; /* struct l_sched_param * */ *n_args = 2; break; } @@ -1234,7 +1234,11 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) } /* linux_rt_sigqueueinfo */ case 178: { - *n_args = 0; + struct linux_rt_sigqueueinfo_args *p = params; + iarg[0] = p->pid; /* l_pid_t */ + iarg[1] = p->sig; /* l_int */ + uarg[2] = (intptr_t) p->info; /* l_siginfo_t * */ + *n_args = 3; break; } /* linux_rt_sigsuspend */ @@ -1693,17 +1697,29 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) } /* linux_epoll_create */ case 254: { - *n_args = 0; + struct linux_epoll_create_args *p = params; + iarg[0] = p->size; /* l_int */ + *n_args = 1; break; } /* linux_epoll_ctl */ case 255: { - *n_args = 0; + struct linux_epoll_ctl_args *p = params; + iarg[0] = p->epfd; /* l_int */ + iarg[1] = p->op; /* l_int */ + iarg[2] = p->fd; /* l_int */ + uarg[3] = (intptr_t) p->event; /* struct epoll_event * */ + *n_args = 4; break; } /* linux_epoll_wait */ case 256: { - *n_args = 0; + struct linux_epoll_wait_args *p = params; + iarg[0] = p->epfd; /* l_int */ + uarg[1] = (intptr_t) p->events; /* struct epoll_event * */ + iarg[2] = p->maxevents; /* l_int */ + iarg[3] = p->timeout; /* l_int */ + *n_args = 4; break; } /* linux_remap_file_pages */ @@ -1886,7 +1902,13 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) } /* linux_waitid */ case 284: { - *n_args = 0; + struct linux_waitid_args *p = params; + iarg[0] = p->idtype; /* int */ + iarg[1] = p->id; /* l_pid_t */ + uarg[2] = (intptr_t) p->info; /* l_siginfo_t * */ + iarg[3] = p->options; /* int */ + uarg[4] = (intptr_t) p->rusage; /* struct l_rusage * */ + *n_args = 5; break; } /* linux_add_key */ @@ -2057,18 +2079,30 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) iarg[0] = p->dfd; /* l_int */ uarg[1] = (intptr_t) p->filename; /* const char * */ iarg[2] = p->amode; /* l_int */ - iarg[3] = p->flag; /* int */ - *n_args = 4; + *n_args = 3; break; } /* linux_pselect6 */ case 308: { - *n_args = 0; + struct linux_pselect6_args *p = params; + iarg[0] = p->nfds; /* l_int */ + uarg[1] = (intptr_t) p->readfds; /* l_fd_set * */ + uarg[2] = (intptr_t) p->writefds; /* l_fd_set * */ + uarg[3] = (intptr_t) p->exceptfds; /* l_fd_set * */ + uarg[4] = (intptr_t) p->tsp; /* struct l_timespec * */ + uarg[5] = (intptr_t) p->sig; /* l_uintptr_t * */ + *n_args = 6; break; } /* linux_ppoll */ case 309: { - *n_args = 0; + struct linux_ppoll_args *p = params; + uarg[0] = (intptr_t) p->fds; /* struct pollfd * */ + uarg[1] = p->nfds; /* uint32_t */ + uarg[2] = (intptr_t) p->tsp; /* struct l_timespec * */ + uarg[3] = (intptr_t) p->sset; /* l_sigset_t * */ + iarg[4] = p->ssize; /* l_size_t */ + *n_args = 5; break; } /* linux_unshare */ @@ -2125,12 +2159,23 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) } /* linux_epoll_pwait */ case 319: { - *n_args = 0; + struct linux_epoll_pwait_args *p = params; + iarg[0] = p->epfd; /* l_int */ + uarg[1] = (intptr_t) p->events; /* struct epoll_event * */ + iarg[2] = p->maxevents; /* l_int */ + iarg[3] = p->timeout; /* l_int */ + uarg[4] = (intptr_t) p->mask; /* l_sigset_t * */ + *n_args = 5; break; } /* linux_utimensat */ case 320: { - *n_args = 0; + struct linux_utimensat_args *p = params; + iarg[0] = p->dfd; /* l_int */ + uarg[1] = (intptr_t) p->pathname; /* const char * */ + uarg[2] = (intptr_t) p->times; /* const struct l_timespec * */ + iarg[3] = p->flags; /* l_int */ + *n_args = 4; break; } /* linux_signalfd */ @@ -2145,12 +2190,19 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) } /* linux_eventfd */ case 323: { - *n_args = 0; + struct linux_eventfd_args *p = params; + iarg[0] = p->initval; /* l_uint */ + *n_args = 1; break; } /* linux_fallocate */ case 324: { - *n_args = 0; + struct linux_fallocate_args *p = params; + iarg[0] = p->fd; /* l_int */ + iarg[1] = p->mode; /* l_int */ + iarg[2] = p->offset; /* l_loff_t */ + iarg[3] = p->len; /* l_loff_t */ + *n_args = 4; break; } /* linux_timerfd_settime */ @@ -2170,17 +2222,26 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) } /* linux_eventfd2 */ case 328: { - *n_args = 0; + struct linux_eventfd2_args *p = params; + iarg[0] = p->initval; /* l_uint */ + iarg[1] = p->flags; /* l_int */ + *n_args = 2; break; } /* linux_epoll_create1 */ case 329: { - *n_args = 0; + struct linux_epoll_create1_args *p = params; + iarg[0] = p->flags; /* l_int */ + *n_args = 1; break; } /* linux_dup3 */ case 330: { - *n_args = 0; + struct linux_dup3_args *p = params; + iarg[0] = p->oldfd; /* l_int */ + iarg[1] = p->newfd; /* l_int */ + iarg[2] = p->flags; /* l_int */ + *n_args = 3; break; } /* linux_pipe2 */ @@ -2218,7 +2279,13 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) } /* linux_recvmmsg */ case 337: { - *n_args = 0; + struct linux_recvmmsg_args *p = params; + iarg[0] = p->s; /* l_int */ + uarg[1] = (intptr_t) p->msg; /* struct l_mmsghdr * */ + iarg[2] = p->vlen; /* l_uint */ + iarg[3] = p->flags; /* l_uint */ + uarg[4] = (intptr_t) p->timeout; /* struct l_timespec * */ + *n_args = 5; break; } /* linux_fanotify_init */ @@ -2233,7 +2300,12 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) } /* linux_prlimit64 */ case 340: { - *n_args = 0; + struct linux_prlimit64_args *p = params; + iarg[0] = p->pid; /* l_pid_t */ + iarg[1] = p->resource; /* l_uint */ + uarg[2] = (intptr_t) p->new; /* struct rlimit * */ + uarg[3] = (intptr_t) p->old; /* struct rlimit * */ + *n_args = 4; break; } /* linux_name_to_handle_at */ @@ -2253,12 +2325,19 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) } /* linux_syncfs */ case 344: { - *n_args = 0; + struct linux_syncfs_args *p = params; + iarg[0] = p->fd; /* l_int */ + *n_args = 1; break; } /* linux_sendmmsg */ case 345: { - *n_args = 0; + struct linux_sendmmsg_args *p = params; + iarg[0] = p->s; /* l_int */ + uarg[1] = (intptr_t) p->msg; /* struct l_mmsghdr * */ + iarg[2] = p->vlen; /* l_uint */ + iarg[3] = p->flags; /* l_uint */ + *n_args = 4; break; } /* linux_setns */ @@ -2287,7 +2366,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) const char *p = NULL; switch (sysnum) { #define nosys linux_nosys - /* sys_exit */ + /* linux_exit */ case 1: switch(ndx) { case 0: @@ -3848,27 +3927,27 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) /* munlockall */ case 153: break; - /* sched_setparam */ + /* linux_sched_setparam */ case 154: switch(ndx) { case 0: - p = "pid_t"; + p = "l_pid_t"; break; case 1: - p = "const struct sched_param *"; + p = "struct l_sched_param *"; break; default: break; }; break; - /* sched_getparam */ + /* linux_sched_getparam */ case 155: switch(ndx) { case 0: - p = "pid_t"; + p = "l_pid_t"; break; case 1: - p = "struct sched_param *"; + p = "struct l_sched_param *"; break; default: break; @@ -4161,6 +4240,19 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; /* linux_rt_sigqueueinfo */ case 178: + switch(ndx) { + case 0: + p = "l_pid_t"; + break; + case 1: + p = "l_int"; + break; + case 2: + p = "l_siginfo_t *"; + break; + default: + break; + }; break; /* linux_rt_sigsuspend */ case 179: @@ -4823,12 +4915,51 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; /* linux_epoll_create */ case 254: + switch(ndx) { + case 0: + p = "l_int"; + break; + default: + break; + }; break; /* linux_epoll_ctl */ case 255: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_int"; + break; + case 2: + p = "l_int"; + break; + case 3: + p = "struct epoll_event *"; + break; + default: + break; + }; break; /* linux_epoll_wait */ case 256: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "struct epoll_event *"; + break; + case 2: + p = "l_int"; + break; + case 3: + p = "l_int"; + break; + default: + break; + }; break; /* linux_remap_file_pages */ case 257: @@ -5068,6 +5199,25 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; /* linux_waitid */ case 284: + switch(ndx) { + case 0: + p = "int"; + break; + case 1: + p = "l_pid_t"; + break; + case 2: + p = "l_siginfo_t *"; + break; + case 3: + p = "int"; + break; + case 4: + p = "struct l_rusage *"; + break; + default: + break; + }; break; /* linux_add_key */ case 286: @@ -5327,18 +5477,56 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) case 2: p = "l_int"; break; - case 3: - p = "int"; - break; default: break; }; break; /* linux_pselect6 */ case 308: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_fd_set *"; + break; + case 2: + p = "l_fd_set *"; + break; + case 3: + p = "l_fd_set *"; + break; + case 4: + p = "struct l_timespec *"; + break; + case 5: + p = "l_uintptr_t *"; + break; + default: + break; + }; break; /* linux_ppoll */ case 309: + switch(ndx) { + case 0: + p = "struct pollfd *"; + break; + case 1: + p = "uint32_t"; + break; + case 2: + p = "struct l_timespec *"; + break; + case 3: + p = "l_sigset_t *"; + break; + case 4: + p = "l_size_t"; + break; + default: + break; + }; break; /* linux_unshare */ case 310: @@ -5392,9 +5580,44 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; /* linux_epoll_pwait */ case 319: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "struct epoll_event *"; + break; + case 2: + p = "l_int"; + break; + case 3: + p = "l_int"; + break; + case 4: + p = "l_sigset_t *"; + break; + default: + break; + }; break; /* linux_utimensat */ case 320: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "const char *"; + break; + case 2: + p = "const struct l_timespec *"; + break; + case 3: + p = "l_int"; + break; + default: + break; + }; break; /* linux_signalfd */ case 321: @@ -5404,9 +5627,32 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; /* linux_eventfd */ case 323: + switch(ndx) { + case 0: + p = "l_uint"; + break; + default: + break; + }; break; /* linux_fallocate */ case 324: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_int"; + break; + case 2: + p = "l_loff_t"; + break; + case 3: + p = "l_loff_t"; + break; + default: + break; + }; break; /* linux_timerfd_settime */ case 325: @@ -5419,12 +5665,42 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; /* linux_eventfd2 */ case 328: + switch(ndx) { + case 0: + p = "l_uint"; + break; + case 1: + p = "l_int"; + break; + default: + break; + }; break; /* linux_epoll_create1 */ case 329: + switch(ndx) { + case 0: + p = "l_int"; + break; + default: + break; + }; break; /* linux_dup3 */ case 330: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_int"; + break; + case 2: + p = "l_int"; + break; + default: + break; + }; break; /* linux_pipe2 */ case 331: @@ -5456,6 +5732,25 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; /* linux_recvmmsg */ case 337: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "struct l_mmsghdr *"; + break; + case 2: + p = "l_uint"; + break; + case 3: + p = "l_uint"; + break; + case 4: + p = "struct l_timespec *"; + break; + default: + break; + }; break; /* linux_fanotify_init */ case 338: @@ -5465,6 +5760,22 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; /* linux_prlimit64 */ case 340: + switch(ndx) { + case 0: + p = "l_pid_t"; + break; + case 1: + p = "l_uint"; + break; + case 2: + p = "struct rlimit *"; + break; + case 3: + p = "struct rlimit *"; + break; + default: + break; + }; break; /* linux_name_to_handle_at */ case 341: @@ -5477,9 +5788,32 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; /* linux_syncfs */ case 344: + switch(ndx) { + case 0: + p = "l_int"; + break; + default: + break; + }; break; /* linux_sendmmsg */ case 345: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "struct l_mmsghdr *"; + break; + case 2: + p = "l_uint"; + break; + case 3: + p = "l_uint"; + break; + default: + break; + }; break; /* linux_setns */ case 346: @@ -5502,7 +5836,7 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) const char *p = NULL; switch (sysnum) { #define nosys linux_nosys - /* sys_exit */ + /* linux_exit */ case 1: if (ndx == 0 || ndx == 1) p = "void"; @@ -6112,12 +6446,12 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; /* munlockall */ case 153: - /* sched_setparam */ + /* linux_sched_setparam */ case 154: if (ndx == 0 || ndx == 1) p = "int"; break; - /* sched_getparam */ + /* linux_sched_getparam */ case 155: if (ndx == 0 || ndx == 1) p = "int"; @@ -6220,6 +6554,9 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; /* linux_rt_sigqueueinfo */ case 178: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_rt_sigsuspend */ case 179: if (ndx == 0 || ndx == 1) @@ -6469,10 +6806,19 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) case 253: /* linux_epoll_create */ case 254: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_epoll_ctl */ case 255: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_epoll_wait */ case 256: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_remap_file_pages */ case 257: /* linux_set_tid_address */ @@ -6569,6 +6915,9 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) case 283: /* linux_waitid */ case 284: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_add_key */ case 286: /* linux_request_key */ @@ -6654,8 +7003,14 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; /* linux_pselect6 */ case 308: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_ppoll */ case 309: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_unshare */ case 310: /* linux_set_robust_list */ @@ -6682,16 +7037,28 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) case 318: /* linux_epoll_pwait */ case 319: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_utimensat */ case 320: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_signalfd */ case 321: /* linux_timerfd_create */ case 322: /* linux_eventfd */ case 323: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_fallocate */ case 324: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_timerfd_settime */ case 325: /* linux_timerfd_gettime */ @@ -6700,10 +7067,19 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) case 327: /* linux_eventfd2 */ case 328: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_epoll_create1 */ case 329: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_dup3 */ case 330: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_pipe2 */ case 331: if (ndx == 0 || ndx == 1) @@ -6721,12 +7097,18 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) case 336: /* linux_recvmmsg */ case 337: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_fanotify_init */ case 338: /* linux_fanotify_mark */ case 339: /* linux_prlimit64 */ case 340: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_name_to_handle_at */ case 341: /* linux_open_by_handle_at */ @@ -6735,8 +7117,14 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) case 343: /* linux_syncfs */ case 344: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_sendmmsg */ case 345: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_setns */ case 346: /* linux_process_vm_readv */ diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c index c06ce11..250e16b 100644 --- a/sys/amd64/linux32/linux32_sysvec.c +++ b/sys/amd64/linux32/linux32_sysvec.c @@ -83,11 +83,10 @@ __FBSDID("$FreeBSD$"); #include <compat/linux/linux_misc.h> #include <compat/linux/linux_signal.h> #include <compat/linux/linux_util.h> +#include <compat/linux/linux_vdso.h> MODULE_VERSION(linux, 1); -MALLOC_DEFINE(M_LINUX, "linux", "Linux mode structures"); - #define AUXARGS_ENTRY_32(pos, id, val) \ do { \ suword32(pos++, id); \ @@ -109,15 +108,16 @@ MALLOC_DEFINE(M_LINUX, "linux", "Linux mode structures"); #define LINUX_SYS_linux_rt_sendsig 0 #define LINUX_SYS_linux_sendsig 0 -const char *linux_platform = "i686"; -static int linux_szplatform; -extern char linux_sigcode[]; -extern int linux_szsigcode; +const char *linux_kplatform; +static int linux_szsigcode; +static vm_object_t linux_shared_page_obj; +static char *linux_shared_page_mapping; +extern char _binary_linux32_locore_o_start; +extern char _binary_linux32_locore_o_end; extern struct sysent linux_sysent[LINUX_SYS_MAXSYSCALL]; SET_DECLARE(linux_ioctl_handler_set, struct linux_ioctl_handler); -SET_DECLARE(linux_device_handler_set, struct linux_device_handler); static int elf_linux_fixup(register_t **stack_base, struct image_params *iparams); @@ -127,9 +127,8 @@ static void exec_linux_setregs(struct thread *td, struct image_params *imgp, u_long stack); static void linux32_fixlimit(struct rlimit *rl, int which); static boolean_t linux32_trans_osrel(const Elf_Note *note, int32_t *osrel); - -static eventhandler_tag linux_exit_tag; -static eventhandler_tag linux_exec_tag; +static void linux_vdso_install(void *param); +static void linux_vdso_deinstall(void *param); /* * Linux syscalls return negative errno's, we do positive and map them @@ -151,28 +150,6 @@ static int bsd_to_linux_errno[ELAST + 1] = { -72, -67, -71 }; -int bsd_to_linux_signal[LINUX_SIGTBLSZ] = { - LINUX_SIGHUP, LINUX_SIGINT, LINUX_SIGQUIT, LINUX_SIGILL, - LINUX_SIGTRAP, LINUX_SIGABRT, 0, LINUX_SIGFPE, - LINUX_SIGKILL, LINUX_SIGBUS, LINUX_SIGSEGV, LINUX_SIGSYS, - LINUX_SIGPIPE, LINUX_SIGALRM, LINUX_SIGTERM, LINUX_SIGURG, - LINUX_SIGSTOP, LINUX_SIGTSTP, LINUX_SIGCONT, LINUX_SIGCHLD, - LINUX_SIGTTIN, LINUX_SIGTTOU, LINUX_SIGIO, LINUX_SIGXCPU, - LINUX_SIGXFSZ, LINUX_SIGVTALRM, LINUX_SIGPROF, LINUX_SIGWINCH, - 0, LINUX_SIGUSR1, LINUX_SIGUSR2 -}; - -int linux_to_bsd_signal[LINUX_SIGTBLSZ] = { - SIGHUP, SIGINT, SIGQUIT, SIGILL, - SIGTRAP, SIGABRT, SIGBUS, SIGFPE, - SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2, - SIGPIPE, SIGALRM, SIGTERM, SIGBUS, - SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP, - SIGTTIN, SIGTTOU, SIGURG, SIGXCPU, - SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH, - SIGIO, SIGURG, SIGSYS -}; - #define LINUX_T_UNKNOWN 255 static int _bsd_to_linux_trapcode[] = { LINUX_T_UNKNOWN, /* 0 */ @@ -219,6 +196,11 @@ struct linux32_ps_strings { u_int ps_nenvstr; /* the number of environment strings */ }; +LINUX_VDSO_SYM_INTPTR(linux32_sigcode); +LINUX_VDSO_SYM_INTPTR(linux32_rt_sigcode); +LINUX_VDSO_SYM_INTPTR(linux32_vsyscall); +LINUX_VDSO_SYM_CHAR(linux_platform); + /* * If FreeBSD & Linux have a difference of opinion about what a trap * means, deal with it here. @@ -246,11 +228,10 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp) { Elf32_Auxargs *args; Elf32_Addr *base; - Elf32_Addr *pos, *uplatform; + Elf32_Addr *pos; struct linux32_ps_strings *arginfo; arginfo = (struct linux32_ps_strings *)LINUX32_PS_STRINGS; - uplatform = (Elf32_Addr *)((caddr_t)arginfo - linux_szplatform); KASSERT(curthread->td_proc == imgp->proc, ("unsafe elf_linux_fixup(), should be curproc")); @@ -258,6 +239,9 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp) args = (Elf32_Auxargs *)imgp->auxargs; pos = base + (imgp->args->argc + imgp->args->envc + 2); + AUXARGS_ENTRY_32(pos, LINUX_AT_SYSINFO_EHDR, + imgp->proc->p_sysent->sv_shared_page_base); + AUXARGS_ENTRY_32(pos, LINUX_AT_SYSINFO, linux32_vsyscall); AUXARGS_ENTRY_32(pos, LINUX_AT_HWCAP, cpu_feature); /* @@ -282,7 +266,10 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp) AUXARGS_ENTRY_32(pos, AT_EUID, imgp->proc->p_ucred->cr_svuid); AUXARGS_ENTRY_32(pos, AT_GID, imgp->proc->p_ucred->cr_rgid); AUXARGS_ENTRY_32(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid); - AUXARGS_ENTRY_32(pos, LINUX_AT_PLATFORM, PTROUT(uplatform)); + AUXARGS_ENTRY_32(pos, LINUX_AT_PLATFORM, PTROUT(linux_platform)); + AUXARGS_ENTRY(pos, LINUX_AT_RANDOM, PTROUT(imgp->canary)); + if (imgp->execpathp != 0) + AUXARGS_ENTRY(pos, LINUX_AT_EXECFN, PTROUT(imgp->execpathp)); if (args->execfd != -1) AUXARGS_ENTRY_32(pos, AT_EXECFD, args->execfd); AUXARGS_ENTRY_32(pos, AT_NULL, 0); @@ -293,11 +280,9 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp) base--; suword32(base, (uint32_t)imgp->args->argc); *stack_base = (register_t *)base; - return 0; + return (0); } -extern unsigned long linux_sznonrtsigcode; - static void linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) { @@ -337,9 +322,7 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) /* * Build the argument list for the signal handler. */ - if (p->p_sysent->sv_sigtbl) - if (sig <= p->p_sysent->sv_sigsize) - sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; + sig = bsd_to_linux_signal(sig); bzero(&frame, sizeof(frame)); @@ -352,7 +335,8 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) ksiginfo_to_lsiginfo(ksi, &frame.sf_si, sig); /* - * Build the signal context to be used by sigreturn. + * Build the signal context to be used by sigreturn + * and libgcc unwind. */ frame.sf_sc.uc_flags = 0; /* XXX ??? */ frame.sf_sc.uc_link = 0; /* XXX ??? */ @@ -365,11 +349,12 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) bsd_to_linux_sigset(mask, &frame.sf_sc.uc_sigmask); - frame.sf_sc.uc_mcontext.sc_mask = frame.sf_sc.uc_sigmask.__bits[0]; + frame.sf_sc.uc_mcontext.sc_mask = frame.sf_sc.uc_sigmask.__mask; frame.sf_sc.uc_mcontext.sc_edi = regs->tf_rdi; frame.sf_sc.uc_mcontext.sc_esi = regs->tf_rsi; frame.sf_sc.uc_mcontext.sc_ebp = regs->tf_rbp; frame.sf_sc.uc_mcontext.sc_ebx = regs->tf_rbx; + frame.sf_sc.uc_mcontext.sc_esp = regs->tf_rsp; frame.sf_sc.uc_mcontext.sc_edx = regs->tf_rdx; frame.sf_sc.uc_mcontext.sc_ecx = regs->tf_rcx; frame.sf_sc.uc_mcontext.sc_eax = regs->tf_rax; @@ -411,7 +396,7 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) * Build context to run handler in. */ regs->tf_rsp = PTROUT(fp); - regs->tf_rip = p->p_sysent->sv_sigcode_base + linux_sznonrtsigcode; + regs->tf_rip = linux32_rt_sigcode; regs->tf_rflags &= ~(PSL_T | PSL_D); regs->tf_cs = _ucode32sel; regs->tf_ss = _udatasel; @@ -445,7 +430,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) struct trapframe *regs; struct l_sigframe *fp, frame; l_sigset_t lmask; - int oonstack, i; + int oonstack; int sig, code; sig = ksi->ksi_signo; @@ -483,9 +468,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) /* * Build the argument list for the signal handler. */ - if (p->p_sysent->sv_sigtbl) - if (sig <= p->p_sysent->sv_sigsize) - sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; + sig = bsd_to_linux_signal(sig); bzero(&frame, sizeof(frame)); @@ -497,7 +480,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) /* * Build the signal context to be used by sigreturn. */ - frame.sf_sc.sc_mask = lmask.__bits[0]; + frame.sf_sc.sc_mask = lmask.__mask; frame.sf_sc.sc_gs = regs->tf_gs; frame.sf_sc.sc_fs = regs->tf_fs; frame.sf_sc.sc_es = regs->tf_es; @@ -506,6 +489,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) frame.sf_sc.sc_esi = regs->tf_rsi; frame.sf_sc.sc_ebp = regs->tf_rbp; frame.sf_sc.sc_ebx = regs->tf_rbx; + frame.sf_sc.sc_esp = regs->tf_rsp; frame.sf_sc.sc_edx = regs->tf_rdx; frame.sf_sc.sc_ecx = regs->tf_rcx; frame.sf_sc.sc_eax = regs->tf_rax; @@ -518,8 +502,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) frame.sf_sc.sc_cr2 = (u_int32_t)(uintptr_t)ksi->ksi_addr; frame.sf_sc.sc_trapno = bsd_to_linux_trapcode(code); - for (i = 0; i < (LINUX_NSIG_WORDS-1); i++) - frame.sf_extramask[i] = lmask.__bits[i+1]; + frame.sf_extramask[0] = lmask.__mask; if (copyout(&frame, fp, sizeof(frame)) != 0) { /* @@ -534,7 +517,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) * Build context to run handler in. */ regs->tf_rsp = PTROUT(fp); - regs->tf_rip = p->p_sysent->sv_sigcode_base; + regs->tf_rip = linux32_sigcode; regs->tf_rflags &= ~(PSL_T | PSL_D); regs->tf_cs = _ucode32sel; regs->tf_ss = _udatasel; @@ -565,7 +548,7 @@ linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args) struct trapframe *regs; sigset_t bmask; l_sigset_t lmask; - int eflags, i; + int eflags; ksiginfo_t ksi; regs = td->td_frame; @@ -606,9 +589,8 @@ linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args) return(EINVAL); } - lmask.__bits[0] = frame.sf_sc.sc_mask; - for (i = 0; i < (LINUX_NSIG_WORDS-1); i++) - lmask.__bits[i+1] = frame.sf_extramask[i]; + lmask.__mask = frame.sf_sc.sc_mask; + lmask.__mask = frame.sf_extramask[0]; linux_to_bsd_sigset(&lmask, &bmask); kern_sigprocmask(td, SIG_SETMASK, &bmask, NULL, 0); @@ -758,7 +740,8 @@ linux32_fetch_syscall_args(struct thread *td, struct syscall_args *sa) sa->code = frame->tf_rax; if (sa->code >= p->p_sysent->sv_size) - sa->callp = &p->p_sysent->sv_table[0]; + /* nosys */ + sa->callp = &p->p_sysent->sv_table[p->p_sysent->sv_size - 1]; else sa->callp = &p->p_sysent->sv_table[sa->code]; sa->narg = sa->callp->sy_narg; @@ -862,21 +845,36 @@ linux_copyout_strings(struct image_params *imgp) char *stringp, *destp; u_int32_t *stack_base; struct linux32_ps_strings *arginfo; + char canary[LINUX_AT_RANDOM_LEN]; + size_t execpath_len; /* * Calculate string base and vector table pointers. - * Also deal with signal trampoline code for this exec type. */ + if (imgp->execpath != NULL && imgp->auxargs != NULL) + execpath_len = strlen(imgp->execpath) + 1; + else + execpath_len = 0; + arginfo = (struct linux32_ps_strings *)LINUX32_PS_STRINGS; - destp = (caddr_t)arginfo - SPARE_USRSPACE - linux_szplatform - - roundup((ARG_MAX - imgp->args->stringspace), - sizeof(char *)); + destp = (caddr_t)arginfo - SPARE_USRSPACE - + roundup(sizeof(canary), sizeof(char *)) - + roundup(execpath_len, sizeof(char *)) - + roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *)); + + if (execpath_len != 0) { + imgp->execpathp = (uintptr_t)arginfo - execpath_len; + copyout(imgp->execpath, (void *)imgp->execpathp, execpath_len); + } /* - * Install LINUX_PLATFORM + * Prepare the canary for SSP. */ - copyout(linux_platform, ((caddr_t)arginfo - linux_szplatform), - linux_szplatform); + arc4rand(canary, sizeof(canary), 0); + imgp->canary = (uintptr_t)arginfo - + roundup(execpath_len, sizeof(char *)) - + roundup(sizeof(canary), sizeof(char *)); + copyout(canary, (void *)imgp->canary, sizeof(canary)); /* * If we have a valid auxargs ptr, prepare some room @@ -970,6 +968,13 @@ static u_long linux32_maxvmem = LINUX32_MAXVMEM; SYSCTL_ULONG(_compat_linux32, OID_AUTO, maxvmem, CTLFLAG_RW, &linux32_maxvmem, 0, ""); +#if defined(DEBUG) +SYSCTL_PROC(_compat_linux32, OID_AUTO, debug, + CTLTYPE_STRING | CTLFLAG_RW, + 0, 0, linux_sysctl_debug, "A", + "Linux debugging control"); +#endif + static void linux32_fixlimit(struct rlimit *rl, int which) { @@ -1006,14 +1011,14 @@ struct sysentvec elf_linux_sysvec = { .sv_size = LINUX_SYS_MAXSYSCALL, .sv_table = linux_sysent, .sv_mask = 0, - .sv_sigsize = LINUX_SIGTBLSZ, - .sv_sigtbl = bsd_to_linux_signal, + .sv_sigsize = 0, + .sv_sigtbl = NULL, .sv_errsize = ELAST + 1, .sv_errtbl = bsd_to_linux_errno, .sv_transtrap = translate_traps, .sv_fixup = elf_linux_fixup, .sv_sendsig = linux_sendsig, - .sv_sigcode = linux_sigcode, + .sv_sigcode = &_binary_linux32_locore_o_start, .sv_szsigcode = &linux_szsigcode, .sv_prepsyscall = NULL, .sv_name = "Linux ELF32", @@ -1037,8 +1042,44 @@ struct sysentvec elf_linux_sysvec = { .sv_shared_page_base = LINUX32_SHAREDPAGE, .sv_shared_page_len = PAGE_SIZE, .sv_schedtail = linux_schedtail, + .sv_thread_detach = linux_thread_detach, }; -INIT_SYSENTVEC(elf_sysvec, &elf_linux_sysvec); + +static void +linux_vdso_install(void *param) +{ + + linux_szsigcode = (&_binary_linux32_locore_o_end - + &_binary_linux32_locore_o_start); + + if (linux_szsigcode > elf_linux_sysvec.sv_shared_page_len) + panic("Linux invalid vdso size\n"); + + __elfN(linux_vdso_fixup)(&elf_linux_sysvec); + + linux_shared_page_obj = __elfN(linux_shared_page_init) + (&linux_shared_page_mapping); + + __elfN(linux_vdso_reloc)(&elf_linux_sysvec, LINUX32_SHAREDPAGE); + + bcopy(elf_linux_sysvec.sv_sigcode, linux_shared_page_mapping, + linux_szsigcode); + elf_linux_sysvec.sv_shared_page_obj = linux_shared_page_obj; + + linux_kplatform = linux_shared_page_mapping + + (linux_platform - (caddr_t)LINUX32_SHAREDPAGE); +} +SYSINIT(elf_linux_vdso_init, SI_SUB_EXEC, SI_ORDER_ANY, + (sysinit_cfunc_t)linux_vdso_install, NULL); + +static void +linux_vdso_deinstall(void *param) +{ + + __elfN(linux_shared_page_fini)(linux_shared_page_obj); +}; +SYSUNINIT(elf_linux_vdso_uninit, SI_SUB_EXEC, SI_ORDER_FIRST, + (sysinit_cfunc_t)linux_vdso_deinstall, NULL); static char GNU_ABI_VENDOR[] = "GNU"; static int GNULINUX_ABI_DESC = 0; @@ -1110,7 +1151,6 @@ linux_elf_modevent(module_t mod, int type, void *data) Elf32_Brandinfo **brandinfo; int error; struct linux_ioctl_handler **lihp; - struct linux_device_handler **ldhp; error = 0; @@ -1123,19 +1163,8 @@ linux_elf_modevent(module_t mod, int type, void *data) if (error == 0) { SET_FOREACH(lihp, linux_ioctl_handler_set) linux_ioctl_register_handler(*lihp); - SET_FOREACH(ldhp, linux_device_handler_set) - linux_device_register_handler(*ldhp); - mtx_init(&emul_lock, "emuldata lock", NULL, MTX_DEF); - sx_init(&emul_shared_lock, "emuldata->shared lock"); LIST_INIT(&futex_list); mtx_init(&futex_mtx, "ftllk", NULL, MTX_DEF); - linux_exit_tag = EVENTHANDLER_REGISTER(process_exit, - linux_proc_exit, NULL, 1000); - linux_exec_tag = EVENTHANDLER_REGISTER(process_exec, - linux_proc_exec, NULL, 1000); - linux_szplatform = roundup(strlen(linux_platform) + 1, - sizeof(char *)); - linux_osd_jail_register(); stclohz = (stathz ? stathz : hz); if (bootverbose) printf("Linux ELF exec handler installed\n"); @@ -1156,23 +1185,16 @@ linux_elf_modevent(module_t mod, int type, void *data) if (error == 0) { SET_FOREACH(lihp, linux_ioctl_handler_set) linux_ioctl_unregister_handler(*lihp); - SET_FOREACH(ldhp, linux_device_handler_set) - linux_device_unregister_handler(*ldhp); - mtx_destroy(&emul_lock); - sx_destroy(&emul_shared_lock); mtx_destroy(&futex_mtx); - EVENTHANDLER_DEREGISTER(process_exit, linux_exit_tag); - EVENTHANDLER_DEREGISTER(process_exec, linux_exec_tag); - linux_osd_jail_deregister(); if (bootverbose) printf("Linux ELF exec handler removed\n"); } else printf("Could not deinstall ELF interpreter entry\n"); break; default: - return EOPNOTSUPP; + return (EOPNOTSUPP); } - return error; + return (error); } static moduledata_t linux_elf_mod = { @@ -1182,3 +1204,4 @@ static moduledata_t linux_elf_mod = { }; DECLARE_MODULE_TIED(linuxelf, linux_elf_mod, SI_SUB_EXEC, SI_ORDER_ANY); +MODULE_DEPEND(linuxelf, linux_common, 1, 1, 1); diff --git a/sys/amd64/linux32/linux32_vdso.lds.s b/sys/amd64/linux32/linux32_vdso.lds.s new file mode 100644 index 0000000..a49c209 --- /dev/null +++ b/sys/amd64/linux32/linux32_vdso.lds.s @@ -0,0 +1,66 @@ +/* + * Linker script for 32-bit vDSO. + * Copied from Linux kernel arch/x86/vdso/vdso-layout.lds.S + * and arch/x86/vdso/vdso32/vdso32.lds.S + * + * $FreeBSD$ + */ + +SECTIONS +{ + . = . + SIZEOF_HEADERS; + + .hash : { *(.hash) } :text + .gnu.hash : { *(.gnu.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + + .note : { *(.note.*) } :text :note + + .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr + .eh_frame : { KEEP (*(.eh_frame)) } :text + + .dynamic : { *(.dynamic) } :text :dynamic + + .rodata : { *(.rodata*) } :text + .data : { + *(.data*) + *(.sdata*) + *(.got.plt) *(.got) + *(.gnu.linkonce.d.*) + *(.bss*) + *(.dynbss*) + *(.gnu.linkonce.b.*) + } + + .altinstructions : { *(.altinstructions) } + .altinstr_replacement : { *(.altinstr_replacement) } + + . = ALIGN(0x100); + .text : { *(.text*) } :text =0x90909090 +} + +PHDRS +{ + text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */ + dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ + note PT_NOTE FLAGS(4); /* PF_R */ + eh_frame_hdr PT_GNU_EH_FRAME; +} + +ENTRY(linux32_vsyscall); + +VERSION +{ + LINUX_2.5 { + global: + linux32_vsyscall; + linux32_sigcode; + linux32_rt_sigcode; + linux_platform; + local: *; + }; +} diff --git a/sys/amd64/linux32/syscalls.master b/sys/amd64/linux32/syscalls.master index 5b39dc3..5f688f3 100644 --- a/sys/amd64/linux32/syscalls.master +++ b/sys/amd64/linux32/syscalls.master @@ -38,8 +38,7 @@ ; #ifdef's, etc. may be included, and are copied to the output files. 0 AUE_NULL UNIMPL setup -1 AUE_EXIT NOPROTO { void sys_exit(int rval); } exit \ - sys_exit_args void +1 AUE_EXIT STD { void linux_exit(int rval); } 2 AUE_FORK STD { int linux_fork(void); } 3 AUE_NULL NOPROTO { int read(int fd, char *buf, \ u_int nbyte); } @@ -268,10 +267,10 @@ 151 AUE_MUNLOCK NOPROTO { int munlock(const void *addr, size_t len); } 152 AUE_MLOCKALL NOPROTO { int mlockall(int how); } 153 AUE_MUNLOCKALL NOPROTO { int munlockall(void); } -154 AUE_SCHED_SETPARAM NOPROTO { int sched_setparam(pid_t pid, \ - const struct sched_param *param); } -155 AUE_SCHED_GETPARAM NOPROTO { int sched_getparam(pid_t pid, \ - struct sched_param *param); } +154 AUE_SCHED_SETPARAM STD { int linux_sched_setparam(l_pid_t pid, \ + struct l_sched_param *param); } +155 AUE_SCHED_GETPARAM STD { int linux_sched_getparam(l_pid_t pid, \ + struct l_sched_param *param); } 156 AUE_SCHED_SETSCHEDULER STD { int linux_sched_setscheduler( \ l_pid_t pid, l_int policy, \ struct l_sched_param *param); } @@ -319,7 +318,8 @@ l_siginfo_t *ptr, \ struct l_timeval *timeout, \ l_size_t sigsetsize); } -178 AUE_NULL STD { int linux_rt_sigqueueinfo(void); } +178 AUE_NULL STD { int linux_rt_sigqueueinfo(l_pid_t pid, l_int sig, \ + l_siginfo_t *info); } 179 AUE_NULL STD { int linux_rt_sigsuspend( \ l_sigset_t *newset, \ l_size_t sigsetsize); } @@ -430,9 +430,11 @@ 251 AUE_NULL UNIMPL 252 AUE_EXIT STD { int linux_exit_group(int error_code); } 253 AUE_NULL STD { int linux_lookup_dcookie(void); } -254 AUE_NULL STD { int linux_epoll_create(void); } -255 AUE_NULL STD { int linux_epoll_ctl(void); } -256 AUE_NULL STD { int linux_epoll_wait(void); } +254 AUE_NULL STD { int linux_epoll_create(l_int size); } +255 AUE_NULL STD { int linux_epoll_ctl(l_int epfd, l_int op, l_int fd, \ + struct epoll_event *event); } +256 AUE_NULL STD { int linux_epoll_wait(l_int epfd, struct epoll_event *events, \ + l_int maxevents, l_int timeout); } 257 AUE_NULL STD { int linux_remap_file_pages(void); } 258 AUE_NULL STD { int linux_set_tid_address(int *tidptr); } 259 AUE_NULL STD { int linux_timer_create(clockid_t clock_id, \ @@ -467,7 +469,9 @@ 281 AUE_NULL STD { int linux_mq_notify(void); } 282 AUE_NULL STD { int linux_mq_getsetattr(void); } 283 AUE_NULL STD { int linux_kexec_load(void); } -284 AUE_NULL STD { int linux_waitid(void); } +284 AUE_WAIT6 STD { int linux_waitid(int idtype, l_pid_t id, \ + l_siginfo_t *info, int options, \ + struct l_rusage *rusage); } 285 AUE_NULL UNIMPL ; linux 2.6.11: 286 AUE_NULL STD { int linux_add_key(void); } @@ -505,9 +509,13 @@ char *buf, l_int bufsiz); } 306 AUE_FCHMODAT STD { int linux_fchmodat(l_int dfd, const char *filename, \ l_mode_t mode); } -307 AUE_FACCESSAT STD { int linux_faccessat(l_int dfd, const char *filename, l_int amode, int flag); } -308 AUE_NULL STD { int linux_pselect6(void); } -309 AUE_NULL STD { int linux_ppoll(void); } +307 AUE_FACCESSAT STD { int linux_faccessat(l_int dfd, const char *filename, \ + l_int amode); } +308 AUE_SELECT STD { int linux_pselect6(l_int nfds, l_fd_set *readfds, \ + l_fd_set *writefds, l_fd_set *exceptfds, \ + struct l_timespec *tsp, l_uintptr_t *sig); } +309 AUE_POLL STD { int linux_ppoll(struct pollfd *fds, uint32_t nfds, \ + struct l_timespec *tsp, l_sigset_t *sset, l_size_t ssize); } 310 AUE_NULL STD { int linux_unshare(void); } ; linux 2.6.17: 311 AUE_NULL STD { int linux_set_robust_list(struct linux_robust_list_head *head, \ @@ -522,22 +530,26 @@ 317 AUE_NULL STD { int linux_move_pages(void); } ; linux 2.6.19: 318 AUE_NULL STD { int linux_getcpu(void); } -319 AUE_NULL STD { int linux_epoll_pwait(void); } +319 AUE_NULL STD { int linux_epoll_pwait(l_int epfd, struct epoll_event *events, \ + l_int maxevents, l_int timeout, l_sigset_t *mask); } ; linux 2.6.22: -320 AUE_NULL STD { int linux_utimensat(void); } +320 AUE_FUTIMESAT STD { int linux_utimensat(l_int dfd, const char *pathname, \ + const struct l_timespec *times, l_int flags); } 321 AUE_NULL STD { int linux_signalfd(void); } 322 AUE_NULL STD { int linux_timerfd_create(void); } -323 AUE_NULL STD { int linux_eventfd(void); } +323 AUE_NULL STD { int linux_eventfd(l_uint initval); } ; linux 2.6.23: -324 AUE_NULL STD { int linux_fallocate(void); } +324 AUE_NULL STD { int linux_fallocate(l_int fd, l_int mode, \ + l_loff_t offset, l_loff_t len); } ; linux 2.6.25: 325 AUE_NULL STD { int linux_timerfd_settime(void); } 326 AUE_NULL STD { int linux_timerfd_gettime(void); } ; linux 2.6.27: 327 AUE_NULL STD { int linux_signalfd4(void); } -328 AUE_NULL STD { int linux_eventfd2(void); } -329 AUE_NULL STD { int linux_epoll_create1(void); } -330 AUE_NULL STD { int linux_dup3(void); } +328 AUE_NULL STD { int linux_eventfd2(l_uint initval, l_int flags); } +329 AUE_NULL STD { int linux_epoll_create1(l_int flags); } +330 AUE_NULL STD { int linux_dup3(l_int oldfd, \ + l_int newfd, l_int flags); } 331 AUE_NULL STD { int linux_pipe2(l_int *pipefds, l_int flags); } 332 AUE_NULL STD { int linux_inotify_init1(void); } ; linux 2.6.30: @@ -547,17 +559,26 @@ 335 AUE_NULL STD { int linux_rt_tsigqueueinfo(void); } 336 AUE_NULL STD { int linux_perf_event_open(void); } ; linux 2.6.33: -337 AUE_NULL STD { int linux_recvmmsg(void); } +337 AUE_NULL STD { int linux_recvmmsg(l_int s, \ + struct l_mmsghdr *msg, l_uint vlen, \ + l_uint flags, struct l_timespec *timeout); } 338 AUE_NULL STD { int linux_fanotify_init(void); } 339 AUE_NULL STD { int linux_fanotify_mark(void); } ; linux 2.6.36: -340 AUE_NULL STD { int linux_prlimit64(void); } +340 AUE_NULL STD { int linux_prlimit64(l_pid_t pid, \ + l_uint resource, \ + struct rlimit *new, \ + struct rlimit *old); } ; later: 341 AUE_NULL STD { int linux_name_to_handle_at(void); } 342 AUE_NULL STD { int linux_open_by_handle_at(void); } 343 AUE_NULL STD { int linux_clock_adjtime(void); } -344 AUE_NULL STD { int linux_syncfs(void); } -345 AUE_NULL STD { int linux_sendmmsg(void); } +344 AUE_SYNC STD { int linux_syncfs(l_int fd); } +345 AUE_NULL STD { int linux_sendmmsg(l_int s, \ + struct l_mmsghdr *msg, l_uint vlen, \ + l_uint flags); } 346 AUE_NULL STD { int linux_setns(void); } 347 AUE_NULL STD { int linux_process_vm_readv(void); } 348 AUE_NULL STD { int linux_process_vm_writev(void); } +; please, keep this line at the end. +349 AUE_NULL UNIMPL nosys diff --git a/sys/arm/arm/elf_machdep.c b/sys/arm/arm/elf_machdep.c index 931a82b..8472858 100644 --- a/sys/arm/arm/elf_machdep.c +++ b/sys/arm/arm/elf_machdep.c @@ -79,6 +79,7 @@ struct sysentvec elf32_freebsd_sysvec = { .sv_fetch_syscall_args = cpu_fetch_syscall_args, .sv_syscallnames = syscallnames, .sv_schedtail = NULL, + .sv_thread_detach = NULL, }; static Elf32_Brandinfo freebsd_brand_info = { diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c index 17e96b5..66dae32 100644 --- a/sys/arm/arm/machdep.c +++ b/sys/arm/arm/machdep.c @@ -259,10 +259,6 @@ sendsig(catcher, ksi, mask) sigexit(td, SIGILL); } - /* Translate the signal if appropriate. */ - if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) - sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; - /* * Build context to run handler in. We invoke the handler * directly, only returning via the trampoline. Note the diff --git a/sys/boot/Makefile b/sys/boot/Makefile index 3b098e9..4b30df4 100644 --- a/sys/boot/Makefile +++ b/sys/boot/Makefile @@ -1,7 +1,6 @@ # $FreeBSD$ .include <bsd.own.mk> -.include <bsd.arch.inc.mk> .if ${MK_FORTH} != "no" # Build the add-in FORTH interpreter. @@ -9,13 +8,12 @@ SUBDIR+= ficl SUBDIR+= forth .endif +.include <bsd.arch.inc.mk> + # Pick the machine-dependent subdir based on the target architecture. ADIR= ${MACHINE:S/powerpc64/powerpc/} .if exists(${.CURDIR}/${ADIR}/.) SUBDIR+= ${ADIR} .endif -.if ${MACHINE} == "amd64" -SUBDIR+= i386 -.endif .include <bsd.subdir.mk> diff --git a/sys/boot/Makefile.amd64 b/sys/boot/Makefile.amd64 index 2b85283..384cf7a 100644 --- a/sys/boot/Makefile.amd64 +++ b/sys/boot/Makefile.amd64 @@ -8,3 +8,5 @@ SUBDIR+= userboot .if ${MK_FORTH} != "no" SUBDIR+= ficl32 .endif + +SUBDIR+= i386 diff --git a/sys/boot/common/part.c b/sys/boot/common/part.c index 4457619..518df1a 100644 --- a/sys/boot/common/part.c +++ b/sys/boot/common/part.c @@ -306,6 +306,7 @@ ptable_gptread(struct ptable *table, void *dev, diskread_t dread) table->type = PTABLE_NONE; goto out; } + DEBUG("GPT detected"); size = MIN(hdr.hdr_entries * hdr.hdr_entsz, MAXTBLSZ * table->sectorsize); for (i = 0; i < size / hdr.hdr_entsz; i++) { @@ -631,6 +632,11 @@ ptable_open(void *dev, off_t sectors, uint16_t sectorsize, if (buf[DOSMAGICOFFSET] != 0x55 || buf[DOSMAGICOFFSET + 1] != 0xaa) { DEBUG("magic sequence not found"); +#if defined(LOADER_GPT_SUPPORT) + /* There is no PMBR, check that we have backup GPT */ + table->type = PTABLE_GPT; + table = ptable_gptread(table, dev, dread); +#endif goto out; } /* Check that we have PMBR. Also do some validation. */ diff --git a/sys/boot/efi/Makefile.inc b/sys/boot/efi/Makefile.inc index 58c4726..83db76a 100644 --- a/sys/boot/efi/Makefile.inc +++ b/sys/boot/efi/Makefile.inc @@ -4,13 +4,21 @@ BINDIR?= /boot .if ${MACHINE_CPUARCH} == "i386" CFLAGS+= -march=i386 +CFLAGS+= -msoft-float .endif # Options used when building app-specific efi components # See conf/kern.mk for the correct set of these -CFLAGS+= -ffreestanding -fshort-wchar -Wformat -CFLAGS+= -mno-red-zone -CFLAGS+= -mno-mmx -mno-sse -mno-aes -mno-avx -msoft-float +CFLAGS+= -ffreestanding -Wformat LDFLAGS+= -nostdlib +.if ${MACHINE_CPUARCH} == "amd64" +CFLAGS+= -fshort-wchar +CFLAGS+= -mno-red-zone +CFLAGS+= -mno-mmx -mno-sse +CFLAGS.clang+= -mno-aes -mno-avx +CFLAGS+= -msoft-float +.endif + + .include "../Makefile.inc" diff --git a/sys/boot/efi/boot1/Makefile b/sys/boot/efi/boot1/Makefile index 554df39..ddf3147 100644 --- a/sys/boot/efi/boot1/Makefile +++ b/sys/boot/efi/boot1/Makefile @@ -18,19 +18,25 @@ SRCS= boot1.c reloc.c start.S CFLAGS+= -fPIC CFLAGS+= -I. CFLAGS+= -I${.CURDIR}/../include -CFLAGS+= -I${.CURDIR}/../include/${MACHINE_CPUARCH} +CFLAGS+= -I${.CURDIR}/../include/${MACHINE} CFLAGS+= -I${.CURDIR}/../../../contrib/dev/acpica/include CFLAGS+= -I${.CURDIR}/../../.. # Always add MI sources and REGULAR efi loader bits -.PATH: ${.CURDIR}/../loader/arch/amd64 ${.CURDIR}/../../common +.PATH: ${.CURDIR}/../loader/arch/${MACHINE} +.PATH: ${.CURDIR}/../loader +.PATH: ${.CURDIR}/../../common CFLAGS+= -I${.CURDIR}/../../common FILES= boot1.efi boot1.efifat FILESMODE_boot1.efi= ${BINMODE} -LDSCRIPT= ${.CURDIR}/../loader/arch/${MACHINE_CPUARCH}/ldscript.${MACHINE_CPUARCH} -LDFLAGS= -Wl,-T${LDSCRIPT} -Wl,-Bsymbolic -shared -Wl,-znocombreloc +LDSCRIPT= ${.CURDIR}/../loader/arch/${MACHINE}/ldscript.${MACHINE} +LDFLAGS= -Wl,-T${LDSCRIPT} -Wl,-Bsymbolic -shared + +.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" +LDFLAGS+= -Wl,-znocombreloc +.endif ${PROG}: ${LDSCRIPT} @@ -62,8 +68,8 @@ boot1.o: ${.CURDIR}/../../common/ufsread.c boot1.efifat: boot1.efi echo ${.OBJDIR} - uudecode ${.CURDIR}/fat.tmpl.bz2.uu - mv fat.tmpl.bz2 ${.TARGET}.bz2 + uudecode ${.CURDIR}/fat-${MACHINE}.tmpl.bz2.uu + mv fat-${MACHINE}.tmpl.bz2 ${.TARGET}.bz2 bzip2 -f -d ${.TARGET}.bz2 dd if=boot1.efi of=${.TARGET} seek=${BOOT1_OFFSET} conv=notrunc @@ -73,6 +79,7 @@ CLEANFILES= boot1.efifat .include <bsd.prog.mk> +.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" beforedepend ${OBJS}: machine x86 CLEANFILES+= machine x86 boot1.efi @@ -82,3 +89,4 @@ machine: x86: ln -sf ${.CURDIR}/../../../x86/include x86 +.endif diff --git a/sys/boot/efi/boot1/fat.tmpl.bz2.uu b/sys/boot/efi/boot1/fat-amd64.tmpl.bz2.uu index c9044ee..d8a44b7 100644 --- a/sys/boot/efi/boot1/fat.tmpl.bz2.uu +++ b/sys/boot/efi/boot1/fat-amd64.tmpl.bz2.uu @@ -1,7 +1,7 @@ FAT template boot filesystem created by generate-fat.sh DO NOT EDIT $FreeBSD$ -begin 644 fat.tmpl.bz2 +begin 644 fat-amd64.tmpl.bz2 M0EIH.3%!629362AK*D(`&I+____[ZZKJZ_^N_ZO^Z_Z_OJ[L`4`!7I0$#&$" M0$!$3&(<P`(;J*C:0E0E#30&AH`T````9#0```9````#)ZF0:,-3U/409,`) M@`"8`C3",````$R:8F@P`C`````"24U,D>I-DTU,)ZAZ0VA-!M0T'J`>H#"9 diff --git a/sys/boot/efi/libefi/Makefile b/sys/boot/efi/libefi/Makefile index 99c2e9b..8180d9e 100644 --- a/sys/boot/efi/libefi/Makefile +++ b/sys/boot/efi/libefi/Makefile @@ -10,7 +10,7 @@ SRCS= delay.c efi_console.c efinet.c efipart.c errno.c handles.c \ CFLAGS+= -fPIC -mno-red-zone .endif CFLAGS+= -I${.CURDIR}/../include -CFLAGS+= -I${.CURDIR}/../include/${MACHINE_CPUARCH} +CFLAGS+= -I${.CURDIR}/../include/${MACHINE} CFLAGS+= -I${.CURDIR}/../../../../lib/libstand # Pick up the bootstrap header for some interface items diff --git a/sys/boot/efi/loader/Makefile b/sys/boot/efi/loader/Makefile index 26fd8a0..8d3fe87 100644 --- a/sys/boot/efi/loader/Makefile +++ b/sys/boot/efi/loader/Makefile @@ -23,16 +23,16 @@ SRCS= autoload.c \ smbios.c \ vers.c -.PATH: ${.CURDIR}/arch/${MACHINE_CPUARCH} +.PATH: ${.CURDIR}/arch/${MACHINE} # For smbios.c .PATH: ${.CURDIR}/../../i386/libi386 -.include "${.CURDIR}/arch/${MACHINE_CPUARCH}/Makefile.inc" +.include "${.CURDIR}/arch/${MACHINE}/Makefile.inc" CFLAGS+= -fPIC CFLAGS+= -I${.CURDIR} -CFLAGS+= -I${.CURDIR}/arch/${MACHINE_CPUARCH} +CFLAGS+= -I${.CURDIR}/arch/${MACHINE} CFLAGS+= -I${.CURDIR}/../include -CFLAGS+= -I${.CURDIR}/../include/${MACHINE_CPUARCH} +CFLAGS+= -I${.CURDIR}/../include/${MACHINE} CFLAGS+= -I${.CURDIR}/../../../contrib/dev/acpica/include CFLAGS+= -I${.CURDIR}/../../.. CFLAGS+= -I${.CURDIR}/../../i386/libi386 @@ -42,7 +42,7 @@ CFLAGS+= -DNO_PCI -DEFI BOOT_FORTH= yes CFLAGS+= -DBOOT_FORTH CFLAGS+= -I${.CURDIR}/../../ficl -CFLAGS+= -I${.CURDIR}/../../ficl/${MACHINE_CPUARCH} +CFLAGS+= -I${.CURDIR}/../../ficl/${MACHINE} LIBFICL= ${.OBJDIR}/../../ficl/libficl.a .endif @@ -61,12 +61,12 @@ CFLAGS+= -I${.CURDIR}/../../common FILES= loader.efi FILESMODE_loader.efi= ${BINMODE} -LDSCRIPT= ${.CURDIR}/arch/${MACHINE_CPUARCH}/ldscript.${MACHINE_CPUARCH} +LDSCRIPT= ${.CURDIR}/arch/${MACHINE}/ldscript.${MACHINE} LDFLAGS= -Wl,-T${LDSCRIPT} -Wl,-Bsymbolic -shared -Wl,-znocombreloc CLEANFILES= vers.c loader.efi -NEWVERSWHAT= "EFI loader" ${MACHINE_CPUARCH} +NEWVERSWHAT= "EFI loader" ${MACHINE} vers.c: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/../../efi/loader/version sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT} diff --git a/sys/boot/forth/loader.conf b/sys/boot/forth/loader.conf index 88f5411..141b862 100644 --- a/sys/boot/forth/loader.conf +++ b/sys/boot/forth/loader.conf @@ -73,6 +73,7 @@ entropy_cache_type="/boot/entropy" #password="" # Prevent changes to boot options #bootlock_password="" # Prevent booting (see check-password.4th(8)) #geom_eli_passphrase_prompt="NO" # Prompt for geli(8) passphrase to mount root +bootenv_autolist="YES" # Auto populate the list of ZFS Boot Environments #beastie_disable="NO" # Turn the beastie boot menu on and off #kernels="kernel kernel.old" # Kernels to display in the boot menu #loader_logo="orbbw" # Desired logo: orbbw, orb, fbsdbw, beastiebw, beastie, none diff --git a/sys/boot/forth/menu-commands.4th b/sys/boot/forth/menu-commands.4th index 797c7e6..5c6350a 100644 --- a/sys/boot/forth/menu-commands.4th +++ b/sys/boot/forth/menu-commands.4th @@ -351,4 +351,68 @@ also menu-namespace also menu-command-helpers 2 goto_menu ; +\ +\ Set boot environment defaults +\ + +: init_bootenv ( -- ) + s" set menu_caption[1]=${bemenu_current}${vfs.root.mountfrom}" evaluate + s" set ansi_caption[1]=${beansi_current}${vfs.root.mountfrom}" evaluate + s" set menu_caption[2]=${bemenu_bootfs}${zfs_be_active}" evaluate + s" set ansi_caption[2]=${beansi_bootfs}${zfs_be_active}" evaluate + s" set menu_caption[3]=${bemenu_page}${zfs_be_currpage}${bemenu_pageof}${zfs_be_pages}" evaluate + s" set ansi_caption[3]=${beansi_page}${zfs_be_currpage}${bemenu_pageof}${zfs_be_pages}" evaluate +; + +\ +\ Redraw the entire screen. A long BE name can corrupt the menu +\ + +: be_draw_screen + clear \ Clear the screen (in screen.4th) + print_version \ print version string (bottom-right; see version.4th) + draw-beastie \ Draw FreeBSD logo at right (in beastie.4th) + draw-brand \ Draw brand.4th logo at top (in brand.4th) + menu-init \ Initialize menu and draw bounding box (in menu.4th) +; + +\ +\ Select a boot environment +\ + +: set_bootenv ( N -- N TRUE ) + dup s" set vfs.root.mountfrom=${bootenv_root[E]}" 38 +c! evaluate + s" set currdev=${vfs.root.mountfrom}:" evaluate + s" unload" evaluate + free-module-options + s" /boot/defaults/loader.conf" read-conf + s" /boot/loader.conf" read-conf + s" /boot/loader.conf.local" read-conf + init_bootenv + be_draw_screen + menu-redraw + TRUE +; + +\ +\ Switch to the next page of boot environments +\ + +: set_be_page ( N -- N TRUE ) + s" zfs_be_currpage" getenv dup -1 = if + drop s" 1" + else + 0 s>d 2swap + >number ( ud caddr/u -- ud' caddr'/u' ) \ convert string to numbers + 2drop \ drop the string + 1 um/mod ( ud u1 -- u2 u3 ) \ convert double ud' to single u3' and remainder u2 + swap drop ( ud2 u3 -- u3 ) \ drop the remainder u2 + 1+ \ increment the page number + s>d <# #s #> \ convert back to a string + then + s" zfs_be_currpage" setenv + s" reloadbe" evaluate + 3 goto_menu +; + only forth definitions diff --git a/sys/boot/forth/menu.rc b/sys/boot/forth/menu.rc index 7ffeef4..3c7de71 100644 --- a/sys/boot/forth/menu.rc +++ b/sys/boot/forth/menu.rc @@ -68,6 +68,13 @@ set mainmenu_command[6]="2 goto_menu" set mainmenu_keycode[6]=111 set mainansi_caption[6]="Configure Boot ^[1mO^[mptions..." +s" currdev" getenv dup 0> [if] drop 4 s" zfs:" compare 0= [if] + set mainmenu_caption[7]="Select Boot [E]nvironment..." + set mainmenu_command[7]="3 goto_menu" + set mainmenu_keycode[7]=101 + set mainansi_caption[7]="Select Boot ^[1mE^[37mnvironment..." +[then] [else] drop [then] + \ \ BOOT OPTIONS MENU \ @@ -119,6 +126,37 @@ set optionsmenu_keycode[6]=118 set optionsansi_caption[6]="^[1mV^[merbose..... ^[34;1mOff^[m" set optionstoggled_ansi[6]="^[1mV^[merbose..... ^[32;7mOn^[m" +\ +\ BOOT ENVIRONMENT MENU +\ + +set menuset_name3="bootenv" + +set bemenu_current="Active: " +set beansi_current="^[1m${bemenu_current}^[m" +set bemenu_bootfs="bootfs: " +set beansi_bootfs="^[1m${bemenu_bootfs}^[m" +set bemenu_page="[P]age: " +set beansi_page="^[1mP^[mage: " +set bemenu_pageof=" of " +set beansi_pageof="${bemenu_pageof}" +set zfs_be_currpage=1 + +set bootenvmenu_init="init_bootenv" + +set bootenvmenu_command[1]="be_draw_screen 1 goto_menu" +set bootenvmenu_keycode[1]=8 + +set bootenvmenu_command[2]="set_bootenv" +set bootenvmenu_keycode[2]=97 +set bootenv_root[2]="${zfs_be_active}" + +set bootenvmenu_command[3]="set_be_page" +set bootenvmenu_keycode[3]=112 + +set bootenvmenu_options=4 +set bootenvmenu_optionstext="Boot Environments:" + \ Enable automatic booting (add ``autoboot_delay=N'' to loader.conf(5) to \ customize the timeout; default is 10-seconds) \ @@ -128,6 +166,21 @@ set menu_timeout_command="boot" \ try-include /boot/menu.rc.local +\ Initialize boot environment variables +\ +s" reloadbe" sfind ( xt|0 bool ) [if] + s" bootenv_autolist" getenv dup -1 = [if] + drop s" execute" evaluate \ Use evaluate to avoid passing + \ reloadbe an optional parameter + [else] + s" YES" compare-insensitive 0= [if] + s" execute" evaluate + [then] + [then] +[else] + drop ( xt=0 ) +[then] + \ Display the main menu (see `menu.4th') set menuset_initial=1 menuset-loadinitial diff --git a/sys/boot/forth/support.4th b/sys/boot/forth/support.4th index 6db232b..1acef70 100644 --- a/sys/boot/forth/support.4th +++ b/sys/boot/forth/support.4th @@ -930,6 +930,30 @@ only forth definitions also support-functions repeat ; +: free-one-module { addr -- addr } + addr module.name strfree + addr module.loadname strfree + addr module.type strfree + addr module.args strfree + addr module.beforeload strfree + addr module.afterload strfree + addr module.loaderror strfree + addr +; + +: free-module-options + module_options @ + begin + ?dup + while + free-one-module + dup module.next @ + swap free-memory + repeat + 0 module_options ! + 0 last_module_option ! +; + only forth also support-functions definitions \ Variables used for processing multiple conf files diff --git a/sys/boot/i386/loader/main.c b/sys/boot/i386/loader/main.c index c1a3ca4..be08271 100644 --- a/sys/boot/i386/loader/main.c +++ b/sys/boot/i386/loader/main.c @@ -69,6 +69,7 @@ static int isa_inb(int port); static void isa_outb(int port, int value); void exit(int code); #ifdef LOADER_ZFS_SUPPORT +static void init_zfs_bootenv(char *currdev); static void i386_zfs_probe(void); #endif @@ -291,12 +292,45 @@ extract_currdev(void) new_currdev.d_unit = 0; } +#ifdef LOADER_ZFS_SUPPORT + if (new_currdev.d_type == DEVT_ZFS) + init_zfs_bootenv(zfs_fmtdev(&new_currdev)); +#endif + env_setenv("currdev", EV_VOLATILE, i386_fmtdev(&new_currdev), i386_setcurrdev, env_nounset); env_setenv("loaddev", EV_VOLATILE, i386_fmtdev(&new_currdev), env_noset, env_nounset); } +#ifdef LOADER_ZFS_SUPPORT +static void +init_zfs_bootenv(char *currdev) +{ + char *beroot; + + if (strlen(currdev) == 0) + return; + if(strncmp(currdev, "zfs:", 4) != 0) + return; + /* Remove the trailing : */ + currdev[strlen(currdev) - 1] = '\0'; + setenv("zfs_be_active", currdev, 1); + setenv("zfs_be_currpage", "1", 1); + /* Do not overwrite if already set */ + setenv("vfs.root.mountfrom", currdev, 0); + /* Forward past zfs: */ + currdev = strchr(currdev, ':'); + currdev++; + /* Remove the last element (current bootenv) */ + beroot = strrchr(currdev, '/'); + if (beroot != NULL) + beroot[0] = '\0'; + beroot = currdev; + setenv("zfs_be_root", beroot, 1); +} +#endif + COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot); static int @@ -350,6 +384,40 @@ command_lszfs(int argc, char *argv[]) command_errmsg = strerror(err); return (CMD_ERROR); } + + return (CMD_OK); +} + +COMMAND_SET(reloadbe, "reloadbe", "refresh the list of ZFS Boot Environments", + command_reloadbe); + +static int +command_reloadbe(int argc, char *argv[]) +{ + int err; + char *root; + + if (argc > 2) { + command_errmsg = "wrong number of arguments"; + return (CMD_ERROR); + } + + if (argc == 2) { + err = zfs_bootenv(argv[1]); + } else { + root = getenv("zfs_be_root"); + if (root == NULL) { + /* There does not appear to be a ZFS pool here, exit without error */ + return (CMD_OK); + } + err = zfs_bootenv(getenv("zfs_be_root")); + } + + if (err != 0) { + command_errmsg = strerror(err); + return (CMD_ERROR); + } + return (CMD_OK); } #endif diff --git a/sys/boot/userboot/userboot/main.c b/sys/boot/userboot/userboot/main.c index c9353ab..e4d546a 100644 --- a/sys/boot/userboot/userboot/main.c +++ b/sys/boot/userboot/userboot/main.c @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$"); static void userboot_zfs_probe(void); static int userboot_zfs_found; +static void init_zfs_bootenv(char *currdev); #endif #define USERBOOT_VERSION USERBOOT_VERSION_3 @@ -167,6 +168,7 @@ extract_currdev(void) zdev.d_type = zdev.d_dev->dv_type; dev = *(struct disk_devdesc *)&zdev; + init_zfs_bootenv(zfs_fmtdev(&dev)); } else #endif @@ -198,6 +200,32 @@ extract_currdev(void) #if defined(USERBOOT_ZFS_SUPPORT) static void +init_zfs_bootenv(char *currdev) +{ + char *beroot; + + if (strlen(currdev) == 0) + return; + if(strncmp(currdev, "zfs:", 4) != 0) + return; + /* Remove the trailing : */ + currdev[strlen(currdev) - 1] = '\0'; + setenv("zfs_be_active", currdev, 1); + setenv("zfs_be_currpage", "1", 1); + /* Do not overwrite if already set */ + setenv("vfs.root.mountfrom", currdev, 0); + /* Forward past zfs: */ + currdev = strchr(currdev, ':'); + currdev++; + /* Remove the last element (current bootenv) */ + beroot = strrchr(currdev, '/'); + if (beroot != NULL) + beroot[0] = '\0'; + beroot = currdev; + setenv("zfs_be_root", beroot, 1); +} + +static void userboot_zfs_probe(void) { char devname[32]; @@ -237,6 +265,38 @@ command_lszfs(int argc, char *argv[]) } return (CMD_OK); } + +COMMAND_SET(reloadbe, "reloadbe", "refresh the list of ZFS Boot Environments", + command_reloadbe); + +static int +command_reloadbe(int argc, char *argv[]) +{ + int err; + char *root; + + if (argc > 2) { + command_errmsg = "wrong number of arguments"; + return (CMD_ERROR); + } + + if (argc == 2) { + err = zfs_bootenv(argv[1]); + } else { + root = getenv("zfs_be_root"); + if (root == NULL) { + return (CMD_OK); + } + err = zfs_bootenv(root); + } + + if (err != 0) { + command_errmsg = strerror(err); + return (CMD_ERROR); + } + + return (CMD_OK); +} #endif /* USERBOOT_ZFS_SUPPORT */ COMMAND_SET(quit, "quit", "exit the loader", command_quit); diff --git a/sys/boot/zfs/libzfs.h b/sys/boot/zfs/libzfs.h index 6834f8b..b289849 100644 --- a/sys/boot/zfs/libzfs.h +++ b/sys/boot/zfs/libzfs.h @@ -62,6 +62,9 @@ int zfs_parsedev(struct zfs_devdesc *dev, const char *devspec, char *zfs_fmtdev(void *vdev); int zfs_probe_dev(const char *devname, uint64_t *pool_guid); int zfs_list(const char *name); +int zfs_bootenv(const char *name); +int zfs_belist_add(const char *name); +int zfs_set_env(void); extern struct devsw zfs_dev; extern struct fs_ops zfs_fsops; diff --git a/sys/boot/zfs/zfs.c b/sys/boot/zfs/zfs.c index 64c738d..0679a57 100644 --- a/sys/boot/zfs/zfs.c +++ b/sys/boot/zfs/zfs.c @@ -48,6 +48,10 @@ __FBSDID("$FreeBSD$"); #include "zfsimpl.c" +/* Define the range of indexes to be populated with ZFS Boot Environments */ +#define ZFS_BE_FIRST 4 +#define ZFS_BE_LAST 8 + static int zfs_open(const char *path, struct open_file *f); static int zfs_write(struct open_file *f, void *buf, size_t size, size_t *resid); static int zfs_close(struct open_file *f); @@ -80,6 +84,16 @@ struct file { zap_leaf_phys_t *f_zap_leaf; /* zap leaf buffer */ }; +static int zfs_env_index; +static int zfs_env_count; + +SLIST_HEAD(zfs_be_list, zfs_be_entry) zfs_be_head = SLIST_HEAD_INITIALIZER(zfs_be_head); +struct zfs_be_list *zfs_be_headp; +struct zfs_be_entry { + const char *name; + SLIST_ENTRY(zfs_be_entry) entries; +} *zfs_be, *zfs_be_tmp; + /* * Open a file. */ @@ -691,6 +705,161 @@ zfs_list(const char *name) rv = zfs_lookup_dataset(spa, dsname, &objid); if (rv != 0) return (rv); - rv = zfs_list_dataset(spa, objid); + + return (zfs_list_dataset(spa, objid)); +} + +int +zfs_bootenv(const char *name) +{ + static char poolname[ZFS_MAXNAMELEN], *dsname, *root; + char becount[4]; + uint64_t objid; + spa_t *spa; + int len, rv, pages, perpage, currpage; + + if (name == NULL) + return (EINVAL); + if ((root = getenv("zfs_be_root")) == NULL) + return (EINVAL); + + if (strcmp(name, root) != 0) { + if (setenv("zfs_be_root", name, 1) != 0) + return (ENOMEM); + } + + SLIST_INIT(&zfs_be_head); + zfs_env_count = 0; + len = strlen(name); + dsname = strchr(name, '/'); + if (dsname != NULL) { + len = dsname - name; + dsname++; + } else + dsname = ""; + memcpy(poolname, name, len); + poolname[len] = '\0'; + + spa = spa_find_by_name(poolname); + if (!spa) + return (ENXIO); + rv = zfs_lookup_dataset(spa, dsname, &objid); + if (rv != 0) + return (rv); + rv = zfs_callback_dataset(spa, objid, zfs_belist_add); + + /* Calculate and store the number of pages of BEs */ + perpage = (ZFS_BE_LAST - ZFS_BE_FIRST + 1); + pages = (zfs_env_count / perpage) + ((zfs_env_count % perpage) > 0 ? 1 : 0); + snprintf(becount, 4, "%d", pages); + if (setenv("zfs_be_pages", becount, 1) != 0) + return (ENOMEM); + + /* Roll over the page counter if it has exceeded the maximum */ + currpage = strtol(getenv("zfs_be_currpage"), NULL, 10); + if (currpage > pages) { + if (setenv("zfs_be_currpage", "1", 1) != 0) + return (ENOMEM); + } + + /* Populate the menu environment variables */ + zfs_set_env(); + + /* Clean up the SLIST of ZFS BEs */ + while (!SLIST_EMPTY(&zfs_be_head)) { + zfs_be = SLIST_FIRST(&zfs_be_head); + SLIST_REMOVE_HEAD(&zfs_be_head, entries); + free(zfs_be); + } + return (rv); } + +int +zfs_belist_add(const char *name) +{ + + /* Add the boot environment to the head of the SLIST */ + zfs_be = malloc(sizeof(struct zfs_be_entry)); + zfs_be->name = name; + SLIST_INSERT_HEAD(&zfs_be_head, zfs_be, entries); + zfs_env_count++; + + return (0); +} + +int +zfs_set_env(void) +{ + char envname[32], envval[256]; + char *beroot, *pagenum; + int rv, page, ctr; + + beroot = getenv("zfs_be_root"); + if (beroot == NULL) { + return (1); + } + + pagenum = getenv("zfs_be_currpage"); + if (pagenum != NULL) { + page = strtol(pagenum, NULL, 10); + } else { + page = 1; + } + + ctr = 1; + rv = 0; + zfs_env_index = ZFS_BE_FIRST; + SLIST_FOREACH_SAFE(zfs_be, &zfs_be_head, entries, zfs_be_tmp) { + /* Skip to the requested page number */ + if (ctr <= ((ZFS_BE_LAST - ZFS_BE_FIRST + 1) * (page - 1))) { + ctr++; + continue; + } + + snprintf(envname, sizeof(envname), "bootenvmenu_caption[%d]", zfs_env_index); + snprintf(envval, sizeof(envval), "%s", zfs_be->name); + rv = setenv(envname, envval, 1); + if (rv != 0) { + break; + } + + snprintf(envname, sizeof(envname), "bootenvansi_caption[%d]", zfs_env_index); + rv = setenv(envname, envval, 1); + if (rv != 0){ + break; + } + + snprintf(envname, sizeof(envname), "bootenvmenu_command[%d]", zfs_env_index); + rv = setenv(envname, "set_bootenv", 1); + if (rv != 0){ + break; + } + + snprintf(envname, sizeof(envname), "bootenv_root[%d]", zfs_env_index); + snprintf(envval, sizeof(envval), "zfs:%s/%s", beroot, zfs_be->name); + rv = setenv(envname, envval, 1); + if (rv != 0){ + break; + } + + zfs_env_index++; + if (zfs_env_index > ZFS_BE_LAST) { + break; + } + + } + + for (; zfs_env_index <= ZFS_BE_LAST; zfs_env_index++) { + snprintf(envname, sizeof(envname), "bootenvmenu_caption[%d]", zfs_env_index); + (void)unsetenv(envname); + snprintf(envname, sizeof(envname), "bootenvansi_caption[%d]", zfs_env_index); + (void)unsetenv(envname); + snprintf(envname, sizeof(envname), "bootenvmenu_command[%d]", zfs_env_index); + (void)unsetenv(envname); + snprintf(envname, sizeof(envname), "bootenv_root[%d]", zfs_env_index); + (void)unsetenv(envname); + } + + return (rv); +}
\ No newline at end of file diff --git a/sys/boot/zfs/zfsimpl.c b/sys/boot/zfs/zfsimpl.c index d889047..927fbad 100644 --- a/sys/boot/zfs/zfsimpl.c +++ b/sys/boot/zfs/zfsimpl.c @@ -1473,7 +1473,7 @@ zap_lookup(const spa_t *spa, const dnode_phys_t *dnode, const char *name, uint64 * the directory contents. */ static int -mzap_list(const dnode_phys_t *dnode) +mzap_list(const dnode_phys_t *dnode, int (*callback)(const char *)) { const mzap_phys_t *mz; const mzap_ent_phys_t *mze; @@ -1492,7 +1492,7 @@ mzap_list(const dnode_phys_t *dnode) mze = &mz->mz_chunk[i]; if (mze->mze_name[0]) //printf("%-32s 0x%jx\n", mze->mze_name, (uintmax_t)mze->mze_value); - printf("%s\n", mze->mze_name); + callback(mze->mze_name); } return (0); @@ -1503,7 +1503,7 @@ mzap_list(const dnode_phys_t *dnode) * the directory header. */ static int -fzap_list(const spa_t *spa, const dnode_phys_t *dnode) +fzap_list(const spa_t *spa, const dnode_phys_t *dnode, int (*callback)(const char *)) { int bsize = dnode->dn_datablkszsec << SPA_MINBLOCKSHIFT; zap_phys_t zh = *(zap_phys_t *) zap_scratch; @@ -1566,13 +1566,21 @@ fzap_list(const spa_t *spa, const dnode_phys_t *dnode) value = fzap_leaf_value(&zl, zc); //printf("%s 0x%jx\n", name, (uintmax_t)value); - printf("%s\n", name); + callback((const char *)name); } } return (0); } +static int zfs_printf(const char *name) +{ + + printf("%s\n", name); + + return (0); +} + /* * List a zap directory. */ @@ -1587,9 +1595,9 @@ zap_list(const spa_t *spa, const dnode_phys_t *dnode) zap_type = *(uint64_t *) zap_scratch; if (zap_type == ZBT_MICRO) - return mzap_list(dnode); + return mzap_list(dnode, zfs_printf); else - return fzap_list(spa, dnode); + return fzap_list(spa, dnode, zfs_printf); } static int @@ -1858,6 +1866,48 @@ zfs_list_dataset(const spa_t *spa, uint64_t objnum/*, int pos, char *entry*/) return (zap_list(spa, &child_dir_zap) != 0); } + +int +zfs_callback_dataset(const spa_t *spa, uint64_t objnum, int (*callback)(const char *name)) +{ + uint64_t dir_obj, child_dir_zapobj, zap_type; + dnode_phys_t child_dir_zap, dir, dataset; + dsl_dataset_phys_t *ds; + dsl_dir_phys_t *dd; + int err; + + err = objset_get_dnode(spa, &spa->spa_mos, objnum, &dataset); + if (err != 0) { + printf("ZFS: can't find dataset %ju\n", (uintmax_t)objnum); + return (err); + } + ds = (dsl_dataset_phys_t *) &dataset.dn_bonus; + dir_obj = ds->ds_dir_obj; + + err = objset_get_dnode(spa, &spa->spa_mos, dir_obj, &dir); + if (err != 0) { + printf("ZFS: can't find dirobj %ju\n", (uintmax_t)dir_obj); + return (err); + } + dd = (dsl_dir_phys_t *)&dir.dn_bonus; + + child_dir_zapobj = dd->dd_child_dir_zapobj; + err = objset_get_dnode(spa, &spa->spa_mos, child_dir_zapobj, &child_dir_zap); + if (err != 0) { + printf("ZFS: can't find child zap %ju\n", (uintmax_t)dir_obj); + return (err); + } + + err = dnode_read(spa, &child_dir_zap, 0, zap_scratch, child_dir_zap.dn_datablkszsec * 512); + if (err != 0) + return (err); + + zap_type = *(uint64_t *) zap_scratch; + if (zap_type == ZBT_MICRO) + return mzap_list(&child_dir_zap, callback); + else + return fzap_list(spa, &child_dir_zap, callback); +} #endif /* diff --git a/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c b/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c index 1954873..19fb43c 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c +++ b/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c @@ -63,6 +63,8 @@ #if !defined(sun) #include <sys/dtrace_bsd.h> #include <sys/eventhandler.h> +#include <sys/sysctl.h> +#include <sys/u8_textprep.h> #include <sys/user.h> #include <vm/vm.h> #include <vm/pmap.h> @@ -172,13 +174,14 @@ static volatile uint64_t fasttrap_mod_gen; /* * When the fasttrap provider is loaded, fasttrap_max is set to either - * FASTTRAP_MAX_DEFAULT or the value for fasttrap-max-probes in the - * fasttrap.conf file. Each time a probe is created, fasttrap_total is - * incremented by the number of tracepoints that may be associated with that - * probe; fasttrap_total is capped at fasttrap_max. + * FASTTRAP_MAX_DEFAULT, or the value for fasttrap-max-probes in the + * fasttrap.conf file (Illumos), or the value provied in the loader.conf (FreeBSD). + * Each time a probe is created, fasttrap_total is incremented by the number + * of tracepoints that may be associated with that probe; fasttrap_total is capped + * at fasttrap_max. */ #define FASTTRAP_MAX_DEFAULT 250000 -static uint32_t fasttrap_max; +static uint32_t fasttrap_max = FASTTRAP_MAX_DEFAULT; static uint32_t fasttrap_total; /* @@ -226,6 +229,17 @@ static kmutex_t fasttrap_cpuc_pid_lock[MAXCPU]; static eventhandler_tag fasttrap_thread_dtor_tag; #endif +static unsigned long tpoints_hash_size = FASTTRAP_TPOINTS_DEFAULT_SIZE; + +#ifdef __FreeBSD__ +SYSCTL_DECL(_kern_dtrace); +SYSCTL_NODE(_kern_dtrace, OID_AUTO, fasttrap, CTLFLAG_RD, 0, "DTrace fasttrap parameters"); +SYSCTL_UINT(_kern_dtrace_fasttrap, OID_AUTO, max_probes, CTLFLAG_RWTUN, &fasttrap_max, + FASTTRAP_MAX_DEFAULT, "Maximum number of fasttrap probes"); +SYSCTL_ULONG(_kern_dtrace_fasttrap, OID_AUTO, tpoints_hash_size, CTLFLAG_RDTUN, &tpoints_hash_size, + FASTTRAP_TPOINTS_DEFAULT_SIZE, "Size of the tracepoint hash table"); +#endif + static int fasttrap_highbit(ulong_t i) { @@ -2466,8 +2480,6 @@ fasttrap_load(void) #if defined(sun) fasttrap_max = ddi_getprop(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS, "fasttrap-max-probes", FASTTRAP_MAX_DEFAULT); -#else - fasttrap_max = FASTTRAP_MAX_DEFAULT; #endif fasttrap_total = 0; @@ -2478,12 +2490,14 @@ fasttrap_load(void) nent = ddi_getprop(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS, "fasttrap-hash-size", FASTTRAP_TPOINTS_DEFAULT_SIZE); #else - nent = FASTTRAP_TPOINTS_DEFAULT_SIZE; + nent = tpoints_hash_size; #endif if (nent == 0 || nent > 0x1000000) nent = FASTTRAP_TPOINTS_DEFAULT_SIZE; + tpoints_hash_size = nent; + if (ISP2(nent)) fasttrap_tpoints.fth_nent = nent; else diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c index afcef0d..2f60c13 100644 --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -1429,6 +1429,49 @@ freebsd32_futimesat(struct thread *td, struct freebsd32_futimesat_args *uap) } int +freebsd32_futimens(struct thread *td, struct freebsd32_futimens_args *uap) +{ + struct timespec32 ts32[2]; + struct timespec ts[2], *tsp; + int error; + + if (uap->times != NULL) { + error = copyin(uap->times, ts32, sizeof(ts32)); + if (error) + return (error); + CP(ts32[0], ts[0], tv_sec); + CP(ts32[0], ts[0], tv_nsec); + CP(ts32[1], ts[1], tv_sec); + CP(ts32[1], ts[1], tv_nsec); + tsp = ts; + } else + tsp = NULL; + return (kern_futimens(td, uap->fd, tsp, UIO_SYSSPACE)); +} + +int +freebsd32_utimensat(struct thread *td, struct freebsd32_utimensat_args *uap) +{ + struct timespec32 ts32[2]; + struct timespec ts[2], *tsp; + int error; + + if (uap->times != NULL) { + error = copyin(uap->times, ts32, sizeof(ts32)); + if (error) + return (error); + CP(ts32[0], ts[0], tv_sec); + CP(ts32[0], ts[0], tv_nsec); + CP(ts32[1], ts[1], tv_sec); + CP(ts32[1], ts[1], tv_nsec); + tsp = ts; + } else + tsp = NULL; + return (kern_utimensat(td, uap->fd, uap->path, UIO_USERSPACE, + tsp, UIO_SYSSPACE, uap->flag)); +} + +int freebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap) { struct timeval32 tv32; diff --git a/sys/compat/freebsd32/freebsd32_proto.h b/sys/compat/freebsd32/freebsd32_proto.h index c4a1e30..16dc17e 100644 --- a/sys/compat/freebsd32/freebsd32_proto.h +++ b/sys/compat/freebsd32/freebsd32_proto.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: stable/10/sys/compat/freebsd32/syscalls.master 276955 2015-01-11 07:02:03Z dchagin + * created from FreeBSD: stable/10/sys/compat/freebsd32/syscalls.master 293474 2016-01-09 14:20:23Z dchagin */ #ifndef _FREEBSD32_SYSPROTO_H_ @@ -699,6 +699,16 @@ struct freebsd32_ppoll_args { char ts_l_[PADL_(const struct timespec32 *)]; const struct timespec32 * ts; char ts_r_[PADR_(const struct timespec32 *)]; char set_l_[PADL_(const sigset_t *)]; const sigset_t * set; char set_r_[PADR_(const sigset_t *)]; }; +struct freebsd32_futimens_args { + char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; + char times_l_[PADL_(struct timespec *)]; struct timespec * times; char times_r_[PADR_(struct timespec *)]; +}; +struct freebsd32_utimensat_args { + char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; + char times_l_[PADL_(struct timespec *)]; struct timespec * times; char times_r_[PADR_(struct timespec *)]; + char flag_l_[PADL_(int)]; int flag; char flag_r_[PADR_(int)]; +}; #if !defined(PAD64_REQUIRED) && (defined(__powerpc__) || defined(__mips__)) #define PAD64_REQUIRED #endif @@ -833,6 +843,8 @@ int freebsd32_procctl(struct thread *, struct freebsd32_procctl_args *); int freebsd32_procctl(struct thread *, struct freebsd32_procctl_args *); #endif int freebsd32_ppoll(struct thread *, struct freebsd32_ppoll_args *); +int freebsd32_futimens(struct thread *, struct freebsd32_futimens_args *); +int freebsd32_utimensat(struct thread *, struct freebsd32_utimensat_args *); #ifdef COMPAT_43 @@ -1250,6 +1262,8 @@ int freebsd7_freebsd32_shmctl(struct thread *, struct freebsd7_freebsd32_shmctl_ #define FREEBSD32_SYS_AUE_freebsd32_procctl AUE_NULL #define FREEBSD32_SYS_AUE_freebsd32_procctl AUE_NULL #define FREEBSD32_SYS_AUE_freebsd32_ppoll AUE_POLL +#define FREEBSD32_SYS_AUE_freebsd32_futimens AUE_FUTIMES +#define FREEBSD32_SYS_AUE_freebsd32_utimensat AUE_FUTIMESAT #undef PAD_ #undef PADL_ diff --git a/sys/compat/freebsd32/freebsd32_syscall.h b/sys/compat/freebsd32/freebsd32_syscall.h index 92af89b..cf4e492 100644 --- a/sys/compat/freebsd32/freebsd32_syscall.h +++ b/sys/compat/freebsd32/freebsd32_syscall.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: stable/10/sys/compat/freebsd32/syscalls.master 276955 2015-01-11 07:02:03Z dchagin + * created from FreeBSD: stable/10/sys/compat/freebsd32/syscalls.master 293474 2016-01-09 14:20:23Z dchagin */ #define FREEBSD32_SYS_syscall 0 @@ -455,4 +455,6 @@ #define FREEBSD32_SYS_freebsd32_procctl 544 #define FREEBSD32_SYS_freebsd32_procctl 544 #define FREEBSD32_SYS_freebsd32_ppoll 545 -#define FREEBSD32_SYS_MAXSYSCALL 546 +#define FREEBSD32_SYS_freebsd32_futimens 546 +#define FREEBSD32_SYS_freebsd32_utimensat 547 +#define FREEBSD32_SYS_MAXSYSCALL 548 diff --git a/sys/compat/freebsd32/freebsd32_syscalls.c b/sys/compat/freebsd32/freebsd32_syscalls.c index 01a1201..5b442c3 100644 --- a/sys/compat/freebsd32/freebsd32_syscalls.c +++ b/sys/compat/freebsd32/freebsd32_syscalls.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: stable/10/sys/compat/freebsd32/syscalls.master 276955 2015-01-11 07:02:03Z dchagin + * created from FreeBSD: stable/10/sys/compat/freebsd32/syscalls.master 293474 2016-01-09 14:20:23Z dchagin */ const char *freebsd32_syscallnames[] = { @@ -579,4 +579,6 @@ const char *freebsd32_syscallnames[] = { "freebsd32_procctl", /* 544 = freebsd32_procctl */ #endif "freebsd32_ppoll", /* 545 = freebsd32_ppoll */ + "freebsd32_futimens", /* 546 = freebsd32_futimens */ + "freebsd32_utimensat", /* 547 = freebsd32_utimensat */ }; diff --git a/sys/compat/freebsd32/freebsd32_sysent.c b/sys/compat/freebsd32/freebsd32_sysent.c index 3b0b3fe..f3321a0 100644 --- a/sys/compat/freebsd32/freebsd32_sysent.c +++ b/sys/compat/freebsd32/freebsd32_sysent.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: stable/10/sys/compat/freebsd32/syscalls.master 276955 2015-01-11 07:02:03Z dchagin + * created from FreeBSD: stable/10/sys/compat/freebsd32/syscalls.master 293474 2016-01-09 14:20:23Z dchagin */ #include "opt_compat.h" @@ -616,4 +616,6 @@ struct sysent freebsd32_sysent[] = { { AS(freebsd32_procctl_args), (sy_call_t *)freebsd32_procctl, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 544 = freebsd32_procctl */ #endif { AS(freebsd32_ppoll_args), (sy_call_t *)freebsd32_ppoll, AUE_POLL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 545 = freebsd32_ppoll */ + { AS(freebsd32_futimens_args), (sy_call_t *)freebsd32_futimens, AUE_FUTIMES, NULL, 0, 0, 0, SY_THR_STATIC }, /* 546 = freebsd32_futimens */ + { AS(freebsd32_utimensat_args), (sy_call_t *)freebsd32_utimensat, AUE_FUTIMESAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 547 = freebsd32_utimensat */ }; diff --git a/sys/compat/freebsd32/freebsd32_systrace_args.c b/sys/compat/freebsd32/freebsd32_systrace_args.c index 6d9ab1c..87cf3b3 100644 --- a/sys/compat/freebsd32/freebsd32_systrace_args.c +++ b/sys/compat/freebsd32/freebsd32_systrace_args.c @@ -3323,6 +3323,24 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) *n_args = 4; break; } + /* freebsd32_futimens */ + case 546: { + struct freebsd32_futimens_args *p = params; + iarg[0] = p->fd; /* int */ + uarg[1] = (intptr_t) p->times; /* struct timespec * */ + *n_args = 2; + break; + } + /* freebsd32_utimensat */ + case 547: { + struct freebsd32_utimensat_args *p = params; + iarg[0] = p->fd; /* int */ + uarg[1] = (intptr_t) p->path; /* char * */ + uarg[2] = (intptr_t) p->times; /* struct timespec * */ + iarg[3] = p->flag; /* int */ + *n_args = 4; + break; + } default: *n_args = 0; break; @@ -8907,6 +8925,38 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; }; break; + /* freebsd32_futimens */ + case 546: + switch(ndx) { + case 0: + p = "int"; + break; + case 1: + p = "struct timespec *"; + break; + default: + break; + }; + break; + /* freebsd32_utimensat */ + case 547: + switch(ndx) { + case 0: + p = "int"; + break; + case 1: + p = "char *"; + break; + case 2: + p = "struct timespec *"; + break; + case 3: + p = "int"; + break; + default: + break; + }; + break; default: break; }; @@ -10795,6 +10845,16 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) if (ndx == 0 || ndx == 1) p = "int"; break; + /* freebsd32_futimens */ + case 546: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* freebsd32_utimensat */ + case 547: + if (ndx == 0 || ndx == 1) + p = "int"; + break; default: break; }; diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master index 48c2f3e..6c167bf 100644 --- a/sys/compat/freebsd32/syscalls.master +++ b/sys/compat/freebsd32/syscalls.master @@ -1069,3 +1069,8 @@ 545 AUE_POLL STD { int freebsd32_ppoll(struct pollfd *fds, \ u_int nfds, const struct timespec32 *ts, \ const sigset_t *set); } +546 AUE_FUTIMES STD { int freebsd32_futimens(int fd, \ + struct timespec *times); } +547 AUE_FUTIMESAT STD { int freebsd32_utimensat(int fd, \ + char *path, \ + struct timespec *times, int flag); } diff --git a/sys/compat/ia32/ia32_sysvec.c b/sys/compat/ia32/ia32_sysvec.c index bfc17d6..206935a 100644 --- a/sys/compat/ia32/ia32_sysvec.c +++ b/sys/compat/ia32/ia32_sysvec.c @@ -139,6 +139,7 @@ struct sysentvec ia32_freebsd_sysvec = { .sv_shared_page_base = FREEBSD32_SHAREDPAGE, .sv_shared_page_len = PAGE_SIZE, .sv_schedtail = NULL, + .sv_thread_detach = NULL, }; INIT_SYSENTVEC(elf_ia32_sysvec, &ia32_freebsd_sysvec); diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c index 4aae77e..6e591e9 100644 --- a/sys/compat/linprocfs/linprocfs.c +++ b/sys/compat/linprocfs/linprocfs.c @@ -39,13 +39,12 @@ * @(#)procfs_status.c 8.4 (Berkeley) 6/15/94 */ -#include "opt_compat.h" - #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/queue.h> +#include <sys/systm.h> #include <sys/blist.h> #include <sys/conf.h> #include <sys/exec.h> @@ -53,6 +52,7 @@ __FBSDID("$FreeBSD$"); #include <sys/filedesc.h> #include <sys/jail.h> #include <sys/kernel.h> +#include <sys/limits.h> #include <sys/linker.h> #include <sys/lock.h> #include <sys/malloc.h> @@ -68,6 +68,7 @@ __FBSDID("$FreeBSD$"); #include <sys/smp.h> #include <sys/socket.h> #include <sys/sysctl.h> +#include <sys/sysent.h> #include <sys/systm.h> #include <sys/time.h> #include <sys/tty.h> @@ -78,7 +79,7 @@ __FBSDID("$FreeBSD$"); #include <sys/bus.h> #include <net/if.h> -#include <net/vnet.h> +#include <net/if_types.h> #include <vm/vm.h> #include <vm/vm_extern.h> @@ -98,11 +99,7 @@ __FBSDID("$FreeBSD$"); #include <machine/md_var.h> #endif /* __i386__ || __amd64__ */ -#ifdef COMPAT_FREEBSD32 -#include <compat/freebsd32/freebsd32_util.h> -#endif - -#include <compat/linux/linux_ioctl.h> +#include <compat/linux/linux.h> #include <compat/linux/linux_mib.h> #include <compat/linux/linux_misc.h> #include <compat/linux/linux_util.h> @@ -734,6 +731,7 @@ linprocfs_doprocstatus(PFS_FILL_ARGS) segsz_t lsize; struct thread *td2; struct sigacts *ps; + l_sigset_t siglist, sigignore, sigcatch; int i; PROC_LOCK(p); @@ -822,29 +820,25 @@ linprocfs_doprocstatus(PFS_FILL_ARGS) /* * Signal masks - * - * We support up to 128 signals, while Linux supports 32, - * but we only define 32 (the same 32 as Linux, to boot), so - * just show the lower 32 bits of each mask. XXX hack. - * - * NB: on certain platforms (Sparc at least) Linux actually - * supports 64 signals, but this code is a long way from - * running on anything but i386, so ignore that for now. */ PROC_LOCK(p); - sbuf_printf(sb, "SigPnd:\t%08x\n", p->p_siglist.__bits[0]); - /* - * I can't seem to find out where the signal mask is in - * relation to struct proc, so SigBlk is left unimplemented. - */ - sbuf_printf(sb, "SigBlk:\t%08x\n", 0); /* XXX */ + bsd_to_linux_sigset(&p->p_siglist, &siglist); ps = p->p_sigacts; mtx_lock(&ps->ps_mtx); - sbuf_printf(sb, "SigIgn:\t%08x\n", ps->ps_sigignore.__bits[0]); - sbuf_printf(sb, "SigCgt:\t%08x\n", ps->ps_sigcatch.__bits[0]); + bsd_to_linux_sigset(&ps->ps_sigignore, &sigignore); + bsd_to_linux_sigset(&ps->ps_sigcatch, &sigcatch); mtx_unlock(&ps->ps_mtx); PROC_UNLOCK(p); + sbuf_printf(sb, "SigPnd:\t%016jx\n", siglist.__mask); + /* + * XXX. SigBlk - target thread's signal mask, td_sigmask. + * To implement SigBlk pseudofs should support proc/tid dir entries. + */ + sbuf_printf(sb, "SigBlk:\t%016x\n", 0); + sbuf_printf(sb, "SigIgn:\t%016jx\n", sigignore.__mask); + sbuf_printf(sb, "SigCgt:\t%016jx\n", sigcatch.__mask); + /* * Linux also prints the capability masks, but we don't have * capabilities yet, and when we do get them they're likely to @@ -937,34 +931,22 @@ linprocfs_doproccmdline(PFS_FILL_ARGS) static int linprocfs_doprocenviron(PFS_FILL_ARGS) { - int ret; - - PROC_LOCK(p); - if ((ret = p_candebug(td, p)) != 0) { - PROC_UNLOCK(p); - return (ret); - } /* * Mimic linux behavior and pass only processes with usermode * address space as valid. Return zero silently otherwize. */ - if (p->p_vmspace == &vmspace0) { - PROC_UNLOCK(p); + if (p->p_vmspace == &vmspace0) return (0); - } - if ((p->p_flag & P_SYSTEM) != 0) { - PROC_UNLOCK(p); - return (0); - } - - PROC_UNLOCK(p); - - ret = proc_getenvv(td, p, sb); - return (ret); + return (proc_getenvv(td, p, sb)); } +static char l32_map_str[] = "%08lx-%08lx %s%s%s%s %08lx %02x:%02x %lu%s%s\n"; +static char l64_map_str[] = "%016lx-%016lx %s%s%s%s %08lx %02x:%02x %lu%s%s\n"; +static char vdso_str[] = " [vdso]"; +static char stack_str[] = " [stack]"; + /* * Filler function for proc/pid/maps */ @@ -980,6 +962,7 @@ linprocfs_doprocmaps(PFS_FILL_ARGS) vm_prot_t e_prot; unsigned int last_timestamp; char *name = "", *freename = NULL; + const char *l_map_str; ino_t ino; int ref_count, shadow_count, flags; int error; @@ -999,6 +982,11 @@ linprocfs_doprocmaps(PFS_FILL_ARGS) vm = vmspace_acquire_ref(p); if (vm == NULL) return (ESRCH); + + if (SV_CURPROC_FLAG(SV_LP64)) + l_map_str = l64_map_str; + else + l_map_str = l32_map_str; map = &vm->vm_map; vm_map_lock_read(map); for (entry = map->header.next; entry != &map->header; @@ -1037,6 +1025,11 @@ linprocfs_doprocmaps(PFS_FILL_ARGS) VOP_GETATTR(vp, &vat, td->td_ucred); ino = vat.va_fileid; vput(vp); + } else if (SV_PROC_ABI(p) == SV_ABI_LINUX) { + if (e_start == p->p_sysent->sv_shared_page_base) + name = vdso_str; + if (e_end == p->p_sysent->sv_usrstack) + name = stack_str; } } else { flags = 0; @@ -1048,8 +1041,7 @@ linprocfs_doprocmaps(PFS_FILL_ARGS) * format: * start, end, access, offset, major, minor, inode, name. */ - error = sbuf_printf(sb, - "%08lx-%08lx %s%s%s%s %08lx %02x:%02x %lu%s%s\n", + error = sbuf_printf(sb, l_map_str, (u_long)e_start, (u_long)e_end, (e_prot & VM_PROT_READ)?"r":"-", (e_prot & VM_PROT_WRITE)?"w":"-", @@ -1086,6 +1078,35 @@ linprocfs_doprocmaps(PFS_FILL_ARGS) } /* + * Criteria for interface name translation + */ +#define IFP_IS_ETH(ifp) (ifp->if_type == IFT_ETHER) + +static int +linux_ifname(struct ifnet *ifp, char *buffer, size_t buflen) +{ + struct ifnet *ifscan; + int ethno; + + IFNET_RLOCK_ASSERT(); + + /* Short-circuit non ethernet interfaces */ + if (!IFP_IS_ETH(ifp)) + return (strlcpy(buffer, ifp->if_xname, buflen)); + + /* Determine the (relative) unit number for ethernet interfaces */ + ethno = 0; + TAILQ_FOREACH(ifscan, &V_ifnet, if_link) { + if (ifscan == ifp) + return (snprintf(buffer, buflen, "eth%d", ethno)); + if (IFP_IS_ETH(ifscan)) + ethno++; + } + + return (0); +} + +/* * Filler function for proc/net/dev */ static int @@ -1232,8 +1253,6 @@ linprocfs_doscsiscsi(PFS_FILL_ARGS) return (0); } -extern struct cdevsw *cdevsw[]; - /* * Filler function for proc/devices */ @@ -1328,6 +1347,52 @@ linprocfs_douuid(PFS_FILL_ARGS) return(0); } +/* + * Filler function for proc/pid/auxv + */ +static int +linprocfs_doauxv(PFS_FILL_ARGS) +{ + struct sbuf *asb; + off_t buflen, resid; + int error; + + /* + * Mimic linux behavior and pass only processes with usermode + * address space as valid. Return zero silently otherwise. + */ + if (p->p_vmspace == &vmspace0) + return (0); + + if (uio->uio_resid == 0) + return (0); + if (uio->uio_offset < 0 || uio->uio_resid < 0) + return (EINVAL); + + asb = sbuf_new_auto(); + if (asb == NULL) + return (ENOMEM); + error = proc_getauxv(td, p, asb); + if (error == 0) + error = sbuf_finish(asb); + + resid = sbuf_len(asb) - uio->uio_offset; + if (resid > uio->uio_resid) + buflen = uio->uio_resid; + else + buflen = resid; + if (buflen > IOSIZE_MAX) + return (EINVAL); + if (buflen > MAXPHYS) + buflen = MAXPHYS; + if (resid <= 0) + return (0); + + if (error == 0) + error = uiomove(sbuf_data(asb) + uio->uio_offset, buflen, uio); + sbuf_delete(asb); + return (error); +} /* * Constructor @@ -1386,7 +1451,7 @@ linprocfs_init(PFS_INIT_ARGS) pfs_create_link(dir, "cwd", &linprocfs_doproccwd, NULL, NULL, NULL, 0); pfs_create_file(dir, "environ", &linprocfs_doprocenviron, - NULL, NULL, NULL, PFS_RD); + NULL, &procfs_candebug, NULL, PFS_RD); pfs_create_link(dir, "exe", &procfs_doprocfile, NULL, &procfs_notsystem, NULL, 0); pfs_create_file(dir, "maps", &linprocfs_doprocmaps, @@ -1403,6 +1468,8 @@ linprocfs_init(PFS_INIT_ARGS) NULL, NULL, NULL, PFS_RD); pfs_create_link(dir, "fd", &linprocfs_dofdescfs, NULL, NULL, NULL, 0); + pfs_create_file(dir, "auxv", &linprocfs_doauxv, + NULL, &procfs_candebug, NULL, PFS_RD|PFS_RAWRD); /* /proc/scsi/... */ dir = pfs_create_dir(root, "scsi", NULL, NULL, NULL, 0); @@ -1448,7 +1515,11 @@ linprocfs_uninit(PFS_INIT_ARGS) } PSEUDOFS(linprocfs, 1, 0); +#if defined(__amd64__) +MODULE_DEPEND(linprocfs, linux_common, 1, 1, 1); +#else MODULE_DEPEND(linprocfs, linux, 1, 1, 1); +#endif MODULE_DEPEND(linprocfs, procfs, 1, 1, 1); MODULE_DEPEND(linprocfs, sysvmsg, 1, 1, 1); MODULE_DEPEND(linprocfs, sysvsem, 1, 1, 1); diff --git a/sys/compat/linsysfs/linsysfs.c b/sys/compat/linsysfs/linsysfs.c index 45f44af..8b5f9b5 100644 --- a/sys/compat/linsysfs/linsysfs.c +++ b/sys/compat/linsysfs/linsysfs.c @@ -61,12 +61,6 @@ __FBSDID("$FreeBSD$"); #include <machine/bus.h> -#include "opt_compat.h" -#ifdef COMPAT_LINUX32 /* XXX */ -#include <machine/../linux32/linux.h> -#else -#include <machine/../linux/linux.h> -#endif #include <compat/linux/linux_ioctl.h> #include <compat/linux/linux_mib.h> #include <compat/linux/linux_util.h> @@ -281,4 +275,8 @@ linsysfs_uninit(PFS_INIT_ARGS) } PSEUDOFS(linsysfs, 1, 0); +#if defined(__amd64__) +MODULE_DEPEND(linsysfs, linux_common, 1, 1, 1); +#else MODULE_DEPEND(linsysfs, linux, 1, 1, 1); +#endif diff --git a/sys/compat/linux/check_error.d b/sys/compat/linux/check_error.d index 9e3c00a..389e768 100644 --- a/sys/compat/linux/check_error.d +++ b/sys/compat/linux/check_error.d @@ -36,8 +36,8 @@ */ linuxulator*:dummy::not_implemented, -linuxulator*:emul:proc_exit:child_clear_tid_error, -linuxulator*:emul:proc_exit:futex_failed, +linuxulator*:emul:linux_thread_detach:child_clear_tid_error, +linuxulator*:emul:linux_thread_detach:futex_failed, linuxulator*:emul:linux_schedtail:copyout_error, linuxulator*:futex:futex_get:error, linuxulator*:futex:futex_sleep:requeue_error, diff --git a/sys/compat/linux/check_internal_locks.d b/sys/compat/linux/check_internal_locks.d index 2bdef68..b9d7c61 100644 --- a/sys/compat/linux/check_internal_locks.d +++ b/sys/compat/linux/check_internal_locks.d @@ -41,14 +41,9 @@ BEGIN { - check["emul_lock"] = 0; - check["emul_shared_rlock"] = 0; - check["emul_shared_wlock"] = 0; check["futex_mtx"] = 0; } -linuxulator*:locks:emul_lock:locked, -linuxulator*:locks:emul_shared_wlock:locked, linuxulator*:locks:futex_mtx:locked /check[probefunc] > 0/ { @@ -57,9 +52,6 @@ linuxulator*:locks:futex_mtx:locked stack(); } -linuxulator*:locks:emul_lock:locked, -linuxulator*:locks:emul_shared_rlock:locked, -linuxulator*:locks:emul_shared_wlock:locked, linuxulator*:locks:futex_mtx:locked { ++check[probefunc]; @@ -69,9 +61,6 @@ linuxulator*:locks:futex_mtx:locked spec[probefunc] = speculation(); } -linuxulator*:locks:emul_lock:unlock, -linuxulator*:locks:emul_shared_rlock:unlock, -linuxulator*:locks:emul_shared_wlock:unlock, linuxulator*:locks:futex_mtx:unlock /check[probefunc] == 0/ { @@ -82,9 +71,6 @@ linuxulator*:locks:futex_mtx:unlock stack(); } -linuxulator*:locks:emul_lock:unlock, -linuxulator*:locks:emul_shared_rlock:unlock, -linuxulator*:locks:emul_shared_wlock:unlock, linuxulator*:locks:futex_mtx:unlock { discard(spec[probefunc]); @@ -95,27 +81,6 @@ linuxulator*:locks:futex_mtx:unlock /* Timeout handling */ tick-10s -/spec["emul_lock"] != 0 && timestamp - ts["emul_lock"] >= 9999999000/ -{ - commit(spec["emul_lock"]); - spec["emul_lock"] = 0; -} - -tick-10s -/spec["emul_shared_wlock"] != 0 && timestamp - ts["emul_shared_wlock"] >= 9999999000/ -{ - commit(spec["emul_shared_wlock"]); - spec["emul_shared_wlock"] = 0; -} - -tick-10s -/spec["emul_shared_rlock"] != 0 && timestamp - ts["emul_shared_rlock"] >= 9999999000/ -{ - commit(spec["emul_shared_rlock"]); - spec["emul_shared_rlock"] = 0; -} - -tick-10s /spec["futex_mtx"] != 0 && timestamp - ts["futex_mtx"] >= 9999999000/ { commit(spec["futex_mtx"]); diff --git a/sys/compat/linux/linux.c b/sys/compat/linux/linux.c new file mode 100644 index 0000000..d1d7877 --- /dev/null +++ b/sys/compat/linux/linux.c @@ -0,0 +1,205 @@ +/*- + * Copyright (c) 2015 Dmitry Chagin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/signalvar.h> + +#include <compat/linux/linux.h> + + +static int bsd_to_linux_sigtbl[LINUX_SIGTBLSZ] = { + LINUX_SIGHUP, /* SIGHUP */ + LINUX_SIGINT, /* SIGINT */ + LINUX_SIGQUIT, /* SIGQUIT */ + LINUX_SIGILL, /* SIGILL */ + LINUX_SIGTRAP, /* SIGTRAP */ + LINUX_SIGABRT, /* SIGABRT */ + 0, /* SIGEMT */ + LINUX_SIGFPE, /* SIGFPE */ + LINUX_SIGKILL, /* SIGKILL */ + LINUX_SIGBUS, /* SIGBUS */ + LINUX_SIGSEGV, /* SIGSEGV */ + LINUX_SIGSYS, /* SIGSYS */ + LINUX_SIGPIPE, /* SIGPIPE */ + LINUX_SIGALRM, /* SIGALRM */ + LINUX_SIGTERM, /* SIGTERM */ + LINUX_SIGURG, /* SIGURG */ + LINUX_SIGSTOP, /* SIGSTOP */ + LINUX_SIGTSTP, /* SIGTSTP */ + LINUX_SIGCONT, /* SIGCONT */ + LINUX_SIGCHLD, /* SIGCHLD */ + LINUX_SIGTTIN, /* SIGTTIN */ + LINUX_SIGTTOU, /* SIGTTOU */ + LINUX_SIGIO, /* SIGIO */ + LINUX_SIGXCPU, /* SIGXCPU */ + LINUX_SIGXFSZ, /* SIGXFSZ */ + LINUX_SIGVTALRM,/* SIGVTALRM */ + LINUX_SIGPROF, /* SIGPROF */ + LINUX_SIGWINCH, /* SIGWINCH */ + 0, /* SIGINFO */ + LINUX_SIGUSR1, /* SIGUSR1 */ + LINUX_SIGUSR2 /* SIGUSR2 */ +}; + +static int linux_to_bsd_sigtbl[LINUX_SIGTBLSZ] = { + SIGHUP, /* LINUX_SIGHUP */ + SIGINT, /* LINUX_SIGINT */ + SIGQUIT, /* LINUX_SIGQUIT */ + SIGILL, /* LINUX_SIGILL */ + SIGTRAP, /* LINUX_SIGTRAP */ + SIGABRT, /* LINUX_SIGABRT */ + SIGBUS, /* LINUX_SIGBUS */ + SIGFPE, /* LINUX_SIGFPE */ + SIGKILL, /* LINUX_SIGKILL */ + SIGUSR1, /* LINUX_SIGUSR1 */ + SIGSEGV, /* LINUX_SIGSEGV */ + SIGUSR2, /* LINUX_SIGUSR2 */ + SIGPIPE, /* LINUX_SIGPIPE */ + SIGALRM, /* LINUX_SIGALRM */ + SIGTERM, /* LINUX_SIGTERM */ + SIGBUS, /* LINUX_SIGSTKFLT */ + SIGCHLD, /* LINUX_SIGCHLD */ + SIGCONT, /* LINUX_SIGCONT */ + SIGSTOP, /* LINUX_SIGSTOP */ + SIGTSTP, /* LINUX_SIGTSTP */ + SIGTTIN, /* LINUX_SIGTTIN */ + SIGTTOU, /* LINUX_SIGTTOU */ + SIGURG, /* LINUX_SIGURG */ + SIGXCPU, /* LINUX_SIGXCPU */ + SIGXFSZ, /* LINUX_SIGXFSZ */ + SIGVTALRM, /* LINUX_SIGVTALARM */ + SIGPROF, /* LINUX_SIGPROF */ + SIGWINCH, /* LINUX_SIGWINCH */ + SIGIO, /* LINUX_SIGIO */ + /* + * FreeBSD does not have SIGPWR signal, map Linux SIGPWR signal + * to the first unused FreeBSD signal number. Since Linux supports + * signals from 1 to 64 we are ok here as our SIGRTMIN = 65. + */ + SIGRTMIN, /* LINUX_SIGPWR */ + SIGSYS /* LINUX_SIGSYS */ +}; + +/* + * Map Linux RT signals to the FreeBSD RT signals. + */ +static inline int +linux_to_bsd_rt_signal(int sig) +{ + + return (SIGRTMIN + 1 + sig - LINUX_SIGRTMIN); +} + +static inline int +bsd_to_linux_rt_signal(int sig) +{ + + return (sig - SIGRTMIN - 1 + LINUX_SIGRTMIN); +} + +int +linux_to_bsd_signal(int sig) +{ + + KASSERT(sig > 0 && sig <= LINUX_SIGRTMAX, ("Invalid Linux signal\n")); + + if (sig < LINUX_SIGRTMIN) + return (linux_to_bsd_sigtbl[_SIG_IDX(sig)]); + + return (linux_to_bsd_rt_signal(sig)); +} + +int +bsd_to_linux_signal(int sig) +{ + + if (sig <= LINUX_SIGTBLSZ) + return (bsd_to_linux_sigtbl[_SIG_IDX(sig)]); + if (sig == SIGRTMIN) + return (LINUX_SIGPWR); + + return (bsd_to_linux_rt_signal(sig)); +} + +int +linux_to_bsd_sigaltstack(int lsa) +{ + int bsa = 0; + + if (lsa & LINUX_SS_DISABLE) + bsa |= SS_DISABLE; + /* + * Linux ignores SS_ONSTACK flag for ss + * parameter while FreeBSD prohibits it. + */ + return (bsa); +} + +int +bsd_to_linux_sigaltstack(int bsa) +{ + int lsa = 0; + + if (bsa & SS_DISABLE) + lsa |= LINUX_SS_DISABLE; + if (bsa & SS_ONSTACK) + lsa |= LINUX_SS_ONSTACK; + return (lsa); +} + +void +linux_to_bsd_sigset(l_sigset_t *lss, sigset_t *bss) +{ + int b, l; + + SIGEMPTYSET(*bss); + for (l = 1; l <= LINUX_SIGRTMAX; l++) { + if (LINUX_SIGISMEMBER(*lss, l)) { + b = linux_to_bsd_signal(l); + if (b) + SIGADDSET(*bss, b); + } + } +} + +void +bsd_to_linux_sigset(sigset_t *bss, l_sigset_t *lss) +{ + int b, l; + + LINUX_SIGEMPTYSET(*lss); + for (b = 1; b <= SIGRTMAX; b++) { + if (SIGISMEMBER(*bss, b)) { + l = bsd_to_linux_signal(b); + if (l) + LINUX_SIGADDSET(*lss, l); + } + } +} diff --git a/sys/compat/linux/linux.h b/sys/compat/linux/linux.h new file mode 100644 index 0000000..974440f --- /dev/null +++ b/sys/compat/linux/linux.h @@ -0,0 +1,95 @@ +/*- + * Copyright (c) 2015 Dmitry Chagin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _LINUX_MI_H_ +#define _LINUX_MI_H_ + +/* sigaltstack */ +#define LINUX_SS_ONSTACK 1 +#define LINUX_SS_DISABLE 2 + +int linux_to_bsd_sigaltstack(int lsa); +int bsd_to_linux_sigaltstack(int bsa); + +/* sigset */ +typedef struct { + uint64_t __mask; +} l_sigset_t; + +/* primitives to manipulate sigset_t */ +#define LINUX_SIGEMPTYSET(set) (set).__mask = 0 +#define LINUX_SIGISMEMBER(set, sig) (1UL & ((set).__mask >> _SIG_IDX(sig))) +#define LINUX_SIGADDSET(set, sig) (set).__mask |= 1UL << _SIG_IDX(sig) + +void linux_to_bsd_sigset(l_sigset_t *, sigset_t *); +void bsd_to_linux_sigset(sigset_t *, l_sigset_t *); + +/* signaling */ +#define LINUX_SIGHUP 1 +#define LINUX_SIGINT 2 +#define LINUX_SIGQUIT 3 +#define LINUX_SIGILL 4 +#define LINUX_SIGTRAP 5 +#define LINUX_SIGABRT 6 +#define LINUX_SIGIOT LINUX_SIGABRT +#define LINUX_SIGBUS 7 +#define LINUX_SIGFPE 8 +#define LINUX_SIGKILL 9 +#define LINUX_SIGUSR1 10 +#define LINUX_SIGSEGV 11 +#define LINUX_SIGUSR2 12 +#define LINUX_SIGPIPE 13 +#define LINUX_SIGALRM 14 +#define LINUX_SIGTERM 15 +#define LINUX_SIGSTKFLT 16 +#define LINUX_SIGCHLD 17 +#define LINUX_SIGCONT 18 +#define LINUX_SIGSTOP 19 +#define LINUX_SIGTSTP 20 +#define LINUX_SIGTTIN 21 +#define LINUX_SIGTTOU 22 +#define LINUX_SIGURG 23 +#define LINUX_SIGXCPU 24 +#define LINUX_SIGXFSZ 25 +#define LINUX_SIGVTALRM 26 +#define LINUX_SIGPROF 27 +#define LINUX_SIGWINCH 28 +#define LINUX_SIGIO 29 +#define LINUX_SIGPOLL LINUX_SIGIO +#define LINUX_SIGPWR 30 +#define LINUX_SIGSYS 31 +#define LINUX_SIGTBLSZ 31 +#define LINUX_SIGRTMIN 32 +#define LINUX_SIGRTMAX 64 + +#define LINUX_SIG_VALID(sig) ((sig) <= LINUX_SIGRTMAX && (sig) > 0) + +int linux_to_bsd_signal(int sig); +int bsd_to_linux_signal(int sig); + +#endif /* _LINUX_MI_H_ */ diff --git a/sys/compat/linux/linux_common.c b/sys/compat/linux/linux_common.c new file mode 100644 index 0000000..b9e3531 --- /dev/null +++ b/sys/compat/linux/linux_common.c @@ -0,0 +1,93 @@ +/*- + * Copyright (c) 2014 Vassilis Laganakos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/exec.h> +#include <sys/imgact.h> +#include <sys/imgact_elf.h> +#include <sys/kernel.h> +#include <sys/malloc.h> +#include <sys/eventhandler.h> +#include <sys/sysctl.h> + +#include <compat/linux/linux_emul.h> +#include <compat/linux/linux_mib.h> +#include <compat/linux/linux_util.h> + +FEATURE(linuxulator_v4l, "V4L ioctl wrapper support in the linuxulator"); +FEATURE(linuxulator_v4l2, "V4L2 ioctl wrapper support in the linuxulator"); + +MODULE_VERSION(linux_common, 1); + +SET_DECLARE(linux_device_handler_set, struct linux_device_handler); + +static eventhandler_tag linux_exec_tag; +static eventhandler_tag linux_thread_dtor_tag; +static eventhandler_tag linux_exit_tag; + + +static int +linux_common_modevent(module_t mod, int type, void *data) +{ + struct linux_device_handler **ldhp; + + switch(type) { + case MOD_LOAD: + linux_osd_jail_register(); + linux_exit_tag = EVENTHANDLER_REGISTER(process_exit, + linux_proc_exit, NULL, 1000); + linux_exec_tag = EVENTHANDLER_REGISTER(process_exec, + linux_proc_exec, NULL, 1000); + linux_thread_dtor_tag = EVENTHANDLER_REGISTER(thread_dtor, + linux_thread_dtor, NULL, EVENTHANDLER_PRI_ANY); + SET_FOREACH(ldhp, linux_device_handler_set) + linux_device_register_handler(*ldhp); + break; + case MOD_UNLOAD: + linux_osd_jail_deregister(); + SET_FOREACH(ldhp, linux_device_handler_set) + linux_device_unregister_handler(*ldhp); + EVENTHANDLER_DEREGISTER(process_exit, linux_exit_tag); + EVENTHANDLER_DEREGISTER(process_exec, linux_exec_tag); + EVENTHANDLER_DEREGISTER(thread_dtor, linux_thread_dtor_tag); + break; + default: + return (EOPNOTSUPP); + } + return (0); +} + +static moduledata_t linux_common_mod = { + "linuxcommon", + linux_common_modevent, + 0 +}; + +DECLARE_MODULE(linuxcommon, linux_common_mod, SI_SUB_EXEC, SI_ORDER_ANY); diff --git a/sys/compat/linux/linux_emul.c b/sys/compat/linux/linux_emul.c index 61156ba..c2bf3ae 100644 --- a/sys/compat/linux/linux_emul.c +++ b/sys/compat/linux/linux_emul.c @@ -1,5 +1,6 @@ /*- * Copyright (c) 2006 Roman Divacky + * Copyright (c) 2013 Dmitry Chagin * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,364 +30,235 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); -#include "opt_compat.h" -#include "opt_kdtrace.h" - #include <sys/param.h> #include <sys/systm.h> #include <sys/imgact.h> #include <sys/kernel.h> +#include <sys/ktr.h> #include <sys/lock.h> #include <sys/malloc.h> #include <sys/mutex.h> -#include <sys/sdt.h> #include <sys/sx.h> #include <sys/proc.h> #include <sys/syscallsubr.h> #include <sys/sysent.h> -#include <sys/sysproto.h> -#include <sys/unistd.h> - -#ifdef COMPAT_LINUX32 -#include <machine/../linux32/linux.h> -#include <machine/../linux32/linux32_proto.h> -#else -#include <machine/../linux/linux.h> -#include <machine/../linux/linux_proto.h> -#endif - -#include <compat/linux/linux_dtrace.h> + #include <compat/linux/linux_emul.h> -#include <compat/linux/linux_futex.h> #include <compat/linux/linux_misc.h> +#include <compat/linux/linux_util.h> -/** - * Special DTrace provider for the linuxulator. - * - * In this file we define the provider for the entire linuxulator. All - * modules (= files of the linuxulator) use it. - * - * We define a different name depending on the emulated bitsize, see - * ../../<ARCH>/linux{,32}/linux.h, e.g.: - * native bitsize = linuxulator - * amd64, 32bit emulation = linuxulator32 - */ -LIN_SDT_PROVIDER_DEFINE(LINUX_DTRACE); -/** - * Special DTrace module "locks", it covers some linuxulator internal - * locks. - */ -LIN_SDT_PROBE_DEFINE1(locks, emul_lock, locked, "struct mtx *"); -LIN_SDT_PROBE_DEFINE1(locks, emul_lock, unlock, "struct mtx *"); -LIN_SDT_PROBE_DEFINE1(locks, emul_shared_rlock, locked, "struct sx *"); -LIN_SDT_PROBE_DEFINE1(locks, emul_shared_rlock, unlock, "struct sx *"); -LIN_SDT_PROBE_DEFINE1(locks, emul_shared_wlock, locked, "struct sx *"); -LIN_SDT_PROBE_DEFINE1(locks, emul_shared_wlock, unlock, "struct sx *"); - -/** - * DTrace probes in this module. +/* + * This returns reference to the thread emuldata entry (if found) + * + * Hold PROC_LOCK when referencing emuldata from other threads. */ -LIN_SDT_PROBE_DEFINE2(emul, em_find, entry, "struct proc *", "int"); -LIN_SDT_PROBE_DEFINE0(emul, em_find, return); -LIN_SDT_PROBE_DEFINE3(emul, proc_init, entry, "struct thread *", "pid_t", - "int"); -LIN_SDT_PROBE_DEFINE0(emul, proc_init, create_thread); -LIN_SDT_PROBE_DEFINE0(emul, proc_init, fork); -LIN_SDT_PROBE_DEFINE0(emul, proc_init, exec); -LIN_SDT_PROBE_DEFINE0(emul, proc_init, return); -LIN_SDT_PROBE_DEFINE1(emul, proc_exit, entry, "struct proc *"); -LIN_SDT_PROBE_DEFINE0(emul, proc_exit, futex_failed); -LIN_SDT_PROBE_DEFINE3(emul, proc_exit, reparent, "pid_t", "pid_t", - "struct proc *"); -LIN_SDT_PROBE_DEFINE1(emul, proc_exit, child_clear_tid_error, "int"); -LIN_SDT_PROBE_DEFINE0(emul, proc_exit, return); -LIN_SDT_PROBE_DEFINE2(emul, proc_exec, entry, "struct proc *", - "struct image_params *"); -LIN_SDT_PROBE_DEFINE0(emul, proc_exec, return); -LIN_SDT_PROBE_DEFINE0(emul, linux_schedtail, entry); -LIN_SDT_PROBE_DEFINE1(emul, linux_schedtail, copyout_error, "int"); -LIN_SDT_PROBE_DEFINE0(emul, linux_schedtail, return); -LIN_SDT_PROBE_DEFINE1(emul, linux_set_tid_address, entry, "int *"); -LIN_SDT_PROBE_DEFINE0(emul, linux_set_tid_address, return); -LIN_SDT_PROBE_DEFINE2(emul, linux_kill_threads, entry, "struct thread *", - "int"); -LIN_SDT_PROBE_DEFINE1(emul, linux_kill_threads, kill, "pid_t"); -LIN_SDT_PROBE_DEFINE0(emul, linux_kill_threads, return); - -struct sx emul_shared_lock; -struct mtx emul_lock; - -/* this returns locked reference to the emuldata entry (if found) */ struct linux_emuldata * -em_find(struct proc *p, int locked) +em_find(struct thread *td) { struct linux_emuldata *em; - LIN_SDT_PROBE2(emul, em_find, entry, p, locked); + em = td->td_emuldata; - if (locked == EMUL_DOLOCK) - EMUL_LOCK(&emul_lock); + return (em); +} - em = p->p_emuldata; +/* + * This returns reference to the proc pemuldata entry (if found) + * + * Hold PROC_LOCK when referencing proc pemuldata from other threads. + * Hold LINUX_PEM_LOCK wher referencing pemuldata members. + */ +struct linux_pemuldata * +pem_find(struct proc *p) +{ + struct linux_pemuldata *pem; - if (em == NULL && locked == EMUL_DOLOCK) - EMUL_UNLOCK(&emul_lock); + pem = p->p_emuldata; - LIN_SDT_PROBE1(emul, em_find, return, em); - return (em); + return (pem); } -int -linux_proc_init(struct thread *td, pid_t child, int flags) +void +linux_proc_init(struct thread *td, struct thread *newtd, int flags) { - struct linux_emuldata *em, *p_em; + struct linux_emuldata *em; + struct linux_pemuldata *pem; + struct epoll_emuldata *emd; struct proc *p; - LIN_SDT_PROBE3(emul, proc_init, entry, td, child, flags); + if (newtd != NULL) { + p = newtd->td_proc; - if (child != 0) { - /* fork or create a thread */ - em = malloc(sizeof *em, M_LINUX, M_WAITOK | M_ZERO); - em->pid = child; - em->pdeath_signal = 0; - em->flags = 0; - em->robust_futexes = NULL; + /* non-exec call */ + em = malloc(sizeof(*em), M_TEMP, M_WAITOK | M_ZERO); if (flags & LINUX_CLONE_THREAD) { - /* handled later in the code */ - LIN_SDT_PROBE0(emul, proc_init, create_thread); - } else { - struct linux_emuldata_shared *s; + LINUX_CTR1(proc_init, "thread newtd(%d)", + newtd->td_tid); - LIN_SDT_PROBE0(emul, proc_init, fork); + em->em_tid = newtd->td_tid; + } else { + LINUX_CTR1(proc_init, "fork newtd(%d)", p->p_pid); - s = malloc(sizeof *s, M_LINUX, M_WAITOK | M_ZERO); - s->refs = 1; - s->group_pid = child; + em->em_tid = p->p_pid; - LIST_INIT(&s->threads); - em->shared = s; + pem = malloc(sizeof(*pem), M_LINUX, M_WAITOK | M_ZERO); + sx_init(&pem->pem_sx, "lpemlk"); + p->p_emuldata = pem; } + newtd->td_emuldata = em; } else { + p = td->td_proc; + /* exec */ - LIN_SDT_PROBE0(emul, proc_init, exec); + LINUX_CTR1(proc_init, "exec newtd(%d)", p->p_pid); /* lookup the old one */ - em = em_find(td->td_proc, EMUL_DOLOCK); + em = em_find(td); KASSERT(em != NULL, ("proc_init: emuldata not found in exec case.\n")); - } - - em->child_clear_tid = NULL; - em->child_set_tid = NULL; - /* - * allocate the shared struct only in clone()/fork cases in the case - * of clone() td = calling proc and child = pid of the newly created - * proc - */ - if (child != 0) { - if (flags & LINUX_CLONE_THREAD) { - /* lookup the parent */ - /* - * we dont have to lock the p_em because - * its waiting for us in linux_clone so - * there is no chance of it changing the - * p_em->shared address - */ - p_em = em_find(td->td_proc, EMUL_DONTLOCK); - KASSERT(p_em != NULL, ("proc_init: parent emuldata not found for CLONE_THREAD\n")); - em->shared = p_em->shared; - EMUL_SHARED_WLOCK(&emul_shared_lock); - em->shared->refs++; - EMUL_SHARED_WUNLOCK(&emul_shared_lock); - } else { - /* - * handled earlier to avoid malloc(M_WAITOK) with - * rwlock held - */ - } + em->em_tid = p->p_pid; + em->flags = 0; + em->pdeath_signal = 0; + em->robust_futexes = NULL; + em->child_clear_tid = NULL; + em->child_set_tid = NULL; - EMUL_SHARED_WLOCK(&emul_shared_lock); - LIST_INSERT_HEAD(&em->shared->threads, em, threads); - EMUL_SHARED_WUNLOCK(&emul_shared_lock); + /* epoll should be destroyed in a case of exec. */ + pem = pem_find(p); + KASSERT(pem != NULL, ("proc_exit: proc emuldata not found.\n")); - p = pfind(child); - KASSERT(p != NULL, ("process not found in proc_init\n")); - p->p_emuldata = em; - PROC_UNLOCK(p); - } else - EMUL_UNLOCK(&emul_lock); + if (pem->epoll != NULL) { + emd = pem->epoll; + pem->epoll = NULL; + free(emd, M_EPOLL); + } + } - LIN_SDT_PROBE0(emul, proc_init, return); - return (0); } -void +void linux_proc_exit(void *arg __unused, struct proc *p) { - struct linux_emuldata *em; - int error, shared_flags, shared_xstat; - struct thread *td = FIRST_THREAD_IN_PROC(p); - int *child_clear_tid; - struct proc *q, *nq; + struct linux_pemuldata *pem; + struct epoll_emuldata *emd; + struct thread *td = curthread; - if (__predict_true(p->p_sysent != &elf_linux_sysvec)) + if (__predict_false(SV_CURPROC_ABI() != SV_ABI_LINUX)) return; - LIN_SDT_PROBE1(emul, proc_exit, entry, p); - - release_futexes(p); + LINUX_CTR3(proc_exit, "thread(%d) proc(%d) p %p", + td->td_tid, p->p_pid, p); - /* find the emuldata */ - em = em_find(p, EMUL_DOLOCK); + pem = pem_find(p); + if (pem == NULL) + return; + (p->p_sysent->sv_thread_detach)(td); - KASSERT(em != NULL, ("proc_exit: emuldata not found.\n")); + p->p_emuldata = NULL; - /* reparent all procs that are not a thread leader to initproc */ - if (em->shared->group_pid != p->p_pid) { - LIN_SDT_PROBE3(emul, proc_exit, reparent, - em->shared->group_pid, p->p_pid, p); - - child_clear_tid = em->child_clear_tid; - EMUL_UNLOCK(&emul_lock); - sx_xlock(&proctree_lock); - wakeup(initproc); - PROC_LOCK(p); - proc_reparent(p, initproc); - p->p_sigparent = SIGCHLD; - PROC_UNLOCK(p); - sx_xunlock(&proctree_lock); - } else { - child_clear_tid = em->child_clear_tid; - EMUL_UNLOCK(&emul_lock); + if (pem->epoll != NULL) { + emd = pem->epoll; + pem->epoll = NULL; + free(emd, M_EPOLL); } - EMUL_SHARED_WLOCK(&emul_shared_lock); - shared_flags = em->shared->flags; - shared_xstat = em->shared->xstat; - LIST_REMOVE(em, threads); + sx_destroy(&pem->pem_sx); + free(pem, M_LINUX); +} - em->shared->refs--; - if (em->shared->refs == 0) { - EMUL_SHARED_WUNLOCK(&emul_shared_lock); - free(em->shared, M_LINUX); - } else - EMUL_SHARED_WUNLOCK(&emul_shared_lock); +int +linux_common_execve(struct thread *td, struct image_args *eargs) +{ + struct linux_pemuldata *pem; + struct epoll_emuldata *emd; + struct vmspace *oldvmspace; + struct linux_emuldata *em; + struct proc *p; + int error; - if ((shared_flags & EMUL_SHARED_HASXSTAT) != 0) - p->p_xstat = shared_xstat; + p = td->td_proc; - if (child_clear_tid != NULL) { - struct linux_sys_futex_args cup; - int null = 0; + error = pre_execve(td, &oldvmspace); + if (error != 0) + return (error); - error = copyout(&null, child_clear_tid, sizeof(null)); - if (error) { - LIN_SDT_PROBE1(emul, proc_exit, - child_clear_tid_error, error); + error = kern_execve(td, eargs, NULL); + post_execve(td, error, oldvmspace); + if (error != 0) + return (error); - free(em, M_LINUX); + /* + * In a case of transition from Linux binary execing to + * FreeBSD binary we destroy linux emuldata thread & proc entries. + */ + if (SV_CURPROC_ABI() != SV_ABI_LINUX) { + PROC_LOCK(p); + em = em_find(td); + KASSERT(em != NULL, ("proc_exec: thread emuldata not found.\n")); + td->td_emuldata = NULL; - LIN_SDT_PROBE0(emul, proc_exit, return); - return; - } + pem = pem_find(p); + KASSERT(pem != NULL, ("proc_exec: proc pemuldata not found.\n")); + p->p_emuldata = NULL; + PROC_UNLOCK(p); - /* futexes stuff */ - cup.uaddr = child_clear_tid; - cup.op = LINUX_FUTEX_WAKE; - cup.val = 0x7fffffff; /* Awake everyone */ - cup.timeout = NULL; - cup.uaddr2 = NULL; - cup.val3 = 0; - error = linux_sys_futex(FIRST_THREAD_IN_PROC(p), &cup); - /* - * this cannot happen at the moment and if this happens it - * probably means there is a user space bug - */ - if (error) { - LIN_SDT_PROBE0(emul, proc_exit, futex_failed); - printf(LMSG("futex stuff in proc_exit failed.\n")); + if (pem->epoll != NULL) { + emd = pem->epoll; + pem->epoll = NULL; + free(emd, M_EPOLL); } - } - /* clean the stuff up */ - free(em, M_LINUX); - - /* this is a little weird but rewritten from exit1() */ - sx_xlock(&proctree_lock); - q = LIST_FIRST(&p->p_children); - for (; q != NULL; q = nq) { - nq = LIST_NEXT(q, p_sibling); - if (q->p_flag & P_WEXIT) - continue; - if (__predict_false(q->p_sysent != &elf_linux_sysvec)) - continue; - em = em_find(q, EMUL_DOLOCK); - KASSERT(em != NULL, ("linux_reparent: emuldata not found: %i\n", q->p_pid)); - PROC_LOCK(q); - if ((q->p_flag & P_WEXIT) == 0 && em->pdeath_signal != 0) { - kern_psignal(q, em->pdeath_signal); - } - PROC_UNLOCK(q); - EMUL_UNLOCK(&emul_lock); + free(em, M_TEMP); + free(pem, M_LINUX); } - sx_xunlock(&proctree_lock); - - LIN_SDT_PROBE0(emul, proc_exit, return); + return (0); } -/* - * This is used in a case of transition from FreeBSD binary execing to linux binary - * in this case we create linux emuldata proc entry with the pid of the currently running - * process. - */ void linux_proc_exec(void *arg __unused, struct proc *p, struct image_params *imgp) { - if (__predict_false(imgp->sysent == &elf_linux_sysvec)) { - LIN_SDT_PROBE2(emul, proc_exec, entry, p, imgp); - } - if (__predict_false(imgp->sysent == &elf_linux_sysvec - && p->p_sysent != &elf_linux_sysvec)) - linux_proc_init(FIRST_THREAD_IN_PROC(p), p->p_pid, 0); - if (__predict_false((p->p_sysent->sv_flags & SV_ABI_MASK) == - SV_ABI_LINUX)) - /* Kill threads regardless of imgp->sysent value */ - linux_kill_threads(FIRST_THREAD_IN_PROC(p), SIGKILL); - if (__predict_false(imgp->sysent != &elf_linux_sysvec - && p->p_sysent == &elf_linux_sysvec)) { - struct linux_emuldata *em; - - /* - * XXX:There's a race because here we assign p->p_emuldata NULL - * but the process is still counted as linux one for a short - * time so some other process might reference it and try to - * access its p->p_emuldata and panicing on a NULL reference. - */ - em = em_find(p, EMUL_DONTLOCK); - - KASSERT(em != NULL, ("proc_exec: emuldata not found.\n")); - - EMUL_SHARED_WLOCK(&emul_shared_lock); - LIST_REMOVE(em, threads); + struct thread *td = curthread; + struct thread *othertd; - PROC_LOCK(p); - p->p_emuldata = NULL; - PROC_UNLOCK(p); + /* + * In a case of execing from linux binary properly detach + * other threads from the user space. + */ + if (__predict_false(SV_PROC_ABI(p) == SV_ABI_LINUX)) { + FOREACH_THREAD_IN_PROC(p, othertd) { + if (td != othertd) + (p->p_sysent->sv_thread_detach)(othertd); + } + } - em->shared->refs--; - if (em->shared->refs == 0) { - EMUL_SHARED_WUNLOCK(&emul_shared_lock); - free(em->shared, M_LINUX); - } else - EMUL_SHARED_WUNLOCK(&emul_shared_lock); + /* + * In a case of execing to linux binary we create linux + * emuldata thread entry. + */ + if (__predict_false((imgp->sysent->sv_flags & SV_ABI_MASK) == + SV_ABI_LINUX)) { - free(em, M_LINUX); + if (SV_PROC_ABI(p) == SV_ABI_LINUX) + linux_proc_init(td, NULL, 0); + else + linux_proc_init(td, td, 0); } +} - if (__predict_false(imgp->sysent == &elf_linux_sysvec)) { - LIN_SDT_PROBE0(emul, proc_exec, return); - } +void +linux_thread_dtor(void *arg __unused, struct thread *td) +{ + struct linux_emuldata *em; + + em = em_find(td); + if (em == NULL) + return; + td->td_emuldata = NULL; + + LINUX_CTR1(thread_dtor, "thread(%d)", em->em_tid); + + free(em, M_TEMP); } void @@ -399,76 +271,15 @@ linux_schedtail(struct thread *td) p = td->td_proc; - LIN_SDT_PROBE1(emul, linux_schedtail, entry, p); - - /* find the emuldata */ - em = em_find(p, EMUL_DOLOCK); - - KASSERT(em != NULL, ("linux_schedtail: emuldata not found.\n")); + em = em_find(td); + KASSERT(em != NULL, ("linux_schedtail: thread emuldata not found.\n")); child_set_tid = em->child_set_tid; - EMUL_UNLOCK(&emul_lock); if (child_set_tid != NULL) { - error = copyout(&p->p_pid, (int *)child_set_tid, - sizeof(p->p_pid)); - - if (error != 0) { - LIN_SDT_PROBE1(emul, linux_schedtail, copyout_error, - error); - } - } - - LIN_SDT_PROBE0(emul, linux_schedtail, return); - - return; -} - -int -linux_set_tid_address(struct thread *td, struct linux_set_tid_address_args *args) -{ - struct linux_emuldata *em; - - LIN_SDT_PROBE1(emul, linux_set_tid_address, entry, args->tidptr); - - /* find the emuldata */ - em = em_find(td->td_proc, EMUL_DOLOCK); - - KASSERT(em != NULL, ("set_tid_address: emuldata not found.\n")); - - em->child_clear_tid = args->tidptr; - td->td_retval[0] = td->td_proc->p_pid; - - EMUL_UNLOCK(&emul_lock); - - LIN_SDT_PROBE0(emul, linux_set_tid_address, return); - return 0; -} - -void -linux_kill_threads(struct thread *td, int sig) -{ - struct linux_emuldata *em, *td_em, *tmp_em; - struct proc *sp; - - LIN_SDT_PROBE2(emul, linux_kill_threads, entry, td, sig); - - td_em = em_find(td->td_proc, EMUL_DONTLOCK); - - KASSERT(td_em != NULL, ("linux_kill_threads: emuldata not found.\n")); - - EMUL_SHARED_RLOCK(&emul_shared_lock); - LIST_FOREACH_SAFE(em, &td_em->shared->threads, threads, tmp_em) { - if (em->pid == td_em->pid) - continue; - - sp = pfind(em->pid); - if ((sp->p_flag & P_WEXIT) == 0) - kern_psignal(sp, sig); - PROC_UNLOCK(sp); - - LIN_SDT_PROBE1(emul, linux_kill_threads, kill, em->pid); - } - EMUL_SHARED_RUNLOCK(&emul_shared_lock); - - LIN_SDT_PROBE0(emul, linux_kill_threads, return); + error = copyout(&em->em_tid, child_set_tid, + sizeof(em->em_tid)); + LINUX_CTR4(schedtail, "thread(%d) %p stored %d error %d", + td->td_tid, child_set_tid, em->em_tid, error); + } else + LINUX_CTR1(schedtail, "thread(%d)", em->em_tid); } diff --git a/sys/compat/linux/linux_emul.h b/sys/compat/linux/linux_emul.h index f409a34..7262093 100644 --- a/sys/compat/linux/linux_emul.h +++ b/sys/compat/linux/linux_emul.h @@ -1,5 +1,6 @@ /*- * Copyright (c) 2006 Roman Divacky + * Copyright (c) 2013 Dmitry Chagin * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,91 +32,48 @@ #ifndef _LINUX_EMUL_H_ #define _LINUX_EMUL_H_ -#define EMUL_SHARED_HASXSTAT 0x01 - -struct linux_emuldata_shared { - int refs; - int flags; - int xstat; - pid_t group_pid; - - LIST_HEAD(, linux_emuldata) threads; /* head of list of linux threads */ -}; - /* * modeled after similar structure in NetBSD * this will be extended as we need more functionality */ struct linux_emuldata { - pid_t pid; - int *child_set_tid; /* in clone(): Child's TID to set on clone */ int *child_clear_tid;/* in clone(): Child's TID to clear on exit */ - struct linux_emuldata_shared *shared; - int pdeath_signal; /* parent death signal */ - int flags; /* different emuldata flags */ + int flags; /* thread emuldata flags */ + int em_tid; /* thread id */ struct linux_robust_list_head *robust_futexes; - - LIST_ENTRY(linux_emuldata) threads; /* list of linux threads */ }; -struct linux_emuldata *em_find(struct proc *, int locked); - -/* - * DTrace probes for locks should be fired after locking and before releasing - * to prevent races (to provide data/function stability in dtrace, see the - * output of "dtrace -v ..." and the corresponding dtrace docs). - */ -#define EMUL_LOCK(l) do { \ - mtx_lock(l); \ - LIN_SDT_PROBE1(locks, emul_lock, \ - locked, l); \ - } while (0) -#define EMUL_UNLOCK(l) do { \ - LIN_SDT_PROBE1(locks, emul_lock, \ - unlock, l); \ - mtx_unlock(l); \ - } while (0) +struct linux_emuldata *em_find(struct thread *); -#define EMUL_SHARED_RLOCK(l) do { \ - sx_slock(l); \ - LIN_SDT_PROBE1(locks, emul_shared_rlock, \ - locked, l); \ - } while (0) -#define EMUL_SHARED_RUNLOCK(l) do { \ - LIN_SDT_PROBE1(locks, emul_shared_rlock, \ - unlock, l); \ - sx_sunlock(l); \ - } while (0) -#define EMUL_SHARED_WLOCK(l) do { \ - sx_xlock(l); \ - LIN_SDT_PROBE1(locks, emul_shared_wlock, \ - locked, l); \ - } while (0) -#define EMUL_SHARED_WUNLOCK(l) do { \ - LIN_SDT_PROBE1(locks, emul_shared_wlock, \ - unlock, l); \ - sx_xunlock(l); \ - } while (0) - -/* for em_find use */ -#define EMUL_DOLOCK 1 -#define EMUL_DONTLOCK 0 +void linux_proc_init(struct thread *, struct thread *, int); +void linux_proc_exit(void *, struct proc *); +void linux_schedtail(struct thread *); +void linux_proc_exec(void *, struct proc *, struct image_params *); +void linux_thread_dtor(void *arg __unused, struct thread *); +void linux_thread_detach(struct thread *); +int linux_common_execve(struct thread *, struct image_args *); -/* emuldata flags */ +/* process emuldata flags */ #define LINUX_XDEPR_REQUEUEOP 0x00000001 /* uses deprecated futex REQUEUE op*/ +#define LINUX_XUNSUP_EPOLL 0x00000002 /* unsupported epoll events */ +#define LINUX_XUNSUP_FUTEXPIOP 0x00000004 /* uses unsupported pi futex */ -int linux_proc_init(struct thread *, pid_t, int); -void linux_proc_exit(void *, struct proc *); -void linux_schedtail(struct thread *); -void linux_proc_exec(void *, struct proc *, struct image_params *); -void linux_kill_threads(struct thread *, int); +struct linux_pemuldata { + uint32_t flags; /* process emuldata flags */ + struct sx pem_sx; /* lock for this struct */ + void *epoll; /* epoll data */ +}; + +#define LINUX_PEM_XLOCK(p) sx_xlock(&(p)->pem_sx) +#define LINUX_PEM_XUNLOCK(p) sx_xunlock(&(p)->pem_sx) +#define LINUX_PEM_SLOCK(p) sx_slock(&(p)->pem_sx) +#define LINUX_PEM_SUNLOCK(p) sx_sunlock(&(p)->pem_sx) -extern struct sx emul_shared_lock; -extern struct mtx emul_lock; +struct linux_pemuldata *pem_find(struct proc *); #endif /* !_LINUX_EMUL_H_ */ diff --git a/sys/compat/linux/linux_event.c b/sys/compat/linux/linux_event.c new file mode 100644 index 0000000..1fe3445 --- /dev/null +++ b/sys/compat/linux/linux_event.c @@ -0,0 +1,882 @@ +/*- + * Copyright (c) 2007 Roman Divacky + * Copyright (c) 2014 Dmitry Chagin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include "opt_compat.h" + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/imgact.h> +#include <sys/kernel.h> +#include <sys/limits.h> +#include <sys/lock.h> +#include <sys/mutex.h> +#include <sys/capability.h> +#include <sys/types.h> +#include <sys/file.h> +#include <sys/filedesc.h> +#include <sys/errno.h> +#include <sys/event.h> +#include <sys/poll.h> +#include <sys/proc.h> +#include <sys/selinfo.h> +#include <sys/sx.h> +#include <sys/syscallsubr.h> +#include <sys/timespec.h> + +#ifdef COMPAT_LINUX32 +#include <machine/../linux32/linux.h> +#include <machine/../linux32/linux32_proto.h> +#else +#include <machine/../linux/linux.h> +#include <machine/../linux/linux_proto.h> +#endif + +#include <compat/linux/linux_emul.h> +#include <compat/linux/linux_event.h> +#include <compat/linux/linux_file.h> +#include <compat/linux/linux_util.h> + +/* + * epoll defines 'struct epoll_event' with the field 'data' as 64 bits + * on all architectures. But on 32 bit architectures BSD 'struct kevent' only + * has 32 bit opaque pointer as 'udata' field. So we can't pass epoll supplied + * data verbatuim. Therefore we allocate 64-bit memory block to pass + * user supplied data for every file descriptor. + */ + +typedef uint64_t epoll_udata_t; + +struct epoll_emuldata { + uint32_t fdc; /* epoll udata max index */ + epoll_udata_t udata[1]; /* epoll user data vector */ +}; + +#define EPOLL_DEF_SZ 16 +#define EPOLL_SIZE(fdn) \ + (sizeof(struct epoll_emuldata)+(fdn) * sizeof(epoll_udata_t)) + +struct epoll_event { + uint32_t events; + epoll_udata_t data; +} +#if defined(__amd64__) +__attribute__((packed)) +#endif +; + +#define LINUX_MAX_EVENTS (INT_MAX / sizeof(struct epoll_event)) + +static void epoll_fd_install(struct thread *td, int fd, epoll_udata_t udata); +static int epoll_to_kevent(struct thread *td, struct file *epfp, + int fd, struct epoll_event *l_event, int *kev_flags, + struct kevent *kevent, int *nkevents); +static void kevent_to_epoll(struct kevent *kevent, struct epoll_event *l_event); +static int epoll_kev_copyout(void *arg, struct kevent *kevp, int count); +static int epoll_kev_copyin(void *arg, struct kevent *kevp, int count); +static int epoll_delete_event(struct thread *td, struct file *epfp, + int fd, int filter); +static int epoll_delete_all_events(struct thread *td, struct file *epfp, + int fd); + +struct epoll_copyin_args { + struct kevent *changelist; +}; + +struct epoll_copyout_args { + struct epoll_event *leventlist; + struct proc *p; + uint32_t count; + int error; +}; + +/* eventfd */ +typedef uint64_t eventfd_t; + +static fo_rdwr_t eventfd_read; +static fo_rdwr_t eventfd_write; +static fo_truncate_t eventfd_truncate; +static fo_ioctl_t eventfd_ioctl; +static fo_poll_t eventfd_poll; +static fo_kqfilter_t eventfd_kqfilter; +static fo_stat_t eventfd_stat; +static fo_close_t eventfd_close; + +static struct fileops eventfdops = { + .fo_read = eventfd_read, + .fo_write = eventfd_write, + .fo_truncate = eventfd_truncate, + .fo_ioctl = eventfd_ioctl, + .fo_poll = eventfd_poll, + .fo_kqfilter = eventfd_kqfilter, + .fo_stat = eventfd_stat, + .fo_close = eventfd_close, + .fo_chmod = invfo_chmod, + .fo_chown = invfo_chown, + .fo_sendfile = invfo_sendfile, + .fo_flags = DFLAG_PASSABLE +}; + +static void filt_eventfddetach(struct knote *kn); +static int filt_eventfdread(struct knote *kn, long hint); +static int filt_eventfdwrite(struct knote *kn, long hint); + +static struct filterops eventfd_rfiltops = { + .f_isfd = 1, + .f_detach = filt_eventfddetach, + .f_event = filt_eventfdread +}; +static struct filterops eventfd_wfiltops = { + .f_isfd = 1, + .f_detach = filt_eventfddetach, + .f_event = filt_eventfdwrite +}; + +struct eventfd { + eventfd_t efd_count; + uint32_t efd_flags; + struct selinfo efd_sel; + struct mtx efd_lock; +}; + +static int eventfd_create(struct thread *td, uint32_t initval, int flags); + + +static void +epoll_fd_install(struct thread *td, int fd, epoll_udata_t udata) +{ + struct linux_pemuldata *pem; + struct epoll_emuldata *emd; + struct proc *p; + + p = td->td_proc; + + pem = pem_find(p); + KASSERT(pem != NULL, ("epoll proc emuldata not found.\n")); + + LINUX_PEM_XLOCK(pem); + if (pem->epoll == NULL) { + emd = malloc(EPOLL_SIZE(fd), M_EPOLL, M_WAITOK); + emd->fdc = fd; + pem->epoll = emd; + } else { + emd = pem->epoll; + if (fd > emd->fdc) { + emd = realloc(emd, EPOLL_SIZE(fd), M_EPOLL, M_WAITOK); + emd->fdc = fd; + pem->epoll = emd; + } + } + emd->udata[fd] = udata; + LINUX_PEM_XUNLOCK(pem); +} + +static int +epoll_create_common(struct thread *td, int flags) +{ + int error; + + error = kern_kqueue(td, flags); + if (error) + return (error); + + epoll_fd_install(td, EPOLL_DEF_SZ, 0); + + return (0); +} + +int +linux_epoll_create(struct thread *td, struct linux_epoll_create_args *args) +{ + + /* + * args->size is unused. Linux just tests it + * and then forgets it as well. + */ + if (args->size <= 0) + return (EINVAL); + + return (epoll_create_common(td, 0)); +} + +int +linux_epoll_create1(struct thread *td, struct linux_epoll_create1_args *args) +{ + int flags; + + if ((args->flags & ~(LINUX_O_CLOEXEC)) != 0) + return (EINVAL); + + flags = 0; + if ((args->flags & LINUX_O_CLOEXEC) != 0) + flags |= O_CLOEXEC; + + return (epoll_create_common(td, flags)); +} + +/* Structure converting function from epoll to kevent. */ +static int +epoll_to_kevent(struct thread *td, struct file *epfp, + int fd, struct epoll_event *l_event, int *kev_flags, + struct kevent *kevent, int *nkevents) +{ + uint32_t levents = l_event->events; + struct linux_pemuldata *pem; + struct proc *p; + + /* flags related to how event is registered */ + if ((levents & LINUX_EPOLLONESHOT) != 0) + *kev_flags |= EV_ONESHOT; + if ((levents & LINUX_EPOLLET) != 0) + *kev_flags |= EV_CLEAR; + if ((levents & LINUX_EPOLLERR) != 0) + *kev_flags |= EV_ERROR; + if ((levents & LINUX_EPOLLRDHUP) != 0) + *kev_flags |= EV_EOF; + + /* flags related to what event is registered */ + if ((levents & LINUX_EPOLL_EVRD) != 0) { + EV_SET(kevent++, fd, EVFILT_READ, *kev_flags, 0, 0, 0); + ++(*nkevents); + } + if ((levents & LINUX_EPOLL_EVWR) != 0) { + EV_SET(kevent++, fd, EVFILT_WRITE, *kev_flags, 0, 0, 0); + ++(*nkevents); + } + + if ((levents & ~(LINUX_EPOLL_EVSUP)) != 0) { + p = td->td_proc; + + pem = pem_find(p); + KASSERT(pem != NULL, ("epoll proc emuldata not found.\n")); + KASSERT(pem->epoll != NULL, ("epoll proc epolldata not found.\n")); + + LINUX_PEM_XLOCK(pem); + if ((pem->flags & LINUX_XUNSUP_EPOLL) == 0) { + pem->flags |= LINUX_XUNSUP_EPOLL; + LINUX_PEM_XUNLOCK(pem); + linux_msg(td, "epoll_ctl unsupported flags: 0x%x\n", + levents); + } else + LINUX_PEM_XUNLOCK(pem); + return (EINVAL); + } + + return (0); +} + +/* + * Structure converting function from kevent to epoll. In a case + * this is called on error in registration we store the error in + * event->data and pick it up later in linux_epoll_ctl(). + */ +static void +kevent_to_epoll(struct kevent *kevent, struct epoll_event *l_event) +{ + + if ((kevent->flags & EV_ERROR) != 0) { + l_event->events = LINUX_EPOLLERR; + return; + } + + switch (kevent->filter) { + case EVFILT_READ: + l_event->events = LINUX_EPOLLIN|LINUX_EPOLLRDNORM|LINUX_EPOLLPRI; + if ((kevent->flags & EV_EOF) != 0) + l_event->events |= LINUX_EPOLLRDHUP; + break; + case EVFILT_WRITE: + l_event->events = LINUX_EPOLLOUT|LINUX_EPOLLWRNORM; + break; + } +} + +/* + * Copyout callback used by kevent. This converts kevent + * events to epoll events and copies them back to the + * userspace. This is also called on error on registering + * of the filter. + */ +static int +epoll_kev_copyout(void *arg, struct kevent *kevp, int count) +{ + struct epoll_copyout_args *args; + struct linux_pemuldata *pem; + struct epoll_emuldata *emd; + struct epoll_event *eep; + int error, fd, i; + + args = (struct epoll_copyout_args*) arg; + eep = malloc(sizeof(*eep) * count, M_EPOLL, M_WAITOK | M_ZERO); + + pem = pem_find(args->p); + KASSERT(pem != NULL, ("epoll proc emuldata not found.\n")); + LINUX_PEM_SLOCK(pem); + emd = pem->epoll; + KASSERT(emd != NULL, ("epoll proc epolldata not found.\n")); + + for (i = 0; i < count; i++) { + kevent_to_epoll(&kevp[i], &eep[i]); + + fd = kevp[i].ident; + KASSERT(fd <= emd->fdc, ("epoll user data vector" + " is too small.\n")); + eep[i].data = emd->udata[fd]; + } + LINUX_PEM_SUNLOCK(pem); + + error = copyout(eep, args->leventlist, count * sizeof(*eep)); + if (error == 0) { + args->leventlist += count; + args->count += count; + } else if (args->error == 0) + args->error = error; + + free(eep, M_EPOLL); + return (error); +} + +/* + * Copyin callback used by kevent. This copies already + * converted filters from kernel memory to the kevent + * internal kernel memory. Hence the memcpy instead of + * copyin. + */ +static int +epoll_kev_copyin(void *arg, struct kevent *kevp, int count) +{ + struct epoll_copyin_args *args; + + args = (struct epoll_copyin_args*) arg; + + memcpy(kevp, args->changelist, count * sizeof(*kevp)); + args->changelist += count; + + return (0); +} + +/* + * Load epoll filter, convert it to kevent filter + * and load it into kevent subsystem. + */ +int +linux_epoll_ctl(struct thread *td, struct linux_epoll_ctl_args *args) +{ + struct file *epfp, *fp; + struct epoll_copyin_args ciargs; + struct kevent kev[2]; + struct kevent_copyops k_ops = { &ciargs, + NULL, + epoll_kev_copyin}; + struct epoll_event le; + cap_rights_t rights; + int kev_flags; + int nchanges = 0; + int error; + + if (args->op != LINUX_EPOLL_CTL_DEL) { + error = copyin(args->event, &le, sizeof(le)); + if (error != 0) + return (error); + } + + error = fget(td, args->epfd, + cap_rights_init(&rights, CAP_KQUEUE_CHANGE), &epfp); + if (error != 0) + return (error); + if (epfp->f_type != DTYPE_KQUEUE) + goto leave1; + + /* Protect user data vector from incorrectly supplied fd. */ + error = fget(td, args->fd, cap_rights_init(&rights, CAP_POLL_EVENT), &fp); + if (error != 0) + goto leave1; + + /* Linux disallows spying on himself */ + if (epfp == fp) { + error = EINVAL; + goto leave0; + } + + ciargs.changelist = kev; + + switch (args->op) { + case LINUX_EPOLL_CTL_MOD: + /* + * We don't memorize which events were set for this FD + * on this level, so just delete all we could have set: + * EVFILT_READ and EVFILT_WRITE, ignoring any errors + */ + error = epoll_delete_all_events(td, epfp, args->fd); + if (error) + goto leave0; + /* FALLTHROUGH */ + + case LINUX_EPOLL_CTL_ADD: + kev_flags = EV_ADD | EV_ENABLE; + break; + + case LINUX_EPOLL_CTL_DEL: + /* CTL_DEL means unregister this fd with this epoll */ + error = epoll_delete_all_events(td, epfp, args->fd); + goto leave0; + + default: + error = EINVAL; + goto leave0; + } + + error = epoll_to_kevent(td, epfp, args->fd, &le, &kev_flags, + kev, &nchanges); + if (error) + goto leave0; + + epoll_fd_install(td, args->fd, le.data); + + error = kern_kevent_fp(td, epfp, nchanges, 0, &k_ops, NULL); + +leave0: + fdrop(fp, td); + +leave1: + fdrop(epfp, td); + return (error); +} + +/* + * Wait for a filter to be triggered on the epoll file descriptor. + */ +static int +linux_epoll_wait_common(struct thread *td, int epfd, struct epoll_event *events, + int maxevents, int timeout, sigset_t *uset) +{ + struct file *epfp; + struct timespec ts, *tsp; + cap_rights_t rights; + struct epoll_copyout_args coargs; + struct kevent_copyops k_ops = { &coargs, + epoll_kev_copyout, + NULL}; + int error; + + if (maxevents <= 0 || maxevents > LINUX_MAX_EVENTS) + return (EINVAL); + + if (uset != NULL) { + error = kern_sigprocmask(td, SIG_SETMASK, uset, + &td->td_oldsigmask, 0); + if (error != 0) + return (error); + td->td_pflags |= TDP_OLDMASK; + /* + * Make sure that ast() is called on return to + * usermode and TDP_OLDMASK is cleared, restoring old + * sigmask. + */ + thread_lock(td); + td->td_flags |= TDF_ASTPENDING; + thread_unlock(td); + } + + error = fget(td, epfd, + cap_rights_init(&rights, CAP_KQUEUE_EVENT), &epfp); + if (error != 0) + return (error); + + coargs.leventlist = events; + coargs.p = td->td_proc; + coargs.count = 0; + coargs.error = 0; + + if (timeout != -1) { + if (timeout < 0) { + error = EINVAL; + goto leave; + } + /* Convert from milliseconds to timespec. */ + ts.tv_sec = timeout / 1000; + ts.tv_nsec = (timeout % 1000) * 1000000; + tsp = &ts; + } else { + tsp = NULL; + } + + error = kern_kevent_fp(td, epfp, 0, maxevents, &k_ops, tsp); + if (error == 0 && coargs.error != 0) + error = coargs.error; + + /* + * kern_kevent might return ENOMEM which is not expected from epoll_wait. + * Maybe we should translate that but I don't think it matters at all. + */ + if (error == 0) + td->td_retval[0] = coargs.count; +leave: + fdrop(epfp, td); + return (error); +} + +int +linux_epoll_wait(struct thread *td, struct linux_epoll_wait_args *args) +{ + + return (linux_epoll_wait_common(td, args->epfd, args->events, + args->maxevents, args->timeout, NULL)); +} + +int +linux_epoll_pwait(struct thread *td, struct linux_epoll_pwait_args *args) +{ + sigset_t mask, *pmask; + l_sigset_t lmask; + int error; + + if (args->mask != NULL) { + error = copyin(args->mask, &lmask, sizeof(l_sigset_t)); + if (error != 0) + return (error); + linux_to_bsd_sigset(&lmask, &mask); + pmask = &mask; + } else + pmask = NULL; + return (linux_epoll_wait_common(td, args->epfd, args->events, + args->maxevents, args->timeout, pmask)); +} + +static int +epoll_delete_event(struct thread *td, struct file *epfp, int fd, int filter) +{ + struct epoll_copyin_args ciargs; + struct kevent kev; + struct kevent_copyops k_ops = { &ciargs, + NULL, + epoll_kev_copyin}; + int error; + + ciargs.changelist = &kev; + EV_SET(&kev, fd, filter, EV_DELETE | EV_DISABLE, 0, 0, 0); + + error = kern_kevent_fp(td, epfp, 1, 0, &k_ops, NULL); + + /* + * here we ignore ENONT, because we don't keep track of events here + */ + if (error == ENOENT) + error = 0; + return (error); +} + +static int +epoll_delete_all_events(struct thread *td, struct file *epfp, int fd) +{ + int error1, error2; + + error1 = epoll_delete_event(td, epfp, fd, EVFILT_READ); + error2 = epoll_delete_event(td, epfp, fd, EVFILT_WRITE); + + /* report any errors we got */ + return (error1 == 0 ? error2 : error1); +} + +static int +eventfd_create(struct thread *td, uint32_t initval, int flags) +{ + struct filedesc *fdp; + struct eventfd *efd; + struct file *fp; + int fflags, fd, error; + + fflags = 0; + if ((flags & LINUX_O_CLOEXEC) != 0) + fflags |= O_CLOEXEC; + + fdp = td->td_proc->p_fd; + error = falloc(td, &fp, &fd, fflags); + if (error) + return (error); + + efd = malloc(sizeof(*efd), M_EPOLL, M_WAITOK | M_ZERO); + efd->efd_flags = flags; + efd->efd_count = initval; + mtx_init(&efd->efd_lock, "eventfd", NULL, MTX_DEF); + + knlist_init_mtx(&efd->efd_sel.si_note, &efd->efd_lock); + + fflags = FREAD | FWRITE; + if ((flags & LINUX_O_NONBLOCK) != 0) + fflags |= FNONBLOCK; + + finit(fp, fflags, DTYPE_LINUXEFD, efd, &eventfdops); + fdrop(fp, td); + + td->td_retval[0] = fd; + return (error); +} + +int +linux_eventfd(struct thread *td, struct linux_eventfd_args *args) +{ + + return (eventfd_create(td, args->initval, 0)); +} + +int +linux_eventfd2(struct thread *td, struct linux_eventfd2_args *args) +{ + + if ((args->flags & ~(LINUX_O_CLOEXEC|LINUX_O_NONBLOCK|LINUX_EFD_SEMAPHORE)) != 0) + return (EINVAL); + + return (eventfd_create(td, args->initval, args->flags)); +} + +static int +eventfd_close(struct file *fp, struct thread *td) +{ + struct eventfd *efd; + + efd = fp->f_data; + if (fp->f_type != DTYPE_LINUXEFD || efd == NULL) + return (EBADF); + + seldrain(&efd->efd_sel); + knlist_destroy(&efd->efd_sel.si_note); + + fp->f_ops = &badfileops; + mtx_destroy(&efd->efd_lock); + free(efd, M_EPOLL); + + return (0); +} + +static int +eventfd_read(struct file *fp, struct uio *uio, struct ucred *active_cred, + int flags, struct thread *td) +{ + struct eventfd *efd; + eventfd_t count; + int error; + + efd = fp->f_data; + if (fp->f_type != DTYPE_LINUXEFD || efd == NULL) + return (EBADF); + + if (uio->uio_resid < sizeof(eventfd_t)) + return (EINVAL); + + error = 0; + mtx_lock(&efd->efd_lock); +retry: + if (efd->efd_count == 0) { + if ((efd->efd_flags & LINUX_O_NONBLOCK) != 0) { + mtx_unlock(&efd->efd_lock); + return (EAGAIN); + } + error = mtx_sleep(&efd->efd_count, &efd->efd_lock, PCATCH, "lefdrd", 0); + if (error == 0) + goto retry; + } + if (error == 0) { + if ((efd->efd_flags & LINUX_EFD_SEMAPHORE) != 0) { + count = 1; + --efd->efd_count; + } else { + count = efd->efd_count; + efd->efd_count = 0; + } + KNOTE_LOCKED(&efd->efd_sel.si_note, 0); + selwakeup(&efd->efd_sel); + wakeup(&efd->efd_count); + mtx_unlock(&efd->efd_lock); + error = uiomove(&count, sizeof(eventfd_t), uio); + } else + mtx_unlock(&efd->efd_lock); + + return (error); +} + +static int +eventfd_write(struct file *fp, struct uio *uio, struct ucred *active_cred, + int flags, struct thread *td) +{ + struct eventfd *efd; + eventfd_t count; + int error; + + efd = fp->f_data; + if (fp->f_type != DTYPE_LINUXEFD || efd == NULL) + return (EBADF); + + if (uio->uio_resid < sizeof(eventfd_t)) + return (EINVAL); + + error = uiomove(&count, sizeof(eventfd_t), uio); + if (error) + return (error); + if (count == UINT64_MAX) + return (EINVAL); + + mtx_lock(&efd->efd_lock); +retry: + if (UINT64_MAX - efd->efd_count <= count) { + if ((efd->efd_flags & LINUX_O_NONBLOCK) != 0) { + mtx_unlock(&efd->efd_lock); + return (EAGAIN); + } + error = mtx_sleep(&efd->efd_count, &efd->efd_lock, + PCATCH, "lefdwr", 0); + if (error == 0) + goto retry; + } + if (error == 0) { + efd->efd_count += count; + KNOTE_LOCKED(&efd->efd_sel.si_note, 0); + selwakeup(&efd->efd_sel); + wakeup(&efd->efd_count); + } + mtx_unlock(&efd->efd_lock); + + return (error); +} + +static int +eventfd_poll(struct file *fp, int events, struct ucred *active_cred, + struct thread *td) +{ + struct eventfd *efd; + int revents = 0; + + efd = fp->f_data; + if (fp->f_type != DTYPE_LINUXEFD || efd == NULL) + return (POLLERR); + + mtx_lock(&efd->efd_lock); + if ((events & (POLLIN|POLLRDNORM)) && efd->efd_count > 0) + revents |= events & (POLLIN|POLLRDNORM); + if ((events & (POLLOUT|POLLWRNORM)) && UINT64_MAX - 1 > efd->efd_count) + revents |= events & (POLLOUT|POLLWRNORM); + if (revents == 0) + selrecord(td, &efd->efd_sel); + mtx_unlock(&efd->efd_lock); + + return (revents); +} + +/*ARGSUSED*/ +static int +eventfd_kqfilter(struct file *fp, struct knote *kn) +{ + struct eventfd *efd; + + efd = fp->f_data; + if (fp->f_type != DTYPE_LINUXEFD || efd == NULL) + return (EINVAL); + + mtx_lock(&efd->efd_lock); + switch (kn->kn_filter) { + case EVFILT_READ: + kn->kn_fop = &eventfd_rfiltops; + break; + case EVFILT_WRITE: + kn->kn_fop = &eventfd_wfiltops; + break; + default: + mtx_unlock(&efd->efd_lock); + return (EINVAL); + } + + kn->kn_hook = efd; + knlist_add(&efd->efd_sel.si_note, kn, 1); + mtx_unlock(&efd->efd_lock); + + return (0); +} + +static void +filt_eventfddetach(struct knote *kn) +{ + struct eventfd *efd = kn->kn_hook; + + mtx_lock(&efd->efd_lock); + knlist_remove(&efd->efd_sel.si_note, kn, 1); + mtx_unlock(&efd->efd_lock); +} + +/*ARGSUSED*/ +static int +filt_eventfdread(struct knote *kn, long hint) +{ + struct eventfd *efd = kn->kn_hook; + int ret; + + mtx_assert(&efd->efd_lock, MA_OWNED); + ret = (efd->efd_count > 0); + + return (ret); +} + +/*ARGSUSED*/ +static int +filt_eventfdwrite(struct knote *kn, long hint) +{ + struct eventfd *efd = kn->kn_hook; + int ret; + + mtx_assert(&efd->efd_lock, MA_OWNED); + ret = (UINT64_MAX - 1 > efd->efd_count); + + return (ret); +} + +/*ARGSUSED*/ +static int +eventfd_truncate(struct file *fp, off_t length, struct ucred *active_cred, + struct thread *td) +{ + + return (ENXIO); +} + +/*ARGSUSED*/ +static int +eventfd_ioctl(struct file *fp, u_long cmd, void *data, + struct ucred *active_cred, struct thread *td) +{ + + return (ENXIO); +} + +/*ARGSUSED*/ +static int +eventfd_stat(struct file *fp, struct stat *st, struct ucred *active_cred, + struct thread *td) +{ + + return (ENXIO); +} diff --git a/sys/compat/linux/linux_event.h b/sys/compat/linux/linux_event.h new file mode 100644 index 0000000..9b7d37b --- /dev/null +++ b/sys/compat/linux/linux_event.h @@ -0,0 +1,60 @@ +/*- + * Copyright (c) 2007 Roman Divacky + * Copyright (c) 2014 Dmitry Chagin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _LINUX_EVENT_H_ +#define _LINUX_EVENT_H_ + +#define LINUX_EPOLLIN 0x001 +#define LINUX_EPOLLPRI 0x002 +#define LINUX_EPOLLOUT 0x004 +#define LINUX_EPOLLRDNORM 0x040 +#define LINUX_EPOLLRDBAND 0x080 +#define LINUX_EPOLLWRNORM 0x100 +#define LINUX_EPOLLWRBAND 0x200 +#define LINUX_EPOLLMSG 0x400 +#define LINUX_EPOLLERR 0x008 +#define LINUX_EPOLLHUP 0x010 +#define LINUX_EPOLLRDHUP 0x2000 +#define LINUX_EPOLLWAKEUP 1u<<29 +#define LINUX_EPOLLONESHOT 1u<<30 +#define LINUX_EPOLLET 1u<<31 + +#define LINUX_EPOLL_EVRD (LINUX_EPOLLIN|LINUX_EPOLLRDNORM \ + |LINUX_EPOLLHUP|LINUX_EPOLLERR|LINUX_EPOLLPRI) +#define LINUX_EPOLL_EVWR (LINUX_EPOLLOUT|LINUX_EPOLLWRNORM) +#define LINUX_EPOLL_EVSUP (LINUX_EPOLLET|LINUX_EPOLLONESHOT \ + |LINUX_EPOLL_EVRD|LINUX_EPOLL_EVWR|LINUX_EPOLLRDHUP) + +#define LINUX_EPOLL_CTL_ADD 1 +#define LINUX_EPOLL_CTL_DEL 2 +#define LINUX_EPOLL_CTL_MOD 3 + +#define LINUX_EFD_SEMAPHORE (1 << 0) + +#endif /* !_LINUX_EVENT_H_ */ diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c index 19104a4..ee1d1ba 100644 --- a/sys/compat/linux/linux_file.c +++ b/sys/compat/linux/linux_file.c @@ -235,6 +235,7 @@ linux_lseek(struct thread *td, struct linux_lseek_args *args) return error; } +#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) int linux_llseek(struct thread *td, struct linux_llseek_args *args) { @@ -273,6 +274,7 @@ linux_readdir(struct thread *td, struct linux_readdir_args *args) lda.count = 1; return linux_getdents(td, &lda); } +#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ /* * Note that linux_getdents(2) and linux_getdents64(2) have the same @@ -367,8 +369,8 @@ getdents_common(struct thread *td, struct linux_getdents64_args *args, buflen = max(LINUX_DIRBLKSIZ, nbytes); buflen = min(buflen, MAXBSIZE); - buf = malloc(buflen, M_TEMP, M_WAITOK); - lbuf = malloc(LINUX_MAXRECLEN, M_TEMP, M_WAITOK | M_ZERO); + buf = malloc(buflen, M_LINUX, M_WAITOK); + lbuf = malloc(LINUX_MAXRECLEN, M_LINUX, M_WAITOK | M_ZERO); vn_lock(vp, LK_SHARED | LK_RETRY); aiov.iov_base = buf; @@ -519,8 +521,8 @@ out: VOP_UNLOCK(vp, 0); foffset_unlock(fp, off, 0); fdrop(fp, td); - free(buf, M_TEMP); - free(lbuf, M_TEMP); + free(buf, M_LINUX); + free(lbuf, M_LINUX); return (error); } @@ -578,10 +580,8 @@ int linux_faccessat(struct thread *td, struct linux_faccessat_args *args) { char *path; - int error, dfd, flag; + int error, dfd; - if (args->flag & ~LINUX_AT_EACCESS) - return (EINVAL); /* linux convention */ if (args->amode & ~(F_OK | X_OK | W_OK | R_OK)) return (EINVAL); @@ -594,8 +594,7 @@ linux_faccessat(struct thread *td, struct linux_faccessat_args *args) printf(ARGS(access, "%s, %d"), path, args->amode); #endif - flag = (args->flag & LINUX_AT_EACCESS) == 0 ? 0 : AT_EACCESS; - error = kern_accessat(td, dfd, path, UIO_SYSSPACE, flag, args->amode); + error = kern_accessat(td, dfd, path, UIO_SYSSPACE, 0, args->amode); LFREEPATH(path); return (error); @@ -919,6 +918,7 @@ linux_truncate(struct thread *td, struct linux_truncate_args *args) return (error); } +#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) int linux_truncate64(struct thread *td, struct linux_truncate64_args *args) { @@ -936,6 +936,8 @@ linux_truncate64(struct thread *td, struct linux_truncate64_args *args) LFREEPATH(path); return (error); } +#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ + int linux_ftruncate(struct thread *td, struct linux_ftruncate_args *args) { @@ -1123,6 +1125,7 @@ linux_mount(struct thread *td, struct linux_mount_args *args) return (error); } +#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) int linux_oldumount(struct thread *td, struct linux_oldumount_args *args) { @@ -1132,6 +1135,7 @@ linux_oldumount(struct thread *td, struct linux_oldumount_args *args) args2.flags = 0; return (linux_umount(td, &args2)); } +#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ int linux_umount(struct thread *td, struct linux_umount_args *args) @@ -1262,7 +1266,7 @@ bsd_to_linux_flock64(struct flock *bsd_flock, struct l_flock64 *linux_flock) #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ static int -fcntl_common(struct thread *td, struct linux_fcntl64_args *args) +fcntl_common(struct thread *td, struct linux_fcntl_args *args) { struct l_flock linux_flock; struct flock bsd_flock; @@ -1380,6 +1384,9 @@ fcntl_common(struct thread *td, struct linux_fcntl64_args *args) fdrop(fp, td); return (kern_fcntl(td, args->fd, F_SETOWN, args->arg)); + + case LINUX_F_DUPFD_CLOEXEC: + return (kern_fcntl(td, args->fd, F_DUPFD_CLOEXEC, args->arg)); } return (EINVAL); @@ -1388,17 +1395,13 @@ fcntl_common(struct thread *td, struct linux_fcntl64_args *args) int linux_fcntl(struct thread *td, struct linux_fcntl_args *args) { - struct linux_fcntl64_args args64; #ifdef DEBUG if (ldebug(fcntl)) printf(ARGS(fcntl, "%d, %08x, *"), args->fd, args->cmd); #endif - args64.fd = args->fd; - args64.cmd = args->cmd; - args64.arg = args->arg; - return (fcntl_common(td, &args64)); + return (fcntl_common(td, args)); } #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) @@ -1407,6 +1410,7 @@ linux_fcntl64(struct thread *td, struct linux_fcntl64_args *args) { struct l_flock64 linux_flock; struct flock bsd_flock; + struct linux_fcntl_args fcntl_args; int error; #ifdef DEBUG @@ -1447,7 +1451,10 @@ linux_fcntl64(struct thread *td, struct linux_fcntl64_args *args) (intptr_t)&bsd_flock)); } - return (fcntl_common(td, args)); + fcntl_args.fd = args->fd; + fcntl_args.cmd = args->cmd; + fcntl_args.arg = args->arg; + return (fcntl_common(td, &fcntl_args)); } #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ @@ -1543,6 +1550,7 @@ linux_fadvise64(struct thread *td, struct linux_fadvise64_args *args) advice)); } +#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) int linux_fadvise64_64(struct thread *td, struct linux_fadvise64_64_args *args) { @@ -1554,6 +1562,7 @@ linux_fadvise64_64(struct thread *td, struct linux_fadvise64_64_args *args) return (kern_posix_fadvise(td, args->fd, args->offset, args->len, advice)); } +#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ int linux_pipe(struct thread *td, struct linux_pipe_args *args) @@ -1600,3 +1609,37 @@ linux_pipe2(struct thread *td, struct linux_pipe2_args *args) /* XXX: Close descriptors on error. */ return (copyout(fildes, args->pipefds, sizeof(fildes))); } + +int +linux_dup3(struct thread *td, struct linux_dup3_args *args) +{ + int cmd; + intptr_t newfd; + + if (args->oldfd == args->newfd) + return (EINVAL); + if ((args->flags & ~LINUX_O_CLOEXEC) != 0) + return (EINVAL); + if (args->flags & LINUX_O_CLOEXEC) + cmd = F_DUP2FD_CLOEXEC; + else + cmd = F_DUP2FD; + + newfd = args->newfd; + return (kern_fcntl(td, args->oldfd, cmd, newfd)); +} + +int +linux_fallocate(struct thread *td, struct linux_fallocate_args *args) +{ + + /* + * We emulate only posix_fallocate system call for which + * mode should be 0. + */ + if (args->mode != 0) + return (ENOSYS); + + return (kern_posix_fallocate(td, args->fd, args->offset, + args->len)); +} diff --git a/sys/compat/linux/linux_file.h b/sys/compat/linux/linux_file.h index 2d3106f..f27d5b4 100644 --- a/sys/compat/linux/linux_file.h +++ b/sys/compat/linux/linux_file.h @@ -54,4 +54,75 @@ #define LINUX_MS_NOEXEC 0x0008 #define LINUX_MS_REMOUNT 0x0020 +/* + * common open/fcntl flags + */ +#define LINUX_O_RDONLY 00000000 +#define LINUX_O_WRONLY 00000001 +#define LINUX_O_RDWR 00000002 +#define LINUX_O_ACCMODE 00000003 +#define LINUX_O_CREAT 00000100 +#define LINUX_O_EXCL 00000200 +#define LINUX_O_NOCTTY 00000400 +#define LINUX_O_TRUNC 00001000 +#define LINUX_O_APPEND 00002000 +#define LINUX_O_NONBLOCK 00004000 +#define LINUX_O_NDELAY LINUX_O_NONBLOCK +#define LINUX_O_SYNC 00010000 +#define LINUX_FASYNC 00020000 +#define LINUX_O_DIRECT 00040000 /* Direct disk access hint */ +#define LINUX_O_LARGEFILE 00100000 +#define LINUX_O_DIRECTORY 00200000 /* Must be a directory */ +#define LINUX_O_NOFOLLOW 00400000 /* Do not follow links */ +#define LINUX_O_NOATIME 01000000 +#define LINUX_O_CLOEXEC 02000000 + +#define LINUX_F_DUPFD 0 +#define LINUX_F_GETFD 1 +#define LINUX_F_SETFD 2 +#define LINUX_F_GETFL 3 +#define LINUX_F_SETFL 4 +#ifndef LINUX_F_GETLK +#define LINUX_F_GETLK 5 +#define LINUX_F_SETLK 6 +#define LINUX_F_SETLKW 7 +#endif +#ifndef LINUX_F_SETOWN +#define LINUX_F_SETOWN 8 +#define LINUX_F_GETOWN 9 +#endif +#ifndef LINUX_F_SETSIG +#define LINUX_F_SETSIG 10 +#define LINUX_F_GETSIG 11 +#endif +#ifndef LINUX_F_SETOWN_EX +#define LINUX_F_SETOWN_EX 15 +#define LINUX_F_GETOWN_EX 16 +#define LINUX_F_GETOWNER_UIDS 17 +#endif + +#define LINUX_F_SPECIFIC_BASE 1024 + +#define LINUX_F_SETLEASE (LINUX_F_SPECIFIC_BASE + 0) +#define LINUX_F_GETLEASE (LINUX_F_SPECIFIC_BASE + 1) +#define LINUX_F_CANCELLK (LINUX_F_SPECIFIC_BASE + 5) +#define LINUX_F_DUPFD_CLOEXEC (LINUX_F_SPECIFIC_BASE + 6) +#define LINUX_F_NOTIFY (LINUX_F_SPECIFIC_BASE + 2) +#define LINUX_F_SETPIPE_SZ (LINUX_F_SPECIFIC_BASE + 7) +#define LINUX_F_GETPIPE_SZ (LINUX_F_SPECIFIC_BASE + 8) + +#define LINUX_F_GETLKP 36 +#define LINUX_F_SETLKP 37 +#define LINUX_F_SETLKPW 38 + +#define LINUX_F_OWNER_TID 0 +#define LINUX_F_OWNER_PID 1 +#define LINUX_F_OWNER_PGRP 2 + +#ifndef LINUX_F_RDLCK +#define LINUX_F_RDLCK 0 +#define LINUX_F_WRLCK 1 +#define LINUX_F_UNLCK 2 +#endif + #endif /* !_LINUX_FILE_H_ */ diff --git a/sys/compat/linux/linux_fork.c b/sys/compat/linux/linux_fork.c index 0ab7d3a..9e7c71f 100644 --- a/sys/compat/linux/linux_fork.c +++ b/sys/compat/linux/linux_fork.c @@ -35,13 +35,20 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/systm.h> #include <sys/imgact.h> +#include <sys/ktr.h> #include <sys/lock.h> #include <sys/mutex.h> #include <sys/proc.h> +#include <sys/racct.h> #include <sys/sched.h> -#include <sys/sdt.h> +#include <sys/syscallsubr.h> #include <sys/sx.h> #include <sys/unistd.h> +#include <sys/wait.h> + +#include <vm/vm.h> +#include <vm/pmap.h> +#include <vm/vm_map.h> #ifdef COMPAT_LINUX32 #include <machine/../linux32/linux.h> @@ -50,18 +57,10 @@ __FBSDID("$FreeBSD$"); #include <machine/../linux/linux.h> #include <machine/../linux/linux_proto.h> #endif -#include <compat/linux/linux_dtrace.h> -#include <compat/linux/linux_signal.h> #include <compat/linux/linux_emul.h> +#include <compat/linux/linux_futex.h> #include <compat/linux/linux_misc.h> - -/* DTrace init */ -LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE); - -/* Linuxulator-global DTrace probes */ -LIN_SDT_PROBE_DECLARE(locks, emul_lock, locked); -LIN_SDT_PROBE_DECLARE(locks, emul_lock, unlock); - +#include <compat/linux/linux_util.h> int linux_fork(struct thread *td, struct linux_fork_args *args) @@ -79,14 +78,11 @@ linux_fork(struct thread *td, struct linux_fork_args *args) != 0) return (error); - td->td_retval[0] = p2->p_pid; - td->td_retval[1] = 0; + td2 = FIRST_THREAD_IN_PROC(p2); - error = linux_proc_init(td, td->td_retval[0], 0); - if (error) - return (error); + linux_proc_init(td, td2, 0); - td2 = FIRST_THREAD_IN_PROC(p2); + td->td_retval[0] = p2->p_pid; /* * Make this runnable after we are finished with it. @@ -115,13 +111,11 @@ linux_vfork(struct thread *td, struct linux_vfork_args *args) 0, &p2, NULL, 0)) != 0) return (error); - td->td_retval[0] = p2->p_pid; + td2 = FIRST_THREAD_IN_PROC(p2); - error = linux_proc_init(td, td->td_retval[0], 0); - if (error) - return (error); + linux_proc_init(td, td2, 0); - td2 = FIRST_THREAD_IN_PROC(p2); + td->td_retval[0] = p2->p_pid; /* * Make this runnable after we are finished with it. @@ -134,8 +128,8 @@ linux_vfork(struct thread *td, struct linux_vfork_args *args) return (0); } -int -linux_clone(struct thread *td, struct linux_clone_args *args) +static int +linux_clone_proc(struct thread *td, struct linux_clone_args *args) { int error, ff = RFPROC | RFSTOPPED; struct proc *p2; @@ -153,9 +147,7 @@ linux_clone(struct thread *td, struct linux_clone_args *args) exit_signal = args->flags & 0x000000ff; if (LINUX_SIG_VALID(exit_signal)) { - if (exit_signal <= LINUX_SIGTBLSZ) - exit_signal = - linux_to_bsd_signal[_SIG_IDX(exit_signal)]; + exit_signal = linux_to_bsd_signal(exit_signal); } else if (exit_signal != 0) return (EINVAL); @@ -172,22 +164,6 @@ linux_clone(struct thread *td, struct linux_clone_args *args) if (!(args->flags & (LINUX_CLONE_FILES | LINUX_CLONE_FS))) ff |= RFFDG; - /* - * Attempt to detect when linux_clone(2) is used for creating - * kernel threads. Unfortunately despite the existence of the - * CLONE_THREAD flag, version of linuxthreads package used in - * most popular distros as of beginning of 2005 doesn't make - * any use of it. Therefore, this detection relies on - * empirical observation that linuxthreads sets certain - * combination of flags, so that we can make more or less - * precise detection and notify the FreeBSD kernel that several - * processes are in fact part of the same threading group, so - * that special treatment is necessary for signal delivery - * between those processes and fd locking. - */ - if ((args->flags & 0xffffff00) == LINUX_THREADING_FLAGS) - ff |= RFTHREAD; - if (args->flags & LINUX_CLONE_PARENT_SETTID) if (args->parent_tidptr == NULL) return (EINVAL); @@ -199,29 +175,13 @@ linux_clone(struct thread *td, struct linux_clone_args *args) if (error) return (error); - if (args->flags & (LINUX_CLONE_PARENT | LINUX_CLONE_THREAD)) { - sx_xlock(&proctree_lock); - PROC_LOCK(p2); - proc_reparent(p2, td->td_proc->p_pptr); - PROC_UNLOCK(p2); - sx_xunlock(&proctree_lock); - } + td2 = FIRST_THREAD_IN_PROC(p2); /* create the emuldata */ - error = linux_proc_init(td, p2->p_pid, args->flags); - /* reference it - no need to check this */ - em = em_find(p2, EMUL_DOLOCK); - KASSERT(em != NULL, ("clone: emuldata not found.")); - /* and adjust it */ - - if (args->flags & LINUX_CLONE_THREAD) { -#ifdef notyet - PROC_LOCK(p2); - p2->p_pgrp = td->td_proc->p_pgrp; - PROC_UNLOCK(p2); -#endif - exit_signal = 0; - } + linux_proc_init(td, td2, args->flags); + + em = em_find(td2); + KASSERT(em != NULL, ("clone_proc: emuldata not found.\n")); if (args->flags & LINUX_CLONE_CHILD_SETTID) em->child_set_tid = args->child_tidptr; @@ -233,8 +193,6 @@ linux_clone(struct thread *td, struct linux_clone_args *args) else em->child_clear_tid = NULL; - EMUL_UNLOCK(&emul_lock); - if (args->flags & LINUX_CLONE_PARENT_SETTID) { error = copyout(&p2->p_pid, args->parent_tidptr, sizeof(p2->p_pid)); @@ -245,14 +203,12 @@ linux_clone(struct thread *td, struct linux_clone_args *args) PROC_LOCK(p2); p2->p_sigparent = exit_signal; PROC_UNLOCK(p2); - td2 = FIRST_THREAD_IN_PROC(p2); /* * In a case of stack = NULL, we are supposed to COW calling process * stack. This is what normal fork() does, so we just keep tf_rsp arg * intact. */ - if (args->stack) - linux_set_upcall_kse(td2, PTROUT(args->stack)); + linux_set_upcall_kse(td2, PTROUT(args->stack)); if (args->flags & LINUX_CLONE_SETTLS) linux_set_cloned_tls(td2, args->tls); @@ -263,6 +219,7 @@ linux_clone(struct thread *td, struct linux_clone_args *args) "stack %p sig = %d"), (int)p2->p_pid, args->stack, exit_signal); #endif + /* * Make this runnable after we are finished with it. */ @@ -272,7 +229,233 @@ linux_clone(struct thread *td, struct linux_clone_args *args) thread_unlock(td2); td->td_retval[0] = p2->p_pid; - td->td_retval[1] = 0; return (0); } + +static int +linux_clone_thread(struct thread *td, struct linux_clone_args *args) +{ + struct linux_emuldata *em; + struct thread *newtd; + struct proc *p; + int error; + +#ifdef DEBUG + if (ldebug(clone)) { + printf(ARGS(clone, "thread: flags %x, stack %p, parent tid: %p, " + "child tid: %p"), (unsigned)args->flags, + args->stack, args->parent_tidptr, args->child_tidptr); + } +#endif + + LINUX_CTR4(clone_thread, "thread(%d) flags %x ptid %p ctid %p", + td->td_tid, (unsigned)args->flags, + args->parent_tidptr, args->child_tidptr); + + if (args->flags & LINUX_CLONE_PARENT_SETTID) + if (args->parent_tidptr == NULL) + return (EINVAL); + + /* Threads should be created with own stack */ + if (args->stack == NULL) + return (EINVAL); + + p = td->td_proc; + +#ifdef RACCT + if (racct_enable) { + PROC_LOCK(p); + error = racct_add(p, RACCT_NTHR, 1); + PROC_UNLOCK(p); + if (error != 0) + return (EPROCLIM); + } +#endif + + /* Initialize our td */ + error = kern_thr_alloc(p, 0, &newtd); + if (error) + goto fail; + + cpu_set_upcall(newtd, td); + + bzero(&newtd->td_startzero, + __rangeof(struct thread, td_startzero, td_endzero)); + bcopy(&td->td_startcopy, &newtd->td_startcopy, + __rangeof(struct thread, td_startcopy, td_endcopy)); + + newtd->td_proc = p; + newtd->td_ucred = crhold(td->td_ucred); + + /* create the emuldata */ + linux_proc_init(td, newtd, args->flags); + + em = em_find(newtd); + KASSERT(em != NULL, ("clone_thread: emuldata not found.\n")); + + if (args->flags & LINUX_CLONE_SETTLS) + linux_set_cloned_tls(newtd, args->tls); + + if (args->flags & LINUX_CLONE_CHILD_SETTID) + em->child_set_tid = args->child_tidptr; + else + em->child_set_tid = NULL; + + if (args->flags & LINUX_CLONE_CHILD_CLEARTID) + em->child_clear_tid = args->child_tidptr; + else + em->child_clear_tid = NULL; + + cpu_thread_clean(newtd); + + linux_set_upcall_kse(newtd, PTROUT(args->stack)); + + PROC_LOCK(p); + p->p_flag |= P_HADTHREADS; + bcopy(p->p_comm, newtd->td_name, sizeof(newtd->td_name)); + + if (args->flags & LINUX_CLONE_PARENT) + thread_link(newtd, p->p_pptr); + else + thread_link(newtd, p); + + thread_lock(td); + /* let the scheduler know about these things. */ + sched_fork_thread(td, newtd); + thread_unlock(td); + if (P_SHOULDSTOP(p)) + newtd->td_flags |= TDF_ASTPENDING | TDF_NEEDSUSPCHK; + PROC_UNLOCK(p); + + tidhash_add(newtd); + +#ifdef DEBUG + if (ldebug(clone)) + printf(ARGS(clone, "successful clone to %d, stack %p"), + (int)newtd->td_tid, args->stack); +#endif + + LINUX_CTR2(clone_thread, "thread(%d) successful clone to %d", + td->td_tid, newtd->td_tid); + + if (args->flags & LINUX_CLONE_PARENT_SETTID) { + error = copyout(&newtd->td_tid, args->parent_tidptr, + sizeof(newtd->td_tid)); + if (error) + printf(LMSG("clone_thread: copyout failed!")); + } + + /* + * Make this runnable after we are finished with it. + */ + thread_lock(newtd); + TD_SET_CAN_RUN(newtd); + sched_add(newtd, SRQ_BORING); + thread_unlock(newtd); + + td->td_retval[0] = newtd->td_tid; + + return (0); + +fail: +#ifdef RACCT + if (racct_enable) { + PROC_LOCK(p); + racct_sub(p, RACCT_NTHR, 1); + PROC_UNLOCK(p); + } +#endif + return (error); +} + +int +linux_clone(struct thread *td, struct linux_clone_args *args) +{ + + if (args->flags & LINUX_CLONE_THREAD) + return (linux_clone_thread(td, args)); + else + return (linux_clone_proc(td, args)); +} + +int +linux_exit(struct thread *td, struct linux_exit_args *args) +{ + struct linux_emuldata *em; + + em = em_find(td); + KASSERT(em != NULL, ("exit: emuldata not found.\n")); + + LINUX_CTR2(exit, "thread(%d) (%d)", em->em_tid, args->rval); + + linux_thread_detach(td); + + /* + * XXX. When the last two threads of a process + * exit via pthread_exit() try thr_exit() first. + */ + kern_thr_exit(td); + exit1(td, W_EXITCODE(args->rval, 0)); + /* NOTREACHED */ +} + +int +linux_set_tid_address(struct thread *td, struct linux_set_tid_address_args *args) +{ + struct linux_emuldata *em; + + em = em_find(td); + KASSERT(em != NULL, ("set_tid_address: emuldata not found.\n")); + + em->child_clear_tid = args->tidptr; + + td->td_retval[0] = em->em_tid; + + LINUX_CTR3(set_tid_address, "tidptr(%d) %p, returns %d", + em->em_tid, args->tidptr, td->td_retval[0]); + + return (0); +} + +void +linux_thread_detach(struct thread *td) +{ + struct linux_sys_futex_args cup; + struct linux_emuldata *em; + int *child_clear_tid; + int error; + + em = em_find(td); + KASSERT(em != NULL, ("thread_detach: emuldata not found.\n")); + + LINUX_CTR1(thread_detach, "thread(%d)", em->em_tid); + + release_futexes(td, em); + + child_clear_tid = em->child_clear_tid; + + if (child_clear_tid != NULL) { + + LINUX_CTR2(thread_detach, "thread(%d) %p", + em->em_tid, child_clear_tid); + + error = suword32(child_clear_tid, 0); + if (error != 0) + return; + + cup.uaddr = child_clear_tid; + cup.op = LINUX_FUTEX_WAKE; + cup.val = 1; /* wake one */ + cup.timeout = NULL; + cup.uaddr2 = NULL; + cup.val3 = 0; + error = linux_sys_futex(td, &cup); + /* + * this cannot happen at the moment and if this happens it + * probably means there is a user space bug + */ + if (error != 0) + linux_msg(td, "futex stuff in thread_detach failed."); + } +} diff --git a/sys/compat/linux/linux_futex.c b/sys/compat/linux/linux_futex.c index eb79ad9..4573f73 100644 --- a/sys/compat/linux/linux_futex.c +++ b/sys/compat/linux/linux_futex.c @@ -66,15 +66,12 @@ __KERNEL_RCSID(1, "$NetBSD: linux_futex.c,v 1.7 2006/07/24 19:01:49 manu Exp $") #include <compat/linux/linux_dtrace.h> #include <compat/linux/linux_emul.h> #include <compat/linux/linux_futex.h> +#include <compat/linux/linux_timer.h> #include <compat/linux/linux_util.h> /* DTrace init */ LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE); -/* Linuxulator-global DTrace probes */ -LIN_SDT_PROBE_DECLARE(locks, emul_lock, locked); -LIN_SDT_PROBE_DECLARE(locks, emul_lock, unlock); - /** * Futex part for the special DTrace module "locks". */ @@ -175,8 +172,8 @@ LIN_SDT_PROBE_DEFINE2(futex, linux_get_robust_list, entry, "struct thread *", "struct linux_get_robust_list_args *"); LIN_SDT_PROBE_DEFINE1(futex, linux_get_robust_list, copyout_error, "int"); LIN_SDT_PROBE_DEFINE1(futex, linux_get_robust_list, return, "int"); -LIN_SDT_PROBE_DEFINE3(futex, handle_futex_death, entry, "struct proc *", - "uint32_t *", "unsigned int"); +LIN_SDT_PROBE_DEFINE3(futex, handle_futex_death, entry, + "struct linux_emuldata *", "uint32_t *", "unsigned int"); LIN_SDT_PROBE_DEFINE1(futex, handle_futex_death, copyin_error, "int"); LIN_SDT_PROBE_DEFINE1(futex, handle_futex_death, return, "int"); LIN_SDT_PROBE_DEFINE3(futex, fetch_robust_entry, entry, @@ -184,13 +181,11 @@ LIN_SDT_PROBE_DEFINE3(futex, fetch_robust_entry, entry, "unsigned int *"); LIN_SDT_PROBE_DEFINE1(futex, fetch_robust_entry, copyin_error, "int"); LIN_SDT_PROBE_DEFINE1(futex, fetch_robust_entry, return, "int"); -LIN_SDT_PROBE_DEFINE1(futex, release_futexes, entry, "struct proc *"); +LIN_SDT_PROBE_DEFINE2(futex, release_futexes, entry, "struct thread *", + "struct linux_emuldata *"); LIN_SDT_PROBE_DEFINE1(futex, release_futexes, copyin_error, "int"); LIN_SDT_PROBE_DEFINE0(futex, release_futexes, return); -static MALLOC_DEFINE(M_FUTEX, "futex", "Linux futexes"); -static MALLOC_DEFINE(M_FUTEX_WP, "futex wp", "Linux futexes wp"); - struct futex; struct waiting_proc { @@ -253,6 +248,21 @@ struct mtx futex_mtx; /* protects the futex list */ * wp_list to prevent double wakeup. */ +static void futex_put(struct futex *, struct waiting_proc *); +static int futex_get0(uint32_t *, struct futex **f, uint32_t); +static int futex_get(uint32_t *, struct waiting_proc **, struct futex **, + uint32_t); +static int futex_sleep(struct futex *, struct waiting_proc *, int); +static int futex_wake(struct futex *, int, uint32_t); +static int futex_requeue(struct futex *, int, struct futex *, int); +static int futex_wait(struct futex *, struct waiting_proc *, int, + uint32_t); +static int futex_atomic_op(struct thread *, int, uint32_t *); +static int handle_futex_death(struct linux_emuldata *, uint32_t *, + unsigned int); +static int fetch_robust_entry(struct linux_robust_list **, + struct linux_robust_list **, unsigned int *); + /* support.s */ int futex_xchgl(int oparg, uint32_t *uaddr, int *oldval); int futex_addl(int oparg, uint32_t *uaddr, int *oldval); @@ -260,6 +270,7 @@ int futex_orl(int oparg, uint32_t *uaddr, int *oldval); int futex_andl(int oparg, uint32_t *uaddr, int *oldval); int futex_xorl(int oparg, uint32_t *uaddr, int *oldval); + static void futex_put(struct futex *f, struct waiting_proc *wp) { @@ -657,10 +668,11 @@ int linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args) { int clockrt, nrwake, op_ret, ret; - struct linux_emuldata *em; + struct linux_pemuldata *pem; struct waiting_proc *wp; struct futex *f, *f2; - struct l_timespec timeout; + struct l_timespec ltimeout; + struct timespec timeout; struct timeval utv, ctv; int timeout_hz; int error; @@ -704,6 +716,38 @@ linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args) LINUX_CTR3(sys_futex, "WAIT uaddr %p val 0x%x bitset 0x%x", args->uaddr, args->val, args->val3); + if (args->timeout != NULL) { + error = copyin(args->timeout, <imeout, sizeof(ltimeout)); + if (error) { + LIN_SDT_PROBE1(futex, linux_sys_futex, copyin_error, + error); + LIN_SDT_PROBE1(futex, linux_sys_futex, return, error); + return (error); + } + error = linux_to_native_timespec(&timeout, <imeout); + if (error) + return (error); + TIMESPEC_TO_TIMEVAL(&utv, &timeout); + error = itimerfix(&utv); + if (error) { + LIN_SDT_PROBE1(futex, linux_sys_futex, itimerfix_error, + error); + LIN_SDT_PROBE1(futex, linux_sys_futex, return, error); + return (error); + } + if (clockrt) { + microtime(&ctv); + timevalsub(&utv, &ctv); + } else if (args->op == LINUX_FUTEX_WAIT_BITSET) { + microuptime(&ctv); + timevalsub(&utv, &ctv); + } + if (utv.tv_sec < 0) + timevalclear(&utv); + timeout_hz = tvtohz(&utv); + } else + timeout_hz = 0; + error = futex_get(args->uaddr, &wp, &f, flags | FUTEX_CREATE_WP); if (error) { @@ -736,37 +780,6 @@ linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args) return (EWOULDBLOCK); } - if (args->timeout != NULL) { - error = copyin(args->timeout, &timeout, sizeof(timeout)); - if (error) { - LIN_SDT_PROBE1(futex, linux_sys_futex, copyin_error, - error); - LIN_SDT_PROBE1(futex, linux_sys_futex, return, error); - futex_put(f, wp); - return (error); - } - TIMESPEC_TO_TIMEVAL(&utv, &timeout); - error = itimerfix(&utv); - if (error) { - LIN_SDT_PROBE1(futex, linux_sys_futex, itimerfix_error, - error); - LIN_SDT_PROBE1(futex, linux_sys_futex, return, error); - futex_put(f, wp); - return (error); - } - if (clockrt) { - microtime(&ctv); - timevalsub(&utv, &ctv); - } else if (args->op == LINUX_FUTEX_WAIT_BITSET) { - microuptime(&ctv); - timevalsub(&utv, &ctv); - } - if (utv.tv_sec < 0) - timevalclear(&utv); - timeout_hz = tvtohz(&utv); - } else - timeout_hz = 0; - error = futex_wait(f, wp, timeout_hz, args->val3); break; @@ -943,29 +956,43 @@ linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args) case LINUX_FUTEX_LOCK_PI: /* not yet implemented */ - linux_msg(td, - "linux_sys_futex: " - "op LINUX_FUTEX_LOCK_PI not implemented\n"); - LIN_SDT_PROBE0(futex, linux_sys_futex, unimplemented_lock_pi); + pem = pem_find(td->td_proc); + if ((pem->flags & LINUX_XUNSUP_FUTEXPIOP) == 0) { + linux_msg(td, + "linux_sys_futex: " + "unsupported futex_pi op\n"); + pem->flags |= LINUX_XUNSUP_FUTEXPIOP; + LIN_SDT_PROBE0(futex, linux_sys_futex, + unimplemented_lock_pi); + } LIN_SDT_PROBE1(futex, linux_sys_futex, return, ENOSYS); return (ENOSYS); case LINUX_FUTEX_UNLOCK_PI: /* not yet implemented */ - linux_msg(td, - "linux_sys_futex: " - "op LINUX_FUTEX_UNLOCK_PI not implemented\n"); - LIN_SDT_PROBE0(futex, linux_sys_futex, unimplemented_unlock_pi); + pem = pem_find(td->td_proc); + if ((pem->flags & LINUX_XUNSUP_FUTEXPIOP) == 0) { + linux_msg(td, + "linux_sys_futex: " + "unsupported futex_pi op\n"); + pem->flags |= LINUX_XUNSUP_FUTEXPIOP; + LIN_SDT_PROBE0(futex, linux_sys_futex, + unimplemented_unlock_pi); + } LIN_SDT_PROBE1(futex, linux_sys_futex, return, ENOSYS); return (ENOSYS); case LINUX_FUTEX_TRYLOCK_PI: /* not yet implemented */ - linux_msg(td, - "linux_sys_futex: " - "op LINUX_FUTEX_TRYLOCK_PI not implemented\n"); - LIN_SDT_PROBE0(futex, linux_sys_futex, - unimplemented_trylock_pi); + pem = pem_find(td->td_proc); + if ((pem->flags & LINUX_XUNSUP_FUTEXPIOP) == 0) { + linux_msg(td, + "linux_sys_futex: " + "unsupported futex_pi op\n"); + pem->flags |= LINUX_XUNSUP_FUTEXPIOP; + LIN_SDT_PROBE0(futex, linux_sys_futex, + unimplemented_trylock_pi); + } LIN_SDT_PROBE1(futex, linux_sys_futex, return, ENOSYS); return (ENOSYS); @@ -977,12 +1004,12 @@ linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args) * Glibc versions prior to 2.3.3 fall back to FUTEX_WAKE when * FUTEX_REQUEUE returned EINVAL. */ - em = em_find(td->td_proc, EMUL_DONTLOCK); - if ((em->flags & LINUX_XDEPR_REQUEUEOP) == 0) { + pem = pem_find(td->td_proc); + if ((pem->flags & LINUX_XDEPR_REQUEUEOP) == 0) { linux_msg(td, "linux_sys_futex: " "unsupported futex_requeue op\n"); - em->flags |= LINUX_XDEPR_REQUEUEOP; + pem->flags |= LINUX_XDEPR_REQUEUEOP; LIN_SDT_PROBE0(futex, linux_sys_futex, deprecated_requeue); } @@ -992,21 +1019,29 @@ linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args) case LINUX_FUTEX_WAIT_REQUEUE_PI: /* not yet implemented */ - linux_msg(td, - "linux_sys_futex: " - "op FUTEX_WAIT_REQUEUE_PI not implemented\n"); - LIN_SDT_PROBE0(futex, linux_sys_futex, - unimplemented_wait_requeue_pi); + pem = pem_find(td->td_proc); + if ((pem->flags & LINUX_XUNSUP_FUTEXPIOP) == 0) { + linux_msg(td, + "linux_sys_futex: " + "unsupported futex_pi op\n"); + pem->flags |= LINUX_XUNSUP_FUTEXPIOP; + LIN_SDT_PROBE0(futex, linux_sys_futex, + unimplemented_wait_requeue_pi); + } LIN_SDT_PROBE1(futex, linux_sys_futex, return, ENOSYS); return (ENOSYS); case LINUX_FUTEX_CMP_REQUEUE_PI: /* not yet implemented */ - linux_msg(td, - "linux_sys_futex: " - "op LINUX_FUTEX_CMP_REQUEUE_PI not implemented\n"); - LIN_SDT_PROBE0(futex, linux_sys_futex, - unimplemented_cmp_requeue_pi); + pem = pem_find(td->td_proc); + if ((pem->flags & LINUX_XUNSUP_FUTEXPIOP) == 0) { + linux_msg(td, + "linux_sys_futex: " + "unsupported futex_pi op\n"); + pem->flags |= LINUX_XUNSUP_FUTEXPIOP; + LIN_SDT_PROBE0(futex, linux_sys_futex, + unimplemented_cmp_requeue_pi); + } LIN_SDT_PROBE1(futex, linux_sys_futex, return, ENOSYS); return (ENOSYS); @@ -1036,9 +1071,8 @@ linux_set_robust_list(struct thread *td, struct linux_set_robust_list_args *args return (EINVAL); } - em = em_find(td->td_proc, EMUL_DOLOCK); + em = em_find(td); em->robust_futexes = args->head; - EMUL_UNLOCK(&emul_lock); LIN_SDT_PROBE1(futex, linux_set_robust_list, return, 0); return (0); @@ -1050,29 +1084,36 @@ linux_get_robust_list(struct thread *td, struct linux_get_robust_list_args *args struct linux_emuldata *em; struct linux_robust_list_head *head; l_size_t len = sizeof(struct linux_robust_list_head); + struct thread *td2; int error = 0; LIN_SDT_PROBE2(futex, linux_get_robust_list, entry, td, args); if (!args->pid) { - em = em_find(td->td_proc, EMUL_DONTLOCK); + em = em_find(td); + KASSERT(em != NULL, ("get_robust_list: emuldata notfound.\n")); head = em->robust_futexes; } else { - struct proc *p; - - p = pfind(args->pid); - if (p == NULL) { + td2 = tdfind(args->pid, -1); + if (td2 == NULL) { LIN_SDT_PROBE1(futex, linux_get_robust_list, return, ESRCH); return (ESRCH); } + if (SV_PROC_ABI(td2->td_proc) != SV_ABI_LINUX) { + LIN_SDT_PROBE1(futex, linux_get_robust_list, return, + EPERM); + PROC_UNLOCK(td2->td_proc); + return (EPERM); + } - em = em_find(p, EMUL_DONTLOCK); + em = em_find(td2); + KASSERT(em != NULL, ("get_robust_list: emuldata notfound.\n")); /* XXX: ptrace? */ if (priv_check(td, PRIV_CRED_SETUID) || priv_check(td, PRIV_CRED_SETEUID) || - p_candebug(td, p)) { - PROC_UNLOCK(p); + p_candebug(td, td2->td_proc)) { + PROC_UNLOCK(td2->td_proc); LIN_SDT_PROBE1(futex, linux_get_robust_list, return, EPERM); @@ -1080,7 +1121,7 @@ linux_get_robust_list(struct thread *td, struct linux_get_robust_list_args *args } head = em->robust_futexes; - PROC_UNLOCK(p); + PROC_UNLOCK(td2->td_proc); } error = copyout(&len, args->len, sizeof(l_size_t)); @@ -1102,13 +1143,14 @@ linux_get_robust_list(struct thread *td, struct linux_get_robust_list_args *args } static int -handle_futex_death(struct proc *p, uint32_t *uaddr, unsigned int pi) +handle_futex_death(struct linux_emuldata *em, uint32_t *uaddr, + unsigned int pi) { uint32_t uval, nval, mval; struct futex *f; int error; - LIN_SDT_PROBE3(futex, handle_futex_death, entry, p, uaddr, pi); + LIN_SDT_PROBE3(futex, handle_futex_death, entry, em, uaddr, pi); retry: error = copyin(uaddr, &uval, 4); @@ -1117,7 +1159,7 @@ retry: LIN_SDT_PROBE1(futex, handle_futex_death, return, EFAULT); return (EFAULT); } - if ((uval & FUTEX_TID_MASK) == p->p_pid) { + if ((uval & FUTEX_TID_MASK) == em->em_tid) { mval = (uval & FUTEX_WAITERS) | FUTEX_OWNER_DIED; nval = casuword32(uaddr, uval, mval); @@ -1174,18 +1216,16 @@ fetch_robust_entry(struct linux_robust_list **entry, /* This walks the list of robust futexes releasing them. */ void -release_futexes(struct proc *p) +release_futexes(struct thread *td, struct linux_emuldata *em) { struct linux_robust_list_head *head = NULL; struct linux_robust_list *entry, *next_entry, *pending; unsigned int limit = 2048, pi, next_pi, pip; - struct linux_emuldata *em; l_long futex_offset; int rc, error; - LIN_SDT_PROBE1(futex, release_futexes, entry, p); + LIN_SDT_PROBE2(futex, release_futexes, entry, td, em); - em = em_find(p, EMUL_DONTLOCK); head = em->robust_futexes; if (head == NULL) { @@ -1215,7 +1255,7 @@ release_futexes(struct proc *p) rc = fetch_robust_entry(&next_entry, PTRIN(&entry->next), &next_pi); if (entry != pending) - if (handle_futex_death(p, + if (handle_futex_death(em, (uint32_t *)((caddr_t)entry + futex_offset), pi)) { LIN_SDT_PROBE0(futex, release_futexes, return); return; @@ -1235,7 +1275,7 @@ release_futexes(struct proc *p) } if (pending) - handle_futex_death(p, (uint32_t *)((caddr_t)pending + futex_offset), pip); + handle_futex_death(em, (uint32_t *)((caddr_t)pending + futex_offset), pip); LIN_SDT_PROBE0(futex, release_futexes, return); } diff --git a/sys/compat/linux/linux_futex.h b/sys/compat/linux/linux_futex.h index 0990daa..7922743 100644 --- a/sys/compat/linux/linux_futex.h +++ b/sys/compat/linux/linux_futex.h @@ -76,6 +76,7 @@ extern struct mtx futex_mtx; #define FUTEX_TID_MASK 0x3fffffff #define FUTEX_BITSET_MATCH_ANY 0xffffffff -void release_futexes(struct proc *); +void release_futexes(struct thread *, + struct linux_emuldata *); #endif /* !_LINUX_FUTEX_H */ diff --git a/sys/compat/linux/linux_getcwd.c b/sys/compat/linux/linux_getcwd.c index 1c7080d..da1c726 100644 --- a/sys/compat/linux/linux_getcwd.c +++ b/sys/compat/linux/linux_getcwd.c @@ -186,7 +186,7 @@ linux_getcwd_scandir(lvpp, uvpp, bpp, bufp, td) dirbuflen = DIRBLKSIZ; if (dirbuflen < va.va_blocksize) dirbuflen = va.va_blocksize; - dirbuf = malloc(dirbuflen, M_TEMP, M_WAITOK); + dirbuf = malloc(dirbuflen, M_LINUX, M_WAITOK); #if 0 unionread: @@ -274,7 +274,7 @@ unionread: out: vput(lvp); *lvpp = NULL; - free(dirbuf, M_TEMP); + free(dirbuf, M_LINUX); return error; } diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c index ab95e64..8858e2f 100644 --- a/sys/compat/linux/linux_ioctl.c +++ b/sys/compat/linux/linux_ioctl.c @@ -68,7 +68,6 @@ __FBSDID("$FreeBSD$"); #include <net/if.h> #include <net/if_dl.h> #include <net/if_types.h> -#include <net/vnet.h> #include <dev/usb/usb_ioctl.h> @@ -95,9 +94,6 @@ __FBSDID("$FreeBSD$"); CTASSERT(LINUX_IFNAMSIZ == IFNAMSIZ); -FEATURE(linuxulator_v4l, "V4L ioctl wrapper support in the linuxulator"); -FEATURE(linuxulator_v4l2, "V4L2 ioctl wrapper support in the linuxulator"); - static linux_ioctl_function_t linux_ioctl_cdrom; static linux_ioctl_function_t linux_ioctl_vfat; static linux_ioctl_function_t linux_ioctl_console; @@ -1980,8 +1976,6 @@ linux_ioctl_sound(struct thread *td, struct linux_ioctl_args *args) * Console related ioctls */ -#define ISSIGVALID(sig) ((sig) > 0 && (sig) < NSIG) - static int linux_ioctl_console(struct thread *td, struct linux_ioctl_args *args) { @@ -2064,8 +2058,16 @@ linux_ioctl_console(struct thread *td, struct linux_ioctl_args *args) struct vt_mode mode; if ((error = copyin((void *)args->arg, &mode, sizeof(mode)))) break; - if (!ISSIGVALID(mode.frsig) && ISSIGVALID(mode.acqsig)) - mode.frsig = mode.acqsig; + if (LINUX_SIG_VALID(mode.relsig)) + mode.relsig = linux_to_bsd_signal(mode.relsig); + else + mode.relsig = 0; + if (LINUX_SIG_VALID(mode.acqsig)) + mode.acqsig = linux_to_bsd_signal(mode.acqsig); + else + mode.acqsig = 0; + /* XXX. Linux ignores frsig and set it to 0. */ + mode.frsig = 0; if ((error = copyout(&mode, (void *)args->arg, sizeof(mode)))) break; args->cmd = VT_SETMODE; @@ -2108,34 +2110,6 @@ linux_ioctl_console(struct thread *td, struct linux_ioctl_args *args) #define IFP_IS_ETH(ifp) (ifp->if_type == IFT_ETHER) /* - * Interface function used by linprocfs (at the time of writing). It's not - * used by the Linuxulator itself. - */ -int -linux_ifname(struct ifnet *ifp, char *buffer, size_t buflen) -{ - struct ifnet *ifscan; - int ethno; - - IFNET_RLOCK_ASSERT(); - - /* Short-circuit non ethernet interfaces */ - if (!IFP_IS_ETH(ifp)) - return (strlcpy(buffer, ifp->if_xname, buflen)); - - /* Determine the (relative) unit number for ethernet interfaces */ - ethno = 0; - TAILQ_FOREACH(ifscan, &V_ifnet, if_link) { - if (ifscan == ifp) - return (snprintf(buffer, buflen, "eth%d", ethno)); - if (IFP_IS_ETH(ifscan)) - ethno++; - } - - return (0); -} - -/* * Translate a Linux interface name to a FreeBSD interface name, * and return the associated ifnet structure * bsdname and lxname need to be least IFNAMSIZ bytes long, but @@ -3621,9 +3595,16 @@ linux_ioctl(struct thread *td, struct linux_ioctl_args *args) sx_sunlock(&linux_ioctl_sx); fdrop(fp, td); - linux_msg(td, "ioctl fd=%d, cmd=0x%x ('%c',%d) is not implemented", - args->fd, (int)(args->cmd & 0xffff), - (int)(args->cmd & 0xff00) >> 8, (int)(args->cmd & 0xff)); + switch (args->cmd & 0xffff) { + case LINUX_BTRFS_IOC_CLONE: + return (ENOTSUP); + + default: + linux_msg(td, "ioctl fd=%d, cmd=0x%x ('%c',%d) is not implemented", + args->fd, (int)(args->cmd & 0xffff), + (int)(args->cmd & 0xff00) >> 8, (int)(args->cmd & 0xff)); + break; + } return (EINVAL); } diff --git a/sys/compat/linux/linux_ioctl.h b/sys/compat/linux/linux_ioctl.h index 3f63b21..873937d 100644 --- a/sys/compat/linux/linux_ioctl.h +++ b/sys/compat/linux/linux_ioctl.h @@ -581,13 +581,6 @@ #define LINUX_IOCTL_DRM_MAX 0x64ff /* - * This doesn't really belong here, but I can't think of a better - * place to put it. - */ -struct ifnet; -int linux_ifname(struct ifnet *, char *, size_t); - -/* * video */ #define LINUX_VIDIOCGCAP 0x7601 @@ -752,6 +745,12 @@ int linux_ifname(struct ifnet *, char *, size_t); #define FBSD_LUSB_MIN 0xffdd /* + * Linux btrfs clone operation + */ +#define LINUX_BTRFS_IOC_CLONE 0x9409 /* 0x40049409 */ + + +/* * Pluggable ioctl handlers */ struct linux_ioctl_args; diff --git a/sys/compat/linux/linux_ipc.c b/sys/compat/linux/linux_ipc.c index 1237edc..7a92c6a 100644 --- a/sys/compat/linux/linux_ipc.c +++ b/sys/compat/linux/linux_ipc.c @@ -117,16 +117,6 @@ bsd_to_linux_shm_info( struct shm_info *bpp, struct l_shm_info *lpp) lpp->swap_successes = bpp->swap_successes ; } -struct l_ipc_perm { - l_key_t key; - l_uid16_t uid; - l_gid16_t gid; - l_uid16_t cuid; - l_gid16_t cgid; - l_ushort mode; - l_ushort seq; -}; - static void linux_to_bsd_ipc_perm(struct l_ipc_perm *lpp, struct ipc_perm *bpp) { diff --git a/sys/compat/linux/linux_ipc.h b/sys/compat/linux/linux_ipc.h index f1531ba..8e9c050 100644 --- a/sys/compat/linux/linux_ipc.h +++ b/sys/compat/linux/linux_ipc.h @@ -82,7 +82,7 @@ #define LINUX_IPC_64 0x0100 /* New version (support 32-bit UIDs, bigger message sizes, etc. */ -#if defined(__i386__) || defined(__amd64__) +#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) struct linux_msgctl_args { @@ -177,6 +177,6 @@ int linux_shmctl(struct thread *, struct linux_shmctl_args *); int linux_shmdt(struct thread *, struct linux_shmdt_args *); int linux_shmget(struct thread *, struct linux_shmget_args *); -#endif /* __i386__ || __amd64__ */ +#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ #endif /* _LINUX_IPC_H_ */ diff --git a/sys/compat/linux/linux_mib.c b/sys/compat/linux/linux_mib.c index cf64599..396344b 100644 --- a/sys/compat/linux/linux_mib.c +++ b/sys/compat/linux/linux_mib.c @@ -29,9 +29,6 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); -#include "opt_compat.h" -#include "opt_kdtrace.h" - #include <sys/param.h> #include <sys/kernel.h> #include <sys/sdt.h> @@ -42,85 +39,11 @@ __FBSDID("$FreeBSD$"); #include <sys/mount.h> #include <sys/jail.h> #include <sys/lock.h> -#include <sys/mutex.h> #include <sys/sx.h> -#ifdef COMPAT_LINUX32 -#include <machine/../linux32/linux.h> -#else -#include <machine/../linux/linux.h> -#endif -#include <compat/linux/linux_dtrace.h> #include <compat/linux/linux_mib.h> #include <compat/linux/linux_misc.h> -/* DTrace init */ -LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE); - -/** - * DTrace probes in this module. - */ -LIN_SDT_PROBE_DEFINE0(mib, linux_sysctl_osname, entry); -LIN_SDT_PROBE_DEFINE1(mib, linux_sysctl_osname, sysctl_string_error, "int"); -LIN_SDT_PROBE_DEFINE1(mib, linux_sysctl_osname, return, "int"); - -LIN_SDT_PROBE_DEFINE0(mib, linux_sysctl_osrelease, entry); -LIN_SDT_PROBE_DEFINE1(mib, linux_sysctl_osrelease, sysctl_string_error, "int"); -LIN_SDT_PROBE_DEFINE1(mib, linux_sysctl_osrelease, return, "int"); -LIN_SDT_PROBE_DEFINE0(mib, linux_sysctl_oss_version, entry); -LIN_SDT_PROBE_DEFINE1(mib, linux_sysctl_oss_version, sysctl_string_error, - "int"); -LIN_SDT_PROBE_DEFINE1(mib, linux_sysctl_oss_version, return, "int"); -LIN_SDT_PROBE_DEFINE2(mib, linux_map_osrel, entry, "char *", "int *"); -LIN_SDT_PROBE_DEFINE1(mib, linux_map_osrel, return, "int"); -LIN_SDT_PROBE_DEFINE2(mib, linux_get_prison, entry, "struct prison *", - "struct prison **"); -LIN_SDT_PROBE_DEFINE1(mib, linux_get_prison, return, "struct linux_prison *"); -LIN_SDT_PROBE_DEFINE2(mib, linux_alloc_prison, entry, "struct prison *", - "struct linux_prison **"); -LIN_SDT_PROBE_DEFINE1(mib, linux_alloc_prison, return, "int"); -LIN_SDT_PROBE_DEFINE2(mib, linux_prison_create, entry, "void *", "void *"); -LIN_SDT_PROBE_DEFINE1(mib, linux_prison_create, vfs_copyopt_error, "int"); -LIN_SDT_PROBE_DEFINE1(mib, linux_prison_create, return, "int"); -LIN_SDT_PROBE_DEFINE2(mib, linux_prison_check, entry, "void *", "void *"); -LIN_SDT_PROBE_DEFINE1(mib, linux_prison_check, vfs_copyopt_error, "int"); -LIN_SDT_PROBE_DEFINE1(mib, linux_prison_check, vfs_getopt_error, "int"); -LIN_SDT_PROBE_DEFINE1(mib, linux_prison_check, return, "int"); -LIN_SDT_PROBE_DEFINE2(mib, linux_prison_set, entry, "void *", "void *"); -LIN_SDT_PROBE_DEFINE1(mib, linux_prison_set, vfs_copyopt_error, "int"); -LIN_SDT_PROBE_DEFINE1(mib, linux_prison_set, vfs_getopt_error, "int"); -LIN_SDT_PROBE_DEFINE1(mib, linux_prison_set, return, "int"); -LIN_SDT_PROBE_DEFINE2(mib, linux_prison_get, entry, "void *", "void *"); -LIN_SDT_PROBE_DEFINE1(mib, linux_prison_get, vfs_setopt_error, "int"); -LIN_SDT_PROBE_DEFINE1(mib, linux_prison_get, vfs_setopts_error, "int"); -LIN_SDT_PROBE_DEFINE1(mib, linux_prison_get, return, "int"); -LIN_SDT_PROBE_DEFINE1(mib, linux_prison_destructor, entry, "void *"); -LIN_SDT_PROBE_DEFINE0(mib, linux_prison_destructor, return); -LIN_SDT_PROBE_DEFINE0(mib, linux_osd_jail_register, entry); -LIN_SDT_PROBE_DEFINE0(mib, linux_osd_jail_register, return); -LIN_SDT_PROBE_DEFINE0(mib, linux_osd_jail_deregister, entry); -LIN_SDT_PROBE_DEFINE0(mib, linux_osd_jail_deregister, return); -LIN_SDT_PROBE_DEFINE2(mib, linux_get_osname, entry, "struct thread *", - "char *"); -LIN_SDT_PROBE_DEFINE0(mib, linux_get_osname, return); -LIN_SDT_PROBE_DEFINE2(mib, linux_set_osname, entry, "struct thread *", - "char *"); -LIN_SDT_PROBE_DEFINE1(mib, linux_set_osname, return, "int"); -LIN_SDT_PROBE_DEFINE2(mib, linux_get_osrelease, entry, "struct thread *", - "char *"); -LIN_SDT_PROBE_DEFINE0(mib, linux_get_osrelease, return); -LIN_SDT_PROBE_DEFINE1(mib, linux_kernver, entry, "struct thread *"); -LIN_SDT_PROBE_DEFINE1(mib, linux_kernver, return, "int"); -LIN_SDT_PROBE_DEFINE2(mib, linux_set_osrelease, entry, "struct thread *", - "char *"); -LIN_SDT_PROBE_DEFINE1(mib, linux_set_osrelease, return, "int"); -LIN_SDT_PROBE_DEFINE1(mib, linux_get_oss_version, entry, "struct thread *"); -LIN_SDT_PROBE_DEFINE1(mib, linux_get_oss_version, return, "int"); - -LIN_SDT_PROBE_DEFINE2(mib, linux_set_oss_version, entry, "struct thread *", - "int"); -LIN_SDT_PROBE_DEFINE1(mib, linux_set_oss_version, return, "int"); - struct linux_prison { char pr_osname[LINUX_MAX_UTSNAME]; char pr_osrelease[LINUX_MAX_UTSNAME]; @@ -130,15 +53,14 @@ struct linux_prison { static struct linux_prison lprison0 = { .pr_osname = "Linux", - .pr_osrelease = "2.6.18", + .pr_osrelease = LINUX_VERSION_STR, .pr_oss_version = 0x030600, - .pr_osrel = 2006018 + .pr_osrel = LINUX_VERSION_CODE }; static unsigned linux_osd_jail_slot; -static SYSCTL_NODE(_compat, OID_AUTO, linux, CTLFLAG_RW, 0, - "Linux mode"); +SYSCTL_NODE(_compat, OID_AUTO, linux, CTLFLAG_RW, 0, "Linux mode"); static int linux_set_osname(struct thread *td, char *osname); static int linux_set_osrelease(struct thread *td, char *osrelease); @@ -150,19 +72,12 @@ linux_sysctl_osname(SYSCTL_HANDLER_ARGS) char osname[LINUX_MAX_UTSNAME]; int error; - LIN_SDT_PROBE0(mib, linux_sysctl_osname, entry); - linux_get_osname(req->td, osname); error = sysctl_handle_string(oidp, osname, LINUX_MAX_UTSNAME, req); - if (error != 0 || req->newptr == NULL) { - LIN_SDT_PROBE1(mib, linux_sysctl_osname, sysctl_string_error, - error); - LIN_SDT_PROBE1(mib, linux_sysctl_osname, return, error); + if (error != 0 || req->newptr == NULL) return (error); - } error = linux_set_osname(req->td, osname); - LIN_SDT_PROBE1(mib, linux_sysctl_osname, return, error); return (error); } @@ -177,19 +92,12 @@ linux_sysctl_osrelease(SYSCTL_HANDLER_ARGS) char osrelease[LINUX_MAX_UTSNAME]; int error; - LIN_SDT_PROBE0(mib, linux_sysctl_osrelease, entry); - linux_get_osrelease(req->td, osrelease); error = sysctl_handle_string(oidp, osrelease, LINUX_MAX_UTSNAME, req); - if (error != 0 || req->newptr == NULL) { - LIN_SDT_PROBE1(mib, linux_sysctl_osrelease, sysctl_string_error, - error); - LIN_SDT_PROBE1(mib, linux_sysctl_osrelease, return, error); + if (error != 0 || req->newptr == NULL) return (error); - } error = linux_set_osrelease(req->td, osrelease); - LIN_SDT_PROBE1(mib, linux_sysctl_osrelease, return, error); return (error); } @@ -204,19 +112,12 @@ linux_sysctl_oss_version(SYSCTL_HANDLER_ARGS) int oss_version; int error; - LIN_SDT_PROBE0(mib, linux_sysctl_oss_version, entry); - oss_version = linux_get_oss_version(req->td); error = sysctl_handle_int(oidp, &oss_version, 0, req); - if (error != 0 || req->newptr == NULL) { - LIN_SDT_PROBE1(mib, linux_sysctl_oss_version, - sysctl_string_error, error); - LIN_SDT_PROBE1(mib, linux_sysctl_oss_version, return, error); + if (error != 0 || req->newptr == NULL) return (error); - } error = linux_set_oss_version(req->td, oss_version); - LIN_SDT_PROBE1(mib, linux_sysctl_oss_version, return, error); return (error); } @@ -234,37 +135,26 @@ linux_map_osrel(char *osrelease, int *osrel) char *sep, *eosrelease; int len, v0, v1, v2, v; - LIN_SDT_PROBE2(mib, linux_map_osrel, entry, osrelease, osrel); - len = strlen(osrelease); eosrelease = osrelease + len; v0 = strtol(osrelease, &sep, 10); - if (osrelease == sep || sep + 1 >= eosrelease || *sep != '.') { - LIN_SDT_PROBE1(mib, linux_map_osrel, return, EINVAL); + if (osrelease == sep || sep + 1 >= eosrelease || *sep != '.') return (EINVAL); - } osrelease = sep + 1; v1 = strtol(osrelease, &sep, 10); - if (osrelease == sep || sep + 1 >= eosrelease || *sep != '.') { - LIN_SDT_PROBE1(mib, linux_map_osrel, return, EINVAL); + if (osrelease == sep || sep + 1 >= eosrelease || *sep != '.') return (EINVAL); - } osrelease = sep + 1; v2 = strtol(osrelease, &sep, 10); - if (osrelease == sep || sep != eosrelease) { - LIN_SDT_PROBE1(mib, linux_map_osrel, return, EINVAL); + if (osrelease == sep || sep != eosrelease) return (EINVAL); - } v = v0 * 1000000 + v1 * 1000 + v2; - if (v < 1000000) { - LIN_SDT_PROBE1(mib, linux_map_osrel, return, EINVAL); + if (v < 1000000) return (EINVAL); - } *osrel = v; - LIN_SDT_PROBE1(mib, linux_map_osrel, return, 0); return (0); } @@ -278,8 +168,6 @@ linux_find_prison(struct prison *spr, struct prison **prp) struct prison *pr; struct linux_prison *lpr; - LIN_SDT_PROBE2(mib, linux_get_prison, entry, spr, prp); - if (!linux_osd_jail_slot) /* In case osd_register failed. */ spr = &prison0; @@ -294,7 +182,6 @@ linux_find_prison(struct prison *spr, struct prison **prp) } *prp = pr; - LIN_SDT_PROBE1(mib, linux_get_prison, return, lpr); return (lpr); } @@ -309,8 +196,6 @@ linux_alloc_prison(struct prison *pr, struct linux_prison **lprp) struct linux_prison *lpr, *nlpr; int error; - LIN_SDT_PROBE2(mib, linux_alloc_prison, entry, pr, lprp); - /* If this prison already has Linux info, return that. */ error = 0; lpr = linux_find_prison(pr, &ppr); @@ -344,7 +229,6 @@ linux_alloc_prison(struct prison *pr, struct linux_prison **lprp) else mtx_unlock(&pr->pr_mtx); - LIN_SDT_PROBE1(mib, linux_alloc_prison, return, error); return (error); } @@ -356,26 +240,16 @@ linux_prison_create(void *obj, void *data) { struct prison *pr = obj; struct vfsoptlist *opts = data; - int jsys, error; - - LIN_SDT_PROBE2(mib, linux_prison_create, entry, obj, data); + int jsys; - error = vfs_copyopt(opts, "linux", &jsys, sizeof(jsys)); - if (error != 0) { - LIN_SDT_PROBE1(mib, linux_prison_create, vfs_copyopt_error, - error); - } else if (jsys == JAIL_SYS_INHERIT) { - LIN_SDT_PROBE1(mib, linux_prison_create, return, 0); + if (vfs_copyopt(opts, "linux", &jsys, sizeof(jsys)) == 0 && + jsys == JAIL_SYS_INHERIT) return (0); - } /* * Inherit a prison's initial values from its parent * (different from JAIL_SYS_INHERIT which also inherits changes). */ - error = linux_alloc_prison(pr, NULL); - - LIN_SDT_PROBE1(mib, linux_prison_create, return, error); - return (error); + return (linux_alloc_prison(pr, NULL)); } static int @@ -385,80 +259,46 @@ linux_prison_check(void *obj __unused, void *data) char *osname, *osrelease; int error, jsys, len, osrel, oss_version; - LIN_SDT_PROBE2(mib, linux_prison_check, entry, obj, data); - /* Check that the parameters are correct. */ error = vfs_copyopt(opts, "linux", &jsys, sizeof(jsys)); - if (error != 0) { - LIN_SDT_PROBE1(mib, linux_prison_check, vfs_copyopt_error, - error); - } if (error != ENOENT) { - if (error != 0) { - LIN_SDT_PROBE1(mib, linux_prison_check, return, error); + if (error != 0) return (error); - } - if (jsys != JAIL_SYS_NEW && jsys != JAIL_SYS_INHERIT) { - LIN_SDT_PROBE1(mib, linux_prison_check, return, EINVAL); + if (jsys != JAIL_SYS_NEW && jsys != JAIL_SYS_INHERIT) return (EINVAL); - } } error = vfs_getopt(opts, "linux.osname", (void **)&osname, &len); - if (error != 0) { - LIN_SDT_PROBE1(mib, linux_prison_check, vfs_getopt_error, - error); - } if (error != ENOENT) { - if (error != 0) { - LIN_SDT_PROBE1(mib, linux_prison_check, return, error); + if (error != 0) return (error); - } - if (len == 0 || osname[len - 1] != '\0') { - LIN_SDT_PROBE1(mib, linux_prison_check, return, EINVAL); + if (len == 0 || osname[len - 1] != '\0') return (EINVAL); - } if (len > LINUX_MAX_UTSNAME) { vfs_opterror(opts, "linux.osname too long"); - LIN_SDT_PROBE1(mib, linux_prison_check, return, - ENAMETOOLONG); return (ENAMETOOLONG); } } error = vfs_getopt(opts, "linux.osrelease", (void **)&osrelease, &len); - if (error != 0) { - LIN_SDT_PROBE1(mib, linux_prison_check, vfs_getopt_error, - error); - } if (error != ENOENT) { - if (error != 0) { - LIN_SDT_PROBE1(mib, linux_prison_check, return, error); + if (error != 0) return (error); - } - if (len == 0 || osrelease[len - 1] != '\0') { - LIN_SDT_PROBE1(mib, linux_prison_check, return, EINVAL); + if (len == 0 || osrelease[len - 1] != '\0') return (EINVAL); - } if (len > LINUX_MAX_UTSNAME) { vfs_opterror(opts, "linux.osrelease too long"); - LIN_SDT_PROBE1(mib, linux_prison_check, return, - ENAMETOOLONG); return (ENAMETOOLONG); } error = linux_map_osrel(osrelease, &osrel); if (error != 0) { vfs_opterror(opts, "linux.osrelease format error"); - LIN_SDT_PROBE1(mib, linux_prison_check, return, error); return (error); } } error = vfs_copyopt(opts, "linux.oss_version", &oss_version, sizeof(oss_version)); - if (error != 0) - LIN_SDT_PROBE1(mib, linux_prison_check, vfs_copyopt_error, error); if (error == ENOENT) error = 0; - LIN_SDT_PROBE1(mib, linux_prison_check, return, error); return (error); } @@ -471,32 +311,22 @@ linux_prison_set(void *obj, void *data) char *osname, *osrelease; int error, gotversion, jsys, len, oss_version; - LIN_SDT_PROBE2(mib, linux_prison_set, entry, obj, data); - /* Set the parameters, which should be correct. */ error = vfs_copyopt(opts, "linux", &jsys, sizeof(jsys)); - if (error != 0) - LIN_SDT_PROBE1(mib, linux_prison_set, vfs_copyopt_error, error); if (error == ENOENT) jsys = -1; error = vfs_getopt(opts, "linux.osname", (void **)&osname, &len); - if (error != 0) - LIN_SDT_PROBE1(mib, linux_prison_set, vfs_getopt_error, error); if (error == ENOENT) osname = NULL; else jsys = JAIL_SYS_NEW; error = vfs_getopt(opts, "linux.osrelease", (void **)&osrelease, &len); - if (error != 0) - LIN_SDT_PROBE1(mib, linux_prison_set, vfs_getopt_error, error); if (error == ENOENT) osrelease = NULL; else jsys = JAIL_SYS_NEW; error = vfs_copyopt(opts, "linux.oss_version", &oss_version, sizeof(oss_version)); - if (error != 0) - LIN_SDT_PROBE1(mib, linux_prison_set, vfs_copyopt_error, error); if (error == ENOENT) gotversion = 0; else { @@ -518,15 +348,12 @@ linux_prison_set(void *obj, void *data) error = linux_alloc_prison(pr, &lpr); if (error) { mtx_unlock(&pr->pr_mtx); - LIN_SDT_PROBE1(mib, linux_prison_set, return, error); return (error); } if (osrelease) { error = linux_map_osrel(osrelease, &lpr->pr_osrel); if (error) { mtx_unlock(&pr->pr_mtx); - LIN_SDT_PROBE1(mib, linux_prison_set, return, - error); return (error); } strlcpy(lpr->pr_osrelease, osrelease, @@ -539,7 +366,6 @@ linux_prison_set(void *obj, void *data) mtx_unlock(&pr->pr_mtx); } - LIN_SDT_PROBE1(mib, linux_prison_set, return, 0); return (0); } @@ -562,74 +388,44 @@ linux_prison_get(void *obj, void *data) static int version0; - LIN_SDT_PROBE2(mib, linux_prison_get, entry, obj, data); - /* See if this prison is the one with the Linux info. */ lpr = linux_find_prison(pr, &ppr); i = (ppr == pr) ? JAIL_SYS_NEW : JAIL_SYS_INHERIT; error = vfs_setopt(opts, "linux", &i, sizeof(i)); - if (error != 0) { - LIN_SDT_PROBE1(mib, linux_prison_get, vfs_setopt_error, error); - if (error != ENOENT) - goto done; - } + if (error != 0 && error != ENOENT) + goto done; if (i) { error = vfs_setopts(opts, "linux.osname", lpr->pr_osname); - if (error != 0) { - LIN_SDT_PROBE1(mib, linux_prison_get, vfs_setopts_error, - error); - if (error != ENOENT) - goto done; - } + if (error != 0 && error != ENOENT) + goto done; error = vfs_setopts(opts, "linux.osrelease", lpr->pr_osrelease); - if (error != 0) { - LIN_SDT_PROBE1(mib, linux_prison_get, vfs_setopts_error, - error); - if (error != ENOENT) - goto done; - } + if (error != 0 && error != ENOENT) + goto done; error = vfs_setopt(opts, "linux.oss_version", &lpr->pr_oss_version, sizeof(lpr->pr_oss_version)); - if (error != 0) { - LIN_SDT_PROBE1(mib, linux_prison_get, vfs_setopt_error, - error); - if(error != ENOENT) - goto done; - } + if (error != 0 && error != ENOENT) + goto done; } else { /* * If this prison is inheriting its Linux info, report * empty/zero parameters. */ error = vfs_setopts(opts, "linux.osname", ""); - if (error != 0) { - LIN_SDT_PROBE1(mib, linux_prison_get, vfs_setopts_error, - error); - if(error != ENOENT) - goto done; - } + if (error != 0 && error != ENOENT) + goto done; error = vfs_setopts(opts, "linux.osrelease", ""); - if (error != 0) { - LIN_SDT_PROBE1(mib, linux_prison_get, vfs_setopts_error, - error); - if(error != ENOENT) - goto done; - } + if (error != 0 && error != ENOENT) + goto done; error = vfs_setopt(opts, "linux.oss_version", &version0, sizeof(lpr->pr_oss_version)); - if (error != 0) { - LIN_SDT_PROBE1(mib, linux_prison_get, vfs_setopt_error, - error); - if(error != ENOENT) - goto done; - } + if (error != 0 && error != ENOENT) + goto done; } error = 0; done: mtx_unlock(&ppr->pr_mtx); - LIN_SDT_PROBE1(mib, linux_prison_get, return, error); return (error); } @@ -637,9 +433,7 @@ static void linux_prison_destructor(void *data) { - LIN_SDT_PROBE1(mib, linux_prison_destructor, entry, data); free(data, M_PRISON); - LIN_SDT_PROBE0(mib, linux_prison_destructor, return); } void @@ -653,8 +447,6 @@ linux_osd_jail_register(void) [PR_METHOD_CHECK] = linux_prison_check }; - LIN_SDT_PROBE0(mib, linux_osd_jail_register, entry); - linux_osd_jail_slot = osd_jail_register(linux_prison_destructor, methods); if (linux_osd_jail_slot > 0) { @@ -664,20 +456,14 @@ linux_osd_jail_register(void) (void)linux_alloc_prison(pr, NULL); sx_xunlock(&allprison_lock); } - - LIN_SDT_PROBE0(mib, linux_osd_jail_register, return); } void linux_osd_jail_deregister(void) { - LIN_SDT_PROBE0(mib, linux_osd_jail_register, entry); - if (linux_osd_jail_slot) osd_jail_deregister(linux_osd_jail_slot); - - LIN_SDT_PROBE0(mib, linux_osd_jail_register, return); } void @@ -686,13 +472,9 @@ linux_get_osname(struct thread *td, char *dst) struct prison *pr; struct linux_prison *lpr; - LIN_SDT_PROBE2(mib, linux_get_osname, entry, td, dst); - lpr = linux_find_prison(td->td_ucred->cr_prison, &pr); bcopy(lpr->pr_osname, dst, LINUX_MAX_UTSNAME); mtx_unlock(&pr->pr_mtx); - - LIN_SDT_PROBE0(mib, linux_get_osname, return); } static int @@ -701,13 +483,10 @@ linux_set_osname(struct thread *td, char *osname) struct prison *pr; struct linux_prison *lpr; - LIN_SDT_PROBE2(mib, linux_set_osname, entry, td, osname); - lpr = linux_find_prison(td->td_ucred->cr_prison, &pr); strlcpy(lpr->pr_osname, osname, LINUX_MAX_UTSNAME); mtx_unlock(&pr->pr_mtx); - LIN_SDT_PROBE1(mib, linux_set_osname, return, 0); return (0); } @@ -717,13 +496,9 @@ linux_get_osrelease(struct thread *td, char *dst) struct prison *pr; struct linux_prison *lpr; - LIN_SDT_PROBE2(mib, linux_get_osrelease, entry, td, dst); - lpr = linux_find_prison(td->td_ucred->cr_prison, &pr); bcopy(lpr->pr_osrelease, dst, LINUX_MAX_UTSNAME); mtx_unlock(&pr->pr_mtx); - - LIN_SDT_PROBE0(mib, linux_get_osrelease, return); } int @@ -733,13 +508,10 @@ linux_kernver(struct thread *td) struct linux_prison *lpr; int osrel; - LIN_SDT_PROBE1(mib, linux_kernver, entry, td); - lpr = linux_find_prison(td->td_ucred->cr_prison, &pr); osrel = lpr->pr_osrel; mtx_unlock(&pr->pr_mtx); - LIN_SDT_PROBE1(mib, linux_kernver, return, osrel); return (osrel); } @@ -750,15 +522,12 @@ linux_set_osrelease(struct thread *td, char *osrelease) struct linux_prison *lpr; int error; - LIN_SDT_PROBE2(mib, linux_set_osrelease, entry, td, osrelease); - lpr = linux_find_prison(td->td_ucred->cr_prison, &pr); error = linux_map_osrel(osrelease, &lpr->pr_osrel); if (error == 0) strlcpy(lpr->pr_osrelease, osrelease, LINUX_MAX_UTSNAME); mtx_unlock(&pr->pr_mtx); - LIN_SDT_PROBE1(mib, linux_set_osrelease, return, error); return (error); } @@ -769,13 +538,10 @@ linux_get_oss_version(struct thread *td) struct linux_prison *lpr; int version; - LIN_SDT_PROBE1(mib, linux_get_oss_version, entry, td); - lpr = linux_find_prison(td->td_ucred->cr_prison, &pr); version = lpr->pr_oss_version; mtx_unlock(&pr->pr_mtx); - LIN_SDT_PROBE1(mib, linux_get_oss_version, return, version); return (version); } @@ -785,74 +551,9 @@ linux_set_oss_version(struct thread *td, int oss_version) struct prison *pr; struct linux_prison *lpr; - LIN_SDT_PROBE2(mib, linux_set_oss_version, entry, td, oss_version); - lpr = linux_find_prison(td->td_ucred->cr_prison, &pr); lpr->pr_oss_version = oss_version; mtx_unlock(&pr->pr_mtx); - LIN_SDT_PROBE1(mib, linux_set_oss_version, return, 0); return (0); } - -#if defined(DEBUG) || defined(KTR) -/* XXX: can be removed when every ldebug(...) and KTR stuff are removed. */ - -u_char linux_debug_map[howmany(LINUX_SYS_MAXSYSCALL, sizeof(u_char))]; - -static int -linux_debug(int syscall, int toggle, int global) -{ - - if (global) { - char c = toggle ? 0 : 0xff; - - memset(linux_debug_map, c, sizeof(linux_debug_map)); - return (0); - } - if (syscall < 0 || syscall >= LINUX_SYS_MAXSYSCALL) - return (EINVAL); - if (toggle) - clrbit(linux_debug_map, syscall); - else - setbit(linux_debug_map, syscall); - return (0); -} - -/* - * Usage: sysctl linux.debug=<syscall_nr>.<0/1> - * - * E.g.: sysctl linux.debug=21.0 - * - * As a special case, syscall "all" will apply to all syscalls globally. - */ -#define LINUX_MAX_DEBUGSTR 16 -static int -linux_sysctl_debug(SYSCTL_HANDLER_ARGS) -{ - char value[LINUX_MAX_DEBUGSTR], *p; - int error, sysc, toggle; - int global = 0; - - value[0] = '\0'; - error = sysctl_handle_string(oidp, value, LINUX_MAX_DEBUGSTR, req); - if (error || req->newptr == NULL) - return (error); - for (p = value; *p != '\0' && *p != '.'; p++); - if (*p == '\0') - return (EINVAL); - *p++ = '\0'; - sysc = strtol(value, NULL, 0); - toggle = strtol(p, NULL, 0); - if (strcmp(value, "all") == 0) - global = 1; - error = linux_debug(sysc, toggle, global); - return (error); -} - -SYSCTL_PROC(_compat_linux, OID_AUTO, debug, - CTLTYPE_STRING | CTLFLAG_RW, - 0, 0, linux_sysctl_debug, "A", - "Linux debugging control"); - -#endif /* DEBUG || KTR */ diff --git a/sys/compat/linux/linux_mib.h b/sys/compat/linux/linux_mib.h index e8eedf9..80b6c97 100644 --- a/sys/compat/linux/linux_mib.h +++ b/sys/compat/linux/linux_mib.h @@ -31,6 +31,10 @@ #ifndef _LINUX_MIB_H_ #define _LINUX_MIB_H_ +#ifdef SYSCTL_DECL +SYSCTL_DECL(_compat_linux); +#endif + void linux_osd_jail_register(void); void linux_osd_jail_deregister(void); @@ -42,8 +46,19 @@ int linux_get_oss_version(struct thread *td); int linux_kernver(struct thread *td); -#define LINUX_KERNVER_2004000 2004000 -#define LINUX_KERNVER_2006000 2006000 +#define LINUX_KVERSION 2 +#define LINUX_KPATCHLEVEL 6 +#define LINUX_KSUBLEVEL 32 + +#define LINUX_KERNVER(a,b,c) (((a) << 16) + ((b) << 8) + (c)) +#define LINUX_VERSION_CODE LINUX_KERNVER(LINUX_KVERSION, \ + LINUX_KPATCHLEVEL, LINUX_KSUBLEVEL) +#define LINUX_KERNVERSTR(x) #x +#define LINUX_XKERNVERSTR(x) LINUX_KERNVERSTR(x) +#define LINUX_VERSION_STR LINUX_XKERNVERSTR(LINUX_KVERSION.LINUX_KPATCHLEVEL.LINUX_KSUBLEVEL) + +#define LINUX_KERNVER_2004000 LINUX_KERNVER(2,4,0) +#define LINUX_KERNVER_2006000 LINUX_KERNVER(2,6,0) #define linux_use26(t) (linux_kernver(t) >= LINUX_KERNVER_2006000) diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index ac2384c..d87d786 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -89,21 +89,24 @@ __FBSDID("$FreeBSD$"); #include <compat/linux/linux_file.h> #include <compat/linux/linux_mib.h> #include <compat/linux/linux_signal.h> +#include <compat/linux/linux_timer.h> #include <compat/linux/linux_util.h> #include <compat/linux/linux_sysproto.h> #include <compat/linux/linux_emul.h> #include <compat/linux/linux_misc.h> -/* DTrace init */ -LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE); - -/* Linuxulator-global DTrace probes */ -LIN_SDT_PROBE_DECLARE(locks, emul_lock, locked); -LIN_SDT_PROBE_DECLARE(locks, emul_lock, unlock); -LIN_SDT_PROBE_DECLARE(locks, emul_shared_rlock, locked); -LIN_SDT_PROBE_DECLARE(locks, emul_shared_rlock, unlock); -LIN_SDT_PROBE_DECLARE(locks, emul_shared_wlock, locked); -LIN_SDT_PROBE_DECLARE(locks, emul_shared_wlock, unlock); +/** + * Special DTrace provider for the linuxulator. + * + * In this file we define the provider for the entire linuxulator. All + * modules (= files of the linuxulator) use it. + * + * We define a different name depending on the emulated bitsize, see + * ../../<ARCH>/linux{,32}/linux.h, e.g.: + * native bitsize = linuxulator + * amd64, 32bit emulation = linuxulator32 + */ +LIN_SDT_PROVIDER_DEFINE(LINUX_DTRACE); int stclohz; /* Statistics clock frequency */ @@ -130,6 +133,15 @@ struct l_sysinfo { l_uint mem_unit; char _f[20-2*sizeof(l_long)-sizeof(l_int)]; /* padding */ }; + +struct l_pselect6arg { + l_uintptr_t ss; + l_size_t ss_len; +}; + +static int linux_utimensat_nsec_valid(l_long); + + int linux_sysinfo(struct thread *td, struct linux_sysinfo_args *args) { @@ -524,7 +536,7 @@ linux_select(struct thread *td, struct linux_select_args *args) tvp = NULL; error = kern_select(td, args->nfds, args->readfds, args->writefds, - args->exceptfds, tvp, sizeof(l_int) * 8); + args->exceptfds, tvp, LINUX_NFDBITS); #ifdef DEBUG if (ldebug(select)) @@ -691,9 +703,9 @@ linux_times(struct thread *td, struct linux_times_args *args) if (args->buf != NULL) { p = td->td_proc; PROC_LOCK(p); - PROC_SLOCK(p); + PROC_STATLOCK(p); calcru(p, &utime, &stime); - PROC_SUNLOCK(p); + PROC_STATUNLOCK(p); calccru(p, &cutime, &cstime); PROC_UNLOCK(p); @@ -739,12 +751,11 @@ linux_newuname(struct thread *td, struct linux_newuname_args *args) *p = '\0'; break; } - strlcpy(utsname.machine, linux_platform, LINUX_MAX_UTSNAME); + strlcpy(utsname.machine, linux_kplatform, LINUX_MAX_UTSNAME); return (copyout(&utsname, args->buf, sizeof(utsname))); } -#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) struct l_utimbuf { l_time_t l_actime; l_time_t l_modtime; @@ -815,6 +826,98 @@ linux_utimes(struct thread *td, struct linux_utimes_args *args) return (error); } +static int +linux_utimensat_nsec_valid(l_long nsec) +{ + + if (nsec == LINUX_UTIME_OMIT || nsec == LINUX_UTIME_NOW) + return (0); + if (nsec >= 0 && nsec <= 999999999) + return (0); + return (1); +} + +int +linux_utimensat(struct thread *td, struct linux_utimensat_args *args) +{ + struct l_timespec l_times[2]; + struct timespec times[2], *timesp = NULL; + char *path = NULL; + int error, dfd, flags = 0; + + dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd; + +#ifdef DEBUG + if (ldebug(utimensat)) + printf(ARGS(utimensat, "%d, *"), dfd); +#endif + + if (args->flags & ~LINUX_AT_SYMLINK_NOFOLLOW) + return (EINVAL); + + if (args->times != NULL) { + error = copyin(args->times, l_times, sizeof(l_times)); + if (error != 0) + return (error); + + if (linux_utimensat_nsec_valid(l_times[0].tv_nsec) != 0 || + linux_utimensat_nsec_valid(l_times[1].tv_nsec) != 0) + return (EINVAL); + + times[0].tv_sec = l_times[0].tv_sec; + switch (l_times[0].tv_nsec) + { + case LINUX_UTIME_OMIT: + times[0].tv_nsec = UTIME_OMIT; + break; + case LINUX_UTIME_NOW: + times[0].tv_nsec = UTIME_NOW; + break; + default: + times[0].tv_nsec = l_times[0].tv_nsec; + } + + times[1].tv_sec = l_times[1].tv_sec; + switch (l_times[1].tv_nsec) + { + case LINUX_UTIME_OMIT: + times[1].tv_nsec = UTIME_OMIT; + break; + case LINUX_UTIME_NOW: + times[1].tv_nsec = UTIME_NOW; + break; + default: + times[1].tv_nsec = l_times[1].tv_nsec; + break; + } + timesp = times; + } + + if (times[0].tv_nsec == UTIME_OMIT && times[1].tv_nsec == UTIME_OMIT) + /* This breaks POSIX, but is what the Linux kernel does + * _on purpose_ (documented in the man page for utimensat(2)), + * so we must follow that behaviour. */ + return (0); + + if (args->pathname != NULL) + LCONVPATHEXIST_AT(td, args->pathname, &path, dfd); + else if (args->flags != 0) + return (EINVAL); + + if (args->flags & LINUX_AT_SYMLINK_NOFOLLOW) + flags |= AT_SYMLINK_NOFOLLOW; + + if (path == NULL) + error = kern_futimens(td, dfd, timesp, UIO_SYSSPACE); + else { + error = kern_utimensat(td, dfd, path, UIO_SYSSPACE, timesp, + UIO_SYSSPACE, flags); + LFREEPATH(path); + } + + return (error); +} + int linux_futimesat(struct thread *td, struct linux_futimesat_args *args) { @@ -847,7 +950,6 @@ linux_futimesat(struct thread *td, struct linux_futimesat_args *args) LFREEPATH(fname); return (error); } -#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ int linux_common_wait(struct thread *td, int pid, int *status, @@ -863,41 +965,131 @@ linux_common_wait(struct thread *td, int pid, int *status, tmpstat &= 0xffff; if (WIFSIGNALED(tmpstat)) tmpstat = (tmpstat & 0xffffff80) | - BSD_TO_LINUX_SIGNAL(WTERMSIG(tmpstat)); + bsd_to_linux_signal(WTERMSIG(tmpstat)); else if (WIFSTOPPED(tmpstat)) tmpstat = (tmpstat & 0xffff00ff) | - (BSD_TO_LINUX_SIGNAL(WSTOPSIG(tmpstat)) << 8); + (bsd_to_linux_signal(WSTOPSIG(tmpstat)) << 8); + else if (WIFCONTINUED(tmpstat)) + tmpstat = 0xffff; error = copyout(&tmpstat, status, sizeof(int)); } return (error); } +#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) int linux_waitpid(struct thread *td, struct linux_waitpid_args *args) { - int options; - + struct linux_wait4_args wait4_args; + #ifdef DEBUG if (ldebug(waitpid)) printf(ARGS(waitpid, "%d, %p, %d"), args->pid, (void *)args->status, args->options); #endif - /* - * this is necessary because the test in kern_wait doesn't work - * because we mess with the options here - */ - if (args->options & ~(WUNTRACED | WNOHANG | WCONTINUED | __WCLONE)) + + wait4_args.pid = args->pid; + wait4_args.status = args->status; + wait4_args.options = args->options; + wait4_args.rusage = NULL; + + return (linux_wait4(td, &wait4_args)); +} +#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ + +int +linux_wait4(struct thread *td, struct linux_wait4_args *args) +{ + int error, options; + struct rusage ru, *rup; + +#ifdef DEBUG + if (ldebug(wait4)) + printf(ARGS(wait4, "%d, %p, %d, %p"), + args->pid, (void *)args->status, args->options, + (void *)args->rusage); +#endif + if (args->options & ~(LINUX_WUNTRACED | LINUX_WNOHANG | + LINUX_WCONTINUED | __WCLONE | __WNOTHREAD | __WALL)) return (EINVAL); - - options = (args->options & (WNOHANG | WUNTRACED)); - /* WLINUXCLONE should be equal to __WCLONE, but we make sure */ - if (args->options & __WCLONE) - options |= WLINUXCLONE; - return (linux_common_wait(td, args->pid, args->status, options, NULL)); + options = WEXITED; + linux_to_bsd_waitopts(args->options, &options); + + if (args->rusage != NULL) + rup = &ru; + else + rup = NULL; + error = linux_common_wait(td, args->pid, args->status, options, rup); + if (error != 0) + return (error); + if (args->rusage != NULL) + error = linux_copyout_rusage(&ru, args->rusage); + return (error); } +int +linux_waitid(struct thread *td, struct linux_waitid_args *args) +{ + int status, options, sig; + struct __wrusage wru; + siginfo_t siginfo; + l_siginfo_t lsi; + idtype_t idtype; + struct proc *p; + int error; + + options = 0; + linux_to_bsd_waitopts(args->options, &options); + + if (options & ~(WNOHANG | WNOWAIT | WEXITED | WUNTRACED | WCONTINUED)) + return (EINVAL); + if (!(options & (WEXITED | WUNTRACED | WCONTINUED))) + return (EINVAL); + + switch (args->idtype) { + case LINUX_P_ALL: + idtype = P_ALL; + break; + case LINUX_P_PID: + if (args->id <= 0) + return (EINVAL); + idtype = P_PID; + break; + case LINUX_P_PGID: + if (args->id <= 0) + return (EINVAL); + idtype = P_PGID; + break; + default: + return (EINVAL); + } + + error = kern_wait6(td, idtype, args->id, &status, options, + &wru, &siginfo); + if (error != 0) + return (error); + if (args->rusage != NULL) { + error = linux_copyout_rusage(&wru.wru_children, + args->rusage); + if (error != 0) + return (error); + } + if (args->info != NULL) { + p = td->td_proc; + if (td->td_retval[0] == 0) + bzero(&lsi, sizeof(lsi)); + else { + sig = bsd_to_linux_signal(siginfo.si_signo); + siginfo_to_lsiginfo(&siginfo, &lsi, sig); + } + error = copyout(&lsi, args->info, sizeof(lsi)); + } + td->td_retval[0] = 0; + + return (error); +} int linux_mknod(struct thread *td, struct linux_mknod_args *args) @@ -909,7 +1101,8 @@ linux_mknod(struct thread *td, struct linux_mknod_args *args) #ifdef DEBUG if (ldebug(mknod)) - printf(ARGS(mknod, "%s, %d, %d"), path, args->mode, args->dev); + printf(ARGS(mknod, "%s, %d, %ju"), path, args->mode, + (uintmax_t)args->dev); #endif switch (args->mode & S_IFMT) { @@ -1079,6 +1272,7 @@ linux_getitimer(struct thread *td, struct linux_getitimer_args *uap) return (copyout(&ls, uap->itv, sizeof(ls))); } +#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) int linux_nice(struct thread *td, struct linux_nice_args *args) { @@ -1089,6 +1283,7 @@ linux_nice(struct thread *td, struct linux_nice_args *args) bsd_args.prio = args->inc; return (sys_setpriority(td, &bsd_args)); } +#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ int linux_setgroups(struct thread *td, struct linux_setgroups_args *args) @@ -1102,7 +1297,7 @@ linux_setgroups(struct thread *td, struct linux_setgroups_args *args) ngrp = args->gidsetsize; if (ngrp < 0 || ngrp >= ngroups_max + 1) return (EINVAL); - linux_gidset = malloc(ngrp * sizeof(*linux_gidset), M_TEMP, M_WAITOK); + linux_gidset = malloc(ngrp * sizeof(*linux_gidset), M_LINUX, M_WAITOK); error = copyin(args->grouplist, linux_gidset, ngrp * sizeof(l_gid_t)); if (error) goto out; @@ -1141,7 +1336,7 @@ linux_setgroups(struct thread *td, struct linux_setgroups_args *args) crfree(oldcred); error = 0; out: - free(linux_gidset, M_TEMP); + free(linux_gidset, M_LINUX); return (error); } @@ -1173,14 +1368,14 @@ linux_getgroups(struct thread *td, struct linux_getgroups_args *args) ngrp = 0; linux_gidset = malloc(bsd_gidsetsz * sizeof(*linux_gidset), - M_TEMP, M_WAITOK); + M_LINUX, M_WAITOK); while (ngrp < bsd_gidsetsz) { linux_gidset[ngrp] = bsd_gidset[ngrp + 1]; ngrp++; } error = copyout(linux_gidset, args->grouplist, ngrp * sizeof(l_gid_t)); - free(linux_gidset, M_TEMP); + free(linux_gidset, M_LINUX); if (error) return (error); @@ -1218,6 +1413,7 @@ linux_setrlimit(struct thread *td, struct linux_setrlimit_args *args) return (kern_setrlimit(td, which, &bsd_rlim)); } +#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) int linux_old_getrlimit(struct thread *td, struct linux_old_getrlimit_args *args) { @@ -1260,6 +1456,7 @@ linux_old_getrlimit(struct thread *td, struct linux_old_getrlimit_args *args) #endif return (copyout(&rlim, args->rlim, sizeof(rlim))); } +#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ int linux_getrlimit(struct thread *td, struct linux_getrlimit_args *args) @@ -1295,7 +1492,9 @@ int linux_sched_setscheduler(struct thread *td, struct linux_sched_setscheduler_args *args) { - struct sched_setscheduler_args bsd; + struct sched_param sched_param; + struct thread *tdt; + int error, policy; #ifdef DEBUG if (ldebug(sched_setscheduler)) @@ -1305,39 +1504,51 @@ linux_sched_setscheduler(struct thread *td, switch (args->policy) { case LINUX_SCHED_OTHER: - bsd.policy = SCHED_OTHER; + policy = SCHED_OTHER; break; case LINUX_SCHED_FIFO: - bsd.policy = SCHED_FIFO; + policy = SCHED_FIFO; break; case LINUX_SCHED_RR: - bsd.policy = SCHED_RR; + policy = SCHED_RR; break; default: return (EINVAL); } - bsd.pid = args->pid; - bsd.param = (struct sched_param *)args->param; - return (sys_sched_setscheduler(td, &bsd)); + error = copyin(args->param, &sched_param, sizeof(sched_param)); + if (error) + return (error); + + tdt = linux_tdfind(td, args->pid, -1); + if (tdt == NULL) + return (ESRCH); + + error = kern_sched_setscheduler(td, tdt, policy, &sched_param); + PROC_UNLOCK(tdt->td_proc); + return (error); } int linux_sched_getscheduler(struct thread *td, struct linux_sched_getscheduler_args *args) { - struct sched_getscheduler_args bsd; - int error; + struct thread *tdt; + int error, policy; #ifdef DEBUG if (ldebug(sched_getscheduler)) printf(ARGS(sched_getscheduler, "%d"), args->pid); #endif - bsd.pid = args->pid; - error = sys_sched_getscheduler(td, &bsd); + tdt = linux_tdfind(td, args->pid, -1); + if (tdt == NULL) + return (ESRCH); + + error = kern_sched_getscheduler(td, tdt, &policy); + PROC_UNLOCK(tdt->td_proc); - switch (td->td_retval[0]) { + switch (policy) { case SCHED_OTHER: td->td_retval[0] = LINUX_SCHED_OTHER; break; @@ -1348,7 +1559,6 @@ linux_sched_getscheduler(struct thread *td, td->td_retval[0] = LINUX_SCHED_RR; break; } - return (error); } @@ -1474,20 +1684,12 @@ linux_reboot(struct thread *td, struct linux_reboot_args *args) int linux_getpid(struct thread *td, struct linux_getpid_args *args) { - struct linux_emuldata *em; #ifdef DEBUG if (ldebug(getpid)) printf(ARGS(getpid, "")); #endif - - if (linux_use26(td)) { - em = em_find(td->td_proc, EMUL_DONTLOCK); - KASSERT(em != NULL, ("getpid: emuldata not found.\n")); - td->td_retval[0] = em->shared->group_pid; - } else { - td->td_retval[0] = td->td_proc->p_pid; - } + td->td_retval[0] = td->td_proc->p_pid; return (0); } @@ -1495,13 +1697,18 @@ linux_getpid(struct thread *td, struct linux_getpid_args *args) int linux_gettid(struct thread *td, struct linux_gettid_args *args) { + struct linux_emuldata *em; #ifdef DEBUG if (ldebug(gettid)) printf(ARGS(gettid, "")); #endif - td->td_retval[0] = td->td_proc->p_pid; + em = em_find(td); + KASSERT(em != NULL, ("gettid: emuldata not found.\n")); + + td->td_retval[0] = em->em_tid; + return (0); } @@ -1509,50 +1716,15 @@ linux_gettid(struct thread *td, struct linux_gettid_args *args) int linux_getppid(struct thread *td, struct linux_getppid_args *args) { - struct linux_emuldata *em; - struct proc *p, *pp; #ifdef DEBUG if (ldebug(getppid)) printf(ARGS(getppid, "")); #endif - if (!linux_use26(td)) { - PROC_LOCK(td->td_proc); - td->td_retval[0] = td->td_proc->p_pptr->p_pid; - PROC_UNLOCK(td->td_proc); - return (0); - } - - em = em_find(td->td_proc, EMUL_DONTLOCK); - - KASSERT(em != NULL, ("getppid: process emuldata not found.\n")); - - /* find the group leader */ - p = pfind(em->shared->group_pid); - - if (p == NULL) { -#ifdef DEBUG - printf(LMSG("parent process not found.\n")); -#endif - return (0); - } - - pp = p->p_pptr; /* switch to parent */ - PROC_LOCK(pp); - PROC_UNLOCK(p); - - /* if its also linux process */ - if (pp->p_sysent == &elf_linux_sysvec) { - em = em_find(pp, EMUL_DONTLOCK); - KASSERT(em != NULL, ("getppid: parent emuldata not found.\n")); - - td->td_retval[0] = em->shared->group_pid; - } else - td->td_retval[0] = pp->p_pid; - - PROC_UNLOCK(pp); - + PROC_LOCK(td->td_proc); + td->td_retval[0] = td->td_proc->p_pptr->p_pid; + PROC_UNLOCK(td->td_proc); return (0); } @@ -1657,22 +1829,14 @@ linux_setdomainname(struct thread *td, struct linux_setdomainname_args *args) int linux_exit_group(struct thread *td, struct linux_exit_group_args *args) { - struct linux_emuldata *em; #ifdef DEBUG if (ldebug(exit_group)) printf(ARGS(exit_group, "%i"), args->error_code); #endif - em = em_find(td->td_proc, EMUL_DONTLOCK); - if (em->shared->refs > 1) { - EMUL_SHARED_WLOCK(&emul_shared_lock); - em->shared->flags |= EMUL_SHARED_HASXSTAT; - em->shared->xstat = W_EXITCODE(args->error_code, 0); - EMUL_SHARED_WUNLOCK(&emul_shared_lock); - if (linux_use26(td)) - linux_kill_threads(td, SIGKILL); - } + LINUX_CTR2(exit_group, "thread(%d) (%d)", td->td_tid, + args->error_code); /* * XXX: we should send a signal to the parent if @@ -1680,8 +1844,7 @@ linux_exit_group(struct thread *td, struct linux_exit_group_args *args) * as it doesnt occur often. */ exit1(td, W_EXITCODE(args->error_code, 0)); - - return (0); + /* NOTREACHED */ } #define _LINUX_CAPABILITY_VERSION 0x19980330 @@ -1789,24 +1952,23 @@ linux_prctl(struct thread *td, struct linux_prctl_args *args) #ifdef DEBUG if (ldebug(prctl)) - printf(ARGS(prctl, "%d, %d, %d, %d, %d"), args->option, - args->arg2, args->arg3, args->arg4, args->arg5); + printf(ARGS(prctl, "%d, %ju, %ju, %ju, %ju"), args->option, + (uintmax_t)args->arg2, (uintmax_t)args->arg3, + (uintmax_t)args->arg4, (uintmax_t)args->arg5); #endif switch (args->option) { case LINUX_PR_SET_PDEATHSIG: if (!LINUX_SIG_VALID(args->arg2)) return (EINVAL); - em = em_find(p, EMUL_DOLOCK); + em = em_find(td); KASSERT(em != NULL, ("prctl: emuldata not found.\n")); em->pdeath_signal = args->arg2; - EMUL_UNLOCK(&emul_lock); break; case LINUX_PR_GET_PDEATHSIG: - em = em_find(p, EMUL_DOLOCK); + em = em_find(td); KASSERT(em != NULL, ("prctl: emuldata not found.\n")); pdeath_signal = em->pdeath_signal; - EMUL_UNLOCK(&emul_lock); error = copyout(&pdeath_signal, (void *)(register_t)args->arg2, sizeof(pdeath_signal)); @@ -1871,6 +2033,57 @@ linux_prctl(struct thread *td, struct linux_prctl_args *args) return (error); } +int +linux_sched_setparam(struct thread *td, + struct linux_sched_setparam_args *uap) +{ + struct sched_param sched_param; + struct thread *tdt; + int error; + +#ifdef DEBUG + if (ldebug(sched_setparam)) + printf(ARGS(sched_setparam, "%d, *"), uap->pid); +#endif + + error = copyin(uap->param, &sched_param, sizeof(sched_param)); + if (error) + return (error); + + tdt = linux_tdfind(td, uap->pid, -1); + if (tdt == NULL) + return (ESRCH); + + error = kern_sched_setparam(td, tdt, &sched_param); + PROC_UNLOCK(tdt->td_proc); + return (error); +} + +int +linux_sched_getparam(struct thread *td, + struct linux_sched_getparam_args *uap) +{ + struct sched_param sched_param; + struct thread *tdt; + int error; + +#ifdef DEBUG + if (ldebug(sched_getparam)) + printf(ARGS(sched_getparam, "%d, *"), uap->pid); +#endif + + tdt = linux_tdfind(td, uap->pid, -1); + if (tdt == NULL) + return (ESRCH); + + error = kern_sched_getparam(td, tdt, &sched_param); + PROC_UNLOCK(tdt->td_proc); + if (error == 0) + error = copyout(&sched_param, uap->param, + sizeof(sched_param)); + return (error); +} + /* * Get affinity of a process. */ @@ -1879,6 +2092,7 @@ linux_sched_getaffinity(struct thread *td, struct linux_sched_getaffinity_args *args) { int error; + struct thread *tdt; struct cpuset_getaffinity_args cga; #ifdef DEBUG @@ -1889,9 +2103,14 @@ linux_sched_getaffinity(struct thread *td, if (args->len < sizeof(cpuset_t)) return (EINVAL); + tdt = linux_tdfind(td, args->pid, -1); + if (tdt == NULL) + return (ESRCH); + + PROC_UNLOCK(tdt->td_proc); cga.level = CPU_LEVEL_WHICH; - cga.which = CPU_WHICH_PID; - cga.id = args->pid; + cga.which = CPU_WHICH_TID; + cga.id = tdt->td_tid; cga.cpusetsize = sizeof(cpuset_t); cga.mask = (cpuset_t *) args->user_mask_ptr; @@ -1909,6 +2128,7 @@ linux_sched_setaffinity(struct thread *td, struct linux_sched_setaffinity_args *args) { struct cpuset_setaffinity_args csa; + struct thread *tdt; #ifdef DEBUG if (ldebug(sched_setaffinity)) @@ -1918,11 +2138,369 @@ linux_sched_setaffinity(struct thread *td, if (args->len < sizeof(cpuset_t)) return (EINVAL); + tdt = linux_tdfind(td, args->pid, -1); + if (tdt == NULL) + return (ESRCH); + + PROC_UNLOCK(tdt->td_proc); csa.level = CPU_LEVEL_WHICH; - csa.which = CPU_WHICH_PID; - csa.id = args->pid; + csa.which = CPU_WHICH_TID; + csa.id = tdt->td_tid; csa.cpusetsize = sizeof(cpuset_t); csa.mask = (cpuset_t *) args->user_mask_ptr; return (sys_cpuset_setaffinity(td, &csa)); } + +struct linux_rlimit64 { + uint64_t rlim_cur; + uint64_t rlim_max; +}; + +int +linux_prlimit64(struct thread *td, struct linux_prlimit64_args *args) +{ + struct rlimit rlim, nrlim; + struct linux_rlimit64 lrlim; + struct proc *p; + u_int which; + int flags; + int error; + +#ifdef DEBUG + if (ldebug(prlimit64)) + printf(ARGS(prlimit64, "%d, %d, %p, %p"), args->pid, + args->resource, (void *)args->new, (void *)args->old); +#endif + + if (args->resource >= LINUX_RLIM_NLIMITS) + return (EINVAL); + + which = linux_to_bsd_resource[args->resource]; + if (which == -1) + return (EINVAL); + + if (args->new != NULL) { + /* + * Note. Unlike FreeBSD where rlim is signed 64-bit Linux + * rlim is unsigned 64-bit. FreeBSD treats negative limits + * as INFINITY so we do not need a conversion even. + */ + error = copyin(args->new, &nrlim, sizeof(nrlim)); + if (error != 0) + return (error); + } + + flags = PGET_HOLD | PGET_NOTWEXIT; + if (args->new != NULL) + flags |= PGET_CANDEBUG; + else + flags |= PGET_CANSEE; + error = pget(args->pid, flags, &p); + if (error != 0) + return (error); + + if (args->old != NULL) { + PROC_LOCK(p); + lim_rlimit(p, which, &rlim); + PROC_UNLOCK(p); + if (rlim.rlim_cur == RLIM_INFINITY) + lrlim.rlim_cur = LINUX_RLIM_INFINITY; + else + lrlim.rlim_cur = rlim.rlim_cur; + if (rlim.rlim_max == RLIM_INFINITY) + lrlim.rlim_max = LINUX_RLIM_INFINITY; + else + lrlim.rlim_max = rlim.rlim_max; + error = copyout(&lrlim, args->old, sizeof(lrlim)); + if (error != 0) + goto out; + } + + if (args->new != NULL) + error = kern_proc_setrlimit(td, p, which, &nrlim); + + out: + PRELE(p); + return (error); +} + +int +linux_pselect6(struct thread *td, struct linux_pselect6_args *args) +{ + struct timeval utv, tv0, tv1, *tvp; + struct l_pselect6arg lpse6; + struct l_timespec lts; + struct timespec uts; + l_sigset_t l_ss; + sigset_t *ssp; + sigset_t ss; + int error; + + ssp = NULL; + if (args->sig != NULL) { + error = copyin(args->sig, &lpse6, sizeof(lpse6)); + if (error != 0) + return (error); + if (lpse6.ss_len != sizeof(l_ss)) + return (EINVAL); + if (lpse6.ss != 0) { + error = copyin(PTRIN(lpse6.ss), &l_ss, + sizeof(l_ss)); + if (error != 0) + return (error); + linux_to_bsd_sigset(&l_ss, &ss); + ssp = &ss; + } + } + + /* + * Currently glibc changes nanosecond number to microsecond. + * This mean losing precision but for now it is hardly seen. + */ + if (args->tsp != NULL) { + error = copyin(args->tsp, <s, sizeof(lts)); + if (error != 0) + return (error); + error = linux_to_native_timespec(&uts, <s); + if (error != 0) + return (error); + + TIMESPEC_TO_TIMEVAL(&utv, &uts); + if (itimerfix(&utv)) + return (EINVAL); + + microtime(&tv0); + tvp = &utv; + } else + tvp = NULL; + + error = kern_pselect(td, args->nfds, args->readfds, args->writefds, + args->exceptfds, tvp, ssp, LINUX_NFDBITS); + + if (error == 0 && args->tsp != NULL) { + if (td->td_retval[0] != 0) { + /* + * Compute how much time was left of the timeout, + * by subtracting the current time and the time + * before we started the call, and subtracting + * that result from the user-supplied value. + */ + + microtime(&tv1); + timevalsub(&tv1, &tv0); + timevalsub(&utv, &tv1); + if (utv.tv_sec < 0) + timevalclear(&utv); + } else + timevalclear(&utv); + + TIMEVAL_TO_TIMESPEC(&utv, &uts); + + native_to_linux_timespec(<s, &uts); + error = copyout(<s, args->tsp, sizeof(lts)); + } + + return (error); +} + +int +linux_ppoll(struct thread *td, struct linux_ppoll_args *args) +{ + struct timespec ts0, ts1; + struct l_timespec lts; + struct timespec uts, *tsp; + l_sigset_t l_ss; + sigset_t *ssp; + sigset_t ss; + int error; + + if (args->sset != NULL) { + if (args->ssize != sizeof(l_ss)) + return (EINVAL); + error = copyin(args->sset, &l_ss, sizeof(l_ss)); + if (error) + return (error); + linux_to_bsd_sigset(&l_ss, &ss); + ssp = &ss; + } else + ssp = NULL; + if (args->tsp != NULL) { + error = copyin(args->tsp, <s, sizeof(lts)); + if (error) + return (error); + error = linux_to_native_timespec(&uts, <s); + if (error != 0) + return (error); + + nanotime(&ts0); + tsp = &uts; + } else + tsp = NULL; + + error = kern_poll(td, args->fds, args->nfds, tsp, ssp); + + if (error == 0 && args->tsp != NULL) { + if (td->td_retval[0]) { + nanotime(&ts1); + timespecsub(&ts1, &ts0); + timespecsub(&uts, &ts1); + if (uts.tv_sec < 0) + timespecclear(&uts); + } else + timespecclear(&uts); + + native_to_linux_timespec(<s, &uts); + error = copyout(<s, args->tsp, sizeof(lts)); + } + + return (error); +} + +#if defined(DEBUG) || defined(KTR) +/* XXX: can be removed when every ldebug(...) and KTR stuff are removed. */ + +u_char linux_debug_map[howmany(LINUX_SYS_MAXSYSCALL, sizeof(u_char))]; + +static int +linux_debug(int syscall, int toggle, int global) +{ + + if (global) { + char c = toggle ? 0 : 0xff; + + memset(linux_debug_map, c, sizeof(linux_debug_map)); + return (0); + } + if (syscall < 0 || syscall >= LINUX_SYS_MAXSYSCALL) + return (EINVAL); + if (toggle) + clrbit(linux_debug_map, syscall); + else + setbit(linux_debug_map, syscall); + return (0); +} + +/* + * Usage: sysctl linux.debug=<syscall_nr>.<0/1> + * + * E.g.: sysctl linux.debug=21.0 + * + * As a special case, syscall "all" will apply to all syscalls globally. + */ +#define LINUX_MAX_DEBUGSTR 16 +int +linux_sysctl_debug(SYSCTL_HANDLER_ARGS) +{ + char value[LINUX_MAX_DEBUGSTR], *p; + int error, sysc, toggle; + int global = 0; + + value[0] = '\0'; + error = sysctl_handle_string(oidp, value, LINUX_MAX_DEBUGSTR, req); + if (error || req->newptr == NULL) + return (error); + for (p = value; *p != '\0' && *p != '.'; p++); + if (*p == '\0') + return (EINVAL); + *p++ = '\0'; + sysc = strtol(value, NULL, 0); + toggle = strtol(p, NULL, 0); + if (strcmp(value, "all") == 0) + global = 1; + error = linux_debug(sysc, toggle, global); + return (error); +} + +#endif /* DEBUG || KTR */ + +int +linux_sched_rr_get_interval(struct thread *td, + struct linux_sched_rr_get_interval_args *uap) +{ + struct timespec ts; + struct l_timespec lts; + struct thread *tdt; + int error; + + /* + * According to man in case the invalid pid specified + * EINVAL should be returned. + */ + if (uap->pid < 0) + return (EINVAL); + + tdt = linux_tdfind(td, uap->pid, -1); + if (tdt == NULL) + return (ESRCH); + + error = kern_sched_rr_get_interval_td(td, tdt, &ts); + PROC_UNLOCK(tdt->td_proc); + if (error != 0) + return (error); + native_to_linux_timespec(<s, &ts); + return (copyout(<s, uap->interval, sizeof(lts))); +} + +/* + * In case when the Linux thread is the initial thread in + * the thread group thread id is equal to the process id. + * Glibc depends on this magic (assert in pthread_getattr_np.c). + */ +struct thread * +linux_tdfind(struct thread *td, lwpid_t tid, pid_t pid) +{ + struct linux_emuldata *em; + struct thread *tdt; + struct proc *p; + + tdt = NULL; + if (tid == 0 || tid == td->td_tid) { + tdt = td; + PROC_LOCK(tdt->td_proc); + } else if (tid > PID_MAX) + tdt = tdfind(tid, pid); + else { + /* + * Initial thread where the tid equal to the pid. + */ + p = pfind(tid); + if (p != NULL) { + if (SV_PROC_ABI(p) != SV_ABI_LINUX) { + /* + * p is not a Linuxulator process. + */ + PROC_UNLOCK(p); + return (NULL); + } + FOREACH_THREAD_IN_PROC(p, tdt) { + em = em_find(tdt); + if (tid == em->em_tid) + return (tdt); + } + PROC_UNLOCK(p); + } + return (NULL); + } + + return (tdt); +} + +void +linux_to_bsd_waitopts(int options, int *bsdopts) +{ + + if (options & LINUX_WNOHANG) + *bsdopts |= WNOHANG; + if (options & LINUX_WUNTRACED) + *bsdopts |= WUNTRACED; + if (options & LINUX_WEXITED) + *bsdopts |= WEXITED; + if (options & LINUX_WCONTINUED) + *bsdopts |= WCONTINUED; + if (options & LINUX_WNOWAIT) + *bsdopts |= WNOWAIT; + + if (options & __WCLONE) + *bsdopts |= WLINUXCLONE; +} diff --git a/sys/compat/linux/linux_misc.h b/sys/compat/linux/linux_misc.h index 154d78f..f969c4d 100644 --- a/sys/compat/linux/linux_misc.h +++ b/sys/compat/linux/linux_misc.h @@ -31,6 +31,11 @@ #ifndef _LINUX_MISC_H_ #define _LINUX_MISC_H_ +#include <sys/sysctl.h> + + /* bits per mask */ +#define LINUX_NFDBITS sizeof(l_fd_mask) * 8 + /* * Miscellaneous */ @@ -55,7 +60,7 @@ #define LINUX_MREMAP_MAYMOVE 1 #define LINUX_MREMAP_FIXED 2 -extern const char *linux_platform; +extern const char *linux_kplatform; /* * Non-standard aux entry types used in Linux ELF binaries. @@ -68,7 +73,12 @@ extern const char *linux_platform; #define LINUX_AT_BASE_PLATFORM 24 /* string identifying real platform, may * differ from AT_PLATFORM. */ +#define LINUX_AT_RANDOM 25 /* address of random bytes */ #define LINUX_AT_EXECFN 31 /* filename of program */ +#define LINUX_AT_SYSINFO 32 /* vsyscall */ +#define LINUX_AT_SYSINFO_EHDR 33 /* vdso header */ + +#define LINUX_AT_RANDOM_LEN 16 /* size of random bytes */ /* Linux sets the i387 to extended precision. */ #if defined(__i386__) || defined(__amd64__) @@ -88,10 +98,6 @@ extern const char *linux_platform; #define LINUX_CLONE_CHILD_CLEARTID 0x00200000 #define LINUX_CLONE_CHILD_SETTID 0x01000000 -#define LINUX_THREADING_FLAGS \ - (LINUX_CLONE_VM | LINUX_CLONE_FS | LINUX_CLONE_FILES | \ - LINUX_CLONE_SIGHAND | LINUX_CLONE_THREAD) - /* Scheduling policies */ #define LINUX_SCHED_OTHER 0 #define LINUX_SCHED_FIFO 1 @@ -113,13 +119,37 @@ struct l_new_utsname { #define LINUX_CLOCK_REALTIME_HR 4 #define LINUX_CLOCK_MONOTONIC_HR 5 +#define LINUX_UTIME_NOW 0x3FFFFFFF +#define LINUX_UTIME_OMIT 0x3FFFFFFE + extern int stclohz; -#define __WCLONE 0x80000000 +#define LINUX_WNOHANG 0x00000001 +#define LINUX_WUNTRACED 0x00000002 +#define LINUX_WSTOPPED LINUX_WUNTRACED +#define LINUX_WEXITED 0x00000004 +#define LINUX_WCONTINUED 0x00000008 +#define LINUX_WNOWAIT 0x01000000 + + +#define __WNOTHREAD 0x20000000 +#define __WALL 0x40000000 +#define __WCLONE 0x80000000 + +/* Linux waitid idtype */ +#define LINUX_P_ALL 0 +#define LINUX_P_PID 1 +#define LINUX_P_PGID 2 + +#define LINUX_RLIM_INFINITY (~0UL) int linux_common_wait(struct thread *td, int pid, int *status, int options, struct rusage *ru); +void linux_to_bsd_waitopts(int options, int *bsdopts); int linux_set_upcall_kse(struct thread *td, register_t stack); int linux_set_cloned_tls(struct thread *td, void *desc); +struct thread *linux_tdfind(struct thread *, lwpid_t, pid_t); + +int linux_sysctl_debug(SYSCTL_HANDLER_ARGS); #endif /* _LINUX_MISC_H_ */ diff --git a/sys/compat/linux/linux_signal.c b/sys/compat/linux/linux_signal.c index 1c778f9..0ecf537 100644 --- a/sys/compat/linux/linux_signal.c +++ b/sys/compat/linux/linux_signal.c @@ -53,40 +53,12 @@ __FBSDID("$FreeBSD$"); #include <compat/linux/linux_signal.h> #include <compat/linux/linux_util.h> #include <compat/linux/linux_emul.h> +#include <compat/linux/linux_misc.h> -void -linux_to_bsd_sigset(l_sigset_t *lss, sigset_t *bss) -{ - int b, l; - - SIGEMPTYSET(*bss); - bss->__bits[0] = lss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1); - bss->__bits[1] = lss->__bits[1]; - for (l = 1; l <= LINUX_SIGTBLSZ; l++) { - if (LINUX_SIGISMEMBER(*lss, l)) { - b = linux_to_bsd_signal[_SIG_IDX(l)]; - if (b) - SIGADDSET(*bss, b); - } - } -} +static int linux_do_tkill(struct thread *td, struct thread *tdt, + ksiginfo_t *ksi); +static void sicode_to_lsicode(int si_code, int *lsi_code); -void -bsd_to_linux_sigset(sigset_t *bss, l_sigset_t *lss) -{ - int b, l; - - LINUX_SIGEMPTYSET(*lss); - lss->__bits[0] = bss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1); - lss->__bits[1] = bss->__bits[1]; - for (b = 1; b <= LINUX_SIGTBLSZ; b++) { - if (SIGISMEMBER(*bss, b)) { - l = bsd_to_linux_signal[_SIG_IDX(b)]; - if (l) - LINUX_SIGADDSET(*lss, l); - } - } -} static void linux_to_bsd_sigaction(l_sigaction_t *lsa, struct sigaction *bsa) @@ -155,11 +127,7 @@ linux_do_sigaction(struct thread *td, int linux_sig, l_sigaction_t *linux_nsa, linux_to_bsd_sigaction(linux_nsa, nsa); } else nsa = NULL; - - if (linux_sig <= LINUX_SIGTBLSZ) - sig = linux_to_bsd_signal[_SIG_IDX(linux_sig)]; - else - sig = linux_sig; + sig = linux_to_bsd_signal(linux_sig); error = kern_sigaction(td, sig, nsa, osa, 0); if (error) @@ -171,7 +139,7 @@ linux_do_sigaction(struct thread *td, int linux_sig, l_sigaction_t *linux_nsa, return (0); } - +#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) int linux_signal(struct thread *td, struct linux_signal_args *args) { @@ -193,6 +161,7 @@ linux_signal(struct thread *td, struct linux_signal_args *args) return (error); } +#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ int linux_rt_sigaction(struct thread *td, struct linux_rt_sigaction_args *args) @@ -262,6 +231,7 @@ linux_do_sigprocmask(struct thread *td, int how, l_sigset_t *new, return (error); } +#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) int linux_sigprocmask(struct thread *td, struct linux_sigprocmask_args *args) { @@ -279,7 +249,7 @@ linux_sigprocmask(struct thread *td, struct linux_sigprocmask_args *args) if (error) return (error); LINUX_SIGEMPTYSET(set); - set.__bits[0] = mask; + set.__mask = mask; } error = linux_do_sigprocmask(td, args->how, @@ -287,12 +257,13 @@ linux_sigprocmask(struct thread *td, struct linux_sigprocmask_args *args) args->omask ? &oset : NULL); if (args->omask != NULL && !error) { - mask = oset.__bits[0]; + mask = oset.__mask; error = copyout(&mask, args->omask, sizeof(l_osigset_t)); } return (error); } +#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ int linux_rt_sigprocmask(struct thread *td, struct linux_rt_sigprocmask_args *args) @@ -327,6 +298,7 @@ linux_rt_sigprocmask(struct thread *td, struct linux_rt_sigprocmask_args *args) return (error); } +#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) int linux_sgetmask(struct thread *td, struct linux_sgetmask_args *args) { @@ -341,7 +313,7 @@ linux_sgetmask(struct thread *td, struct linux_sgetmask_args *args) PROC_LOCK(p); bsd_to_linux_sigset(&td->td_sigmask, &mask); PROC_UNLOCK(p); - td->td_retval[0] = mask.__bits[0]; + td->td_retval[0] = mask.__mask; return (0); } @@ -359,9 +331,9 @@ linux_ssetmask(struct thread *td, struct linux_ssetmask_args *args) PROC_LOCK(p); bsd_to_linux_sigset(&td->td_sigmask, &lset); - td->td_retval[0] = lset.__bits[0]; + td->td_retval[0] = lset.__mask; LINUX_SIGEMPTYSET(lset); - lset.__bits[0] = args->mask; + lset.__mask = args->mask; linux_to_bsd_sigset(&lset, &bset); td->td_sigmask = bset; SIG_CANTMASK(td->td_sigmask); @@ -370,9 +342,6 @@ linux_ssetmask(struct thread *td, struct linux_ssetmask_args *args) return (0); } -/* - * MPSAFE - */ int linux_sigpending(struct thread *td, struct linux_sigpending_args *args) { @@ -392,9 +361,10 @@ linux_sigpending(struct thread *td, struct linux_sigpending_args *args) SIGSETAND(bset, td->td_sigmask); PROC_UNLOCK(p); bsd_to_linux_sigset(&bset, &lset); - mask = lset.__bits[0]; + mask = lset.__mask; return (copyout(&mask, args->mask, sizeof(mask))); } +#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ /* * MPSAFE @@ -458,8 +428,8 @@ linux_rt_sigtimedwait(struct thread *td, #ifdef DEBUG if (ldebug(rt_sigtimedwait)) printf(LMSG("linux_rt_sigtimedwait: " - "incoming timeout (%d/%d)\n"), - ltv.tv_sec, ltv.tv_usec); + "incoming timeout (%jd/%jd)\n"), + (intmax_t)ltv.tv_sec, (intmax_t)ltv.tv_usec); #endif tv.tv_sec = (long)ltv.tv_sec; tv.tv_usec = (suseconds_t)ltv.tv_usec; @@ -495,7 +465,7 @@ linux_rt_sigtimedwait(struct thread *td, if (error) return (error); - sig = BSD_TO_LINUX_SIGNAL(info.ksi_signo); + sig = bsd_to_linux_signal(info.ksi_signo); if (args->ptr) { memset(&linfo, 0, sizeof(linfo)); @@ -527,66 +497,31 @@ linux_kill(struct thread *td, struct linux_kill_args *args) if (!LINUX_SIG_VALID(args->signum) && args->signum != 0) return (EINVAL); - if (args->signum > 0 && args->signum <= LINUX_SIGTBLSZ) - tmp.signum = linux_to_bsd_signal[_SIG_IDX(args->signum)]; + if (args->signum > 0) + tmp.signum = linux_to_bsd_signal(args->signum); else - tmp.signum = args->signum; + tmp.signum = 0; tmp.pid = args->pid; return (sys_kill(td, &tmp)); } static int -linux_do_tkill(struct thread *td, l_int tgid, l_int pid, l_int signum) +linux_do_tkill(struct thread *td, struct thread *tdt, ksiginfo_t *ksi) { - struct proc *proc = td->td_proc; - struct linux_emuldata *em; struct proc *p; - ksiginfo_t ksi; int error; - AUDIT_ARG_SIGNUM(signum); - AUDIT_ARG_PID(pid); - - /* - * Allow signal 0 as a means to check for privileges - */ - if (!LINUX_SIG_VALID(signum) && signum != 0) - return (EINVAL); - - if (signum > 0 && signum <= LINUX_SIGTBLSZ) - signum = linux_to_bsd_signal[_SIG_IDX(signum)]; - - if ((p = pfind(pid)) == NULL) { - if ((p = zpfind(pid)) == NULL) - return (ESRCH); - } - + p = tdt->td_proc; + AUDIT_ARG_SIGNUM(ksi->ksi_signo); + AUDIT_ARG_PID(p->p_pid); AUDIT_ARG_PROCESS(p); - error = p_cansignal(td, p, signum); - if (error != 0 || signum == 0) - goto out; - - error = ESRCH; - em = em_find(p, EMUL_DONTLOCK); - if (em == NULL) { -#ifdef DEBUG - printf("emuldata not found in do_tkill.\n"); -#endif + error = p_cansignal(td, p, ksi->ksi_signo); + if (error != 0 || ksi->ksi_signo == 0) goto out; - } - if (tgid > 0 && em->shared->group_pid != tgid) - goto out; - - ksiginfo_init(&ksi); - ksi.ksi_signo = signum; - ksi.ksi_code = LINUX_SI_TKILL; - ksi.ksi_errno = 0; - ksi.ksi_pid = proc->p_pid; - ksi.ksi_uid = proc->p_ucred->cr_ruid; - error = pksignal(p, ksi.ksi_signo, &ksi); + tdksignal(tdt, ksi->ksi_signo, ksi); out: PROC_UNLOCK(p); @@ -596,20 +531,53 @@ out: int linux_tgkill(struct thread *td, struct linux_tgkill_args *args) { + struct thread *tdt; + ksiginfo_t ksi; + int sig; #ifdef DEBUG if (ldebug(tgkill)) - printf(ARGS(tgkill, "%d, %d, %d"), args->tgid, args->pid, args->sig); + printf(ARGS(tgkill, "%d, %d, %d"), + args->tgid, args->pid, args->sig); #endif + if (args->pid <= 0 || args->tgid <=0) return (EINVAL); - return (linux_do_tkill(td, args->tgid, args->pid, args->sig)); + /* + * Allow signal 0 as a means to check for privileges + */ + if (!LINUX_SIG_VALID(args->sig) && args->sig != 0) + return (EINVAL); + + if (args->sig > 0) + sig = linux_to_bsd_signal(args->sig); + else + sig = 0; + + tdt = linux_tdfind(td, args->pid, args->tgid); + if (tdt == NULL) + return (ESRCH); + + ksiginfo_init(&ksi); + ksi.ksi_signo = sig; + ksi.ksi_code = SI_LWP; + ksi.ksi_errno = 0; + ksi.ksi_pid = td->td_proc->p_pid; + ksi.ksi_uid = td->td_proc->p_ucred->cr_ruid; + return (linux_do_tkill(td, tdt, &ksi)); } +/* + * Deprecated since 2.5.75. Replaced by tgkill(). + */ int linux_tkill(struct thread *td, struct linux_tkill_args *args) { + struct thread *tdt; + ksiginfo_t ksi; + int sig; + #ifdef DEBUG if (ldebug(tkill)) printf(ARGS(tkill, "%i, %i"), args->tid, args->sig); @@ -617,40 +585,182 @@ linux_tkill(struct thread *td, struct linux_tkill_args *args) if (args->tid <= 0) return (EINVAL); - return (linux_do_tkill(td, 0, args->tid, args->sig)); + if (!LINUX_SIG_VALID(args->sig)) + return (EINVAL); + + sig = linux_to_bsd_signal(args->sig); + + tdt = linux_tdfind(td, args->tid, -1); + if (tdt == NULL) + return (ESRCH); + + ksiginfo_init(&ksi); + ksi.ksi_signo = sig; + ksi.ksi_code = SI_LWP; + ksi.ksi_errno = 0; + ksi.ksi_pid = td->td_proc->p_pid; + ksi.ksi_uid = td->td_proc->p_ucred->cr_ruid; + return (linux_do_tkill(td, tdt, &ksi)); +} + +void +ksiginfo_to_lsiginfo(const ksiginfo_t *ksi, l_siginfo_t *lsi, l_int sig) +{ + + siginfo_to_lsiginfo(&ksi->ksi_info, lsi, sig); +} + +static void +sicode_to_lsicode(int si_code, int *lsi_code) +{ + + switch (si_code) { + case SI_USER: + *lsi_code = LINUX_SI_USER; + break; + case SI_KERNEL: + *lsi_code = LINUX_SI_KERNEL; + break; + case SI_QUEUE: + *lsi_code = LINUX_SI_QUEUE; + break; + case SI_TIMER: + *lsi_code = LINUX_SI_TIMER; + break; + case SI_MESGQ: + *lsi_code = LINUX_SI_MESGQ; + break; + case SI_ASYNCIO: + *lsi_code = LINUX_SI_ASYNCIO; + break; + case SI_LWP: + *lsi_code = LINUX_SI_TKILL; + break; + default: + *lsi_code = si_code; + break; + } } void -ksiginfo_to_lsiginfo(ksiginfo_t *ksi, l_siginfo_t *lsi, l_int sig) +siginfo_to_lsiginfo(const siginfo_t *si, l_siginfo_t *lsi, l_int sig) { + /* sig alredy converted */ lsi->lsi_signo = sig; - lsi->lsi_code = ksi->ksi_code; + sicode_to_lsicode(si->si_code, &lsi->lsi_code); - switch (sig) { - case LINUX_SIGPOLL: - /* XXX si_fd? */ - lsi->lsi_band = ksi->ksi_band; + switch (si->si_code) { + case SI_LWP: + lsi->lsi_pid = si->si_pid; + lsi->lsi_uid = si->si_uid; break; - case LINUX_SIGCHLD: - lsi->lsi_pid = ksi->ksi_pid; - lsi->lsi_uid = ksi->ksi_uid; - lsi->lsi_status = ksi->ksi_status; + + case SI_TIMER: + lsi->lsi_int = si->si_value.sival_int; + lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); + lsi->lsi_tid = si->si_timerid; break; - case LINUX_SIGBUS: - case LINUX_SIGILL: - case LINUX_SIGFPE: - case LINUX_SIGSEGV: - lsi->lsi_addr = PTROUT(ksi->ksi_addr); + + case SI_QUEUE: + lsi->lsi_pid = si->si_pid; + lsi->lsi_uid = si->si_uid; + lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); break; + + case SI_ASYNCIO: + lsi->lsi_int = si->si_value.sival_int; + lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); + break; + default: - /* XXX SI_TIMER etc... */ - lsi->lsi_pid = ksi->ksi_pid; - lsi->lsi_uid = ksi->ksi_uid; + switch (sig) { + case LINUX_SIGPOLL: + /* XXX si_fd? */ + lsi->lsi_band = si->si_band; + break; + + case LINUX_SIGCHLD: + lsi->lsi_errno = 0; + lsi->lsi_pid = si->si_pid; + lsi->lsi_uid = si->si_uid; + + if (si->si_code == CLD_STOPPED) + lsi->lsi_status = bsd_to_linux_signal(si->si_status); + else if (si->si_code == CLD_CONTINUED) + lsi->lsi_status = bsd_to_linux_signal(SIGCONT); + else + lsi->lsi_status = si->si_status; + break; + + case LINUX_SIGBUS: + case LINUX_SIGILL: + case LINUX_SIGFPE: + case LINUX_SIGSEGV: + lsi->lsi_addr = PTROUT(si->si_addr); + break; + + default: + lsi->lsi_pid = si->si_pid; + lsi->lsi_uid = si->si_uid; + if (sig >= LINUX_SIGRTMIN) { + lsi->lsi_int = si->si_value.sival_int; + lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); + } + break; + } break; } - if (sig >= LINUX_SIGRTMIN) { - lsi->lsi_int = ksi->ksi_info.si_value.sival_int; - lsi->lsi_ptr = PTROUT(ksi->ksi_info.si_value.sival_ptr); +} + +void +lsiginfo_to_ksiginfo(const l_siginfo_t *lsi, ksiginfo_t *ksi, int sig) +{ + + ksi->ksi_signo = sig; + ksi->ksi_code = lsi->lsi_code; /* XXX. Convert. */ + ksi->ksi_pid = lsi->lsi_pid; + ksi->ksi_uid = lsi->lsi_uid; + ksi->ksi_status = lsi->lsi_status; + ksi->ksi_addr = PTRIN(lsi->lsi_addr); + ksi->ksi_info.si_value.sival_int = lsi->lsi_int; +} + +int +linux_rt_sigqueueinfo(struct thread *td, struct linux_rt_sigqueueinfo_args *args) +{ + l_siginfo_t linfo; + struct proc *p; + ksiginfo_t ksi; + int error; + int sig; + + if (!LINUX_SIG_VALID(args->sig)) + return (EINVAL); + + error = copyin(args->info, &linfo, sizeof(linfo)); + if (error != 0) + return (error); + + if (linfo.lsi_code >= 0) + return (EPERM); + + sig = linux_to_bsd_signal(args->sig); + + error = ESRCH; + if ((p = pfind(args->pid)) != NULL || + (p = zpfind(args->pid)) != NULL) { + error = p_cansignal(td, p, sig); + if (error != 0) { + PROC_UNLOCK(p); + return (error); + } + + ksiginfo_init(&ksi); + lsiginfo_to_ksiginfo(&linfo, &ksi, sig); + error = tdsendsignal(p, NULL, sig, &ksi); + PROC_UNLOCK(p); } + + return (error); } diff --git a/sys/compat/linux/linux_signal.h b/sys/compat/linux/linux_signal.h index 426cf43..510bfb3 100644 --- a/sys/compat/linux/linux_signal.h +++ b/sys/compat/linux/linux_signal.h @@ -31,19 +31,21 @@ #ifndef _LINUX_SIGNAL_H_ #define _LINUX_SIGNAL_H_ -#define LINUX_SI_TKILL -6; - -extern int bsd_to_linux_signal[]; -extern int linux_to_bsd_signal[]; +/* + * si_code values + */ +#define LINUX_SI_USER 0 /* sent by kill, sigsend, raise */ +#define LINUX_SI_KERNEL 0x80 /* sent by the kernel from somewhere */ +#define LINUX_SI_QUEUE -1 /* sent by sigqueue */ +#define LINUX_SI_TIMER -2 /* sent by timer expiration */ +#define LINUX_SI_MESGQ -3 /* sent by real time mesq state change */ +#define LINUX_SI_ASYNCIO -4 /* sent by AIO completion */ +#define LINUX_SI_SIGIO -5 /* sent by queued SIGIO */ +#define LINUX_SI_TKILL -6 /* sent by tkill system call */ -void linux_to_bsd_sigset(l_sigset_t *, sigset_t *); -void bsd_to_linux_sigset(sigset_t *, l_sigset_t *); int linux_do_sigaction(struct thread *, int, l_sigaction_t *, l_sigaction_t *); -void ksiginfo_to_lsiginfo(ksiginfo_t *ksi, l_siginfo_t *lsi, l_int sig); - -#define LINUX_SIG_VALID(sig) ((sig) <= LINUX_NSIG && (sig) > 0) - -#define BSD_TO_LINUX_SIGNAL(sig) \ - (((sig) <= LINUX_SIGTBLSZ) ? bsd_to_linux_signal[_SIG_IDX(sig)] : sig) +void ksiginfo_to_lsiginfo(const ksiginfo_t *ksi, l_siginfo_t *lsi, l_int sig); +void siginfo_to_lsiginfo(const siginfo_t *si, l_siginfo_t *lsi, l_int sig); +void lsiginfo_to_ksiginfo(const l_siginfo_t *lsi, ksiginfo_t *ksi, int sig); #endif /* _LINUX_SIGNAL_H_ */ diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c index 4b07b5c..34af9da 100644 --- a/sys/compat/linux/linux_socket.c +++ b/sys/compat/linux/linux_socket.c @@ -70,10 +70,17 @@ __FBSDID("$FreeBSD$"); #include <machine/../linux/linux.h> #include <machine/../linux/linux_proto.h> #endif +#include <compat/linux/linux_file.h> #include <compat/linux/linux_socket.h> +#include <compat/linux/linux_timer.h> #include <compat/linux/linux_util.h> static int linux_to_bsd_domain(int); +static int linux_sendmsg_common(struct thread *, l_int, struct l_msghdr *, + l_uint); +static int linux_recvmsg_common(struct thread *, l_int, struct l_msghdr *, + l_uint, struct msghdr *); +static int linux_set_socket_flags(int, int *); /* * Reads a linux sockaddr and does any necessary translation. @@ -428,7 +435,6 @@ linux_to_bsd_sockaddr(struct sockaddr *arg, int len) return (error); } - static int linux_sa_put(struct osockaddr *osa) { @@ -477,6 +483,8 @@ bsd_to_linux_cmsg_type(int cmsg_type) return (LINUX_SCM_RIGHTS); case SCM_CREDS: return (LINUX_SCM_CREDENTIALS); + case SCM_TIMESTAMP: + return (LINUX_SCM_TIMESTAMP); } return (-1); } @@ -529,20 +537,15 @@ bsd_to_linux_msghdr(const struct msghdr *bhdr, struct l_msghdr *lhdr) } static int -linux_set_socket_flags(struct thread *td, int s, int flags) +linux_set_socket_flags(int lflags, int *flags) { - int error; - if (flags & LINUX_SOCK_NONBLOCK) { - error = kern_fcntl(td, s, F_SETFL, O_NONBLOCK); - if (error) - return (error); - } - if (flags & LINUX_SOCK_CLOEXEC) { - error = kern_fcntl(td, s, F_SETFD, FD_CLOEXEC); - if (error) - return (error); - } + if (lflags & ~(LINUX_SOCK_CLOEXEC | LINUX_SOCK_NONBLOCK)) + return (EINVAL); + if (lflags & LINUX_SOCK_NONBLOCK) + *flags |= SOCK_NONBLOCK; + if (lflags & LINUX_SOCK_CLOEXEC) + *flags |= SOCK_CLOEXEC; return (0); } @@ -585,15 +588,6 @@ linux_check_hdrincl(struct thread *td, int s) return (optval == 0); } -struct linux_sendto_args { - int s; - l_uintptr_t msg; - int len; - int flags; - l_uintptr_t to; - int tolen; -}; - /* * Updated sendto() when IP_HDRINCL is set: * tweak endian-dependent fields in the IP packet. @@ -618,7 +612,7 @@ linux_sendto_hdrincl(struct thread *td, struct linux_sendto_args *linux_args) linux_args->len > IP_MAXPACKET) return (EINVAL); - packet = (struct ip *)malloc(linux_args->len, M_TEMP, M_WAITOK); + packet = (struct ip *)malloc(linux_args->len, M_LINUX, M_WAITOK); /* Make kernel copy of the packet to be sent */ if ((error = copyin(PTRIN(linux_args->msg), packet, @@ -641,17 +635,11 @@ linux_sendto_hdrincl(struct thread *td, struct linux_sendto_args *linux_args) error = linux_sendit(td, linux_args->s, &msg, linux_args->flags, NULL, UIO_SYSSPACE); goout: - free(packet, M_TEMP); + free(packet, M_LINUX); return (error); } -struct linux_socket_args { - int domain; - int type; - int protocol; -}; - -static int +int linux_socket(struct thread *td, struct linux_socket_args *args) { struct socket_args /* { @@ -659,15 +647,16 @@ linux_socket(struct thread *td, struct linux_socket_args *args) int type; int protocol; } */ bsd_args; - int retval_socket, socket_flags; + int retval_socket; bsd_args.protocol = args->protocol; - socket_flags = args->type & ~LINUX_SOCK_TYPE_MASK; - if (socket_flags & ~(LINUX_SOCK_CLOEXEC | LINUX_SOCK_NONBLOCK)) - return (EINVAL); bsd_args.type = args->type & LINUX_SOCK_TYPE_MASK; if (bsd_args.type < 0 || bsd_args.type > LINUX_SOCK_MAX) return (EINVAL); + retval_socket = linux_set_socket_flags(args->type & ~LINUX_SOCK_TYPE_MASK, + &bsd_args.type); + if (retval_socket != 0) + return (retval_socket); bsd_args.domain = linux_to_bsd_domain(args->domain); if (bsd_args.domain == -1) return (EAFNOSUPPORT); @@ -676,13 +665,6 @@ linux_socket(struct thread *td, struct linux_socket_args *args) if (retval_socket) return (retval_socket); - retval_socket = linux_set_socket_flags(td, td->td_retval[0], - socket_flags); - if (retval_socket) { - (void)kern_close(td, td->td_retval[0]); - goto out; - } - if (bsd_args.type == SOCK_RAW && (bsd_args.protocol == IPPROTO_RAW || bsd_args.protocol == 0) && bsd_args.domain == PF_INET) { @@ -711,17 +693,10 @@ linux_socket(struct thread *td, struct linux_socket_args *args) } #endif -out: return (retval_socket); } -struct linux_bind_args { - int s; - l_uintptr_t name; - int namelen; -}; - -static int +int linux_bind(struct thread *td, struct linux_bind_args *args) { struct sockaddr *sa; @@ -739,13 +714,6 @@ linux_bind(struct thread *td, struct linux_bind_args *args) return (error); } -struct linux_connect_args { - int s; - l_uintptr_t name; - int namelen; -}; -int linux_connect(struct thread *, struct linux_connect_args *); - int linux_connect(struct thread *td, struct linux_connect_args *args) { @@ -790,12 +758,7 @@ linux_connect(struct thread *td, struct linux_connect_args *args) return (error); } -struct linux_listen_args { - int s; - int backlog; -}; - -static int +int linux_listen(struct thread *td, struct linux_listen_args *args) { struct listen_args /* { @@ -812,43 +775,31 @@ static int linux_accept_common(struct thread *td, int s, l_uintptr_t addr, l_uintptr_t namelen, int flags) { - struct accept_args /* { + struct accept4_args /* { int s; struct sockaddr * __restrict name; socklen_t * __restrict anamelen; + int flags; } */ bsd_args; int error; - if (flags & ~(LINUX_SOCK_CLOEXEC | LINUX_SOCK_NONBLOCK)) - return (EINVAL); - bsd_args.s = s; /* XXX: */ bsd_args.name = (struct sockaddr * __restrict)PTRIN(addr); bsd_args.anamelen = PTRIN(namelen);/* XXX */ - error = sys_accept(td, &bsd_args); + bsd_args.flags = 0; + error = linux_set_socket_flags(flags, &bsd_args.flags); + if (error != 0) + return (error); + error = sys_accept4(td, &bsd_args); bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.name); if (error) { if (error == EFAULT && namelen != sizeof(struct sockaddr_in)) return (EINVAL); return (error); } - - /* - * linux appears not to copy flags from the parent socket to the - * accepted one, so we must clear the flags in the new descriptor - * and apply the requested flags. - */ - error = kern_fcntl(td, td->td_retval[0], F_SETFL, 0); - if (error) - goto out; - error = linux_set_socket_flags(td, td->td_retval[0], flags); - if (error) - goto out; if (addr) error = linux_sa_put(PTRIN(addr)); - -out: if (error) { (void)kern_close(td, td->td_retval[0]); td->td_retval[0] = 0; @@ -856,13 +807,7 @@ out: return (error); } -struct linux_accept_args { - int s; - l_uintptr_t addr; - l_uintptr_t namelen; -}; - -static int +int linux_accept(struct thread *td, struct linux_accept_args *args) { @@ -870,14 +815,7 @@ linux_accept(struct thread *td, struct linux_accept_args *args) args->namelen, 0)); } -struct linux_accept4_args { - int s; - l_uintptr_t addr; - l_uintptr_t namelen; - int flags; -}; - -static int +int linux_accept4(struct thread *td, struct linux_accept4_args *args) { @@ -885,13 +823,7 @@ linux_accept4(struct thread *td, struct linux_accept4_args *args) args->namelen, args->flags)); } -struct linux_getsockname_args { - int s; - l_uintptr_t addr; - l_uintptr_t namelen; -}; - -static int +int linux_getsockname(struct thread *td, struct linux_getsockname_args *args) { struct getsockname_args /* { @@ -915,13 +847,7 @@ linux_getsockname(struct thread *td, struct linux_getsockname_args *args) return (0); } -struct linux_getpeername_args { - int s; - l_uintptr_t addr; - l_uintptr_t namelen; -}; - -static int +int linux_getpeername(struct thread *td, struct linux_getpeername_args *args) { struct getpeername_args /* { @@ -944,14 +870,7 @@ linux_getpeername(struct thread *td, struct linux_getpeername_args *args) return (0); } -struct linux_socketpair_args { - int domain; - int type; - int protocol; - l_uintptr_t rsv; -}; - -static int +int linux_socketpair(struct thread *td, struct linux_socketpair_args *args) { struct socketpair_args /* { @@ -960,20 +879,18 @@ linux_socketpair(struct thread *td, struct linux_socketpair_args *args) int protocol; int *rsv; } */ bsd_args; - int error, socket_flags; - int sv[2]; + int error; bsd_args.domain = linux_to_bsd_domain(args->domain); if (bsd_args.domain != PF_LOCAL) return (EAFNOSUPPORT); - - socket_flags = args->type & ~LINUX_SOCK_TYPE_MASK; - if (socket_flags & ~(LINUX_SOCK_CLOEXEC | LINUX_SOCK_NONBLOCK)) - return (EINVAL); bsd_args.type = args->type & LINUX_SOCK_TYPE_MASK; if (bsd_args.type < 0 || bsd_args.type > LINUX_SOCK_MAX) return (EINVAL); - + error = linux_set_socket_flags(args->type & ~LINUX_SOCK_TYPE_MASK, + &bsd_args.type); + if (error != 0) + return (error); if (args->protocol != 0 && args->protocol != PF_UNIX) /* @@ -986,27 +903,10 @@ linux_socketpair(struct thread *td, struct linux_socketpair_args *args) else bsd_args.protocol = 0; bsd_args.rsv = (int *)PTRIN(args->rsv); - error = kern_socketpair(td, bsd_args.domain, bsd_args.type, - bsd_args.protocol, sv); - if (error) - return (error); - error = linux_set_socket_flags(td, sv[0], socket_flags); - if (error) - goto out; - error = linux_set_socket_flags(td, sv[1], socket_flags); - if (error) - goto out; - - error = copyout(sv, bsd_args.rsv, 2 * sizeof(int)); - -out: - if (error) { - (void)kern_close(td, sv[0]); - (void)kern_close(td, sv[1]); - } - return (error); + return (sys_socketpair(td, &bsd_args)); } +#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) struct linux_send_args { int s; l_uintptr_t msg; @@ -1062,8 +962,9 @@ linux_recv(struct thread *td, struct linux_recv_args *args) bsd_args.fromlenaddr = 0; return (sys_recvfrom(td, &bsd_args)); } +#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ -static int +int linux_sendto(struct thread *td, struct linux_sendto_args *args) { struct msghdr msg; @@ -1087,63 +988,58 @@ linux_sendto(struct thread *td, struct linux_sendto_args *args) return (error); } -struct linux_recvfrom_args { - int s; - l_uintptr_t buf; - int len; - int flags; - l_uintptr_t from; - l_uintptr_t fromlen; -}; - -static int +int linux_recvfrom(struct thread *td, struct linux_recvfrom_args *args) { - struct recvfrom_args /* { - int s; - caddr_t buf; - size_t len; - int flags; - struct sockaddr * __restrict from; - socklen_t * __restrict fromlenaddr; - } */ bsd_args; - size_t len; + struct msghdr msg; + struct iovec aiov; int error; - if ((error = copyin(PTRIN(args->fromlen), &len, sizeof(size_t)))) - return (error); + if (PTRIN(args->fromlen) != NULL) { + error = copyin(PTRIN(args->fromlen), &msg.msg_namelen, + sizeof(msg.msg_namelen)); + if (error != 0) + return (error); - bsd_args.s = args->s; - bsd_args.buf = PTRIN(args->buf); - bsd_args.len = args->len; - bsd_args.flags = linux_to_bsd_msg_flags(args->flags); - /* XXX: */ - bsd_args.from = (struct sockaddr * __restrict)PTRIN(args->from); - bsd_args.fromlenaddr = PTRIN(args->fromlen);/* XXX */ - - linux_to_bsd_sockaddr((struct sockaddr *)bsd_args.from, len); - error = sys_recvfrom(td, &bsd_args); - bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.from); - - if (error) + error = linux_to_bsd_sockaddr((struct sockaddr *)PTRIN(args->from), + msg.msg_namelen); + if (error != 0) + return (error); + } else + msg.msg_namelen = 0; + + msg.msg_name = (struct sockaddr * __restrict)PTRIN(args->from); + msg.msg_iov = &aiov; + msg.msg_iovlen = 1; + aiov.iov_base = PTRIN(args->buf); + aiov.iov_len = args->len; + msg.msg_control = 0; + msg.msg_flags = linux_to_bsd_msg_flags(args->flags); + + error = kern_recvit(td, args->s, &msg, UIO_USERSPACE, NULL); + if (error != 0) return (error); - if (args->from) { - error = linux_sa_put((struct osockaddr *) + + if (PTRIN(args->from) != NULL) { + error = bsd_to_linux_sockaddr((struct sockaddr *) PTRIN(args->from)); - if (error) + if (error != 0) return (error); + + error = linux_sa_put((struct osockaddr *) + PTRIN(args->from)); } - return (0); -} -struct linux_sendmsg_args { - int s; - l_uintptr_t msg; - int flags; -}; + if (PTRIN(args->fromlen) != NULL) + error = copyout(&msg.msg_namelen, PTRIN(args->fromlen), + sizeof(msg.msg_namelen)); + + return (error); +} static int -linux_sendmsg(struct thread *td, struct linux_sendmsg_args *args) +linux_sendmsg_common(struct thread *td, l_int s, struct l_msghdr *msghdr, + l_uint flags) { struct cmsghdr *cmsg; struct cmsgcred cmcred; @@ -1159,8 +1055,8 @@ linux_sendmsg(struct thread *td, struct linux_sendmsg_args *args) void *data; int error; - error = copyin(PTRIN(args->msg), &linux_msg, sizeof(linux_msg)); - if (error) + error = copyin(msghdr, &linux_msg, sizeof(linux_msg)); + if (error != 0) return (error); /* @@ -1174,7 +1070,7 @@ linux_sendmsg(struct thread *td, struct linux_sendmsg_args *args) linux_msg.msg_control = PTROUT(NULL); error = linux_to_bsd_msghdr(&msg, &linux_msg); - if (error) + if (error != 0) return (error); #ifdef COMPAT_LINUX32 @@ -1183,29 +1079,27 @@ linux_sendmsg(struct thread *td, struct linux_sendmsg_args *args) #else error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE); #endif - if (error) + if (error != 0) return (error); control = NULL; cmsg = NULL; if ((ptr_cmsg = LINUX_CMSG_FIRSTHDR(&linux_msg)) != NULL) { - error = kern_getsockname(td, args->s, &sa, &datalen); - if (error) + error = kern_getsockname(td, s, &sa, &datalen); + if (error != 0) goto bad; sa_family = sa->sa_family; free(sa, M_SONAME); error = ENOBUFS; - cmsg = malloc(CMSG_HDRSZ, M_TEMP, M_WAITOK | M_ZERO); + cmsg = malloc(CMSG_HDRSZ, M_LINUX, M_WAITOK|M_ZERO); control = m_get(M_WAITOK, MT_CONTROL); - if (control == NULL) - goto bad; do { error = copyin(ptr_cmsg, &linux_cmsg, sizeof(struct l_cmsghdr)); - if (error) + if (error != 0) goto bad; error = EINVAL; @@ -1269,28 +1163,60 @@ linux_sendmsg(struct thread *td, struct linux_sendmsg_args *args) msg.msg_iov = iov; msg.msg_flags = 0; - error = linux_sendit(td, args->s, &msg, args->flags, control, - UIO_USERSPACE); + error = linux_sendit(td, s, &msg, flags, control, UIO_USERSPACE); bad: + m_freem(control); free(iov, M_IOV); if (cmsg) - free(cmsg, M_TEMP); + free(cmsg, M_LINUX); return (error); } -struct linux_recvmsg_args { - int s; - l_uintptr_t msg; - int flags; -}; +int +linux_sendmsg(struct thread *td, struct linux_sendmsg_args *args) +{ + + return (linux_sendmsg_common(td, args->s, PTRIN(args->msg), + args->flags)); +} + +int +linux_sendmmsg(struct thread *td, struct linux_sendmmsg_args *args) +{ + struct l_mmsghdr *msg; + l_uint retval; + int error, datagrams; + + if (args->vlen > UIO_MAXIOV) + args->vlen = UIO_MAXIOV; + + msg = PTRIN(args->msg); + datagrams = 0; + while (datagrams < args->vlen) { + error = linux_sendmsg_common(td, args->s, &msg->msg_hdr, + args->flags); + if (error != 0) + break; + + retval = td->td_retval[0]; + error = copyout(&retval, &msg->msg_len, sizeof(msg->msg_len)); + if (error != 0) + break; + ++msg; + ++datagrams; + } + if (error == 0) + td->td_retval[0] = datagrams; + return (error); +} static int -linux_recvmsg(struct thread *td, struct linux_recvmsg_args *args) +linux_recvmsg_common(struct thread *td, l_int s, struct l_msghdr *msghdr, + l_uint flags, struct msghdr *msg) { struct cmsghdr *cm; struct cmsgcred *cmcred; - struct msghdr msg; struct l_cmsghdr *linux_cmsg = NULL; struct l_ucred linux_ucred; socklen_t datalen, outlen; @@ -1298,55 +1224,57 @@ linux_recvmsg(struct thread *td, struct linux_recvmsg_args *args) struct iovec *iov, *uiov; struct mbuf *control = NULL; struct mbuf **controlp; + struct timeval *ftmvl; + l_timeval ltmvl; caddr_t outbuf; void *data; int error, i, fd, fds, *fdp; - error = copyin(PTRIN(args->msg), &linux_msg, sizeof(linux_msg)); - if (error) + error = copyin(msghdr, &linux_msg, sizeof(linux_msg)); + if (error != 0) return (error); - error = linux_to_bsd_msghdr(&msg, &linux_msg); - if (error) + error = linux_to_bsd_msghdr(msg, &linux_msg); + if (error != 0) return (error); #ifdef COMPAT_LINUX32 - error = linux32_copyiniov(PTRIN(msg.msg_iov), msg.msg_iovlen, + error = linux32_copyiniov(PTRIN(msg->msg_iov), msg->msg_iovlen, &iov, EMSGSIZE); #else - error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE); + error = copyiniov(msg->msg_iov, msg->msg_iovlen, &iov, EMSGSIZE); #endif - if (error) + if (error != 0) return (error); - if (msg.msg_name) { - error = linux_to_bsd_sockaddr((struct sockaddr *)msg.msg_name, - msg.msg_namelen); - if (error) + if (msg->msg_name) { + error = linux_to_bsd_sockaddr((struct sockaddr *)msg->msg_name, + msg->msg_namelen); + if (error != 0) goto bad; } - uiov = msg.msg_iov; - msg.msg_iov = iov; - controlp = (msg.msg_control != NULL) ? &control : NULL; - error = kern_recvit(td, args->s, &msg, UIO_USERSPACE, controlp); - msg.msg_iov = uiov; - if (error) + uiov = msg->msg_iov; + msg->msg_iov = iov; + controlp = (msg->msg_control != NULL) ? &control : NULL; + error = kern_recvit(td, s, msg, UIO_USERSPACE, controlp); + msg->msg_iov = uiov; + if (error != 0) goto bad; - error = bsd_to_linux_msghdr(&msg, &linux_msg); - if (error) + error = bsd_to_linux_msghdr(msg, &linux_msg); + if (error != 0) goto bad; if (linux_msg.msg_name) { error = bsd_to_linux_sockaddr((struct sockaddr *) PTRIN(linux_msg.msg_name)); - if (error) + if (error != 0) goto bad; } if (linux_msg.msg_name && linux_msg.msg_namelen > 2) { error = linux_sa_put(PTRIN(linux_msg.msg_name)); - if (error) + if (error != 0) goto bad; } @@ -1354,12 +1282,12 @@ linux_recvmsg(struct thread *td, struct linux_recvmsg_args *args) outlen = 0; if (control) { - linux_cmsg = malloc(L_CMSG_HDRSZ, M_TEMP, M_WAITOK | M_ZERO); + linux_cmsg = malloc(L_CMSG_HDRSZ, M_LINUX, M_WAITOK | M_ZERO); - msg.msg_control = mtod(control, struct cmsghdr *); - msg.msg_controllen = control->m_len; + msg->msg_control = mtod(control, struct cmsghdr *); + msg->msg_controllen = control->m_len; - cm = CMSG_FIRSTHDR(&msg); + cm = CMSG_FIRSTHDR(msg); while (cm != NULL) { linux_cmsg->cmsg_type = @@ -1379,7 +1307,7 @@ linux_recvmsg(struct thread *td, struct linux_recvmsg_args *args) switch (cm->cmsg_type) { case SCM_RIGHTS: - if (args->flags & LINUX_MSG_CMSG_CLOEXEC) { + if (flags & LINUX_MSG_CMSG_CLOEXEC) { fds = datalen / sizeof(int); fdp = data; for (i = 0; i < fds; i++) { @@ -1408,6 +1336,18 @@ linux_recvmsg(struct thread *td, struct linux_recvmsg_args *args) data = &linux_ucred; datalen = sizeof(linux_ucred); break; + + case SCM_TIMESTAMP: + if (datalen != sizeof(struct timeval)) { + error = EMSGSIZE; + goto bad; + } + ftmvl = (struct timeval *)data; + ltmvl.tv_sec = ftmvl->tv_sec; + ltmvl.tv_usec = ftmvl->tv_usec; + data = <mvl; + datalen = sizeof(ltmvl); + break; } if (outlen + LINUX_CMSG_LEN(datalen) > @@ -1436,28 +1376,92 @@ linux_recvmsg(struct thread *td, struct linux_recvmsg_args *args) outbuf += LINUX_CMSG_ALIGN(datalen); outlen += LINUX_CMSG_LEN(datalen); - cm = CMSG_NXTHDR(&msg, cm); + cm = CMSG_NXTHDR(msg, cm); } } out: linux_msg.msg_controllen = outlen; - error = copyout(&linux_msg, PTRIN(args->msg), sizeof(linux_msg)); + error = copyout(&linux_msg, msghdr, sizeof(linux_msg)); bad: free(iov, M_IOV); m_freem(control); - free(linux_cmsg, M_TEMP); + free(linux_cmsg, M_LINUX); return (error); } -struct linux_shutdown_args { - int s; - int how; -}; +int +linux_recvmsg(struct thread *td, struct linux_recvmsg_args *args) +{ + struct msghdr bsd_msg; -static int + return (linux_recvmsg_common(td, args->s, PTRIN(args->msg), + args->flags, &bsd_msg)); +} + +int +linux_recvmmsg(struct thread *td, struct linux_recvmmsg_args *args) +{ + struct l_mmsghdr *msg; + struct msghdr bsd_msg; + struct l_timespec lts; + struct timespec ts, tts; + l_uint retval; + int error, datagrams; + + if (args->timeout) { + error = copyin(args->timeout, <s, sizeof(struct l_timespec)); + if (error != 0) + return (error); + error = linux_to_native_timespec(&ts, <s); + if (error != 0) + return (error); + getnanotime(&tts); + timespecadd(&tts, &ts); + } + + msg = PTRIN(args->msg); + datagrams = 0; + while (datagrams < args->vlen) { + error = linux_recvmsg_common(td, args->s, &msg->msg_hdr, + args->flags & ~LINUX_MSG_WAITFORONE, &bsd_msg); + if (error != 0) + break; + + retval = td->td_retval[0]; + error = copyout(&retval, &msg->msg_len, sizeof(msg->msg_len)); + if (error != 0) + break; + ++msg; + ++datagrams; + + /* + * MSG_WAITFORONE turns on MSG_DONTWAIT after one packet. + */ + if (args->flags & LINUX_MSG_WAITFORONE) + args->flags |= LINUX_MSG_DONTWAIT; + + /* + * See BUGS section of recvmmsg(2). + */ + if (args->timeout) { + getnanotime(&ts); + timespecsub(&ts, &tts); + if (!timespecisset(&ts) || ts.tv_sec > 0) + break; + } + /* Out of band data, return right away. */ + if (bsd_msg.msg_flags & MSG_OOB) + break; + } + if (error == 0) + td->td_retval[0] = datagrams; + return (error); +} + +int linux_shutdown(struct thread *td, struct linux_shutdown_args *args) { struct shutdown_args /* { @@ -1470,15 +1474,7 @@ linux_shutdown(struct thread *td, struct linux_shutdown_args *args) return (sys_shutdown(td, &bsd_args)); } -struct linux_setsockopt_args { - int s; - int level; - int optname; - l_uintptr_t optval; - int optlen; -}; - -static int +int linux_setsockopt(struct thread *td, struct linux_setsockopt_args *args) { struct setsockopt_args /* { @@ -1543,15 +1539,7 @@ linux_setsockopt(struct thread *td, struct linux_setsockopt_args *args) return (error); } -struct linux_getsockopt_args { - int s; - int level; - int optname; - l_uintptr_t optval; - l_uintptr_t optlen; -}; - -static int +int linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args) { struct getsockopt_args /* { @@ -1635,6 +1623,8 @@ linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args) return (error); } +#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) + /* Argument list sizes for linux_socketcall */ #define LINUX_AL(x) ((x) * sizeof(l_ulong)) @@ -1649,7 +1639,8 @@ static const unsigned char lxs_args[] = { LINUX_AL(6) /* recvfrom */, LINUX_AL(2) /* shutdown */, LINUX_AL(5) /* setsockopt */, LINUX_AL(5) /* getsockopt */, LINUX_AL(3) /* sendmsg */, LINUX_AL(3) /* recvmsg */, - LINUX_AL(4) /* accept4 */ + LINUX_AL(4) /* accept4 */, LINUX_AL(5) /* recvmmsg */, + LINUX_AL(4) /* sendmmsg */ }; #define LINUX_AL_SIZE sizeof(lxs_args) / sizeof(lxs_args[0]) - 1 @@ -1705,8 +1696,13 @@ linux_socketcall(struct thread *td, struct linux_socketcall_args *args) return (linux_recvmsg(td, arg)); case LINUX_ACCEPT4: return (linux_accept4(td, arg)); + case LINUX_RECVMMSG: + return (linux_recvmmsg(td, arg)); + case LINUX_SENDMMSG: + return (linux_sendmmsg(td, arg)); } uprintf("LINUX: 'socket' typ=%d not implemented\n", args->what); return (ENOSYS); } +#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ diff --git a/sys/compat/linux/linux_socket.h b/sys/compat/linux/linux_socket.h index e6efadb..b32a969 100644 --- a/sys/compat/linux/linux_socket.h +++ b/sys/compat/linux/linux_socket.h @@ -48,12 +48,36 @@ #define LINUX_MSG_RST 0x1000 #define LINUX_MSG_ERRQUEUE 0x2000 #define LINUX_MSG_NOSIGNAL 0x4000 +#define LINUX_MSG_WAITFORONE 0x10000 #define LINUX_MSG_CMSG_CLOEXEC 0x40000000 /* Socket-level control message types */ #define LINUX_SCM_RIGHTS 0x01 -#define LINUX_SCM_CREDENTIALS 0x02 +#define LINUX_SCM_CREDENTIALS 0x02 +#define LINUX_SCM_TIMESTAMP 0x1D + +struct l_msghdr { + l_uintptr_t msg_name; + l_int msg_namelen; + l_uintptr_t msg_iov; + l_size_t msg_iovlen; + l_uintptr_t msg_control; + l_size_t msg_controllen; + l_uint msg_flags; +}; + +struct l_mmsghdr { + struct l_msghdr msg_hdr; + l_uint msg_len; + +}; + +struct l_cmsghdr { + l_size_t cmsg_len; + l_int cmsg_level; + l_int cmsg_type; +}; /* Ancilliary data object information macros */ @@ -116,6 +140,133 @@ struct l_ucred { uint32_t gid; }; +#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) + +struct linux_sendto_args { + int s; + l_uintptr_t msg; + int len; + int flags; + l_uintptr_t to; + int tolen; +}; + +struct linux_socket_args { + int domain; + int type; + int protocol; +}; + +struct linux_bind_args { + int s; + l_uintptr_t name; + int namelen; +}; + +struct linux_connect_args { + int s; + l_uintptr_t name; + int namelen; +}; + +struct linux_listen_args { + int s; + int backlog; +}; + +struct linux_accept_args { + int s; + l_uintptr_t addr; + l_uintptr_t namelen; +}; + +struct linux_accept4_args { + int s; + l_uintptr_t addr; + l_uintptr_t namelen; + int flags; +}; + +struct linux_getsockname_args { + int s; + l_uintptr_t addr; + l_uintptr_t namelen; +}; + +struct linux_getpeername_args { + int s; + l_uintptr_t addr; + l_uintptr_t namelen; +}; + +struct linux_socketpair_args { + int domain; + int type; + int protocol; + l_uintptr_t rsv; +}; + +struct linux_recvfrom_args { + int s; + l_uintptr_t buf; + int len; + int flags; + l_uintptr_t from; + l_uintptr_t fromlen; +}; + +struct linux_sendmsg_args { + int s; + l_uintptr_t msg; + int flags; +}; + +struct linux_recvmsg_args { + int s; + l_uintptr_t msg; + int flags; +}; + +struct linux_shutdown_args { + int s; + int how; +}; + +struct linux_setsockopt_args { + int s; + int level; + int optname; + l_uintptr_t optval; + int optlen; +}; + +struct linux_getsockopt_args { + int s; + int level; + int optname; + l_uintptr_t optval; + l_uintptr_t optlen; +}; + +int linux_socket(struct thread *td, struct linux_socket_args *args); +int linux_bind(struct thread *td, struct linux_bind_args *args); +int linux_connect(struct thread *, struct linux_connect_args *); +int linux_listen(struct thread *td, struct linux_listen_args *args); +int linux_accept(struct thread *td, struct linux_accept_args *args); +int linux_accept4(struct thread *td, struct linux_accept4_args *args); +int linux_getsockname(struct thread *td, struct linux_getsockname_args *args); +int linux_getpeername(struct thread *td, struct linux_getpeername_args *args); +int linux_socketpair(struct thread *td, struct linux_socketpair_args *args); +int linux_sendto(struct thread *td, struct linux_sendto_args *args); +int linux_recvfrom(struct thread *td, struct linux_recvfrom_args *args); +int linux_sendmsg(struct thread *td, struct linux_sendmsg_args *args); +int linux_recvmsg(struct thread *td, struct linux_recvmsg_args *args); +int linux_shutdown(struct thread *td, struct linux_shutdown_args *args); +int linux_setsockopt(struct thread *td, struct linux_setsockopt_args *args); +int linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args); + +#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ + /* Operations for socketcall */ #define LINUX_SOCKET 1 @@ -136,6 +287,8 @@ struct l_ucred { #define LINUX_SENDMSG 16 #define LINUX_RECVMSG 17 #define LINUX_ACCEPT4 18 +#define LINUX_RECVMMSG 19 +#define LINUX_SENDMMSG 20 /* Socket options */ #define LINUX_IP_TOS 1 diff --git a/sys/compat/linux/linux_stats.c b/sys/compat/linux/linux_stats.c index 2e05c85..f96acc0 100644 --- a/sys/compat/linux/linux_stats.c +++ b/sys/compat/linux/linux_stats.c @@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$"); #include "opt_compat.h" #include <sys/param.h> +#include <sys/capsicum.h> #include <sys/dirent.h> #include <sys/file.h> #include <sys/filedesc.h> @@ -58,7 +59,6 @@ __FBSDID("$FreeBSD$"); #include <compat/linux/linux_util.h> #include <compat/linux/linux_file.h> -#define LINUX_SHMFS_MAGIC 0x01021994 static void translate_vnhook_major_minor(struct vnode *vp, struct stat *sb) @@ -251,6 +251,7 @@ linux_newfstat(struct thread *td, struct linux_newfstat_args *args) return (error); } +#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) static int stat_copyout(struct stat *buf, void *ubuf) { @@ -325,19 +326,19 @@ linux_lstat(struct thread *td, struct linux_lstat_args *args) LFREEPATH(path); return(stat_copyout(&buf, args->up)); } +#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ -/* XXX - All fields of type l_int are defined as l_long on i386 */ struct l_statfs { - l_int f_type; - l_int f_bsize; - l_int f_blocks; - l_int f_bfree; - l_int f_bavail; - l_int f_files; - l_int f_ffree; + l_long f_type; + l_long f_bsize; + l_long f_blocks; + l_long f_bfree; + l_long f_bavail; + l_long f_files; + l_long f_ffree; l_fsid_t f_fsid; - l_int f_namelen; - l_int f_spare[6]; + l_long f_namelen; + l_long f_spare[6]; }; #define LINUX_CODA_SUPER_MAGIC 0x73757245L @@ -351,6 +352,7 @@ struct l_statfs { #define LINUX_PROC_SUPER_MAGIC 0x9fa0L #define LINUX_UFS_SUPER_MAGIC 0x00011954L /* XXX - UFS_MAGIC in Linux */ #define LINUX_DEVFS_SUPER_MAGIC 0x1373L +#define LINUX_SHMFS_MAGIC 0x01021994 static long bsd_to_linux_ftype(const char *fstypename) @@ -368,6 +370,7 @@ bsd_to_linux_ftype(const char *fstypename) {"hpfs", LINUX_HPFS_SUPER_MAGIC}, {"coda", LINUX_CODA_SUPER_MAGIC}, {"devfs", LINUX_DEVFS_SUPER_MAGIC}, + {"tmpfs", LINUX_SHMFS_MAGIC}, {NULL, 0L}}; for (i = 0; b2l_tbl[i].bsd_name != NULL; i++) @@ -399,7 +402,7 @@ linux_statfs(struct thread *td, struct linux_statfs_args *args) struct l_statfs linux_statfs; struct statfs bsd_statfs; char *path; - int error, dev_shm; + int error; LCONVPATHEXIST(td, args->path, &path); @@ -407,20 +410,15 @@ linux_statfs(struct thread *td, struct linux_statfs_args *args) if (ldebug(statfs)) printf(ARGS(statfs, "%s, *"), path); #endif - dev_shm = 0; error = kern_statfs(td, path, UIO_SYSSPACE, &bsd_statfs); - if (strncmp(path, "/dev/shm", sizeof("/dev/shm") - 1) == 0) - dev_shm = (path[8] == '\0' - || (path[8] == '/' && path[9] == '\0')); LFREEPATH(path); if (error) return (error); bsd_to_linux_statfs(&bsd_statfs, &linux_statfs); - if (dev_shm) - linux_statfs.f_type = LINUX_SHMFS_MAGIC; return copyout(&linux_statfs, args->buf, sizeof(linux_statfs)); } +#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) static void bsd_to_linux_statfs64(struct statfs *bsd_statfs, struct l_statfs64 *linux_statfs) { @@ -461,6 +459,7 @@ linux_statfs64(struct thread *td, struct linux_statfs64_args *args) bsd_to_linux_statfs64(&bsd_statfs, &linux_statfs); return copyout(&linux_statfs, args->buf, sizeof(linux_statfs)); } +#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ int linux_fstatfs(struct thread *td, struct linux_fstatfs_args *args) @@ -493,7 +492,7 @@ linux_ustat(struct thread *td, struct linux_ustat_args *args) { #ifdef DEBUG if (ldebug(ustat)) - printf(ARGS(ustat, "%d, *"), args->dev); + printf(ARGS(ustat, "%ju, *"), (uintmax_t)args->dev); #endif return (EOPNOTSUPP); @@ -624,4 +623,74 @@ linux_fstatat64(struct thread *td, struct linux_fstatat64_args *args) return (error); } +#else /* __amd64__ && !COMPAT_LINUX32 */ + +int +linux_newfstatat(struct thread *td, struct linux_newfstatat_args *args) +{ + char *path; + int error, dfd, flag; + struct stat buf; + + if (args->flag & ~LINUX_AT_SYMLINK_NOFOLLOW) + return (EINVAL); + flag = (args->flag & LINUX_AT_SYMLINK_NOFOLLOW) ? + AT_SYMLINK_NOFOLLOW : 0; + + dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd; + LCONVPATHEXIST_AT(td, args->pathname, &path, dfd); + +#ifdef DEBUG + if (ldebug(newfstatat)) + printf(ARGS(newfstatat, "%i, %s, %i"), args->dfd, path, args->flag); +#endif + + error = linux_kern_statat(td, flag, dfd, path, UIO_SYSSPACE, &buf); + if (error == 0) + error = newstat_copyout(&buf, args->statbuf); + LFREEPATH(path); + + return (error); +} + #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ + +int +linux_syncfs(struct thread *td, struct linux_syncfs_args *args) +{ + cap_rights_t rights; + struct mount *mp; + struct vnode *vp; + int error, save; + + error = fgetvp(td, args->fd, cap_rights_init(&rights, CAP_FSYNC), &vp); + if (error != 0) + /* + * Linux syncfs() returns only EBADF, however fgetvp() + * can return EINVAL in case of file descriptor does + * not represent a vnode. XXX. + */ + return (error); + + mp = vp->v_mount; + mtx_lock(&mountlist_mtx); + error = vfs_busy(mp, MBF_MNTLSTLOCK); + if (error != 0) { + /* See comment above. */ + mtx_unlock(&mountlist_mtx); + goto out; + } + if ((mp->mnt_flag & MNT_RDONLY) == 0 && + vn_start_write(NULL, &mp, V_NOWAIT) == 0) { + save = curthread_pflags_set(TDP_SYNCIO); + vfs_msync(mp, MNT_NOWAIT); + VFS_SYNC(mp, MNT_NOWAIT); + curthread_pflags_restore(save); + vn_finished_write(mp); + } + vfs_unbusy(mp); + + out: + vrele(vp); + return (error); +} diff --git a/sys/compat/linux/linux_sysctl.c b/sys/compat/linux/linux_sysctl.c index decd8f8..27b7a3d 100644 --- a/sys/compat/linux/linux_sysctl.c +++ b/sys/compat/linux/linux_sysctl.c @@ -141,12 +141,12 @@ linux_sysctl(struct thread *td, struct linux_sysctl_args *args) return (ENOTDIR); } - mib = malloc(la.nlen * sizeof(l_int), M_TEMP, M_WAITOK); + mib = malloc(la.nlen * sizeof(l_int), M_LINUX, M_WAITOK); error = copyin(PTRIN(la.name), mib, la.nlen * sizeof(l_int)); if (error) { LIN_SDT_PROBE1(sysctl, linux_sysctl, copyin_error, error); LIN_SDT_PROBE1(sysctl, linux_sysctl, return, error); - free(mib, M_TEMP); + free(mib, M_LINUX); return (error); } @@ -158,7 +158,7 @@ linux_sysctl(struct thread *td, struct linux_sysctl_args *args) switch (mib[1]) { case LINUX_KERN_VERSION: error = handle_string(&la, version); - free(mib, M_TEMP); + free(mib, M_LINUX); LIN_SDT_PROBE1(sysctl, linux_sysctl, return, error); return (error); default: @@ -187,7 +187,7 @@ linux_sysctl(struct thread *td, struct linux_sysctl_args *args) sbuf_delete(sb); } - free(mib, M_TEMP); + free(mib, M_LINUX); LIN_SDT_PROBE1(sysctl, linux_sysctl, return, ENOTDIR); return (ENOTDIR); diff --git a/sys/compat/linux/linux_time.c b/sys/compat/linux/linux_time.c index e03af00..663ac92 100644 --- a/sys/compat/linux/linux_time.c +++ b/sys/compat/linux/linux_time.c @@ -40,8 +40,11 @@ __KERNEL_RCSID(0, "$NetBSD: linux_time.c,v 1.14 2006/05/14 03:40:54 christos Exp #include <sys/param.h> #include <sys/kernel.h> +#include <sys/lock.h> #include <sys/ucred.h> #include <sys/mount.h> +#include <sys/mutex.h> +#include <sys/resourcevar.h> #include <sys/sdt.h> #include <sys/signal.h> #include <sys/stdint.h> @@ -60,7 +63,7 @@ __KERNEL_RCSID(0, "$NetBSD: linux_time.c,v 1.14 2006/05/14 03:40:54 christos Exp #endif #include <compat/linux/linux_dtrace.h> -#include <compat/linux/linux_misc.h> +#include <compat/linux/linux_timer.h> /* DTrace init */ LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE); @@ -103,27 +106,20 @@ LIN_SDT_PROBE_DEFINE1(time, linux_clock_getres, return, "int"); LIN_SDT_PROBE_DEFINE2(time, linux_nanosleep, entry, "const struct l_timespec *", "struct l_timespec *"); LIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, conversion_error, "int"); -LIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, nanosleep_error, "int"); LIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, copyout_error, "int"); LIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, copyin_error, "int"); LIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, return, "int"); LIN_SDT_PROBE_DEFINE4(time, linux_clock_nanosleep, entry, "clockid_t", "int", "struct l_timespec *", "struct l_timespec *"); LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, conversion_error, "int"); -LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, nanosleep_error, "int"); LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, copyout_error, "int"); LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, copyin_error, "int"); LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, unsupported_flags, "int"); LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, unsupported_clockid, "int"); LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, return, "int"); -static void native_to_linux_timespec(struct l_timespec *, - struct timespec *); -static int linux_to_native_timespec(struct timespec *, - struct l_timespec *); -static int linux_to_native_clockid(clockid_t *, clockid_t); -static void +void native_to_linux_timespec(struct l_timespec *ltp, struct timespec *ntp) { @@ -135,7 +131,7 @@ native_to_linux_timespec(struct l_timespec *ltp, struct timespec *ntp) LIN_SDT_PROBE0(time, native_to_linux_timespec, return); } -static int +int linux_to_native_timespec(struct timespec *ntp, struct l_timespec *ltp) { @@ -152,12 +148,26 @@ linux_to_native_timespec(struct timespec *ntp, struct l_timespec *ltp) return (0); } -static int +int linux_to_native_clockid(clockid_t *n, clockid_t l) { LIN_SDT_PROBE2(time, linux_to_native_clockid, entry, n, l); + if (l < 0) { + /* cpu-clock */ + if ((l & LINUX_CLOCKFD_MASK) == LINUX_CLOCKFD) + return (EINVAL); + if (LINUX_CPUCLOCK_WHICH(l) >= LINUX_CPUCLOCK_MAX) + return (EINVAL); + + if (LINUX_CPUCLOCK_PERTHREAD(l)) + *n = CLOCK_THREAD_CPUTIME_ID; + else + *n = CLOCK_PROCESS_CPUTIME_ID; + return (0); + } + switch (l) { case LINUX_CLOCK_REALTIME: *n = CLOCK_REALTIME; @@ -165,21 +175,27 @@ linux_to_native_clockid(clockid_t *n, clockid_t l) case LINUX_CLOCK_MONOTONIC: *n = CLOCK_MONOTONIC; break; - case LINUX_CLOCK_PROCESS_CPUTIME_ID: - case LINUX_CLOCK_THREAD_CPUTIME_ID: - case LINUX_CLOCK_REALTIME_HR: - case LINUX_CLOCK_MONOTONIC_HR: + case LINUX_CLOCK_REALTIME_COARSE: + *n = CLOCK_REALTIME_FAST; + break; + case LINUX_CLOCK_MONOTONIC_COARSE: + *n = CLOCK_MONOTONIC_FAST; + break; + case LINUX_CLOCK_MONOTONIC_RAW: + case LINUX_CLOCK_BOOTTIME: + case LINUX_CLOCK_REALTIME_ALARM: + case LINUX_CLOCK_BOOTTIME_ALARM: + case LINUX_CLOCK_SGI_CYCLE: + case LINUX_CLOCK_TAI: LIN_SDT_PROBE1(time, linux_to_native_clockid, unsupported_clockid, l); LIN_SDT_PROBE1(time, linux_to_native_clockid, return, EINVAL); return (EINVAL); - break; default: LIN_SDT_PROBE1(time, linux_to_native_clockid, unknown_clockid, l); LIN_SDT_PROBE1(time, linux_to_native_clockid, return, EINVAL); return (EINVAL); - break; } LIN_SDT_PROBE1(time, linux_to_native_clockid, return, 0); @@ -190,9 +206,14 @@ int linux_clock_gettime(struct thread *td, struct linux_clock_gettime_args *args) { struct l_timespec lts; - int error; - clockid_t nwhich = 0; /* XXX: GCC */ struct timespec tp; + struct rusage ru; + struct thread *targettd; + struct proc *p; + int error, clockwhich; + clockid_t nwhich = 0; /* XXX: GCC */ + pid_t pid; + lwpid_t tid; LIN_SDT_PROBE2(time, linux_clock_gettime, entry, args->which, args->tp); @@ -203,7 +224,100 @@ linux_clock_gettime(struct thread *td, struct linux_clock_gettime_args *args) LIN_SDT_PROBE1(time, linux_clock_gettime, return, error); return (error); } - error = kern_clock_gettime(td, nwhich, &tp); + + switch (nwhich) { + case CLOCK_PROCESS_CPUTIME_ID: + clockwhich = LINUX_CPUCLOCK_WHICH(args->which); + pid = LINUX_CPUCLOCK_ID(args->which); + if (pid == 0) { + p = td->td_proc; + PROC_LOCK(p); + } else { + error = pget(pid, PGET_CANSEE, &p); + if (error != 0) + return (EINVAL); + } + switch (clockwhich) { + case LINUX_CPUCLOCK_PROF: + PROC_STATLOCK(p); + calcru(p, &ru.ru_utime, &ru.ru_stime); + PROC_STATUNLOCK(p); + PROC_UNLOCK(p); + timevaladd(&ru.ru_utime, &ru.ru_stime); + TIMEVAL_TO_TIMESPEC(&ru.ru_utime, &tp); + break; + case LINUX_CPUCLOCK_VIRT: + PROC_STATLOCK(p); + calcru(p, &ru.ru_utime, &ru.ru_stime); + PROC_STATUNLOCK(p); + PROC_UNLOCK(p); + TIMEVAL_TO_TIMESPEC(&ru.ru_utime, &tp); + break; + case LINUX_CPUCLOCK_SCHED: + PROC_UNLOCK(p); + error = kern_clock_getcpuclockid2(td, pid, + CPUCLOCK_WHICH_PID, &nwhich); + if (error != 0) + return (EINVAL); + error = kern_clock_gettime(td, nwhich, &tp); + break; + default: + PROC_UNLOCK(p); + return (EINVAL); + } + + break; + + case CLOCK_THREAD_CPUTIME_ID: + clockwhich = LINUX_CPUCLOCK_WHICH(args->which); + p = td->td_proc; + tid = LINUX_CPUCLOCK_ID(args->which); + if (tid == 0) { + targettd = td; + PROC_LOCK(p); + } else { + targettd = tdfind(tid, p->p_pid); + if (targettd == NULL) + return (EINVAL); + } + switch (clockwhich) { + case LINUX_CPUCLOCK_PROF: + PROC_STATLOCK(p); + thread_lock(targettd); + rufetchtd(targettd, &ru); + thread_unlock(targettd); + PROC_STATUNLOCK(p); + PROC_UNLOCK(p); + timevaladd(&ru.ru_utime, &ru.ru_stime); + TIMEVAL_TO_TIMESPEC(&ru.ru_utime, &tp); + break; + case LINUX_CPUCLOCK_VIRT: + PROC_STATLOCK(p); + thread_lock(targettd); + rufetchtd(targettd, &ru); + thread_unlock(targettd); + PROC_STATUNLOCK(p); + PROC_UNLOCK(p); + TIMEVAL_TO_TIMESPEC(&ru.ru_utime, &tp); + break; + case LINUX_CPUCLOCK_SCHED: + error = kern_clock_getcpuclockid2(td, tid, + CPUCLOCK_WHICH_TID, &nwhich); + PROC_UNLOCK(p); + if (error != 0) + return (EINVAL); + error = kern_clock_gettime(td, nwhich, &tp); + break; + default: + PROC_UNLOCK(p); + return (EINVAL); + } + break; + + default: + error = kern_clock_gettime(td, nwhich, &tp); + break; + } if (error != 0) { LIN_SDT_PROBE1(time, linux_clock_gettime, gettime_error, error); LIN_SDT_PROBE1(time, linux_clock_gettime, return, error); @@ -261,19 +375,16 @@ linux_clock_settime(struct thread *td, struct linux_clock_settime_args *args) int linux_clock_getres(struct thread *td, struct linux_clock_getres_args *args) { + struct proc *p; struct timespec ts; struct l_timespec lts; - int error; + int error, clockwhich; clockid_t nwhich = 0; /* XXX: GCC */ + pid_t pid; + lwpid_t tid; LIN_SDT_PROBE2(time, linux_clock_getres, entry, args->which, args->tp); - if (args->tp == NULL) { - LIN_SDT_PROBE0(time, linux_clock_getres, nullcall); - LIN_SDT_PROBE1(time, linux_clock_getres, return, 0); - return (0); - } - error = linux_to_native_clockid(&nwhich, args->which); if (error != 0) { LIN_SDT_PROBE1(time, linux_clock_getres, conversion_error, @@ -281,6 +392,59 @@ linux_clock_getres(struct thread *td, struct linux_clock_getres_args *args) LIN_SDT_PROBE1(time, linux_clock_getres, return, error); return (error); } + + /* + * Check user supplied clock id in case of per-process + * or thread-specific cpu-time clock. + */ + switch (nwhich) { + case CLOCK_THREAD_CPUTIME_ID: + tid = LINUX_CPUCLOCK_ID(args->which); + if (tid != 0) { + p = td->td_proc; + if (tdfind(tid, p->p_pid) == NULL) + return (ESRCH); + PROC_UNLOCK(p); + } + break; + case CLOCK_PROCESS_CPUTIME_ID: + pid = LINUX_CPUCLOCK_ID(args->which); + if (pid != 0) { + error = pget(pid, PGET_CANSEE, &p); + if (error != 0) + return (EINVAL); + PROC_UNLOCK(p); + } + break; + } + + if (args->tp == NULL) { + LIN_SDT_PROBE0(time, linux_clock_getres, nullcall); + LIN_SDT_PROBE1(time, linux_clock_getres, return, 0); + return (0); + } + + switch (nwhich) { + case CLOCK_THREAD_CPUTIME_ID: + case CLOCK_PROCESS_CPUTIME_ID: + clockwhich = LINUX_CPUCLOCK_WHICH(args->which); + switch (clockwhich) { + case LINUX_CPUCLOCK_PROF: + nwhich = CLOCK_PROF; + break; + case LINUX_CPUCLOCK_VIRT: + nwhich = CLOCK_VIRTUAL; + break; + case LINUX_CPUCLOCK_SCHED: + break; + default: + return (EINVAL); + } + break; + + default: + break; + } error = kern_clock_getres(td, nwhich, &ts); if (error != 0) { LIN_SDT_PROBE1(time, linux_clock_getres, getres_error, error); @@ -303,7 +467,7 @@ linux_nanosleep(struct thread *td, struct linux_nanosleep_args *args) struct timespec *rmtp; struct l_timespec lrqts, lrmts; struct timespec rqts, rmts; - int error; + int error, error2; LIN_SDT_PROBE2(time, linux_nanosleep, entry, args->rqtp, args->rmtp); @@ -315,9 +479,9 @@ linux_nanosleep(struct thread *td, struct linux_nanosleep_args *args) } if (args->rmtp != NULL) - rmtp = &rmts; + rmtp = &rmts; else - rmtp = NULL; + rmtp = NULL; error = linux_to_native_timespec(&rqts, &lrqts); if (error != 0) { @@ -326,25 +490,19 @@ linux_nanosleep(struct thread *td, struct linux_nanosleep_args *args) return (error); } error = kern_nanosleep(td, &rqts, rmtp); - if (error != 0) { - LIN_SDT_PROBE1(time, linux_nanosleep, nanosleep_error, error); - LIN_SDT_PROBE1(time, linux_nanosleep, return, error); - return (error); - } - if (args->rmtp != NULL) { - native_to_linux_timespec(&lrmts, rmtp); - error = copyout(&lrmts, args->rmtp, sizeof(lrmts)); - if (error != 0) { + native_to_linux_timespec(&lrmts, rmtp); + error2 = copyout(&lrmts, args->rmtp, sizeof(lrmts)); + if (error2 != 0) { LIN_SDT_PROBE1(time, linux_nanosleep, copyout_error, - error); - LIN_SDT_PROBE1(time, linux_nanosleep, return, error); - return (error); + error2); + LIN_SDT_PROBE1(time, linux_nanosleep, return, error2); + return (error2); } } - LIN_SDT_PROBE1(time, linux_nanosleep, return, 0); - return (0); + LIN_SDT_PROBE1(time, linux_nanosleep, return, error); + return (error); } int @@ -353,7 +511,7 @@ linux_clock_nanosleep(struct thread *td, struct linux_clock_nanosleep_args *args struct timespec *rmtp; struct l_timespec lrqts, lrmts; struct timespec rqts, rmts; - int error; + int error, error2; LIN_SDT_PROBE4(time, linux_clock_nanosleep, entry, args->which, args->flags, args->rqtp, args->rmtp); @@ -373,7 +531,7 @@ linux_clock_nanosleep(struct thread *td, struct linux_clock_nanosleep_args *args return (EINVAL); } - error = copyin(args->rqtp, &lrqts, sizeof lrqts); + error = copyin(args->rqtp, &lrqts, sizeof(lrqts)); if (error != 0) { LIN_SDT_PROBE1(time, linux_clock_nanosleep, copyin_error, error); @@ -382,9 +540,9 @@ linux_clock_nanosleep(struct thread *td, struct linux_clock_nanosleep_args *args } if (args->rmtp != NULL) - rmtp = &rmts; + rmtp = &rmts; else - rmtp = NULL; + rmtp = NULL; error = linux_to_native_timespec(&rqts, &lrqts); if (error != 0) { @@ -394,24 +552,19 @@ linux_clock_nanosleep(struct thread *td, struct linux_clock_nanosleep_args *args return (error); } error = kern_nanosleep(td, &rqts, rmtp); - if (error != 0) { - LIN_SDT_PROBE1(time, linux_clock_nanosleep, nanosleep_error, - error); - LIN_SDT_PROBE1(time, linux_clock_nanosleep, return, error); - return (error); - } - if (args->rmtp != NULL) { + /* XXX. Not for TIMER_ABSTIME */ native_to_linux_timespec(&lrmts, rmtp); - error = copyout(&lrmts, args->rmtp, sizeof lrmts ); - if (error != 0) { + error2 = copyout(&lrmts, args->rmtp, sizeof(lrmts)); + if (error2 != 0) { + LIN_SDT_PROBE1(time, linux_clock_nanosleep, + copyout_error, error2); LIN_SDT_PROBE1(time, linux_clock_nanosleep, - copyout_error, error); - LIN_SDT_PROBE1(time, linux_nanosleep, return, error); - return (error); + return, error2); + return (error2); } } - LIN_SDT_PROBE1(time, linux_clock_nanosleep, return, 0); - return (0); + LIN_SDT_PROBE1(time, linux_clock_nanosleep, return, error); + return (error); } diff --git a/sys/compat/linux/linux_timer.c b/sys/compat/linux/linux_timer.c index 92dae4c..7dbddbe 100644 --- a/sys/compat/linux/linux_timer.c +++ b/sys/compat/linux/linux_timer.c @@ -49,23 +49,6 @@ __FBSDID("$FreeBSD$"); #endif #include <compat/linux/linux_timer.h> -static int -linux_convert_l_clockid(clockid_t *clock_id) -{ - - switch (*clock_id) { - case LINUX_CLOCK_REALTIME: - *clock_id = CLOCK_REALTIME; - break; - case LINUX_CLOCK_MONOTONIC: - *clock_id = CLOCK_MONOTONIC; - break; - default: - return (EINVAL); - } - - return (0); -} static int linux_convert_l_sigevent(struct l_sigevent *l_sig, struct sigevent *sig) @@ -75,7 +58,7 @@ linux_convert_l_sigevent(struct l_sigevent *l_sig, struct sigevent *sig) switch (l_sig->sigev_notify) { case L_SIGEV_SIGNAL: sig->sigev_notify = SIGEV_SIGNAL; - CP(*l_sig, *sig, sigev_signo); + sig->sigev_signo = linux_to_bsd_signal(l_sig->sigev_signo); PTRIN_CP(*l_sig, *sig, sigev_value.sival_ptr); break; case L_SIGEV_NONE: @@ -92,7 +75,7 @@ linux_convert_l_sigevent(struct l_sigevent *l_sig, struct sigevent *sig) case L_SIGEV_THREAD_ID: sig->sigev_notify = SIGEV_THREAD_ID; CP2(*l_sig, *sig, _l_sigev_un._tid, sigev_notify_thread_id); - CP(*l_sig, *sig, sigev_signo); + sig->sigev_signo = linux_to_bsd_signal(l_sig->sigev_signo); PTRIN_CP(*l_sig, *sig, sigev_value.sival_ptr); break; default: @@ -106,6 +89,7 @@ linux_timer_create(struct thread *td, struct linux_timer_create_args *uap) { struct l_sigevent l_ev; struct sigevent ev, *evp; + clockid_t nwhich; int error, id; if (uap->evp == NULL) { @@ -119,10 +103,10 @@ linux_timer_create(struct thread *td, struct linux_timer_create_args *uap) return (error); evp = &ev; } - error = linux_convert_l_clockid(&uap->clock_id); + error = linux_to_native_clockid(&nwhich, uap->clock_id); if (error != 0) return (error); - error = kern_ktimer_create(td, uap->clock_id, evp, &id, -1); + error = kern_ktimer_create(td, nwhich, evp, &id, -1); if (error == 0) { error = copyout(&id, uap->timerid, sizeof(int)); if (error != 0) @@ -179,4 +163,3 @@ linux_timer_delete(struct thread *td, struct linux_timer_delete_args *uap) return (kern_ktimer_delete(td, uap->timerid)); } - diff --git a/sys/compat/linux/linux_timer.h b/sys/compat/linux/linux_timer.h index 4f64ee5..c79c08d 100644 --- a/sys/compat/linux/linux_timer.h +++ b/sys/compat/linux/linux_timer.h @@ -56,6 +56,23 @@ #define LINUX_CLOCK_SGI_CYCLE 10 #define LINUX_CLOCK_TAI 11 +#define LINUX_CPUCLOCK_PERTHREAD_MASK 4 +#define LINUX_CPUCLOCK_MASK 3 +#define LINUX_CPUCLOCK_WHICH(clock) \ + ((clock) & (clockid_t) LINUX_CPUCLOCK_MASK) +#define LINUX_CPUCLOCK_PROF 0 +#define LINUX_CPUCLOCK_VIRT 1 +#define LINUX_CPUCLOCK_SCHED 2 +#define LINUX_CPUCLOCK_MAX 3 +#define LINUX_CLOCKFD LINUX_CPUCLOCK_MAX +#define LINUX_CLOCKFD_MASK \ + (LINUX_CPUCLOCK_PERTHREAD_MASK|LINUX_CPUCLOCK_MASK) + +#define LINUX_CPUCLOCK_ID(clock) ((pid_t) ~((clock) >> 3)) +#define LINUX_CPUCLOCK_PERTHREAD(clock) \ + (((clock) & (clockid_t) LINUX_CPUCLOCK_PERTHREAD_MASK) != 0) + + #define L_SIGEV_SIGNAL 0 #define L_SIGEV_NONE 1 #define L_SIGEV_THREAD 2 @@ -94,4 +111,10 @@ struct l_itimerspec { struct l_timespec it_value; }; +void native_to_linux_timespec(struct l_timespec *, + struct timespec *); +int linux_to_native_timespec(struct timespec *, + struct l_timespec *); +int linux_to_native_clockid(clockid_t *, clockid_t); + #endif /* _LINUX_TIMER_H */ diff --git a/sys/compat/linux/linux_uid16.c b/sys/compat/linux/linux_uid16.c index a2c3214..9acc047 100644 --- a/sys/compat/linux/linux_uid16.c +++ b/sys/compat/linux/linux_uid16.c @@ -172,12 +172,12 @@ linux_setgroups16(struct thread *td, struct linux_setgroups16_args *args) LIN_SDT_PROBE1(uid16, linux_setgroups16, return, EINVAL); return (EINVAL); } - linux_gidset = malloc(ngrp * sizeof(*linux_gidset), M_TEMP, M_WAITOK); + linux_gidset = malloc(ngrp * sizeof(*linux_gidset), M_LINUX, M_WAITOK); error = copyin(args->gidset, linux_gidset, ngrp * sizeof(l_gid16_t)); if (error) { LIN_SDT_PROBE1(uid16, linux_setgroups16, copyin_error, error); LIN_SDT_PROBE1(uid16, linux_setgroups16, return, error); - free(linux_gidset, M_TEMP); + free(linux_gidset, M_LINUX); return (error); } newcred = crget(); @@ -219,7 +219,7 @@ linux_setgroups16(struct thread *td, struct linux_setgroups16_args *args) crfree(oldcred); error = 0; out: - free(linux_gidset, M_TEMP); + free(linux_gidset, M_LINUX); LIN_SDT_PROBE1(uid16, linux_setgroups16, return, error); return (error); @@ -260,14 +260,14 @@ linux_getgroups16(struct thread *td, struct linux_getgroups16_args *args) ngrp = 0; linux_gidset = malloc(bsd_gidsetsz * sizeof(*linux_gidset), - M_TEMP, M_WAITOK); + M_LINUX, M_WAITOK); while (ngrp < bsd_gidsetsz) { linux_gidset[ngrp] = bsd_gidset[ngrp + 1]; ngrp++; } error = copyout(linux_gidset, args->gidset, ngrp * sizeof(l_gid16_t)); - free(linux_gidset, M_TEMP); + free(linux_gidset, M_LINUX); if (error) { LIN_SDT_PROBE1(uid16, linux_getgroups16, copyout_error, error); LIN_SDT_PROBE1(uid16, linux_getgroups16, return, error); diff --git a/sys/compat/linux/linux_util.c b/sys/compat/linux/linux_util.c index 76c210c..fe49120 100644 --- a/sys/compat/linux/linux_util.c +++ b/sys/compat/linux/linux_util.c @@ -53,48 +53,14 @@ __FBSDID("$FreeBSD$"); #include <machine/stdarg.h> #include <compat/linux/linux_util.h> -#ifdef COMPAT_LINUX32 -#include <machine/../linux32/linux.h> -#else -#include <machine/../linux/linux.h> -#endif -#include <compat/linux/linux_dtrace.h> +MALLOC_DEFINE(M_LINUX, "linux", "Linux mode structures"); +MALLOC_DEFINE(M_EPOLL, "lepoll", "Linux events structures"); +MALLOC_DEFINE(M_FUTEX, "futex", "Linux futexes"); +MALLOC_DEFINE(M_FUTEX_WP, "futex wp", "Linux futex waiting proc"); const char linux_emul_path[] = "/compat/linux"; -/* DTrace init */ -LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE); - -/** - * DTrace probes in this module. - */ -LIN_SDT_PROBE_DEFINE5(util, linux_emul_convpath, entry, "const char *", - "enum uio_seg", "char **", "int", "int"); -LIN_SDT_PROBE_DEFINE1(util, linux_emul_convpath, return, "int"); -LIN_SDT_PROBE_DEFINE1(util, linux_msg, entry, "const char *"); -LIN_SDT_PROBE_DEFINE0(util, linux_msg, return); -LIN_SDT_PROBE_DEFINE2(util, linux_driver_get_name_dev, entry, "device_t", - "const char *"); -LIN_SDT_PROBE_DEFINE0(util, linux_driver_get_name_dev, nullcall); -LIN_SDT_PROBE_DEFINE1(util, linux_driver_get_name_dev, return, "char *"); -LIN_SDT_PROBE_DEFINE3(util, linux_driver_get_major_minor, entry, "char *", - "int *", "int *"); -LIN_SDT_PROBE_DEFINE0(util, linux_driver_get_major_minor, nullcall); -LIN_SDT_PROBE_DEFINE1(util, linux_driver_get_major_minor, notfound, "char *"); -LIN_SDT_PROBE_DEFINE3(util, linux_driver_get_major_minor, return, "int", - "int", "int"); -LIN_SDT_PROBE_DEFINE0(util, linux_get_char_devices, entry); -LIN_SDT_PROBE_DEFINE1(util, linux_get_char_devices, return, "char *"); -LIN_SDT_PROBE_DEFINE1(util, linux_free_get_char_devices, entry, "char *"); -LIN_SDT_PROBE_DEFINE0(util, linux_free_get_char_devices, return); -LIN_SDT_PROBE_DEFINE1(util, linux_device_register_handler, entry, - "struct linux_device_handler *"); -LIN_SDT_PROBE_DEFINE1(util, linux_device_register_handler, return, "int"); -LIN_SDT_PROBE_DEFINE1(util, linux_device_unregister_handler, entry, - "struct linux_device_handler *"); -LIN_SDT_PROBE_DEFINE1(util, linux_device_unregister_handler, return, "int"); - /* * Search an alternate path before passing pathname arguments on to * system calls. Useful for keeping a separate 'emulation tree'. @@ -108,13 +74,9 @@ linux_emul_convpath(struct thread *td, const char *path, enum uio_seg pathseg, { int retval; - LIN_SDT_PROBE5(util, linux_emul_convpath, entry, path, pathseg, pbuf, - cflag, dfd); - retval = kern_alternate_path(td, linux_emul_path, path, pathseg, pbuf, cflag, dfd); - LIN_SDT_PROBE1(util, linux_emul_convpath, return, retval); return (retval); } @@ -124,16 +86,12 @@ linux_msg(const struct thread *td, const char *fmt, ...) va_list ap; struct proc *p; - LIN_SDT_PROBE1(util, linux_msg, entry, fmt); - p = td->td_proc; printf("linux: pid %d (%s): ", (int)p->p_pid, p->p_comm); va_start(ap, fmt); vprintf(fmt, ap); va_end(ap); printf("\n"); - - LIN_SDT_PROBE0(util, linux_msg, return); } struct device_element @@ -156,24 +114,14 @@ linux_driver_get_name_dev(device_t dev) struct device_element *de; const char *device_name = device_get_name(dev); - LIN_SDT_PROBE2(util, linux_driver_get_name_dev, entry, dev, - device_name); - - if (device_name == NULL) { - LIN_SDT_PROBE0(util, linux_driver_get_name_dev, nullcall); - LIN_SDT_PROBE1(util, linux_driver_get_name_dev, return, NULL); + if (device_name == NULL) return NULL; - } TAILQ_FOREACH(de, &devices, list) { - if (strcmp(device_name, de->entry.bsd_driver_name) == 0) { - LIN_SDT_PROBE1(util, linux_driver_get_name_dev, return, - de->entry.linux_driver_name); + if (strcmp(device_name, de->entry.bsd_driver_name) == 0) return (de->entry.linux_driver_name); - } } - LIN_SDT_PROBE1(util, linux_driver_get_name_dev, return, NULL); - return NULL; + return (NULL); } int @@ -181,15 +129,8 @@ linux_driver_get_major_minor(const char *node, int *major, int *minor) { struct device_element *de; - LIN_SDT_PROBE3(util, linux_driver_get_major_minor, entry, node, major, - minor); - - if (node == NULL || major == NULL || minor == NULL) { - LIN_SDT_PROBE0(util, linux_driver_get_major_minor, nullcall); - LIN_SDT_PROBE3(util, linux_driver_get_major_minor, return, 1, - 0, 0); + if (node == NULL || major == NULL || minor == NULL) return 1; - } if (strlen(node) > strlen("pts/") && strncmp(node, "pts/", strlen("pts/")) == 0) { @@ -204,25 +145,18 @@ linux_driver_get_major_minor(const char *node, int *major, int *minor) *major = 136 + (devno / 256); *minor = devno % 256; - LIN_SDT_PROBE3(util, linux_driver_get_major_minor, return, 0, - *major, *minor); - return 0; + return (0); } TAILQ_FOREACH(de, &devices, list) { if (strcmp(node, de->entry.bsd_device_name) == 0) { *major = de->entry.linux_major; *minor = de->entry.linux_minor; - - LIN_SDT_PROBE3(util, linux_driver_get_major_minor, - return, 0, *major, *minor); - return 0; + return (0); } } - LIN_SDT_PROBE1(util, linux_driver_get_major_minor, notfound, node); - LIN_SDT_PROBE3(util, linux_driver_get_major_minor, return, 1, 0, 0); - return 1; + return (1); } char * @@ -233,8 +167,6 @@ linux_get_char_devices() char formated[256]; int current_size = 0, string_size = 1024; - LIN_SDT_PROBE0(util, linux_get_char_devices, entry); - string = malloc(string_size, M_LINUX, M_WAITOK); string[0] = '\000'; last = ""; @@ -261,19 +193,14 @@ linux_get_char_devices() } } - LIN_SDT_PROBE1(util, linux_get_char_devices, return, string); - return string; + return (string); } void linux_free_get_char_devices(char *string) { - LIN_SDT_PROBE1(util, linux_get_char_devices, entry, string); - free(string, M_LINUX); - - LIN_SDT_PROBE0(util, linux_get_char_devices, return); } static int linux_major_starting = 200; @@ -283,13 +210,8 @@ linux_device_register_handler(struct linux_device_handler *d) { struct device_element *de; - LIN_SDT_PROBE1(util, linux_device_register_handler, entry, d); - - if (d == NULL) { - LIN_SDT_PROBE1(util, linux_device_register_handler, return, - EINVAL); + if (d == NULL) return (EINVAL); - } de = malloc(sizeof(*de), M_LINUX, M_WAITOK); if (d->linux_major < 0) { @@ -300,7 +222,6 @@ linux_device_register_handler(struct linux_device_handler *d) /* Add the element to the list, sorted on span. */ TAILQ_INSERT_TAIL(&devices, de, list); - LIN_SDT_PROBE1(util, linux_device_register_handler, return, 0); return (0); } @@ -309,25 +230,17 @@ linux_device_unregister_handler(struct linux_device_handler *d) { struct device_element *de; - LIN_SDT_PROBE1(util, linux_device_unregister_handler, entry, d); - - if (d == NULL) { - LIN_SDT_PROBE1(util, linux_device_unregister_handler, return, - EINVAL); + if (d == NULL) return (EINVAL); - } TAILQ_FOREACH(de, &devices, list) { if (bcmp(d, &de->entry, sizeof(*d)) == 0) { TAILQ_REMOVE(&devices, de, list); free(de, M_LINUX); - LIN_SDT_PROBE1(util, linux_device_unregister_handler, - return, 0); return (0); } } - LIN_SDT_PROBE1(util, linux_device_unregister_handler, return, EINVAL); return (EINVAL); } diff --git a/sys/compat/linux/linux_util.h b/sys/compat/linux/linux_util.h index 6be0392..a52a7b9 100644 --- a/sys/compat/linux/linux_util.h +++ b/sys/compat/linux/linux_util.h @@ -44,6 +44,11 @@ #include <sys/cdefs.h> #include <sys/uio.h> +MALLOC_DECLARE(M_LINUX); +MALLOC_DECLARE(M_EPOLL); +MALLOC_DECLARE(M_FUTEX); +MALLOC_DECLARE(M_FUTEX_WP); + extern const char linux_emul_path[]; int linux_emul_convpath(struct thread *, const char *, enum uio_seg, char **, int, int); @@ -115,7 +120,6 @@ void linux_free_get_char_devices(char *string); #define LINUX_CTRFMT(nm, fmt) #nm"("fmt")" #define LINUX_CTR6(f, m, p1, p2, p3, p4, p5, p6) do { \ - if (ldebug(f)) \ CTR6(KTR_LINUX, LINUX_CTRFMT(f, m), \ p1, p2, p3, p4, p5, p6); \ } while (0) diff --git a/sys/compat/linux/linux_vdso.c b/sys/compat/linux/linux_vdso.c new file mode 100644 index 0000000..5ab0ee6 --- /dev/null +++ b/sys/compat/linux/linux_vdso.c @@ -0,0 +1,244 @@ +/*- + * Copyright (c) 2013 Dmitry Chagin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include "opt_compat.h" + +#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) +#define __ELF_WORD_SIZE 32 +#else +#define __ELF_WORD_SIZE 64 +#endif + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/elf.h> +#include <sys/kernel.h> +#include <sys/lock.h> +#include <sys/rwlock.h> +#include <sys/queue.h> +#include <sys/sysent.h> + +#include <vm/vm.h> +#include <vm/vm_param.h> +#include <vm/pmap.h> +#include <vm/vm_extern.h> +#include <vm/vm_kern.h> +#include <vm/vm_map.h> +#include <vm/vm_object.h> +#include <vm/vm_page.h> +#include <vm/vm_pager.h> + +#include <compat/linux/linux_vdso.h> + +SLIST_HEAD(, linux_vdso_sym) __elfN(linux_vdso_syms) = + SLIST_HEAD_INITIALIZER(__elfN(linux_vdso_syms)); + +static int __elfN(symtabindex); +static int __elfN(symstrindex); + +static void +__elfN(linux_vdso_lookup)(Elf_Ehdr *, struct linux_vdso_sym *); + + +void +__elfN(linux_vdso_sym_init)(struct linux_vdso_sym *s) +{ + + SLIST_INSERT_HEAD(&__elfN(linux_vdso_syms), s, sym); +} + +vm_object_t +__elfN(linux_shared_page_init)(char **mapping) +{ + vm_page_t m; + vm_object_t obj; + vm_offset_t addr; + + obj = vm_pager_allocate(OBJT_PHYS, 0, PAGE_SIZE, + VM_PROT_DEFAULT, 0, NULL); + VM_OBJECT_WLOCK(obj); + m = vm_page_grab(obj, 0, VM_ALLOC_NOBUSY | VM_ALLOC_ZERO); + m->valid = VM_PAGE_BITS_ALL; + VM_OBJECT_WUNLOCK(obj); + addr = kva_alloc(PAGE_SIZE); + pmap_qenter(addr, &m, 1); + *mapping = (char *)addr; + return (obj); +} + +void +__elfN(linux_shared_page_fini)(vm_object_t obj) +{ + + vm_object_deallocate(obj); +} + +void +__elfN(linux_vdso_fixup)(struct sysentvec *sv) +{ + Elf_Ehdr *ehdr; + Elf_Shdr *shdr; + int i; + + ehdr = (Elf_Ehdr *) sv->sv_sigcode; + + if (!IS_ELF(*ehdr) || + ehdr->e_ident[EI_CLASS] != ELF_TARG_CLASS || + ehdr->e_ident[EI_DATA] != ELF_TARG_DATA || + ehdr->e_ident[EI_VERSION] != EV_CURRENT || + ehdr->e_shoff == 0 || + ehdr->e_shentsize != sizeof(Elf_Shdr)) + panic("Linux invalid vdso header.\n"); + + if (ehdr->e_type != ET_DYN) + panic("Linux invalid vdso header.\n"); + + shdr = (Elf_Shdr *) ((caddr_t)ehdr + ehdr->e_shoff); + + __elfN(symtabindex) = -1; + __elfN(symstrindex) = -1; + for (i = 0; i < ehdr->e_shnum; i++) { + if (shdr[i].sh_size == 0) + continue; + if (shdr[i].sh_type == SHT_DYNSYM) { + __elfN(symtabindex) = i; + __elfN(symstrindex) = shdr[i].sh_link; + } + } + + if (__elfN(symtabindex) == -1 || __elfN(symstrindex) == -1) + panic("Linux invalid vdso header.\n"); + + ehdr->e_ident[EI_OSABI] = ELFOSABI_LINUX; +} + +void +__elfN(linux_vdso_reloc)(struct sysentvec *sv, long vdso_adjust) +{ + struct linux_vdso_sym *lsym; + Elf_Ehdr *ehdr; + Elf_Phdr *phdr; + Elf_Shdr *shdr; + Elf_Dyn *dyn; + Elf_Sym *sym; + int i, symcnt; + + ehdr = (Elf_Ehdr *) sv->sv_sigcode; + + /* Adjust our so relative to the sigcode_base */ + if (vdso_adjust != 0) { + ehdr->e_entry += vdso_adjust; + phdr = (Elf_Phdr *)((caddr_t)ehdr + ehdr->e_phoff); + + /* phdrs */ + for (i = 0; i < ehdr->e_phnum; i++) { + phdr[i].p_vaddr += vdso_adjust; + if (phdr[i].p_type != PT_DYNAMIC) + continue; + dyn = (Elf_Dyn *)((caddr_t)ehdr + phdr[i].p_offset); + for(; dyn->d_tag != DT_NULL; dyn++) { + switch (dyn->d_tag) { + case DT_PLTGOT: + case DT_HASH: + case DT_STRTAB: + case DT_SYMTAB: + case DT_RELA: + case DT_INIT: + case DT_FINI: + case DT_REL: + case DT_DEBUG: + case DT_JMPREL: + case DT_VERSYM: + case DT_VERDEF: + case DT_VERNEED: + case DT_ADDRRNGLO ... DT_ADDRRNGHI: + dyn->d_un.d_ptr += vdso_adjust; + break; + case DT_ENCODING ... DT_LOOS-1: + case DT_LOOS ... DT_HIOS: + if (dyn->d_tag >= DT_ENCODING && + (dyn->d_tag & 1) == 0) + dyn->d_un.d_ptr += vdso_adjust; + break; + default: + break; + } + } + } + + /* sections */ + shdr = (Elf_Shdr *)((caddr_t)ehdr + ehdr->e_shoff); + for(i = 0; i < ehdr->e_shnum; i++) { + if (!(shdr[i].sh_flags & SHF_ALLOC)) + continue; + shdr[i].sh_addr += vdso_adjust; + if (shdr[i].sh_type != SHT_SYMTAB && + shdr[i].sh_type != SHT_DYNSYM) + continue; + + sym = (Elf_Sym *)((caddr_t)ehdr + shdr[i].sh_offset); + symcnt = shdr[i].sh_size / sizeof(*sym); + + for(i = 0; i < symcnt; i++, sym++) { + if (sym->st_shndx == SHN_UNDEF || + sym->st_shndx == SHN_ABS) + continue; + sym->st_value += vdso_adjust; + } + } + } + + SLIST_FOREACH(lsym, &__elfN(linux_vdso_syms), sym) + __elfN(linux_vdso_lookup)(ehdr, lsym); +} + +static void +__elfN(linux_vdso_lookup)(Elf_Ehdr *ehdr, struct linux_vdso_sym *vsym) +{ + vm_offset_t strtab, symname; + uint32_t symcnt; + Elf_Shdr *shdr; + int i; + + shdr = (Elf_Shdr *) ((caddr_t)ehdr + ehdr->e_shoff); + + strtab = (vm_offset_t)((caddr_t)ehdr + + shdr[__elfN(symstrindex)].sh_offset); + Elf_Sym *sym = (Elf_Sym *)((caddr_t)ehdr + + shdr[__elfN(symtabindex)].sh_offset); + symcnt = shdr[__elfN(symtabindex)].sh_size / sizeof(*sym); + + for (i = 0; i < symcnt; ++i, ++sym) { + symname = strtab + sym->st_name; + if (strncmp(vsym->symname, (char *)symname, vsym->size) == 0) { + *vsym->ptr = (uintptr_t)sym->st_value; + break; + } + } +} diff --git a/sys/compat/linux/linux_vdso.h b/sys/compat/linux/linux_vdso.h new file mode 100644 index 0000000..e11ee8a --- /dev/null +++ b/sys/compat/linux/linux_vdso.h @@ -0,0 +1,65 @@ +/*- + * Copyright (c) 2013 Dmitry Chagin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _LINUX_VDSO_H_ +#define _LINUX_VDSO_H_ + +#include <sys/types.h> + +struct linux_vdso_sym { + SLIST_ENTRY(linux_vdso_sym) sym; + uint32_t size; + uintptr_t * ptr; + char symname[]; +}; + +vm_object_t __elfN(linux_shared_page_init)(char **); +void __elfN(linux_shared_page_fini)(vm_object_t); +void __elfN(linux_vdso_fixup)(struct sysentvec *); +void __elfN(linux_vdso_reloc)(struct sysentvec *, long); +void __elfN(linux_vdso_sym_init)(struct linux_vdso_sym *); + +#define LINUX_VDSO_SYM_INTPTR(name) \ +uintptr_t name; \ +LINUX_VDSO_SYM_DEFINE(name) + +#define LINUX_VDSO_SYM_CHAR(name) \ +const char * name; \ +LINUX_VDSO_SYM_DEFINE(name) + +#define LINUX_VDSO_SYM_DEFINE(name) \ +static struct linux_vdso_sym name ## sym = { \ + .symname = #name, \ + .size = sizeof(#name), \ + .ptr = (uintptr_t *)&name \ +}; \ +SYSINIT(__elfN(name ## _sym_init), SI_SUB_EXEC, \ + SI_ORDER_FIRST, __elfN(linux_vdso_sym_init), &name ## sym); \ +struct __hack + +#endif /* _LINUX_VDSO_H_ */ diff --git a/sys/compat/linux/stats_timing.d b/sys/compat/linux/stats_timing.d index d0b6f73..1b60dc9 100644 --- a/sys/compat/linux/stats_timing.d +++ b/sys/compat/linux/stats_timing.d @@ -39,7 +39,6 @@ * possible for a given application * - graph of longest running (CPU-time!) function in total * - may help finding problem cases in the kernel code - * - timing statistics for the emul_lock * - graph of longest held (CPU-time!) locks */ diff --git a/sys/compat/svr4/svr4_misc.c b/sys/compat/svr4/svr4_misc.c index e244700..5d1a409 100644 --- a/sys/compat/svr4/svr4_misc.c +++ b/sys/compat/svr4/svr4_misc.c @@ -875,9 +875,9 @@ svr4_sys_times(td, uap) p = td->td_proc; PROC_LOCK(p); - PROC_SLOCK(p); + PROC_STATLOCK(p); calcru(p, &utime, &stime); - PROC_SUNLOCK(p); + PROC_STATUNLOCK(p); calccru(p, &cutime, &cstime); PROC_UNLOCK(p); @@ -1288,9 +1288,9 @@ loop: pid = p->p_pid; status = p->p_xstat; ru = p->p_ru; - PROC_SLOCK(p); + PROC_STATLOCK(p); calcru(p, &ru.ru_utime, &ru.ru_stime); - PROC_SUNLOCK(p); + PROC_STATUNLOCK(p); PROC_UNLOCK(p); sx_sunlock(&proctree_lock); @@ -1315,9 +1315,9 @@ loop: pid = p->p_pid; status = W_STOPCODE(p->p_xstat); ru = p->p_ru; - PROC_SLOCK(p); + PROC_STATLOCK(p); calcru(p, &ru.ru_utime, &ru.ru_stime); - PROC_SUNLOCK(p); + PROC_STATUNLOCK(p); PROC_UNLOCK(p); if (((uap->options & SVR4_WNOWAIT)) == 0) { @@ -1339,9 +1339,9 @@ loop: pid = p->p_pid; ru = p->p_ru; status = SIGCONT; - PROC_SLOCK(p); + PROC_STATLOCK(p); calcru(p, &ru.ru_utime, &ru.ru_stime); - PROC_SUNLOCK(p); + PROC_STATUNLOCK(p); PROC_UNLOCK(p); if (((uap->options & SVR4_WNOWAIT)) == 0) { diff --git a/sys/compat/svr4/svr4_sysvec.c b/sys/compat/svr4/svr4_sysvec.c index 561a838..125a7d8 100644 --- a/sys/compat/svr4/svr4_sysvec.c +++ b/sys/compat/svr4/svr4_sysvec.c @@ -196,6 +196,7 @@ struct sysentvec svr4_sysvec = { .sv_fetch_syscall_args = cpu_fetch_syscall_args, .sv_syscallnames = NULL, .sv_schedtail = NULL, + .sv_thread_detach = NULL, }; const char svr4_emul_path[] = "/compat/svr4"; diff --git a/sys/conf/NOTES b/sys/conf/NOTES index 9c8b9c9..78fb6ee 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -2494,6 +2494,7 @@ device sdhci # amdsmb AMD 8111 SMBus 2.0 Controller # nfpm NVIDIA nForce Power Management Unit # nfsmb NVIDIA nForce2/3/4 MCP SMBus 2.0 Controller +# ismt Intel SMBus 2.0 controller chips (on Atom S1200, C2000) # device smbus # Bus support, required for smb below. @@ -2505,6 +2506,7 @@ device amdpm device amdsmb device nfpm device nfsmb +device ismt device smb diff --git a/sys/conf/files b/sys/conf/files index 286a4f1..957b034 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1528,6 +1528,7 @@ dev/iscsi_initiator/isc_cam.c optional iscsi_initiator scbus dev/iscsi_initiator/isc_soc.c optional iscsi_initiator scbus dev/iscsi_initiator/isc_sm.c optional iscsi_initiator scbus dev/iscsi_initiator/isc_subr.c optional iscsi_initiator scbus +dev/ismt/ismt.c optional ismt dev/isp/isp.c optional isp dev/isp/isp_freebsd.c optional isp dev/isp/isp_library.c optional isp diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64 index 53d8494..cfc7884 100644 --- a/sys/conf/files.amd64 +++ b/sys/conf/files.amd64 @@ -20,6 +20,18 @@ linux32_assym.h optional compat_linux32 \ no-obj no-implicit-rule before-depend \ clean "linux32_assym.h" # +linux32_locore.o optional compat_linux32 \ + dependency "linux32_assym.h $S/amd64/linux32/linux32_locore.s" \ + compile-with "${CC} -x assembler-with-cpp -DLOCORE -m32 -shared -s -pipe -I. -I$S -Werror -Wall -fno-common -nostdinc -nostdlib -Wl,-T$S/amd64/linux32/linux32_vdso.lds.s -Wl,-soname=linux32_vdso.so,--eh-frame-hdr,-fPIC,-warn-common ${.IMPSRC} -o ${.TARGET}" \ + no-obj no-implicit-rule \ + clean "linux32_locore.o" +# +linux32_vdso.so optional compat_linux32 \ + dependency "linux32_locore.o" \ + compile-with "${OBJCOPY} --input-target binary --output-target elf64-x86-64-freebsd --binary-architecture i386 linux32_locore.o ${.TARGET}" \ + no-implicit-rule \ + clean "linux32_vdso.so" +# ia32_genassym.o standard \ dependency "$S/compat/ia32/ia32_genassym.c" \ compile-with "${CC} ${CFLAGS:N-fno-common} -c ${.IMPSRC}" \ @@ -510,8 +522,6 @@ compat/linsysfs/linsysfs.c optional linsysfs # Linux/i386 binary support # amd64/linux32/linux32_dummy.c optional compat_linux32 -amd64/linux32/linux32_locore.s optional compat_linux32 \ - dependency "linux32_assym.h" amd64/linux32/linux32_machdep.c optional compat_linux32 amd64/linux32/linux32_support.s optional compat_linux32 \ dependency "linux32_assym.h" @@ -534,6 +544,10 @@ compat/linux/linux_time.c optional compat_linux32 compat/linux/linux_timer.c optional compat_linux32 compat/linux/linux_uid16.c optional compat_linux32 compat/linux/linux_util.c optional compat_linux32 +compat/linux/linux_vdso.c optional compat_linux32 +compat/linux/linux_common.c optional compat_linux32 +compat/linux/linux_event.c optional compat_linux32 +compat/linux/linux.c optional compat_linux32 dev/amr/amr_linux.c optional compat_linux32 amr dev/mfi/mfi_linux.c optional compat_linux32 mfi # diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index 5cd89dc..fb6e4b2 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -19,6 +19,18 @@ linux_assym.h optional compat_linux \ no-obj no-implicit-rule before-depend \ clean "linux_assym.h" # +linux_locore.o optional compat_linux \ + dependency "linux_assym.h $S/i386/linux/linux_locore.s" \ + compile-with "${CC} -x assembler-with-cpp -DLOCORE -shared -s -pipe -I. -I$S -Werror -Wall -fno-common -nostdinc -nostdlib -Wl,-T$S/i386/linux/linux_vdso.lds.s -Wl,-soname=linux_vdso.so,--eh-frame-hdr,-fPIC,-warn-common ${.IMPSRC} -o ${.TARGET}" \ + no-obj no-implicit-rule \ + clean "linux_locore.o" +# +linux_vdso.so optional compat_linux \ + dependency "linux_locore.o" \ + compile-with "${OBJCOPY} --input-target binary --output-target elf32-i386-freebsd --binary-architecture i386 linux_locore.o ${.TARGET}" \ + no-implicit-rule \ + clean "linux_vdso.so" +# svr4_genassym.o optional compat_svr4 \ dependency "$S/i386/svr4/svr4_genassym.c" \ compile-with "${CC} ${CFLAGS:N-fno-common} -c ${.IMPSRC}" \ @@ -80,6 +92,7 @@ hptrr_lib.o optional hptrr \ cddl/contrib/opensolaris/common/atomic/i386/opensolaris_atomic.S optional zfs compile-with "${ZFS_S}" compat/linprocfs/linprocfs.c optional linprocfs compat/linsysfs/linsysfs.c optional linsysfs +compat/linux/linux_event.c optional compat_linux compat/linux/linux_emul.c optional compat_linux compat/linux/linux_file.c optional compat_linux compat/linux/linux_fork.c optional compat_linux @@ -97,6 +110,8 @@ compat/linux/linux_time.c optional compat_linux compat/linux/linux_timer.c optional compat_linux compat/linux/linux_uid16.c optional compat_linux compat/linux/linux_util.c optional compat_linux +compat/linux/linux_vdso.c optional compat_linux +compat/linux/linux.c optional compat_linux compat/ndis/kern_ndis.c optional ndisapi pci compat/ndis/kern_windrv.c optional ndisapi pci compat/ndis/subr_hal.c optional ndisapi pci @@ -521,8 +536,6 @@ i386/isa/prof_machdep.c optional profiling-routine i386/isa/spic.c optional spic i386/linux/imgact_linux.c optional compat_linux i386/linux/linux_dummy.c optional compat_linux -i386/linux/linux_locore.s optional compat_linux \ - dependency "linux_assym.h" i386/linux/linux_machdep.c optional compat_linux i386/linux/linux_ptrace.c optional compat_linux i386/linux/linux_support.s optional compat_linux \ diff --git a/sys/conf/files.pc98 b/sys/conf/files.pc98 index a1a9663..fd560fc 100644 --- a/sys/conf/files.pc98 +++ b/sys/conf/files.pc98 @@ -21,6 +21,18 @@ linux_assym.h optional compat_linux \ no-obj no-implicit-rule before-depend \ clean "linux_assym.h" # +linux_locore.o optional compat_linux \ + dependency "linux_assym.h $S/i386/linux/linux_locore.s" \ + compile-with "${CC} -x assembler-with-cpp -DLOCORE -shared -s -pipe -I. -I$S -Werror -Wall -fno-common -nostdinc -nostdlib -Wl,-T$S/i386/linux/linux_vdso.lds.s -Wl,-soname=linux_vdso.so,--eh-frame-hdr,-fPIC,-warn-common ${.IMPSRC} -o ${.TARGET}" \ + no-obj no-implicit-rule \ + clean "linux_locore.o" +# +linux_vdso.so optional compat_linux \ + dependency "linux_locore.o" \ + compile-with "${OBJCOPY} --input-target binary --output-target elf32-i386-freebsd --binary-architecture i386 linux_locore.o ${.TARGET}" \ + no-implicit-rule \ + clean "linux_vdso.so" +# svr4_genassym.o optional compat_svr4 \ dependency "$S/i386/svr4/svr4_genassym.c" \ compile-with "${CC} ${CFLAGS:N-fno-common} -c ${.IMPSRC}" \ @@ -41,6 +53,7 @@ ukbdmap.h optional ukbd_dflt_keymap \ cddl/contrib/opensolaris/common/atomic/i386/opensolaris_atomic.S optional zfs compile-with "${ZFS_S}" compat/linprocfs/linprocfs.c optional linprocfs compat/linsysfs/linsysfs.c optional linsysfs +compat/linux/linux_event.c optional compat_linux compat/linux/linux_emul.c optional compat_linux compat/linux/linux_file.c optional compat_linux compat/linux/linux_fork.c optional compat_linux @@ -58,6 +71,8 @@ compat/linux/linux_time.c optional compat_linux compat/linux/linux_timer.c optional compat_linux compat/linux/linux_uid16.c optional compat_linux compat/linux/linux_util.c optional compat_linux +compat/linux/linux_vdso.c optional compat_linux +compat/linux/linux.c optional compat_linux compat/svr4/imgact_svr4.c optional compat_svr4 compat/svr4/svr4_fcntl.c optional compat_svr4 compat/svr4/svr4_filio.c optional compat_svr4 @@ -192,8 +207,6 @@ i386/isa/pmtimer.c optional pmtimer i386/isa/prof_machdep.c optional profiling-routine i386/linux/imgact_linux.c optional compat_linux i386/linux/linux_dummy.c optional compat_linux -i386/linux/linux_locore.s optional compat_linux \ - dependency "linux_assym.h" i386/linux/linux_machdep.c optional compat_linux i386/linux/linux_ptrace.c optional compat_linux i386/linux/linux_support.s optional compat_linux \ diff --git a/sys/dev/bxe/bxe.c b/sys/dev/bxe/bxe.c index c984add..0a50cbe 100644 --- a/sys/dev/bxe/bxe.c +++ b/sys/dev/bxe/bxe.c @@ -483,6 +483,10 @@ static const struct { 4, STATS_FLAGS_FUNC, "rx_pkts"}, { STATS_OFFSET32(rx_tpa_pkts), 4, STATS_FLAGS_FUNC, "rx_tpa_pkts"}, + { STATS_OFFSET32(rx_erroneous_jumbo_sge_pkts), + 4, STATS_FLAGS_FUNC, "rx_erroneous_jumbo_sge_pkts"}, + { STATS_OFFSET32(rx_bxe_service_rxsgl), + 4, STATS_FLAGS_FUNC, "rx_bxe_service_rxsgl"}, { STATS_OFFSET32(rx_jumbo_sge_pkts), 4, STATS_FLAGS_FUNC, "rx_jumbo_sge_pkts"}, { STATS_OFFSET32(rx_soft_errors), @@ -596,6 +600,10 @@ static const struct { 4, "rx_pkts"}, { Q_STATS_OFFSET32(rx_tpa_pkts), 4, "rx_tpa_pkts"}, + { Q_STATS_OFFSET32(rx_erroneous_jumbo_sge_pkts), + 4, "rx_erroneous_jumbo_sge_pkts"}, + { Q_STATS_OFFSET32(rx_bxe_service_rxsgl), + 4, "rx_bxe_service_rxsgl"}, { Q_STATS_OFFSET32(rx_jumbo_sge_pkts), 4, "rx_jumbo_sge_pkts"}, { Q_STATS_OFFSET32(rx_soft_errors), @@ -739,6 +747,8 @@ static __noinline int bxe_nic_unload(struct bxe_softc *sc, static void bxe_handle_sp_tq(void *context, int pending); static void bxe_handle_fp_tq(void *context, int pending); +static int bxe_add_cdev(struct bxe_softc *sc); +static void bxe_del_cdev(struct bxe_softc *sc); /* calculate crc32 on a buffer (NOTE: crc32_length MUST be aligned to 8) */ uint32_t @@ -3486,11 +3496,14 @@ bxe_rxeof(struct bxe_softc *sc, m_adj(m, pad); m->m_pkthdr.len = m->m_len = len; - if (len != lenonbd){ + if ((len > 60) && (len > lenonbd)) { + fp->eth_q_stats.rx_bxe_service_rxsgl++; rc = bxe_service_rxsgl(fp, len, lenonbd, m, cqe_fp); if (rc) break; fp->eth_q_stats.rx_jumbo_sge_pkts++; + } else if (lenonbd < len) { + fp->eth_q_stats.rx_erroneous_jumbo_sge_pkts++; } /* assign packet to this interface interface */ @@ -4503,7 +4516,7 @@ bxe_nic_unload(struct bxe_softc *sc, sc->rx_mode = BXE_RX_MODE_NONE; /* XXX set rx mode ??? */ - if (IS_PF(sc)) { + if (IS_PF(sc) && !sc->grcdump_done) { /* set ALWAYS_ALIVE bit in shmem */ sc->fw_drv_pulse_wr_seq |= DRV_PULSE_ALWAYS_ALIVE; @@ -4523,7 +4536,8 @@ bxe_nic_unload(struct bxe_softc *sc, ; /* bxe_vfpf_close_vf(sc); */ } else if (unload_mode != UNLOAD_RECOVERY) { /* if this is a normal/close unload need to clean up chip */ - bxe_chip_cleanup(sc, unload_mode, keep_link); + if (!sc->grcdump_done) + bxe_chip_cleanup(sc, unload_mode, keep_link); } else { /* Send the UNLOAD_REQUEST to the MCP */ bxe_send_unload_req(sc, unload_mode); @@ -16154,9 +16168,12 @@ bxe_sysctl_state(SYSCTL_HANDLER_ARGS) } if (result == 1) { + uint32_t temp; sc = (struct bxe_softc *)arg1; + BLOGI(sc, "... dumping driver state ...\n"); - /* XXX */ + temp = SHMEM2_RD(sc, temperature_in_half_celsius); + BLOGI(sc, "\t Device Temperature = %d Celsius\n", (temp/2)); } return (error); @@ -16294,6 +16311,12 @@ bxe_add_sysctls(struct bxe_softc *sc) CTLFLAG_RW, &sc->debug, "debug logging mode"); + sc->trigger_grcdump = 0; + SYSCTL_ADD_UINT(ctx, children, OID_AUTO, "trigger_grcdump", + CTLFLAG_RW, &sc->trigger_grcdump, 0, + "set by driver when a grcdump is needed"); + + sc->rx_budget = bxe_rx_budget; SYSCTL_ADD_UINT(ctx, children, OID_AUTO, "rx_budget", CTLFLAG_RW, &sc->rx_budget, 0, @@ -16422,8 +16445,20 @@ bxe_attach(device_t dev) return (ENXIO); } + if (bxe_add_cdev(sc) != 0) { + if (sc->ifnet != NULL) { + ether_ifdetach(sc->ifnet); + } + ifmedia_removeall(&sc->ifmedia); + bxe_release_mutexes(sc); + bxe_deallocate_bars(sc); + pci_disable_busmaster(dev); + return (ENXIO); + } + /* allocate device interrupts */ if (bxe_interrupt_alloc(sc) != 0) { + bxe_del_cdev(sc); if (sc->ifnet != NULL) { ether_ifdetach(sc->ifnet); } @@ -16437,6 +16472,7 @@ bxe_attach(device_t dev) /* allocate ilt */ if (bxe_alloc_ilt_mem(sc) != 0) { bxe_interrupt_free(sc); + bxe_del_cdev(sc); if (sc->ifnet != NULL) { ether_ifdetach(sc->ifnet); } @@ -16451,6 +16487,7 @@ bxe_attach(device_t dev) if (bxe_alloc_hsi_mem(sc) != 0) { bxe_free_ilt_mem(sc); bxe_interrupt_free(sc); + bxe_del_cdev(sc); if (sc->ifnet != NULL) { ether_ifdetach(sc->ifnet); } @@ -16522,6 +16559,8 @@ bxe_detach(device_t dev) return(EBUSY); } + bxe_del_cdev(sc); + /* stop the periodic callout */ bxe_periodic_stop(sc); @@ -18842,3 +18881,457 @@ ecore_storm_memset_struct(struct bxe_softc *sc, } } + +/* + * character device - ioctl interface definitions + */ + + +#include "bxe_dump.h" +#include "bxe_ioctl.h" +#include <sys/conf.h> + +static int bxe_eioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, + struct thread *td); + +static struct cdevsw bxe_cdevsw = { + .d_version = D_VERSION, + .d_ioctl = bxe_eioctl, + .d_name = "bxecnic", +}; + +#define BXE_PATH(sc) (CHIP_IS_E1x(sc) ? 0 : (sc->pcie_func & 1)) + + +#define DUMP_ALL_PRESETS 0x1FFF +#define DUMP_MAX_PRESETS 13 +#define IS_E1_REG(chips) ((chips & DUMP_CHIP_E1) == DUMP_CHIP_E1) +#define IS_E1H_REG(chips) ((chips & DUMP_CHIP_E1H) == DUMP_CHIP_E1H) +#define IS_E2_REG(chips) ((chips & DUMP_CHIP_E2) == DUMP_CHIP_E2) +#define IS_E3A0_REG(chips) ((chips & DUMP_CHIP_E3A0) == DUMP_CHIP_E3A0) +#define IS_E3B0_REG(chips) ((chips & DUMP_CHIP_E3B0) == DUMP_CHIP_E3B0) + +#define IS_REG_IN_PRESET(presets, idx) \ + ((presets & (1 << (idx-1))) == (1 << (idx-1))) + + +static int +bxe_get_preset_regs_len(struct bxe_softc *sc, uint32_t preset) +{ + if (CHIP_IS_E1(sc)) + return dump_num_registers[0][preset-1]; + else if (CHIP_IS_E1H(sc)) + return dump_num_registers[1][preset-1]; + else if (CHIP_IS_E2(sc)) + return dump_num_registers[2][preset-1]; + else if (CHIP_IS_E3A0(sc)) + return dump_num_registers[3][preset-1]; + else if (CHIP_IS_E3B0(sc)) + return dump_num_registers[4][preset-1]; + else + return 0; +} + +static int +bxe_get_max_regs_len(struct bxe_softc *sc) +{ + uint32_t preset_idx; + int regdump_len32, len32; + + regdump_len32 = bxe_get_preset_regs_len(sc, 1); + + /* Calculate the total preset regs length */ + for (preset_idx = 2; preset_idx <= DUMP_MAX_PRESETS; preset_idx++) { + + len32 = bxe_get_preset_regs_len(sc, preset_idx); + + if (regdump_len32 < len32) + regdump_len32 = len32; + } + + return regdump_len32; +} + +static int +bxe_get_total_regs_len32(struct bxe_softc *sc) +{ + uint32_t preset_idx; + int regdump_len32 = 0; + + + /* Calculate the total preset regs length */ + for (preset_idx = 1; preset_idx <= DUMP_MAX_PRESETS; preset_idx++) { + regdump_len32 += bxe_get_preset_regs_len(sc, preset_idx); + } + + return regdump_len32; +} + +static const uint32_t * +__bxe_get_page_addr_ar(struct bxe_softc *sc) +{ + if (CHIP_IS_E2(sc)) + return page_vals_e2; + else if (CHIP_IS_E3(sc)) + return page_vals_e3; + else + return NULL; +} + +static uint32_t +__bxe_get_page_reg_num(struct bxe_softc *sc) +{ + if (CHIP_IS_E2(sc)) + return PAGE_MODE_VALUES_E2; + else if (CHIP_IS_E3(sc)) + return PAGE_MODE_VALUES_E3; + else + return 0; +} + +static const uint32_t * +__bxe_get_page_write_ar(struct bxe_softc *sc) +{ + if (CHIP_IS_E2(sc)) + return page_write_regs_e2; + else if (CHIP_IS_E3(sc)) + return page_write_regs_e3; + else + return NULL; +} + +static uint32_t +__bxe_get_page_write_num(struct bxe_softc *sc) +{ + if (CHIP_IS_E2(sc)) + return PAGE_WRITE_REGS_E2; + else if (CHIP_IS_E3(sc)) + return PAGE_WRITE_REGS_E3; + else + return 0; +} + +static const struct reg_addr * +__bxe_get_page_read_ar(struct bxe_softc *sc) +{ + if (CHIP_IS_E2(sc)) + return page_read_regs_e2; + else if (CHIP_IS_E3(sc)) + return page_read_regs_e3; + else + return NULL; +} + +static uint32_t +__bxe_get_page_read_num(struct bxe_softc *sc) +{ + if (CHIP_IS_E2(sc)) + return PAGE_READ_REGS_E2; + else if (CHIP_IS_E3(sc)) + return PAGE_READ_REGS_E3; + else + return 0; +} + +static bool +bxe_is_reg_in_chip(struct bxe_softc *sc, const struct reg_addr *reg_info) +{ + if (CHIP_IS_E1(sc)) + return IS_E1_REG(reg_info->chips); + else if (CHIP_IS_E1H(sc)) + return IS_E1H_REG(reg_info->chips); + else if (CHIP_IS_E2(sc)) + return IS_E2_REG(reg_info->chips); + else if (CHIP_IS_E3A0(sc)) + return IS_E3A0_REG(reg_info->chips); + else if (CHIP_IS_E3B0(sc)) + return IS_E3B0_REG(reg_info->chips); + else + return 0; +} + +static bool +bxe_is_wreg_in_chip(struct bxe_softc *sc, const struct wreg_addr *wreg_info) +{ + if (CHIP_IS_E1(sc)) + return IS_E1_REG(wreg_info->chips); + else if (CHIP_IS_E1H(sc)) + return IS_E1H_REG(wreg_info->chips); + else if (CHIP_IS_E2(sc)) + return IS_E2_REG(wreg_info->chips); + else if (CHIP_IS_E3A0(sc)) + return IS_E3A0_REG(wreg_info->chips); + else if (CHIP_IS_E3B0(sc)) + return IS_E3B0_REG(wreg_info->chips); + else + return 0; +} + +/** + * bxe_read_pages_regs - read "paged" registers + * + * @bp device handle + * @p output buffer + * + * Reads "paged" memories: memories that may only be read by first writing to a + * specific address ("write address") and then reading from a specific address + * ("read address"). There may be more than one write address per "page" and + * more than one read address per write address. + */ +static void +bxe_read_pages_regs(struct bxe_softc *sc, uint32_t *p, uint32_t preset) +{ + uint32_t i, j, k, n; + + /* addresses of the paged registers */ + const uint32_t *page_addr = __bxe_get_page_addr_ar(sc); + /* number of paged registers */ + int num_pages = __bxe_get_page_reg_num(sc); + /* write addresses */ + const uint32_t *write_addr = __bxe_get_page_write_ar(sc); + /* number of write addresses */ + int write_num = __bxe_get_page_write_num(sc); + /* read addresses info */ + const struct reg_addr *read_addr = __bxe_get_page_read_ar(sc); + /* number of read addresses */ + int read_num = __bxe_get_page_read_num(sc); + uint32_t addr, size; + + for (i = 0; i < num_pages; i++) { + for (j = 0; j < write_num; j++) { + REG_WR(sc, write_addr[j], page_addr[i]); + + for (k = 0; k < read_num; k++) { + if (IS_REG_IN_PRESET(read_addr[k].presets, preset)) { + size = read_addr[k].size; + for (n = 0; n < size; n++) { + addr = read_addr[k].addr + n*4; + *p++ = REG_RD(sc, addr); + } + } + } + } + } + return; +} + + +static int +bxe_get_preset_regs(struct bxe_softc *sc, uint32_t *p, uint32_t preset) +{ + uint32_t i, j, addr; + const struct wreg_addr *wreg_addr_p = NULL; + + if (CHIP_IS_E1(sc)) + wreg_addr_p = &wreg_addr_e1; + else if (CHIP_IS_E1H(sc)) + wreg_addr_p = &wreg_addr_e1h; + else if (CHIP_IS_E2(sc)) + wreg_addr_p = &wreg_addr_e2; + else if (CHIP_IS_E3A0(sc)) + wreg_addr_p = &wreg_addr_e3; + else if (CHIP_IS_E3B0(sc)) + wreg_addr_p = &wreg_addr_e3b0; + else + return (-1); + + /* Read the idle_chk registers */ + for (i = 0; i < IDLE_REGS_COUNT; i++) { + if (bxe_is_reg_in_chip(sc, &idle_reg_addrs[i]) && + IS_REG_IN_PRESET(idle_reg_addrs[i].presets, preset)) { + for (j = 0; j < idle_reg_addrs[i].size; j++) + *p++ = REG_RD(sc, idle_reg_addrs[i].addr + j*4); + } + } + + /* Read the regular registers */ + for (i = 0; i < REGS_COUNT; i++) { + if (bxe_is_reg_in_chip(sc, ®_addrs[i]) && + IS_REG_IN_PRESET(reg_addrs[i].presets, preset)) { + for (j = 0; j < reg_addrs[i].size; j++) + *p++ = REG_RD(sc, reg_addrs[i].addr + j*4); + } + } + + /* Read the CAM registers */ + if (bxe_is_wreg_in_chip(sc, wreg_addr_p) && + IS_REG_IN_PRESET(wreg_addr_p->presets, preset)) { + for (i = 0; i < wreg_addr_p->size; i++) { + *p++ = REG_RD(sc, wreg_addr_p->addr + i*4); + + /* In case of wreg_addr register, read additional + registers from read_regs array + */ + for (j = 0; j < wreg_addr_p->read_regs_count; j++) { + addr = *(wreg_addr_p->read_regs); + *p++ = REG_RD(sc, addr + j*4); + } + } + } + + /* Paged registers are supported in E2 & E3 only */ + if (CHIP_IS_E2(sc) || CHIP_IS_E3(sc)) { + /* Read "paged" registers */ + bxe_read_pages_regs(sc, p, preset); + } + + return 0; +} + +static int +bxe_grc_dump(struct bxe_softc *sc, bxe_grcdump_t *dump) +{ + int rval = 0; + uint32_t preset_idx; + uint8_t *buf; + uint32_t size; + struct dump_header *d_hdr; + + ecore_disable_blocks_parity(sc); + + buf = dump->grcdump; + d_hdr = dump->grcdump; + + d_hdr->header_size = (sizeof(struct dump_header) >> 2) - 1; + d_hdr->version = BNX2X_DUMP_VERSION; + d_hdr->preset = DUMP_ALL_PRESETS; + + if (CHIP_IS_E1(sc)) { + d_hdr->dump_meta_data = DUMP_CHIP_E1; + } else if (CHIP_IS_E1H(sc)) { + d_hdr->dump_meta_data = DUMP_CHIP_E1H; + } else if (CHIP_IS_E2(sc)) { + d_hdr->dump_meta_data = DUMP_CHIP_E2 | + (BXE_PATH(sc) ? DUMP_PATH_1 : DUMP_PATH_0); + } else if (CHIP_IS_E3A0(sc)) { + d_hdr->dump_meta_data = DUMP_CHIP_E3A0 | + (BXE_PATH(sc) ? DUMP_PATH_1 : DUMP_PATH_0); + } else if (CHIP_IS_E3B0(sc)) { + d_hdr->dump_meta_data = DUMP_CHIP_E3B0 | + (BXE_PATH(sc) ? DUMP_PATH_1 : DUMP_PATH_0); + } + + dump->grcdump_dwords = sizeof(struct dump_header) >> 2; + buf += sizeof(struct dump_header); + + for (preset_idx = 1; preset_idx <= DUMP_MAX_PRESETS; preset_idx++) { + + /* Skip presets with IOR */ + if ((preset_idx == 2) || (preset_idx == 5) || (preset_idx == 8) || + (preset_idx == 11)) + continue; + + rval = bxe_get_preset_regs(sc, sc->grc_dump, preset_idx); + + if (rval) + break; + + size = bxe_get_preset_regs_len(sc, preset_idx) * (sizeof (uint32_t)); + + rval = copyout(sc->grc_dump, buf, size); + + if (rval) + break; + + dump->grcdump_dwords += (size / (sizeof (uint32_t))); + + buf += size; + } + + ecore_clear_blocks_parity(sc); + ecore_enable_blocks_parity(sc); + + sc->grcdump_done = 1; + return(rval); +} + +static int +bxe_add_cdev(struct bxe_softc *sc) +{ + int max_preset_size; + + max_preset_size = bxe_get_max_regs_len(sc) * (sizeof (uint32_t)); + + sc->grc_dump = malloc(max_preset_size, M_DEVBUF, M_NOWAIT); + + if (sc->grc_dump == NULL) + return (-1); + + sc->ioctl_dev = make_dev(&bxe_cdevsw, + sc->ifnet->if_dunit, + UID_ROOT, + GID_WHEEL, + 0600, + "%s", + if_name(sc->ifnet)); + + if (sc->ioctl_dev == NULL) { + + free(sc->grc_dump, M_DEVBUF); + + return (-1); + } + + sc->ioctl_dev->si_drv1 = sc; + + return (0); +} + +static void +bxe_del_cdev(struct bxe_softc *sc) +{ + if (sc->ioctl_dev != NULL) + destroy_dev(sc->ioctl_dev); + + if (sc->grc_dump == NULL) + free(sc->grc_dump, M_DEVBUF); + + return; +} + +static int +bxe_eioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, + struct thread *td) +{ + struct bxe_softc *sc; + int rval = 0; + device_t pci_dev; + bxe_grcdump_t *dump = NULL; + int grc_dump_size; + + if ((sc = (struct bxe_softc *)dev->si_drv1) == NULL) + return ENXIO; + + pci_dev= sc->dev; + + dump = (bxe_grcdump_t *)data; + + switch(cmd) { + + case BXE_GRC_DUMP_SIZE: + dump->pci_func = sc->pcie_func; + dump->grcdump_size = (bxe_get_total_regs_len32(sc) * sizeof(uint32_t)) + + sizeof(struct dump_header); + break; + + case BXE_GRC_DUMP: + + grc_dump_size = (bxe_get_total_regs_len32(sc) * sizeof(uint32_t)) + + sizeof(struct dump_header); + + if ((sc->grc_dump == NULL) || (dump->grcdump == NULL) || + (dump->grcdump_size < grc_dump_size)) { + rval = EINVAL; + break; + } + + rval = bxe_grc_dump(sc, dump); + + break; + + default: + break; + } + + return (rval); +} diff --git a/sys/dev/bxe/bxe.h b/sys/dev/bxe/bxe.h index 32b63f5..dc382ba 100644 --- a/sys/dev/bxe/bxe.h +++ b/sys/dev/bxe/bxe.h @@ -1830,6 +1830,11 @@ struct bxe_softc { uint8_t prio_to_cos[BXE_MAX_PRIORITY]; int panic; + + struct cdev *ioctl_dev; + void *grc_dump; + int trigger_grcdump; + int grcdump_done; }; /* struct bxe_softc */ /* IOCTL sub-commands for edebug and firmware upgrade */ @@ -2296,6 +2301,7 @@ void ecore_storm_memset_struct(struct bxe_softc *sc, uint32_t addr, "ERROR: " format, \ ## args); \ } \ + sc->trigger_grcdump |= 0x1; \ } while(0) #ifdef ECORE_STOP_ON_ERROR diff --git a/sys/dev/bxe/bxe_dump.h b/sys/dev/bxe/bxe_dump.h new file mode 100644 index 0000000..4985003 --- /dev/null +++ b/sys/dev/bxe/bxe_dump.h @@ -0,0 +1,2231 @@ +/* + * Copyright (c) 2007-2015 QLogic Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef __BXE_DUMP_H__ +#define __BXE_DUMP_H__ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +/* WaitP Definitions */ +#define DRV_DUMP_XSTORM_WAITP_ADDRESS 0x2b8a80 +#define DRV_DUMP_TSTORM_WAITP_ADDRESS 0x1b8a80 +#define DRV_DUMP_USTORM_WAITP_ADDRESS 0x338a80 +#define DRV_DUMP_CSTORM_WAITP_ADDRESS 0x238a80 + +/* Possible Chips */ +#define DUMP_CHIP_E1 1 +#define DUMP_CHIP_E1H 2 +#define DUMP_CHIP_E2 4 +#define DUMP_CHIP_E3A0 8 +#define DUMP_CHIP_E3B0 16 +#define DUMP_PATH_0 512 +#define DUMP_PATH_1 1024 +#define NUM_PRESETS 13 +#define NUM_CHIPS 5 + +struct dump_header { + uint32_t header_size; /* Size in DWORDs excluding this field */ + uint32_t version; + uint32_t preset; + uint32_t dump_meta_data; /* OR of CHIP and PATH. */ +}; + +#define BNX2X_DUMP_VERSION 0x61111111 +struct reg_addr { + uint32_t addr; + uint32_t size; + uint32_t chips; + uint32_t presets; +}; + +struct wreg_addr { + uint32_t addr; + uint32_t size; + uint32_t read_regs_count; + const uint32_t *read_regs; + uint32_t chips; + uint32_t presets; +}; + +#define PAGE_MODE_VALUES_E2 2 +#define PAGE_READ_REGS_E2 1 +#define PAGE_WRITE_REGS_E2 1 +static const uint32_t page_vals_e2[] = {0, 128}; +static const uint32_t page_write_regs_e2[] = {328476}; +static const struct reg_addr page_read_regs_e2[] = { + {0x58000, 4608, DUMP_CHIP_E2, 0x30} +}; + +#define PAGE_MODE_VALUES_E3 2 +#define PAGE_READ_REGS_E3 1 +#define PAGE_WRITE_REGS_E3 1 +static const uint32_t page_vals_e3[] = {0, 128}; +static const uint32_t page_write_regs_e3[] = {328476}; +static const struct reg_addr page_read_regs_e3[] = { + {0x58000, 4608, DUMP_CHIP_E3A0 | DUMP_CHIP_E3B0, 0x30} +}; + +static const struct reg_addr reg_addrs[] = { + { 0x2000, 1, 0x1f, 0xfff}, + { 0x2004, 1, 0x1f, 0x1fff}, + { 0x2008, 25, 0x1f, 0xfff}, + { 0x206c, 1, 0x1f, 0x1fff}, + { 0x2070, 313, 0x1f, 0xfff}, + { 0x2800, 103, 0x1f, 0xfff}, + { 0x3000, 287, 0x1f, 0xfff}, + { 0x3800, 331, 0x1f, 0xfff}, + { 0x8800, 6, 0x1f, 0x924}, + { 0x8818, 1, 0x1e, 0x924}, + { 0x9000, 4, 0x1c, 0x924}, + { 0x9010, 7, 0x1c, 0xfff}, + { 0x902c, 1, 0x1c, 0x924}, + { 0x9030, 1, 0x1c, 0xfff}, + { 0x9034, 13, 0x1c, 0x924}, + { 0x9068, 16, 0x1c, 0xfff}, + { 0x90a8, 98, 0x1c, 0x924}, + { 0x9230, 2, 0x1c, 0xfff}, + { 0x9238, 3, 0x1c, 0x924}, + { 0x9244, 1, 0x1c, 0xfff}, + { 0x9248, 1, 0x1c, 0x924}, + { 0x924c, 1, 0x4, 0x924}, + { 0x9250, 16, 0x1c, 0x924}, + { 0x92a8, 2, 0x1c, 0x1fff}, + { 0x92b4, 1, 0x1c, 0x1fff}, + { 0x9400, 33, 0x1c, 0x924}, + { 0x9484, 5, 0x18, 0x924}, + { 0xa000, 27, 0x1f, 0x924}, + { 0xa06c, 1, 0x3, 0x924}, + { 0xa070, 2, 0x1f, 0x924}, + { 0xa078, 1, 0x1f, 0x1fff}, + { 0xa07c, 31, 0x1f, 0x924}, + { 0xa0f8, 1, 0x1f, 0x1fff}, + { 0xa0fc, 3, 0x1f, 0x924}, + { 0xa108, 1, 0x1f, 0x1fff}, + { 0xa10c, 3, 0x1f, 0x924}, + { 0xa118, 1, 0x1f, 0x1fff}, + { 0xa11c, 28, 0x1f, 0x924}, + { 0xa18c, 4, 0x3, 0x924}, + { 0xa19c, 3, 0x1f, 0x924}, + { 0xa1a8, 1, 0x1f, 0x1fff}, + { 0xa1ac, 3, 0x1f, 0x924}, + { 0xa1b8, 1, 0x1f, 0x1fff}, + { 0xa1bc, 54, 0x1f, 0x924}, + { 0xa294, 2, 0x3, 0x924}, + { 0xa29c, 2, 0x1f, 0x924}, + { 0xa2a4, 2, 0x7, 0x924}, + { 0xa2ac, 2, 0x1f, 0x924}, + { 0xa2b4, 1, 0x1f, 0x1fff}, + { 0xa2b8, 49, 0x1f, 0x924}, + { 0xa38c, 2, 0x1f, 0x1fff}, + { 0xa398, 1, 0x1f, 0x1fff}, + { 0xa39c, 7, 0x1e, 0x924}, + { 0xa3b8, 2, 0x18, 0x924}, + { 0xa3c0, 1, 0x1e, 0x924}, + { 0xa3c4, 1, 0x1e, 0xfff}, + { 0xa3c8, 1, 0x1e, 0x924}, + { 0xa3d0, 1, 0x1e, 0x924}, + { 0xa3d8, 1, 0x1e, 0x924}, + { 0xa3e0, 1, 0x1e, 0x924}, + { 0xa3e8, 1, 0x1e, 0x924}, + { 0xa3f0, 1, 0x1e, 0x924}, + { 0xa3f8, 1, 0x1e, 0x924}, + { 0xa400, 1, 0x1f, 0x924}, + { 0xa404, 1, 0x1f, 0xfff}, + { 0xa408, 2, 0x1f, 0x1fff}, + { 0xa410, 7, 0x1f, 0x924}, + { 0xa42c, 12, 0x1f, 0xfff}, + { 0xa45c, 1, 0x1f, 0x924}, + { 0xa460, 1, 0x1f, 0x1924}, + { 0xa464, 15, 0x1f, 0x924}, + { 0xa4a0, 1, 0x7, 0x924}, + { 0xa4a4, 2, 0x1f, 0x924}, + { 0xa4ac, 2, 0x3, 0x924}, + { 0xa4b4, 1, 0x7, 0x924}, + { 0xa4b8, 2, 0x3, 0x924}, + { 0xa4c0, 3, 0x1f, 0x924}, + { 0xa4cc, 5, 0x3, 0x924}, + { 0xa4e0, 3, 0x1f, 0x924}, + { 0xa4fc, 2, 0x1f, 0x924}, + { 0xa504, 1, 0x3, 0x924}, + { 0xa508, 3, 0x1f, 0x924}, + { 0xa518, 1, 0x1f, 0x924}, + { 0xa520, 1, 0x1f, 0x924}, + { 0xa528, 1, 0x1f, 0x924}, + { 0xa530, 1, 0x1f, 0x924}, + { 0xa538, 1, 0x1f, 0x924}, + { 0xa540, 1, 0x1f, 0x924}, + { 0xa548, 1, 0x3, 0x924}, + { 0xa550, 1, 0x3, 0x924}, + { 0xa558, 1, 0x3, 0x924}, + { 0xa560, 1, 0x3, 0x924}, + { 0xa568, 1, 0x3, 0x924}, + { 0xa570, 1, 0x1f, 0x924}, + { 0xa580, 1, 0x1f, 0x1fff}, + { 0xa590, 1, 0x1f, 0x1fff}, + { 0xa5a0, 1, 0x7, 0x924}, + { 0xa5c0, 1, 0x1f, 0x924}, + { 0xa5e0, 1, 0x1e, 0x924}, + { 0xa5e8, 1, 0x1e, 0x924}, + { 0xa5f0, 1, 0x1e, 0x924}, + { 0xa5f8, 1, 0x6, 0x924}, + { 0xa5fc, 1, 0x1e, 0x924}, + { 0xa600, 5, 0x1e, 0xfff}, + { 0xa614, 1, 0x1e, 0x924}, + { 0xa618, 1, 0x1e, 0xfff}, + { 0xa61c, 1, 0x1e, 0x924}, + { 0xa620, 6, 0x1c, 0x924}, + { 0xa638, 20, 0x4, 0x924}, + { 0xa688, 35, 0x1c, 0x924}, + { 0xa714, 1, 0x1c, 0xfff}, + { 0xa718, 2, 0x1c, 0x924}, + { 0xa720, 1, 0x1c, 0xfff}, + { 0xa724, 3, 0x1c, 0x924}, + { 0xa730, 1, 0x4, 0x924}, + { 0xa734, 2, 0x1c, 0x924}, + { 0xa73c, 4, 0x4, 0x924}, + { 0xa74c, 1, 0x1c, 0x924}, + { 0xa750, 1, 0x1c, 0xfff}, + { 0xa754, 3, 0x1c, 0x924}, + { 0xa760, 5, 0x4, 0x924}, + { 0xa774, 7, 0x1c, 0x924}, + { 0xa790, 15, 0x4, 0x924}, + { 0xa7cc, 4, 0x1c, 0x924}, + { 0xa7e0, 6, 0x18, 0x924}, + { 0xa800, 18, 0x4, 0x924}, + { 0xa848, 33, 0x1c, 0x924}, + { 0xa8cc, 2, 0x18, 0x924}, + { 0xa8d4, 4, 0x1c, 0x924}, + { 0xa8e4, 1, 0x18, 0x924}, + { 0xa8e8, 1, 0x1c, 0x924}, + { 0xa8f0, 1, 0x1c, 0x924}, + { 0xa8f8, 30, 0x18, 0x924}, + { 0xa974, 73, 0x18, 0x924}, + { 0xac30, 1, 0x18, 0x924}, + { 0xac40, 1, 0x18, 0x924}, + { 0xac50, 1, 0x18, 0x924}, + { 0xac60, 1, 0x10, 0x924}, + { 0x10000, 9, 0x1f, 0x924}, + { 0x10024, 1, 0x7, 0x924}, + { 0x10028, 5, 0x1f, 0x924}, + { 0x1003c, 6, 0x7, 0x924}, + { 0x10054, 20, 0x1f, 0x924}, + { 0x100a4, 4, 0x7, 0x924}, + { 0x100b4, 11, 0x1f, 0x924}, + { 0x100e0, 4, 0x7, 0x924}, + { 0x100f0, 8, 0x1f, 0x924}, + { 0x10110, 6, 0x7, 0x924}, + { 0x10128, 110, 0x1f, 0x924}, + { 0x102e0, 4, 0x7, 0x924}, + { 0x102f0, 18, 0x1f, 0x924}, + { 0x10338, 20, 0x7, 0x924}, + { 0x10388, 10, 0x1f, 0x924}, + { 0x103d0, 2, 0x3, 0x1fff}, + { 0x103dc, 1, 0x3, 0x1fff}, + { 0x10400, 6, 0x7, 0x924}, + { 0x10418, 1, 0x1f, 0xfff}, + { 0x1041c, 1, 0x1f, 0x924}, + { 0x10420, 1, 0x1f, 0xfff}, + { 0x10424, 1, 0x1f, 0x924}, + { 0x10428, 1, 0x1f, 0xfff}, + { 0x1042c, 1, 0x1f, 0x924}, + { 0x10430, 10, 0x7, 0x924}, + { 0x10458, 2, 0x1f, 0x924}, + { 0x10460, 1, 0x1f, 0xfff}, + { 0x10464, 4, 0x1f, 0x924}, + { 0x10474, 1, 0x1f, 0xfff}, + { 0x10478, 14, 0x1f, 0x924}, + { 0x104b0, 12, 0x7, 0x924}, + { 0x104e0, 1, 0x1f, 0xfff}, + { 0x104e8, 1, 0x1f, 0x924}, + { 0x104ec, 1, 0x1f, 0xfff}, + { 0x104f4, 1, 0x1f, 0x924}, + { 0x104f8, 1, 0x1f, 0xfff}, + { 0x10500, 2, 0x1f, 0x924}, + { 0x10508, 1, 0x1f, 0xfff}, + { 0x1050c, 9, 0x1f, 0x924}, + { 0x10530, 1, 0x1f, 0xfff}, + { 0x10534, 1, 0x1f, 0x924}, + { 0x10538, 1, 0x1f, 0xfff}, + { 0x1053c, 3, 0x1f, 0x924}, + { 0x10548, 1, 0x1f, 0xfff}, + { 0x1054c, 3, 0x1f, 0x924}, + { 0x10558, 1, 0x1f, 0xfff}, + { 0x1055c, 123, 0x1f, 0x924}, + { 0x10750, 2, 0x7, 0x924}, + { 0x10760, 2, 0x7, 0x924}, + { 0x10770, 2, 0x7, 0x924}, + { 0x10780, 2, 0x7, 0x924}, + { 0x10790, 2, 0x1f, 0x924}, + { 0x107a0, 2, 0x7, 0x924}, + { 0x107b0, 2, 0x7, 0x924}, + { 0x107c0, 2, 0x7, 0x924}, + { 0x107d0, 2, 0x7, 0x924}, + { 0x107e0, 2, 0x1f, 0x924}, + { 0x10880, 2, 0x1f, 0x924}, + { 0x10900, 2, 0x1f, 0x924}, + { 0x16000, 1, 0x6, 0x924}, + { 0x16004, 25, 0x1e, 0x924}, + { 0x16070, 8, 0x1e, 0x924}, + { 0x16090, 4, 0xe, 0x924}, + { 0x160a0, 6, 0x1e, 0x924}, + { 0x160c0, 7, 0x1e, 0x924}, + { 0x160dc, 2, 0x6, 0x924}, + { 0x160e4, 6, 0x1e, 0x924}, + { 0x160fc, 4, 0x1e, 0x1fff}, + { 0x1610c, 2, 0x6, 0x924}, + { 0x16114, 6, 0x1e, 0x924}, + { 0x16140, 48, 0x1e, 0x1fff}, + { 0x16204, 5, 0x1e, 0x924}, + { 0x18000, 1, 0x1e, 0x924}, + { 0x18008, 1, 0x1e, 0x924}, + { 0x18010, 35, 0x1c, 0x924}, + { 0x180a4, 2, 0x1c, 0x924}, + { 0x180c0, 9, 0x1c, 0x924}, + { 0x180e4, 1, 0xc, 0x924}, + { 0x180e8, 2, 0x1c, 0x924}, + { 0x180f0, 1, 0xc, 0x924}, + { 0x180f4, 79, 0x1c, 0x924}, + { 0x18230, 1, 0xc, 0x924}, + { 0x18234, 2, 0x1c, 0x924}, + { 0x1823c, 1, 0xc, 0x924}, + { 0x18240, 13, 0x1c, 0x924}, + { 0x18274, 1, 0x4, 0x924}, + { 0x18278, 12, 0x1c, 0x924}, + { 0x182a8, 1, 0x1c, 0xfff}, + { 0x182ac, 3, 0x1c, 0x924}, + { 0x182b8, 1, 0x1c, 0xfff}, + { 0x182bc, 19, 0x1c, 0x924}, + { 0x18308, 1, 0x1c, 0xfff}, + { 0x1830c, 3, 0x1c, 0x924}, + { 0x18318, 1, 0x1c, 0xfff}, + { 0x1831c, 7, 0x1c, 0x924}, + { 0x18338, 1, 0x1c, 0xfff}, + { 0x1833c, 3, 0x1c, 0x924}, + { 0x18348, 1, 0x1c, 0xfff}, + { 0x1834c, 28, 0x1c, 0x924}, + { 0x183bc, 2, 0x1c, 0x1fff}, + { 0x183c8, 3, 0x1c, 0x1fff}, + { 0x183d8, 1, 0x1c, 0x1fff}, + { 0x18440, 48, 0x1c, 0x1fff}, + { 0x18500, 15, 0x1c, 0x924}, + { 0x18570, 1, 0x18, 0xfff}, + { 0x18574, 1, 0x18, 0x924}, + { 0x18578, 1, 0x18, 0xfff}, + { 0x1857c, 4, 0x18, 0x924}, + { 0x1858c, 1, 0x18, 0xfff}, + { 0x18590, 1, 0x18, 0x924}, + { 0x18594, 1, 0x18, 0xfff}, + { 0x18598, 32, 0x18, 0x924}, + { 0x18618, 5, 0x10, 0x924}, + { 0x1862c, 4, 0x10, 0xfff}, + { 0x1863c, 16, 0x10, 0x924}, + { 0x18680, 44, 0x10, 0x924}, + { 0x18748, 12, 0x10, 0x924}, + { 0x18788, 1, 0x10, 0x924}, + { 0x1879c, 6, 0x10, 0x924}, + { 0x187c4, 51, 0x10, 0x924}, + { 0x18a00, 48, 0x10, 0x924}, + { 0x20000, 24, 0x1f, 0x924}, + { 0x20060, 8, 0x1f, 0x9e4}, + { 0x20080, 94, 0x1f, 0x924}, + { 0x201f8, 1, 0x3, 0x924}, + { 0x201fc, 1, 0x1f, 0x924}, + { 0x20200, 1, 0x3, 0x924}, + { 0x20204, 1, 0x1f, 0x924}, + { 0x20208, 1, 0x3, 0x924}, + { 0x2020c, 4, 0x1f, 0x924}, + { 0x2021c, 11, 0x1f, 0xfff}, + { 0x20248, 24, 0x1f, 0x924}, + { 0x202b8, 2, 0x1f, 0x1fff}, + { 0x202c4, 1, 0x1f, 0x1fff}, + { 0x202c8, 1, 0x1c, 0x924}, + { 0x202d8, 4, 0x1c, 0x924}, + { 0x202f0, 1, 0x10, 0x924}, + { 0x20400, 1, 0x1f, 0x924}, + { 0x20404, 1, 0x1f, 0xfff}, + { 0x2040c, 2, 0x1f, 0xfff}, + { 0x20414, 2, 0x1f, 0x924}, + { 0x2041c, 2, 0x1f, 0xfff}, + { 0x20424, 2, 0x1f, 0x924}, + { 0x2042c, 18, 0x1e, 0x924}, + { 0x20480, 1, 0x1f, 0x924}, + { 0x20500, 1, 0x1f, 0x924}, + { 0x20600, 1, 0x1f, 0x924}, + { 0x28000, 1, 0x1f, 0x9e4}, + { 0x28004, 255, 0x1f, 0x180}, + { 0x28400, 1, 0x1f, 0x1c0}, + { 0x28404, 255, 0x1f, 0x180}, + { 0x28800, 1, 0x1f, 0x1c0}, + { 0x28804, 255, 0x1f, 0x180}, + { 0x28c00, 1, 0x1f, 0x1c0}, + { 0x28c04, 255, 0x1f, 0x180}, + { 0x29000, 1, 0x1f, 0x1c0}, + { 0x29004, 255, 0x1f, 0x180}, + { 0x29400, 1, 0x1f, 0x1c0}, + { 0x29404, 255, 0x1f, 0x180}, + { 0x29800, 1, 0x1f, 0x1c0}, + { 0x29804, 255, 0x1f, 0x180}, + { 0x29c00, 1, 0x1f, 0x1c0}, + { 0x29c04, 255, 0x1f, 0x180}, + { 0x2a000, 1, 0x1f, 0x1c0}, + { 0x2a004, 255, 0x1f, 0x180}, + { 0x2a400, 1, 0x1f, 0x1c0}, + { 0x2a404, 255, 0x1f, 0x180}, + { 0x2a800, 1, 0x1f, 0x1c0}, + { 0x2a804, 255, 0x1f, 0x180}, + { 0x2ac00, 1, 0x1f, 0x1c0}, + { 0x2ac04, 255, 0x1f, 0x180}, + { 0x2b000, 1, 0x1f, 0x1c0}, + { 0x2b004, 255, 0x1f, 0x180}, + { 0x2b400, 1, 0x1f, 0x1c0}, + { 0x2b404, 255, 0x1f, 0x180}, + { 0x2b800, 1, 0x1f, 0x1c0}, + { 0x2b804, 255, 0x1f, 0x180}, + { 0x2bc00, 1, 0x1f, 0x1c0}, + { 0x2bc04, 255, 0x1f, 0x180}, + { 0x2c000, 1, 0x1f, 0x1c0}, + { 0x2c004, 255, 0x1f, 0x180}, + { 0x2c400, 1, 0x1f, 0x1c0}, + { 0x2c404, 255, 0x1f, 0x180}, + { 0x2c800, 1, 0x1f, 0x1c0}, + { 0x2c804, 255, 0x1f, 0x180}, + { 0x2cc00, 1, 0x1f, 0x1c0}, + { 0x2cc04, 255, 0x1f, 0x180}, + { 0x2d000, 1, 0x1f, 0x1c0}, + { 0x2d004, 255, 0x1f, 0x180}, + { 0x2d400, 1, 0x1f, 0x1c0}, + { 0x2d404, 255, 0x1f, 0x180}, + { 0x2d800, 1, 0x1f, 0x1c0}, + { 0x2d804, 255, 0x1f, 0x180}, + { 0x2dc00, 1, 0x1f, 0x1c0}, + { 0x2dc04, 255, 0x1f, 0x180}, + { 0x2e000, 1, 0x1f, 0x1c0}, + { 0x2e004, 255, 0x1f, 0x180}, + { 0x2e400, 1, 0x1f, 0x1c0}, + { 0x2e404, 255, 0x1f, 0x180}, + { 0x2e800, 1, 0x1f, 0x1c0}, + { 0x2e804, 255, 0x1f, 0x180}, + { 0x2ec00, 1, 0x1f, 0x1c0}, + { 0x2ec04, 255, 0x1f, 0x180}, + { 0x2f000, 1, 0x1f, 0x1c0}, + { 0x2f004, 255, 0x1f, 0x180}, + { 0x2f400, 1, 0x1f, 0x1c0}, + { 0x2f404, 255, 0x1f, 0x180}, + { 0x2f800, 1, 0x1f, 0x1c0}, + { 0x2f804, 255, 0x1f, 0x180}, + { 0x2fc00, 1, 0x1f, 0x1c0}, + { 0x2fc04, 255, 0x1f, 0x180}, + { 0x30000, 1, 0x1f, 0x9e4}, + { 0x30004, 255, 0x1f, 0x180}, + { 0x30400, 1, 0x1f, 0x1c0}, + { 0x30404, 255, 0x1f, 0x180}, + { 0x30800, 1, 0x1f, 0x1c0}, + { 0x30804, 255, 0x1f, 0x180}, + { 0x30c00, 1, 0x1f, 0x1c0}, + { 0x30c04, 255, 0x1f, 0x180}, + { 0x31000, 1, 0x1f, 0x1c0}, + { 0x31004, 255, 0x1f, 0x180}, + { 0x31400, 1, 0x1f, 0x1c0}, + { 0x31404, 255, 0x1f, 0x180}, + { 0x31800, 1, 0x1f, 0x1c0}, + { 0x31804, 255, 0x1f, 0x180}, + { 0x31c00, 1, 0x1f, 0x1c0}, + { 0x31c04, 255, 0x1f, 0x180}, + { 0x32000, 1, 0x1f, 0x1c0}, + { 0x32004, 255, 0x1f, 0x180}, + { 0x32400, 1, 0x1f, 0x1c0}, + { 0x32404, 255, 0x1f, 0x180}, + { 0x32800, 1, 0x1f, 0x1c0}, + { 0x32804, 255, 0x1f, 0x180}, + { 0x32c00, 1, 0x1f, 0x1c0}, + { 0x32c04, 255, 0x1f, 0x180}, + { 0x33000, 1, 0x1f, 0x1c0}, + { 0x33004, 255, 0x1f, 0x180}, + { 0x33400, 1, 0x1f, 0x1c0}, + { 0x33404, 255, 0x1f, 0x180}, + { 0x33800, 1, 0x1f, 0x1c0}, + { 0x33804, 255, 0x1f, 0x180}, + { 0x33c00, 1, 0x1f, 0x1c0}, + { 0x33c04, 255, 0x1f, 0x180}, + { 0x34000, 1, 0x1f, 0x1c0}, + { 0x34004, 255, 0x1f, 0x180}, + { 0x34400, 1, 0x1f, 0x1c0}, + { 0x34404, 255, 0x1f, 0x180}, + { 0x34800, 1, 0x1f, 0x1c0}, + { 0x34804, 255, 0x1f, 0x180}, + { 0x34c00, 1, 0x1f, 0x1c0}, + { 0x34c04, 255, 0x1f, 0x180}, + { 0x35000, 1, 0x1f, 0x1c0}, + { 0x35004, 255, 0x1f, 0x180}, + { 0x35400, 1, 0x1f, 0x1c0}, + { 0x35404, 255, 0x1f, 0x180}, + { 0x35800, 1, 0x1f, 0x1c0}, + { 0x35804, 255, 0x1f, 0x180}, + { 0x35c00, 1, 0x1f, 0x1c0}, + { 0x35c04, 255, 0x1f, 0x180}, + { 0x36000, 1, 0x1f, 0x1c0}, + { 0x36004, 255, 0x1f, 0x180}, + { 0x36400, 1, 0x1f, 0x1c0}, + { 0x36404, 255, 0x1f, 0x180}, + { 0x36800, 1, 0x1f, 0x1c0}, + { 0x36804, 255, 0x1f, 0x180}, + { 0x36c00, 1, 0x1f, 0x1c0}, + { 0x36c04, 255, 0x1f, 0x180}, + { 0x37000, 1, 0x1f, 0x1c0}, + { 0x37004, 255, 0x1f, 0x180}, + { 0x37400, 1, 0x1f, 0x1c0}, + { 0x37404, 255, 0x1f, 0x180}, + { 0x37800, 1, 0x1f, 0x1c0}, + { 0x37804, 255, 0x1f, 0x180}, + { 0x37c00, 1, 0x1f, 0x1c0}, + { 0x37c04, 255, 0x1f, 0x180}, + { 0x38000, 1, 0x1f, 0x1c0}, + { 0x38004, 255, 0x1f, 0x180}, + { 0x38400, 1, 0x1f, 0x1c0}, + { 0x38404, 255, 0x1f, 0x180}, + { 0x38800, 1, 0x1f, 0x1c0}, + { 0x38804, 255, 0x1f, 0x180}, + { 0x38c00, 1, 0x1f, 0x1c0}, + { 0x38c04, 255, 0x1f, 0x180}, + { 0x39000, 1, 0x1f, 0x1c0}, + { 0x39004, 255, 0x1f, 0x180}, + { 0x39400, 1, 0x1f, 0x1c0}, + { 0x39404, 255, 0x1f, 0x180}, + { 0x39800, 1, 0x1f, 0x1c0}, + { 0x39804, 255, 0x1f, 0x180}, + { 0x39c00, 1, 0x1f, 0x1c0}, + { 0x39c04, 255, 0x1f, 0x180}, + { 0x3a000, 1, 0x1f, 0x1c0}, + { 0x3a004, 255, 0x1f, 0x180}, + { 0x3a400, 1, 0x1f, 0x1c0}, + { 0x3a404, 255, 0x1f, 0x180}, + { 0x3a800, 1, 0x1f, 0x1c0}, + { 0x3a804, 255, 0x1f, 0x180}, + { 0x3ac00, 1, 0x1f, 0x1c0}, + { 0x3ac04, 255, 0x1f, 0x180}, + { 0x3b000, 1, 0x1f, 0x1c0}, + { 0x3b004, 255, 0x1f, 0x180}, + { 0x3b400, 1, 0x1f, 0x1c0}, + { 0x3b404, 255, 0x1f, 0x180}, + { 0x3b800, 1, 0x1f, 0x1c0}, + { 0x3b804, 255, 0x1f, 0x180}, + { 0x3bc00, 1, 0x1f, 0x1c0}, + { 0x3bc04, 255, 0x1f, 0x180}, + { 0x3c000, 1, 0x1f, 0x1c0}, + { 0x3c004, 255, 0x1f, 0x180}, + { 0x3c400, 1, 0x1f, 0x1c0}, + { 0x3c404, 255, 0x1f, 0x180}, + { 0x3c800, 1, 0x1f, 0x1c0}, + { 0x3c804, 255, 0x1f, 0x180}, + { 0x3cc00, 1, 0x1f, 0x1c0}, + { 0x3cc04, 255, 0x1f, 0x180}, + { 0x3d000, 1, 0x1f, 0x1c0}, + { 0x3d004, 255, 0x1f, 0x180}, + { 0x3d400, 1, 0x1f, 0x1c0}, + { 0x3d404, 255, 0x1f, 0x180}, + { 0x3d800, 1, 0x1f, 0x1c0}, + { 0x3d804, 255, 0x1f, 0x180}, + { 0x3dc00, 1, 0x1f, 0x1c0}, + { 0x3dc04, 255, 0x1f, 0x180}, + { 0x3e000, 1, 0x1f, 0x1c0}, + { 0x3e004, 255, 0x1f, 0x180}, + { 0x3e400, 1, 0x1f, 0x1c0}, + { 0x3e404, 255, 0x1f, 0x180}, + { 0x3e800, 1, 0x1f, 0x1c0}, + { 0x3e804, 255, 0x1f, 0x180}, + { 0x3ec00, 1, 0x1f, 0x1c0}, + { 0x3ec04, 255, 0x1f, 0x180}, + { 0x3f000, 1, 0x1f, 0x1c0}, + { 0x3f004, 255, 0x1f, 0x180}, + { 0x3f400, 1, 0x1f, 0x1c0}, + { 0x3f404, 255, 0x1f, 0x180}, + { 0x3f800, 1, 0x1f, 0x1c0}, + { 0x3f804, 255, 0x1f, 0x180}, + { 0x3fc00, 1, 0x1f, 0x1c0}, + { 0x3fc04, 255, 0x1f, 0x180}, + { 0x40000, 85, 0x1f, 0x924}, + { 0x40154, 13, 0x1f, 0xfff}, + { 0x40198, 2, 0x1f, 0x1fff}, + { 0x401a4, 1, 0x1f, 0x1fff}, + { 0x401a8, 8, 0x1e, 0x924}, + { 0x401c8, 1, 0x2, 0x924}, + { 0x401cc, 2, 0x1e, 0x924}, + { 0x401d4, 2, 0x1c, 0x924}, + { 0x40200, 4, 0x1f, 0x924}, + { 0x40220, 6, 0x1c, 0x924}, + { 0x40238, 8, 0xc, 0x924}, + { 0x40258, 4, 0x1c, 0x924}, + { 0x40268, 2, 0x18, 0x924}, + { 0x40270, 17, 0x10, 0x924}, + { 0x40400, 43, 0x1f, 0x924}, + { 0x404bc, 2, 0x1f, 0x1fff}, + { 0x404c8, 1, 0x1f, 0x1fff}, + { 0x404cc, 3, 0x1e, 0x924}, + { 0x404e0, 1, 0x1c, 0x924}, + { 0x40500, 2, 0x1f, 0x924}, + { 0x40510, 2, 0x1f, 0x924}, + { 0x40520, 2, 0x1f, 0x924}, + { 0x40530, 2, 0x1f, 0x924}, + { 0x40540, 2, 0x1f, 0x924}, + { 0x40550, 10, 0x1c, 0x924}, + { 0x40610, 2, 0x1c, 0x924}, + { 0x42000, 164, 0x1f, 0x924}, + { 0x422b0, 2, 0x1f, 0x1fff}, + { 0x422bc, 1, 0x1f, 0x1fff}, + { 0x422c0, 4, 0x1c, 0x924}, + { 0x422d4, 5, 0x1e, 0x924}, + { 0x422e8, 1, 0x1c, 0x924}, + { 0x42400, 49, 0x1f, 0x924}, + { 0x424c8, 32, 0x1f, 0x924}, + { 0x42548, 1, 0x1f, 0xfff}, + { 0x4254c, 1, 0x1f, 0x924}, + { 0x42550, 1, 0x1f, 0xfff}, + { 0x42554, 1, 0x1f, 0x924}, + { 0x42558, 1, 0x1f, 0xfff}, + { 0x4255c, 1, 0x1f, 0x924}, + { 0x42568, 2, 0x1f, 0x924}, + { 0x42640, 5, 0x1c, 0x924}, + { 0x42800, 1, 0x1f, 0x924}, + { 0x50000, 1, 0x1f, 0x1fff}, + { 0x50004, 19, 0x1f, 0x924}, + { 0x50050, 8, 0x1f, 0x93c}, + { 0x50070, 60, 0x1f, 0x924}, + { 0x50160, 8, 0x1f, 0xfff}, + { 0x50180, 20, 0x1f, 0x924}, + { 0x501e0, 2, 0x1f, 0x1fff}, + { 0x501ec, 1, 0x1f, 0x1fff}, + { 0x501f0, 4, 0x1e, 0x924}, + { 0x50200, 1, 0x1f, 0x924}, + { 0x50204, 1, 0x1f, 0xfff}, + { 0x5020c, 2, 0x1f, 0xfff}, + { 0x50214, 2, 0x1f, 0x924}, + { 0x5021c, 1, 0x1f, 0xfff}, + { 0x50220, 2, 0x1f, 0x924}, + { 0x50228, 6, 0x1e, 0x924}, + { 0x50240, 1, 0x1f, 0x924}, + { 0x50280, 1, 0x1f, 0x924}, + { 0x50300, 1, 0x1c, 0x924}, + { 0x5030c, 1, 0x1c, 0x924}, + { 0x50318, 1, 0x1c, 0x934}, + { 0x5031c, 1, 0x1c, 0x924}, + { 0x50320, 2, 0x1c, 0x934}, + { 0x50330, 1, 0x10, 0x924}, + { 0x52000, 1, 0x1f, 0x924}, + { 0x54000, 1, 0x1f, 0x93c}, + { 0x54004, 255, 0x1f, 0x30}, + { 0x54400, 1, 0x1f, 0x38}, + { 0x54404, 255, 0x1f, 0x30}, + { 0x54800, 1, 0x1f, 0x38}, + { 0x54804, 255, 0x1f, 0x30}, + { 0x54c00, 1, 0x1f, 0x38}, + { 0x54c04, 255, 0x1f, 0x30}, + { 0x55000, 1, 0x1f, 0x38}, + { 0x55004, 255, 0x1f, 0x30}, + { 0x55400, 1, 0x1f, 0x38}, + { 0x55404, 255, 0x1f, 0x30}, + { 0x55800, 1, 0x1f, 0x38}, + { 0x55804, 255, 0x1f, 0x30}, + { 0x55c00, 1, 0x1f, 0x38}, + { 0x55c04, 255, 0x1f, 0x30}, + { 0x56000, 1, 0x1f, 0x38}, + { 0x56004, 255, 0x1f, 0x30}, + { 0x56400, 1, 0x1f, 0x38}, + { 0x56404, 255, 0x1f, 0x30}, + { 0x56800, 1, 0x1f, 0x38}, + { 0x56804, 255, 0x1f, 0x30}, + { 0x56c00, 1, 0x1f, 0x38}, + { 0x56c04, 255, 0x1f, 0x30}, + { 0x57000, 1, 0x1f, 0x38}, + { 0x57004, 255, 0x1f, 0x30}, + { 0x58000, 1, 0x1f, 0x934}, + { 0x58004, 8191, 0x3, 0x30}, + { 0x60000, 26, 0x1f, 0x924}, + { 0x60068, 8, 0x3, 0x924}, + { 0x60088, 2, 0x1f, 0x924}, + { 0x60090, 1, 0x1f, 0xfff}, + { 0x60094, 9, 0x1f, 0x924}, + { 0x600b8, 9, 0x3, 0x924}, + { 0x600dc, 1, 0x1f, 0x924}, + { 0x600e0, 5, 0x3, 0x924}, + { 0x600f4, 1, 0x7, 0x924}, + { 0x600f8, 1, 0x3, 0x924}, + { 0x600fc, 8, 0x1f, 0x924}, + { 0x6012c, 2, 0x1f, 0x1fff}, + { 0x60138, 1, 0x1f, 0x1fff}, + { 0x6013c, 24, 0x2, 0x924}, + { 0x6019c, 2, 0x1c, 0x924}, + { 0x601ac, 18, 0x1c, 0x924}, + { 0x60200, 1, 0x1f, 0xb6d}, + { 0x60204, 2, 0x1f, 0x249}, + { 0x60210, 13, 0x1c, 0x924}, + { 0x60244, 16, 0x10, 0x924}, + { 0x61000, 1, 0x1f, 0xb6d}, + { 0x61004, 511, 0x1f, 0x249}, + { 0x61800, 512, 0x18, 0x249}, + { 0x70000, 8, 0x1f, 0xb6d}, + { 0x70020, 8184, 0x1f, 0x249}, + { 0x78000, 8192, 0x18, 0x249}, + { 0x85000, 3, 0x1f, 0x1000}, + { 0x8501c, 7, 0x1f, 0x1000}, + { 0x85048, 1, 0x1f, 0x1000}, + { 0x85200, 32, 0x1f, 0x1000}, + { 0xa0000, 16384, 0x3, 0x1000}, + { 0xb0000, 16384, 0x2, 0x1000}, + { 0xc1000, 7, 0x1f, 0x924}, + { 0xc102c, 2, 0x1f, 0x1fff}, + { 0xc1038, 1, 0x1f, 0x1fff}, + { 0xc103c, 2, 0x1c, 0x924}, + { 0xc1800, 2, 0x1f, 0x924}, + { 0xc2000, 164, 0x1f, 0x924}, + { 0xc22b0, 2, 0x1f, 0x1fff}, + { 0xc22bc, 1, 0x1f, 0x1fff}, + { 0xc22c0, 5, 0x1c, 0x924}, + { 0xc22d8, 4, 0x1c, 0x924}, + { 0xc2400, 49, 0x1f, 0x924}, + { 0xc24c8, 32, 0x1f, 0x924}, + { 0xc2548, 1, 0x1f, 0xfff}, + { 0xc254c, 1, 0x1f, 0x924}, + { 0xc2550, 1, 0x1f, 0xfff}, + { 0xc2554, 1, 0x1f, 0x924}, + { 0xc2558, 1, 0x1f, 0xfff}, + { 0xc255c, 1, 0x1f, 0x924}, + { 0xc2568, 2, 0x1f, 0x924}, + { 0xc2600, 1, 0x1f, 0x924}, + { 0xc4000, 165, 0x1f, 0x924}, + { 0xc42b4, 2, 0x1f, 0x1fff}, + { 0xc42c0, 1, 0x1f, 0x1fff}, + { 0xc42d8, 2, 0x1c, 0x924}, + { 0xc42e0, 7, 0x1e, 0x924}, + { 0xc42fc, 1, 0x1c, 0x924}, + { 0xc4400, 51, 0x1f, 0x924}, + { 0xc44d0, 32, 0x1f, 0x924}, + { 0xc4550, 1, 0x1f, 0xfff}, + { 0xc4554, 1, 0x1f, 0x924}, + { 0xc4558, 1, 0x1f, 0xfff}, + { 0xc455c, 1, 0x1f, 0x924}, + { 0xc4560, 1, 0x1f, 0xfff}, + { 0xc4564, 1, 0x1f, 0x924}, + { 0xc4570, 2, 0x1f, 0x924}, + { 0xc4578, 5, 0x1c, 0x924}, + { 0xc4600, 1, 0x1f, 0x924}, + { 0xd0000, 19, 0x1f, 0x924}, + { 0xd004c, 8, 0x1f, 0x1927}, + { 0xd006c, 64, 0x1f, 0x924}, + { 0xd016c, 8, 0x1f, 0xfff}, + { 0xd018c, 19, 0x1f, 0x924}, + { 0xd01e8, 2, 0x1f, 0x1fff}, + { 0xd01f4, 1, 0x1f, 0x1fff}, + { 0xd01fc, 1, 0x1c, 0x924}, + { 0xd0200, 1, 0x1f, 0x924}, + { 0xd0204, 1, 0x1f, 0xfff}, + { 0xd020c, 3, 0x1f, 0xfff}, + { 0xd0218, 4, 0x1f, 0x924}, + { 0xd0228, 18, 0x1e, 0x924}, + { 0xd0280, 1, 0x1f, 0x924}, + { 0xd0300, 1, 0x1f, 0x924}, + { 0xd0400, 1, 0x1f, 0x924}, + { 0xd0818, 1, 0x10, 0x924}, + { 0xd4000, 1, 0x1f, 0x1927}, + { 0xd4004, 255, 0x1f, 0x6}, + { 0xd4400, 1, 0x1f, 0x1007}, + { 0xd4404, 255, 0x1f, 0x6}, + { 0xd4800, 1, 0x1f, 0x1007}, + { 0xd4804, 255, 0x1f, 0x6}, + { 0xd4c00, 1, 0x1f, 0x1007}, + { 0xd4c04, 255, 0x1f, 0x6}, + { 0xd5000, 1, 0x1f, 0x1007}, + { 0xd5004, 255, 0x1f, 0x6}, + { 0xd5400, 1, 0x1f, 0x1007}, + { 0xd5404, 255, 0x1f, 0x6}, + { 0xd5800, 1, 0x1f, 0x1007}, + { 0xd5804, 255, 0x1f, 0x6}, + { 0xd5c00, 1, 0x1f, 0x1007}, + { 0xd5c04, 255, 0x1f, 0x6}, + { 0xd6000, 1, 0x1f, 0x1007}, + { 0xd6004, 255, 0x1f, 0x6}, + { 0xd6400, 1, 0x1f, 0x1007}, + { 0xd6404, 255, 0x1f, 0x6}, + { 0xd8000, 1, 0x1f, 0x1927}, + { 0xd8004, 255, 0x1f, 0x6}, + { 0xd8400, 1, 0x1f, 0x1007}, + { 0xd8404, 255, 0x1f, 0x6}, + { 0xd8800, 1, 0x1f, 0x1007}, + { 0xd8804, 255, 0x1f, 0x6}, + { 0xd8c00, 1, 0x1f, 0x1007}, + { 0xd8c04, 255, 0x1f, 0x6}, + { 0xd9000, 1, 0x1f, 0x1007}, + { 0xd9004, 255, 0x1f, 0x6}, + { 0xd9400, 1, 0x1f, 0x1007}, + { 0xd9404, 255, 0x1f, 0x6}, + { 0xd9800, 1, 0x1f, 0x1007}, + { 0xd9804, 255, 0x1f, 0x6}, + { 0xd9c00, 1, 0x1f, 0x1007}, + { 0xd9c04, 255, 0x1f, 0x6}, + { 0xda000, 1, 0x1f, 0x1007}, + { 0xda004, 255, 0x1f, 0x6}, + { 0xda400, 1, 0x1f, 0x1007}, + { 0xda404, 255, 0x1f, 0x6}, + { 0xda800, 1, 0x1f, 0x1007}, + { 0xda804, 255, 0x1f, 0x6}, + { 0xdac00, 1, 0x1f, 0x1007}, + { 0xdac04, 255, 0x1f, 0x6}, + { 0xdb000, 1, 0x1f, 0x1007}, + { 0xdb004, 255, 0x1f, 0x6}, + { 0xdb400, 1, 0x1f, 0x1007}, + { 0xdb404, 255, 0x1f, 0x6}, + { 0xdb800, 1, 0x1f, 0x1007}, + { 0xdb804, 255, 0x1f, 0x6}, + { 0xdbc00, 1, 0x1f, 0x1007}, + { 0xdbc04, 255, 0x1f, 0x6}, + { 0xdc000, 1, 0x1f, 0x1007}, + { 0xdc004, 255, 0x1f, 0x6}, + { 0xdc400, 1, 0x1f, 0x1007}, + { 0xdc404, 255, 0x1f, 0x6}, + { 0xdc800, 1, 0x1f, 0x1007}, + { 0xdc804, 255, 0x1f, 0x6}, + { 0xdcc00, 1, 0x1f, 0x1007}, + { 0xdcc04, 255, 0x1f, 0x6}, + { 0xdd000, 1, 0x1f, 0x1007}, + { 0xdd004, 255, 0x1f, 0x6}, + { 0xdd400, 1, 0x1f, 0x1007}, + { 0xdd404, 255, 0x1f, 0x6}, + { 0xdd800, 1, 0x1f, 0x1007}, + { 0xdd804, 255, 0x1f, 0x6}, + { 0xddc00, 1, 0x1f, 0x1007}, + { 0xddc04, 255, 0x1f, 0x6}, + { 0xde000, 1, 0x1f, 0x1007}, + { 0xde004, 255, 0x1f, 0x6}, + { 0xde400, 1, 0x1f, 0x1007}, + { 0xde404, 255, 0x1f, 0x6}, + { 0xde800, 1, 0x1f, 0x1007}, + { 0xde804, 255, 0x1f, 0x6}, + { 0xdec00, 1, 0x1f, 0x1007}, + { 0xdec04, 255, 0x1f, 0x6}, + { 0xdf000, 1, 0x1f, 0x1007}, + { 0xdf004, 255, 0x1f, 0x6}, + { 0xdf400, 1, 0x1f, 0x1007}, + { 0xdf404, 255, 0x1f, 0x6}, + { 0xdf800, 1, 0x1f, 0x1007}, + { 0xdf804, 255, 0x1f, 0x6}, + { 0xdfc00, 1, 0x1f, 0x1007}, + { 0xdfc04, 255, 0x1f, 0x6}, + { 0xe0000, 21, 0x1f, 0x924}, + { 0xe0054, 8, 0x1f, 0xf24}, + { 0xe0074, 49, 0x1f, 0x924}, + { 0xe0138, 1, 0x3, 0x924}, + { 0xe013c, 6, 0x1f, 0x924}, + { 0xe0154, 8, 0x1f, 0xfff}, + { 0xe0174, 21, 0x1f, 0x924}, + { 0xe01d8, 2, 0x1f, 0x1fff}, + { 0xe01e4, 1, 0x1f, 0x1fff}, + { 0xe01f4, 1, 0x4, 0x924}, + { 0xe01f8, 1, 0x1c, 0x924}, + { 0xe0200, 1, 0x1f, 0x924}, + { 0xe0204, 1, 0x1f, 0xfff}, + { 0xe020c, 2, 0x1f, 0xfff}, + { 0xe0214, 2, 0x1f, 0x924}, + { 0xe021c, 2, 0x1f, 0xfff}, + { 0xe0224, 2, 0x1f, 0x924}, + { 0xe022c, 18, 0x1e, 0x924}, + { 0xe0280, 1, 0x1f, 0x924}, + { 0xe0300, 1, 0x1f, 0x924}, + { 0xe0400, 1, 0x10, 0x924}, + { 0xe1000, 1, 0x1f, 0x924}, + { 0xe2000, 1, 0x1f, 0xf24}, + { 0xe2004, 255, 0x1f, 0xc00}, + { 0xe2400, 1, 0x1f, 0xe00}, + { 0xe2404, 255, 0x1f, 0xc00}, + { 0xe2800, 1, 0x1f, 0xe00}, + { 0xe2804, 255, 0x1f, 0xc00}, + { 0xe2c00, 1, 0x1f, 0xe00}, + { 0xe2c04, 255, 0x1f, 0xc00}, + { 0xe3000, 1, 0x1f, 0xe00}, + { 0xe3004, 255, 0x1f, 0xc00}, + { 0xe3400, 1, 0x1f, 0xe00}, + { 0xe3404, 255, 0x1f, 0xc00}, + { 0xe3800, 1, 0x1f, 0xe00}, + { 0xe3804, 255, 0x1f, 0xc00}, + { 0xe3c00, 1, 0x1f, 0xe00}, + { 0xe3c04, 255, 0x1f, 0xc00}, + { 0xf0000, 1, 0x1f, 0xf24}, + { 0xf0004, 255, 0x1f, 0xc00}, + { 0xf0400, 1, 0x1f, 0xe00}, + { 0xf0404, 255, 0x1f, 0xc00}, + { 0xf0800, 1, 0x1f, 0xe00}, + { 0xf0804, 255, 0x1f, 0xc00}, + { 0xf0c00, 1, 0x1f, 0xe00}, + { 0xf0c04, 255, 0x1f, 0xc00}, + { 0xf1000, 1, 0x1f, 0xe00}, + { 0xf1004, 255, 0x1f, 0xc00}, + { 0xf1400, 1, 0x1f, 0xe00}, + { 0xf1404, 255, 0x1f, 0xc00}, + { 0xf1800, 1, 0x1f, 0xe00}, + { 0xf1804, 255, 0x1f, 0xc00}, + { 0xf1c00, 1, 0x1f, 0xe00}, + { 0xf1c04, 255, 0x1f, 0xc00}, + { 0xf2000, 1, 0x1f, 0xe00}, + { 0xf2004, 255, 0x1f, 0xc00}, + { 0xf2400, 1, 0x1f, 0xe00}, + { 0xf2404, 255, 0x1f, 0xc00}, + { 0xf2800, 1, 0x1f, 0xe00}, + { 0xf2804, 255, 0x1f, 0xc00}, + { 0xf2c00, 1, 0x1f, 0xe00}, + { 0xf2c04, 255, 0x1f, 0xc00}, + { 0xf3000, 1, 0x1f, 0xe00}, + { 0xf3004, 255, 0x1f, 0xc00}, + { 0xf3400, 1, 0x1f, 0xe00}, + { 0xf3404, 255, 0x1f, 0xc00}, + { 0xf3800, 1, 0x1f, 0xe00}, + { 0xf3804, 255, 0x1f, 0xc00}, + { 0xf3c00, 1, 0x1f, 0xe00}, + { 0xf3c04, 255, 0x1f, 0xc00}, + { 0xf4000, 1, 0x1f, 0xe00}, + { 0xf4004, 255, 0x1f, 0xc00}, + { 0xf4400, 1, 0x1f, 0xe00}, + { 0xf4404, 255, 0x1f, 0xc00}, + { 0xf4800, 1, 0x1f, 0xe00}, + { 0xf4804, 255, 0x1f, 0xc00}, + { 0xf4c00, 1, 0x1f, 0xe00}, + { 0xf4c04, 255, 0x1f, 0xc00}, + { 0xf5000, 1, 0x1f, 0xe00}, + { 0xf5004, 255, 0x1f, 0xc00}, + { 0xf5400, 1, 0x1f, 0xe00}, + { 0xf5404, 255, 0x1f, 0xc00}, + { 0xf5800, 1, 0x1f, 0xe00}, + { 0xf5804, 255, 0x1f, 0xc00}, + { 0xf5c00, 1, 0x1f, 0xe00}, + { 0xf5c04, 255, 0x1f, 0xc00}, + { 0xf6000, 1, 0x1f, 0xe00}, + { 0xf6004, 255, 0x1f, 0xc00}, + { 0xf6400, 1, 0x1f, 0xe00}, + { 0xf6404, 255, 0x1f, 0xc00}, + { 0xf6800, 1, 0x1f, 0xe00}, + { 0xf6804, 255, 0x1f, 0xc00}, + { 0xf6c00, 1, 0x1f, 0xe00}, + { 0xf6c04, 255, 0x1f, 0xc00}, + { 0xf7000, 1, 0x1f, 0xe00}, + { 0xf7004, 255, 0x1f, 0xc00}, + { 0xf7400, 1, 0x1f, 0xe00}, + { 0xf7404, 255, 0x1f, 0xc00}, + { 0xf7800, 1, 0x1f, 0xe00}, + { 0xf7804, 255, 0x1f, 0xc00}, + { 0xf7c00, 1, 0x1f, 0xe00}, + { 0xf7c04, 255, 0x1f, 0xc00}, + { 0xf8000, 1, 0x1f, 0xe00}, + { 0xf8004, 255, 0x1f, 0xc00}, + { 0xf8400, 1, 0x1f, 0xe00}, + { 0xf8404, 255, 0x1f, 0xc00}, + { 0xf8800, 1, 0x1f, 0xe00}, + { 0xf8804, 255, 0x1f, 0xc00}, + { 0xf8c00, 1, 0x1f, 0xe00}, + { 0xf8c04, 255, 0x1f, 0xc00}, + { 0xf9000, 1, 0x1f, 0xe00}, + { 0xf9004, 255, 0x1f, 0xc00}, + { 0xf9400, 1, 0x1f, 0xe00}, + { 0xf9404, 255, 0x1f, 0xc00}, + { 0xf9800, 1, 0x1f, 0xe00}, + { 0xf9804, 255, 0x1f, 0xc00}, + { 0xf9c00, 1, 0x1f, 0xe00}, + { 0xf9c04, 255, 0x1f, 0xc00}, + { 0xfa000, 1, 0x1f, 0xe00}, + { 0xfa004, 255, 0x1f, 0xc00}, + { 0xfa400, 1, 0x1f, 0xe00}, + { 0xfa404, 255, 0x1f, 0xc00}, + { 0xfa800, 1, 0x1f, 0xe00}, + { 0xfa804, 255, 0x1f, 0xc00}, + { 0xfac00, 1, 0x1f, 0xe00}, + { 0xfac04, 255, 0x1f, 0xc00}, + { 0xfb000, 1, 0x1f, 0xe00}, + { 0xfb004, 255, 0x1f, 0xc00}, + { 0xfb400, 1, 0x1f, 0xe00}, + { 0xfb404, 255, 0x1f, 0xc00}, + { 0xfb800, 1, 0x1f, 0xe00}, + { 0xfb804, 255, 0x1f, 0xc00}, + { 0xfbc00, 1, 0x1f, 0xe00}, + { 0xfbc04, 255, 0x1f, 0xc00}, + { 0xfc000, 1, 0x1f, 0xe00}, + { 0xfc004, 255, 0x1f, 0xc00}, + { 0xfc400, 1, 0x1f, 0xe00}, + { 0xfc404, 255, 0x1f, 0xc00}, + { 0xfc800, 1, 0x1f, 0xe00}, + { 0xfc804, 255, 0x1f, 0xc00}, + { 0xfcc00, 1, 0x1f, 0xe00}, + { 0xfcc04, 255, 0x1f, 0xc00}, + { 0xfd000, 1, 0x1f, 0xe00}, + { 0xfd004, 255, 0x1f, 0xc00}, + { 0xfd400, 1, 0x1f, 0xe00}, + { 0xfd404, 255, 0x1f, 0xc00}, + { 0xfd800, 1, 0x1f, 0xe00}, + { 0xfd804, 255, 0x1f, 0xc00}, + { 0xfdc00, 1, 0x1f, 0xe00}, + { 0xfdc04, 255, 0x1f, 0xc00}, + { 0xfe000, 1, 0x1f, 0xe00}, + { 0xfe004, 255, 0x1f, 0xc00}, + { 0xfe400, 1, 0x1f, 0xe00}, + { 0xfe404, 255, 0x1f, 0xc00}, + { 0xfe800, 1, 0x1f, 0xe00}, + { 0xfe804, 255, 0x1f, 0xc00}, + { 0xfec00, 1, 0x1f, 0xe00}, + { 0xfec04, 255, 0x1f, 0xc00}, + { 0xff000, 1, 0x1f, 0xe00}, + { 0xff004, 255, 0x1f, 0xc00}, + { 0xff400, 1, 0x1f, 0xe00}, + { 0xff404, 255, 0x1f, 0xc00}, + { 0xff800, 1, 0x1f, 0xe00}, + { 0xff804, 255, 0x1f, 0xc00}, + { 0xffc00, 1, 0x1f, 0xe00}, + { 0xffc04, 255, 0x1f, 0xc00}, + { 0x101000, 5, 0x1f, 0x924}, + { 0x101014, 1, 0x1f, 0xfff}, + { 0x101018, 6, 0x1f, 0x924}, + { 0x101040, 2, 0x1f, 0x1fff}, + { 0x10104c, 1, 0x1f, 0x1fff}, + { 0x101050, 1, 0x1e, 0x924}, + { 0x101054, 3, 0x1c, 0x924}, + { 0x101100, 1, 0x1f, 0x924}, + { 0x101800, 8, 0x1f, 0x924}, + { 0x102000, 18, 0x1f, 0x924}, + { 0x102058, 2, 0x1f, 0x1fff}, + { 0x102064, 1, 0x1f, 0x1fff}, + { 0x102068, 6, 0x1c, 0x924}, + { 0x102080, 16, 0x1f, 0xfff}, + { 0x1020c0, 1, 0x1f, 0x924}, + { 0x1020c8, 8, 0x2, 0x924}, + { 0x1020e8, 9, 0x1c, 0x924}, + { 0x102400, 1, 0x1f, 0x924}, + { 0x103000, 1, 0x1f, 0x924}, + { 0x103004, 2, 0x1f, 0xfff}, + { 0x10300c, 23, 0x1f, 0x924}, + { 0x103088, 2, 0x1f, 0x1fff}, + { 0x103094, 1, 0x1f, 0x1fff}, + { 0x103098, 1, 0x1e, 0x924}, + { 0x10309c, 2, 0x1e, 0xfff}, + { 0x1030a4, 2, 0x1e, 0x924}, + { 0x1030ac, 2, 0x1c, 0x924}, + { 0x1030b4, 1, 0x4, 0x924}, + { 0x1030b8, 2, 0x1c, 0xfff}, + { 0x1030c0, 3, 0x1c, 0x924}, + { 0x1030cc, 1, 0x1c, 0xfff}, + { 0x1030d0, 1, 0x1c, 0x924}, + { 0x1030d8, 2, 0x1c, 0x924}, + { 0x1030e0, 1, 0x1c, 0xfff}, + { 0x1030e4, 5, 0x1c, 0x924}, + { 0x103400, 136, 0x1c, 0x1fff}, + { 0x103800, 8, 0x1f, 0x924}, + { 0x104000, 1, 0x1f, 0x924}, + { 0x104004, 1, 0x1f, 0xfff}, + { 0x104008, 4, 0x1f, 0x924}, + { 0x104018, 1, 0x1f, 0xfff}, + { 0x10401c, 1, 0x1f, 0x924}, + { 0x104020, 1, 0x1f, 0xfff}, + { 0x104024, 6, 0x1f, 0x924}, + { 0x10403c, 1, 0x1f, 0xfff}, + { 0x104040, 47, 0x1f, 0x924}, + { 0x10410c, 2, 0x1f, 0x1fff}, + { 0x104118, 1, 0x1f, 0x1fff}, + { 0x10411c, 16, 0x1c, 0x924}, + { 0x104200, 17, 0x1f, 0x924}, + { 0x104400, 1, 0x1f, 0x1fff}, + { 0x104404, 63, 0x1f, 0xfff}, + { 0x104500, 192, 0x1f, 0xdb6}, + { 0x104800, 1, 0x1f, 0x1fff}, + { 0x104804, 63, 0x1f, 0xfff}, + { 0x104900, 192, 0x1f, 0xdb6}, + { 0x105000, 4, 0x1f, 0x1fff}, + { 0x105010, 252, 0x1f, 0xfff}, + { 0x105400, 768, 0x1f, 0xdb6}, + { 0x107000, 7, 0x1c, 0x924}, + { 0x10701c, 1, 0x18, 0x924}, + { 0x108000, 33, 0x3, 0x924}, + { 0x1080ac, 5, 0x2, 0x924}, + { 0x108100, 5, 0x3, 0x924}, + { 0x108120, 5, 0x3, 0x924}, + { 0x108200, 74, 0x3, 0x924}, + { 0x108400, 74, 0x3, 0x924}, + { 0x108800, 152, 0x3, 0x924}, + { 0x110000, 111, 0x1c, 0x924}, + { 0x1101cc, 2, 0x1c, 0x1fff}, + { 0x1101d8, 1, 0x1c, 0x1fff}, + { 0x1101dc, 1, 0x18, 0x924}, + { 0x110200, 4, 0x1c, 0x924}, + { 0x120000, 92, 0x1f, 0x924}, + { 0x120170, 2, 0x3, 0x924}, + { 0x120178, 14, 0x1f, 0x924}, + { 0x1201b0, 2, 0x1f, 0xfff}, + { 0x1201b8, 93, 0x1f, 0x924}, + { 0x12032c, 1, 0x1f, 0xfff}, + { 0x120330, 15, 0x1f, 0x924}, + { 0x12036c, 3, 0x1f, 0xfff}, + { 0x120378, 36, 0x1f, 0x924}, + { 0x120408, 2, 0x1f, 0xfff}, + { 0x120410, 1, 0x1f, 0x924}, + { 0x120414, 15, 0x1f, 0xfff}, + { 0x120450, 10, 0x1f, 0x924}, + { 0x120478, 2, 0x1f, 0xfff}, + { 0x120480, 43, 0x1f, 0x924}, + { 0x12052c, 1, 0x1f, 0xfff}, + { 0x120530, 5, 0x1f, 0x924}, + { 0x120544, 4, 0x3, 0x924}, + { 0x120554, 4, 0x1f, 0x924}, + { 0x120564, 2, 0x1f, 0xfff}, + { 0x12057c, 2, 0x1f, 0x1fff}, + { 0x120588, 3, 0x1f, 0x1fff}, + { 0x120598, 1, 0x1f, 0x1fff}, + { 0x12059c, 22, 0x1e, 0x924}, + { 0x1205f4, 1, 0x6, 0x924}, + { 0x1205f8, 4, 0x1c, 0x924}, + { 0x120618, 1, 0x1c, 0x924}, + { 0x12061c, 31, 0x1e, 0x924}, + { 0x120698, 3, 0x1c, 0x924}, + { 0x1206a4, 1, 0x4, 0x924}, + { 0x1206a8, 1, 0x1c, 0x924}, + { 0x1206b0, 38, 0x1c, 0x924}, + { 0x120748, 1, 0x1c, 0xfff}, + { 0x12074c, 11, 0x1c, 0x924}, + { 0x120778, 2, 0x1c, 0xfff}, + { 0x120780, 23, 0x1c, 0x924}, + { 0x1207dc, 1, 0x4, 0x924}, + { 0x1207fc, 1, 0x1c, 0x924}, + { 0x12080c, 2, 0x1f, 0xfff}, + { 0x120814, 1, 0x1f, 0x924}, + { 0x120818, 1, 0x1f, 0xfff}, + { 0x12081c, 1, 0x1f, 0x924}, + { 0x120820, 1, 0x1f, 0xfff}, + { 0x120824, 1, 0x1f, 0x924}, + { 0x120828, 1, 0x1f, 0xfff}, + { 0x12082c, 1, 0x1f, 0x924}, + { 0x120830, 1, 0x1f, 0xfff}, + { 0x120834, 1, 0x1f, 0x924}, + { 0x120838, 1, 0x1f, 0xfff}, + { 0x12083c, 1, 0x1f, 0x924}, + { 0x120840, 1, 0x1f, 0xfff}, + { 0x120844, 1, 0x1f, 0x924}, + { 0x120848, 1, 0x1f, 0xfff}, + { 0x12084c, 1, 0x1f, 0x924}, + { 0x120850, 1, 0x1f, 0xfff}, + { 0x120854, 1, 0x1f, 0x924}, + { 0x120858, 1, 0x1f, 0xfff}, + { 0x12085c, 1, 0x1f, 0x924}, + { 0x120860, 1, 0x1f, 0xfff}, + { 0x120864, 1, 0x1f, 0x924}, + { 0x120868, 1, 0x1f, 0xfff}, + { 0x12086c, 1, 0x1f, 0x924}, + { 0x120870, 1, 0x1f, 0xfff}, + { 0x120874, 1, 0x1f, 0x924}, + { 0x120878, 1, 0x1f, 0xfff}, + { 0x12087c, 1, 0x1f, 0x924}, + { 0x120880, 1, 0x1f, 0xfff}, + { 0x120884, 1, 0x1f, 0x924}, + { 0x120888, 1, 0x1f, 0xfff}, + { 0x12088c, 1, 0x1f, 0x924}, + { 0x120890, 1, 0x1f, 0xfff}, + { 0x120894, 1, 0x1f, 0x924}, + { 0x120898, 1, 0x1f, 0xfff}, + { 0x12089c, 1, 0x1f, 0x924}, + { 0x1208a0, 1, 0x1f, 0xfff}, + { 0x1208a4, 1, 0x1f, 0x924}, + { 0x1208a8, 1, 0x1f, 0xfff}, + { 0x1208ac, 1, 0x1f, 0x924}, + { 0x1208b0, 1, 0x1f, 0xfff}, + { 0x1208b4, 1, 0x1f, 0x924}, + { 0x1208b8, 1, 0x1f, 0xfff}, + { 0x1208bc, 1, 0x1f, 0x924}, + { 0x1208c0, 1, 0x1f, 0xfff}, + { 0x1208c4, 1, 0x1f, 0x924}, + { 0x1208c8, 1, 0x1f, 0xfff}, + { 0x1208cc, 1, 0x1f, 0x924}, + { 0x1208d0, 1, 0x1f, 0xfff}, + { 0x1208d4, 1, 0x1f, 0x924}, + { 0x1208d8, 1, 0x1f, 0xfff}, + { 0x1208dc, 1, 0x1f, 0x924}, + { 0x1208e0, 1, 0x1f, 0xfff}, + { 0x1208e4, 1, 0x1f, 0x924}, + { 0x1208e8, 1, 0x1f, 0xfff}, + { 0x1208ec, 1, 0x1f, 0x924}, + { 0x1208f0, 1, 0x1f, 0xfff}, + { 0x1208f4, 1, 0x1f, 0x924}, + { 0x1208f8, 1, 0x1f, 0xfff}, + { 0x1208fc, 1, 0x1f, 0x924}, + { 0x120900, 1, 0x1f, 0xfff}, + { 0x120904, 1, 0x1f, 0x924}, + { 0x120908, 1, 0x1f, 0xfff}, + { 0x12090c, 1, 0x1f, 0x924}, + { 0x120910, 7, 0x1c, 0x924}, + { 0x120930, 9, 0x1c, 0x924}, + { 0x12095c, 37, 0x18, 0x924}, + { 0x120a00, 2, 0x7, 0x924}, + { 0x120b00, 1, 0x18, 0x924}, + { 0x122000, 2, 0x1f, 0x924}, + { 0x122008, 2046, 0x1, 0x924}, + { 0x128000, 6144, 0x1e, 0x924}, + { 0x130000, 1, 0x1c, 0x1fff}, + { 0x130004, 11, 0x1c, 0x924}, + { 0x130030, 1, 0x1c, 0xfff}, + { 0x130034, 6, 0x1c, 0x924}, + { 0x13004c, 3, 0x1c, 0xfff}, + { 0x130058, 3, 0x1c, 0x924}, + { 0x130064, 2, 0x1c, 0xfff}, + { 0x13006c, 8, 0x1c, 0x924}, + { 0x13009c, 2, 0x1c, 0x1fff}, + { 0x1300a8, 1, 0x1c, 0x1fff}, + { 0x130100, 12, 0x1c, 0x924}, + { 0x130130, 1, 0x1c, 0xfff}, + { 0x130134, 14, 0x1c, 0x924}, + { 0x13016c, 1, 0x1c, 0xfff}, + { 0x130170, 1, 0x1c, 0x924}, + { 0x130180, 1, 0x1c, 0x924}, + { 0x130200, 1, 0x1c, 0x924}, + { 0x130280, 1, 0x1c, 0x924}, + { 0x130300, 1, 0x1c, 0xfff}, + { 0x130304, 4, 0x1c, 0x924}, + { 0x130380, 1, 0x1c, 0x924}, + { 0x130400, 1, 0x1c, 0x924}, + { 0x130480, 1, 0x1c, 0xfff}, + { 0x130484, 4, 0x1c, 0x924}, + { 0x130800, 72, 0x1c, 0x924}, + { 0x131000, 136, 0x1c, 0x924}, + { 0x132000, 148, 0x1c, 0x924}, + { 0x134000, 544, 0x1c, 0x924}, + { 0x140000, 1, 0x1f, 0x924}, + { 0x140004, 9, 0xf, 0x924}, + { 0x140028, 8, 0x1f, 0x924}, + { 0x140048, 5, 0xf, 0x924}, + { 0x14005c, 2, 0xf, 0xfff}, + { 0x140064, 3, 0xf, 0x924}, + { 0x140070, 1, 0x1f, 0x924}, + { 0x140074, 10, 0xf, 0x924}, + { 0x14009c, 1, 0x1f, 0x924}, + { 0x1400a0, 5, 0xf, 0x924}, + { 0x1400b4, 7, 0x1f, 0x924}, + { 0x1400d0, 2, 0xf, 0xfff}, + { 0x1400d8, 2, 0xf, 0x924}, + { 0x1400e0, 1, 0xf, 0xfff}, + { 0x1400e4, 5, 0xf, 0x924}, + { 0x1400f8, 2, 0x1f, 0x924}, + { 0x140100, 5, 0x3, 0x924}, + { 0x140114, 5, 0xf, 0x924}, + { 0x140128, 7, 0x1f, 0x924}, + { 0x140144, 9, 0xf, 0x924}, + { 0x140168, 8, 0x1f, 0x924}, + { 0x140188, 3, 0xf, 0x924}, + { 0x140194, 13, 0x1f, 0x924}, + { 0x1401d8, 2, 0x1f, 0x1fff}, + { 0x1401e4, 1, 0x1f, 0x1fff}, + { 0x140200, 6, 0xf, 0xfff}, + { 0x1402e0, 2, 0xc, 0x924}, + { 0x1402e8, 2, 0x1c, 0x924}, + { 0x1402f0, 9, 0xc, 0x924}, + { 0x140314, 9, 0x10, 0x924}, + { 0x140338, 7, 0x10, 0xfff}, + { 0x140354, 7, 0x10, 0x924}, + { 0x140370, 7, 0x10, 0xfff}, + { 0x14038c, 14, 0x10, 0x924}, + { 0x1404b0, 14, 0x10, 0x924}, + { 0x15c000, 2, 0x1e, 0x924}, + { 0x15c008, 5, 0x2, 0x924}, + { 0x15c020, 8, 0x1c, 0x924}, + { 0x15c040, 1, 0xc, 0x924}, + { 0x15c044, 2, 0x1c, 0x924}, + { 0x15c04c, 8, 0xc, 0x924}, + { 0x15c06c, 8, 0x1c, 0x924}, + { 0x15c090, 13, 0x1c, 0x924}, + { 0x15c0c8, 24, 0x1c, 0x924}, + { 0x15c128, 2, 0xc, 0x924}, + { 0x15c130, 1, 0x1c, 0x924}, + { 0x15c138, 6, 0x1c, 0x924}, + { 0x15c150, 2, 0x18, 0x924}, + { 0x15c158, 2, 0x8, 0x924}, + { 0x15c160, 23, 0x10, 0x924}, + { 0x15c1bc, 6, 0x10, 0xfff}, + { 0x15c1d4, 23, 0x10, 0x924}, + { 0x15c230, 7, 0x10, 0xfff}, + { 0x15c24c, 90, 0x10, 0x924}, + { 0x160004, 6, 0x18, 0x924}, + { 0x16003c, 1, 0x10, 0x924}, + { 0x160040, 6, 0x18, 0x924}, + { 0x16005c, 6, 0x18, 0x924}, + { 0x160074, 1, 0x10, 0x924}, + { 0x160078, 2, 0x18, 0x924}, + { 0x160300, 8, 0x18, 0x924}, + { 0x160330, 6, 0x18, 0x924}, + { 0x160404, 6, 0x18, 0x924}, + { 0x16043c, 1, 0x10, 0x924}, + { 0x160440, 6, 0x18, 0x924}, + { 0x16045c, 6, 0x18, 0x924}, + { 0x160474, 1, 0x10, 0x924}, + { 0x160478, 2, 0x18, 0x924}, + { 0x160700, 8, 0x18, 0x924}, + { 0x160730, 6, 0x18, 0x924}, + { 0x161000, 7, 0x1f, 0x924}, + { 0x16102c, 2, 0x1f, 0x1fff}, + { 0x161038, 1, 0x1f, 0x1fff}, + { 0x16103c, 2, 0x1c, 0x924}, + { 0x161800, 2, 0x1f, 0x924}, + { 0x162000, 54, 0x18, 0x924}, + { 0x162200, 60, 0x18, 0x924}, + { 0x162400, 54, 0x18, 0x924}, + { 0x162600, 60, 0x18, 0x924}, + { 0x162800, 54, 0x18, 0x924}, + { 0x162a00, 60, 0x18, 0x924}, + { 0x162c00, 54, 0x18, 0x924}, + { 0x162e00, 60, 0x18, 0x924}, + { 0x163000, 1, 0x18, 0x924}, + { 0x163008, 1, 0x18, 0x924}, + { 0x163010, 1, 0x18, 0x924}, + { 0x163018, 1, 0x18, 0x924}, + { 0x163020, 5, 0x18, 0x924}, + { 0x163038, 3, 0x18, 0x924}, + { 0x163048, 3, 0x18, 0x924}, + { 0x163058, 1, 0x18, 0x924}, + { 0x163060, 1, 0x18, 0x924}, + { 0x163068, 1, 0x18, 0x924}, + { 0x163070, 3, 0x18, 0x924}, + { 0x163080, 1, 0x18, 0x924}, + { 0x163088, 3, 0x18, 0x924}, + { 0x163098, 1, 0x18, 0x924}, + { 0x1630a0, 1, 0x18, 0x924}, + { 0x1630a8, 1, 0x18, 0x924}, + { 0x1630b0, 2, 0x10, 0x924}, + { 0x1630c0, 1, 0x18, 0x924}, + { 0x1630c8, 1, 0x18, 0x924}, + { 0x1630d0, 1, 0x18, 0x924}, + { 0x1630d8, 1, 0x18, 0x924}, + { 0x1630e0, 2, 0x18, 0x924}, + { 0x163110, 1, 0x18, 0x924}, + { 0x163120, 2, 0x18, 0x924}, + { 0x163420, 4, 0x18, 0x924}, + { 0x163438, 2, 0x18, 0x924}, + { 0x163488, 2, 0x18, 0x924}, + { 0x163520, 2, 0x18, 0x924}, + { 0x163800, 1, 0x18, 0x924}, + { 0x163808, 1, 0x18, 0x924}, + { 0x163810, 1, 0x18, 0x924}, + { 0x163818, 1, 0x18, 0x924}, + { 0x163820, 5, 0x18, 0x924}, + { 0x163838, 3, 0x18, 0x924}, + { 0x163848, 3, 0x18, 0x924}, + { 0x163858, 1, 0x18, 0x924}, + { 0x163860, 1, 0x18, 0x924}, + { 0x163868, 1, 0x18, 0x924}, + { 0x163870, 3, 0x18, 0x924}, + { 0x163880, 1, 0x18, 0x924}, + { 0x163888, 3, 0x18, 0x924}, + { 0x163898, 1, 0x18, 0x924}, + { 0x1638a0, 1, 0x18, 0x924}, + { 0x1638a8, 1, 0x18, 0x924}, + { 0x1638b0, 2, 0x10, 0x924}, + { 0x1638c0, 1, 0x18, 0x924}, + { 0x1638c8, 1, 0x18, 0x924}, + { 0x1638d0, 1, 0x18, 0x924}, + { 0x1638d8, 1, 0x18, 0x924}, + { 0x1638e0, 2, 0x18, 0x924}, + { 0x163910, 1, 0x18, 0x924}, + { 0x163920, 2, 0x18, 0x924}, + { 0x163c20, 4, 0x18, 0x924}, + { 0x163c38, 2, 0x18, 0x924}, + { 0x163c88, 2, 0x18, 0x924}, + { 0x163d20, 2, 0x18, 0x924}, + { 0x164000, 5, 0x1f, 0x924}, + { 0x164014, 2, 0x1f, 0xfff}, + { 0x16401c, 53, 0x1f, 0x924}, + { 0x164100, 2, 0x1f, 0x1fff}, + { 0x16410c, 1, 0x1f, 0x1fff}, + { 0x164110, 2, 0x1e, 0x924}, + { 0x164118, 15, 0x1c, 0x924}, + { 0x164200, 1, 0x1f, 0x924}, + { 0x164208, 1, 0x1f, 0x924}, + { 0x164210, 1, 0x1f, 0x924}, + { 0x164218, 1, 0x1f, 0x924}, + { 0x164220, 1, 0x1f, 0x924}, + { 0x164228, 1, 0x1f, 0x924}, + { 0x164230, 1, 0x1f, 0x924}, + { 0x164238, 1, 0x1f, 0x924}, + { 0x164240, 1, 0x1f, 0x924}, + { 0x164248, 1, 0x1f, 0x924}, + { 0x164250, 1, 0x1f, 0x924}, + { 0x164258, 1, 0x1f, 0x924}, + { 0x164260, 1, 0x1f, 0x924}, + { 0x164270, 2, 0x1f, 0x924}, + { 0x164280, 2, 0x1f, 0x924}, + { 0x164800, 2, 0x1f, 0x924}, + { 0x165000, 2, 0x1f, 0x924}, + { 0x166000, 164, 0x1f, 0x924}, + { 0x1662b0, 2, 0x1f, 0x1fff}, + { 0x1662bc, 1, 0x1f, 0x1fff}, + { 0x1662cc, 7, 0x1c, 0x924}, + { 0x166400, 49, 0x1f, 0x924}, + { 0x1664c8, 32, 0x1f, 0x924}, + { 0x166548, 1, 0x1f, 0xfff}, + { 0x16654c, 1, 0x1f, 0x924}, + { 0x166550, 1, 0x1f, 0xfff}, + { 0x166554, 1, 0x1f, 0x924}, + { 0x166558, 1, 0x1f, 0xfff}, + { 0x16655c, 1, 0x1f, 0x924}, + { 0x166568, 2, 0x1f, 0x924}, + { 0x166570, 5, 0x1c, 0x924}, + { 0x166800, 1, 0x1f, 0x924}, + { 0x168000, 1, 0x1f, 0xfff}, + { 0x168004, 1, 0x1f, 0x924}, + { 0x168008, 1, 0x1f, 0xfff}, + { 0x16800c, 1, 0x1f, 0x924}, + { 0x168010, 1, 0x1f, 0xfff}, + { 0x168014, 1, 0x1f, 0x924}, + { 0x168018, 1, 0x1f, 0xfff}, + { 0x16801c, 3, 0x1f, 0x924}, + { 0x168028, 2, 0x1f, 0xfff}, + { 0x168030, 10, 0x1f, 0x924}, + { 0x168058, 9, 0x1f, 0xfff}, + { 0x16807c, 106, 0x1f, 0x924}, + { 0x168224, 2, 0x3, 0x924}, + { 0x16822c, 3, 0x1f, 0x924}, + { 0x168238, 1, 0x1f, 0xfff}, + { 0x16823c, 25, 0x1f, 0x924}, + { 0x1682a0, 12, 0x3, 0x924}, + { 0x1682d0, 7, 0x1f, 0xfff}, + { 0x1682ec, 5, 0x1f, 0x924}, + { 0x168300, 2, 0x3, 0xfff}, + { 0x168308, 65, 0x1f, 0xfff}, + { 0x16840c, 1, 0x1f, 0x924}, + { 0x168410, 2, 0x1f, 0xfff}, + { 0x168418, 2, 0x3, 0x924}, + { 0x168420, 6, 0x1f, 0x924}, + { 0x168448, 2, 0x1f, 0x1fff}, + { 0x168454, 1, 0x1f, 0x1fff}, + { 0x168800, 19, 0x1f, 0x924}, + { 0x168900, 1, 0x1f, 0x924}, + { 0x168a00, 128, 0x1f, 0xfff}, + { 0x16a000, 1536, 0x1f, 0x924}, + { 0x16c000, 1536, 0x1f, 0x924}, + { 0x16e000, 16, 0x2, 0x924}, + { 0x16e040, 8, 0x1c, 0x924}, + { 0x16e100, 1, 0x2, 0x924}, + { 0x16e200, 2, 0x2, 0xfff}, + { 0x16e400, 1, 0x2, 0x924}, + { 0x16e404, 2, 0x2, 0xfff}, + { 0x16e40c, 94, 0x2, 0x924}, + { 0x16e584, 64, 0x2, 0xfff}, + { 0x16e684, 2, 0x1e, 0xfff}, + { 0x16e68c, 4, 0x2, 0xfff}, + { 0x16e69c, 8, 0x2, 0x924}, + { 0x16e6bc, 4, 0x1e, 0x924}, + { 0x16e6cc, 4, 0x2, 0x924}, + { 0x16e6e0, 2, 0x1c, 0x924}, + { 0x16e6e8, 5, 0xc, 0x924}, + { 0x16e6fc, 4, 0x1c, 0xfff}, + { 0x16e70c, 1, 0x1c, 0x924}, + { 0x16e768, 17, 0x1c, 0x924}, + { 0x16e7ac, 12, 0x10, 0xfff}, + { 0x170000, 24, 0x1f, 0x924}, + { 0x170060, 4, 0x3, 0x924}, + { 0x170070, 13, 0x1f, 0x924}, + { 0x1700a4, 1, 0x1f, 0xfff}, + { 0x1700a8, 1, 0x1f, 0x924}, + { 0x1700ac, 2, 0x1f, 0xfff}, + { 0x1700b4, 3, 0x1f, 0x924}, + { 0x1700c0, 1, 0x1f, 0xfff}, + { 0x1700c4, 44, 0x1f, 0x924}, + { 0x170184, 2, 0x1f, 0x1fff}, + { 0x170190, 1, 0x1f, 0x1fff}, + { 0x170194, 11, 0x1c, 0x924}, + { 0x1701c4, 1, 0x1c, 0x924}, + { 0x1701cc, 7, 0x1c, 0x924}, + { 0x1701e8, 1, 0x18, 0x924}, + { 0x1701ec, 1, 0x1c, 0x924}, + { 0x1701f4, 1, 0x1c, 0x924}, + { 0x170200, 4, 0x1f, 0x924}, + { 0x170214, 1, 0x1f, 0x924}, + { 0x170218, 77, 0x1c, 0x924}, + { 0x170400, 64, 0x1c, 0x924}, + { 0x178000, 1, 0x1f, 0x924}, + { 0x180000, 61, 0x1f, 0x924}, + { 0x180114, 2, 0x1f, 0x1fff}, + { 0x180120, 3, 0x1f, 0x1fff}, + { 0x180130, 1, 0x1f, 0x1fff}, + { 0x18013c, 2, 0x1e, 0x924}, + { 0x180200, 27, 0x1f, 0x924}, + { 0x18026c, 1, 0x1f, 0xfff}, + { 0x180270, 12, 0x1f, 0x924}, + { 0x1802a0, 1, 0x1f, 0xfff}, + { 0x1802a4, 17, 0x1f, 0x924}, + { 0x180340, 4, 0x1f, 0x924}, + { 0x180380, 1, 0x1c, 0x924}, + { 0x180388, 1, 0x1c, 0x924}, + { 0x180390, 1, 0x1c, 0x924}, + { 0x180398, 1, 0x1c, 0x924}, + { 0x1803a0, 5, 0x1c, 0x924}, + { 0x1803b4, 2, 0x18, 0x924}, + { 0x181000, 4, 0x1f, 0x93c}, + { 0x181010, 1020, 0x1f, 0x38}, + { 0x182000, 4, 0x18, 0x924}, + { 0x1a0000, 1, 0x1f, 0x92c}, + { 0x1a0004, 5631, 0x1f, 0x8}, + { 0x1a5800, 2560, 0x1e, 0x8}, + { 0x1a8000, 1, 0x1f, 0x92c}, + { 0x1a8004, 8191, 0x1e, 0x8}, + { 0x1b0000, 1, 0x1f, 0x92c}, + { 0x1b0004, 15, 0x2, 0x8}, + { 0x1b0040, 1, 0x1e, 0x92c}, + { 0x1b0044, 239, 0x2, 0x8}, + { 0x1b0400, 1, 0x1f, 0x92c}, + { 0x1b0404, 255, 0x2, 0x8}, + { 0x1b0800, 1, 0x1f, 0x924}, + { 0x1b0840, 1, 0x1e, 0x924}, + { 0x1b0c00, 1, 0x1f, 0x1fff}, + { 0x1b1000, 1, 0x1f, 0x1fff}, + { 0x1b1040, 1, 0x1e, 0x1fff}, + { 0x1b1400, 1, 0x1f, 0x924}, + { 0x1b1440, 1, 0x1e, 0x924}, + { 0x1b1480, 1, 0x1e, 0x924}, + { 0x1b14c0, 1, 0x1e, 0x924}, + { 0x1b1800, 128, 0x1f, 0x10}, + { 0x1b1c00, 128, 0x1f, 0x10}, + { 0x1b2000, 1, 0x1f, 0xdb6}, + { 0x1b2400, 1, 0x1e, 0x92c}, + { 0x1b2404, 5631, 0x1c, 0x8}, + { 0x1b8000, 1, 0x1f, 0xfff}, + { 0x1b8040, 1, 0x1f, 0xfff}, + { 0x1b8080, 1, 0x1f, 0xfff}, + { 0x1b80c0, 1, 0x1f, 0xfff}, + { 0x1b8100, 1, 0x1f, 0x924}, + { 0x1b8140, 1, 0x1f, 0x924}, + { 0x1b8180, 1, 0x1f, 0x924}, + { 0x1b81c0, 1, 0x1f, 0x924}, + { 0x1b8200, 1, 0x1f, 0x924}, + { 0x1b8240, 1, 0x1f, 0x924}, + { 0x1b8280, 1, 0x1f, 0x924}, + { 0x1b82c0, 1, 0x1f, 0x924}, + { 0x1b8300, 1, 0x1f, 0x924}, + { 0x1b8340, 1, 0x1f, 0x924}, + { 0x1b8380, 1, 0x1f, 0x924}, + { 0x1b83c0, 1, 0x1f, 0x924}, + { 0x1b8400, 1, 0x1f, 0x924}, + { 0x1b8440, 1, 0x1f, 0x924}, + { 0x1b8480, 1, 0x1f, 0x924}, + { 0x1b84c0, 1, 0x1f, 0x924}, + { 0x1b8500, 1, 0x1f, 0x924}, + { 0x1b8540, 1, 0x1f, 0x924}, + { 0x1b8580, 1, 0x1f, 0x924}, + { 0x1b85c0, 19, 0x1c, 0x924}, + { 0x1b8800, 1, 0x1f, 0x924}, + { 0x1b8840, 1, 0x1f, 0x924}, + { 0x1b8880, 1, 0x1f, 0x924}, + { 0x1b88c0, 1, 0x1f, 0x924}, + { 0x1b8900, 1, 0x1f, 0x924}, + { 0x1b8940, 1, 0x1f, 0x924}, + { 0x1b8980, 1, 0x1f, 0x924}, + { 0x1b89c0, 1, 0x1f, 0x924}, + { 0x1b8a00, 1, 0x1f, 0x934}, + { 0x1b8a40, 1, 0x1f, 0x924}, + { 0x1b8a80, 1, 0x1f, 0x492}, + { 0x1b8ac0, 1, 0x1f, 0x924}, + { 0x1b8b00, 1, 0x1f, 0x924}, + { 0x1b8b40, 1, 0x1f, 0x924}, + { 0x1b8b80, 1, 0x1f, 0x924}, + { 0x1b8bc0, 1, 0x1f, 0x924}, + { 0x1b8c00, 1, 0x1f, 0x924}, + { 0x1b8c40, 1, 0x1f, 0x924}, + { 0x1b8c80, 1, 0x1f, 0x924}, + { 0x1b8cc0, 1, 0x1f, 0x924}, + { 0x1b8cc4, 1, 0x1c, 0x924}, + { 0x1b8d00, 1, 0x1f, 0x924}, + { 0x1b8d40, 1, 0x1f, 0x924}, + { 0x1b8d80, 1, 0x1f, 0x924}, + { 0x1b8dc0, 1, 0x1f, 0x924}, + { 0x1b8e00, 1, 0x1f, 0x924}, + { 0x1b8e40, 1, 0x1f, 0x924}, + { 0x1b8e80, 1, 0x1f, 0x924}, + { 0x1b8e84, 1, 0x1c, 0x924}, + { 0x1b8ec0, 1, 0x1e, 0x924}, + { 0x1b8f00, 1, 0x1e, 0x924}, + { 0x1b8f40, 1, 0x1e, 0x924}, + { 0x1b8f80, 1, 0x1e, 0x924}, + { 0x1b8fc0, 1, 0x1e, 0x924}, + { 0x1b8fd4, 5, 0x1c, 0x924}, + { 0x1b8fe8, 2, 0x18, 0x924}, + { 0x1b9000, 1, 0x1c, 0x924}, + { 0x1b9040, 3, 0x1c, 0x924}, + { 0x1b905c, 1, 0x18, 0x924}, + { 0x1b9064, 1, 0x10, 0x924}, + { 0x1b9080, 10, 0x10, 0x924}, + { 0x1c0000, 2, 0x1f, 0x924}, + { 0x200000, 65, 0x1f, 0x924}, + { 0x200124, 2, 0x1f, 0x1fff}, + { 0x200130, 3, 0x1f, 0x1fff}, + { 0x200140, 1, 0x1f, 0x1fff}, + { 0x20014c, 2, 0x1e, 0x924}, + { 0x200200, 27, 0x1f, 0x924}, + { 0x20026c, 1, 0x1f, 0xfff}, + { 0x200270, 12, 0x1f, 0x924}, + { 0x2002a0, 1, 0x1f, 0xfff}, + { 0x2002a4, 17, 0x1f, 0x924}, + { 0x200340, 4, 0x1f, 0x924}, + { 0x200380, 1, 0x1c, 0x924}, + { 0x200388, 1, 0x1c, 0x924}, + { 0x200390, 1, 0x1c, 0x924}, + { 0x200398, 1, 0x1c, 0x924}, + { 0x2003a0, 1, 0x1c, 0x924}, + { 0x2003a8, 2, 0x1c, 0x924}, + { 0x202000, 4, 0x1f, 0x1927}, + { 0x202010, 2044, 0x1f, 0x1007}, + { 0x204000, 4, 0x18, 0x924}, + { 0x220000, 1, 0x1f, 0x925}, + { 0x220004, 5631, 0x1f, 0x1}, + { 0x225800, 2560, 0x1e, 0x1}, + { 0x228000, 1, 0x1f, 0x925}, + { 0x228004, 8191, 0x1e, 0x1}, + { 0x230000, 1, 0x1f, 0x925}, + { 0x230004, 15, 0x2, 0x1}, + { 0x230040, 1, 0x1e, 0x925}, + { 0x230044, 239, 0x2, 0x1}, + { 0x230400, 1, 0x1f, 0x925}, + { 0x230404, 255, 0x2, 0x1}, + { 0x230800, 1, 0x1f, 0x924}, + { 0x230840, 1, 0x1e, 0x924}, + { 0x230c00, 1, 0x1f, 0x924}, + { 0x231000, 1, 0x1f, 0x924}, + { 0x231040, 1, 0x1e, 0x924}, + { 0x231400, 1, 0x1f, 0x924}, + { 0x231440, 1, 0x1e, 0x924}, + { 0x231480, 1, 0x1e, 0x924}, + { 0x2314c0, 1, 0x1e, 0x924}, + { 0x231800, 128, 0x1f, 0x2}, + { 0x231c00, 128, 0x1f, 0x2}, + { 0x232000, 1, 0x1f, 0xdb6}, + { 0x232400, 1, 0x1e, 0x925}, + { 0x232404, 5631, 0x1c, 0x1}, + { 0x238000, 1, 0x1f, 0xfff}, + { 0x238040, 1, 0x1f, 0xfff}, + { 0x238080, 1, 0x1f, 0xfff}, + { 0x2380c0, 1, 0x1f, 0xfff}, + { 0x238100, 1, 0x1f, 0x924}, + { 0x238140, 1, 0x1f, 0x924}, + { 0x238180, 1, 0x1f, 0x924}, + { 0x2381c0, 1, 0x1f, 0x924}, + { 0x238200, 1, 0x1f, 0x924}, + { 0x238240, 1, 0x1f, 0x924}, + { 0x238280, 1, 0x1f, 0x924}, + { 0x2382c0, 1, 0x1f, 0x924}, + { 0x238300, 1, 0x1f, 0x924}, + { 0x238340, 1, 0x1f, 0x924}, + { 0x238380, 1, 0x1f, 0x924}, + { 0x2383c0, 1, 0x1f, 0x924}, + { 0x238400, 1, 0x1f, 0x924}, + { 0x238440, 1, 0x1f, 0x924}, + { 0x238480, 1, 0x1f, 0x924}, + { 0x2384c0, 1, 0x1f, 0x924}, + { 0x238500, 1, 0x1f, 0x924}, + { 0x238540, 1, 0x1f, 0x924}, + { 0x238580, 1, 0x1f, 0x924}, + { 0x2385c0, 19, 0x1c, 0x924}, + { 0x238800, 1, 0x1f, 0x924}, + { 0x238840, 1, 0x1f, 0x924}, + { 0x238880, 1, 0x1f, 0x924}, + { 0x2388c0, 1, 0x1f, 0x924}, + { 0x238900, 1, 0x1f, 0x924}, + { 0x238940, 1, 0x1f, 0x924}, + { 0x238980, 1, 0x1f, 0x924}, + { 0x2389c0, 1, 0x1f, 0x924}, + { 0x238a00, 1, 0x1f, 0x926}, + { 0x238a40, 1, 0x1f, 0x924}, + { 0x238a80, 1, 0x1f, 0x492}, + { 0x238ac0, 1, 0x1f, 0x924}, + { 0x238b00, 1, 0x1f, 0x924}, + { 0x238b40, 1, 0x1f, 0x924}, + { 0x238b80, 1, 0x1f, 0x924}, + { 0x238bc0, 1, 0x1f, 0x924}, + { 0x238c00, 1, 0x1f, 0x924}, + { 0x238c40, 1, 0x1f, 0x924}, + { 0x238c80, 1, 0x1f, 0x924}, + { 0x238cc0, 1, 0x1f, 0x924}, + { 0x238cc4, 1, 0x1c, 0x924}, + { 0x238d00, 1, 0x1f, 0x924}, + { 0x238d40, 1, 0x1f, 0x924}, + { 0x238d80, 1, 0x1f, 0x924}, + { 0x238dc0, 1, 0x1f, 0x924}, + { 0x238e00, 1, 0x1f, 0x924}, + { 0x238e40, 1, 0x1f, 0x924}, + { 0x238e80, 1, 0x1f, 0x924}, + { 0x238e84, 1, 0x1c, 0x924}, + { 0x238ec0, 1, 0x1e, 0x924}, + { 0x238f00, 1, 0x1e, 0x924}, + { 0x238f40, 1, 0x1e, 0x924}, + { 0x238f80, 1, 0x1e, 0x924}, + { 0x238fc0, 1, 0x1e, 0x924}, + { 0x238fd4, 5, 0x1c, 0x924}, + { 0x238fe8, 2, 0x18, 0x924}, + { 0x239000, 1, 0x1c, 0x924}, + { 0x239040, 3, 0x1c, 0x924}, + { 0x23905c, 1, 0x18, 0x924}, + { 0x239064, 1, 0x10, 0x924}, + { 0x239080, 10, 0x10, 0x924}, + { 0x240000, 2, 0x1f, 0x924}, + { 0x280000, 65, 0x1f, 0x924}, + { 0x280124, 2, 0x1f, 0x1fff}, + { 0x280130, 3, 0x1f, 0x1fff}, + { 0x280140, 1, 0x1f, 0x1fff}, + { 0x28014c, 2, 0x1e, 0x924}, + { 0x280200, 27, 0x1f, 0x924}, + { 0x28026c, 1, 0x1f, 0xfff}, + { 0x280270, 12, 0x1f, 0x924}, + { 0x2802a0, 1, 0x1f, 0xfff}, + { 0x2802a4, 17, 0x1f, 0x924}, + { 0x280340, 4, 0x1f, 0x924}, + { 0x280380, 1, 0x1c, 0x924}, + { 0x280388, 1, 0x1c, 0x924}, + { 0x280390, 1, 0x1c, 0x924}, + { 0x280398, 1, 0x1c, 0x924}, + { 0x2803a0, 1, 0x1c, 0x924}, + { 0x2803a8, 2, 0x1c, 0x924}, + { 0x282000, 4, 0x1f, 0x9e4}, + { 0x282010, 2044, 0x1f, 0x1c0}, + { 0x284000, 4, 0x18, 0x924}, + { 0x2a0000, 1, 0x1f, 0x964}, + { 0x2a0004, 5631, 0x1f, 0x40}, + { 0x2a5800, 2560, 0x1e, 0x40}, + { 0x2a8000, 1, 0x1f, 0x964}, + { 0x2a8004, 8191, 0x1e, 0x40}, + { 0x2b0000, 1, 0x1f, 0x964}, + { 0x2b0004, 15, 0x2, 0x40}, + { 0x2b0040, 1, 0x1e, 0x964}, + { 0x2b0044, 239, 0x2, 0x40}, + { 0x2b0400, 1, 0x1f, 0x964}, + { 0x2b0404, 255, 0x2, 0x40}, + { 0x2b0800, 1, 0x1f, 0x924}, + { 0x2b0840, 1, 0x1e, 0x924}, + { 0x2b0c00, 1, 0x1f, 0x924}, + { 0x2b1000, 1, 0x1f, 0x924}, + { 0x2b1040, 1, 0x1e, 0x924}, + { 0x2b1400, 1, 0x1f, 0x924}, + { 0x2b1440, 1, 0x1e, 0x924}, + { 0x2b1480, 1, 0x1e, 0x924}, + { 0x2b14c0, 1, 0x1e, 0x924}, + { 0x2b1800, 128, 0x1f, 0x80}, + { 0x2b1c00, 128, 0x1f, 0x80}, + { 0x2b2000, 1, 0x1f, 0xdb6}, + { 0x2b2400, 1, 0x1e, 0x964}, + { 0x2b2404, 5631, 0x1c, 0x40}, + { 0x2b8000, 1, 0x1f, 0xfff}, + { 0x2b8040, 1, 0x1f, 0xfff}, + { 0x2b8080, 1, 0x1f, 0xfff}, + { 0x2b80c0, 1, 0x1f, 0x924}, + { 0x2b8100, 1, 0x1f, 0x924}, + { 0x2b8140, 1, 0x1f, 0x924}, + { 0x2b8180, 1, 0x1f, 0x924}, + { 0x2b81c0, 1, 0x1f, 0x924}, + { 0x2b8200, 1, 0x1f, 0x924}, + { 0x2b8240, 1, 0x1f, 0x924}, + { 0x2b8280, 1, 0x1f, 0x924}, + { 0x2b82c0, 1, 0x1f, 0x924}, + { 0x2b8300, 1, 0x1f, 0x924}, + { 0x2b8340, 1, 0x1f, 0x924}, + { 0x2b8380, 1, 0x1f, 0x924}, + { 0x2b83c0, 1, 0x1f, 0x924}, + { 0x2b8400, 1, 0x1f, 0x924}, + { 0x2b8440, 1, 0x1f, 0x924}, + { 0x2b8480, 1, 0x1f, 0x924}, + { 0x2b84c0, 1, 0x1f, 0x924}, + { 0x2b8500, 1, 0x1f, 0x924}, + { 0x2b8540, 1, 0x1f, 0x924}, + { 0x2b8580, 1, 0x1f, 0x924}, + { 0x2b85c0, 19, 0x1c, 0x924}, + { 0x2b8800, 1, 0x1f, 0x924}, + { 0x2b8840, 1, 0x1f, 0x924}, + { 0x2b8880, 1, 0x1f, 0x924}, + { 0x2b88c0, 1, 0x1f, 0x924}, + { 0x2b8900, 1, 0x1f, 0x924}, + { 0x2b8940, 1, 0x1f, 0x924}, + { 0x2b8980, 1, 0x1f, 0x924}, + { 0x2b89c0, 1, 0x1f, 0x924}, + { 0x2b8a00, 1, 0x1f, 0x9a4}, + { 0x2b8a40, 1, 0x1f, 0x924}, + { 0x2b8a80, 1, 0x1f, 0x492}, + { 0x2b8ac0, 1, 0x1f, 0x924}, + { 0x2b8b00, 1, 0x1f, 0x924}, + { 0x2b8b40, 1, 0x1f, 0x924}, + { 0x2b8b80, 1, 0x1f, 0x924}, + { 0x2b8bc0, 1, 0x1f, 0x924}, + { 0x2b8c00, 1, 0x1f, 0x924}, + { 0x2b8c40, 1, 0x1f, 0x924}, + { 0x2b8c80, 1, 0x1f, 0x924}, + { 0x2b8cc0, 1, 0x1f, 0x924}, + { 0x2b8cc4, 1, 0x1c, 0x924}, + { 0x2b8d00, 1, 0x1f, 0x924}, + { 0x2b8d40, 1, 0x1f, 0x924}, + { 0x2b8d80, 1, 0x1f, 0x924}, + { 0x2b8dc0, 1, 0x1f, 0x924}, + { 0x2b8e00, 1, 0x1f, 0x924}, + { 0x2b8e40, 1, 0x1f, 0x924}, + { 0x2b8e80, 1, 0x1f, 0x924}, + { 0x2b8e84, 1, 0x1c, 0x924}, + { 0x2b8ec0, 1, 0x1e, 0x924}, + { 0x2b8f00, 1, 0x1e, 0x924}, + { 0x2b8f40, 1, 0x1e, 0x924}, + { 0x2b8f80, 1, 0x1e, 0x924}, + { 0x2b8fc0, 1, 0x1e, 0x924}, + { 0x2b8fd4, 5, 0x1c, 0x924}, + { 0x2b8fe8, 2, 0x18, 0x924}, + { 0x2b9000, 1, 0x1c, 0x924}, + { 0x2b9040, 3, 0x1c, 0x924}, + { 0x2b905c, 1, 0x18, 0x924}, + { 0x2b9064, 1, 0x10, 0x924}, + { 0x2b9080, 10, 0x10, 0x924}, + { 0x2c0000, 2, 0x1f, 0x1fff}, + { 0x300000, 65, 0x1f, 0x924}, + { 0x300124, 2, 0x1f, 0x1fff}, + { 0x300130, 3, 0x1f, 0x1fff}, + { 0x300140, 1, 0x1f, 0x1fff}, + { 0x30014c, 2, 0x1e, 0x924}, + { 0x300200, 27, 0x1f, 0x924}, + { 0x30026c, 1, 0x1f, 0xfff}, + { 0x300270, 12, 0x1f, 0x924}, + { 0x3002a0, 1, 0x1f, 0xfff}, + { 0x3002a4, 17, 0x1f, 0x924}, + { 0x300340, 4, 0x1f, 0x924}, + { 0x300380, 1, 0x1c, 0x924}, + { 0x300388, 1, 0x1c, 0x924}, + { 0x300390, 1, 0x1c, 0x924}, + { 0x300398, 1, 0x1c, 0x924}, + { 0x3003a0, 1, 0x1c, 0x924}, + { 0x3003a8, 2, 0x1c, 0x924}, + { 0x302000, 4, 0x1f, 0xf24}, + { 0x302010, 2044, 0x1f, 0xe00}, + { 0x304000, 4, 0x18, 0x924}, + { 0x320000, 1, 0x1f, 0xb24}, + { 0x320004, 5631, 0x1f, 0x200}, + { 0x325800, 2560, 0x1e, 0x200}, + { 0x328000, 1, 0x1f, 0xb24}, + { 0x328004, 8191, 0x1e, 0x200}, + { 0x330000, 1, 0x1f, 0xb24}, + { 0x330004, 15, 0x2, 0x200}, + { 0x330040, 1, 0x1e, 0xb24}, + { 0x330044, 239, 0x2, 0x200}, + { 0x330400, 1, 0x1f, 0xb24}, + { 0x330404, 255, 0x2, 0x200}, + { 0x330800, 1, 0x1f, 0x924}, + { 0x330840, 1, 0x1e, 0x924}, + { 0x330c00, 1, 0x1f, 0x924}, + { 0x331000, 1, 0x1f, 0x924}, + { 0x331040, 1, 0x1e, 0x924}, + { 0x331400, 1, 0x1f, 0x924}, + { 0x331440, 1, 0x1e, 0x924}, + { 0x331480, 1, 0x1e, 0x924}, + { 0x3314c0, 1, 0x1e, 0x924}, + { 0x331800, 128, 0x1f, 0x400}, + { 0x331c00, 128, 0x1f, 0x400}, + { 0x332000, 1, 0x1f, 0xdb6}, + { 0x332400, 1, 0x1e, 0xb24}, + { 0x332404, 5631, 0x1c, 0x200}, + { 0x338000, 1, 0x1f, 0xfff}, + { 0x338040, 1, 0x1f, 0xfff}, + { 0x338080, 1, 0x1f, 0xfff}, + { 0x3380c0, 1, 0x1f, 0xfff}, + { 0x338100, 1, 0x1f, 0x924}, + { 0x338140, 1, 0x1f, 0x924}, + { 0x338180, 1, 0x1f, 0x924}, + { 0x3381c0, 1, 0x1f, 0x924}, + { 0x338200, 1, 0x1f, 0x924}, + { 0x338240, 1, 0x1f, 0x924}, + { 0x338280, 1, 0x1f, 0x924}, + { 0x3382c0, 1, 0x1f, 0x924}, + { 0x338300, 1, 0x1f, 0x924}, + { 0x338340, 1, 0x1f, 0x924}, + { 0x338380, 1, 0x1f, 0x924}, + { 0x3383c0, 1, 0x1f, 0x924}, + { 0x338400, 1, 0x1f, 0x924}, + { 0x338440, 1, 0x1f, 0x924}, + { 0x338480, 1, 0x1f, 0x924}, + { 0x3384c0, 1, 0x1f, 0x924}, + { 0x338500, 1, 0x1f, 0x924}, + { 0x338540, 1, 0x1f, 0x924}, + { 0x338580, 1, 0x1f, 0x924}, + { 0x3385c0, 19, 0x1c, 0x924}, + { 0x338800, 1, 0x1f, 0x924}, + { 0x338840, 1, 0x1f, 0x924}, + { 0x338880, 1, 0x1f, 0x924}, + { 0x3388c0, 1, 0x1f, 0x924}, + { 0x338900, 1, 0x1f, 0x924}, + { 0x338940, 1, 0x1f, 0x924}, + { 0x338980, 1, 0x1f, 0x924}, + { 0x3389c0, 1, 0x1f, 0x924}, + { 0x338a00, 1, 0x1f, 0xd24}, + { 0x338a40, 1, 0x1f, 0x924}, + { 0x338a80, 1, 0x1f, 0x492}, + { 0x338ac0, 1, 0x1f, 0x924}, + { 0x338b00, 1, 0x1f, 0x924}, + { 0x338b40, 1, 0x1f, 0x924}, + { 0x338b80, 1, 0x1f, 0x924}, + { 0x338bc0, 1, 0x1f, 0x924}, + { 0x338c00, 1, 0x1f, 0x924}, + { 0x338c40, 1, 0x1f, 0x924}, + { 0x338c80, 1, 0x1f, 0x924}, + { 0x338cc0, 1, 0x1f, 0x924}, + { 0x338cc4, 1, 0x1c, 0x924}, + { 0x338d00, 1, 0x1f, 0x924}, + { 0x338d40, 1, 0x1f, 0x924}, + { 0x338d80, 1, 0x1f, 0x924}, + { 0x338dc0, 1, 0x1f, 0x924}, + { 0x338e00, 1, 0x1f, 0x924}, + { 0x338e40, 1, 0x1f, 0x924}, + { 0x338e80, 1, 0x1f, 0x924}, + { 0x338e84, 1, 0x1c, 0x924}, + { 0x338ec0, 1, 0x1e, 0x924}, + { 0x338f00, 1, 0x1e, 0x924}, + { 0x338f40, 1, 0x1e, 0x924}, + { 0x338f80, 1, 0x1e, 0x924}, + { 0x338fc0, 1, 0x1e, 0x924}, + { 0x338fd4, 5, 0x1c, 0x924}, + { 0x338fe8, 2, 0x18, 0x924}, + { 0x339000, 1, 0x1c, 0x924}, + { 0x339040, 3, 0x1c, 0x924}, + { 0x33905c, 1, 0x18, 0x924}, + { 0x339064, 1, 0x10, 0x924}, + { 0x339080, 10, 0x10, 0x924}, + { 0x340000, 2, 0x1f, 0x924}, + { 0x3a0000, 40960, 0x1c, 0x1000} +}; + +#define REGS_COUNT ARRAY_SIZE(reg_addrs) + +static const struct reg_addr idle_reg_addrs[] = { + { 0x2104, 1, 0x1f, 0xfff}, + { 0x2110, 2, 0x1f, 0xfff}, + { 0x211c, 8, 0x1f, 0xfff}, + { 0x2814, 1, 0x1f, 0xfff}, + { 0x281c, 2, 0x1f, 0xfff}, + { 0x2854, 1, 0x1f, 0xfff}, + { 0x285c, 1, 0x1f, 0xfff}, + { 0x3040, 1, 0x1f, 0xfff}, + { 0x9010, 7, 0x1c, 0xfff}, + { 0x9030, 1, 0x1c, 0xfff}, + { 0x9068, 16, 0x1c, 0xfff}, + { 0x9230, 2, 0x1c, 0xfff}, + { 0x9244, 1, 0x1c, 0xfff}, + { 0x9298, 1, 0x1c, 0xfff}, + { 0x92a8, 1, 0x1c, 0x1fff}, + { 0xa38c, 1, 0x1f, 0x1fff}, + { 0xa3c4, 1, 0x1e, 0xfff}, + { 0xa404, 1, 0x1f, 0xfff}, + { 0xa408, 2, 0x1f, 0x1fff}, + { 0xa42c, 12, 0x1f, 0xfff}, + { 0xa580, 1, 0x1f, 0x1fff}, + { 0xa590, 1, 0x1f, 0x1fff}, + { 0xa600, 5, 0x1e, 0xfff}, + { 0xa618, 1, 0x1e, 0xfff}, + { 0xa714, 1, 0x1c, 0xfff}, + { 0xa720, 1, 0x1c, 0xfff}, + { 0xa750, 1, 0x1c, 0xfff}, + { 0xc09c, 1, 0x3, 0xfff}, + { 0x103b0, 1, 0x1f, 0xfff}, + { 0x103c0, 1, 0x1f, 0xfff}, + { 0x103d0, 1, 0x3, 0x1fff}, + { 0x10418, 1, 0x1f, 0xfff}, + { 0x10420, 1, 0x1f, 0xfff}, + { 0x10428, 1, 0x1f, 0xfff}, + { 0x10460, 1, 0x1f, 0xfff}, + { 0x10474, 1, 0x1f, 0xfff}, + { 0x104e0, 1, 0x1f, 0xfff}, + { 0x104ec, 1, 0x1f, 0xfff}, + { 0x104f8, 1, 0x1f, 0xfff}, + { 0x10508, 1, 0x1f, 0xfff}, + { 0x10530, 1, 0x1f, 0xfff}, + { 0x10538, 1, 0x1f, 0xfff}, + { 0x10548, 1, 0x1f, 0xfff}, + { 0x10558, 1, 0x1f, 0xfff}, + { 0x182a8, 1, 0x1c, 0xfff}, + { 0x182b8, 1, 0x1c, 0xfff}, + { 0x18308, 1, 0x1c, 0xfff}, + { 0x18318, 1, 0x1c, 0xfff}, + { 0x18338, 1, 0x1c, 0xfff}, + { 0x18348, 1, 0x1c, 0xfff}, + { 0x183bc, 1, 0x1c, 0x1fff}, + { 0x183cc, 1, 0x1c, 0x1fff}, + { 0x18570, 1, 0x18, 0xfff}, + { 0x18578, 1, 0x18, 0xfff}, + { 0x1858c, 1, 0x18, 0xfff}, + { 0x18594, 1, 0x18, 0xfff}, + { 0x1862c, 4, 0x10, 0xfff}, + { 0x2021c, 11, 0x1f, 0xfff}, + { 0x202a8, 1, 0x1f, 0xfff}, + { 0x202b8, 1, 0x1f, 0x1fff}, + { 0x20404, 1, 0x1f, 0xfff}, + { 0x2040c, 2, 0x1f, 0xfff}, + { 0x2041c, 2, 0x1f, 0xfff}, + { 0x40154, 14, 0x1f, 0xfff}, + { 0x40198, 1, 0x1f, 0x1fff}, + { 0x404ac, 1, 0x1f, 0xfff}, + { 0x404bc, 1, 0x1f, 0x1fff}, + { 0x42290, 1, 0x1f, 0xfff}, + { 0x422a0, 1, 0x1f, 0xfff}, + { 0x422b0, 1, 0x1f, 0x1fff}, + { 0x42548, 1, 0x1f, 0xfff}, + { 0x42550, 1, 0x1f, 0xfff}, + { 0x42558, 1, 0x1f, 0xfff}, + { 0x50160, 8, 0x1f, 0xfff}, + { 0x501d0, 1, 0x1f, 0xfff}, + { 0x501e0, 1, 0x1f, 0x1fff}, + { 0x50204, 1, 0x1f, 0xfff}, + { 0x5020c, 2, 0x1f, 0xfff}, + { 0x5021c, 1, 0x1f, 0xfff}, + { 0x60090, 1, 0x1f, 0xfff}, + { 0x6011c, 1, 0x1f, 0xfff}, + { 0x6012c, 1, 0x1f, 0x1fff}, + { 0xc101c, 1, 0x1f, 0xfff}, + { 0xc102c, 1, 0x1f, 0x1fff}, + { 0xc2290, 1, 0x1f, 0xfff}, + { 0xc22a0, 1, 0x1f, 0xfff}, + { 0xc22b0, 1, 0x1f, 0x1fff}, + { 0xc2548, 1, 0x1f, 0xfff}, + { 0xc2550, 1, 0x1f, 0xfff}, + { 0xc2558, 1, 0x1f, 0xfff}, + { 0xc4294, 1, 0x1f, 0xfff}, + { 0xc42a4, 1, 0x1f, 0xfff}, + { 0xc42b4, 1, 0x1f, 0x1fff}, + { 0xc4550, 1, 0x1f, 0xfff}, + { 0xc4558, 1, 0x1f, 0xfff}, + { 0xc4560, 1, 0x1f, 0xfff}, + { 0xd016c, 8, 0x1f, 0xfff}, + { 0xd01d8, 1, 0x1f, 0xfff}, + { 0xd01e8, 1, 0x1f, 0x1fff}, + { 0xd0204, 1, 0x1f, 0xfff}, + { 0xd020c, 3, 0x1f, 0xfff}, + { 0xe0154, 8, 0x1f, 0xfff}, + { 0xe01c8, 1, 0x1f, 0xfff}, + { 0xe01d8, 1, 0x1f, 0x1fff}, + { 0xe0204, 1, 0x1f, 0xfff}, + { 0xe020c, 2, 0x1f, 0xfff}, + { 0xe021c, 2, 0x1f, 0xfff}, + { 0x101014, 1, 0x1f, 0xfff}, + { 0x101030, 1, 0x1f, 0xfff}, + { 0x101040, 1, 0x1f, 0x1fff}, + { 0x102058, 1, 0x1f, 0x1fff}, + { 0x102080, 16, 0x1f, 0xfff}, + { 0x103004, 2, 0x1f, 0xfff}, + { 0x103068, 1, 0x1f, 0xfff}, + { 0x103078, 1, 0x1f, 0xfff}, + { 0x103088, 1, 0x1f, 0x1fff}, + { 0x10309c, 2, 0x1e, 0xfff}, + { 0x1030b8, 2, 0x1c, 0xfff}, + { 0x1030cc, 1, 0x1c, 0xfff}, + { 0x1030e0, 1, 0x1c, 0xfff}, + { 0x104004, 1, 0x1f, 0xfff}, + { 0x104018, 1, 0x1f, 0xfff}, + { 0x104020, 1, 0x1f, 0xfff}, + { 0x10403c, 1, 0x1f, 0xfff}, + { 0x1040fc, 1, 0x1f, 0xfff}, + { 0x10410c, 1, 0x1f, 0x1fff}, + { 0x104400, 1, 0x1f, 0x1fff}, + { 0x104404, 63, 0x1f, 0xfff}, + { 0x104800, 1, 0x1f, 0x1fff}, + { 0x104804, 63, 0x1f, 0xfff}, + { 0x105000, 4, 0x1f, 0x1fff}, + { 0x105010, 252, 0x1f, 0xfff}, + { 0x108094, 1, 0x3, 0xfff}, + { 0x1201b0, 2, 0x1f, 0xfff}, + { 0x12032c, 1, 0x1f, 0xfff}, + { 0x12036c, 3, 0x1f, 0xfff}, + { 0x120408, 2, 0x1f, 0xfff}, + { 0x120414, 15, 0x1f, 0xfff}, + { 0x120478, 2, 0x1f, 0xfff}, + { 0x12052c, 1, 0x1f, 0xfff}, + { 0x120564, 3, 0x1f, 0xfff}, + { 0x12057c, 1, 0x1f, 0x1fff}, + { 0x12058c, 1, 0x1f, 0x1fff}, + { 0x120608, 1, 0x1e, 0xfff}, + { 0x120748, 1, 0x1c, 0xfff}, + { 0x120778, 2, 0x1c, 0xfff}, + { 0x120808, 3, 0x1f, 0xfff}, + { 0x120818, 1, 0x1f, 0xfff}, + { 0x120820, 1, 0x1f, 0xfff}, + { 0x120828, 1, 0x1f, 0xfff}, + { 0x120830, 1, 0x1f, 0xfff}, + { 0x120838, 1, 0x1f, 0xfff}, + { 0x120840, 1, 0x1f, 0xfff}, + { 0x120848, 1, 0x1f, 0xfff}, + { 0x120850, 1, 0x1f, 0xfff}, + { 0x120858, 1, 0x1f, 0xfff}, + { 0x120860, 1, 0x1f, 0xfff}, + { 0x120868, 1, 0x1f, 0xfff}, + { 0x120870, 1, 0x1f, 0xfff}, + { 0x120878, 1, 0x1f, 0xfff}, + { 0x120880, 1, 0x1f, 0xfff}, + { 0x120888, 1, 0x1f, 0xfff}, + { 0x120890, 1, 0x1f, 0xfff}, + { 0x120898, 1, 0x1f, 0xfff}, + { 0x1208a0, 1, 0x1f, 0xfff}, + { 0x1208a8, 1, 0x1f, 0xfff}, + { 0x1208b0, 1, 0x1f, 0xfff}, + { 0x1208b8, 1, 0x1f, 0xfff}, + { 0x1208c0, 1, 0x1f, 0xfff}, + { 0x1208c8, 1, 0x1f, 0xfff}, + { 0x1208d0, 1, 0x1f, 0xfff}, + { 0x1208d8, 1, 0x1f, 0xfff}, + { 0x1208e0, 1, 0x1f, 0xfff}, + { 0x1208e8, 1, 0x1f, 0xfff}, + { 0x1208f0, 1, 0x1f, 0xfff}, + { 0x1208f8, 1, 0x1f, 0xfff}, + { 0x120900, 1, 0x1f, 0xfff}, + { 0x120908, 1, 0x1f, 0xfff}, + { 0x130030, 1, 0x1c, 0xfff}, + { 0x13004c, 3, 0x1c, 0xfff}, + { 0x130064, 2, 0x1c, 0xfff}, + { 0x13009c, 1, 0x1c, 0x1fff}, + { 0x130130, 1, 0x1c, 0xfff}, + { 0x13016c, 1, 0x1c, 0xfff}, + { 0x130300, 1, 0x1c, 0xfff}, + { 0x130480, 1, 0x1c, 0xfff}, + { 0x14005c, 2, 0xf, 0xfff}, + { 0x1400d0, 2, 0xf, 0xfff}, + { 0x1400e0, 1, 0xf, 0xfff}, + { 0x1401c8, 1, 0xf, 0xfff}, + { 0x140200, 6, 0xf, 0xfff}, + { 0x140338, 7, 0x10, 0xfff}, + { 0x140370, 7, 0x10, 0xfff}, + { 0x15c1bc, 6, 0x10, 0xfff}, + { 0x15c230, 7, 0x10, 0xfff}, + { 0x16101c, 1, 0x1f, 0xfff}, + { 0x16102c, 1, 0x1f, 0x1fff}, + { 0x164014, 2, 0x1f, 0xfff}, + { 0x1640f0, 1, 0x1f, 0xfff}, + { 0x166290, 1, 0x1f, 0xfff}, + { 0x1662a0, 1, 0x1f, 0xfff}, + { 0x1662b0, 1, 0x1f, 0x1fff}, + { 0x166548, 1, 0x1f, 0xfff}, + { 0x166550, 1, 0x1f, 0xfff}, + { 0x166558, 1, 0x1f, 0xfff}, + { 0x168000, 1, 0x1f, 0xfff}, + { 0x168008, 1, 0x1f, 0xfff}, + { 0x168010, 1, 0x1f, 0xfff}, + { 0x168018, 1, 0x1f, 0xfff}, + { 0x168028, 2, 0x1f, 0xfff}, + { 0x168058, 9, 0x1f, 0xfff}, + { 0x168238, 1, 0x1f, 0xfff}, + { 0x1682d0, 7, 0x1f, 0xfff}, + { 0x168300, 2, 0x3, 0xfff}, + { 0x168308, 65, 0x1f, 0xfff}, + { 0x168410, 2, 0x1f, 0xfff}, + { 0x168438, 1, 0x1f, 0xfff}, + { 0x168448, 1, 0x1f, 0x1fff}, + { 0x168a00, 128, 0x1f, 0xfff}, + { 0x16e200, 128, 0x2, 0xfff}, + { 0x16e404, 2, 0x2, 0xfff}, + { 0x16e584, 64, 0x2, 0xfff}, + { 0x16e684, 2, 0x1e, 0xfff}, + { 0x16e68c, 4, 0x2, 0xfff}, + { 0x16e6fc, 4, 0x1c, 0xfff}, + { 0x16e7ac, 12, 0x10, 0xfff}, + { 0x1700a4, 1, 0x1f, 0xfff}, + { 0x1700ac, 2, 0x1f, 0xfff}, + { 0x1700c0, 1, 0x1f, 0xfff}, + { 0x170174, 1, 0x1f, 0xfff}, + { 0x170184, 1, 0x1f, 0x1fff}, + { 0x1800f4, 1, 0x1f, 0xfff}, + { 0x180104, 1, 0x1f, 0xfff}, + { 0x180114, 1, 0x1f, 0x1fff}, + { 0x180124, 1, 0x1f, 0x1fff}, + { 0x18026c, 1, 0x1f, 0xfff}, + { 0x1802a0, 1, 0x1f, 0xfff}, + { 0x1b8000, 1, 0x1f, 0xfff}, + { 0x1b8040, 1, 0x1f, 0xfff}, + { 0x1b8080, 1, 0x1f, 0xfff}, + { 0x1b80c0, 1, 0x1f, 0xfff}, + { 0x200104, 1, 0x1f, 0xfff}, + { 0x200114, 1, 0x1f, 0xfff}, + { 0x200124, 1, 0x1f, 0x1fff}, + { 0x200134, 1, 0x1f, 0x1fff}, + { 0x20026c, 1, 0x1f, 0xfff}, + { 0x2002a0, 1, 0x1f, 0xfff}, + { 0x238000, 1, 0x1f, 0xfff}, + { 0x238040, 1, 0x1f, 0xfff}, + { 0x238080, 1, 0x1f, 0xfff}, + { 0x2380c0, 1, 0x1f, 0xfff}, + { 0x280104, 1, 0x1f, 0xfff}, + { 0x280114, 1, 0x1f, 0xfff}, + { 0x280124, 1, 0x1f, 0x1fff}, + { 0x280134, 1, 0x1f, 0x1fff}, + { 0x28026c, 1, 0x1f, 0xfff}, + { 0x2802a0, 1, 0x1f, 0xfff}, + { 0x2b8000, 1, 0x1f, 0xfff}, + { 0x2b8040, 1, 0x1f, 0xfff}, + { 0x2b8080, 1, 0x1f, 0xfff}, + { 0x300104, 1, 0x1f, 0xfff}, + { 0x300114, 1, 0x1f, 0xfff}, + { 0x300124, 1, 0x1f, 0x1fff}, + { 0x300134, 1, 0x1f, 0x1fff}, + { 0x30026c, 1, 0x1f, 0xfff}, + { 0x3002a0, 1, 0x1f, 0xfff}, + { 0x338000, 1, 0x1f, 0xfff}, + { 0x338040, 1, 0x1f, 0xfff}, + { 0x338080, 1, 0x1f, 0xfff}, + { 0x3380c0, 1, 0x1f, 0xfff} +}; + +#define IDLE_REGS_COUNT ARRAY_SIZE(idle_reg_addrs) + +static const uint32_t read_reg_e1[] = { + 0x1b1000}; + +static const struct wreg_addr wreg_addr_e1 = { + 0x1b0c00, 192, 1, read_reg_e1, 0x1f, 0x1fff}; + +static const uint32_t read_reg_e1h[] = { + 0x1b1040, 0x1b1000}; + +static const struct wreg_addr wreg_addr_e1h = { + 0x1b0c00, 256, 2, read_reg_e1h, 0x1f, 0x1fff}; + +static const uint32_t read_reg_e2[] = { + 0x1b1040, 0x1b1000}; + +static const struct wreg_addr wreg_addr_e2 = { + 0x1b0c00, 128, 2, read_reg_e2, 0x1f, 0x1fff}; + +static const uint32_t read_reg_e3[] = { + 0x1b1040, 0x1b1000}; + +static const struct wreg_addr wreg_addr_e3 = { + 0x1b0c00, 128, 2, read_reg_e3, 0x1f, 0x1fff}; + +static const uint32_t read_reg_e3b0[] = { + 0x1b1040, 0x1b1000}; + +static const struct wreg_addr wreg_addr_e3b0 = { + 0x1b0c00, 128, 2, read_reg_e3b0, 0x1f, 0x1fff}; + +static const unsigned int dump_num_registers[NUM_CHIPS][NUM_PRESETS] = { + {19758, 17543, 26951, 18705, 17287, 26695, 19812, 31367, 40775, 19788, + 25223, 34631, 19074}, + {31750, 18273, 32253, 30697, 18017, 31997, 31804, 32097, 46077, 31780, + 25953, 39933, 35895}, + {36527, 17928, 33697, 35474, 18700, 34466, 36581, 31752, 47521, 36557, + 25608, 41377, 43903}, + {45239, 17936, 34387, 44186, 18708, 35156, 45293, 31760, 48211, 45269, + 25616, 42067, 43903}, + {45302, 17999, 34802, 44249, 18771, 35571, 45356, 31823, 48626, 45332, + 25679, 42482, 43903} +}; +#endif /* #ifndef __BXE_DUMP_H__ */ diff --git a/sys/dev/bxe/bxe_ioctl.h b/sys/dev/bxe/bxe_ioctl.h new file mode 100644 index 0000000..2504982 --- /dev/null +++ b/sys/dev/bxe/bxe_ioctl.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2015-2016 Qlogic Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _BXE_IOCTL_H_ +#define _BXE_IOCTL_H_ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/ioccom.h> + + +struct bxe_grcdump { + uint16_t pci_func; + uint32_t grcdump_size; + void *grcdump; + uint32_t grcdump_dwords; +}; +typedef struct bxe_grcdump bxe_grcdump_t; + + +/* + * Read grcdump size + */ +#define BXE_GRC_DUMP_SIZE _IOWR('e', 1, bxe_grcdump_t) + +/* + * Read grcdump + */ +#define BXE_GRC_DUMP _IOWR('e', 2, bxe_grcdump_t) + + +#endif /* #ifndef _QLNX_IOCTL_H_ */ diff --git a/sys/dev/bxe/bxe_stats.c b/sys/dev/bxe/bxe_stats.c index bbc6605..e41f470 100644 --- a/sys/dev/bxe/bxe_stats.c +++ b/sys/dev/bxe/bxe_stats.c @@ -1227,6 +1227,8 @@ bxe_drv_stats_update(struct bxe_softc *sc) UPDATE_ESTAT_QSTAT(rx_calls); UPDATE_ESTAT_QSTAT(rx_pkts); UPDATE_ESTAT_QSTAT(rx_tpa_pkts); + UPDATE_ESTAT_QSTAT(rx_erroneous_jumbo_sge_pkts); + UPDATE_ESTAT_QSTAT(rx_bxe_service_rxsgl); UPDATE_ESTAT_QSTAT(rx_jumbo_sge_pkts); UPDATE_ESTAT_QSTAT(rx_soft_errors); UPDATE_ESTAT_QSTAT(rx_hw_csum_errors); diff --git a/sys/dev/bxe/bxe_stats.h b/sys/dev/bxe/bxe_stats.h index c7fa1df..a91c0cb 100644 --- a/sys/dev/bxe/bxe_stats.h +++ b/sys/dev/bxe/bxe_stats.h @@ -218,6 +218,8 @@ struct bxe_eth_stats { uint32_t rx_calls; uint32_t rx_pkts; uint32_t rx_tpa_pkts; + uint32_t rx_erroneous_jumbo_sge_pkts; + uint32_t rx_bxe_service_rxsgl; uint32_t rx_jumbo_sge_pkts; uint32_t rx_soft_errors; uint32_t rx_hw_csum_errors; @@ -319,6 +321,8 @@ struct bxe_eth_q_stats { uint32_t rx_calls; uint32_t rx_pkts; uint32_t rx_tpa_pkts; + uint32_t rx_erroneous_jumbo_sge_pkts; + uint32_t rx_bxe_service_rxsgl; uint32_t rx_jumbo_sge_pkts; uint32_t rx_soft_errors; uint32_t rx_hw_csum_errors; @@ -413,6 +417,8 @@ struct bxe_eth_q_stats_old { uint32_t rx_calls_old; uint32_t rx_pkts_old; uint32_t rx_tpa_pkts_old; + uint32_t rx_erroneous_jumbo_sge_pkts_old; + uint32_t rx_bxe_service_rxsgl_old; uint32_t rx_jumbo_sge_pkts_old; uint32_t rx_soft_errors_old; uint32_t rx_hw_csum_errors_old; diff --git a/sys/dev/bxe/ecore_init.h b/sys/dev/bxe/ecore_init.h index 7eab811..31417cc 100644 --- a/sys/dev/bxe/ecore_init.h +++ b/sys/dev/bxe/ecore_init.h @@ -749,10 +749,17 @@ static inline void ecore_set_mcp_parity(struct bxe_softc *sc, uint8_t enable) for (i = 0; i < ARRSIZE(mcp_attn_ctl_regs); i++) { reg_val = REG_RD(sc, mcp_attn_ctl_regs[i].addr); +#if 0 if (enable) reg_val |= MISC_AEU_ENABLE_MCP_PRTY_BITS; /* Linux is using mcp_attn_ctl_regs[i].bits */ else reg_val &= ~MISC_AEU_ENABLE_MCP_PRTY_BITS; /* Linux is using mcp_attn_ctl_regs[i].bits */ +#else + if (enable) + reg_val |= mcp_attn_ctl_regs[i].bits; + else + reg_val &= ~mcp_attn_ctl_regs[i].bits; +#endif REG_WR(sc, mcp_attn_ctl_regs[i].addr, reg_val); } diff --git a/sys/dev/hyperv/include/hyperv.h b/sys/dev/hyperv/include/hyperv.h index 6727503..b5600ba 100644 --- a/sys/dev/hyperv/include/hyperv.h +++ b/sys/dev/hyperv/include/hyperv.h @@ -759,7 +759,6 @@ typedef struct hv_vmbus_channel { hv_vmbus_ring_buffer_info inbound; struct mtx inbound_lock; - hv_vmbus_handle control_work_queue; hv_vmbus_pfn_channel_callback on_channel_callback; void* channel_callback_context; diff --git a/sys/dev/hyperv/vmbus/hv_channel_mgmt.c b/sys/dev/hyperv/vmbus/hv_channel_mgmt.c index d17d696..c7f3538 100644 --- a/sys/dev/hyperv/vmbus/hv_channel_mgmt.c +++ b/sys/dev/hyperv/vmbus/hv_channel_mgmt.c @@ -34,13 +34,6 @@ __FBSDID("$FreeBSD$"); #include "hv_vmbus_priv.h" -typedef void (*hv_pfn_channel_msg_handler)(hv_vmbus_channel_msg_header* msg); - -typedef struct hv_vmbus_channel_msg_table_entry { - hv_vmbus_channel_msg_type messageType; - hv_pfn_channel_msg_handler messageHandler; -} hv_vmbus_channel_msg_table_entry; - /* * Internal functions */ @@ -52,36 +45,46 @@ static void vmbus_channel_on_gpadl_created(hv_vmbus_channel_msg_header* hdr); static void vmbus_channel_on_gpadl_torndown(hv_vmbus_channel_msg_header* hdr); static void vmbus_channel_on_offers_delivered(hv_vmbus_channel_msg_header* hdr); static void vmbus_channel_on_version_response(hv_vmbus_channel_msg_header* hdr); -static void vmbus_channel_process_offer(void *context); /** * Channel message dispatch table */ hv_vmbus_channel_msg_table_entry g_channel_message_table[HV_CHANNEL_MESSAGE_COUNT] = { - { HV_CHANNEL_MESSAGE_INVALID, NULL }, - { HV_CHANNEL_MESSAGE_OFFER_CHANNEL, vmbus_channel_on_offer }, + { HV_CHANNEL_MESSAGE_INVALID, + 0, NULL }, + { HV_CHANNEL_MESSAGE_OFFER_CHANNEL, + 0, vmbus_channel_on_offer }, { HV_CHANNEL_MESSAGE_RESCIND_CHANNEL_OFFER, - vmbus_channel_on_offer_rescind }, - { HV_CHANNEL_MESSAGE_REQUEST_OFFERS, NULL }, + 0, vmbus_channel_on_offer_rescind }, + { HV_CHANNEL_MESSAGE_REQUEST_OFFERS, + 0, NULL }, { HV_CHANNEL_MESSAGE_ALL_OFFERS_DELIVERED, - vmbus_channel_on_offers_delivered }, - { HV_CHANNEL_MESSAGE_OPEN_CHANNEL, NULL }, + 1, vmbus_channel_on_offers_delivered }, + { HV_CHANNEL_MESSAGE_OPEN_CHANNEL, + 0, NULL }, { HV_CHANNEL_MESSAGE_OPEN_CHANNEL_RESULT, - vmbus_channel_on_open_result }, - { HV_CHANNEL_MESSAGE_CLOSE_CHANNEL, NULL }, - { HV_CHANNEL_MESSAGEL_GPADL_HEADER, NULL }, - { HV_CHANNEL_MESSAGE_GPADL_BODY, NULL }, + 1, vmbus_channel_on_open_result }, + { HV_CHANNEL_MESSAGE_CLOSE_CHANNEL, + 0, NULL }, + { HV_CHANNEL_MESSAGEL_GPADL_HEADER, + 0, NULL }, + { HV_CHANNEL_MESSAGE_GPADL_BODY, + 0, NULL }, { HV_CHANNEL_MESSAGE_GPADL_CREATED, - vmbus_channel_on_gpadl_created }, - { HV_CHANNEL_MESSAGE_GPADL_TEARDOWN, NULL }, + 1, vmbus_channel_on_gpadl_created }, + { HV_CHANNEL_MESSAGE_GPADL_TEARDOWN, + 0, NULL }, { HV_CHANNEL_MESSAGE_GPADL_TORNDOWN, - vmbus_channel_on_gpadl_torndown }, - { HV_CHANNEL_MESSAGE_REL_ID_RELEASED, NULL }, - { HV_CHANNEL_MESSAGE_INITIATED_CONTACT, NULL }, + 1, vmbus_channel_on_gpadl_torndown }, + { HV_CHANNEL_MESSAGE_REL_ID_RELEASED, + 0, NULL }, + { HV_CHANNEL_MESSAGE_INITIATED_CONTACT, + 0, NULL }, { HV_CHANNEL_MESSAGE_VERSION_RESPONSE, - vmbus_channel_on_version_response }, - { HV_CHANNEL_MESSAGE_UNLOAD, NULL } + 1, vmbus_channel_on_version_response }, + { HV_CHANNEL_MESSAGE_UNLOAD, + 0, NULL } }; @@ -209,15 +212,6 @@ hv_queue_work_item( return (taskqueue_enqueue(wq->queue, &w->work)); } -/** - * @brief Rescind the offer by initiating a device removal - */ -static void -vmbus_channel_process_rescind_offer(void *context) -{ - hv_vmbus_channel* channel = (hv_vmbus_channel*) context; - hv_vmbus_child_device_unregister(channel->device); -} /** * @brief Allocate and initialize a vmbus channel object @@ -240,14 +234,6 @@ hv_vmbus_allocate_channel(void) TAILQ_INIT(&channel->sc_list_anchor); - channel->control_work_queue = hv_work_queue_create("control"); - - if (channel->control_work_queue == NULL) { - mtx_destroy(&channel->inbound_lock); - free(channel, M_DEVBUF); - return (NULL); - } - return (channel); } @@ -258,7 +244,6 @@ static inline void ReleaseVmbusChannel(void *context) { hv_vmbus_channel* channel = (hv_vmbus_channel*) context; - hv_work_queue_close(channel->control_work_queue); free(channel, M_DEVBUF); } @@ -284,14 +269,12 @@ hv_vmbus_free_vmbus_channel(hv_vmbus_channel* channel) * associated with this offer */ static void -vmbus_channel_process_offer(void *context) +vmbus_channel_process_offer(hv_vmbus_channel *new_channel) { - hv_vmbus_channel* new_channel; boolean_t f_new; hv_vmbus_channel* channel; int ret; - new_channel = (hv_vmbus_channel*) context; f_new = TRUE; channel = NULL; @@ -524,11 +507,7 @@ vmbus_channel_on_offer(hv_vmbus_channel_msg_header* hdr) new_channel->monitor_group = (uint8_t) offer->monitor_id / 32; new_channel->monitor_bit = (uint8_t) offer->monitor_id % 32; - /* TODO: Make sure the offer comes from our parent partition */ - hv_queue_work_item( - new_channel->control_work_queue, - vmbus_channel_process_offer, - new_channel); + vmbus_channel_process_offer(new_channel); } /** @@ -549,8 +528,7 @@ vmbus_channel_on_offer_rescind(hv_vmbus_channel_msg_header* hdr) if (channel == NULL) return; - hv_queue_work_item(channel->control_work_queue, - vmbus_channel_process_rescind_offer, channel); + hv_vmbus_child_device_unregister(channel->device); } /** diff --git a/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c b/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c index 91813bb..f7eae26 100644 --- a/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c +++ b/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c @@ -76,8 +76,12 @@ vmbus_msg_swintr(void *arg) { int cpu; void* page_addr; + hv_vmbus_channel_msg_header *hdr; + hv_vmbus_channel_msg_table_entry *entry; + hv_vmbus_channel_msg_type msg_type; hv_vmbus_message* msg; hv_vmbus_message* copied; + static bool warned = false; cpu = (int)(long)arg; KASSERT(cpu <= mp_maxid, ("VMBUS: vmbus_msg_swintr: " @@ -87,9 +91,24 @@ vmbus_msg_swintr(void *arg) msg = (hv_vmbus_message*) page_addr + HV_VMBUS_MESSAGE_SINT; for (;;) { - if (msg->header.message_type == HV_MESSAGE_TYPE_NONE) { + if (msg->header.message_type == HV_MESSAGE_TYPE_NONE) break; /* no message */ - } else { + + hdr = (hv_vmbus_channel_msg_header *)msg->u.payload; + msg_type = hdr->message_type; + + if (msg_type >= HV_CHANNEL_MESSAGE_COUNT && !warned) { + warned = true; + printf("VMBUS: unknown message type = %d\n", msg_type); + goto handled; + } + + entry = &g_channel_message_table[msg_type]; + + if (entry->handler_no_sleep) + entry->messageHandler(hdr); + else { + copied = malloc(sizeof(hv_vmbus_message), M_DEVBUF, M_NOWAIT); KASSERT(copied != NULL, @@ -97,11 +116,13 @@ vmbus_msg_swintr(void *arg) " hv_vmbus_message!")); if (copied == NULL) continue; + memcpy(copied, msg, sizeof(hv_vmbus_message)); hv_queue_work_item(hv_vmbus_g_connection.work_queue, - hv_vmbus_on_channel_message, copied); - } - + hv_vmbus_on_channel_message, + copied); + } +handled: msg->header.message_type = HV_MESSAGE_TYPE_NONE; /* diff --git a/sys/dev/hyperv/vmbus/hv_vmbus_priv.h b/sys/dev/hyperv/vmbus/hv_vmbus_priv.h index faa6dec..0503d06 100644 --- a/sys/dev/hyperv/vmbus/hv_vmbus_priv.h +++ b/sys/dev/hyperv/vmbus/hv_vmbus_priv.h @@ -586,6 +586,16 @@ typedef enum { extern hv_vmbus_context hv_vmbus_g_context; extern hv_vmbus_connection hv_vmbus_g_connection; +typedef void (*vmbus_msg_handler)(hv_vmbus_channel_msg_header *msg); + +typedef struct hv_vmbus_channel_msg_table_entry { + hv_vmbus_channel_msg_type messageType; + + bool handler_no_sleep; /* true: the handler doesn't sleep */ + vmbus_msg_handler messageHandler; +} hv_vmbus_channel_msg_table_entry; + +extern hv_vmbus_channel_msg_table_entry g_channel_message_table[]; /* * Private, VM Bus functions diff --git a/sys/dev/ismt/ismt.c b/sys/dev/ismt/ismt.c new file mode 100644 index 0000000..3fbcfed --- /dev/null +++ b/sys/dev/ismt/ismt.c @@ -0,0 +1,778 @@ +/*- + * Copyright (C) 2014 Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/bus.h> +#include <sys/errno.h> +#include <sys/kernel.h> +#include <sys/lock.h> +#include <sys/module.h> +#include <sys/priority.h> +#include <sys/proc.h> +#include <sys/syslog.h> + +#include <machine/bus.h> +#include <sys/rman.h> +#include <machine/resource.h> + +#include <dev/pci/pcireg.h> +#include <dev/pci/pcivar.h> +#include <dev/smbus/smbconf.h> + +#include "smbus_if.h" + +#define ISMT_DESC_ENTRIES 32 + +/* Hardware Descriptor Constants - Control Field */ +#define ISMT_DESC_CWRL 0x01 /* Command/Write Length */ +#define ISMT_DESC_BLK 0X04 /* Perform Block Transaction */ +#define ISMT_DESC_FAIR 0x08 /* Set fairness flag upon successful arbit. */ +#define ISMT_DESC_PEC 0x10 /* Packet Error Code */ +#define ISMT_DESC_I2C 0x20 /* I2C Enable */ +#define ISMT_DESC_INT 0x40 /* Interrupt */ +#define ISMT_DESC_SOE 0x80 /* Stop On Error */ + +/* Hardware Descriptor Constants - Status Field */ +#define ISMT_DESC_SCS 0x01 /* Success */ +#define ISMT_DESC_DLTO 0x04 /* Data Low Time Out */ +#define ISMT_DESC_NAK 0x08 /* NAK Received */ +#define ISMT_DESC_CRC 0x10 /* CRC Error */ +#define ISMT_DESC_CLTO 0x20 /* Clock Low Time Out */ +#define ISMT_DESC_COL 0x40 /* Collisions */ +#define ISMT_DESC_LPR 0x80 /* Large Packet Received */ + +/* Macros */ +#define ISMT_DESC_ADDR_RW(addr, is_read) ((addr << 1) | (is_read)) + +/* iSMT General Register address offsets (SMBBAR + <addr>) */ +#define ISMT_GR_GCTRL 0x000 /* General Control */ +#define ISMT_GR_SMTICL 0x008 /* SMT Interrupt Cause Location */ +#define ISMT_GR_ERRINTMSK 0x010 /* Error Interrupt Mask */ +#define ISMT_GR_ERRAERMSK 0x014 /* Error AER Mask */ +#define ISMT_GR_ERRSTS 0x018 /* Error Status */ +#define ISMT_GR_ERRINFO 0x01c /* Error Information */ + +/* iSMT Master Registers */ +#define ISMT_MSTR_MDBA 0x100 /* Master Descriptor Base Address */ +#define ISMT_MSTR_MCTRL 0x108 /* Master Control */ +#define ISMT_MSTR_MSTS 0x10c /* Master Status */ +#define ISMT_MSTR_MDS 0x110 /* Master Descriptor Size */ +#define ISMT_MSTR_RPOLICY 0x114 /* Retry Policy */ + +/* iSMT Miscellaneous Registers */ +#define ISMT_SPGT 0x300 /* SMBus PHY Global Timing */ + +/* General Control Register (GCTRL) bit definitions */ +#define ISMT_GCTRL_TRST 0x04 /* Target Reset */ +#define ISMT_GCTRL_KILL 0x08 /* Kill */ +#define ISMT_GCTRL_SRST 0x40 /* Soft Reset */ + +/* Master Control Register (MCTRL) bit definitions */ +#define ISMT_MCTRL_SS 0x01 /* Start/Stop */ +#define ISMT_MCTRL_MEIE 0x10 /* Master Error Interrupt Enable */ +#define ISMT_MCTRL_FMHP 0x00ff0000 /* Firmware Master Head Ptr (FMHP) */ + +/* Master Status Register (MSTS) bit definitions */ +#define ISMT_MSTS_HMTP 0xff0000 /* HW Master Tail Pointer (HMTP) */ +#define ISMT_MSTS_MIS 0x20 /* Master Interrupt Status (MIS) */ +#define ISMT_MSTS_MEIS 0x10 /* Master Error Int Status (MEIS) */ +#define ISMT_MSTS_IP 0x01 /* In Progress */ + +/* Master Descriptor Size (MDS) bit definitions */ +#define ISMT_MDS_MASK 0xff /* Master Descriptor Size mask (MDS) */ + +/* SMBus PHY Global Timing Register (SPGT) bit definitions */ +#define ISMT_SPGT_SPD_MASK 0xc0000000 /* SMBus Speed mask */ +#define ISMT_SPGT_SPD_80K 0x00 /* 80 kHz */ +#define ISMT_SPGT_SPD_100K (0x1 << 30) /* 100 kHz */ +#define ISMT_SPGT_SPD_400K (0x2 << 30) /* 400 kHz */ +#define ISMT_SPGT_SPD_1M (0x3 << 30) /* 1 MHz */ + +/* MSI Control Register (MSICTL) bit definitions */ +#define ISMT_MSICTL_MSIE 0x01 /* MSI Enable */ + +#define ISMT_MAX_BLOCK_SIZE 32 /* per SMBus spec */ + +//#define ISMT_DEBUG device_printf +#ifndef ISMT_DEBUG +#define ISMT_DEBUG(...) +#endif + +/* iSMT Hardware Descriptor */ +struct ismt_desc { + uint8_t tgtaddr_rw; /* target address & r/w bit */ + uint8_t wr_len_cmd; /* write length in bytes or a command */ + uint8_t rd_len; /* read length */ + uint8_t control; /* control bits */ + uint8_t status; /* status bits */ + uint8_t retry; /* collision retry and retry count */ + uint8_t rxbytes; /* received bytes */ + uint8_t txbytes; /* transmitted bytes */ + uint32_t dptr_low; /* lower 32 bit of the data pointer */ + uint32_t dptr_high; /* upper 32 bit of the data pointer */ +} __packed; + +#define DESC_SIZE (ISMT_DESC_ENTRIES * sizeof(struct ismt_desc)) + +#define DMA_BUFFER_SIZE 64 + +struct ismt_softc { + device_t pcidev; + device_t smbdev; + + struct thread *bus_reserved; + + int intr_rid; + struct resource *intr_res; + void *intr_handle; + + bus_space_tag_t mmio_tag; + bus_space_handle_t mmio_handle; + int mmio_rid; + struct resource *mmio_res; + + uint8_t head; + + struct ismt_desc *desc; + bus_dma_tag_t desc_dma_tag; + bus_dmamap_t desc_dma_map; + uint64_t desc_bus_addr; + + uint8_t *dma_buffer; + bus_dma_tag_t dma_buffer_dma_tag; + bus_dmamap_t dma_buffer_dma_map; + uint64_t dma_buffer_bus_addr; + + uint8_t using_msi; +}; + +static void +ismt_intr(void *arg) +{ + struct ismt_softc *sc = arg; + uint32_t val; + + val = bus_read_4(sc->mmio_res, ISMT_MSTR_MSTS); + ISMT_DEBUG(sc->pcidev, "%s MSTS=0x%x\n", __func__, val); + + val |= (ISMT_MSTS_MIS | ISMT_MSTS_MEIS); + bus_write_4(sc->mmio_res, ISMT_MSTR_MSTS, val); + + wakeup(sc); +} + +static int +ismt_callback(device_t dev, int index, void *data) +{ + struct ismt_softc *sc; + int acquired, err; + + sc = device_get_softc(dev); + + switch (index) { + case SMB_REQUEST_BUS: + acquired = atomic_cmpset_ptr( + (uintptr_t *)&sc->bus_reserved, + (uintptr_t)NULL, (uintptr_t)curthread); + ISMT_DEBUG(dev, "SMB_REQUEST_BUS acquired=%d\n", acquired); + if (acquired) + err = 0; + else + err = EWOULDBLOCK; + break; + case SMB_RELEASE_BUS: + KASSERT(sc->bus_reserved == curthread, + ("SMB_RELEASE_BUS called by wrong thread\n")); + ISMT_DEBUG(dev, "SMB_RELEASE_BUS\n"); + atomic_store_rel_ptr((uintptr_t *)&sc->bus_reserved, + (uintptr_t)NULL); + err = 0; + break; + default: + err = SMB_EABORT; + break; + } + + return (err); +} + +static struct ismt_desc * +ismt_alloc_desc(struct ismt_softc *sc) +{ + struct ismt_desc *desc; + + KASSERT(sc->bus_reserved == curthread, + ("curthread %p did not request bus (%p has reserved)\n", + curthread, sc->bus_reserved)); + + desc = &sc->desc[sc->head++]; + if (sc->head == ISMT_DESC_ENTRIES) + sc->head = 0; + + memset(desc, 0, sizeof(*desc)); + + return (desc); +} + +static int +ismt_submit(struct ismt_softc *sc, struct ismt_desc *desc, uint8_t slave, + uint8_t is_read) +{ + uint32_t err, fmhp, val; + + desc->control |= ISMT_DESC_FAIR; + if (sc->using_msi) + desc->control |= ISMT_DESC_INT; + + desc->tgtaddr_rw = ISMT_DESC_ADDR_RW(slave, is_read); + desc->dptr_low = (sc->dma_buffer_bus_addr & 0xFFFFFFFFLL); + desc->dptr_high = (sc->dma_buffer_bus_addr >> 32); + + wmb(); + + fmhp = sc->head << 16; + val = bus_read_4(sc->mmio_res, ISMT_MSTR_MCTRL); + val &= ~ISMT_MCTRL_FMHP; + val |= fmhp; + bus_write_4(sc->mmio_res, ISMT_MSTR_MCTRL, val); + + /* set the start bit */ + val = bus_read_4(sc->mmio_res, ISMT_MSTR_MCTRL); + val |= ISMT_MCTRL_SS; + bus_write_4(sc->mmio_res, ISMT_MSTR_MCTRL, val); + + err = tsleep(sc, PWAIT, "ismt_wait", 5 * hz); + + if (err != 0) { + ISMT_DEBUG(sc->pcidev, "%s timeout\n", __func__); + return (SMB_ETIMEOUT); + } + + ISMT_DEBUG(sc->pcidev, "%s status=0x%x\n", __func__, desc->status); + + if (desc->status & ISMT_DESC_SCS) + return (SMB_ENOERR); + + if (desc->status & ISMT_DESC_NAK) + return (SMB_ENOACK); + + if (desc->status & ISMT_DESC_CRC) + return (SMB_EBUSERR); + + if (desc->status & ISMT_DESC_COL) + return (SMB_ECOLLI); + + if (desc->status & ISMT_DESC_LPR) + return (SMB_EINVAL); + + if (desc->status & (ISMT_DESC_DLTO | ISMT_DESC_CLTO)) + return (SMB_ETIMEOUT); + + return (SMB_EBUSERR); +} + + +static int +ismt_quick(device_t dev, u_char slave, int how) +{ + struct ismt_desc *desc; + struct ismt_softc *sc; + int is_read; + + ISMT_DEBUG(dev, "%s\n", __func__); + + if (how != SMB_QREAD && how != SMB_QWRITE) { + return (SMB_ENOTSUPP); + } + + sc = device_get_softc(dev); + desc = ismt_alloc_desc(sc); + is_read = (how == SMB_QREAD ? 1 : 0); + return (ismt_submit(sc, desc, slave, is_read)); +} + +static int +ismt_sendb(device_t dev, u_char slave, char byte) +{ + struct ismt_desc *desc; + struct ismt_softc *sc; + + ISMT_DEBUG(dev, "%s\n", __func__); + + sc = device_get_softc(dev); + desc = ismt_alloc_desc(sc); + desc->control = ISMT_DESC_CWRL; + desc->wr_len_cmd = byte; + + return (ismt_submit(sc, desc, slave, 0)); +} + +static int +ismt_recvb(device_t dev, u_char slave, char *byte) +{ + struct ismt_desc *desc; + struct ismt_softc *sc; + int err; + + ISMT_DEBUG(dev, "%s\n", __func__); + + sc = device_get_softc(dev); + desc = ismt_alloc_desc(sc); + desc->rd_len = 1; + + err = ismt_submit(sc, desc, slave, 1); + + if (err != SMB_ENOERR) + return (err); + + *byte = sc->dma_buffer[0]; + + return (err); +} + +static int +ismt_writeb(device_t dev, u_char slave, char cmd, char byte) +{ + struct ismt_desc *desc; + struct ismt_softc *sc; + + ISMT_DEBUG(dev, "%s\n", __func__); + + sc = device_get_softc(dev); + desc = ismt_alloc_desc(sc); + desc->wr_len_cmd = 2; + sc->dma_buffer[0] = cmd; + sc->dma_buffer[1] = byte; + + return (ismt_submit(sc, desc, slave, 0)); +} + +static int +ismt_writew(device_t dev, u_char slave, char cmd, short word) +{ + struct ismt_desc *desc; + struct ismt_softc *sc; + + ISMT_DEBUG(dev, "%s\n", __func__); + + sc = device_get_softc(dev); + desc = ismt_alloc_desc(sc); + desc->wr_len_cmd = 3; + sc->dma_buffer[0] = cmd; + sc->dma_buffer[1] = word & 0xFF; + sc->dma_buffer[2] = word >> 8; + + return (ismt_submit(sc, desc, slave, 0)); +} + +static int +ismt_readb(device_t dev, u_char slave, char cmd, char *byte) +{ + struct ismt_desc *desc; + struct ismt_softc *sc; + int err; + + ISMT_DEBUG(dev, "%s\n", __func__); + + sc = device_get_softc(dev); + desc = ismt_alloc_desc(sc); + desc->control = ISMT_DESC_CWRL; + desc->wr_len_cmd = cmd; + desc->rd_len = 1; + + err = ismt_submit(sc, desc, slave, 1); + + if (err != SMB_ENOERR) + return (err); + + *byte = sc->dma_buffer[0]; + + return (err); +} + +static int +ismt_readw(device_t dev, u_char slave, char cmd, short *word) +{ + struct ismt_desc *desc; + struct ismt_softc *sc; + int err; + + ISMT_DEBUG(dev, "%s\n", __func__); + + sc = device_get_softc(dev); + desc = ismt_alloc_desc(sc); + desc->control = ISMT_DESC_CWRL; + desc->wr_len_cmd = cmd; + desc->rd_len = 2; + + err = ismt_submit(sc, desc, slave, 1); + + if (err != SMB_ENOERR) + return (err); + + *word = sc->dma_buffer[0] | (sc->dma_buffer[1] << 8); + + return (err); +} + +static int +ismt_pcall(device_t dev, u_char slave, char cmd, short sdata, short *rdata) +{ + struct ismt_desc *desc; + struct ismt_softc *sc; + int err; + + ISMT_DEBUG(dev, "%s\n", __func__); + + sc = device_get_softc(dev); + desc = ismt_alloc_desc(sc); + desc->wr_len_cmd = 3; + desc->rd_len = 2; + sc->dma_buffer[0] = cmd; + sc->dma_buffer[1] = sdata & 0xff; + sc->dma_buffer[2] = sdata >> 8; + + err = ismt_submit(sc, desc, slave, 0); + + if (err != SMB_ENOERR) + return (err); + + *rdata = sc->dma_buffer[0] | (sc->dma_buffer[1] << 8); + + return (err); +} + +static int +ismt_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf) +{ + struct ismt_desc *desc; + struct ismt_softc *sc; + + ISMT_DEBUG(dev, "%s\n", __func__); + + if (count == 0 || count > ISMT_MAX_BLOCK_SIZE) + return (SMB_EINVAL); + + sc = device_get_softc(dev); + desc = ismt_alloc_desc(sc); + desc->control = ISMT_DESC_I2C; + desc->wr_len_cmd = count + 1; + sc->dma_buffer[0] = cmd; + memcpy(&sc->dma_buffer[1], buf, count); + + return (ismt_submit(sc, desc, slave, 0)); +} + +static int +ismt_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf) +{ + struct ismt_desc *desc; + struct ismt_softc *sc; + int err; + + ISMT_DEBUG(dev, "%s\n", __func__); + + if (*count == 0 || *count > ISMT_MAX_BLOCK_SIZE) + return (SMB_EINVAL); + + sc = device_get_softc(dev); + desc = ismt_alloc_desc(sc); + desc->control = ISMT_DESC_I2C | ISMT_DESC_CWRL; + desc->wr_len_cmd = cmd; + desc->rd_len = *count; + + err = ismt_submit(sc, desc, slave, 0); + + if (err != SMB_ENOERR) + return (err); + + memcpy(buf, sc->dma_buffer, desc->rxbytes); + *count = desc->rxbytes; + + return (err); +} + +static int +ismt_detach(device_t dev) +{ + struct ismt_softc *sc; + int error; + + ISMT_DEBUG(dev, "%s\n", __func__); + sc = device_get_softc(dev); + + error = bus_generic_detach(dev); + if (error) + return (error); + + device_delete_child(dev, sc->smbdev); + + if (sc->intr_handle != NULL) { + bus_teardown_intr(dev, sc->intr_res, sc->intr_handle); + sc->intr_handle = NULL; + } + if (sc->intr_res != NULL) { + bus_release_resource(dev, + SYS_RES_IRQ, sc->intr_rid, sc->intr_res); + sc->intr_res = NULL; + } + if (sc->using_msi == 1) + pci_release_msi(dev); + + if (sc->mmio_res != NULL) { + bus_release_resource(dev, + SYS_RES_MEMORY, sc->mmio_rid, sc->mmio_res); + sc->mmio_res = NULL; + } + + bus_dmamap_unload(sc->desc_dma_tag, sc->desc_dma_map); + bus_dmamap_unload(sc->dma_buffer_dma_tag, sc->dma_buffer_dma_map); + + bus_dmamem_free(sc->desc_dma_tag, sc->desc, + sc->desc_dma_map); + bus_dmamem_free(sc->dma_buffer_dma_tag, sc->dma_buffer, + sc->dma_buffer_dma_map); + + bus_dma_tag_destroy(sc->desc_dma_tag); + bus_dma_tag_destroy(sc->dma_buffer_dma_tag); + + pci_disable_busmaster(dev); + + return 0; +} + +static void +ismt_single_map(void *arg, bus_dma_segment_t *seg, int nseg, int error) +{ + uint64_t *bus_addr = (uint64_t *)arg; + + KASSERT(error == 0, ("%s: error=%d\n", __func__, error)); + KASSERT(nseg == 1, ("%s: nseg=%d\n", __func__, nseg)); + + *bus_addr = seg[0].ds_addr; +} + +static int +ismt_attach(device_t dev) +{ + struct ismt_softc *sc = device_get_softc(dev); + int err, num_vectors, val; + + sc->pcidev = dev; + pci_enable_busmaster(dev); + + if ((sc->smbdev = device_add_child(dev, "smbus", -1)) == NULL) { + device_printf(dev, "no smbus child found\n"); + err = ENXIO; + goto fail; + } + + sc->mmio_rid = PCIR_BAR(0); + sc->mmio_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, + &sc->mmio_rid, RF_ACTIVE); + if (sc->mmio_res == NULL) { + device_printf(dev, "cannot allocate mmio region\n"); + err = ENOMEM; + goto fail; + } + + sc->mmio_tag = rman_get_bustag(sc->mmio_res); + sc->mmio_handle = rman_get_bushandle(sc->mmio_res); + + /* Attach "smbus" child */ + if ((err = bus_generic_attach(dev)) != 0) { + device_printf(dev, "failed to attach child: %d\n", err); + err = ENXIO; + goto fail; + } + + bus_dma_tag_create(bus_get_dma_tag(dev), 4, PAGE_SIZE, + BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, + DESC_SIZE, 1, DESC_SIZE, + 0, NULL, NULL, &sc->desc_dma_tag); + + bus_dma_tag_create(bus_get_dma_tag(dev), 4, PAGE_SIZE, + BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, + DMA_BUFFER_SIZE, 1, DMA_BUFFER_SIZE, + 0, NULL, NULL, &sc->dma_buffer_dma_tag); + + bus_dmamap_create(sc->desc_dma_tag, 0, + &sc->desc_dma_map); + bus_dmamap_create(sc->dma_buffer_dma_tag, 0, + &sc->dma_buffer_dma_map); + + bus_dmamem_alloc(sc->desc_dma_tag, + (void **)&sc->desc, BUS_DMA_WAITOK, + &sc->desc_dma_map); + bus_dmamem_alloc(sc->dma_buffer_dma_tag, + (void **)&sc->dma_buffer, BUS_DMA_WAITOK, + &sc->dma_buffer_dma_map); + + bus_dmamap_load(sc->desc_dma_tag, + sc->desc_dma_map, sc->desc, DESC_SIZE, + ismt_single_map, &sc->desc_bus_addr, 0); + bus_dmamap_load(sc->dma_buffer_dma_tag, + sc->dma_buffer_dma_map, sc->dma_buffer, DMA_BUFFER_SIZE, + ismt_single_map, &sc->dma_buffer_bus_addr, 0); + + bus_write_4(sc->mmio_res, ISMT_MSTR_MDBA, + (sc->desc_bus_addr & 0xFFFFFFFFLL)); + bus_write_4(sc->mmio_res, ISMT_MSTR_MDBA + 4, + (sc->desc_bus_addr >> 32)); + + /* initialize the Master Control Register (MCTRL) */ + bus_write_4(sc->mmio_res, ISMT_MSTR_MCTRL, ISMT_MCTRL_MEIE); + + /* initialize the Master Status Register (MSTS) */ + bus_write_4(sc->mmio_res, ISMT_MSTR_MSTS, 0); + + /* initialize the Master Descriptor Size (MDS) */ + val = bus_read_4(sc->mmio_res, ISMT_MSTR_MDS); + val &= ~ISMT_MDS_MASK; + val |= (ISMT_DESC_ENTRIES - 1); + bus_write_4(sc->mmio_res, ISMT_MSTR_MDS, val); + + sc->using_msi = 1; + + if (pci_msi_count(dev) == 0) { + sc->using_msi = 0; + goto intx; + } + + num_vectors = 1; + if (pci_alloc_msi(dev, &num_vectors) != 0) { + sc->using_msi = 0; + goto intx; + } + + sc->intr_rid = 1; + sc->intr_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, + &sc->intr_rid, RF_ACTIVE); + + if (sc->intr_res == NULL) { + sc->using_msi = 0; + pci_release_msi(dev); + } + +intx: + if (sc->using_msi == 0) { + sc->intr_rid = 0; + sc->intr_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, + &sc->intr_rid, RF_SHAREABLE | RF_ACTIVE); + if (sc->intr_res == NULL) { + device_printf(dev, "cannot allocate irq\n"); + err = ENXIO; + goto fail; + } + } + + ISMT_DEBUG(dev, "using_msi = %d\n", sc->using_msi); + + err = bus_setup_intr(dev, sc->intr_res, + INTR_TYPE_MISC | INTR_MPSAFE, NULL, ismt_intr, sc, + &sc->intr_handle); + if (err != 0) { + device_printf(dev, "cannot setup interrupt\n"); + err = ENXIO; + goto fail; + } + + return (0); + +fail: + ismt_detach(dev); + return (err); +} + +#define ID_INTEL_S1200_SMT0 0x0c598086 +#define ID_INTEL_S1200_SMT1 0x0c5a8086 +#define ID_INTEL_C2000_SMT 0x1f158086 + +static int +ismt_probe(device_t dev) +{ + const char *desc; + + switch (pci_get_devid(dev)) { + case ID_INTEL_S1200_SMT0: + desc = "Atom Processor S1200 SMBus 2.0 Controller 0"; + break; + case ID_INTEL_S1200_SMT1: + desc = "Atom Processor S1200 SMBus 2.0 Controller 1"; + break; + case ID_INTEL_C2000_SMT: + desc = "Atom Processor C2000 SMBus 2.0"; + break; + default: + return (ENXIO); + } + + device_set_desc(dev, desc); + return (BUS_PROBE_DEFAULT); +} + +/* Device methods */ +static device_method_t ismt_pci_methods[] = { + DEVMETHOD(device_probe, ismt_probe), + DEVMETHOD(device_attach, ismt_attach), + DEVMETHOD(device_detach, ismt_detach), + + DEVMETHOD(smbus_callback, ismt_callback), + DEVMETHOD(smbus_quick, ismt_quick), + DEVMETHOD(smbus_sendb, ismt_sendb), + DEVMETHOD(smbus_recvb, ismt_recvb), + DEVMETHOD(smbus_writeb, ismt_writeb), + DEVMETHOD(smbus_writew, ismt_writew), + DEVMETHOD(smbus_readb, ismt_readb), + DEVMETHOD(smbus_readw, ismt_readw), + DEVMETHOD(smbus_pcall, ismt_pcall), + DEVMETHOD(smbus_bwrite, ismt_bwrite), + DEVMETHOD(smbus_bread, ismt_bread), + + DEVMETHOD_END +}; + +static driver_t ismt_pci_driver = { + "ismt", + ismt_pci_methods, + sizeof(struct ismt_softc) +}; + +static devclass_t ismt_pci_devclass; + +DRIVER_MODULE(ismt, pci, ismt_pci_driver, ismt_pci_devclass, 0, 0); +DRIVER_MODULE(smbus, ismt, smbus_driver, smbus_devclass, 0, 0); + +MODULE_DEPEND(ismt, pci, 1, 1, 1); +MODULE_DEPEND(ismt, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER); +MODULE_VERSION(ismt, 1); diff --git a/sys/dev/mpr/mpr_sas_lsi.c b/sys/dev/mpr/mpr_sas_lsi.c index 7d6ef70..b2ffe96 100644 --- a/sys/dev/mpr/mpr_sas_lsi.c +++ b/sys/dev/mpr/mpr_sas_lsi.c @@ -885,7 +885,13 @@ mprsas_get_sas_address_for_sata_disk(struct mpr_softc *sc, ioc_status = le16toh(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; sas_status = mpi_reply.SASStatus; - if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { + switch (ioc_status) { + case MPI2_IOCSTATUS_SUCCESS: + break; + case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR: + /* No sense sleeping. this error won't get better */ + break; + default: if (sc->spinup_wait_time > 0) { mpr_dprint(sc, MPR_INFO, "Sleeping %d seconds " "after SATA ID error to wait for spinup\n", @@ -894,8 +900,10 @@ mprsas_get_sas_address_for_sata_disk(struct mpr_softc *sc, "mprid", sc->spinup_wait_time * hz); } } - } while (((rc && (rc != EWOULDBLOCK)) || ioc_status || sas_status) && - (try_count < 5)); + } while (((rc && (rc != EWOULDBLOCK)) || + (ioc_status && + (ioc_status != MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR)) + || sas_status) && (try_count < 5)); if (rc == 0 && !ioc_status && !sas_status) { mpr_dprint(sc, MPR_MAPPING, "%s: got SATA identify " diff --git a/sys/dev/mps/mps_sas_lsi.c b/sys/dev/mps/mps_sas_lsi.c index 434663a..268383a 100644 --- a/sys/dev/mps/mps_sas_lsi.c +++ b/sys/dev/mps/mps_sas_lsi.c @@ -794,7 +794,13 @@ mpssas_get_sas_address_for_sata_disk(struct mps_softc *sc, ioc_status = le16toh(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; sas_status = mpi_reply.SASStatus; - if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { + switch (ioc_status) { + case MPI2_IOCSTATUS_SUCCESS: + break; + case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR: + /* No sense sleeping. this error won't get better */ + break; + default: if (sc->spinup_wait_time > 0) { mps_dprint(sc, MPS_INFO, "Sleeping %d seconds " "after SATA ID error to wait for spinup\n", @@ -803,8 +809,10 @@ mpssas_get_sas_address_for_sata_disk(struct mps_softc *sc, "mpsid", sc->spinup_wait_time * hz); } } - } while (((rc && (rc != EWOULDBLOCK)) || ioc_status || sas_status) && - (try_count < 5)); + } while (((rc && (rc != EWOULDBLOCK)) || + (ioc_status && + (ioc_status != MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR)) + || sas_status) && (try_count < 5)); if (rc == 0 && !ioc_status && !sas_status) { mps_dprint(sc, MPS_MAPPING, "%s: got SATA identify " diff --git a/sys/dev/nvd/nvd.c b/sys/dev/nvd/nvd.c index 5d75876..7be8a18 100644 --- a/sys/dev/nvd/nvd.c +++ b/sys/dev/nvd/nvd.c @@ -47,6 +47,8 @@ struct nvd_disk; static disk_ioctl_t nvd_ioctl; static disk_strategy_t nvd_strategy; +static void nvd_done(void *arg, const struct nvme_completion *cpl); + static void *nvd_new_disk(struct nvme_namespace *ns, void *ctrlr); static void destroy_geom_disk(struct nvd_disk *ndisk); @@ -71,6 +73,7 @@ struct nvd_disk { struct nvme_namespace *ns; uint32_t cur_depth; + uint32_t ordered_in_flight; TAILQ_ENTRY(nvd_disk) global_tailq; TAILQ_ENTRY(nvd_disk) ctrlr_tailq; @@ -148,6 +151,28 @@ nvd_unload() nvme_unregister_consumer(consumer_handle); } +static int +nvd_bio_submit(struct nvd_disk *ndisk, struct bio *bp) +{ + int err; + + bp->bio_driver1 = NULL; + atomic_add_int(&ndisk->cur_depth, 1); + err = nvme_ns_bio_process(ndisk->ns, bp, nvd_done); + if (err) { + atomic_add_int(&ndisk->cur_depth, -1); + if (__predict_false(bp->bio_flags & BIO_ORDERED)) + atomic_add_int(&ndisk->ordered_in_flight, -1); + bp->bio_error = err; + bp->bio_flags |= BIO_ERROR; + bp->bio_resid = bp->bio_bcount; + biodone(bp); + return (-1); + } + + return (0); +} + static void nvd_strategy(struct bio *bp) { @@ -155,6 +180,18 @@ nvd_strategy(struct bio *bp) ndisk = (struct nvd_disk *)bp->bio_disk->d_drv1; + if (__predict_false(bp->bio_flags & BIO_ORDERED)) + atomic_add_int(&ndisk->ordered_in_flight, 1); + + if (__predict_true(ndisk->ordered_in_flight == 0)) { + nvd_bio_submit(ndisk, bp); + return; + } + + /* + * There are ordered bios in flight, so we need to submit + * bios through the task queue to enforce ordering. + */ mtx_lock(&ndisk->bioqlock); bioq_insert_tail(&ndisk->bioq, bp); mtx_unlock(&ndisk->bioqlock); @@ -186,6 +223,8 @@ nvd_done(void *arg, const struct nvme_completion *cpl) ndisk = bp->bio_disk->d_drv1; atomic_add_int(&ndisk->cur_depth, -1); + if (__predict_false(bp->bio_flags & BIO_ORDERED)) + atomic_add_int(&ndisk->ordered_in_flight, -1); biodone(bp); } @@ -195,7 +234,6 @@ nvd_bioq_process(void *arg, int pending) { struct nvd_disk *ndisk = arg; struct bio *bp; - int err; for (;;) { mtx_lock(&ndisk->bioqlock); @@ -204,30 +242,8 @@ nvd_bioq_process(void *arg, int pending) if (bp == NULL) break; -#ifdef BIO_ORDERED - /* - * BIO_ORDERED flag dictates that all outstanding bios - * must be completed before processing the bio with - * BIO_ORDERED flag set. - */ - if (bp->bio_flags & BIO_ORDERED) { - while (ndisk->cur_depth > 0) { - pause("nvd flush", 1); - } - } -#endif - - bp->bio_driver1 = NULL; - atomic_add_int(&ndisk->cur_depth, 1); - - err = nvme_ns_bio_process(ndisk->ns, bp, nvd_done); - - if (err) { - atomic_add_int(&ndisk->cur_depth, -1); - bp->bio_error = err; - bp->bio_flags |= BIO_ERROR; - bp->bio_resid = bp->bio_bcount; - biodone(bp); + if (nvd_bio_submit(ndisk, bp) != 0) { + continue; } #ifdef BIO_ORDERED @@ -287,7 +303,7 @@ nvd_new_disk(struct nvme_namespace *ns, void *ctrlr_arg) disk->d_unit = TAILQ_LAST(&disk_head, disk_list)->disk->d_unit + 1; - disk->d_flags = 0; + disk->d_flags = DISKFLAG_DIRECT_COMPLETION; if (nvme_ns_get_flags(ns) & NVME_NS_DEALLOCATE_SUPPORTED) disk->d_flags |= DISKFLAG_CANDELETE; @@ -317,6 +333,7 @@ nvd_new_disk(struct nvme_namespace *ns, void *ctrlr_arg) ndisk->ns = ns; ndisk->disk = disk; ndisk->cur_depth = 0; + ndisk->ordered_in_flight = 0; mtx_init(&ndisk->bioqlock, "NVD bioq lock", NULL, MTX_DEF); bioq_init(&ndisk->bioq); diff --git a/sys/dev/nvme/nvme.c b/sys/dev/nvme/nvme.c index cc14d34..9db2b14 100644 --- a/sys/dev/nvme/nvme.c +++ b/sys/dev/nvme/nvme.c @@ -270,8 +270,6 @@ nvme_attach(device_t dev) return (status); } - nvme_sysctl_initialize_ctrlr(ctrlr); - pci_enable_busmaster(dev); ctrlr->config_hook.ich_func = nvme_ctrlr_start_config_hook; diff --git a/sys/dev/nvme/nvme_ctrlr.c b/sys/dev/nvme/nvme_ctrlr.c index 928d294..86f2a54 100644 --- a/sys/dev/nvme/nvme_ctrlr.c +++ b/sys/dev/nvme/nvme_ctrlr.c @@ -1,5 +1,5 @@ /*- - * Copyright (C) 2012-2015 Intel Corporation + * Copyright (C) 2012-2016 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$"); static void nvme_ctrlr_construct_and_submit_aer(struct nvme_controller *ctrlr, struct nvme_async_event_request *aer); +static void nvme_ctrlr_setup_interrupts(struct nvme_controller *ctrlr); static int nvme_ctrlr_allocate_bar(struct nvme_controller *ctrlr) @@ -140,6 +141,13 @@ nvme_ctrlr_construct_io_qpairs(struct nvme_controller *ctrlr) */ num_trackers = min(num_trackers, (num_entries-1)); + /* + * This was calculated previously when setting up interrupts, but + * a controller could theoretically support fewer I/O queues than + * MSI-X vectors. So calculate again here just to be safe. + */ + ctrlr->num_cpus_per_ioq = howmany(mp_ncpus, ctrlr->num_io_queues); + ctrlr->ioq = malloc(ctrlr->num_io_queues * sizeof(struct nvme_qpair), M_NVME, M_ZERO | M_WAITOK); @@ -160,8 +168,13 @@ nvme_ctrlr_construct_io_qpairs(struct nvme_controller *ctrlr) num_trackers, ctrlr); - if (ctrlr->per_cpu_io_queues) - bus_bind_intr(ctrlr->dev, qpair->res, i); + /* + * Do not bother binding interrupts if we only have one I/O + * interrupt thread for this controller. + */ + if (ctrlr->num_io_queues > 1) + bus_bind_intr(ctrlr->dev, qpair->res, + i * ctrlr->num_cpus_per_ioq); } return (0); @@ -306,8 +319,15 @@ nvme_ctrlr_hw_reset(struct nvme_controller *ctrlr) int i; nvme_admin_qpair_disable(&ctrlr->adminq); - for (i = 0; i < ctrlr->num_io_queues; i++) - nvme_io_qpair_disable(&ctrlr->ioq[i]); + /* + * I/O queues are not allocated before the initial HW + * reset, so do not try to disable them. Use is_initialized + * to determine if this is the initial HW reset. + */ + if (ctrlr->is_initialized) { + for (i = 0; i < ctrlr->num_io_queues; i++) + nvme_io_qpair_disable(&ctrlr->ioq[i]); + } DELAY(100*1000); @@ -363,7 +383,7 @@ static int nvme_ctrlr_set_num_qpairs(struct nvme_controller *ctrlr) { struct nvme_completion_poll_status status; - int cq_allocated, i, sq_allocated; + int cq_allocated, sq_allocated; status.done = FALSE; nvme_ctrlr_cmd_set_num_queues(ctrlr, ctrlr->num_io_queues, @@ -384,26 +404,12 @@ nvme_ctrlr_set_num_qpairs(struct nvme_controller *ctrlr) cq_allocated = (status.cpl.cdw0 >> 16) + 1; /* - * Check that the controller was able to allocate the number of - * queues we requested. If not, revert to one IO queue pair. + * Controller may allocate more queues than we requested, + * so use the minimum of the number requested and what was + * actually allocated. */ - if (sq_allocated < ctrlr->num_io_queues || - cq_allocated < ctrlr->num_io_queues) { - - /* - * Destroy extra IO queue pairs that were created at - * controller construction time but are no longer - * needed. This will only happen when a controller - * supports fewer queues than MSI-X vectors. This - * is not the normal case, but does occur with the - * Chatham prototype board. - */ - for (i = 1; i < ctrlr->num_io_queues; i++) - nvme_io_qpair_destroy(&ctrlr->ioq[i]); - - ctrlr->num_io_queues = 1; - ctrlr->per_cpu_io_queues = 0; - } + ctrlr->num_io_queues = min(ctrlr->num_io_queues, sq_allocated); + ctrlr->num_io_queues = min(ctrlr->num_io_queues, cq_allocated); return (0); } @@ -687,9 +693,20 @@ static void nvme_ctrlr_start(void *ctrlr_arg) { struct nvme_controller *ctrlr = ctrlr_arg; + uint32_t old_num_io_queues; int i; - nvme_qpair_reset(&ctrlr->adminq); + /* + * Only reset adminq here when we are restarting the + * controller after a reset. During initialization, + * we have already submitted admin commands to get + * the number of I/O queues supported, so cannot reset + * the adminq again here. + */ + if (ctrlr->is_resetting) { + nvme_qpair_reset(&ctrlr->adminq); + } + for (i = 0; i < ctrlr->num_io_queues; i++) nvme_qpair_reset(&ctrlr->ioq[i]); @@ -700,11 +717,25 @@ nvme_ctrlr_start(void *ctrlr_arg) return; } + /* + * The number of qpairs are determined during controller initialization, + * including using NVMe SET_FEATURES/NUMBER_OF_QUEUES to determine the + * HW limit. We call SET_FEATURES again here so that it gets called + * after any reset for controllers that depend on the driver to + * explicit specify how many queues it will use. This value should + * never change between resets, so panic if somehow that does happen. + */ + old_num_io_queues = ctrlr->num_io_queues; if (nvme_ctrlr_set_num_qpairs(ctrlr) != 0) { nvme_ctrlr_fail(ctrlr); return; } + if (old_num_io_queues != ctrlr->num_io_queues) { + panic("num_io_queues changed from %u to %u", old_num_io_queues, + ctrlr->num_io_queues); + } + if (nvme_ctrlr_create_qpairs(ctrlr) != 0) { nvme_ctrlr_fail(ctrlr); return; @@ -727,7 +758,16 @@ nvme_ctrlr_start_config_hook(void *arg) { struct nvme_controller *ctrlr = arg; - nvme_ctrlr_start(ctrlr); + nvme_qpair_reset(&ctrlr->adminq); + nvme_admin_qpair_enable(&ctrlr->adminq); + + if (nvme_ctrlr_set_num_qpairs(ctrlr) == 0 && + nvme_ctrlr_construct_io_qpairs(ctrlr) == 0) + nvme_ctrlr_start(ctrlr); + else + nvme_ctrlr_fail(ctrlr); + + nvme_sysctl_initialize_ctrlr(ctrlr); config_intrhook_disestablish(&ctrlr->config_hook); ctrlr->is_initialized = 1; @@ -778,8 +818,9 @@ static int nvme_ctrlr_configure_intx(struct nvme_controller *ctrlr) { + ctrlr->msix_enabled = 0; ctrlr->num_io_queues = 1; - ctrlr->per_cpu_io_queues = 0; + ctrlr->num_cpus_per_ioq = mp_ncpus; ctrlr->rid = 0; ctrlr->res = bus_alloc_resource_any(ctrlr->dev, SYS_RES_IRQ, &ctrlr->rid, RF_SHAREABLE | RF_ACTIVE); @@ -927,13 +968,93 @@ static struct cdevsw nvme_ctrlr_cdevsw = { .d_ioctl = nvme_ctrlr_ioctl }; +static void +nvme_ctrlr_setup_interrupts(struct nvme_controller *ctrlr) +{ + device_t dev; + int per_cpu_io_queues; + int min_cpus_per_ioq; + int num_vectors_requested, num_vectors_allocated; + int num_vectors_available; + + dev = ctrlr->dev; + min_cpus_per_ioq = 1; + TUNABLE_INT_FETCH("hw.nvme.min_cpus_per_ioq", &min_cpus_per_ioq); + + if (min_cpus_per_ioq < 1) { + min_cpus_per_ioq = 1; + } else if (min_cpus_per_ioq > mp_ncpus) { + min_cpus_per_ioq = mp_ncpus; + } + + per_cpu_io_queues = 1; + TUNABLE_INT_FETCH("hw.nvme.per_cpu_io_queues", &per_cpu_io_queues); + + if (per_cpu_io_queues == 0) { + min_cpus_per_ioq = mp_ncpus; + } + + ctrlr->force_intx = 0; + TUNABLE_INT_FETCH("hw.nvme.force_intx", &ctrlr->force_intx); + + /* + * FreeBSD currently cannot allocate more than about 190 vectors at + * boot, meaning that systems with high core count and many devices + * requesting per-CPU interrupt vectors will not get their full + * allotment. So first, try to allocate as many as we may need to + * understand what is available, then immediately release them. + * Then figure out how many of those we will actually use, based on + * assigning an equal number of cores to each I/O queue. + */ + + /* One vector for per core I/O queue, plus one vector for admin queue. */ + num_vectors_available = min(pci_msix_count(dev), mp_ncpus + 1); + if (pci_alloc_msix(dev, &num_vectors_available) != 0) { + num_vectors_available = 0; + } + pci_release_msi(dev); + + if (ctrlr->force_intx || num_vectors_available < 2) { + nvme_ctrlr_configure_intx(ctrlr); + return; + } + + /* + * Do not use all vectors for I/O queues - one must be saved for the + * admin queue. + */ + ctrlr->num_cpus_per_ioq = max(min_cpus_per_ioq, + howmany(mp_ncpus, num_vectors_available - 1)); + + ctrlr->num_io_queues = howmany(mp_ncpus, ctrlr->num_cpus_per_ioq); + num_vectors_requested = ctrlr->num_io_queues + 1; + num_vectors_allocated = num_vectors_requested; + + /* + * Now just allocate the number of vectors we need. This should + * succeed, since we previously called pci_alloc_msix() + * successfully returning at least this many vectors, but just to + * be safe, if something goes wrong just revert to INTx. + */ + if (pci_alloc_msix(dev, &num_vectors_allocated) != 0) { + nvme_ctrlr_configure_intx(ctrlr); + return; + } + + if (num_vectors_allocated < num_vectors_requested) { + pci_release_msi(dev); + nvme_ctrlr_configure_intx(ctrlr); + return; + } + + ctrlr->msix_enabled = 1; +} + int nvme_ctrlr_construct(struct nvme_controller *ctrlr, device_t dev) { union cap_lo_register cap_lo; union cap_hi_register cap_hi; - int i, per_cpu_io_queues, rid; - int num_vectors_requested, num_vectors_allocated; int status, timeout_period; ctrlr->dev = dev; @@ -968,116 +1089,13 @@ nvme_ctrlr_construct(struct nvme_controller *ctrlr, device_t dev) nvme_retry_count = NVME_DEFAULT_RETRY_COUNT; TUNABLE_INT_FETCH("hw.nvme.retry_count", &nvme_retry_count); - per_cpu_io_queues = 1; - TUNABLE_INT_FETCH("hw.nvme.per_cpu_io_queues", &per_cpu_io_queues); - ctrlr->per_cpu_io_queues = per_cpu_io_queues ? TRUE : FALSE; - - if (ctrlr->per_cpu_io_queues) - ctrlr->num_io_queues = mp_ncpus; - else - ctrlr->num_io_queues = 1; - - ctrlr->force_intx = 0; - TUNABLE_INT_FETCH("hw.nvme.force_intx", &ctrlr->force_intx); - ctrlr->enable_aborts = 0; TUNABLE_INT_FETCH("hw.nvme.enable_aborts", &ctrlr->enable_aborts); - ctrlr->msix_enabled = 1; - - if (ctrlr->force_intx) { - ctrlr->msix_enabled = 0; - goto intx; - } - - /* One vector per IO queue, plus one vector for admin queue. */ - num_vectors_requested = ctrlr->num_io_queues + 1; - - /* - * If we cannot even allocate 2 vectors (one for admin, one for - * I/O), then revert to INTx. - */ - if (pci_msix_count(dev) < 2) { - ctrlr->msix_enabled = 0; - goto intx; - } else if (pci_msix_count(dev) < num_vectors_requested) { - ctrlr->per_cpu_io_queues = FALSE; - ctrlr->num_io_queues = 1; - num_vectors_requested = 2; /* one for admin, one for I/O */ - } - - num_vectors_allocated = num_vectors_requested; - if (pci_alloc_msix(dev, &num_vectors_allocated) != 0) { - ctrlr->msix_enabled = 0; - goto intx; - } else if (num_vectors_allocated < num_vectors_requested) { - if (num_vectors_allocated < 2) { - pci_release_msi(dev); - ctrlr->msix_enabled = 0; - goto intx; - } else { - ctrlr->per_cpu_io_queues = FALSE; - ctrlr->num_io_queues = 1; - /* - * Release whatever vectors were allocated, and just - * reallocate the two needed for the admin and single - * I/O qpair. - */ - num_vectors_allocated = 2; - pci_release_msi(dev); - if (pci_alloc_msix(dev, &num_vectors_allocated) != 0) - panic("could not reallocate any vectors\n"); - if (num_vectors_allocated != 2) - panic("could not reallocate 2 vectors\n"); - } - } - - /* - * On earlier FreeBSD releases, there are reports that - * pci_alloc_msix() can return successfully with all vectors - * requested, but a subsequent bus_alloc_resource_any() - * for one of those vectors fails. This issue occurs more - * readily with multiple devices using per-CPU vectors. - * To workaround this issue, try to allocate the resources now, - * and fall back to INTx if we cannot allocate all of them. - * This issue cannot be reproduced on more recent versions of - * FreeBSD which have increased the maximum number of MSI-X - * vectors, but adding the workaround makes it easier for - * vendors wishing to import this driver into kernels based on - * older versions of FreeBSD. - */ - for (i = 0; i < num_vectors_allocated; i++) { - rid = i + 1; - ctrlr->msi_res[i] = bus_alloc_resource_any(ctrlr->dev, - SYS_RES_IRQ, &rid, RF_ACTIVE); - - if (ctrlr->msi_res[i] == NULL) { - ctrlr->msix_enabled = 0; - while (i > 0) { - i--; - bus_release_resource(ctrlr->dev, - SYS_RES_IRQ, - rman_get_rid(ctrlr->msi_res[i]), - ctrlr->msi_res[i]); - } - pci_release_msi(dev); - nvme_printf(ctrlr, "could not obtain all MSI-X " - "resources, reverting to intx\n"); - break; - } - } - -intx: - - if (!ctrlr->msix_enabled) - nvme_ctrlr_configure_intx(ctrlr); + nvme_ctrlr_setup_interrupts(ctrlr); ctrlr->max_xfer_size = NVME_MAX_XFER_SIZE; nvme_ctrlr_construct_admin_qpair(ctrlr); - status = nvme_ctrlr_construct_io_qpairs(ctrlr); - - if (status != 0) - return (status); ctrlr->cdev = make_dev(&nvme_ctrlr_cdevsw, device_get_unit(dev), UID_ROOT, GID_WHEEL, 0600, "nvme%d", device_get_unit(dev)); @@ -1189,11 +1207,7 @@ nvme_ctrlr_submit_io_request(struct nvme_controller *ctrlr, { struct nvme_qpair *qpair; - if (ctrlr->per_cpu_io_queues) - qpair = &ctrlr->ioq[curcpu]; - else - qpair = &ctrlr->ioq[0]; - + qpair = &ctrlr->ioq[curcpu / ctrlr->num_cpus_per_ioq]; nvme_qpair_submit_request(qpair, req); } diff --git a/sys/dev/nvme/nvme_private.h b/sys/dev/nvme/nvme_private.h index 6137b41..3330711 100644 --- a/sys/dev/nvme/nvme_private.h +++ b/sys/dev/nvme/nvme_private.h @@ -265,7 +265,7 @@ struct nvme_controller { uint32_t enable_aborts; uint32_t num_io_queues; - boolean_t per_cpu_io_queues; + uint32_t num_cpus_per_ioq; /* Fields for tracking progress during controller initialization. */ struct intr_config_hook config_hook; @@ -276,8 +276,6 @@ struct nvme_controller { struct task fail_req_task; struct taskqueue *taskqueue; - struct resource *msi_res[MAXCPU + 1]; - /* For shared legacy interrupt. */ int rid; struct resource *res; diff --git a/sys/dev/nvme/nvme_qpair.c b/sys/dev/nvme/nvme_qpair.c index d0cb8c6..92fe672 100644 --- a/sys/dev/nvme/nvme_qpair.c +++ b/sys/dev/nvme/nvme_qpair.c @@ -479,8 +479,9 @@ nvme_qpair_construct(struct nvme_qpair *qpair, uint32_t id, * the queue's vector to get the corresponding rid to use. */ qpair->rid = vector + 1; - qpair->res = ctrlr->msi_res[vector]; + qpair->res = bus_alloc_resource_any(ctrlr->dev, SYS_RES_IRQ, + &qpair->rid, RF_ACTIVE); bus_setup_intr(ctrlr->dev, qpair->res, INTR_TYPE_MISC | INTR_MPSAFE, NULL, nvme_qpair_msix_handler, qpair, &qpair->tag); diff --git a/sys/dev/nvme/nvme_sysctl.c b/sys/dev/nvme/nvme_sysctl.c index 0ebbbf7..44b0ab7 100644 --- a/sys/dev/nvme/nvme_sysctl.c +++ b/sys/dev/nvme/nvme_sysctl.c @@ -1,5 +1,5 @@ /*- - * Copyright (C) 2012-2013 Intel Corporation + * Copyright (C) 2012-2016 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -251,6 +251,10 @@ nvme_sysctl_initialize_ctrlr(struct nvme_controller *ctrlr) ctrlr_tree = device_get_sysctl_tree(ctrlr->dev); ctrlr_list = SYSCTL_CHILDREN(ctrlr_tree); + SYSCTL_ADD_UINT(ctrlr_ctx, ctrlr_list, OID_AUTO, "num_cpus_per_ioq", + CTLFLAG_RD, &ctrlr->num_cpus_per_ioq, 0, + "Number of CPUs assigned per I/O queue pair"); + SYSCTL_ADD_PROC(ctrlr_ctx, ctrlr_list, OID_AUTO, "int_coal_time", CTLTYPE_UINT | CTLFLAG_RW, ctrlr, 0, nvme_sysctl_int_coal_time, "IU", diff --git a/sys/dev/usb/controller/dwc_otg.c b/sys/dev/usb/controller/dwc_otg.c index c0c8f88..97fc70f 100644 --- a/sys/dev/usb/controller/dwc_otg.c +++ b/sys/dev/usb/controller/dwc_otg.c @@ -457,6 +457,18 @@ dwc_otg_init_fifo(struct dwc_otg_softc *sc, uint8_t mode) return (0); } +static uint8_t +dwc_otg_uses_split(struct usb_device *udev) +{ + /* + * When a LOW or FULL speed device is connected directly to + * the USB port we don't use split transactions: + */ + return (udev->speed != USB_SPEED_HIGH && + udev->parent_hs_hub != NULL && + udev->parent_hs_hub->parent_hub != NULL); +} + static void dwc_otg_update_host_frame_interval(struct dwc_otg_softc *sc) { @@ -3325,16 +3337,16 @@ dwc_otg_setup_standard_chain(struct usb_xfer *xfer) else hcchar |= (td->ep_type << HCCHAR_EPTYPE_SHIFT); - if (usbd_get_speed(xfer->xroot->udev) == USB_SPEED_LOW) - hcchar |= HCCHAR_LSPDDEV; if (UE_GET_DIR(xfer->endpointno) == UE_DIR_IN) hcchar |= HCCHAR_EPDIR_IN; switch (xfer->xroot->udev->speed) { - case USB_SPEED_FULL: case USB_SPEED_LOW: + hcchar |= HCCHAR_LSPDDEV; + /* FALLTHROUGH */ + case USB_SPEED_FULL: /* check if root HUB port is running High Speed */ - if (xfer->xroot->udev->parent_hs_hub != NULL) { + if (dwc_otg_uses_split(xfer->xroot->udev)) { hcsplt = HCSPLT_SPLTENA | (xfer->xroot->udev->hs_port_no << HCSPLT_PRTADDR_SHIFT) | @@ -4156,7 +4168,10 @@ dwc_otg_device_isoc_start(struct usb_xfer *xfer) framenum = DSTS_SOFFN_GET(temp); } - if (xfer->xroot->udev->parent_hs_hub != NULL) + /* + * Check if port is doing 8000 or 1000 frames per second: + */ + if (sc->sc_flags.status_high_speed) framenum /= 8; framenum &= DWC_OTG_FRAME_MASK; @@ -4833,7 +4848,7 @@ dwc_otg_xfer_setup(struct usb_setup_params *parm) td = USB_ADD_BYTES(parm->buf, parm->size[0]); /* compute shared bandwidth resource index for TT */ - if (parm->udev->parent_hs_hub != NULL && parm->udev->speed != USB_SPEED_HIGH) { + if (dwc_otg_uses_split(parm->udev)) { if (parm->udev->parent_hs_hub->ddesc.bDeviceProtocol == UDPROTO_HSHUBMTT) td->tt_index = parm->udev->device_index; else diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c index 816a340..ba56e56 100644 --- a/sys/fs/devfs/devfs_vnops.c +++ b/sys/fs/devfs/devfs_vnops.c @@ -1114,7 +1114,7 @@ devfs_open(struct vop_open_args *ap) error = dsw->d_fdopen(dev, ap->a_mode, td, fp); else error = dsw->d_open(dev, ap->a_mode, S_IFCHR, td); - /* cleanup any cdevpriv upon error */ + /* Clean up any cdevpriv upon error. */ if (error != 0) devfs_clear_cdevpriv(); td->td_fpop = fpop; diff --git a/sys/fs/ext2fs/ext2_bmap.c b/sys/fs/ext2fs/ext2_bmap.c index d144e92..7d4a880 100644 --- a/sys/fs/ext2fs/ext2_bmap.c +++ b/sys/fs/ext2fs/ext2_bmap.c @@ -96,6 +96,7 @@ ext4_bmapext(struct vnode *vp, int32_t bn, int64_t *bnp, int *runp, int *runb) struct ext4_extent *ep; struct ext4_extent_path path = { .ep_bp = NULL }; daddr_t lbn; + int ret = 0; ip = VTOI(vp); fs = ip->i_e2fs; @@ -113,15 +114,21 @@ ext4_bmapext(struct vnode *vp, int32_t bn, int64_t *bnp, int *runp, int *runb) ext4_ext_find_extent(fs, ip, lbn, &path); ep = path.ep_ext; if (ep == NULL) - return (EIO); + ret = EIO; + else { + *bnp = fsbtodb(fs, lbn - ep->e_blk + + (ep->e_start_lo | (daddr_t)ep->e_start_hi << 32)); - *bnp = fsbtodb(fs, lbn - ep->e_blk + - (ep->e_start_lo | (daddr_t)ep->e_start_hi << 32)); + if (*bnp == 0) + *bnp = -1; + } - if (*bnp == 0) - *bnp = -1; + if (path.ep_bp != NULL) { + brelse(path.ep_bp); + path.ep_bp = NULL; + } - return (0); + return (ret); } /* diff --git a/sys/fs/procfs/procfs_status.c b/sys/fs/procfs/procfs_status.c index a97e0a9..5a00ee1 100644 --- a/sys/fs/procfs/procfs_status.c +++ b/sys/fs/procfs/procfs_status.c @@ -125,9 +125,9 @@ procfs_doprocstatus(PFS_FILL_ARGS) if (p->p_flag & P_INMEM) { struct timeval start, ut, st; - PROC_SLOCK(p); + PROC_STATLOCK(p); calcru(p, &ut, &st); - PROC_SUNLOCK(p); + PROC_STATUNLOCK(p); start = p->p_stats->p_start; timevaladd(&start, &boottime); sbuf_printf(sb, " %jd,%ld %jd,%ld %jd,%ld", diff --git a/sys/fs/pseudofs/pseudofs.c b/sys/fs/pseudofs/pseudofs.c index d7894af..1824d0b 100644 --- a/sys/fs/pseudofs/pseudofs.c +++ b/sys/fs/pseudofs/pseudofs.c @@ -52,9 +52,11 @@ static MALLOC_DEFINE(M_PFSNODES, "pfs_nodes", "pseudofs nodes"); SYSCTL_NODE(_vfs, OID_AUTO, pfs, CTLFLAG_RW, 0, "pseudofs"); +#ifdef PSEUDOFS_TRACE int pfs_trace; SYSCTL_INT(_vfs_pfs, OID_AUTO, trace, CTLFLAG_RW, &pfs_trace, 0, "enable tracing of pseudofs vnode operations"); +#endif #if PFS_FSNAMELEN != MFSNAMELEN #error "PFS_FSNAMELEN is not equal to MFSNAMELEN" diff --git a/sys/geom/nop/g_nop.c b/sys/geom/nop/g_nop.c index 837f3f4..f36472d 100644 --- a/sys/geom/nop/g_nop.c +++ b/sys/geom/nop/g_nop.c @@ -119,6 +119,24 @@ g_nop_start(struct bio *bp) sc->sc_wrotebytes += bp->bio_length; failprob = sc->sc_wfailprob; break; + case BIO_DELETE: + sc->sc_deletes++; + break; + case BIO_GETATTR: + sc->sc_getattrs++; + break; + case BIO_FLUSH: + sc->sc_flushes++; + break; + case BIO_CMD0: + sc->sc_cmd0s++; + break; + case BIO_CMD1: + sc->sc_cmd1s++; + break; + case BIO_CMD2: + sc->sc_cmd2s++; + break; } mtx_unlock(&sc->sc_lock); if (failprob > 0) { @@ -238,6 +256,12 @@ g_nop_create(struct gctl_req *req, struct g_class *mp, struct g_provider *pp, sc->sc_wfailprob = wfailprob; sc->sc_reads = 0; sc->sc_writes = 0; + sc->sc_deletes = 0; + sc->sc_getattrs = 0; + sc->sc_flushes = 0; + sc->sc_cmd0s = 0; + sc->sc_cmd1s = 0; + sc->sc_cmd2s = 0; sc->sc_readbytes = 0; sc->sc_wrotebytes = 0; mtx_init(&sc->sc_lock, "gnop lock", NULL, MTX_DEF); @@ -602,6 +626,12 @@ g_nop_ctl_reset(struct gctl_req *req, struct g_class *mp) sc = pp->geom->softc; sc->sc_reads = 0; sc->sc_writes = 0; + sc->sc_deletes = 0; + sc->sc_getattrs = 0; + sc->sc_flushes = 0; + sc->sc_cmd0s = 0; + sc->sc_cmd1s = 0; + sc->sc_cmd2s = 0; sc->sc_readbytes = 0; sc->sc_wrotebytes = 0; } @@ -659,6 +689,12 @@ g_nop_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, sbuf_printf(sb, "%s<Error>%d</Error>\n", indent, sc->sc_error); sbuf_printf(sb, "%s<Reads>%ju</Reads>\n", indent, sc->sc_reads); sbuf_printf(sb, "%s<Writes>%ju</Writes>\n", indent, sc->sc_writes); + sbuf_printf(sb, "%s<Deletes>%ju</Deletes>\n", indent, sc->sc_deletes); + sbuf_printf(sb, "%s<Getattrs>%ju</Getattrs>\n", indent, sc->sc_getattrs); + sbuf_printf(sb, "%s<Flushes>%ju</Flushes>\n", indent, sc->sc_flushes); + sbuf_printf(sb, "%s<Cmd0s>%ju</Cmd0s>\n", indent, sc->sc_cmd0s); + sbuf_printf(sb, "%s<Cmd1s>%ju</Cmd1s>\n", indent, sc->sc_cmd1s); + sbuf_printf(sb, "%s<Cmd2s>%ju</Cmd2s>\n", indent, sc->sc_cmd2s); sbuf_printf(sb, "%s<ReadBytes>%ju</ReadBytes>\n", indent, sc->sc_readbytes); sbuf_printf(sb, "%s<WroteBytes>%ju</WroteBytes>\n", indent, diff --git a/sys/geom/nop/g_nop.h b/sys/geom/nop/g_nop.h index b5e954a..beba43e 100644 --- a/sys/geom/nop/g_nop.h +++ b/sys/geom/nop/g_nop.h @@ -65,6 +65,12 @@ struct g_nop_softc { u_int sc_wfailprob; uintmax_t sc_reads; uintmax_t sc_writes; + uintmax_t sc_deletes; + uintmax_t sc_getattrs; + uintmax_t sc_flushes; + uintmax_t sc_cmd0s; + uintmax_t sc_cmd1s; + uintmax_t sc_cmd2s; uintmax_t sc_readbytes; uintmax_t sc_wrotebytes; struct mtx sc_lock; diff --git a/sys/geom/part/g_part_gpt.c b/sys/geom/part/g_part_gpt.c index d7650e9..88a9d12 100644 --- a/sys/geom/part/g_part_gpt.c +++ b/sys/geom/part/g_part_gpt.c @@ -823,22 +823,23 @@ g_part_gpt_probe(struct g_part_table *table, struct g_consumer *cp) return (error); res = le16dec(buf + DOSMAGICOFFSET); pri = G_PART_PROBE_PRI_LOW; - for (index = 0; index < NDOSPART; index++) { - if (buf[DOSPARTOFF + DOSPARTSIZE * index + 4] == 0xee) - pri = G_PART_PROBE_PRI_HIGH; - } - g_free(buf); - if (res != DOSMAGIC) - return (ENXIO); + if (res == DOSMAGIC) { + for (index = 0; index < NDOSPART; index++) { + if (buf[DOSPARTOFF + DOSPARTSIZE * index + 4] == 0xee) + pri = G_PART_PROBE_PRI_HIGH; + } + g_free(buf); - /* Check that there's a primary header. */ - buf = g_read_data(cp, pp->sectorsize, pp->sectorsize, &error); - if (buf == NULL) - return (error); - res = memcmp(buf, GPT_HDR_SIG, 8); - g_free(buf); - if (res == 0) - return (pri); + /* Check that there's a primary header. */ + buf = g_read_data(cp, pp->sectorsize, pp->sectorsize, &error); + if (buf == NULL) + return (error); + res = memcmp(buf, GPT_HDR_SIG, 8); + g_free(buf); + if (res == 0) + return (pri); + } else + g_free(buf); /* No primary? Check that there's a secondary. */ buf = g_read_data(cp, pp->mediasize - pp->sectorsize, pp->sectorsize, diff --git a/sys/i386/i386/elf_machdep.c b/sys/i386/i386/elf_machdep.c index 6acd32a..81d6e35 100644 --- a/sys/i386/i386/elf_machdep.c +++ b/sys/i386/i386/elf_machdep.c @@ -88,6 +88,7 @@ struct sysentvec elf32_freebsd_sysvec = { .sv_shared_page_base = SHAREDPAGE, .sv_shared_page_len = PAGE_SIZE, .sv_schedtail = NULL, + .sv_thread_detach = NULL, }; INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec); diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index b3dae26..36aeca5 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -400,10 +400,6 @@ osendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) } else fp = (struct osigframe *)regs->tf_esp - 1; - /* Translate the signal if appropriate. */ - if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) - sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; - /* Build the argument list for the signal handler. */ sf.sf_signum = sig; sf.sf_scp = (register_t)&fp->sf_siginfo.si_sc; @@ -551,10 +547,6 @@ freebsd4_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) } else sfp = (struct sigframe4 *)regs->tf_esp - 1; - /* Translate the signal if appropriate. */ - if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) - sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; - /* Build the argument list for the signal handler. */ sf.sf_signum = sig; sf.sf_ucontext = (register_t)&sfp->sf_uc; diff --git a/sys/i386/ibcs2/ibcs2_sysvec.c b/sys/i386/ibcs2/ibcs2_sysvec.c index 5d007c7..16507ee 100644 --- a/sys/i386/ibcs2/ibcs2_sysvec.c +++ b/sys/i386/ibcs2/ibcs2_sysvec.c @@ -89,6 +89,7 @@ struct sysentvec ibcs2_svr3_sysvec = { .sv_fetch_syscall_args = cpu_fetch_syscall_args, .sv_syscallnames = NULL, .sv_schedtail = NULL, + .sv_thread_detach = NULL, }; static int diff --git a/sys/i386/linux/linux.h b/sys/i386/linux/linux.h index 27eff32..36b2084 100644 --- a/sys/i386/linux/linux.h +++ b/sys/i386/linux/linux.h @@ -33,6 +33,7 @@ #include <sys/signal.h> /* for sigval union */ +#include <compat/linux/linux.h> #include <i386/linux/linux_syscall.h> /* @@ -40,14 +41,12 @@ */ extern u_char linux_debug_map[]; #define ldebug(name) isclr(linux_debug_map, LINUX_SYS_linux_ ## name) -#define ARGS(nm, fmt) "linux(%ld): "#nm"("fmt")\n", (long)td->td_proc->p_pid -#define LMSG(fmt) "linux(%ld): "fmt"\n", (long)td->td_proc->p_pid +#define ARGS(nm, fmt) "linux(%ld/%ld): "#nm"("fmt")\n", \ + (long)td->td_proc->p_pid, (long)td->td_tid +#define LMSG(fmt) "linux(%ld/%ld): "fmt"\n", \ + (long)td->td_proc->p_pid, (long)td->td_tid #define LINUX_DTRACE linuxulator -#ifdef MALLOC_DECLARE -MALLOC_DECLARE(M_LINUX); -#endif - #define LINUX_SHAREDPAGE (VM_MAXUSER_ADDRESS - PAGE_SIZE) #define LINUX_USRSTACK LINUX_SHAREDPAGE @@ -91,6 +90,7 @@ typedef l_uint l_uid_t; typedef l_ushort l_uid16_t; typedef l_int l_timer_t; typedef l_int l_mqd_t; +typedef l_ulong l_fd_mask; typedef struct { l_int val[2]; @@ -106,7 +106,7 @@ typedef struct { /* * Miscellaneous */ -#define LINUX_AT_COUNT 16 /* Count of used aux entry types. +#define LINUX_AT_COUNT 20 /* Count of used aux entry types. * Keep this synchronized with * elf_linux_fixup() code. */ @@ -235,48 +235,7 @@ struct l_statfs64 { l_int f_spare[6]; }; -/* - * Signalling - */ -#define LINUX_SIGHUP 1 -#define LINUX_SIGINT 2 -#define LINUX_SIGQUIT 3 -#define LINUX_SIGILL 4 -#define LINUX_SIGTRAP 5 -#define LINUX_SIGABRT 6 -#define LINUX_SIGIOT LINUX_SIGABRT -#define LINUX_SIGBUS 7 -#define LINUX_SIGFPE 8 -#define LINUX_SIGKILL 9 -#define LINUX_SIGUSR1 10 -#define LINUX_SIGSEGV 11 -#define LINUX_SIGUSR2 12 -#define LINUX_SIGPIPE 13 -#define LINUX_SIGALRM 14 -#define LINUX_SIGTERM 15 -#define LINUX_SIGSTKFLT 16 -#define LINUX_SIGCHLD 17 -#define LINUX_SIGCONT 18 -#define LINUX_SIGSTOP 19 -#define LINUX_SIGTSTP 20 -#define LINUX_SIGTTIN 21 -#define LINUX_SIGTTOU 22 -#define LINUX_SIGURG 23 -#define LINUX_SIGXCPU 24 -#define LINUX_SIGXFSZ 25 -#define LINUX_SIGVTALRM 26 -#define LINUX_SIGPROF 27 -#define LINUX_SIGWINCH 28 -#define LINUX_SIGIO 29 -#define LINUX_SIGPOLL LINUX_SIGIO -#define LINUX_SIGPWR 30 -#define LINUX_SIGSYS 31 -#define LINUX_SIGRTMIN 32 - -#define LINUX_SIGTBLSZ 31 #define LINUX_NSIG_WORDS 2 -#define LINUX_NBPW 32 -#define LINUX_NSIG (LINUX_NBPW * LINUX_NSIG_WORDS) /* sigaction flags */ #define LINUX_SA_NOCLDSTOP 0x00000001 @@ -294,27 +253,13 @@ struct l_statfs64 { #define LINUX_SIG_UNBLOCK 1 #define LINUX_SIG_SETMASK 2 -/* sigset_t macros */ -#define LINUX_SIGEMPTYSET(set) (set).__bits[0] = (set).__bits[1] = 0 -#define LINUX_SIGISMEMBER(set, sig) SIGISMEMBER(set, sig) -#define LINUX_SIGADDSET(set, sig) SIGADDSET(set, sig) - /* sigaltstack */ #define LINUX_MINSIGSTKSZ 2048 -#define LINUX_SS_ONSTACK 1 -#define LINUX_SS_DISABLE 2 - -int linux_to_bsd_sigaltstack(int lsa); -int bsd_to_linux_sigaltstack(int bsa); typedef void (*l_handler_t)(l_int); typedef l_ulong l_osigset_t; typedef struct { - l_uint __bits[LINUX_NSIG_WORDS]; -} l_sigset_t; - -typedef struct { l_handler_t lsa_handler; l_osigset_t lsa_mask; l_ulong lsa_flags; @@ -497,50 +442,14 @@ struct l_rt_sigframe { }; extern struct sysentvec linux_sysvec; -extern struct sysentvec elf_linux_sysvec; /* - * open/fcntl flags + * arch specific open/fcntl flags */ -#define LINUX_O_RDONLY 00000000 -#define LINUX_O_WRONLY 00000001 -#define LINUX_O_RDWR 00000002 -#define LINUX_O_ACCMODE 00000003 -#define LINUX_O_CREAT 00000100 -#define LINUX_O_EXCL 00000200 -#define LINUX_O_NOCTTY 00000400 -#define LINUX_O_TRUNC 00001000 -#define LINUX_O_APPEND 00002000 -#define LINUX_O_NONBLOCK 00004000 -#define LINUX_O_NDELAY LINUX_O_NONBLOCK -#define LINUX_O_SYNC 00010000 -#define LINUX_FASYNC 00020000 -#define LINUX_O_DIRECT 00040000 /* Direct disk access hint */ -#define LINUX_O_LARGEFILE 00100000 -#define LINUX_O_DIRECTORY 00200000 /* Must be a directory */ -#define LINUX_O_NOFOLLOW 00400000 /* Do not follow links */ -#define LINUX_O_NOATIME 01000000 -#define LINUX_O_CLOEXEC 02000000 - -#define LINUX_F_DUPFD 0 -#define LINUX_F_GETFD 1 -#define LINUX_F_SETFD 2 -#define LINUX_F_GETFL 3 -#define LINUX_F_SETFL 4 -#define LINUX_F_GETLK 5 -#define LINUX_F_SETLK 6 -#define LINUX_F_SETLKW 7 -#define LINUX_F_SETOWN 8 -#define LINUX_F_GETOWN 9 - #define LINUX_F_GETLK64 12 #define LINUX_F_SETLK64 13 #define LINUX_F_SETLKW64 14 -#define LINUX_F_RDLCK 0 -#define LINUX_F_WRLCK 1 -#define LINUX_F_UNLCK 2 - union l_semun { l_int val; struct l_semid_ds *buf; @@ -549,6 +458,16 @@ union l_semun { void *__pad; }; +struct l_ipc_perm { + l_key_t key; + l_uid16_t uid; + l_gid16_t gid; + l_uid16_t cuid; + l_gid16_t cgid; + l_ushort mode; + l_ushort seq; +}; + /* * Socket defines */ @@ -585,22 +504,6 @@ struct l_sockaddr { char sa_data[14]; }; -struct l_msghdr { - l_uintptr_t msg_name; - l_int msg_namelen; - l_uintptr_t msg_iov; - l_size_t msg_iovlen; - l_uintptr_t msg_control; - l_size_t msg_controllen; - l_uint msg_flags; -}; - -struct l_cmsghdr { - l_size_t cmsg_len; - l_int cmsg_level; - l_int cmsg_type; -}; - struct l_ifmap { l_ulong mem_start; l_ulong mem_end; @@ -739,6 +642,8 @@ struct l_desc_struct { #define LINUX_GET_USEABLE(desc) \ (((desc)->b >> LINUX_ENTRY_B_USEABLE) & 1) +#define linux_copyout_rusage(r, u) copyout(r, u, sizeof(*r)) + /* robust futexes */ struct linux_robust_list { struct linux_robust_list *next; diff --git a/sys/i386/linux/linux_dummy.c b/sys/i386/linux/linux_dummy.c index ab77790..8c42f89 100644 --- a/sys/i386/linux/linux_dummy.c +++ b/sys/i386/linux/linux_dummy.c @@ -65,23 +65,18 @@ DUMMY(sysfs); DUMMY(vm86); DUMMY(query_module); DUMMY(nfsservctl); -DUMMY(rt_sigqueueinfo); DUMMY(sendfile); /* different semantics */ DUMMY(setfsuid); DUMMY(setfsgid); DUMMY(pivot_root); DUMMY(mincore); DUMMY(lookup_dcookie); -DUMMY(epoll_create); -DUMMY(epoll_ctl); -DUMMY(epoll_wait); DUMMY(remap_file_pages); DUMMY(fstatfs64); DUMMY(mbind); DUMMY(get_mempolicy); DUMMY(set_mempolicy); DUMMY(kexec_load); -DUMMY(waitid); /* linux 2.6.11: */ DUMMY(add_key); DUMMY(request_key); @@ -94,8 +89,6 @@ DUMMY(inotify_add_watch); DUMMY(inotify_rm_watch); /* linux 2.6.16: */ DUMMY(migrate_pages); -DUMMY(pselect6); -DUMMY(ppoll); DUMMY(unshare); /* linux 2.6.17: */ DUMMY(splice); @@ -106,22 +99,14 @@ DUMMY(vmsplice); DUMMY(move_pages); /* linux 2.6.19: */ DUMMY(getcpu); -DUMMY(epoll_pwait); /* linux 2.6.22: */ -DUMMY(utimensat); DUMMY(signalfd); DUMMY(timerfd_create); -DUMMY(eventfd); -/* linux 2.6.23: */ -DUMMY(fallocate); /* linux 2.6.25: */ DUMMY(timerfd_settime); DUMMY(timerfd_gettime); /* linux 2.6.27: */ DUMMY(signalfd4); -DUMMY(eventfd2); -DUMMY(epoll_create1); -DUMMY(dup3); DUMMY(inotify_init1); /* linux 2.6.30: */ DUMMY(preadv); @@ -130,17 +115,12 @@ DUMMY(pwritev); DUMMY(rt_tsigqueueinfo); DUMMY(perf_event_open); /* linux 2.6.33: */ -DUMMY(recvmmsg); DUMMY(fanotify_init); DUMMY(fanotify_mark); -/* linux 2.6.36: */ -DUMMY(prlimit64); /* later: */ DUMMY(name_to_handle_at); DUMMY(open_by_handle_at); DUMMY(clock_adjtime); -DUMMY(syncfs); -DUMMY(sendmmsg); DUMMY(setns); DUMMY(process_vm_readv); DUMMY(process_vm_writev); diff --git a/sys/i386/linux/linux_genassym.c b/sys/i386/linux/linux_genassym.c index 1e84572..9735110 100644 --- a/sys/i386/linux/linux_genassym.c +++ b/sys/i386/linux/linux_genassym.c @@ -6,6 +6,7 @@ __FBSDID("$FreeBSD$"); #include <sys/systm.h> #include <i386/linux/linux.h> +#include <compat/linux/linux_mib.h> ASSYM(LINUX_SIGF_HANDLER, offsetof(struct l_sigframe, sf_handler)); ASSYM(LINUX_SIGF_SC, offsetof(struct l_sigframe, sf_sc)); @@ -14,3 +15,5 @@ ASSYM(LINUX_SC_EFLAGS, offsetof(struct l_sigcontext, sc_eflags)); ASSYM(LINUX_RT_SIGF_HANDLER, offsetof(struct l_rt_sigframe, sf_handler)); ASSYM(LINUX_RT_SIGF_UC, offsetof(struct l_rt_sigframe, sf_sc)); ASSYM(LINUX_RT_SIGF_SC, offsetof(struct l_ucontext, uc_mcontext)); +ASSYM(LINUX_SC_ESP, offsetof(struct l_sigcontext, sc_esp)); +ASSYM(LINUX_VERSION_CODE, LINUX_VERSION_CODE); diff --git a/sys/i386/linux/linux_locore.s b/sys/i386/linux/linux_locore.s index a3e0e7dc..6c4d19c 100644 --- a/sys/i386/linux/linux_locore.s +++ b/sys/i386/linux/linux_locore.s @@ -5,33 +5,145 @@ #include <i386/linux/linux_syscall.h> /* system call numbers */ +#include "assym.s" + +/* + * To avoid excess stack frame the signal trampoline code emulates + * the 'call' instruction. + */ NON_GPROF_ENTRY(linux_sigcode) - call *LINUX_SIGF_HANDLER(%esp) - leal LINUX_SIGF_SC(%esp),%ebx /* linux scp */ - mov LINUX_SC_GS(%ebx),%gs - movl %esp, %ebx /* pass sigframe */ - push %eax /* fake ret addr */ + movl %esp, %ebx /* preserve sigframe */ + call .getip0 +.getip0: + popl %eax + add $.startsigcode-.getip0, %eax /* ret address */ + push %eax + jmp *LINUX_SIGF_HANDLER(%ebx) +.startsigcode: + popl %eax /* gcc unwind code need this */ movl $LINUX_SYS_linux_sigreturn,%eax /* linux_sigreturn() */ int $0x80 /* enter kernel with args */ +.endsigcode: 0: jmp 0b - ALIGN_TEXT -/* XXXXX */ -linux_rt_sigcode: - call *LINUX_RT_SIGF_HANDLER(%esp) + +NON_GPROF_ENTRY(linux_rt_sigcode) leal LINUX_RT_SIGF_UC(%esp),%ebx /* linux ucp */ leal LINUX_RT_SIGF_SC(%ebx),%ecx /* linux sigcontext */ - mov LINUX_SC_GS(%ecx),%gs - push %eax /* fake ret addr */ + movl %esp, %edi + call .getip1 +.getip1: + popl %eax + add $.startrtsigcode-.getip1, %eax /* ret address */ + push %eax + jmp *LINUX_RT_SIGF_HANDLER(%edi) +.startrtsigcode: movl $LINUX_SYS_linux_rt_sigreturn,%eax /* linux_rt_sigreturn() */ int $0x80 /* enter kernel with args */ +.endrtsigcode: 0: jmp 0b - ALIGN_TEXT -/* XXXXX */ -linux_esigcode: - - .data - .globl linux_szsigcode, linux_sznonrtsigcode -linux_szsigcode: - .long linux_esigcode-linux_sigcode -linux_sznonrtsigcode: - .long linux_rt_sigcode-linux_sigcode + +NON_GPROF_ENTRY(linux_vsyscall) +.startvsyscall: + int $0x80 + ret +.endvsyscall: + +#if 0 + .section .note.Linux, "a",@note + .long 2f - 1f /* namesz */ + .balign 4 + .long 4f - 3f /* descsz */ + .long 0 +1: + .asciz "Linux" +2: + .balign 4 +3: + .long LINUX_VERSION_CODE +4: + .balign 4 + .previous +#endif + +#define do_cfa_expr(offset) \ + .byte 0x0f; /* DW_CFA_def_cfa_expression */ \ + .uleb128 11f-10f; /* length */ \ +10: .byte 0x74; /* DW_OP_breg4 */ \ + .sleb128 offset; /* offset */ \ + .byte 0x06; /* DW_OP_deref */ \ +11: + + + /* CIE */ + .section .eh_frame,"a",@progbits +.LSTARTFRAMEDLSI1: + .long .LENDCIEDLSI1-.LSTARTCIEDLSI1 +.LSTARTCIEDLSI1: + .long 0 /* CIE ID */ + .byte 1 /* Version number */ + .string "zRS" /* NULL-terminated + * augmentation string + */ + .uleb128 1 /* Code alignment factor */ + .sleb128 -4 /* Data alignment factor */ + .byte 8 /* Return address + * register column + */ + .uleb128 1 /* Augmentation value length */ + .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */ + .byte 0 /* DW_CFA_nop */ + .align 4 +.LENDCIEDLSI1: + + /* FDE */ + .long .LENDFDEDLSI1-.LSTARTFDEDLSI1 /* Length FDE */ +.LSTARTFDEDLSI1: + .long .LSTARTFDEDLSI1-.LSTARTFRAMEDLSI1 /* CIE pointer */ + .long .startsigcode-. /* PC-relative start address */ + .long .endsigcode-.startsigcode + .uleb128 0 /* Augmentation */ + do_cfa_expr(LINUX_SIGF_SC-8) + .align 4 +.LENDFDEDLSI1: + + .long .LENDFDEDLSI2-.LSTARTFDEDLSI2 /* Length FDE */ +.LSTARTFDEDLSI2: + .long .LSTARTFDEDLSI2-.LSTARTFRAMEDLSI1 /* CIE pointer */ + .long .startrtsigcode-. /* PC-relative start address */ + .long .endrtsigcode-.startrtsigcode + .uleb128 0 /* Augmentation */ + do_cfa_expr(LINUX_RT_SIGF_SC-4+LINUX_SC_ESP) + .align 4 +.LENDFDEDLSI2: + .previous + + .section .eh_frame,"a",@progbits +.LSTARTFRAMEDLSI2: + .long .LENDCIEDLSI2-.LSTARTCIEDLSI2 +.LSTARTCIEDLSI2: + .long 0 /* CIE ID */ + .byte 1 /* Version number */ + .string "zR" /* NULL-terminated + * augmentation string + */ + .uleb128 1 /* Code alignment factor */ + .sleb128 -4 /* Data alignment factor */ + .byte 8 /* Return address register column */ + .uleb128 1 /* Augmentation value length */ + .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */ + .byte 0x0c /* DW_CFA_def_cfa */ + .uleb128 4 + .uleb128 4 + .byte 0x88 /* DW_CFA_offset, column 0x8 */ + .uleb128 1 + .align 4 +.LENDCIEDLSI2: + .long .LENDFDEDLSI3-.LSTARTFDEDLSI3 /* Length FDE */ +.LSTARTFDEDLSI3: + .long .LSTARTFDEDLSI3-.LSTARTFRAMEDLSI2 /* CIE pointer */ + .long .startvsyscall-. /* PC-relative start address */ + .long .endvsyscall-.startvsyscall + .uleb128 0 + .align 4 +.LENDFDEDLSI3: + .previous diff --git a/sys/i386/linux/linux_machdep.c b/sys/i386/linux/linux_machdep.c index effc32a..c9f969b 100644 --- a/sys/i386/linux/linux_machdep.c +++ b/sys/i386/linux/linux_machdep.c @@ -99,35 +99,11 @@ static int linux_mmap_common(struct thread *td, l_uintptr_t addr, l_size_t len, l_int prot, l_int flags, l_int fd, l_loff_t pos); -int -linux_to_bsd_sigaltstack(int lsa) -{ - int bsa = 0; - - if (lsa & LINUX_SS_DISABLE) - bsa |= SS_DISABLE; - if (lsa & LINUX_SS_ONSTACK) - bsa |= SS_ONSTACK; - return (bsa); -} - -int -bsd_to_linux_sigaltstack(int bsa) -{ - int lsa = 0; - - if (bsa & SS_DISABLE) - lsa |= LINUX_SS_DISABLE; - if (bsa & SS_ONSTACK) - lsa |= LINUX_SS_ONSTACK; - return (lsa); -} int linux_execve(struct thread *td, struct linux_execve_args *args) { struct image_args eargs; - struct vmspace *oldvmspace; char *newpath; int error; @@ -138,26 +114,11 @@ linux_execve(struct thread *td, struct linux_execve_args *args) printf(ARGS(execve, "%s"), newpath); #endif - error = pre_execve(td, &oldvmspace); - if (error != 0) { - free(newpath, M_TEMP); - return (error); - } error = exec_copyin_args(&eargs, newpath, UIO_SYSSPACE, args->argp, args->envp); free(newpath, M_TEMP); if (error == 0) - error = kern_execve(td, &eargs, NULL); - if (error == 0) { - /* linux process can exec fbsd one, dont attempt - * to create emuldata for such process using - * linux_proc_init, this leads to a panic on KASSERT - * because such process has p->p_emuldata == NULL - */ - if (SV_PROC_ABI(td->td_proc) == SV_ABI_LINUX) - error = linux_proc_init(td, 0, 0); - } - post_execve(td, error, oldvmspace); + error = linux_common_execve(td, &eargs); return (error); } @@ -368,8 +329,14 @@ int linux_set_upcall_kse(struct thread *td, register_t stack) { - td->td_frame->tf_esp = stack; + if (stack) + td->td_frame->tf_esp = stack; + /* + * The newly created Linux thread returns + * to the user space by the same path that a parent do. + */ + td->td_frame->tf_eax = 0; return (0); } @@ -710,7 +677,7 @@ linux_sigaction(struct thread *td, struct linux_sigaction_args *args) act.lsa_flags = osa.lsa_flags; act.lsa_restorer = osa.lsa_restorer; LINUX_SIGEMPTYSET(act.lsa_mask); - act.lsa_mask.__bits[0] = osa.lsa_mask; + act.lsa_mask.__mask = osa.lsa_mask; } error = linux_do_sigaction(td, args->sig, args->nsa ? &act : NULL, @@ -720,7 +687,7 @@ linux_sigaction(struct thread *td, struct linux_sigaction_args *args) osa.lsa_handler = oact.lsa_handler; osa.lsa_flags = oact.lsa_flags; osa.lsa_restorer = oact.lsa_restorer; - osa.lsa_mask = oact.lsa_mask.__bits[0]; + osa.lsa_mask = oact.lsa_mask.__mask; error = copyout(&osa, args->osa, sizeof(l_osigaction_t)); } @@ -744,7 +711,7 @@ linux_sigsuspend(struct thread *td, struct linux_sigsuspend_args *args) #endif LINUX_SIGEMPTYSET(mask); - mask.__bits[0] = args->mask; + mask.__mask = args->mask; linux_to_bsd_sigset(&mask, &sigmask); return (kern_sigsuspend(td, sigmask)); } @@ -1048,34 +1015,3 @@ linux_mq_getsetattr(struct thread *td, struct linux_mq_getsetattr_args *args) return (ENOSYS); #endif } - -int -linux_wait4(struct thread *td, struct linux_wait4_args *args) -{ - int error, options; - struct rusage ru, *rup; - -#ifdef DEBUG - if (ldebug(wait4)) - printf(ARGS(wait4, "%d, %p, %d, %p"), - args->pid, (void *)args->status, args->options, - (void *)args->rusage); -#endif - - options = (args->options & (WNOHANG | WUNTRACED)); - /* WLINUXCLONE should be equal to __WCLONE, but we make sure */ - if (args->options & __WCLONE) - options |= WLINUXCLONE; - - if (args->rusage != NULL) - rup = &ru; - else - rup = NULL; - error = linux_common_wait(td, args->pid, args->status, options, rup); - if (error) - return (error); - if (args->rusage != NULL) - error = copyout(&ru, args->rusage, sizeof(ru)); - - return (error); -} diff --git a/sys/i386/linux/linux_proto.h b/sys/i386/linux/linux_proto.h index 862cd2d..62dc2ae 100644 --- a/sys/i386/linux/linux_proto.h +++ b/sys/i386/linux/linux_proto.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: stable/10/sys/i386/linux/syscalls.master 276810 2015-01-08 06:23:11Z dchagin + * created from FreeBSD: stable/10/sys/i386/linux/syscalls.master 293592 2016-01-09 17:54:37Z dchagin */ #ifndef _LINUX_SYSPROTO_H_ @@ -35,6 +35,9 @@ struct thread; #endif #define nosys linux_nosys +struct linux_exit_args { + char rval_l_[PADL_(int)]; int rval; char rval_r_[PADR_(int)]; +}; struct linux_fork_args { register_t dummy; }; @@ -357,7 +360,7 @@ struct linux_wait4_args { char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)]; char status_l_[PADL_(l_int *)]; l_int * status; char status_r_[PADR_(l_int *)]; char options_l_[PADL_(l_int)]; l_int options; char options_r_[PADR_(l_int)]; - char rusage_l_[PADL_(struct l_rusage *)]; struct l_rusage * rusage; char rusage_r_[PADR_(struct l_rusage *)]; + char rusage_l_[PADL_(void *)]; void * rusage; char rusage_r_[PADR_(void *)]; }; struct linux_swapoff_args { register_t dummy; @@ -473,6 +476,14 @@ struct linux_fdatasync_args { struct linux_sysctl_args { char args_l_[PADL_(struct l___sysctl_args *)]; struct l___sysctl_args * args; char args_r_[PADR_(struct l___sysctl_args *)]; }; +struct linux_sched_setparam_args { + char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)]; + char param_l_[PADL_(struct l_sched_param *)]; struct l_sched_param * param; char param_r_[PADR_(struct l_sched_param *)]; +}; +struct linux_sched_getparam_args { + char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)]; + char param_l_[PADL_(struct l_sched_param *)]; struct l_sched_param * param; char param_r_[PADR_(struct l_sched_param *)]; +}; struct linux_sched_setscheduler_args { char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)]; char policy_l_[PADL_(l_int)]; l_int policy; char policy_r_[PADR_(l_int)]; @@ -487,6 +498,10 @@ struct linux_sched_get_priority_max_args { struct linux_sched_get_priority_min_args { char policy_l_[PADL_(l_int)]; l_int policy; char policy_r_[PADR_(l_int)]; }; +struct linux_sched_rr_get_interval_args { + char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)]; + char interval_l_[PADL_(struct l_timespec *)]; struct l_timespec * interval; char interval_r_[PADR_(struct l_timespec *)]; +}; struct linux_nanosleep_args { char rqtp_l_[PADL_(const struct l_timespec *)]; const struct l_timespec * rqtp; char rqtp_r_[PADR_(const struct l_timespec *)]; char rmtp_l_[PADL_(struct l_timespec *)]; struct l_timespec * rmtp; char rmtp_r_[PADR_(struct l_timespec *)]; @@ -560,7 +575,9 @@ struct linux_rt_sigtimedwait_args { char sigsetsize_l_[PADL_(l_size_t)]; l_size_t sigsetsize; char sigsetsize_r_[PADR_(l_size_t)]; }; struct linux_rt_sigqueueinfo_args { - register_t dummy; + char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)]; + char sig_l_[PADL_(l_int)]; l_int sig; char sig_r_[PADR_(l_int)]; + char info_l_[PADL_(l_siginfo_t *)]; l_siginfo_t * info; char info_r_[PADR_(l_siginfo_t *)]; }; struct linux_rt_sigsuspend_args { char newset_l_[PADL_(l_sigset_t *)]; l_sigset_t * newset; char newset_r_[PADR_(l_sigset_t *)]; @@ -766,13 +783,19 @@ struct linux_lookup_dcookie_args { register_t dummy; }; struct linux_epoll_create_args { - register_t dummy; + char size_l_[PADL_(l_int)]; l_int size; char size_r_[PADR_(l_int)]; }; struct linux_epoll_ctl_args { - register_t dummy; + char epfd_l_[PADL_(l_int)]; l_int epfd; char epfd_r_[PADR_(l_int)]; + char op_l_[PADL_(l_int)]; l_int op; char op_r_[PADR_(l_int)]; + char fd_l_[PADL_(l_int)]; l_int fd; char fd_r_[PADR_(l_int)]; + char event_l_[PADL_(struct epoll_event *)]; struct epoll_event * event; char event_r_[PADR_(struct epoll_event *)]; }; struct linux_epoll_wait_args { - register_t dummy; + char epfd_l_[PADL_(l_int)]; l_int epfd; char epfd_r_[PADR_(l_int)]; + char events_l_[PADL_(struct epoll_event *)]; struct epoll_event * events; char events_r_[PADR_(struct epoll_event *)]; + char maxevents_l_[PADL_(l_int)]; l_int maxevents; char maxevents_r_[PADR_(l_int)]; + char timeout_l_[PADL_(l_int)]; l_int timeout; char timeout_r_[PADR_(l_int)]; }; struct linux_remap_file_pages_args { register_t dummy; @@ -887,7 +910,11 @@ struct linux_kexec_load_args { register_t dummy; }; struct linux_waitid_args { - register_t dummy; + char idtype_l_[PADL_(int)]; int idtype; char idtype_r_[PADR_(int)]; + char id_l_[PADL_(l_pid_t)]; l_pid_t id; char id_r_[PADR_(l_pid_t)]; + char info_l_[PADL_(l_siginfo_t *)]; l_siginfo_t * info; char info_r_[PADR_(l_siginfo_t *)]; + char options_l_[PADL_(int)]; int options; char options_r_[PADR_(int)]; + char rusage_l_[PADL_(void *)]; void * rusage; char rusage_r_[PADR_(void *)]; }; struct linux_add_key_args { register_t dummy; @@ -989,13 +1016,21 @@ struct linux_faccessat_args { char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)]; char filename_l_[PADL_(const char *)]; const char * filename; char filename_r_[PADR_(const char *)]; char amode_l_[PADL_(l_int)]; l_int amode; char amode_r_[PADR_(l_int)]; - char flag_l_[PADL_(l_int)]; l_int flag; char flag_r_[PADR_(l_int)]; }; struct linux_pselect6_args { - register_t dummy; + char nfds_l_[PADL_(l_int)]; l_int nfds; char nfds_r_[PADR_(l_int)]; + char readfds_l_[PADL_(l_fd_set *)]; l_fd_set * readfds; char readfds_r_[PADR_(l_fd_set *)]; + char writefds_l_[PADL_(l_fd_set *)]; l_fd_set * writefds; char writefds_r_[PADR_(l_fd_set *)]; + char exceptfds_l_[PADL_(l_fd_set *)]; l_fd_set * exceptfds; char exceptfds_r_[PADR_(l_fd_set *)]; + char tsp_l_[PADL_(struct l_timespec *)]; struct l_timespec * tsp; char tsp_r_[PADR_(struct l_timespec *)]; + char sig_l_[PADL_(l_uintptr_t *)]; l_uintptr_t * sig; char sig_r_[PADR_(l_uintptr_t *)]; }; struct linux_ppoll_args { - register_t dummy; + char fds_l_[PADL_(struct pollfd *)]; struct pollfd * fds; char fds_r_[PADR_(struct pollfd *)]; + char nfds_l_[PADL_(uint32_t)]; uint32_t nfds; char nfds_r_[PADR_(uint32_t)]; + char tsp_l_[PADL_(struct l_timespec *)]; struct l_timespec * tsp; char tsp_r_[PADR_(struct l_timespec *)]; + char sset_l_[PADL_(l_sigset_t *)]; l_sigset_t * sset; char sset_r_[PADR_(l_sigset_t *)]; + char ssize_l_[PADL_(l_size_t)]; l_size_t ssize; char ssize_r_[PADR_(l_size_t)]; }; struct linux_unshare_args { register_t dummy; @@ -1028,10 +1063,17 @@ struct linux_getcpu_args { register_t dummy; }; struct linux_epoll_pwait_args { - register_t dummy; + char epfd_l_[PADL_(l_int)]; l_int epfd; char epfd_r_[PADR_(l_int)]; + char events_l_[PADL_(struct epoll_event *)]; struct epoll_event * events; char events_r_[PADR_(struct epoll_event *)]; + char maxevents_l_[PADL_(l_int)]; l_int maxevents; char maxevents_r_[PADR_(l_int)]; + char timeout_l_[PADL_(l_int)]; l_int timeout; char timeout_r_[PADR_(l_int)]; + char mask_l_[PADL_(l_sigset_t *)]; l_sigset_t * mask; char mask_r_[PADR_(l_sigset_t *)]; }; struct linux_utimensat_args { - register_t dummy; + char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)]; + char pathname_l_[PADL_(const char *)]; const char * pathname; char pathname_r_[PADR_(const char *)]; + char times_l_[PADL_(const struct l_timespec *)]; const struct l_timespec * times; char times_r_[PADR_(const struct l_timespec *)]; + char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)]; }; struct linux_signalfd_args { register_t dummy; @@ -1040,10 +1082,13 @@ struct linux_timerfd_create_args { register_t dummy; }; struct linux_eventfd_args { - register_t dummy; + char initval_l_[PADL_(l_uint)]; l_uint initval; char initval_r_[PADR_(l_uint)]; }; struct linux_fallocate_args { - register_t dummy; + char fd_l_[PADL_(l_int)]; l_int fd; char fd_r_[PADR_(l_int)]; + char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)]; + char offset_l_[PADL_(l_loff_t)]; l_loff_t offset; char offset_r_[PADR_(l_loff_t)]; + char len_l_[PADL_(l_loff_t)]; l_loff_t len; char len_r_[PADR_(l_loff_t)]; }; struct linux_timerfd_settime_args { register_t dummy; @@ -1055,13 +1100,16 @@ struct linux_signalfd4_args { register_t dummy; }; struct linux_eventfd2_args { - register_t dummy; + char initval_l_[PADL_(l_uint)]; l_uint initval; char initval_r_[PADR_(l_uint)]; + char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)]; }; struct linux_epoll_create1_args { - register_t dummy; + char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)]; }; struct linux_dup3_args { - register_t dummy; + char oldfd_l_[PADL_(l_int)]; l_int oldfd; char oldfd_r_[PADR_(l_int)]; + char newfd_l_[PADL_(l_int)]; l_int newfd; char newfd_r_[PADR_(l_int)]; + char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)]; }; struct linux_pipe2_args { char pipefds_l_[PADL_(l_int *)]; l_int * pipefds; char pipefds_r_[PADR_(l_int *)]; @@ -1083,7 +1131,11 @@ struct linux_perf_event_open_args { register_t dummy; }; struct linux_recvmmsg_args { - register_t dummy; + char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)]; + char msg_l_[PADL_(struct l_mmsghdr *)]; struct l_mmsghdr * msg; char msg_r_[PADR_(struct l_mmsghdr *)]; + char vlen_l_[PADL_(l_uint)]; l_uint vlen; char vlen_r_[PADR_(l_uint)]; + char flags_l_[PADL_(l_uint)]; l_uint flags; char flags_r_[PADR_(l_uint)]; + char timeout_l_[PADL_(struct l_timespec *)]; struct l_timespec * timeout; char timeout_r_[PADR_(struct l_timespec *)]; }; struct linux_fanotify_init_args { register_t dummy; @@ -1092,7 +1144,10 @@ struct linux_fanotify_mark_args { register_t dummy; }; struct linux_prlimit64_args { - register_t dummy; + char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)]; + char resource_l_[PADL_(l_uint)]; l_uint resource; char resource_r_[PADR_(l_uint)]; + char new_l_[PADL_(struct rlimit *)]; struct rlimit * new; char new_r_[PADR_(struct rlimit *)]; + char old_l_[PADL_(struct rlimit *)]; struct rlimit * old; char old_r_[PADR_(struct rlimit *)]; }; struct linux_name_to_handle_at_args { register_t dummy; @@ -1104,10 +1159,13 @@ struct linux_clock_adjtime_args { register_t dummy; }; struct linux_syncfs_args { - register_t dummy; + char fd_l_[PADL_(l_int)]; l_int fd; char fd_r_[PADR_(l_int)]; }; struct linux_sendmmsg_args { - register_t dummy; + char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)]; + char msg_l_[PADL_(struct l_mmsghdr *)]; struct l_mmsghdr * msg; char msg_r_[PADR_(struct l_mmsghdr *)]; + char vlen_l_[PADL_(l_uint)]; l_uint vlen; char vlen_r_[PADR_(l_uint)]; + char flags_l_[PADL_(l_uint)]; l_uint flags; char flags_r_[PADR_(l_uint)]; }; struct linux_setns_args { register_t dummy; @@ -1119,6 +1177,7 @@ struct linux_process_vm_writev_args { register_t dummy; }; #define nosys linux_nosys +int linux_exit(struct thread *, struct linux_exit_args *); int linux_fork(struct thread *, struct linux_fork_args *); int linux_open(struct thread *, struct linux_open_args *); int linux_waitpid(struct thread *, struct linux_waitpid_args *); @@ -1230,10 +1289,13 @@ int linux_msync(struct thread *, struct linux_msync_args *); int linux_getsid(struct thread *, struct linux_getsid_args *); int linux_fdatasync(struct thread *, struct linux_fdatasync_args *); int linux_sysctl(struct thread *, struct linux_sysctl_args *); +int linux_sched_setparam(struct thread *, struct linux_sched_setparam_args *); +int linux_sched_getparam(struct thread *, struct linux_sched_getparam_args *); int linux_sched_setscheduler(struct thread *, struct linux_sched_setscheduler_args *); int linux_sched_getscheduler(struct thread *, struct linux_sched_getscheduler_args *); int linux_sched_get_priority_max(struct thread *, struct linux_sched_get_priority_max_args *); int linux_sched_get_priority_min(struct thread *, struct linux_sched_get_priority_min_args *); +int linux_sched_rr_get_interval(struct thread *, struct linux_sched_rr_get_interval_args *); int linux_nanosleep(struct thread *, struct linux_nanosleep_args *); int linux_mremap(struct thread *, struct linux_mremap_args *); int linux_setresuid16(struct thread *, struct linux_setresuid16_args *); @@ -1422,6 +1484,7 @@ int linux_process_vm_writev(struct thread *, struct linux_process_vm_writev_args #endif /* COMPAT_FREEBSD7 */ +#define LINUX_SYS_AUE_linux_exit AUE_EXIT #define LINUX_SYS_AUE_linux_fork AUE_FORK #define LINUX_SYS_AUE_linux_open AUE_OPEN_RWTC #define LINUX_SYS_AUE_linux_waitpid AUE_WAIT4 @@ -1533,10 +1596,13 @@ int linux_process_vm_writev(struct thread *, struct linux_process_vm_writev_args #define LINUX_SYS_AUE_linux_getsid AUE_GETSID #define LINUX_SYS_AUE_linux_fdatasync AUE_NULL #define LINUX_SYS_AUE_linux_sysctl AUE_SYSCTL +#define LINUX_SYS_AUE_linux_sched_setparam AUE_SCHED_SETPARAM +#define LINUX_SYS_AUE_linux_sched_getparam AUE_SCHED_GETPARAM #define LINUX_SYS_AUE_linux_sched_setscheduler AUE_SCHED_SETSCHEDULER #define LINUX_SYS_AUE_linux_sched_getscheduler AUE_SCHED_GETSCHEDULER #define LINUX_SYS_AUE_linux_sched_get_priority_max AUE_SCHED_GET_PRIORITY_MAX #define LINUX_SYS_AUE_linux_sched_get_priority_min AUE_SCHED_GET_PRIORITY_MIN +#define LINUX_SYS_AUE_linux_sched_rr_get_interval AUE_SCHED_RR_GET_INTERVAL #define LINUX_SYS_AUE_linux_nanosleep AUE_NULL #define LINUX_SYS_AUE_linux_mremap AUE_NULL #define LINUX_SYS_AUE_linux_setresuid16 AUE_SETRESUID @@ -1633,7 +1699,7 @@ int linux_process_vm_writev(struct thread *, struct linux_process_vm_writev_args #define LINUX_SYS_AUE_linux_mq_notify AUE_NULL #define LINUX_SYS_AUE_linux_mq_getsetattr AUE_NULL #define LINUX_SYS_AUE_linux_kexec_load AUE_NULL -#define LINUX_SYS_AUE_linux_waitid AUE_NULL +#define LINUX_SYS_AUE_linux_waitid AUE_WAIT6 #define LINUX_SYS_AUE_linux_add_key AUE_NULL #define LINUX_SYS_AUE_linux_request_key AUE_NULL #define LINUX_SYS_AUE_linux_keyctl AUE_NULL @@ -1656,8 +1722,8 @@ int linux_process_vm_writev(struct thread *, struct linux_process_vm_writev_args #define LINUX_SYS_AUE_linux_readlinkat AUE_READLINKAT #define LINUX_SYS_AUE_linux_fchmodat AUE_FCHMODAT #define LINUX_SYS_AUE_linux_faccessat AUE_FACCESSAT -#define LINUX_SYS_AUE_linux_pselect6 AUE_NULL -#define LINUX_SYS_AUE_linux_ppoll AUE_NULL +#define LINUX_SYS_AUE_linux_pselect6 AUE_SELECT +#define LINUX_SYS_AUE_linux_ppoll AUE_POLL #define LINUX_SYS_AUE_linux_unshare AUE_NULL #define LINUX_SYS_AUE_linux_set_robust_list AUE_NULL #define LINUX_SYS_AUE_linux_get_robust_list AUE_NULL @@ -1668,7 +1734,7 @@ int linux_process_vm_writev(struct thread *, struct linux_process_vm_writev_args #define LINUX_SYS_AUE_linux_move_pages AUE_NULL #define LINUX_SYS_AUE_linux_getcpu AUE_NULL #define LINUX_SYS_AUE_linux_epoll_pwait AUE_NULL -#define LINUX_SYS_AUE_linux_utimensat AUE_NULL +#define LINUX_SYS_AUE_linux_utimensat AUE_FUTIMESAT #define LINUX_SYS_AUE_linux_signalfd AUE_NULL #define LINUX_SYS_AUE_linux_timerfd_create AUE_NULL #define LINUX_SYS_AUE_linux_eventfd AUE_NULL @@ -1692,7 +1758,7 @@ int linux_process_vm_writev(struct thread *, struct linux_process_vm_writev_args #define LINUX_SYS_AUE_linux_name_to_handle_at AUE_NULL #define LINUX_SYS_AUE_linux_open_by_handle_at AUE_NULL #define LINUX_SYS_AUE_linux_clock_adjtime AUE_NULL -#define LINUX_SYS_AUE_linux_syncfs AUE_NULL +#define LINUX_SYS_AUE_linux_syncfs AUE_SYNC #define LINUX_SYS_AUE_linux_sendmmsg AUE_NULL #define LINUX_SYS_AUE_linux_setns AUE_NULL #define LINUX_SYS_AUE_linux_process_vm_readv AUE_NULL diff --git a/sys/i386/linux/linux_ptrace.c b/sys/i386/linux/linux_ptrace.c index 46a1169..2925e6b 100644 --- a/sys/i386/linux/linux_ptrace.c +++ b/sys/i386/linux/linux_ptrace.c @@ -91,8 +91,7 @@ static __inline int map_signum(int signum) { - if (signum > 0 && signum <= LINUX_SIGTBLSZ) - signum = linux_to_bsd_signal[_SIG_IDX(signum)]; + signum = linux_to_bsd_signal(signum); return ((signum == SIGSTOP)? 0 : signum); } diff --git a/sys/i386/linux/linux_syscall.h b/sys/i386/linux/linux_syscall.h index b7f9d76..170c1cc 100644 --- a/sys/i386/linux/linux_syscall.h +++ b/sys/i386/linux/linux_syscall.h @@ -3,10 +3,10 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: stable/10/sys/i386/linux/syscalls.master 276810 2015-01-08 06:23:11Z dchagin + * created from FreeBSD: stable/10/sys/i386/linux/syscalls.master 293592 2016-01-09 17:54:37Z dchagin */ -#define LINUX_SYS_exit 1 +#define LINUX_SYS_linux_exit 1 #define LINUX_SYS_linux_fork 2 #define LINUX_SYS_read 3 #define LINUX_SYS_write 4 @@ -148,14 +148,14 @@ #define LINUX_SYS_munlock 151 #define LINUX_SYS_mlockall 152 #define LINUX_SYS_munlockall 153 -#define LINUX_SYS_sched_setparam 154 -#define LINUX_SYS_sched_getparam 155 +#define LINUX_SYS_linux_sched_setparam 154 +#define LINUX_SYS_linux_sched_getparam 155 #define LINUX_SYS_linux_sched_setscheduler 156 #define LINUX_SYS_linux_sched_getscheduler 157 #define LINUX_SYS_sched_yield 158 #define LINUX_SYS_linux_sched_get_priority_max 159 #define LINUX_SYS_linux_sched_get_priority_min 160 -#define LINUX_SYS_sched_rr_get_interval 161 +#define LINUX_SYS_linux_sched_rr_get_interval 161 #define LINUX_SYS_linux_nanosleep 162 #define LINUX_SYS_linux_mremap 163 #define LINUX_SYS_linux_setresuid16 164 @@ -328,4 +328,4 @@ #define LINUX_SYS_linux_setns 346 #define LINUX_SYS_linux_process_vm_readv 347 #define LINUX_SYS_linux_process_vm_writev 348 -#define LINUX_SYS_MAXSYSCALL 349 +#define LINUX_SYS_MAXSYSCALL 350 diff --git a/sys/i386/linux/linux_syscalls.c b/sys/i386/linux/linux_syscalls.c index 725abf0..20b4032 100644 --- a/sys/i386/linux/linux_syscalls.c +++ b/sys/i386/linux/linux_syscalls.c @@ -3,13 +3,13 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: stable/10/sys/i386/linux/syscalls.master 276810 2015-01-08 06:23:11Z dchagin + * created from FreeBSD: stable/10/sys/i386/linux/syscalls.master 293592 2016-01-09 17:54:37Z dchagin */ const char *linux_syscallnames[] = { #define nosys linux_nosys "#0", /* 0 = setup */ - "exit", /* 1 = exit */ + "linux_exit", /* 1 = linux_exit */ "linux_fork", /* 2 = linux_fork */ "read", /* 3 = read */ "write", /* 4 = write */ @@ -162,14 +162,14 @@ const char *linux_syscallnames[] = { "munlock", /* 151 = munlock */ "mlockall", /* 152 = mlockall */ "munlockall", /* 153 = munlockall */ - "sched_setparam", /* 154 = sched_setparam */ - "sched_getparam", /* 155 = sched_getparam */ + "linux_sched_setparam", /* 154 = linux_sched_setparam */ + "linux_sched_getparam", /* 155 = linux_sched_getparam */ "linux_sched_setscheduler", /* 156 = linux_sched_setscheduler */ "linux_sched_getscheduler", /* 157 = linux_sched_getscheduler */ "sched_yield", /* 158 = sched_yield */ "linux_sched_get_priority_max", /* 159 = linux_sched_get_priority_max */ "linux_sched_get_priority_min", /* 160 = linux_sched_get_priority_min */ - "sched_rr_get_interval", /* 161 = sched_rr_get_interval */ + "linux_sched_rr_get_interval", /* 161 = linux_sched_rr_get_interval */ "linux_nanosleep", /* 162 = linux_nanosleep */ "linux_mremap", /* 163 = linux_mremap */ "linux_setresuid16", /* 164 = linux_setresuid16 */ @@ -357,4 +357,5 @@ const char *linux_syscallnames[] = { "linux_setns", /* 346 = linux_setns */ "linux_process_vm_readv", /* 347 = linux_process_vm_readv */ "linux_process_vm_writev", /* 348 = linux_process_vm_writev */ + "#349", /* 349 = nosys */ }; diff --git a/sys/i386/linux/linux_sysent.c b/sys/i386/linux/linux_sysent.c index 880ad65..465a9d3 100644 --- a/sys/i386/linux/linux_sysent.c +++ b/sys/i386/linux/linux_sysent.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: stable/10/sys/i386/linux/syscalls.master 276810 2015-01-08 06:23:11Z dchagin + * created from FreeBSD: stable/10/sys/i386/linux/syscalls.master 293592 2016-01-09 17:54:37Z dchagin */ #include <sys/param.h> @@ -19,7 +19,7 @@ struct sysent linux_sysent[] = { #define nosys linux_nosys { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 0 = setup */ - { AS(sys_exit_args), (sy_call_t *)sys_sys_exit, AUE_EXIT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 1 = exit */ + { AS(linux_exit_args), (sy_call_t *)linux_exit, AUE_EXIT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 1 = linux_exit */ { 0, (sy_call_t *)linux_fork, AUE_FORK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 2 = linux_fork */ { AS(read_args), (sy_call_t *)sys_read, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 3 = read */ { AS(write_args), (sy_call_t *)sys_write, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 4 = write */ @@ -172,14 +172,14 @@ struct sysent linux_sysent[] = { { AS(munlock_args), (sy_call_t *)sys_munlock, AUE_MUNLOCK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 151 = munlock */ { AS(mlockall_args), (sy_call_t *)sys_mlockall, AUE_MLOCKALL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 152 = mlockall */ { 0, (sy_call_t *)sys_munlockall, AUE_MUNLOCKALL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 153 = munlockall */ - { AS(sched_setparam_args), (sy_call_t *)sys_sched_setparam, AUE_SCHED_SETPARAM, NULL, 0, 0, 0, SY_THR_STATIC }, /* 154 = sched_setparam */ - { AS(sched_getparam_args), (sy_call_t *)sys_sched_getparam, AUE_SCHED_GETPARAM, NULL, 0, 0, 0, SY_THR_STATIC }, /* 155 = sched_getparam */ + { AS(linux_sched_setparam_args), (sy_call_t *)linux_sched_setparam, AUE_SCHED_SETPARAM, NULL, 0, 0, 0, SY_THR_STATIC }, /* 154 = linux_sched_setparam */ + { AS(linux_sched_getparam_args), (sy_call_t *)linux_sched_getparam, AUE_SCHED_GETPARAM, NULL, 0, 0, 0, SY_THR_STATIC }, /* 155 = linux_sched_getparam */ { AS(linux_sched_setscheduler_args), (sy_call_t *)linux_sched_setscheduler, AUE_SCHED_SETSCHEDULER, NULL, 0, 0, 0, SY_THR_STATIC }, /* 156 = linux_sched_setscheduler */ { AS(linux_sched_getscheduler_args), (sy_call_t *)linux_sched_getscheduler, AUE_SCHED_GETSCHEDULER, NULL, 0, 0, 0, SY_THR_STATIC }, /* 157 = linux_sched_getscheduler */ { 0, (sy_call_t *)sys_sched_yield, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 158 = sched_yield */ { AS(linux_sched_get_priority_max_args), (sy_call_t *)linux_sched_get_priority_max, AUE_SCHED_GET_PRIORITY_MAX, NULL, 0, 0, 0, SY_THR_STATIC }, /* 159 = linux_sched_get_priority_max */ { AS(linux_sched_get_priority_min_args), (sy_call_t *)linux_sched_get_priority_min, AUE_SCHED_GET_PRIORITY_MIN, NULL, 0, 0, 0, SY_THR_STATIC }, /* 160 = linux_sched_get_priority_min */ - { AS(sched_rr_get_interval_args), (sy_call_t *)sys_sched_rr_get_interval, AUE_SCHED_RR_GET_INTERVAL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 161 = sched_rr_get_interval */ + { AS(linux_sched_rr_get_interval_args), (sy_call_t *)linux_sched_rr_get_interval, AUE_SCHED_RR_GET_INTERVAL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 161 = linux_sched_rr_get_interval */ { AS(linux_nanosleep_args), (sy_call_t *)linux_nanosleep, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 162 = linux_nanosleep */ { AS(linux_mremap_args), (sy_call_t *)linux_mremap, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 163 = linux_mremap */ { AS(linux_setresuid16_args), (sy_call_t *)linux_setresuid16, AUE_SETRESUID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 164 = linux_setresuid16 */ @@ -196,7 +196,7 @@ struct sysent linux_sysent[] = { { AS(linux_rt_sigprocmask_args), (sy_call_t *)linux_rt_sigprocmask, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 175 = linux_rt_sigprocmask */ { AS(linux_rt_sigpending_args), (sy_call_t *)linux_rt_sigpending, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 176 = linux_rt_sigpending */ { AS(linux_rt_sigtimedwait_args), (sy_call_t *)linux_rt_sigtimedwait, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 177 = linux_rt_sigtimedwait */ - { 0, (sy_call_t *)linux_rt_sigqueueinfo, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 178 = linux_rt_sigqueueinfo */ + { AS(linux_rt_sigqueueinfo_args), (sy_call_t *)linux_rt_sigqueueinfo, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 178 = linux_rt_sigqueueinfo */ { AS(linux_rt_sigsuspend_args), (sy_call_t *)linux_rt_sigsuspend, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 179 = linux_rt_sigsuspend */ { AS(linux_pread_args), (sy_call_t *)linux_pread, AUE_PREAD, NULL, 0, 0, 0, SY_THR_STATIC }, /* 180 = linux_pread */ { AS(linux_pwrite_args), (sy_call_t *)linux_pwrite, AUE_PWRITE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 181 = linux_pwrite */ @@ -272,9 +272,9 @@ struct sysent linux_sysent[] = { { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 251 = */ { AS(linux_exit_group_args), (sy_call_t *)linux_exit_group, AUE_EXIT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 252 = linux_exit_group */ { 0, (sy_call_t *)linux_lookup_dcookie, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 253 = linux_lookup_dcookie */ - { 0, (sy_call_t *)linux_epoll_create, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 254 = linux_epoll_create */ - { 0, (sy_call_t *)linux_epoll_ctl, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 255 = linux_epoll_ctl */ - { 0, (sy_call_t *)linux_epoll_wait, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 256 = linux_epoll_wait */ + { AS(linux_epoll_create_args), (sy_call_t *)linux_epoll_create, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 254 = linux_epoll_create */ + { AS(linux_epoll_ctl_args), (sy_call_t *)linux_epoll_ctl, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 255 = linux_epoll_ctl */ + { AS(linux_epoll_wait_args), (sy_call_t *)linux_epoll_wait, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 256 = linux_epoll_wait */ { 0, (sy_call_t *)linux_remap_file_pages, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 257 = linux_remap_file_pages */ { AS(linux_set_tid_address_args), (sy_call_t *)linux_set_tid_address, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 258 = linux_set_tid_address */ { AS(linux_timer_create_args), (sy_call_t *)linux_timer_create, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 259 = linux_timer_create */ @@ -302,7 +302,7 @@ struct sysent linux_sysent[] = { { AS(linux_mq_notify_args), (sy_call_t *)linux_mq_notify, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 281 = linux_mq_notify */ { AS(linux_mq_getsetattr_args), (sy_call_t *)linux_mq_getsetattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 282 = linux_mq_getsetattr */ { 0, (sy_call_t *)linux_kexec_load, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 283 = linux_kexec_load */ - { 0, (sy_call_t *)linux_waitid, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 284 = linux_waitid */ + { AS(linux_waitid_args), (sy_call_t *)linux_waitid, AUE_WAIT6, NULL, 0, 0, 0, SY_THR_STATIC }, /* 284 = linux_waitid */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 285 = */ { 0, (sy_call_t *)linux_add_key, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 286 = linux_add_key */ { 0, (sy_call_t *)linux_request_key, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 287 = linux_request_key */ @@ -326,8 +326,8 @@ struct sysent linux_sysent[] = { { AS(linux_readlinkat_args), (sy_call_t *)linux_readlinkat, AUE_READLINKAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 305 = linux_readlinkat */ { AS(linux_fchmodat_args), (sy_call_t *)linux_fchmodat, AUE_FCHMODAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 306 = linux_fchmodat */ { AS(linux_faccessat_args), (sy_call_t *)linux_faccessat, AUE_FACCESSAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 307 = linux_faccessat */ - { 0, (sy_call_t *)linux_pselect6, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 308 = linux_pselect6 */ - { 0, (sy_call_t *)linux_ppoll, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 309 = linux_ppoll */ + { AS(linux_pselect6_args), (sy_call_t *)linux_pselect6, AUE_SELECT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 308 = linux_pselect6 */ + { AS(linux_ppoll_args), (sy_call_t *)linux_ppoll, AUE_POLL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 309 = linux_ppoll */ { 0, (sy_call_t *)linux_unshare, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 310 = linux_unshare */ { AS(linux_set_robust_list_args), (sy_call_t *)linux_set_robust_list, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 311 = linux_set_robust_list */ { AS(linux_get_robust_list_args), (sy_call_t *)linux_get_robust_list, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 312 = linux_get_robust_list */ @@ -337,34 +337,35 @@ struct sysent linux_sysent[] = { { 0, (sy_call_t *)linux_vmsplice, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 316 = linux_vmsplice */ { 0, (sy_call_t *)linux_move_pages, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 317 = linux_move_pages */ { 0, (sy_call_t *)linux_getcpu, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 318 = linux_getcpu */ - { 0, (sy_call_t *)linux_epoll_pwait, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 319 = linux_epoll_pwait */ - { 0, (sy_call_t *)linux_utimensat, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 320 = linux_utimensat */ + { AS(linux_epoll_pwait_args), (sy_call_t *)linux_epoll_pwait, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 319 = linux_epoll_pwait */ + { AS(linux_utimensat_args), (sy_call_t *)linux_utimensat, AUE_FUTIMESAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 320 = linux_utimensat */ { 0, (sy_call_t *)linux_signalfd, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 321 = linux_signalfd */ { 0, (sy_call_t *)linux_timerfd_create, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 322 = linux_timerfd_create */ - { 0, (sy_call_t *)linux_eventfd, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 323 = linux_eventfd */ - { 0, (sy_call_t *)linux_fallocate, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 324 = linux_fallocate */ + { AS(linux_eventfd_args), (sy_call_t *)linux_eventfd, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 323 = linux_eventfd */ + { AS(linux_fallocate_args), (sy_call_t *)linux_fallocate, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 324 = linux_fallocate */ { 0, (sy_call_t *)linux_timerfd_settime, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 325 = linux_timerfd_settime */ { 0, (sy_call_t *)linux_timerfd_gettime, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 326 = linux_timerfd_gettime */ { 0, (sy_call_t *)linux_signalfd4, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 327 = linux_signalfd4 */ - { 0, (sy_call_t *)linux_eventfd2, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 328 = linux_eventfd2 */ - { 0, (sy_call_t *)linux_epoll_create1, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 329 = linux_epoll_create1 */ - { 0, (sy_call_t *)linux_dup3, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 330 = linux_dup3 */ + { AS(linux_eventfd2_args), (sy_call_t *)linux_eventfd2, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 328 = linux_eventfd2 */ + { AS(linux_epoll_create1_args), (sy_call_t *)linux_epoll_create1, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 329 = linux_epoll_create1 */ + { AS(linux_dup3_args), (sy_call_t *)linux_dup3, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 330 = linux_dup3 */ { AS(linux_pipe2_args), (sy_call_t *)linux_pipe2, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 331 = linux_pipe2 */ { 0, (sy_call_t *)linux_inotify_init1, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 332 = linux_inotify_init1 */ { 0, (sy_call_t *)linux_preadv, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 333 = linux_preadv */ { 0, (sy_call_t *)linux_pwritev, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 334 = linux_pwritev */ { 0, (sy_call_t *)linux_rt_tsigqueueinfo, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 335 = linux_rt_tsigqueueinfo */ { 0, (sy_call_t *)linux_perf_event_open, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 336 = linux_perf_event_open */ - { 0, (sy_call_t *)linux_recvmmsg, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 337 = linux_recvmmsg */ + { AS(linux_recvmmsg_args), (sy_call_t *)linux_recvmmsg, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 337 = linux_recvmmsg */ { 0, (sy_call_t *)linux_fanotify_init, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 338 = linux_fanotify_init */ { 0, (sy_call_t *)linux_fanotify_mark, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 339 = linux_fanotify_mark */ - { 0, (sy_call_t *)linux_prlimit64, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 340 = linux_prlimit64 */ + { AS(linux_prlimit64_args), (sy_call_t *)linux_prlimit64, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 340 = linux_prlimit64 */ { 0, (sy_call_t *)linux_name_to_handle_at, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 341 = linux_name_to_handle_at */ { 0, (sy_call_t *)linux_open_by_handle_at, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 342 = linux_open_by_handle_at */ { 0, (sy_call_t *)linux_clock_adjtime, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 343 = linux_clock_adjtime */ - { 0, (sy_call_t *)linux_syncfs, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 344 = linux_syncfs */ - { 0, (sy_call_t *)linux_sendmmsg, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 345 = linux_sendmmsg */ + { AS(linux_syncfs_args), (sy_call_t *)linux_syncfs, AUE_SYNC, NULL, 0, 0, 0, SY_THR_STATIC }, /* 344 = linux_syncfs */ + { AS(linux_sendmmsg_args), (sy_call_t *)linux_sendmmsg, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 345 = linux_sendmmsg */ { 0, (sy_call_t *)linux_setns, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 346 = linux_setns */ { 0, (sy_call_t *)linux_process_vm_readv, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 347 = linux_process_vm_readv */ { 0, (sy_call_t *)linux_process_vm_writev, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 348 = linux_process_vm_writev */ + { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 349 = nosys */ }; diff --git a/sys/i386/linux/linux_systrace_args.c b/sys/i386/linux/linux_systrace_args.c index 3564fda..85fc9ca 100644 --- a/sys/i386/linux/linux_systrace_args.c +++ b/sys/i386/linux/linux_systrace_args.c @@ -12,9 +12,9 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) int64_t *iarg = (int64_t *) uarg; switch (sysnum) { #define nosys linux_nosys - /* sys_exit */ + /* linux_exit */ case 1: { - struct sys_exit_args *p = params; + struct linux_exit_args *p = params; iarg[0] = p->rval; /* int */ *n_args = 1; break; @@ -792,7 +792,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) iarg[0] = p->pid; /* l_pid_t */ uarg[1] = (intptr_t) p->status; /* l_int * */ iarg[2] = p->options; /* l_int */ - uarg[3] = (intptr_t) p->rusage; /* struct l_rusage * */ + uarg[3] = (intptr_t) p->rusage; /* void * */ *n_args = 4; break; } @@ -1081,19 +1081,19 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) *n_args = 0; break; } - /* sched_setparam */ + /* linux_sched_setparam */ case 154: { - struct sched_setparam_args *p = params; - iarg[0] = p->pid; /* pid_t */ - uarg[1] = (intptr_t) p->param; /* const struct sched_param * */ + struct linux_sched_setparam_args *p = params; + iarg[0] = p->pid; /* l_pid_t */ + uarg[1] = (intptr_t) p->param; /* struct l_sched_param * */ *n_args = 2; break; } - /* sched_getparam */ + /* linux_sched_getparam */ case 155: { - struct sched_getparam_args *p = params; - iarg[0] = p->pid; /* pid_t */ - uarg[1] = (intptr_t) p->param; /* struct sched_param * */ + struct linux_sched_getparam_args *p = params; + iarg[0] = p->pid; /* l_pid_t */ + uarg[1] = (intptr_t) p->param; /* struct l_sched_param * */ *n_args = 2; break; } @@ -1132,9 +1132,9 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) *n_args = 1; break; } - /* sched_rr_get_interval */ + /* linux_sched_rr_get_interval */ case 161: { - struct sched_rr_get_interval_args *p = params; + struct linux_sched_rr_get_interval_args *p = params; iarg[0] = p->pid; /* l_pid_t */ uarg[1] = (intptr_t) p->interval; /* struct l_timespec * */ *n_args = 2; @@ -1277,7 +1277,11 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) } /* linux_rt_sigqueueinfo */ case 178: { - *n_args = 0; + struct linux_rt_sigqueueinfo_args *p = params; + iarg[0] = p->pid; /* l_pid_t */ + iarg[1] = p->sig; /* l_int */ + uarg[2] = (intptr_t) p->info; /* l_siginfo_t * */ + *n_args = 3; break; } /* linux_rt_sigsuspend */ @@ -1743,17 +1747,29 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) } /* linux_epoll_create */ case 254: { - *n_args = 0; + struct linux_epoll_create_args *p = params; + iarg[0] = p->size; /* l_int */ + *n_args = 1; break; } /* linux_epoll_ctl */ case 255: { - *n_args = 0; + struct linux_epoll_ctl_args *p = params; + iarg[0] = p->epfd; /* l_int */ + iarg[1] = p->op; /* l_int */ + iarg[2] = p->fd; /* l_int */ + uarg[3] = (intptr_t) p->event; /* struct epoll_event * */ + *n_args = 4; break; } /* linux_epoll_wait */ case 256: { - *n_args = 0; + struct linux_epoll_wait_args *p = params; + iarg[0] = p->epfd; /* l_int */ + uarg[1] = (intptr_t) p->events; /* struct epoll_event * */ + iarg[2] = p->maxevents; /* l_int */ + iarg[3] = p->timeout; /* l_int */ + *n_args = 4; break; } /* linux_remap_file_pages */ @@ -1962,7 +1978,13 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) } /* linux_waitid */ case 284: { - *n_args = 0; + struct linux_waitid_args *p = params; + iarg[0] = p->idtype; /* int */ + iarg[1] = p->id; /* l_pid_t */ + uarg[2] = (intptr_t) p->info; /* l_siginfo_t * */ + iarg[3] = p->options; /* int */ + uarg[4] = (intptr_t) p->rusage; /* void * */ + *n_args = 5; break; } /* linux_add_key */ @@ -2133,18 +2155,30 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) iarg[0] = p->dfd; /* l_int */ uarg[1] = (intptr_t) p->filename; /* const char * */ iarg[2] = p->amode; /* l_int */ - iarg[3] = p->flag; /* l_int */ - *n_args = 4; + *n_args = 3; break; } /* linux_pselect6 */ case 308: { - *n_args = 0; + struct linux_pselect6_args *p = params; + iarg[0] = p->nfds; /* l_int */ + uarg[1] = (intptr_t) p->readfds; /* l_fd_set * */ + uarg[2] = (intptr_t) p->writefds; /* l_fd_set * */ + uarg[3] = (intptr_t) p->exceptfds; /* l_fd_set * */ + uarg[4] = (intptr_t) p->tsp; /* struct l_timespec * */ + uarg[5] = (intptr_t) p->sig; /* l_uintptr_t * */ + *n_args = 6; break; } /* linux_ppoll */ case 309: { - *n_args = 0; + struct linux_ppoll_args *p = params; + uarg[0] = (intptr_t) p->fds; /* struct pollfd * */ + uarg[1] = p->nfds; /* uint32_t */ + uarg[2] = (intptr_t) p->tsp; /* struct l_timespec * */ + uarg[3] = (intptr_t) p->sset; /* l_sigset_t * */ + iarg[4] = p->ssize; /* l_size_t */ + *n_args = 5; break; } /* linux_unshare */ @@ -2201,12 +2235,23 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) } /* linux_epoll_pwait */ case 319: { - *n_args = 0; + struct linux_epoll_pwait_args *p = params; + iarg[0] = p->epfd; /* l_int */ + uarg[1] = (intptr_t) p->events; /* struct epoll_event * */ + iarg[2] = p->maxevents; /* l_int */ + iarg[3] = p->timeout; /* l_int */ + uarg[4] = (intptr_t) p->mask; /* l_sigset_t * */ + *n_args = 5; break; } /* linux_utimensat */ case 320: { - *n_args = 0; + struct linux_utimensat_args *p = params; + iarg[0] = p->dfd; /* l_int */ + uarg[1] = (intptr_t) p->pathname; /* const char * */ + uarg[2] = (intptr_t) p->times; /* const struct l_timespec * */ + iarg[3] = p->flags; /* l_int */ + *n_args = 4; break; } /* linux_signalfd */ @@ -2221,12 +2266,19 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) } /* linux_eventfd */ case 323: { - *n_args = 0; + struct linux_eventfd_args *p = params; + iarg[0] = p->initval; /* l_uint */ + *n_args = 1; break; } /* linux_fallocate */ case 324: { - *n_args = 0; + struct linux_fallocate_args *p = params; + iarg[0] = p->fd; /* l_int */ + iarg[1] = p->mode; /* l_int */ + iarg[2] = p->offset; /* l_loff_t */ + iarg[3] = p->len; /* l_loff_t */ + *n_args = 4; break; } /* linux_timerfd_settime */ @@ -2246,17 +2298,26 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) } /* linux_eventfd2 */ case 328: { - *n_args = 0; + struct linux_eventfd2_args *p = params; + iarg[0] = p->initval; /* l_uint */ + iarg[1] = p->flags; /* l_int */ + *n_args = 2; break; } /* linux_epoll_create1 */ case 329: { - *n_args = 0; + struct linux_epoll_create1_args *p = params; + iarg[0] = p->flags; /* l_int */ + *n_args = 1; break; } /* linux_dup3 */ case 330: { - *n_args = 0; + struct linux_dup3_args *p = params; + iarg[0] = p->oldfd; /* l_int */ + iarg[1] = p->newfd; /* l_int */ + iarg[2] = p->flags; /* l_int */ + *n_args = 3; break; } /* linux_pipe2 */ @@ -2294,7 +2355,13 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) } /* linux_recvmmsg */ case 337: { - *n_args = 0; + struct linux_recvmmsg_args *p = params; + iarg[0] = p->s; /* l_int */ + uarg[1] = (intptr_t) p->msg; /* struct l_mmsghdr * */ + iarg[2] = p->vlen; /* l_uint */ + iarg[3] = p->flags; /* l_uint */ + uarg[4] = (intptr_t) p->timeout; /* struct l_timespec * */ + *n_args = 5; break; } /* linux_fanotify_init */ @@ -2309,7 +2376,12 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) } /* linux_prlimit64 */ case 340: { - *n_args = 0; + struct linux_prlimit64_args *p = params; + iarg[0] = p->pid; /* l_pid_t */ + iarg[1] = p->resource; /* l_uint */ + uarg[2] = (intptr_t) p->new; /* struct rlimit * */ + uarg[3] = (intptr_t) p->old; /* struct rlimit * */ + *n_args = 4; break; } /* linux_name_to_handle_at */ @@ -2329,12 +2401,19 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) } /* linux_syncfs */ case 344: { - *n_args = 0; + struct linux_syncfs_args *p = params; + iarg[0] = p->fd; /* l_int */ + *n_args = 1; break; } /* linux_sendmmsg */ case 345: { - *n_args = 0; + struct linux_sendmmsg_args *p = params; + iarg[0] = p->s; /* l_int */ + uarg[1] = (intptr_t) p->msg; /* struct l_mmsghdr * */ + iarg[2] = p->vlen; /* l_uint */ + iarg[3] = p->flags; /* l_uint */ + *n_args = 4; break; } /* linux_setns */ @@ -2363,7 +2442,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) const char *p = NULL; switch (sysnum) { #define nosys linux_nosys - /* sys_exit */ + /* linux_exit */ case 1: switch(ndx) { case 0: @@ -3548,7 +3627,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) p = "l_int"; break; case 3: - p = "struct l_rusage *"; + p = "void *"; break; default: break; @@ -3982,27 +4061,27 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) /* munlockall */ case 153: break; - /* sched_setparam */ + /* linux_sched_setparam */ case 154: switch(ndx) { case 0: - p = "pid_t"; + p = "l_pid_t"; break; case 1: - p = "const struct sched_param *"; + p = "struct l_sched_param *"; break; default: break; }; break; - /* sched_getparam */ + /* linux_sched_getparam */ case 155: switch(ndx) { case 0: - p = "pid_t"; + p = "l_pid_t"; break; case 1: - p = "struct sched_param *"; + p = "struct l_sched_param *"; break; default: break; @@ -4057,7 +4136,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; }; break; - /* sched_rr_get_interval */ + /* linux_sched_rr_get_interval */ case 161: switch(ndx) { case 0: @@ -4298,6 +4377,19 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; /* linux_rt_sigqueueinfo */ case 178: + switch(ndx) { + case 0: + p = "l_pid_t"; + break; + case 1: + p = "l_int"; + break; + case 2: + p = "l_siginfo_t *"; + break; + default: + break; + }; break; /* linux_rt_sigsuspend */ case 179: @@ -4970,12 +5062,51 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; /* linux_epoll_create */ case 254: + switch(ndx) { + case 0: + p = "l_int"; + break; + default: + break; + }; break; /* linux_epoll_ctl */ case 255: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_int"; + break; + case 2: + p = "l_int"; + break; + case 3: + p = "struct epoll_event *"; + break; + default: + break; + }; break; /* linux_epoll_wait */ case 256: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "struct epoll_event *"; + break; + case 2: + p = "l_int"; + break; + case 3: + p = "l_int"; + break; + default: + break; + }; break; /* linux_remap_file_pages */ case 257: @@ -5299,6 +5430,25 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; /* linux_waitid */ case 284: + switch(ndx) { + case 0: + p = "int"; + break; + case 1: + p = "l_pid_t"; + break; + case 2: + p = "l_siginfo_t *"; + break; + case 3: + p = "int"; + break; + case 4: + p = "void *"; + break; + default: + break; + }; break; /* linux_add_key */ case 286: @@ -5558,18 +5708,56 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) case 2: p = "l_int"; break; - case 3: - p = "l_int"; - break; default: break; }; break; /* linux_pselect6 */ case 308: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_fd_set *"; + break; + case 2: + p = "l_fd_set *"; + break; + case 3: + p = "l_fd_set *"; + break; + case 4: + p = "struct l_timespec *"; + break; + case 5: + p = "l_uintptr_t *"; + break; + default: + break; + }; break; /* linux_ppoll */ case 309: + switch(ndx) { + case 0: + p = "struct pollfd *"; + break; + case 1: + p = "uint32_t"; + break; + case 2: + p = "struct l_timespec *"; + break; + case 3: + p = "l_sigset_t *"; + break; + case 4: + p = "l_size_t"; + break; + default: + break; + }; break; /* linux_unshare */ case 310: @@ -5623,9 +5811,44 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; /* linux_epoll_pwait */ case 319: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "struct epoll_event *"; + break; + case 2: + p = "l_int"; + break; + case 3: + p = "l_int"; + break; + case 4: + p = "l_sigset_t *"; + break; + default: + break; + }; break; /* linux_utimensat */ case 320: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "const char *"; + break; + case 2: + p = "const struct l_timespec *"; + break; + case 3: + p = "l_int"; + break; + default: + break; + }; break; /* linux_signalfd */ case 321: @@ -5635,9 +5858,32 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; /* linux_eventfd */ case 323: + switch(ndx) { + case 0: + p = "l_uint"; + break; + default: + break; + }; break; /* linux_fallocate */ case 324: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_int"; + break; + case 2: + p = "l_loff_t"; + break; + case 3: + p = "l_loff_t"; + break; + default: + break; + }; break; /* linux_timerfd_settime */ case 325: @@ -5650,12 +5896,42 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; /* linux_eventfd2 */ case 328: + switch(ndx) { + case 0: + p = "l_uint"; + break; + case 1: + p = "l_int"; + break; + default: + break; + }; break; /* linux_epoll_create1 */ case 329: + switch(ndx) { + case 0: + p = "l_int"; + break; + default: + break; + }; break; /* linux_dup3 */ case 330: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "l_int"; + break; + case 2: + p = "l_int"; + break; + default: + break; + }; break; /* linux_pipe2 */ case 331: @@ -5687,6 +5963,25 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; /* linux_recvmmsg */ case 337: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "struct l_mmsghdr *"; + break; + case 2: + p = "l_uint"; + break; + case 3: + p = "l_uint"; + break; + case 4: + p = "struct l_timespec *"; + break; + default: + break; + }; break; /* linux_fanotify_init */ case 338: @@ -5696,6 +5991,22 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; /* linux_prlimit64 */ case 340: + switch(ndx) { + case 0: + p = "l_pid_t"; + break; + case 1: + p = "l_uint"; + break; + case 2: + p = "struct rlimit *"; + break; + case 3: + p = "struct rlimit *"; + break; + default: + break; + }; break; /* linux_name_to_handle_at */ case 341: @@ -5708,9 +6019,32 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; /* linux_syncfs */ case 344: + switch(ndx) { + case 0: + p = "l_int"; + break; + default: + break; + }; break; /* linux_sendmmsg */ case 345: + switch(ndx) { + case 0: + p = "l_int"; + break; + case 1: + p = "struct l_mmsghdr *"; + break; + case 2: + p = "l_uint"; + break; + case 3: + p = "l_uint"; + break; + default: + break; + }; break; /* linux_setns */ case 346: @@ -5733,7 +6067,7 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) const char *p = NULL; switch (sysnum) { #define nosys linux_nosys - /* sys_exit */ + /* linux_exit */ case 1: if (ndx == 0 || ndx == 1) p = "void"; @@ -6365,12 +6699,12 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; /* munlockall */ case 153: - /* sched_setparam */ + /* linux_sched_setparam */ case 154: if (ndx == 0 || ndx == 1) p = "int"; break; - /* sched_getparam */ + /* linux_sched_getparam */ case 155: if (ndx == 0 || ndx == 1) p = "int"; @@ -6397,7 +6731,7 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) if (ndx == 0 || ndx == 1) p = "int"; break; - /* sched_rr_get_interval */ + /* linux_sched_rr_get_interval */ case 161: if (ndx == 0 || ndx == 1) p = "int"; @@ -6475,6 +6809,9 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; /* linux_rt_sigqueueinfo */ case 178: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_rt_sigsuspend */ case 179: if (ndx == 0 || ndx == 1) @@ -6729,10 +7066,19 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) case 253: /* linux_epoll_create */ case 254: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_epoll_ctl */ case 255: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_epoll_wait */ case 256: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_remap_file_pages */ case 257: /* linux_set_tid_address */ @@ -6847,6 +7193,9 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) case 283: /* linux_waitid */ case 284: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_add_key */ case 286: /* linux_request_key */ @@ -6932,8 +7281,14 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; /* linux_pselect6 */ case 308: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_ppoll */ case 309: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_unshare */ case 310: /* linux_set_robust_list */ @@ -6960,16 +7315,28 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) case 318: /* linux_epoll_pwait */ case 319: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_utimensat */ case 320: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_signalfd */ case 321: /* linux_timerfd_create */ case 322: /* linux_eventfd */ case 323: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_fallocate */ case 324: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_timerfd_settime */ case 325: /* linux_timerfd_gettime */ @@ -6978,10 +7345,19 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) case 327: /* linux_eventfd2 */ case 328: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_epoll_create1 */ case 329: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_dup3 */ case 330: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_pipe2 */ case 331: if (ndx == 0 || ndx == 1) @@ -6999,12 +7375,18 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) case 336: /* linux_recvmmsg */ case 337: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_fanotify_init */ case 338: /* linux_fanotify_mark */ case 339: /* linux_prlimit64 */ case 340: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_name_to_handle_at */ case 341: /* linux_open_by_handle_at */ @@ -7013,8 +7395,14 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) case 343: /* linux_syncfs */ case 344: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_sendmmsg */ case 345: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_setns */ case 346: /* linux_process_vm_readv */ diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c index 67d5056..7c980ce 100644 --- a/sys/i386/linux/linux_sysvec.c +++ b/sys/i386/linux/linux_sysvec.c @@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$"); #include <sys/proc.h> #include <sys/signalvar.h> #include <sys/syscallsubr.h> +#include <sys/sysctl.h> #include <sys/sysent.h> #include <sys/sysproto.h> #include <sys/vnode.h> @@ -71,17 +72,23 @@ __FBSDID("$FreeBSD$"); #include <compat/linux/linux_misc.h> #include <compat/linux/linux_signal.h> #include <compat/linux/linux_util.h> +#include <compat/linux/linux_vdso.h> MODULE_VERSION(linux, 1); -MALLOC_DEFINE(M_LINUX, "linux", "Linux mode structures"); - #if BYTE_ORDER == LITTLE_ENDIAN #define SHELLMAGIC 0x2123 /* #! */ #else #define SHELLMAGIC 0x2321 #endif +#if defined(DEBUG) +SYSCTL_PROC(_compat_linux, OID_AUTO, debug, + CTLTYPE_STRING | CTLFLAG_RW, + 0, 0, linux_sysctl_debug, "A", + "Linux debugging control"); +#endif + /* * Allow the sendsig functions to use the ldebug() facility * even though they are not syscalls themselves. Map them @@ -93,13 +100,15 @@ MALLOC_DEFINE(M_LINUX, "linux", "Linux mode structures"); #define LINUX_PS_STRINGS (LINUX_USRSTACK - sizeof(struct ps_strings)) -extern char linux_sigcode[]; -extern int linux_szsigcode; +static int linux_szsigcode; +static vm_object_t linux_shared_page_obj; +static char *linux_shared_page_mapping; +extern char _binary_linux_locore_o_start; +extern char _binary_linux_locore_o_end; extern struct sysent linux_sysent[LINUX_SYS_MAXSYSCALL]; SET_DECLARE(linux_ioctl_handler_set, struct linux_ioctl_handler); -SET_DECLARE(linux_device_handler_set, struct linux_device_handler); static int linux_fixup(register_t **stack_base, struct image_params *iparams); @@ -110,12 +119,15 @@ static void exec_linux_setregs(struct thread *td, struct image_params *imgp, u_long stack); static register_t *linux_copyout_strings(struct image_params *imgp); static boolean_t linux_trans_osrel(const Elf_Note *note, int32_t *osrel); +static void linux_vdso_install(void *param); +static void linux_vdso_deinstall(void *param); static int linux_szplatform; -const char *linux_platform; +const char *linux_kplatform; static eventhandler_tag linux_exit_tag; static eventhandler_tag linux_exec_tag; +static eventhandler_tag linux_thread_dtor_tag; /* * Linux syscalls return negative errno's, we do positive and map them @@ -137,28 +149,6 @@ static int bsd_to_linux_errno[ELAST + 1] = { -72, -67, -71 }; -int bsd_to_linux_signal[LINUX_SIGTBLSZ] = { - LINUX_SIGHUP, LINUX_SIGINT, LINUX_SIGQUIT, LINUX_SIGILL, - LINUX_SIGTRAP, LINUX_SIGABRT, 0, LINUX_SIGFPE, - LINUX_SIGKILL, LINUX_SIGBUS, LINUX_SIGSEGV, LINUX_SIGSYS, - LINUX_SIGPIPE, LINUX_SIGALRM, LINUX_SIGTERM, LINUX_SIGURG, - LINUX_SIGSTOP, LINUX_SIGTSTP, LINUX_SIGCONT, LINUX_SIGCHLD, - LINUX_SIGTTIN, LINUX_SIGTTOU, LINUX_SIGIO, LINUX_SIGXCPU, - LINUX_SIGXFSZ, LINUX_SIGVTALRM, LINUX_SIGPROF, LINUX_SIGWINCH, - 0, LINUX_SIGUSR1, LINUX_SIGUSR2 -}; - -int linux_to_bsd_signal[LINUX_SIGTBLSZ] = { - SIGHUP, SIGINT, SIGQUIT, SIGILL, - SIGTRAP, SIGABRT, SIGBUS, SIGFPE, - SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2, - SIGPIPE, SIGALRM, SIGTERM, SIGBUS, - SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP, - SIGTTIN, SIGTTOU, SIGURG, SIGXCPU, - SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH, - SIGIO, SIGURG, SIGSYS -}; - #define LINUX_T_UNKNOWN 255 static int _bsd_to_linux_trapcode[] = { LINUX_T_UNKNOWN, /* 0 */ @@ -198,6 +188,10 @@ static int _bsd_to_linux_trapcode[] = { _bsd_to_linux_trapcode[(code)]: \ LINUX_T_UNKNOWN) +LINUX_VDSO_SYM_INTPTR(linux_sigcode); +LINUX_VDSO_SYM_INTPTR(linux_rt_sigcode); +LINUX_VDSO_SYM_INTPTR(linux_vsyscall); + /* * If FreeBSD & Linux have a difference of opinion about what a trap * means, deal with it here. @@ -208,15 +202,15 @@ static int translate_traps(int signal, int trap_code) { if (signal != SIGBUS) - return signal; + return (signal); switch (trap_code) { case T_PROTFLT: case T_TSSFLT: case T_DOUBLEFLT: case T_PAGEFLT: - return SIGSEGV; + return (SIGSEGV); default: - return signal; + return (signal); } } @@ -254,6 +248,9 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp) args = (Elf32_Auxargs *)imgp->auxargs; pos = *stack_base + (imgp->args->argc + imgp->args->envc + 2); + AUXARGS_ENTRY(pos, LINUX_AT_SYSINFO_EHDR, + imgp->proc->p_sysent->sv_shared_page_base); + AUXARGS_ENTRY(pos, LINUX_AT_SYSINFO, linux_vsyscall); AUXARGS_ENTRY(pos, LINUX_AT_HWCAP, cpu_feature); /* @@ -279,6 +276,9 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp) AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_ucred->cr_rgid); AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid); AUXARGS_ENTRY(pos, LINUX_AT_PLATFORM, PTROUT(uplatform)); + AUXARGS_ENTRY(pos, LINUX_AT_RANDOM, imgp->canary); + if (imgp->execpathp != 0) + AUXARGS_ENTRY(pos, LINUX_AT_EXECFN, imgp->execpathp); if (args->execfd != -1) AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd); AUXARGS_ENTRY(pos, AT_NULL, 0); @@ -302,23 +302,45 @@ linux_copyout_strings(struct image_params *imgp) char *stringp, *destp; register_t *stack_base; struct ps_strings *arginfo; + char canary[LINUX_AT_RANDOM_LEN]; + size_t execpath_len; struct proc *p; /* * Calculate string base and vector table pointers. - * Also deal with signal trampoline code for this exec type. */ p = imgp->proc; + if (imgp->execpath != NULL && imgp->auxargs != NULL) + execpath_len = strlen(imgp->execpath) + 1; + else + execpath_len = 0; arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings; destp = (caddr_t)arginfo - SPARE_USRSPACE - linux_szplatform - + roundup(sizeof(canary), sizeof(char *)) - + roundup(execpath_len, sizeof(char *)) - roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *)); /* * install LINUX_PLATFORM */ - copyout(linux_platform, ((caddr_t)arginfo - linux_szplatform), + copyout(linux_kplatform, ((caddr_t)arginfo - linux_szplatform), linux_szplatform); + if (execpath_len != 0) { + imgp->execpathp = (uintptr_t)arginfo - + linux_szplatform - execpath_len; + copyout(imgp->execpath, (void *)imgp->execpathp, execpath_len); + } + + /* + * Prepare the canary for SSP. + */ + arc4rand(canary, sizeof(canary), 0); + imgp->canary = (uintptr_t)arginfo - linux_szplatform - + roundup(execpath_len, sizeof(char *)) - + roundup(sizeof(canary), sizeof(char *)); + copyout(canary, (void *)imgp->canary, sizeof(canary)); + /* * If we have a valid auxargs ptr, prepare some room * on the stack. @@ -398,10 +420,6 @@ linux_copyout_strings(struct image_params *imgp) return (stack_base); } - - -extern unsigned long linux_sznonrtsigcode; - static void linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) { @@ -440,9 +458,7 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) /* * Build the argument list for the signal handler. */ - if (p->p_sysent->sv_sigtbl) - if (sig <= p->p_sysent->sv_sigsize) - sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; + sig = bsd_to_linux_signal(sig); bzero(&frame, sizeof(frame)); @@ -468,7 +484,7 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) bsd_to_linux_sigset(mask, &frame.sf_sc.uc_sigmask); - frame.sf_sc.uc_mcontext.sc_mask = frame.sf_sc.uc_sigmask.__bits[0]; + frame.sf_sc.uc_mcontext.sc_mask = frame.sf_sc.uc_sigmask.__mask; frame.sf_sc.uc_mcontext.sc_gs = rgs(); frame.sf_sc.uc_mcontext.sc_fs = regs->tf_fs; frame.sf_sc.uc_mcontext.sc_es = regs->tf_es; @@ -477,6 +493,7 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) frame.sf_sc.uc_mcontext.sc_esi = regs->tf_esi; frame.sf_sc.uc_mcontext.sc_ebp = regs->tf_ebp; frame.sf_sc.uc_mcontext.sc_ebx = regs->tf_ebx; + frame.sf_sc.uc_mcontext.sc_esp = regs->tf_esp; frame.sf_sc.uc_mcontext.sc_edx = regs->tf_edx; frame.sf_sc.uc_mcontext.sc_ecx = regs->tf_ecx; frame.sf_sc.uc_mcontext.sc_eax = regs->tf_eax; @@ -514,7 +531,7 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) * Build context to run handler in. */ regs->tf_esp = (int)fp; - regs->tf_eip = p->p_sysent->sv_sigcode_base + linux_sznonrtsigcode; + regs->tf_eip = linux_rt_sigcode; regs->tf_eflags &= ~(PSL_T | PSL_VM | PSL_D); regs->tf_cs = _ucodesel; regs->tf_ds = _udatasel; @@ -546,7 +563,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) struct l_sigframe *fp, frame; l_sigset_t lmask; int sig, code; - int oonstack, i; + int oonstack; PROC_LOCK_ASSERT(p, MA_OWNED); psp = p->p_sigacts; @@ -582,9 +599,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) /* * Build the argument list for the signal handler. */ - if (p->p_sysent->sv_sigtbl) - if (sig <= p->p_sysent->sv_sigsize) - sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; + sig = bsd_to_linux_signal(sig); bzero(&frame, sizeof(frame)); @@ -596,7 +611,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) /* * Build the signal context to be used by sigreturn. */ - frame.sf_sc.sc_mask = lmask.__bits[0]; + frame.sf_sc.sc_mask = lmask.__mask; frame.sf_sc.sc_gs = rgs(); frame.sf_sc.sc_fs = regs->tf_fs; frame.sf_sc.sc_es = regs->tf_es; @@ -605,6 +620,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) frame.sf_sc.sc_esi = regs->tf_esi; frame.sf_sc.sc_ebp = regs->tf_ebp; frame.sf_sc.sc_ebx = regs->tf_ebx; + frame.sf_sc.sc_esp = regs->tf_esp; frame.sf_sc.sc_edx = regs->tf_edx; frame.sf_sc.sc_ecx = regs->tf_ecx; frame.sf_sc.sc_eax = regs->tf_eax; @@ -617,8 +633,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) frame.sf_sc.sc_cr2 = (register_t)ksi->ksi_addr; frame.sf_sc.sc_trapno = bsd_to_linux_trapcode(ksi->ksi_trapno); - for (i = 0; i < (LINUX_NSIG_WORDS-1); i++) - frame.sf_extramask[i] = lmask.__bits[i+1]; + frame.sf_extramask[0] = lmask.__mask; if (copyout(&frame, fp, sizeof(frame)) != 0) { /* @@ -633,7 +648,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) * Build context to run handler in. */ regs->tf_esp = (int)fp; - regs->tf_eip = p->p_sysent->sv_sigcode_base; + regs->tf_eip = linux_sigcode; regs->tf_eflags &= ~(PSL_T | PSL_VM | PSL_D); regs->tf_cs = _ucodesel; regs->tf_ds = _udatasel; @@ -661,7 +676,7 @@ linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args) struct trapframe *regs; l_sigset_t lmask; sigset_t bmask; - int eflags, i; + int eflags; ksiginfo_t ksi; regs = td->td_frame; @@ -684,7 +699,7 @@ linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args) #define EFLAGS_SECURE(ef, oef) ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0) eflags = frame.sf_sc.sc_eflags; if (!EFLAGS_SECURE(eflags, regs->tf_eflags)) - return(EINVAL); + return (EINVAL); /* * Don't allow users to load a valid privileged %cs. Let the @@ -699,12 +714,10 @@ linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args) ksi.ksi_trapno = T_PROTFLT; ksi.ksi_addr = (void *)regs->tf_eip; trapsignal(td, &ksi); - return(EINVAL); + return (EINVAL); } - lmask.__bits[0] = frame.sf_sc.sc_mask; - for (i = 0; i < (LINUX_NSIG_WORDS-1); i++) - lmask.__bits[i+1] = frame.sf_extramask[i]; + lmask.__mask = frame.sf_sc.sc_mask; linux_to_bsd_sigset(&lmask, &bmask); kern_sigprocmask(td, SIG_SETMASK, &bmask, NULL, 0); @@ -775,7 +788,7 @@ linux_rt_sigreturn(struct thread *td, struct linux_rt_sigreturn_args *args) #define EFLAGS_SECURE(ef, oef) ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0) eflags = context->sc_eflags; if (!EFLAGS_SECURE(eflags, regs->tf_eflags)) - return(EINVAL); + return (EINVAL); /* * Don't allow users to load a valid privileged %cs. Let the @@ -790,7 +803,7 @@ linux_rt_sigreturn(struct thread *td, struct linux_rt_sigreturn_args *args) ksi.ksi_trapno = T_PROTFLT; ksi.ksi_addr = (void *)regs->tf_eip; trapsignal(td, &ksi); - return(EINVAL); + return (EINVAL); } linux_to_bsd_sigset(&uc.uc_sigmask, &bmask); @@ -852,7 +865,8 @@ linux_fetch_syscall_args(struct thread *td, struct syscall_args *sa) sa->args[5] = frame->tf_ebp; /* Unconfirmed */ if (sa->code >= p->p_sysent->sv_size) - sa->callp = &p->p_sysent->sv_table[0]; + /* nosys */ + sa->callp = &p->p_sysent->sv_table[p->p_sysent->sv_size - 1]; else sa->callp = &p->p_sysent->sv_table[sa->code]; sa->narg = sa->callp->sy_narg; @@ -942,14 +956,14 @@ struct sysentvec linux_sysvec = { .sv_size = LINUX_SYS_MAXSYSCALL, .sv_table = linux_sysent, .sv_mask = 0, - .sv_sigsize = LINUX_SIGTBLSZ, - .sv_sigtbl = bsd_to_linux_signal, + .sv_sigsize = 0, + .sv_sigtbl = NULL, .sv_errsize = ELAST + 1, .sv_errtbl = bsd_to_linux_errno, .sv_transtrap = translate_traps, .sv_fixup = linux_fixup, .sv_sendsig = linux_sendsig, - .sv_sigcode = linux_sigcode, + .sv_sigcode = &_binary_linux_locore_o_start, .sv_szsigcode = &linux_szsigcode, .sv_prepsyscall = NULL, .sv_name = "Linux a.out", @@ -973,6 +987,7 @@ struct sysentvec linux_sysvec = { .sv_shared_page_base = LINUX_SHAREDPAGE, .sv_shared_page_len = PAGE_SIZE, .sv_schedtail = linux_schedtail, + .sv_thread_detach = linux_thread_detach, }; INIT_SYSENTVEC(aout_sysvec, &linux_sysvec); @@ -980,14 +995,14 @@ struct sysentvec elf_linux_sysvec = { .sv_size = LINUX_SYS_MAXSYSCALL, .sv_table = linux_sysent, .sv_mask = 0, - .sv_sigsize = LINUX_SIGTBLSZ, - .sv_sigtbl = bsd_to_linux_signal, + .sv_sigsize = 0, + .sv_sigtbl = NULL, .sv_errsize = ELAST + 1, .sv_errtbl = bsd_to_linux_errno, .sv_transtrap = translate_traps, .sv_fixup = elf_linux_fixup, .sv_sendsig = linux_sendsig, - .sv_sigcode = linux_sigcode, + .sv_sigcode = &_binary_linux_locore_o_start, .sv_szsigcode = &linux_szsigcode, .sv_prepsyscall = NULL, .sv_name = "Linux ELF", @@ -1011,8 +1026,41 @@ struct sysentvec elf_linux_sysvec = { .sv_shared_page_base = LINUX_SHAREDPAGE, .sv_shared_page_len = PAGE_SIZE, .sv_schedtail = linux_schedtail, + .sv_thread_detach = linux_thread_detach, +}; + +static void +linux_vdso_install(void *param) +{ + + linux_szsigcode = (&_binary_linux_locore_o_end - + &_binary_linux_locore_o_start); + + if (linux_szsigcode > elf_linux_sysvec.sv_shared_page_len) + panic("Linux invalid vdso size\n"); + + __elfN(linux_vdso_fixup)(&elf_linux_sysvec); + + linux_shared_page_obj = __elfN(linux_shared_page_init) + (&linux_shared_page_mapping); + + __elfN(linux_vdso_reloc)(&elf_linux_sysvec, LINUX_SHAREDPAGE); + + bcopy(elf_linux_sysvec.sv_sigcode, linux_shared_page_mapping, + linux_szsigcode); + elf_linux_sysvec.sv_shared_page_obj = linux_shared_page_obj; +} +SYSINIT(elf_linux_vdso_init, SI_SUB_EXEC, SI_ORDER_ANY, + (sysinit_cfunc_t)linux_vdso_install, NULL); + +static void +linux_vdso_deinstall(void *param) +{ + + __elfN(linux_shared_page_fini)(linux_shared_page_obj); }; -INIT_SYSENTVEC(elf_sysvec, &elf_linux_sysvec); +SYSUNINIT(elf_linux_vdso_uninit, SI_SUB_EXEC, SI_ORDER_FIRST, + (sysinit_cfunc_t)linux_vdso_deinstall, NULL); static char GNU_ABI_VENDOR[] = "GNU"; static int GNULINUX_ABI_DESC = 0; @@ -1084,7 +1132,6 @@ linux_elf_modevent(module_t mod, int type, void *data) Elf32_Brandinfo **brandinfo; int error; struct linux_ioctl_handler **lihp; - struct linux_device_handler **ldhp; error = 0; @@ -1097,18 +1144,16 @@ linux_elf_modevent(module_t mod, int type, void *data) if (error == 0) { SET_FOREACH(lihp, linux_ioctl_handler_set) linux_ioctl_register_handler(*lihp); - SET_FOREACH(ldhp, linux_device_handler_set) - linux_device_register_handler(*ldhp); - mtx_init(&emul_lock, "emuldata lock", NULL, MTX_DEF); - sx_init(&emul_shared_lock, "emuldata->shared lock"); LIST_INIT(&futex_list); mtx_init(&futex_mtx, "ftllk", NULL, MTX_DEF); linux_exit_tag = EVENTHANDLER_REGISTER(process_exit, linux_proc_exit, NULL, 1000); linux_exec_tag = EVENTHANDLER_REGISTER(process_exec, linux_proc_exec, NULL, 1000); - linux_get_machine(&linux_platform); - linux_szplatform = roundup(strlen(linux_platform) + 1, + linux_thread_dtor_tag = EVENTHANDLER_REGISTER(thread_dtor, + linux_thread_dtor, NULL, EVENTHANDLER_PRI_ANY); + linux_get_machine(&linux_kplatform); + linux_szplatform = roundup(strlen(linux_kplatform) + 1, sizeof(char *)); linux_osd_jail_register(); stclohz = (stathz ? stathz : hz); @@ -1131,13 +1176,10 @@ linux_elf_modevent(module_t mod, int type, void *data) if (error == 0) { SET_FOREACH(lihp, linux_ioctl_handler_set) linux_ioctl_unregister_handler(*lihp); - SET_FOREACH(ldhp, linux_device_handler_set) - linux_device_unregister_handler(*ldhp); - mtx_destroy(&emul_lock); - sx_destroy(&emul_shared_lock); mtx_destroy(&futex_mtx); EVENTHANDLER_DEREGISTER(process_exit, linux_exit_tag); EVENTHANDLER_DEREGISTER(process_exec, linux_exec_tag); + EVENTHANDLER_DEREGISTER(thread_dtor, linux_thread_dtor_tag); linux_osd_jail_deregister(); if (bootverbose) printf("Linux ELF exec handler removed\n"); @@ -1145,9 +1187,9 @@ linux_elf_modevent(module_t mod, int type, void *data) printf("Could not deinstall ELF interpreter entry\n"); break; default: - return EOPNOTSUPP; + return (EOPNOTSUPP); } - return error; + return (error); } static moduledata_t linux_elf_mod = { diff --git a/sys/i386/linux/linux_vdso.lds.s b/sys/i386/linux/linux_vdso.lds.s new file mode 100644 index 0000000..dcb61cf --- /dev/null +++ b/sys/i386/linux/linux_vdso.lds.s @@ -0,0 +1,65 @@ +/* + * Linker script for 32-bit vDSO. + * Copied from Linux kernel arch/x86/vdso/vdso-layout.lds.S + * and arch/x86/vdso/vdso32/vdso32.lds.S + * + * $FreeBSD$ + */ + +SECTIONS +{ + . = . + SIZEOF_HEADERS; + + .hash : { *(.hash) } :text + .gnu.hash : { *(.gnu.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + + .note : { *(.note.*) } :text :note + + .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr + .eh_frame : { KEEP (*(.eh_frame)) } :text + + .dynamic : { *(.dynamic) } :text :dynamic + + .rodata : { *(.rodata*) } :text + .data : { + *(.data*) + *(.sdata*) + *(.got.plt) *(.got) + *(.gnu.linkonce.d.*) + *(.bss*) + *(.dynbss*) + *(.gnu.linkonce.b.*) + } + + .altinstructions : { *(.altinstructions) } + .altinstr_replacement : { *(.altinstr_replacement) } + + . = ALIGN(0x100); + .text : { *(.text*) } :text =0x90909090 +} + +PHDRS +{ + text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */ + dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ + note PT_NOTE FLAGS(4); /* PF_R */ + eh_frame_hdr PT_GNU_EH_FRAME; +} + +ENTRY(linux_vsyscall); + +VERSION +{ + LINUX_2.5 { + global: + linux_vsyscall; + linux_sigcode; + linux_rt_sigcode; + local: *; + }; +} diff --git a/sys/i386/linux/syscalls.master b/sys/i386/linux/syscalls.master index 5b4f3a6..e6609a9 100644 --- a/sys/i386/linux/syscalls.master +++ b/sys/i386/linux/syscalls.master @@ -37,8 +37,7 @@ ; #ifdef's, etc. may be included, and are copied to the output files. 0 AUE_NULL UNIMPL setup -1 AUE_EXIT NOPROTO { void sys_exit(int rval); } exit \ - sys_exit_args void +1 AUE_EXIT STD { void linux_exit(int rval); } 2 AUE_FORK STD { int linux_fork(void); } 3 AUE_NULL NOPROTO { int read(int fd, char *buf, \ u_int nbyte); } @@ -209,7 +208,7 @@ 113 AUE_NULL STD { int linux_vm86old(void); } 114 AUE_WAIT4 STD { int linux_wait4(l_pid_t pid, \ l_int *status, l_int options, \ - struct l_rusage *rusage); } + void *rusage); } 115 AUE_SWAPOFF STD { int linux_swapoff(void); } 116 AUE_NULL STD { int linux_sysinfo(struct l_sysinfo *info); } 117 AUE_NULL STD { int linux_ipc(l_uint what, l_int arg1, \ @@ -270,10 +269,10 @@ 151 AUE_MUNLOCK NOPROTO { int munlock(const void *addr, size_t len); } 152 AUE_MLOCKALL NOPROTO { int mlockall(int how); } 153 AUE_MUNLOCKALL NOPROTO { int munlockall(void); } -154 AUE_SCHED_SETPARAM NOPROTO { int sched_setparam(pid_t pid, \ - const struct sched_param *param); } -155 AUE_SCHED_GETPARAM NOPROTO { int sched_getparam(pid_t pid, \ - struct sched_param *param); } +154 AUE_SCHED_SETPARAM STD { int linux_sched_setparam(l_pid_t pid, \ + struct l_sched_param *param); } +155 AUE_SCHED_GETPARAM STD { int linux_sched_getparam(l_pid_t pid, \ + struct l_sched_param *param); } 156 AUE_SCHED_SETSCHEDULER STD { int linux_sched_setscheduler( \ l_pid_t pid, l_int policy, \ struct l_sched_param *param); } @@ -284,8 +283,8 @@ l_int policy); } 160 AUE_SCHED_GET_PRIORITY_MIN STD { int linux_sched_get_priority_min( \ l_int policy); } -161 AUE_SCHED_RR_GET_INTERVAL NOPROTO { int sched_rr_get_interval(l_pid_t pid, \ - struct l_timespec *interval); } +161 AUE_SCHED_RR_GET_INTERVAL STD { int linux_sched_rr_get_interval( \ + l_pid_t pid, struct l_timespec *interval); } 162 AUE_NULL STD { int linux_nanosleep( \ const struct l_timespec *rqtp, \ struct l_timespec *rmtp); } @@ -321,7 +320,8 @@ l_siginfo_t *ptr, \ struct l_timeval *timeout, \ l_size_t sigsetsize); } -178 AUE_NULL STD { int linux_rt_sigqueueinfo(void); } +178 AUE_NULL STD { int linux_rt_sigqueueinfo(l_pid_t pid, l_int sig, \ + l_siginfo_t *info); } 179 AUE_NULL STD { int linux_rt_sigsuspend( \ l_sigset_t *newset, \ l_size_t sigsetsize); } @@ -432,9 +432,11 @@ 251 AUE_NULL UNIMPL 252 AUE_EXIT STD { int linux_exit_group(int error_code); } 253 AUE_NULL STD { int linux_lookup_dcookie(void); } -254 AUE_NULL STD { int linux_epoll_create(void); } -255 AUE_NULL STD { int linux_epoll_ctl(void); } -256 AUE_NULL STD { int linux_epoll_wait(void); } +254 AUE_NULL STD { int linux_epoll_create(l_int size); } +255 AUE_NULL STD { int linux_epoll_ctl(l_int epfd, l_int op, l_int fd, \ + struct epoll_event *event); } +256 AUE_NULL STD { int linux_epoll_wait(l_int epfd, struct epoll_event *events, \ + l_int maxevents, l_int timeout); } 257 AUE_NULL STD { int linux_remap_file_pages(void); } 258 AUE_NULL STD { int linux_set_tid_address(int *tidptr); } 259 AUE_NULL STD { int linux_timer_create(clockid_t clock_id, \ @@ -475,7 +477,9 @@ 282 AUE_NULL STD { int linux_mq_getsetattr(l_mqd_t mqd, const struct mq_attr *attr, \ struct mq_attr *oattr); } 283 AUE_NULL STD { int linux_kexec_load(void); } -284 AUE_NULL STD { int linux_waitid(void); } +284 AUE_WAIT6 STD { int linux_waitid(int idtype, l_pid_t id, \ + l_siginfo_t *info, int options, \ + void *rusage); } 285 AUE_NULL UNIMPL ; linux 2.6.11: 286 AUE_NULL STD { int linux_add_key(void); } @@ -513,9 +517,13 @@ char *buf, l_int bufsiz); } 306 AUE_FCHMODAT STD { int linux_fchmodat(l_int dfd, const char *filename, \ l_mode_t mode); } -307 AUE_FACCESSAT STD { int linux_faccessat(l_int dfd, const char *filename, l_int amode, l_int flag); } -308 AUE_NULL STD { int linux_pselect6(void); } -309 AUE_NULL STD { int linux_ppoll(void); } +307 AUE_FACCESSAT STD { int linux_faccessat(l_int dfd, const char *filename, \ + l_int amode); } +308 AUE_SELECT STD { int linux_pselect6(l_int nfds, l_fd_set *readfds, \ + l_fd_set *writefds, l_fd_set *exceptfds, \ + struct l_timespec *tsp, l_uintptr_t *sig); } +309 AUE_POLL STD { int linux_ppoll(struct pollfd *fds, uint32_t nfds, \ + struct l_timespec *tsp, l_sigset_t *sset, l_size_t ssize); } 310 AUE_NULL STD { int linux_unshare(void); } ; linux 2.6.17: 311 AUE_NULL STD { int linux_set_robust_list(struct linux_robust_list_head *head, \ @@ -530,22 +538,26 @@ 317 AUE_NULL STD { int linux_move_pages(void); } ; linux 2.6.19: 318 AUE_NULL STD { int linux_getcpu(void); } -319 AUE_NULL STD { int linux_epoll_pwait(void); } +319 AUE_NULL STD { int linux_epoll_pwait(l_int epfd, struct epoll_event *events, \ + l_int maxevents, l_int timeout, l_sigset_t *mask); } ; linux 2.6.22: -320 AUE_NULL STD { int linux_utimensat(void); } +320 AUE_FUTIMESAT STD { int linux_utimensat(l_int dfd, const char *pathname, \ + const struct l_timespec *times, l_int flags); } 321 AUE_NULL STD { int linux_signalfd(void); } 322 AUE_NULL STD { int linux_timerfd_create(void); } -323 AUE_NULL STD { int linux_eventfd(void); } +323 AUE_NULL STD { int linux_eventfd(l_uint initval); } ; linux 2.6.23: -324 AUE_NULL STD { int linux_fallocate(void); } +324 AUE_NULL STD { int linux_fallocate(l_int fd, l_int mode, \ + l_loff_t offset, l_loff_t len); } ; linux 2.6.25: 325 AUE_NULL STD { int linux_timerfd_settime(void); } 326 AUE_NULL STD { int linux_timerfd_gettime(void); } ; linux 2.6.27: 327 AUE_NULL STD { int linux_signalfd4(void); } -328 AUE_NULL STD { int linux_eventfd2(void); } -329 AUE_NULL STD { int linux_epoll_create1(void); } -330 AUE_NULL STD { int linux_dup3(void); } +328 AUE_NULL STD { int linux_eventfd2(l_uint initval, l_int flags); } +329 AUE_NULL STD { int linux_epoll_create1(l_int flags); } +330 AUE_NULL STD { int linux_dup3(l_int oldfd, \ + l_int newfd, l_int flags); } 331 AUE_NULL STD { int linux_pipe2(l_int *pipefds, l_int flags); } 332 AUE_NULL STD { int linux_inotify_init1(void); } ; linux 2.6.30: @@ -555,17 +567,26 @@ 335 AUE_NULL STD { int linux_rt_tsigqueueinfo(void); } 336 AUE_NULL STD { int linux_perf_event_open(void); } ; linux 2.6.33: -337 AUE_NULL STD { int linux_recvmmsg(void); } +337 AUE_NULL STD { int linux_recvmmsg(l_int s, \ + struct l_mmsghdr *msg, l_uint vlen, \ + l_uint flags, struct l_timespec *timeout); } 338 AUE_NULL STD { int linux_fanotify_init(void); } 339 AUE_NULL STD { int linux_fanotify_mark(void); } ; linux 2.6.36: -340 AUE_NULL STD { int linux_prlimit64(void); } +340 AUE_NULL STD { int linux_prlimit64(l_pid_t pid, \ + l_uint resource, \ + struct rlimit *new, \ + struct rlimit *old); } ; later: 341 AUE_NULL STD { int linux_name_to_handle_at(void); } 342 AUE_NULL STD { int linux_open_by_handle_at(void); } 343 AUE_NULL STD { int linux_clock_adjtime(void); } -344 AUE_NULL STD { int linux_syncfs(void); } -345 AUE_NULL STD { int linux_sendmmsg(void); } +344 AUE_SYNC STD { int linux_syncfs(l_int fd); } +345 AUE_NULL STD { int linux_sendmmsg(l_int s, \ + struct l_mmsghdr *msg, l_uint vlen, \ + l_uint flags); } 346 AUE_NULL STD { int linux_setns(void); } 347 AUE_NULL STD { int linux_process_vm_readv(void); } 348 AUE_NULL STD { int linux_process_vm_writev(void); } +; please, keep this line at the end. +349 AUE_NULL UNIMPL nosys diff --git a/sys/kern/capabilities.conf b/sys/kern/capabilities.conf index f7a46ae..d0ea97c 100644 --- a/sys/kern/capabilities.conf +++ b/sys/kern/capabilities.conf @@ -220,8 +220,9 @@ fsync ftruncate ## -## Allow futimes(2), subject to capability rights. +## Allow futimens(2) and futimes(2), subject to capability rights. ## +futimens futimes ## @@ -453,6 +454,7 @@ readlinkat renameat symlinkat unlinkat +utimensat ## ## Allow entry into open(2). This system call will fail, since access to the diff --git a/sys/kern/imgact_aout.c b/sys/kern/imgact_aout.c index 3ae78de..edd5f5f 100644 --- a/sys/kern/imgact_aout.c +++ b/sys/kern/imgact_aout.c @@ -99,6 +99,7 @@ struct sysentvec aout_sysvec = { .sv_fetch_syscall_args = cpu_fetch_syscall_args, .sv_syscallnames = syscallnames, .sv_schedtail = NULL, + .sv_thread_detach = NULL, }; #elif defined(__amd64__) diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index 584b5da..05f3a43 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -986,7 +986,9 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) if (error == 0) have_interp = TRUE; } - if (!have_interp && newinterp != NULL) { + if (!have_interp && newinterp != NULL && + (brand_info->interp_path == NULL || + strcmp(interp, brand_info->interp_path) == 0)) { error = __elfN(load_file)(imgp->proc, newinterp, &addr, &imgp->entry_addr, sv->sv_pagesize); if (error == 0) diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index 23b4a6d..6cb5017 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -414,6 +414,7 @@ struct sysentvec null_sysvec = { .sv_fetch_syscall_args = null_fetch_syscall_args, .sv_syscallnames = NULL, .sv_schedtail = NULL, + .sv_thread_detach = NULL, }; /* @@ -608,9 +609,9 @@ proc0_post(void *dummy __unused) sx_slock(&allproc_lock); FOREACH_PROC_IN_SYSTEM(p) { microuptime(&p->p_stats->p_start); - PROC_SLOCK(p); + PROC_STATLOCK(p); rufetch(p, &ru); /* Clears thread stats */ - PROC_SUNLOCK(p); + PROC_STATUNLOCK(p); p->p_rux.rux_runtime = 0; p->p_rux.rux_uticks = 0; p->p_rux.rux_sticks = 0; diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index 18cc995..10e6b6d 100644 --- a/sys/kern/init_sysent.c +++ b/sys/kern/init_sysent.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: stable/10/sys/kern/syscalls.master 276955 2015-01-11 07:02:03Z dchagin + * created from FreeBSD: stable/10/sys/kern/syscalls.master 293474 2016-01-09 14:20:23Z dchagin */ #include "opt_compat.h" @@ -580,4 +580,6 @@ struct sysent sysent[] = { { AS(aio_mlock_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 543 = aio_mlock */ { AS(procctl_args), (sy_call_t *)sys_procctl, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 544 = procctl */ { AS(ppoll_args), (sy_call_t *)sys_ppoll, AUE_POLL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 545 = ppoll */ + { AS(futimens_args), (sy_call_t *)sys_futimens, AUE_FUTIMES, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 546 = futimens */ + { AS(utimensat_args), (sy_call_t *)sys_utimensat, AUE_FUTIMESAT, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 547 = utimensat */ }; diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c index 08c58be..c62c10f 100644 --- a/sys/kern/kern_clock.c +++ b/sys/kern/kern_clock.c @@ -433,16 +433,16 @@ hardclock_cpu(int usermode) flags = 0; if (usermode && timevalisset(&pstats->p_timer[ITIMER_VIRTUAL].it_value)) { - PROC_SLOCK(p); + PROC_ITIMLOCK(p); if (itimerdecr(&pstats->p_timer[ITIMER_VIRTUAL], tick) == 0) flags |= TDF_ALRMPEND | TDF_ASTPENDING; - PROC_SUNLOCK(p); + PROC_ITIMUNLOCK(p); } if (timevalisset(&pstats->p_timer[ITIMER_PROF].it_value)) { - PROC_SLOCK(p); + PROC_ITIMLOCK(p); if (itimerdecr(&pstats->p_timer[ITIMER_PROF], tick) == 0) flags |= TDF_PROFPEND | TDF_ASTPENDING; - PROC_SUNLOCK(p); + PROC_ITIMUNLOCK(p); } thread_lock(td); sched_tick(1); @@ -521,18 +521,18 @@ hardclock_cnt(int cnt, int usermode) flags = 0; if (usermode && timevalisset(&pstats->p_timer[ITIMER_VIRTUAL].it_value)) { - PROC_SLOCK(p); + PROC_ITIMLOCK(p); if (itimerdecr(&pstats->p_timer[ITIMER_VIRTUAL], tick * cnt) == 0) flags |= TDF_ALRMPEND | TDF_ASTPENDING; - PROC_SUNLOCK(p); + PROC_ITIMUNLOCK(p); } if (timevalisset(&pstats->p_timer[ITIMER_PROF].it_value)) { - PROC_SLOCK(p); + PROC_ITIMLOCK(p); if (itimerdecr(&pstats->p_timer[ITIMER_PROF], tick * cnt) == 0) flags |= TDF_PROFPEND | TDF_ASTPENDING; - PROC_SUNLOCK(p); + PROC_ITIMUNLOCK(p); } thread_lock(td); sched_tick(cnt); diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index dae1d54..e665a8e 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -731,13 +731,20 @@ filt_usertouch(struct knote *kn, struct kevent *kev, u_long type) int sys_kqueue(struct thread *td, struct kqueue_args *uap) { + + return (kern_kqueue(td, 0)); +} + +int +kern_kqueue(struct thread *td, int flags) +{ struct filedesc *fdp; struct kqueue *kq; struct file *fp; int fd, error; fdp = td->td_proc->p_fd; - error = falloc(td, &fp, &fd, 0); + error = falloc(td, &fp, &fd, flags); if (error) goto done2; @@ -863,12 +870,9 @@ int kern_kevent(struct thread *td, int fd, int nchanges, int nevents, struct kevent_copyops *k_ops, const struct timespec *timeout) { - struct kevent keva[KQ_NEVENTS]; - struct kevent *kevp, *changes; - struct kqueue *kq; - struct file *fp; cap_rights_t rights; - int i, n, nerrors, error; + struct file *fp; + int error; cap_rights_init(&rights); if (nchanges > 0) @@ -879,9 +883,24 @@ kern_kevent(struct thread *td, int fd, int nchanges, int nevents, if (error != 0) return (error); + error = kern_kevent_fp(td, fp, nchanges, nevents, k_ops, timeout); + fdrop(fp, td); + + return (error); +} + +int +kern_kevent_fp(struct thread *td, struct file *fp, int nchanges, int nevents, + struct kevent_copyops *k_ops, const struct timespec *timeout) +{ + struct kevent keva[KQ_NEVENTS]; + struct kevent *kevp, *changes; + struct kqueue *kq; + int i, n, nerrors, error; + error = kqueue_acquire(fp, &kq); if (error != 0) - goto done_norel; + return (error); nerrors = 0; @@ -921,8 +940,6 @@ kern_kevent(struct thread *td, int fd, int nchanges, int nevents, error = kqueue_scan(kq, nevents, k_ops, timeout, keva, td); done: kqueue_release(kq, 0); -done_norel: - fdrop(fp, td); return (error); } diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index d00a554..76b4427 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -660,7 +660,9 @@ exit1(struct thread *td, int rv) /* * Save our children's rusage information in our exit rusage. */ + PROC_STATLOCK(p); ruadd(&p->p_ru, &p->p_rux, &p->p_stats->p_cru, &p->p_crux); + PROC_STATUNLOCK(p); /* * Make sure the scheduler takes this thread out of its tables etc. @@ -1044,8 +1046,6 @@ proc_to_reap(struct thread *td, struct proc *p, idtype_t idtype, id_t id, return (0); } - PROC_SLOCK(p); - if (siginfo != NULL) { bzero(siginfo, sizeof(*siginfo)); siginfo->si_errno = 0; @@ -1092,7 +1092,9 @@ proc_to_reap(struct thread *td, struct proc *p, idtype_t idtype, id_t id, if (wrusage != NULL) { rup = &wrusage->wru_self; *rup = p->p_ru; + PROC_STATLOCK(p); calcru(p, &rup->ru_utime, &rup->ru_stime); + PROC_STATUNLOCK(p); rup = &wrusage->wru_children; *rup = p->p_stats->p_cru; @@ -1100,10 +1102,10 @@ proc_to_reap(struct thread *td, struct proc *p, idtype_t idtype, id_t id, } if (p->p_state == PRS_ZOMBIE && !check_only) { + PROC_SLOCK(p); proc_reap(td, p, status, options); return (-1); } - PROC_SUNLOCK(p); PROC_UNLOCK(p); return (1); } diff --git a/sys/kern/kern_module.c b/sys/kern/kern_module.c index b769320..479345e 100644 --- a/sys/kern/kern_module.c +++ b/sys/kern/kern_module.c @@ -158,16 +158,12 @@ module_register(const moduledata_t *data, linker_file_t container) newmod = module_lookupbyname(data->name); if (newmod != NULL) { MOD_XUNLOCK; - printf("module_register: module %s already exists!\n", - data->name); + printf("%s: cannot register %s from %s; already loaded from %s\n", + __func__, data->name, container->filename, newmod->file->filename); return (EEXIST); } namelen = strlen(data->name) + 1; newmod = malloc(sizeof(struct module) + namelen, M_MODULE, M_WAITOK); - if (newmod == NULL) { - MOD_XUNLOCK; - return (ENOMEM); - } newmod->refs = 1; newmod->id = nextid++; newmod->name = (char *)(newmod + 1); diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index ac0152a..c9b7ca3 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -872,11 +872,11 @@ fill_kinfo_proc_only(struct proc *p, struct kinfo_proc *kp) kp->ki_fibnum = p->p_fibnum; kp->ki_start = p->p_stats->p_start; timevaladd(&kp->ki_start, &boottime); - PROC_SLOCK(p); + PROC_STATLOCK(p); rufetch(p, &kp->ki_rusage); kp->ki_runtime = cputick2usec(p->p_rux.rux_runtime); calcru(p, &kp->ki_rusage.ru_utime, &kp->ki_rusage.ru_stime); - PROC_SUNLOCK(p); + PROC_STATUNLOCK(p); calccru(p, &kp->ki_childutime, &kp->ki_childstime); /* Some callers want child times in a single value. */ kp->ki_childtime = kp->ki_childstime; @@ -941,7 +941,7 @@ fill_kinfo_thread(struct thread *td, struct kinfo_proc *kp, int preferthread) PROC_LOCK_ASSERT(p, MA_OWNED); if (preferthread) - PROC_SLOCK(p); + PROC_STATLOCK(p); thread_lock(td); if (td->td_wmesg != NULL) strlcpy(kp->ki_wmesg, td->td_wmesg, sizeof(kp->ki_wmesg)); @@ -1008,7 +1008,7 @@ fill_kinfo_thread(struct thread *td, struct kinfo_proc *kp, int preferthread) kp->ki_sigmask = td->td_sigmask; thread_unlock(td); if (preferthread) - PROC_SUNLOCK(p); + PROC_STATUNLOCK(p); } /* diff --git a/sys/kern/kern_racct.c b/sys/kern/kern_racct.c index 448922a..9e67034 100644 --- a/sys/kern/kern_racct.c +++ b/sys/kern/kern_racct.c @@ -1214,11 +1214,11 @@ racctd(void) microuptime(&wallclock); timevalsub(&wallclock, &p->p_stats->p_start); - PROC_SLOCK(p); + PROC_STATLOCK(p); FOREACH_THREAD_IN_PROC(p, td) ruxagg(p, td); runtime = cputick2usec(p->p_rux.rux_runtime); - PROC_SUNLOCK(p); + PROC_STATUNLOCK(p); #ifdef notyet KASSERT(runtime >= p->p_prev_runtime, ("runtime < p_prev_runtime")); diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c index b8b8fee..3a5d575 100644 --- a/sys/kern/kern_resource.c +++ b/sys/kern/kern_resource.c @@ -631,11 +631,11 @@ lim_cb(void *arg) */ if (p->p_cpulimit == RLIM_INFINITY) return; - PROC_SLOCK(p); + PROC_STATLOCK(p); FOREACH_THREAD_IN_PROC(p, td) { ruxagg(p, td); } - PROC_SUNLOCK(p); + PROC_STATUNLOCK(p); if (p->p_rux.rux_runtime > p->p_cpulimit * cpu_tickrate()) { lim_rlimit(p, RLIMIT_CPU, &rlim); if (p->p_rux.rux_runtime >= rlim.rlim_max * cpu_tickrate()) { @@ -847,7 +847,7 @@ calcru(struct proc *p, struct timeval *up, struct timeval *sp) uint64_t runtime, u; PROC_LOCK_ASSERT(p, MA_OWNED); - PROC_SLOCK_ASSERT(p, MA_OWNED); + PROC_STATLOCK_ASSERT(p, MA_OWNED); /* * If we are getting stats for the current process, then add in the * stats that this thread has accumulated in its current time slice. @@ -879,7 +879,7 @@ rufetchtd(struct thread *td, struct rusage *ru) uint64_t runtime, u; p = td->td_proc; - PROC_SLOCK_ASSERT(p, MA_OWNED); + PROC_STATLOCK_ASSERT(p, MA_OWNED); THREAD_LOCK_ASSERT(td, MA_OWNED); /* * If we are getting stats for the current thread, then add in the @@ -1015,11 +1015,11 @@ kern_getrusage(struct thread *td, int who, struct rusage *rup) break; case RUSAGE_THREAD: - PROC_SLOCK(p); + PROC_STATLOCK(p); thread_lock(td); rufetchtd(td, rup); thread_unlock(td); - PROC_SUNLOCK(p); + PROC_STATUNLOCK(p); break; default: @@ -1066,7 +1066,7 @@ ruxagg_locked(struct rusage_ext *rux, struct thread *td) { THREAD_LOCK_ASSERT(td, MA_OWNED); - PROC_SLOCK_ASSERT(td->td_proc, MA_OWNED); + PROC_STATLOCK_ASSERT(td->td_proc, MA_OWNED); rux->rux_runtime += td->td_incruntime; rux->rux_uticks += td->td_uticks; rux->rux_sticks += td->td_sticks; @@ -1096,7 +1096,7 @@ rufetch(struct proc *p, struct rusage *ru) { struct thread *td; - PROC_SLOCK_ASSERT(p, MA_OWNED); + PROC_STATLOCK_ASSERT(p, MA_OWNED); *ru = p->p_ru; if (p->p_numthreads > 0) { @@ -1117,10 +1117,10 @@ rufetchcalc(struct proc *p, struct rusage *ru, struct timeval *up, struct timeval *sp) { - PROC_SLOCK(p); + PROC_STATLOCK(p); rufetch(p, ru); calcru(p, up, sp); - PROC_SUNLOCK(p); + PROC_STATUNLOCK(p); } /* diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c index 5eba047..8139c8c 100644 --- a/sys/kern/kern_shutdown.c +++ b/sys/kern/kern_shutdown.c @@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$"); #include <sys/conf.h> #include <sys/cons.h> #include <sys/eventhandler.h> +#include <sys/filedesc.h> #include <sys/jail.h> #include <sys/kdb.h> #include <sys/kernel.h> @@ -157,10 +158,16 @@ static struct dumperinfo dumper; /* our selected dumper */ static struct pcb dumppcb; /* Registers. */ lwpid_t dumptid; /* Thread ID. */ +static struct cdevsw reroot_cdevsw = { + .d_version = D_VERSION, + .d_name = "reroot", +}; + static void poweroff_wait(void *, int); static void shutdown_halt(void *junk, int howto); static void shutdown_panic(void *junk, int howto); static void shutdown_reset(void *junk, int howto); +static int kern_reroot(void); /* register various local shutdown events */ static void @@ -180,6 +187,26 @@ shutdown_conf(void *unused) SYSINIT(shutdown_conf, SI_SUB_INTRINSIC, SI_ORDER_ANY, shutdown_conf, NULL); /* + * The only reason this exists is to create the /dev/reroot/ directory, + * used by reroot code in init(8) as a mountpoint for tmpfs. + */ +static void +reroot_conf(void *unused) +{ + int error; + struct cdev *cdev; + + error = make_dev_p(MAKEDEV_CHECKNAME | MAKEDEV_WAITOK, &cdev, + &reroot_cdevsw, NULL, UID_ROOT, GID_WHEEL, 0600, "reroot/reroot"); + if (error != 0) { + printf("%s: failed to create device node, error %d", + __func__, error); + } +} + +SYSINIT(reroot_conf, SI_SUB_DEVFS, SI_ORDER_ANY, reroot_conf, NULL); + +/* * The system call that results in a reboot. */ /* ARGSUSED */ @@ -195,9 +222,13 @@ sys_reboot(struct thread *td, struct reboot_args *uap) if (error == 0) error = priv_check(td, PRIV_REBOOT); if (error == 0) { - mtx_lock(&Giant); - kern_reboot(uap->opt); - mtx_unlock(&Giant); + if (uap->opt & RB_REROOT) { + error = kern_reroot(); + } else { + mtx_lock(&Giant); + kern_reboot(uap->opt); + mtx_unlock(&Giant); + } } return (error); } @@ -462,6 +493,102 @@ kern_reboot(int howto) } /* + * The system call that results in changing the rootfs. + */ +static int +kern_reroot(void) +{ + struct vnode *oldrootvnode, *vp; + struct mount *mp, *devmp; + int error; + + if (curproc != initproc) + return (EPERM); + + /* + * Mark the filesystem containing currently-running executable + * (the temporary copy of init(8)) busy. + */ + vp = curproc->p_textvp; + error = vn_lock(vp, LK_SHARED); + if (error != 0) + return (error); + mp = vp->v_mount; + error = vfs_busy(mp, MBF_NOWAIT); + if (error != 0) { + vfs_ref(mp); + VOP_UNLOCK(vp, 0); + error = vfs_busy(mp, 0); + vn_lock(vp, LK_SHARED | LK_RETRY); + vfs_rel(mp); + if (error != 0) { + VOP_UNLOCK(vp, 0); + return (ENOENT); + } + if (vp->v_iflag & VI_DOOMED) { + VOP_UNLOCK(vp, 0); + vfs_unbusy(mp); + return (ENOENT); + } + } + VOP_UNLOCK(vp, 0); + + /* + * Remove the filesystem containing currently-running executable + * from the mount list, to prevent it from being unmounted + * by vfs_unmountall(), and to avoid confusing vfs_mountroot(). + * + * Also preserve /dev - forcibly unmounting it could cause driver + * reinitialization. + */ + + vfs_ref(rootdevmp); + devmp = rootdevmp; + rootdevmp = NULL; + + mtx_lock(&mountlist_mtx); + TAILQ_REMOVE(&mountlist, mp, mnt_list); + TAILQ_REMOVE(&mountlist, devmp, mnt_list); + mtx_unlock(&mountlist_mtx); + + oldrootvnode = rootvnode; + + /* + * Unmount everything except for the two filesystems preserved above. + */ + vfs_unmountall(); + + /* + * Add /dev back; vfs_mountroot() will move it into its new place. + */ + mtx_lock(&mountlist_mtx); + TAILQ_INSERT_HEAD(&mountlist, devmp, mnt_list); + mtx_unlock(&mountlist_mtx); + rootdevmp = devmp; + vfs_rel(rootdevmp); + + /* + * Mount the new rootfs. + */ + vfs_mountroot(); + + /* + * Update all references to the old rootvnode. + */ + mountcheckdirs(oldrootvnode, rootvnode); + + /* + * Add the temporary filesystem back and unbusy it. + */ + mtx_lock(&mountlist_mtx); + TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list); + mtx_unlock(&mountlist_mtx); + vfs_unbusy(mp); + + return (0); +} + +/* * If the shutdown was a clean halt, behave accordingly. */ static void diff --git a/sys/kern/kern_thr.c b/sys/kern/kern_thr.c index 058dc19..98965b1 100644 --- a/sys/kern/kern_thr.c +++ b/sys/kern/kern_thr.c @@ -192,12 +192,6 @@ thread_create(struct thread *td, struct rtprio *rtp, p = td->td_proc; - /* Have race condition but it is cheap. */ - if (p->p_numthreads >= max_threads_per_proc) { - ++max_threads_hits; - return (EPROCLIM); - } - if (rtp != NULL) { switch(rtp->type) { case RTP_PRIO_REALTIME: @@ -225,11 +219,9 @@ thread_create(struct thread *td, struct rtprio *rtp, #endif /* Initialize our td */ - newtd = thread_alloc(0); - if (newtd == NULL) { - error = ENOMEM; + error = kern_thr_alloc(p, 0, &newtd); + if (error) goto fail; - } cpu_set_upcall(newtd, td); @@ -305,9 +297,6 @@ int sys_thr_exit(struct thread *td, struct thr_exit_args *uap) /* long *state */ { - struct proc *p; - - p = td->td_proc; /* Signal userland that it can free the stack. */ if ((void *)uap->state != NULL) { @@ -315,8 +304,17 @@ sys_thr_exit(struct thread *td, struct thr_exit_args *uap) kern_umtx_wake(td, uap->state, INT_MAX, 0); } - rw_wlock(&tidhash_lock); + return (kern_thr_exit(td)); +} + +int +kern_thr_exit(struct thread *td) +{ + struct proc *p; + p = td->td_proc; + + rw_wlock(&tidhash_lock); PROC_LOCK(p); if (p->p_numthreads != 1) { @@ -558,3 +556,20 @@ sys_thr_set_name(struct thread *td, struct thr_set_name_args *uap) PROC_UNLOCK(p); return (error); } + +int +kern_thr_alloc(struct proc *p, int pages, struct thread **ntd) +{ + + /* Have race condition but it is cheap. */ + if (p->p_numthreads >= max_threads_per_proc) { + ++max_threads_hits; + return (EPROCLIM); + } + + *ntd = thread_alloc(pages); + if (*ntd == NULL) + return (ENOMEM); + + return (0); +} diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c index 5dc2bb0..96f68609ca 100644 --- a/sys/kern/kern_thread.c +++ b/sys/kern/kern_thread.c @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include <sys/sched.h> #include <sys/sleepqueue.h> #include <sys/selinfo.h> +#include <sys/sysent.h> #include <sys/turnstile.h> #include <sys/ktr.h> #include <sys/rwlock.h> @@ -472,6 +473,9 @@ thread_exit(void) PMC_SWITCH_CONTEXT(td, PMC_FN_CSW_OUT); #endif PROC_UNLOCK(p); + PROC_STATLOCK(p); + thread_lock(td); + PROC_SUNLOCK(p); /* Do the same timestamp bookkeeping that mi_switch() would do. */ new_switchtime = cpu_ticks(); @@ -486,9 +490,8 @@ thread_exit(void) td->td_ru.ru_nvcsw++; ruxagg(p, td); rucollect(&p->p_ru, &td->td_ru); + PROC_STATUNLOCK(p); - thread_lock(td); - PROC_SUNLOCK(p); td->td_state = TDS_INACTIVE; #ifdef WITNESS witness_thread_exit(td); @@ -883,6 +886,14 @@ thread_suspend_check(int return_instead) if ((p->p_flag & P_SINGLE_EXIT) && (p->p_singlethread != td)) { PROC_UNLOCK(p); tidhash_remove(td); + + /* + * Allow Linux emulation layer to do some work + * before thread suicide. + */ + if (__predict_false(p->p_sysent->sv_thread_detach != NULL)) + (p->p_sysent->sv_thread_detach)(td); + PROC_LOCK(p); tdsigcleanup(td); umtx_thread_exit(td); diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c index 73d5e15..6ae0fb1 100644 --- a/sys/kern/kern_time.c +++ b/sys/kern/kern_time.c @@ -273,10 +273,10 @@ get_process_cputime(struct proc *targetp, struct timespec *ats) uint64_t runtime; struct rusage ru; - PROC_SLOCK(targetp); + PROC_STATLOCK(targetp); rufetch(targetp, &ru); runtime = targetp->p_rux.rux_runtime; - PROC_SUNLOCK(targetp); + PROC_STATUNLOCK(targetp); cputick2timespec(runtime, ats); } @@ -325,17 +325,17 @@ kern_clock_gettime(struct thread *td, clockid_t clock_id, struct timespec *ats) break; case CLOCK_VIRTUAL: PROC_LOCK(p); - PROC_SLOCK(p); + PROC_STATLOCK(p); calcru(p, &user, &sys); - PROC_SUNLOCK(p); + PROC_STATUNLOCK(p); PROC_UNLOCK(p); TIMEVAL_TO_TIMESPEC(&user, ats); break; case CLOCK_PROF: PROC_LOCK(p); - PROC_SLOCK(p); + PROC_STATLOCK(p); calcru(p, &user, &sys); - PROC_SUNLOCK(p); + PROC_STATUNLOCK(p); PROC_UNLOCK(p); timevaladd(&user, &sys); TIMEVAL_TO_TIMESPEC(&user, ats); @@ -695,9 +695,9 @@ kern_getitimer(struct thread *td, u_int which, struct itimerval *aitv) timevalsub(&aitv->it_value, &ctv); } } else { - PROC_SLOCK(p); + PROC_ITIMLOCK(p); *aitv = p->p_stats->p_timer[which]; - PROC_SUNLOCK(p); + PROC_ITIMUNLOCK(p); } return (0); } @@ -779,10 +779,10 @@ kern_setitimer(struct thread *td, u_int which, struct itimerval *aitv, aitv->it_value.tv_usec != 0 && aitv->it_value.tv_usec < tick) aitv->it_value.tv_usec = tick; - PROC_SLOCK(p); + PROC_ITIMLOCK(p); *oitv = p->p_stats->p_timer[which]; p->p_stats->p_timer[which] = *aitv; - PROC_SUNLOCK(p); + PROC_ITIMUNLOCK(p); } return (0); } diff --git a/sys/kern/p1003_1b.c b/sys/kern/p1003_1b.c index fb89efc..ac6cd60 100644 --- a/sys/kern/p1003_1b.c +++ b/sys/kern/p1003_1b.c @@ -130,16 +130,29 @@ sys_sched_setparam(struct thread *td, struct sched_setparam_args *uap) targettd = FIRST_THREAD_IN_PROC(targetp); } - e = p_cansched(td, targetp); - if (e == 0) { - e = ksched_setparam(ksched, targettd, - (const struct sched_param *)&sched_param); - } + e = kern_sched_setparam(td, targettd, &sched_param); PROC_UNLOCK(targetp); return (e); } int +kern_sched_setparam(struct thread *td, struct thread *targettd, + struct sched_param *param) +{ + struct proc *targetp; + int error; + + targetp = targettd->td_proc; + PROC_LOCK_ASSERT(targetp, MA_OWNED); + + error = p_cansched(td, targetp); + if (error == 0) + error = ksched_setparam(ksched, targettd, + (const struct sched_param *)param); + return (error); +} + +int sys_sched_getparam(struct thread *td, struct sched_getparam_args *uap) { int e; @@ -159,10 +172,7 @@ sys_sched_getparam(struct thread *td, struct sched_getparam_args *uap) targettd = FIRST_THREAD_IN_PROC(targetp); } - e = p_cansee(td, targetp); - if (e == 0) { - e = ksched_getparam(ksched, targettd, &sched_param); - } + e = kern_sched_getparam(td, targettd, &sched_param); PROC_UNLOCK(targetp); if (e == 0) e = copyout(&sched_param, uap->param, sizeof(sched_param)); @@ -170,6 +180,22 @@ sys_sched_getparam(struct thread *td, struct sched_getparam_args *uap) } int +kern_sched_getparam(struct thread *td, struct thread *targettd, + struct sched_param *param) +{ + struct proc *targetp; + int error; + + targetp = targettd->td_proc; + PROC_LOCK_ASSERT(targetp, MA_OWNED); + + error = p_cansee(td, targetp); + if (error == 0) + error = ksched_getparam(ksched, targettd, param); + return (error); +} + +int sys_sched_setscheduler(struct thread *td, struct sched_setscheduler_args *uap) { int e; @@ -177,11 +203,6 @@ sys_sched_setscheduler(struct thread *td, struct sched_setscheduler_args *uap) struct thread *targettd; struct proc *targetp; - /* Don't allow non root user to set a scheduler policy. */ - e = priv_check(td, PRIV_SCHED_SET); - if (e) - return (e); - e = copyin(uap->param, &sched_param, sizeof(sched_param)); if (e) return (e); @@ -197,16 +218,35 @@ sys_sched_setscheduler(struct thread *td, struct sched_setscheduler_args *uap) targettd = FIRST_THREAD_IN_PROC(targetp); } - e = p_cansched(td, targetp); - if (e == 0) { - e = ksched_setscheduler(ksched, targettd, - uap->policy, (const struct sched_param *)&sched_param); - } + e = kern_sched_setscheduler(td, targettd, uap->policy, + &sched_param); PROC_UNLOCK(targetp); return (e); } int +kern_sched_setscheduler(struct thread *td, struct thread *targettd, + int policy, struct sched_param *param) +{ + struct proc *targetp; + int error; + + targetp = targettd->td_proc; + PROC_LOCK_ASSERT(targetp, MA_OWNED); + + /* Don't allow non root user to set a scheduler policy. */ + error = priv_check(td, PRIV_SCHED_SET); + if (error) + return (error); + + error = p_cansched(td, targetp); + if (error == 0) + error = ksched_setscheduler(ksched, targettd, policy, + (const struct sched_param *)param); + return (error); +} + +int sys_sched_getscheduler(struct thread *td, struct sched_getscheduler_args *uap) { int e, policy; @@ -224,17 +264,31 @@ sys_sched_getscheduler(struct thread *td, struct sched_getscheduler_args *uap) targettd = FIRST_THREAD_IN_PROC(targetp); } - e = p_cansee(td, targetp); - if (e == 0) { - e = ksched_getscheduler(ksched, targettd, &policy); - td->td_retval[0] = policy; - } + e = kern_sched_getscheduler(td, targettd, &policy); PROC_UNLOCK(targetp); + if (e == 0) + td->td_retval[0] = policy; return (e); } int +kern_sched_getscheduler(struct thread *td, struct thread *targettd, + int *policy) +{ + struct proc *targetp; + int error; + + targetp = targettd->td_proc; + PROC_LOCK_ASSERT(targetp, MA_OWNED); + + error = p_cansee(td, targetp); + if (error == 0) + error = ksched_getscheduler(ksched, targettd, policy); + return (error); +} + +int sys_sched_yield(struct thread *td, struct sched_yield_args *uap) { @@ -296,13 +350,26 @@ kern_sched_rr_get_interval(struct thread *td, pid_t pid, targettd = FIRST_THREAD_IN_PROC(targetp); } - e = p_cansee(td, targetp); - if (e == 0) - e = ksched_rr_get_interval(ksched, targettd, ts); + e = kern_sched_rr_get_interval_td(td, targettd, ts); PROC_UNLOCK(targetp); return (e); } +int +kern_sched_rr_get_interval_td(struct thread *td, struct thread *targettd, + struct timespec *ts) +{ + struct proc *p; + int error; + + p = targettd->td_proc; + PROC_LOCK_ASSERT(p, MA_OWNED); + + error = p_cansee(td, p); + if (error == 0) + error = ksched_rr_get_interval(ksched, targettd, ts); + return (error); +} #endif static void diff --git a/sys/kern/subr_prof.c b/sys/kern/subr_prof.c index fcfd748..3d4e86a 100644 --- a/sys/kern/subr_prof.c +++ b/sys/kern/subr_prof.c @@ -421,12 +421,12 @@ sys_profil(struct thread *td, struct profil_args *uap) } PROC_LOCK(p); upp = &td->td_proc->p_stats->p_prof; - PROC_SLOCK(p); + PROC_PROFLOCK(p); upp->pr_off = uap->offset; upp->pr_scale = uap->scale; upp->pr_base = uap->samples; upp->pr_size = uap->size; - PROC_SUNLOCK(p); + PROC_PROFUNLOCK(p); startprofclock(p); PROC_UNLOCK(p); @@ -466,15 +466,15 @@ addupc_intr(struct thread *td, uintfptr_t pc, u_int ticks) if (ticks == 0) return; prof = &td->td_proc->p_stats->p_prof; - PROC_SLOCK(td->td_proc); + PROC_PROFLOCK(td->td_proc); if (pc < prof->pr_off || (i = PC_TO_INDEX(pc, prof)) >= prof->pr_size) { - PROC_SUNLOCK(td->td_proc); + PROC_PROFUNLOCK(td->td_proc); return; /* out of range; ignore */ } addr = prof->pr_base + i; - PROC_SUNLOCK(td->td_proc); + PROC_PROFUNLOCK(td->td_proc); if ((v = fuswintr(addr)) == -1 || suswintr(addr, v + ticks) == -1) { td->td_profil_addr = pc; td->td_profil_ticks = ticks; @@ -509,15 +509,15 @@ addupc_task(struct thread *td, uintfptr_t pc, u_int ticks) } p->p_profthreads++; prof = &p->p_stats->p_prof; - PROC_SLOCK(p); + PROC_PROFLOCK(p); if (pc < prof->pr_off || (i = PC_TO_INDEX(pc, prof)) >= prof->pr_size) { - PROC_SUNLOCK(p); + PROC_PROFUNLOCK(p); goto out; } addr = prof->pr_base + i; - PROC_SUNLOCK(p); + PROC_PROFUNLOCK(p); PROC_UNLOCK(p); if (copyin(addr, &v, sizeof(v)) == 0) { v += ticks; diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c index d05659e..38d3420 100644 --- a/sys/kern/syscalls.c +++ b/sys/kern/syscalls.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: stable/10/sys/kern/syscalls.master 276955 2015-01-11 07:02:03Z dchagin + * created from FreeBSD: stable/10/sys/kern/syscalls.master 293474 2016-01-09 14:20:23Z dchagin */ const char *syscallnames[] = { @@ -553,4 +553,6 @@ const char *syscallnames[] = { "aio_mlock", /* 543 = aio_mlock */ "procctl", /* 544 = procctl */ "ppoll", /* 545 = ppoll */ + "futimens", /* 546 = futimens */ + "utimensat", /* 547 = utimensat */ }; diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 09b9273..49b7c6d 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -983,5 +983,10 @@ 545 AUE_POLL STD { int ppoll(struct pollfd *fds, u_int nfds, \ const struct timespec *ts, \ const sigset_t *set); } +546 AUE_FUTIMES STD { int futimens(int fd, \ + struct timespec *times); } +547 AUE_FUTIMESAT STD { int utimensat(int fd, \ + char *path, \ + struct timespec *times, int flag); } ; Please copy any additions and changes to the following compatability tables: ; sys/compat/freebsd32/syscalls.master diff --git a/sys/kern/systrace_args.c b/sys/kern/systrace_args.c index 729a959..7c337f3 100644 --- a/sys/kern/systrace_args.c +++ b/sys/kern/systrace_args.c @@ -3396,6 +3396,24 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) *n_args = 4; break; } + /* futimens */ + case 546: { + struct futimens_args *p = params; + iarg[0] = p->fd; /* int */ + uarg[1] = (intptr_t) p->times; /* struct timespec * */ + *n_args = 2; + break; + } + /* utimensat */ + case 547: { + struct utimensat_args *p = params; + iarg[0] = p->fd; /* int */ + uarg[1] = (intptr_t) p->path; /* char * */ + uarg[2] = (intptr_t) p->times; /* struct timespec * */ + iarg[3] = p->flag; /* int */ + *n_args = 4; + break; + } default: *n_args = 0; break; @@ -9053,6 +9071,38 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; }; break; + /* futimens */ + case 546: + switch(ndx) { + case 0: + p = "int"; + break; + case 1: + p = "struct timespec *"; + break; + default: + break; + }; + break; + /* utimensat */ + case 547: + switch(ndx) { + case 0: + p = "int"; + break; + case 1: + p = "char *"; + break; + case 2: + p = "struct timespec *"; + break; + case 3: + p = "int"; + break; + default: + break; + }; + break; default: break; }; @@ -11006,6 +11056,16 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) if (ndx == 0 || ndx == 1) p = "int"; break; + /* futimens */ + case 546: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* utimensat */ + case 547: + if (ndx == 0 || ndx == 1) + p = "int"; + break; default: break; }; diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index 36d03f9..3ca995f 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -1359,6 +1359,8 @@ dounmount(struct mount *mp, int flags, struct thread *td) vput(coveredvp); } vfs_event_signal(NULL, VQ_UNMOUNT, 0); + if (mp == rootdevmp) + rootdevmp = NULL; vfs_mount_destroy(mp); return (0); } diff --git a/sys/kern/vfs_mountroot.c b/sys/kern/vfs_mountroot.c index 473cd79..184976a 100644 --- a/sys/kern/vfs_mountroot.c +++ b/sys/kern/vfs_mountroot.c @@ -95,6 +95,11 @@ static struct mntarg *parse_mountroot_options(struct mntarg *, const char *); */ struct vnode *rootvnode; +/* + * Mount of the system's /dev. + */ +struct mount *rootdevmp; + char *rootdevnames[2] = {NULL, NULL}; struct mtx root_holds_mtx; @@ -215,27 +220,39 @@ vfs_mountroot_devfs(struct thread *td, struct mount **mpp) *mpp = NULL; - vfsp = vfs_byname("devfs"); - KASSERT(vfsp != NULL, ("Could not find devfs by name")); - if (vfsp == NULL) - return (ENOENT); - - mp = vfs_mount_alloc(NULLVP, vfsp, "/dev", td->td_ucred); + if (rootdevmp != NULL) { + /* + * Already have /dev; this happens during rerooting. + */ + error = vfs_busy(rootdevmp, 0); + if (error != 0) + return (error); + *mpp = rootdevmp; + } else { + vfsp = vfs_byname("devfs"); + KASSERT(vfsp != NULL, ("Could not find devfs by name")); + if (vfsp == NULL) + return (ENOENT); + + mp = vfs_mount_alloc(NULLVP, vfsp, "/dev", td->td_ucred); + + error = VFS_MOUNT(mp); + KASSERT(error == 0, ("VFS_MOUNT(devfs) failed %d", error)); + if (error) + return (error); - error = VFS_MOUNT(mp); - KASSERT(error == 0, ("VFS_MOUNT(devfs) failed %d", error)); - if (error) - return (error); + opts = malloc(sizeof(struct vfsoptlist), M_MOUNT, M_WAITOK); + TAILQ_INIT(opts); + mp->mnt_opt = opts; - opts = malloc(sizeof(struct vfsoptlist), M_MOUNT, M_WAITOK); - TAILQ_INIT(opts); - mp->mnt_opt = opts; + mtx_lock(&mountlist_mtx); + TAILQ_INSERT_HEAD(&mountlist, mp, mnt_list); + mtx_unlock(&mountlist_mtx); - mtx_lock(&mountlist_mtx); - TAILQ_INSERT_HEAD(&mountlist, mp, mnt_list); - mtx_unlock(&mountlist_mtx); + *mpp = mp; + rootdevmp = mp; + } - *mpp = mp; set_rootvnode(); error = kern_symlink(td, "/", "dev", UIO_SYSSPACE); diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index bad816b..a721c5a 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -3728,6 +3728,21 @@ SYSCTL_PROC(_kern, KERN_VNODE, vnode, CTLTYPE_OPAQUE | CTLFLAG_RD | ""); #endif +static void +unmount_or_warn(struct mount *mp) +{ + int error; + + error = dounmount(mp, MNT_FORCE, curthread); + if (error != 0 && strcmp(mp->mnt_vfc->vfc_name, "devfs") != 0) { + printf("unmount of %s failed (", mp->mnt_stat.f_mntonname); + if (error == EBUSY) + printf("BUSY)\n"); + else + printf("%d)\n", error); + } +} + /* * Unmount all filesystems. The list is traversed in reverse order * of mounting to avoid dependencies. @@ -3735,42 +3750,28 @@ SYSCTL_PROC(_kern, KERN_VNODE, vnode, CTLTYPE_OPAQUE | CTLFLAG_RD | void vfs_unmountall(void) { - struct mount *mp; - struct thread *td; - int error; + struct mount *mp, *tmp; CTR1(KTR_VFS, "%s: unmounting all filesystems", __func__); - td = curthread; /* * Since this only runs when rebooting, it is not interlocked. */ - while(!TAILQ_EMPTY(&mountlist)) { - mp = TAILQ_LAST(&mountlist, mntlist); + TAILQ_FOREACH_REVERSE_SAFE(mp, &mountlist, mntlist, mnt_list, tmp) { vfs_ref(mp); - error = dounmount(mp, MNT_FORCE, td); - if (error != 0) { - TAILQ_REMOVE(&mountlist, mp, mnt_list); - /* - * XXX: Due to the way in which we mount the root - * file system off of devfs, devfs will generate a - * "busy" warning when we try to unmount it before - * the root. Don't print a warning as a result in - * order to avoid false positive errors that may - * cause needless upset. - */ - if (strcmp(mp->mnt_vfc->vfc_name, "devfs") != 0) { - printf("unmount of %s failed (", - mp->mnt_stat.f_mntonname); - if (error == EBUSY) - printf("BUSY)\n"); - else - printf("%d)\n", error); - } - } else { - /* The unmount has removed mp from the mountlist */ - } + + /* + * Forcibly unmounting "/dev" before "/" would prevent clean + * unmount of the latter. + */ + if (mp == rootdevmp) + continue; + + unmount_or_warn(mp); } + + if (rootdevmp != NULL) + unmount_or_warn(rootdevmp); } /* diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 685eaa5..4dafe75 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -96,12 +96,14 @@ SDT_PROBE_DEFINE2(vfs, , stat, mode, "char *", "int"); SDT_PROBE_DEFINE2(vfs, , stat, reg, "char *", "int"); static int chroot_refuse_vdir_fds(struct filedesc *fdp); -static int getutimes(const struct timeval *, enum uio_seg, struct timespec *); static int kern_chflags(struct thread *td, const char *path, enum uio_seg pathseg, u_long flags); static int kern_chflagsat(struct thread *td, int fd, const char *path, enum uio_seg pathseg, u_long flags, int atflag); static int setfflags(struct thread *td, struct vnode *, u_long); +static int getutimes(const struct timeval *, enum uio_seg, struct timespec *); +static int getutimens(const struct timespec *, enum uio_seg, + struct timespec *, int *); static int setutimes(struct thread *td, struct vnode *, const struct timespec *, int, int); static int vn_access(struct vnode *vp, int user_flags, struct ucred *cred, @@ -3110,7 +3112,53 @@ getutimes(usrtvp, tvpseg, tsp) } /* - * Common implementation code for utimes(), lutimes(), and futimes(). + * Common implementation code for futimens(), utimensat(). + */ +#define UTIMENS_NULL 0x1 +#define UTIMENS_EXIT 0x2 +static int +getutimens(const struct timespec *usrtsp, enum uio_seg tspseg, + struct timespec *tsp, int *retflags) +{ + struct timespec tsnow; + int error; + + vfs_timestamp(&tsnow); + *retflags = 0; + if (usrtsp == NULL) { + tsp[0] = tsnow; + tsp[1] = tsnow; + *retflags |= UTIMENS_NULL; + return (0); + } + if (tspseg == UIO_SYSSPACE) { + tsp[0] = usrtsp[0]; + tsp[1] = usrtsp[1]; + } else if ((error = copyin(usrtsp, tsp, sizeof(*tsp) * 2)) != 0) + return (error); + if (tsp[0].tv_nsec == UTIME_OMIT && tsp[1].tv_nsec == UTIME_OMIT) + *retflags |= UTIMENS_EXIT; + if (tsp[0].tv_nsec == UTIME_NOW && tsp[1].tv_nsec == UTIME_NOW) + *retflags |= UTIMENS_NULL; + if (tsp[0].tv_nsec == UTIME_OMIT) + tsp[0].tv_sec = VNOVAL; + else if (tsp[0].tv_nsec == UTIME_NOW) + tsp[0] = tsnow; + else if (tsp[0].tv_nsec < 0 || tsp[0].tv_nsec >= 1000000000L) + return (EINVAL); + if (tsp[1].tv_nsec == UTIME_OMIT) + tsp[1].tv_sec = VNOVAL; + else if (tsp[1].tv_nsec == UTIME_NOW) + tsp[1] = tsnow; + else if (tsp[1].tv_nsec < 0 || tsp[1].tv_nsec >= 1000000000L) + return (EINVAL); + + return (0); +} + +/* + * Common implementation code for utimes(), lutimes(), futimes(), futimens(), + * and utimensat(). */ static int setutimes(td, vp, ts, numtimes, nullflag) @@ -3307,6 +3355,80 @@ kern_futimes(struct thread *td, int fd, struct timeval *tptr, return (error); } +int +sys_futimens(struct thread *td, struct futimens_args *uap) +{ + + return (kern_futimens(td, uap->fd, uap->times, UIO_USERSPACE)); +} + +int +kern_futimens(struct thread *td, int fd, struct timespec *tptr, + enum uio_seg tptrseg) +{ + struct timespec ts[2]; + struct file *fp; + cap_rights_t rights; + int error, flags; + + AUDIT_ARG_FD(fd); + error = getutimens(tptr, tptrseg, ts, &flags); + if (error != 0) + return (error); + if (flags & UTIMENS_EXIT) + return (0); + error = getvnode(td->td_proc->p_fd, fd, + cap_rights_init(&rights, CAP_FUTIMES), &fp); + if (error != 0) + return (error); +#ifdef AUDIT + vn_lock(fp->f_vnode, LK_SHARED | LK_RETRY); + AUDIT_ARG_VNODE1(fp->f_vnode); + VOP_UNLOCK(fp->f_vnode, 0); +#endif + error = setutimes(td, fp->f_vnode, ts, 2, flags & UTIMENS_NULL); + fdrop(fp, td); + return (error); +} + +int +sys_utimensat(struct thread *td, struct utimensat_args *uap) +{ + + return (kern_utimensat(td, uap->fd, uap->path, UIO_USERSPACE, + uap->times, UIO_USERSPACE, uap->flag)); +} + +int +kern_utimensat(struct thread *td, int fd, char *path, enum uio_seg pathseg, + struct timespec *tptr, enum uio_seg tptrseg, int flag) +{ + struct nameidata nd; + struct timespec ts[2]; + int error, flags; + + if (flag & ~AT_SYMLINK_NOFOLLOW) + return (EINVAL); + + if ((error = getutimens(tptr, tptrseg, ts, &flags)) != 0) + return (error); + NDINIT_AT(&nd, LOOKUP, ((flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : + FOLLOW) | AUDITVNODE1, pathseg, path, fd, td); + if ((error = namei(&nd)) != 0) + return (error); + /* + * We are allowed to call namei() regardless of 2xUTIME_OMIT. + * POSIX states: + * "If both tv_nsec fields are UTIME_OMIT... EACCESS may be detected." + * "Search permission is denied by a component of the path prefix." + */ + NDFREE(&nd, NDF_ONLY_PNBUF); + if ((flags & UTIMENS_EXIT) == 0) + error = setutimes(td, nd.ni_vp, ts, 2, flags & UTIMENS_NULL); + vrele(nd.ni_vp); + return (error); +} + /* * Truncate a file given its path name. */ diff --git a/sys/kgssapi/gss_impl.c b/sys/kgssapi/gss_impl.c index 172471a..d27f219 100644 --- a/sys/kgssapi/gss_impl.c +++ b/sys/kgssapi/gss_impl.c @@ -105,14 +105,17 @@ sys_gssd_syscall(struct thread *td, struct gssd_syscall_args *uap) if (error) return (error); - sun.sun_family = AF_LOCAL; - strcpy(sun.sun_path, path); - sun.sun_len = SUN_LEN(&sun); - - nconf = getnetconfigent("local"); - cl = clnt_reconnect_create(nconf, - (struct sockaddr *) &sun, GSSD, GSSDVERS, - RPC_MAXDATASIZE, RPC_MAXDATASIZE); + if (path[0] != '\0') { + sun.sun_family = AF_LOCAL; + strcpy(sun.sun_path, path); + sun.sun_len = SUN_LEN(&sun); + + nconf = getnetconfigent("local"); + cl = clnt_reconnect_create(nconf, + (struct sockaddr *) &sun, GSSD, GSSDVERS, + RPC_MAXDATASIZE, RPC_MAXDATASIZE); + } else + cl = NULL; mtx_lock(&kgss_gssd_lock); oldcl = kgss_gssd_handle; diff --git a/sys/mips/mips/elf_machdep.c b/sys/mips/mips/elf_machdep.c index 2e22281..626b5f8 100644 --- a/sys/mips/mips/elf_machdep.c +++ b/sys/mips/mips/elf_machdep.c @@ -83,6 +83,7 @@ struct sysentvec elf64_freebsd_sysvec = { .sv_fetch_syscall_args = cpu_fetch_syscall_args, .sv_syscallnames = syscallnames, .sv_schedtail = NULL, + .sv_thread_detach = NULL, }; static Elf64_Brandinfo freebsd_brand_info = { @@ -139,6 +140,7 @@ struct sysentvec elf32_freebsd_sysvec = { .sv_fetch_syscall_args = cpu_fetch_syscall_args, .sv_syscallnames = syscallnames, .sv_schedtail = NULL, + .sv_thread_detach = NULL, }; static Elf32_Brandinfo freebsd_brand_info = { diff --git a/sys/mips/mips/freebsd32_machdep.c b/sys/mips/mips/freebsd32_machdep.c index 9de4685b..5303420 100644 --- a/sys/mips/mips/freebsd32_machdep.c +++ b/sys/mips/mips/freebsd32_machdep.c @@ -106,6 +106,7 @@ struct sysentvec elf32_freebsd_sysvec = { .sv_fetch_syscall_args = cpu_fetch_syscall_args, .sv_syscallnames = freebsd32_syscallnames, .sv_schedtail = NULL, + .sv_thread_detach = NULL, }; INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec); @@ -418,12 +419,6 @@ freebsd32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) sfp = (struct sigframe32 *)((vm_offset_t)(td->td_frame->sp - sizeof(struct sigframe32)) & ~(sizeof(__int64_t) - 1)); - /* Translate the signal if appropriate */ - if (p->p_sysent->sv_sigtbl) { - if (sig <= p->p_sysent->sv_sigsize) - sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; - } - /* Build the argument list for the signal handler. */ td->td_frame->a0 = sig; td->td_frame->a2 = (register_t)(intptr_t)&sfp->sf_uc; diff --git a/sys/mips/mips/pm_machdep.c b/sys/mips/mips/pm_machdep.c index 7db671d..2ec211d 100644 --- a/sys/mips/mips/pm_machdep.c +++ b/sys/mips/mips/pm_machdep.c @@ -133,12 +133,6 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) sfp = (struct sigframe *)((vm_offset_t)(regs->sp - sizeof(struct sigframe)) & ~(sizeof(__int64_t) - 1)); - /* Translate the signal if appropriate */ - if (p->p_sysent->sv_sigtbl) { - if (sig <= p->p_sysent->sv_sigsize) - sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; - } - /* Build the argument list for the signal handler. */ regs->a0 = sig; regs->a2 = (register_t)(intptr_t)&sfp->sf_uc; diff --git a/sys/modules/Makefile b/sys/modules/Makefile index 609c72c..5135093 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -197,6 +197,8 @@ SUBDIR= \ ${_linprocfs} \ ${_linsysfs} \ ${_linux} \ + ${_linux_common} \ + ${_linux64} \ lmc \ lpt \ mac_biba \ @@ -749,6 +751,8 @@ _lindev= lindev _linprocfs= linprocfs _linsysfs= linsysfs _linux= linux +_linux64= linux64 +_linux_common= linux_common _mly= mly .if ${MK_OFED} != "no" || defined(ALL_MODULES) _mlx4= mlx4 diff --git a/sys/modules/i2c/controllers/Makefile b/sys/modules/i2c/controllers/Makefile index c9d9fbb..2b4432f 100644 --- a/sys/modules/i2c/controllers/Makefile +++ b/sys/modules/i2c/controllers/Makefile @@ -3,7 +3,7 @@ .if ${MACHINE} == "pc98" SUBDIR = lpbb .else -SUBDIR = alpm amdpm amdsmb ichsmb intpm nfsmb viapm lpbb pcf +SUBDIR = alpm amdpm amdsmb ichsmb intpm ismt nfsmb viapm lpbb pcf .endif .include <bsd.subdir.mk> diff --git a/sys/modules/i2c/controllers/ismt/Makefile b/sys/modules/i2c/controllers/ismt/Makefile new file mode 100644 index 0000000..411bab1 --- /dev/null +++ b/sys/modules/i2c/controllers/ismt/Makefile @@ -0,0 +1,8 @@ +#$FreeBSD$ + +.PATH: ${.CURDIR}/../../../../dev/ismt +KMOD = ismt +SRCS = device_if.h bus_if.h iicbb_if.h pci_if.h smbus_if.h \ + ismt.c + +.include <bsd.kmod.mk> diff --git a/sys/modules/if_gif/Makefile b/sys/modules/if_gif/Makefile index a501dd6..d8ba44c 100644 --- a/sys/modules/if_gif/Makefile +++ b/sys/modules/if_gif/Makefile @@ -5,11 +5,18 @@ .PATH: ${.CURDIR}/../../net ${.CURDIR}/../../netinet ${.CURDIR}/../../netinet6 KMOD= if_gif -SRCS= if_gif.c in_gif.c opt_inet.h opt_inet6.h opt_mrouting.h +SRCS= if_gif.c opt_inet.h opt_inet6.h opt_mrouting.h .if !defined(KERNBUILDDIR) +.if ${MK_INET_SUPPORT} != "no" opt_inet.h: echo "#define INET 1" > ${.TARGET} +.endif +.else +OPT_INET!= cat ${KERNBUILDDIR}/opt_inet.h; echo +.if empty(OPT_INET) +MK_INET_SUPPORT= no +.endif .if ${MK_INET6_SUPPORT} != "no" opt_inet6.h: @@ -25,6 +32,10 @@ MK_INET6_SUPPORT= no .endif .endif +.if ${MK_INET_SUPPORT} != "no" +SRCS+= in_gif.c +.endif + .if ${MK_INET6_SUPPORT} != "no" SRCS+= in6_gif.c .endif diff --git a/sys/modules/linprocfs/Makefile b/sys/modules/linprocfs/Makefile index 4b1b375..979429f 100644 --- a/sys/modules/linprocfs/Makefile +++ b/sys/modules/linprocfs/Makefile @@ -5,11 +5,6 @@ KMOD= linprocfs SRCS= vnode_if.h \ device_if.h bus_if.h \ - linprocfs.c \ - opt_compat.h - -.if ${MACHINE_CPUARCH} == "amd64" -CFLAGS+=-DCOMPAT_LINUX32 -.endif + linprocfs.c .include <bsd.kmod.mk> diff --git a/sys/modules/linsysfs/Makefile b/sys/modules/linsysfs/Makefile index 4017967..13230ff 100644 --- a/sys/modules/linsysfs/Makefile +++ b/sys/modules/linsysfs/Makefile @@ -5,11 +5,6 @@ KMOD= linsysfs SRCS= vnode_if.h \ device_if.h bus_if.h pci_if.h \ - linsysfs.c \ - opt_compat.h - -.if ${MACHINE_CPUARCH} == "amd64" -CFLAGS+=-DCOMPAT_LINUX32 -.endif + linsysfs.c .include <bsd.kmod.mk> diff --git a/sys/modules/linux/Makefile b/sys/modules/linux/Makefile index c10cb10..0e70ce6 100644 --- a/sys/modules/linux/Makefile +++ b/sys/modules/linux/Makefile @@ -7,15 +7,18 @@ CFLAGS+=-DCOMPAT_FREEBSD32 -DCOMPAT_LINUX32 .PATH: ${.CURDIR}/../../compat/linux ${.CURDIR}/../../${MACHINE_CPUARCH}/linux${SFX} +VDSO= linux${SFX}_vdso + KMOD= linux -SRCS= linux_fork.c linux${SFX}_dummy.c linux_emul.c linux_file.c \ +SRCS= linux_fork.c linux${SFX}_dummy.c linux_file.c linux_event.c \ linux_futex.c linux_getcwd.c linux_ioctl.c linux_ipc.c \ - linux${SFX}_machdep.c linux_mib.c linux_misc.c linux_signal.c \ + linux${SFX}_machdep.c linux_misc.c linux_signal.c \ linux_socket.c linux_stats.c linux_sysctl.c linux${SFX}_sysent.c \ - linux${SFX}_sysvec.c linux_uid16.c linux_util.c linux_time.c \ - linux_timer.c \ + linux${SFX}_sysvec.c linux_uid16.c linux_time.c \ + linux_timer.c linux_vdso.c \ opt_inet6.h opt_compat.h opt_kdtrace.h opt_posix.h opt_usb.h \ - vnode_if.h device_if.h bus_if.h assym.s + vnode_if.h device_if.h bus_if.h assym.s \ + linux${SFX}_support.s DPSRCS= linux${SFX}_genassym.c # XXX: for assym.s @@ -24,37 +27,50 @@ SRCS+= opt_kstack_pages.h opt_nfs.h opt_compat.h opt_hwpmc_hooks.h SRCS+= opt_apic.h .endif -OBJS= linux${SFX}_locore.o linux${SFX}_support.o +OBJS= ${VDSO}.so .if ${MACHINE_CPUARCH} == "i386" -SRCS+= linux_ptrace.c imgact_linux.c opt_cpu.h +SRCS+= linux_ptrace.c imgact_linux.c linux_util.c linux_mib.c \ + linux_emul.c opt_cpu.h linux.c .endif +.if ${MACHINE_CPUARCH} == "i386" EXPORT_SYMS= EXPORT_SYMS+= linux_emul_path EXPORT_SYMS+= linux_get_osname EXPORT_SYMS+= linux_get_osrelease -EXPORT_SYMS+= linux_ifname EXPORT_SYMS+= linux_ioctl_register_handler EXPORT_SYMS+= linux_ioctl_unregister_handler +.endif -CLEANFILES= linux${SFX}_assym.h linux${SFX}_genassym.o +CLEANFILES= linux${SFX}_assym.h linux${SFX}_genassym.o linux${SFX}_locore.o linux${SFX}_assym.h: linux${SFX}_genassym.o -.if exists(@) -linux${SFX}_assym.h: @/kern/genassym.sh -.endif - sh @/kern/genassym.sh linux${SFX}_genassym.o > ${.TARGET} + sh ${SYSDIR}/kern/genassym.sh linux${SFX}_genassym.o > ${.TARGET} -linux${SFX}_locore.o: linux${SFX}_locore.s linux${SFX}_assym.h - ${CC} -c -x assembler-with-cpp -DLOCORE ${CFLAGS} \ +linux${SFX}_locore.o: linux${SFX}_assym.h assym.s + ${CC} -x assembler-with-cpp -DLOCORE -m32 -shared -s \ + -pipe -I. -I${SYSDIR} -Werror -Wall -fno-common -nostdinc -nostdlib \ + -fno-omit-frame-pointer \ + -Wl,-T${.CURDIR}/../../${MACHINE_CPUARCH}/linux${SFX}/${VDSO}.lds.s \ + -Wl,-soname=${VDSO}.so.1,--eh-frame-hdr,-fPIC,-warn-common \ ${.IMPSRC} -o ${.TARGET} -linux${SFX}_support.o: linux${SFX}_support.s assym.s linux${SFX}_assym.h +linux${SFX}_support.o: linux${SFX}_assym.h assym.s ${CC} -c -x assembler-with-cpp -DLOCORE ${CFLAGS} \ ${.IMPSRC} -o ${.TARGET} -linux${SFX}_genassym.o: linux${SFX}_genassym.c linux.h @ machine x86 +.if ${MACHINE_CPUARCH} == "amd64" +${VDSO}.so: linux${SFX}_locore.o + ${OBJCOPY} --input-target binary --output-target elf64-x86-64-freebsd \ + --binary-architecture i386 linux${SFX}_locore.o ${.TARGET} +.else +${VDSO}.so: linux${SFX}_locore.o + ${OBJCOPY} --input-target binary --output-target elf32-i386-freebsd \ + --binary-architecture i386 linux${SFX}_locore.o ${.TARGET} +.endif + +linux${SFX}_genassym.o: ${CC} -c ${CFLAGS:N-fno-common} ${.IMPSRC} .if !defined(KERNBUILDDIR) @@ -63,6 +79,9 @@ opt_inet6.h: .if defined(KTR) CFLAGS+= -DKTR .endif +.if defined(DEBUG) +CFLAGS+= -DDEBUG +.endif .endif .include <bsd.kmod.mk> diff --git a/sys/modules/linux64/Makefile b/sys/modules/linux64/Makefile new file mode 100644 index 0000000..1656323 --- /dev/null +++ b/sys/modules/linux64/Makefile @@ -0,0 +1,55 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../compat/linux ${.CURDIR}/../../${MACHINE_ARCH}/linux + +VDSO= linux_vdso + +KMOD= linux64 +SRCS= linux_fork.c linux_dummy.c linux_file.c linux_event.c \ + linux_futex.c linux_getcwd.c linux_ioctl.c linux_ipc.c \ + linux_machdep.c linux_misc.c linux_signal.c \ + linux_socket.c linux_stats.c linux_sysctl.c linux_sysent.c \ + linux_sysvec.c linux_time.c linux_vdso.c linux_timer.c \ + opt_inet6.h opt_compat.h opt_kdtrace.h opt_posix.h opt_usb.h \ + vnode_if.h device_if.h bus_if.h assym.s \ + linux_support.s +DPSRCS= linux_genassym.c + +# XXX: for assym.s +SRCS+= opt_kstack_pages.h opt_nfs.h opt_apic.h opt_hwpmc_hooks.h + +CLEANFILES= linux_assym.h linux_genassym.o linux_locore.o + +OBJS= ${VDSO}.so + +linux_assym.h: linux_genassym.o + sh ${SYSDIR}/kern/genassym.sh linux_genassym.o > ${.TARGET} + +linux_locore.o: linux_locore.s linux_assym.h + ${CC} -x assembler-with-cpp -DLOCORE -shared -mcmodel=small \ + -pipe -I. -I${SYSDIR} -Werror -Wall -fno-common -nostdinc \ + -Wl,-T${.CURDIR}/../../${MACHINE_CPUARCH}/linux/${VDSO}.lds.s \ + -Wl,-soname=${VDSO}.so.1,-fPIC,-warn-common -nostdlib \ + ${.IMPSRC} -o ${.TARGET} + +${VDSO}.so: linux_locore.o + ${OBJCOPY} --input-target binary --output-target elf64-x86-64-freebsd \ + -S -g --binary-architecture i386:x86-64 linux_locore.o ${.TARGET} + +linux_support.o: assym.s linux_assym.h + ${CC} -c -x assembler-with-cpp -DLOCORE ${CFLAGS} \ + ${.IMPSRC} -o ${.TARGET} + +linux_genassym.o: + ${CC} -c ${CFLAGS:N-fno-common} ${.IMPSRC} + +.if !defined(KERNBUILDDIR) +.if defined(DEBUG) +CFLAGS+=-DDEBUG +.endif +.if defined(KTR) +CFLAGS+=-DKTR +.endif +.endif + +.include <bsd.kmod.mk> diff --git a/sys/modules/linux_common/Makefile b/sys/modules/linux_common/Makefile new file mode 100644 index 0000000..91449f7 --- /dev/null +++ b/sys/modules/linux_common/Makefile @@ -0,0 +1,25 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../compat/linux + +KMOD= linux_common +SRCS= linux_common.c linux_mib.c linux_util.c linux_emul.c \ + linux.c opt_compat.h device_if.h vnode_if.h bus_if.h + +EXPORT_SYMS= +EXPORT_SYMS+= linux_emul_path +EXPORT_SYMS+= linux_ioctl_register_handler +EXPORT_SYMS+= linux_ioctl_unregister_handler +EXPORT_SYMS+= linux_get_osname +EXPORT_SYMS+= linux_get_osrelease + +.if !defined(KERNBUILDDIR) +.if defined(DEBUG) +CFLAGS+=-DDEBUG +.endif +.if defined(KTR) +CFLAGS+=-DKTR +.endif +.endif + +.include <bsd.kmod.mk> diff --git a/sys/modules/pseudofs/Makefile b/sys/modules/pseudofs/Makefile index d5696c5..6ddb749 100644 --- a/sys/modules/pseudofs/Makefile +++ b/sys/modules/pseudofs/Makefile @@ -23,4 +23,10 @@ EXPORT_SYMS= pfs_mount \ pfs_enable \ pfs_destroy +.if !defined(KERNBUILDDIR) +.if defined(PSEUDOFS_TRACE) +CFLAGS+=-DPSEUDOFS_TRACE +.endif +.endif + .include <bsd.kmod.mk> diff --git a/sys/net/if_gif.c b/sys/net/if_gif.c index 589fa3f..c2d1b54 100644 --- a/sys/net/if_gif.c +++ b/sys/net/if_gif.c @@ -527,7 +527,6 @@ gif_input(struct mbuf *m, struct ifnet *ifp, int proto, uint8_t ecn) struct gif_softc *sc; struct ether_header *eh; struct ifnet *oldifp; - uint32_t gif_options; int isr, n, af; if (ifp == NULL) { @@ -536,7 +535,6 @@ gif_input(struct mbuf *m, struct ifnet *ifp, int proto, uint8_t ecn) return; } sc = ifp->if_softc; - gif_options = sc->gif_options; m->m_pkthdr.rcvif = ifp; m_clrprotoflags(m); switch (proto) { diff --git a/sys/net/if_gre.c b/sys/net/if_gre.c index 17a324c..bad9dd5 100644 --- a/sys/net/if_gre.c +++ b/sys/net/if_gre.c @@ -682,7 +682,10 @@ gre_input(struct mbuf **mp, int *offp, int proto) struct grehdr *gh; struct ifnet *ifp; struct mbuf *m; - uint32_t *opts, key; + uint32_t *opts; +#ifdef notyet + uint32_t key; +#endif uint16_t flags; int hlen, isr, af; @@ -715,17 +718,27 @@ gre_input(struct mbuf **mp, int *offp, int proto) opts++; } if (flags & GRE_FLAGS_KP) { +#ifdef notyet + /* + * XXX: The current implementation uses the key only for outgoing + * packets. But we can check the key value here, or even in the + * encapcheck function. + */ key = ntohl(*opts); +#endif hlen += sizeof(uint32_t); opts++; + } +#ifdef notyet } else key = 0; - /* if (sc->gre_key != 0 && (key != sc->gre_key || key != 0)) goto drop; - */ +#endif if (flags & GRE_FLAGS_SP) { - /* seq = ntohl(*opts); */ +#ifdef notyet + seq = ntohl(*opts); +#endif hlen += sizeof(uint32_t); } switch (ntohs(gh->gre_proto)) { diff --git a/sys/netinet/cc/cc_cubic.c b/sys/netinet/cc/cc_cubic.c index 17a6985..339ee6f 100644 --- a/sys/netinet/cc/cc_cubic.c +++ b/sys/netinet/cc/cc_cubic.c @@ -299,8 +299,10 @@ static void cubic_post_recovery(struct cc_var *ccv) { struct cubic *cubic_data; + int pipe; cubic_data = ccv->cc_data; + pipe = 0; /* Fast convergence heuristic. */ if (cubic_data->max_cwnd < cubic_data->prev_max_cwnd) @@ -315,10 +317,13 @@ cubic_post_recovery(struct cc_var *ccv) * * XXXLAS: Find a way to do this without needing curack */ - if (SEQ_GT(ccv->curack + CCV(ccv, snd_ssthresh), - CCV(ccv, snd_max))) - CCV(ccv, snd_cwnd) = CCV(ccv, snd_max) - ccv->curack + - CCV(ccv, t_maxseg); + if (V_tcp_do_rfc6675_pipe) + pipe = tcp_compute_pipe(ccv->ccvc.tcp); + else + pipe = CCV(ccv, snd_max) - ccv->curack; + + if (pipe < CCV(ccv, snd_ssthresh)) + CCV(ccv, snd_cwnd) = pipe + CCV(ccv, t_maxseg); else /* Update cwnd based on beta and adjusted max_cwnd. */ CCV(ccv, snd_cwnd) = max(1, ((CUBIC_BETA * diff --git a/sys/netinet/cc/cc_newreno.c b/sys/netinet/cc/cc_newreno.c index 96d64fe..31b70cc 100644 --- a/sys/netinet/cc/cc_newreno.c +++ b/sys/netinet/cc/cc_newreno.c @@ -214,6 +214,9 @@ newreno_cong_signal(struct cc_var *ccv, uint32_t type) static void newreno_post_recovery(struct cc_var *ccv) { + int pipe; + pipe = 0; + if (IN_FASTRECOVERY(CCV(ccv, t_flags))) { /* * Fast recovery will conclude after returning from this @@ -224,10 +227,13 @@ newreno_post_recovery(struct cc_var *ccv) * * XXXLAS: Find a way to do this without needing curack */ - if (SEQ_GT(ccv->curack + CCV(ccv, snd_ssthresh), - CCV(ccv, snd_max))) - CCV(ccv, snd_cwnd) = CCV(ccv, snd_max) - - ccv->curack + CCV(ccv, t_maxseg); + if (V_tcp_do_rfc6675_pipe) + pipe = tcp_compute_pipe(ccv->ccvc.tcp); + else + pipe = CCV(ccv, snd_max) - ccv->curack; + + if (pipe < CCV(ccv, snd_ssthresh)) + CCV(ccv, snd_cwnd) = pipe + CCV(ccv, t_maxseg); else CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh); } diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index a59874e..114802e 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -148,6 +148,11 @@ SYSCTL_VNET_INT(_net_inet_tcp, OID_AUTO, drop_synfin, CTLFLAG_RW, &VNET_NAME(drop_synfin), 0, "Drop TCP packets with SYN+FIN set"); +VNET_DEFINE(int, tcp_do_rfc6675_pipe) = 0; +SYSCTL_INT(_net_inet_tcp, OID_AUTO, do_pipe, CTLFLAG_VNET | CTLFLAG_RW, + &VNET_NAME(tcp_do_rfc6675_pipe), 0, + "Use calculated pipe/in-flight bytes per RFC 6675"); + VNET_DEFINE(int, tcp_do_rfc3042) = 1; #define V_tcp_do_rfc3042 VNET(tcp_do_rfc3042) SYSCTL_VNET_INT(_net_inet_tcp, OID_AUTO, rfc3042, CTLFLAG_RW, @@ -1441,7 +1446,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, int drop_hdrlen, int tlen, uint8_t iptos, int ti_locked) { - int thflags, acked, ourfinisacked, needoutput = 0; + int thflags, acked, ourfinisacked, needoutput = 0, sack_changed; int rstreason, todrop, win; u_long tiwin; char *s; @@ -1462,6 +1467,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, thflags = th->th_flags; inc = &tp->t_inpcb->inp_inc; tp->sackhint.last_sack_ack = 0; + sack_changed = 0; /* * If this is either a state-changing packet or current state isn't @@ -2452,13 +2458,21 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, if ((tp->t_flags & TF_SACK_PERMIT) && ((to.to_flags & TOF_SACK) || !TAILQ_EMPTY(&tp->snd_holes))) - tcp_sack_doack(tp, &to, th->th_ack); + sack_changed = tcp_sack_doack(tp, &to, th->th_ack); + else + /* + * Reset the value so that previous (valid) value + * from the last ack with SACK doesn't get used. + */ + tp->sackhint.sacked_bytes = 0; /* Run HHOOK_TCP_ESTABLISHED_IN helper hooks. */ hhook_run_tcp_est_in(tp, th, &to); if (SEQ_LEQ(th->th_ack, tp->snd_una)) { - if (tlen == 0 && tiwin == tp->snd_wnd) { + if (tlen == 0 && + (tiwin == tp->snd_wnd || + (tp->t_flags & TF_SACK_PERMIT))) { TCPSTAT_INC(tcps_rcvdupack); /* * If we have outstanding data (other than @@ -2487,8 +2501,20 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, * When using TCP ECN, notify the peer that * we reduced the cwnd. */ - if (!tcp_timer_active(tp, TT_REXMT) || - th->th_ack != tp->snd_una) + /* + * Following 2 kinds of acks should not affect + * dupack counting: + * 1) Old acks + * 2) Acks with SACK but without any new SACK + * information in them. These could result from + * any anomaly in the network like a switch + * duplicating packets or a possible DoS attack. + */ + if (th->th_ack != tp->snd_una || + ((tp->t_flags & TF_SACK_PERMIT) && + !sack_changed)) + break; + else if (!tcp_timer_active(tp, TT_REXMT)) tp->t_dupacks = 0; else if (++tp->t_dupacks > tcprexmtthresh || IN_FASTRECOVERY(tp->t_flags)) { @@ -2503,8 +2529,12 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, * we have less than 1/2 the original window's * worth of data in flight. */ - awnd = (tp->snd_nxt - tp->snd_fack) + - tp->sackhint.sack_bytes_rexmit; + if (V_tcp_do_rfc6675_pipe) + awnd = tcp_compute_pipe(tp); + else + awnd = (tp->snd_nxt - tp->snd_fack) + + tp->sackhint.sack_bytes_rexmit; + if (awnd < tp->snd_ssthresh) { tp->snd_cwnd += tp->t_maxseg; if (tp->snd_cwnd > tp->snd_ssthresh) @@ -2643,9 +2673,20 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, tp->snd_cwnd = oldcwnd; goto drop; } - } else - tp->t_dupacks = 0; + } break; + } else { + /* + * This ack is advancing the left edge, reset the + * counter. + */ + tp->t_dupacks = 0; + /* + * If this ack also has new SACK info, increment the + * counter as per rfc6675. + */ + if ((tp->t_flags & TF_SACK_PERMIT) && sack_changed) + tp->t_dupacks++; } KASSERT(SEQ_GT(th->th_ack, tp->snd_una), @@ -2664,7 +2705,6 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, } else cc_post_recovery(tp, th); } - tp->t_dupacks = 0; /* * If we reach this point, ACK is not a duplicate, * i.e., it ACKs something we sent. @@ -3796,3 +3836,11 @@ tcp_newreno_partial_ack(struct tcpcb *tp, struct tcphdr *th) tp->snd_cwnd = 0; tp->snd_cwnd += tp->t_maxseg; } + +int +tcp_compute_pipe(struct tcpcb *tp) +{ + return (tp->snd_max - tp->snd_una + + tp->sackhint.sack_bytes_rexmit - + tp->sackhint.sacked_bytes); +} diff --git a/sys/netinet/tcp_sack.c b/sys/netinet/tcp_sack.c index 440bd64..0ea6916 100644 --- a/sys/netinet/tcp_sack.c +++ b/sys/netinet/tcp_sack.c @@ -344,17 +344,22 @@ tcp_sackhole_remove(struct tcpcb *tp, struct sackhole *hole) * Process cumulative ACK and the TCP SACK option to update the scoreboard. * tp->snd_holes is an ordered list of holes (oldest to newest, in terms of * the sequence space). + * Returns 1 if incoming ACK has previously unknown SACK information, + * 0 otherwise. Note: We treat (snd_una, th_ack) as a sack block so any changes + * to that (i.e. left edge moving) would also be considered a change in SACK + * information which is slightly different than rfc6675. */ -void +int tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack) { struct sackhole *cur, *temp; struct sackblk sack, sack_blocks[TCP_MAX_SACK + 1], *sblkp; - int i, j, num_sack_blks; + int i, j, num_sack_blks, sack_changed; INP_WLOCK_ASSERT(tp->t_inpcb); num_sack_blks = 0; + sack_changed = 0; /* * If SND.UNA will be advanced by SEG.ACK, and if SACK holes exist, * treat [SND.UNA, SEG.ACK) as if it is a SACK block. @@ -368,6 +373,7 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack) * received new blocks from the other side. */ if (to->to_flags & TOF_SACK) { + tp->sackhint.sacked_bytes = 0; /* reset */ for (i = 0; i < to->to_nsacks; i++) { bcopy((to->to_sacks + i * TCPOLEN_SACK), &sack, sizeof(sack)); @@ -378,8 +384,11 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack) SEQ_GT(sack.start, th_ack) && SEQ_LT(sack.start, tp->snd_max) && SEQ_GT(sack.end, tp->snd_una) && - SEQ_LEQ(sack.end, tp->snd_max)) + SEQ_LEQ(sack.end, tp->snd_max)) { sack_blocks[num_sack_blks++] = sack; + tp->sackhint.sacked_bytes += + (sack.end-sack.start); + } } } /* @@ -387,7 +396,7 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack) * received. */ if (num_sack_blks == 0) - return; + return (sack_changed); /* * Sort the SACK blocks so we can update the scoreboard with just one @@ -438,6 +447,7 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack) tp->snd_fack = sblkp->end; /* Go to the previous sack block. */ sblkp--; + sack_changed = 1; } else { /* * We failed to add a new hole based on the current @@ -454,9 +464,11 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack) SEQ_LT(tp->snd_fack, sblkp->end)) tp->snd_fack = sblkp->end; } - } else if (SEQ_LT(tp->snd_fack, sblkp->end)) + } else if (SEQ_LT(tp->snd_fack, sblkp->end)) { /* fack is advanced. */ tp->snd_fack = sblkp->end; + sack_changed = 1; + } /* We must have at least one SACK hole in scoreboard. */ KASSERT(!TAILQ_EMPTY(&tp->snd_holes), ("SACK scoreboard must not be empty")); @@ -485,6 +497,7 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack) tp->sackhint.sack_bytes_rexmit -= (cur->rxmit - cur->start); KASSERT(tp->sackhint.sack_bytes_rexmit >= 0, ("sackhint bytes rtx >= 0")); + sack_changed = 1; if (SEQ_LEQ(sblkp->start, cur->start)) { /* Data acks at least the beginning of hole. */ if (SEQ_GEQ(sblkp->end, cur->end)) { @@ -540,6 +553,7 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack) else sblkp--; } + return (sack_changed); } /* diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c index 8d2cc98..fe2eb0b 100644 --- a/sys/netinet/tcp_syncache.c +++ b/sys/netinet/tcp_syncache.c @@ -1852,6 +1852,7 @@ syncookie_mac(struct in_conninfo *inc, tcp_seq irs, uint8_t flags, } SipHash_Update(&ctx, &inc->inc_fport, sizeof(inc->inc_fport)); SipHash_Update(&ctx, &inc->inc_lport, sizeof(inc->inc_lport)); + SipHash_Update(&ctx, &irs, sizeof(irs)); SipHash_Update(&ctx, &flags, sizeof(flags)); SipHash_Update(&ctx, &secmod, sizeof(secmod)); SipHash_Final((u_int8_t *)&siphash, &ctx); diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h index cff81c5..f422d8a 100644 --- a/sys/netinet/tcp_var.h +++ b/sys/netinet/tcp_var.h @@ -73,7 +73,12 @@ struct sackhint { tcp_seq last_sack_ack; /* Most recent/largest sacked ack */ int ispare; /* explicit pad for 64bit alignment */ - uint64_t _pad[2]; /* 1 sacked_bytes, 1 TBD */ + int sacked_bytes; /* + * Total sacked bytes reported by the + * receiver via sack option + */ + uint32_t _pad1[1]; /* TBD */ + uint64_t _pad[1]; /* TBD */ }; struct tcptemp { @@ -668,6 +673,9 @@ VNET_DECLARE(int, tcp_ecn_maxretries); VNET_DECLARE(struct hhook_head *, tcp_hhh[HHOOK_TCP_LAST + 1]); #define V_tcp_hhh VNET(tcp_hhh) +VNET_DECLARE(int, tcp_do_rfc6675_pipe); +#define V_tcp_do_rfc6675_pipe VNET(tcp_do_rfc6675_pipe) + int tcp_addoptions(struct tcpopt *, u_char *); int tcp_ccalgounload(struct cc_algo *unload_algo); struct tcpcb * @@ -748,7 +756,7 @@ void tcp_hc_update(struct in_conninfo *, struct hc_metrics_lite *); extern struct pr_usrreqs tcp_usrreqs; tcp_seq tcp_new_isn(struct tcpcb *); -void tcp_sack_doack(struct tcpcb *, struct tcpopt *, tcp_seq); +int tcp_sack_doack(struct tcpcb *, struct tcpopt *, tcp_seq); void tcp_update_sack_list(struct tcpcb *tp, tcp_seq rcv_laststart, tcp_seq rcv_lastend); void tcp_clean_sackreport(struct tcpcb *tp); void tcp_sack_adjust(struct tcpcb *tp); @@ -757,6 +765,7 @@ void tcp_sack_partialack(struct tcpcb *, struct tcphdr *); void tcp_free_sackholes(struct tcpcb *tp); int tcp_newreno(struct tcpcb *, struct tcphdr *); u_long tcp_seq_subtract(u_long, u_long ); +int tcp_compute_pipe(struct tcpcb *); void cc_cong_signal(struct tcpcb *tp, struct tcphdr *th, uint32_t type); diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index 28a830f..f07f670 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -2449,6 +2449,7 @@ in6_if2idlen(struct ifnet *ifp) #ifdef IFT_MIP case IFT_MIP: /* ditto */ #endif + case IFT_BRIDGE: /* bridge(4) only does Ethernet-like links */ case IFT_INFINIBAND: return (64); case IFT_FDDI: /* RFC2467 */ diff --git a/sys/ofed/include/linux/file.h b/sys/ofed/include/linux/file.h index 1f72822..38ae4c9 100644 --- a/sys/ofed/include/linux/file.h +++ b/sys/ofed/include/linux/file.h @@ -95,10 +95,11 @@ fd_install(unsigned int fd, struct linux_file *filp) if (fget_unlocked(curthread->td_proc->p_fd, fd, NULL, 0, &file, NULL) != 0) { - file = NULL; + filp->_file = NULL; + } else { + filp->_file = file; + finit(file, filp->f_mode, DTYPE_DEV, filp, &linuxfileops); } - filp->_file = file; - finit(file, filp->f_mode, DTYPE_DEV, filp, &linuxfileops); /* drop the extra reference */ fput(filp); diff --git a/sys/powerpc/powerpc/elf32_machdep.c b/sys/powerpc/powerpc/elf32_machdep.c index b8f4bed..e8d563a 100644 --- a/sys/powerpc/powerpc/elf32_machdep.c +++ b/sys/powerpc/powerpc/elf32_machdep.c @@ -107,6 +107,7 @@ struct sysentvec elf32_freebsd_sysvec = { .sv_shared_page_base = FREEBSD32_SHAREDPAGE, .sv_shared_page_len = PAGE_SIZE, .sv_schedtail = NULL, + .sv_thread_detach = NULL, }; INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec); diff --git a/sys/powerpc/powerpc/elf64_machdep.c b/sys/powerpc/powerpc/elf64_machdep.c index 558cf0a..4324266 100644 --- a/sys/powerpc/powerpc/elf64_machdep.c +++ b/sys/powerpc/powerpc/elf64_machdep.c @@ -83,6 +83,7 @@ struct sysentvec elf64_freebsd_sysvec = { .sv_shared_page_base = SHAREDPAGE, .sv_shared_page_len = PAGE_SIZE, .sv_schedtail = NULL, + .sv_thread_detach = NULL, }; INIT_SYSENTVEC(elf64_sysvec, &elf64_freebsd_sysvec); diff --git a/sys/powerpc/powerpc/exec_machdep.c b/sys/powerpc/powerpc/exec_machdep.c index 691cf2d..85d778e 100644 --- a/sys/powerpc/powerpc/exec_machdep.c +++ b/sys/powerpc/powerpc/exec_machdep.c @@ -231,12 +231,6 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) } /* - * Translate the signal if appropriate (Linux emu ?) - */ - if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) - sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; - - /* * Save the floating-point state, if necessary, then copy it. */ /* XXX */ diff --git a/sys/sparc64/sparc64/elf_machdep.c b/sys/sparc64/sparc64/elf_machdep.c index 621e643..0dab76d 100644 --- a/sys/sparc64/sparc64/elf_machdep.c +++ b/sys/sparc64/sparc64/elf_machdep.c @@ -87,6 +87,7 @@ static struct sysentvec elf64_freebsd_sysvec = { .sv_fetch_syscall_args = cpu_fetch_syscall_args, .sv_syscallnames = syscallnames, .sv_schedtail = NULL, + .sv_thread_detach = NULL, }; static Elf64_Brandinfo freebsd_brand_info = { diff --git a/sys/sparc64/sparc64/machdep.c b/sys/sparc64/sparc64/machdep.c index 07be1c8..dd6f31c 100644 --- a/sys/sparc64/sparc64/machdep.c +++ b/sys/sparc64/sparc64/machdep.c @@ -658,10 +658,6 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) fp = (struct frame *)sfp - 1; - /* Translate the signal if appropriate. */ - if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) - sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; - /* Build the argument list for the signal handler. */ tf->tf_out[0] = sig; tf->tf_out[2] = (register_t)&sfp->sf_uc; diff --git a/sys/sys/capsicum.h b/sys/sys/capsicum.h index 6ccb424..54b1c33 100644 --- a/sys/sys/capsicum.h +++ b/sys/sys/capsicum.h @@ -146,9 +146,9 @@ #define CAP_FSTATAT (CAP_FSTAT | CAP_LOOKUP) /* Allows for fstatfs(2). */ #define CAP_FSTATFS CAPRIGHT(0, 0x0000000000100000ULL) -/* Allows for futimes(2). */ +/* Allows for futimens(2) and futimes(2). */ #define CAP_FUTIMES CAPRIGHT(0, 0x0000000000200000ULL) -/* Allows for futimes(2) and futimesat(2). */ +/* Allows for futimens(2), futimes(2), futimesat(2) and utimensat(2). */ #define CAP_FUTIMESAT (CAP_FUTIMES | CAP_LOOKUP) /* Allows for linkat(2) and renameat(2) (destination directory descriptor). */ #define CAP_LINKAT (CAP_LOOKUP | 0x0000000000400000ULL) diff --git a/sys/sys/file.h b/sys/sys/file.h index e3bdbe9..a8112be 100644 --- a/sys/sys/file.h +++ b/sys/sys/file.h @@ -65,6 +65,7 @@ struct socket; #define DTYPE_PTS 10 /* pseudo teletype master device */ #define DTYPE_DEV 11 /* Device specific fd type */ #define DTYPE_PROCDESC 12 /* process descriptor */ +#define DTYPE_LINUXEFD 13 /* emulation eventfd type */ #ifdef _KERNEL diff --git a/sys/sys/param.h b/sys/sys/param.h index e58c77e..1fd1313 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -58,7 +58,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1002505 /* Master, propagated to newvers */ +#define __FreeBSD_version 1002508 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 5b441bc..119349a 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -323,6 +323,7 @@ struct thread { void *td_su; /* (k) FFS SU private */ u_int td_dbg_sc_code; /* (c) Syscall code to debugger. */ u_int td_dbg_sc_narg; /* (c) Syscall arg count to debugger.*/ + void *td_emuldata; /* Emulator state data */ }; struct mtx *thread_lock_block(struct thread *); @@ -616,6 +617,18 @@ struct proc { #define PROC_SUNLOCK(p) mtx_unlock_spin(&(p)->p_slock) #define PROC_SLOCK_ASSERT(p, type) mtx_assert(&(p)->p_slock, (type)) +#define PROC_STATLOCK(p) mtx_lock_spin(&(p)->p_slock) +#define PROC_STATUNLOCK(p) mtx_unlock_spin(&(p)->p_slock) +#define PROC_STATLOCK_ASSERT(p, type) mtx_assert(&(p)->p_slock, (type)) + +#define PROC_ITIMLOCK(p) mtx_lock_spin(&(p)->p_slock) +#define PROC_ITIMUNLOCK(p) mtx_unlock_spin(&(p)->p_slock) +#define PROC_ITIMLOCK_ASSERT(p, type) mtx_assert(&(p)->p_slock, (type)) + +#define PROC_PROFLOCK(p) mtx_lock_spin(&(p)->p_slock) +#define PROC_PROFUNLOCK(p) mtx_unlock_spin(&(p)->p_slock) +#define PROC_PROFLOCK_ASSERT(p, type) mtx_assert(&(p)->p_slock, (type)) + /* These flags are kept in p_flag. */ #define P_ADVLOCK 0x00001 /* Process may hold a POSIX advisory lock. */ #define P_CONTROLT 0x00002 /* Has a controlling terminal. */ diff --git a/sys/sys/reboot.h b/sys/sys/reboot.h index 6b8e25e..ebe688e 100644 --- a/sys/sys/reboot.h +++ b/sys/sys/reboot.h @@ -59,6 +59,7 @@ #define RB_RESERVED1 0x40000 /* reserved for internal use of boot blocks */ #define RB_RESERVED2 0x80000 /* reserved for internal use of boot blocks */ #define RB_PAUSE 0x100000 /* pause after each output line during probe */ +#define RB_REROOT 0x200000 /* unmount the rootfs and mount it again */ #define RB_MULTIPLE 0x20000000 /* use multiple consoles */ #define RB_BOOTINFO 0x80000000 /* have `struct bootinfo *' arg */ diff --git a/sys/sys/stat.h b/sys/sys/stat.h index 0f3284f..e6ff5a6 100644 --- a/sys/sys/stat.h +++ b/sys/sys/stat.h @@ -307,6 +307,11 @@ struct nstat { #endif /* __BSD_VISIBLE */ +#if __POSIX_VISIBLE >= 200809 +#define UTIME_NOW -1 +#define UTIME_OMIT -2 +#endif + #ifndef _KERNEL __BEGIN_DECLS #if __BSD_VISIBLE @@ -322,6 +327,9 @@ int fchmod(int, mode_t); #endif #if __POSIX_VISIBLE >= 200809 int fchmodat(int, const char *, mode_t, int); +int futimens(int fd, const struct timespec times[2]); +int utimensat(int fd, const char *path, const struct timespec times[2], + int flag); #endif int fstat(int, struct stat *); #if __BSD_VISIBLE diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h index 80f0941..19b76dd 100644 --- a/sys/sys/syscall.h +++ b/sys/sys/syscall.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: stable/10/sys/kern/syscalls.master 276955 2015-01-11 07:02:03Z dchagin + * created from FreeBSD: stable/10/sys/kern/syscalls.master 293474 2016-01-09 14:20:23Z dchagin */ #define SYS_syscall 0 @@ -465,4 +465,6 @@ #define SYS_aio_mlock 543 #define SYS_procctl 544 #define SYS_ppoll 545 -#define SYS_MAXSYSCALL 546 +#define SYS_futimens 546 +#define SYS_utimensat 547 +#define SYS_MAXSYSCALL 548 diff --git a/sys/sys/syscall.mk b/sys/sys/syscall.mk index 30014a1..334c591 100644 --- a/sys/sys/syscall.mk +++ b/sys/sys/syscall.mk @@ -1,7 +1,7 @@ # FreeBSD system call names. # DO NOT EDIT-- this file is automatically generated. # $FreeBSD$ -# created from FreeBSD: stable/10/sys/kern/syscalls.master 276955 2015-01-11 07:02:03Z dchagin +# created from FreeBSD: stable/10/sys/kern/syscalls.master 293474 2016-01-09 14:20:23Z dchagin MIASM = \ syscall.o \ exit.o \ @@ -412,4 +412,6 @@ MIASM = \ pipe2.o \ aio_mlock.o \ procctl.o \ - ppoll.o + ppoll.o \ + futimens.o \ + utimensat.o diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h index f59bbb9..e038c98 100644 --- a/sys/sys/syscallsubr.h +++ b/sys/sys/syscallsubr.h @@ -55,6 +55,7 @@ struct sendfile_args; struct sockaddr; struct stat; struct thr_param; +struct sched_param; struct __wrusage; int kern___getcwd(struct thread *td, char *buf, enum uio_seg bufseg, @@ -106,6 +107,8 @@ int kern_fstatfs(struct thread *td, int fd, struct statfs *buf); int kern_ftruncate(struct thread *td, int fd, off_t length); int kern_futimes(struct thread *td, int fd, struct timeval *tptr, enum uio_seg tptrseg); +int kern_futimens(struct thread *td, int fd, struct timespec *tptr, + enum uio_seg tptrseg); int kern_getdirentries(struct thread *td, int fd, char *buf, u_int count, long *basep, ssize_t *residp, enum uio_seg bufseg); int kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize, @@ -125,6 +128,10 @@ int kern_jail_get(struct thread *td, struct uio *options, int flags); int kern_jail_set(struct thread *td, struct uio *options, int flags); int kern_kevent(struct thread *td, int fd, int nchanges, int nevents, struct kevent_copyops *k_ops, const struct timespec *timeout); +int kern_kevent_fp(struct thread *td, struct file *fp, int nchanges, + int nevents, struct kevent_copyops *k_ops, + const struct timespec *timeout); +int kern_kqueue(struct thread *td, int flags); int kern_kldload(struct thread *td, const char *file, int *fileid); int kern_kldstat(struct thread *td, int fileid, struct kld_file_stat *stat); int kern_kldunload(struct thread *td, int fileid, int flags); @@ -193,8 +200,18 @@ int kern_renameat(struct thread *td, int oldfd, char *old, int newfd, int kern_rmdir(struct thread *td, char *path, enum uio_seg pathseg); int kern_rmdirat(struct thread *td, int fd, char *path, enum uio_seg pathseg); +int kern_sched_getparam(struct thread *td, struct thread *targettd, + struct sched_param *param); +int kern_sched_getscheduler(struct thread *td, struct thread *targettd, + int *policy); +int kern_sched_setparam(struct thread *td, struct thread *targettd, + struct sched_param *param); +int kern_sched_setscheduler(struct thread *td, struct thread *targettd, + int policy, struct sched_param *param); int kern_sched_rr_get_interval(struct thread *td, pid_t pid, struct timespec *ts); +int kern_sched_rr_get_interval_td(struct thread *td, struct thread *targettd, + struct timespec *ts); int kern_semctl(struct thread *td, int semid, int semnum, int cmd, union semun *arg, register_t *rval); int kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou, @@ -244,6 +261,8 @@ int kern_ktimer_settime(struct thread *td, int timer_id, int flags, int kern_ktimer_gettime(struct thread *td, int timer_id, struct itimerspec *val); int kern_ktimer_getoverrun(struct thread *td, int timer_id); +int kern_thr_alloc(struct proc *, int pages, struct thread **); +int kern_thr_exit(struct thread *td); int kern_thr_new(struct thread *td, struct thr_param *param); int kern_thr_suspend(struct thread *td, struct timespec *tsp); int kern_truncate(struct thread *td, char *path, enum uio_seg pathseg, @@ -255,6 +274,9 @@ int kern_utimes(struct thread *td, char *path, enum uio_seg pathseg, struct timeval *tptr, enum uio_seg tptrseg); int kern_utimesat(struct thread *td, int fd, char *path, enum uio_seg pathseg, struct timeval *tptr, enum uio_seg tptrseg); +int kern_utimensat(struct thread *td, int fd, char *path, + enum uio_seg pathseg, struct timespec *tptr, enum uio_seg tptrseg, + int follow); int kern_wait(struct thread *td, pid_t pid, int *status, int options, struct rusage *rup); int kern_wait6(struct thread *td, enum idtype idtype, id_t id, int *status, diff --git a/sys/sys/sysent.h b/sys/sys/sysent.h index c49db41..a93d552 100644 --- a/sys/sys/sysent.h +++ b/sys/sys/sysent.h @@ -130,6 +130,7 @@ struct sysentvec { uint32_t sv_timekeep_gen; void *sv_shared_page_obj; void (*sv_schedtail)(struct thread *); + void (*sv_thread_detach)(struct thread *); }; #define SV_ILP32 0x000100 diff --git a/sys/sys/sysproto.h b/sys/sys/sysproto.h index ab1a5b0..d8c84f7 100644 --- a/sys/sys/sysproto.h +++ b/sys/sys/sysproto.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: stable/10/sys/kern/syscalls.master 276955 2015-01-11 07:02:03Z dchagin + * created from FreeBSD: stable/10/sys/kern/syscalls.master 293474 2016-01-09 14:20:23Z dchagin */ #ifndef _SYS_SYSPROTO_H_ @@ -1825,6 +1825,16 @@ struct ppoll_args { char ts_l_[PADL_(const struct timespec *)]; const struct timespec * ts; char ts_r_[PADR_(const struct timespec *)]; char set_l_[PADL_(const sigset_t *)]; const sigset_t * set; char set_r_[PADR_(const sigset_t *)]; }; +struct futimens_args { + char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; + char times_l_[PADL_(struct timespec *)]; struct timespec * times; char times_r_[PADR_(struct timespec *)]; +}; +struct utimensat_args { + char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; + char times_l_[PADL_(struct timespec *)]; struct timespec * times; char times_r_[PADR_(struct timespec *)]; + char flag_l_[PADL_(int)]; int flag; char flag_r_[PADR_(int)]; +}; int nosys(struct thread *, struct nosys_args *); void sys_sys_exit(struct thread *, struct sys_exit_args *); int sys_fork(struct thread *, struct fork_args *); @@ -2219,6 +2229,8 @@ int sys_pipe2(struct thread *, struct pipe2_args *); int sys_aio_mlock(struct thread *, struct aio_mlock_args *); int sys_procctl(struct thread *, struct procctl_args *); int sys_ppoll(struct thread *, struct ppoll_args *); +int sys_futimens(struct thread *, struct futimens_args *); +int sys_utimensat(struct thread *, struct utimensat_args *); #ifdef COMPAT_43 @@ -2927,6 +2939,8 @@ int freebsd7_shmctl(struct thread *, struct freebsd7_shmctl_args *); #define SYS_AUE_aio_mlock AUE_NULL #define SYS_AUE_procctl AUE_NULL #define SYS_AUE_ppoll AUE_POLL +#define SYS_AUE_futimens AUE_FUTIMES +#define SYS_AUE_utimensat AUE_FUTIMESAT #undef PAD_ #undef PADL_ diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index e738212..3badf34 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -417,6 +417,7 @@ extern int vttoif_tab[]; * Global vnode data. */ extern struct vnode *rootvnode; /* root (i.e. "/") vnode */ +extern struct mount *rootdevmp; /* "/dev" mount */ extern int async_io_version; /* 0 or POSIX version of AIO i'face */ extern int desiredvnodes; /* number of vnodes desired */ extern struct uma_zone *namei_zone; diff --git a/sys/xen/xenbus/xenbusb.c b/sys/xen/xenbus/xenbusb.c index 1f84795..cf0d673 100644 --- a/sys/xen/xenbus/xenbusb.c +++ b/sys/xen/xenbus/xenbusb.c @@ -561,7 +561,6 @@ xenbusb_devices_changed(struct xs_watch *watch, const char **vec, struct xenbusb_softc *xbs; device_t dev; char *node; - char *bus; char *type; char *id; char *p; @@ -580,7 +579,6 @@ xenbusb_devices_changed(struct xs_watch *watch, const char **vec, p = strchr(node, '/'); if (p == NULL) goto out; - bus = node; *p = 0; type = p + 1; |