Commit a1366931 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] s390: core

From: Martin Schwidefsky <schwidefsky@de.ibm.com>

s390 core changes:
 - Merge 31 and 64 bit NR_CPUS config option. Default to 32 cpus.
 - Remove unused system calls from compat_linux.c.
 - Add statfs64 and fstatfs64. Reserve system call number for
   remap_file_pages.
 - Merge do_signal32 into do_signal.
 - Don't remove the per bit and the program mask from the user psw
   due to a signal.
 - Fix a problem with gdb and interrupted system calls.
 - Fix single stepping of interrupted system calls.
 - Fix compiler warnings in bitops.h.
parent 8142773c
......@@ -95,24 +95,11 @@ config SMP
Even if you don't know what to do here, say Y.
config NR_CPUS
int "Maximum number of CPUs (2-32)"
range 2 32
depends on SMP && ARCH_S390X = 'n'
default "32"
help
This allows you to specify the maximum number of CPUs which this
kernel will support. The maximum supported value is 32 and the
minimum value which makes sense is 2.
This is purely to save memory - each supported CPU adds
approximately eight kilobytes to the kernel image.
config NR_CPUS
int "Maximum number of CPUs (2-64)"
range 2 64
depends on SMP && ARCH_S390X
default "64"
depends on SMP
default "32"
help
This allows you to specify the maximum number of CPUs which this
kernel will support. The maximum supported value is 64 and the
......
......@@ -22,6 +22,10 @@ int main(void)
DEFINE(__THREAD_ksp, offsetof(struct task_struct, thread.ksp),);
DEFINE(__THREAD_per, offsetof(struct task_struct, thread.per_info),);
BLANK();
DEFINE(__PER_atmid, offsetof(per_struct, lowcore.words.perc_atmid),);
DEFINE(__PER_address, offsetof(per_struct, lowcore.words.address),);
DEFINE(__PER_access_id, offsetof(per_struct, lowcore.words.access_id),);
BLANK();
DEFINE(__TI_task, offsetof(struct thread_info, task),);
DEFINE(__TI_domain, offsetof(struct thread_info, exec_domain),);
DEFINE(__TI_flags, offsetof(struct thread_info, flags),);
......
......@@ -828,11 +828,6 @@ int cp_compat_stat(struct kstat *stat, struct compat_stat *statbuf)
return err;
}
asmlinkage int sys32_sysfs(int option, u32 arg1, u32 arg2)
{
return sys_sysfs(option, arg1, arg2);
}
struct ncp_mount_data32 {
int version;
unsigned int ncp_fd;
......@@ -1718,33 +1713,6 @@ asmlinkage int sys32_settimeofday(struct compat_timeval *tv, struct timezone *tz
return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
}
asmlinkage int sys32_utimes(char __user *filename,
struct compat_timeval __user *tvs)
{
char *kfilename;
struct timeval ktvs[2];
mm_segment_t old_fs;
int ret;
kfilename = getname(filename);
ret = PTR_ERR(kfilename);
if (!IS_ERR(kfilename)) {
if (tvs) {
if (get_tv32(&ktvs[0], tvs) ||
get_tv32(&ktvs[1], 1+tvs))
return -EFAULT;
}
old_fs = get_fs();
set_fs(KERNEL_DS);
ret = sys_utimes(kfilename, &ktvs[0]);
set_fs(old_fs);
putname(kfilename);
}
return ret;
}
/* These are here just in case some old sparc32 binary calls it. */
asmlinkage int sys32_pause(void)
{
......@@ -1753,17 +1721,6 @@ asmlinkage int sys32_pause(void)
return -ERESTARTNOHAND;
}
asmlinkage int sys32_prctl(int option, u32 arg2, u32 arg3, u32 arg4, u32 arg5)
{
return sys_prctl(option,
(unsigned long) arg2,
(unsigned long) arg3,
(unsigned long) arg4,
(unsigned long) arg5);
}
asmlinkage compat_ssize_t sys32_pread64(unsigned int fd, char *ubuf,
compat_size_t count, u32 poshi, u32 poslo)
{
......@@ -1897,13 +1854,6 @@ asmlinkage int sys32_adjtimex(struct timex32 *utp)
return ret;
}
asmlinkage int sys_setpriority32(u32 which, u32 who, u32 niceval)
{
return sys_setpriority((int) which,
(int) who,
(int) niceval);
}
struct __sysctl_args32 {
u32 name;
int nlen;
......
......@@ -144,6 +144,11 @@ typedef struct
PSW32_MASK_IO | PSW32_MASK_EXT | PSW32_MASK_MCHECK | \
PSW32_MASK_PSTATE)
#define PSW32_MASK_MERGE(CURRENT,NEW) \
(((CURRENT) & ~(PSW32_MASK_CC|PSW32_MASK_PM)) | \
((NEW) & (PSW32_MASK_CC|PSW32_MASK_PM)))
typedef struct
{
_psw_t32 psw;
......
......@@ -53,8 +53,6 @@ typedef struct
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;
......@@ -123,7 +121,7 @@ sys32_sigsuspend(struct pt_regs * regs,int history0, int history1, old_sigset_t
while (1) {
set_current_state(TASK_INTERRUPTIBLE);
schedule();
if (do_signal32(regs, &saveset))
if (do_signal(regs, &saveset))
return -EINTR;
}
}
......@@ -158,7 +156,7 @@ sys32_rt_sigsuspend(struct pt_regs * regs,compat_sigset_t *unewset, size_t sigse
while (1) {
set_current_state(TASK_INTERRUPTIBLE);
schedule();
if (do_signal32(regs, &saveset))
if (do_signal(regs, &saveset))
return -EINTR;
}
}
......@@ -294,8 +292,8 @@ 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.mask = PSW32_MASK_MERGE(PSW32_USER_BITS,
(__u32)(regs->psw.mask >> 32));
regs32.psw.addr = PSW32_ADDR_AMODE31 | (__u32) regs->psw.addr;
for (i = 0; i < NUM_GPRS; i++)
regs32.gprs[i] = (__u32) regs->gprs[i];
......@@ -320,8 +318,8 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 *sregs)
err = __copy_from_user(&regs32, &sregs->regs, sizeof(regs32));
if (err)
return err;
regs->psw.mask = PSW_USER32_BITS |
(__u64)(regs32.psw.mask & PSW32_MASK_CC) << 32;
regs->psw.mask = PSW_MASK_MERGE(regs->psw.mask,
(__u64)regs32.psw.mask << 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];
......@@ -482,7 +480,6 @@ static void setup_frame32(int sig, struct k_sigaction *ka,
/* 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;
......@@ -539,7 +536,6 @@ static void setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
/* 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;
......@@ -556,36 +552,12 @@ static void setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
* OK, we're invoking a handler
*/
static void
void
handle_signal32(unsigned long sig, siginfo_t *info, sigset_t *oldset,
struct pt_regs * regs)
{
struct k_sigaction *ka = &current->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 -ERESTART_RESTARTBLOCK:
current_thread_info()->restart_block.fn =
do_no_restart_syscall;
clear_thread_flag(TIF_RESTART_SVC);
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 -= regs->ilc;
}
}
/* Set up the stack frame */
if (ka->sa.sa_flags & SA_SIGINFO)
setup_rt_frame32(sig, ka, info, oldset, regs);
......@@ -604,53 +576,3 @@ handle_signal32(unsigned long sig, siginfo_t *info, sigset_t *oldset,
}
}
/*
* 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 = &current->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 -= regs->ilc;
}
/* Restart the system call with a new system call number */
if (regs->gprs[2] == -ERESTART_RESTARTBLOCK) {
regs->gprs[2] = __NR_restart_syscall;
set_thread_flag(TIF_RESTART_SVC);
}
}
return 0;
}
......@@ -1097,6 +1097,7 @@ compat_sys_futex_wrapper:
lgfr %r3,%r3 # int
lgfr %r4,%r4 # int
llgtr %r5,%r5 # struct compat_timespec *
llgtr %r6,%r6 # u32 *
jg compat_sys_futex # branch to system call
.globl sys32_setxattr_wrapper
......@@ -1338,3 +1339,17 @@ sys32_io_cancel_wrapper:
llgtr %r3,%r3 # struct iocb *
llgtr %r4,%r4 # struct io_event *
jg sys_io_cancel
.globl compat_sys_statfs64_wrapper
compat_sys_statfs64_wrapper:
llgtr %r2,%r2 # const char *
llgfr %r3,%r3 # compat_size_t
llgtr %r4,%r4 # struct compat_statfs64 *
jg compat_statfs64
.globl compat_sys_fstatfs64_wrapper
compat_sys_fstatfs64_wrapper:
llgfr %r2,%r2 # unsigned int fd
llgfr %r3,%r3 # compat_size_t
llgtr %r4,%r4 # struct compat_statfs64 *
jg compat_fstatfs64
......@@ -432,6 +432,9 @@ pgm_per:
pgm_per_std:
SAVE_ALL __LC_PGM_OLD_PSW,1
GET_THREAD_INFO
mvc __THREAD_per+__PER_atmid(2,%r9),__LC_PER_ATMID
mvc __THREAD_per+__PER_address(4,%r9),__LC_PER_ADDRESS
mvc __THREAD_per+__PER_access_id(1,%r9),__LC_PER_ACCESS_ID
la %r4,0x7f
l %r3,__LC_PGM_ILC # load program interruption code
nr %r4,%r3 # clear per-event-bit and ilc
......@@ -445,7 +448,7 @@ pgm_per_only:
la %r2,SP_PTREGS(15) # address of register-save area
l %r1,BASED(.Lhandle_per) # load adr. of per handler
la %r14,BASED(sysc_return) # load adr. of system return
br %r1 # branch to handle_per_exception
br %r1 # branch to do_debugger_trap
#
# it was a single stepped SVC that is causing all the trouble
......@@ -455,6 +458,9 @@ pgm_svcper:
lh %r7,0x8a # get svc number from lowcore
stosm 24(%r15),0x03 # reenable interrupts
GET_THREAD_INFO # load pointer to task_struct to R9
mvc __THREAD_per+__PER_atmid(2,%r9),__LC_PER_ATMID
mvc __THREAD_per+__PER_address(4,%r9),__LC_PER_ADDRESS
mvc __THREAD_per+__PER_access_id(1,%r9),__LC_PER_ACCESS_ID
sla %r7,2 # *4 and test for svc 0
bnz BASED(pgm_svcstd) # svc number > 0 ?
# svc 0: system call number in %r1
......@@ -473,18 +479,18 @@ pgm_svcstd:
pgm_svcret:
tm __TI_flags+3(%r9),_TIF_SIGPENDING
bo BASED(pgm_svcper_nosig)
bno BASED(pgm_svcper_nosig)
la %r2,SP_PTREGS(%r15) # load pt_regs
sr %r3,%r3 # clear *oldset
l %r1,BASED(.Ldo_signal)
basr %r4,%r1 # call do_signal
basr %r14,%r1 # call do_signal
pgm_svcper_nosig:
mvi SP_TRAP+3(%r15),0x28 # set trap indication to pgm check
la %r2,SP_PTREGS(15) # address of register-save area
l %r1,BASED(.Lhandle_per) # load adr. of per handler
la %r14,BASED(sysc_return) # load adr. of system return
br %r1 # branch to handle_per_exception
br %r1 # branch to do_debugger_trap
#
# call trace before and after sys_call
#
......@@ -690,7 +696,7 @@ restart_go:
.Ldo_softirq: .long do_softirq
.Lentry_base: .long entry_base
.Lext_hash: .long ext_int_hash
.Lhandle_per: .long handle_per_exception
.Lhandle_per: .long do_debugger_trap
.Ljump_table: .long pgm_check_table
.Lschedule: .long schedule
.Lclone: .long sys_clone
......
......@@ -471,6 +471,9 @@ pgm_per:
pgm_per_std:
SAVE_ALL __LC_PGM_OLD_PSW,1
GET_THREAD_INFO
mvc __THREAD_per+__PER_atmid(2,%r9),__LC_PER_ATMID
mvc __THREAD_per+__PER_address(8,%r9),__LC_PER_ADDRESS
mvc __THREAD_per+__PER_access_id(1,%r9),__LC_PER_ACCESS_ID
lghi %r4,0x7f
lgf %r3,__LC_PGM_ILC # load program interruption code
nr %r4,%r3 # clear per-event-bit and ilc
......@@ -483,7 +486,7 @@ pgm_per_std:
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
jg do_debugger_trap
#
# it was a single stepped SVC that is causing all the trouble
......@@ -493,6 +496,9 @@ pgm_svcper:
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
mvc __THREAD_per+__PER_atmid(2,%r9),__LC_PER_ATMID
mvc __THREAD_per+__PER_address(8,%r9),__LC_PER_ADDRESS
mvc __THREAD_per+__PER_access_id(1,%r9),__LC_PER_ACCESS_ID
slag %r7,%r7,2 # *4 and test for svc 0
jnz pgm_svcstd
# svc 0: system call number in %r1
......@@ -516,7 +522,7 @@ pgm_svcper_noemu:
pgm_svcret:
tm __TI_flags+7(%r9),_TIF_SIGPENDING
jo pgm_svcper_nosig
jno pgm_svcper_nosig
la %r2,SP_PTREGS(%r15) # load pt_regs
sgr %r3,%r3 # clear *oldset
brasl %r14,do_signal
......@@ -526,7 +532,7 @@ pgm_svcper_nosig:
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
jg do_debugger_trap
#
# call trace before and after sys_call
#
......
......@@ -193,9 +193,9 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data)
*/
if (addr == (addr_t) &dummy->regs.psw.mask &&
#ifdef CONFIG_S390_SUPPORT
(data & ~PSW_MASK_CC) != PSW_USER32_BITS &&
data != PSW_MASK_MERGE(PSW_USER32_BITS, data) &&
#endif
(data & ~PSW_MASK_CC) != PSW_USER_BITS)
data != PSW_MASK_MERGE(PSW_USER_BITS, data))
/* Invalid psw mask. */
return -EINVAL;
#ifndef CONFIG_ARCH_S390X
......@@ -331,7 +331,7 @@ peek_user_emu31(struct task_struct *child, addr_t addr, addr_t data)
if (addr == (addr_t) &dummy32->regs.psw.mask) {
/* Fake a 31 bit psw mask. */
tmp = (__u32)(__KSTK_PTREGS(child)->psw.mask >> 32);
tmp = (tmp & PSW32_MASK_CC) | PSW32_USER_BITS;
tmp = PSW32_MASK_MERGE(PSW32_USER_BITS, tmp);
} else if (addr == (addr_t) &dummy32->regs.psw.addr) {
/* Fake a 31 bit psw address. */
tmp = (__u32) __KSTK_PTREGS(child)->psw.addr |
......@@ -402,11 +402,11 @@ poke_user_emu31(struct task_struct *child, addr_t addr, addr_t data)
*/
if (addr == (addr_t) &dummy32->regs.psw.mask) {
/* Build a 64 bit psw mask from 31 bit mask. */
if ((tmp & ~PSW32_MASK_CC) != PSW32_USER_BITS)
if (tmp != PSW32_MASK_MERGE(PSW32_USER_BITS, tmp))
/* Invalid psw mask. */
return -EINVAL;
__KSTK_PTREGS(child)->psw.mask = PSW_USER32_BITS |
((tmp & PSW32_MASK_CC) << 32);
__KSTK_PTREGS(child)->psw.mask =
PSW_MASK_MERGE(PSW_USER32_BITS, (__u64) tmp << 32);
} else if (addr == (addr_t) &dummy32->regs.psw.addr) {
/* Build a 64 bit psw address from 31 bit address. */
__KSTK_PTREGS(child)->psw.addr =
......
......@@ -148,9 +148,14 @@ sys_sigaltstack(const stack_t *uss, stack_t *uoss, struct pt_regs *regs)
/* Returns non-zero on fault. */
static int save_sigregs(struct pt_regs *regs, _sigregs *sregs)
{
unsigned long old_mask = regs->psw.mask;
int err;
/* Copy a 'clean' PSW mask to the user to avoid leaking
information about whether PER is currently on. */
regs->psw.mask = PSW_MASK_MERGE(PSW_USER_BITS, regs->psw.mask);
err = __copy_to_user(&sregs->regs, regs, sizeof(_s390_regs_common));
regs->psw.mask = old_mask;
if (err != 0)
return err;
/*
......@@ -165,13 +170,14 @@ static int save_sigregs(struct pt_regs *regs, _sigregs *sregs)
/* Returns positive number on error */
static int restore_sigregs(struct pt_regs *regs, _sigregs *sregs)
{
unsigned long old_mask = regs->psw.mask;
int err;
/* Alwys make any pending restarted system call return -EINTR */
current_thread_info()->restart_block.fn = do_no_restart_syscall;
err = __copy_from_user(regs, &sregs->regs, sizeof(_s390_regs_common));
regs->psw.mask = PSW_USER_BITS | (regs->psw.mask & PSW_MASK_CC);
regs->psw.mask = PSW_MASK_MERGE(old_mask, regs->psw.mask);
regs->psw.addr |= PSW_ADDR_AMODE;
if (err)
return err;
......@@ -319,7 +325,6 @@ static void setup_frame(int sig, struct k_sigaction *ka,
/* Set up registers for signal handler */
regs->gprs[15] = (unsigned long) frame;
regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE;
regs->psw.mask = PSW_USER_BITS;
regs->gprs[2] = map_signal(sig);
regs->gprs[3] = (unsigned long) &frame->sc;
......@@ -378,7 +383,6 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
/* Set up registers for signal handler */
regs->gprs[15] = (unsigned long) frame;
regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE;
regs->psw.mask = PSW_USER_BITS;
regs->gprs[2] = map_signal(sig);
regs->gprs[3] = (unsigned long) &frame->info;
......@@ -401,30 +405,6 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
{
struct k_sigaction *ka = &current->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 -ERESTART_RESTARTBLOCK:
current_thread_info()->restart_block.fn =
do_no_restart_syscall;
clear_thread_flag(TIF_RESTART_SVC);
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 -= regs->ilc;
}
}
/* Set up the stack frame */
if (ka->sa.sa_flags & SA_SIGINFO)
setup_rt_frame(sig, ka, info, oldset, regs);
......@@ -454,6 +434,7 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
*/
int do_signal(struct pt_regs *regs, sigset_t *oldset)
{
unsigned long retval = 0, continue_addr = 0, restart_addr = 0;
siginfo_t info;
int signr;
......@@ -468,35 +449,62 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
if (!oldset)
oldset = &current->blocked;
#ifdef CONFIG_S390_SUPPORT
if (test_thread_flag(TIF_31BIT)) {
extern asmlinkage int do_signal32(struct pt_regs *regs,
sigset_t *oldset);
return do_signal32(regs, oldset);
}
#endif
/* Are we from a system call? */
if (regs->trap == __LC_SVC_OLD_PSW) {
continue_addr = regs->psw.addr;
restart_addr = continue_addr - regs->ilc;
retval = regs->gprs[2];
/* Prepare for system call restart. We do this here so that a
debugger will see the already changed PSW. */
if (retval == -ERESTARTNOHAND ||
retval == -ERESTARTSYS ||
retval == -ERESTARTNOINTR) {
regs->gprs[2] = regs->orig_gpr2;
regs->psw.addr = restart_addr;
} else if (retval == -ERESTART_RESTARTBLOCK) {
regs->gprs[2] = -EINTR;
}
}
/* Get signal to deliver. When running under ptrace, at this point
the debugger may change all our registers ... */
signr = get_signal_to_deliver(&info, regs, NULL);
/* Depending on the signal settings we may need to revert the
decision to restart the system call. */
if (signr > 0 && regs->psw.addr == restart_addr) {
if (retval == -ERESTARTNOHAND
|| (retval == -ERESTARTSYS
&& !(current->sighand->action[signr-1].sa.sa_flags
& SA_RESTART))) {
regs->gprs[2] = -EINTR;
regs->psw.addr = continue_addr;
}
}
if (signr > 0) {
/* Whee! Actually deliver the signal. */
#ifdef CONFIG_S390_SUPPORT
if (test_thread_flag(TIF_31BIT)) {
extern void handle_signal32(unsigned long sig,
siginfo_t *info,
sigset_t *oldset,
struct pt_regs *regs);
handle_signal32(signr, &info, oldset, regs);
return 1;
}
#endif
handle_signal(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 -= regs->ilc;
}
/* Restart the system call with a new system call number */
if (regs->gprs[2] == -ERESTART_RESTARTBLOCK) {
regs->gprs[2] = __NR_restart_syscall;
set_thread_flag(TIF_RESTART_SVC);
}
/* Restart a different system call. */
if (retval == -ERESTART_RESTARTBLOCK
&& regs->psw.addr == continue_addr) {
regs->gprs[2] = __NR_restart_syscall;
set_thread_flag(TIF_RESTART_SVC);
}
return 0;
}
......@@ -245,52 +245,7 @@ asmlinkage __SYS_RETTYPE sys_ipc (uint call, int first, int second,
return -EINVAL;
}
/*
* Old cruft
*/
asmlinkage int sys_uname(struct old_utsname * name)
{
int err;
if (!name)
return -EFAULT;
down_read(&uts_sem);
err=copy_to_user(name, &system_utsname, sizeof (*name));
up_read(&uts_sem);
return err?-EFAULT:0;
}
#ifndef CONFIG_ARCH_S390X
asmlinkage int sys_olduname(struct oldold_utsname * name)
{
int error;
if (!name)
return -EFAULT;
if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
return -EFAULT;
down_read(&uts_sem);
error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
error |= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
error |= __put_user(0,name->nodename+__OLD_UTS_LEN);
error |= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
error |= __put_user(0,name->release+__OLD_UTS_LEN);
error |= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
error |= __put_user(0,name->version+__OLD_UTS_LEN);
error |= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
error |= __put_user(0,name->machine+__OLD_UTS_LEN);
up_read(&uts_sem);
error = error ? -EFAULT : 0;
return error;
}
#else /* CONFIG_ARCH_S390X */
#ifdef CONFIG_ARCH_S390X
asmlinkage int s390x_newuname(struct new_utsname * name)
{
int ret = sys_newuname(name);
......
......@@ -54,7 +54,7 @@ SYSCALL(sys_pipe,sys_pipe,sys32_pipe_wrapper)
SYSCALL(sys_times,sys_times,compat_sys_times_wrapper)
NI_SYSCALL /* old prof syscall */
SYSCALL(sys_brk,sys_brk,sys32_brk_wrapper) /* 45 */
SYSCALL(sys_setgid16,sys_ni_syscall,sys32_setgid16) /* old setgid16 syscall*/
SYSCALL(sys_setgid16,sys_ni_syscall,sys32_setgid16_wrapper) /* old setgid16 syscall*/
SYSCALL(sys_getgid16,sys_ni_syscall,sys32_getgid16) /* old getgid16 syscall*/
SYSCALL(sys_signal,sys_signal,sys32_signal_wrapper)
SYSCALL(sys_geteuid16,sys_ni_syscall,sys32_geteuid16) /* old geteuid16 syscall */
......@@ -273,3 +273,5 @@ SYSCALL(sys_clock_getres,sys_clock_getres,sys32_clock_getres_wrapper)
SYSCALL(sys_clock_nanosleep,sys_clock_nanosleep,sys32_clock_nanosleep_wrapper)
NI_SYSCALL /* reserved for vserver */
SYSCALL(s390_fadvise64_64,sys_ni_syscall,sys32_fadvise64_64_wrapper)
SYSCALL(sys_statfs64,sys_statfs64,compat_sys_statfs64_wrapper)
SYSCALL(sys_fstatfs64,sys_fstatfs64,compat_sys_fstatfs64_wrapper)
......@@ -308,7 +308,7 @@ static inline void *get_check_address(struct pt_regs *regs)
return (void *)((regs->psw.addr-S390_lowcore.pgm_ilc) & PSW_ADDR_INSN);
}
static int do_debugger_trap(struct pt_regs *regs)
int do_debugger_trap(struct pt_regs *regs)
{
if ((regs->psw.mask & PSW_MASK_PSTATE) &&
(current->ptrace & PT_PTRACED)) {
......@@ -652,23 +652,3 @@ void __init trap_init(void)
#endif
}
}
void handle_per_exception(struct pt_regs *regs)
{
if (regs->psw.mask & PSW_MASK_PSTATE) {
per_struct *per_info=&current->thread.per_info;
per_info->lowcore.words.perc_atmid=S390_lowcore.per_perc_atmid;
per_info->lowcore.words.address=S390_lowcore.per_address;
per_info->lowcore.words.access_id=S390_lowcore.per_access_id;
}
if (do_debugger_trap(regs)) {
/* I've seen this possibly a task structure being reused ? */
printk("Spurious per exception detected\n");
printk("switching off per tracing for this task.\n");
show_regs(regs);
/* Hopefully switching off per tracing will help us survive */
regs->psw.mask &= ~PSW_MASK_PER;
}
}
......@@ -532,7 +532,7 @@ __constant_test_bit(unsigned long nr, const volatile unsigned long *addr) {
* Find-bit routines..
*/
static inline int
find_first_zero_bit(unsigned long * addr, unsigned int size)
find_first_zero_bit(const unsigned long * addr, unsigned int size)
{
unsigned long cmp, count;
unsigned int res;
......@@ -571,7 +571,7 @@ find_first_zero_bit(unsigned long * addr, unsigned int size)
}
static inline int
find_first_bit(unsigned long * addr, unsigned int size)
find_first_bit(const unsigned long * addr, unsigned int size)
{
unsigned long cmp, count;
unsigned int res;
......@@ -610,7 +610,7 @@ find_first_bit(unsigned long * addr, unsigned int size)
}
static inline int
find_next_zero_bit (unsigned long * addr, int size, int offset)
find_next_zero_bit (const unsigned long * addr, int size, int offset)
{
unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
unsigned long bitvec, reg;
......@@ -649,7 +649,7 @@ find_next_zero_bit (unsigned long * addr, int size, int offset)
}
static inline int
find_next_bit (unsigned long * addr, int size, int offset)
find_next_bit (const unsigned long * addr, int size, int offset)
{
unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
unsigned long bitvec, reg;
......@@ -693,7 +693,7 @@ find_next_bit (unsigned long * addr, int size, int offset)
* Find-bit routines..
*/
static inline unsigned long
find_first_zero_bit(unsigned long * addr, unsigned long size)
find_first_zero_bit(const unsigned long * addr, unsigned long size)
{
unsigned long res, cmp, count;
......@@ -735,7 +735,7 @@ find_first_zero_bit(unsigned long * addr, unsigned long size)
}
static inline unsigned long
find_first_bit(unsigned long * addr, unsigned long size)
find_first_bit(const unsigned long * addr, unsigned long size)
{
unsigned long res, cmp, count;
......@@ -777,7 +777,7 @@ find_first_bit(unsigned long * addr, unsigned long size)
}
static inline unsigned long
find_next_zero_bit (unsigned long * addr, unsigned long size, unsigned long offset)
find_next_zero_bit (const unsigned long * addr, unsigned long size, unsigned long offset)
{
unsigned long * p = ((unsigned long *) addr) + (offset >> 6);
unsigned long bitvec, reg;
......@@ -821,7 +821,7 @@ find_next_zero_bit (unsigned long * addr, unsigned long size, unsigned long offs
}
static inline unsigned long
find_next_bit (unsigned long * addr, unsigned long size, unsigned long offset)
find_next_bit (const unsigned long * addr, unsigned long size, unsigned long offset)
{
unsigned long * p = ((unsigned long *) addr) + (offset >> 6);
unsigned long bitvec, reg;
......
......@@ -44,6 +44,10 @@
#define __LC_PGM_ILC 0x08C
#define __LC_PGM_INT_CODE 0x08E
#define __LC_PER_ATMID 0x096
#define __LC_PER_ADDRESS 0x098
#define __LC_PER_ACCESS_ID 0x0A1
#define __LC_SUBCHANNEL_ID 0x0B8
#define __LC_SUBCHANNEL_NR 0x0BA
#define __LC_IO_INT_PARM 0x0BC
......
......@@ -277,6 +277,14 @@ typedef struct
PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK | \
PSW_MASK_PSTATE)
/* This macro merges a NEW PSW mask specified by the user into
the currently active PSW mask CURRENT, modifying only those
bits in CURRENT that the user may be allowed to change: this
is the condition code and the program mask bits. */
#define PSW_MASK_MERGE(CURRENT,NEW) \
(((CURRENT) & ~(PSW_MASK_CC|PSW_MASK_PM)) | \
((NEW) & (PSW_MASK_CC|PSW_MASK_PM)))
/*
* The first entries in pt_regs and user_regs_struct
* are common for the two structures. The s390_regs structure
......
......@@ -256,12 +256,15 @@
#define __NR_clock_gettime (__NR_timer_create+6)
#define __NR_clock_getres (__NR_timer_create+7)
#define __NR_clock_nanosleep (__NR_timer_create+8)
/*
* Number 263 is reserved for vserver
*/
#define __NR_fadvise64_64 264
#define __NR_statfs64 265
#define __NR_fstatfs64 266
#define NR_syscalls 265
#define NR_syscalls 267
/*
* There are some system calls that are not present on 64 bit, some
......
......@@ -1146,7 +1146,8 @@ asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struc
return retval;
}
#if !defined(__alpha__) && !defined(__ia64__) && !defined(__arm__)
#if !defined(__alpha__) && !defined(__ia64__) && \
!defined(__arm__) && !defined(__s390__)
/*
* sys_waitpid() remains for compatibility. waitpid() should be
......
......@@ -2482,7 +2482,8 @@ sys_rt_sigaction(int sig,
#endif /* __sparc__ */
#endif
#if !defined(__alpha__) && !defined(__ia64__) && !defined(__arm__)
#if !defined(__alpha__) && !defined(__ia64__) && \
!defined(__arm__) && !defined(__s390__)
/*
* For backwards compatibility. Functionality superseded by sigprocmask.
*/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment