Commit 3fb67b11 authored by Martin Schwidefsky's avatar Martin Schwidefsky Committed by Linus Torvalds

[PATCH] s390: core changes

From: Arnd Bergmann <arndb@de.ibm.com>
From: Christian Bornträger <cborntra@de.ibm.com>
From: Michael Holzheu <holzheu@de.ibm.com>
From: Martin Schwidefsky <schwidefsky@de.ibm.com>

s390 core changes:
 - Fix cpu_idle loop if /proc/sys/kernel/hz_timer is set.
 - Store correct trap indication on 64 bit for call to do_debugger_trap
   in the single stepped svc code.
 - Avoid the use of alloca in the debug feature.
 - Remove extraneous includes of linux/version.h.
 - Regenerate default configuration.
 - Mention eServer z890 in Kconfig help text.
 - Prevent gcc 3.4 from removing statically defined per cpu variables.
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 48a3a8cd
...@@ -67,9 +67,9 @@ config MARCH_Z900 ...@@ -67,9 +67,9 @@ config MARCH_Z900
on older 31 bit only CPUs. on older 31 bit only CPUs.
config MARCH_Z990 config MARCH_Z990
bool "IBM eServer zSeries model z990" bool "IBM eServer zSeries model z890 and z990"
help help
Select this enable optimizations for model z990. Select this enable optimizations for model z890/z990.
This will be slightly faster but does not work on This will be slightly faster but does not work on
older machines such as the z900. older machines such as the z900.
...@@ -154,7 +154,7 @@ config QDIO ...@@ -154,7 +154,7 @@ config QDIO
tristate "QDIO support" tristate "QDIO support"
---help--- ---help---
This driver provides the Queued Direct I/O base support for the This driver provides the Queued Direct I/O base support for the
IBM S/390 (G5 and G6) and eServer zSeries (z800, z900 and z990). IBM S/390 (G5 and G6) and eServer zSeries (z800, z890, z900 and z990).
For details please refer to the documentation provided by IBM at For details please refer to the documentation provided by IBM at
<http://www10.software.ibm.com/developerworks/opensource/linux390> <http://www10.software.ibm.com/developerworks/opensource/linux390>
......
...@@ -29,6 +29,7 @@ CONFIG_IKCONFIG_PROC=y ...@@ -29,6 +29,7 @@ CONFIG_IKCONFIG_PROC=y
# CONFIG_EMBEDDED is not set # CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_FUTEX=y CONFIG_FUTEX=y
CONFIG_EPOLL=y CONFIG_EPOLL=y
CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_NOOP=y
...@@ -45,6 +46,7 @@ CONFIG_MODULES=y ...@@ -45,6 +46,7 @@ CONFIG_MODULES=y
CONFIG_OBSOLETE_MODPARM=y CONFIG_OBSOLETE_MODPARM=y
# CONFIG_MODVERSIONS is not set # CONFIG_MODVERSIONS is not set
CONFIG_KMOD=y CONFIG_KMOD=y
CONFIG_STOP_MACHINE=y
# #
# Base setup # Base setup
...@@ -84,12 +86,14 @@ CONFIG_PFAULT=y ...@@ -84,12 +86,14 @@ CONFIG_PFAULT=y
# CONFIG_SHARED_KERNEL is not set # CONFIG_SHARED_KERNEL is not set
# CONFIG_CMM is not set # CONFIG_CMM is not set
# CONFIG_VIRT_TIMER is not set # CONFIG_VIRT_TIMER is not set
# CONFIG_NO_IDLE_HZ is not set CONFIG_NO_IDLE_HZ=y
CONFIG_NO_IDLE_HZ_INIT=y
# CONFIG_PCMCIA is not set # CONFIG_PCMCIA is not set
# #
# Generic Driver Options # Generic Driver Options
# #
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set # CONFIG_FW_LOADER is not set
# CONFIG_DEBUG_DRIVER is not set # CONFIG_DEBUG_DRIVER is not set
...@@ -126,7 +130,6 @@ CONFIG_SCSI_LOGGING=y ...@@ -126,7 +130,6 @@ CONFIG_SCSI_LOGGING=y
# SCSI low-level drivers # SCSI low-level drivers
# #
# CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_DPT_I2O is not set
# CONFIG_SCSI_SATA is not set # CONFIG_SCSI_SATA is not set
# CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_EATA_PIO is not set
# CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_DEBUG is not set
...@@ -277,6 +280,7 @@ CONFIG_NET_SCH_TBF=m ...@@ -277,6 +280,7 @@ CONFIG_NET_SCH_TBF=m
CONFIG_NET_SCH_GRED=m CONFIG_NET_SCH_GRED=m
CONFIG_NET_SCH_DSMARK=m CONFIG_NET_SCH_DSMARK=m
# CONFIG_NET_SCH_DELAY is not set # CONFIG_NET_SCH_DELAY is not set
# CONFIG_NET_SCH_INGRESS is not set
CONFIG_NET_QOS=y CONFIG_NET_QOS=y
CONFIG_NET_ESTIMATOR=y CONFIG_NET_ESTIMATOR=y
CONFIG_NET_CLS=y CONFIG_NET_CLS=y
...@@ -285,8 +289,11 @@ CONFIG_NET_CLS_ROUTE4=m ...@@ -285,8 +289,11 @@ CONFIG_NET_CLS_ROUTE4=m
CONFIG_NET_CLS_ROUTE=y CONFIG_NET_CLS_ROUTE=y
CONFIG_NET_CLS_FW=m CONFIG_NET_CLS_FW=m
CONFIG_NET_CLS_U32=m CONFIG_NET_CLS_U32=m
# CONFIG_CLS_U32_PERF is not set
# CONFIG_NET_CLS_IND is not set
CONFIG_NET_CLS_RSVP=m CONFIG_NET_CLS_RSVP=m
CONFIG_NET_CLS_RSVP6=m CONFIG_NET_CLS_RSVP6=m
# CONFIG_NET_CLS_ACT is not set
CONFIG_NET_CLS_POLICE=y CONFIG_NET_CLS_POLICE=y
# #
...@@ -311,7 +318,11 @@ CONFIG_NET_ETHERNET=y ...@@ -311,7 +318,11 @@ CONFIG_NET_ETHERNET=y
# CONFIG_MII is not set # CONFIG_MII is not set
# #
# Gigabit Ethernet (1000/10000 Mbit) # Ethernet (1000 Mbit)
#
#
# Ethernet (10000 Mbit)
# #
# #
...@@ -450,7 +461,6 @@ CONFIG_MSDOS_PARTITION=y ...@@ -450,7 +461,6 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_SOLARIS_X86_PARTITION is not set # CONFIG_SOLARIS_X86_PARTITION is not set
# CONFIG_UNIXWARE_DISKLABEL is not set # CONFIG_UNIXWARE_DISKLABEL is not set
# CONFIG_LDM_PARTITION is not set # CONFIG_LDM_PARTITION is not set
# CONFIG_NEC98_PARTITION is not set
# CONFIG_SGI_PARTITION is not set # CONFIG_SGI_PARTITION is not set
# CONFIG_ULTRIX_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set # CONFIG_SUN_PARTITION is not set
...@@ -509,5 +519,6 @@ CONFIG_CRYPTO=y ...@@ -509,5 +519,6 @@ CONFIG_CRYPTO=y
# #
# Library routines # Library routines
# #
# CONFIG_CRC16 is not set
# CONFIG_CRC32 is not set # CONFIG_CRC32 is not set
# CONFIG_LIBCRC32C is not set # CONFIG_LIBCRC32C is not set
...@@ -54,7 +54,7 @@ typedef struct ...@@ -54,7 +54,7 @@ typedef struct
* *
*/ */
long args[0]; long args[0];
} debug_sprintf_entry; } debug_sprintf_entry_t;
extern void tod_to_timeval(uint64_t todval, struct timeval *xtime); extern void tod_to_timeval(uint64_t todval, struct timeval *xtime);
...@@ -88,7 +88,7 @@ static int debug_raw_header_fn(debug_info_t * id, struct debug_view *view, ...@@ -88,7 +88,7 @@ static int debug_raw_header_fn(debug_info_t * id, struct debug_view *view,
int area, debug_entry_t * entry, char *out_buf); int area, debug_entry_t * entry, char *out_buf);
static int debug_sprintf_format_fn(debug_info_t * id, struct debug_view *view, static int debug_sprintf_format_fn(debug_info_t * id, struct debug_view *view,
char *out_buf, debug_sprintf_entry *curr_event); char *out_buf, debug_sprintf_entry_t *curr_event);
/* globals */ /* globals */
...@@ -692,31 +692,21 @@ extern inline debug_entry_t *get_active_entry(debug_info_t * id) ...@@ -692,31 +692,21 @@ extern inline debug_entry_t *get_active_entry(debug_info_t * id)
} }
/* /*
* debug_common: * debug_finish_entry:
* - set timestamp, caller address, cpu number etc. * - set timestamp, caller address, cpu number etc.
*/ */
extern inline debug_entry_t *debug_common(debug_info_t * id, int level, extern inline void debug_finish_entry(debug_info_t * id, debug_entry_t* active,
const void *buf, int len, int exception) int level, int exception)
{ {
unsigned long flags;
debug_entry_t *active;
spin_lock_irqsave(&id->lock, flags);
active = get_active_entry(id);
STCK(active->id.stck); STCK(active->id.stck);
active->id.fields.cpuid = smp_processor_id(); active->id.fields.cpuid = smp_processor_id();
active->caller = __builtin_return_address(0); active->caller = __builtin_return_address(0);
active->id.fields.exception = exception; active->id.fields.exception = exception;
active->id.fields.level = level; active->id.fields.level = level;
memset(DEBUG_DATA(active), 0, id->buf_size);
memcpy(DEBUG_DATA(active), buf, MIN(len, id->buf_size));
proceed_active_entry(id); proceed_active_entry(id);
if(exception) if(exception)
proceed_active_area(id); proceed_active_area(id);
spin_unlock_irqrestore(&id->lock, flags);
return active;
} }
/* /*
...@@ -727,7 +717,17 @@ extern inline debug_entry_t *debug_common(debug_info_t * id, int level, ...@@ -727,7 +717,17 @@ extern inline debug_entry_t *debug_common(debug_info_t * id, int level,
debug_entry_t *debug_event_common(debug_info_t * id, int level, const void *buf, debug_entry_t *debug_event_common(debug_info_t * id, int level, const void *buf,
int len) int len)
{ {
return debug_common(id, level, buf, len, 0); unsigned long flags;
debug_entry_t *active;
spin_lock_irqsave(&id->lock, flags);
active = get_active_entry(id);
memset(DEBUG_DATA(active), 0, id->buf_size);
memcpy(DEBUG_DATA(active), buf, MIN(len, id->buf_size));
debug_finish_entry(id, active, level, 0);
spin_unlock_irqrestore(&id->lock, flags);
return active;
} }
/* /*
...@@ -738,7 +738,17 @@ debug_entry_t *debug_event_common(debug_info_t * id, int level, const void *buf, ...@@ -738,7 +738,17 @@ debug_entry_t *debug_event_common(debug_info_t * id, int level, const void *buf,
debug_entry_t *debug_exception_common(debug_info_t * id, int level, debug_entry_t *debug_exception_common(debug_info_t * id, int level,
const void *buf, int len) const void *buf, int len)
{ {
return debug_common(id, level, buf, len, 1); unsigned long flags;
debug_entry_t *active;
spin_lock_irqsave(&id->lock, flags);
active = get_active_entry(id);
memset(DEBUG_DATA(active), 0, id->buf_size);
memcpy(DEBUG_DATA(active), buf, MIN(len, id->buf_size));
debug_finish_entry(id, active, level, 1);
spin_unlock_irqrestore(&id->lock, flags);
return active;
} }
/* /*
...@@ -764,27 +774,28 @@ debug_entry_t *debug_sprintf_event(debug_info_t* id, ...@@ -764,27 +774,28 @@ debug_entry_t *debug_sprintf_event(debug_info_t* id,
int level,char *string,...) int level,char *string,...)
{ {
va_list ap; va_list ap;
int numargs,alloc_size,idx; int numargs,idx;
debug_sprintf_entry *curr_event; unsigned long flags;
debug_entry_t *retval = NULL; debug_sprintf_entry_t *curr_event;
debug_entry_t *active;
if((!id) || (level > id->level)) if((!id) || (level > id->level))
return NULL; return NULL;
else {
numargs=debug_count_numargs(string); numargs=debug_count_numargs(string);
alloc_size=offsetof(debug_sprintf_entry,args[numargs]);
curr_event=alloca(alloc_size); spin_lock_irqsave(&id->lock, flags);
active = get_active_entry(id);
if(curr_event){ curr_event=(debug_sprintf_entry_t *) DEBUG_DATA(active);
va_start(ap,string); va_start(ap,string);
curr_event->string=string; curr_event->string=string;
for(idx=0;idx<numargs;idx++) for(idx=0;idx<MIN(numargs,((id->buf_size / sizeof(long))-1));idx++)
curr_event->args[idx]=va_arg(ap,long); curr_event->args[idx]=va_arg(ap,long);
retval=debug_common(id,level, curr_event,alloc_size,0); va_end(ap);
va_end(ap); debug_finish_entry(id, active, level, 0);
} spin_unlock_irqrestore(&id->lock, flags);
return retval;
} return active;
} }
/* /*
...@@ -795,27 +806,28 @@ debug_entry_t *debug_sprintf_exception(debug_info_t* id, ...@@ -795,27 +806,28 @@ debug_entry_t *debug_sprintf_exception(debug_info_t* id,
int level,char *string,...) int level,char *string,...)
{ {
va_list ap; va_list ap;
int numargs,alloc_size,idx; int numargs,idx;
debug_sprintf_entry *curr_event; unsigned long flags;
debug_entry_t *retval = NULL; debug_sprintf_entry_t *curr_event;
debug_entry_t *active;
if((!id) || (level > id->level)) if((!id) || (level > id->level))
return NULL; return NULL;
else {
numargs=debug_count_numargs(string); numargs=debug_count_numargs(string);
alloc_size=offsetof(debug_sprintf_entry,args[numargs]);
curr_event=alloca(alloc_size); spin_lock_irqsave(&id->lock, flags);
active = get_active_entry(id);
if(curr_event){ curr_event=(debug_sprintf_entry_t *)DEBUG_DATA(active);
va_start(ap,string); va_start(ap,string);
curr_event->string=string; curr_event->string=string;
for(idx=0;idx<numargs;idx++) for(idx=0;idx<MIN(numargs,((id->buf_size / sizeof(long))-1));idx++)
curr_event->args[idx]=va_arg(ap,long); curr_event->args[idx]=va_arg(ap,long);
retval=debug_common(id,level, curr_event,alloc_size,1); va_end(ap);
va_end(ap); debug_finish_entry(id, active, level, 1);
} spin_unlock_irqrestore(&id->lock, flags);
return retval;
} return active;
} }
/* /*
...@@ -1127,7 +1139,7 @@ int debug_dflt_header_fn(debug_info_t * id, struct debug_view *view, ...@@ -1127,7 +1139,7 @@ int debug_dflt_header_fn(debug_info_t * id, struct debug_view *view,
#define DEBUG_SPRINTF_MAX_ARGS 10 #define DEBUG_SPRINTF_MAX_ARGS 10
int debug_sprintf_format_fn(debug_info_t * id, struct debug_view *view, int debug_sprintf_format_fn(debug_info_t * id, struct debug_view *view,
char *out_buf, debug_sprintf_entry *curr_event) char *out_buf, debug_sprintf_entry_t *curr_event)
{ {
int num_longs, num_used_args = 0,i, rc = 0; int num_longs, num_used_args = 0,i, rc = 0;
int index[DEBUG_SPRINTF_MAX_ARGS]; int index[DEBUG_SPRINTF_MAX_ARGS];
......
...@@ -305,7 +305,8 @@ sysc_restart: ...@@ -305,7 +305,8 @@ sysc_restart:
# #
sysc_singlestep: sysc_singlestep:
ni __TI_flags+7(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP ni __TI_flags+7(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP
mvi SP_TRAP+1(%r15),0x28 # set trap indication to pgm check lhi %r0,__LC_PGM_OLD_PSW
sth %r0,SP_TRAP(%r15) # set trap indication to pgm check
la %r2,SP_PTREGS(%r15) # address of register-save area la %r2,SP_PTREGS(%r15) # address of register-save area
larl %r14,sysc_return # load adr. of system return larl %r14,sysc_return # load adr. of system return
jg do_debugger_trap # branch to do_debugger_trap jg do_debugger_trap # branch to do_debugger_trap
......
...@@ -518,19 +518,19 @@ void start_hz_timer(struct pt_regs *regs) ...@@ -518,19 +518,19 @@ void start_hz_timer(struct pt_regs *regs)
* Stop the HZ tick on the current CPU. * Stop the HZ tick on the current CPU.
* Only cpu_idle may call this function. * Only cpu_idle may call this function.
*/ */
int stop_hz_timer(void) void stop_hz_timer(void)
{ {
__u64 timer; __u64 timer;
if (sysctl_hz_timer != 0) if (sysctl_hz_timer != 0)
return 1; return;
/* /*
* 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())
return 1; return;
/* /*
* This cpu is going really idle. Set up the clock comparator * This cpu is going really idle. Set up the clock comparator
...@@ -540,8 +540,6 @@ int stop_hz_timer(void) ...@@ -540,8 +540,6 @@ int stop_hz_timer(void)
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));
return 0;
} }
#endif #endif
...@@ -572,8 +570,7 @@ int stop_timers(void) ...@@ -572,8 +570,7 @@ int stop_timers(void)
#endif #endif
#ifdef CONFIG_NO_IDLE_HZ #ifdef CONFIG_NO_IDLE_HZ
if (stop_hz_timer()) stop_hz_timer();
return 1;
#endif #endif
/* enable monitor call class 0 */ /* enable monitor call class 0 */
......
...@@ -34,7 +34,6 @@ struct __debug_entry{ ...@@ -34,7 +34,6 @@ struct __debug_entry{
#define __DEBUG_FEATURE_VERSION 1 /* version of debug feature */ #define __DEBUG_FEATURE_VERSION 1 /* version of debug feature */
#ifdef __KERNEL__ #ifdef __KERNEL__
#include <linux/version.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/time.h> #include <linux/time.h>
......
#ifndef __ARCH_S390_PERCPU__ #ifndef __ARCH_S390_PERCPU__
#define __ARCH_S390_PERCPU__ #define __ARCH_S390_PERCPU__
#include <asm-generic/percpu.h> #include <linux/compiler.h>
#include <asm/lowcore.h> #include <asm/lowcore.h>
#define __GENERIC_PER_CPU
/* /*
* For builtin kernel code s390 uses the generic implementation for * s390 uses its own implementation for per cpu data, the offset of
* per cpu data, with the exception that the offset of the cpu local * the cpu local data area is cached in the cpu's lowcore memory.
* data area is cached in the cpu's lowcore memory
* For 64 bit module code s390 forces the use of a GOT slot for the * For 64 bit module code s390 forces the use of a GOT slot for the
* address of the per cpu variable. This is needed because the module * address of the per cpu variable. This is needed because the module
* may be more than 4G above the per cpu area. * may be more than 4G above the per cpu area.
*/ */
#if defined(__s390x__) && defined(MODULE) #if defined(__s390x__) && defined(MODULE)
#define __get_got_cpu_var(var,offset) \
#define __reloc_hide(var,offset) \
(*({ unsigned long *__ptr; \ (*({ unsigned long *__ptr; \
asm ( "larl %0,per_cpu__"#var"@GOTENT" : "=a" (__ptr) ); \ asm ( "larl %0,per_cpu__"#var"@GOTENT" \
((typeof(&per_cpu__##var))((*__ptr) + offset)); \ : "=a" (__ptr) : "X" (per_cpu__##var) ); \
})) (typeof(&per_cpu__##var))((*__ptr) + (offset)); }))
#undef __get_cpu_var
#define __get_cpu_var(var) __get_got_cpu_var(var,S390_lowcore.percpu_offset)
#undef per_cpu
#define per_cpu(var,cpu) __get_got_cpu_var(var,__per_cpu_offset[cpu])
#else #else
#undef __get_cpu_var
#define __get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, S390_lowcore.percpu_offset)) #define __reloc_hide(var, offset) \
(*({ unsigned long __ptr; \
asm ( "" : "=a" (__ptr) : "0" (&per_cpu__##var) ); \
(typeof(&per_cpu__##var)) (__ptr + (offset)); }))
#endif #endif
#ifdef CONFIG_SMP
extern unsigned long __per_cpu_offset[NR_CPUS];
/* Separate out the type, so (int[3], foo) works. */
#define DEFINE_PER_CPU(type, name) \
__attribute__((__section__(".data.percpu"))) \
__typeof__(type) per_cpu__##name
#define __get_cpu_var(var) __reloc_hide(var,S390_lowcore.percpu_offset)
#define per_cpu(var,cpu) __reloc_hide(var,__per_cpu_offset[cpu])
/* A macro to avoid #include hell... */
#define percpu_modcopy(pcpudst, src, size) \
do { \
unsigned int __i; \
for (__i = 0; __i < NR_CPUS; __i++) \
if (cpu_possible(__i)) \
memcpy((pcpudst)+__per_cpu_offset[__i], \
(src), (size)); \
} while (0)
#else /* ! SMP */
#define DEFINE_PER_CPU(type, name) \
__typeof__(type) per_cpu__##name
#define __get_cpu_var(var) __reloc_hide(var,0)
#define per_cpu(var,cpu) __reloc_hide(var,0)
#endif /* SMP */
#define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name
#define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(per_cpu__##var)
#define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var)
#endif /* __ARCH_S390_PERCPU__ */ #endif /* __ARCH_S390_PERCPU__ */
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/hdreg.h> #include <linux/hdreg.h>
#include <linux/version.h>
#include <asm/dasd.h> #include <asm/dasd.h>
#endif #endif
......
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