Messages in this thread Patch in this message | | | From | Martin Schwidefsky <> | Subject | [PATCH] s390 (12/16): s390/s390x unification - part 3. | Date | Mon, 14 Apr 2003 19:53:11 +0200 |
| |
Merge s390x and s390 to one architecture.
diffstat: compat_signal.c | 644 +++++++++++++++++++++++++++++ compat_wrapper.S | 1211 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ cpcmd.c | 47 +- debug.c | 14 entry.S | 269 ------------ entry64.S | 710 ++++++++++++++++++++++++++++++++ 6 files changed, 2613 insertions(+), 282 deletions(-)
diff -urN linux-2.5.67/arch/s390/kernel/compat_signal.c linux-2.5.67-s390/arch/s390/kernel/compat_signal.c --- linux-2.5.67/arch/s390/kernel/compat_signal.c Thu Jan 1 01:00:00 1970 +++ linux-2.5.67-s390/arch/s390/kernel/compat_signal.c Mon Apr 14 19:11:56 2003 @@ -0,0 +1,644 @@ +/* + * arch/s390/kernel/signal32.c + * + * S390 version + * Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation + * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) + * Gerhard Tonn (ton@de.ibm.com) + * + * Copyright (C) 1991, 1992 Linus Torvalds + * + * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson + */ + +#include <linux/config.h> +#include <linux/compat.h> +#include <linux/sched.h> +#include <linux/mm.h> +#include <linux/smp.h> +#include <linux/smp_lock.h> +#include <linux/kernel.h> +#include <linux/signal.h> +#include <linux/errno.h> +#include <linux/wait.h> +#include <linux/ptrace.h> +#include <linux/unistd.h> +#include <linux/stddef.h> +#include <linux/tty.h> +#include <linux/personality.h> +#include <linux/binfmts.h> +#include <asm/ucontext.h> +#include <asm/uaccess.h> +#include <asm/lowcore.h> +#include "compat_linux.h" +#include "compat_ptrace.h" + +#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) + +typedef struct +{ + __u8 callee_used_stack[__SIGNAL_FRAMESIZE32]; + struct sigcontext32 sc; + _sigregs32 sregs; + __u8 retcode[S390_SYSCALL_SIZE]; +} sigframe32; + +typedef struct +{ + __u8 callee_used_stack[__SIGNAL_FRAMESIZE32]; + __u8 retcode[S390_SYSCALL_SIZE]; + struct siginfo32 info; + struct ucontext32 uc; +} rt_sigframe32; + +asmlinkage int FASTCALL(do_signal(struct pt_regs *regs, sigset_t *oldset)); + +int do_signal32(struct pt_regs *regs, sigset_t *oldset); + +int copy_siginfo_to_user32(siginfo_t32 *to, siginfo_t *from) +{ + int err; + + if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t32))) + return -EFAULT; + + /* If you change siginfo_t structure, please be sure + this code is fixed accordingly. + It should never copy any pad contained in the structure + to avoid security leaks, but must copy the generic + 3 ints plus the relevant union member. + This routine must convert siginfo from 64bit to 32bit as well + at the same time. */ + err = __put_user(from->si_signo, &to->si_signo); + err |= __put_user(from->si_errno, &to->si_errno); + err |= __put_user((short)from->si_code, &to->si_code); + if (from->si_code < 0) + err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); + else { + switch (from->si_code >> 16) { + case __SI_KILL >> 16: + err |= __put_user(from->si_pid, &to->si_pid); + err |= __put_user(from->si_uid, &to->si_uid); + break; + case __SI_CHLD >> 16: + err |= __put_user(from->si_pid, &to->si_pid); + err |= __put_user(from->si_uid, &to->si_uid); + err |= __put_user(from->si_utime, &to->si_utime); + err |= __put_user(from->si_stime, &to->si_stime); + err |= __put_user(from->si_status, &to->si_status); + break; + case __SI_FAULT >> 16: + err |= __put_user((unsigned long) from->si_addr, + &to->si_addr); + break; + case __SI_POLL >> 16: + case __SI_TIMER >> 16: + err |= __put_user(from->si_band, &to->si_band); + err |= __put_user(from->si_fd, &to->si_fd); + break; + default: + break; + /* case __SI_RT: This is not generated by the kernel as of now. */ + } + } + return err; +} + +/* + * Atomically swap in the new signal mask, and wait for a signal. + */ +asmlinkage int +sys32_sigsuspend(struct pt_regs * regs,int history0, int history1, old_sigset_t mask) +{ + sigset_t saveset; + + mask &= _BLOCKABLE; + spin_lock_irq(¤t->sighand->siglock); + saveset = current->blocked; + siginitset(¤t->blocked, mask); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + regs->gprs[2] = -EINTR; + + while (1) { + set_current_state(TASK_INTERRUPTIBLE); + schedule(); + if (do_signal32(regs, &saveset)) + return -EINTR; + } +} + +asmlinkage int +sys32_rt_sigsuspend(struct pt_regs * regs,compat_sigset_t *unewset, size_t sigsetsize) +{ + sigset_t saveset, newset; + compat_sigset_t set32; + + /* XXX: Don't preclude handling different sized sigset_t's. */ + if (sigsetsize != sizeof(sigset_t)) + return -EINVAL; + + if (copy_from_user(&set32, unewset, sizeof(set32))) + return -EFAULT; + switch (_NSIG_WORDS) { + case 4: newset.sig[3] = set32.sig[6] + (((long)set32.sig[7]) << 32); + case 3: newset.sig[2] = set32.sig[4] + (((long)set32.sig[5]) << 32); + case 2: newset.sig[1] = set32.sig[2] + (((long)set32.sig[3]) << 32); + case 1: newset.sig[0] = set32.sig[0] + (((long)set32.sig[1]) << 32); + } + sigdelsetmask(&newset, ~_BLOCKABLE); + + spin_lock_irq(¤t->sighand->siglock); + saveset = current->blocked; + current->blocked = newset; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + regs->gprs[2] = -EINTR; + + while (1) { + set_current_state(TASK_INTERRUPTIBLE); + schedule(); + if (do_signal32(regs, &saveset)) + return -EINTR; + } +} + +asmlinkage int +sys32_sigaction(int sig, const struct old_sigaction32 *act, + struct old_sigaction32 *oact) +{ + struct k_sigaction new_ka, old_ka; + int ret; + + if (act) { + compat_old_sigset_t mask; + if (verify_area(VERIFY_READ, act, sizeof(*act)) || + __get_user((unsigned long)new_ka.sa.sa_handler, &act->sa_handler) || + __get_user((unsigned long)new_ka.sa.sa_restorer, &act->sa_restorer)) + return -EFAULT; + __get_user(new_ka.sa.sa_flags, &act->sa_flags); + __get_user(mask, &act->sa_mask); + siginitset(&new_ka.sa.sa_mask, mask); + } + + ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); + + if (!ret && oact) { + if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) || + __put_user((unsigned long)old_ka.sa.sa_handler, &oact->sa_handler) || + __put_user((unsigned long)old_ka.sa.sa_restorer, &oact->sa_restorer)) + return -EFAULT; + __put_user(old_ka.sa.sa_flags, &oact->sa_flags); + __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); + } + + return ret; +} + +int +do_sigaction(int sig, const struct k_sigaction *act, struct k_sigaction *oact); + +asmlinkage long +sys32_rt_sigaction(int sig, const struct sigaction32 *act, + struct sigaction32 *oact, size_t sigsetsize) +{ + struct k_sigaction new_ka, old_ka; + int ret; + compat_sigset_t set32; + + /* XXX: Don't preclude handling different sized sigset_t's. */ + if (sigsetsize != sizeof(compat_sigset_t)) + return -EINVAL; + + if (act) { + ret = get_user((unsigned long)new_ka.sa.sa_handler, &act->sa_handler); + ret |= __copy_from_user(&set32, &act->sa_mask, + sizeof(compat_sigset_t)); + switch (_NSIG_WORDS) { + case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6] + | (((long)set32.sig[7]) << 32); + case 3: new_ka.sa.sa_mask.sig[2] = set32.sig[4] + | (((long)set32.sig[5]) << 32); + case 2: new_ka.sa.sa_mask.sig[1] = set32.sig[2] + | (((long)set32.sig[3]) << 32); + case 1: new_ka.sa.sa_mask.sig[0] = set32.sig[0] + | (((long)set32.sig[1]) << 32); + } + ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags); + + if (ret) + return -EFAULT; + } + + ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); + + if (!ret && oact) { + switch (_NSIG_WORDS) { + case 4: + set32.sig[7] = (old_ka.sa.sa_mask.sig[3] >> 32); + set32.sig[6] = old_ka.sa.sa_mask.sig[3]; + case 3: + set32.sig[5] = (old_ka.sa.sa_mask.sig[2] >> 32); + set32.sig[4] = old_ka.sa.sa_mask.sig[2]; + case 2: + set32.sig[3] = (old_ka.sa.sa_mask.sig[1] >> 32); + set32.sig[2] = old_ka.sa.sa_mask.sig[1]; + case 1: + set32.sig[1] = (old_ka.sa.sa_mask.sig[0] >> 32); + set32.sig[0] = old_ka.sa.sa_mask.sig[0]; + } + ret = put_user((unsigned long)old_ka.sa.sa_handler, &oact->sa_handler); + ret |= __copy_to_user(&oact->sa_mask, &set32, + sizeof(compat_sigset_t)); + ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags); + } + + return ret; +} + +asmlinkage int +sys32_sigaltstack(const stack_t32 *uss, stack_t32 *uoss, struct pt_regs *regs) +{ + stack_t kss, koss; + int ret, err = 0; + mm_segment_t old_fs = get_fs(); + + if (uss) { + if (!access_ok(VERIFY_READ, uss, sizeof(*uss))) + return -EFAULT; + err |= __get_user((unsigned long) kss.ss_sp, &uss->ss_sp); + err |= __get_user(kss.ss_size, &uss->ss_size); + err |= __get_user(kss.ss_flags, &uss->ss_flags); + if (err) + return -EFAULT; + } + + set_fs (KERNEL_DS); + ret = do_sigaltstack(uss ? &kss : NULL , uoss ? &koss : NULL, regs->gprs[15]); + set_fs (old_fs); + + if (!ret && uoss) { + if (!access_ok(VERIFY_WRITE, uoss, sizeof(*uoss))) + return -EFAULT; + err |= __put_user((unsigned long) koss.ss_sp, &uoss->ss_sp); + err |= __put_user(koss.ss_size, &uoss->ss_size); + err |= __put_user(koss.ss_flags, &uoss->ss_flags); + if (err) + return -EFAULT; + } + return ret; +} + +static int save_sigregs32(struct pt_regs *regs,_sigregs32 *sregs) +{ + _s390_regs_common32 regs32; + int err, i; + + regs32.psw.mask = PSW32_USER_BITS | + ((__u32)(regs->psw.mask >> 32) & PSW32_MASK_CC); + regs32.psw.addr = PSW32_ADDR_AMODE31 | (__u32) regs->psw.addr; + for (i = 0; i < NUM_GPRS; i++) + regs32.gprs[i] = (__u32) regs->gprs[i]; + memcpy(regs32.acrs, regs->acrs, sizeof(regs32.acrs)); + err = __copy_to_user(&sregs->regs, ®s32, sizeof(regs32)); + if (err) + return err; + save_fp_regs(¤t->thread.fp_regs); + /* s390_fp_regs and _s390_fp_regs32 are the same ! */ + return __copy_to_user(&sregs->fpregs, ¤t->thread.fp_regs, + sizeof(_s390_fp_regs32)); +} + +static int restore_sigregs32(struct pt_regs *regs,_sigregs32 *sregs) +{ + _s390_regs_common32 regs32; + int err, i; + + err = __copy_from_user(®s32, &sregs->regs, sizeof(regs32)); + if (err) + return err; + regs->psw.mask = PSW_USER32_BITS | + (__u64)(regs32.psw.mask & PSW32_MASK_CC) << 32; + regs->psw.addr = (__u64)(regs32.psw.addr & PSW32_ADDR_INSN); + for (i = 0; i < NUM_GPRS; i++) + regs->gprs[i] = (__u64) regs32.gprs[i]; + memcpy(regs->acrs, regs32.acrs, sizeof(regs32.acrs)); + + err = __copy_from_user(¤t->thread.fp_regs, &sregs->fpregs, + sizeof(_s390_fp_regs32)); + current->thread.fp_regs.fpc &= FPC_VALID_MASK; + if (err) + return err; + + restore_fp_regs(¤t->thread.fp_regs); + regs->trap = -1; /* disable syscall checks */ + return 0; +} + +asmlinkage long sys32_sigreturn(struct pt_regs *regs) +{ + sigframe32 *frame = (sigframe32 *)regs->gprs[15]; + sigset_t set; + + if (verify_area(VERIFY_READ, frame, sizeof(*frame))) + goto badframe; + if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE32)) + goto badframe; + + sigdelsetmask(&set, ~_BLOCKABLE); + spin_lock_irq(¤t->sighand->siglock); + current->blocked = set; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + + if (restore_sigregs32(regs, &frame->sregs)) + goto badframe; + + return regs->gprs[2]; + +badframe: + force_sig(SIGSEGV, current); + return 0; +} + +asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs) +{ + rt_sigframe32 *frame = (rt_sigframe32 *)regs->gprs[15]; + sigset_t set; + stack_t st; + __u32 ss_sp; + int err; + mm_segment_t old_fs = get_fs(); + + if (verify_area(VERIFY_READ, frame, sizeof(*frame))) + goto badframe; + if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) + goto badframe; + + sigdelsetmask(&set, ~_BLOCKABLE); + spin_lock_irq(¤t->sighand->siglock); + current->blocked = set; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + + if (restore_sigregs32(regs, &frame->uc.uc_mcontext)) + goto badframe; + + err = __get_user(ss_sp, &frame->uc.uc_stack.ss_sp); + st.ss_sp = (void *) A((unsigned long)ss_sp); + err |= __get_user(st.ss_size, &frame->uc.uc_stack.ss_size); + err |= __get_user(st.ss_flags, &frame->uc.uc_stack.ss_flags); + if (err) + goto badframe; + + /* It is more difficult to avoid calling this function than to + call it and ignore errors. */ + set_fs (KERNEL_DS); + do_sigaltstack(&st, NULL, regs->gprs[15]); + set_fs (old_fs); + + return regs->gprs[2]; + +badframe: + force_sig(SIGSEGV, current); + return 0; +} + +/* + * Set up a signal frame. + */ + + +/* + * Determine which stack to use.. + */ +static inline void * +get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) +{ + unsigned long sp; + + /* Default to using normal stack */ + sp = (unsigned long) A(regs->gprs[15]); + + /* This is the X/Open sanctioned signal stack switching. */ + if (ka->sa.sa_flags & SA_ONSTACK) { + if (! on_sig_stack(sp)) + sp = current->sas_ss_sp + current->sas_ss_size; + } + + /* This is the legacy signal stack switching. */ + else if (!user_mode(regs) && + !(ka->sa.sa_flags & SA_RESTORER) && + ka->sa.sa_restorer) { + sp = (unsigned long) ka->sa.sa_restorer; + } + + return (void *)((sp - frame_size) & -8ul); +} + +static inline int map_signal(int sig) +{ + if (current_thread_info()->exec_domain + && current_thread_info()->exec_domain->signal_invmap + && sig < 32) + return current_thread_info()->exec_domain->signal_invmap[sig]; + else + return sig; +} + +static void setup_frame32(int sig, struct k_sigaction *ka, + sigset_t *set, struct pt_regs * regs) +{ + sigframe32 *frame = get_sigframe(ka, regs, sizeof(sigframe32)); + if (!access_ok(VERIFY_WRITE, frame, sizeof(sigframe32))) + goto give_sigsegv; + + if (__copy_to_user(&frame->sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE32)) + goto give_sigsegv; + + if (save_sigregs32(regs, &frame->sregs)) + goto give_sigsegv; + if (__put_user((unsigned long) &frame->sregs, &frame->sc.sregs)) + goto give_sigsegv; + + /* Set up to return from userspace. If provided, use a stub + already in userspace. */ + if (ka->sa.sa_flags & SA_RESTORER) { + regs->gprs[14] = (__u64) ka->sa.sa_restorer; + } else { + regs->gprs[14] = (__u64) frame->retcode; + if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn, + (u16 *)(frame->retcode))) + goto give_sigsegv; + } + + /* Set up backchain. */ + if (__put_user(regs->gprs[15], (unsigned int *) frame)) + goto give_sigsegv; + + /* Set up registers for signal handler */ + regs->gprs[15] = (__u64) frame; + regs->psw.addr = (__u64) ka->sa.sa_handler; + regs->psw.mask = PSW_USER32_BITS; + + regs->gprs[2] = map_signal(sig); + regs->gprs[3] = (__u64) &frame->sc; + + /* We forgot to include these in the sigcontext. + To avoid breaking binary compatibility, they are passed as args. */ + regs->gprs[4] = current->thread.trap_no; + regs->gprs[5] = current->thread.prot_addr; + return; + +give_sigsegv: + if (sig == SIGSEGV) + ka->sa.sa_handler = SIG_DFL; + force_sig(SIGSEGV, current); +} + +static void setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info, + sigset_t *set, struct pt_regs * regs) +{ + int err = 0; + rt_sigframe32 *frame = get_sigframe(ka, regs, sizeof(rt_sigframe32)); + if (!access_ok(VERIFY_WRITE, frame, sizeof(rt_sigframe32))) + goto give_sigsegv; + + if (copy_siginfo_to_user32(&frame->info, info)) + goto give_sigsegv; + + /* Create the ucontext. */ + err |= __put_user(0, &frame->uc.uc_flags); + err |= __put_user(0, &frame->uc.uc_link); + err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); + err |= __put_user(sas_ss_flags(regs->gprs[15]), + &frame->uc.uc_stack.ss_flags); + err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); + err |= save_sigregs32(regs, &frame->uc.uc_mcontext); + err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); + if (err) + goto give_sigsegv; + + /* Set up to return from userspace. If provided, use a stub + already in userspace. */ + if (ka->sa.sa_flags & SA_RESTORER) { + regs->gprs[14] = (__u64) ka->sa.sa_restorer; + } else { + regs->gprs[14] = (__u64) frame->retcode; + err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn, + (u16 *)(frame->retcode)); + } + + /* Set up backchain. */ + if (__put_user(regs->gprs[15], (unsigned int *) frame)) + goto give_sigsegv; + + /* Set up registers for signal handler */ + regs->gprs[15] = (__u64) frame; + regs->psw.addr = (__u64) ka->sa.sa_handler; + regs->psw.mask = PSW_USER32_BITS; + + regs->gprs[2] = map_signal(sig); + regs->gprs[3] = (__u64) &frame->info; + regs->gprs[4] = (__u64) &frame->uc; + return; + +give_sigsegv: + if (sig == SIGSEGV) + ka->sa.sa_handler = SIG_DFL; + force_sig(SIGSEGV, current); +} + +/* + * OK, we're invoking a handler + */ + +static void +handle_signal32(unsigned long sig, siginfo_t *info, sigset_t *oldset, + struct pt_regs * regs) +{ + struct k_sigaction *ka = ¤t->sighand->action[sig-1]; + + /* Are we from a system call? */ + if (regs->trap == __LC_SVC_OLD_PSW) { + /* If so, check system call restarting.. */ + switch (regs->gprs[2]) { + case -ERESTARTNOHAND: + regs->gprs[2] = -EINTR; + break; + + case -ERESTARTSYS: + if (!(ka->sa.sa_flags & SA_RESTART)) { + regs->gprs[2] = -EINTR; + break; + } + /* fallthrough */ + case -ERESTARTNOINTR: + regs->gprs[2] = regs->orig_gpr2; + regs->psw.addr -= 2; + } + } + + /* Set up the stack frame */ + if (ka->sa.sa_flags & SA_SIGINFO) + setup_rt_frame32(sig, ka, info, oldset, regs); + else + setup_frame32(sig, ka, oldset, regs); + + if (ka->sa.sa_flags & SA_ONESHOT) + ka->sa.sa_handler = SIG_DFL; + + if (!(ka->sa.sa_flags & SA_NODEFER)) { + spin_lock_irq(¤t->sighand->siglock); + sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); + sigaddset(¤t->blocked,sig); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + } +} + +/* + * Note that 'init' is a special process: it doesn't get signals it doesn't + * want to handle. Thus you cannot kill init even with a SIGKILL even by + * mistake. + * + * Note that we go through the signals twice: once to check the signals that + * the kernel can handle, and then we build all the user-level signal handling + * stack-frames in one go after that. + */ +int do_signal32(struct pt_regs *regs, sigset_t *oldset) +{ + siginfo_t info; + int signr; + + /* + * We want the common case to go fast, which + * is why we may in certain cases get here from + * kernel mode. Just return without doing anything + * if so. + */ + if (!user_mode(regs)) + return 1; + + if (!oldset) + oldset = ¤t->blocked; + + signr = get_signal_to_deliver(&info, regs, NULL); + if (signr > 0) { + /* Whee! Actually deliver the signal. */ + handle_signal32(signr, &info, oldset, regs); + return 1; + } + + /* Did we come from a system call? */ + if ( regs->trap == __LC_SVC_OLD_PSW /* System Call! */ ) { + /* Restart the system call - no handlers present */ + if (regs->gprs[2] == -ERESTARTNOHAND || + regs->gprs[2] == -ERESTARTSYS || + regs->gprs[2] == -ERESTARTNOINTR) { + regs->gprs[2] = regs->orig_gpr2; + regs->psw.addr -= 2; + } + } + return 0; +} diff -urN linux-2.5.67/arch/s390/kernel/compat_wrapper.S linux-2.5.67-s390/arch/s390/kernel/compat_wrapper.S --- linux-2.5.67/arch/s390/kernel/compat_wrapper.S Thu Jan 1 01:00:00 1970 +++ linux-2.5.67-s390/arch/s390/kernel/compat_wrapper.S Mon Apr 14 19:11:56 2003 @@ -0,0 +1,1211 @@ +/* +* arch/s390/kernel/sys_wrapper31.S +* wrapper for 31 bit compatible system calls. +* +* S390 version +* Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation +* Author(s): Gerhard Tonn (ton@de.ibm.com), +*/ + + .globl sys32_exit_wrapper +sys32_exit_wrapper: + lgfr %r2,%r2 # int + jg sys_exit # branch to sys_exit + + .globl sys32_read_wrapper +sys32_read_wrapper: + llgfr %r2,%r2 # unsigned int + llgtr %r3,%r3 # char * + llgfr %r4,%r4 # size_t + jg sys32_read # branch to sys_read + + .globl sys32_write_wrapper +sys32_write_wrapper: + llgfr %r2,%r2 # unsigned int + llgtr %r3,%r3 # const char * + llgfr %r4,%r4 # size_t + jg sys32_write # branch to system call + + .globl sys32_open_wrapper +sys32_open_wrapper: + llgtr %r2,%r2 # const char * + lgfr %r3,%r3 # int + lgfr %r4,%r4 # int + jg sys_open # branch to system call + + .globl sys32_close_wrapper +sys32_close_wrapper: + llgfr %r2,%r2 # unsigned int + jg sys_close # branch to system call + + .globl sys32_creat_wrapper +sys32_creat_wrapper: + llgtr %r2,%r2 # const char * + lgfr %r3,%r3 # int + jg sys_creat # branch to system call + + .globl sys32_link_wrapper +sys32_link_wrapper: + llgtr %r2,%r2 # const char * + llgtr %r3,%r3 # const char * + jg sys_link # branch to system call + + .globl sys32_unlink_wrapper +sys32_unlink_wrapper: + llgtr %r2,%r2 # const char * + jg sys_unlink # branch to system call + + .globl sys32_chdir_wrapper +sys32_chdir_wrapper: + llgtr %r2,%r2 # const char * + jg sys_chdir # branch to system call + + .globl sys32_time_wrapper +sys32_time_wrapper: + llgtr %r2,%r2 # int * + jg sys_time # branch to system call + + .globl sys32_mknod_wrapper +sys32_mknod_wrapper: + llgtr %r2,%r2 # const char * + lgfr %r3,%r3 # int + llgfr %r4,%r4 # dev + jg sys_mknod # branch to system call + + .globl sys32_chmod_wrapper +sys32_chmod_wrapper: + llgtr %r2,%r2 # const char * + llgfr %r3,%r3 # mode_t + jg sys_chmod # branch to system call + + .globl sys32_lchown16_wrapper +sys32_lchown16_wrapper: + llgtr %r2,%r2 # const char * + llgfr %r3,%r3 # __kernel_old_uid_emu31_t + llgfr %r4,%r4 # __kernel_old_uid_emu31_t + jg sys32_lchown16 # branch to system call + + .globl sys32_lseek_wrapper +sys32_lseek_wrapper: + llgfr %r2,%r2 # unsigned int + lgfr %r3,%r3 # off_t + llgfr %r4,%r4 # unsigned int + jg sys_lseek # branch to system call + +#sys32_getpid_wrapper # void + + .globl sys32_mount_wrapper +sys32_mount_wrapper: + llgtr %r2,%r2 # char * + llgtr %r3,%r3 # char * + llgtr %r4,%r4 # char * + llgfr %r5,%r5 # unsigned long + llgtr %r6,%r6 # void * + jg sys32_mount # branch to system call + + .globl sys32_oldumount_wrapper +sys32_oldumount_wrapper: + llgtr %r2,%r2 # char * + jg sys_oldumount # branch to system call + + .globl sys32_setuid16_wrapper +sys32_setuid16_wrapper: + llgfr %r2,%r2 # __kernel_old_uid_emu31_t + jg sys32_setuid16 # branch to system call + +#sys32_getuid16_wrapper # void + + .globl sys32_ptrace_wrapper +sys32_ptrace_wrapper: + lgfr %r2,%r2 # long + lgfr %r3,%r3 # long + llgtr %r4,%r4 # long + llgfr %r5,%r5 # long + jg sys_ptrace # branch to system call + + .globl sys32_alarm_wrapper +sys32_alarm_wrapper: + llgtr %r2,%r2 # unsigned int + jg sys_alarm # branch to system call + +#sys32_pause_wrapper # void + + .globl compat_sys_utime_wrapper +compat_sys_utime_wrapper: + llgtr %r2,%r2 # char * + llgtr %r3,%r3 # struct compat_utimbuf * + jg compat_sys_utime # branch to system call + + .globl sys32_access_wrapper +sys32_access_wrapper: + llgtr %r2,%r2 # const char * + lgfr %r3,%r3 # int + jg sys_access # branch to system call + + .globl sys32_nice_wrapper +sys32_nice_wrapper: + lgfr %r2,%r2 # int + jg sys_nice # branch to system call + +#sys32_sync_wrapper # void + + .globl sys32_kill_wrapper +sys32_kill_wrapper: + lgfr %r2,%r2 # int + lgfr %r3,%r3 # int + jg sys_kill # branch to system call + + .globl sys32_rename_wrapper +sys32_rename_wrapper: + llgtr %r2,%r2 # const char * + llgtr %r3,%r3 # const char * + jg sys_rename # branch to system call + + .globl sys32_mkdir_wrapper +sys32_mkdir_wrapper: + llgtr %r2,%r2 # const char * + lgfr %r3,%r3 # int + jg sys_mkdir # branch to system call + + .globl sys32_rmdir_wrapper +sys32_rmdir_wrapper: + llgtr %r2,%r2 # const char * + jg sys_rmdir # branch to system call + + .globl sys32_dup_wrapper +sys32_dup_wrapper: + llgfr %r2,%r2 # unsigned int + jg sys_dup # branch to system call + + .globl sys32_pipe_wrapper +sys32_pipe_wrapper: + llgtr %r2,%r2 # u32 * + jg sys_pipe # branch to system call + + .globl compat_sys_times_wrapper +compat_sys_times_wrapper: + llgtr %r2,%r2 # struct compat_tms * + jg compat_sys_times # branch to system call + + .globl sys32_brk_wrapper +sys32_brk_wrapper: + llgtr %r2,%r2 # unsigned long + jg sys_brk # branch to system call + + .globl sys32_setgid16_wrapper +sys32_setgid16_wrapper: + llgfr %r2,%r2 # __kernel_old_gid_emu31_t + jg sys32_setgid16 # branch to system call + +#sys32_getgid16_wrapper # void + + .globl sys32_signal_wrapper +sys32_signal_wrapper: + lgfr %r2,%r2 # int + llgfr %r3,%r3 # __sighandler_t + jg sys_signal + +#sys32_geteuid16_wrapper # void + +#sys32_getegid16_wrapper # void + + .globl sys32_acct_wrapper +sys32_acct_wrapper: + llgtr %r2,%r2 # char * + jg sys_acct # branch to system call + + .globl sys32_umount_wrapper +sys32_umount_wrapper: + llgtr %r2,%r2 # char * + lgfr %r3,%r3 # int + jg sys_umount # branch to system call + + .globl sys32_ioctl_wrapper +sys32_ioctl_wrapper: + llgfr %r2,%r2 # unsigned int + llgfr %r3,%r3 # unsigned int + llgfr %r4,%r4 # unsigned int + jg sys32_ioctl # branch to system call + + .globl compat_sys_fcntl_wrapper +compat_sys_fcntl_wrapper: + llgfr %r2,%r2 # unsigned int + llgfr %r3,%r3 # unsigned int + llgfr %r4,%r4 # unsigned long + jg compat_sys_fcntl # branch to system call + + .globl sys32_setpgid_wrapper +sys32_setpgid_wrapper: + lgfr %r2,%r2 # pid_t + lgfr %r3,%r3 # pid_t + jg sys_setpgid # branch to system call + + .globl sys32_umask_wrapper +sys32_umask_wrapper: + lgfr %r3,%r3 # int + jg sys_umask # branch to system call + + .globl sys32_chroot_wrapper +sys32_chroot_wrapper: + llgtr %r2,%r2 # char * + jg sys_chroot # branch to system call + + .globl sys32_ustat_wrapper +sys32_ustat_wrapper: + llgfr %r2,%r2 # dev_t + llgtr %r3,%r3 # struct ustat * + jg sys_ustat + + .globl sys32_dup2_wrapper +sys32_dup2_wrapper: + llgfr %r2,%r2 # unsigned int + llgfr %r3,%r3 # unsigned int + jg sys_dup2 # branch to system call + +#sys32_getppid_wrapper # void + +#sys32_getpgrp_wrapper # void + +#sys32_setsid_wrapper # void + + .globl sys32_sigaction_wrapper +sys32_sigaction_wrapper: + lgfr %r2,%r2 # int + llgtr %r3,%r3 # const struct old_sigaction * + jg sys32_sigaction # branch to system call + + .globl sys32_setreuid16_wrapper +sys32_setreuid16_wrapper: + llgfr %r2,%r2 # __kernel_old_uid_emu31_t + llgfr %r3,%r3 # __kernel_old_uid_emu31_t + jg sys32_setreuid16 # branch to system call + + .globl sys32_setregid16_wrapper +sys32_setregid16_wrapper: + llgfr %r2,%r2 # __kernel_old_gid_emu31_t + llgfr %r3,%r3 # __kernel_old_gid_emu31_t + jg sys32_setregid16 # branch to system call + +#sys32_sigsuspend_wrapper # done in sigsuspend_glue + + .globl compat_sys_sigpending_wrapper +compat_sys_sigpending_wrapper: + llgtr %r2,%r2 # compat_old_sigset_t * + jg compat_sys_sigpending # branch to system call + + .globl sys32_sethostname_wrapper +sys32_sethostname_wrapper: + llgtr %r2,%r2 # char * + lgfr %r3,%r3 # int + jg sys_sethostname # branch to system call + + .globl sys32_setrlimit_wrapper +sys32_setrlimit_wrapper: + llgfr %r2,%r2 # unsigned int + llgtr %r3,%r3 # struct rlimit_emu31 * + jg sys32_setrlimit # branch to system call + + .globl sys32_old_getrlimit_wrapper +sys32_old_getrlimit_wrapper: + llgfr %r2,%r2 # unsigned int + llgtr %r3,%r3 # struct rlimit_emu31 * + jg sys32_old_getrlimit # branch to system call + + .globl sys32_getrlimit_wrapper +sys32_getrlimit_wrapper: + llgfr %r2,%r2 # unsigned int + llgtr %r3,%r3 # struct rlimit_emu31 * + jg sys32_getrlimit # branch to system call + + .globl sys32_mmap2_wrapper +sys32_mmap2_wrapper: + llgtr %r2,%r2 # struct mmap_arg_struct_emu31 * + jg sys32_mmap2 # branch to system call + + .globl sys32_getrusage_wrapper +sys32_getrusage_wrapper: + lgfr %r2,%r2 # int + llgtr %r3,%r3 # struct rusage_emu31 * + jg sys32_getrusage # branch to system call + + .globl sys32_gettimeofday_wrapper +sys32_gettimeofday_wrapper: + llgtr %r2,%r2 # struct timeval_emu31 * + llgtr %r3,%r3 # struct timezone * + jg sys32_gettimeofday # branch to system call + + .globl sys32_settimeofday_wrapper +sys32_settimeofday_wrapper: + llgtr %r2,%r2 # struct timeval_emu31 * + llgtr %r3,%r3 # struct timezone * + jg sys32_settimeofday # branch to system call + + .globl sys32_getgroups16_wrapper +sys32_getgroups16_wrapper: + lgfr %r2,%r2 # int + llgtr %r3,%r3 # __kernel_old_gid_emu31_t * + jg sys32_getgroups16 # branch to system call + + .globl sys32_setgroups16_wrapper +sys32_setgroups16_wrapper: + lgfr %r2,%r2 # int + llgtr %r3,%r3 # __kernel_old_gid_emu31_t * + jg sys32_setgroups16 # branch to system call + + .globl sys32_symlink_wrapper +sys32_symlink_wrapper: + llgtr %r2,%r2 # const char * + llgtr %r3,%r3 # const char * + jg sys_symlink # branch to system call + + .globl sys32_readlink_wrapper +sys32_readlink_wrapper: + llgtr %r2,%r2 # const char * + llgtr %r3,%r3 # char * + lgfr %r4,%r4 # int + jg sys_readlink # branch to system call + + .globl sys32_uselib_wrapper +sys32_uselib_wrapper: + llgtr %r2,%r2 # const char * + jg sys_uselib # branch to system call + + .globl sys32_swapon_wrapper +sys32_swapon_wrapper: + llgtr %r2,%r2 # const char * + lgfr %r3,%r3 # int + jg sys_swapon # branch to system call + + .globl sys32_reboot_wrapper +sys32_reboot_wrapper: + lgfr %r2,%r2 # int + lgfr %r3,%r3 # int + llgfr %r4,%r4 # unsigned int + llgtr %r5,%r5 # void * + jg sys_reboot # branch to system call + + .globl old32_readdir_wrapper +old32_readdir_wrapper: + llgfr %r2,%r2 # unsigned int + llgtr %r3,%r3 # void * + llgfr %r4,%r4 # unsigned int + jg old32_readdir # branch to system call + + .globl old32_mmap_wrapper +old32_mmap_wrapper: + llgtr %r2,%r2 # struct mmap_arg_struct_emu31 * + jg old32_mmap # branch to system call + + .globl sys32_munmap_wrapper +sys32_munmap_wrapper: + llgfr %r2,%r2 # unsigned long + llgfr %r3,%r3 # size_t + jg sys_munmap # branch to system call + + .globl sys32_truncate_wrapper +sys32_truncate_wrapper: + llgtr %r2,%r2 # const char * + llgfr %r3,%r3 # unsigned long + jg sys_truncate # branch to system call + + .globl sys32_ftruncate_wrapper +sys32_ftruncate_wrapper: + llgfr %r2,%r2 # unsigned int + llgfr %r3,%r3 # unsigned long + jg sys_ftruncate # branch to system call + + .globl sys32_fchmod_wrapper +sys32_fchmod_wrapper: + llgfr %r2,%r2 # unsigned int + llgfr %r3,%r3 # mode_t + jg sys_fchmod # branch to system call + + .globl sys32_fchown16_wrapper +sys32_fchown16_wrapper: + llgfr %r2,%r2 # unsigned int + llgtr %r3,%r3 # __kernel_old_uid_emu31_t * + llgtr %r4,%r4 # __kernel_old_gid_emu31_t * + jg sys32_fchown16 # branch to system call + + .globl sys32_getpriority_wrapper +sys32_getpriority_wrapper: + lgfr %r2,%r2 # int + lgfr %r3,%r3 # int + jg sys_getpriority # branch to system call + + .globl sys32_setpriority_wrapper +sys32_setpriority_wrapper: + lgfr %r2,%r2 # int + lgfr %r3,%r3 # int + lgfr %r4,%r4 # int + jg sys_setpriority # branch to system call + + .globl compat_sys_statfs_wrapper +compat_sys_statfs_wrapper: + llgtr %r2,%r2 # char * + llgtr %r3,%r3 # struct compat_statfs * + jg compat_sys_statfs # branch to system call + + .globl compat_sys_fstatfs_wrapper +compat_sys_fstatfs_wrapper: + llgfr %r2,%r2 # unsigned int + llgtr %r3,%r3 # struct compat_statfs * + jg compat_sys_fstatfs # branch to system call + + .globl compat_sys_socketcall_wrapper +compat_sys_socketcall_wrapper: + lgfr %r2,%r2 # int + llgtr %r3,%r3 # u32 * + jg compat_sys_socketcall # branch to system call + + .globl sys32_syslog_wrapper +sys32_syslog_wrapper: + lgfr %r2,%r2 # int + llgtr %r3,%r3 # char * + lgfr %r4,%r4 # int + jg sys_syslog # branch to system call + + .globl compat_sys_setitimer_wrapper +compat_sys_setitimer_wrapper: + lgfr %r2,%r2 # int + llgtr %r3,%r3 # struct itimerval_emu31 * + llgtr %r4,%r4 # struct itimerval_emu31 * + jg compat_sys_setitimer # branch to system call + + .globl compat_sys_getitimer_wrapper +compat_sys_getitimer_wrapper: + lgfr %r2,%r2 # int + llgtr %r3,%r3 # struct itimerval_emu31 * + jg compat_sys_getitimer # branch to system call + + .globl compat_sys_newstat_wrapper +compat_sys_newstat_wrapper: + llgtr %r2,%r2 # char * + llgtr %r3,%r3 # struct stat_emu31 * + jg compat_sys_newstat # branch to system call + + .globl compat_sys_newlstat_wrapper +compat_sys_newlstat_wrapper: + llgtr %r2,%r2 # char * + llgtr %r3,%r3 # struct stat_emu31 * + jg compat_sys_newlstat # branch to system call + + .globl compat_sys_newfstat_wrapper +compat_sys_newfstat_wrapper: + llgfr %r2,%r2 # unsigned int + llgtr %r3,%r3 # struct stat_emu31 * + jg compat_sys_newfstat # branch to system call + +#sys32_vhangup_wrapper # void + + .globl sys32_wait4_wrapper +sys32_wait4_wrapper: + lgfr %r2,%r2 # pid_t + llgtr %r3,%r3 # unsigned int * + lgfr %r4,%r4 # int + llgtr %r5,%r5 # struct rusage * + jg sys32_wait4 # branch to system call + + .globl sys32_swapoff_wrapper +sys32_swapoff_wrapper: + llgtr %r2,%r2 # const char * + jg sys_swapoff # branch to system call + + .globl sys32_sysinfo_wrapper +sys32_sysinfo_wrapper: + llgtr %r2,%r2 # struct sysinfo_emu31 * + jg sys32_sysinfo # branch to system call + + .globl sys32_ipc_wrapper +sys32_ipc_wrapper: + llgfr %r2,%r2 # uint + lgfr %r3,%r3 # int + lgfr %r4,%r4 # int + lgfr %r5,%r5 # int + llgtr %r6,%r6 # void * + jg sys32_ipc # branch to system call + + .globl sys32_fsync_wrapper +sys32_fsync_wrapper: + llgfr %r2,%r2 # unsigned int + jg sys_fsync # branch to system call + +#sys32_sigreturn_wrapper # done in sigreturn_glue + +#sys32_clone_wrapper # done in clone_glue + + .globl sys32_setdomainname_wrapper +sys32_setdomainname_wrapper: + llgtr %r2,%r2 # char * + lgfr %r3,%r3 # int + jg sys_setdomainname # branch to system call + + .globl sys32_newuname_wrapper +sys32_newuname_wrapper: + llgtr %r2,%r2 # struct new_utsname * + jg s390x_newuname # branch to system call + + .globl sys32_adjtimex_wrapper +sys32_adjtimex_wrapper: + llgtr %r2,%r2 # struct timex_emu31 * + jg sys32_adjtimex # branch to system call + + .globl sys32_mprotect_wrapper +sys32_mprotect_wrapper: + llgtr %r2,%r2 # unsigned long (actually pointer + llgfr %r3,%r3 # size_t + llgfr %r4,%r4 # unsigned long + jg sys_mprotect # branch to system call + + .globl compat_sys_sigprocmask_wrapper +compat_sys_sigprocmask_wrapper: + lgfr %r2,%r2 # int + llgtr %r3,%r3 # compat_old_sigset_t * + llgtr %r4,%r4 # compat_old_sigset_t * + jg compat_sys_sigprocmask # branch to system call + + .globl sys32_init_module_wrapper +sys32_init_module_wrapper: + llgtr %r2,%r2 # const char * + llgtr %r3,%r3 # struct module * + jg sys32_init_module # branch to system call + + .globl sys32_delete_module_wrapper +sys32_delete_module_wrapper: + llgtr %r2,%r2 # const char * + jg sys32_delete_module # branch to system call + + .globl sys32_quotactl_wrapper +sys32_quotactl_wrapper: + lgfr %r2,%r2 # int + llgtr %r3,%r3 # const char * + lgfr %r4,%r4 # int + llgtr %r5,%r5 # caddr_t + jg sys_quotactl # branch to system call + + .globl sys32_getpgid_wrapper +sys32_getpgid_wrapper: + lgfr %r2,%r2 # pid_t + jg sys_getpgid # branch to system call + + .globl sys32_fchdir_wrapper +sys32_fchdir_wrapper: + llgfr %r2,%r2 # unsigned int + jg sys_fchdir # branch to system call + + .globl sys32_bdflush_wrapper +sys32_bdflush_wrapper: + lgfr %r2,%r2 # int + lgfr %r3,%r3 # long + jg sys_bdflush # branch to system call + + .globl sys32_sysfs_wrapper +sys32_sysfs_wrapper: + lgfr %r2,%r2 # int + llgfr %r3,%r3 # unsigned long + llgfr %r4,%r4 # unsigned long + jg sys_sysfs # branch to system call + + .globl sys32_personality_wrapper +sys32_personality_wrapper: + llgfr %r2,%r2 # unsigned long + jg s390x_personality # branch to system call + + .globl sys32_setfsuid16_wrapper +sys32_setfsuid16_wrapper: + llgfr %r2,%r2 # __kernel_old_uid_emu31_t + jg sys32_setfsuid16 # branch to system call + + .globl sys32_setfsgid16_wrapper +sys32_setfsgid16_wrapper: + llgfr %r2,%r2 # __kernel_old_gid_emu31_t + jg sys32_setfsgid16 # branch to system call + + .globl sys32_llseek_wrapper +sys32_llseek_wrapper: + llgfr %r2,%r2 # unsigned int + llgfr %r3,%r3 # unsigned long + llgfr %r4,%r4 # unsigned long + llgtr %r5,%r5 # loff_t * + llgfr %r6,%r6 # unsigned int + jg sys_llseek # branch to system call + + .globl sys32_getdents_wrapper +sys32_getdents_wrapper: + llgfr %r2,%r2 # unsigned int + llgtr %r3,%r3 # void * + llgfr %r4,%r4 # unsigned int + jg sys32_getdents # branch to system call + + .globl sys32_select_wrapper +sys32_select_wrapper: + lgfr %r2,%r2 # int + llgtr %r3,%r3 # fd_set * + llgtr %r4,%r4 # fd_set * + llgtr %r5,%r5 # fd_set * + llgtr %r6,%r6 # struct timeval_emu31 * + jg sys32_select # branch to system call + + .globl sys32_flock_wrapper +sys32_flock_wrapper: + llgfr %r2,%r2 # unsigned int + llgfr %r3,%r3 # unsigned int + jg sys_flock # branch to system call + + .globl sys32_msync_wrapper +sys32_msync_wrapper: + llgfr %r2,%r2 # unsigned long + llgfr %r3,%r3 # size_t + lgfr %r4,%r4 # int + jg sys_msync # branch to system call + + .globl sys32_readv_wrapper +sys32_readv_wrapper: + llgfr %r2,%r2 # unsigned long + llgtr %r3,%r3 # const struct iovec_emu31 * + llgfr %r4,%r4 # unsigned long + jg sys32_readv # branch to system call + + .globl sys32_writev_wrapper +sys32_writev_wrapper: + llgfr %r2,%r2 # unsigned long + llgtr %r3,%r3 # const struct iovec_emu31 * + llgfr %r4,%r4 # unsigned long + jg sys32_writev # branch to system call + + .globl sys32_getsid_wrapper +sys32_getsid_wrapper: + lgfr %r2,%r2 # pid_t + jg sys_getsid # branch to system call + + .globl sys32_fdatasync_wrapper +sys32_fdatasync_wrapper: + llgfr %r2,%r2 # unsigned int + jg sys_fdatasync # branch to system call + +#sys32_sysctl_wrapper # tbd + + .globl sys32_mlock_wrapper +sys32_mlock_wrapper: + llgfr %r2,%r2 # unsigned long + llgfr %r3,%r3 # size_t + jg sys_mlock # branch to system call + + .globl sys32_munlock_wrapper +sys32_munlock_wrapper: + llgfr %r2,%r2 # unsigned long + llgfr %r3,%r3 # size_t + jg sys_munlock # branch to system call + + .globl sys32_mlockall_wrapper +sys32_mlockall_wrapper: + lgfr %r2,%r2 # int + jg sys_mlockall # branch to system call + +#sys32_munlockall_wrapper # void + + .globl sys32_sched_setparam_wrapper +sys32_sched_setparam_wrapper: + lgfr %r2,%r2 # pid_t + llgtr %r3,%r3 # struct sched_param * + jg sys_sched_setparam # branch to system call + + .globl sys32_sched_getparam_wrapper +sys32_sched_getparam_wrapper: + lgfr %r2,%r2 # pid_t + llgtr %r3,%r3 # struct sched_param * + jg sys_sched_getparam # branch to system call + + .globl sys32_sched_setscheduler_wrapper +sys32_sched_setscheduler_wrapper: + lgfr %r2,%r2 # pid_t + lgfr %r3,%r3 # int + llgtr %r4,%r4 # struct sched_param * + jg sys_sched_setscheduler # branch to system call + + .globl sys32_sched_getscheduler_wrapper +sys32_sched_getscheduler_wrapper: + lgfr %r2,%r2 # pid_t + jg sys_sched_getscheduler # branch to system call + +#sys32_sched_yield_wrapper # void + + .globl sys32_sched_get_priority_max_wrapper +sys32_sched_get_priority_max_wrapper: + lgfr %r2,%r2 # int + jg sys_sched_get_priority_max # branch to system call + + .globl sys32_sched_get_priority_min_wrapper +sys32_sched_get_priority_min_wrapper: + lgfr %r2,%r2 # int + jg sys_sched_get_priority_min # branch to system call + + .globl sys32_sched_rr_get_interval_wrapper +sys32_sched_rr_get_interval_wrapper: + lgfr %r2,%r2 # pid_t + llgtr %r3,%r3 # struct compat_timespec * + jg sys32_sched_rr_get_interval # branch to system call + + .globl compat_sys_nanosleep_wrapper +compat_sys_nanosleep_wrapper: + llgtr %r2,%r2 # struct compat_timespec * + llgtr %r3,%r3 # struct compat_timespec * + jg compat_sys_nanosleep # branch to system call + + .globl sys32_mremap_wrapper +sys32_mremap_wrapper: + llgfr %r2,%r2 # unsigned long + llgfr %r3,%r3 # unsigned long + llgfr %r4,%r4 # unsigned long + llgfr %r5,%r5 # unsigned long + llgfr %r6,%r6 # unsigned long + jg sys_mremap # branch to system call + + .globl sys32_setresuid16_wrapper +sys32_setresuid16_wrapper: + llgfr %r2,%r2 # __kernel_old_uid_emu31_t + llgfr %r3,%r3 # __kernel_old_uid_emu31_t + llgfr %r4,%r4 # __kernel_old_uid_emu31_t + jg sys32_setresuid16 # branch to system call + + .globl sys32_getresuid16_wrapper +sys32_getresuid16_wrapper: + llgtr %r2,%r2 # __kernel_old_uid_emu31_t * + llgtr %r3,%r3 # __kernel_old_uid_emu31_t * + llgtr %r4,%r4 # __kernel_old_uid_emu31_t * + jg sys32_getresuid16 # branch to system call + + .globl sys32_poll_wrapper +sys32_poll_wrapper: + llgtr %r2,%r2 # struct pollfd * + llgfr %r3,%r3 # unsigned int + lgfr %r4,%r4 # long + jg sys_poll # branch to system call + + .globl sys32_nfsservctl_wrapper +sys32_nfsservctl_wrapper: + lgfr %r2,%r2 # int + llgtr %r3,%r3 # struct nfsctl_arg_emu31 * + llgtr %r4,%r4 # union nfsctl_res_emu31 * + jg sys32_nfsservctl # branch to system call + + .globl sys32_setresgid16_wrapper +sys32_setresgid16_wrapper: + llgfr %r2,%r2 # __kernel_old_gid_emu31_t + llgfr %r3,%r3 # __kernel_old_gid_emu31_t + llgfr %r4,%r4 # __kernel_old_gid_emu31_t + jg sys32_setresgid16 # branch to system call + + .globl sys32_getresgid16_wrapper +sys32_getresgid16_wrapper: + llgtr %r2,%r2 # __kernel_old_gid_emu31_t * + llgtr %r3,%r3 # __kernel_old_gid_emu31_t * + llgtr %r4,%r4 # __kernel_old_gid_emu31_t * + jg sys32_getresgid16 # branch to system call + + .globl sys32_prctl_wrapper +sys32_prctl_wrapper: + lgfr %r2,%r2 # int + llgfr %r3,%r3 # unsigned long + llgfr %r4,%r4 # unsigned long + llgfr %r5,%r5 # unsigned long + llgfr %r6,%r6 # unsigned long + jg sys_prctl # branch to system call + +#sys32_rt_sigreturn_wrapper # done in rt_sigreturn_glue + + .globl sys32_rt_sigaction_wrapper +sys32_rt_sigaction_wrapper: + lgfr %r2,%r2 # int + llgtr %r3,%r3 # const struct sigaction_emu31 * + llgtr %r4,%r4 # const struct sigaction_emu31 * + llgfr %r5,%r5 # size_t + jg sys32_rt_sigaction # branch to system call + + .globl sys32_rt_sigprocmask_wrapper +sys32_rt_sigprocmask_wrapper: + lgfr %r2,%r2 # int + llgtr %r3,%r3 # old_sigset_emu31 * + llgtr %r4,%r4 # old_sigset_emu31 * + jg sys32_rt_sigprocmask # branch to system call + + .globl sys32_rt_sigpending_wrapper +sys32_rt_sigpending_wrapper: + llgtr %r2,%r2 # sigset_emu31 * + llgfr %r3,%r3 # size_t + jg sys32_rt_sigpending # branch to system call + + .globl sys32_rt_sigtimedwait_wrapper +sys32_rt_sigtimedwait_wrapper: + llgtr %r2,%r2 # const sigset_emu31_t * + llgtr %r3,%r3 # siginfo_emu31_t * + llgtr %r4,%r4 # const struct compat_timespec * + llgfr %r5,%r5 # size_t + jg sys32_rt_sigtimedwait # branch to system call + + .globl sys32_rt_sigqueueinfo_wrapper +sys32_rt_sigqueueinfo_wrapper: + lgfr %r2,%r2 # int + lgfr %r3,%r3 # int + llgtr %r4,%r4 # siginfo_emu31_t * + jg sys32_rt_sigqueueinfo # branch to system call + +#sys32_rt_sigsuspend_wrapper # done in rt_sigsuspend_glue + + .globl sys32_pread64_wrapper +sys32_pread64_wrapper: + llgfr %r2,%r2 # unsigned int + llgtr %r3,%r3 # char * + llgfr %r4,%r4 # size_t + llgfr %r5,%r5 # u32 + llgfr %r6,%r6 # u32 + jg sys32_pread64 # branch to system call + + .globl sys32_pwrite64_wrapper +sys32_pwrite64_wrapper: + llgfr %r2,%r2 # unsigned int + llgtr %r3,%r3 # const char * + llgfr %r4,%r4 # size_t + llgfr %r5,%r5 # u32 + llgfr %r6,%r6 # u32 + jg sys32_pwrite64 # branch to system call + + .globl sys32_chown16_wrapper +sys32_chown16_wrapper: + llgtr %r2,%r2 # const char * + llgfr %r3,%r3 # __kernel_old_uid_emu31_t + llgfr %r4,%r4 # __kernel_old_gid_emu31_t + jg sys32_chown16 # branch to system call + + .globl sys32_getcwd_wrapper +sys32_getcwd_wrapper: + llgtr %r2,%r2 # char * + llgfr %r3,%r3 # unsigned long + jg sys_getcwd # branch to system call + + .globl sys32_capget_wrapper +sys32_capget_wrapper: + llgtr %r2,%r2 # cap_user_header_t + llgtr %r3,%r3 # cap_user_data_t + jg sys_capget # branch to system call + + .globl sys32_capset_wrapper +sys32_capset_wrapper: + llgtr %r2,%r2 # cap_user_header_t + llgtr %r3,%r3 # const cap_user_data_t + jg sys_capset # branch to system call + + .globl sys32_sigaltstack_wrapper +sys32_sigaltstack_wrapper: + llgtr %r2,%r2 # const stack_emu31_t * + llgtr %r3,%r3 # stack_emu31_t * + jg sys32_sigaltstack + + .globl sys32_sendfile_wrapper +sys32_sendfile_wrapper: + lgfr %r2,%r2 # int + lgfr %r3,%r3 # int + llgtr %r4,%r4 # __kernel_off_emu31_t * + llgfr %r5,%r5 # size_t + jg sys32_sendfile # branch to system call + +#sys32_vfork_wrapper # done in vfork_glue + + .globl sys32_truncate64_wrapper +sys32_truncate64_wrapper: + llgtr %r2,%r2 # const char * + lgfr %r3,%r3 # s32 + llgfr %r4,%r4 # u32 + jg sys32_truncate64 # branch to system call + + .globl sys32_ftruncate64_wrapper +sys32_ftruncate64_wrapper: + llgfr %r2,%r2 # unsigned int + lgfr %r3,%r3 # s32 + llgfr %r4,%r4 # u32 + jg sys32_ftruncate64 # branch to system call + + .globl sys32_lchown_wrapper +sys32_lchown_wrapper: + llgtr %r2,%r2 # const char * + llgfr %r3,%r3 # uid_t + llgfr %r4,%r4 # gid_t + jg sys_lchown # branch to system call + +#sys32_getuid_wrapper # void +#sys32_getgid_wrapper # void +#sys32_geteuid_wrapper # void +#sys32_getegid_wrapper # void + + .globl sys32_setreuid_wrapper +sys32_setreuid_wrapper: + llgfr %r2,%r2 # uid_t + llgfr %r3,%r3 # uid_t + jg sys_setreuid # branch to system call + + .globl sys32_setregid_wrapper +sys32_setregid_wrapper: + llgfr %r2,%r2 # gid_t + llgfr %r3,%r3 # gid_t + jg sys_setregid # branch to system call + + .globl sys32_getgroups_wrapper +sys32_getgroups_wrapper: + lgfr %r2,%r2 # int + llgtr %r3,%r3 # gid_t * + jg sys_getgroups # branch to system call + + .globl sys32_setgroups_wrapper +sys32_setgroups_wrapper: + lgfr %r2,%r2 # int + llgtr %r3,%r3 # gid_t * + jg sys_setgroups # branch to system call + + .globl sys32_fchown_wrapper +sys32_fchown_wrapper: + llgfr %r2,%r2 # unsigned int + llgfr %r3,%r3 # uid_t + llgfr %r4,%r4 # gid_t + jg sys_fchown # branch to system call + + .globl sys32_setresuid_wrapper +sys32_setresuid_wrapper: + llgfr %r2,%r2 # uid_t + llgfr %r3,%r3 # uid_t + llgfr %r4,%r4 # uid_t + jg sys_setresuid # branch to system call + + .globl sys32_getresuid_wrapper +sys32_getresuid_wrapper: + llgtr %r2,%r2 # uid_t * + llgtr %r3,%r3 # uid_t * + llgtr %r4,%r4 # uid_t * + jg sys_getresuid # branch to system call + + .globl sys32_setresgid_wrapper +sys32_setresgid_wrapper: + llgfr %r2,%r2 # gid_t + llgfr %r3,%r3 # gid_t + llgfr %r4,%r4 # gid_t + jg sys_setresgid # branch to system call + + .globl sys32_getresgid_wrapper +sys32_getresgid_wrapper: + llgtr %r2,%r2 # gid_t * + llgtr %r3,%r3 # gid_t * + llgtr %r4,%r4 # gid_t * + jg sys_getresgid # branch to system call + + .globl sys32_chown_wrapper +sys32_chown_wrapper: + llgtr %r2,%r2 # const char * + llgfr %r3,%r3 # uid_t + llgfr %r4,%r4 # gid_t + jg sys_chown # branch to system call + + .globl sys32_setuid_wrapper +sys32_setuid_wrapper: + llgfr %r2,%r2 # uid_t + jg sys_setuid # branch to system call + + .globl sys32_setgid_wrapper +sys32_setgid_wrapper: + llgfr %r2,%r2 # gid_t + jg sys_setgid # branch to system call + + .globl sys32_setfsuid_wrapper +sys32_setfsuid_wrapper: + llgfr %r2,%r2 # uid_t + jg sys_setfsuid # branch to system call + + .globl sys32_setfsgid_wrapper +sys32_setfsgid_wrapper: + llgfr %r2,%r2 # gid_t + jg sys_setfsgid # branch to system call + + .globl sys32_pivot_root_wrapper +sys32_pivot_root_wrapper: + llgtr %r2,%r2 # const char * + llgtr %r3,%r3 # const char * + jg sys_pivot_root # branch to system call + + .globl sys32_mincore_wrapper +sys32_mincore_wrapper: + llgfr %r2,%r2 # unsigned long + llgfr %r3,%r3 # size_t + llgtr %r4,%r4 # unsigned char * + jg sys_mincore # branch to system call + + .globl sys32_madvise_wrapper +sys32_madvise_wrapper: + llgfr %r2,%r2 # unsigned long + llgfr %r3,%r3 # size_t + lgfr %r4,%r4 # int + jg sys_madvise # branch to system call + + .globl sys32_getdents64_wrapper +sys32_getdents64_wrapper: + llgfr %r2,%r2 # unsigned int + llgtr %r3,%r3 # void * + llgfr %r4,%r4 # unsigned int + jg sys_getdents64 # branch to system call + + .globl compat_sys_fcntl64_wrapper +compat_sys_fcntl64_wrapper: + llgfr %r2,%r2 # unsigned int + llgfr %r3,%r3 # unsigned int + llgfr %r4,%r4 # unsigned long + jg compat_sys_fcntl64 # branch to system call + + .globl sys32_stat64_wrapper +sys32_stat64_wrapper: + llgtr %r2,%r2 # char * + llgtr %r3,%r3 # struct stat64 * + llgfr %r4,%r4 # long + jg sys32_stat64 # branch to system call + + .globl sys32_lstat64_wrapper +sys32_lstat64_wrapper: + llgtr %r2,%r2 # char * + llgtr %r3,%r3 # struct stat64 * + llgfr %r4,%r4 # long + jg sys32_lstat64 # branch to system call + + .globl sys32_stime_wrapper +sys32_stime_wrapper: + llgtr %r2,%r2 # int * + jg sys_stime # branch to system call + + .globl sys32_sysctl_wrapper +sys32_sysctl_wrapper: + llgtr %r2,%r2 # struct __sysctl_args32 * + jg sys32_sysctl + + .globl sys32_fstat64_wrapper +sys32_fstat64_wrapper: + llgfr %r2,%r2 # unsigned long + llgtr %r3,%r3 # struct stat64 * + llgfr %r4,%r4 # long + jg sys32_fstat64 # branch to system call + + .globl compat_sys_futex_wrapper +compat_sys_futex_wrapper: + llgtr %r2,%r2 # u32 * + lgfr %r3,%r3 # int + lgfr %r4,%r4 # int + llgtr %r5,%r5 # struct compat_timespec * + jg compat_sys_futex # branch to system call + + .globl sys32_setxattr_wrapper +sys32_setxattr_wrapper: + llgtr %r2,%r2 # char * + llgtr %r3,%r3 # char * + llgtr %r4,%r4 # void * + llgfr %r5,%r5 # size_t + lgfr %r6,%r6 # int + jg sys_setxattr + + .globl sys32_lsetxattr_wrapper +sys32_lsetxattr_wrapper: + llgtr %r2,%r2 # char * + llgtr %r3,%r3 # char * + llgtr %r4,%r4 # void * + llgfr %r5,%r5 # size_t + lgfr %r6,%r6 # int + jg sys_lsetxattr + + .globl sys32_fsetxattr_wrapper +sys32_fsetxattr_wrapper: + lgfr %r2,%r2 # int + llgtr %r3,%r3 # char * + llgtr %r4,%r4 # void * + llgfr %r5,%r5 # size_t + lgfr %r6,%r6 # int + jg sys_fsetxattr + + .globl sys32_getxattr_wrapper +sys32_getxattr_wrapper: + llgtr %r2,%r2 # char * + llgtr %r3,%r3 # char * + llgtr %r4,%r4 # void * + llgfr %r5,%r5 # size_t + jg sys_getxattr + + .globl sys32_lgetxattr_wrapper +sys32_lgetxattr_wrapper: + llgtr %r2,%r2 # char * + llgtr %r3,%r3 # char * + llgtr %r4,%r4 # void * + llgfr %r5,%r5 # size_t + jg sys_lgetxattr + + .globl sys32_fgetxattr_wrapper +sys32_fgetxattr_wrapper: + lgfr %r2,%r2 # int + llgtr %r3,%r3 # char * + llgtr %r4,%r4 # void * + llgfr %r5,%r5 # size_t + jg sys_fgetxattr + + .globl sys32_listxattr_wrapper +sys32_listxattr_wrapper: + llgtr %r2,%r2 # char * + llgtr %r3,%r3 # char * + llgfr %r4,%r4 # size_t + jg sys_listxattr + + .globl sys32_llistxattr_wrapper +sys32_llistxattr_wrapper: + llgtr %r2,%r2 # char * + llgtr %r3,%r3 # char * + llgfr %r4,%r4 # size_t + jg sys_llistxattr + + .globl sys32_flistxattr_wrapper +sys32_flistxattr_wrapper: + lgfr %r2,%r2 # int + llgtr %r3,%r3 # char * + llgfr %r4,%r4 # size_t + jg sys_flistxattr + + .globl sys32_removexattr_wrapper +sys32_removexattr_wrapper: + llgtr %r2,%r2 # char * + llgtr %r3,%r3 # char * + jg sys_removexattr + + .globl sys32_lremovexattr_wrapper +sys32_lremovexattr_wrapper: + llgtr %r2,%r2 # char * + llgtr %r3,%r3 # char * + jg sys_lremovexattr + + .globl sys32_fremovexattr_wrapper +sys32_fremovexattr_wrapper: + lgfr %r2,%r2 # int + llgtr %r3,%r3 # char * + jg sys_fremovexattr + + .globl sys32_sched_setaffinity_wrapper +sys32_sched_setaffinity_wrapper: + lgfr %r2,%r2 # int + llgfr %r3,%r3 # unsigned int + llgtr %r4,%r4 # unsigned long * + jg sys32_sched_setaffinity + + .globl sys32_sched_getaffinity_wrapper +sys32_sched_getaffinity_wrapper: + lgfr %r2,%r2 # int + llgfr %r3,%r3 # unsigned int + llgtr %r4,%r4 # unsigned long * + jg sys32_sched_getaffinity + + .globl sys32_exit_group_wrapper +sys32_exit_group_wrapper: + lgfr %r2,%r2 # int + jg sys_exit_group # branch to system call + + .globl sys32_set_tid_address_wrapper +sys32_set_tid_address_wrapper: + llgtr %r2,%r2 # int * + jg sys_set_tid_address # branch to system call diff -urN linux-2.5.67/arch/s390/kernel/cpcmd.c linux-2.5.67-s390/arch/s390/kernel/cpcmd.c --- linux-2.5.67/arch/s390/kernel/cpcmd.c Mon Apr 7 19:31:15 2003 +++ linux-2.5.67-s390/arch/s390/kernel/cpcmd.c Mon Apr 14 19:11:56 2003 @@ -10,19 +10,26 @@ #include <linux/kernel.h> #include <linux/string.h> #include <asm/ebcdic.h> +#include <linux/spinlock.h> #include <asm/cpcmd.h> +#include <asm/system.h> + +static spinlock_t cpcmd_lock = SPIN_LOCK_UNLOCKED; +static char cpcmd_buf[128]; void cpcmd(char *cmd, char *response, int rlen) { const int mask = 0x40000000L; - char obuffer[128]; - int olen; + unsigned long flags; + int cmdlen; - olen = strlen(cmd); - strcpy(obuffer, cmd); - ASCEBC(obuffer,olen); + spin_lock_irqsave(&cpcmd_lock, flags); + cmdlen = strlen(cmd); + strcpy(cpcmd_buf, cmd); + ASCEBC(cpcmd_buf, cmdlen); if (response != NULL && rlen > 0) { +#ifndef CONFIG_ARCH_S390X asm volatile ("LRA 2,0(%0)\n\t" "LR 4,%1\n\t" "O 4,%4\n\t" @@ -30,17 +37,43 @@ "LR 5,%3\n\t" ".long 0x83240008 # Diagnose 83\n\t" : /* no output */ - : "a" (obuffer), "d" (olen), + : "a" (cpcmd_buf), "d" (cmdlen), + "a" (response), "d" (rlen), "m" (mask) + : "2", "3", "4", "5" ); +#else /* CONFIG_ARCH_S390X */ + asm volatile (" lrag 2,0(%0)\n" + " lgr 4,%1\n" + " o 4,%4\n" + " lrag 3,0(%2)\n" + " lgr 5,%3\n" + " sam31\n" + " .long 0x83240008 # Diagnose 83\n" + " sam64" + : /* no output */ + : "a" (cpcmd_buf), "d" (cmdlen), "a" (response), "d" (rlen), "m" (mask) : "2", "3", "4", "5" ); +#endif /* CONFIG_ARCH_S390X */ EBCASC(response, rlen); } else { +#ifndef CONFIG_ARCH_S390X asm volatile ("LRA 2,0(%0)\n\t" "LR 3,%1\n\t" ".long 0x83230008 # Diagnose 83\n\t" : /* no output */ - : "a" (obuffer), "d" (olen) + : "a" (cpcmd_buf), "d" (cmdlen) + : "2", "3" ); +#else /* CONFIG_ARCH_S390X */ + asm volatile (" lrag 2,0(%0)\n" + " lgr 3,%1\n" + " sam31\n" + " .long 0x83230008 # Diagnose 83\n" + " sam64" + : /* no output */ + : "a" (cpcmd_buf), "d" (cmdlen) : "2", "3" ); +#endif /* CONFIG_ARCH_S390X */ } + spin_unlock_irqrestore(&cpcmd_lock, flags); } diff -urN linux-2.5.67/arch/s390/kernel/debug.c linux-2.5.67-s390/arch/s390/kernel/debug.c --- linux-2.5.67/arch/s390/kernel/debug.c Mon Apr 7 19:30:42 2003 +++ linux-2.5.67-s390/arch/s390/kernel/debug.c Mon Apr 14 19:11:56 2003 @@ -16,7 +16,6 @@ #include <linux/errno.h> #include <linux/slab.h> #include <linux/ctype.h> -#include <linux/version.h> #include <asm/uaccess.h> #include <asm/semaphore.h> @@ -1111,17 +1110,10 @@ except_str = "*"; else except_str = "-"; - caller = (unsigned long) entry->caller; -#if defined(CONFIG_ARCH_S390X) - rc += sprintf(out_buf, "%02i %011lu:%06lu %1u %1s %02i %016lx ", + caller = ((unsigned long) entry->caller) & PSW_ADDR_INSN; + rc += sprintf(out_buf, "%02i %011lu:%06lu %1u %1s %02i %p ", area, time_val.tv_sec, time_val.tv_usec, level, - except_str, entry->id.fields.cpuid, caller); -#else - caller &= 0x7fffffff; - rc += sprintf(out_buf, "%02i %011lu:%06lu %1u %1s %02i %08lx ", - area, time_val.tv_sec, time_val.tv_usec, level, - except_str, entry->id.fields.cpuid, caller); -#endif + except_str, entry->id.fields.cpuid, (void *) caller); return rc; } diff -urN linux-2.5.67/arch/s390/kernel/entry.S linux-2.5.67-s390/arch/s390/kernel/entry.S --- linux-2.5.67/arch/s390/kernel/entry.S Mon Apr 14 19:11:52 2003 +++ linux-2.5.67-s390/arch/s390/kernel/entry.S Mon Apr 14 19:11:56 2003 @@ -364,271 +364,12 @@ l %r1,BASED(.Lsigaltstack) br %r1 # branch to sys_sigreturn - .globl sys_call_table + +#define SYSCALL(esa,esame,emu) .long esa + .globl sys_call_table sys_call_table: - .long sys_ni_syscall /* 0 */ - .long sys_exit - .long sys_fork_glue - .long sys_read - .long sys_write - .long sys_open /* 5 */ - .long sys_close - .long sys_restart_syscall - .long sys_creat - .long sys_link - .long sys_unlink /* 10 */ - .long sys_execve_glue - .long sys_chdir - .long sys_time - .long sys_mknod - .long sys_chmod /* 15 */ - .long sys_lchown16 - .long sys_ni_syscall /* old break syscall holder */ - .long sys_ni_syscall /* old stat syscall holder */ - .long sys_lseek - .long sys_getpid /* 20 */ - .long sys_mount - .long sys_oldumount - .long sys_setuid16 - .long sys_getuid16 - .long sys_stime /* 25 */ - .long sys_ptrace - .long sys_alarm - .long sys_ni_syscall /* old fstat syscall holder */ - .long sys_pause - .long sys_utime /* 30 */ - .long sys_ni_syscall /* old stty syscall holder */ - .long sys_ni_syscall /* old gtty syscall holder */ - .long sys_access - .long sys_nice - .long sys_ni_syscall /* 35 */ /* old ftime syscall holder */ - .long sys_sync - .long sys_kill - .long sys_rename - .long sys_mkdir - .long sys_rmdir /* 40 */ - .long sys_dup - .long sys_pipe - .long sys_times - .long sys_ni_syscall /* old prof syscall holder */ - .long sys_brk /* 45 */ - .long sys_setgid16 - .long sys_getgid16 - .long sys_signal - .long sys_geteuid16 - .long sys_getegid16 /* 50 */ - .long sys_acct - .long sys_umount - .long sys_ni_syscall /* old lock syscall holder */ - .long sys_ioctl - .long sys_fcntl /* 55 */ - .long sys_ni_syscall /* old mpx syscall holder */ - .long sys_setpgid - .long sys_ni_syscall /* old ulimit syscall holder */ - .long sys_ni_syscall /* old uname syscall holder */ - .long sys_umask /* 60 */ - .long sys_chroot - .long sys_ustat - .long sys_dup2 - .long sys_getppid - .long sys_getpgrp /* 65 */ - .long sys_setsid - .long sys_sigaction - .long sys_ni_syscall /* old sgetmask syscall holder */ - .long sys_ni_syscall /* old ssetmask syscall holder */ - .long sys_setreuid16 /* 70 */ - .long sys_setregid16 - .long sys_sigsuspend_glue - .long sys_sigpending - .long sys_sethostname - .long sys_setrlimit /* 75 */ - .long sys_old_getrlimit - .long sys_getrusage - .long sys_gettimeofday - .long sys_settimeofday - .long sys_getgroups16 /* 80 */ - .long sys_setgroups16 - .long sys_ni_syscall /* old select syscall holder */ - .long sys_symlink - .long sys_ni_syscall /* old lstat syscall holder */ - .long sys_readlink /* 85 */ - .long sys_uselib - .long sys_swapon - .long sys_reboot - .long sys_ni_syscall /* old readdir syscall holder */ - .long old_mmap /* 90 */ - .long sys_munmap - .long sys_truncate - .long sys_ftruncate - .long sys_fchmod - .long sys_fchown16 /* 95 */ - .long sys_getpriority - .long sys_setpriority - .long sys_ni_syscall /* old profil syscall holder */ - .long sys_statfs - .long sys_fstatfs /* 100 */ - .long sys_ioperm - .long sys_socketcall - .long sys_syslog - .long sys_setitimer - .long sys_getitimer /* 105 */ - .long sys_newstat - .long sys_newlstat - .long sys_newfstat - .long sys_ni_syscall /* old uname syscall holder */ - .long sys_ni_syscall /* 110 */ /* iopl for i386 */ - .long sys_vhangup - .long sys_ni_syscall /* old "idle" system call */ - .long sys_ni_syscall /* vm86old for i386 */ - .long sys_wait4 - .long sys_swapoff /* 115 */ - .long sys_sysinfo - .long sys_ipc - .long sys_fsync - .long sys_sigreturn_glue - .long sys_clone_glue /* 120 */ - .long sys_setdomainname - .long sys_newuname - .long sys_ni_syscall /* modify_ldt for i386 */ - .long sys_adjtimex - .long sys_mprotect /* 125 */ - .long sys_sigprocmask - .long sys_ni_syscall /* old "create module" */ - .long sys_init_module - .long sys_delete_module - .long sys_ni_syscall /* 130: old get_kernel_syms */ - .long sys_quotactl - .long sys_getpgid - .long sys_fchdir - .long sys_bdflush - .long sys_sysfs /* 135 */ - .long sys_personality - .long sys_ni_syscall /* for afs_syscall */ - .long sys_setfsuid16 - .long sys_setfsgid16 - .long sys_llseek /* 140 */ - .long sys_getdents - .long sys_select - .long sys_flock - .long sys_msync - .long sys_readv /* 145 */ - .long sys_writev - .long sys_getsid - .long sys_fdatasync - .long sys_sysctl - .long sys_mlock /* 150 */ - .long sys_munlock - .long sys_mlockall - .long sys_munlockall - .long sys_sched_setparam - .long sys_sched_getparam /* 155 */ - .long sys_sched_setscheduler - .long sys_sched_getscheduler - .long sys_sched_yield - .long sys_sched_get_priority_max - .long sys_sched_get_priority_min /* 160 */ - .long sys_sched_rr_get_interval - .long sys_nanosleep - .long sys_mremap - .long sys_setresuid16 - .long sys_getresuid16 /* 165 */ - .long sys_ni_syscall /* for vm86 */ - .long sys_ni_syscall /* old sys_query_module */ - .long sys_poll - .long sys_nfsservctl - .long sys_setresgid16 /* 170 */ - .long sys_getresgid16 - .long sys_prctl - .long sys_rt_sigreturn_glue - .long sys_rt_sigaction - .long sys_rt_sigprocmask /* 175 */ - .long sys_rt_sigpending - .long sys_rt_sigtimedwait - .long sys_rt_sigqueueinfo - .long sys_rt_sigsuspend_glue - .long sys_pread64 /* 180 */ - .long sys_pwrite64 - .long sys_chown16 - .long sys_getcwd - .long sys_capget - .long sys_capset /* 185 */ - .long sys_sigaltstack_glue - .long sys_sendfile - .long sys_ni_syscall /* streams1 */ - .long sys_ni_syscall /* streams2 */ - .long sys_vfork_glue /* 190 */ - .long sys_getrlimit - .long sys_mmap2 - .long sys_truncate64 - .long sys_ftruncate64 - .long sys_stat64 /* 195 */ - .long sys_lstat64 - .long sys_fstat64 - .long sys_lchown - .long sys_getuid - .long sys_getgid /* 200 */ - .long sys_geteuid - .long sys_getegid - .long sys_setreuid - .long sys_setregid - .long sys_getgroups /* 205 */ - .long sys_setgroups - .long sys_fchown - .long sys_setresuid - .long sys_getresuid - .long sys_setresgid /* 210 */ - .long sys_getresgid - .long sys_chown - .long sys_setuid - .long sys_setgid - .long sys_setfsuid /* 215 */ - .long sys_setfsgid - .long sys_pivot_root - .long sys_mincore - .long sys_madvise - .long sys_getdents64 /* 220 */ - .long sys_fcntl64 - .long sys_readahead - .long sys_sendfile64 - .long sys_setxattr - .long sys_lsetxattr /* 225 */ - .long sys_fsetxattr - .long sys_getxattr - .long sys_lgetxattr - .long sys_fgetxattr - .long sys_listxattr /* 230 */ - .long sys_llistxattr - .long sys_flistxattr - .long sys_removexattr - .long sys_lremovexattr - .long sys_fremovexattr /* 235 */ - .long sys_gettid - .long sys_tkill - .long sys_futex - .long sys_sched_setaffinity - .long sys_sched_getaffinity /* 240 */ - .long sys_ni_syscall - .long sys_ni_syscall /* reserved for TUX */ - .long sys_io_setup - .long sys_io_destroy - .long sys_io_getevents /* 245 */ - .long sys_io_submit - .long sys_io_cancel - .long sys_exit_group - .long sys_epoll_create - .long sys_epoll_ctl /* 250 */ - .long sys_epoll_wait - .long sys_set_tid_address - .long sys_fadvise64 - .long sys_timer_create - .long sys_timer_settime /* 255 */ - .long sys_timer_gettime - .long sys_timer_getoverrun - .long sys_timer_delete - .long sys_clock_settime - .long sys_clock_gettime - .long sys_clock_getres - .long sys_clock_nanosleep +#include "syscalls.S" +#undef SYSCALL /* * Program check handler routine diff -urN linux-2.5.67/arch/s390/kernel/entry64.S linux-2.5.67-s390/arch/s390/kernel/entry64.S --- linux-2.5.67/arch/s390/kernel/entry64.S Thu Jan 1 01:00:00 1970 +++ linux-2.5.67-s390/arch/s390/kernel/entry64.S Mon Apr 14 19:11:56 2003 @@ -0,0 +1,710 @@ +/* + * arch/s390/kernel/entry.S + * S390 low-level entry points. + * + * S390 version + * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation + * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), + * Hartmut Penner (hp@de.ibm.com), + * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), + */ + +#include <linux/sys.h> +#include <linux/linkage.h> +#include <linux/config.h> +#include <asm/cache.h> +#include <asm/lowcore.h> +#include <asm/errno.h> +#include <asm/ptrace.h> +#include <asm/thread_info.h> +#include <asm/offsets.h> +#include <asm/unistd.h> + +/* + * Stack layout for the system_call stack entry. + * The first few entries are identical to the user_regs_struct. + */ +SP_PTREGS = STACK_FRAME_OVERHEAD +SP_PSW = STACK_FRAME_OVERHEAD + PT_PSWMASK +SP_R0 = STACK_FRAME_OVERHEAD + PT_GPR0 +SP_R1 = STACK_FRAME_OVERHEAD + PT_GPR1 +SP_R2 = STACK_FRAME_OVERHEAD + PT_GPR2 +SP_R3 = STACK_FRAME_OVERHEAD + PT_GPR3 +SP_R4 = STACK_FRAME_OVERHEAD + PT_GPR4 +SP_R5 = STACK_FRAME_OVERHEAD + PT_GPR5 +SP_R6 = STACK_FRAME_OVERHEAD + PT_GPR6 +SP_R7 = STACK_FRAME_OVERHEAD + PT_GPR7 +SP_R8 = STACK_FRAME_OVERHEAD + PT_GPR8 +SP_R9 = STACK_FRAME_OVERHEAD + PT_GPR9 +SP_R10 = STACK_FRAME_OVERHEAD + PT_GPR10 +SP_R11 = STACK_FRAME_OVERHEAD + PT_GPR11 +SP_R12 = STACK_FRAME_OVERHEAD + PT_GPR12 +SP_R13 = STACK_FRAME_OVERHEAD + PT_GPR13 +SP_R14 = STACK_FRAME_OVERHEAD + PT_GPR14 +SP_R15 = STACK_FRAME_OVERHEAD + PT_GPR15 +SP_AREGS = STACK_FRAME_OVERHEAD + PT_ACR0 +SP_ORIG_R2 = STACK_FRAME_OVERHEAD + PT_ORIGGPR2 +/* Now the additional entries */ +SP_TRAP = (SP_ORIG_R2+GPR_SIZE) +SP_SIZE = (SP_TRAP+4) + +_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_RESTART_SVC) +_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED) + +/* + * Register usage in interrupt handlers: + * R9 - pointer to current task structure + * R13 - pointer to literal pool + * R14 - return register for function calls + * R15 - kernel stack pointer + */ + + .macro SAVE_ALL psworg,sync # system entry macro + stmg %r14,%r15,__LC_SAVE_AREA + stam %a2,%a4,__LC_SAVE_AREA+16 + larl %r14,.Lconst + tm \psworg+1,0x01 # test problem state bit + .if \sync + jz 1f # skip stack setup save + .else + jnz 0f # from user -> load kernel stack + lg %r14,__LC_ASYNC_STACK # are we already on the async. stack ? + slgr %r14,%r15 + srag %r14,%r14,14 + larl %r14,.Lconst + jz 1f + lg %r15,__LC_ASYNC_STACK # load async. stack + j 1f + .endif +0: lg %r15,__LC_KERNEL_STACK # problem state -> load ksp + lam %a2,%a4,.Lc_ac-.Lconst(%r14) +1: aghi %r15,-SP_SIZE # make room for registers & psw + nill %r15,0xfff8 # align stack pointer to 8 + stmg %r0,%r13,SP_R0(%r15) # store gprs 0-13 to kernel stack + stg %r2,SP_ORIG_R2(%r15) # store original content of gpr 2 + mvc SP_R14(16,%r15),__LC_SAVE_AREA # move r14 and r15 to stack + stam %a0,%a15,SP_AREGS(%r15) # store access registers to kst. + mvc SP_AREGS+8(12,%r15),__LC_SAVE_AREA+16 # store ac. regs + mvc SP_PSW(16,%r15),\psworg # move user PSW to stack + mvc SP_TRAP(4,%r15),.L\psworg-.Lconst(%r14) # store trap ind. + xc 0(8,%r15),0(%r15) # clear back chain + .endm + + .macro RESTORE_ALL sync # system exit macro + mvc __LC_RETURN_PSW(16),SP_PSW(%r15) # move user PSW to lowcore + lam %a0,%a15,SP_AREGS(%r15) # load the access registers + lmg %r0,%r15,SP_R0(%r15) # load gprs 0-15 of user + ni __LC_RETURN_PSW+1,0xfd # clear wait state bit + lpswe __LC_RETURN_PSW # back to caller + .endm + + .macro GET_THREAD_INFO + lg %r9,__LC_KERNEL_STACK # load pointer to task_struct to %r9 + aghi %r9,-16384 + .endm + + +/* + * Scheduler resume function, called by switch_to + * gpr2 = (task_struct *) prev + * gpr3 = (task_struct *) next + * Returns: + * gpr2 = prev + */ + .globl resume +resume: + tm __THREAD_per+4(%r3),0xe8 # is the new process using per ? + jz resume_noper # if not we're fine + stctg %c9,%c11,48(%r15) # We are using per stuff + clc __THREAD_per(24,%r3),48(%r15) + je resume_noper # we got away without bashing TLB's + lctlg %c9,%c11,__THREAD_per(%r3) # Nope we didn't +resume_noper: + stmg %r6,%r15,48(%r15) # store resume registers of prev task + stg %r15,__THREAD_ksp(%r2) # store kernel stack to prev->tss.ksp + lg %r15,__THREAD_ksp(%r3) # load kernel stack from next->tss.ksp + stam %a2,%a2,__THREAD_ar2(%r2) # store kernel access reg. 2 + stam %a4,%a4,__THREAD_ar4(%r2) # store kernel access reg. 4 + lam %a2,%a2,__THREAD_ar2(%r3) # load kernel access reg. 2 + lam %a4,%a4,__THREAD_ar4(%r3) # load kernel access reg. 4 + lmg %r6,%r15,48(%r15) # load resume registers of next task + lg %r3,__THREAD_info(%r3) # load thread_info from task struct + aghi %r3,16384 + stg %r3,__LC_KERNEL_STACK # __LC_KERNEL_STACK = new kernel stack + br %r14 + +/* + * do_softirq calling function. We want to run the softirq functions on the + * asynchronous interrupt stack. + */ + .global do_call_softirq +do_call_softirq: + stmg %r12,%r15,48(%r15) + lgr %r12,%r15 + lg %r0,__LC_ASYNC_STACK + slgr %r0,%r15 + srag %r0,%r0,14 + je 0f + lg %r15,__LC_ASYNC_STACK +0: aghi %r15,-STACK_FRAME_OVERHEAD + stg %r12,0(%r15) # store back chain + brasl %r14,do_softirq + lmg %r12,%r15,48(%r12) + br %r14 + +/* + * SVC interrupt handler routine. System calls are synchronous events and + * are executed with interrupts enabled. + */ + + .globl system_call +system_call: + SAVE_ALL __LC_SVC_OLD_PSW,1 + llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore + stosm 48(%r15),0x03 # reenable interrupts + GET_THREAD_INFO # load pointer to task_struct to R9 + slag %r7,%r7,2 # *4 and test for svc 0 + jnz sysc_do_restart + # svc 0: system call number in %r1 + clg %r1,.Lnr_syscalls-.Lconst(%r14) + jnl sysc_do_restart + slag %r7,%r1,2 # svc 0: system call number in %r1 +sysc_do_restart: + larl %r10,sys_call_table +#ifdef CONFIG_S390_SUPPORT + tm SP_PSW+3(%r15),0x01 # are we running in 31 bit mode ? + jo sysc_noemu + larl %r10,sys_call_table_emu # use 31 bit emulation system calls +sysc_noemu: +#endif + tm __TI_flags+7(%r9),_TIF_SYSCALL_TRACE + lgf %r8,0(%r7,%r10) # load address of system call routine + jo sysc_tracesys + basr %r14,%r8 # call sys_xxxx + stg %r2,SP_R2(%r15) # store return value (change R2 on stack) + # ATTENTION: check sys_execve_glue before + # changing anything here !! + +sysc_return: + stnsm 48(%r15),0xfc # disable I/O and ext. interrupts + tm __TI_flags+7(%r9),_TIF_WORK_SVC + jnz sysc_work # there is work to do (signals etc.) +sysc_leave: + RESTORE_ALL 1 + +# +# recheck if there is more work to do +# +sysc_work_loop: + stnsm 48(%r15),0xfc # disable I/O and ext. interrupts + GET_THREAD_INFO # load pointer to task_struct to R9 + tm __TI_flags+7(%r9),_TIF_WORK_SVC + jz sysc_leave # there is no work to do +# +# One of the work bits is on. Find out which one. +# Checked are: _TIF_SIGPENDING and _TIF_NEED_RESCHED +# +sysc_work: + tm __TI_flags+7(%r9),_TIF_NEED_RESCHED + jo sysc_reschedule + tm __TI_flags+7(%r9),_TIF_SIGPENDING + jo sysc_sigpending + tm __TI_flags+7(%r9),_TIF_RESTART_SVC + jo sysc_restart + j sysc_leave + +# +# _TIF_NEED_RESCHED is set, call schedule +# +sysc_reschedule: + stosm 48(%r15),0x03 # reenable interrupts + larl %r14,sysc_work_loop + jg schedule # return point is sysc_return + +# +# _TIF_SIGPENDING is set, call do_signal +# +sysc_sigpending: + stosm 48(%r15),0x03 # reenable interrupts + la %r2,SP_PTREGS(%r15) # load pt_regs + sgr %r3,%r3 # clear *oldset + brasl %r14,do_signal # call do_signal + stnsm 48(%r15),0xfc # disable I/O and ext. interrupts + j sysc_leave # out of here, do NOT recheck + +# +# _TIF_RESTART_SVC is set, set up registers and restart svc +# +sysc_restart: + ni __TI_flags+3(%r9),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC + stosm 48(%r15),0x03 # reenable interrupts + lg %r7,SP_R2(%r15) # load new svc number + slag %r7,%r7,3 # *8 + mvc SP_R2(8,%r15),SP_ORIG_R2(%r15) # restore first argument + lmg %r2,%r6,SP_R2(%r15) # load svc arguments + j sysc_do_restart # restart svc + +# +# call syscall_trace before and after system call +# special linkage: %r12 contains the return address for trace_svc +# +sysc_tracesys: + srl %r7,3 + stg %r7,SP_R2(%r15) + brasl %r14,syscall_trace + larl %r1,.Lnr_syscalls + clc SP_R2(8,%r15),0(%r1) + jl sysc_tracego + lg %r7,SP_R2(%r15) # strace might have changed the + sll %r7,3 # system call + lgf %r8,0(%r7,%r10) +sysc_tracego: + lmg %r3,%r6,SP_R3(%r15) + lg %r2,SP_ORIG_R2(%r15) + basr %r14,%r8 # call sys_xxx + stg %r2,SP_R2(%r15) # store return value + tm __TI_flags+7(%r9),_TIF_SYSCALL_TRACE + jno sysc_return + larl %r14,sysc_return # return point is sysc_return + jg syscall_trace + +# +# a new process exits the kernel with ret_from_fork +# + .globl ret_from_fork +ret_from_fork: + GET_THREAD_INFO # load pointer to task_struct to R9 + larl %r14,sysc_return + jg schedule_tail # return to sysc_return + +# +# clone, fork, vfork, exec and sigreturn need glue, +# because they all expect pt_regs as parameter, +# but are called with different parameter. +# return-address is set up above +# +sys_clone_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs + jg sys_clone # branch to sys_clone + +#ifdef CONFIG_S390_SUPPORT +sys32_clone_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs + jg sys32_clone # branch to sys32_clone +#endif + +sys_fork_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs + jg sys_fork # branch to sys_fork + +sys_vfork_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs + jg sys_vfork # branch to sys_vfork + +sys_execve_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs + lgr %r12,%r14 # save return address + brasl %r14,sys_execve # call sys_execve + ltgr %r2,%r2 # check if execve failed + bnz 0(%r12) # it did fail -> store result in gpr2 + b 6(%r12) # SKIP STG 2,SP_R2(15) in + # system_call/sysc_tracesys +#ifdef CONFIG_S390_SUPPORT +sys32_execve_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs + lgr %r12,%r14 # save return address + brasl %r14,sys32_execve # call sys32_execve + ltgr %r2,%r2 # check if execve failed + bnz 0(%r12) # it did fail -> store result in gpr2 + b 6(%r12) # SKIP STG 2,SP_R2(15) in + # system_call/sysc_tracesys +#endif + +sys_sigreturn_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs as parameter + jg sys_sigreturn # branch to sys_sigreturn + +#ifdef CONFIG_S390_SUPPORT +sys32_sigreturn_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs as parameter + jg sys32_sigreturn # branch to sys32_sigreturn +#endif + +sys_rt_sigreturn_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs as parameter + jg sys_rt_sigreturn # branch to sys_sigreturn + +#ifdef CONFIG_S390_SUPPORT +sys32_rt_sigreturn_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs as parameter + jg sys32_rt_sigreturn # branch to sys32_sigreturn +#endif + +# +# sigsuspend and rt_sigsuspend need pt_regs as an additional +# parameter and they have to skip the store of %r2 into the +# user register %r2 because the return value was set in +# sigsuspend and rt_sigsuspend already and must not be overwritten! +# + +sys_sigsuspend_glue: + lgr %r5,%r4 # move mask back + lgr %r4,%r3 # move history1 parameter + lgr %r3,%r2 # move history0 parameter + la %r2,SP_PTREGS(%r15) # load pt_regs as first parameter + la %r14,6(%r14) # skip store of return value + jg sys_sigsuspend # branch to sys_sigsuspend + +#ifdef CONFIG_S390_SUPPORT +sys32_sigsuspend_glue: + llgfr %r4,%r4 # unsigned long + lgr %r5,%r4 # move mask back + lgfr %r3,%r3 # int + lgr %r4,%r3 # move history1 parameter + lgfr %r2,%r2 # int + lgr %r3,%r2 # move history0 parameter + la %r2,SP_PTREGS(%r15) # load pt_regs as first parameter + la %r14,6(%r14) # skip store of return value + jg sys32_sigsuspend # branch to sys32_sigsuspend +#endif + +sys_rt_sigsuspend_glue: + lgr %r4,%r3 # move sigsetsize parameter + lgr %r3,%r2 # move unewset parameter + la %r2,SP_PTREGS(%r15) # load pt_regs as first parameter + la %r14,6(%r14) # skip store of return value + jg sys_rt_sigsuspend # branch to sys_rt_sigsuspend + +#ifdef CONFIG_S390_SUPPORT +sys32_rt_sigsuspend_glue: + llgfr %r3,%r3 # size_t + lgr %r4,%r3 # move sigsetsize parameter + llgtr %r2,%r2 # sigset_emu31_t * + lgr %r3,%r2 # move unewset parameter + la %r2,SP_PTREGS(%r15) # load pt_regs as first parameter + la %r14,6(%r14) # skip store of return value + jg sys32_rt_sigsuspend # branch to sys32_rt_sigsuspend +#endif + +sys_sigaltstack_glue: + la %r4,SP_PTREGS(%r15) # load pt_regs as parameter + jg sys_sigaltstack # branch to sys_sigreturn + +#ifdef CONFIG_S390_SUPPORT +sys32_sigaltstack_glue: + la %r4,SP_PTREGS(%r15) # load pt_regs as parameter + jg sys32_sigaltstack_wrapper # branch to sys_sigreturn +#endif + +#define SYSCALL(esa,esame,emu) .long esame + .globl sys_call_table +sys_call_table: +#include "syscalls.S" +#undef SYSCALL + +#ifdef CONFIG_S390_SUPPORT + +#define SYSCALL(esa,esame,emu) .long emu + .globl sys_call_table_emu +sys_call_table_emu: +#include "syscalls.S" +#undef SYSCALL +#endif + +/* + * Program check handler routine + */ + + .globl pgm_check_handler +pgm_check_handler: +/* + * First we need to check for a special case: + * Single stepping an instruction that disables the PER event mask will + * cause a PER event AFTER the mask has been set. Example: SVC or LPSW. + * For a single stepped SVC the program check handler gets control after + * the SVC new PSW has been loaded. But we want to execute the SVC first and + * then handle the PER event. Therefore we update the SVC old PSW to point + * to the pgm_check_handler and branch to the SVC handler after we checked + * if we have to load the kernel stack register. + * For every other possible cause for PER event without the PER mask set + * we just ignore the PER event (FIXME: is there anything we have to do + * for LPSW?). + */ + tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception + jnz pgm_per # got per exception -> special case + SAVE_ALL __LC_PGM_OLD_PSW,1 + lgf %r3,__LC_PGM_ILC # load program interruption code + lghi %r8,0x7f + ngr %r8,%r3 + sll %r8,3 + GET_THREAD_INFO + larl %r1,pgm_check_table + lg %r1,0(%r8,%r1) # load address of handler routine + la %r2,SP_PTREGS(%r15) # address of register-save area + larl %r14,sysc_return + br %r1 # branch to interrupt-handler + +# +# handle per exception +# +pgm_per: + tm __LC_PGM_OLD_PSW,0x40 # test if per event recording is on + jnz pgm_per_std # ok, normal per event from user space +# ok its one of the special cases, now we need to find out which one + clc __LC_PGM_OLD_PSW(16),__LC_SVC_NEW_PSW + je pgm_svcper +# no interesting special case, ignore PER event + lpswe __LC_PGM_OLD_PSW + +# +# Normal per exception +# +pgm_per_std: + SAVE_ALL __LC_PGM_OLD_PSW,1 + GET_THREAD_INFO + lghi %r4,0x7f + lgf %r3,__LC_PGM_ILC # load program interruption code + nr %r4,%r3 # clear per-event-bit and ilc + je pgm_per_only # only per of per+check ? + sll %r4,3 + larl %r1,pgm_check_table + lg %r1,0(%r4,%r1) # load address of handler routine + la %r2,SP_PTREGS(%r15) # address of register-save area + basr %r14,%r1 # branch to interrupt-handler +pgm_per_only: + la %r2,SP_PTREGS(15) # address of register-save area + larl %r14,sysc_return # load adr. of system return + jg handle_per_exception + +# +# it was a single stepped SVC that is causing all the trouble +# +pgm_svcper: + SAVE_ALL __LC_SVC_OLD_PSW,1 + llgh %r8,__LC_SVC_INT_CODE # get svc number from lowcore + stosm 48(%r15),0x03 # reenable interrupts + GET_THREAD_INFO # load pointer to task_struct to R9 + slag %r7,%r7,2 # *4 and test for svc 0 + jnz pgm_svcstd + # svc 0: system call number in %r1 + clg %r1,.Lnr_syscalls-.Lconst(%r14) + slag %r7,%r1,2 +pgm_svcstd: + larl %r7,sys_call_table +#ifdef CONFIG_S390_SUPPORT + tm SP_PSW+3(%r15),0x01 # are we running in 31 bit mode ? + jo pgm_svcper_noemu + larl %r7,sys_call_table_emu # use 31 bit emulation system calls +pgm_svcper_noemu: +#endif + tm __TI_flags+3(%r9),_TIF_SYSCALL_TRACE + lgf %r8,0(%r8,%r7) # load address of system call routine + jo pgm_tracesys + basr %r14,%r8 # call sys_xxxx + stg %r2,SP_R2(%r15) # store return value (change R2 on stack) + # ATTENTION: check sys_execve_glue before + # changing anything here !! + +pgm_svcret: + tm __TI_flags+3(%r9),_TIF_SIGPENDING + jo pgm_svcper_nosig + la %r2,SP_PTREGS(%r15) # load pt_regs + sgr %r3,%r3 # clear *oldset + brasl %r14,do_signal + +pgm_svcper_nosig: + lhi %r0,__LC_PGM_OLD_PSW # set trap indication back to pgm_chk + st %r0,SP_TRAP(%r15) + la %r2,SP_PTREGS(15) # address of register-save area + larl %r14,sysc_return # load adr. of system return + jg handle_per_exception +# +# call trace before and after sys_call +# +pgm_tracesys: + lgfr %r7,%r7 + stg %r7,SP_R2(%r15) + brasl %r14,syscall_trace + clc SP_R2(8,%r15),.Lnr_syscalls + jnl pgm_svc_go + lg %r2,SP_R2(%r15) + sllg %r2,%r2,3 # strace wants to change the syscall + lgf %r8,0(%r2,%r7) +pgm_svc_go: + lmg %r3,%r6,SP_R3(%r15) + lg %r2,SP_ORIG_R2(%r15) + basr %r14,%r8 # call sys_xxx + stg %r2,SP_R2(%r15) # store return value + tm __TI_flags+7(%r9),_TIF_SYSCALL_TRACE + jno pgm_svcret + larl %r14,pgm_svcret # return point is sysc_return + jg syscall_trace + +/* + * IO interrupt handler routine + */ + .globl io_int_handler +io_int_handler: + SAVE_ALL __LC_IO_OLD_PSW,0 + GET_THREAD_INFO # load pointer to task_struct to R9 + la %r2,SP_PTREGS(%r15) # address of register-save area + llgh %r3,__LC_SUBCHANNEL_NR # load subchannel number + llgf %r4,__LC_IO_INT_PARM # load interruption parm + llgf %r5,__LC_IO_INT_WORD # load interruption word + brasl %r14,do_IRQ # call standard irq handler + +io_return: + tm SP_PSW+1(%r15),0x01 # returning to user ? +#ifdef CONFIG_PREEMPT + jno io_preempt # no -> check for preemptive scheduling +#else + jno io_leave # no-> skip resched & signal +#endif + tm __TI_flags+7(%r9),_TIF_WORK_INT + jnz io_work # there is work to do (signals etc.) +io_leave: + RESTORE_ALL 0 + +#ifdef CONFIG_PREEMPT +io_preempt: + icm %r0,15,__TI_precount(%r9) + jnz io_leave +io_resume_loop: + tm __TI_flags+7(%r9),_TIF_NEED_RESCHED + jno io_leave + larl %r1,.Lc_pactive + mvc __TI_precount(4,%r9),0(%r1) + # hmpf, we are on the async. stack but to call schedule + # we have to move the interrupt frame to the process stack + lg %r1,SP_R15(%r15) + aghi %r1,-SP_SIZE + nill %r1,0xfff8 + mvc SP_PTREGS(SP_SIZE-SP_PTREGS,%r1),SP_PTREGS(%r15) + xc 0(8,%r1),0(%r1) # clear back chain + lgr %r15,%r1 + stosm 48(%r15),0x03 # reenable interrupts + brasl %r14,schedule # call schedule + stnsm 48(%r15),0xfc # disable I/O and ext. interrupts + GET_THREAD_INFO # load pointer to task_struct to R9 + xc __TI_precount(4,%r9),__TI_precount(%r9) + j io_resume_loop +#endif + +# +# recheck if there is more work to do +# +io_work_loop: + stnsm 48(%r15),0xfc # disable I/O and ext. interrupts + GET_THREAD_INFO # load pointer to task_struct to R9 + tm __TI_flags+7(%r9),_TIF_WORK_INT + jz io_leave # there is no work to do +# +# One of the work bits is on. Find out which one. +# Checked are: _TIF_SIGPENDING and _TIF_NEED_RESCHED +# +io_work: + tm __TI_flags+7(%r9),_TIF_NEED_RESCHED + jo io_reschedule + tm __TI_flags+7(%r9),_TIF_SIGPENDING + jo io_sigpending + j io_leave + +# +# _TIF_NEED_RESCHED is set, call schedule +# +io_reschedule: + stosm 48(%r15),0x03 # reenable interrupts + larl %r14,io_work_loop + jg schedule # call scheduler + +# +# _TIF_SIGPENDING is set, call do_signal +# +io_sigpending: + stosm 48(%r15),0x03 # reenable interrupts + la %r2,SP_PTREGS(%r15) # load pt_regs + slgr %r3,%r3 # clear *oldset + brasl %r14,do_signal # call do_signal + stnsm 48(%r15),0xfc # disable I/O and ext. interrupts + j sysc_leave # out of here, do NOT recheck + +/* + * External interrupt handler routine + */ + .globl ext_int_handler +ext_int_handler: + SAVE_ALL __LC_EXT_OLD_PSW,0 + GET_THREAD_INFO # load pointer to task_struct to R9 + llgh %r6,__LC_EXT_INT_CODE # get interruption code + lgr %r1,%r6 # calculate index = code & 0xff + nill %r1,0xff + sll %r1,3 + larl %r7,ext_int_hash + lg %r7,0(%r1,%r7) # get first list entry for hash value + ltgr %r7,%r7 # == NULL ? + jz io_return # yes, nothing to do, exit +ext_int_loop: + ch %r6,16(%r7) # compare external interrupt code + jne ext_int_next + lg %r1,8(%r7) # get handler address + la %r2,SP_PTREGS(%r15) # address of register-save area + lgr %r3,%r6 # interruption code + basr %r14,%r1 # call handler +ext_int_next: + lg %r7,0(%r7) # next list entry + ltgr %r7,%r7 + jnz ext_int_loop + j io_return + +/* + * Machine check handler routines + */ + .globl mcck_int_handler +mcck_int_handler: + SAVE_ALL __LC_MCK_OLD_PSW,0 + brasl %r14,s390_do_machine_check +mcck_return: + RESTORE_ALL 0 + +#ifdef CONFIG_SMP +/* + * Restart interruption handler, kick starter for additional CPUs + */ + .globl restart_int_handler +restart_int_handler: + lg %r15,__LC_SAVE_AREA+120 # load ksp + lghi %r10,__LC_CREGS_SAVE_AREA + lctlg %c0,%c15,0(%r10) # get new ctl regs + lghi %r10,__LC_AREGS_SAVE_AREA + lam %a0,%a15,0(%r10) + stosm 0(%r15),0x04 # now we can turn dat on + lmg %r6,%r15,48(%r15) # load registers from clone + jg start_secondary +#else +/* + * If we do not run with SMP enabled, let the new CPU crash ... + */ + .globl restart_int_handler +restart_int_handler: + basr %r1,0 +restart_base: + lpswe restart_crash-restart_base(%r1) + .align 8 +restart_crash: + .long 0x000a0000,0x00000000,0x00000000,0x00000000 +restart_go: +#endif + +/* + * Integer constants + */ + .align 4 +.Lconst: +.Lc_ac: .long 0,0,1 +.Lc_pactive: .long PREEMPT_ACTIVE +.L0x0130: .long 0x0130 +.L0x0140: .long 0x0140 +.L0x0150: .long 0x0150 +.L0x0160: .long 0x0160 +.L0x0170: .long 0x0170 +.Lnr_syscalls: .long NR_syscalls - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |