From: Martin Schwidefsky From: Arnd Bergmann From: Christian Bornträger From: Michael Holzheu From: Martin Schwidefsky 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: Martin Schwidefsky Signed-off-by: Andrew Morton --- 25-akpm/arch/s390/Kconfig | 6 - 25-akpm/arch/s390/defconfig | 19 ++++- 25-akpm/arch/s390/kernel/debug.c | 120 ++++++++++++++++++++----------------- 25-akpm/arch/s390/kernel/entry64.S | 3 25-akpm/arch/s390/kernel/time.c | 11 +-- 25-akpm/include/asm-s390/debug.h | 1 25-akpm/include/asm-s390/percpu.h | 68 ++++++++++++++++---- 25-akpm/include/asm-s390/vtoc.h | 1 8 files changed, 144 insertions(+), 85 deletions(-) diff -puN arch/s390/defconfig~s390-core-changes arch/s390/defconfig --- 25/arch/s390/defconfig~s390-core-changes 2004-06-30 10:16:29.145329072 -0700 +++ 25-akpm/arch/s390/defconfig 2004-06-30 10:16:29.160326792 -0700 @@ -29,6 +29,7 @@ CONFIG_IKCONFIG_PROC=y # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_IOSCHED_NOOP=y @@ -45,6 +46,7 @@ CONFIG_MODULES=y CONFIG_OBSOLETE_MODPARM=y # CONFIG_MODVERSIONS is not set CONFIG_KMOD=y +CONFIG_STOP_MACHINE=y # # Base setup @@ -84,12 +86,14 @@ CONFIG_PFAULT=y # CONFIG_SHARED_KERNEL is not set # CONFIG_CMM 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 # # Generic Driver Options # +CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set # CONFIG_DEBUG_DRIVER is not set @@ -126,7 +130,6 @@ CONFIG_SCSI_LOGGING=y # SCSI low-level drivers # # CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_SATA is not set # CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_DEBUG is not set @@ -277,6 +280,7 @@ CONFIG_NET_SCH_TBF=m CONFIG_NET_SCH_GRED=m CONFIG_NET_SCH_DSMARK=m # CONFIG_NET_SCH_DELAY is not set +# CONFIG_NET_SCH_INGRESS is not set CONFIG_NET_QOS=y CONFIG_NET_ESTIMATOR=y CONFIG_NET_CLS=y @@ -285,8 +289,11 @@ CONFIG_NET_CLS_ROUTE4=m CONFIG_NET_CLS_ROUTE=y CONFIG_NET_CLS_FW=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_RSVP6=m +# CONFIG_NET_CLS_ACT is not set CONFIG_NET_CLS_POLICE=y # @@ -311,7 +318,11 @@ CONFIG_NET_ETHERNET=y # CONFIG_MII is not set # -# Gigabit Ethernet (1000/10000 Mbit) +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) # # @@ -450,7 +461,6 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_SOLARIS_X86_PARTITION is not set # CONFIG_UNIXWARE_DISKLABEL is not set # CONFIG_LDM_PARTITION is not set -# CONFIG_NEC98_PARTITION is not set # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set @@ -509,5 +519,6 @@ CONFIG_CRYPTO=y # # Library routines # +# CONFIG_CRC16 is not set # CONFIG_CRC32 is not set # CONFIG_LIBCRC32C is not set diff -puN arch/s390/Kconfig~s390-core-changes arch/s390/Kconfig --- 25/arch/s390/Kconfig~s390-core-changes 2004-06-30 10:16:29.146328920 -0700 +++ 25-akpm/arch/s390/Kconfig 2004-06-30 10:16:29.159326944 -0700 @@ -67,9 +67,9 @@ config MARCH_Z900 on older 31 bit only CPUs. config MARCH_Z990 - bool "IBM eServer zSeries model z990" + bool "IBM eServer zSeries model z890 and z990" 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 older machines such as the z900. @@ -154,7 +154,7 @@ config QDIO tristate "QDIO support" ---help--- 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 diff -puN arch/s390/kernel/debug.c~s390-core-changes arch/s390/kernel/debug.c --- 25/arch/s390/kernel/debug.c~s390-core-changes 2004-06-30 10:16:29.148328616 -0700 +++ 25-akpm/arch/s390/kernel/debug.c 2004-06-30 10:16:29.169325424 -0700 @@ -54,7 +54,7 @@ typedef struct * */ long args[0]; -} debug_sprintf_entry; +} debug_sprintf_entry_t; extern void tod_to_timeval(uint64_t todval, struct timeval *xtime); @@ -88,7 +88,7 @@ static int debug_raw_header_fn(debug_inf int area, debug_entry_t * entry, char *out_buf); 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 */ @@ -692,31 +692,21 @@ extern inline debug_entry_t *get_active_ } /* - * debug_common: + * debug_finish_entry: * - set timestamp, caller address, cpu number etc. */ -extern inline debug_entry_t *debug_common(debug_info_t * id, int level, - const void *buf, int len, int exception) +extern inline void debug_finish_entry(debug_info_t * id, debug_entry_t* active, + 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); active->id.fields.cpuid = smp_processor_id(); active->caller = __builtin_return_address(0); active->id.fields.exception = exception; 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); if(exception) proceed_active_area(id); - spin_unlock_irqrestore(&id->lock, flags); - - return active; } /* @@ -727,7 +717,17 @@ extern inline debug_entry_t *debug_commo debug_entry_t *debug_event_common(debug_info_t * id, int level, const void *buf, 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_ debug_entry_t *debug_exception_common(debug_info_t * id, int level, 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 int level,char *string,...) { va_list ap; - int numargs,alloc_size,idx; - debug_sprintf_entry *curr_event; - debug_entry_t *retval = NULL; + int numargs,idx; + unsigned long flags; + debug_sprintf_entry_t *curr_event; + debug_entry_t *active; if((!id) || (level > id->level)) return NULL; - else { - numargs=debug_count_numargs(string); - alloc_size=offsetof(debug_sprintf_entry,args[numargs]); - curr_event=alloca(alloc_size); - - if(curr_event){ - va_start(ap,string); - curr_event->string=string; - for(idx=0;idxargs[idx]=va_arg(ap,long); - retval=debug_common(id,level, curr_event,alloc_size,0); - va_end(ap); - } - return retval; - } + + numargs=debug_count_numargs(string); + + spin_lock_irqsave(&id->lock, flags); + active = get_active_entry(id); + curr_event=(debug_sprintf_entry_t *) DEBUG_DATA(active); + va_start(ap,string); + curr_event->string=string; + for(idx=0;idxbuf_size / sizeof(long))-1));idx++) + curr_event->args[idx]=va_arg(ap,long); + va_end(ap); + debug_finish_entry(id, active, level, 0); + spin_unlock_irqrestore(&id->lock, flags); + + return active; } /* @@ -795,27 +806,28 @@ debug_entry_t *debug_sprintf_exception(d int level,char *string,...) { va_list ap; - int numargs,alloc_size,idx; - debug_sprintf_entry *curr_event; - debug_entry_t *retval = NULL; + int numargs,idx; + unsigned long flags; + debug_sprintf_entry_t *curr_event; + debug_entry_t *active; if((!id) || (level > id->level)) return NULL; - else { - numargs=debug_count_numargs(string); - alloc_size=offsetof(debug_sprintf_entry,args[numargs]); - curr_event=alloca(alloc_size); - - if(curr_event){ - va_start(ap,string); - curr_event->string=string; - for(idx=0;idxargs[idx]=va_arg(ap,long); - retval=debug_common(id,level, curr_event,alloc_size,1); - va_end(ap); - } - return retval; - } + + numargs=debug_count_numargs(string); + + spin_lock_irqsave(&id->lock, flags); + active = get_active_entry(id); + curr_event=(debug_sprintf_entry_t *)DEBUG_DATA(active); + va_start(ap,string); + curr_event->string=string; + for(idx=0;idxbuf_size / sizeof(long))-1));idx++) + curr_event->args[idx]=va_arg(ap,long); + va_end(ap); + debug_finish_entry(id, active, level, 1); + spin_unlock_irqrestore(&id->lock, flags); + + return active; } /* @@ -1127,7 +1139,7 @@ int debug_dflt_header_fn(debug_info_t * #define DEBUG_SPRINTF_MAX_ARGS 10 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 index[DEBUG_SPRINTF_MAX_ARGS]; diff -puN arch/s390/kernel/entry64.S~s390-core-changes arch/s390/kernel/entry64.S --- 25/arch/s390/kernel/entry64.S~s390-core-changes 2004-06-30 10:16:29.150328312 -0700 +++ 25-akpm/arch/s390/kernel/entry64.S 2004-06-30 10:16:29.170325272 -0700 @@ -305,7 +305,8 @@ sysc_restart: # sysc_singlestep: 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 larl %r14,sysc_return # load adr. of system return jg do_debugger_trap # branch to do_debugger_trap diff -puN arch/s390/kernel/time.c~s390-core-changes arch/s390/kernel/time.c --- 25/arch/s390/kernel/time.c~s390-core-changes 2004-06-30 10:16:29.151328160 -0700 +++ 25-akpm/arch/s390/kernel/time.c 2004-06-30 10:16:29.171325120 -0700 @@ -518,19 +518,19 @@ void start_hz_timer(struct pt_regs *regs * Stop the HZ tick on the current CPU. * Only cpu_idle may call this function. */ -int stop_hz_timer(void) +void stop_hz_timer(void) { __u64 timer; if (sysctl_hz_timer != 0) - return 1; + return; /* * Leave the clock comparator set up for the next timer * tick if either rcu or a softirq is pending. */ if (rcu_pending(smp_processor_id()) || local_softirq_pending()) - return 1; + return; /* * This cpu is going really idle. Set up the clock comparator @@ -540,8 +540,6 @@ int stop_hz_timer(void) timer = (__u64) (next_timer_interrupt() - jiffies) + jiffies_64; timer = jiffies_timer_cc + timer * CLK_TICKS_PER_JIFFY; asm volatile ("SCKC %0" : : "m" (timer)); - - return 0; } #endif @@ -572,8 +570,7 @@ int stop_timers(void) #endif #ifdef CONFIG_NO_IDLE_HZ - if (stop_hz_timer()) - return 1; + stop_hz_timer(); #endif /* enable monitor call class 0 */ diff -puN include/asm-s390/debug.h~s390-core-changes include/asm-s390/debug.h --- 25/include/asm-s390/debug.h~s390-core-changes 2004-06-30 10:16:29.153327856 -0700 +++ 25-akpm/include/asm-s390/debug.h 2004-06-30 10:16:29.171325120 -0700 @@ -34,7 +34,6 @@ struct __debug_entry{ #define __DEBUG_FEATURE_VERSION 1 /* version of debug feature */ #ifdef __KERNEL__ -#include #include #include #include diff -puN include/asm-s390/percpu.h~s390-core-changes include/asm-s390/percpu.h --- 25/include/asm-s390/percpu.h~s390-core-changes 2004-06-30 10:16:29.154327704 -0700 +++ 25-akpm/include/asm-s390/percpu.h 2004-06-30 10:16:29.172324968 -0700 @@ -1,30 +1,70 @@ #ifndef __ARCH_S390_PERCPU__ #define __ARCH_S390_PERCPU__ -#include +#include #include +#define __GENERIC_PER_CPU + /* - * For builtin kernel code s390 uses the generic implementation for - * per cpu data, with the exception that the offset of the cpu local - * data area is cached in the cpu's lowcore memory + * s390 uses its own implementation for per cpu data, the offset of + * the cpu local 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 * address of the per cpu variable. This is needed because the module * may be more than 4G above the per cpu area. */ #if defined(__s390x__) && defined(MODULE) -#define __get_got_cpu_var(var,offset) \ + +#define __reloc_hide(var,offset) \ (*({ unsigned long *__ptr; \ - asm ( "larl %0,per_cpu__"#var"@GOTENT" : "=a" (__ptr) ); \ - ((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]) + asm ( "larl %0,per_cpu__"#var"@GOTENT" \ + : "=a" (__ptr) : "X" (per_cpu__##var) ); \ + (typeof(&per_cpu__##var))((*__ptr) + (offset)); })) + #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 +#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__ */ diff -puN include/asm-s390/vtoc.h~s390-core-changes include/asm-s390/vtoc.h --- 25/include/asm-s390/vtoc.h~s390-core-changes 2004-06-30 10:16:29.155327552 -0700 +++ 25-akpm/include/asm-s390/vtoc.h 2004-06-30 10:16:29.172324968 -0700 @@ -14,7 +14,6 @@ #include #include #include -#include #include #endif _