1995473aec0be1d9993205accc03e19d32d4e4a2aJeff Dike/* 2ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright 2003 PathScale, Inc. 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Licensed under the GPL 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7c5d4bb171cab17576779a51d23d313abcb3db102Jeff Dike#include <linux/stddef.h> 8c5d4bb171cab17576779a51d23d313abcb3db102Jeff Dike#include <linux/err.h> 9c5d4bb171cab17576779a51d23d313abcb3db102Jeff Dike#include <linux/hardirq.h> 10c5d4bb171cab17576779a51d23d313abcb3db102Jeff Dike#include <linux/mm.h> 116613c5e8603bc41741487828f48c6a4d701f7814Alexey Dobriyan#include <linux/module.h> 12c5d4bb171cab17576779a51d23d313abcb3db102Jeff Dike#include <linux/personality.h> 13c5d4bb171cab17576779a51d23d313abcb3db102Jeff Dike#include <linux/proc_fs.h> 14c5d4bb171cab17576779a51d23d313abcb3db102Jeff Dike#include <linux/ptrace.h> 15c5d4bb171cab17576779a51d23d313abcb3db102Jeff Dike#include <linux/random.h> 165a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 17c5d4bb171cab17576779a51d23d313abcb3db102Jeff Dike#include <linux/sched.h> 186613c5e8603bc41741487828f48c6a4d701f7814Alexey Dobriyan#include <linux/seq_file.h> 19c5d4bb171cab17576779a51d23d313abcb3db102Jeff Dike#include <linux/tick.h> 20c5d4bb171cab17576779a51d23d313abcb3db102Jeff Dike#include <linux/threads.h> 21c5d4bb171cab17576779a51d23d313abcb3db102Jeff Dike#include <asm/current.h> 22c5d4bb171cab17576779a51d23d313abcb3db102Jeff Dike#include <asm/pgtable.h> 23445c5786c9ce02b6816bb11fd3394a134fa6d244Al Viro#include <asm/mmu_context.h> 24c5d4bb171cab17576779a51d23d313abcb3db102Jeff Dike#include <asm/uaccess.h> 254ff83ce1114827f707b7f1f4f2e5f69de9df94acJeff Dike#include "as-layout.h" 26ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike#include "kern_util.h" 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "os.h" 2877bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike#include "skas.h" 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 30ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike/* 31ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike * This is a per-cpu array. A processor only modifies its entry and it only 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * cares about its entry, so it's OK if another processor is modifying its 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * entry. 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } }; 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 372dc5802a22d68d83ef4c3d616912949a6527bb65Karol Swietlickistatic inline int external_pid(void) 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3977bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike /* FIXME: Need to look up userspace_pid by cpu */ 40ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike return userspace_pid[0]; 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint pid_to_processor_id(int pid) 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 47c5d4bb171cab17576779a51d23d313abcb3db102Jeff Dike for (i = 0; i < ncpus; i++) { 48ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike if (cpu_tasks[i].pid == pid) 496e21aec3fcf6c8862b755d45c0af45acdefff976Jeff Dike return i; 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 516e21aec3fcf6c8862b755d45c0af45acdefff976Jeff Dike return -1; 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid free_stack(unsigned long stack, int order) 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free_pages(stack, order); 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsunsigned long alloc_stack(int order, int atomic) 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long page; 6253f9fc93f90a43701d6aaf3919be0614bb088b83Al Viro gfp_t flags = GFP_KERNEL; 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6446db4a42dd1190a311c2fb45106dfd0842c65a94Paolo 'Blaisorblade' Giarrusso if (atomic) 6546db4a42dd1190a311c2fb45106dfd0842c65a94Paolo 'Blaisorblade' Giarrusso flags = GFP_ATOMIC; 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds page = __get_free_pages(flags, order); 675c8aaceab88ac787c0a4038b29143c954c2a45e0Jeff Dike 686e21aec3fcf6c8862b755d45c0af45acdefff976Jeff Dike return page; 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int pid; 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds current->thread.request.u.thread.proc = fn; 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds current->thread.request.u.thread.arg = arg; 77e0877f07e85a46e4fde32bd84f08551d360839feJeff Dike pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0, 78e0877f07e85a46e4fde32bd84f08551d360839feJeff Dike ¤t->thread.regs, 0, NULL, NULL); 796e21aec3fcf6c8862b755d45c0af45acdefff976Jeff Dike return pid; 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8173395a0002aa9573ffc8d989587b79663847f705Al ViroEXPORT_SYMBOL(kernel_thread); 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 836e21aec3fcf6c8862b755d45c0af45acdefff976Jeff Dikestatic inline void set_current(struct task_struct *task) 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 85ca9bc0bb2d1c7afdd34ec79b3de4d16a8e0225e8Al Viro cpu_tasks[task_thread_info(task)->cpu] = ((struct cpu_task) 862dc5802a22d68d83ef4c3d616912949a6527bb65Karol Swietlicki { external_pid(), task }); 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 89291248fd6e371bcbfb8a77689c5d741a1527488fKarol Swietlickiextern void arch_switch_to(struct task_struct *to); 9077bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike 9176b278edd99fb55525fcf2706095e388bd3d122cRichard Weinbergervoid *__switch_to(struct task_struct *from, struct task_struct *to) 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 93995473aec0be1d9993205accc03e19d32d4e4a2aJeff Dike to->thread.prev_sched = from; 94995473aec0be1d9993205accc03e19d32d4e4a2aJeff Dike set_current(to); 95f6e34c6af6f18bd6c66bfb1c6a7c57068412aa73Jeff Dike 963eddddcf239c89bbd3c50d1440001a3d384ed40aJeff Dike do { 976aa802ce6acc9b1f0b34114b3f7c21c84872cc3aJeff Dike current->thread.saved_task = NULL; 9877bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike 99c5d4bb171cab17576779a51d23d313abcb3db102Jeff Dike switch_threads(&from->thread.switch_buf, 100c5d4bb171cab17576779a51d23d313abcb3db102Jeff Dike &to->thread.switch_buf); 10177bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike 102291248fd6e371bcbfb8a77689c5d741a1527488fKarol Swietlicki arch_switch_to(current); 10377bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike 104ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike if (current->thread.saved_task) 1053eddddcf239c89bbd3c50d1440001a3d384ed40aJeff Dike show_regs(&(current->thread.regs)); 106c5d4bb171cab17576779a51d23d313abcb3db102Jeff Dike to = current->thread.saved_task; 107c5d4bb171cab17576779a51d23d313abcb3db102Jeff Dike from = current; 108291248fd6e371bcbfb8a77689c5d741a1527488fKarol Swietlicki } while (current->thread.saved_task); 109f6e34c6af6f18bd6c66bfb1c6a7c57068412aa73Jeff Dike 1106e21aec3fcf6c8862b755d45c0af45acdefff976Jeff Dike return current->thread.prev_sched; 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid interrupt_end(void) 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 115ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike if (need_resched()) 1166e21aec3fcf6c8862b755d45c0af45acdefff976Jeff Dike schedule(); 117ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike if (test_tsk_thread_flag(current, TIF_SIGPENDING)) 1186e21aec3fcf6c8862b755d45c0af45acdefff976Jeff Dike do_signal(); 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid exit_thread(void) 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 124995473aec0be1d9993205accc03e19d32d4e4a2aJeff Dike 125c2220b2a124d2fe7b0074b23680177c8e905a76cAl Viroint get_current_pid(void) 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 127c2220b2a124d2fe7b0074b23680177c8e905a76cAl Viro return task_pid_nr(current); 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 130ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike/* 131ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike * This is called magically, by its address being stuffed in a jmp_buf 13277bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike * and being longjmp-d to. 13377bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike */ 13477bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dikevoid new_thread_handler(void) 13577bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike{ 13677bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike int (*fn)(void *), n; 13777bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike void *arg; 13877bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike 139ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike if (current->thread.prev_sched != NULL) 14077bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike schedule_tail(current->thread.prev_sched); 14177bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike current->thread.prev_sched = NULL; 14277bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike 14377bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike fn = current->thread.request.u.thread.proc; 14477bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike arg = current->thread.request.u.thread.arg; 14577bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike 146ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike /* 147ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike * The return value is 1 if the kernel thread execs a process, 14877bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike * 0 if it just exits 14977bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike */ 15077bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike n = run_kernel_thread(fn, arg, ¤t->thread.exec_buf); 151ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike if (n == 1) { 15277bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike /* Handle any immediate reschedules or signals */ 15377bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike interrupt_end(); 15477bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike userspace(¤t->thread.regs.regs); 15577bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike } 15677bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike else do_exit(0); 15777bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike} 15877bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike 15977bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike/* Called magically, see new_thread_handler above */ 16077bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dikevoid fork_handler(void) 16177bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike{ 16277bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike force_flush_all(); 16377bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike 16477bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike schedule_tail(current->thread.prev_sched); 16577bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike 166ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike /* 167ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike * XXX: if interrupt_end() calls schedule, this call to 16877bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike * arch_switch_to isn't needed. We could want to apply this to 169ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike * improve performance. -bb 170ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike */ 171291248fd6e371bcbfb8a77689c5d741a1527488fKarol Swietlicki arch_switch_to(current); 17277bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike 17377bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike current->thread.prev_sched = NULL; 17477bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike 17577bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike /* Handle any immediate reschedules or signals */ 17677bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike interrupt_end(); 17777bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike 17877bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike userspace(¤t->thread.regs.regs); 17977bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike} 18077bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike 1816f2c55b843836d26528c56a0968689accaedbc67Alexey Dobriyanint copy_thread(unsigned long clone_flags, unsigned long sp, 182995473aec0be1d9993205accc03e19d32d4e4a2aJeff Dike unsigned long stack_top, struct task_struct * p, 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pt_regs *regs) 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 18577bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike void (*handler)(void); 18677bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike int ret = 0; 187aa6758d4867cd07bd76105ade6177fe6148e559aPaolo 'Blaisorblade' Giarrusso 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->thread = (struct thread_struct) INIT_THREAD; 189aa6758d4867cd07bd76105ade6177fe6148e559aPaolo 'Blaisorblade' Giarrusso 190ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike if (current->thread.forking) { 19177bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike memcpy(&p->thread.regs.regs, ®s->regs, 19277bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike sizeof(p->thread.regs.regs)); 19318badddaa84e13e126f4ca5df47ac55b97a2635aJeff Dike REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.gp, 0); 194ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike if (sp != 0) 19518badddaa84e13e126f4ca5df47ac55b97a2635aJeff Dike REGS_SP(p->thread.regs.regs.gp) = sp; 196aa6758d4867cd07bd76105ade6177fe6148e559aPaolo 'Blaisorblade' Giarrusso 19777bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike handler = fork_handler; 198aa6758d4867cd07bd76105ade6177fe6148e559aPaolo 'Blaisorblade' Giarrusso 19977bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike arch_copy_thread(¤t->thread.arch, &p->thread.arch); 20077bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike } 20177bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike else { 202fbfe9c847edf57ac8232aeafb290f272289893a3Ingo van Lil get_safe_registers(p->thread.regs.regs.gp, p->thread.regs.regs.fp); 20377bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike p->thread.request.u.thread = current->thread.request.u.thread; 20477bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike handler = new_thread_handler; 20577bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike } 20677bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike 20777bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike new_thread(task_stack_page(p), &p->thread.switch_buf, handler); 20877bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike 20977bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike if (current->thread.forking) { 21077bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike clear_flushed_tls(p); 21177bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike 21277bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike /* 21377bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike * Set a new TLS for the child thread? 21477bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike */ 21577bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike if (clone_flags & CLONE_SETTLS) 21677bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike ret = arch_copy_tls(p); 21777bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike } 218aa6758d4867cd07bd76105ade6177fe6148e559aPaolo 'Blaisorblade' Giarrusso 219aa6758d4867cd07bd76105ade6177fe6148e559aPaolo 'Blaisorblade' Giarrusso return ret; 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid initial_thread_cb(void (*proc)(void *), void *arg) 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int save_kmalloc_ok = kmalloc_ok; 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kmalloc_ok = 0; 2276aa802ce6acc9b1f0b34114b3f7c21c84872cc3aJeff Dike initial_thread_cb_skas(proc, arg); 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kmalloc_ok = save_kmalloc_ok; 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 230995473aec0be1d9993205accc03e19d32d4e4a2aJeff Dike 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid default_idle(void) 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 233b160fb6309dc907cbd8849e549d83badb86dd35bJeff Dike unsigned long long nsecs; 234b160fb6309dc907cbd8849e549d83badb86dd35bJeff Dike 235c5d4bb171cab17576779a51d23d313abcb3db102Jeff Dike while (1) { 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* endless idle loop with no priority at all */ 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * although we are an idle CPU, we do not want to 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * get into the scheduler unnecessarily. 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 242ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike if (need_resched()) 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds schedule(); 244995473aec0be1d9993205accc03e19d32d4e4a2aJeff Dike 2451268fbc746ea1cd279886a740dcbad4ba5232225Frederic Weisbecker tick_nohz_idle_enter(); 2461268fbc746ea1cd279886a740dcbad4ba5232225Frederic Weisbecker rcu_idle_enter(); 247b160fb6309dc907cbd8849e549d83badb86dd35bJeff Dike nsecs = disable_timer(); 248b160fb6309dc907cbd8849e549d83badb86dd35bJeff Dike idle_sleep(nsecs); 2491268fbc746ea1cd279886a740dcbad4ba5232225Frederic Weisbecker rcu_idle_exit(); 2501268fbc746ea1cd279886a740dcbad4ba5232225Frederic Weisbecker tick_nohz_idle_exit(); 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid cpu_idle(void) 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 256a5a678c80beac4d163babda243a27eeb9c89bd89Jeff Dike cpu_tasks[current_thread_info()->cpu].pid = os_getpid(); 25777bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike default_idle(); 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 260b63162939cd797c8269964ce856ed1f2fec5f70ePaolo 'Blaisorblade' Giarrussoint __cant_sleep(void) { 261b63162939cd797c8269964ce856ed1f2fec5f70ePaolo 'Blaisorblade' Giarrusso return in_atomic() || irqs_disabled() || in_interrupt(); 262b63162939cd797c8269964ce856ed1f2fec5f70ePaolo 'Blaisorblade' Giarrusso /* Is in_interrupt() really needed? */ 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint user_context(unsigned long sp) 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long stack; 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stack = sp & (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER); 270a5a678c80beac4d163babda243a27eeb9c89bd89Jeff Dike return stack != (unsigned long) current_thread_info(); 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern exitcall_t __uml_exitcall_begin, __uml_exitcall_end; 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid do_uml_exitcalls(void) 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds exitcall_t *call; 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds call = &__uml_exitcall_end; 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (--call >= &__uml_exitcall_begin) 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (*call)(); 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 284c0a9290ecf0dbb89958cb3a3f78964015a7de402WANG Congchar *uml_strdup(const char *string) 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 286dfe52244e004f5103478966cd88351feb5c50d79Robert Love return kstrdup(string, GFP_KERNEL); 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 28873395a0002aa9573ffc8d989587b79663847f705Al ViroEXPORT_SYMBOL(uml_strdup); 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint copy_to_user_proc(void __user *to, void *from, int size) 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2926e21aec3fcf6c8862b755d45c0af45acdefff976Jeff Dike return copy_to_user(to, from, size); 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint copy_from_user_proc(void *to, void __user *from, int size) 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2976e21aec3fcf6c8862b755d45c0af45acdefff976Jeff Dike return copy_from_user(to, from, size); 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint clear_user_proc(void __user *buf, int size) 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3026e21aec3fcf6c8862b755d45c0af45acdefff976Jeff Dike return clear_user(buf, size); 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint strlen_user_proc(char __user *str) 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3076e21aec3fcf6c8862b755d45c0af45acdefff976Jeff Dike return strlen_user(str); 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint smp_sigio_handler(void) 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_SMP 313a5a678c80beac4d163babda243a27eeb9c89bd89Jeff Dike int cpu = current_thread_info()->cpu; 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IPI_handler(cpu); 315ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike if (cpu != 0) 3166e21aec3fcf6c8862b755d45c0af45acdefff976Jeff Dike return 1; 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 3186e21aec3fcf6c8862b755d45c0af45acdefff976Jeff Dike return 0; 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint cpu(void) 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 323a5a678c80beac4d163babda243a27eeb9c89bd89Jeff Dike return current_thread_info()->cpu; 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic atomic_t using_sysemu = ATOMIC_INIT(0); 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint sysemu_supported; 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid set_using_sysemu(int value) 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (value > sysemu_supported) 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds atomic_set(&using_sysemu, value); 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint get_using_sysemu(void) 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return atomic_read(&using_sysemu); 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3416613c5e8603bc41741487828f48c6a4d701f7814Alexey Dobriyanstatic int sysemu_proc_show(struct seq_file *m, void *v) 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3436613c5e8603bc41741487828f48c6a4d701f7814Alexey Dobriyan seq_printf(m, "%d\n", get_using_sysemu()); 3446613c5e8603bc41741487828f48c6a4d701f7814Alexey Dobriyan return 0; 3456613c5e8603bc41741487828f48c6a4d701f7814Alexey Dobriyan} 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3476613c5e8603bc41741487828f48c6a4d701f7814Alexey Dobriyanstatic int sysemu_proc_open(struct inode *inode, struct file *file) 3486613c5e8603bc41741487828f48c6a4d701f7814Alexey Dobriyan{ 3496613c5e8603bc41741487828f48c6a4d701f7814Alexey Dobriyan return single_open(file, sysemu_proc_show, NULL); 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3526613c5e8603bc41741487828f48c6a4d701f7814Alexey Dobriyanstatic ssize_t sysemu_proc_write(struct file *file, const char __user *buf, 3536613c5e8603bc41741487828f48c6a4d701f7814Alexey Dobriyan size_t count, loff_t *pos) 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char tmp[2]; 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (copy_from_user(tmp, buf, 1)) 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tmp[0] >= '0' && tmp[0] <= '2') 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds set_using_sysemu(tmp[0] - '0'); 362ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike /* We use the first char, but pretend to write everything */ 363ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike return count; 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3666613c5e8603bc41741487828f48c6a4d701f7814Alexey Dobriyanstatic const struct file_operations sysemu_proc_fops = { 3676613c5e8603bc41741487828f48c6a4d701f7814Alexey Dobriyan .owner = THIS_MODULE, 3686613c5e8603bc41741487828f48c6a4d701f7814Alexey Dobriyan .open = sysemu_proc_open, 3696613c5e8603bc41741487828f48c6a4d701f7814Alexey Dobriyan .read = seq_read, 3706613c5e8603bc41741487828f48c6a4d701f7814Alexey Dobriyan .llseek = seq_lseek, 3716613c5e8603bc41741487828f48c6a4d701f7814Alexey Dobriyan .release = single_release, 3726613c5e8603bc41741487828f48c6a4d701f7814Alexey Dobriyan .write = sysemu_proc_write, 3736613c5e8603bc41741487828f48c6a4d701f7814Alexey Dobriyan}; 3746613c5e8603bc41741487828f48c6a4d701f7814Alexey Dobriyan 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint __init make_proc_sysemu(void) 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct proc_dir_entry *ent; 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!sysemu_supported) 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3816613c5e8603bc41741487828f48c6a4d701f7814Alexey Dobriyan ent = proc_create("sysemu", 0600, NULL, &sysemu_proc_fops); 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ent == NULL) 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 38530f417c65e151dc96998a8ef721149a43998bc65Christophe Lucas printk(KERN_WARNING "Failed to register /proc/sysemu\n"); 3866e21aec3fcf6c8862b755d45c0af45acdefff976Jeff Dike return 0; 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldslate_initcall(make_proc_sysemu); 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint singlestepping(void * t) 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct task_struct *task = t ? t : current; 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 398c5d4bb171cab17576779a51d23d313abcb3db102Jeff Dike if (!(task->ptrace & PT_DTRACE)) 399ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike return 0; 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (task->thread.singlestep_syscall) 402ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike return 1; 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 2; 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 407b8bd0220c1ac6273eda66e25d992654219f846b6Bodo Stroesser/* 408b8bd0220c1ac6273eda66e25d992654219f846b6Bodo Stroesser * Only x86 and x86_64 have an arch_align_stack(). 409b8bd0220c1ac6273eda66e25d992654219f846b6Bodo Stroesser * All other arches have "#define arch_align_stack(x) (x)" 410b8bd0220c1ac6273eda66e25d992654219f846b6Bodo Stroesser * in their asm/system.h 411b8bd0220c1ac6273eda66e25d992654219f846b6Bodo Stroesser * As this is included in UML from asm-um/system-generic.h, 412b8bd0220c1ac6273eda66e25d992654219f846b6Bodo Stroesser * we can use it to behave as the subarch does. 413b8bd0220c1ac6273eda66e25d992654219f846b6Bodo Stroesser */ 414b8bd0220c1ac6273eda66e25d992654219f846b6Bodo Stroesser#ifndef arch_align_stack 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsunsigned long arch_align_stack(unsigned long sp) 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4178f80e9466e18288df7391c9d21532c4125ac9c62Jeff Dike if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sp -= get_random_int() % 8192; 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return sp & ~0xf; 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 421b8bd0220c1ac6273eda66e25d992654219f846b6Bodo Stroesser#endif 422c11274655558e72d8d4a598c0077874c094d97d5Jeff Dike 423c11274655558e72d8d4a598c0077874c094d97d5Jeff Dikeunsigned long get_wchan(struct task_struct *p) 424c11274655558e72d8d4a598c0077874c094d97d5Jeff Dike{ 425c11274655558e72d8d4a598c0077874c094d97d5Jeff Dike unsigned long stack_page, sp, ip; 426c11274655558e72d8d4a598c0077874c094d97d5Jeff Dike bool seen_sched = 0; 427c11274655558e72d8d4a598c0077874c094d97d5Jeff Dike 428c11274655558e72d8d4a598c0077874c094d97d5Jeff Dike if ((p == NULL) || (p == current) || (p->state == TASK_RUNNING)) 429c11274655558e72d8d4a598c0077874c094d97d5Jeff Dike return 0; 430c11274655558e72d8d4a598c0077874c094d97d5Jeff Dike 431c11274655558e72d8d4a598c0077874c094d97d5Jeff Dike stack_page = (unsigned long) task_stack_page(p); 432c11274655558e72d8d4a598c0077874c094d97d5Jeff Dike /* Bail if the process has no kernel stack for some reason */ 433c11274655558e72d8d4a598c0077874c094d97d5Jeff Dike if (stack_page == 0) 434c11274655558e72d8d4a598c0077874c094d97d5Jeff Dike return 0; 435c11274655558e72d8d4a598c0077874c094d97d5Jeff Dike 436c11274655558e72d8d4a598c0077874c094d97d5Jeff Dike sp = p->thread.switch_buf->JB_SP; 437c11274655558e72d8d4a598c0077874c094d97d5Jeff Dike /* 438c11274655558e72d8d4a598c0077874c094d97d5Jeff Dike * Bail if the stack pointer is below the bottom of the kernel 439c11274655558e72d8d4a598c0077874c094d97d5Jeff Dike * stack for some reason 440c11274655558e72d8d4a598c0077874c094d97d5Jeff Dike */ 441c11274655558e72d8d4a598c0077874c094d97d5Jeff Dike if (sp < stack_page) 442c11274655558e72d8d4a598c0077874c094d97d5Jeff Dike return 0; 443c11274655558e72d8d4a598c0077874c094d97d5Jeff Dike 444c11274655558e72d8d4a598c0077874c094d97d5Jeff Dike while (sp < stack_page + THREAD_SIZE) { 445c11274655558e72d8d4a598c0077874c094d97d5Jeff Dike ip = *((unsigned long *) sp); 446c11274655558e72d8d4a598c0077874c094d97d5Jeff Dike if (in_sched_functions(ip)) 447c11274655558e72d8d4a598c0077874c094d97d5Jeff Dike /* Ignore everything until we're above the scheduler */ 448c11274655558e72d8d4a598c0077874c094d97d5Jeff Dike seen_sched = 1; 449c11274655558e72d8d4a598c0077874c094d97d5Jeff Dike else if (kernel_text_address(ip) && seen_sched) 450c11274655558e72d8d4a598c0077874c094d97d5Jeff Dike return ip; 451c11274655558e72d8d4a598c0077874c094d97d5Jeff Dike 452c11274655558e72d8d4a598c0077874c094d97d5Jeff Dike sp += sizeof(unsigned long); 453c11274655558e72d8d4a598c0077874c094d97d5Jeff Dike } 454c11274655558e72d8d4a598c0077874c094d97d5Jeff Dike 455c11274655558e72d8d4a598c0077874c094d97d5Jeff Dike return 0; 456c11274655558e72d8d4a598c0077874c094d97d5Jeff Dike} 4578192ab42bf60e1e9b7efa046990e9cc5e4a95cf4Jeff Dike 4588192ab42bf60e1e9b7efa046990e9cc5e4a95cf4Jeff Dikeint elf_core_copy_fpregs(struct task_struct *t, elf_fpregset_t *fpu) 4598192ab42bf60e1e9b7efa046990e9cc5e4a95cf4Jeff Dike{ 4608192ab42bf60e1e9b7efa046990e9cc5e4a95cf4Jeff Dike int cpu = current_thread_info()->cpu; 4618192ab42bf60e1e9b7efa046990e9cc5e4a95cf4Jeff Dike 4628192ab42bf60e1e9b7efa046990e9cc5e4a95cf4Jeff Dike return save_fp_registers(userspace_pid[cpu], (unsigned long *) fpu); 4638192ab42bf60e1e9b7efa046990e9cc5e4a95cf4Jeff Dike} 4648192ab42bf60e1e9b7efa046990e9cc5e4a95cf4Jeff Dike 465