From: Dave A. <ai...@us...> - 2003-06-10 01:48:31
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/s390x/kernel In directory sc8-pr-cvs1:/tmp/cvs-serv23180/arch/s390x/kernel Modified Files: debug.c entry.S init_task.c ioctl32.c linux32.c process.c ptrace.c s390_ksyms.c setup.c smp.c time.c traps.c wrapper32.S Log Message: DA: sync to Marcelo 2.4.18 + remove init_mmap (no longer needed) Index: debug.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/s390x/kernel/debug.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- debug.c 9 Apr 2002 17:03:17 -0000 1.2 +++ debug.c 10 Jun 2003 01:46:13 -0000 1.3 @@ -228,8 +228,10 @@ strncpy(rc->name, name, MIN(strlen(name), (DEBUG_MAX_PROCF_LEN - 1))); rc->name[MIN(strlen(name), (DEBUG_MAX_PROCF_LEN - 1))] = 0; memset(rc->views, 0, DEBUG_MAX_VIEWS * sizeof(struct debug_view *)); +#ifdef CONFIG_PROC_FS memset(rc->proc_entries, 0 ,DEBUG_MAX_VIEWS * sizeof(struct proc_dir_entry*)); +#endif /* CONFIG_PROC_FS */ atomic_set(&(rc->ref_count), 0); return rc; @@ -346,8 +348,10 @@ if (!db_info) return; if (atomic_dec_and_test(&db_info->ref_count)) { +#ifdef DEBUG printk(KERN_INFO "debug: freeing debug area %p (%s)\n", db_info, db_info->name); +#endif for (i = 0; i < DEBUG_MAX_VIEWS; i++) { if (db_info->views[i] != NULL) debug_delete_proc_dir_entry @@ -541,14 +545,18 @@ debug_info_snapshot = debug_info_copy(debug_info); if(!debug_info_snapshot){ +#ifdef DEBUG printk(KERN_ERR "debug_open: debug_info_copy failed (out of mem)\n"); +#endif rc = -ENOMEM; goto out; } if ((file->private_data = kmalloc(sizeof(file_private_info_t), GFP_ATOMIC)) == 0) { +#ifdef DEBUG printk(KERN_ERR "debug_open: kmalloc failed\n"); +#endif debug_info_free(debug_info_snapshot); rc = -ENOMEM; goto out; @@ -602,6 +610,7 @@ { struct proc_dir_entry *rc = NULL; +#ifdef CONFIG_PROC_FS #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,98)) const char *fn = name; int len; @@ -634,6 +643,7 @@ #endif out: +#endif /* CONFIG_PROC_FS */ return rc; } @@ -646,12 +656,14 @@ (struct proc_dir_entry *root, struct proc_dir_entry *proc_entry) { +#ifdef CONFIG_PROC_FS #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,98)) proc_unregister(root, proc_entry->low_ino); kfree(proc_entry); #else remove_proc_entry(proc_entry->name, root); #endif +#endif /* CONFIG_PROC_FS */ } /* @@ -677,9 +689,11 @@ goto out; debug_register_view(rc, &debug_level_view); debug_register_view(rc, &debug_flush_view); +#ifdef DEBUG printk(KERN_INFO "debug: reserved %d areas of %d pages for debugging %s\n", nr_areas, 1 << page_order, rc->name); +#endif out: if (rc == NULL){ printk(KERN_ERR "debug: debug_register failed for %s\n",name); @@ -699,7 +713,9 @@ if (!id) goto out; down(&debug_lock); +#ifdef DEBUG printk(KERN_INFO "debug: unregistering %s\n", id->name); +#endif debug_info_put(id); up(&debug_lock); @@ -906,11 +922,13 @@ down(&debug_lock); if (!initialized) { +#ifdef CONFIG_PROC_FS debug_proc_root_entry = debug_create_proc_dir_entry(&proc_root, DEBUG_DIR_ROOT, S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR | S_IWGRP, NULL, NULL); +#endif /* CONFIG_PROC_FS */ printk(KERN_INFO "debug: Initialization complete\n"); initialized = 1; } @@ -1271,7 +1289,9 @@ #ifdef DEBUG printk("debug_cleanup_module: \n"); #endif +#ifdef CONFIG_PROC_FS debug_delete_proc_dir_entry(&proc_root, debug_proc_root_entry); +#endif /* CONFIG_PROC_FS */ return; } Index: entry.S =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/s390x/kernel/entry.S,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- entry.S 9 Apr 2002 17:03:17 -0000 1.2 +++ entry.S 10 Jun 2003 01:46:13 -0000 1.3 @@ -79,7 +79,7 @@ sigpending = 16 need_resched = 32 tsk_ptrace = 40 -processor = 92 +processor = 88 /* * Register usage in interrupt handlers: Index: init_task.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/s390x/kernel/init_task.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- init_task.c 25 Feb 2001 23:15:23 -0000 1.1.1.1 +++ init_task.c 10 Jun 2003 01:46:13 -0000 1.2 @@ -12,7 +12,6 @@ #include <asm/uaccess.h> #include <asm/pgtable.h> -static struct vm_area_struct init_mmap = INIT_MMAP; static struct fs_struct init_fs = INIT_FS; static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS; Index: ioctl32.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/s390x/kernel/ioctl32.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- ioctl32.c 9 Apr 2002 17:03:17 -0000 1.2 +++ ioctl32.c 10 Jun 2003 01:46:13 -0000 1.3 @@ -24,6 +24,7 @@ #include <linux/route.h> #include <linux/ext2_fs.h> #include <linux/hdreg.h> +#include <linux/if_bonding.h> #include <asm/types.h> #include <asm/uaccess.h> #include <asm/dasd.h> @@ -195,6 +196,58 @@ out: if(ifc.ifc_buf != NULL) kfree (ifc.ifc_buf); + return err; +} + +static int bond_ioctl(unsigned long fd, unsigned int cmd, unsigned long arg) +{ + struct ifreq ifr; + mm_segment_t old_fs; + int err, len; + u32 data; + + if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32))) + return -EFAULT; + ifr.ifr_data = (__kernel_caddr_t)get_free_page(GFP_KERNEL); + if (!ifr.ifr_data) + return -EAGAIN; + + switch (cmd) { + case SIOCBONDENSLAVE: + case SIOCBONDRELEASE: + case SIOCBONDSETHWADDR: + case SIOCBONDCHANGEACTIVE: + len = IFNAMSIZ * sizeof(char); + break; + case SIOCBONDSLAVEINFOQUERY: + len = sizeof(struct ifslave); + break; + case SIOCBONDINFOQUERY: + len = sizeof(struct ifbond); + break; + default: + err = -EINVAL; + goto out; + }; + + __get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data)); + if (copy_from_user(ifr.ifr_data, (char *)A(data), len)) { + err = -EFAULT; + goto out; + } + + old_fs = get_fs(); + set_fs (KERNEL_DS); + err = sys_ioctl (fd, cmd, (unsigned long)&ifr); + set_fs (old_fs); + if (!err) { + len = copy_to_user((char *)A(data), ifr.ifr_data, len); + if (len) + err = -EFAULT; + } + +out: + free_page((unsigned long)ifr.ifr_data); return err; } Index: linux32.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/s390x/kernel/linux32.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- linux32.c 9 Apr 2002 17:03:17 -0000 1.2 +++ linux32.c 10 Jun 2003 01:46:13 -0000 1.3 @@ -897,24 +897,24 @@ return sys32_fcntl(fd, cmd, arg); } -struct mem_dqblk32 { +struct dqblk32 { + __u32 dqb_bhardlimit; + __u32 dqb_bsoftlimit; + __u32 dqb_curblocks; __u32 dqb_ihardlimit; __u32 dqb_isoftlimit; __u32 dqb_curinodes; - __u32 dqb_bhardlimit; - __u32 dqb_bsoftlimit; - __u64 dqb_curspace; __kernel_time_t32 dqb_btime; __kernel_time_t32 dqb_itime; }; -extern asmlinkage long sys_quotactl(int cmd, const char *special, int id, __kernel_caddr_t addr); +extern asmlinkage int sys_quotactl(int cmd, const char *special, int id, caddr_t addr); asmlinkage int sys32_quotactl(int cmd, const char *special, int id, unsigned long addr) { int cmds = cmd >> SUBCMDSHIFT; int err; - struct mem_dqblk d; + struct dqblk d; mm_segment_t old_fs; char *spec; @@ -924,32 +924,32 @@ case Q_SETQUOTA: case Q_SETUSE: case Q_SETQLIM: - if (copy_from_user (&d, (struct mem_dqblk32 *)addr, - sizeof (struct mem_dqblk32))) + if (copy_from_user (&d, (struct dqblk32 *)addr, + sizeof (struct dqblk32))) return -EFAULT; - d.dqb_itime = ((struct mem_dqblk32 *)&d)->dqb_itime; - d.dqb_btime = ((struct mem_dqblk32 *)&d)->dqb_btime; + d.dqb_itime = ((struct dqblk32 *)&d)->dqb_itime; + d.dqb_btime = ((struct dqblk32 *)&d)->dqb_btime; break; default: return sys_quotactl(cmd, special, - id, (__kernel_caddr_t)addr); + id, (caddr_t)addr); } spec = getname (special); err = PTR_ERR(spec); if (IS_ERR(spec)) return err; old_fs = get_fs (); set_fs (KERNEL_DS); - err = sys_quotactl(cmd, (const char *)spec, id, (__kernel_caddr_t)&d); + err = sys_quotactl(cmd, (const char *)spec, id, (caddr_t)&d); set_fs (old_fs); putname (spec); if (err) return err; if (cmds == Q_GETQUOTA) { __kernel_time_t b = d.dqb_btime, i = d.dqb_itime; - ((struct mem_dqblk32 *)&d)->dqb_itime = i; - ((struct mem_dqblk32 *)&d)->dqb_btime = b; - if (copy_to_user ((struct mem_dqblk32 *)addr, &d, - sizeof (struct mem_dqblk32))) + ((struct dqblk32 *)&d)->dqb_itime = i; + ((struct dqblk32 *)&d)->dqb_btime = b; + if (copy_to_user ((struct dqblk32 *)addr, &d, + sizeof (struct dqblk32))) return -EFAULT; } return 0; Index: process.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/s390x/kernel/process.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- process.c 9 Apr 2002 17:03:18 -0000 1.2 +++ process.c 10 Jun 2003 01:46:14 -0000 1.3 @@ -75,171 +75,22 @@ } } -/* - As all the register will only be made displayable to the root - user ( via printk ) or checking if the uid of the user is 0 from - the /proc filesystem please god this will be secure enough DJB. - The lines are given one at a time so as not to chew stack space in - printk on a crash & also for the proc filesystem when you get - 0 returned you know you've got all the lines - */ - -static int sprintf_regs(int line, char *buff, struct task_struct *task, struct pt_regs *regs) -{ - int linelen=0; - int regno,chaincnt; - u64 backchain,prev_backchain,endchain; - u64 ksp = 0; - char *mode = "???"; - - enum - { - sp_linefeed, - sp_psw, - sp_ksp, - sp_gprs, - sp_gprs1, - sp_gprs2, - sp_gprs3, - sp_gprs4, - sp_gprs5, - sp_gprs6, - sp_gprs7, - sp_gprs8, - sp_acrs, - sp_acrs1, - sp_acrs2, - sp_acrs3, - sp_acrs4, - sp_kern_backchain, - sp_kern_backchain1 - }; - - if (task) - ksp = task->thread.ksp; - if (regs && !(regs->psw.mask & PSW_PROBLEM_STATE)) - ksp = regs->gprs[15]; - - if (regs) - mode = (regs->psw.mask & PSW_PROBLEM_STATE)? - "User" : "Kernel"; - - switch(line) - { - case sp_linefeed: - linelen=sprintf(buff,"\n"); - break; - case sp_psw: - if(regs) - linelen=sprintf(buff, "%s PSW: %016lx %016lx %s\n", mode, - (unsigned long) regs->psw.mask, - (unsigned long) regs->psw.addr, - print_tainted()); - else - linelen=sprintf(buff,"pt_regs=NULL some info unavailable\n"); - break; - case sp_ksp: - linelen=sprintf(&buff[linelen], - "task: %016lx ksp: %016lx pt_regs: %016lx\n", - (addr_t)task, (addr_t)ksp, (addr_t)regs); - break; - case sp_gprs: - if(regs) - linelen=sprintf(buff, "%s GPRS:\n", mode); - break; - case sp_gprs1 ... sp_gprs8: - if(regs) - { - regno=(line-sp_gprs1)*2; - linelen = sprintf(buff,"%016lx %016lx\n", - regs->gprs[regno], - regs->gprs[regno+1]); - } - break; - case sp_acrs: - if(regs) - linelen=sprintf(buff, "%s ACRS:\n", mode); - break; - case sp_acrs1 ... sp_acrs4: - if(regs) - { - regno=(line-sp_acrs1)*4; - linelen=sprintf(buff,"%08x %08x %08x %08x\n", - regs->acrs[regno], - regs->acrs[regno+1], - regs->acrs[regno+2], - regs->acrs[regno+3]); - } - break; - case sp_kern_backchain: - if (regs && (regs->psw.mask & PSW_PROBLEM_STATE)) - break; - if (ksp) - linelen=sprintf(buff, "Kernel BackChain CallChain\n"); - break; - default: - if (ksp) - { - - backchain=ksp&PSW_ADDR_MASK; - endchain=((backchain&(-THREAD_SIZE))+THREAD_SIZE); - prev_backchain=backchain-1; - line-=sp_kern_backchain1; - for(chaincnt=0;;chaincnt++) - { - if((backchain==0)||(backchain>=endchain) - ||(chaincnt>=8)||(prev_backchain>=backchain)) - break; - if(chaincnt==line) - { - linelen+=sprintf(&buff[linelen]," %016lx [<%016lx>]\n", - backchain, - *(u64 *)(backchain+112)&PSW_ADDR_MASK); - break; - } - prev_backchain=backchain; - backchain=(*((u64 *)backchain))&PSW_ADDR_MASK; - } - } - } - return(linelen); -} +extern void show_registers(struct pt_regs *regs); +extern void show_trace(unsigned long *sp); void show_regs(struct pt_regs *regs) { - char buff[80]; - int i, line; - - printk("CPU: %d\n",smp_processor_id()); - printk("Process %s (pid: %d, stackpage=%016lX)\n", - current->comm, current->pid, 4096+(addr_t)current); - - for (line = 0; sprintf_regs(line, buff, current, regs); line++) - printk(buff); - - if (regs->psw.mask & PSW_PROBLEM_STATE) - { - printk("User Code:\n"); - memset(buff, 0, 20); - copy_from_user(buff, - (char *) (regs->psw.addr & PSW_ADDR_MASK), 20); - for (i = 0; i < 20; i++) - printk("%02x ", buff[i]); - printk("\n"); - } -} - -char *task_show_regs(struct task_struct *task, char *buffer) -{ - int line, len; + struct task_struct *tsk = current; - for (line = 0; ; line++) - { - len = sprintf_regs(line, buffer, task, NULL); - if (!len) break; - buffer += len; - } - return buffer; + printk("CPU: %d %s\n", tsk->processor, print_tainted()); + printk("Process %s (pid: %d, task: %016lx, ksp: %016lx)\n", + current->comm, current->pid, (unsigned long) tsk, + tsk->thread.ksp); + + show_registers(regs); + /* Show stack backtrace if pt_regs is from kernel mode */ + if (!(regs->psw.mask & PSW_PROBLEM_STATE)) + show_trace((unsigned long *) regs->gprs[15]); } int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) @@ -301,16 +152,10 @@ unsigned long gprs[10]; /* gprs 6 -15 */ unsigned long fprs[2]; /* fpr 4 and 6 */ unsigned long empty[2]; -#if CONFIG_REMOTE_DEBUG - struct gdb_pt_regs childregs; -#else struct pt_regs childregs; -#endif } *frame; frame = (struct stack_frame *) (4*PAGE_SIZE + (unsigned long) p) -1; - frame = (struct stack_frame *) (((unsigned long) frame)&-8L); - p->thread.regs = &frame->childregs; p->thread.ksp = (unsigned long) frame; frame->childregs = *regs; frame->childregs.gprs[15] = new_stackp; Index: ptrace.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/s390x/kernel/ptrace.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- ptrace.c 9 Apr 2002 17:03:18 -0000 1.2 +++ ptrace.c 10 Jun 2003 01:46:14 -0000 1.3 @@ -41,7 +41,7 @@ void FixPerRegisters(struct task_struct *task) { - struct pt_regs *regs = task->thread.regs; + struct pt_regs *regs = __KSTK_PTREGS(task); per_struct *per_info= (per_struct *)&task->thread.per_info; @@ -169,7 +169,7 @@ mask=PSW_ADDR_MASK; if(useraddr<PT_FPC) { - realuseraddr=(addr_t)&(((u8 *)task->thread.regs)[useraddr]); + realuseraddr=((addr_t) __KSTK_PTREGS(task)) + useraddr; if(useraddr<PT_PSWMASK) { copymax=PT_PSWMASK; Index: s390_ksyms.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/s390x/kernel/s390_ksyms.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- s390_ksyms.c 9 Apr 2002 17:03:18 -0000 1.2 +++ s390_ksyms.c 10 Jun 2003 01:46:14 -0000 1.3 @@ -21,8 +21,9 @@ EXPORT_SYMBOL_NOVERS(_oi_bitmap); EXPORT_SYMBOL_NOVERS(_ni_bitmap); EXPORT_SYMBOL_NOVERS(_zb_findmap); -EXPORT_SYMBOL_NOVERS(__copy_from_user_fixup); -EXPORT_SYMBOL_NOVERS(__copy_to_user_fixup); +EXPORT_SYMBOL_NOVERS(__copy_from_user_asm); +EXPORT_SYMBOL_NOVERS(__copy_to_user_asm); +EXPORT_SYMBOL_NOVERS(__clear_user_asm); /* * semaphore ops @@ -38,6 +39,7 @@ EXPORT_SYMBOL_NOVERS(memcmp); EXPORT_SYMBOL_NOVERS(memset); EXPORT_SYMBOL_NOVERS(memmove); +EXPORT_SYMBOL_NOVERS(memscan); EXPORT_SYMBOL_NOVERS(strlen); EXPORT_SYMBOL_NOVERS(strchr); EXPORT_SYMBOL_NOVERS(strcmp); @@ -67,4 +69,3 @@ EXPORT_SYMBOL(console_mode); EXPORT_SYMBOL(console_device); EXPORT_SYMBOL_NOVERS(do_call_softirq); - Index: setup.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/s390x/kernel/setup.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- setup.c 9 Apr 2002 17:03:18 -0000 1.2 +++ setup.c 10 Jun 2003 01:46:14 -0000 1.3 @@ -425,9 +425,10 @@ lowcore->io_new_psw.mask = _IO_PSW_MASK; lowcore->io_new_psw.addr = (addr_t) &io_int_handler; lowcore->ipl_device = S390_lowcore.ipl_device; - lowcore->kernel_stack = ((__u32) &init_task_union) + 16384; + lowcore->kernel_stack = ((__u64) &init_task_union) + 16384; lowcore->async_stack = (__u64) __alloc_bootmem(4*PAGE_SIZE, 4*PAGE_SIZE, 0) + 16384; + lowcore->jiffy_timer = -1LL; set_prefix((__u32)(__u64) lowcore); cpu_init(); boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr; @@ -474,15 +475,16 @@ static int show_cpuinfo(struct seq_file *m, void *v) { struct cpuinfo_S390 *cpuinfo; - unsigned n = v; + unsigned long n = (unsigned long) v - 1; - if (!n--) { + if (!n) { seq_printf(m, "vendor_id : IBM/S390\n" "# processors : %i\n" "bogomips per cpu: %lu.%02lu\n", smp_num_cpus, loops_per_jiffy/(500000/HZ), (loops_per_jiffy/(5000/HZ))%100); - } else if (cpu_online_map & (1 << n)) { + } + if (cpu_online_map & (1 << n)) { cpuinfo = &safe_get_cpu_lowcore(n).cpu_data; seq_printf(m, "processor %i: " "version = %02X, " @@ -497,7 +499,7 @@ static void *c_start(struct seq_file *m, loff_t *pos) { - return *pos <= NR_CPUS ? (void)(*pos+1) : NULL; + return *pos <= NR_CPUS ? (void *)((unsigned long) *pos + 1) : NULL; } static void *c_next(struct seq_file *m, void *v, loff_t *pos) { Index: smp.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/s390x/kernel/smp.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- smp.c 10 Jun 2003 01:13:16 -0000 1.3 +++ smp.c 10 Jun 2003 01:46:14 -0000 1.4 @@ -49,9 +49,6 @@ static int max_cpus = NR_CPUS; /* Setup configured maximum number of CPUs to activate */ int smp_num_cpus; struct _lowcore *lowcore_ptr[NR_CPUS]; -unsigned int prof_multiplier[NR_CPUS]; -unsigned int prof_old_multiplier[NR_CPUS]; -unsigned int prof_counter[NR_CPUS]; cycles_t cacheflush_time=0; int smp_threads_ready=0; /* Set when the idlers are all forked. */ static atomic_t smp_commenced = ATOMIC_INIT(0); @@ -453,7 +450,7 @@ /* * Activate a secondary processor. */ -extern void init_100hz_timer(void); +extern void init_cpu_timer(void); extern int pfault_init(void); int __init start_secondary(void *cpuvoid) @@ -465,8 +462,8 @@ /* Wait for completion of smp startup */ while (!atomic_read(&smp_commenced)) /* nothing */ ; - /* init per CPU 100 hz timer */ - init_100hz_timer(); + /* init per CPU timer */ + init_cpu_timer(); #ifdef CONFIG_PFAULT /* Enable pfault pseudo page faults on this cpu. */ pfault_init(); @@ -519,7 +516,7 @@ cpu_lowcore=&get_cpu_lowcore(cpu); cpu_lowcore->save_area[15] = idle->thread.ksp; - cpu_lowcore->kernel_stack = (idle->thread.ksp | 16383) + 1; + cpu_lowcore->kernel_stack = (__u64) idle + 16384; __asm__ __volatile__("la 1,%0\n\t" "stctg 0,15,0(1)\n\t" "la 1,%1\n\t" @@ -571,15 +568,7 @@ /* * Initialize the logical to physical CPU number mapping - * and the per-CPU profiling counter/multiplier */ - - for (i = 0; i < NR_CPUS; i++) { - prof_counter[i] = 1; - prof_old_multiplier[i] = 1; - prof_multiplier[i] = 1; - } - print_cpu_info(&safe_get_cpu_lowcore(0).cpu_data); for(i = 0; i < smp_num_cpus; i++) @@ -631,56 +620,6 @@ int setup_profiling_timer(unsigned int multiplier) { return 0; -} - -/* - * Local timer interrupt handler. It does both profiling and - * process statistics/rescheduling. - * - * We do profiling in every local tick, statistics/rescheduling - * happen only every 'profiling multiplier' ticks. The default - * multiplier is 1 and it can be changed by writing the new multiplier - * value into /proc/profile. - */ - -void smp_local_timer_interrupt(struct pt_regs * regs) -{ - int user = (user_mode(regs) != 0); - int cpu = smp_processor_id(); - - /* - * The profiling function is SMP safe. (nothing can mess - * around with "current", and the profiling counters are - * updated with atomic operations). This is especially - * useful with a profiling multiplier != 1 - */ - if (!user_mode(regs)) - s390_do_profile(regs->psw.addr); - - if (!--prof_counter[cpu]) { - - /* - * The multiplier may have changed since the last time we got - * to this point as a result of the user writing to - * /proc/profile. In this case we need to adjust the APIC - * timer accordingly. - * - * Interrupts are already masked off at this point. - */ - prof_counter[cpu] = prof_multiplier[cpu]; - if (prof_counter[cpu] != prof_old_multiplier[cpu]) { - prof_old_multiplier[cpu] = prof_counter[cpu]; - } - - /* - * After doing the above, we need to make like - * a normal interrupt - otherwise timer interrupts - * ignore the global interrupt lock, which is the - * WrongThing (tm) to do. - */ - - update_process_times(user); - } } EXPORT_SYMBOL(lowcore_ptr); Index: time.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/s390x/kernel/time.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- time.c 9 Apr 2002 17:03:18 -0000 1.2 +++ time.c 10 Jun 2003 01:46:14 -0000 1.3 @@ -33,65 +33,33 @@ #include <asm/irq.h> #include <asm/s390_ext.h> - /* change this if you have some constant time drift */ -#define USECS_PER_JIFFY ((signed long)1000000/HZ) -#define CLK_TICKS_PER_JIFFY ((signed long)USECS_PER_JIFFY<<12) +#define USECS_PER_JIFFY ((unsigned long) 1000000/HZ) +#define CLK_TICKS_PER_JIFFY ((unsigned long) USECS_PER_JIFFY << 12) #define TICK_SIZE tick -static uint64_t init_timer_cc, last_timer_cc; +static uint64_t init_timer_cc; extern rwlock_t xtime_lock; extern unsigned long wall_jiffies; -void tod_to_timeval(uint64_t todval, struct timeval *xtime) +void tod_to_timeval(__u64 todval, struct timeval *xtime) { -#if 0 - const int high_bit = 0x80000000L; - const int c_f4240 = 0xf4240L; - const int c_7a120 = 0x7a120; - /* We have to divide the 64 bit value todval by 4096 - * (because the 2^12 bit is the one that changes every - * microsecond) and then split it into seconds and - * microseconds. A value of max (2^52-1) divided by - * the value 0xF4240 can yield a max result of approx - * (2^32.068). Thats to big to fit into a signed int - * ... hacking time! - */ - asm volatile ("L 2,%1\n\t" - "LR 3,2\n\t" - "SRL 2,12\n\t" - "SLL 3,20\n\t" - "L 4,%O1+4(%R1)\n\t" - "SRL 4,12\n\t" - "OR 3,4\n\t" /* now R2/R3 contain (todval >> 12) */ - "SR 4,4\n\t" - "CL 2,%2\n\t" - "JL .+12\n\t" - "S 2,%2\n\t" - "L 4,%3\n\t" - "D 2,%4\n\t" - "OR 3,4\n\t" - "ST 2,%O0+4(%R0)\n\t" - "ST 3,%0" - : "=m" (*xtime) : "m" (todval), - "m" (c_7a120), "m" (high_bit), "m" (c_f4240) - : "cc", "memory", "2", "3", "4" ); -#else - todval >>= 12; - xtime->tv_sec = todval / 1000000; - xtime->tv_usec = todval % 1000000; -#endif + todval >>= 12; + xtime->tv_sec = todval / 1000000; + xtime->tv_usec = todval % 1000000; } -unsigned long do_gettimeoffset(void) +static inline unsigned long do_gettimeoffset(void) { - __u64 timer_cc; + __u64 now; - asm volatile ("STCK %0" : "=m" (timer_cc)); - /* We require the offset from the previous interrupt */ - return ((unsigned long)((timer_cc - last_timer_cc)>>12)); + asm ("STCK %0" : "=m" (now)); + now = (now - init_timer_cc) >> 12; + /* We require the offset from the latest update of xtime */ + now -= (__u64) wall_jiffies*USECS_PER_JIFFY; + return (unsigned long) now; } /* @@ -101,15 +69,10 @@ { unsigned long flags; unsigned long usec, sec; - unsigned long lost_ticks; read_lock_irqsave(&xtime_lock, flags); - lost_ticks = jiffies - wall_jiffies; - usec = do_gettimeoffset(); - if (lost_ticks) - usec +=(USECS_PER_JIFFY*lost_ticks); sec = xtime.tv_sec; - usec += xtime.tv_usec; + usec = xtime.tv_usec + do_gettimeoffset(); read_unlock_irqrestore(&xtime_lock, flags); while (usec >= 1000000) { @@ -155,51 +118,31 @@ extern __u16 boot_cpu_addr; #endif -void do_timer_interrupt(struct pt_regs *regs, __u16 error_code) +static void do_comparator_interrupt(struct pt_regs *regs, __u16 error_code) { int cpu = smp_processor_id(); irq_enter(cpu, 0); - /* - * reset timer to 10ms minus time already elapsed - * since timer-interrupt pending - */ + /* + * set clock comparator for next tick + */ + S390_lowcore.jiffy_timer += CLK_TICKS_PER_JIFFY; + asm volatile ("SCKC %0" : : "m" (S390_lowcore.jiffy_timer)); + #ifdef CONFIG_SMP - if(S390_lowcore.cpu_data.cpu_addr==boot_cpu_addr) { + if (S390_lowcore.cpu_data.cpu_addr == boot_cpu_addr) write_lock(&xtime_lock); - last_timer_cc = S390_lowcore.jiffy_timer_cc; - } -#else - last_timer_cc = S390_lowcore.jiffy_timer_cc; -#endif - /* set clock comparator */ - S390_lowcore.jiffy_timer_cc += CLK_TICKS_PER_JIFFY; - asm volatile ("SCKC %0" : : "m" (S390_lowcore.jiffy_timer_cc)); -/* - * In the SMP case we use the local timer interrupt to do the - * profiling, except when we simulate SMP mode on a uniprocessor - * system, in that case we have to call the local interrupt handler. - */ -#ifdef CONFIG_SMP - /* when SMP, do smp_local_timer_interrupt for *all* CPUs, - but only do the rest for the boot CPU */ - smp_local_timer_interrupt(regs); -#else - if (!user_mode(regs)) - s390_do_profile(regs->psw.addr); -#endif + update_process_times(user_mode(regs)); -#ifdef CONFIG_SMP - if(S390_lowcore.cpu_data.cpu_addr==boot_cpu_addr) -#endif - { + if (S390_lowcore.cpu_data.cpu_addr == boot_cpu_addr) { do_timer(regs); -#ifdef CONFIG_SMP write_unlock(&xtime_lock); -#endif } +#else + do_timer(regs); +#endif irq_exit(cpu, 0); } @@ -207,19 +150,17 @@ /* * Start the clock comparator on the current CPU */ -static unsigned long cr0 __attribute__ ((aligned (8))); - -void init_100hz_timer(void) +void init_cpu_timer(void) { + unsigned long cr0; + /* allow clock comparator timer interrupt */ asm volatile ("STCTG 0,0,%0" : "=m" (cr0) : : "memory"); cr0 |= 0x800; asm volatile ("LCTLG 0,0,%0" : : "m" (cr0) : "memory"); - /* set clock comparator */ - /* read the TOD clock */ - asm volatile ("STCK %0" : "=m" (S390_lowcore.jiffy_timer_cc)); - S390_lowcore.jiffy_timer_cc += CLK_TICKS_PER_JIFFY; - asm volatile ("SCKC %0" : : "m" (S390_lowcore.jiffy_timer_cc)); + S390_lowcore.jiffy_timer = (__u64) jiffies * CLK_TICKS_PER_JIFFY; + S390_lowcore.jiffy_timer += init_timer_cc + CLK_TICKS_PER_JIFFY; + asm volatile ("SCKC %0" : : "m" (S390_lowcore.jiffy_timer)); } /* @@ -228,6 +169,7 @@ */ void __init time_init(void) { + __u64 set_time_cc; int cc; /* kick the TOD clock */ @@ -247,15 +189,16 @@ printk("time_init: TOD clock stopped/non-operational\n"); break; } + + /* set xtime */ + set_time_cc = init_timer_cc - 0x8126d60e46000000LL + + (0x3c26700LL*1000000*4096); + tod_to_timeval(set_time_cc, &xtime); + /* request the 0x1004 external interrupt */ - if (register_external_interrupt(0x1004, do_timer_interrupt) != 0) - panic("Couldn't request external interrupts 0x1004"); - init_100hz_timer(); - init_timer_cc = S390_lowcore.jiffy_timer_cc; - init_timer_cc -= 0x8126d60e46000000LL - - (0x3c26700LL*1000000*4096); - tod_to_timeval(init_timer_cc, &xtime); + if (register_external_interrupt(0x1004, do_comparator_interrupt) != 0) + panic("Couldn't request external interrupt 0x1004"); - /* Set do_get_fast_time function pointer. */ - do_get_fast_time = do_gettimeofday; + /* init CPU timer */ + init_cpu_timer(); } Index: traps.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/s390x/kernel/traps.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- traps.c 9 Apr 2002 17:03:18 -0000 1.2 +++ traps.c 10 Jun 2003 01:46:14 -0000 1.3 @@ -26,6 +26,7 @@ #include <linux/smp_lock.h> #include <linux/init.h> #include <linux/delay.h> +#include <linux/module.h> #include <asm/system.h> #include <asm/uaccess.h> @@ -58,6 +59,203 @@ extern void pfault_interrupt(struct pt_regs *regs, __u16 error_code); #endif +int kstack_depth_to_print = 20; + +/* + * If the address is either in the .text section of the + * kernel, or in the vmalloc'ed module regions, it *may* + * be the address of a calling routine + */ +extern char _stext, _etext; + +#ifdef CONFIG_MODULES + +extern struct module *module_list; +extern struct module kernel_module; + +static inline int kernel_text_address(unsigned long addr) +{ + int retval = 0; + struct module *mod; + + if (addr >= (unsigned long) &_stext && + addr <= (unsigned long) &_etext) + return 1; + + for (mod = module_list; mod != &kernel_module; mod = mod->next) { + /* mod_bound tests for addr being inside the vmalloc'ed + * module area. Of course it'd be better to test only + * for the .text subset... */ + if (mod_bound(addr, 0, mod)) { + retval = 1; + break; + } + } + + return retval; +} + +#else + +static inline int kernel_text_address(unsigned long addr) +{ + return (addr >= (unsigned long) &_stext && + addr <= (unsigned long) &_etext); +} + +#endif + +void show_trace(unsigned long * stack) +{ + unsigned long backchain, low_addr, high_addr, ret_addr; + int i; + + if (!stack) + stack = (unsigned long*)&stack; + + printk("Call Trace: "); + low_addr = ((unsigned long) stack) & PSW_ADDR_MASK; + high_addr = (low_addr & (-THREAD_SIZE)) + THREAD_SIZE; + /* Skip the first frame (biased stack) */ + backchain = *((unsigned long *) low_addr) & PSW_ADDR_MASK; + /* Print up to 8 lines */ + for (i = 0; i < 8; i++) { + if (backchain < low_addr || backchain >= high_addr) + break; + ret_addr = *((unsigned long *) (backchain+112)) & PSW_ADDR_MASK; + if (!kernel_text_address(ret_addr)) + break; + if (i && ((i % 3) == 0)) + printk("\n "); + printk("[<%016lx>] ", ret_addr); + low_addr = backchain; + backchain = *((unsigned long *) backchain) & PSW_ADDR_MASK; + } + printk("\n"); +} + +void show_trace_task(struct task_struct *tsk) +{ + /* + * We can't print the backtrace of a running process. It is + * unreliable at best and can cause kernel oopses. + */ + if (task_has_cpu(tsk)) + return; + show_trace((unsigned long *) tsk->thread.ksp); +} + +void show_stack(unsigned long *sp) +{ + unsigned long *stack; + int i; + + // debugging aid: "show_stack(NULL);" prints the + // back trace for this cpu. + + if (sp == NULL) + sp = (unsigned long*) &sp; + + stack = sp; + for (i = 0; i < kstack_depth_to_print; i++) { + if (((addr_t) stack & (THREAD_SIZE-1)) == 0) + break; + if (i && ((i % 4) == 0)) + printk("\n "); + printk("%016lx ", *stack++); + } + printk("\n"); + show_trace(sp); +} + +void show_registers(struct pt_regs *regs) +{ + mm_segment_t old_fs; + char *mode; + int i; + + mode = (regs->psw.mask & PSW_PROBLEM_STATE) ? "User" : "Krnl"; + printk("%s PSW : %016lx %016lx\n", + mode, (unsigned long) regs->psw.mask, + (unsigned long) regs->psw.addr); + printk("%s GPRS: %016lx %016lx %016lx %016lx\n", mode, + regs->gprs[0], regs->gprs[1], regs->gprs[2], regs->gprs[3]); + printk(" %016lx %016lx %016lx %016lx\n", + regs->gprs[4], regs->gprs[5], regs->gprs[6], regs->gprs[7]); + printk(" %016lx %016lx %016lx %016lx\n", + regs->gprs[8], regs->gprs[9], regs->gprs[10], regs->gprs[11]); + printk(" %016lx %016lx %016lx %016lx\n", + regs->gprs[12], regs->gprs[13], regs->gprs[14], regs->gprs[15]); + printk("%s ACRS: %08x %08x %08x %08x\n", mode, + regs->acrs[0], regs->acrs[1], regs->acrs[2], regs->acrs[3]); + printk(" %08x %08x %08x %08x\n", + regs->acrs[4], regs->acrs[5], regs->acrs[6], regs->acrs[7]); + printk(" %08x %08x %08x %08x\n", + regs->acrs[8], regs->acrs[9], regs->acrs[10], regs->acrs[11]); + printk(" %08x %08x %08x %08x\n", + regs->acrs[12], regs->acrs[13], regs->acrs[14], regs->acrs[15]); + + /* + * Print the first 20 byte of the instruction stream at the + * time of the fault. + */ + old_fs = get_fs(); + if (regs->psw.mask & PSW_PROBLEM_STATE) + set_fs(USER_DS); + else + set_fs(KERNEL_DS); + printk("%s Code: ", mode); + for (i = 0; i < 20; i++) { + unsigned char c; + if (__get_user(c, (char *)(regs->psw.addr + i))) { + printk(" Bad PSW."); + break; + } + printk("%02x ", c); + } + set_fs(old_fs); + + printk("\n"); +} + +/* This is called from fs/proc/array.c */ +char *task_show_regs(struct task_struct *task, char *buf) +{ + struct pt_regs *regs; + + regs = __KSTK_PTREGS(task); + buf += sprintf(buf, "task: %016lx, ksp: %016lx\n", + (unsigned long) task, task->thread.ksp); + buf += sprintf(buf, "User PSW : %016lx %016lx\n", + (unsigned long) regs->psw.mask, + (unsigned long) regs->psw.addr); + buf += sprintf(buf, "User GPRS: %016lx %016lx %016lx %016lx\n", + regs->gprs[0], regs->gprs[1], + regs->gprs[2], regs->gprs[3]); + buf += sprintf(buf, " %016lx %016lx %016lx %016lx\n", + regs->gprs[4], regs->gprs[5], + regs->gprs[6], regs->gprs[7]); + buf += sprintf(buf, " %016lx %016lx %016lx %016lx\n", + regs->gprs[8], regs->gprs[9], + regs->gprs[10], regs->gprs[11]); + buf += sprintf(buf, " %016lx %016lx %016lx %016lx\n", + regs->gprs[12], regs->gprs[13], + regs->gprs[14], regs->gprs[15]); + buf += sprintf(buf, "User ACRS: %08x %08x %08x %08x\n", + regs->acrs[0], regs->acrs[1], + regs->acrs[2], regs->acrs[3]); + buf += sprintf(buf, " %08x %08x %08x %08x\n", + regs->acrs[4], regs->acrs[5], + regs->acrs[6], regs->acrs[7]); + buf += sprintf(buf, " %08x %08x %08x %08x\n", + regs->acrs[8], regs->acrs[9], + regs->acrs[10], regs->acrs[11]); + buf += sprintf(buf, " %08x %08x %08x %08x\n", + regs->acrs[12], regs->acrs[13], + regs->acrs[14], regs->acrs[15]); + return buf; +} + spinlock_t die_lock = SPIN_LOCK_UNLOCKED; void die(const char * str, struct pt_regs * regs, long err) @@ -142,7 +340,7 @@ #if CONFIG_REMOTE_DEBUG if(gdb_stub_initialised) { - gdb_stub_handle_exception((gdb_pt_regs *)regs,signal); + gdb_stub_handle_exception(regs, signal); return 0; } #endif Index: wrapper32.S =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/s390x/kernel/wrapper32.S,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- wrapper32.S 9 Apr 2002 17:03:18 -0000 1.2 +++ wrapper32.S 10 Jun 2003 01:46:14 -0000 1.3 @@ -120,8 +120,8 @@ lgfr %r2,%r2 # long lgfr %r3,%r3 # long llgtr %r4,%r4 # long - lgfr %r5,%r5 # long - jg sys32_ptrace # branch to system call + llgfr %r5,%r5 # long + jg sys_ptrace # branch to system call .globl sys32_alarm_wrapper sys32_alarm_wrapper: |