patch-2.4.2 linux/arch/s390/kernel/process.c
Next file: linux/arch/s390/kernel/ptrace.c
Previous file: linux/arch/s390/kernel/mathemu.c
Back to the patch index
Back to the overall index
- Lines: 338
- Date:
Tue Feb 13 14:13:43 2001
- Orig file:
v2.4.1/linux/arch/s390/kernel/process.c
- Orig date:
Tue Sep 5 13:50:01 2000
diff -u --recursive --new-file v2.4.1/linux/arch/s390/kernel/process.c linux/arch/s390/kernel/process.c
@@ -28,7 +28,7 @@
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/user.h>
#include <linux/a.out.h>
@@ -67,7 +67,9 @@
if (softirq_active(smp_processor_id()) &
softirq_mask(smp_processor_id())) {
do_softirq();
- continue;
+ __sti();
+ if (!current->need_resched)
+ continue;
}
if (current->need_resched) {
schedule();
@@ -92,12 +94,13 @@
0 returned you know you've got all the lines
*/
-int sprintf_regs(int line, char *buff, struct task_struct * task,
- struct thread_struct *thread, struct pt_regs * regs)
-{
+static int sprintf_regs(int line, char *buff, struct task_struct *task, struct pt_regs *regs)
+{
int linelen=0;
int regno,chaincnt;
u32 backchain,prev_backchain,endchain;
+ u32 ksp = 0;
+ char *mode = "???";
enum
{
@@ -118,106 +121,125 @@
sp_kern_backchain1
};
- if(task)
- thread = &task->thread;
- if(thread)
- regs = thread->regs;
- switch (line) {
- case sp_linefeed:
+ 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,"User PSW: %08lx %08lx\n",
- (unsigned long) regs->psw.mask,
- (unsigned long) regs->psw.addr);
+ linelen=sprintf(buff, "%s PSW: %08lx %08lx\n", mode,
+ (unsigned long) regs->psw.mask,
+ (unsigned long) regs->psw.addr);
else
- linelen = sprintf(buff,"pt_regs=NULL some info unavailable\n");
+ linelen=sprintf(buff,"pt_regs=NULL some info unavailable\n");
break;
case sp_ksp:
- if (task)
- linelen += sprintf(&buff[linelen],
- "task: %08x ", (addr_t)task);
- if (thread)
- linelen += sprintf(&buff[linelen],
- "thread: %08x ksp: %08x ",
- (addr_t)thread,(addr_t)thread->ksp);
- if (regs)
- linelen += sprintf(&buff[linelen],
- "pt_regs: %08x\n", (addr_t)regs);
+ linelen=sprintf(&buff[linelen],
+ "task: %08x ksp: %08x pt_regs: %08x\n",
+ (addr_t)task, (addr_t)ksp, (addr_t)regs);
break;
case sp_gprs:
- if (regs)
- linelen = sprintf(buff,"User GPRS:\n");
+ if(regs)
+ linelen=sprintf(buff, "%s GPRS:\n", mode);
break;
case sp_gprs1 ... sp_gprs4:
- if (regs) {
- regno = (line-sp_gprs1)*4;
- linelen = sprintf(buff,"%08x %08x %08x %08x\n",
- regs->gprs[regno],
- regs->gprs[regno+1],
- regs->gprs[regno+2],
- regs->gprs[regno+3]);
+ if(regs)
+ {
+ regno=(line-sp_gprs1)*4;
+ linelen=sprintf(buff,"%08x %08x %08x %08x\n",
+ regs->gprs[regno],
+ regs->gprs[regno+1],
+ regs->gprs[regno+2],
+ regs->gprs[regno+3]);
}
break;
case sp_acrs:
- if (regs)
- linelen = sprintf(buff,"User ACRS:\n");
+ 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]);
+ 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 (thread && thread->ksp && regs)
- linelen = sprintf(buff,"Kernel BackChain CallChain BackChain CallChain\n");
+ if (regs && (regs->psw.mask & PSW_PROBLEM_STATE))
+ break;
+ if (ksp)
+ linelen=sprintf(buff, "Kernel BackChain CallChain\n");
break;
default:
- if(thread && thread->ksp && regs) {
- backchain = (thread->ksp & PSW_ADDR_MASK);
- endchain = ((backchain & (-8192)) + 8192);
- prev_backchain = backchain - 1;
- line -= sp_kern_backchain1;
- for (chaincnt = 0; ; chaincnt++) {
- if ((backchain == 0) ||
- (backchain >= endchain) ||
- (chaincnt >= 8) ||
- (prev_backchain >= backchain))
+ if (ksp)
+ {
+
+ backchain=ksp&PSW_ADDR_MASK;
+ endchain=((backchain&(-8192))+8192);
+ 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 >> 1) == line) {
- linelen += sprintf(&buff[linelen],"%s%08x %08x ",
- (chaincnt&1) ? "":" ",
- backchain,*(u32 *)(backchain+56));
- }
- if ((chaincnt >> 1) > line)
+ if(chaincnt==line)
+ {
+ linelen+=sprintf(&buff[linelen]," %08x [<%08lx>]\n",
+ backchain,
+ *(u32 *)(backchain+56)&PSW_ADDR_MASK);
break;
- prev_backchain = backchain;
- backchain = (*((u32 *)backchain)) & PSW_ADDR_MASK;
+ }
+ prev_backchain=backchain;
+ backchain=(*((u32 *)backchain))&PSW_ADDR_MASK;
}
- if (linelen)
- linelen += sprintf(&buff[linelen],"\n");
}
}
- return linelen;
+ return(linelen);
}
-void show_regs(struct task_struct *task, struct thread_struct *thread,
- struct pt_regs *regs)
+void show_regs(struct pt_regs *regs)
{
char buff[80];
int line;
+
+ printk("CPU: %d\n",smp_processor_id());
+ printk("Process %s (pid: %d, stackpage=%08X)\n",
+ current->comm, current->pid, 4096+(addr_t)current);
- for (line = 0; sprintf_regs(line,buff,task,thread,regs); line++)
+ for (line = 0; sprintf_regs(line, buff, current, regs); line++)
printk(buff);
}
+char *task_show_regs(struct task_struct *task, char *buffer)
+{
+ int line, len;
+
+ for (line = 0; ; line++)
+ {
+ len = sprintf_regs(line, buffer, task, task->thread.regs);
+ if (!len) break;
+ buffer += len;
+ }
+ return buffer;
+}
+
+
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{
int clone_arg = flags | CLONE_VM;
@@ -327,7 +349,7 @@
lock_kernel();
clone_flags = regs.gprs[3];
- newsp = regs.gprs[2];
+ newsp = regs.orig_gpr2;
if (!newsp)
newsp = regs.gprs[15];
ret = do_fork(clone_flags, newsp, ®s, 0);
@@ -365,7 +387,19 @@
goto out;
error = do_execve(filename, (char **) regs.gprs[3], (char **) regs.gprs[4], ®s);
if (error == 0)
- current->flags &= ~PF_DTRACE;
+ {
+ current->ptrace &= ~PT_DTRACE;
+ current->thread.fp_regs.fpc=0;
+ if(MACHINE_HAS_IEEE)
+ {
+ __asm__ __volatile__
+ ("sr 0,0\n\t"
+ "sfpc 0,0\n\t"
+ :
+ :
+ :"0");
+ }
+ }
putname(filename);
out:
return error;
@@ -412,21 +446,77 @@
unsigned long get_wchan(struct task_struct *p)
{
- unsigned long r14, r15;
+ unsigned long r14, r15, bc;
unsigned long stack_page;
int count = 0;
if (!p || p == current || p->state == TASK_RUNNING)
return 0;
stack_page = (unsigned long) p;
r15 = p->thread.ksp;
+ if (!stack_page || r15 < stack_page || r15 >= 8188+stack_page)
+ return 0;
+ bc = (*(unsigned long *) r15) & 0x7fffffff;
do {
- r14 = *(unsigned long *) (r15+56);
+ if (bc < stack_page || bc >= 8188+stack_page)
+ return 0;
+ r14 = (*(unsigned long *) (bc+56)) & 0x7fffffff;
if (r14 < first_sched || r14 >= last_sched)
return r14;
- r15 = *(unsigned long *) (r15+60);
+ bc = (*(unsigned long *) bc) & 0x7fffffff;
} while (count++ < 16);
return 0;
}
#undef last_sched
#undef first_sched
+/*
+ * This should be safe even if called from tq_scheduler
+ * A typical mask would be sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGTERM) or 0.
+ *
+ */
+void s390_daemonize(char *name,unsigned long mask,int use_init_fs)
+{
+ struct fs_struct *fs;
+ extern struct task_struct *child_reaper;
+ struct task_struct *this_process=current;
+
+ /*
+ * If we were started as result of loading a module, close all of the
+ * user space pages. We don't need them, and if we didn't close them
+ * they would be locked into memory.
+ */
+ exit_mm(current);
+
+ this_process->session = 1;
+ this_process->pgrp = 1;
+ if(name)
+ {
+ strncpy(current->comm,name,15);
+ current->comm[15]=0;
+ }
+ else
+ current->comm[0]=0;
+ /* set signal mask to what we want to respond */
+ siginitsetinv(¤t->blocked,mask);
+ /* exit_signal isn't set up */
+ /* if we inherit from cpu idle */
+ this_process->exit_signal=SIGCHLD;
+ /* if priority=0 schedule can go into a tight loop */
+ this_process->policy= SCHED_OTHER;
+ /* nice goes priority=20-nice; */
+ this_process->nice=10;
+ if(use_init_fs)
+ {
+ exit_fs(this_process); /* current->fs->count--; */
+ fs = init_task.fs;
+ current->fs = fs;
+ atomic_inc(&fs->count);
+ exit_files(current);
+ }
+ write_lock_irq(&tasklist_lock);
+ /* We want init as our parent */
+ REMOVE_LINKS(this_process);
+ this_process->p_opptr=this_process->p_pptr=child_reaper;
+ SET_LINKS(this_process);
+ write_unlock_irq(&tasklist_lock);
+}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)