diff options
author | David S. Miller <davem@davemloft.net> | 2008-04-20 02:14:23 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-04-21 15:10:15 -0700 |
commit | ec98c6b9b47df6df1c1fa6cf3d427414f8c2cf16 (patch) | |
tree | b144d907e47f8ade53296bd19850af708692386f /arch/sparc64 | |
parent | 3925e6fc1f774048404fdd910b0345b06c699eb4 (diff) |
[SPARC]: Remove SunOS and Solaris binary support.
As per Documentation/feature-removal-schedule.txt
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64')
29 files changed, 37 insertions, 8104 deletions
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index 463d1be32c9..b782d874759 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig @@ -87,9 +87,6 @@ config GENERIC_HARDIRQS_NO__DO_IRQ bool def_bool y -config ARCH_SUPPORTS_AOUT - def_bool y - choice prompt "Kernel page size" default SPARC64_PAGE_SIZE_8KB @@ -147,11 +144,6 @@ config HOTPLUG_CPU source "init/Kconfig" -config SYSVIPC_COMPAT - bool - depends on COMPAT && SYSVIPC - default y - config GENERIC_HARDIRQS bool default y @@ -379,6 +371,10 @@ config SUN_OPENPROMFS To compile the /proc/openprom support as a module, choose M here: the module will be called openpromfs. If unsure, choose M. +menu "Executable file formats" + +source "fs/Kconfig.binfmt" + config SPARC32_COMPAT bool "Kernel support for Linux/Sparc 32bit binary compatibility" help @@ -391,37 +387,10 @@ config COMPAT default y select COMPAT_BINFMT_ELF -config BINFMT_AOUT32 - bool "Kernel support for 32-bit (ie. SunOS) a.out binaries" - depends on SPARC32_COMPAT && ARCH_SUPPORTS_AOUT - help - This allows you to run 32-bit a.out format binaries on your Ultra. - If you want to run SunOS binaries (see SunOS binary emulation below) - or other a.out binaries, say Y. If unsure, say N. - -menu "Executable file formats" - -source "fs/Kconfig.binfmt" - -config SUNOS_EMUL - bool "SunOS binary emulation" - depends on BINFMT_AOUT32 - help - This allows you to run most SunOS binaries. If you want to do this, - say Y here and place appropriate files in /usr/gnemul/sunos. See - <http://www.ultralinux.org/faq.html> for more information. If you - want to run SunOS binaries on an Ultra you must also say Y to - "Kernel support for 32-bit a.out binaries" above. - -config SOLARIS_EMUL - tristate "Solaris binary emulation (EXPERIMENTAL)" - depends on SPARC32_COMPAT && NET && EXPERIMENTAL - help - This is experimental code which will enable you to run (many) - Solaris binaries on your SPARC Linux machine. - - To compile this code as a module, choose M here: the - module will be called solaris. +config SYSVIPC_COMPAT + bool + depends on COMPAT && SYSVIPC + default y endmenu diff --git a/arch/sparc64/Makefile b/arch/sparc64/Makefile index f0c22f82698..9cb75c852b4 100644 --- a/arch/sparc64/Makefile +++ b/arch/sparc64/Makefile @@ -27,7 +27,6 @@ endif head-y := arch/sparc64/kernel/head.o arch/sparc64/kernel/init_task.o core-y += arch/sparc64/kernel/ arch/sparc64/mm/ -core-$(CONFIG_SOLARIS_EMUL) += arch/sparc64/solaris/ core-y += arch/sparc64/math-emu/ libs-y += arch/sparc64/prom/ arch/sparc64/lib/ drivers-$(CONFIG_OPROFILE) += arch/sparc64/oprofile/ diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index 9d4bd222949..e1835868ad3 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.25-rc3 -# Wed Mar 26 04:33:35 2008 +# Linux kernel version: 2.6.25 +# Sun Apr 20 01:33:21 2008 # CONFIG_SPARC=y CONFIG_SPARC64=y @@ -22,7 +22,6 @@ CONFIG_HAVE_SETUP_PER_CPU_AREA=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_OF=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_ARCH_SUPPORTS_AOUT=y CONFIG_SPARC64_PAGE_SIZE_8KB=y # CONFIG_SPARC64_PAGE_SIZE_64KB is not set # CONFIG_SPARC64_PAGE_SIZE_512KB is not set @@ -61,6 +60,7 @@ CONFIG_RT_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y CONFIG_RELAY=y CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set @@ -100,7 +100,9 @@ CONFIG_PROFILING=y CONFIG_OPROFILE=m CONFIG_HAVE_OPROFILE=y CONFIG_KPROBES=y +CONFIG_KRETPROBES=y CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y CONFIG_PROC_PAGE_MONITOR=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -131,8 +133,6 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" CONFIG_CLASSIC_RCU=y -# CONFIG_PREEMPT_RCU is not set -CONFIG_SYSVIPC_COMPAT=y CONFIG_GENERIC_HARDIRQS=y # @@ -182,9 +182,6 @@ CONFIG_PCI_MSI=y # CONFIG_PCI_LEGACY is not set # CONFIG_PCI_DEBUG is not set CONFIG_SUN_OPENPROMFS=m -CONFIG_SPARC32_COMPAT=y -CONFIG_COMPAT=y -# CONFIG_BINFMT_AOUT32 is not set # # Executable file formats @@ -192,13 +189,14 @@ CONFIG_COMPAT=y CONFIG_BINFMT_ELF=y CONFIG_COMPAT_BINFMT_ELF=y CONFIG_BINFMT_MISC=m -CONFIG_SOLARIS_EMUL=y +CONFIG_SPARC32_COMPAT=y +CONFIG_COMPAT=y +CONFIG_SYSVIPC_COMPAT=y CONFIG_SCHED_SMT=y CONFIG_SCHED_MC=y # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set -# CONFIG_RCU_TRACE is not set # CONFIG_CMDLINE_BOOL is not set # @@ -263,8 +261,10 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m CONFIG_INET6_XFRM_MODE_BEET=m # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set CONFIG_IPV6_SIT=m +CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m # CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set CONFIG_IP_DCCP=m @@ -368,7 +368,7 @@ CONFIG_IDE=y CONFIG_BLK_DEV_IDE=y # -# Please see Documentation/ide.txt for help/info on IDE drives +# Please see Documentation/ide/ide.txt for help/info on IDE drives # # CONFIG_BLK_DEV_IDE_SATA is not set CONFIG_BLK_DEV_IDEDISK=y @@ -384,7 +384,6 @@ CONFIG_IDE_PROC_FS=y # # IDE chipset support/bugfixes # -CONFIG_IDE_GENERIC=y # CONFIG_BLK_DEV_PLATFORM is not set CONFIG_BLK_DEV_IDEDMA_SFF=y @@ -422,7 +421,7 @@ CONFIG_BLK_DEV_ALI15X3=y # CONFIG_BLK_DEV_VIA82CXXX is not set # CONFIG_BLK_DEV_TC86C001 is not set CONFIG_BLK_DEV_IDEDMA=y -CONFIG_IDE_ARCH_OBSOLETE_INIT=y +# CONFIG_BLK_DEV_HD_ONLY is not set # CONFIG_BLK_DEV_HD is not set # @@ -588,7 +587,6 @@ CONFIG_E1000_NAPI=y # CONFIG_SIS190 is not set # CONFIG_SKGE is not set # CONFIG_SKY2 is not set -# CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set CONFIG_TIGON3=m CONFIG_BNX2=m @@ -613,6 +611,7 @@ CONFIG_NIU=m # # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set # # USB Network Adapters @@ -1472,7 +1471,7 @@ CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_CRC32C=m CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_TEST=m -CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_AUTHENC=y # CONFIG_CRYPTO_LZO is not set CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_HIFN_795X is not set diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile index 459462e80a1..63c6ae0dd27 100644 --- a/arch/sparc64/kernel/Makefile +++ b/arch/sparc64/kernel/Makefile @@ -21,7 +21,6 @@ obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o \ obj-$(CONFIG_PCI_MSI) += pci_msi.o obj-$(CONFIG_SMP) += smp.o trampoline.o hvtramp.o obj-$(CONFIG_SPARC32_COMPAT) += sys32.o sys_sparc32.o signal32.o -obj-$(CONFIG_BINFMT_AOUT32) += binfmt_aout32.o obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_US3_FREQ) += us3_cpufreq.o obj-$(CONFIG_US2E_FREQ) += us2e_cpufreq.o @@ -30,11 +29,3 @@ obj-$(CONFIG_SUN_LDOMS) += ldc.o vio.o viohs.o ds.o obj-$(CONFIG_AUDIT) += audit.o obj-$(CONFIG_AUDIT)$(CONFIG_SPARC32_COMPAT) += compat_audit.o obj-y += $(obj-yy) - -ifdef CONFIG_SUNOS_EMUL - obj-y += sys_sunos32.o sunos_ioctl32.o -else - ifdef CONFIG_SOLARIS_EMUL - obj-y += sys_sunos32.o sunos_ioctl32.o - endif -endif diff --git a/arch/sparc64/kernel/binfmt_aout32.c b/arch/sparc64/kernel/binfmt_aout32.c deleted file mode 100644 index 9877f2d7672..00000000000 --- a/arch/sparc64/kernel/binfmt_aout32.c +++ /dev/null @@ -1,419 +0,0 @@ -/* - * linux/fs/binfmt_aout.c - * - * Copyright (C) 1991, 1992, 1996 Linus Torvalds - * - * Hacked a bit by DaveM to make it work with 32-bit SunOS - * binaries on the sparc64 port. - */ - -#include <linux/module.h> - -#include <linux/sched.h> -#include <linux/kernel.h> -#include <linux/mm.h> -#include <linux/mman.h> -#include <linux/a.out.h> -#include <linux/errno.h> -#include <linux/signal.h> -#include <linux/string.h> -#include <linux/fs.h> -#include <linux/file.h> -#include <linux/stat.h> -#include <linux/fcntl.h> -#include <linux/ptrace.h> -#include <linux/user.h> -#include <linux/slab.h> -#include <linux/binfmts.h> -#include <linux/personality.h> -#include <linux/init.h> - -#include <asm/system.h> -#include <asm/uaccess.h> -#include <asm/pgalloc.h> -#include <asm/mmu_context.h> -#include <asm/a.out-core.h> - -static int load_aout32_binary(struct linux_binprm *, struct pt_regs * regs); -static int load_aout32_library(struct file*); -static int aout32_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit); - -static struct linux_binfmt aout32_format = { - .module = THIS_MODULE, - .load_binary = load_aout32_binary, - .load_shlib = load_aout32_library, - .core_dump = aout32_core_dump, - .min_coredump = PAGE_SIZE, -}; - -static void set_brk(unsigned long start, unsigned long end) -{ - start = PAGE_ALIGN(start); - end = PAGE_ALIGN(end); - if (end <= start) - return; - down_write(¤t->mm->mmap_sem); - do_brk(start, end - start); - up_write(¤t->mm->mmap_sem); -} - -/* - * These are the only things you should do on a core-file: use only these - * macros to write out all the necessary info. - */ - -static int dump_write(struct file *file, const void *addr, int nr) -{ - return file->f_op->write(file, addr, nr, &file->f_pos) == nr; -} - -#define DUMP_WRITE(addr, nr) \ - if (!dump_write(file, (void *)(addr), (nr))) \ - goto end_coredump; - -#define DUMP_SEEK(offset) \ -if (file->f_op->llseek) { \ - if (file->f_op->llseek(file,(offset),0) != (offset)) \ - goto end_coredump; \ -} else file->f_pos = (offset) - -/* - * Routine writes a core dump image in the current directory. - * Currently only a stub-function. - * - * Note that setuid/setgid files won't make a core-dump if the uid/gid - * changed due to the set[u|g]id. It's enforced by the "current->mm->dumpable" - * field, which also makes sure the core-dumps won't be recursive if the - * dumping of the process results in another error.. - */ - -static int aout32_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit) -{ - mm_segment_t fs; - int has_dumped = 0; - unsigned long dump_start, dump_size; - struct user dump; -# define START_DATA(u) (u.u_tsize) -# define START_STACK(u) ((regs->u_regs[UREG_FP]) & ~(PAGE_SIZE - 1)) - - fs = get_fs(); - set_fs(KERNEL_DS); - has_dumped = 1; - current->flags |= PF_DUMPCORE; - strncpy(dump.u_comm, current->comm, sizeof(dump.u_comm)); - dump.signal = signr; - aout_dump_thread(regs, &dump); - -/* If the size of the dump file exceeds the rlimit, then see what would happen - if we wrote the stack, but not the data area. */ - if (dump.u_dsize + dump.u_ssize > limit) - dump.u_dsize = 0; - -/* Make sure we have enough room to write the stack and data areas. */ - if (dump.u_ssize > limit) - dump.u_ssize = 0; - -/* make sure we actually have a data and stack area to dump */ - set_fs(USER_DS); - if (!access_ok(VERIFY_READ, (void __user *) START_DATA(dump), dump.u_dsize)) - dump.u_dsize = 0; - if (!access_ok(VERIFY_READ, (void __user *) START_STACK(dump), dump.u_ssize)) - dump.u_ssize = 0; - - set_fs(KERNEL_DS); -/* struct user */ - DUMP_WRITE(&dump,sizeof(dump)); -/* now we start writing out the user space info */ - set_fs(USER_DS); -/* Dump the data area */ - if (dump.u_dsize != 0) { - dump_start = START_DATA(dump); - dump_size = dump.u_dsize; - DUMP_WRITE(dump_start,dump_size); - } -/* Now prepare to dump the stack area */ - if (dump.u_ssize != 0) { - dump_start = START_STACK(dump); - dump_size = dump.u_ssize; - DUMP_WRITE(dump_start,dump_size); - } -/* Finally dump the task struct. Not be used by gdb, but could be useful */ - set_fs(KERNEL_DS); - DUMP_WRITE(current,sizeof(*current)); -end_coredump: - set_fs(fs); - return has_dumped; -} - -/* - * create_aout32_tables() parses the env- and arg-strings in new user - * memory and creates the pointer tables from them, and puts their - * addresses on the "stack", returning the new stack pointer value. - */ - -static u32 __user *create_aout32_tables(char __user *p, struct linux_binprm *bprm) -{ - u32 __user *argv; - u32 __user *envp; - u32 __user *sp; - int argc = bprm->argc; - int envc = bprm->envc; - - sp = (u32 __user *)((-(unsigned long)sizeof(char *))&(unsigned long)p); - - /* This imposes the proper stack alignment for a new process. */ - sp = (u32 __user *) (((unsigned long) sp) & ~7); - if ((envc+argc+3)&1) - --sp; - - sp -= envc+1; - envp = sp; - sp -= argc+1; - argv = sp; - put_user(argc,--sp); - current->mm->arg_start = (unsigned long) p; - while (argc-->0) { - char c; - put_user(((u32)(unsigned long)(p)),argv++); - do { - get_user(c,p++); - } while (c); - } - put_user(0,argv); - current->mm->arg_end = current->mm->env_start = (unsigned long) p; - while (envc-->0) { - char c; - put_user(((u32)(unsigned long)(p)),envp++); - do { - get_user(c,p++); - } while (c); - } - put_user(0,envp); - current->mm->env_end = (unsigned long) p; - return sp; -} - -/* - * These are the functions used to load a.out style executables and shared - * libraries. There is no binary dependent code anywhere else. - */ - -static int load_aout32_binary(struct linux_binprm * bprm, struct pt_regs * regs) -{ - struct exec ex; - unsigned long error; - unsigned long fd_offset; - unsigned long rlim; - unsigned long orig_thr_flags; - int retval; - - ex = *((struct exec *) bprm->buf); /* exec-header */ - if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC && - N_MAGIC(ex) != QMAGIC && N_MAGIC(ex) != NMAGIC) || - N_TRSIZE(ex) || N_DRSIZE(ex) || - bprm->file->f_path.dentry->d_inode->i_size < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) { - return -ENOEXEC; - } - - fd_offset = N_TXTOFF(ex); - - /* Check initial limits. This avoids letting people circumvent - * size limits imposed on them by creating programs with large - * arrays in the data or bss. - */ - rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; - if (rlim >= RLIM_INFINITY) - rlim = ~0; - if (ex.a_data + ex.a_bss > rlim) - return -ENOMEM; - - /* Flush all traces of the currently running executable */ - retval = flush_old_exec(bprm); - if (retval) - return retval; - - /* OK, This is the point of no return */ - set_personality(PER_SUNOS); - - current->mm->end_code = ex.a_text + - (current->mm->start_code = N_TXTADDR(ex)); - current->mm->end_data = ex.a_data + - (current->mm->start_data = N_DATADDR(ex)); - current->mm->brk = ex.a_bss + - (current->mm->start_brk = N_BSSADDR(ex)); - current->mm->free_area_cache = current->mm->mmap_base; - current->mm->cached_hole_size = 0; - - current->mm->mmap = NULL; - compute_creds(bprm); - current->flags &= ~PF_FORKNOEXEC; - if (N_MAGIC(ex) == NMAGIC) { - loff_t pos = fd_offset; - /* Fuck me plenty... */ - down_write(¤t->mm->mmap_sem); - error = do_brk(N_TXTADDR(ex), ex.a_text); - up_write(¤t->mm->mmap_sem); - bprm->file->f_op->read(bprm->file, (char __user *)N_TXTADDR(ex), - ex.a_text, &pos); - down_write(¤t->mm->mmap_sem); - error = do_brk(N_DATADDR(ex), ex.a_data); - up_write(¤t->mm->mmap_sem); - bprm->file->f_op->read(bprm->file, (char __user *)N_DATADDR(ex), - ex.a_data, &pos); - goto beyond_if; - } - - if (N_MAGIC(ex) == OMAGIC) { - loff_t pos = fd_offset; - down_write(¤t->mm->mmap_sem); - do_brk(N_TXTADDR(ex) & PAGE_MASK, - ex.a_text+ex.a_data + PAGE_SIZE - 1); - up_write(¤t->mm->mmap_sem); - bprm->file->f_op->read(bprm->file, (char __user *)N_TXTADDR(ex), - ex.a_text+ex.a_data, &pos); - } else { - static unsigned long error_time; - if ((ex.a_text & 0xfff || ex.a_data & 0xfff) && - (N_MAGIC(ex) != NMAGIC) && (jiffies-error_time) > 5*HZ) - { - printk(KERN_NOTICE "executable not page aligned\n"); - error_time = jiffies; - } - - if (!bprm->file->f_op->mmap) { - loff_t pos = fd_offset; - down_write(¤t->mm->mmap_sem); - do_brk(0, ex.a_text+ex.a_data); - up_write(¤t->mm->mmap_sem); - bprm->file->f_op->read(bprm->file, - (char __user *)N_TXTADDR(ex), - ex.a_text+ex.a_data, &pos); - goto beyond_if; - } - - down_write(¤t->mm->mmap_sem); - error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text, - PROT_READ | PROT_EXEC, - MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, - fd_offset); - up_write(¤t->mm->mmap_sem); - - if (error != N_TXTADDR(ex)) { - send_sig(SIGKILL, current, 0); - return error; - } - - down_write(¤t->mm->mmap_sem); - error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data, - PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, - fd_offset + ex.a_text); - up_write(¤t->mm->mmap_sem); - if (error != N_DATADDR(ex)) { - send_sig(SIGKILL, current, 0); - return error; - } - } -beyond_if: - set_binfmt(&aout32_format); - - set_brk(current->mm->start_brk, current->mm->brk); - - /* Make sure STACK_TOP returns the right thing. */ - orig_thr_flags = current_thread_info()->flags; - current_thread_info()->flags |= _TIF_32BIT; - - retval = setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT); - if (retval < 0) { - current_thread_info()->flags = orig_thr_flags; - - /* Someone check-me: is this error path enough? */ - send_sig(SIGKILL, current, 0); - return retval; - } - - current->mm->start_stack = - (unsigned long) create_aout32_tables((char __user *)bprm->p, bprm); - tsb_context_switch(current->mm); - - start_thread32(regs, ex.a_entry, current->mm->start_stack); - if (current->ptrace & PT_PTRACED) - send_sig(SIGTRAP, current, 0); - return 0; -} - -/* N.B. Move to .h file and use code in fs/binfmt_aout.c? */ -static int load_aout32_library(struct file *file) -{ - struct inode * inode; - unsigned long bss, start_addr, len; - unsigned long error; - int retval; - struct exec ex; - - inode = file->f_path.dentry->d_inode; - - retval = -ENOEXEC; - error = kernel_read(file, 0, (char *) &ex, sizeof(ex)); - if (error != sizeof(ex)) - goto out; - - /* We come in here for the regular a.out style of shared libraries */ - if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != QMAGIC) || N_TRSIZE(ex) || - N_DRSIZE(ex) || ((ex.a_entry & 0xfff) && N_MAGIC(ex) == ZMAGIC) || - inode->i_size < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) { - goto out; - } - - if (N_MAGIC(ex) == ZMAGIC && N_TXTOFF(ex) && - (N_TXTOFF(ex) < inode->i_sb->s_blocksize)) { - printk("N_TXTOFF < BLOCK_SIZE. Please convert library\n"); - goto out; - } - - if (N_FLAGS(ex)) - goto out; - - /* For QMAGIC, the starting address is 0x20 into the page. We mask - this off to get the starting address for the page */ - - start_addr = ex.a_entry & 0xfffff000; - - /* Now use mmap to map the library into memory. */ - down_write(¤t->mm->mmap_sem); - error = do_mmap(file, start_addr, ex.a_text + ex.a_data, - PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE, - N_TXTOFF(ex)); - up_write(¤t->mm->mmap_sem); - retval = error; - if (error != start_addr) - goto out; - - len = PAGE_ALIGN(ex.a_text + ex.a_data); - bss = ex.a_text + ex.a_data + ex.a_bss; - if (bss > len) { - down_write(¤t->mm->mmap_sem); - error = do_brk(start_addr + len, bss - len); - up_write(¤t->mm->mmap_sem); - retval = error; - if (error != start_addr + len) - goto out; - } - retval = 0; -out: - return retval; -} - -static int __init init_aout32_binfmt(void) -{ - return register_binfmt(&aout32_format); -} - -static void __exit exit_aout32_binfmt(void) -{ - unregister_binfmt(&aout32_format); -} - -module_init(init_aout32_binfmt); -module_exit(exit_aout32_binfmt); diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index 49eca4b1cf2..fb43c76bdc2 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S @@ -1353,63 +1353,6 @@ breakpoint_trap: ba,pt %xcc, rtrap nop -#if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \ - defined(CONFIG_SOLARIS_EMUL_MODULE) - /* SunOS uses syscall zero as the 'indirect syscall' it looks - * like indir_syscall(scall_num, arg0, arg1, arg2...); etc. - * This is complete brain damage. - */ - .globl sunos_indir -sunos_indir: - srl %o0, 0, %o0 - mov %o7, %l4 - cmp %o0, NR_SYSCALLS - blu,a,pt %icc, 1f - sll %o0, 0x2, %o0 - sethi %hi(sunos_nosys), %l6 - b,pt %xcc, 2f - or %l6, %lo(sunos_nosys), %l6 -1: sethi %hi(sunos_sys_table), %l7 - or %l7, %lo(sunos_sys_table), %l7 - lduw [%l7 + %o0], %l6 -2: mov %o1, %o0 - mov %o2, %o1 - mov %o3, %o2 - mov %o4, %o3 - mov %o5, %o4 - call %l6 - mov %l4, %o7 - - .globl sunos_getpid -sunos_getpid: - call sys_getppid - nop - call sys_getpid - stx %o0, [%sp + PTREGS_OFF + PT_V9_I1] - b,pt %xcc, ret_sys_call - stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] - - /* SunOS getuid() returns uid in %o0 and euid in %o1 */ - .globl sunos_getuid -sunos_getuid: - call sys32_geteuid16 - nop - call sys32_getuid16 - stx %o0, [%sp + PTREGS_OFF + PT_V9_I1] - b,pt %xcc, ret_sys_call - stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] - - /* SunOS getgid() returns gid in %o0 and egid in %o1 */ - .globl sunos_getgid -sunos_getgid: - call sys32_getegid16 - nop - call sys32_getgid16 - stx %o0, [%sp + PTREGS_OFF + PT_V9_I1] - b,pt %xcc, ret_sys_call - stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] -#endif - /* SunOS's execv() call only specifies the argv argument, the * environment settings are the same as the calling processes. */ @@ -1591,7 +1534,7 @@ linux_syscall_trace: mov %i4, %o4 - /* Linux 32-bit and SunOS system calls enter here... */ + /* Linux 32-bit system calls enter here... */ .align 32 .globl linux_sparc_syscall32 linux_sparc_syscall32: @@ -1614,7 +1557,7 @@ linux_sparc_syscall32: srl %i3, 0, %o3 ! IEU0 ba,a,pt %xcc, 3f - /* Linux native and SunOS system calls enter here... */ + /* Linux native system calls enter here... */ .align 32 .globl linux_sparc_syscall, ret_sys_call linux_sparc_syscall: diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c index 9d51956e8e2..1c47009eb5e 100644 --- a/arch/sparc64/kernel/signal.c +++ b/arch/sparc64/kernel/signal.c @@ -25,7 +25,6 @@ #include <asm/uaccess.h> #include <asm/ptrace.h> -#include <asm/svr4.h> #include <asm/pgtable.h> #include <asm/fpumacro.h> #include <asm/uctx.h> diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c index 8c1c121330f..74e0512f135 100644 --- a/arch/sparc64/kernel/signal32.c +++ b/arch/sparc64/kernel/signal32.c @@ -23,7 +23,6 @@ #include <asm/uaccess.h> #include <asm/ptrace.h> -#include <asm/svr4.h> #include <asm/pgtable.h> #include <asm/psrcompat.h> #include <asm/fpumacro.h> @@ -798,281 +797,6 @@ sigsegv: force_sigsegv(signo, current); } -/* Setup a Solaris stack frame */ -static void -setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc, - struct pt_regs *regs, int signr, sigset_t *oldset) -{ - svr4_signal_frame_t __user *sfp; - svr4_gregset_t __user *gr; - svr4_siginfo_t __user *si; - svr4_mcontext_t __user *mc; - svr4_gwindows_t __user *gw; - svr4_ucontext_t __user *uc; - svr4_sigset_t setv; - unsigned int psr; - int i, err; - - synchronize_user_stack(); - save_and_clear_fpu(); - - regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL; - sfp = (svr4_signal_frame_t __user *) - get_sigframe(sa, regs, - sizeof(struct reg_window32) + SVR4_SF_ALIGNED); - - if (invalid_frame_pointer(sfp, sizeof(*sfp))) - do_exit(SIGILL); - - /* Start with a clean frame pointer and fill it */ - err = clear_user(sfp, sizeof(*sfp)); - - /* Setup convenience variables */ - si = &sfp->si; - uc = &sfp->uc; - gw = &sfp->gw; - mc = &uc->mcontext; - gr = &mc->greg; - - /* FIXME: where am I supposed to put this? - * sc->sigc_onstack = old_status; - * anyways, it does not look like it is used for anything at all. - */ - setv.sigbits[0] = oldset->sig[0]; - setv.sigbits[1] = (oldset->sig[0] >> 32); - if (_NSIG_WORDS >= 2) { - setv.sigbits[2] = oldset->sig[1]; - setv.sigbits[3] = (oldset->sig[1] >> 32); - err |= __copy_to_user(&uc->sigmask, &setv, sizeof(svr4_sigset_t)); - } else - err |= __copy_to_user(&uc->sigmask, &setv, - 2 * sizeof(unsigned int)); - - /* Store registers */ - if (test_thread_flag(TIF_32BIT)) { - regs->tpc &= 0xffffffff; - regs->tnpc &= 0xffffffff; - } - err |= __put_user(regs->tpc, &((*gr)[SVR4_PC])); - err |= __put_user(regs->tnpc, &((*gr)[SVR4_NPC])); - psr = tstate_to_psr(regs->tstate); - if (current_thread_info()->fpsaved[0] & FPRS_FEF) - psr |= PSR_EF; - err |= __put_user(psr, &((*gr)[SVR4_PSR])); - err |= __put_user(regs->y, &((*gr)[SVR4_Y])); - - /* Copy g[1..7] and o[0..7] registers */ - for (i = 0; i < 7; i++) - err |= __put_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i); - for (i = 0; i < 8; i++) - err |= __put_user(regs->u_regs[UREG_I0+i], (&(*gr)[SVR4_O0])+i); - - /* Setup sigaltstack */ - err |= __put_user(current->sas_ss_sp, &uc->stack.sp); - err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &uc->stack.flags); - err |= __put_user(current->sas_ss_size, &uc->stack.size); - - /* Save the currently window file: */ - - /* 1. Link sfp->uc->gwins to our windows */ - err |= __put_user(ptr_to_compat(gw), &mc->gwin); - - /* 2. Number of windows to restore at setcontext (): */ - err |= __put_user(get_thread_wsaved(), &gw->count); - - /* 3. We just pay attention to the gw->count field on setcontext */ - set_thread_wsaved(0); /* So process is allowed to execute. */ - - /* Setup the signal information. Solaris expects a bunch of - * information to be passed to the signal handler, we don't provide - * that much currently, should use siginfo. - */ - err |= __put_user(signr, &si->siginfo.signo); - err |= __put_user(SVR4_SINOINFO, &si->siginfo.code); - if (err) - goto sigsegv; - - regs->u_regs[UREG_FP] = (unsigned long) sfp; - regs->tpc = (unsigned long) sa->sa_handler; - regs->tnpc = (regs->tpc + 4); - if (test_thread_flag(TIF_32BIT)) { - regs->tpc &= 0xffffffff; - regs->tnpc &= 0xffffffff; - } - - /* Arguments passed to signal handler */ - if (regs->u_regs[14]){ - struct reg_window32 __user *rw = (struct reg_window32 __user *) - (regs->u_regs[14] & 0x00000000ffffffffUL); - - err |= __put_user(signr, &rw->ins[0]); - err |= __put_user((u64)si, &rw->ins[1]); - err |= __put_user((u64)uc, &rw->ins[2]); - err |= __put_user((u64)sfp, &rw->ins[6]); /* frame pointer */ - if (err) - goto sigsegv; - - regs->u_regs[UREG_I0] = signr; - regs->u_regs[UREG_I1] = (u32)(u64) si; - regs->u_regs[UREG_I2] = (u32)(u64) uc; - } - return; - -sigsegv: - force_sigsegv(signr, current); -} - -asmlinkage int -svr4_getcontext(svr4_ucontext_t __user *uc, struct pt_regs *regs) -{ - svr4_gregset_t __user *gr; - svr4_mcontext_t __user *mc; - svr4_sigset_t setv; - int i, err; - u32 psr; - - synchronize_user_stack(); - save_and_clear_fpu(); - - if (get_thread_wsaved()) - do_exit(SIGSEGV); - - err = clear_user(uc, sizeof(*uc)); - - /* Setup convenience variables */ - mc = &uc->mcontext; - gr = &mc->greg; - - setv.sigbits[0] = current->blocked.sig[0]; - setv.sigbits[1] = (current->blocked.sig[0] >> 32); - if (_NSIG_WORDS >= 2) { - setv.sigbits[2] = current->blocked.sig[1]; - setv.sigbits[3] = (current->blocked.sig[1] >> 32); - err |= __copy_to_user(&uc->sigmask, &setv, sizeof(svr4_sigset_t)); - } else - err |= __copy_to_user(&uc->sigmask, &setv, 2 * sizeof(unsigned)); - - /* Store registers */ - if (test_thread_flag(TIF_32BIT)) { - regs->tpc &= 0xffffffff; - regs->tnpc &= 0xffffffff; - } - err |= __put_user(regs->tpc, &uc->mcontext.greg[SVR4_PC]); - err |= __put_user(regs->tnpc, &uc->mcontext.greg[SVR4_NPC]); - - psr = tstate_to_psr(regs->tstate) & ~PSR_EF; - if (current_thread_info()->fpsaved[0] & FPRS_FEF) - psr |= PSR_EF; - err |= __put_user(psr, &uc->mcontext.greg[SVR4_PSR]); - - err |= __put_user(regs->y, &uc->mcontext.greg[SVR4_Y]); - - /* Copy g[1..7] and o[0..7] registers */ - for (i = 0; i < 7; i++) - err |= __put_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i); - for (i = 0; i < 8; i++) - err |= __put_user(regs->u_regs[UREG_I0+i], (&(*gr)[SVR4_O0])+i); - - /* Setup sigaltstack */ - err |= __put_user(current->sas_ss_sp, &uc->stack.sp); - err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &uc->stack.flags); - err |= __put_user(current->sas_ss_size, &uc->stack.size); - - /* The register file is not saved - * we have already stuffed all of it with sync_user_stack - */ - return (err ? -EFAULT : 0); -} - - -/* Set the context for a svr4 application, this is Solaris way to sigreturn */ -asmlinkage int svr4_setcontext(svr4_ucontext_t __user *c, struct pt_regs *regs) -{ - svr4_gregset_t __user *gr; - mm_segment_t old_fs; - u32 pc, npc, psr, u_ss_sp; - sigset_t set; - svr4_sigset_t setv; - int i, err; - stack_t st; - - /* Fixme: restore windows, or is this already taken care of in - * svr4_setup_frame when sync_user_windows is done? - */ - flush_user_windows(); - - if (get_thread_wsaved()) - goto sigsegv; - - if (((unsigned long) c) & 3){ - printk("Unaligned structure passed\n"); - goto sigsegv; - } - - if (!__access_ok(c, sizeof(*c))) { - /* Miguel, add nice debugging msg _here_. ;-) */ - goto sigsegv; - } - - /* Check for valid PC and nPC */ - gr = &c->mcontext.greg; - err = __get_user(pc, &((*gr)[SVR4_PC])); - err |= __get_user(npc, &((*gr)[SVR4_NPC])); - if ((pc | npc) & 3) - goto sigsegv; - - /* Retrieve information from passed ucontext */ - /* note that nPC is ored a 1, this is used to inform entry.S */ - /* that we don't want it to mess with our PC and nPC */ - - err |= copy_from_user(&setv, &c->sigmask, sizeof(svr4_sigset_t)); - set.sig[0] = setv.sigbits[0] | (((long)setv.sigbits[1]) << 32); - if (_NSIG_WORDS >= 2) - set.sig[1] = setv.sigbits[2] | (((long)setv.sigbits[3]) << 32); - - err |= __get_user(u_ss_sp, &c->stack.sp); - st.ss_sp = compat_ptr(u_ss_sp); - err |= __get_user(st.ss_flags, &c->stack.flags); - err |= __get_user(st.ss_size, &c->stack.size); - if (err) - goto sigsegv; - - /* It is more difficult to avoid calling this function than to - call it and ignore errors. */ - old_fs = get_fs(); - set_fs(KERNEL_DS); - do_sigaltstack((stack_t __user *) &st, NULL, regs->u_regs[UREG_I6]); - set_fs(old_fs); - - sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sighand->siglock); - current->blocked = set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - regs->tpc = pc; - regs->tnpc = npc | 1; - if (test_thread_flag(TIF_32BIT)) { - regs->tpc &= 0xffffffff; - regs->tnpc &= 0xffffffff; - } - err |= __get_user(regs->y, &((*gr)[SVR4_Y])); - err |= __get_user(psr, &((*gr)[SVR4_PSR])); - regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC); - regs->tstate |= psr_to_tstate_icc(psr); - - /* Restore g[1..7] and o[0..7] registers */ - for (i = 0; i < 7; i++) - err |= __get_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i); - for (i = 0; i < 8; i++) - err |= __get_user(regs->u_regs[UREG_I0+i], (&(*gr)[SVR4_O0])+i); - if (err) - goto sigsegv; - - return -EINTR; -sigsegv: - return -EFAULT; -} - static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, unsigned long signr, sigset_t *oldset, siginfo_t *info) @@ -1216,20 +940,14 @@ sigsegv: static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka, siginfo_t *info, - sigset_t *oldset, struct pt_regs *regs, - int svr4_signal) + sigset_t *oldset, struct pt_regs *regs) { - if (svr4_signal) - setup_svr4_frame32(&ka->sa, regs->tpc, regs->tnpc, - regs, signr, oldset); - else { - if (ka->sa.sa_flags & SA_SIGINFO) - setup_rt_frame32(ka, regs, signr, oldset, info); - else if (test_thread_flag(TIF_NEWSIGNALS)) - new_setup_frame32(ka, regs, signr, oldset); - else - setup_frame32(&ka->sa, regs, signr, oldset, info); - } + if (ka->sa.sa_flags & SA_SIGINFO) + setup_rt_frame32(ka, regs, signr, oldset, info); + else if (test_thread_flag(TIF_NEWSIGNALS)) + new_setup_frame32(ka, regs, signr, oldset); + else + setup_frame32(&ka->sa, regs, signr, oldset, info); spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); if (!(ka->sa.sa_flags & SA_NOMASK)) @@ -1270,7 +988,6 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs, struct signal_deliver_cookie cookie; struct k_sigaction ka; int signr; - int svr4_signal = current->personality == PER_SVR4; cookie.restart_syscall = restart_syscall; cookie.orig_i0 = orig_i0; @@ -1279,8 +996,7 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs, if (signr > 0) { if (cookie.restart_syscall) syscall_restart32(orig_i0, regs, &ka.sa); - handle_signal32(signr, &ka, &info, oldset, - regs, svr4_signal); + handle_signal32(signr, &ka, &info, oldset, regs); /* a signal was successfully delivered; the saved * sigmask will have been stored in the signal frame, diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index 051b8d9cb98..38736460b8d 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c @@ -33,13 +33,11 @@ #include <asm/io.h> #include <asm/irq.h> #include <asm/idprom.h> -#include <asm/svr4.h> #include <asm/elf.h> #include <asm/head.h> #include <asm/smp.h> #include <asm/mostek.h> #include <asm/ptrace.h> -#include <asm/user.h> #include <asm/uaccess.h> #include <asm/checksum.h> #include <asm/fpumacro.h> @@ -73,13 +71,8 @@ extern __kernel_size_t strlen(const char *); extern void linux_sparc_syscall(void); extern void rtrap(void); extern void show_regs(struct pt_regs *); -extern void solaris_syscall(void); extern void syscall_trace(struct pt_regs *, int); -extern u32 sunos_sys_table[], sys_call_table32[]; -extern void tl0_solaris(void); extern void sys_sigsuspend(void); -extern int svr4_getcontext(svr4_ucontext_t *uc, struct pt_regs *regs); -extern int svr4_setcontext(svr4_ucontext_t *uc, struct pt_regs *regs); extern int compat_sys_ioctl(unsigned int fd, unsigned int cmd, u32 arg); extern int (*handle_mathemu)(struct pt_regs *, struct fpustate *); extern long sparc32_open(const char __user * filename, int flags, int mode); @@ -90,8 +83,6 @@ extern int __ashrdi3(int, int); extern int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs); -extern unsigned int sys_call_table[]; - extern void xor_vis_2(unsigned long, unsigned long *, unsigned long *); extern void xor_vis_3(unsigned long, unsigned long *, unsigned long *, unsigned long *); @@ -213,11 +204,6 @@ EXPORT_SYMBOL(pci_dma_supported); /* I/O device mmaping on Sparc64. */ EXPORT_SYMBOL(io_remap_pfn_range); -#if defined(CONFIG_COMPAT) && defined(CONFIG_NET) -/* Solaris/SunOS binary compatibility */ -EXPORT_SYMBOL(verify_compat_iovec); -#endif - EXPORT_SYMBOL(dump_fpu); EXPORT_SYMBOL(put_fs_struct); @@ -254,30 +240,6 @@ EXPORT_SYMBOL(strlen); EXPORT_SYMBOL(__strlen_user); EXPORT_SYMBOL(__strnlen_user); -#ifdef CONFIG_SOLARIS_EMUL_MODULE -EXPORT_SYMBOL(linux_sparc_syscall); -EXPORT_SYMBOL(rtrap); -EXPORT_SYMBOL(show_regs); -EXPORT_SYMBOL(solaris_syscall); -EXPORT_SYMBOL(syscall_trace); -EXPORT_SYMBOL(sunos_sys_table); -EXPORT_SYMBOL(sys_call_table32); -EXPORT_SYMBOL(tl0_solaris); -EXPORT_SYMBOL(sys_sigsuspend); -EXPORT_SYMBOL(sys_getppid); -EXPORT_SYMBOL(sys_getpid); -EXPORT_SYMBOL(sys_geteuid); -EXPORT_SYMBOL(sys_getuid); -EXPORT_SYMBOL(sys_getegid); -EXPORT_SYMBOL(sysctl_nr_open); -EXPORT_SYMBOL(sys_getgid); -EXPORT_SYMBOL(svr4_getcontext); -EXPORT_SYMBOL(svr4_setcontext); -EXPORT_SYMBOL(compat_sys_ioctl); -EXPORT_SYMBOL(sys_ioctl); -EXPORT_SYMBOL(sparc32_open); -#endif - /* Special internal versions of library functions. */ EXPORT_SYMBOL(_clear_page); EXPORT_SYMBOL(clear_user_page); @@ -334,9 +296,6 @@ EXPORT_SYMBOL(do_BUG); /* for ns8703 */ EXPORT_SYMBOL(ns87303_lock); -/* for solaris compat module */ -EXPORT_SYMBOL_GPL(sys_call_table); - EXPORT_SYMBOL(tick_ops); EXPORT_SYMBOL(xor_vis_2); diff --git a/arch/sparc64/kernel/sunos_ioctl32.c b/arch/sparc64/kernel/sunos_ioctl32.c deleted file mode 100644 index 75d2bad4983..00000000000 --- a/arch/sparc64/kernel/sunos_ioctl32.c +++ /dev/null @@ -1,275 +0,0 @@ -/* $Id: sunos_ioctl32.c,v 1.11 2000/07/30 23:12:24 davem Exp $ - * sunos_ioctl32.c: SunOS ioctl compatibility on sparc64. - * - * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx) - * Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu) - */ - -#include <asm/uaccess.h> - -#include <linux/sched.h> -#include <linux/errno.h> -#include <linux/string.h> -#include <linux/termios.h> -#include <linux/tty.h> -#include <linux/ioctl.h> -#include <linux/route.h> -#include <linux/sockios.h> -#include <linux/if.h> -#include <linux/netdevice.h> -#include <linux/if_arp.h> -#include <linux/fs.h> -#include <linux/file.h> -#include <linux/mm.h> -#include <linux/smp.h> -#include <linux/syscalls.h> -#include <linux/compat.h> - -#define SUNOS_NR_OPEN 256 - -struct rtentry32 { - u32 rt_pad1; - struct sockaddr rt_dst; /* target address */ - struct sockaddr rt_gateway; /* gateway addr (RTF_GATEWAY) */ - struct sockaddr rt_genmask; /* target network mask (IP) */ - unsigned short rt_flags; - short rt_pad2; - u32 rt_pad3; - unsigned char rt_tos; - unsigned char rt_class; - short rt_pad4; - short rt_metric; /* +1 for binary compatibility! */ - /* char * */ u32 rt_dev; /* forcing the device at add */ - u32 rt_mtu; /* per route MTU/Window */ - u32 rt_window; /* Window clamping */ - unsigned short rt_irtt; /* Initial RTT */ - -}; - -struct ifmap32 { - u32 mem_start; - u32 mem_end; - unsigned short base_addr; - unsigned char irq; - unsigned char dma; - unsigned char port; -}; - -struct ifreq32 { -#define IFHWADDRLEN 6 -#define IFNAMSIZ 16 - union { - char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */ - } ifr_ifrn; - union { - struct sockaddr ifru_addr; - struct sockaddr ifru_dstaddr; - struct sockaddr ifru_broadaddr; - struct sockaddr ifru_netmask; - struct sockaddr ifru_hwaddr; - short ifru_flags; - int ifru_ivalue; - int ifru_mtu; - struct ifmap32 ifru_map; - char ifru_slave[IFNAMSIZ]; /* Just fits the size */ - compat_caddr_t ifru_data; - } ifr_ifru; -}; - -struct ifconf32 { - int ifc_len; /* size of buffer */ - compat_caddr_t ifcbuf; -}; - -extern asmlinkage int compat_sys_ioctl(unsigned int, unsigned int, u32); - -asmlinkage int sunos_ioctl (int fd, u32 cmd, u32 arg) -{ - int ret = -EBADF; - - if(fd >= SUNOS_NR_OPEN) - goto out; - if(!fcheck(fd)) - goto out; - - if(cmd == TIOCSETD) { - mm_segment_t old_fs = get_fs(); - int __user *p; - int ntty = N_TTY; - int tmp; - - p = (int __user *) (unsigned long) arg; - ret = -EFAULT; - if(get_user(tmp, p)) - goto out; - if(tmp == 2) { - set_fs(KERNEL_DS); - ret = sys_ioctl(fd, cmd, (unsigned long) &ntty); - set_fs(old_fs); - ret = (ret == -EINVAL ? -EOPNOTSUPP : ret); - goto out; - } - } - if(cmd == TIOCNOTTY) { - ret = sys_setsid(); - goto out; - } - switch(cmd) { - case _IOW('r', 10, struct rtentry32): - ret = compat_sys_ioctl(fd, SIOCADDRT, arg); - goto out; - case _IOW('r', 11, struct rtentry32): - ret = compat_sys_ioctl(fd, SIOCDELRT, arg); - goto out; - - case _IOW('i', 12, struct ifreq32): - ret = compat_sys_ioctl(fd, SIOCSIFADDR, arg); - goto out; - case _IOWR('i', 13, struct ifreq32): - ret = compat_sys_ioctl(fd, SIOCGIFADDR, arg); - goto out; - case _IOW('i', 14, struct ifreq32): - ret = compat_sys_ioctl(fd, SIOCSIFDSTADDR, arg); - goto out; - case _IOWR('i', 15, struct ifreq32): - ret = compat_sys_ioctl(fd, SIOCGIFDSTADDR, arg); - goto out; - case _IOW('i', 16, struct ifreq32): - ret = compat_sys_ioctl(fd, SIOCSIFFLAGS, arg); - goto out; - case _IOWR('i', 17, struct ifreq32): - ret = compat_sys_ioctl(fd, SIOCGIFFLAGS, arg); - goto out; - case _IOW('i', 18, struct ifreq32): - ret = compat_sys_ioctl(fd, SIOCSIFMEM, arg); - goto out; - case _IOWR('i', 19, struct ifreq32): - ret = compat_sys_ioctl(fd, SIOCGIFMEM, arg); - goto out; - - case _IOWR('i', 20, struct ifconf32): - ret = compat_sys_ioctl(fd, SIOCGIFCONF, arg); - goto out; - - case _IOW('i', 21, struct ifreq32): - ret = compat_sys_ioctl(fd, SIOCSIFMTU, arg); - goto out; - - case _IOWR('i', 22, struct ifreq32): - ret = compat_sys_ioctl(fd, SIOCGIFMTU, arg); - goto out; - - case _IOWR('i', 23, struct ifreq32): - ret = compat_sys_ioctl(fd, SIOCGIFBRDADDR, arg); - goto out; - case _IOW('i', 24, struct ifreq32): - ret = compat_sys_ioctl(fd, SIOCSIFBRDADDR, arg); - goto out; - case _IOWR('i', 25, struct ifreq32): - ret = compat_sys_ioctl(fd, SIOCGIFNETMASK, arg); - goto out; - case _IOW('i', 26, struct ifreq32): - ret = compat_sys_ioctl(fd, SIOCSIFNETMASK, arg); - goto out; - case _IOWR('i', 27, struct ifreq32): - ret = compat_sys_ioctl(fd, SIOCGIFMETRIC, arg); - goto out; - case _IOW('i', 28, struct ifreq32): - ret = compat_sys_ioctl(fd, SIOCSIFMETRIC, arg); - goto out; - - case _IOW('i', 30, struct arpreq): - ret = compat_sys_ioctl(fd, SIOCSARP, arg); - goto out; - case _IOWR('i', 31, struct arpreq): - ret = compat_sys_ioctl(fd, SIOCGARP, arg); - goto out; - case _IOW('i', 32, struct arpreq): - ret = compat_sys_ioctl(fd, SIOCDARP, arg); - goto out; - - case _IOW('i', 40, struct ifreq32): /* SIOCUPPER */ - case _IOW('i', 41, struct ifreq32): /* SIOCLOWER */ - case _IOW('i', 44, struct ifreq32): /* SIOCSETSYNC */ - case _IOW('i', 45, struct ifreq32): /* SIOCGETSYNC */ - case _IOW('i', 46, struct ifreq32): /* SIOCSSDSTATS */ - case _IOW('i', 47, struct ifreq32): /* SIOCSSESTATS */ - case _IOW('i', 48, struct ifreq32): /* SIOCSPROMISC */ - ret = -EOPNOTSUPP; - goto out; - - case _IOW('i', 49, struct ifreq32): - ret = compat_sys_ioctl(fd, SIOCADDMULTI, arg); - goto out; - case _IOW('i', 50, struct ifreq32): - ret = compat_sys_ioctl(fd, SIOCDELMULTI, arg); - goto out; - - /* FDDI interface ioctls, unsupported. */ - - case _IOW('i', 51, struct ifreq32): /* SIOCFDRESET */ - case _IOW('i', 52, struct ifreq32): /* SIOCFDSLEEP */ - case _IOW('i', 53, struct ifreq32): /* SIOCSTRTFMWAR */ - case _IOW('i', 54, struct ifreq32): /* SIOCLDNSTRTFW */ - case _IOW('i', 55, struct ifreq32): /* SIOCGETFDSTAT */ - case _IOW('i', 56, struct ifreq32): /* SIOCFDNMIINT */ - case _IOW('i', 57, struct ifreq32): /* SIOCFDEXUSER */ - case _IOW('i', 58, struct ifreq32): /* SIOCFDGNETMAP */ - case _IOW('i', 59, struct ifreq32): /* SIOCFDGIOCTL */ - printk("FDDI ioctl, returning EOPNOTSUPP\n"); - ret = -EOPNOTSUPP; - goto out; - - case _IOW('t', 125, int): - /* More stupid tty sunos ioctls, just - * say it worked. - */ - ret = 0; - goto out; - - /* Non posix grp */ - case _IOW('t', 118, int): { - int oldval, newval, __user *ptr; - - cmd = TIOCSPGRP; - ptr = (int __user *) (unsigned long) arg; - ret = -EFAULT; - if(get_user(oldval, ptr)) - goto out; - ret = compat_sys_ioctl(fd, cmd, arg); - __get_user(newval, ptr); - if(newval == -1) { - __put_user(oldval, ptr); - ret = -EIO; - } - if(ret == -ENOTTY) - ret = -EIO; - goto out; - } - - case _IOR('t', 119, int): { - int oldval, newval, __user *ptr; - - cmd = TIOCGPGRP; - ptr = (int __user *) (unsigned long) arg; - ret = -EFAULT; - if(get_user(oldval, ptr)) - goto out; - ret = compat_sys_ioctl(fd, cmd, arg); - __get_user(newval, ptr); - if(newval == -1) { - __put_user(oldval, ptr); - ret = -EIO; - } - if(ret == -ENOTTY) - ret = -EIO; - goto out; - } - }; - - ret = compat_sys_ioctl(fd, cmd, arg); - /* so stupid... */ - ret = (ret == -EINVAL ? -EOPNOTSUPP : ret); -out: - return ret; -} diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c index f952745d0f3..73ed01ba40d 100644 --- a/arch/sparc64/kernel/sys_sparc.c +++ b/arch/sparc64/kernel/sys_sparc.c @@ -720,44 +720,6 @@ out: return err; } -asmlinkage long solaris_syscall(struct pt_regs *regs) -{ - static int count; - - regs->tpc = regs->tnpc; - regs->tnpc += 4; - if (test_thread_flag(TIF_32BIT)) { - regs->tpc &= 0xffffffff; - regs->tnpc &= 0xffffffff; - } - if (++count <= 5) { - printk ("For Solaris binary emulation you need solaris module loaded\n"); - show_regs (regs); - } - send_sig(SIGSEGV, current, 1); - - return -ENOSYS; -} - -#ifndef CONFIG_SUNOS_EMUL -asmlinkage long sunos_syscall(struct pt_regs *regs) -{ - static int count; - - regs->tpc = regs->tnpc; - regs->tnpc += 4; - if (test_thread_flag(TIF_32BIT)) { - regs->tpc &= 0xffffffff; - regs->tnpc &= 0xffffffff; - } - if (++count <= 20) - printk ("SunOS binary emulation not compiled in\n"); - force_sig(SIGSEGV, current); - - return -ENOSYS; -} -#endif - asmlinkage long sys_utrap_install(utrap_entry_t type, utrap_handler_t new_p, utrap_handler_t new_d, diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c deleted file mode 100644 index e91194fe39d..00000000000 --- a/arch/sparc64/kernel/sys_sunos32.c +++ /dev/null @@ -1,1359 +0,0 @@ -/* $Id: sys_sunos32.c,v 1.64 2002/02/09 19:49:31 davem Exp $ - * sys_sunos32.c: SunOS binary compatibility layer on sparc64. - * - * Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu) - * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx) - * - * Based upon preliminary work which is: - * - * Copyright (C) 1995 Adrian M. Rodriguez (adrian@remus.rutgers.edu) - */ - -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/types.h> -#include <linux/capability.h> -#include <linux/compat.h> -#include <linux/mman.h> -#include <linux/mm.h> -#include <linux/swap.h> -#include <linux/fs.h> -#include <linux/file.h> -#include <linux/resource.h> -#include <linux/ipc.h> -#include <linux/shm.h> -#include <linux/msg.h> -#include <linux/sem.h> -#include <linux/signal.h> -#include <linux/uio.h> -#include <linux/utsname.h> -#include <linux/major.h> -#include <linux/stat.h> -#include <linux/slab.h> -#include <linux/pagemap.h> -#include <linux/errno.h> -#include <linux/smp.h> -#include <linux/smp_lock.h> -#include <linux/syscalls.h> - -#include <asm/uaccess.h> -#include <asm/page.h> -#include <asm/pgtable.h> -#include <asm/pconf.h> -#include <asm/idprom.h> /* for gethostid() */ -#include <asm/unistd.h> -#include <asm/system.h> -#include <asm/compat_signal.h> - -/* For the nfs mount emulation */ -#include <linux/socket.h> -#include <linux/in.h> -#include <linux/nfs.h> -#include <linux/nfs2.h> -#include <linux/nfs_mount.h> - -/* for sunos_select */ -#include <linux/time.h> -#include <linux/personality.h> - -/* For SOCKET_I */ -#include <net/sock.h> -#include <net/compat.h> - -#define SUNOS_NR_OPEN 256 - -asmlinkage u32 sunos_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u32 off) -{ - struct file *file = NULL; - unsigned long retval, ret_type; - - if (flags & MAP_NORESERVE) { - static int cnt; - if (cnt++ < 10) - printk("%s: unimplemented SunOS MAP_NORESERVE mmap() flag\n", - current->comm); - flags &= ~MAP_NORESERVE; - } - retval = -EBADF; - if (!(flags & MAP_ANONYMOUS)) { - struct inode * inode; - if (fd >= SUNOS_NR_OPEN) - goto out; - file = fget(fd); - if (!file) - goto out; - inode = file->f_path.dentry->d_inode; - if (imajor(inode) == MEM_MAJOR && iminor(inode) == 5) { - flags |= MAP_ANONYMOUS; - fput(file); - file = NULL; - } - } - - retval = -EINVAL; - if (!(flags & MAP_FIXED)) - addr = 0; - else if (len > 0xf0000000 || addr > 0xf0000000 - len) - goto out_putf; - ret_type = flags & _MAP_NEW; - flags &= ~_MAP_NEW; - - flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); - down_write(¤t->mm->mmap_sem); - retval = do_mmap(file, - (unsigned long) addr, (unsigned long) len, - (unsigned long) prot, (unsigned long) flags, - (unsigned long) off); - up_write(¤t->mm->mmap_sem); - if (!ret_type) - retval = ((retval < 0xf0000000) ? 0 : retval); -out_putf: - if (file) - fput(file); -out: - return (u32) retval; -} - -asmlinkage int sunos_mctl(u32 addr, u32 len, int function, u32 arg) -{ - return 0; -} - -asmlinkage int sunos_brk(u32 baddr) -{ - int freepages, retval = -ENOMEM; - unsigned long rlim; - unsigned long newbrk, oldbrk, brk = (unsigned long) baddr; - - down_write(¤t->mm->mmap_sem); - if (brk < current->mm->end_code) - goto out; - newbrk = PAGE_ALIGN(brk); - oldbrk = PAGE_ALIGN(current->mm->brk); - retval = 0; - if (oldbrk == newbrk) { - current->mm->brk = brk; - goto out; - } - /* Always allow shrinking brk. */ - if (brk <= current->mm->brk) { - current->mm->brk = brk; - do_munmap(current->mm, newbrk, oldbrk-newbrk); - goto out; - } - /* Check against rlimit and stack.. */ - retval = -ENOMEM; - rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; - if (rlim >= RLIM_INFINITY) - rlim = ~0; - if (brk - current->mm->end_code > rlim) - goto out; - /* Check against existing mmap mappings. */ - if (find_vma_intersection(current->mm, oldbrk, newbrk+PAGE_SIZE)) - goto out; - /* stupid algorithm to decide if we have enough memory: while - * simple, it hopefully works in most obvious cases.. Easy to - * fool it, but this should catch most mistakes. - */ - freepages = global_page_state(NR_FILE_PAGES); - freepages >>= 1; - freepages += nr_free_pages(); - freepages += nr_swap_pages; - freepages -= num_physpages >> 4; - freepages -= (newbrk-oldbrk) >> PAGE_SHIFT; - if (freepages < 0) - goto out; - /* Ok, we have probably got enough memory - let it rip. */ - current->mm->brk = brk; - do_brk(oldbrk, newbrk-oldbrk); - retval = 0; -out: - up_write(¤t->mm->mmap_sem); - return retval; -} - -asmlinkage u32 sunos_sbrk(int increment) -{ - int error, oldbrk; - - /* This should do it hopefully... */ - oldbrk = (int)current->mm->brk; - error = sunos_brk(((int) current->mm->brk) + increment); - if (!error) - error = oldbrk; - return error; -} - -asmlinkage u32 sunos_sstk(int increment) -{ - printk("%s: Call to sunos_sstk(increment<%d>) is unsupported\n", - current->comm, increment); - - return (u32)-1; -} - -/* Give hints to the kernel as to what paging strategy to use... - * Completely bogus, don't remind me. - */ -#define VA_NORMAL 0 /* Normal vm usage expected */ -#define VA_ABNORMAL 1 /* Abnormal/random vm usage probable */ -#define VA_SEQUENTIAL 2 /* Accesses will be of a sequential nature */ -#define VA_INVALIDATE 3 /* Page table entries should be flushed ??? */ -static char *vstrings[] = { - "VA_NORMAL", - "VA_ABNORMAL", - "VA_SEQUENTIAL", - "VA_INVALIDATE", -}; - -asmlinkage void sunos_vadvise(u32 strategy) -{ - static int count; - - /* I wanna see who uses this... */ - if (count++ < 5) - printk("%s: Advises us to use %s paging strategy\n", - current->comm, - strategy <= 3 ? vstrings[strategy] : "BOGUS"); -} - -/* This just wants the soft limit (ie. rlim_cur element) of the RLIMIT_NOFILE - * resource limit and is for backwards compatibility with older sunos - * revs. - */ -asmlinkage int sunos_getdtablesize(void) -{ - return SUNOS_NR_OPEN; -} - - -#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) - -asmlinkage u32 sunos_sigblock(u32 blk_mask) -{ - u32 old; - - spin_lock_irq(¤t->sighand->siglock); - old = (u32) current->blocked.sig[0]; - current->blocked.sig[0] |= (blk_mask & _BLOCKABLE); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - return old; -} - -asmlinkage u32 sunos_sigsetmask(u32 newmask) -{ - u32 retval; - - spin_lock_irq(¤t->sighand->siglock); - retval = (u32) current->blocked.sig[0]; - current->blocked.sig[0] = (newmask & _BLOCKABLE); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - return retval; -} - -/* SunOS getdents is very similar to the newer Linux (iBCS2 compliant) */ -/* getdents system call, the format of the structure just has a different */ -/* layout (d_off+d_ino instead of d_ino+d_off) */ -struct sunos_dirent { - s32 d_off; - u32 d_ino; - u16 d_reclen; - u16 d_namlen; - char d_name[1]; -}; - -struct sunos_dirent_callback { - struct sunos_dirent __user *curr; - struct sunos_dirent __user *previous; - int count; - int error; -}; - -#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de))) -#define ROUND_UP(x) (((x)+sizeof(s32)-1) & ~(sizeof(s32)-1)) - -static int sunos_filldir(void * __buf, const char * name, int namlen, - loff_t offset, ino_t ino, unsigned int d_type) -{ - struct sunos_dirent __user *dirent; - struct sunos_dirent_callback * buf = (struct sunos_dirent_callback *) __buf; - int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); - u32 d_ino; - - buf->error = -EINVAL; /* only used if we fail.. */ - if (reclen > buf->count) - return -EINVAL; - d_ino = ino; - if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) - return -EOVERFLOW; - dirent = buf->previous; - if (dirent) - put_user(offset, &dirent->d_off); - dirent = buf->curr; - buf->previous = dirent; - put_user(d_ino, &dirent->d_ino); - put_user(namlen, &dirent->d_namlen); - put_user(reclen, &dirent->d_reclen); - if (copy_to_user(dirent->d_name, name, namlen)) - return -EFAULT; - put_user(0, dirent->d_name + namlen); - dirent = (void __user *) dirent + reclen; - buf->curr = dirent; - buf->count -= reclen; - return 0; -} - -asmlinkage int sunos_getdents(unsigned int fd, void __user *dirent, int cnt) -{ - struct file * file; - struct sunos_dirent __user *lastdirent; - struct sunos_dirent_callback buf; - int error = -EBADF; - - if (fd >= SUNOS_NR_OPEN) - goto out; - - file = fget(fd); - if (!file) - goto out; - - error = -EINVAL; - if (cnt < (sizeof(struct sunos_dirent) + 255)) - goto out_putf; - - buf.curr = (struct sunos_dirent __user *) dirent; - buf.previous = NULL; - buf.count = cnt; - buf.error = 0; - - error = vfs_readdir(file, sunos_filldir, &buf); - if (error < 0) - goto out_putf; - - lastdirent = buf.previous; - error = buf.error; - if (lastdirent) { - put_user(file->f_pos, &lastdirent->d_off); - error = cnt - buf.count; - } - -out_putf: - fput(file); -out: - return error; -} - -/* Old sunos getdirentries, severely broken compatibility stuff here. */ -struct sunos_direntry { - u32 d_ino; - u16 d_reclen; - u16 d_namlen; - char d_name[1]; -}; - -struct sunos_direntry_callback { - struct sunos_direntry __user *curr; - struct sunos_direntry __user *previous; - int count; - int error; -}; - -static int sunos_filldirentry(void * __buf, const char * name, int namlen, - loff_t offset, ino_t ino, unsigned int d_type) -{ - struct sunos_direntry __user *dirent; - struct sunos_direntry_callback * buf = - (struct sunos_direntry_callback *) __buf; - int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); - u32 d_ino; - - buf->error = -EINVAL; /* only used if we fail.. */ - if (reclen > buf->count) - return -EINVAL; - d_ino = ino; - if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) - return -EOVERFLOW; - dirent = buf->previous; - dirent = buf->curr; - buf->previous = dirent; - put_user(d_ino, &dirent->d_ino); - put_user(namlen, &dirent->d_namlen); - put_user(reclen, &dirent->d_reclen); - if (copy_to_user(dirent->d_name, name, namlen)) - return -EFAULT; - put_user(0, dirent->d_name + namlen); - dirent = (void __user *) dirent + reclen; - buf->curr = dirent; - buf->count -= reclen; - return 0; -} - -asmlinkage int sunos_getdirentries(unsigned int fd, - void __user *dirent, - int cnt, - unsigned int __user *basep) -{ - struct file * file; - struct sunos_direntry __user *lastdirent; - int error = -EBADF; - struct sunos_direntry_callback buf; - - if (fd >= SUNOS_NR_OPEN) - goto out; - - file = fget(fd); - if (!file) - goto out; - - error = -EINVAL; - if (cnt < (sizeof(struct sunos_direntry) + 255)) - goto out_putf; - - buf.curr = (struct sunos_direntry __user *) dirent; - buf.previous = NULL; - buf.count = cnt; - buf.error = 0; - - error = vfs_readdir(file, sunos_filldirentry, &buf); - if (error < 0) - goto out_putf; - - lastdirent = buf.previous; - error = buf.error; - if (lastdirent) { - put_user(file->f_pos, basep); - error = cnt - buf.count; - } - -out_putf: - fput(file); -out: - return error; -} - -struct sunos_utsname { - char sname[9]; - char nname[9]; - char nnext[56]; - char rel[9]; - char ver[9]; - char mach[9]; -}; - -asmlinkage int sunos_uname(struct sunos_utsname __user *name) -{ - int ret; - - down_read(&uts_sem); - ret = copy_to_user(&name->sname[0], &utsname()->sysname[0], - sizeof(name->sname) - 1); - ret |= copy_to_user(&name->nname[0], &utsname()->nodename[0], - sizeof(name->nname) - 1); - ret |= put_user('\0', &name->nname[8]); - ret |= copy_to_user(&name->rel[0], &utsname()->release[0], - sizeof(name->rel) - 1); - ret |= copy_to_user(&name->ver[0], &utsname()->version[0], - sizeof(name->ver) - 1); - ret |= copy_to_user(&name->mach[0], &utsname()->machine[0], - sizeof(name->mach) - 1); - up_read(&uts_sem); - return (ret ? -EFAULT : 0); -} - -asmlinkage int sunos_nosys(void) -{ - struct pt_regs *regs; - siginfo_t info; - static int cnt; - - regs = current_thread_info()->kregs; - if (test_thread_flag(TIF_32BIT)) { - regs->tpc &= 0xffffffff; - regs->tnpc &= 0xffffffff; - } - info.si_signo = SIGSYS; - info.si_errno = 0; - info.si_code = __SI_FAULT|0x100; - info.si_addr = (void __user *)regs->tpc; - info.si_trapno = regs->u_regs[UREG_G1]; - send_sig_info(SIGSYS, &info, current); - if (cnt++ < 4) { - printk("Process makes ni_syscall number %d, register dump:\n", - (int) regs->u_regs[UREG_G1]); - show_regs(regs); - } - return -ENOSYS; -} - -/* This is not a real and complete implementation yet, just to keep - * the easy SunOS binaries happy. - */ -asmlinkage int sunos_fpathconf(int fd, int name) -{ - int ret; - - switch(name) { - case _PCONF_LINK: - ret = LINK_MAX; - break; - case _PCONF_CANON: - ret = MAX_CANON; - break; - case _PCONF_INPUT: - ret = MAX_INPUT; - break; - case _PCONF_NAME: - ret = NAME_MAX; - break; - case _PCONF_PATH: - ret = PATH_MAX; - break; - case _PCONF_PIPE: - ret = PIPE_BUF; - break; - case _PCONF_CHRESTRICT: /* XXX Investigate XXX */ - ret = 1; - break; - case _PCONF_NOTRUNC: /* XXX Investigate XXX */ - case _PCONF_VDISABLE: - ret = 0; - break; - default: - ret = -EINVAL; - break; - } - return ret; -} - -asmlinkage int sunos_pathconf(u32 u_path, int name) -{ - int ret; - - ret = sunos_fpathconf(0, name); /* XXX cheese XXX */ - return ret; -} - -asmlinkage int sunos_select(int width, u32 inp, u32 outp, u32 exp, u32 tvp_x) -{ - int ret; - - /* SunOS binaries expect that select won't change the tvp contents */ - ret = compat_sys_select(width, compat_ptr(inp), compat_ptr(outp), - compat_ptr(exp), compat_ptr(tvp_x)); - if (ret == -EINTR && tvp_x) { - struct compat_timeval __user *tvp = compat_ptr(tvp_x); - time_t sec, usec; - - __get_user(sec, &tvp->tv_sec); - __get_user(usec, &tvp->tv_usec); - if (sec == 0 && usec == 0) - ret = 0; - } - return ret; -} - -asmlinkage void sunos_nop(void) -{ - return; -} - -#if 0 /* This code doesn't translate user pointers correctly, - * disable for now. -DaveM - */ - -/* XXXXXXXXXX SunOS mount/umount. XXXXXXXXXXX */ -#define SMNT_RDONLY 1 -#define SMNT_NOSUID 2 -#define SMNT_NEWTYPE 4 -#define SMNT_GRPID 8 -#define SMNT_REMOUNT 16 -#define SMNT_NOSUB 32 -#define SMNT_MULTI 64 -#define SMNT_SYS5 128 - -struct sunos_fh_t { - char fh_data [NFS_FHSIZE]; -}; - -struct sunos_nfs_mount_args { - struct sockaddr_in *addr; /* file server address */ - struct nfs_fh *fh; /* File handle to be mounted */ - int flags; /* flags */ - int wsize; /* write size in bytes */ - int rsize; /* read size in bytes */ - int timeo; /* initial timeout in .1 secs */ - int retrans; /* times to retry send */ - char *hostname; /* server's hostname */ - int acregmin; /* attr cache file min secs */ - int acregmax; /* attr cache file max secs */ - int acdirmin; /* attr cache dir min secs */ - int acdirmax; /* attr cache dir max secs */ - char *netname; /* server's netname */ -}; - - -/* Bind the socket on a local reserved port and connect it to the - * remote server. This on Linux/i386 is done by the mount program, - * not by the kernel. - */ -/* XXXXXXXXXXXXXXXXXXXX */ -static int -sunos_nfs_get_server_fd (int fd, struct sockaddr_in *addr) -{ - struct sockaddr_in local; - struct sockaddr_in server; - int try_port; - int ret; - struct socket *socket; - struct inode *inode; - struct file *file; - - file = fget(fd); - if (!file) - return 0; - - inode = file->f_path.dentry->d_inode; - - socket = SOCKET_I(inode); - local.sin_family = AF_INET; - local.sin_addr.s_addr = htonl(INADDR_ANY); - - /* IPPORT_RESERVED = 1024, can't find the definition in the kernel */ - try_port = 1024; - do { - local.sin_port = htons (--try_port); - ret = socket->ops->bind(socket, (struct sockaddr*)&local, - sizeof(local)); - } while (ret && try_port > (1024 / 2)); - - if (ret) { - fput(file); - return 0; - } - - server.sin_family = AF_INET; - server.sin_addr = addr->sin_addr; - server.sin_port = NFS_PORT; - - /* Call sys_connect */ - ret = socket->ops->connect (socket, (struct sockaddr *) &server, - sizeof (server), file->f_flags); - fput(file); - if (ret < 0) - return 0; - return 1; -} - -/* XXXXXXXXXXXXXXXXXXXX */ -static int get_default (int value, int def_value) -{ - if (value) - return value; - else - return def_value; -} - -/* XXXXXXXXXXXXXXXXXXXX */ -static int sunos_nfs_mount(char *dir_name, int linux_flags, void __user *data) -{ - int server_fd, err; - char *the_name, *mount_page; - struct nfs_mount_data linux_nfs_mount; - struct sunos_nfs_mount_args sunos_mount; - - /* Ok, here comes the fun part: Linux's nfs mount needs a - * socket connection to the server, but SunOS mount does not - * require this, so we use the information on the destination - * address to create a socket and bind it to a reserved - * port on this system - */ - if (copy_from_user(&sunos_mount, data, sizeof(sunos_mount))) - return -EFAULT; - - server_fd = sys_socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (server_fd < 0) - return -ENXIO; - - if (copy_from_user(&linux_nfs_mount.addr, sunos_mount.addr, - sizeof(*sunos_mount.addr)) || - copy_from_user(&linux_nfs_mount.root, sunos_mount.fh, - sizeof(*sunos_mount.fh))) { - sys_close (server_fd); - return -EFAULT; - } - - if (!sunos_nfs_get_server_fd (server_fd, &linux_nfs_mount.addr)){ - sys_close (server_fd); - return -ENXIO; - } - - /* Now, bind it to a locally reserved port */ - linux_nfs_mount.version = NFS_MOUNT_VERSION; - linux_nfs_mount.flags = sunos_mount.flags; - linux_nfs_mount.fd = server_fd; - - linux_nfs_mount.rsize = get_default (sunos_mount.rsize, 8192); - linux_nfs_mount.wsize = get_default (sunos_mount.wsize, 8192); - linux_nfs_mount.timeo = get_default (sunos_mount.timeo, 10); - linux_nfs_mount.retrans = sunos_mount.retrans; - - linux_nfs_mount.acregmin = sunos_mount.acregmin; - linux_nfs_mount.acregmax = sunos_mount.acregmax; - linux_nfs_mount.acdirmin = sunos_mount.acdirmin; - linux_nfs_mount.acdirmax = sunos_mount.acdirmax; - - the_name = getname(sunos_mount.hostname); - if (IS_ERR(the_name)) - return PTR_ERR(the_name); - - strlcpy(linux_nfs_mount.hostname, the_name, - sizeof(linux_nfs_mount.hostname)); - putname (the_name); - - mount_page = (char *) get_zeroed_page(GFP_KERNEL); - if (!mount_page) - return -ENOMEM; - - memcpy(mount_page, &linux_nfs_mount, sizeof(linux_nfs_mount)); - - err = do_mount("", dir_name, "nfs", linux_flags, mount_page); - - free_page((unsigned long) mount_page); - return err; -} - -/* XXXXXXXXXXXXXXXXXXXX */ -asmlinkage int -sunos_mount(char *type, char *dir, int flags, void *data) -{ - int linux_flags = 0; - int ret = -EINVAL; - char *dev_fname = 0; - char *dir_page, *type_page; - - if (!capable (CAP_SYS_ADMIN)) - return -EPERM; - - /* We don't handle the integer fs type */ - if ((flags & SMNT_NEWTYPE) == 0) - goto out; - - /* Do not allow for those flags we don't support */ - if (flags & (SMNT_GRPID|SMNT_NOSUB|SMNT_MULTI|SMNT_SYS5)) - goto out; - - if (flags & SMNT_REMOUNT) - linux_flags |= MS_REMOUNT; - if (flags & SMNT_RDONLY) - linux_flags |= MS_RDONLY; - if (flags & SMNT_NOSUID) - linux_flags |= MS_NOSUID; - - dir_page = getname(dir); - ret = PTR_ERR(dir_page); - if (IS_ERR(dir_page)) - goto out; - - type_page = getname(type); - ret = PTR_ERR(type_page); - if (IS_ERR(type_page)) - goto out1; - - if (strcmp(type_page, "ext2") == 0) { - dev_fname = getname(data); - } else if (strcmp(type_page, "iso9660") == 0) { - dev_fname = getname(data); - } else if (strcmp(type_page, "minix") == 0) { - dev_fname = getname(data); - } else if (strcmp(type_page, "nfs") == 0) { - ret = sunos_nfs_mount (dir_page, flags, data); - goto out2; - } else if (strcmp(type_page, "ufs") == 0) { - printk("Warning: UFS filesystem mounts unsupported.\n"); - ret = -ENODEV; - goto out2; - } else if (strcmp(type_page, "proc")) { - ret = -ENODEV; - goto out2; - } - ret = PTR_ERR(dev_fname); - if (IS_ERR(dev_fname)) - goto out2; - lock_kernel(); - ret = do_mount(dev_fname, dir_page, type_page, linux_flags, NULL); - unlock_kernel(); - if (dev_fname) - putname(dev_fname); -out2: - putname(type_page); -out1: - putname(dir_page); -out: - return ret; -} -#endif - -asmlinkage int sunos_setpgrp(pid_t pid, pid_t pgid) -{ - int ret; - - /* So stupid... */ - if ((!pid || pid == current->pid) && - !pgid) { - sys_setsid(); - ret = 0; - } else { - ret = sys_setpgid(pid, pgid); - } - return ret; -} - -/* So stupid... */ -extern long compat_sys_wait4(compat_pid_t, compat_uint_t __user *, int, - struct compat_rusage __user *); - -asmlinkage int sunos_wait4(compat_pid_t pid, compat_uint_t __user *stat_addr, int options, struct compat_rusage __user *ru) -{ - int ret; - - ret = compat_sys_wait4((pid ? pid : ((compat_pid_t)-1)), - stat_addr, options, ru); - return ret; -} - -asmlinkage int sunos_killpg(int pgrp, int sig) -{ - int ret; - - rcu_read_lock(); - ret = -EINVAL; - if (pgrp > 0) - ret = kill_pgrp(find_vpid(pgrp), sig, 0); - rcu_read_unlock(); - - return ret; -} - -asmlinkage int sunos_audit(void) -{ - printk ("sys_audit\n"); - return -1; -} - -asmlinkage u32 sunos_gethostid(void) -{ - u32 ret; - - ret = (((u32)idprom->id_machtype << 24) | ((u32)idprom->id_sernum)); - - return ret; -} - -/* sysconf options, for SunOS compatibility */ -#define _SC_ARG_MAX 1 -#define _SC_CHILD_MAX 2 -#define _SC_CLK_TCK 3 -#define _SC_NGROUPS_MAX 4 -#define _SC_OPEN_MAX 5 -#define _SC_JOB_CONTROL 6 -#define _SC_SAVED_IDS 7 -#define _SC_VERSION 8 - -asmlinkage s32 sunos_sysconf (int name) -{ - s32 ret; - - switch (name){ - case _SC_ARG_MAX: - ret = ARG_MAX; - break; - case _SC_CHILD_MAX: - ret = current->signal->rlim[RLIMIT_NPROC].rlim_cur; - break; - case _SC_CLK_TCK: - ret = HZ; - break; - case _SC_NGROUPS_MAX: - ret = NGROUPS_MAX; - break; - case _SC_OPEN_MAX: - ret = current->signal->rlim[RLIMIT_NOFILE].rlim_cur; - break; - case _SC_JOB_CONTROL: - ret = 1; /* yes, we do support job control */ - break; - case _SC_SAVED_IDS: - ret = 1; /* yes, we do support saved uids */ - break; - case _SC_VERSION: - /* mhm, POSIX_VERSION is in /usr/include/unistd.h - * should it go on /usr/include/linux? - */ - ret = 199009; - break; - default: - ret = -1; - break; - }; - return ret; -} - -asmlinkage int sunos_semsys(int op, u32 arg1, u32 arg2, u32 arg3, void __user *ptr) -{ - union semun arg4; - int ret; - - switch (op) { - case 0: - /* Most arguments match on a 1:1 basis but cmd doesn't */ - switch(arg3) { - case 4: - arg3=GETPID; break; - case 5: - arg3=GETVAL; break; - case 6: - arg3=GETALL; break; - case 3: - arg3=GETNCNT; break; - case 7: - arg3=GETZCNT; break; - case 8: - arg3=SETVAL; break; - case 9: - arg3=SETALL; break; - } - /* sys_semctl(): */ - /* value to modify semaphore to */ - arg4.__pad = ptr; - ret = sys_semctl((int)arg1, (int)arg2, (int)arg3, arg4); - break; - case 1: - /* sys_semget(): */ - ret = sys_semget((key_t)arg1, (int)arg2, (int)arg3); - break; - case 2: - /* sys_semop(): */ - ret = sys_semop((int)arg1, (struct sembuf __user *)(unsigned long)arg2, - (unsigned int) arg3); - break; - default: - ret = -EINVAL; - break; - }; - return ret; -} - -struct msgbuf32 { - s32 mtype; - char mtext[1]; -}; - -struct ipc_perm32 -{ - key_t key; - compat_uid_t uid; - compat_gid_t gid; - compat_uid_t cuid; - compat_gid_t cgid; - compat_mode_t mode; - unsigned short seq; -}; - -struct msqid_ds32 -{ - struct ipc_perm32 msg_perm; - u32 msg_first; - u32 msg_last; - compat_time_t msg_stime; - compat_time_t msg_rtime; - compat_time_t msg_ctime; - u32 wwait; - u32 rwait; - unsigned short msg_cbytes; - unsigned short msg_qnum; - unsigned short msg_qbytes; - compat_ipc_pid_t msg_lspid; - compat_ipc_pid_t msg_lrpid; -}; - -static inline int sunos_msqid_get(struct msqid_ds32 __user *user, - struct msqid_ds *kern) -{ - if (get_user(kern->msg_perm.key, &user->msg_perm.key) || - __get_user(kern->msg_perm.uid, &user->msg_perm.uid) || - __get_user(kern->msg_perm.gid, &user->msg_perm.gid) || - __get_user(kern->msg_perm.cuid, &user->msg_perm.cuid) || - __get_user(kern->msg_perm.cgid, &user->msg_perm.cgid) || - __get_user(kern->msg_stime, &user->msg_stime) || - __get_user(kern->msg_rtime, &user->msg_rtime) || - __get_user(kern->msg_ctime, &user->msg_ctime) || - __get_user(kern->msg_ctime, &user->msg_cbytes) || - __get_user(kern->msg_ctime, &user->msg_qnum) || - __get_user(kern->msg_ctime, &user->msg_qbytes) || - __get_user(kern->msg_ctime, &user->msg_lspid) || - __get_user(kern->msg_ctime, &user->msg_lrpid)) - return -EFAULT; - return 0; -} - -static inline int sunos_msqid_put(struct msqid_ds32 __user *user, - struct msqid_ds *kern) -{ - if (put_user(kern->msg_perm.key, &user->msg_perm.key) || - __put_user(kern->msg_perm.uid, &user->msg_perm.uid) || - __put_user(kern->msg_perm.gid, &user->msg_perm.gid) || - __put_user(kern->msg_perm.cuid, &user->msg_perm.cuid) || - __put_user(kern->msg_perm.cgid, &user->msg_perm.cgid) || - __put_user(kern->msg_stime, &user->msg_stime) || - __put_user(kern->msg_rtime, &user->msg_rtime) || - __put_user(kern->msg_ctime, &user->msg_ctime) || - __put_user(kern->msg_ctime, &user->msg_cbytes) || - __put_user(kern->msg_ctime, &user->msg_qnum) || - __put_user(kern->msg_ctime, &user->msg_qbytes) || - __put_user(kern->msg_ctime, &user->msg_lspid) || - __put_user(kern->msg_ctime, &user->msg_lrpid)) - return -EFAULT; - return 0; -} - -static inline int sunos_msgbuf_get(struct msgbuf32 __user *user, struct msgbuf *kern, int len) -{ - if (get_user(kern->mtype, &user->mtype) || - __copy_from_user(kern->mtext, &user->mtext, len)) - return -EFAULT; - return 0; -} - -static inline int sunos_msgbuf_put(struct msgbuf32 __user *user, struct msgbuf *kern, int len) -{ - if (put_user(kern->mtype, &user->mtype) || - __copy_to_user(user->mtext, kern->mtext, len)) - return -EFAULT; - return 0; -} - -asmlinkage int sunos_msgsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 arg4) -{ - struct sparc_stackf32 __user *sp; - struct msqid_ds kds; - struct msgbuf *kmbuf; - mm_segment_t old_fs = get_fs(); - u32 arg5; - int rval; - - switch(op) { - case 0: - rval = sys_msgget((key_t)arg1, (int)arg2); - break; - case 1: - if (!sunos_msqid_get((struct msqid_ds32 __user *)(unsigned long)arg3, &kds)) { - set_fs(KERNEL_DS); - rval = sys_msgctl((int)arg1, (int)arg2, - (struct msqid_ds __user *)(unsigned long)arg3); - set_fs(old_fs); - if (!rval) - rval = sunos_msqid_put((struct msqid_ds32 __user *)(unsigned long)arg3, - &kds); - } else - rval = -EFAULT; - break; - case 2: - rval = -EFAULT; - kmbuf = kmalloc(sizeof(struct msgbuf) + arg3, - GFP_KERNEL); - if (!kmbuf) - break; - sp = (struct sparc_stackf32 __user *) - (current_thread_info()->kregs->u_regs[UREG_FP] & 0xffffffffUL); - if (get_user(arg5, &sp->xxargs[0])) { - rval = -EFAULT; - kfree(kmbuf); - break; - } - set_fs(KERNEL_DS); - rval = sys_msgrcv((int)arg1, (struct msgbuf __user *) kmbuf, - (size_t)arg3, - (long)arg4, (int)arg5); - set_fs(old_fs); - if (!rval) - rval = sunos_msgbuf_put((struct msgbuf32 __user *)(unsigned long)arg2, - kmbuf, arg3); - kfree(kmbuf); - break; - case 3: - rval = -EFAULT; - kmbuf = kmalloc(sizeof(struct msgbuf) + arg3, - GFP_KERNEL); - if (!kmbuf || sunos_msgbuf_get((struct msgbuf32 __user *)(unsigned long)arg2, - kmbuf, arg3)) - break; - set_fs(KERNEL_DS); - rval = sys_msgsnd((int)arg1, (struct msgbuf __user *) kmbuf, - (size_t)arg3, (int)arg4); - set_fs(old_fs); - kfree(kmbuf); - break; - default: - rval = -EINVAL; - break; - } - return rval; -} - -struct shmid_ds32 { - struct ipc_perm32 shm_perm; - int shm_segsz; - compat_time_t shm_atime; - compat_time_t shm_dtime; - compat_time_t shm_ctime; - compat_ipc_pid_t shm_cpid; - compat_ipc_pid_t shm_lpid; - unsigned short shm_nattch; -}; - -static inline int sunos_shmid_get(struct shmid_ds32 __user *user, - struct shmid_ds *kern) -{ - if (get_user(kern->shm_perm.key, &user->shm_perm.key) || - __get_user(kern->shm_perm.uid, &user->shm_perm.uid) || - __get_user(kern->shm_perm.gid, &user->shm_perm.gid) || - __get_user(kern->shm_perm.cuid, &user->shm_perm.cuid) || - __get_user(kern->shm_perm.cgid, &user->shm_perm.cgid) || - __get_user(kern->shm_segsz, &user->shm_segsz) || - __get_user(kern->shm_atime, &user->shm_atime) || - __get_user(kern->shm_dtime, &user->shm_dtime) || - __get_user(kern->shm_ctime, &user->shm_ctime) || - __get_user(kern->shm_cpid, &user->shm_cpid) || - __get_user(kern->shm_lpid, &user->shm_lpid) || - __get_user(kern->shm_nattch, &user->shm_nattch)) - return -EFAULT; - return 0; -} - -static inline int sunos_shmid_put(struct shmid_ds32 __user *user, - struct shmid_ds *kern) -{ - if (put_user(kern->shm_perm.key, &user->shm_perm.key) || - __put_user(kern->shm_perm.uid, &user->shm_perm.uid) || - __put_user(kern->shm_perm.gid, &user->shm_perm.gid) || - __put_user(kern->shm_perm.cuid, &user->shm_perm.cuid) || - __put_user(kern->shm_perm.cgid, &user->shm_perm.cgid) || - __put_user(kern->shm_segsz, &user->shm_segsz) || - __put_user(kern->shm_atime, &user->shm_atime) || - __put_user(kern->shm_dtime, &user->shm_dtime) || - __put_user(kern->shm_ctime, &user->shm_ctime) || - __put_user(kern->shm_cpid, &user->shm_cpid) || - __put_user(kern->shm_lpid, &user->shm_lpid) || - __put_user(kern->shm_nattch, &user->shm_nattch)) - return -EFAULT; - return 0; -} - -asmlinkage int sunos_shmsys(int op, u32 arg1, u32 arg2, u32 arg3) -{ - struct shmid_ds ksds; - unsigned long raddr; - mm_segment_t old_fs = get_fs(); - int rval; - - switch(op) { - case 0: - /* do_shmat(): attach a shared memory area */ - rval = do_shmat((int)arg1,(char __user *)(unsigned long)arg2,(int)arg3,&raddr); - if (!rval) - rval = (int) raddr; - break; - case 1: - /* sys_shmctl(): modify shared memory area attr. */ - if (!sunos_shmid_get((struct shmid_ds32 __user *)(unsigned long)arg3, &ksds)) { - set_fs(KERNEL_DS); - rval = sys_shmctl((int) arg1,(int) arg2, - (struct shmid_ds __user *) &ksds); - set_fs(old_fs); - if (!rval) - rval = sunos_shmid_put((struct shmid_ds32 __user *)(unsigned long)arg3, - &ksds); - } else - rval = -EFAULT; - break; - case 2: - /* sys_shmdt(): detach a shared memory area */ - rval = sys_shmdt((char __user *)(unsigned long)arg1); - break; - case 3: - /* sys_shmget(): get a shared memory area */ - rval = sys_shmget((key_t)arg1,(int)arg2,(int)arg3); - break; - default: - rval = -EINVAL; - break; - }; - return rval; -} - -extern asmlinkage long sparc32_open(const char __user * filename, int flags, int mode); - -asmlinkage int sunos_open(u32 fname, int flags, int mode) -{ - const char __user *filename = compat_ptr(fname); - - return sparc32_open(filename, flags, mode); -} - -#define SUNOS_EWOULDBLOCK 35 - -/* see the sunos man page read(2v) for an explanation - of this garbage. We use O_NDELAY to mark - file descriptors that have been set non-blocking - using 4.2BSD style calls. (tridge) */ - -static inline int check_nonblock(int ret, int fd) -{ - if (ret == -EAGAIN) { - struct file * file = fget(fd); - if (file) { - if (file->f_flags & O_NDELAY) - ret = -SUNOS_EWOULDBLOCK; - fput(file); - } - } - return ret; -} - -asmlinkage int sunos_read(unsigned int fd, char __user *buf, u32 count) -{ - int ret; - - ret = check_nonblock(sys_read(fd, buf, count), fd); - return ret; -} - -asmlinkage int sunos_readv(u32 fd, void __user *vector, s32 count) -{ - int ret; - - ret = check_nonblock(compat_sys_readv(fd, vector, count), fd); - return ret; -} - -asmlinkage int sunos_write(unsigned int fd, char __user *buf, u32 count) -{ - int ret; - - ret = check_nonblock(sys_write(fd, buf, count), fd); - return ret; -} - -asmlinkage int sunos_writev(u32 fd, void __user *vector, s32 count) -{ - int ret; - - ret = check_nonblock(compat_sys_writev(fd, vector, count), fd); - return ret; -} - -asmlinkage int sunos_recv(u32 __fd, void __user *ubuf, int size, unsigned flags) -{ - int ret, fd = (int) __fd; - - ret = check_nonblock(sys_recv(fd, ubuf, size, flags), fd); - return ret; -} - -asmlinkage int sunos_send(u32 __fd, void __user *buff, int len, unsigned flags) -{ - int ret, fd = (int) __fd; - - ret = check_nonblock(sys_send(fd, buff, len, flags), fd); - return ret; -} - -asmlinkage int sunos_accept(u32 __fd, struct sockaddr __user *sa, int __user *addrlen) -{ - int ret, fd = (int) __fd; - - while (1) { - ret = check_nonblock(sys_accept(fd, sa, addrlen), fd); - if (ret != -ENETUNREACH && ret != -EHOSTUNREACH) - break; - } - return ret; -} - -#define SUNOS_SV_INTERRUPT 2 - -asmlinkage int sunos_sigaction (int sig, - struct old_sigaction32 __user *act, - struct old_sigaction32 __user *oact) -{ - struct k_sigaction new_ka, old_ka; - int ret; - - if (act) { - compat_old_sigset_t mask; - u32 u_handler; - - if (get_user(u_handler, &act->sa_handler) || - __get_user(new_ka.sa.sa_flags, &act->sa_flags)) - return -EFAULT; - new_ka.sa.sa_handler = compat_ptr(u_handler); - __get_user(mask, &act->sa_mask); - new_ka.sa.sa_restorer = NULL; - new_ka.ka_restorer = NULL; - siginitset(&new_ka.sa.sa_mask, mask); - new_ka.sa.sa_flags ^= SUNOS_SV_INTERRUPT; - } - - ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); - - if (!ret && oact) { - old_ka.sa.sa_flags ^= SUNOS_SV_INTERRUPT; - if (put_user(ptr_to_compat(old_ka.sa.sa_handler), &oact->sa_handler) || - __put_user(old_ka.sa.sa_flags, &oact->sa_flags)) - return -EFAULT; - __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); - } - - return ret; -} - -asmlinkage int sunos_setsockopt(u32 __fd, u32 __level, u32 __optname, - char __user *optval, u32 __optlen) -{ - int fd = (int) __fd; - int level = (int) __level; - int optname = (int) __optname; - int optlen = (int) __optlen; - int tr_opt = optname; - int ret; - - if (level == SOL_IP) { - /* Multicast socketopts (ttl, membership) */ - if (tr_opt >=2 && tr_opt <= 6) - tr_opt += 30; - } - ret = sys_setsockopt(fd, level, tr_opt, - optval, optlen); - return ret; -} - -asmlinkage int sunos_getsockopt(u32 __fd, u32 __level, u32 __optname, - char __user *optval, int __user *optlen) -{ - int fd = (int) __fd; - int level = (int) __level; - int optname = (int) __optname; - int tr_opt = optname; - int ret; - - if (level == SOL_IP) { - /* Multicast socketopts (ttl, membership) */ - if (tr_opt >=2 && tr_opt <= 6) - tr_opt += 30; - } - ret = compat_sys_getsockopt(fd, level, tr_opt, - optval, optlen); - return ret; -} diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S index 6b9b718e24a..a4fef2ba1ae 100644 --- a/arch/sparc64/kernel/systbls.S +++ b/arch/sparc64/kernel/systbls.S @@ -155,125 +155,3 @@ sys_call_table: .word sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait /*310*/ .word sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate .word sys_timerfd_settime, sys_timerfd_gettime - -#if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \ - defined(CONFIG_SOLARIS_EMUL_MODULE) - /* Now the 32-bit SunOS syscall table. */ - - .align 4 - .globl sunos_sys_table -sunos_sys_table: -/*0*/ .word sunos_indir, sys32_exit, sys_fork - .word sunos_read, sunos_write, sunos_open - .word sys_close, sunos_wait4, sys_creat - .word sys_link, sys_unlink, sunos_execv - .word sys_chdir, sunos_nosys, sys32_mknod - .word sys_chmod, sys32_lchown16, sunos_brk - .word sunos_nosys, sys32_lseek, sunos_getpid - .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_getuid, sunos_nosys, sys_ptrace - .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys - .word sys_access, sunos_nosys, sunos_nosys - .word sys_sync, sys_kill, compat_sys_newstat - .word sunos_nosys, compat_sys_newlstat, sys_dup - .word sys_pipe, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_getgid - .word sunos_nosys, sunos_nosys -/*50*/ .word sunos_nosys, sys_acct, sunos_nosys - .word sunos_mctl, sunos_ioctl, sys_reboot - .word sunos_nosys, sys_symlink, sys_readlink - .word sys32_execve, sys_umask, sys_chroot - .word compat_sys_newfstat, sunos_nosys, sys_getpagesize - .word sys_msync, sys_vfork, sunos_nosys - .word sunos_nosys, sunos_sbrk, sunos_sstk - .word sunos_mmap, sunos_vadvise, sys_munmap - .word sys_mprotect, sys_madvise, sys_vhangup - .word sunos_nosys, sys_mincore, sys32_getgroups16 - .word sys32_setgroups16, sys_getpgrp, sunos_setpgrp - .word compat_sys_setitimer, sunos_nosys, sys_swapon - .word compat_sys_getitimer, sys_gethostname, sys_sethostname - .word sunos_getdtablesize, sys_dup2, sunos_nop - .word compat_sys_fcntl, sunos_select, sunos_nop - .word sys_fsync, sys32_setpriority, sys32_socket - .word sys32_connect, sunos_accept -/*100*/ .word sys_getpriority, sunos_send, sunos_recv - .word sunos_nosys, sys32_bind, sunos_setsockopt - .word sys32_listen, sunos_nosys, sunos_sigaction - .word sunos_sigblock, sunos_sigsetmask, sys_sigpause - .word sys32_sigstack, sys32_recvmsg, sys32_sendmsg - .word sunos_nosys, sys32_gettimeofday, compat_sys_getrusage - .word sunos_getsockopt, sunos_nosys, sunos_readv - .word sunos_writev, sys32_settimeofday, sys32_fchown16 - .word sys_fchmod, sys32_recvfrom, sys32_setreuid16 - .word sys32_setregid16, sys_rename, sys_truncate - .word sys_ftruncate, sys_flock, sunos_nosys - .word sys32_sendto, sys32_shutdown, sys32_socketpair - .word sys_mkdir, sys_rmdir, sys32_utimes - .word sys32_sigreturn, sunos_nosys, sys32_getpeername - .word sunos_gethostid, sunos_nosys, compat_sys_getrlimit - .word compat_sys_setrlimit, sunos_killpg, sunos_nosys - .word sunos_nosys, sunos_nosys -/*150*/ .word sys32_getsockname, sunos_nosys, sunos_nosys - .word sys_poll, sunos_nosys, sunos_nosys - .word sunos_getdirentries, compat_sys_statfs, compat_sys_fstatfs - .word sys_oldumount, sunos_nosys, sunos_nosys - .word sys_getdomainname, sys_setdomainname - .word sunos_nosys, sys_quotactl, sunos_nosys - .word sunos_nosys, sys_ustat, sunos_semsys - .word sunos_nosys, sunos_shmsys, sunos_audit - .word sunos_nosys, sunos_getdents, sys_setsid - .word sys_fchdir, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, compat_sys_sigpending, sunos_nosys - .word sys_setpgid, sunos_pathconf, sunos_fpathconf - .word sunos_sysconf, sunos_uname, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys -/*200*/ .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys -/*250*/ .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys -/*260*/ .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys -/*270*/ .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys -/*280*/ .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys -/*290*/ .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys -/*300*/ .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys -/*310*/ .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys - -#endif diff --git a/arch/sparc64/kernel/systbls.h b/arch/sparc64/kernel/systbls.h index 8a0d20a35d0..bc9f5dac406 100644 --- a/arch/sparc64/kernel/systbls.h +++ b/arch/sparc64/kernel/systbls.h @@ -27,8 +27,6 @@ extern asmlinkage unsigned long sys64_mremap(unsigned long addr, unsigned long new_addr); extern asmlinkage unsigned long c_sys_nis_syscall(struct pt_regs *regs); extern asmlinkage long sys_getdomainname(char __user *name, int len); -extern asmlinkage long solaris_syscall(struct pt_regs *regs); -extern asmlinkage long sunos_syscall(struct pt_regs *regs); extern asmlinkage long sys_utrap_install(utrap_entry_t type, utrap_handler_t new_p, utrap_handler_t new_d, diff --git a/arch/sparc64/kernel/ttable.S b/arch/sparc64/kernel/ttable.S index 7575aa371da..b0de4c00b11 100644 --- a/arch/sparc64/kernel/ttable.S +++ b/arch/sparc64/kernel/ttable.S @@ -117,16 +117,13 @@ tl0_f4o: FILL_4_OTHER tl0_f5o: FILL_5_OTHER tl0_f6o: FILL_6_OTHER tl0_f7o: FILL_7_OTHER -tl0_sunos: SUNOS_SYSCALL_TRAP +tl0_resv100: BTRAP(0x100) tl0_bkpt: BREAKPOINT_TRAP tl0_divz: TRAP(do_div0) tl0_flushw: FLUSH_WINDOW_TRAP -tl0_resv104: BTRAP(0x104) BTRAP(0x105) BTRAP(0x106) BTRAP(0x107) - .globl tl0_solaris -tl0_solaris: SOLARIS_SYSCALL_TRAP -tl0_resv109: BTRAP(0x109) -tl0_resv10a: BTRAP(0x10a) BTRAP(0x10b) BTRAP(0x10c) BTRAP(0x10d) BTRAP(0x10e) -tl0_resv10f: BTRAP(0x10f) +tl0_resv104: BTRAP(0x104) BTRAP(0x105) BTRAP(0x106) BTRAP(0x107) BTRAP(0x108) +tl0_resv109: BTRAP(0x109) BTRAP(0x10a) BTRAP(0x10b) BTRAP(0x10c) BTRAP(0x10d) +tl0_resv10e: BTRAP(0x10e) BTRAP(0x10f) tl0_linux32: LINUX_32BIT_SYSCALL_TRAP tl0_oldlinux64: LINUX_64BIT_SYSCALL_TRAP tl0_resv112: TRAP_UTRAP(UT_TRAP_INSTRUCTION_18,0x112) TRAP_UTRAP(UT_TRAP_INSTRUCTION_19,0x113) @@ -139,8 +136,7 @@ tl0_resv11e: TRAP_UTRAP(UT_TRAP_INSTRUCTION_30,0x11e) TRAP_UTRAP(UT_TRAP_INSTRUC tl0_getcc: GETCC_TRAP tl0_setcc: SETCC_TRAP tl0_getpsr: TRAP(do_getpsr) -tl0_resv123: BTRAP(0x123) BTRAP(0x124) BTRAP(0x125) BTRAP(0x126) -tl0_solindir: INDIRECT_SOLARIS_SYSCALL(156) +tl0_resv123: BTRAP(0x123) BTRAP(0x124) BTRAP(0x125) BTRAP(0x126) BTRAP(0x127) tl0_resv128: BTRAP(0x128) BTRAP(0x129) BTRAP(0x12a) BTRAP(0x12b) BTRAP(0x12c) tl0_resv12d: BTRAP(0x12d) BTRAP(0x12e) BTRAP(0x12f) BTRAP(0x130) BTRAP(0x131) tl0_resv132: BTRAP(0x132) BTRAP(0x133) BTRAP(0x134) BTRAP(0x135) BTRAP(0x136) diff --git a/arch/sparc64/solaris/Makefile b/arch/sparc64/solaris/Makefile deleted file mode 100644 index 8c8663033bf..00000000000 --- a/arch/sparc64/solaris/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# -# Makefile for the Solaris binary emulation. -# - -EXTRA_AFLAGS := -ansi - -solaris-objs := entry64.o fs.o misc.o signal.o systbl.o socket.o \ - ioctl.o ipc.o socksys.o timod.o - -obj-$(CONFIG_SOLARIS_EMUL) += solaris.o diff --git a/arch/sparc64/solaris/conv.h b/arch/sparc64/solaris/conv.h deleted file mode 100644 index 50e58232cf2..00000000000 --- a/arch/sparc64/solaris/conv.h +++ /dev/null @@ -1,38 +0,0 @@ -/* $Id: conv.h,v 1.4 1998/08/15 20:42:51 davem Exp $ - * conv.h: Utility macros for Solaris emulation - * - * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) - */ - -/* #define DEBUG_SOLARIS */ -#define DEBUG_SOLARIS_KMALLOC - -#ifndef __ASSEMBLY__ - -#include <asm/unistd.h> - -/* Use this to get at 32-bit user passed pointers. */ -#define A(__x) \ -({ unsigned long __ret; \ - __asm__ ("srl %0, 0, %0" \ - : "=r" (__ret) \ - : "0" (__x)); \ - (void __user *)__ret; \ -}) - -extern unsigned sys_call_table[]; -extern unsigned sys_call_table32[]; -extern unsigned sunos_sys_table[]; - -#define SYS(name) ((long)sys_call_table[__NR_##name]) -#define SUNOS(x) ((long)sunos_sys_table[x]) - -#ifdef DEBUG_SOLARIS -#define SOLD(s) printk("%s,%d,%s(): %s\n",__FILE__,__LINE__,__func__,(s)) -#define SOLDD(s) printk("solaris: "); printk s -#else -#define SOLD(s) -#define SOLDD(s) -#endif - -#endif /* __ASSEMBLY__ */ diff --git a/arch/sparc64/solaris/entry64.S b/arch/sparc64/solaris/entry64.S deleted file mode 100644 index f170324e8bf..00000000000 --- a/arch/sparc64/solaris/entry64.S +++ /dev/null @@ -1,223 +0,0 @@ -/* $Id: entry64.S,v 1.7 2002/02/09 19:49:31 davem Exp $ - * entry64.S: Solaris syscall emulation entry point. - * - * Copyright (C) 1996,1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) - * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu) - * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) - */ - -#include <linux/errno.h> - -#include <asm/head.h> -#include <asm/asi.h> -#include <asm/smp.h> -#include <asm/ptrace.h> -#include <asm/page.h> -#include <asm/signal.h> -#include <asm/pgtable.h> -#include <asm/processor.h> -#include <asm/thread_info.h> - -#include "conv.h" - -#define NR_SYSCALLS 256 - - .text -solaris_syscall_trace: - add %sp, PTREGS_OFF, %o0 - call syscall_trace - mov 0, %o1 - srl %i0, 0, %o0 - mov %i4, %o4 - srl %i1, 0, %o1 - mov %i5, %o5 - andcc %l3, 1, %g0 - be,pt %icc, 2f - srl %i2, 0, %o2 - b,pt %xcc, 2f - add %sp, PTREGS_OFF, %o0 - -solaris_sucks: -/* Solaris is a big system which needs to be able to do all the things - * in Inf+1 different ways */ - add %i6, 0x5c, %o0 - mov %i0, %g1 - mov %i1, %i0 - mov %i2, %i1 - srl %o0, 0, %o0 - mov %i3, %i2 - movrz %g1, 256, %g1 /* Ensure we don't loop forever */ - mov %i4, %i3 - mov %i5, %i4 - ba,pt %xcc, solaris_sparc_syscall -exen: lduwa [%o0] ASI_S, %i5 - -exenf: ba,pt %xcc, solaris_sparc_syscall - clr %i5 - -/* For shared binaries, binfmt_elf32 already sets up personality - and exec_domain. This is to handle static binaries as well */ -solaris_reg: - call solaris_register - nop - ba,pt %xcc, 1f - mov %i4, %o4 - -linux_syscall_for_solaris: - sethi %hi(sys_call_table32), %l6 - or %l6, %lo(sys_call_table32), %l6 - sll %l3, 2, %l4 - ba,pt %xcc, 10f - lduw [%l6 + %l4], %l3 - - /* Solaris system calls enter here... */ - .align 32 - .globl solaris_sparc_syscall, entry64_personality_patch -solaris_sparc_syscall: -entry64_personality_patch: - ldub [%g4 + 0x0], %l0 - cmp %g1, 255 - bg,pn %icc, solaris_unimplemented - srl %g1, 0, %g1 - sethi %hi(solaris_sys_table), %l7 - or %l7, %lo(solaris_sys_table), %l7 - brz,pn %g1, solaris_sucks - mov %i4, %o4 - sll %g1, 2, %l4 - cmp %l0, 1 - bne,pn %icc, solaris_reg -1: srl %i0, 0, %o0 - lduw [%l7 + %l4], %l3 - srl %i1, 0, %o1 - ldx [%g6 + TI_FLAGS], %l5 - cmp %l3, NR_SYSCALLS - bleu,a,pn %xcc, linux_syscall_for_solaris - nop - andcc %l3, 1, %g0 - bne,a,pn %icc, 10f - add %sp, PTREGS_OFF, %o0 -10: srl %i2, 0, %o2 - mov %i5, %o5 - andn %l3, 3, %l7 - andcc %l5, _TIF_SYSCALL_TRACE, %g0 - bne,pn %icc, solaris_syscall_trace - mov %i0, %l5 -2: call %l7 - srl %i3, 0, %o3 -ret_from_solaris: - stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] - ldx [%g6 + TI_FLAGS], %l6 - sra %o0, 0, %o0 - mov %ulo(TSTATE_XCARRY | TSTATE_ICARRY), %g2 - ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %g3 - cmp %o0, -ERESTART_RESTARTBLOCK - sllx %g2, 32, %g2 - bgeu,pn %xcc, 1f - andcc %l6, _TIF_SYSCALL_TRACE, %l6 - - /* System call success, clear Carry condition code. */ - andn %g3, %g2, %g3 - stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE] - bne,pn %icc, solaris_syscall_trace2 - ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 - andcc %l1, 1, %g0 - bne,pn %icc, 2f - clr %l6 - add %l1, 0x4, %l2 - stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC] ! pc = npc - call rtrap - stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] !npc = npc+4 - - /* When tnpc & 1, this comes from setcontext and we don't want to advance pc */ -2: andn %l1, 3, %l1 - call rtrap - stx %l1, [%sp + PTREGS_OFF + PT_V9_TNPC] !npc = npc&~3 - -1: - /* System call failure, set Carry condition code. - * Also, get abs(errno) to return to the process. - */ - sub %g0, %o0, %o0 - or %g3, %g2, %g3 - cmp %o0, ERANGE /* 0-ERANGE are identity mapped */ - bleu,pt %icc, 1f - cmp %o0, EMEDIUMTYPE - bgu,pn %icc, 1f - sethi %hi(solaris_err_table), %l6 - sll %o0, 2, %o0 - or %l6, %lo(solaris_err_table), %l6 - ldsw [%l6 + %o0], %o0 -1: stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] - mov 1, %l6 - stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE] - bne,pn %icc, solaris_syscall_trace2 - ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 - andcc %l1, 1, %g0 - bne,pn %icc, 2b - add %l1, 0x4, %l2 - stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC] ! pc = npc - call rtrap - stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] !npc = npc+4 - -solaris_syscall_trace2: - add %sp, PTREGS_OFF, %o0 - call syscall_trace - mov 1, %o1 - add %l1, 0x4, %l2 /* npc = npc+4 */ - andcc %l1, 1, %g0 - bne,pn %icc, 2b - nop - stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC] - call rtrap - stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] - - /* This one is tricky, so that's why we do it in assembly */ - .globl solaris_sigsuspend -solaris_sigsuspend: - call do_sol_sigsuspend - nop - brlz,pn %o0, ret_from_solaris - nop - call sys_sigsuspend - stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] - b,pt %xcc, ret_from_solaris - nop - - .globl solaris_getpid -solaris_getpid: - call sys_getppid - nop - call sys_getpid - stx %o0, [%sp + PTREGS_OFF + PT_V9_I1] - b,pt %xcc, ret_from_solaris - nop - - .globl solaris_getuid -solaris_getuid: - call sys_geteuid - nop - call sys_getuid - stx %o1, [%sp + PTREGS_OFF + PT_V9_I1] - b,pt %xcc, ret_from_solaris - nop - - .globl solaris_getgid -solaris_getgid: - call sys_getegid - nop - call sys_getgid - stx %o1, [%sp + PTREGS_OFF + PT_V9_I1] - b,pt %xcc, ret_from_solaris - nop - - .globl solaris_unimplemented -solaris_unimplemented: - call do_sol_unimplemented - add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, ret_from_solaris - nop - - .section __ex_table,"a" - .align 4 - .word exen, exenf - diff --git a/arch/sparc64/solaris/fs.c b/arch/sparc64/solaris/fs.c deleted file mode 100644 index 7d035f0d3ae..00000000000 --- a/arch/sparc64/solaris/fs.c +++ /dev/null @@ -1,745 +0,0 @@ -/* $Id: fs.c,v 1.27 2002/02/08 03:57:14 davem Exp $ - * fs.c: fs related syscall emulation for Solaris - * - * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) - * - * 1999-08-19 Implemented solaris F_FREESP (truncate) - * fcntl, by Jason Rappleye (rappleye@ccr.buffalo.edu) - */ - -#include <linux/types.h> -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/capability.h> -#include <linux/fs.h> -#include <linux/namei.h> -#include <linux/mm.h> -#include <linux/file.h> -#include <linux/stat.h> -#include <linux/smp_lock.h> -#include <linux/limits.h> -#include <linux/resource.h> -#include <linux/quotaops.h> -#include <linux/mount.h> -#include <linux/vfs.h> - -#include <asm/uaccess.h> -#include <asm/string.h> -#include <asm/ptrace.h> - -#include "conv.h" - -#define R3_VERSION 1 -#define R4_VERSION 2 - -typedef struct { - s32 tv_sec; - s32 tv_nsec; -} timestruct_t; - -struct sol_stat { - u32 st_dev; - s32 st_pad1[3]; /* network id */ - u32 st_ino; - u32 st_mode; - u32 st_nlink; - u32 st_uid; - u32 st_gid; - u32 st_rdev; - s32 st_pad2[2]; - s32 st_size; - s32 st_pad3; /* st_size, off_t expansion */ - timestruct_t st_atime; - timestruct_t st_mtime; - timestruct_t st_ctime; - s32 st_blksize; - s32 st_blocks; - char st_fstype[16]; - s32 st_pad4[8]; /* expansion area */ -}; - -struct sol_stat64 { - u32 st_dev; - s32 st_pad1[3]; /* network id */ - u64 st_ino; - u32 st_mode; - u32 st_nlink; - u32 st_uid; - u32 st_gid; - u32 st_rdev; - s32 st_pad2[2]; - s64 st_size; - timestruct_t st_atime; - timestruct_t st_mtime; - timestruct_t st_ctime; - s64 st_blksize; - s32 st_blocks; - char st_fstype[16]; - s32 st_pad4[4]; /* expansion area */ -}; - -#define UFSMAGIC (((unsigned)'u'<<24)||((unsigned)'f'<<16)||((unsigned)'s'<<8)) - -static inline int putstat(struct sol_stat __user *ubuf, struct kstat *kbuf) -{ - u32 ino; - - if (kbuf->size > MAX_NON_LFS || - !sysv_valid_dev(kbuf->dev) || - !sysv_valid_dev(kbuf->rdev)) - return -EOVERFLOW; - ino = kbuf->ino; - if (sizeof(ino) < sizeof(kbuf->ino) && ino != kbuf->ino) - return -EOVERFLOW; - if (put_user (sysv_encode_dev(kbuf->dev), &ubuf->st_dev) || - __put_user (ino, &ubuf->st_ino) || - __put_user (kbuf->mode, &ubuf->st_mode) || - __put_user (kbuf->nlink, &ubuf->st_nlink) || - __put_user (kbuf->uid, &ubuf->st_uid) || - __put_user (kbuf->gid, &ubuf->st_gid) || - __put_user (sysv_encode_dev(kbuf->rdev), &ubuf->st_rdev) || - __put_user (kbuf->size, &ubuf->st_size) || - __put_user (kbuf->atime.tv_sec, &ubuf->st_atime.tv_sec) || - __put_user (kbuf->atime.tv_nsec, &ubuf->st_atime.tv_nsec) || - __put_user (kbuf->mtime.tv_sec, &ubuf->st_mtime.tv_sec) || - __put_user (kbuf->mtime.tv_nsec, &ubuf->st_mtime.tv_nsec) || - __put_user (kbuf->ctime.tv_sec, &ubuf->st_ctime.tv_sec) || - __put_user (kbuf->ctime.tv_nsec, &ubuf->st_ctime.tv_nsec) || - __put_user (kbuf->blksize, &ubuf->st_blksize) || - __put_user (kbuf->blocks, &ubuf->st_blocks) || - __put_user (UFSMAGIC, (unsigned __user *)ubuf->st_fstype)) - return -EFAULT; - return 0; -} - -static inline int putstat64(struct sol_stat64 __user *ubuf, struct kstat *kbuf) -{ - if (!sysv_valid_dev(kbuf->dev) || !sysv_valid_dev(kbuf->rdev)) - return -EOVERFLOW; - if (put_user (sysv_encode_dev(kbuf->dev), &ubuf->st_dev) || - __put_user (kbuf->ino, &ubuf->st_ino) || - __put_user (kbuf->mode, &ubuf->st_mode) || - __put_user (kbuf->nlink, &ubuf->st_nlink) || - __put_user (kbuf->uid, &ubuf->st_uid) || - __put_user (kbuf->gid, &ubuf->st_gid) || - __put_user (sysv_encode_dev(kbuf->rdev), &ubuf->st_rdev) || - __put_user (kbuf->size, &ubuf->st_size) || - __put_user (kbuf->atime.tv_sec, &ubuf->st_atime.tv_sec) || - __put_user (kbuf->atime.tv_nsec, &ubuf->st_atime.tv_nsec) || - __put_user (kbuf->mtime.tv_sec, &ubuf->st_mtime.tv_sec) || - __put_user (kbuf->mtime.tv_nsec, &ubuf->st_mtime.tv_nsec) || - __put_user (kbuf->ctime.tv_sec, &ubuf->st_ctime.tv_sec) || - __put_user (kbuf->ctime.tv_nsec, &ubuf->st_ctime.tv_nsec) || - __put_user (kbuf->blksize, &ubuf->st_blksize) || - __put_user (kbuf->blocks, &ubuf->st_blocks) || - __put_user (UFSMAGIC, (unsigned __user *)ubuf->st_fstype)) - return -EFAULT; - return 0; -} - -asmlinkage int solaris_stat(u32 filename, u32 statbuf) -{ - struct kstat s; - int ret = vfs_stat(A(filename), &s); - if (!ret) - return putstat(A(statbuf), &s); - return ret; -} - -asmlinkage int solaris_xstat(int vers, u32 filename, u32 statbuf) -{ - /* Solaris doesn't bother with looking at vers, so we do neither */ - return solaris_stat(filename, statbuf); -} - -asmlinkage int solaris_stat64(u32 filename, u32 statbuf) -{ - struct kstat s; - int ret = vfs_stat(A(filename), &s); - if (!ret) - return putstat64(A(statbuf), &s); - return ret; -} - -asmlinkage int solaris_lstat(u32 filename, u32 statbuf) -{ - struct kstat s; - int ret = vfs_lstat(A(filename), &s); - if (!ret) - return putstat(A(statbuf), &s); - return ret; -} - -asmlinkage int solaris_lxstat(int vers, u32 filename, u32 statbuf) -{ - return solaris_lstat(filename, statbuf); -} - -asmlinkage int solaris_lstat64(u32 filename, u32 statbuf) -{ - struct kstat s; - int ret = vfs_lstat(A(filename), &s); - if (!ret) - return putstat64(A(statbuf), &s); - return ret; -} - -asmlinkage int solaris_fstat(unsigned int fd, u32 statbuf) -{ - struct kstat s; - int ret = vfs_fstat(fd, &s); - if (!ret) - return putstat(A(statbuf), &s); - return ret; -} - -asmlinkage int solaris_fxstat(int vers, u32 fd, u32 statbuf) -{ - return solaris_fstat(fd, statbuf); -} - -asmlinkage int solaris_fstat64(unsigned int fd, u32 statbuf) -{ - struct kstat s; - int ret = vfs_fstat(fd, &s); - if (!ret) - return putstat64(A(statbuf), &s); - return ret; -} - -asmlinkage int solaris_mknod(u32 path, u32 mode, s32 dev) -{ - int (*sys_mknod)(const char __user *,int,unsigned) = - (int (*)(const char __user *,int,unsigned))SYS(mknod); - int major = sysv_major(dev); - int minor = sysv_minor(dev); - - /* minor is guaranteed to be OK for MKDEV, major might be not */ - if (major > 0xfff) - return -EINVAL; - return sys_mknod(A(path), mode, new_encode_dev(MKDEV(major,minor))); -} - -asmlinkage int solaris_xmknod(int vers, u32 path, u32 mode, s32 dev) -{ - return solaris_mknod(path, mode, dev); -} - -asmlinkage int solaris_getdents64(unsigned int fd, void __user *dirent, unsigned int count) -{ - int (*sys_getdents)(unsigned int, void __user *, unsigned int) = - (int (*)(unsigned int, void __user *, unsigned int))SYS(getdents); - - return sys_getdents(fd, dirent, count); -} - -/* This statfs thingie probably will go in the near future, but... */ - -struct sol_statfs { - short f_type; - s32 f_bsize; - s32 f_frsize; - s32 f_blocks; - s32 f_bfree; - u32 f_files; - u32 f_ffree; - char f_fname[6]; - char f_fpack[6]; -}; - -asmlinkage int solaris_statfs(u32 path, u32 buf, int len, int fstype) -{ - int ret; - struct statfs s; - mm_segment_t old_fs = get_fs(); - int (*sys_statfs)(const char __user *,struct statfs __user *) = - (int (*)(const char __user *,struct statfs __user *))SYS(statfs); - struct sol_statfs __user *ss = A(buf); - - if (len != sizeof(struct sol_statfs)) return -EINVAL; - if (!fstype) { - /* FIXME: mixing userland and kernel pointers */ - set_fs (KERNEL_DS); - ret = sys_statfs(A(path), &s); - set_fs (old_fs); - if (!ret) { - if (put_user (s.f_type, &ss->f_type) || - __put_user (s.f_bsize, &ss->f_bsize) || - __put_user (0, &ss->f_frsize) || - __put_user (s.f_blocks, &ss->f_blocks) || - __put_user (s.f_bfree, &ss->f_bfree) || - __put_user (s.f_files, &ss->f_files) || - __put_user (s.f_ffree, &ss->f_ffree) || - __clear_user (&ss->f_fname, 12)) - return -EFAULT; - } - return ret; - } -/* Linux can't stat unmounted filesystems so we - * simply lie and claim 100MB of 1GB is free. Sorry. - */ - if (put_user (fstype, &ss->f_type) || - __put_user (1024, &ss->f_bsize) || - __put_user (0, &ss->f_frsize) || - __put_user (1024*1024, &ss->f_blocks) || - __put_user (100*1024, &ss->f_bfree) || - __put_user (60000, &ss->f_files) || - __put_user (50000, &ss->f_ffree) || - __clear_user (&ss->f_fname, 12)) - return -EFAULT; - return 0; -} - -asmlinkage int solaris_fstatfs(u32 fd, u32 buf, int len, int fstype) -{ - int ret; - struct statfs s; - mm_segment_t old_fs = get_fs(); - int (*sys_fstatfs)(unsigned,struct statfs __user *) = - (int (*)(unsigned,struct statfs __user *))SYS(fstatfs); - struct sol_statfs __user *ss = A(buf); - - if (len != sizeof(struct sol_statfs)) return -EINVAL; - if (!fstype) { - set_fs (KERNEL_DS); - ret = sys_fstatfs(fd, &s); - set_fs (old_fs); - if (!ret) { - if (put_user (s.f_type, &ss->f_type) || - __put_user (s.f_bsize, &ss->f_bsize) || - __put_user (0, &ss->f_frsize) || - __put_user (s.f_blocks, &ss->f_blocks) || - __put_user (s.f_bfree, &ss->f_bfree) || - __put_user (s.f_files, &ss->f_files) || - __put_user (s.f_ffree, &ss->f_ffree) || - __clear_user (&ss->f_fname, 12)) - return -EFAULT; - } - return ret; - } - /* Otherwise fstatfs is the same as statfs */ - return solaris_statfs(0, buf, len, fstype); -} - -struct sol_statvfs { - u32 f_bsize; - u32 f_frsize; - u32 f_blocks; - u32 f_bfree; - u32 f_bavail; - u32 f_files; - u32 f_ffree; - u32 f_favail; - u32 f_fsid; - char f_basetype[16]; - u32 f_flag; - u32 f_namemax; - char f_fstr[32]; - u32 f_filler[16]; -}; - -struct sol_statvfs64 { - u32 f_bsize; - u32 f_frsize; - u64 f_blocks; - u64 f_bfree; - u64 f_bavail; - u64 f_files; - u64 f_ffree; - u64 f_favail; - u32 f_fsid; - char f_basetype[16]; - u32 f_flag; - u32 f_namemax; - char f_fstr[32]; - u32 f_filler[16]; -}; - -static int report_statvfs(struct vfsmount *mnt, struct inode *inode, u32 buf) -{ - struct kstatfs s; - int error; - struct sol_statvfs __user *ss = A(buf); - - error = vfs_statfs(mnt->mnt_root, &s); - if (!error) { - const char *p = mnt->mnt_sb->s_type->name; - int i = 0; - int j = strlen (p); - - if (j > 15) j = 15; - if (IS_RDONLY(inode)) i = 1; - if (mnt->mnt_flags & MNT_NOSUID) i |= 2; - if (!sysv_valid_dev(inode->i_sb->s_dev)) - return -EOVERFLOW; - if (put_user (s.f_bsize, &ss->f_bsize) || - __put_user (0, &ss->f_frsize) || - __put_user (s.f_blocks, &ss->f_blocks) || - __put_user (s.f_bfree, &ss->f_bfree) || - __put_user (s.f_bavail, &ss->f_bavail) || - __put_user (s.f_files, &ss->f_files) || - __put_user (s.f_ffree, &ss->f_ffree) || - __put_user (s.f_ffree, &ss->f_favail) || - __put_user (sysv_encode_dev(inode->i_sb->s_dev), &ss->f_fsid) || - __copy_to_user (ss->f_basetype,p,j) || - __put_user (0, (char __user *)&ss->f_basetype[j]) || - __put_user (s.f_namelen, &ss->f_namemax) || - __put_user (i, &ss->f_flag) || - __clear_user (&ss->f_fstr, 32)) - return -EFAULT; - } - return error; -} - -static int report_statvfs64(struct vfsmount *mnt, struct inode *inode, u32 buf) -{ - struct kstatfs s; - int error; - struct sol_statvfs64 __user *ss = A(buf); - - error = vfs_statfs(mnt->mnt_root, &s); - if (!error) { - const char *p = mnt->mnt_sb->s_type->name; - int i = 0; - int j = strlen (p); - - if (j > 15) j = 15; - if (IS_RDONLY(inode)) i = 1; - if (mnt->mnt_flags & MNT_NOSUID) i |= 2; - if (!sysv_valid_dev(inode->i_sb->s_dev)) - return -EOVERFLOW; - if (put_user (s.f_bsize, &ss->f_bsize) || - __put_user (0, &ss->f_frsize) || - __put_user (s.f_blocks, &ss->f_blocks) || - __put_user (s.f_bfree, &ss->f_bfree) || - __put_user (s.f_bavail, &ss->f_bavail) || - __put_user (s.f_files, &ss->f_files) || - __put_user (s.f_ffree, &ss->f_ffree) || - __put_user (s.f_ffree, &ss->f_favail) || - __put_user (sysv_encode_dev(inode->i_sb->s_dev), &ss->f_fsid) || - __copy_to_user (ss->f_basetype,p,j) || - __put_user (0, (char __user *)&ss->f_basetype[j]) || - __put_user (s.f_namelen, &ss->f_namemax) || - __put_user (i, &ss->f_flag) || - __clear_user (&ss->f_fstr, 32)) - return -EFAULT; - } - return error; -} - -asmlinkage int solaris_statvfs(u32 path, u32 buf) -{ - struct nameidata nd; - int error; - - error = user_path_walk(A(path),&nd); - if (!error) { - struct inode *inode = nd.path.dentry->d_inode; - error = report_statvfs(nd.path.mnt, inode, buf); - path_put(&nd.path); - } - return error; -} - -asmlinkage int solaris_fstatvfs(unsigned int fd, u32 buf) -{ - struct file * file; - int error; - - error = -EBADF; - file = fget(fd); - if (file) { - error = report_statvfs(file->f_path.mnt, file->f_path.dentry->d_inode, buf); - fput(file); - } - - return error; -} - -asmlinkage int solaris_statvfs64(u32 path, u32 buf) -{ - struct nameidata nd; - int error; - - lock_kernel(); - error = user_path_walk(A(path), &nd); - if (!error) { - struct inode *inode = nd.path.dentry->d_inode; - error = report_statvfs64(nd.path.mnt, inode, buf); - path_put(&nd.path); - } - unlock_kernel(); - return error; -} - -asmlinkage int solaris_fstatvfs64(unsigned int fd, u32 buf) -{ - struct file * file; - int error; - - error = -EBADF; - file = fget(fd); - if (file) { - lock_kernel(); - error = report_statvfs64(file->f_path.mnt, file->f_path.dentry->d_inode, buf); - unlock_kernel(); - fput(file); - } - return error; -} - -extern asmlinkage long sparc32_open(const char * filename, int flags, int mode); - -asmlinkage int solaris_open(u32 fname, int flags, u32 mode) -{ - const char *filename = (const char *)(long)fname; - int fl = flags & 0xf; - - /* Translate flags first. */ - if (flags & 0x2000) fl |= O_LARGEFILE; - if (flags & 0x8050) fl |= O_SYNC; - if (flags & 0x80) fl |= O_NONBLOCK; - if (flags & 0x100) fl |= O_CREAT; - if (flags & 0x200) fl |= O_TRUNC; - if (flags & 0x400) fl |= O_EXCL; - if (flags & 0x800) fl |= O_NOCTTY; - flags = fl; - - return sparc32_open(filename, flags, mode); -} - -#define SOL_F_SETLK 6 -#define SOL_F_SETLKW 7 -#define SOL_F_FREESP 11 -#define SOL_F_ISSTREAM 13 -#define SOL_F_GETLK 14 -#define SOL_F_PRIV 15 -#define SOL_F_NPRIV 16 -#define SOL_F_QUOTACTL 17 -#define SOL_F_BLOCKS 18 -#define SOL_F_BLKSIZE 19 -#define SOL_F_GETOWN 23 -#define SOL_F_SETOWN 24 - -struct sol_flock { - short l_type; - short l_whence; - u32 l_start; - u32 l_len; - s32 l_sysid; - s32 l_pid; - s32 l_pad[4]; -}; - -asmlinkage int solaris_fcntl(unsigned fd, unsigned cmd, u32 arg) -{ - int (*sys_fcntl)(unsigned,unsigned,unsigned long) = - (int (*)(unsigned,unsigned,unsigned long))SYS(fcntl); - int ret, flags; - - switch (cmd) { - case F_DUPFD: - case F_GETFD: - case F_SETFD: return sys_fcntl(fd, cmd, (unsigned long)arg); - case F_GETFL: - flags = sys_fcntl(fd, cmd, 0); - ret = flags & 0xf; - if (flags & O_SYNC) ret |= 0x8050; - if (flags & O_NONBLOCK) ret |= 0x80; - return ret; - case F_SETFL: - flags = arg & 0xf; - if (arg & 0x8050) flags |= O_SYNC; - if (arg & 0x80) flags |= O_NONBLOCK; - return sys_fcntl(fd, cmd, (long)flags); - case SOL_F_GETLK: - case SOL_F_SETLK: - case SOL_F_SETLKW: - { - struct flock f; - struct sol_flock __user *p = A(arg); - mm_segment_t old_fs = get_fs(); - - switch (cmd) { - case SOL_F_GETLK: cmd = F_GETLK; break; - case SOL_F_SETLK: cmd = F_SETLK; break; - case SOL_F_SETLKW: cmd = F_SETLKW; break; - } - - if (get_user (f.l_type, &p->l_type) || - __get_user (f.l_whence, &p->l_whence) || - __get_user (f.l_start, &p->l_start) || - __get_user (f.l_len, &p->l_len) || - __get_user (f.l_pid, &p->l_sysid)) - return -EFAULT; - - set_fs(KERNEL_DS); - ret = sys_fcntl(fd, cmd, (unsigned long)&f); - set_fs(old_fs); - - if (__put_user (f.l_type, &p->l_type) || - __put_user (f.l_whence, &p->l_whence) || - __put_user (f.l_start, &p->l_start) || - __put_user (f.l_len, &p->l_len) || - __put_user (f.l_pid, &p->l_pid) || - __put_user (0, &p->l_sysid)) - return -EFAULT; - - return ret; - } - case SOL_F_FREESP: - { - int length; - int (*sys_newftruncate)(unsigned int, unsigned long)= - (int (*)(unsigned int, unsigned long))SYS(ftruncate); - - if (get_user(length, &((struct sol_flock __user *)A(arg))->l_start)) - return -EFAULT; - - return sys_newftruncate(fd, length); - } - }; - return -EINVAL; -} - -asmlinkage int solaris_ulimit(int cmd, int val) -{ - switch (cmd) { - case 1: /* UL_GETFSIZE - in 512B chunks */ - return current->signal->rlim[RLIMIT_FSIZE].rlim_cur >> 9; - case 2: /* UL_SETFSIZE */ - if ((unsigned long)val > (LONG_MAX>>9)) return -ERANGE; - val <<= 9; - task_lock(current->group_leader); - if (val > current->signal->rlim[RLIMIT_FSIZE].rlim_max) { - if (!capable(CAP_SYS_RESOURCE)) { - task_unlock(current->group_leader); - return -EPERM; - } - current->signal->rlim[RLIMIT_FSIZE].rlim_max = val; - } - current->signal->rlim[RLIMIT_FSIZE].rlim_cur = val; - task_unlock(current->group_leader); - return 0; - case 3: /* UL_GMEMLIM */ - return current->signal->rlim[RLIMIT_DATA].rlim_cur; - case 4: /* UL_GDESLIM */ - return sysctl_nr_open; - } - return -EINVAL; -} - -/* At least at the time I'm writing this, Linux doesn't have ACLs, so we - just fake this */ -asmlinkage int solaris_acl(u32 filename, int cmd, int nentries, u32 aclbufp) -{ - return -ENOSYS; -} - -asmlinkage int solaris_facl(unsigned int fd, int cmd, int nentries, u32 aclbufp) -{ - return -ENOSYS; -} - -asmlinkage int solaris_pread(unsigned int fd, char __user *buf, u32 count, u32 pos) -{ - ssize_t (*sys_pread64)(unsigned int, char __user *, size_t, loff_t) = - (ssize_t (*)(unsigned int, char __user *, size_t, loff_t))SYS(pread64); - - return sys_pread64(fd, buf, count, (loff_t)pos); -} - -asmlinkage int solaris_pwrite(unsigned int fd, char __user *buf, u32 count, u32 pos) -{ - ssize_t (*sys_pwrite64)(unsigned int, char __user *, size_t, loff_t) = - (ssize_t (*)(unsigned int, char __user *, size_t, loff_t))SYS(pwrite64); - - return sys_pwrite64(fd, buf, count, (loff_t)pos); -} - -/* POSIX.1 names */ -#define _PC_LINK_MAX 1 -#define _PC_MAX_CANON 2 -#define _PC_MAX_INPUT 3 -#define _PC_NAME_MAX 4 -#define _PC_PATH_MAX 5 -#define _PC_PIPE_BUF 6 -#define _PC_NO_TRUNC 7 -#define _PC_VDISABLE 8 -#define _PC_CHOWN_RESTRICTED 9 -/* POSIX.4 names */ -#define _PC_ASYNC_IO 10 -#define _PC_PRIO_IO 11 -#define _PC_SYNC_IO 12 -#define _PC_LAST 12 - -/* This is not a real and complete implementation yet, just to keep - * the easy Solaris binaries happy. - */ -asmlinkage int solaris_fpathconf(int fd, int name) -{ - int ret; - - switch(name) { - case _PC_LINK_MAX: - ret = LINK_MAX; - break; - case _PC_MAX_CANON: - ret = MAX_CANON; - break; - case _PC_MAX_INPUT: - ret = MAX_INPUT; - break; - case _PC_NAME_MAX: - ret = NAME_MAX; - break; - case _PC_PATH_MAX: - ret = PATH_MAX; - break; - case _PC_PIPE_BUF: - ret = PIPE_BUF; - break; - case _PC_CHOWN_RESTRICTED: - ret = 1; - break; - case _PC_NO_TRUNC: - case _PC_VDISABLE: - ret = 0; - break; - default: - ret = -EINVAL; - break; - } - return ret; -} - -asmlinkage int solaris_pathconf(u32 path, int name) -{ - return solaris_fpathconf(0, name); -} - -/* solaris_llseek returns long long - quite difficult */ -asmlinkage long solaris_llseek(struct pt_regs *regs, u32 off_hi, u32 off_lo, int whence) -{ - int (*sys_llseek)(unsigned int, unsigned long, unsigned long, loff_t __user *, unsigned int) = - (int (*)(unsigned int, unsigned long, unsigned long, loff_t __user *, unsigned int))SYS(_llseek); - int ret; - mm_segment_t old_fs = get_fs(); - loff_t retval; - - set_fs(KERNEL_DS); - ret = sys_llseek((unsigned int)regs->u_regs[UREG_I0], off_hi, off_lo, &retval, whence); - set_fs(old_fs); - if (ret < 0) return ret; - regs->u_regs[UREG_I1] = (u32)retval; - return (retval >> 32); -} - -/* Have to mask out all but lower 3 bits */ -asmlinkage int solaris_access(u32 filename, long mode) -{ - int (*sys_access)(const char __user *, int) = - (int (*)(const char __user *, int))SYS(access); - - return sys_access(A(filename), mode & 7); -} diff --git a/arch/sparc64/solaris/ioctl.c b/arch/sparc64/solaris/ioctl.c deleted file mode 100644 index 8ad10a6d993..00000000000 --- a/arch/sparc64/solaris/ioctl.c +++ /dev/null @@ -1,825 +0,0 @@ -/* $Id: ioctl.c,v 1.17 2002/02/08 03:57:14 davem Exp $ - * ioctl.c: Solaris ioctl emulation. - * - * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) - * Copyright (C) 1997,1998 Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz) - * - * Streams & timod emulation based on code - * Copyright (C) 1995, 1996 Mike Jagdis (jaggy@purplet.demon.co.uk) - * - * 1999-08-19 Implemented solaris 'm' (mag tape) and - * 'O' (openprom) ioctls, by Jason Rappleye - * (rappleye@ccr.buffalo.edu) - */ - -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/smp.h> -#include <linux/smp_lock.h> -#include <linux/syscalls.h> -#include <linux/ioctl.h> -#include <linux/fs.h> -#include <linux/file.h> -#include <linux/netdevice.h> -#include <linux/mtio.h> -#include <linux/time.h> -#include <linux/rcupdate.h> -#include <linux/compat.h> - -#include <net/sock.h> -#include <net/net_namespace.h> - -#include <asm/uaccess.h> -#include <asm/termios.h> -#include <asm/openpromio.h> - -#include "conv.h" -#include "socksys.h" - -extern asmlinkage int compat_sys_ioctl(unsigned int fd, unsigned int cmd, - u32 arg); -asmlinkage int solaris_ioctl(unsigned int fd, unsigned int cmd, u32 arg); - -extern int timod_putmsg(unsigned int fd, char __user *ctl_buf, int ctl_len, - char __user *data_buf, int data_len, int flags); -extern int timod_getmsg(unsigned int fd, char __user *ctl_buf, int ctl_maxlen, int __user *ctl_len, - char __user *data_buf, int data_maxlen, int __user *data_len, int *flags); - -/* termio* stuff {{{ */ - -struct solaris_termios { - u32 c_iflag; - u32 c_oflag; - u32 c_cflag; - u32 c_lflag; - u8 c_cc[19]; -}; - -struct solaris_termio { - u16 c_iflag; - u16 c_oflag; - u16 c_cflag; - u16 c_lflag; - s8 c_line; - u8 c_cc[8]; -}; - -struct solaris_termiox { - u16 x_hflag; - u16 x_cflag; - u16 x_rflag[5]; - u16 x_sflag; -}; - -static u32 solaris_to_linux_cflag(u32 cflag) -{ - cflag &= 0x7fdff000; - if (cflag & 0x200000) { - int baud = cflag & 0xf; - cflag &= ~0x20000f; - switch (baud) { - case 0: baud = B57600; break; - case 1: baud = B76800; break; - case 2: baud = B115200; break; - case 3: baud = B153600; break; - case 4: baud = B230400; break; - case 5: baud = B307200; break; - case 6: baud = B460800; break; - } - cflag |= CBAUDEX | baud; - } - return cflag; -} - -static u32 linux_to_solaris_cflag(u32 cflag) -{ - cflag &= ~(CMSPAR | CIBAUD); - if (cflag & CBAUDEX) { - int baud = cflag & CBAUD; - cflag &= ~CBAUD; - switch (baud) { - case B57600: baud = 0; break; - case B76800: baud = 1; break; - case B115200: baud = 2; break; - case B153600: baud = 3; break; - case B230400: baud = 4; break; - case B307200: baud = 5; break; - case B460800: baud = 6; break; - case B614400: baud = 7; break; - case B921600: baud = 8; break; -#if 0 - case B1843200: baud = 9; break; -#endif - } - cflag |= 0x200000 | baud; - } - return cflag; -} - -static inline int linux_to_solaris_termio(unsigned int fd, unsigned int cmd, u32 arg) -{ - struct solaris_termio __user *p = A(arg); - int ret; - - ret = sys_ioctl(fd, cmd, (unsigned long)p); - if (!ret) { - u32 cflag; - - if (__get_user (cflag, &p->c_cflag)) - return -EFAULT; - cflag = linux_to_solaris_cflag(cflag); - if (__put_user (cflag, &p->c_cflag)) - return -EFAULT; - } - return ret; -} - -static int solaris_to_linux_termio(unsigned int fd, unsigned int cmd, u32 arg) -{ - int ret; - struct solaris_termio s; - mm_segment_t old_fs = get_fs(); - - if (copy_from_user (&s, (struct solaris_termio __user *)A(arg), sizeof(struct solaris_termio))) - return -EFAULT; - s.c_cflag = solaris_to_linux_cflag(s.c_cflag); - set_fs(KERNEL_DS); - ret = sys_ioctl(fd, cmd, (unsigned long)&s); - set_fs(old_fs); - return ret; -} - -static inline int linux_to_solaris_termios(unsigned int fd, unsigned int cmd, u32 arg) -{ - int ret; - struct solaris_termios s; - mm_segment_t old_fs = get_fs(); - - set_fs(KERNEL_DS); - ret = sys_ioctl(fd, cmd, (unsigned long)&s); - set_fs(old_fs); - if (!ret) { - struct solaris_termios __user *p = A(arg); - if (put_user (s.c_iflag, &p->c_iflag) || - __put_user (s.c_oflag, &p->c_oflag) || - __put_user (linux_to_solaris_cflag(s.c_cflag), &p->c_cflag) || - __put_user (s.c_lflag, &p->c_lflag) || - __copy_to_user (p->c_cc, s.c_cc, 16) || - __clear_user (p->c_cc + 16, 2)) - return -EFAULT; - } - return ret; -} - -static int solaris_to_linux_termios(unsigned int fd, unsigned int cmd, u32 arg) -{ - int ret; - struct solaris_termios s; - struct solaris_termios __user *p = A(arg); - mm_segment_t old_fs = get_fs(); - - set_fs(KERNEL_DS); - ret = sys_ioctl(fd, TCGETS, (unsigned long)&s); - set_fs(old_fs); - if (ret) return ret; - if (put_user (s.c_iflag, &p->c_iflag) || - __put_user (s.c_oflag, &p->c_oflag) || - __put_user (s.c_cflag, &p->c_cflag) || - __put_user (s.c_lflag, &p->c_lflag) || - __copy_from_user (s.c_cc, p->c_cc, 16)) - return -EFAULT; - s.c_cflag = solaris_to_linux_cflag(s.c_cflag); - set_fs(KERNEL_DS); - ret = sys_ioctl(fd, cmd, (unsigned long)&s); - set_fs(old_fs); - return ret; -} - -static inline int solaris_T(unsigned int fd, unsigned int cmd, u32 arg) -{ - switch (cmd & 0xff) { - case 1: /* TCGETA */ - return linux_to_solaris_termio(fd, TCGETA, arg); - case 2: /* TCSETA */ - return solaris_to_linux_termio(fd, TCSETA, arg); - case 3: /* TCSETAW */ - return solaris_to_linux_termio(fd, TCSETAW, arg); - case 4: /* TCSETAF */ - return solaris_to_linux_termio(fd, TCSETAF, arg); - case 5: /* TCSBRK */ - return sys_ioctl(fd, TCSBRK, arg); - case 6: /* TCXONC */ - return sys_ioctl(fd, TCXONC, arg); - case 7: /* TCFLSH */ - return sys_ioctl(fd, TCFLSH, arg); - case 13: /* TCGETS */ - return linux_to_solaris_termios(fd, TCGETS, arg); - case 14: /* TCSETS */ - return solaris_to_linux_termios(fd, TCSETS, arg); - case 15: /* TCSETSW */ - return solaris_to_linux_termios(fd, TCSETSW, arg); - case 16: /* TCSETSF */ - return solaris_to_linux_termios(fd, TCSETSF, arg); - case 103: /* TIOCSWINSZ */ - return sys_ioctl(fd, TIOCSWINSZ, arg); - case 104: /* TIOCGWINSZ */ - return sys_ioctl(fd, TIOCGWINSZ, arg); - } - return -ENOSYS; -} - -static inline int solaris_t(unsigned int fd, unsigned int cmd, u32 arg) -{ - switch (cmd & 0xff) { - case 20: /* TIOCGPGRP */ - return sys_ioctl(fd, TIOCGPGRP, arg); - case 21: /* TIOCSPGRP */ - return sys_ioctl(fd, TIOCSPGRP, arg); - } - return -ENOSYS; -} - -/* }}} */ - -/* A pseudo STREAMS support {{{ */ - -struct strioctl { - int cmd, timeout, len; - u32 data; -}; - -struct solaris_si_sockparams { - int sp_family; - int sp_type; - int sp_protocol; -}; - -struct solaris_o_si_udata { - int tidusize; - int addrsize; - int optsize; - int etsdusize; - int servtype; - int so_state; - int so_options; - int tsdusize; -}; - -struct solaris_si_udata { - int tidusize; - int addrsize; - int optsize; - int etsdusize; - int servtype; - int so_state; - int so_options; - int tsdusize; - struct solaris_si_sockparams sockparams; -}; - -#define SOLARIS_MODULE_TIMOD 0 -#define SOLARIS_MODULE_SOCKMOD 1 -#define SOLARIS_MODULE_MAX 2 - -static struct module_info { - const char *name; - /* can be expanded further if needed */ -} module_table[ SOLARIS_MODULE_MAX + 1 ] = { - /* the ordering here must match the module numbers above! */ - { "timod" }, - { "sockmod" }, - { NULL } -}; - -static inline int solaris_sockmod(unsigned int fd, unsigned int cmd, u32 arg) -{ - struct inode *ino; - struct fdtable *fdt; - /* I wonder which of these tests are superfluous... --patrik */ - rcu_read_lock(); - fdt = files_fdtable(current->files); - if (! fdt->fd[fd] || - ! fdt->fd[fd]->f_path.dentry || - ! (ino = fdt->fd[fd]->f_path.dentry->d_inode) || - ! S_ISSOCK(ino->i_mode)) { - rcu_read_unlock(); - return TBADF; - } - rcu_read_unlock(); - - switch (cmd & 0xff) { - case 109: /* SI_SOCKPARAMS */ - { - struct solaris_si_sockparams si; - if (copy_from_user (&si, A(arg), sizeof(si))) - return (EFAULT << 8) | TSYSERR; - - /* Should we modify socket ino->socket_i.ops and type? */ - return 0; - } - case 110: /* SI_GETUDATA */ - { - int etsdusize, servtype; - struct solaris_si_udata __user *p = A(arg); - switch (SOCKET_I(ino)->type) { - case SOCK_STREAM: - etsdusize = 1; - servtype = 2; - break; - default: - etsdusize = -2; - servtype = 3; - break; - } - if (put_user(16384, &p->tidusize) || - __put_user(sizeof(struct sockaddr), &p->addrsize) || - __put_user(-1, &p->optsize) || - __put_user(etsdusize, &p->etsdusize) || - __put_user(servtype, &p->servtype) || - __put_user(0, &p->so_state) || - __put_user(0, &p->so_options) || - __put_user(16384, &p->tsdusize) || - __put_user(SOCKET_I(ino)->ops->family, &p->sockparams.sp_family) || - __put_user(SOCKET_I(ino)->type, &p->sockparams.sp_type) || - __put_user(SOCKET_I(ino)->ops->family, &p->sockparams.sp_protocol)) - return (EFAULT << 8) | TSYSERR; - return 0; - } - case 101: /* O_SI_GETUDATA */ - { - int etsdusize, servtype; - struct solaris_o_si_udata __user *p = A(arg); - switch (SOCKET_I(ino)->type) { - case SOCK_STREAM: - etsdusize = 1; - servtype = 2; - break; - default: - etsdusize = -2; - servtype = 3; - break; - } - if (put_user(16384, &p->tidusize) || - __put_user(sizeof(struct sockaddr), &p->addrsize) || - __put_user(-1, &p->optsize) || - __put_user(etsdusize, &p->etsdusize) || - __put_user(servtype, &p->servtype) || - __put_user(0, &p->so_state) || - __put_user(0, &p->so_options) || - __put_user(16384, &p->tsdusize)) - return (EFAULT << 8) | TSYSERR; - return 0; - } - case 102: /* SI_SHUTDOWN */ - case 103: /* SI_LISTEN */ - case 104: /* SI_SETMYNAME */ - case 105: /* SI_SETPEERNAME */ - case 106: /* SI_GETINTRANSIT */ - case 107: /* SI_TCL_LINK */ - case 108: /* SI_TCL_UNLINK */ - ; - } - return TNOTSUPPORT; -} - -static inline int solaris_timod(unsigned int fd, unsigned int cmd, u32 arg, - int len, int __user *len_p) -{ - int ret; - - switch (cmd & 0xff) { - case 141: /* TI_OPTMGMT */ - { - int i; - u32 prim; - SOLD("TI_OPMGMT entry"); - ret = timod_putmsg(fd, A(arg), len, NULL, -1, 0); - SOLD("timod_putmsg() returned"); - if (ret) - return (-ret << 8) | TSYSERR; - i = MSG_HIPRI; - SOLD("calling timod_getmsg()"); - ret = timod_getmsg(fd, A(arg), len, len_p, NULL, -1, NULL, &i); - SOLD("timod_getmsg() returned"); - if (ret) - return (-ret << 8) | TSYSERR; - SOLD("ret ok"); - if (get_user(prim, (u32 __user *)A(arg))) - return (EFAULT << 8) | TSYSERR; - SOLD("got prim"); - if (prim == T_ERROR_ACK) { - u32 tmp, tmp2; - SOLD("prim is T_ERROR_ACK"); - if (get_user(tmp, (u32 __user *)A(arg)+3) || - get_user(tmp2, (u32 __user *)A(arg)+2)) - return (EFAULT << 8) | TSYSERR; - return (tmp2 << 8) | tmp; - } - SOLD("TI_OPMGMT return 0"); - return 0; - } - case 142: /* TI_BIND */ - { - int i; - u32 prim; - SOLD("TI_BIND entry"); - ret = timod_putmsg(fd, A(arg), len, NULL, -1, 0); - SOLD("timod_putmsg() returned"); - if (ret) - return (-ret << 8) | TSYSERR; - len = 1024; /* Solaris allows arbitrary return size */ - i = MSG_HIPRI; - SOLD("calling timod_getmsg()"); - ret = timod_getmsg(fd, A(arg), len, len_p, NULL, -1, NULL, &i); - SOLD("timod_getmsg() returned"); - if (ret) - return (-ret << 8) | TSYSERR; - SOLD("ret ok"); - if (get_user(prim, (u32 __user *)A(arg))) - return (EFAULT << 8) | TSYSERR; - SOLD("got prim"); - if (prim == T_ERROR_ACK) { - u32 tmp, tmp2; - SOLD("prim is T_ERROR_ACK"); - if (get_user(tmp, (u32 __user *)A(arg)+3) || - get_user(tmp2, (u32 __user *)A(arg)+2)) - return (EFAULT << 8) | TSYSERR; - return (tmp2 << 8) | tmp; - } - SOLD("no ERROR_ACK requested"); - if (prim != T_OK_ACK) - return TBADSEQ; - SOLD("OK_ACK requested"); - i = MSG_HIPRI; - SOLD("calling timod_getmsg()"); - ret = timod_getmsg(fd, A(arg), len, len_p, NULL, -1, NULL, &i); - SOLD("timod_getmsg() returned"); - if (ret) - return (-ret << 8) | TSYSERR; - SOLD("TI_BIND return ok"); - return 0; - } - case 140: /* TI_GETINFO */ - case 143: /* TI_UNBIND */ - case 144: /* TI_GETMYNAME */ - case 145: /* TI_GETPEERNAME */ - case 146: /* TI_SETMYNAME */ - case 147: /* TI_SETPEERNAME */ - ; - } - return TNOTSUPPORT; -} - -static inline int solaris_S(struct file *filp, unsigned int fd, unsigned int cmd, u32 arg) -{ - char *p; - int ret; - mm_segment_t old_fs; - struct strioctl si; - struct inode *ino; - struct sol_socket_struct *sock; - struct module_info *mi; - - ino = filp->f_path.dentry->d_inode; - if (!S_ISSOCK(ino->i_mode)) - return -EBADF; - sock = filp->private_data; - if (! sock) { - printk("solaris_S: NULL private_data\n"); - return -EBADF; - } - if (sock->magic != SOLARIS_SOCKET_MAGIC) { - printk("solaris_S: invalid magic\n"); - return -EBADF; - } - - - switch (cmd & 0xff) { - case 1: /* I_NREAD */ - return -ENOSYS; - case 2: /* I_PUSH */ - { - p = getname (A(arg)); - if (IS_ERR (p)) - return PTR_ERR(p); - ret = -EINVAL; - for (mi = module_table; mi->name; mi++) { - if (strcmp(mi->name, p) == 0) { - sol_module m; - if (sock->modcount >= MAX_NR_STREAM_MODULES) { - ret = -ENXIO; - break; - } - m = (sol_module) (mi - module_table); - sock->module[sock->modcount++] = m; - ret = 0; - break; - } - } - putname (p); - return ret; - } - case 3: /* I_POP */ - if (sock->modcount <= 0) return -EINVAL; - sock->modcount--; - return 0; - case 4: /* I_LOOK */ - { - const char *p; - if (sock->modcount <= 0) return -EINVAL; - p = module_table[(unsigned)sock->module[sock->modcount]].name; - if (copy_to_user (A(arg), p, strlen(p))) - return -EFAULT; - return 0; - } - case 5: /* I_FLUSH */ - return 0; - case 8: /* I_STR */ - if (copy_from_user(&si, A(arg), sizeof(struct strioctl))) - return -EFAULT; - /* We ignore what module is actually at the top of stack. */ - switch ((si.cmd >> 8) & 0xff) { - case 'I': - return solaris_sockmod(fd, si.cmd, si.data); - case 'T': - return solaris_timod(fd, si.cmd, si.data, si.len, - &((struct strioctl __user *)A(arg))->len); - default: - return solaris_ioctl(fd, si.cmd, si.data); - } - case 9: /* I_SETSIG */ - return sys_ioctl(fd, FIOSETOWN, current->pid); - case 10: /* I_GETSIG */ - old_fs = get_fs(); - set_fs(KERNEL_DS); - sys_ioctl(fd, FIOGETOWN, (unsigned long)&ret); - set_fs(old_fs); - if (ret == current->pid) return 0x3ff; - else return -EINVAL; - case 11: /* I_FIND */ - { - int i; - p = getname (A(arg)); - if (IS_ERR (p)) - return PTR_ERR(p); - ret = 0; - for (i = 0; i < sock->modcount; i++) { - unsigned m = sock->module[i]; - if (strcmp(module_table[m].name, p) == 0) { - ret = 1; - break; - } - } - putname (p); - return ret; - } - case 19: /* I_SWROPT */ - case 32: /* I_SETCLTIME */ - return 0; /* Lie */ - } - return -ENOSYS; -} - -static inline int solaris_s(unsigned int fd, unsigned int cmd, u32 arg) -{ - switch (cmd & 0xff) { - case 0: /* SIOCSHIWAT */ - case 2: /* SIOCSLOWAT */ - return 0; /* We don't support them */ - case 1: /* SIOCGHIWAT */ - case 3: /* SIOCGLOWAT */ - if (put_user (0, (u32 __user *)A(arg))) - return -EFAULT; - return 0; /* Lie */ - case 7: /* SIOCATMARK */ - return sys_ioctl(fd, SIOCATMARK, arg); - case 8: /* SIOCSPGRP */ - return sys_ioctl(fd, SIOCSPGRP, arg); - case 9: /* SIOCGPGRP */ - return sys_ioctl(fd, SIOCGPGRP, arg); - } - return -ENOSYS; -} - -static inline int solaris_r(unsigned int fd, unsigned int cmd, u32 arg) -{ - switch (cmd & 0xff) { - case 10: /* SIOCADDRT */ - return compat_sys_ioctl(fd, SIOCADDRT, arg); - case 11: /* SIOCDELRT */ - return compat_sys_ioctl(fd, SIOCDELRT, arg); - } - return -ENOSYS; -} - -static inline int solaris_i(unsigned int fd, unsigned int cmd, u32 arg) -{ - switch (cmd & 0xff) { - case 12: /* SIOCSIFADDR */ - return compat_sys_ioctl(fd, SIOCSIFADDR, arg); - case 13: /* SIOCGIFADDR */ - return compat_sys_ioctl(fd, SIOCGIFADDR, arg); - case 14: /* SIOCSIFDSTADDR */ - return compat_sys_ioctl(fd, SIOCSIFDSTADDR, arg); - case 15: /* SIOCGIFDSTADDR */ - return compat_sys_ioctl(fd, SIOCGIFDSTADDR, arg); - case 16: /* SIOCSIFFLAGS */ - return compat_sys_ioctl(fd, SIOCSIFFLAGS, arg); - case 17: /* SIOCGIFFLAGS */ - return compat_sys_ioctl(fd, SIOCGIFFLAGS, arg); - case 18: /* SIOCSIFMEM */ - return compat_sys_ioctl(fd, SIOCSIFMEM, arg); - case 19: /* SIOCGIFMEM */ - return compat_sys_ioctl(fd, SIOCGIFMEM, arg); - case 20: /* SIOCGIFCONF */ - return compat_sys_ioctl(fd, SIOCGIFCONF, arg); - case 21: /* SIOCSIFMTU */ - return compat_sys_ioctl(fd, SIOCSIFMTU, arg); - case 22: /* SIOCGIFMTU */ - return compat_sys_ioctl(fd, SIOCGIFMTU, arg); - case 23: /* SIOCGIFBRDADDR */ - return compat_sys_ioctl(fd, SIOCGIFBRDADDR, arg); - case 24: /* SIOCSIFBRDADDR */ - return compat_sys_ioctl(fd, SIOCSIFBRDADDR, arg); - case 25: /* SIOCGIFNETMASK */ - return compat_sys_ioctl(fd, SIOCGIFNETMASK, arg); - case 26: /* SIOCSIFNETMASK */ - return compat_sys_ioctl(fd, SIOCSIFNETMASK, arg); - case 27: /* SIOCGIFMETRIC */ - return compat_sys_ioctl(fd, SIOCGIFMETRIC, arg); - case 28: /* SIOCSIFMETRIC */ - return compat_sys_ioctl(fd, SIOCSIFMETRIC, arg); - case 30: /* SIOCSARP */ - return compat_sys_ioctl(fd, SIOCSARP, arg); - case 31: /* SIOCGARP */ - return compat_sys_ioctl(fd, SIOCGARP, arg); - case 32: /* SIOCDARP */ - return compat_sys_ioctl(fd, SIOCDARP, arg); - case 52: /* SIOCGETNAME */ - case 53: /* SIOCGETPEER */ - { - struct sockaddr uaddr; - int uaddr_len = sizeof(struct sockaddr), ret; - long args[3]; - mm_segment_t old_fs = get_fs(); - int (*sys_socketcall)(int, unsigned long *) = - (int (*)(int, unsigned long *))SYS(socketcall); - - args[0] = fd; args[1] = (long)&uaddr; args[2] = (long)&uaddr_len; - set_fs(KERNEL_DS); - ret = sys_socketcall(((cmd & 0xff) == 52) ? SYS_GETSOCKNAME : SYS_GETPEERNAME, - args); - set_fs(old_fs); - if (ret >= 0) { - if (copy_to_user(A(arg), &uaddr, uaddr_len)) - return -EFAULT; - } - return ret; - } -#if 0 - case 86: /* SIOCSOCKSYS */ - return socksys_syscall(fd, arg); -#endif - case 87: /* SIOCGIFNUM */ - { - struct net_device *d; - int i = 0; - - read_lock_bh(&dev_base_lock); - for_each_netdev(&init_net, d) - i++; - read_unlock_bh(&dev_base_lock); - - if (put_user (i, (int __user *)A(arg))) - return -EFAULT; - return 0; - } - } - return -ENOSYS; -} - -static int solaris_m(unsigned int fd, unsigned int cmd, u32 arg) -{ - int ret; - - switch (cmd & 0xff) { - case 1: /* MTIOCTOP */ - ret = sys_ioctl(fd, MTIOCTOP, (unsigned long)&arg); - break; - case 2: /* MTIOCGET */ - ret = sys_ioctl(fd, MTIOCGET, (unsigned long)&arg); - break; - case 3: /* MTIOCGETDRIVETYPE */ - case 4: /* MTIOCPERSISTENT */ - case 5: /* MTIOCPERSISTENTSTATUS */ - case 6: /* MTIOCLRERR */ - case 7: /* MTIOCGUARANTEEDORDER */ - case 8: /* MTIOCRESERVE */ - case 9: /* MTIOCRELEASE */ - case 10: /* MTIOCFORCERESERVE */ - case 13: /* MTIOCSTATE */ - case 14: /* MTIOCREADIGNOREILI */ - case 15: /* MTIOCREADIGNOREEOFS */ - case 16: /* MTIOCSHORTFMK */ - default: - ret = -ENOSYS; /* linux doesn't support these */ - break; - }; - - return ret; -} - -static int solaris_O(unsigned int fd, unsigned int cmd, u32 arg) -{ - int ret = -EINVAL; - - switch (cmd & 0xff) { - case 1: /* OPROMGETOPT */ - ret = sys_ioctl(fd, OPROMGETOPT, arg); - break; - case 2: /* OPROMSETOPT */ - ret = sys_ioctl(fd, OPROMSETOPT, arg); - break; - case 3: /* OPROMNXTOPT */ - ret = sys_ioctl(fd, OPROMNXTOPT, arg); - break; - case 4: /* OPROMSETOPT2 */ - ret = sys_ioctl(fd, OPROMSETOPT2, arg); - break; - case 5: /* OPROMNEXT */ - ret = sys_ioctl(fd, OPROMNEXT, arg); - break; - case 6: /* OPROMCHILD */ - ret = sys_ioctl(fd, OPROMCHILD, arg); - break; - case 7: /* OPROMGETPROP */ - ret = sys_ioctl(fd, OPROMGETPROP, arg); - break; - case 8: /* OPROMNXTPROP */ - ret = sys_ioctl(fd, OPROMNXTPROP, arg); - break; - case 9: /* OPROMU2P */ - ret = sys_ioctl(fd, OPROMU2P, arg); - break; - case 10: /* OPROMGETCONS */ - ret = sys_ioctl(fd, OPROMGETCONS, arg); - break; - case 11: /* OPROMGETFBNAME */ - ret = sys_ioctl(fd, OPROMGETFBNAME, arg); - break; - case 12: /* OPROMGETBOOTARGS */ - ret = sys_ioctl(fd, OPROMGETBOOTARGS, arg); - break; - case 13: /* OPROMGETVERSION */ - case 14: /* OPROMPATH2DRV */ - case 15: /* OPROMDEV2PROMNAME */ - case 16: /* OPROMPROM2DEVNAME */ - case 17: /* OPROMGETPROPLEN */ - default: - ret = -EINVAL; - break; - }; - return ret; -} - -/* }}} */ - -asmlinkage int solaris_ioctl(unsigned int fd, unsigned int cmd, u32 arg) -{ - struct file *filp; - int error = -EBADF; - - filp = fget(fd); - if (!filp) - goto out; - - lock_kernel(); - error = -EFAULT; - switch ((cmd >> 8) & 0xff) { - case 'S': error = solaris_S(filp, fd, cmd, arg); break; - case 'T': error = solaris_T(fd, cmd, arg); break; - case 'i': error = solaris_i(fd, cmd, arg); break; - case 'r': error = solaris_r(fd, cmd, arg); break; - case 's': error = solaris_s(fd, cmd, arg); break; - case 't': error = solaris_t(fd, cmd, arg); break; - case 'f': error = sys_ioctl(fd, cmd, arg); break; - case 'm': error = solaris_m(fd, cmd, arg); break; - case 'O': error = solaris_O(fd, cmd, arg); break; - default: - error = -ENOSYS; - break; - } - unlock_kernel(); - fput(filp); -out: - if (error == -ENOSYS) { - unsigned char c = cmd>>8; - - if (c < ' ' || c > 126) c = '.'; - printk("solaris_ioctl: Unknown cmd fd(%d) cmd(%08x '%c') arg(%08x)\n", - (int)fd, (unsigned int)cmd, c, (unsigned int)arg); - error = -EINVAL; - } - return error; -} diff --git a/arch/sparc64/solaris/ipc.c b/arch/sparc64/solaris/ipc.c deleted file mode 100644 index 499135fa706..00000000000 --- a/arch/sparc64/solaris/ipc.c +++ /dev/null @@ -1,126 +0,0 @@ -/* $Id: ipc.c,v 1.5 1999/12/09 00:41:00 davem Exp $ - * ipc.c: Solaris IPC emulation - * - * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) - */ - -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/wait.h> -#include <linux/mm.h> -#include <linux/shm.h> -#include <linux/sem.h> -#include <linux/msg.h> -#include <linux/ipc.h> - -#include <asm/uaccess.h> -#include <asm/string.h> - -#include "conv.h" - -struct solaris_ipc_perm { - s32 uid; - s32 gid; - s32 cuid; - s32 cgid; - u32 mode; - u32 seq; - int key; - s32 pad[4]; -}; - -struct solaris_shmid_ds { - struct solaris_ipc_perm shm_perm; - int shm_segsz; - u32 shm_amp; - unsigned short shm_lkcnt; - char __padxx[2]; - s32 shm_lpid; - s32 shm_cpid; - u32 shm_nattch; - u32 shm_cnattch; - s32 shm_atime; - s32 shm_pad1; - s32 shm_dtime; - s32 shm_pad2; - s32 shm_ctime; - s32 shm_pad3; - unsigned short shm_cv; - char shm_pad4[2]; - u32 shm_sptas; - s32 shm_pad5[2]; -}; - -asmlinkage long solaris_shmsys(int cmd, u32 arg1, u32 arg2, u32 arg3) -{ - int (*sys_ipc)(unsigned,int,int,unsigned long,void __user *,long) = - (int (*)(unsigned,int,int,unsigned long,void __user *,long))SYS(ipc); - mm_segment_t old_fs; - unsigned long raddr; - int ret; - - switch (cmd) { - case 0: /* shmat */ - old_fs = get_fs(); - set_fs(KERNEL_DS); - ret = sys_ipc(SHMAT, arg1, arg3 & ~0x4000, (unsigned long)&raddr, A(arg2), 0); - set_fs(old_fs); - if (ret >= 0) return (u32)raddr; - else return ret; - case 1: /* shmctl */ - switch (arg2) { - case 3: /* SHM_LOCK */ - case 4: /* SHM_UNLOCK */ - return sys_ipc(SHMCTL, arg1, (arg2 == 3) ? SHM_LOCK : SHM_UNLOCK, 0, NULL, 0); - case 10: /* IPC_RMID */ - return sys_ipc(SHMCTL, arg1, IPC_RMID, 0, NULL, 0); - case 11: /* IPC_SET */ - { - struct shmid_ds s; - struct solaris_shmid_ds __user *p = A(arg3); - - if (get_user (s.shm_perm.uid, &p->shm_perm.uid) || - __get_user (s.shm_perm.gid, &p->shm_perm.gid) || - __get_user (s.shm_perm.mode, &p->shm_perm.mode)) - return -EFAULT; - old_fs = get_fs(); - set_fs(KERNEL_DS); - ret = sys_ipc(SHMCTL, arg1, IPC_SET, 0, &s, 0); - set_fs(old_fs); - return ret; - } - case 12: /* IPC_STAT */ - { - struct shmid_ds s; - struct solaris_shmid_ds __user *p = A(arg3); - - old_fs = get_fs(); - set_fs(KERNEL_DS); - ret = sys_ipc(SHMCTL, arg1, IPC_SET, 0, &s, 0); - set_fs(old_fs); - if (put_user (s.shm_perm.uid, &(p->shm_perm.uid)) || - __put_user (s.shm_perm.gid, &(p->shm_perm.gid)) || - __put_user (s.shm_perm.cuid, &(p->shm_perm.cuid)) || - __put_user (s.shm_perm.cgid, &(p->shm_perm.cgid)) || - __put_user (s.shm_perm.mode, &(p->shm_perm.mode)) || - __put_user (s.shm_perm.seq, &(p->shm_perm.seq)) || - __put_user (s.shm_perm.key, &(p->shm_perm.key)) || - __put_user (s.shm_segsz, &(p->shm_segsz)) || - __put_user (s.shm_lpid, &(p->shm_lpid)) || - __put_user (s.shm_cpid, &(p->shm_cpid)) || - __put_user (s.shm_nattch, &(p->shm_nattch)) || - __put_user (s.shm_atime, &(p->shm_atime)) || - __put_user (s.shm_dtime, &(p->shm_dtime)) || - __put_user (s.shm_ctime, &(p->shm_ctime))) - return -EFAULT; - return ret; - } - default: return -EINVAL; - } - case 2: /* shmdt */ - return sys_ipc(SHMDT, 0, 0, 0, A(arg1), 0); - case 3: /* shmget */ - return sys_ipc(SHMGET, arg1, arg2, arg3, NULL, 0); - } - return -EINVAL; -} diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c deleted file mode 100644 index d3e48e9701b..00000000000 --- a/arch/sparc64/solaris/misc.c +++ /dev/null @@ -1,786 +0,0 @@ -/* $Id: misc.c,v 1.36 2002/02/09 19:49:31 davem Exp $ - * misc.c: Miscellaneous syscall emulation for Solaris - * - * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) - */ - -#include <linux/module.h> -#include <linux/types.h> -#include <linux/utsname.h> -#include <linux/limits.h> -#include <linux/mm.h> -#include <linux/smp.h> -#include <linux/tty.h> -#include <linux/mman.h> -#include <linux/file.h> -#include <linux/timex.h> -#include <linux/major.h> -#include <linux/compat.h> - -#include <asm/uaccess.h> -#include <asm/string.h> -#include <asm/oplib.h> -#include <asm/idprom.h> -#include <asm/smp.h> -#include <asm/prom.h> - -#include "conv.h" - -/* Conversion from Linux to Solaris errnos. 0-34 are identity mapped. - Some Linux errnos (EPROCLIM, EDOTDOT, ERREMOTE, EUCLEAN, ENOTNAM, - ENAVAIL, EISNAM, EREMOTEIO, ENOMEDIUM, EMEDIUMTYPE) have no Solaris - equivalents. I return EINVAL in that case, which is very wrong. If - someone suggest a better value for them, you're welcomed. - On the other side, Solaris ECANCELED and ENOTSUP have no Linux equivalents, - but that doesn't matter here. --jj */ -int solaris_err_table[] = { -/* 0 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -/* 10 */ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, -/* 20 */ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, -/* 30 */ 30, 31, 32, 33, 34, 22, 150, 149, 95, 96, -/* 40 */ 97, 98, 99, 120, 121, 122, 123, 124, 125, 126, -/* 50 */ 127, 128, 129, 130, 131, 132, 133, 134, 143, 144, -/* 60 */ 145, 146, 90, 78, 147, 148, 93, 22, 94, 49, -/* 70 */ 151, 66, 60, 62, 63, 35, 77, 36, 45, 46, -/* 80 */ 64, 22, 67, 68, 69, 70, 71, 74, 22, 82, -/* 90 */ 89, 92, 79, 81, 37, 38, 39, 40, 41, 42, -/* 100 */ 43, 44, 50, 51, 52, 53, 54, 55, 56, 57, -/* 110 */ 87, 61, 84, 65, 83, 80, 91, 22, 22, 22, -/* 120 */ 22, 22, 88, 86, 85, 22, 22, -}; - -#define SOLARIS_NR_OPEN 256 - -static u32 do_solaris_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u64 off) -{ - struct file *file = NULL; - unsigned long retval, ret_type; - - /* Do we need it here? */ - set_personality(PER_SVR4); - if (flags & MAP_NORESERVE) { - static int cnt; - - if (cnt < 5) { - printk("%s: unimplemented Solaris MAP_NORESERVE mmap() flag\n", - current->comm); - cnt++; - } - flags &= ~MAP_NORESERVE; - } - retval = -EBADF; - if(!(flags & MAP_ANONYMOUS)) { - if(fd >= SOLARIS_NR_OPEN) - goto out; - file = fget(fd); - if (!file) - goto out; - else { - struct inode * inode = file->f_path.dentry->d_inode; - if(imajor(inode) == MEM_MAJOR && - iminor(inode) == 5) { - flags |= MAP_ANONYMOUS; - fput(file); - file = NULL; - } - } - } - - retval = -EINVAL; - len = PAGE_ALIGN(len); - if(!(flags & MAP_FIXED)) - addr = 0; - else if (len > STACK_TOP32 || addr > STACK_TOP32 - len) - goto out_putf; - ret_type = flags & _MAP_NEW; - flags &= ~_MAP_NEW; - - down_write(¤t->mm->mmap_sem); - flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); - retval = do_mmap(file, - (unsigned long) addr, (unsigned long) len, - (unsigned long) prot, (unsigned long) flags, off); - up_write(¤t->mm->mmap_sem); - if(!ret_type) - retval = ((retval < STACK_TOP32) ? 0 : retval); - -out_putf: - if (file) - fput(file); -out: - return (u32) retval; -} - -asmlinkage u32 solaris_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u32 off) -{ - return do_solaris_mmap(addr, len, prot, flags, fd, (u64) off); -} - -asmlinkage u32 solaris_mmap64(struct pt_regs *regs, u32 len, u32 prot, u32 flags, u32 fd, u32 offhi) -{ - u32 offlo; - - if (regs->u_regs[UREG_G1]) { - if (get_user (offlo, (u32 __user *)(long)((u32)regs->u_regs[UREG_I6] + 0x5c))) - return -EFAULT; - } else { - if (get_user (offlo, (u32 __user *)(long)((u32)regs->u_regs[UREG_I6] + 0x60))) - return -EFAULT; - } - return do_solaris_mmap((u32)regs->u_regs[UREG_I0], len, prot, flags, fd, (((u64)offhi)<<32)|offlo); -} - -asmlinkage int solaris_brk(u32 brk) -{ - int (*sunos_brk)(u32) = (int (*)(u32))SUNOS(17); - - return sunos_brk(brk); -} - -static int __set_utsfield(char __user *to, int to_size, - const char *from, int from_size, - int dotchop, int countfrom) -{ - int len = countfrom ? (to_size > from_size ? - from_size : to_size) : to_size; - int off; - - if (copy_to_user(to, from, len)) - return -EFAULT; - - off = len < to_size? len: len - 1; - if (dotchop) { - const char *p = strnchr(from, len, '.'); - if (p) off = p - from; - } - - if (__put_user('\0', to + off)) - return -EFAULT; - - return 0; -} - -#define set_utsfield(to, from, dotchop, countfrom) \ - __set_utsfield((to), sizeof(to), \ - (from), sizeof(from), \ - (dotchop), (countfrom)) - -struct sol_uname { - char sysname[9]; - char nodename[9]; - char release[9]; - char version[9]; - char machine[9]; -}; - -struct sol_utsname { - char sysname[257]; - char nodename[257]; - char release[257]; - char version[257]; - char machine[257]; -}; - -static char *machine(void) -{ - switch (sparc_cpu_model) { - case sun4: return "sun4"; - case sun4c: return "sun4c"; - case sun4e: return "sun4e"; - case sun4m: return "sun4m"; - case sun4d: return "sun4d"; - case sun4u: return "sun4u"; - default: return "sparc"; - } -} - -static char *platform(char *buffer, int sz) -{ - struct device_node *dp = of_find_node_by_path("/"); - int len; - - *buffer = 0; - len = strlen(dp->name); - if (len > sz) - len = sz; - memcpy(buffer, dp->name, len); - buffer[len] = 0; - if (*buffer) { - char *p; - - for (p = buffer; *p; p++) - if (*p == '/' || *p == ' ') *p = '_'; - return buffer; - } - - return "sun4u"; -} - -static char *serial(char *buffer, int sz) -{ - struct device_node *dp = of_find_node_by_path("/options"); - int len; - - *buffer = 0; - if (dp) { - const char *val = - of_get_property(dp, "system-board-serial#", &len); - - if (val && len > 0) { - if (len > sz) - len = sz; - memcpy(buffer, val, len); - buffer[len] = 0; - } - } - if (!*buffer) - return "4512348717234"; - else - return buffer; -} - -asmlinkage int solaris_utssys(u32 buf, u32 flags, int which, u32 buf2) -{ - struct sol_uname __user *v = A(buf); - int err; - - switch (which) { - case 0: /* old uname */ - /* Let's cheat */ - err = set_utsfield(v->sysname, "SunOS", 1, 0); - down_read(&uts_sem); - err |= set_utsfield(v->nodename, utsname()->nodename, - 1, 1); - up_read(&uts_sem); - err |= set_utsfield(v->release, "2.6", 0, 0); - err |= set_utsfield(v->version, "Generic", 0, 0); - err |= set_utsfield(v->machine, machine(), 0, 0); - return (err ? -EFAULT : 0); - case 2: /* ustat */ - return -ENOSYS; - case 3: /* fusers */ - return -ENOSYS; - default: - return -ENOSYS; - } -} - -asmlinkage int solaris_utsname(u32 buf) -{ - struct sol_utsname __user *v = A(buf); - int err; - - /* Why should we not lie a bit? */ - down_read(&uts_sem); - err = set_utsfield(v->sysname, "SunOS", 0, 0); - err |= set_utsfield(v->nodename, utsname()->nodename, 1, 1); - err |= set_utsfield(v->release, "5.6", 0, 0); - err |= set_utsfield(v->version, "Generic", 0, 0); - err |= set_utsfield(v->machine, machine(), 0, 0); - up_read(&uts_sem); - - return (err ? -EFAULT : 0); -} - -#define SI_SYSNAME 1 /* return name of operating system */ -#define SI_HOSTNAME 2 /* return name of node */ -#define SI_RELEASE 3 /* return release of operating system */ -#define SI_VERSION 4 /* return version field of utsname */ -#define SI_MACHINE 5 /* return kind of machine */ -#define SI_ARCHITECTURE 6 /* return instruction set arch */ -#define SI_HW_SERIAL 7 /* return hardware serial number */ -#define SI_HW_PROVIDER 8 /* return hardware manufacturer */ -#define SI_SRPC_DOMAIN 9 /* return secure RPC domain */ -#define SI_PLATFORM 513 /* return platform identifier */ - -asmlinkage int solaris_sysinfo(int cmd, u32 buf, s32 count) -{ - char *p, *q, *r; - char buffer[256]; - int len; - - /* Again, we cheat :)) */ - switch (cmd) { - case SI_SYSNAME: r = "SunOS"; break; - case SI_HOSTNAME: - r = buffer + 256; - down_read(&uts_sem); - for (p = utsname()->nodename, q = buffer; - q < r && *p && *p != '.'; *q++ = *p++); - up_read(&uts_sem); - *q = 0; - r = buffer; - break; - case SI_RELEASE: r = "5.6"; break; - case SI_MACHINE: r = machine(); break; - case SI_ARCHITECTURE: r = "sparc"; break; - case SI_HW_PROVIDER: r = "Sun_Microsystems"; break; - case SI_HW_SERIAL: r = serial(buffer, sizeof(buffer)); break; - case SI_PLATFORM: r = platform(buffer, sizeof(buffer)); break; - case SI_SRPC_DOMAIN: r = ""; break; - case SI_VERSION: r = "Generic"; break; - default: return -EINVAL; - } - len = strlen(r) + 1; - if (count < len) { - if (copy_to_user(A(buf), r, count - 1) || - __put_user(0, (char __user *)A(buf) + count - 1)) - return -EFAULT; - } else { - if (copy_to_user(A(buf), r, len)) - return -EFAULT; - } - return len; -} - -#define SOLARIS_CONFIG_NGROUPS 2 -#define SOLARIS_CONFIG_CHILD_MAX 3 -#define SOLARIS_CONFIG_OPEN_FILES 4 -#define SOLARIS_CONFIG_POSIX_VER 5 -#define SOLARIS_CONFIG_PAGESIZE 6 -#define SOLARIS_CONFIG_CLK_TCK 7 -#define SOLARIS_CONFIG_XOPEN_VER 8 -#define SOLARIS_CONFIG_PROF_TCK 10 -#define SOLARIS_CONFIG_NPROC_CONF 11 -#define SOLARIS_CONFIG_NPROC_ONLN 12 -#define SOLARIS_CONFIG_AIO_LISTIO_MAX 13 -#define SOLARIS_CONFIG_AIO_MAX 14 -#define SOLARIS_CONFIG_AIO_PRIO_DELTA_MAX 15 -#define SOLARIS_CONFIG_DELAYTIMER_MAX 16 -#define SOLARIS_CONFIG_MQ_OPEN_MAX 17 -#define SOLARIS_CONFIG_MQ_PRIO_MAX 18 -#define SOLARIS_CONFIG_RTSIG_MAX 19 -#define SOLARIS_CONFIG_SEM_NSEMS_MAX 20 -#define SOLARIS_CONFIG_SEM_VALUE_MAX 21 -#define SOLARIS_CONFIG_SIGQUEUE_MAX 22 -#define SOLARIS_CONFIG_SIGRT_MIN 23 -#define SOLARIS_CONFIG_SIGRT_MAX 24 -#define SOLARIS_CONFIG_TIMER_MAX 25 -#define SOLARIS_CONFIG_PHYS_PAGES 26 -#define SOLARIS_CONFIG_AVPHYS_PAGES 27 - -asmlinkage int solaris_sysconf(int id) -{ - switch (id) { - case SOLARIS_CONFIG_NGROUPS: return NGROUPS_MAX; - case SOLARIS_CONFIG_CHILD_MAX: - return current->signal->rlim[RLIMIT_NPROC].rlim_cur; - case SOLARIS_CONFIG_OPEN_FILES: - return current->signal->rlim[RLIMIT_NOFILE].rlim_cur; - case SOLARIS_CONFIG_POSIX_VER: return 199309; - case SOLARIS_CONFIG_PAGESIZE: return PAGE_SIZE; - case SOLARIS_CONFIG_XOPEN_VER: return 3; - case SOLARIS_CONFIG_CLK_TCK: - case SOLARIS_CONFIG_PROF_TCK: - return sparc64_get_clock_tick(smp_processor_id()); -#ifdef CONFIG_SMP - case SOLARIS_CONFIG_NPROC_CONF: return NR_CPUS; - case SOLARIS_CONFIG_NPROC_ONLN: return num_online_cpus(); -#else - case SOLARIS_CONFIG_NPROC_CONF: return 1; - case SOLARIS_CONFIG_NPROC_ONLN: return 1; -#endif - case SOLARIS_CONFIG_SIGRT_MIN: return 37; - case SOLARIS_CONFIG_SIGRT_MAX: return 44; - case SOLARIS_CONFIG_PHYS_PAGES: - case SOLARIS_CONFIG_AVPHYS_PAGES: - { - struct sysinfo s; - - si_meminfo(&s); - if (id == SOLARIS_CONFIG_PHYS_PAGES) - return s.totalram >>= PAGE_SHIFT; - else - return s.freeram >>= PAGE_SHIFT; - } - /* XXX support these as well -jj */ - case SOLARIS_CONFIG_AIO_LISTIO_MAX: return -EINVAL; - case SOLARIS_CONFIG_AIO_MAX: return -EINVAL; - case SOLARIS_CONFIG_AIO_PRIO_DELTA_MAX: return -EINVAL; - case SOLARIS_CONFIG_DELAYTIMER_MAX: return -EINVAL; - case SOLARIS_CONFIG_MQ_OPEN_MAX: return -EINVAL; - case SOLARIS_CONFIG_MQ_PRIO_MAX: return -EINVAL; - case SOLARIS_CONFIG_RTSIG_MAX: return -EINVAL; - case SOLARIS_CONFIG_SEM_NSEMS_MAX: return -EINVAL; - case SOLARIS_CONFIG_SEM_VALUE_MAX: return -EINVAL; - case SOLARIS_CONFIG_SIGQUEUE_MAX: return -EINVAL; - case SOLARIS_CONFIG_TIMER_MAX: return -EINVAL; - default: return -EINVAL; - } -} - -asmlinkage int solaris_procids(int cmd, s32 pid, s32 pgid) -{ - int ret; - - switch (cmd) { - case 0: /* getpgrp */ - return task_pgrp_vnr(current); - case 1: /* setpgrp */ - { - int (*sys_setpgid)(pid_t,pid_t) = - (int (*)(pid_t,pid_t))SYS(setpgid); - - /* can anyone explain me the difference between - Solaris setpgrp and setsid? */ - ret = sys_setpgid(0, 0); - if (ret) return ret; - proc_clear_tty(current); - return task_pgrp_vnr(current); - } - case 2: /* getsid */ - { - int (*sys_getsid)(pid_t) = (int (*)(pid_t))SYS(getsid); - return sys_getsid(pid); - } - case 3: /* setsid */ - { - int (*sys_setsid)(void) = (int (*)(void))SYS(setsid); - return sys_setsid(); - } - case 4: /* getpgid */ - { - int (*sys_getpgid)(pid_t) = (int (*)(pid_t))SYS(getpgid); - return sys_getpgid(pid); - } - case 5: /* setpgid */ - { - int (*sys_setpgid)(pid_t,pid_t) = - (int (*)(pid_t,pid_t))SYS(setpgid); - return sys_setpgid(pid,pgid); - } - } - return -EINVAL; -} - -asmlinkage int solaris_gettimeofday(u32 tim) -{ - int (*sys_gettimeofday)(struct timeval *, struct timezone *) = - (int (*)(struct timeval *, struct timezone *))SYS(gettimeofday); - - return sys_gettimeofday((struct timeval *)(u64)tim, NULL); -} - -#define RLIM_SOL_INFINITY32 0x7fffffff -#define RLIM_SOL_SAVED_MAX32 0x7ffffffe -#define RLIM_SOL_SAVED_CUR32 0x7ffffffd -#define RLIM_SOL_INFINITY ((u64)-3) -#define RLIM_SOL_SAVED_MAX ((u64)-2) -#define RLIM_SOL_SAVED_CUR ((u64)-1) -#define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x) -#define RLIMIT_SOL_NOFILE 5 -#define RLIMIT_SOL_VMEM 6 - -struct rlimit32 { - u32 rlim_cur; - u32 rlim_max; -}; - -asmlinkage int solaris_getrlimit(unsigned int resource, struct rlimit32 __user *rlim) -{ - struct rlimit r; - int ret; - mm_segment_t old_fs = get_fs (); - int (*sys_getrlimit)(unsigned int, struct rlimit *) = - (int (*)(unsigned int, struct rlimit *))SYS(getrlimit); - - if (resource > RLIMIT_SOL_VMEM) - return -EINVAL; - switch (resource) { - case RLIMIT_SOL_NOFILE: resource = RLIMIT_NOFILE; break; - case RLIMIT_SOL_VMEM: resource = RLIMIT_AS; break; - default: break; - } - set_fs (KERNEL_DS); - ret = sys_getrlimit(resource, &r); - set_fs (old_fs); - if (!ret) { - if (r.rlim_cur == RLIM_INFINITY) - r.rlim_cur = RLIM_SOL_INFINITY32; - else if ((u64)r.rlim_cur > RLIM_SOL_INFINITY32) - r.rlim_cur = RLIM_SOL_SAVED_CUR32; - if (r.rlim_max == RLIM_INFINITY) - r.rlim_max = RLIM_SOL_INFINITY32; - else if ((u64)r.rlim_max > RLIM_SOL_INFINITY32) - r.rlim_max = RLIM_SOL_SAVED_MAX32; - ret = put_user (r.rlim_cur, &rlim->rlim_cur); - ret |= __put_user (r.rlim_max, &rlim->rlim_max); - } - return ret; -} - -asmlinkage int solaris_setrlimit(unsigned int resource, struct rlimit32 __user *rlim) -{ - struct rlimit r, rold; - int ret; - mm_segment_t old_fs = get_fs (); - int (*sys_getrlimit)(unsigned int, struct rlimit __user *) = - (int (*)(unsigned int, struct rlimit __user *))SYS(getrlimit); - int (*sys_setrlimit)(unsigned int, struct rlimit __user *) = - (int (*)(unsigned int, struct rlimit __user *))SYS(setrlimit); - - if (resource > RLIMIT_SOL_VMEM) - return -EINVAL; - switch (resource) { - case RLIMIT_SOL_NOFILE: resource = RLIMIT_NOFILE; break; - case RLIMIT_SOL_VMEM: resource = RLIMIT_AS; break; - default: break; - } - if (get_user (r.rlim_cur, &rlim->rlim_cur) || - __get_user (r.rlim_max, &rlim->rlim_max)) - return -EFAULT; - set_fs (KERNEL_DS); - ret = sys_getrlimit(resource, &rold); - if (!ret) { - if (r.rlim_cur == RLIM_SOL_INFINITY32) - r.rlim_cur = RLIM_INFINITY; - else if (r.rlim_cur == RLIM_SOL_SAVED_CUR32) - r.rlim_cur = rold.rlim_cur; - else if (r.rlim_cur == RLIM_SOL_SAVED_MAX32) - r.rlim_cur = rold.rlim_max; - if (r.rlim_max == RLIM_SOL_INFINITY32) - r.rlim_max = RLIM_INFINITY; - else if (r.rlim_max == RLIM_SOL_SAVED_CUR32) - r.rlim_max = rold.rlim_cur; - else if (r.rlim_max == RLIM_SOL_SAVED_MAX32) - r.rlim_max = rold.rlim_max; - ret = sys_setrlimit(resource, &r); - } - set_fs (old_fs); - return ret; -} - -asmlinkage int solaris_getrlimit64(unsigned int resource, struct rlimit __user *rlim) -{ - struct rlimit r; - int ret; - mm_segment_t old_fs = get_fs (); - int (*sys_getrlimit)(unsigned int, struct rlimit __user *) = - (int (*)(unsigned int, struct rlimit __user *))SYS(getrlimit); - - if (resource > RLIMIT_SOL_VMEM) - return -EINVAL; - switch (resource) { - case RLIMIT_SOL_NOFILE: resource = RLIMIT_NOFILE; break; - case RLIMIT_SOL_VMEM: resource = RLIMIT_AS; break; - default: break; - } - set_fs (KERNEL_DS); - ret = sys_getrlimit(resource, &r); - set_fs (old_fs); - if (!ret) { - if (r.rlim_cur == RLIM_INFINITY) - r.rlim_cur = RLIM_SOL_INFINITY; - if (r.rlim_max == RLIM_INFINITY) - r.rlim_max = RLIM_SOL_INFINITY; - ret = put_user (r.rlim_cur, &rlim->rlim_cur); - ret |= __put_user (r.rlim_max, &rlim->rlim_max); - } - return ret; -} - -asmlinkage int solaris_setrlimit64(unsigned int resource, struct rlimit __user *rlim) -{ - struct rlimit r, rold; - int ret; - mm_segment_t old_fs = get_fs (); - int (*sys_getrlimit)(unsigned int, struct rlimit __user *) = - (int (*)(unsigned int, struct rlimit __user *))SYS(getrlimit); - int (*sys_setrlimit)(unsigned int, struct rlimit __user *) = - (int (*)(unsigned int, struct rlimit __user *))SYS(setrlimit); - - if (resource > RLIMIT_SOL_VMEM) - return -EINVAL; - switch (resource) { - case RLIMIT_SOL_NOFILE: resource = RLIMIT_NOFILE; break; - case RLIMIT_SOL_VMEM: resource = RLIMIT_AS; break; - default: break; - } - if (get_user (r.rlim_cur, &rlim->rlim_cur) || - __get_user (r.rlim_max, &rlim->rlim_max)) - return -EFAULT; - set_fs (KERNEL_DS); - ret = sys_getrlimit(resource, &rold); - if (!ret) { - if (r.rlim_cur == RLIM_SOL_INFINITY) - r.rlim_cur = RLIM_INFINITY; - else if (r.rlim_cur == RLIM_SOL_SAVED_CUR) - r.rlim_cur = rold.rlim_cur; - else if (r.rlim_cur == RLIM_SOL_SAVED_MAX) - r.rlim_cur = rold.rlim_max; - if (r.rlim_max == RLIM_SOL_INFINITY) - r.rlim_max = RLIM_INFINITY; - else if (r.rlim_max == RLIM_SOL_SAVED_CUR) - r.rlim_max = rold.rlim_cur; - else if (r.rlim_max == RLIM_SOL_SAVED_MAX) - r.rlim_max = rold.rlim_max; - ret = sys_setrlimit(resource, &r); - } - set_fs (old_fs); - return ret; -} - -struct sol_ntptimeval { - struct compat_timeval time; - s32 maxerror; - s32 esterror; -}; - -struct sol_timex { - u32 modes; - s32 offset; - s32 freq; - s32 maxerror; - s32 esterror; - s32 status; - s32 constant; - s32 precision; - s32 tolerance; - s32 ppsfreq; - s32 jitter; - s32 shift; - s32 stabil; - s32 jitcnt; - s32 calcnt; - s32 errcnt; - s32 stbcnt; -}; - -asmlinkage int solaris_ntp_gettime(struct sol_ntptimeval __user *ntp) -{ - int (*sys_adjtimex)(struct timex __user *) = - (int (*)(struct timex __user *))SYS(adjtimex); - struct timex t; - int ret; - mm_segment_t old_fs = get_fs(); - - set_fs(KERNEL_DS); - t.modes = 0; - ret = sys_adjtimex(&t); - set_fs(old_fs); - if (ret < 0) - return ret; - ret = put_user (t.time.tv_sec, &ntp->time.tv_sec); - ret |= __put_user (t.time.tv_usec, &ntp->time.tv_usec); - ret |= __put_user (t.maxerror, &ntp->maxerror); - ret |= __put_user (t.esterror, &ntp->esterror); - return ret; -} - -asmlinkage int solaris_ntp_adjtime(struct sol_timex __user *txp) -{ - int (*sys_adjtimex)(struct timex __user *) = - (int (*)(struct timex __user *))SYS(adjtimex); - struct timex t; - int ret, err; - mm_segment_t old_fs = get_fs(); - - ret = get_user (t.modes, &txp->modes); - ret |= __get_user (t.offset, &txp->offset); - ret |= __get_user (t.freq, &txp->freq); - ret |= __get_user (t.maxerror, &txp->maxerror); - ret |= __get_user (t.esterror, &txp->esterror); - ret |= __get_user (t.status, &txp->status); - ret |= __get_user (t.constant, &txp->constant); - set_fs(KERNEL_DS); - ret = sys_adjtimex(&t); - set_fs(old_fs); - if (ret < 0) - return ret; - err = put_user (t.offset, &txp->offset); - err |= __put_user (t.freq, &txp->freq); - err |= __put_user (t.maxerror, &txp->maxerror); - err |= __put_user (t.esterror, &txp->esterror); - err |= __put_user (t.status, &txp->status); - err |= __put_user (t.constant, &txp->constant); - err |= __put_user (t.precision, &txp->precision); - err |= __put_user (t.tolerance, &txp->tolerance); - err |= __put_user (t.ppsfreq, &txp->ppsfreq); - err |= __put_user (t.jitter, &txp->jitter); - err |= __put_user (t.shift, &txp->shift); - err |= __put_user (t.stabil, &txp->stabil); - err |= __put_user (t.jitcnt, &txp->jitcnt); - err |= __put_user (t.calcnt, &txp->calcnt); - err |= __put_user (t.errcnt, &txp->errcnt); - err |= __put_user (t.stbcnt, &txp->stbcnt); - if (err) - return -EFAULT; - return ret; -} - -asmlinkage int do_sol_unimplemented(struct pt_regs *regs) -{ - printk ("Unimplemented Solaris syscall %d %08x %08x %08x %08x\n", - (int)regs->u_regs[UREG_G1], - (int)regs->u_regs[UREG_I0], - (int)regs->u_regs[UREG_I1], - (int)regs->u_regs[UREG_I2], - (int)regs->u_regs[UREG_I3]); - return -ENOSYS; -} - -asmlinkage void solaris_register(void) -{ - set_personality(PER_SVR4); -} - -extern long solaris_to_linux_signals[], linux_to_solaris_signals[]; - -struct exec_domain solaris_exec_domain = { - .name = "Solaris", - .handler = NULL, - .pers_low = 1, /* PER_SVR4 personality */ - .pers_high = 1, - .signal_map = solaris_to_linux_signals, - .signal_invmap =linux_to_solaris_signals, - .module = THIS_MODULE, - .next = NULL -}; - -extern int init_socksys(void); - -MODULE_AUTHOR("Jakub Jelinek (jj@ultra.linux.cz), Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)"); -MODULE_DESCRIPTION("Solaris binary emulation module"); -MODULE_LICENSE("GPL"); - -extern u32 tl0_solaris[8]; -#define update_ttable(x) \ - tl0_solaris[3] = (((long)(x) - (long)tl0_solaris - 3) >> 2) | 0x40000000; \ - wmb(); \ - __asm__ __volatile__ ("flush %0" : : "r" (&tl0_solaris[3])) - -extern u32 solaris_sparc_syscall[]; -extern u32 solaris_syscall[]; -extern void cleanup_socksys(void); - -extern u32 entry64_personality_patch; - -static int __init solaris_init(void) -{ - int ret; - - SOLDD(("Solaris module at %p\n", solaris_sparc_syscall)); - register_exec_domain(&solaris_exec_domain); - if ((ret = init_socksys())) { - unregister_exec_domain(&solaris_exec_domain); - return ret; - } - update_ttable(solaris_sparc_syscall); - entry64_personality_patch |= - (offsetof(struct task_struct, personality) + - (sizeof(unsigned long) - 1)); - wmb(); - __asm__ __volatile__("flush %0" - : : "r" (&entry64_personality_patch)); - return 0; -} - -static void __exit solaris_exit(void) -{ - update_ttable(solaris_syscall); - cleanup_socksys(); - unregister_exec_domain(&solaris_exec_domain); -} - -module_init(solaris_init); -module_exit(solaris_exit); diff --git a/arch/sparc64/solaris/signal.c b/arch/sparc64/solaris/signal.c deleted file mode 100644 index de10c9716cf..00000000000 --- a/arch/sparc64/solaris/signal.c +++ /dev/null @@ -1,429 +0,0 @@ -/* $Id: signal.c,v 1.7 2000/09/05 21:44:54 davem Exp $ - * signal.c: Signal emulation for Solaris - * - * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) - */ - -#include <linux/types.h> -#include <linux/errno.h> - -#include <asm/uaccess.h> -#include <asm/svr4.h> -#include <asm/string.h> - -#include "conv.h" -#include "signal.h" - -#define _S(nr) (1L<<((nr)-1)) - -#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP))) - -long linux_to_solaris_signals[] = { - 0, - SOLARIS_SIGHUP, SOLARIS_SIGINT, - SOLARIS_SIGQUIT, SOLARIS_SIGILL, - SOLARIS_SIGTRAP, SOLARIS_SIGIOT, - SOLARIS_SIGEMT, SOLARIS_SIGFPE, - SOLARIS_SIGKILL, SOLARIS_SIGBUS, - SOLARIS_SIGSEGV, SOLARIS_SIGSYS, - SOLARIS_SIGPIPE, SOLARIS_SIGALRM, - SOLARIS_SIGTERM, SOLARIS_SIGURG, - SOLARIS_SIGSTOP, SOLARIS_SIGTSTP, - SOLARIS_SIGCONT, SOLARIS_SIGCLD, - SOLARIS_SIGTTIN, SOLARIS_SIGTTOU, - SOLARIS_SIGPOLL, SOLARIS_SIGXCPU, - SOLARIS_SIGXFSZ, SOLARIS_SIGVTALRM, - SOLARIS_SIGPROF, SOLARIS_SIGWINCH, - SOLARIS_SIGUSR1, SOLARIS_SIGUSR1, - SOLARIS_SIGUSR2, -1, -}; - -long solaris_to_linux_signals[] = { - 0, - SIGHUP, SIGINT, SIGQUIT, SIGILL, - SIGTRAP, SIGIOT, SIGEMT, SIGFPE, - SIGKILL, SIGBUS, SIGSEGV, SIGSYS, - SIGPIPE, SIGALRM, SIGTERM, SIGUSR1, - SIGUSR2, SIGCHLD, -1, SIGWINCH, - SIGURG, SIGPOLL, SIGSTOP, SIGTSTP, - SIGCONT, SIGTTIN, SIGTTOU, SIGVTALRM, - SIGPROF, SIGXCPU, SIGXFSZ, -1, - -1, -1, -1, -1, - -1, -1, -1, -1, - -1, -1, -1, -1, -}; - -static inline long mapsig(long sig) -{ - if ((unsigned long)sig > SOLARIS_NSIGNALS) - return -EINVAL; - return solaris_to_linux_signals[sig]; -} - -asmlinkage int solaris_kill(int pid, int sig) -{ - int (*sys_kill)(int,int) = - (int (*)(int,int))SYS(kill); - int s = mapsig(sig); - - if (s < 0) return s; - return sys_kill(pid, s); -} - -static long sig_handler(int sig, u32 arg, int one_shot) -{ - struct sigaction sa, old; - int ret; - mm_segment_t old_fs = get_fs(); - int (*sys_sigaction)(int,struct sigaction __user *,struct sigaction __user *) = - (int (*)(int,struct sigaction __user *,struct sigaction __user *))SYS(sigaction); - - sigemptyset(&sa.sa_mask); - sa.sa_restorer = NULL; - sa.sa_handler = (__sighandler_t)A(arg); - sa.sa_flags = 0; - if (one_shot) sa.sa_flags = SA_ONESHOT | SA_NOMASK; - set_fs (KERNEL_DS); - ret = sys_sigaction(sig, (void __user *)&sa, (void __user *)&old); - set_fs (old_fs); - if (ret < 0) return ret; - return (u32)(unsigned long)old.sa_handler; -} - -static inline long solaris_signal(int sig, u32 arg) -{ - return sig_handler (sig, arg, 1); -} - -static long solaris_sigset(int sig, u32 arg) -{ - if (arg != 2) /* HOLD */ { - spin_lock_irq(¤t->sighand->siglock); - sigdelsetmask(¤t->blocked, _S(sig)); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - return sig_handler (sig, arg, 0); - } else { - spin_lock_irq(¤t->sighand->siglock); - sigaddsetmask(¤t->blocked, (_S(sig) & ~_BLOCKABLE)); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - return 0; - } -} - -static inline long solaris_sighold(int sig) -{ - return solaris_sigset(sig, 2); -} - -static inline long solaris_sigrelse(int sig) -{ - spin_lock_irq(¤t->sighand->siglock); - sigdelsetmask(¤t->blocked, _S(sig)); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - return 0; -} - -static inline long solaris_sigignore(int sig) -{ - return sig_handler(sig, (u32)(unsigned long)SIG_IGN, 0); -} - -static inline long solaris_sigpause(int sig) -{ - printk ("Need to support solaris sigpause\n"); - return -ENOSYS; -} - -asmlinkage long solaris_sigfunc(int sig, u32 arg) -{ - int func = sig & ~0xff; - - sig = mapsig(sig & 0xff); - if (sig < 0) return sig; - switch (func) { - case 0: return solaris_signal(sig, arg); - case 0x100: return solaris_sigset(sig, arg); - case 0x200: return solaris_sighold(sig); - case 0x400: return solaris_sigrelse(sig); - case 0x800: return solaris_sigignore(sig); - case 0x1000: return solaris_sigpause(sig); - } - return -EINVAL; -} - -typedef struct { - u32 __sigbits[4]; -} sol_sigset_t; - -static inline int mapin(u32 *p, sigset_t *q) -{ - int i; - u32 x; - int sig; - - sigemptyset(q); - x = p[0]; - for (i = 1; i <= SOLARIS_NSIGNALS; i++) { - if (x & 1) { - sig = solaris_to_linux_signals[i]; - if (sig == -1) - return -EINVAL; - sigaddsetmask(q, (1L << (sig - 1))); - } - x >>= 1; - if (i == 32) - x = p[1]; - } - return 0; -} - -static inline int mapout(sigset_t *q, u32 *p) -{ - int i; - int sig; - - p[0] = 0; - p[1] = 0; - for (i = 1; i <= 32; i++) { - if (sigismember(q, sigmask(i))) { - sig = linux_to_solaris_signals[i]; - if (sig == -1) - return -EINVAL; - if (sig > 32) - p[1] |= 1L << (sig - 33); - else - p[0] |= 1L << (sig - 1); - } - } - return 0; -} - -asmlinkage int solaris_sigprocmask(int how, u32 in, u32 out) -{ - sigset_t in_s, *ins, out_s, *outs; - mm_segment_t old_fs = get_fs(); - int ret; - int (*sys_sigprocmask)(int,sigset_t __user *,sigset_t __user *) = - (int (*)(int,sigset_t __user *,sigset_t __user *))SYS(sigprocmask); - - ins = NULL; outs = NULL; - if (in) { - u32 tmp[2]; - - if (copy_from_user (tmp, (void __user *)A(in), 2*sizeof(u32))) - return -EFAULT; - ins = &in_s; - if (mapin (tmp, ins)) return -EINVAL; - } - if (out) outs = &out_s; - set_fs (KERNEL_DS); - ret = sys_sigprocmask((how == 3) ? SIG_SETMASK : how, - (void __user *)ins, (void __user *)outs); - set_fs (old_fs); - if (ret) return ret; - if (out) { - u32 tmp[4]; - - tmp[2] = 0; tmp[3] = 0; - if (mapout (outs, tmp)) return -EINVAL; - if (copy_to_user((void __user *)A(out), tmp, 4*sizeof(u32))) - return -EFAULT; - } - return 0; -} - -asmlinkage long do_sol_sigsuspend(u32 mask) -{ - sigset_t s; - u32 tmp[2]; - - if (copy_from_user (tmp, (sol_sigset_t __user *)A(mask), 2*sizeof(u32))) - return -EFAULT; - if (mapin (tmp, &s)) return -EINVAL; - return (long)s.sig[0]; -} - -struct sol_sigaction { - int sa_flags; - u32 sa_handler; - u32 sa_mask[4]; - int sa_resv[2]; -}; - -asmlinkage int solaris_sigaction(int sig, u32 act, u32 old) -{ - u32 tmp, tmp2[4]; - struct sigaction s, s2; - int ret; - mm_segment_t old_fs = get_fs(); - struct sol_sigaction __user *p = (void __user *)A(old); - int (*sys_sigaction)(int,struct sigaction __user *,struct sigaction __user *) = - (int (*)(int,struct sigaction __user *,struct sigaction __user *))SYS(sigaction); - - sig = mapsig(sig); - if (sig < 0) { - /* We cheat a little bit for Solaris only signals */ - if (old && clear_user(p, sizeof(struct sol_sigaction))) - return -EFAULT; - return 0; - } - if (act) { - if (get_user (tmp, &p->sa_flags)) - return -EFAULT; - s.sa_flags = 0; - if (tmp & SOLARIS_SA_ONSTACK) s.sa_flags |= SA_STACK; - if (tmp & SOLARIS_SA_RESTART) s.sa_flags |= SA_RESTART; - if (tmp & SOLARIS_SA_NODEFER) s.sa_flags |= SA_NOMASK; - if (tmp & SOLARIS_SA_RESETHAND) s.sa_flags |= SA_ONESHOT; - if (tmp & SOLARIS_SA_NOCLDSTOP) s.sa_flags |= SA_NOCLDSTOP; - if (get_user (tmp, &p->sa_handler) || - copy_from_user (tmp2, &p->sa_mask, 2*sizeof(u32))) - return -EFAULT; - s.sa_handler = (__sighandler_t)A(tmp); - if (mapin (tmp2, &s.sa_mask)) return -EINVAL; - s.sa_restorer = NULL; - } - set_fs(KERNEL_DS); - ret = sys_sigaction(sig, act ? (void __user *)&s : NULL, - old ? (void __user *)&s2 : NULL); - set_fs(old_fs); - if (ret) return ret; - if (old) { - if (mapout (&s2.sa_mask, tmp2)) return -EINVAL; - tmp = 0; tmp2[2] = 0; tmp2[3] = 0; - if (s2.sa_flags & SA_STACK) tmp |= SOLARIS_SA_ONSTACK; - if (s2.sa_flags & SA_RESTART) tmp |= SOLARIS_SA_RESTART; - if (s2.sa_flags & SA_NOMASK) tmp |= SOLARIS_SA_NODEFER; - if (s2.sa_flags & SA_ONESHOT) tmp |= SOLARIS_SA_RESETHAND; - if (s2.sa_flags & SA_NOCLDSTOP) tmp |= SOLARIS_SA_NOCLDSTOP; - if (put_user (tmp, &p->sa_flags) || - __put_user ((u32)(unsigned long)s2.sa_handler, &p->sa_handler) || - copy_to_user (&p->sa_mask, tmp2, 4*sizeof(u32))) - return -EFAULT; - } - return 0; -} - -asmlinkage int solaris_sigpending(int which, u32 set) -{ - sigset_t s; - u32 tmp[4]; - switch (which) { - case 1: /* sigpending */ - spin_lock_irq(¤t->sighand->siglock); - sigandsets(&s, ¤t->blocked, ¤t->pending.signal); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - break; - case 2: /* sigfillset - I just set signals which have linux equivalents */ - sigfillset(&s); - break; - default: return -EINVAL; - } - if (mapout (&s, tmp)) return -EINVAL; - tmp[2] = 0; tmp[3] = 0; - if (copy_to_user ((u32 __user *)A(set), tmp, sizeof(tmp))) - return -EFAULT; - return 0; -} - -asmlinkage int solaris_wait(u32 stat_loc) -{ - unsigned __user *p = (unsigned __user *)A(stat_loc); - int (*sys_wait4)(pid_t,unsigned __user *, int, struct rusage __user *) = - (int (*)(pid_t,unsigned __user *, int, struct rusage __user *))SYS(wait4); - int ret, status; - - ret = sys_wait4(-1, p, WUNTRACED, NULL); - if (ret >= 0 && stat_loc) { - if (get_user (status, p)) - return -EFAULT; - if (((status - 1) & 0xffff) < 0xff) - status = linux_to_solaris_signals[status & 0x7f] & 0x7f; - else if ((status & 0xff) == 0x7f) - status = (linux_to_solaris_signals[(status >> 8) & 0xff] << 8) | 0x7f; - if (__put_user (status, p)) - return -EFAULT; - } - return ret; -} - -asmlinkage int solaris_waitid(int idtype, s32 pid, u32 info, int options) -{ - int (*sys_wait4)(pid_t,unsigned __user *, int, struct rusage __user *) = - (int (*)(pid_t,unsigned __user *, int, struct rusage __user *))SYS(wait4); - int opts, status, ret; - - switch (idtype) { - case 0: /* P_PID */ break; - case 1: /* P_PGID */ pid = -pid; break; - case 7: /* P_ALL */ pid = -1; break; - default: return -EINVAL; - } - opts = 0; - if (options & SOLARIS_WUNTRACED) opts |= WUNTRACED; - if (options & SOLARIS_WNOHANG) opts |= WNOHANG; - current->state = TASK_RUNNING; - ret = sys_wait4(pid, (unsigned int __user *)A(info), opts, NULL); - if (ret < 0) return ret; - if (info) { - struct sol_siginfo __user *s = (void __user *)A(info); - - if (get_user (status, (unsigned int __user *)A(info))) - return -EFAULT; - - if (__put_user (SOLARIS_SIGCLD, &s->si_signo) || - __put_user (ret, &s->_data._proc._pid)) - return -EFAULT; - - switch (status & 0xff) { - case 0: ret = SOLARIS_CLD_EXITED; - status = (status >> 8) & 0xff; - break; - case 0x7f: - status = (status >> 8) & 0xff; - switch (status) { - case SIGSTOP: - case SIGTSTP: ret = SOLARIS_CLD_STOPPED; - default: ret = SOLARIS_CLD_EXITED; - } - status = linux_to_solaris_signals[status]; - break; - default: - if (status & 0x80) ret = SOLARIS_CLD_DUMPED; - else ret = SOLARIS_CLD_KILLED; - status = linux_to_solaris_signals[status & 0x7f]; - break; - } - - if (__put_user (ret, &s->si_code) || - __put_user (status, &s->_data._proc._pdata._cld._status)) - return -EFAULT; - } - return 0; -} - -extern int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs); -extern int svr4_getcontext(svr4_ucontext_t *c, struct pt_regs *regs); - -asmlinkage int solaris_context(struct pt_regs *regs) -{ - switch ((unsigned)regs->u_regs[UREG_I0]) { - case 0: /* getcontext */ - return svr4_getcontext((svr4_ucontext_t *)(long)(u32)regs->u_regs[UREG_I1], regs); - case 1: /* setcontext */ - return svr4_setcontext((svr4_ucontext_t *)(long)(u32)regs->u_regs[UREG_I1], regs); - default: - return -EINVAL; - - } -} - -asmlinkage int solaris_sigaltstack(u32 ss, u32 oss) -{ -/* XXX Implement this soon */ - return 0; -} diff --git a/arch/sparc64/solaris/signal.h b/arch/sparc64/solaris/signal.h deleted file mode 100644 index e9157080305..00000000000 --- a/arch/sparc64/solaris/signal.h +++ /dev/null @@ -1,108 +0,0 @@ -/* $Id: signal.h,v 1.3 1998/04/12 06:20:33 davem Exp $ - * signal.h: Signal emulation for Solaris - * - * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) - */ - -#define SOLARIS_SIGHUP 1 -#define SOLARIS_SIGINT 2 -#define SOLARIS_SIGQUIT 3 -#define SOLARIS_SIGILL 4 -#define SOLARIS_SIGTRAP 5 -#define SOLARIS_SIGIOT 6 -#define SOLARIS_SIGEMT 7 -#define SOLARIS_SIGFPE 8 -#define SOLARIS_SIGKILL 9 -#define SOLARIS_SIGBUS 10 -#define SOLARIS_SIGSEGV 11 -#define SOLARIS_SIGSYS 12 -#define SOLARIS_SIGPIPE 13 -#define SOLARIS_SIGALRM 14 -#define SOLARIS_SIGTERM 15 -#define SOLARIS_SIGUSR1 16 -#define SOLARIS_SIGUSR2 17 -#define SOLARIS_SIGCLD 18 -#define SOLARIS_SIGPWR 19 -#define SOLARIS_SIGWINCH 20 -#define SOLARIS_SIGURG 21 -#define SOLARIS_SIGPOLL 22 -#define SOLARIS_SIGSTOP 23 -#define SOLARIS_SIGTSTP 24 -#define SOLARIS_SIGCONT 25 -#define SOLARIS_SIGTTIN 26 -#define SOLARIS_SIGTTOU 27 -#define SOLARIS_SIGVTALRM 28 -#define SOLARIS_SIGPROF 29 -#define SOLARIS_SIGXCPU 30 -#define SOLARIS_SIGXFSZ 31 -#define SOLARIS_SIGWAITING 32 -#define SOLARIS_SIGLWP 33 -#define SOLARIS_SIGFREEZE 34 -#define SOLARIS_SIGTHAW 35 -#define SOLARIS_SIGCANCEL 36 -#define SOLARIS_SIGRTMIN 37 -#define SOLARIS_SIGRTMAX 44 -#define SOLARIS_NSIGNALS 44 - - -#define SOLARIS_SA_ONSTACK 1 -#define SOLARIS_SA_RESETHAND 2 -#define SOLARIS_SA_RESTART 4 -#define SOLARIS_SA_SIGINFO 8 -#define SOLARIS_SA_NODEFER 16 -#define SOLARIS_SA_NOCLDWAIT 0x10000 -#define SOLARIS_SA_NOCLDSTOP 0x20000 - -struct sol_siginfo { - int si_signo; - int si_code; - int si_errno; - union { - char pad[128-3*sizeof(int)]; - struct { - s32 _pid; - union { - struct { - s32 _uid; - s32 _value; - } _kill; - struct { - s32 _utime; - int _status; - s32 _stime; - } _cld; - } _pdata; - } _proc; - struct { /* SIGSEGV, SIGBUS, SIGILL and SIGFPE */ - u32 _addr; - int _trapno; - } _fault; - struct { /* SIGPOLL, SIGXFSZ */ - int _fd; - s32 _band; - } _file; - } _data; -}; - -#define SOLARIS_WUNTRACED 0x04 -#define SOLARIS_WNOHANG 0x40 -#define SOLARIS_WEXITED 0x01 -#define SOLARIS_WTRAPPED 0x02 -#define SOLARIS_WSTOPPED WUNTRACED -#define SOLARIS_WCONTINUED 0x08 -#define SOLARIS_WNOWAIT 0x80 - -#define SOLARIS_TRAP_BRKPT 1 -#define SOLARIS_TRAP_TRACE 2 -#define SOLARIS_CLD_EXITED 1 -#define SOLARIS_CLD_KILLED 2 -#define SOLARIS_CLD_DUMPED 3 -#define SOLARIS_CLD_TRAPPED 4 -#define SOLARIS_CLD_STOPPED 5 -#define SOLARIS_CLD_CONTINUED 6 -#define SOLARIS_POLL_IN 1 -#define SOLARIS_POLL_OUT 2 -#define SOLARIS_POLL_MSG 3 -#define SOLARIS_POLL_ERR 4 -#define SOLARIS_POLL_PRI 5 -#define SOLARIS_POLL_HUP 6 diff --git a/arch/sparc64/solaris/socket.c b/arch/sparc64/solaris/socket.c deleted file mode 100644 index cc69847cf24..00000000000 --- a/arch/sparc64/solaris/socket.c +++ /dev/null @@ -1,461 +0,0 @@ -/* $Id: socket.c,v 1.6 2002/02/08 03:57:14 davem Exp $ - * socket.c: Socket syscall emulation for Solaris 2.6+ - * - * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz) - * - * 1999-08-19 Fixed socketpair code - * Jason Rappleye (rappleye@ccr.buffalo.edu) - */ - -#include <linux/types.h> -#include <linux/mm.h> -#include <linux/slab.h> -#include <linux/socket.h> -#include <linux/file.h> -#include <linux/net.h> -#include <linux/compat.h> -#include <net/compat.h> -#include <net/sock.h> - -#include <asm/uaccess.h> -#include <asm/string.h> -#include <asm/oplib.h> -#include <asm/idprom.h> - -#include "conv.h" - -#define SOCK_SOL_STREAM 2 -#define SOCK_SOL_DGRAM 1 -#define SOCK_SOL_RAW 4 -#define SOCK_SOL_RDM 5 -#define SOCK_SOL_SEQPACKET 6 - -#define SOL_SO_SNDLOWAT 0x1003 -#define SOL_SO_RCVLOWAT 0x1004 -#define SOL_SO_SNDTIMEO 0x1005 -#define SOL_SO_RCVTIMEO 0x1006 -#define SOL_SO_STATE 0x2000 - -#define SOL_SS_NDELAY 0x040 -#define SOL_SS_NONBLOCK 0x080 -#define SOL_SS_ASYNC 0x100 - -#define SO_STATE 0x000e - -static int socket_check(int family, int type) -{ - if (family != PF_UNIX && family != PF_INET) - return -ESOCKTNOSUPPORT; - switch (type) { - case SOCK_SOL_STREAM: type = SOCK_STREAM; break; - case SOCK_SOL_DGRAM: type = SOCK_DGRAM; break; - case SOCK_SOL_RAW: type = SOCK_RAW; break; - case SOCK_SOL_RDM: type = SOCK_RDM; break; - case SOCK_SOL_SEQPACKET: type = SOCK_SEQPACKET; break; - default: return -EINVAL; - } - return type; -} - -static int solaris_to_linux_sockopt(int optname) -{ - switch (optname) { - case SOL_SO_SNDLOWAT: optname = SO_SNDLOWAT; break; - case SOL_SO_RCVLOWAT: optname = SO_RCVLOWAT; break; - case SOL_SO_SNDTIMEO: optname = SO_SNDTIMEO; break; - case SOL_SO_RCVTIMEO: optname = SO_RCVTIMEO; break; - case SOL_SO_STATE: optname = SO_STATE; break; - }; - - return optname; -} - -asmlinkage int solaris_socket(int family, int type, int protocol) -{ - int (*sys_socket)(int, int, int) = - (int (*)(int, int, int))SYS(socket); - - type = socket_check (family, type); - if (type < 0) return type; - return sys_socket(family, type, protocol); -} - -asmlinkage int solaris_socketpair(int *usockvec) -{ - int (*sys_socketpair)(int, int, int, int *) = - (int (*)(int, int, int, int *))SYS(socketpair); - - /* solaris socketpair really only takes one arg at the syscall - * level, int * usockvec. The libs apparently take care of - * making sure that family==AF_UNIX and type==SOCK_STREAM. The - * pointer we really want ends up residing in the first (and - * supposedly only) argument. - */ - - return sys_socketpair(AF_UNIX, SOCK_STREAM, 0, (int *)usockvec); -} - -asmlinkage int solaris_bind(int fd, struct sockaddr *addr, int addrlen) -{ - int (*sys_bind)(int, struct sockaddr *, int) = - (int (*)(int, struct sockaddr *, int))SUNOS(104); - - return sys_bind(fd, addr, addrlen); -} - -asmlinkage int solaris_setsockopt(int fd, int level, int optname, u32 optval, int optlen) -{ - int (*sunos_setsockopt)(int, int, int, u32, int) = - (int (*)(int, int, int, u32, int))SUNOS(105); - - optname = solaris_to_linux_sockopt(optname); - if (optname < 0) - return optname; - if (optname == SO_STATE) - return 0; - - return sunos_setsockopt(fd, level, optname, optval, optlen); -} - -asmlinkage int solaris_getsockopt(int fd, int level, int optname, u32 optval, u32 optlen) -{ - int (*sunos_getsockopt)(int, int, int, u32, u32) = - (int (*)(int, int, int, u32, u32))SUNOS(118); - - optname = solaris_to_linux_sockopt(optname); - if (optname < 0) - return optname; - - if (optname == SO_STATE) - optname = SOL_SO_STATE; - - return sunos_getsockopt(fd, level, optname, optval, optlen); -} - -asmlinkage int solaris_connect(int fd, struct sockaddr __user *addr, int addrlen) -{ - int (*sys_connect)(int, struct sockaddr __user *, int) = - (int (*)(int, struct sockaddr __user *, int))SYS(connect); - - return sys_connect(fd, addr, addrlen); -} - -asmlinkage int solaris_accept(int fd, struct sockaddr __user *addr, int __user *addrlen) -{ - int (*sys_accept)(int, struct sockaddr __user *, int __user *) = - (int (*)(int, struct sockaddr __user *, int __user *))SYS(accept); - - return sys_accept(fd, addr, addrlen); -} - -asmlinkage int solaris_listen(int fd, int backlog) -{ - int (*sys_listen)(int, int) = - (int (*)(int, int))SUNOS(106); - - return sys_listen(fd, backlog); -} - -asmlinkage int solaris_shutdown(int fd, int how) -{ - int (*sys_shutdown)(int, int) = - (int (*)(int, int))SYS(shutdown); - - return sys_shutdown(fd, how); -} - -#define MSG_SOL_OOB 0x1 -#define MSG_SOL_PEEK 0x2 -#define MSG_SOL_DONTROUTE 0x4 -#define MSG_SOL_EOR 0x8 -#define MSG_SOL_CTRUNC 0x10 -#define MSG_SOL_TRUNC 0x20 -#define MSG_SOL_WAITALL 0x40 -#define MSG_SOL_DONTWAIT 0x80 - -static int solaris_to_linux_msgflags(int flags) -{ - int fl = flags & (MSG_OOB|MSG_PEEK|MSG_DONTROUTE); - - if (flags & MSG_SOL_EOR) fl |= MSG_EOR; - if (flags & MSG_SOL_CTRUNC) fl |= MSG_CTRUNC; - if (flags & MSG_SOL_TRUNC) fl |= MSG_TRUNC; - if (flags & MSG_SOL_WAITALL) fl |= MSG_WAITALL; - if (flags & MSG_SOL_DONTWAIT) fl |= MSG_DONTWAIT; - return fl; -} - -static int linux_to_solaris_msgflags(int flags) -{ - int fl = flags & (MSG_OOB|MSG_PEEK|MSG_DONTROUTE); - - if (flags & MSG_EOR) fl |= MSG_SOL_EOR; - if (flags & MSG_CTRUNC) fl |= MSG_SOL_CTRUNC; - if (flags & MSG_TRUNC) fl |= MSG_SOL_TRUNC; - if (flags & MSG_WAITALL) fl |= MSG_SOL_WAITALL; - if (flags & MSG_DONTWAIT) fl |= MSG_SOL_DONTWAIT; - return fl; -} - -asmlinkage int solaris_recvfrom(int s, char __user *buf, int len, int flags, u32 from, u32 fromlen) -{ - int (*sys_recvfrom)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int __user *) = - (int (*)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int __user *))SYS(recvfrom); - - return sys_recvfrom(s, buf, len, solaris_to_linux_msgflags(flags), A(from), A(fromlen)); -} - -asmlinkage int solaris_recv(int s, char __user *buf, int len, int flags) -{ - int (*sys_recvfrom)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int __user *) = - (int (*)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int __user *))SYS(recvfrom); - - return sys_recvfrom(s, buf, len, solaris_to_linux_msgflags(flags), NULL, NULL); -} - -asmlinkage int solaris_sendto(int s, char __user *buf, int len, int flags, u32 to, u32 tolen) -{ - int (*sys_sendto)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int __user *) = - (int (*)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int __user *))SYS(sendto); - - return sys_sendto(s, buf, len, solaris_to_linux_msgflags(flags), A(to), A(tolen)); -} - -asmlinkage int solaris_send(int s, char *buf, int len, int flags) -{ - int (*sys_sendto)(int, void *, size_t, unsigned, struct sockaddr *, int *) = - (int (*)(int, void *, size_t, unsigned, struct sockaddr *, int *))SYS(sendto); - - return sys_sendto(s, buf, len, solaris_to_linux_msgflags(flags), NULL, NULL); -} - -asmlinkage int solaris_getpeername(int fd, struct sockaddr *addr, int *addrlen) -{ - int (*sys_getpeername)(int, struct sockaddr *, int *) = - (int (*)(int, struct sockaddr *, int *))SYS(getpeername); - - return sys_getpeername(fd, addr, addrlen); -} - -asmlinkage int solaris_getsockname(int fd, struct sockaddr *addr, int *addrlen) -{ - int (*sys_getsockname)(int, struct sockaddr *, int *) = - (int (*)(int, struct sockaddr *, int *))SYS(getsockname); - - return sys_getsockname(fd, addr, addrlen); -} - -/* XXX This really belongs in some header file... -DaveM */ -#define MAX_SOCK_ADDR 128 /* 108 for Unix domain - - 16 for IP, 16 for IPX, - 24 for IPv6, - about 80 for AX.25 */ - -struct sol_nmsghdr { - u32 msg_name; - int msg_namelen; - u32 msg_iov; - u32 msg_iovlen; - u32 msg_control; - u32 msg_controllen; - u32 msg_flags; -}; - -struct sol_cmsghdr { - u32 cmsg_len; - int cmsg_level; - int cmsg_type; - unsigned char cmsg_data[0]; -}; - -static inline int msghdr_from_user32_to_kern(struct msghdr *kmsg, - struct sol_nmsghdr __user *umsg) -{ - u32 tmp1, tmp2, tmp3; - int err; - - err = get_user(tmp1, &umsg->msg_name); - err |= __get_user(tmp2, &umsg->msg_iov); - err |= __get_user(tmp3, &umsg->msg_control); - if (err) - return -EFAULT; - - kmsg->msg_name = A(tmp1); - kmsg->msg_iov = A(tmp2); - kmsg->msg_control = A(tmp3); - - err = get_user(kmsg->msg_namelen, &umsg->msg_namelen); - err |= get_user(kmsg->msg_controllen, &umsg->msg_controllen); - err |= get_user(kmsg->msg_flags, &umsg->msg_flags); - - kmsg->msg_flags = solaris_to_linux_msgflags(kmsg->msg_flags); - - return err; -} - -asmlinkage int solaris_sendmsg(int fd, struct sol_nmsghdr __user *user_msg, unsigned user_flags) -{ - struct socket *sock; - char address[MAX_SOCK_ADDR]; - struct iovec iovstack[UIO_FASTIOV], *iov = iovstack; - unsigned char ctl[sizeof(struct cmsghdr) + 20]; - unsigned char *ctl_buf = ctl; - struct msghdr msg_sys; - int err, ctl_len, iov_size, total_len; - - err = -EFAULT; - if (msghdr_from_user32_to_kern(&msg_sys, user_msg)) - goto out; - - sock = sockfd_lookup(fd, &err); - if (!sock) - goto out; - - /* do not move before msg_sys is valid */ - err = -EMSGSIZE; - if (msg_sys.msg_iovlen > UIO_MAXIOV) - goto out_put; - - /* Check whether to allocate the iovec area*/ - err = -ENOMEM; - iov_size = msg_sys.msg_iovlen * sizeof(struct iovec); - if (msg_sys.msg_iovlen > UIO_FASTIOV) { - iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL); - if (!iov) - goto out_put; - } - - err = verify_compat_iovec(&msg_sys, iov, address, VERIFY_READ); - if (err < 0) - goto out_freeiov; - total_len = err; - - err = -ENOBUFS; - if (msg_sys.msg_controllen > INT_MAX) - goto out_freeiov; - - ctl_len = msg_sys.msg_controllen; - if (ctl_len) { - struct sol_cmsghdr __user *ucmsg = msg_sys.msg_control; - unsigned long *kcmsg; - compat_size_t cmlen; - - err = -EINVAL; - if (ctl_len <= sizeof(compat_size_t)) - goto out_freeiov; - - if (ctl_len > sizeof(ctl)) { - err = -ENOBUFS; - ctl_buf = kmalloc(ctl_len, GFP_KERNEL); - if (!ctl_buf) - goto out_freeiov; - } - __get_user(cmlen, &ucmsg->cmsg_len); - kcmsg = (unsigned long *) ctl_buf; - *kcmsg++ = (unsigned long)cmlen; - err = -EFAULT; - if (copy_from_user(kcmsg, &ucmsg->cmsg_level, - ctl_len - sizeof(compat_size_t))) - goto out_freectl; - msg_sys.msg_control = ctl_buf; - } - msg_sys.msg_flags = solaris_to_linux_msgflags(user_flags); - - if (sock->file->f_flags & O_NONBLOCK) - msg_sys.msg_flags |= MSG_DONTWAIT; - err = sock_sendmsg(sock, &msg_sys, total_len); - -out_freectl: - if (ctl_buf != ctl) - sock_kfree_s(sock->sk, ctl_buf, ctl_len); -out_freeiov: - if (iov != iovstack) - sock_kfree_s(sock->sk, iov, iov_size); -out_put: - sockfd_put(sock); -out: - return err; -} - -asmlinkage int solaris_recvmsg(int fd, struct sol_nmsghdr __user *user_msg, unsigned int user_flags) -{ - struct socket *sock; - struct iovec iovstack[UIO_FASTIOV]; - struct iovec *iov = iovstack; - struct msghdr msg_sys; - unsigned long cmsg_ptr; - int err, iov_size, total_len, len; - - /* kernel mode address */ - char addr[MAX_SOCK_ADDR]; - - /* user mode address pointers */ - struct sockaddr __user *uaddr; - int __user *uaddr_len; - - if (msghdr_from_user32_to_kern(&msg_sys, user_msg)) - return -EFAULT; - - sock = sockfd_lookup(fd, &err); - if (!sock) - goto out; - - err = -EMSGSIZE; - if (msg_sys.msg_iovlen > UIO_MAXIOV) - goto out_put; - - /* Check whether to allocate the iovec area*/ - err = -ENOMEM; - iov_size = msg_sys.msg_iovlen * sizeof(struct iovec); - if (msg_sys.msg_iovlen > UIO_FASTIOV) { - iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL); - if (!iov) - goto out_put; - } - - /* - * Save the user-mode address (verify_iovec will change the - * kernel msghdr to use the kernel address space) - */ - - uaddr = (void __user *) msg_sys.msg_name; - uaddr_len = &user_msg->msg_namelen; - err = verify_compat_iovec(&msg_sys, iov, addr, VERIFY_WRITE); - if (err < 0) - goto out_freeiov; - total_len = err; - - cmsg_ptr = (unsigned long) msg_sys.msg_control; - msg_sys.msg_flags = MSG_CMSG_COMPAT; - - if (sock->file->f_flags & O_NONBLOCK) - user_flags |= MSG_DONTWAIT; - - err = sock_recvmsg(sock, &msg_sys, total_len, user_flags); - if(err < 0) - goto out_freeiov; - - len = err; - - if (uaddr != NULL) { - err = move_addr_to_user(addr, msg_sys.msg_namelen, uaddr, uaddr_len); - if (err < 0) - goto out_freeiov; - } - err = __put_user(linux_to_solaris_msgflags(msg_sys.msg_flags), &user_msg->msg_flags); - if (err) - goto out_freeiov; - err = __put_user((unsigned long)msg_sys.msg_control - cmsg_ptr, - &user_msg->msg_controllen); - if (err) - goto out_freeiov; - err = len; - -out_freeiov: - if (iov != iovstack) - sock_kfree_s(sock->sk, iov, iov_size); -out_put: - sockfd_put(sock); -out: - return err; -} diff --git a/arch/sparc64/solaris/socksys.c b/arch/sparc64/solaris/socksys.c deleted file mode 100644 index 7736411f244..00000000000 --- a/arch/sparc64/solaris/socksys.c +++ /dev/null @@ -1,203 +0,0 @@ -/* $Id: socksys.c,v 1.21 2002/02/08 03:57:14 davem Exp $ - * socksys.c: /dev/inet/ stuff for Solaris emulation. - * - * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) - * Copyright (C) 1997, 1998 Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz) - * Copyright (C) 1995, 1996 Mike Jagdis (jaggy@purplet.demon.co.uk) - */ - -/* - * Dave, _please_ give me specifications on this fscking mess so that I - * could at least get it into the state when it wouldn't screw the rest of - * the kernel over. socksys.c and timod.c _stink_ and we are not talking - * H2S here, it's isopropilmercaptan in concentrations way over LD50. -- AV - */ - -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/smp.h> -#include <linux/ioctl.h> -#include <linux/fs.h> -#include <linux/file.h> -#include <linux/init.h> -#include <linux/poll.h> -#include <linux/slab.h> -#include <linux/syscalls.h> -#include <linux/in.h> - -#include <net/sock.h> - -#include <asm/uaccess.h> -#include <asm/termios.h> - -#include "conv.h" -#include "socksys.h" - -static int af_inet_protocols[] = { -IPPROTO_ICMP, IPPROTO_ICMP, IPPROTO_IGMP, IPPROTO_IPIP, IPPROTO_TCP, -IPPROTO_EGP, IPPROTO_PUP, IPPROTO_UDP, IPPROTO_IDP, IPPROTO_RAW, -0, 0, 0, 0, 0, 0, -}; - -#ifndef DEBUG_SOLARIS_KMALLOC - -#define mykmalloc kmalloc -#define mykfree kfree - -#else - -extern void * mykmalloc(size_t s, gfp_t gfp); -extern void mykfree(void *); - -#endif - -static unsigned int (*sock_poll)(struct file *, poll_table *); - -static struct file_operations socksys_file_ops = { - /* Currently empty */ -}; - -static int socksys_open(struct inode * inode, struct file * filp) -{ - int family, type, protocol, fd; - struct dentry *dentry; - int (*sys_socket)(int,int,int) = - (int (*)(int,int,int))SUNOS(97); - struct sol_socket_struct * sock; - - family = ((iminor(inode) >> 4) & 0xf); - switch (family) { - case AF_UNIX: - type = SOCK_STREAM; - protocol = 0; - break; - case AF_INET: - protocol = af_inet_protocols[iminor(inode) & 0xf]; - switch (protocol) { - case IPPROTO_TCP: type = SOCK_STREAM; break; - case IPPROTO_UDP: type = SOCK_DGRAM; break; - default: type = SOCK_RAW; break; - } - break; - default: - type = SOCK_RAW; - protocol = 0; - break; - } - - fd = sys_socket(family, type, protocol); - if (fd < 0) - return fd; - /* - * N.B. The following operations are not legal! - * - * No shit. WTF is it supposed to do, anyway? - * - * Try instead: - * d_delete(filp->f_path.dentry), then d_instantiate with sock inode - */ - dentry = filp->f_path.dentry; - filp->f_path.dentry = dget(fcheck(fd)->f_path.dentry); - filp->f_path.dentry->d_inode->i_rdev = inode->i_rdev; - filp->f_path.dentry->d_inode->i_flock = inode->i_flock; - SOCKET_I(filp->f_path.dentry->d_inode)->file = filp; - filp->f_op = &socksys_file_ops; - sock = (struct sol_socket_struct*) - mykmalloc(sizeof(struct sol_socket_struct), GFP_KERNEL); - if (!sock) return -ENOMEM; - SOLDD(("sock=%016lx(%016lx)\n", sock, filp)); - sock->magic = SOLARIS_SOCKET_MAGIC; - sock->modcount = 0; - sock->state = TS_UNBND; - sock->offset = 0; - sock->pfirst = sock->plast = NULL; - filp->private_data = sock; - SOLDD(("filp->private_data %016lx\n", filp->private_data)); - - sys_close(fd); - dput(dentry); - return 0; -} - -static int socksys_release(struct inode * inode, struct file * filp) -{ - struct sol_socket_struct * sock; - struct T_primsg *it; - - /* XXX: check this */ - sock = (struct sol_socket_struct *)filp->private_data; - SOLDD(("sock release %016lx(%016lx)\n", sock, filp)); - it = sock->pfirst; - while (it) { - struct T_primsg *next = it->next; - - SOLDD(("socksys_release %016lx->%016lx\n", it, next)); - mykfree((char*)it); - it = next; - } - filp->private_data = NULL; - SOLDD(("socksys_release %016lx\n", sock)); - mykfree((char*)sock); - return 0; -} - -static unsigned int socksys_poll(struct file * filp, poll_table * wait) -{ - struct inode *ino; - unsigned int mask = 0; - - ino=filp->f_path.dentry->d_inode; - if (ino && S_ISSOCK(ino->i_mode)) { - struct sol_socket_struct *sock; - sock = (struct sol_socket_struct*)filp->private_data; - if (sock && sock->pfirst) { - mask |= POLLIN | POLLRDNORM; - if (sock->pfirst->pri == MSG_HIPRI) - mask |= POLLPRI; - } - } - if (sock_poll) - mask |= (*sock_poll)(filp, wait); - return mask; -} - -static const struct file_operations socksys_fops = { - .open = socksys_open, - .release = socksys_release, -}; - -int __init init_socksys(void) -{ - int ret; - struct file * file; - int (*sys_socket)(int,int,int) = - (int (*)(int,int,int))SUNOS(97); - int (*sys_close)(unsigned int) = - (int (*)(unsigned int))SYS(close); - - ret = register_chrdev (30, "socksys", &socksys_fops); - if (ret < 0) { - printk ("Couldn't register socksys character device\n"); - return ret; - } - ret = sys_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (ret < 0) { - printk ("Couldn't create socket\n"); - return ret; - } - - file = fcheck(ret); - /* N.B. Is this valid? Suppose the f_ops are in a module ... */ - socksys_file_ops = *file->f_op; - sys_close(ret); - sock_poll = socksys_file_ops.poll; - socksys_file_ops.poll = socksys_poll; - socksys_file_ops.release = socksys_release; - return 0; -} - -void __exit cleanup_socksys(void) -{ - unregister_chrdev(30, "socksys"); -} diff --git a/arch/sparc64/solaris/socksys.h b/arch/sparc64/solaris/socksys.h deleted file mode 100644 index 5d1b78ec160..00000000000 --- a/arch/sparc64/solaris/socksys.h +++ /dev/null @@ -1,208 +0,0 @@ -/* $Id: socksys.h,v 1.2 1998/03/26 08:46:07 jj Exp $ - * socksys.h: Definitions for STREAMS modules emulation code. - * - * Copyright (C) 1998 Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz) - */ - -#define MSG_HIPRI 0x01 -#define MSG_ANY 0x02 -#define MSG_BAND 0x04 - -#define MORECTL 1 -#define MOREDATA 2 - -#define TBADADDR 1 -#define TBADOPT 2 -#define TACCES 3 -#define TBADF 4 -#define TNOADDR 5 -#define TOUTSTATE 6 -#define TBADSEQ 7 -#define TSYSERR 8 -#define TLOOK 9 -#define TBADDATA 10 -#define TBUFOVFLW 11 -#define TFLOW 12 -#define TNODATA 13 -#define TNODIS 14 -#define TNOUDERR 15 -#define TBADFLAG 16 -#define TNOREL 17 -#define TNOTSUPPORT 18 -#define TSTATECHNG 19 - -#define T_CONN_REQ 0 -#define T_CONN_RES 1 -#define T_DISCON_REQ 2 -#define T_DATA_REQ 3 -#define T_EXDATA_REQ 4 -#define T_INFO_REQ 5 -#define T_BIND_REQ 6 -#define T_UNBIND_REQ 7 -#define T_UNITDATA_REQ 8 -#define T_OPTMGMT_REQ 9 -#define T_ORDREL_REQ 10 - -#define T_CONN_IND 11 -#define T_CONN_CON 12 -#define T_DISCON_IND 13 -#define T_DATA_IND 14 -#define T_EXDATA_IND 15 -#define T_INFO_ACK 16 -#define T_BIND_ACK 17 -#define T_ERROR_ACK 18 -#define T_OK_ACK 19 -#define T_UNITDATA_IND 20 -#define T_UDERROR_IND 21 -#define T_OPTMGMT_ACK 22 -#define T_ORDREL_IND 23 - -#define T_NEGOTIATE 0x0004 -#define T_FAILURE 0x0040 - -#define TS_UNBND 0 /* unbound */ -#define TS_WACK_BREQ 1 /* waiting for T_BIND_REQ ack */ -#define TS_WACK_UREQ 2 /* waiting for T_UNBIND_REQ ack */ -#define TS_IDLE 3 /* idle */ -#define TS_WACK_OPTREQ 4 /* waiting for T_OPTMGMT_REQ ack */ -#define TS_WACK_CREQ 5 /* waiting for T_CONN_REQ ack */ -#define TS_WCON_CREQ 6 /* waiting for T_CONN_REQ confirmation */ -#define TS_WRES_CIND 7 /* waiting for T_CONN_IND */ -#define TS_WACK_CRES 8 /* waiting for T_CONN_RES ack */ -#define TS_DATA_XFER 9 /* data transfer */ -#define TS_WIND_ORDREL 10 /* releasing read but not write */ -#define TS_WREQ_ORDREL 11 /* wait to release write but not read */ -#define TS_WACK_DREQ6 12 /* waiting for T_DISCON_REQ ack */ -#define TS_WACK_DREQ7 13 /* waiting for T_DISCON_REQ ack */ -#define TS_WACK_DREQ9 14 /* waiting for T_DISCON_REQ ack */ -#define TS_WACK_DREQ10 15 /* waiting for T_DISCON_REQ ack */ -#define TS_WACK_DREQ11 16 /* waiting for T_DISCON_REQ ack */ -#define TS_NOSTATES 17 - -struct T_conn_req { - s32 PRIM_type; - s32 DEST_length; - s32 DEST_offset; - s32 OPT_length; - s32 OPT_offset; -}; - -struct T_bind_req { - s32 PRIM_type; - s32 ADDR_length; - s32 ADDR_offset; - u32 CONIND_number; -}; - -struct T_unitdata_req { - s32 PRIM_type; - s32 DEST_length; - s32 DEST_offset; - s32 OPT_length; - s32 OPT_offset; -}; - -struct T_optmgmt_req { - s32 PRIM_type; - s32 OPT_length; - s32 OPT_offset; - s32 MGMT_flags; -}; - -struct T_bind_ack { - s32 PRIM_type; - s32 ADDR_length; - s32 ADDR_offset; - u32 CONIND_number; -}; - -struct T_error_ack { - s32 PRIM_type; - s32 ERROR_prim; - s32 TLI_error; - s32 UNIX_error; -}; - -struct T_ok_ack { - s32 PRIM_type; - s32 CORRECT_prim; -}; - -struct T_conn_ind { - s32 PRIM_type; - s32 SRC_length; - s32 SRC_offset; - s32 OPT_length; - s32 OPT_offset; - s32 SEQ_number; -}; - -struct T_conn_con { - s32 PRIM_type; - s32 RES_length; - s32 RES_offset; - s32 OPT_length; - s32 OPT_offset; -}; - -struct T_discon_ind { - s32 PRIM_type; - s32 DISCON_reason; - s32 SEQ_number; -}; - -struct T_unitdata_ind { - s32 PRIM_type; - s32 SRC_length; - s32 SRC_offset; - s32 OPT_length; - s32 OPT_offset; -}; - -struct T_optmgmt_ack { - s32 PRIM_type; - s32 OPT_length; - s32 OPT_offset; - s32 MGMT_flags; -}; - -struct opthdr { - s32 level; - s32 name; - s32 len; - char value[0]; -}; - -struct T_primsg { - struct T_primsg *next; - unsigned char pri; - unsigned char band; - int length; - s32 type; -}; - -struct strbuf { - s32 maxlen; - s32 len; - u32 buf; -} ; - -/* Constants used by STREAMS modules emulation code */ - -typedef char sol_module; - -#define MAX_NR_STREAM_MODULES 16 - -/* Private data structure assigned to sockets. */ - -struct sol_socket_struct { - int magic; - int modcount; - sol_module module[MAX_NR_STREAM_MODULES]; - long state; - int offset; - struct T_primsg *pfirst, *plast; -}; - -#define SOLARIS_SOCKET_MAGIC 0xADDED - diff --git a/arch/sparc64/solaris/systbl.S b/arch/sparc64/solaris/systbl.S deleted file mode 100644 index 7043ca18caf..00000000000 --- a/arch/sparc64/solaris/systbl.S +++ /dev/null @@ -1,285 +0,0 @@ -/* $Id: systbl.S,v 1.11 2000/03/13 21:57:35 davem Exp $ - * systbl.S: System call entry point table for Solaris compatibility. - * - * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) - * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) - */ - -#include <asm/unistd.h> - -/* Fall back to sys_call_table32 entry */ -#define CHAIN(name) __NR_##name - -/* Pass pt_regs pointer as first argument */ -#define REGS(name) name+1 - -/* Hack till all be implemented */ -#define solaris_getpmsg solaris_unimplemented -#define solaris_hrtsys solaris_unimplemented -#define solaris_msgsys solaris_unimplemented -#define solaris_putpmsg solaris_unimplemented -#define solaris_semsys solaris_unimplemented - - .data - .globl solaris_sys_table -solaris_sys_table: - .word solaris_unimplemented /* nosys 0 */ - .word CHAIN(exit) /* exit d 1 */ - .word CHAIN(fork) /* fork 2 */ - .word CHAIN(read) /* read dpd 3 */ - .word CHAIN(write) /* write dpd 4 */ - .word solaris_open /* open soo 5 */ - .word CHAIN(close) /* close d 6 */ - .word solaris_wait /* wait xxx 7 */ - .word CHAIN(creat) /* creat so 8 */ - .word CHAIN(link) /* link ss 9 */ - .word CHAIN(unlink) /* unlink s 10 */ - .word solaris_unimplemented /* exec sxx 11 */ - .word CHAIN(chdir) /* chdir s 12 */ - .word CHAIN(time) /* time 13 */ - .word solaris_mknod /* mknod sox 14 */ - .word CHAIN(chmod) /* chmod so 15 */ - .word CHAIN(chown) /* chown sdd 16 */ - .word solaris_brk /* brk/break x 17 */ - .word solaris_stat /* stat sp 18 */ - .word CHAIN(lseek) /* seek/lseek ddd 19 */ - .word solaris_getpid /* getpid 20 */ - .word solaris_unimplemented /* mount 21 */ - .word CHAIN(umount) /* umount s 22 */ - .word CHAIN(setuid) /* setuid d 23 */ - .word solaris_getuid /* getuid 24 */ - .word CHAIN(stime) /* stime d 25 */ -#if 0 - .word solaris_ptrace /* ptrace xdxx 26 */ -#else - .word CHAIN(ptrace) /* ptrace xdxx 26 */ -#endif - .word CHAIN(alarm) /* alarm d 27 */ - .word solaris_fstat /* fstat dp 28 */ - .word CHAIN(pause) /* pause 29 */ - .word CHAIN(utime) /* utime xx 30 */ - .word solaris_unimplemented /* stty 31 */ - .word solaris_unimplemented /* gtty 32 */ - .word solaris_access /* access so 33 */ - .word CHAIN(nice) /* nice d 34 */ - .word solaris_statfs /* statfs spdd 35 */ - .word CHAIN(sync) /* sync 36 */ - .word solaris_kill /* kill dd 37 */ - .word solaris_fstatfs /* fstatfs dpdd 38 */ - .word solaris_procids /* pgrpsys ddd 39 */ - .word solaris_unimplemented /* xenix 40 */ - .word CHAIN(dup) /* dup d 41 */ - .word CHAIN(pipe) /* pipe 42 */ - .word CHAIN(times) /* times p 43 */ - .word 44 /*CHAIN(profil)*/ /* prof xxxx 44 */ - .word solaris_unimplemented /* lock/plock 45 */ - .word CHAIN(setgid) /* setgid d 46 */ - .word solaris_getgid /* getgid 47 */ - .word solaris_sigfunc /* sigfunc xx 48 */ - .word REGS(solaris_msgsys) /* msgsys dxddd 49 */ - .word solaris_unimplemented /* syssun/3b 50 */ - .word CHAIN(acct) /* acct/sysacct x 51 */ - .word solaris_shmsys /* shmsys ddxo 52 */ - .word REGS(solaris_semsys) /* semsys dddx 53 */ - .word solaris_ioctl /* ioctl dxx 54 */ - .word solaris_unimplemented /* uadmin xxx 55 */ - .word solaris_unimplemented /* reserved:exch 56 */ - .word solaris_utssys /* utssys x 57 */ - .word CHAIN(fsync) /* fsync d 58 */ - .word CHAIN(execve) /* execv spp 59 */ - .word CHAIN(umask) /* umask o 60 */ - .word CHAIN(chroot) /* chroot s 61 */ - .word solaris_fcntl /* fcntl dxx 62 */ - .word solaris_ulimit /* ulimit xx 63 */ - .word solaris_unimplemented /* ? 64 */ - .word solaris_unimplemented /* ? 65 */ - .word solaris_unimplemented /* ? 66 */ - .word solaris_unimplemented /* ? 67 */ - .word solaris_unimplemented /* ? 68 */ - .word solaris_unimplemented /* ? 69 */ - .word solaris_unimplemented /* advfs 70 */ - .word solaris_unimplemented /* unadvfs 71 */ - .word solaris_unimplemented /* rmount 72 */ - .word solaris_unimplemented /* rumount 73 */ - .word solaris_unimplemented /* rfstart 74 */ - .word solaris_unimplemented /* ? 75 */ - .word solaris_unimplemented /* rdebug 76 */ - .word solaris_unimplemented /* rfstop 77 */ - .word solaris_unimplemented /* rfsys 78 */ - .word CHAIN(rmdir) /* rmdir s 79 */ - .word CHAIN(mkdir) /* mkdir so 80 */ - .word CHAIN(getdents) /* getdents dxd 81 */ - .word solaris_unimplemented /* libattach 82 */ - .word solaris_unimplemented /* libdetach 83 */ - .word CHAIN(sysfs) /* sysfs dxx 84 */ - .word solaris_getmsg /* getmsg dxxx 85 */ - .word solaris_putmsg /* putmsg dxxd 86 */ - .word CHAIN(poll) /* poll xdd 87 */ - .word solaris_lstat /* lstat sp 88 */ - .word CHAIN(symlink) /* symlink ss 89 */ - .word CHAIN(readlink) /* readlink spd 90 */ - .word CHAIN(setgroups) /* setgroups dp 91 */ - .word CHAIN(getgroups) /* getgroups dp 92 */ - .word CHAIN(fchmod) /* fchmod do 93 */ - .word CHAIN(fchown) /* fchown ddd 94 */ - .word solaris_sigprocmask /* sigprocmask dxx 95 */ - .word solaris_sigsuspend /* sigsuspend x 96 */ - .word solaris_sigaltstack /* sigaltstack xx 97 */ - .word solaris_sigaction /* sigaction dxx 98 */ - .word solaris_sigpending /* sigpending dd 99 */ - .word REGS(solaris_context) /* context 100 */ - .word solaris_unimplemented /* evsys 101 */ - .word solaris_unimplemented /* evtrapret 102 */ - .word solaris_statvfs /* statvfs sp 103 */ - .word solaris_fstatvfs /* fstatvfs dp 104 */ - .word solaris_unimplemented /* unknown 105 */ - .word solaris_unimplemented /* nfssys 106 */ - .word solaris_waitid /* waitid ddxd 107 */ - .word solaris_unimplemented /* sigsendsys ddd 108 */ - .word REGS(solaris_hrtsys) /* hrtsys xxx 109 */ - .word solaris_unimplemented /* acancel dxd 110 */ - .word solaris_unimplemented /* async 111 */ - .word solaris_unimplemented /* priocntlsys 112 */ - .word solaris_pathconf /* pathconf sd 113 */ - .word CHAIN(mincore) /* mincore d 114 */ - .word solaris_mmap /* mmap xxxxdx 115 */ - .word CHAIN(mprotect) /* mprotect xdx 116 */ - .word CHAIN(munmap) /* munmap xd 117 */ - .word solaris_fpathconf /* fpathconf dd 118 */ - .word CHAIN(fork) /* fork 119 */ - .word solaris_unimplemented /* fchdir d 120 */ - .word CHAIN(readv) /* readv dxd 121 */ - .word CHAIN(writev) /* writev dxd 122 */ - .word solaris_xstat /* xstat dsx 123 */ - .word solaris_lxstat /* lxstat dsx 124 */ - .word solaris_fxstat /* fxstat ddx 125 */ - .word solaris_xmknod /* xmknod dsox 126 */ - .word solaris_unimplemented /* syslocal d 127 */ - .word solaris_setrlimit /* setrlimit dp 128 */ - .word solaris_getrlimit /* getrlimit dp 129 */ - .word CHAIN(chown) /* lchown sdd 130 */ - .word solaris_unimplemented /* memcntl 131 */ - .word solaris_getpmsg /* getpmsg dxxxx 132 */ - .word solaris_putpmsg /* putpmsg dxxdd 133 */ - .word CHAIN(rename) /* rename ss 134 */ - .word solaris_utsname /* uname x 135 */ - .word solaris_unimplemented /* setegid 136 */ - .word solaris_sysconf /* sysconfig d 137 */ - .word solaris_unimplemented /* adjtime 138 */ - .word solaris_sysinfo /* systeminfo dsd 139 */ - .word solaris_unimplemented /* ? 140 */ - .word solaris_unimplemented /* seteuid 141 */ - .word solaris_unimplemented /* ? 142 */ - .word solaris_unimplemented /* ? 143 */ - .word solaris_unimplemented /* secsys dx 144 */ - .word solaris_unimplemented /* filepriv sdxd 145 */ - .word solaris_unimplemented /* procpriv dxd 146 */ - .word solaris_unimplemented /* devstat sdx 147 */ - .word solaris_unimplemented /* aclipc ddddx 148 */ - .word solaris_unimplemented /* fdevstat ddx 149 */ - .word solaris_unimplemented /* flvlfile ddx 150 */ - .word solaris_unimplemented /* lvlfile sdx 151 */ - .word solaris_unimplemented /* ? 152 */ - .word solaris_unimplemented /* fchroot d 153 */ - .word solaris_unimplemented /* lvlproc dx 154 */ - .word solaris_unimplemented /* ? 155 */ - .word solaris_gettimeofday /* gettimeofday x 156 */ - .word CHAIN(getitimer) /* getitimer dx 157 */ - .word CHAIN(setitimer) /* setitimer dxx 158 */ - .word solaris_unimplemented /* lwp-xxx 159 */ - .word solaris_unimplemented /* lwp-xxx 160 */ - .word solaris_unimplemented /* lwp-xxx 161 */ - .word solaris_unimplemented /* lwp-xxx 162 */ - .word solaris_unimplemented /* lwp-xxx 163 */ - .word solaris_unimplemented /* lwp-xxx 164 */ - .word solaris_unimplemented /* lwp-xxx 165 */ - .word solaris_unimplemented /* lwp-xxx 166 */ - .word solaris_unimplemented /* lwp-xxx 167 */ - .word solaris_unimplemented /* lwp-xxx 168 */ - .word solaris_unimplemented /* lwp-xxx 169 */ - .word solaris_unimplemented /* lwp-xxx 170 */ - .word solaris_unimplemented /* lwp-xxx 171 */ - .word solaris_unimplemented /* lwp-xxx 172 */ - .word solaris_pread /* pread dpdd 173 */ - .word solaris_pwrite /* pwrite dpdd 174 */ - .word REGS(solaris_llseek) /* llseek dLd 175 */ - .word solaris_unimplemented /* lwpself 176 */ - .word solaris_unimplemented /* lwpinfo 177 */ - .word solaris_unimplemented /* lwpprivate 178 */ - .word solaris_unimplemented /* processorbind 179 */ - .word solaris_unimplemented /* processorexbind 180 */ - .word solaris_unimplemented /* 181 */ - .word solaris_unimplemented /* sync_mailbox 182 */ - .word solaris_unimplemented /* prepblock 183 */ - .word solaris_unimplemented /* block 184 */ - .word solaris_acl /* acl sddp 185 */ - .word solaris_unimplemented /* unblock 186 */ - .word solaris_unimplemented /* cancelblock 187 */ - .word solaris_unimplemented /* ? 188 */ - .word solaris_unimplemented /* xxxxx 189 */ - .word solaris_unimplemented /* xxxxxe 190 */ - .word solaris_unimplemented /* 191 */ - .word solaris_unimplemented /* 192 */ - .word solaris_unimplemented /* 193 */ - .word solaris_unimplemented /* 194 */ - .word solaris_unimplemented /* 195 */ - .word solaris_unimplemented /* 196 */ - .word solaris_unimplemented /* 197 */ - .word solaris_unimplemented /* 198 */ - .word CHAIN(nanosleep) /* nanosleep dd 199 */ - .word solaris_facl /* facl dddp 200 */ - .word solaris_unimplemented /* 201 */ - .word CHAIN(setreuid) /* setreuid dd 202 */ - .word CHAIN(setregid) /* setregid dd 203 */ - .word solaris_unimplemented /* 204 */ - .word solaris_unimplemented /* 205 */ - .word solaris_unimplemented /* 206 */ - .word solaris_unimplemented /* 207 */ - .word solaris_unimplemented /* 208 */ - .word solaris_unimplemented /* 209 */ - .word solaris_unimplemented /* 210 */ - .word solaris_unimplemented /* 211 */ - .word solaris_unimplemented /* 212 */ - .word solaris_getdents64 /* getdents64 dpd 213 */ - .word REGS(solaris_mmap64) /* mmap64 xxxxdX 214 */ - .word solaris_stat64 /* stat64 sP 215 */ - .word solaris_lstat64 /* lstat64 sP 216 */ - .word solaris_fstat64 /* fstat64 dP 217 */ - .word solaris_statvfs64 /* statvfs64 sP 218 */ - .word solaris_fstatvfs64 /* fstatvfs64 dP 219 */ - .word solaris_setrlimit64 /* setrlimit64 dP 220 */ - .word solaris_getrlimit64 /* getrlimit64 dP 221 */ - .word CHAIN(pread64) /* pread64 dpdD 222 */ - .word CHAIN(pwrite64) /* pwrite64 dpdD 223 */ - .word CHAIN(creat) /* creat64 so 224 */ - .word solaris_open /* open64 soo 225 */ - .word solaris_unimplemented /* 226 */ - .word solaris_unimplemented /* 227 */ - .word solaris_unimplemented /* 228 */ - .word solaris_unimplemented /* 229 */ - .word solaris_socket /* socket ddd 230 */ - .word solaris_socketpair /* socketpair dddp 231 */ - .word solaris_bind /* bind dpd 232 */ - .word solaris_listen /* listen dd 233 */ - .word solaris_accept /* accept dpp 234 */ - .word solaris_connect /* connect dpd 235 */ - .word solaris_shutdown /* shutdown dd 236 */ - .word solaris_recv /* recv dpdd 237 */ - .word solaris_recvfrom /* recvfrom dpddpp 238 */ - .word solaris_recvmsg /* recvmsg dpd 239 */ - .word solaris_send /* send dpdd 240 */ - .word solaris_sendmsg /* sendmsg dpd 241 */ - .word solaris_sendto /* sendto dpddpd 242 */ - .word solaris_getpeername /* getpeername dpp 243 */ - .word solaris_getsockname /* getsockname dpp 244 */ - .word solaris_getsockopt /* getsockopt dddpp 245 */ - .word solaris_setsockopt /* setsockopt dddpp 246 */ - .word solaris_unimplemented /* 247 */ - .word solaris_ntp_gettime /* ntp_gettime p 248 */ - .word solaris_ntp_adjtime /* ntp_adjtime p 249 */ - .word solaris_unimplemented /* 250 */ - .word solaris_unimplemented /* 251 */ - .word solaris_unimplemented /* 252 */ - .word solaris_unimplemented /* 253 */ - .word solaris_unimplemented /* 254 */ - .word solaris_unimplemented /* 255 */ diff --git a/arch/sparc64/solaris/timod.c b/arch/sparc64/solaris/timod.c deleted file mode 100644 index 15234fcd191..00000000000 --- a/arch/sparc64/solaris/timod.c +++ /dev/null @@ -1,976 +0,0 @@ -/* $Id: timod.c,v 1.19 2002/02/08 03:57:14 davem Exp $ - * timod.c: timod emulation. - * - * Copyright (C) 1998 Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz) - * - * Streams & timod emulation based on code - * Copyright (C) 1995, 1996 Mike Jagdis (jaggy@purplet.demon.co.uk) - * - */ - -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/smp.h> -#include <linux/smp_lock.h> -#include <linux/ioctl.h> -#include <linux/fs.h> -#include <linux/file.h> -#include <linux/netdevice.h> -#include <linux/poll.h> - -#include <net/sock.h> - -#include <asm/uaccess.h> -#include <asm/termios.h> - -#include "conv.h" -#include "socksys.h" - -asmlinkage int solaris_ioctl(unsigned int fd, unsigned int cmd, u32 arg); - -static DEFINE_SPINLOCK(timod_pagelock); -static char * page = NULL ; - -#ifndef DEBUG_SOLARIS_KMALLOC - -#define mykmalloc kmalloc -#define mykfree kfree - -#else - -void * mykmalloc(size_t s, gfp_t gfp) -{ - static char * page; - static size_t free; - void * r; - s = ((s + 63) & ~63); - if( s > PAGE_SIZE ) { - SOLD("too big size, calling real kmalloc"); - return kmalloc(s, gfp); - } - if( s > free ) { - /* we are wasting memory, but we don't care */ - page = (char *)__get_free_page(gfp); - free = PAGE_SIZE; - } - r = page; - page += s; - free -= s; - return r; -} - -void mykfree(void *p) -{ -} - -#endif - -#ifndef DEBUG_SOLARIS - -#define BUF_SIZE PAGE_SIZE -#define PUT_MAGIC(a,m) -#define SCHECK_MAGIC(a,m) -#define BUF_OFFSET 0 -#define MKCTL_TRAILER 0 - -#else - -#define BUF_SIZE (PAGE_SIZE-2*sizeof(u64)) -#define BUFPAGE_MAGIC 0xBADC0DEDDEADBABEL -#define MKCTL_MAGIC 0xDEADBABEBADC0DEDL -#define PUT_MAGIC(a,m) do{(*(u64*)(a))=(m);}while(0) -#define SCHECK_MAGIC(a,m) do{if((*(u64*)(a))!=(m))printk("%s,%u,%s(): magic %08x at %p corrupted!\n",\ - __FILE__,__LINE__,__func__,(m),(a));}while(0) -#define BUF_OFFSET sizeof(u64) -#define MKCTL_TRAILER sizeof(u64) - -#endif - -static char *getpage( void ) -{ - char *r; - SOLD("getting page"); - spin_lock(&timod_pagelock); - if (page) { - r = page; - page = NULL; - spin_unlock(&timod_pagelock); - SOLD("got cached"); - return r + BUF_OFFSET; - } - spin_unlock(&timod_pagelock); - SOLD("getting new"); - r = (char *)__get_free_page(GFP_KERNEL); - PUT_MAGIC(r,BUFPAGE_MAGIC); - PUT_MAGIC(r+PAGE_SIZE-sizeof(u64),BUFPAGE_MAGIC); - return r + BUF_OFFSET; -} - -static void putpage(char *p) -{ - SOLD("putting page"); - p = p - BUF_OFFSET; - SCHECK_MAGIC(p,BUFPAGE_MAGIC); - SCHECK_MAGIC(p+PAGE_SIZE-sizeof(u64),BUFPAGE_MAGIC); - spin_lock(&timod_pagelock); - if (page) { - spin_unlock(&timod_pagelock); - free_page((unsigned long)p); - SOLD("freed it"); - } else { - page = p; - spin_unlock(&timod_pagelock); - SOLD("cached it"); - } -} - -static struct T_primsg *timod_mkctl(int size) -{ - struct T_primsg *it; - - SOLD("creating primsg"); - it = (struct T_primsg *)mykmalloc(size+sizeof(*it)-sizeof(s32)+2*MKCTL_TRAILER, GFP_KERNEL); - if (it) { - SOLD("got it"); - it->pri = MSG_HIPRI; - it->length = size; - PUT_MAGIC((char*)((u64)(((char *)&it->type)+size+7)&~7),MKCTL_MAGIC); - } - return it; -} - -static void timod_wake_socket(unsigned int fd) -{ - struct socket *sock; - struct fdtable *fdt; - - SOLD("wakeing socket"); - fdt = files_fdtable(current->files); - sock = SOCKET_I(fdt->fd[fd]->f_path.dentry->d_inode); - wake_up_interruptible(&sock->wait); - read_lock(&sock->sk->sk_callback_lock); - if (sock->fasync_list && !test_bit(SOCK_ASYNC_WAITDATA, &sock->flags)) - __kill_fasync(sock->fasync_list, SIGIO, POLL_IN); - read_unlock(&sock->sk->sk_callback_lock); - SOLD("done"); -} - -static void timod_queue(unsigned int fd, struct T_primsg *it) -{ - struct sol_socket_struct *sock; - struct fdtable *fdt; - - SOLD("queuing primsg"); - fdt = files_fdtable(current->files); - sock = (struct sol_socket_struct *)fdt->fd[fd]->private_data; - it->next = sock->pfirst; - sock->pfirst = it; - if (!sock->plast) - sock->plast = it; - timod_wake_socket(fd); - SOLD("done"); -} - -static void timod_queue_end(unsigned int fd, struct T_primsg *it) -{ - struct sol_socket_struct *sock; - struct fdtable *fdt; - - SOLD("queuing primsg at end"); - fdt = files_fdtable(current->files); - sock = (struct sol_socket_struct *)fdt->fd[fd]->private_data; - it->next = NULL; - if (sock->plast) - sock->plast->next = it; - else - sock->pfirst = it; - sock->plast = it; - SOLD("done"); -} - -static void timod_error(unsigned int fd, int prim, int terr, int uerr) -{ - struct T_primsg *it; - - SOLD("making error"); - it = timod_mkctl(sizeof(struct T_error_ack)); - if (it) { - struct T_error_ack *err = (struct T_error_ack *)&it->type; - - SOLD("got it"); - err->PRIM_type = T_ERROR_ACK; - err->ERROR_prim = prim; - err->TLI_error = terr; - err->UNIX_error = uerr; /* FIXME: convert this */ - timod_queue(fd, it); - } - SOLD("done"); -} - -static void timod_ok(unsigned int fd, int prim) -{ - struct T_primsg *it; - struct T_ok_ack *ok; - - SOLD("creating ok ack"); - it = timod_mkctl(sizeof(*ok)); - if (it) { - SOLD("got it"); - ok = (struct T_ok_ack *)&it->type; - ok->PRIM_type = T_OK_ACK; - ok->CORRECT_prim = prim; - timod_queue(fd, it); - } - SOLD("done"); -} - -static int timod_optmgmt(unsigned int fd, int flag, char __user *opt_buf, int opt_len, int do_ret) -{ - int error, failed; - int ret_space, ret_len; - long args[5]; - char *ret_pos,*ret_buf; - int (*sys_socketcall)(int, unsigned long *) = - (int (*)(int, unsigned long *))SYS(socketcall); - mm_segment_t old_fs = get_fs(); - - SOLD("entry"); - SOLDD(("fd %u flg %u buf %p len %u doret %u",fd,flag,opt_buf,opt_len,do_ret)); - if (!do_ret && (!opt_buf || opt_len <= 0)) - return 0; - SOLD("getting page"); - ret_pos = ret_buf = getpage(); - ret_space = BUF_SIZE; - ret_len = 0; - - error = failed = 0; - SOLD("looping"); - while(opt_len >= sizeof(struct opthdr)) { - struct opthdr *opt; - int orig_opt_len; - SOLD("loop start"); - opt = (struct opthdr *)ret_pos; - if (ret_space < sizeof(struct opthdr)) { - failed = TSYSERR; - break; - } - SOLD("getting opthdr"); - if (copy_from_user(opt, opt_buf, sizeof(struct opthdr)) || - opt->len > opt_len) { - failed = TBADOPT; - break; - } - SOLD("got opthdr"); - if (flag == T_NEGOTIATE) { - char *buf; - - SOLD("handling T_NEGOTIATE"); - buf = ret_pos + sizeof(struct opthdr); - if (ret_space < opt->len + sizeof(struct opthdr) || - copy_from_user(buf, opt_buf+sizeof(struct opthdr), opt->len)) { - failed = TSYSERR; - break; - } - SOLD("got optdata"); - args[0] = fd; - args[1] = opt->level; - args[2] = opt->name; - args[3] = (long)buf; - args[4] = opt->len; - SOLD("calling SETSOCKOPT"); - set_fs(KERNEL_DS); - error = sys_socketcall(SYS_SETSOCKOPT, args); - set_fs(old_fs); - if (error) { - failed = TBADOPT; - break; - } - SOLD("SETSOCKOPT ok"); - } - orig_opt_len = opt->len; - opt->len = ret_space - sizeof(struct opthdr); - if (opt->len < 0) { - failed = TSYSERR; - break; - } - args[0] = fd; - args[1] = opt->level; - args[2] = opt->name; - args[3] = (long)(ret_pos+sizeof(struct opthdr)); - args[4] = (long)&opt->len; - SOLD("calling GETSOCKOPT"); - set_fs(KERNEL_DS); - error = sys_socketcall(SYS_GETSOCKOPT, args); - set_fs(old_fs); - if (error) { - failed = TBADOPT; - break; - } - SOLD("GETSOCKOPT ok"); - ret_space -= sizeof(struct opthdr) + opt->len; - ret_len += sizeof(struct opthdr) + opt->len; - ret_pos += sizeof(struct opthdr) + opt->len; - opt_len -= sizeof(struct opthdr) + orig_opt_len; - opt_buf += sizeof(struct opthdr) + orig_opt_len; - SOLD("loop end"); - } - SOLD("loop done"); - if (do_ret) { - SOLD("generating ret msg"); - if (failed) - timod_error(fd, T_OPTMGMT_REQ, failed, -error); - else { - struct T_primsg *it; - it = timod_mkctl(sizeof(struct T_optmgmt_ack) + ret_len); - if (it) { - struct T_optmgmt_ack *ack = - (struct T_optmgmt_ack *)&it->type; - SOLD("got primsg"); - ack->PRIM_type = T_OPTMGMT_ACK; - ack->OPT_length = ret_len; - ack->OPT_offset = sizeof(struct T_optmgmt_ack); - ack->MGMT_flags = (failed ? T_FAILURE : flag); - memcpy(((char*)ack)+sizeof(struct T_optmgmt_ack), - ret_buf, ret_len); - timod_queue(fd, it); - } - } - } - SOLDD(("put_page %p\n", ret_buf)); - putpage(ret_buf); - SOLD("done"); - return 0; -} - -int timod_putmsg(unsigned int fd, char __user *ctl_buf, int ctl_len, - char __user *data_buf, int data_len, int flags) -{ - int ret, error, terror; - char *buf; - struct file *filp; - struct inode *ino; - struct fdtable *fdt; - struct sol_socket_struct *sock; - mm_segment_t old_fs = get_fs(); - long args[6]; - int (*sys_socketcall)(int, unsigned long __user *) = - (int (*)(int, unsigned long __user *))SYS(socketcall); - int (*sys_sendto)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int) = - (int (*)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int))SYS(sendto); - - fdt = files_fdtable(current->files); - filp = fdt->fd[fd]; - ino = filp->f_path.dentry->d_inode; - sock = (struct sol_socket_struct *)filp->private_data; - SOLD("entry"); - if (get_user(ret, (int __user *)A(ctl_buf))) - return -EFAULT; - switch (ret) { - case T_BIND_REQ: - { - struct T_bind_req req; - - SOLDD(("bind %016lx(%016lx)\n", sock, filp)); - SOLD("T_BIND_REQ"); - if (sock->state != TS_UNBND) { - timod_error(fd, T_BIND_REQ, TOUTSTATE, 0); - return 0; - } - SOLD("state ok"); - if (copy_from_user(&req, ctl_buf, sizeof(req))) { - timod_error(fd, T_BIND_REQ, TSYSERR, EFAULT); - return 0; - } - SOLD("got ctl req"); - if (req.ADDR_offset && req.ADDR_length) { - if (req.ADDR_length > BUF_SIZE) { - timod_error(fd, T_BIND_REQ, TSYSERR, EFAULT); - return 0; - } - SOLD("req size ok"); - buf = getpage(); - if (copy_from_user(buf, ctl_buf + req.ADDR_offset, req.ADDR_length)) { - timod_error(fd, T_BIND_REQ, TSYSERR, EFAULT); - putpage(buf); - return 0; - } - SOLD("got ctl data"); - args[0] = fd; - args[1] = (long)buf; - args[2] = req.ADDR_length; - SOLD("calling BIND"); - set_fs(KERNEL_DS); - error = sys_socketcall(SYS_BIND, args); - set_fs(old_fs); - putpage(buf); - SOLD("BIND returned"); - } else - error = 0; - if (!error) { - struct T_primsg *it; - if (req.CONIND_number) { - args[0] = fd; - args[1] = req.CONIND_number; - SOLD("calling LISTEN"); - set_fs(KERNEL_DS); - error = sys_socketcall(SYS_LISTEN, args); - set_fs(old_fs); - SOLD("LISTEN done"); - } - it = timod_mkctl(sizeof(struct T_bind_ack)+sizeof(struct sockaddr)); - if (it) { - struct T_bind_ack *ack; - - ack = (struct T_bind_ack *)&it->type; - ack->PRIM_type = T_BIND_ACK; - ack->ADDR_offset = sizeof(*ack); - ack->ADDR_length = sizeof(struct sockaddr); - ack->CONIND_number = req.CONIND_number; - args[0] = fd; - args[1] = (long)(ack+sizeof(*ack)); - args[2] = (long)&ack->ADDR_length; - set_fs(KERNEL_DS); - sys_socketcall(SYS_GETSOCKNAME,args); - set_fs(old_fs); - sock->state = TS_IDLE; - timod_ok(fd, T_BIND_REQ); - timod_queue_end(fd, it); - SOLD("BIND done"); - return 0; - } - } - SOLD("some error"); - switch (error) { - case -EINVAL: - terror = TOUTSTATE; - error = 0; - break; - case -EACCES: - terror = TACCES; - error = 0; - break; - case -EADDRNOTAVAIL: - case -EADDRINUSE: - terror = TNOADDR; - error = 0; - break; - default: - terror = TSYSERR; - break; - } - timod_error(fd, T_BIND_REQ, terror, -error); - SOLD("BIND done"); - return 0; - } - case T_CONN_REQ: - { - struct T_conn_req req; - unsigned short oldflags; - struct T_primsg *it; - SOLD("T_CONN_REQ"); - if (sock->state != TS_UNBND && sock->state != TS_IDLE) { - timod_error(fd, T_CONN_REQ, TOUTSTATE, 0); - return 0; - } - SOLD("state ok"); - if (copy_from_user(&req, ctl_buf, sizeof(req))) { - timod_error(fd, T_CONN_REQ, TSYSERR, EFAULT); - return 0; - } - SOLD("got ctl req"); - if (ctl_len > BUF_SIZE) { - timod_error(fd, T_CONN_REQ, TSYSERR, EFAULT); - return 0; - } - SOLD("req size ok"); - buf = getpage(); - if (copy_from_user(buf, ctl_buf, ctl_len)) { - timod_error(fd, T_CONN_REQ, TSYSERR, EFAULT); - putpage(buf); - return 0; - } -#ifdef DEBUG_SOLARIS - { - char * ptr = buf; - int len = ctl_len; - printk("returned data (%d bytes): ",len); - while( len-- ) { - if (!(len & 7)) - printk(" "); - printk("%02x",(unsigned char)*ptr++); - } - printk("\n"); - } -#endif - SOLD("got ctl data"); - args[0] = fd; - args[1] = (long)buf+req.DEST_offset; - args[2] = req.DEST_length; - oldflags = filp->f_flags; - filp->f_flags &= ~O_NONBLOCK; - SOLD("calling CONNECT"); - set_fs(KERNEL_DS); - error = sys_socketcall(SYS_CONNECT, args); - set_fs(old_fs); - filp->f_flags = oldflags; - SOLD("CONNECT done"); - if (!error) { - struct T_conn_con *con; - SOLD("no error"); - it = timod_mkctl(ctl_len); - if (!it) { - putpage(buf); - return -ENOMEM; - } - con = (struct T_conn_con *)&it->type; -#ifdef DEBUG_SOLARIS - { - char * ptr = buf; - int len = ctl_len; - printk("returned data (%d bytes): ",len); - while( len-- ) { - if (!(len & 7)) - printk(" "); - printk("%02x",(unsigned char)*ptr++); - } - printk("\n"); - } -#endif - memcpy(con, buf, ctl_len); - SOLD("copied ctl_buf"); - con->PRIM_type = T_CONN_CON; - sock->state = TS_DATA_XFER; - } else { - struct T_discon_ind *dis; - SOLD("some error"); - it = timod_mkctl(sizeof(*dis)); - if (!it) { - putpage(buf); - return -ENOMEM; - } - SOLD("got primsg"); - dis = (struct T_discon_ind *)&it->type; - dis->PRIM_type = T_DISCON_IND; - dis->DISCON_reason = -error; /* FIXME: convert this as in iABI_errors() */ - dis->SEQ_number = 0; - } - putpage(buf); - timod_ok(fd, T_CONN_REQ); - it->pri = 0; - timod_queue_end(fd, it); - SOLD("CONNECT done"); - return 0; - } - case T_OPTMGMT_REQ: - { - struct T_optmgmt_req req; - SOLD("OPTMGMT_REQ"); - if (copy_from_user(&req, ctl_buf, sizeof(req))) - return -EFAULT; - SOLD("got req"); - return timod_optmgmt(fd, req.MGMT_flags, - req.OPT_offset > 0 ? ctl_buf + req.OPT_offset : NULL, - req.OPT_length, 1); - } - case T_UNITDATA_REQ: - { - struct T_unitdata_req req; - - int err; - SOLD("T_UNITDATA_REQ"); - if (sock->state != TS_IDLE && sock->state != TS_DATA_XFER) { - timod_error(fd, T_CONN_REQ, TOUTSTATE, 0); - return 0; - } - SOLD("state ok"); - if (copy_from_user(&req, ctl_buf, sizeof(req))) { - timod_error(fd, T_CONN_REQ, TSYSERR, EFAULT); - return 0; - } - SOLD("got ctl req"); -#ifdef DEBUG_SOLARIS - { - char * ptr = ctl_buf+req.DEST_offset; - int len = req.DEST_length; - printk("socket address (%d bytes): ",len); - while( len-- ) { - char c; - if (get_user(c,ptr)) - printk("??"); - else - printk("%02x",(unsigned char)c); - ptr++; - } - printk("\n"); - } -#endif - err = sys_sendto(fd, data_buf, data_len, 0, req.DEST_length > 0 ? (struct sockaddr __user *)(ctl_buf+req.DEST_offset) : NULL, req.DEST_length); - if (err == data_len) - return 0; - if(err >= 0) { - printk("timod: sendto failed to send all the data\n"); - return 0; - } - timod_error(fd, T_CONN_REQ, TSYSERR, -err); - return 0; - } - default: - printk(KERN_INFO "timod_putmsg: unsupported command %u.\n", ret); - break; - } - return -EINVAL; -} - -int timod_getmsg(unsigned int fd, char __user *ctl_buf, int ctl_maxlen, s32 __user *ctl_len, - char __user *data_buf, int data_maxlen, s32 __user *data_len, int *flags_p) -{ - int error; - int oldflags; - struct file *filp; - struct inode *ino; - struct fdtable *fdt; - struct sol_socket_struct *sock; - struct T_unitdata_ind udi; - mm_segment_t old_fs = get_fs(); - long args[6]; - char __user *tmpbuf; - int tmplen; - int (*sys_socketcall)(int, unsigned long __user *) = - (int (*)(int, unsigned long __user *))SYS(socketcall); - int (*sys_recvfrom)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int __user *); - - SOLD("entry"); - SOLDD(("%u %p %d %p %p %d %p %d\n", fd, ctl_buf, ctl_maxlen, ctl_len, data_buf, data_maxlen, data_len, *flags_p)); - fdt = files_fdtable(current->files); - filp = fdt->fd[fd]; - ino = filp->f_path.dentry->d_inode; - sock = (struct sol_socket_struct *)filp->private_data; - SOLDD(("%p %p\n", sock->pfirst, sock->pfirst ? sock->pfirst->next : NULL)); - if ( ctl_maxlen > 0 && !sock->pfirst && SOCKET_I(ino)->type == SOCK_STREAM - && sock->state == TS_IDLE) { - SOLD("calling LISTEN"); - args[0] = fd; - args[1] = -1; - set_fs(KERNEL_DS); - sys_socketcall(SYS_LISTEN, args); - set_fs(old_fs); - SOLD("LISTEN done"); - } - if (!(filp->f_flags & O_NONBLOCK)) { - struct poll_wqueues wait_table; - poll_table *wait; - - poll_initwait(&wait_table); - wait = &wait_table.pt; - for(;;) { - SOLD("loop"); - set_current_state(TASK_INTERRUPTIBLE); - /* ! ( l<0 || ( l>=0 && ( ! pfirst || (flags == HIPRI && pri != HIPRI) ) ) ) */ - /* ( ! l<0 && ! ( l>=0 && ( ! pfirst || (flags == HIPRI && pri != HIPRI) ) ) ) */ - /* ( l>=0 && ( ! l>=0 || ! ( ! pfirst || (flags == HIPRI && pri != HIPRI) ) ) ) */ - /* ( l>=0 && ( l<0 || ( pfirst && ! (flags == HIPRI && pri != HIPRI) ) ) ) */ - /* ( l>=0 && ( l<0 || ( pfirst && (flags != HIPRI || pri == HIPRI) ) ) ) */ - /* ( l>=0 && ( pfirst && (flags != HIPRI || pri == HIPRI) ) ) */ - if (ctl_maxlen >= 0 && sock->pfirst && (*flags_p != MSG_HIPRI || sock->pfirst->pri == MSG_HIPRI)) - break; - SOLD("cond 1 passed"); - if ( - #if 1 - *flags_p != MSG_HIPRI && - #endif - ((filp->f_op->poll(filp, wait) & POLLIN) || - (filp->f_op->poll(filp, NULL) & POLLIN) || - signal_pending(current)) - ) { - break; - } - if( *flags_p == MSG_HIPRI ) { - SOLD("avoiding lockup"); - break ; - } - if(wait_table.error) { - SOLD("wait-table error"); - poll_freewait(&wait_table); - return wait_table.error; - } - SOLD("scheduling"); - schedule(); - } - SOLD("loop done"); - current->state = TASK_RUNNING; - poll_freewait(&wait_table); - if (signal_pending(current)) { - SOLD("signal pending"); - return -EINTR; - } - } - if (ctl_maxlen >= 0 && sock->pfirst) { - struct T_primsg *it = sock->pfirst; - int l = min_t(int, ctl_maxlen, it->length); - SCHECK_MAGIC((char*)((u64)(((char *)&it->type)+sock->offset+it->length+7)&~7),MKCTL_MAGIC); - SOLD("purting ctl data"); - if(copy_to_user(ctl_buf, - (char*)&it->type + sock->offset, l)) - return -EFAULT; - SOLD("pur it"); - if(put_user(l, ctl_len)) - return -EFAULT; - SOLD("set ctl_len"); - *flags_p = it->pri; - it->length -= l; - if (it->length) { - SOLD("more ctl"); - sock->offset += l; - return MORECTL; - } else { - SOLD("removing message"); - sock->pfirst = it->next; - if (!sock->pfirst) - sock->plast = NULL; - SOLDD(("getmsg kfree %016lx->%016lx\n", it, sock->pfirst)); - mykfree(it); - sock->offset = 0; - SOLD("ctl done"); - return 0; - } - } - *flags_p = 0; - if (ctl_maxlen >= 0) { - SOLD("ACCEPT perhaps?"); - if (SOCKET_I(ino)->type == SOCK_STREAM && sock->state == TS_IDLE) { - struct T_conn_ind ind; - char *buf = getpage(); - int len = BUF_SIZE; - - SOLD("trying ACCEPT"); - if (put_user(ctl_maxlen - sizeof(ind), ctl_len)) - return -EFAULT; - args[0] = fd; - args[1] = (long)buf; - args[2] = (long)&len; - oldflags = filp->f_flags; - filp->f_flags |= O_NONBLOCK; - SOLD("calling ACCEPT"); - set_fs(KERNEL_DS); - error = sys_socketcall(SYS_ACCEPT, args); - set_fs(old_fs); - filp->f_flags = oldflags; - if (error < 0) { - SOLD("some error"); - putpage(buf); - return error; - } - if (error) { - SOLD("connect"); - putpage(buf); - if (sizeof(ind) > ctl_maxlen) { - SOLD("generating CONN_IND"); - ind.PRIM_type = T_CONN_IND; - ind.SRC_length = len; - ind.SRC_offset = sizeof(ind); - ind.OPT_length = ind.OPT_offset = 0; - ind.SEQ_number = error; - if(copy_to_user(ctl_buf, &ind, sizeof(ind))|| - put_user(sizeof(ind)+ind.SRC_length,ctl_len)) - return -EFAULT; - SOLD("CONN_IND created"); - } - if (data_maxlen >= 0) - put_user(0, data_len); - SOLD("CONN_IND done"); - return 0; - } - if (len>ctl_maxlen) { - SOLD("data don't fit"); - putpage(buf); - return -EFAULT; /* XXX - is this ok ? */ - } - if(copy_to_user(ctl_buf,buf,len) || put_user(len,ctl_len)){ - SOLD("can't copy data"); - putpage(buf); - return -EFAULT; - } - SOLD("ACCEPT done"); - putpage(buf); - } - } - SOLD("checking data req"); - if (data_maxlen <= 0) { - if (data_maxlen == 0) - put_user(0, data_len); - if (ctl_maxlen >= 0) - put_user(0, ctl_len); - return -EAGAIN; - } - SOLD("wants data"); - if (ctl_maxlen > sizeof(udi) && sock->state == TS_IDLE) { - SOLD("udi fits"); - tmpbuf = ctl_buf + sizeof(udi); - tmplen = ctl_maxlen - sizeof(udi); - } else { - SOLD("udi does not fit"); - tmpbuf = NULL; - tmplen = 0; - } - if (put_user(tmplen, ctl_len)) - return -EFAULT; - SOLD("set ctl_len"); - oldflags = filp->f_flags; - filp->f_flags |= O_NONBLOCK; - SOLD("calling recvfrom"); - sys_recvfrom = (int (*)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int __user *))SYS(recvfrom); - error = sys_recvfrom(fd, data_buf, data_maxlen, 0, (struct sockaddr __user *)tmpbuf, ctl_len); - filp->f_flags = oldflags; - if (error < 0) - return error; - SOLD("error >= 0" ) ; - if (error && ctl_maxlen > sizeof(udi) && sock->state == TS_IDLE) { - SOLD("generating udi"); - udi.PRIM_type = T_UNITDATA_IND; - if (get_user(udi.SRC_length, ctl_len)) - return -EFAULT; - udi.SRC_offset = sizeof(udi); - udi.OPT_length = udi.OPT_offset = 0; - if (copy_to_user(ctl_buf, &udi, sizeof(udi)) || - put_user(sizeof(udi)+udi.SRC_length, ctl_len)) - return -EFAULT; - SOLD("udi done"); - } else { - if (put_user(0, ctl_len)) - return -EFAULT; - } - put_user(error, data_len); - SOLD("done"); - return 0; -} - -asmlinkage int solaris_getmsg(unsigned int fd, u32 arg1, u32 arg2, u32 arg3) -{ - struct file *filp; - struct inode *ino; - struct strbuf __user *ctlptr; - struct strbuf __user *datptr; - struct strbuf ctl, dat; - int __user *flgptr; - int flags; - int error = -EBADF; - struct fdtable *fdt; - - SOLD("entry"); - lock_kernel(); - if (fd >= sysctl_nr_open) - goto out; - - fdt = files_fdtable(current->files); - filp = fdt->fd[fd]; - if(!filp) goto out; - - ino = filp->f_path.dentry->d_inode; - if (!ino || !S_ISSOCK(ino->i_mode)) - goto out; - - ctlptr = (struct strbuf __user *)A(arg1); - datptr = (struct strbuf __user *)A(arg2); - flgptr = (int __user *)A(arg3); - - error = -EFAULT; - - if (ctlptr) { - if (copy_from_user(&ctl,ctlptr,sizeof(struct strbuf)) || - put_user(-1,&ctlptr->len)) - goto out; - } else - ctl.maxlen = -1; - - if (datptr) { - if (copy_from_user(&dat,datptr,sizeof(struct strbuf)) || - put_user(-1,&datptr->len)) - goto out; - } else - dat.maxlen = -1; - - if (get_user(flags,flgptr)) - goto out; - - switch (flags) { - case 0: - case MSG_HIPRI: - case MSG_ANY: - case MSG_BAND: - break; - default: - error = -EINVAL; - goto out; - } - - error = timod_getmsg(fd,A(ctl.buf),ctl.maxlen,&ctlptr->len, - A(dat.buf),dat.maxlen,&datptr->len,&flags); - - if (!error && put_user(flags,flgptr)) - error = -EFAULT; -out: - unlock_kernel(); - SOLD("done"); - return error; -} - -asmlinkage int solaris_putmsg(unsigned int fd, u32 arg1, u32 arg2, u32 arg3) -{ - struct file *filp; - struct inode *ino; - struct strbuf __user *ctlptr; - struct strbuf __user *datptr; - struct strbuf ctl, dat; - int flags = (int) arg3; - int error = -EBADF; - struct fdtable *fdt; - - SOLD("entry"); - lock_kernel(); - if (fd >= sysctl_nr_open) - goto out; - - fdt = files_fdtable(current->files); - filp = fdt->fd[fd]; - if(!filp) goto out; - - ino = filp->f_path.dentry->d_inode; - if (!ino) goto out; - - if (!S_ISSOCK(ino->i_mode) && - (imajor(ino) != 30 || iminor(ino) != 1)) - goto out; - - ctlptr = A(arg1); - datptr = A(arg2); - - error = -EFAULT; - - if (ctlptr) { - if (copy_from_user(&ctl,ctlptr,sizeof(ctl))) - goto out; - if (ctl.len < 0 && flags) { - error = -EINVAL; - goto out; - } - } else { - ctl.len = 0; - ctl.buf = 0; - } - - if (datptr) { - if (copy_from_user(&dat,datptr,sizeof(dat))) - goto out; - } else { - dat.len = 0; - dat.buf = 0; - } - - error = timod_putmsg(fd,A(ctl.buf),ctl.len, - A(dat.buf),dat.len,flags); -out: - unlock_kernel(); - SOLD("done"); - return error; -} |