Commit ca2ab032 authored by Martin Schwidefsky's avatar Martin Schwidefsky Committed by Linus Torvalds

[PATCH] s390: core changes

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

s390 core changes:
 - Remove defines for kernel_stack_size and async_stack_size.
 - Reserve system call number for kexec.
 - Add cc-option check for new gcc option packed-stack.
 - Fix race on no_hz_cpu_mask in stop_hz_timer.
 - Fix ptrace to make it send a SIGTRAP before the first instruction
   of a single stepped signal handler is executed.
 - Use force_sig_info with a full siginfo structure for illegal operation.
 - Remove verbatim copy of si_codes from asm-s390/siginfo.h. Use the
   generic definitions.
 - Regenerate default configuration.
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 96408b92
...@@ -34,6 +34,7 @@ cflags-$(CONFIG_MARCH_G5) += $(call cc-option,-march=g5) ...@@ -34,6 +34,7 @@ cflags-$(CONFIG_MARCH_G5) += $(call cc-option,-march=g5)
cflags-$(CONFIG_MARCH_Z900) += $(call cc-option,-march=z900) cflags-$(CONFIG_MARCH_Z900) += $(call cc-option,-march=z900)
cflags-$(CONFIG_MARCH_Z990) += $(call cc-option,-march=z990) cflags-$(CONFIG_MARCH_Z990) += $(call cc-option,-march=z990)
# old style option for packed stacks
ifeq ($(call cc-option-yn,-mkernel-backchain),y) ifeq ($(call cc-option-yn,-mkernel-backchain),y)
cflags-$(CONFIG_PACK_STACK) += -mkernel-backchain -D__PACK_STACK cflags-$(CONFIG_PACK_STACK) += -mkernel-backchain -D__PACK_STACK
aflags-$(CONFIG_PACK_STACK) += -D__PACK_STACK aflags-$(CONFIG_PACK_STACK) += -D__PACK_STACK
...@@ -44,6 +45,17 @@ STACK_SIZE := $(shell echo $$(($(STACK_SIZE)/2)) ) ...@@ -44,6 +45,17 @@ STACK_SIZE := $(shell echo $$(($(STACK_SIZE)/2)) )
endif endif
endif endif
# new style option for packed stacks
ifeq ($(call cc-option-yn,-mpacked-stack),y)
cflags-$(CONFIG_PACK_STACK) += -mpacked-stack -D__PACK_STACK
aflags-$(CONFIG_PACK_STACK) += -D__PACK_STACK
cflags-$(CONFIG_SMALL_STACK) += -D__SMALL_STACK
aflags-$(CONFIG_SMALL_STACK) += -D__SMALL_STACK
ifdef CONFIG_SMALL_STACK
STACK_SIZE := $(shell echo $$(($(STACK_SIZE)/2)) )
endif
endif
ifeq ($(call cc-option-yn,-mstack-size=8192 -mstack-guard=128),y) ifeq ($(call cc-option-yn,-mstack-size=8192 -mstack-guard=128),y)
cflags-$(CONFIG_CHECK_STACK) += -mstack-size=$(STACK_SIZE) cflags-$(CONFIG_CHECK_STACK) += -mstack-size=$(STACK_SIZE)
cflags-$(CONFIG_CHECK_STACK) += -mstack-guard=$(CONFIG_STACK_GUARD) cflags-$(CONFIG_CHECK_STACK) += -mstack-guard=$(CONFIG_STACK_GUARD)
......
# #
# Automatically generated make config: don't edit # Automatically generated make config: don't edit
# Linux kernel version: 2.6.10-rc1 # Linux kernel version: 2.6.10-rc2
# Thu Nov 11 12:54:21 2004 # Tue Nov 30 14:00:30 2004
# #
CONFIG_MMU=y CONFIG_MMU=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y
...@@ -147,7 +147,6 @@ CONFIG_SCSI_FC_ATTRS=y ...@@ -147,7 +147,6 @@ CONFIG_SCSI_FC_ATTRS=y
# SCSI low-level drivers # SCSI low-level drivers
# #
# CONFIG_SCSI_SATA is not set # CONFIG_SCSI_SATA is not set
# CONFIG_SCSI_QLOGIC_1280_1040 is not set
# CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_DEBUG is not set
CONFIG_ZFCP=y CONFIG_ZFCP=y
CONFIG_CCW=y CONFIG_CCW=y
...@@ -197,6 +196,7 @@ CONFIG_MD_RAID1=m ...@@ -197,6 +196,7 @@ CONFIG_MD_RAID1=m
CONFIG_MD_RAID5=m CONFIG_MD_RAID5=m
# CONFIG_MD_RAID6 is not set # CONFIG_MD_RAID6 is not set
CONFIG_MD_MULTIPATH=m CONFIG_MD_MULTIPATH=m
# CONFIG_MD_FAULTY is not set
# CONFIG_BLK_DEV_DM is not set # CONFIG_BLK_DEV_DM is not set
# #
......
...@@ -229,6 +229,8 @@ sysc_sigpending: ...@@ -229,6 +229,8 @@ sysc_sigpending:
basr %r14,%r1 # call do_signal basr %r14,%r1 # call do_signal
tm __TI_flags+3(%r9),_TIF_RESTART_SVC tm __TI_flags+3(%r9),_TIF_RESTART_SVC
bo BASED(sysc_restart) bo BASED(sysc_restart)
tm __TI_flags+3(%r9),_TIF_SINGLE_STEP
bo BASED(sysc_singlestep)
b BASED(sysc_leave) # out of here, do NOT recheck b BASED(sysc_leave) # out of here, do NOT recheck
# #
......
...@@ -231,6 +231,8 @@ sysc_sigpending: ...@@ -231,6 +231,8 @@ sysc_sigpending:
brasl %r14,do_signal # call do_signal brasl %r14,do_signal # call do_signal
tm __TI_flags+7(%r9),_TIF_RESTART_SVC tm __TI_flags+7(%r9),_TIF_RESTART_SVC
jo sysc_restart jo sysc_restart
tm __TI_flags+7(%r9),_TIF_SINGLE_STEP
jo sysc_singlestep
j sysc_leave # out of here, do NOT recheck j sysc_leave # out of here, do NOT recheck
# #
......
...@@ -640,7 +640,10 @@ do_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -640,7 +640,10 @@ do_ptrace(struct task_struct *child, long request, long addr, long data)
return -EIO; return -EIO;
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
child->exit_code = data; child->exit_code = data;
set_single_step(child); if (data)
set_tsk_thread_flag(child, TIF_SINGLE_STEP);
else
set_single_step(child);
/* give it a chance to run. */ /* give it a chance to run. */
wake_up_process(child); wake_up_process(child);
return 0; return 0;
......
...@@ -283,5 +283,6 @@ SYSCALL(sys_mq_open,sys_mq_open,compat_sys_mq_open_wrapper) ...@@ -283,5 +283,6 @@ SYSCALL(sys_mq_open,sys_mq_open,compat_sys_mq_open_wrapper)
SYSCALL(sys_mq_unlink,sys_mq_unlink,sys32_mq_unlink_wrapper) SYSCALL(sys_mq_unlink,sys_mq_unlink,sys32_mq_unlink_wrapper)
SYSCALL(sys_mq_timedsend,sys_mq_timedsend,compat_sys_mq_timedsend_wrapper) SYSCALL(sys_mq_timedsend,sys_mq_timedsend,compat_sys_mq_timedsend_wrapper)
SYSCALL(sys_mq_timedreceive,sys_mq_timedreceive,compat_sys_mq_timedreceive_wrapper) SYSCALL(sys_mq_timedreceive,sys_mq_timedreceive,compat_sys_mq_timedreceive_wrapper)
SYSCALL(sys_mq_notify,sys_mq_notify,compat_sys_mq_notify_wrapper) SYSCALL(sys_mq_notify,sys_mq_notify,compat_sys_mq_notify_wrapper) /* 275 */
SYSCALL(sys_mq_getsetattr,sys_mq_getsetattr,compat_sys_mq_getsetattr_wrapper) SYSCALL(sys_mq_getsetattr,sys_mq_getsetattr,compat_sys_mq_getsetattr_wrapper)
NI_SYSCALL /* reserved for kexec */
...@@ -260,18 +260,21 @@ static inline void stop_hz_timer(void) ...@@ -260,18 +260,21 @@ static inline void stop_hz_timer(void)
if (sysctl_hz_timer != 0) if (sysctl_hz_timer != 0)
return; return;
cpu_set(smp_processor_id(), nohz_cpu_mask);
/* /*
* Leave the clock comparator set up for the next timer * Leave the clock comparator set up for the next timer
* tick if either rcu or a softirq is pending. * tick if either rcu or a softirq is pending.
*/ */
if (rcu_pending(smp_processor_id()) || local_softirq_pending()) if (rcu_pending(smp_processor_id()) || local_softirq_pending()) {
cpu_clear(smp_processor_id(), nohz_cpu_mask);
return; return;
}
/* /*
* This cpu is going really idle. Set up the clock comparator * This cpu is going really idle. Set up the clock comparator
* for the next event. * for the next event.
*/ */
cpu_set(smp_processor_id(), nohz_cpu_mask);
timer = (__u64) (next_timer_interrupt() - jiffies) + jiffies_64; timer = (__u64) (next_timer_interrupt() - jiffies) + jiffies_64;
timer = jiffies_timer_cc + timer * CLK_TICKS_PER_JIFFY; timer = jiffies_timer_cc + timer * CLK_TICKS_PER_JIFFY;
asm volatile ("SCKC %0" : : "m" (timer)); asm volatile ("SCKC %0" : : "m" (timer));
......
...@@ -294,6 +294,20 @@ void die(const char * str, struct pt_regs * regs, long err) ...@@ -294,6 +294,20 @@ void die(const char * str, struct pt_regs * regs, long err)
do_exit(SIGSEGV); do_exit(SIGSEGV);
} }
static void inline
report_user_fault(long interruption_code, struct pt_regs *regs)
{
#if defined(CONFIG_SYSCTL)
if (!sysctl_userprocess_debug)
return;
#endif
#if defined(CONFIG_SYSCTL) || defined(CONFIG_PROCESS_DEBUG)
printk("User process fault: interruption code 0x%lX\n",
interruption_code);
show_regs(regs);
#endif
}
static void inline do_trap(long interruption_code, int signr, char *str, static void inline do_trap(long interruption_code, int signr, char *str,
struct pt_regs *regs, siginfo_t *info) struct pt_regs *regs, siginfo_t *info)
{ {
...@@ -308,23 +322,8 @@ static void inline do_trap(long interruption_code, int signr, char *str, ...@@ -308,23 +322,8 @@ static void inline do_trap(long interruption_code, int signr, char *str,
struct task_struct *tsk = current; struct task_struct *tsk = current;
tsk->thread.trap_no = interruption_code & 0xffff; tsk->thread.trap_no = interruption_code & 0xffff;
if (info) force_sig_info(signr, info, tsk);
force_sig_info(signr, info, tsk); report_user_fault(interruption_code, regs);
else
force_sig(signr, tsk);
#ifndef CONFIG_SYSCTL
#ifdef CONFIG_PROCESS_DEBUG
printk("User process fault: interruption code 0x%lX\n",
interruption_code);
show_regs(regs);
#endif
#else
if (sysctl_userprocess_debug) {
printk("User process fault: interruption code 0x%lX\n",
interruption_code);
show_regs(regs);
}
#endif
} else { } else {
const struct exception_table_entry *fixup; const struct exception_table_entry *fixup;
fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN); fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN);
...@@ -346,10 +345,15 @@ void do_single_step(struct pt_regs *regs) ...@@ -346,10 +345,15 @@ void do_single_step(struct pt_regs *regs)
force_sig(SIGTRAP, current); force_sig(SIGTRAP, current);
} }
#define DO_ERROR(signr, str, name) \ asmlinkage void
asmlinkage void name(struct pt_regs * regs, long interruption_code) \ default_trap_handler(struct pt_regs * regs, long interruption_code)
{ \ {
do_trap(interruption_code, signr, str, regs, NULL); \ if (regs->psw.mask & PSW_MASK_PSTATE) {
local_irq_enable();
do_exit(SIGSEGV);
report_user_fault(interruption_code, regs);
} else
die("Unknown program exception", regs, interruption_code);
} }
#define DO_ERROR_INFO(signr, str, name, sicode, siaddr) \ #define DO_ERROR_INFO(signr, str, name, sicode, siaddr) \
...@@ -363,8 +367,6 @@ asmlinkage void name(struct pt_regs * regs, long interruption_code) \ ...@@ -363,8 +367,6 @@ asmlinkage void name(struct pt_regs * regs, long interruption_code) \
do_trap(interruption_code, signr, str, regs, &info); \ do_trap(interruption_code, signr, str, regs, &info); \
} }
DO_ERROR(SIGSEGV, "Unknown program exception", default_trap_handler)
DO_ERROR_INFO(SIGILL, "addressing exception", addressing_exception, DO_ERROR_INFO(SIGILL, "addressing exception", addressing_exception,
ILL_ILLADR, get_check_address(regs)) ILL_ILLADR, get_check_address(regs))
DO_ERROR_INFO(SIGILL, "execute exception", execute_exception, DO_ERROR_INFO(SIGILL, "execute exception", execute_exception,
...@@ -423,6 +425,7 @@ do_fp_trap(struct pt_regs *regs, void *location, ...@@ -423,6 +425,7 @@ do_fp_trap(struct pt_regs *regs, void *location,
asmlinkage void illegal_op(struct pt_regs * regs, long interruption_code) asmlinkage void illegal_op(struct pt_regs * regs, long interruption_code)
{ {
siginfo_t info;
__u8 opcode[6]; __u8 opcode[6];
__u16 *location; __u16 *location;
int signal = 0; int signal = 0;
...@@ -466,12 +469,27 @@ asmlinkage void illegal_op(struct pt_regs * regs, long interruption_code) ...@@ -466,12 +469,27 @@ asmlinkage void illegal_op(struct pt_regs * regs, long interruption_code)
} else } else
signal = SIGILL; signal = SIGILL;
#ifdef CONFIG_MATHEMU
if (signal == SIGFPE) if (signal == SIGFPE)
do_fp_trap(regs, location, do_fp_trap(regs, location,
current->thread.fp_regs.fpc, interruption_code); current->thread.fp_regs.fpc, interruption_code);
else if (signal) else if (signal == SIGSEGV) {
info.si_signo = signal;
info.si_errno = 0;
info.si_code = SEGV_MAPERR;
info.si_addr = (void *) location;
do_trap(interruption_code, signal, do_trap(interruption_code, signal,
"illegal operation", regs, NULL); "user address fault", regs, &info);
} else
#endif
if (signal) {
info.si_signo = signal;
info.si_errno = 0;
info.si_code = ILL_ILLOPC;
info.si_addr = (void *) location;
do_trap(interruption_code, signal,
"illegal operation", regs, &info);
}
} }
......
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
#ifndef _S390_SIGINFO_H #ifndef _S390_SIGINFO_H
#define _S390_SIGINFO_H #define _S390_SIGINFO_H
#define HAVE_ARCH_SI_CODES
#ifdef __s390x__ #ifdef __s390x__
#define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) #define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int))
#endif #endif
...@@ -22,74 +21,4 @@ ...@@ -22,74 +21,4 @@
#include <asm-generic/siginfo.h> #include <asm-generic/siginfo.h>
/*
* SIGILL si_codes
*/
#define ILL_ILLOPC (__SI_FAULT|1) /* illegal opcode */
#define ILL_ILLOPN (__SI_FAULT|2) /* illegal operand */
#define ILL_ILLADR (__SI_FAULT|3) /* illegal addressing mode */
#define ILL_ILLTRP (__SI_FAULT|4) /* illegal trap */
#define ILL_PRVOPC (__SI_FAULT|5) /* privileged opcode */
#define ILL_PRVREG (__SI_FAULT|6) /* privileged register */
#define ILL_COPROC (__SI_FAULT|7) /* coprocessor error */
#define ILL_BADSTK (__SI_FAULT|8) /* internal stack error */
#define NSIGILL 8
/*
* SIGFPE si_codes
*/
#define FPE_INTDIV (__SI_FAULT|1) /* integer divide by zero */
#define FPE_INTOVF (__SI_FAULT|2) /* integer overflow */
#define FPE_FLTDIV (__SI_FAULT|3) /* floating point divide by zero */
#define FPE_FLTOVF (__SI_FAULT|4) /* floating point overflow */
#define FPE_FLTUND (__SI_FAULT|5) /* floating point underflow */
#define FPE_FLTRES (__SI_FAULT|6) /* floating point inexact result */
#define FPE_FLTINV (__SI_FAULT|7) /* floating point invalid operation */
#define FPE_FLTSUB (__SI_FAULT|8) /* subscript out of range */
#define NSIGFPE 8
/*
* SIGSEGV si_codes
*/
#define SEGV_MAPERR (__SI_FAULT|1) /* address not mapped to object */
#define SEGV_ACCERR (__SI_FAULT|2) /* invalid permissions for mapped object */
#define NSIGSEGV 2
/*
* SIGBUS si_codes
*/
#define BUS_ADRALN (__SI_FAULT|1) /* invalid address alignment */
#define BUS_ADRERR (__SI_FAULT|2) /* non-existant physical address */
#define BUS_OBJERR (__SI_FAULT|3) /* object specific hardware error */
#define NSIGBUS 3
/*
* SIGTRAP si_codes
*/
#define TRAP_BRKPT (__SI_FAULT|1) /* process breakpoint */
#define TRAP_TRACE (__SI_FAULT|2) /* process trace trap */
#define NSIGTRAP 2
/*
* SIGCHLD si_codes
*/
#define CLD_EXITED (__SI_CHLD|1) /* child has exited */
#define CLD_KILLED (__SI_CHLD|2) /* child was killed */
#define CLD_DUMPED (__SI_CHLD|3) /* child terminated abnormally */
#define CLD_TRAPPED (__SI_CHLD|4) /* traced child has trapped */
#define CLD_STOPPED (__SI_CHLD|5) /* child has stopped */
#define CLD_CONTINUED (__SI_CHLD|6) /* stopped child has continued */
#define NSIGCHLD 6
/*
* SIGPOLL si_codes
*/
#define POLL_IN (__SI_POLL|1) /* data input available */
#define POLL_OUT (__SI_POLL|2) /* output buffers available */
#define POLL_MSG (__SI_POLL|3) /* input message available */
#define POLL_ERR (__SI_POLL|4) /* i/o error */
#define POLL_PRI (__SI_POLL|5) /* high priority input available */
#define POLL_HUP (__SI_POLL|6) /* device disconnected */
#define NSIGPOLL 6
#endif #endif
...@@ -269,8 +269,9 @@ ...@@ -269,8 +269,9 @@
#define __NR_mq_timedreceive 274 #define __NR_mq_timedreceive 274
#define __NR_mq_notify 275 #define __NR_mq_notify 275
#define __NR_mq_getsetattr 276 #define __NR_mq_getsetattr 276
/* Number 277 is reserved for new sys_kexec_load */
#define NR_syscalls 277 #define NR_syscalls 278
/* /*
* There are some system calls that are not present on 64 bit, some * There are some system calls that are not present on 64 bit, some
......
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