linux/arch/x86/kernel/process_32.c
<<
>>
Prefs
   1/*
   2 *  Copyright (C) 1995  Linus Torvalds
   3 *
   4 *  Pentium III FXSR, SSE support
   5 *      Gareth Hughes <gareth@valinux.com>, May 2000
   6 */
   7
   8/*
   9 * This file handles the architecture-dependent parts of process handling..
  10 */
  11
  12#include <stdarg.h>
  13
  14#include <linux/cpu.h>
  15#include <linux/errno.h>
  16#include <linux/sched.h>
  17#include <linux/fs.h>
  18#include <linux/kernel.h>
  19#include <linux/mm.h>
  20#include <linux/elfcore.h>
  21#include <linux/smp.h>
  22#include <linux/stddef.h>
  23#include <linux/slab.h>
  24#include <linux/vmalloc.h>
  25#include <linux/user.h>
  26#include <linux/interrupt.h>
  27#include <linux/utsname.h>
  28#include <linux/delay.h>
  29#include <linux/reboot.h>
  30#include <linux/init.h>
  31#include <linux/mc146818rtc.h>
  32#include <linux/module.h>
  33#include <linux/kallsyms.h>
  34#include <linux/ptrace.h>
  35#include <linux/random.h>
  36#include <linux/personality.h>
  37#include <linux/tick.h>
  38#include <linux/percpu.h>
  39#include <linux/prctl.h>
  40
  41#include <asm/uaccess.h>
  42#include <asm/pgtable.h>
  43#include <asm/system.h>
  44#include <asm/io.h>
  45#include <asm/ldt.h>
  46#include <asm/processor.h>
  47#include <asm/i387.h>
  48#include <asm/desc.h>
  49#ifdef CONFIG_MATH_EMULATION
  50#include <asm/math_emu.h>
  51#endif
  52
  53#include <linux/err.h>
  54
  55#include <asm/tlbflush.h>
  56#include <asm/cpu.h>
  57#include <asm/kdebug.h>
  58#include <asm/idle.h>
  59
  60asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
  61
  62DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task;
  63EXPORT_PER_CPU_SYMBOL(current_task);
  64
  65DEFINE_PER_CPU(int, cpu_number);
  66EXPORT_PER_CPU_SYMBOL(cpu_number);
  67
  68/*
  69 * Return saved PC of a blocked thread.
  70 */
  71unsigned long thread_saved_pc(struct task_struct *tsk)
  72{
  73        return ((unsigned long *)tsk->thread.sp)[3];
  74}
  75
  76#ifdef CONFIG_HOTPLUG_CPU
  77#include <asm/nmi.h>
  78
  79static void cpu_exit_clear(void)
  80{
  81        int cpu = raw_smp_processor_id();
  82
  83        idle_task_exit();
  84
  85        cpu_uninit();
  86        irq_ctx_exit(cpu);
  87
  88        cpu_clear(cpu, cpu_callout_map);
  89        cpu_clear(cpu, cpu_callin_map);
  90
  91        numa_remove_cpu(cpu);
  92        c1e_remove_cpu(cpu);
  93}
  94
  95/* We don't actually take CPU down, just spin without interrupts. */
  96static inline void play_dead(void)
  97{
  98        /* This must be done before dead CPU ack */
  99        cpu_exit_clear();
 100        mb();
 101        /* Ack it */
 102        __get_cpu_var(cpu_state) = CPU_DEAD;
 103
 104        /*
 105         * With physical CPU hotplug, we should halt the cpu
 106         */
 107        local_irq_disable();
 108        /* mask all interrupts, flush any and all caches, and halt */
 109        wbinvd_halt();
 110}
 111#else
 112static inline void play_dead(void)
 113{
 114        BUG();
 115}
 116#endif /* CONFIG_HOTPLUG_CPU */
 117
 118/*
 119 * The idle thread. There's no useful work to be
 120 * done, so just try to conserve power and have a
 121 * low exit latency (ie sit in a loop waiting for
 122 * somebody to say that they'd like to reschedule)
 123 */
 124void cpu_idle(void)
 125{
 126        int cpu = smp_processor_id();
 127
 128        current_thread_info()->status |= TS_POLLING;
 129
 130        /* endless idle loop with no priority at all */
 131        while (1) {
 132                tick_nohz_stop_sched_tick(1);
 133                while (!need_resched()) {
 134
 135                        check_pgt_cache();
 136                        rmb();
 137
 138                        if (rcu_pending(cpu))
 139                                rcu_check_callbacks(cpu, 0);
 140
 141                        if (cpu_is_offline(cpu))
 142                                play_dead();
 143
 144                        local_irq_disable();
 145                        __get_cpu_var(irq_stat).idle_timestamp = jiffies;
 146                        /* Don't trace irqs off for idle */
 147                        stop_critical_timings();
 148                        pm_idle();
 149                        start_critical_timings();
 150                }
 151                tick_nohz_restart_sched_tick();
 152                preempt_enable_no_resched();
 153                schedule();
 154                preempt_disable();
 155        }
 156}
 157
 158void __show_registers(struct pt_regs *regs, int all)
 159{
 160        unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
 161        unsigned long d0, d1, d2, d3, d6, d7;
 162        unsigned long sp;
 163        unsigned short ss, gs;
 164
 165        if (user_mode_vm(regs)) {
 166                sp = regs->sp;
 167                ss = regs->ss & 0xffff;
 168                savesegment(gs, gs);
 169        } else {
 170                sp = (unsigned long) (&regs->sp);
 171                savesegment(ss, ss);
 172                savesegment(gs, gs);
 173        }
 174
 175        printk("\n");
 176        printk("Pid: %d, comm: %s %s (%s %.*s)\n",
 177                        task_pid_nr(current), current->comm,
 178                        print_tainted(), init_utsname()->release,
 179                        (int)strcspn(init_utsname()->version, " "),
 180                        init_utsname()->version);
 181
 182        printk("EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n",
 183                        (u16)regs->cs, regs->ip, regs->flags,
 184                        smp_processor_id());
 185        print_symbol("EIP is at %s\n", regs->ip);
 186
 187        printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
 188                regs->ax, regs->bx, regs->cx, regs->dx);
 189        printk("ESI: %08lx EDI: %08lx EBP: %08lx ESP: %08lx\n",
 190                regs->si, regs->di, regs->bp, sp);
 191        printk(" DS: %04x ES: %04x FS: %04x GS: %04x SS: %04x\n",
 192               (u16)regs->ds, (u16)regs->es, (u16)regs->fs, gs, ss);
 193
 194        if (!all)
 195                return;
 196
 197        cr0 = read_cr0();
 198        cr2 = read_cr2();
 199        cr3 = read_cr3();
 200        cr4 = read_cr4_safe();
 201        printk("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n",
 202                        cr0, cr2, cr3, cr4);
 203
 204        get_debugreg(d0, 0);
 205        get_debugreg(d1, 1);
 206        get_debugreg(d2, 2);
 207        get_debugreg(d3, 3);
 208        printk("DR0: %08lx DR1: %08lx DR2: %08lx DR3: %08lx\n",
 209                        d0, d1, d2, d3);
 210
 211        get_debugreg(d6, 6);
 212        get_debugreg(d7, 7);
 213        printk("DR6: %08lx DR7: %08lx\n",
 214                        d6, d7);
 215}
 216
 217void show_regs(struct pt_regs *regs)
 218{
 219        __show_registers(regs, 1);
 220        show_trace(NULL, regs, &regs->sp, regs->bp);
 221}
 222
 223/*
 224 * This gets run with %bx containing the
 225 * function to call, and %dx containing
 226 * the "args".
 227 */
 228extern void kernel_thread_helper(void);
 229
 230/*
 231 * Create a kernel thread
 232 */
 233int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
 234{
 235        struct pt_regs regs;
 236
 237        memset(&regs, 0, sizeof(regs));
 238
 239        regs.bx = (unsigned long) fn;
 240        regs.dx = (unsigned long) arg;
 241
 242        regs.ds = __USER_DS;
 243        regs.es = __USER_DS;
 244        regs.fs = __KERNEL_PERCPU;
 245        regs.orig_ax = -1;
 246        regs.ip = (unsigned long) kernel_thread_helper;
 247        regs.cs = __KERNEL_CS | get_kernel_rpl();
 248        regs.flags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2;
 249
 250        /* Ok, create the new process.. */
 251        return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
 252}
 253EXPORT_SYMBOL(kernel_thread);
 254
 255/*
 256 * Free current thread data structures etc..
 257 */
 258void exit_thread(void)
 259{
 260        /* The process may have allocated an io port bitmap... nuke it. */
 261        if (unlikely(test_thread_flag(TIF_IO_BITMAP))) {
 262                struct task_struct *tsk = current;
 263                struct thread_struct *t = &tsk->thread;
 264                int cpu = get_cpu();
 265                struct tss_struct *tss = &per_cpu(init_tss, cpu);
 266
 267                kfree(t->io_bitmap_ptr);
 268                t->io_bitmap_ptr = NULL;
 269                clear_thread_flag(TIF_IO_BITMAP);
 270                /*
 271                 * Careful, clear this in the TSS too:
 272                 */
 273                memset(tss->io_bitmap, 0xff, tss->io_bitmap_max);
 274                t->io_bitmap_max = 0;
 275                tss->io_bitmap_owner = NULL;
 276                tss->io_bitmap_max = 0;
 277                tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET;
 278                put_cpu();
 279        }
 280}
 281
 282void flush_thread(void)
 283{
 284        struct task_struct *tsk = current;
 285
 286        tsk->thread.debugreg0 = 0;
 287        tsk->thread.debugreg1 = 0;
 288        tsk->thread.debugreg2 = 0;
 289        tsk->thread.debugreg3 = 0;
 290        tsk->thread.debugreg6 = 0;
 291        tsk->thread.debugreg7 = 0;
 292        memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));        
 293        clear_tsk_thread_flag(tsk, TIF_DEBUG);
 294        /*
 295         * Forget coprocessor state..
 296         */
 297        tsk->fpu_counter = 0;
 298        clear_fpu(tsk);
 299        clear_used_math();
 300}
 301
 302void release_thread(struct task_struct *dead_task)
 303{
 304        BUG_ON(dead_task->mm);
 305        release_vm86_irqs(dead_task);
 306}
 307
 308/*
 309 * This gets called before we allocate a new thread and copy
 310 * the current task into it.
 311 */
 312void prepare_to_copy(struct task_struct *tsk)
 313{
 314        unlazy_fpu(tsk);
 315}
 316
 317int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
 318        unsigned long unused,
 319        struct task_struct * p, struct pt_regs * regs)
 320{
 321        struct pt_regs * childregs;
 322        struct task_struct *tsk;
 323        int err;
 324
 325        childregs = task_pt_regs(p);
 326        *childregs = *regs;
 327        childregs->ax = 0;
 328        childregs->sp = sp;
 329
 330        p->thread.sp = (unsigned long) childregs;
 331        p->thread.sp0 = (unsigned long) (childregs+1);
 332
 333        p->thread.ip = (unsigned long) ret_from_fork;
 334
 335        savesegment(gs, p->thread.gs);
 336
 337        tsk = current;
 338        if (unlikely(test_tsk_thread_flag(tsk, TIF_IO_BITMAP))) {
 339                p->thread.io_bitmap_ptr = kmemdup(tsk->thread.io_bitmap_ptr,
 340                                                IO_BITMAP_BYTES, GFP_KERNEL);
 341                if (!p->thread.io_bitmap_ptr) {
 342                        p->thread.io_bitmap_max = 0;
 343                        return -ENOMEM;
 344                }
 345                set_tsk_thread_flag(p, TIF_IO_BITMAP);
 346        }
 347
 348        err = 0;
 349
 350        /*
 351         * Set a new TLS for the child thread?
 352         */
 353        if (clone_flags & CLONE_SETTLS)
 354                err = do_set_thread_area(p, -1,
 355                        (struct user_desc __user *)childregs->si, 0);
 356
 357        if (err && p->thread.io_bitmap_ptr) {
 358                kfree(p->thread.io_bitmap_ptr);
 359                p->thread.io_bitmap_max = 0;
 360        }
 361        return err;
 362}
 363
 364void
 365start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp)
 366{
 367        __asm__("movl %0, %%gs" :: "r"(0));
 368        regs->fs                = 0;
 369        set_fs(USER_DS);
 370        regs->ds                = __USER_DS;
 371        regs->es                = __USER_DS;
 372        regs->ss                = __USER_DS;
 373        regs->cs                = __USER_CS;
 374        regs->ip                = new_ip;
 375        regs->sp                = new_sp;
 376        /*
 377         * Free the old FP and other extended state
 378         */
 379        free_thread_xstate(current);
 380}
 381EXPORT_SYMBOL_GPL(start_thread);
 382
 383static void hard_disable_TSC(void)
 384{
 385        write_cr4(read_cr4() | X86_CR4_TSD);
 386}
 387
 388void disable_TSC(void)
 389{
 390        preempt_disable();
 391        if (!test_and_set_thread_flag(TIF_NOTSC))
 392                /*
 393                 * Must flip the CPU state synchronously with
 394                 * TIF_NOTSC in the current running context.
 395                 */
 396                hard_disable_TSC();
 397        preempt_enable();
 398}
 399
 400static void hard_enable_TSC(void)
 401{
 402        write_cr4(read_cr4() & ~X86_CR4_TSD);
 403}
 404
 405static void enable_TSC(void)
 406{
 407        preempt_disable();
 408        if (test_and_clear_thread_flag(TIF_NOTSC))
 409                /*
 410                 * Must flip the CPU state synchronously with
 411                 * TIF_NOTSC in the current running context.
 412                 */
 413                hard_enable_TSC();
 414        preempt_enable();
 415}
 416
 417int get_tsc_mode(unsigned long adr)
 418{
 419        unsigned int val;
 420
 421        if (test_thread_flag(TIF_NOTSC))
 422                val = PR_TSC_SIGSEGV;
 423        else
 424                val = PR_TSC_ENABLE;
 425
 426        return put_user(val, (unsigned int __user *)adr);
 427}
 428
 429int set_tsc_mode(unsigned int val)
 430{
 431        if (val == PR_TSC_SIGSEGV)
 432                disable_TSC();
 433        else if (val == PR_TSC_ENABLE)
 434                enable_TSC();
 435        else
 436                return -EINVAL;
 437
 438        return 0;
 439}
 440
 441static noinline void
 442__switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
 443                 struct tss_struct *tss)
 444{
 445        struct thread_struct *prev, *next;
 446        unsigned long debugctl;
 447
 448        prev = &prev_p->thread;
 449        next = &next_p->thread;
 450
 451        debugctl = prev->debugctlmsr;
 452        if (next->ds_area_msr != prev->ds_area_msr) {
 453                /* we clear debugctl to make sure DS
 454                 * is not in use when we change it */
 455                debugctl = 0;
 456                update_debugctlmsr(0);
 457                wrmsr(MSR_IA32_DS_AREA, next->ds_area_msr, 0);
 458        }
 459
 460        if (next->debugctlmsr != debugctl)
 461                update_debugctlmsr(next->debugctlmsr);
 462
 463        if (test_tsk_thread_flag(next_p, TIF_DEBUG)) {
 464                set_debugreg(next->debugreg0, 0);
 465                set_debugreg(next->debugreg1, 1);
 466                set_debugreg(next->debugreg2, 2);
 467                set_debugreg(next->debugreg3, 3);
 468                /* no 4 and 5 */
 469                set_debugreg(next->debugreg6, 6);
 470                set_debugreg(next->debugreg7, 7);
 471        }
 472
 473        if (test_tsk_thread_flag(prev_p, TIF_NOTSC) ^
 474            test_tsk_thread_flag(next_p, TIF_NOTSC)) {
 475                /* prev and next are different */
 476                if (test_tsk_thread_flag(next_p, TIF_NOTSC))
 477                        hard_disable_TSC();
 478                else
 479                        hard_enable_TSC();
 480        }
 481
 482#ifdef X86_BTS
 483        if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS))
 484                ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS);
 485
 486        if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS))
 487                ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES);
 488#endif
 489
 490
 491        if (!test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) {
 492                /*
 493                 * Disable the bitmap via an invalid offset. We still cache
 494                 * the previous bitmap owner and the IO bitmap contents:
 495                 */
 496                tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET;
 497                return;
 498        }
 499
 500        if (likely(next == tss->io_bitmap_owner)) {
 501                /*
 502                 * Previous owner of the bitmap (hence the bitmap content)
 503                 * matches the next task, we dont have to do anything but
 504                 * to set a valid offset in the TSS:
 505                 */
 506                tss->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET;
 507                return;
 508        }
 509        /*
 510         * Lazy TSS's I/O bitmap copy. We set an invalid offset here
 511         * and we let the task to get a GPF in case an I/O instruction
 512         * is performed.  The handler of the GPF will verify that the
 513         * faulting task has a valid I/O bitmap and, it true, does the
 514         * real copy and restart the instruction.  This will save us
 515         * redundant copies when the currently switched task does not
 516         * perform any I/O during its timeslice.
 517         */
 518        tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET_LAZY;
 519}
 520
 521/*
 522 *      switch_to(x,yn) should switch tasks from x to y.
 523 *
 524 * We fsave/fwait so that an exception goes off at the right time
 525 * (as a call from the fsave or fwait in effect) rather than to
 526 * the wrong process. Lazy FP saving no longer makes any sense
 527 * with modern CPU's, and this simplifies a lot of things (SMP
 528 * and UP become the same).
 529 *
 530 * NOTE! We used to use the x86 hardware context switching. The
 531 * reason for not using it any more becomes apparent when you
 532 * try to recover gracefully from saved state that is no longer
 533 * valid (stale segment register values in particular). With the
 534 * hardware task-switch, there is no way to fix up bad state in
 535 * a reasonable manner.
 536 *
 537 * The fact that Intel documents the hardware task-switching to
 538 * be slow is a fairly red herring - this code is not noticeably
 539 * faster. However, there _is_ some room for improvement here,
 540 * so the performance issues may eventually be a valid point.
 541 * More important, however, is the fact that this allows us much
 542 * more flexibility.
 543 *
 544 * The return value (in %ax) will be the "prev" task after
 545 * the task-switch, and shows up in ret_from_fork in entry.S,
 546 * for example.
 547 */
 548struct task_struct * __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 549{
 550        struct thread_struct *prev = &prev_p->thread,
 551                                 *next = &next_p->thread;
 552        int cpu = smp_processor_id();
 553        struct tss_struct *tss = &per_cpu(init_tss, cpu);
 554
 555        /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
 556
 557        __unlazy_fpu(prev_p);
 558
 559
 560        /* we're going to use this soon, after a few expensive things */
 561        if (next_p->fpu_counter > 5)
 562                prefetch(next->xstate);
 563
 564        /*
 565         * Reload esp0.
 566         */
 567        load_sp0(tss, next);
 568
 569        /*
 570         * Save away %gs. No need to save %fs, as it was saved on the
 571         * stack on entry.  No need to save %es and %ds, as those are
 572         * always kernel segments while inside the kernel.  Doing this
 573         * before setting the new TLS descriptors avoids the situation
 574         * where we temporarily have non-reloadable segments in %fs
 575         * and %gs.  This could be an issue if the NMI handler ever
 576         * used %fs or %gs (it does not today), or if the kernel is
 577         * running inside of a hypervisor layer.
 578         */
 579        savesegment(gs, prev->gs);
 580
 581        /*
 582         * Load the per-thread Thread-Local Storage descriptor.
 583         */
 584        load_TLS(next, cpu);
 585
 586        /*
 587         * Restore IOPL if needed.  In normal use, the flags restore
 588         * in the switch assembly will handle this.  But if the kernel
 589         * is running virtualized at a non-zero CPL, the popf will
 590         * not restore flags, so it must be done in a separate step.
 591         */
 592        if (get_kernel_rpl() && unlikely(prev->iopl != next->iopl))
 593                set_iopl_mask(next->iopl);
 594
 595        /*
 596         * Now maybe handle debug registers and/or IO bitmaps
 597         */
 598        if (unlikely(task_thread_info(prev_p)->flags & _TIF_WORK_CTXSW_PREV ||
 599                     task_thread_info(next_p)->flags & _TIF_WORK_CTXSW_NEXT))
 600                __switch_to_xtra(prev_p, next_p, tss);
 601
 602        /*
 603         * Leave lazy mode, flushing any hypercalls made here.
 604         * This must be done before restoring TLS segments so
 605         * the GDT and LDT are properly updated, and must be
 606         * done before math_state_restore, so the TS bit is up
 607         * to date.
 608         */
 609        arch_leave_lazy_cpu_mode();
 610
 611        /* If the task has used fpu the last 5 timeslices, just do a full
 612         * restore of the math state immediately to avoid the trap; the
 613         * chances of needing FPU soon are obviously high now
 614         *
 615         * tsk_used_math() checks prevent calling math_state_restore(),
 616         * which can sleep in the case of !tsk_used_math()
 617         */
 618        if (tsk_used_math(next_p) && next_p->fpu_counter > 5)
 619                math_state_restore();
 620
 621        /*
 622         * Restore %gs if needed (which is common)
 623         */
 624        if (prev->gs | next->gs)
 625                loadsegment(gs, next->gs);
 626
 627        x86_write_percpu(current_task, next_p);
 628
 629        return prev_p;
 630}
 631
 632asmlinkage int sys_fork(struct pt_regs regs)
 633{
 634        return do_fork(SIGCHLD, regs.sp, &regs, 0, NULL, NULL);
 635}
 636
 637asmlinkage int sys_clone(struct pt_regs regs)
 638{
 639        unsigned long clone_flags;
 640        unsigned long newsp;
 641        int __user *parent_tidptr, *child_tidptr;
 642
 643        clone_flags = regs.bx;
 644        newsp = regs.cx;
 645        parent_tidptr = (int __user *)regs.dx;
 646        child_tidptr = (int __user *)regs.di;
 647        if (!newsp)
 648                newsp = regs.sp;
 649        return do_fork(clone_flags, newsp, &regs, 0, parent_tidptr, child_tidptr);
 650}
 651
 652/*
 653 * This is trivial, and on the face of it looks like it
 654 * could equally well be done in user mode.
 655 *
 656 * Not so, for quite unobvious reasons - register pressure.
 657 * In user mode vfork() cannot have a stack frame, and if
 658 * done by calling the "clone()" system call directly, you
 659 * do not have enough call-clobbered registers to hold all
 660 * the information you need.
 661 */
 662asmlinkage int sys_vfork(struct pt_regs regs)
 663{
 664        return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.sp, &regs, 0, NULL, NULL);
 665}
 666
 667/*
 668 * sys_execve() executes a new program.
 669 */
 670asmlinkage int sys_execve(struct pt_regs regs)
 671{
 672        int error;
 673        char * filename;
 674
 675        filename = getname((char __user *) regs.bx);
 676        error = PTR_ERR(filename);
 677        if (IS_ERR(filename))
 678                goto out;
 679        error = do_execve(filename,
 680                        (char __user * __user *) regs.cx,
 681                        (char __user * __user *) regs.dx,
 682                        &regs);
 683        if (error == 0) {
 684                /* Make sure we don't return using sysenter.. */
 685                set_thread_flag(TIF_IRET);
 686        }
 687        putname(filename);
 688out:
 689        return error;
 690}
 691
 692#define top_esp                (THREAD_SIZE - sizeof(unsigned long))
 693#define top_ebp                (THREAD_SIZE - 2*sizeof(unsigned long))
 694
 695unsigned long get_wchan(struct task_struct *p)
 696{
 697        unsigned long bp, sp, ip;
 698        unsigned long stack_page;
 699        int count = 0;
 700        if (!p || p == current || p->state == TASK_RUNNING)
 701                return 0;
 702        stack_page = (unsigned long)task_stack_page(p);
 703        sp = p->thread.sp;
 704        if (!stack_page || sp < stack_page || sp > top_esp+stack_page)
 705                return 0;
 706        /* include/asm-i386/system.h:switch_to() pushes bp last. */
 707        bp = *(unsigned long *) sp;
 708        do {
 709                if (bp < stack_page || bp > top_ebp+stack_page)
 710                        return 0;
 711                ip = *(unsigned long *) (bp+4);
 712                if (!in_sched_functions(ip))
 713                        return ip;
 714                bp = *(unsigned long *) bp;
 715        } while (count++ < 16);
 716        return 0;
 717}
 718
 719unsigned long arch_align_stack(unsigned long sp)
 720{
 721        if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
 722                sp -= get_random_int() % 8192;
 723        return sp & ~0xf;
 724}
 725
 726unsigned long arch_randomize_brk(struct mm_struct *mm)
 727{
 728        unsigned long range_end = mm->brk + 0x02000000;
 729        return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
 730}
 731
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.