|
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:
|