* This file handles the architecture-dependent parts of process handling..
*/
-#include <linux/config.h>
#include <linux/compiler.h>
#include <linux/cpu.h>
#include <linux/errno.h>
#include <asm/irq.h>
#include <asm/timer.h>
-asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
+asmlinkage void ret_from_fork(void) asm ("ret_from_fork");
/*
* Return saved PC of a blocked thread. used in kernel/sched.
*/
unsigned long thread_saved_pc(struct task_struct *tsk)
{
- struct stack_frame *sf;
+ struct stack_frame *sf, *low, *high;
- sf = (struct stack_frame *) tsk->thread.ksp;
- sf = (struct stack_frame *) sf->back_chain;
+ if (!tsk || !task_stack_page(tsk))
+ return 0;
+ low = task_stack_page(tsk);
+ high = (struct stack_frame *) task_pt_regs(tsk);
+ sf = (struct stack_frame *) (tsk->thread.ksp & PSW_ADDR_INSN);
+ if (sf <= low || sf > high)
+ return 0;
+ sf = (struct stack_frame *) (sf->back_chain & PSW_ADDR_INSN);
+ if (sf <= low || sf > high)
+ return 0;
return sf->gprs[8];
}
/*
* Need to know about CPUs going idle?
*/
-static struct notifier_block *idle_chain;
+static ATOMIC_NOTIFIER_HEAD(idle_chain);
int register_idle_notifier(struct notifier_block *nb)
{
- return notifier_chain_register(&idle_chain, nb);
+ return atomic_notifier_chain_register(&idle_chain, nb);
}
EXPORT_SYMBOL(register_idle_notifier);
int unregister_idle_notifier(struct notifier_block *nb)
{
- return notifier_chain_unregister(&idle_chain, nb);
+ return atomic_notifier_chain_unregister(&idle_chain, nb);
}
EXPORT_SYMBOL(unregister_idle_notifier);
/* disable monitor call class 0 */
__ctl_clear_bit(8, 15);
- notifier_call_chain(&idle_chain, CPU_NOT_IDLE,
+ atomic_notifier_call_chain(&idle_chain, CPU_NOT_IDLE,
(void *)(long) smp_processor_id());
}
/*
* The idle loop on a S390...
*/
-void default_idle(void)
+static void default_idle(void)
{
int cpu, rc;
return;
}
- rc = notifier_call_chain(&idle_chain, CPU_IDLE, (void *)(long) cpu);
+ rc = atomic_notifier_call_chain(&idle_chain,
+ CPU_IDLE, (void *)(long) cpu);
if (rc != NOTIFY_OK && rc != NOTIFY_DONE)
BUG();
if (rc != NOTIFY_OK) {
__ctl_set_bit(8, 15);
#ifdef CONFIG_HOTPLUG_CPU
- if (cpu_is_offline(cpu))
+ if (cpu_is_offline(cpu)) {
+ preempt_enable_no_resched();
cpu_die();
+ }
#endif
local_mcck_disable();
return;
}
+ trace_hardirqs_on();
/* Wait for external, I/O or machine check interrupt. */
__load_psw_mask(PSW_KERNEL_BITS | PSW_MASK_WAIT |
PSW_MASK_IO | PSW_MASK_EXT);
{
struct task_struct *tsk = current;
- printk("CPU: %d %s\n", tsk->thread_info->cpu, print_tainted());
+ printk("CPU: %d %s\n", task_thread_info(tsk)->cpu, print_tainted());
printk("Process %s (pid: %d, task: %p, ksp: %p)\n",
current->comm, current->pid, (void *) tsk,
(void *) tsk->thread.ksp);
show_registers(regs);
/* Show stack backtrace if pt_regs is from kernel mode */
if (!(regs->psw.mask & PSW_MASK_PSTATE))
- show_trace(0,(unsigned long *) regs->gprs[15]);
+ show_trace(NULL, (unsigned long *) regs->gprs[15]);
}
extern void kernel_thread_starter(void);
-__asm__(".align 4\n"
+asm(
+ ".align 4\n"
"kernel_thread_starter:\n"
" la 2,0(10)\n"
" basr 14,9\n"
struct pt_regs childregs;
} *frame;
- frame = ((struct fake_frame *)
- (THREAD_SIZE + (unsigned long) p->thread_info)) - 1;
+ frame = container_of(task_pt_regs(p), struct fake_frame, childregs);
p->thread.ksp = (unsigned long) frame;
/* Store access registers to kernel stack of new process. */
frame->childregs = *regs;
unsigned long return_address;
int count;
- if (!p || p == current || p->state == TASK_RUNNING || !p->thread_info)
+ if (!p || p == current || p->state == TASK_RUNNING || !task_stack_page(p))
return 0;
- low = (struct stack_frame *) p->thread_info;
- high = (struct stack_frame *)
- ((unsigned long) p->thread_info + THREAD_SIZE) - 1;
+ low = task_stack_page(p);
+ high = (struct stack_frame *) task_pt_regs(p);
sf = (struct stack_frame *) (p->thread.ksp & PSW_ADDR_INSN);
if (sf <= low || sf > high)
return 0;