x86: Document linker script ASSERT() quirk
[safe/jmp/linux-2.6] / arch / x86 / kernel / process.c
index 6afa523..5284cd2 100644 (file)
@@ -8,12 +8,15 @@
 #include <linux/module.h>
 #include <linux/pm.h>
 #include <linux/clockchips.h>
-#include <linux/ftrace.h>
+#include <linux/random.h>
+#include <trace/events/power.h>
 #include <asm/system.h>
 #include <asm/apic.h>
+#include <asm/syscalls.h>
 #include <asm/idle.h>
 #include <asm/uaccess.h>
 #include <asm/i387.h>
+#include <asm/ds.h>
 
 unsigned long idle_halt;
 EXPORT_SYMBOL(idle_halt);
@@ -42,6 +45,8 @@ void free_thread_xstate(struct task_struct *tsk)
                kmem_cache_free(task_xstate_cachep, tsk->thread.xstate);
                tsk->thread.xstate = NULL;
        }
+
+       WARN(tsk->thread.ds_ctx, "leaking DS context\n");
 }
 
 void free_thread_info(struct thread_info *ti)
@@ -55,7 +60,7 @@ void arch_task_cache_init(void)
         task_xstate_cachep =
                kmem_cache_create("task_xstate", xstate_size,
                                  __alignof__(union thread_xstate),
-                                 SLAB_PANIC, NULL);
+                                 SLAB_PANIC | SLAB_NOTRACK, NULL);
 }
 
 /*
@@ -65,11 +70,11 @@ void exit_thread(void)
 {
        struct task_struct *me = current;
        struct thread_struct *t = &me->thread;
+       unsigned long *bp = t->io_bitmap_ptr;
 
-       if (me->thread.io_bitmap_ptr) {
+       if (bp) {
                struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
 
-               kfree(t->io_bitmap_ptr);
                t->io_bitmap_ptr = NULL;
                clear_thread_flag(TIF_IO_BITMAP);
                /*
@@ -78,9 +83,8 @@ void exit_thread(void)
                memset(tss->io_bitmap, 0xff, t->io_bitmap_max);
                t->io_bitmap_max = 0;
                put_cpu();
+               kfree(bp);
        }
-
-       ds_exit_thread(current);
 }
 
 void flush_thread(void)
@@ -292,9 +296,7 @@ static inline int hlt_use_halt(void)
 void default_idle(void)
 {
        if (hlt_use_halt()) {
-               struct power_trace it;
-
-               trace_power_start(&it, POWER_CSTATE, 1);
+               trace_power_start(POWER_CSTATE, 1);
                current_thread_info()->status &= ~TS_POLLING;
                /*
                 * TS_POLLING-cleared state must be visible before we
@@ -307,7 +309,6 @@ void default_idle(void)
                else
                        local_irq_enable();
                current_thread_info()->status |= TS_POLLING;
-               trace_power_end(&it);
        } else {
                local_irq_enable();
                /* loop is done by the caller */
@@ -324,7 +325,7 @@ void stop_this_cpu(void *dummy)
        /*
         * Remove this CPU:
         */
-       cpu_clear(smp_processor_id(), cpu_online_map);
+       set_cpu_online(smp_processor_id(), false);
        disable_local_APIC();
 
        for (;;) {
@@ -365,9 +366,7 @@ EXPORT_SYMBOL_GPL(cpu_idle_wait);
  */
 void mwait_idle_with_hints(unsigned long ax, unsigned long cx)
 {
-       struct power_trace it;
-
-       trace_power_start(&it, POWER_CSTATE, (ax>>4)+1);
+       trace_power_start(POWER_CSTATE, (ax>>4)+1);
        if (!need_resched()) {
                if (cpu_has(&current_cpu_data, X86_FEATURE_CLFLUSH_MONITOR))
                        clflush((void *)&current_thread_info()->flags);
@@ -377,15 +376,13 @@ void mwait_idle_with_hints(unsigned long ax, unsigned long cx)
                if (!need_resched())
                        __mwait(ax, cx);
        }
-       trace_power_end(&it);
 }
 
 /* Default MONITOR/MWAIT with no hints, used for default C1 state */
 static void mwait_idle(void)
 {
-       struct power_trace it;
        if (!need_resched()) {
-               trace_power_start(&it, POWER_CSTATE, 1);
+               trace_power_start(POWER_CSTATE, 1);
                if (cpu_has(&current_cpu_data, X86_FEATURE_CLFLUSH_MONITOR))
                        clflush((void *)&current_thread_info()->flags);
 
@@ -395,7 +392,6 @@ static void mwait_idle(void)
                        __sti_mwait(0, 0);
                else
                        local_irq_enable();
-               trace_power_end(&it);
        } else
                local_irq_enable();
 }
@@ -407,13 +403,11 @@ static void mwait_idle(void)
  */
 static void poll_idle(void)
 {
-       struct power_trace it;
-
-       trace_power_start(&it, POWER_CSTATE, 0);
+       trace_power_start(POWER_CSTATE, 0);
        local_irq_enable();
        while (!need_resched())
                cpu_relax();
-       trace_power_end(&it);
+       trace_power_end(0);
 }
 
 /*
@@ -474,12 +468,13 @@ static int __cpuinit check_c1e_idle(const struct cpuinfo_x86 *c)
        return 1;
 }
 
-static cpumask_t c1e_mask = CPU_MASK_NONE;
+static cpumask_var_t c1e_mask;
 static int c1e_detected;
 
 void c1e_remove_cpu(int cpu)
 {
-       cpu_clear(cpu, c1e_mask);
+       if (c1e_mask != NULL)
+               cpumask_clear_cpu(cpu, c1e_mask);
 }
 
 /*
@@ -508,19 +503,15 @@ static void c1e_idle(void)
        if (c1e_detected) {
                int cpu = smp_processor_id();
 
-               if (!cpu_isset(cpu, c1e_mask)) {
-                       cpu_set(cpu, c1e_mask);
+               if (!cpumask_test_cpu(cpu, c1e_mask)) {
+                       cpumask_set_cpu(cpu, c1e_mask);
                        /*
-                        * Force broadcast so ACPI can not interfere. Needs
-                        * to run with interrupts enabled as it uses
-                        * smp_function_call.
+                        * Force broadcast so ACPI can not interfere.
                         */
-                       local_irq_enable();
                        clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_FORCE,
                                           &cpu);
                        printk(KERN_INFO "Switch to broadcast mode on CPU%d\n",
                               cpu);
-                       local_irq_disable();
                }
                clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
 
@@ -561,6 +552,13 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)
                pm_idle = default_idle;
 }
 
+void __init init_c1e_mask(void)
+{
+       /* If we're using c1e_idle, we need to allocate c1e_mask. */
+       if (pm_idle == c1e_idle)
+               zalloc_cpumask_var(&c1e_mask, GFP_KERNEL);
+}
+
 static int __init idle_setup(char *str)
 {
        if (!str)
@@ -599,3 +597,16 @@ static int __init idle_setup(char *str)
 }
 early_param("idle", idle_setup);
 
+unsigned long arch_align_stack(unsigned long sp)
+{
+       if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
+               sp -= get_random_int() % 8192;
+       return sp & ~0xf;
+}
+
+unsigned long arch_randomize_brk(struct mm_struct *mm)
+{
+       unsigned long range_end = mm->brk + 0x02000000;
+       return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
+}
+