X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Falpha%2Fkernel%2Fprocess.c;h=c151863906932239309079c0719d8d13b148b2b1;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=297e4b48bfe2f025a60c0e5d77ff36835af3ba08;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index 297e4b48b..c15186390 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c @@ -8,7 +8,6 @@ * This file handles the architecture-dependent parts of process handling. */ -#include #include #include #include @@ -26,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -43,21 +43,23 @@ #include "proto.h" #include "pci_impl.h" -void default_idle(void) -{ - barrier(); -} +/* + * Power off function, if any + */ +void (*pm_power_off)(void) = machine_power_off; +EXPORT_SYMBOL(pm_power_off); void cpu_idle(void) { + set_thread_flag(TIF_POLLING_NRFLAG); + while (1) { - void (*idle)(void) = default_idle; /* FIXME -- EV6 and LCA45 know how to power down the CPU. */ while (!need_resched()) - idle(); + cpu_relax(); schedule(); } } @@ -93,7 +95,7 @@ common_shutdown_1(void *generic_ptr) if (cpuid != boot_cpuid) { flags |= 0x00040000UL; /* "remain halted" */ *pflags = flags; - clear_bit(cpuid, &cpu_present_mask); + cpu_clear(cpuid, cpu_present_map); halt(); } #endif @@ -119,14 +121,18 @@ common_shutdown_1(void *generic_ptr) #ifdef CONFIG_SMP /* Wait for the secondaries to halt. */ - clear_bit(boot_cpuid, &cpu_present_mask); - while (cpu_present_mask) + cpu_clear(boot_cpuid, cpu_present_map); + while (cpus_weight(cpu_present_map)) barrier(); #endif /* If booted from SRM, reset some of the original environment. */ if (alpha_using_srm) { #ifdef CONFIG_DUMMY_CONSOLE + /* If we've gotten here after SysRq-b, leave interrupt + context before taking over the console. */ + if (in_interrupt()) + irq_exit(); /* This has the effect of resetting the VGA video origin. */ take_over_console(&dummy_con, 0, MAX_NR_CONSOLES-1, 1); #endif @@ -165,7 +171,6 @@ machine_restart(char *restart_cmd) common_shutdown(LINUX_REBOOT_CMD_RESTART, restart_cmd); } -EXPORT_SYMBOL(machine_restart); void machine_halt(void) @@ -173,7 +178,6 @@ machine_halt(void) common_shutdown(LINUX_REBOOT_CMD_HALT, NULL); } -EXPORT_SYMBOL(machine_halt); void machine_power_off(void) @@ -181,7 +185,6 @@ machine_power_off(void) common_shutdown(LINUX_REBOOT_CMD_POWER_OFF, NULL); } -EXPORT_SYMBOL(machine_power_off); /* Used by sysrq-p, among others. I don't believe r9-r15 are ever saved in the context it's used. */ @@ -189,7 +192,7 @@ EXPORT_SYMBOL(machine_power_off); void show_regs(struct pt_regs *regs) { - dik_show_regs(regs, 0); + dik_show_regs(regs, NULL); } /* @@ -203,6 +206,7 @@ start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) regs->ps = 8; wrusp(sp); } +EXPORT_SYMBOL(start_thread); /* * Free current thread data structures etc.. @@ -239,14 +243,14 @@ release_thread(struct task_struct *dead_task) * with parameters (SIGCHLD, 0). */ int -alpha_clone(unsigned long clone_flags, unsigned long usp, int *parent_tid, - int *child_tid, unsigned long tls_value, struct pt_regs *regs) +alpha_clone(unsigned long clone_flags, unsigned long usp, + int __user *parent_tid, int __user *child_tid, + unsigned long tls_value, struct pt_regs *regs) { if (!usp) usp = rdusp(); - return do_fork(clone_flags & ~CLONE_IDLETASK, usp, regs, 0, - parent_tid, child_tid); + return do_fork(clone_flags, usp, regs, 0, parent_tid, child_tid); } int @@ -274,7 +278,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, { extern void ret_from_fork(void); - struct thread_info *childti = p->thread_info; + struct thread_info *childti = task_thread_info(p); struct pt_regs * childregs; struct switch_stack * childstack, *stack; unsigned long stack_offset, settls; @@ -283,7 +287,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, if (!(regs->ps & 8)) stack_offset = (PAGE_SIZE-1) & (unsigned long) regs; childregs = (struct pt_regs *) - (stack_offset + PAGE_SIZE + (long) childti); + (stack_offset + PAGE_SIZE + task_stack_page(p)); *childregs = *regs; settls = regs->r20; @@ -374,6 +378,7 @@ dump_thread(struct pt_regs * pt, struct user * dump) dump->regs[EF_A2] = pt->r18; memcpy((char *)dump->regs + EF_SIZE, sw->fp, 32 * 8); } +EXPORT_SYMBOL(dump_thread); /* * Fill in the user structure for a ELF core dump. @@ -422,51 +427,31 @@ dump_elf_thread(elf_greg_t *dest, struct pt_regs *pt, struct thread_info *ti) useful value of the thread's UNIQUE field. */ dest[32] = ti->pcb.unique; } +EXPORT_SYMBOL(dump_elf_thread); int dump_elf_task(elf_greg_t *dest, struct task_struct *task) { - struct thread_info *ti; - struct pt_regs *pt; - - ti = task->thread_info; - pt = (struct pt_regs *)((unsigned long)ti + 2*PAGE_SIZE) - 1; - - dump_elf_thread(dest, pt, ti); - + dump_elf_thread(dest, task_pt_regs(task), task_thread_info(task)); return 1; } +EXPORT_SYMBOL(dump_elf_task); int dump_elf_task_fp(elf_fpreg_t *dest, struct task_struct *task) { - struct thread_info *ti; - struct pt_regs *pt; - struct switch_stack *sw; - - ti = task->thread_info; - pt = (struct pt_regs *)((unsigned long)ti + 2*PAGE_SIZE) - 1; - sw = (struct switch_stack *)pt - 1; - + struct switch_stack *sw = (struct switch_stack *)task_pt_regs(task) - 1; memcpy(dest, sw->fp, 32 * 8); - return 1; } +EXPORT_SYMBOL(dump_elf_task_fp); /* * sys_execve() executes a new program. - * - * This works due to the alpha calling sequence: the first 6 args - * are gotten from registers, while the rest is on the stack, so - * we get a0-a5 for free, and then magically find "struct pt_regs" - * on the stack for us.. - * - * Don't do this at home. */ asmlinkage int -sys_execve(char *ufilename, char **argv, char **envp, - unsigned long a3, unsigned long a4, unsigned long a5, - struct pt_regs regs) +do_sys_execve(char __user *ufilename, char __user * __user *argv, + char __user * __user *envp, struct pt_regs *regs) { int error; char *filename; @@ -475,7 +460,7 @@ sys_execve(char *ufilename, char **argv, char **envp, error = PTR_ERR(filename); if (IS_ERR(filename)) goto out; - error = do_execve(filename, argv, envp, ®s); + error = do_execve(filename, argv, envp, regs); putname(filename); out: return error; @@ -496,10 +481,10 @@ out: */ unsigned long -thread_saved_pc(task_t *t) +thread_saved_pc(struct task_struct *t) { - unsigned long base = (unsigned long)t->thread_info; - unsigned long fp, sp = t->thread_info->pcb.ksp; + unsigned long base = (unsigned long)task_stack_page(t); + unsigned long fp, sp = task_thread_info(t)->pcb.ksp; if (sp > base && sp+6*8 < base + 16*1024) { fp = ((unsigned long*)sp)[6]; @@ -510,12 +495,6 @@ thread_saved_pc(task_t *t) return 0; } -/* - * These bracket the sleeping functions.. - */ -#define first_sched ((unsigned long) scheduling_functions_start_here) -#define last_sched ((unsigned long) scheduling_functions_end_here) - unsigned long get_wchan(struct task_struct *p) { @@ -534,8 +513,8 @@ get_wchan(struct task_struct *p) */ pc = thread_saved_pc(p); - if (pc >= first_sched && pc < last_sched) { - schedule_frame = ((unsigned long *)p->thread_info->pcb.ksp)[6]; + if (in_sched_functions(pc)) { + schedule_frame = ((unsigned long *)task_thread_info(p)->pcb.ksp)[6]; return ((unsigned long *)schedule_frame)[12]; } return pc;