vserver 2.0 rc7
[linux-2.6.git] / kernel / stop_machine.c
index e31b1cb..6116b25 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/syscalls.h>
 #include <asm/atomic.h>
 #include <asm/semaphore.h>
+#include <asm/uaccess.h>
 
 /* Since we effect priority and affinity (both of which are visible
  * to, and settable by outside processes) we do indirection via a
@@ -32,7 +33,7 @@ static int stopmachine(void *cpu)
        set_cpus_allowed(current, cpumask_of_cpu((int)(long)cpu));
 
        /* Ack: we are alive */
-       mb(); /* Theoretically the ack = 0 might not be on this CPU yet. */
+       smp_mb(); /* Theoretically the ack = 0 might not be on this CPU yet. */
        atomic_inc(&stopmachine_thread_ack);
 
        /* Simple state machine */
@@ -42,14 +43,14 @@ static int stopmachine(void *cpu)
                        local_irq_disable();
                        irqs_disabled = 1;
                        /* Ack: irqs disabled. */
-                       mb(); /* Must read state first. */
+                       smp_mb(); /* Must read state first. */
                        atomic_inc(&stopmachine_thread_ack);
                } else if (stopmachine_state == STOPMACHINE_PREPARE
                           && !prepared) {
                        /* Everyone is in place, hold CPU. */
                        preempt_disable();
                        prepared = 1;
-                       mb(); /* Must read state first. */
+                       smp_mb(); /* Must read state first. */
                        atomic_inc(&stopmachine_thread_ack);
                }
                /* Yield in first stage: migration threads need to
@@ -61,7 +62,7 @@ static int stopmachine(void *cpu)
        }
 
        /* Ack: we are exiting. */
-       mb(); /* Must read state first. */
+       smp_mb(); /* Must read state first. */
        atomic_inc(&stopmachine_thread_ack);
 
        if (irqs_disabled)
@@ -76,7 +77,7 @@ static int stopmachine(void *cpu)
 static void stopmachine_set_state(enum stopmachine_state state)
 {
        atomic_set(&stopmachine_thread_ack, 0);
-       wmb();
+       smp_wmb();
        stopmachine_state = state;
        while (atomic_read(&stopmachine_thread_ack) != stopmachine_num_threads)
                cpu_relax();
@@ -86,9 +87,13 @@ static int stop_machine(void)
 {
        int i, ret = 0;
        struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
+       mm_segment_t old_fs = get_fs();
 
        /* One high-prio thread per cpu.  We'll do this one. */
-       sys_sched_setscheduler(current->pid, SCHED_FIFO, &param);
+       set_fs(KERNEL_DS);
+       sys_sched_setscheduler(current->pid, SCHED_FIFO,
+                               (struct sched_param __user *)&param);
+       set_fs(old_fs);
 
        atomic_set(&stopmachine_thread_ack, 0);
        stopmachine_num_threads = 0;