Don't trigger softlockup detector on network fs blocked tasks
[safe/jmp/linux-2.6] / kernel / sys.c
index bc8879c..038a7bc 100644 (file)
 #ifndef SET_ENDIAN
 # define SET_ENDIAN(a,b)       (-EINVAL)
 #endif
+#ifndef GET_TSC_CTL
+# define GET_TSC_CTL(a)                (-EINVAL)
+#endif
+#ifndef SET_TSC_CTL
+# define SET_TSC_CTL(a)                (-EINVAL)
+#endif
 
 /*
  * this is where the system-wide overflow UID and GID are defined, for
@@ -106,537 +112,6 @@ EXPORT_SYMBOL(cad_pid);
 
 void (*pm_power_off_prepare)(void);
 
-/*
- *     Notifier list for kernel code which wants to be called
- *     at shutdown. This is used to stop any idling DMA operations
- *     and the like. 
- */
-
-static BLOCKING_NOTIFIER_HEAD(reboot_notifier_list);
-
-/*
- *     Notifier chain core routines.  The exported routines below
- *     are layered on top of these, with appropriate locking added.
- */
-
-static int notifier_chain_register(struct notifier_block **nl,
-               struct notifier_block *n)
-{
-       while ((*nl) != NULL) {
-               if (n->priority > (*nl)->priority)
-                       break;
-               nl = &((*nl)->next);
-       }
-       n->next = *nl;
-       rcu_assign_pointer(*nl, n);
-       return 0;
-}
-
-static int notifier_chain_unregister(struct notifier_block **nl,
-               struct notifier_block *n)
-{
-       while ((*nl) != NULL) {
-               if ((*nl) == n) {
-                       rcu_assign_pointer(*nl, n->next);
-                       return 0;
-               }
-               nl = &((*nl)->next);
-       }
-       return -ENOENT;
-}
-
-/**
- * notifier_call_chain - Informs the registered notifiers about an event.
- *     @nl:            Pointer to head of the blocking notifier chain
- *     @val:           Value passed unmodified to notifier function
- *     @v:             Pointer passed unmodified to notifier function
- *     @nr_to_call:    Number of notifier functions to be called. Don't care
- *                     value of this parameter is -1.
- *     @nr_calls:      Records the number of notifications sent. Don't care
- *                     value of this field is NULL.
- *     @returns:       notifier_call_chain returns the value returned by the
- *                     last notifier function called.
- */
-
-static int __kprobes notifier_call_chain(struct notifier_block **nl,
-                                       unsigned long val, void *v,
-                                       int nr_to_call, int *nr_calls)
-{
-       int ret = NOTIFY_DONE;
-       struct notifier_block *nb, *next_nb;
-
-       nb = rcu_dereference(*nl);
-
-       while (nb && nr_to_call) {
-               next_nb = rcu_dereference(nb->next);
-               ret = nb->notifier_call(nb, val, v);
-
-               if (nr_calls)
-                       (*nr_calls)++;
-
-               if ((ret & NOTIFY_STOP_MASK) == NOTIFY_STOP_MASK)
-                       break;
-               nb = next_nb;
-               nr_to_call--;
-       }
-       return ret;
-}
-
-/*
- *     Atomic notifier chain routines.  Registration and unregistration
- *     use a spinlock, and call_chain is synchronized by RCU (no locks).
- */
-
-/**
- *     atomic_notifier_chain_register - Add notifier to an atomic notifier chain
- *     @nh: Pointer to head of the atomic notifier chain
- *     @n: New entry in notifier chain
- *
- *     Adds a notifier to an atomic notifier chain.
- *
- *     Currently always returns zero.
- */
-
-int atomic_notifier_chain_register(struct atomic_notifier_head *nh,
-               struct notifier_block *n)
-{
-       unsigned long flags;
-       int ret;
-
-       spin_lock_irqsave(&nh->lock, flags);
-       ret = notifier_chain_register(&nh->head, n);
-       spin_unlock_irqrestore(&nh->lock, flags);
-       return ret;
-}
-
-EXPORT_SYMBOL_GPL(atomic_notifier_chain_register);
-
-/**
- *     atomic_notifier_chain_unregister - Remove notifier from an atomic notifier chain
- *     @nh: Pointer to head of the atomic notifier chain
- *     @n: Entry to remove from notifier chain
- *
- *     Removes a notifier from an atomic notifier chain.
- *
- *     Returns zero on success or %-ENOENT on failure.
- */
-int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh,
-               struct notifier_block *n)
-{
-       unsigned long flags;
-       int ret;
-
-       spin_lock_irqsave(&nh->lock, flags);
-       ret = notifier_chain_unregister(&nh->head, n);
-       spin_unlock_irqrestore(&nh->lock, flags);
-       synchronize_rcu();
-       return ret;
-}
-
-EXPORT_SYMBOL_GPL(atomic_notifier_chain_unregister);
-
-/**
- *     __atomic_notifier_call_chain - Call functions in an atomic notifier chain
- *     @nh: Pointer to head of the atomic notifier chain
- *     @val: Value passed unmodified to notifier function
- *     @v: Pointer passed unmodified to notifier function
- *     @nr_to_call: See the comment for notifier_call_chain.
- *     @nr_calls: See the comment for notifier_call_chain.
- *
- *     Calls each function in a notifier chain in turn.  The functions
- *     run in an atomic context, so they must not block.
- *     This routine uses RCU to synchronize with changes to the chain.
- *
- *     If the return value of the notifier can be and'ed
- *     with %NOTIFY_STOP_MASK then atomic_notifier_call_chain()
- *     will return immediately, with the return value of
- *     the notifier function which halted execution.
- *     Otherwise the return value is the return value
- *     of the last notifier function called.
- */
-int __kprobes __atomic_notifier_call_chain(struct atomic_notifier_head *nh,
-                                       unsigned long val, void *v,
-                                       int nr_to_call, int *nr_calls)
-{
-       int ret;
-
-       rcu_read_lock();
-       ret = notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls);
-       rcu_read_unlock();
-       return ret;
-}
-
-EXPORT_SYMBOL_GPL(__atomic_notifier_call_chain);
-
-int __kprobes atomic_notifier_call_chain(struct atomic_notifier_head *nh,
-               unsigned long val, void *v)
-{
-       return __atomic_notifier_call_chain(nh, val, v, -1, NULL);
-}
-
-EXPORT_SYMBOL_GPL(atomic_notifier_call_chain);
-/*
- *     Blocking notifier chain routines.  All access to the chain is
- *     synchronized by an rwsem.
- */
-
-/**
- *     blocking_notifier_chain_register - Add notifier to a blocking notifier chain
- *     @nh: Pointer to head of the blocking notifier chain
- *     @n: New entry in notifier chain
- *
- *     Adds a notifier to a blocking notifier chain.
- *     Must be called in process context.
- *
- *     Currently always returns zero.
- */
-int blocking_notifier_chain_register(struct blocking_notifier_head *nh,
-               struct notifier_block *n)
-{
-       int ret;
-
-       /*
-        * This code gets used during boot-up, when task switching is
-        * not yet working and interrupts must remain disabled.  At
-        * such times we must not call down_write().
-        */
-       if (unlikely(system_state == SYSTEM_BOOTING))
-               return notifier_chain_register(&nh->head, n);
-
-       down_write(&nh->rwsem);
-       ret = notifier_chain_register(&nh->head, n);
-       up_write(&nh->rwsem);
-       return ret;
-}
-
-EXPORT_SYMBOL_GPL(blocking_notifier_chain_register);
-
-/**
- *     blocking_notifier_chain_unregister - Remove notifier from a blocking notifier chain
- *     @nh: Pointer to head of the blocking notifier chain
- *     @n: Entry to remove from notifier chain
- *
- *     Removes a notifier from a blocking notifier chain.
- *     Must be called from process context.
- *
- *     Returns zero on success or %-ENOENT on failure.
- */
-int blocking_notifier_chain_unregister(struct blocking_notifier_head *nh,
-               struct notifier_block *n)
-{
-       int ret;
-
-       /*
-        * This code gets used during boot-up, when task switching is
-        * not yet working and interrupts must remain disabled.  At
-        * such times we must not call down_write().
-        */
-       if (unlikely(system_state == SYSTEM_BOOTING))
-               return notifier_chain_unregister(&nh->head, n);
-
-       down_write(&nh->rwsem);
-       ret = notifier_chain_unregister(&nh->head, n);
-       up_write(&nh->rwsem);
-       return ret;
-}
-
-EXPORT_SYMBOL_GPL(blocking_notifier_chain_unregister);
-
-/**
- *     __blocking_notifier_call_chain - Call functions in a blocking notifier chain
- *     @nh: Pointer to head of the blocking notifier chain
- *     @val: Value passed unmodified to notifier function
- *     @v: Pointer passed unmodified to notifier function
- *     @nr_to_call: See comment for notifier_call_chain.
- *     @nr_calls: See comment for notifier_call_chain.
- *
- *     Calls each function in a notifier chain in turn.  The functions
- *     run in a process context, so they are allowed to block.
- *
- *     If the return value of the notifier can be and'ed
- *     with %NOTIFY_STOP_MASK then blocking_notifier_call_chain()
- *     will return immediately, with the return value of
- *     the notifier function which halted execution.
- *     Otherwise the return value is the return value
- *     of the last notifier function called.
- */
-int __blocking_notifier_call_chain(struct blocking_notifier_head *nh,
-                                  unsigned long val, void *v,
-                                  int nr_to_call, int *nr_calls)
-{
-       int ret = NOTIFY_DONE;
-
-       /*
-        * We check the head outside the lock, but if this access is
-        * racy then it does not matter what the result of the test
-        * is, we re-check the list after having taken the lock anyway:
-        */
-       if (rcu_dereference(nh->head)) {
-               down_read(&nh->rwsem);
-               ret = notifier_call_chain(&nh->head, val, v, nr_to_call,
-                                       nr_calls);
-               up_read(&nh->rwsem);
-       }
-       return ret;
-}
-EXPORT_SYMBOL_GPL(__blocking_notifier_call_chain);
-
-int blocking_notifier_call_chain(struct blocking_notifier_head *nh,
-               unsigned long val, void *v)
-{
-       return __blocking_notifier_call_chain(nh, val, v, -1, NULL);
-}
-EXPORT_SYMBOL_GPL(blocking_notifier_call_chain);
-
-/*
- *     Raw notifier chain routines.  There is no protection;
- *     the caller must provide it.  Use at your own risk!
- */
-
-/**
- *     raw_notifier_chain_register - Add notifier to a raw notifier chain
- *     @nh: Pointer to head of the raw notifier chain
- *     @n: New entry in notifier chain
- *
- *     Adds a notifier to a raw notifier chain.
- *     All locking must be provided by the caller.
- *
- *     Currently always returns zero.
- */
-
-int raw_notifier_chain_register(struct raw_notifier_head *nh,
-               struct notifier_block *n)
-{
-       return notifier_chain_register(&nh->head, n);
-}
-
-EXPORT_SYMBOL_GPL(raw_notifier_chain_register);
-
-/**
- *     raw_notifier_chain_unregister - Remove notifier from a raw notifier chain
- *     @nh: Pointer to head of the raw notifier chain
- *     @n: Entry to remove from notifier chain
- *
- *     Removes a notifier from a raw notifier chain.
- *     All locking must be provided by the caller.
- *
- *     Returns zero on success or %-ENOENT on failure.
- */
-int raw_notifier_chain_unregister(struct raw_notifier_head *nh,
-               struct notifier_block *n)
-{
-       return notifier_chain_unregister(&nh->head, n);
-}
-
-EXPORT_SYMBOL_GPL(raw_notifier_chain_unregister);
-
-/**
- *     __raw_notifier_call_chain - Call functions in a raw notifier chain
- *     @nh: Pointer to head of the raw notifier chain
- *     @val: Value passed unmodified to notifier function
- *     @v: Pointer passed unmodified to notifier function
- *     @nr_to_call: See comment for notifier_call_chain.
- *     @nr_calls: See comment for notifier_call_chain
- *
- *     Calls each function in a notifier chain in turn.  The functions
- *     run in an undefined context.
- *     All locking must be provided by the caller.
- *
- *     If the return value of the notifier can be and'ed
- *     with %NOTIFY_STOP_MASK then raw_notifier_call_chain()
- *     will return immediately, with the return value of
- *     the notifier function which halted execution.
- *     Otherwise the return value is the return value
- *     of the last notifier function called.
- */
-
-int __raw_notifier_call_chain(struct raw_notifier_head *nh,
-                             unsigned long val, void *v,
-                             int nr_to_call, int *nr_calls)
-{
-       return notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls);
-}
-
-EXPORT_SYMBOL_GPL(__raw_notifier_call_chain);
-
-int raw_notifier_call_chain(struct raw_notifier_head *nh,
-               unsigned long val, void *v)
-{
-       return __raw_notifier_call_chain(nh, val, v, -1, NULL);
-}
-
-EXPORT_SYMBOL_GPL(raw_notifier_call_chain);
-
-/*
- *     SRCU notifier chain routines.    Registration and unregistration
- *     use a mutex, and call_chain is synchronized by SRCU (no locks).
- */
-
-/**
- *     srcu_notifier_chain_register - Add notifier to an SRCU notifier chain
- *     @nh: Pointer to head of the SRCU notifier chain
- *     @n: New entry in notifier chain
- *
- *     Adds a notifier to an SRCU notifier chain.
- *     Must be called in process context.
- *
- *     Currently always returns zero.
- */
-
-int srcu_notifier_chain_register(struct srcu_notifier_head *nh,
-               struct notifier_block *n)
-{
-       int ret;
-
-       /*
-        * This code gets used during boot-up, when task switching is
-        * not yet working and interrupts must remain disabled.  At
-        * such times we must not call mutex_lock().
-        */
-       if (unlikely(system_state == SYSTEM_BOOTING))
-               return notifier_chain_register(&nh->head, n);
-
-       mutex_lock(&nh->mutex);
-       ret = notifier_chain_register(&nh->head, n);
-       mutex_unlock(&nh->mutex);
-       return ret;
-}
-
-EXPORT_SYMBOL_GPL(srcu_notifier_chain_register);
-
-/**
- *     srcu_notifier_chain_unregister - Remove notifier from an SRCU notifier chain
- *     @nh: Pointer to head of the SRCU notifier chain
- *     @n: Entry to remove from notifier chain
- *
- *     Removes a notifier from an SRCU notifier chain.
- *     Must be called from process context.
- *
- *     Returns zero on success or %-ENOENT on failure.
- */
-int srcu_notifier_chain_unregister(struct srcu_notifier_head *nh,
-               struct notifier_block *n)
-{
-       int ret;
-
-       /*
-        * This code gets used during boot-up, when task switching is
-        * not yet working and interrupts must remain disabled.  At
-        * such times we must not call mutex_lock().
-        */
-       if (unlikely(system_state == SYSTEM_BOOTING))
-               return notifier_chain_unregister(&nh->head, n);
-
-       mutex_lock(&nh->mutex);
-       ret = notifier_chain_unregister(&nh->head, n);
-       mutex_unlock(&nh->mutex);
-       synchronize_srcu(&nh->srcu);
-       return ret;
-}
-
-EXPORT_SYMBOL_GPL(srcu_notifier_chain_unregister);
-
-/**
- *     __srcu_notifier_call_chain - Call functions in an SRCU notifier chain
- *     @nh: Pointer to head of the SRCU notifier chain
- *     @val: Value passed unmodified to notifier function
- *     @v: Pointer passed unmodified to notifier function
- *     @nr_to_call: See comment for notifier_call_chain.
- *     @nr_calls: See comment for notifier_call_chain
- *
- *     Calls each function in a notifier chain in turn.  The functions
- *     run in a process context, so they are allowed to block.
- *
- *     If the return value of the notifier can be and'ed
- *     with %NOTIFY_STOP_MASK then srcu_notifier_call_chain()
- *     will return immediately, with the return value of
- *     the notifier function which halted execution.
- *     Otherwise the return value is the return value
- *     of the last notifier function called.
- */
-
-int __srcu_notifier_call_chain(struct srcu_notifier_head *nh,
-                              unsigned long val, void *v,
-                              int nr_to_call, int *nr_calls)
-{
-       int ret;
-       int idx;
-
-       idx = srcu_read_lock(&nh->srcu);
-       ret = notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls);
-       srcu_read_unlock(&nh->srcu, idx);
-       return ret;
-}
-EXPORT_SYMBOL_GPL(__srcu_notifier_call_chain);
-
-int srcu_notifier_call_chain(struct srcu_notifier_head *nh,
-               unsigned long val, void *v)
-{
-       return __srcu_notifier_call_chain(nh, val, v, -1, NULL);
-}
-EXPORT_SYMBOL_GPL(srcu_notifier_call_chain);
-
-/**
- *     srcu_init_notifier_head - Initialize an SRCU notifier head
- *     @nh: Pointer to head of the srcu notifier chain
- *
- *     Unlike other sorts of notifier heads, SRCU notifier heads require
- *     dynamic initialization.  Be sure to call this routine before
- *     calling any of the other SRCU notifier routines for this head.
- *
- *     If an SRCU notifier head is deallocated, it must first be cleaned
- *     up by calling srcu_cleanup_notifier_head().  Otherwise the head's
- *     per-cpu data (used by the SRCU mechanism) will leak.
- */
-
-void srcu_init_notifier_head(struct srcu_notifier_head *nh)
-{
-       mutex_init(&nh->mutex);
-       if (init_srcu_struct(&nh->srcu) < 0)
-               BUG();
-       nh->head = NULL;
-}
-
-EXPORT_SYMBOL_GPL(srcu_init_notifier_head);
-
-/**
- *     register_reboot_notifier - Register function to be called at reboot time
- *     @nb: Info about notifier function to be called
- *
- *     Registers a function with the list of functions
- *     to be called at reboot time.
- *
- *     Currently always returns zero, as blocking_notifier_chain_register()
- *     always returns zero.
- */
-int register_reboot_notifier(struct notifier_block * nb)
-{
-       return blocking_notifier_chain_register(&reboot_notifier_list, nb);
-}
-
-EXPORT_SYMBOL(register_reboot_notifier);
-
-/**
- *     unregister_reboot_notifier - Unregister previously registered reboot notifier
- *     @nb: Hook to be unregistered
- *
- *     Unregisters a previously registered reboot
- *     notifier function.
- *
- *     Returns zero on success, or %-ENOENT on failure.
- */
-int unregister_reboot_notifier(struct notifier_block * nb)
-{
-       return blocking_notifier_chain_unregister(&reboot_notifier_list, nb);
-}
-
-EXPORT_SYMBOL(unregister_reboot_notifier);
-
 static int set_one_prio(struct task_struct *p, int niceval, int error)
 {
        int no_nice;
@@ -683,7 +158,7 @@ asmlinkage long sys_setpriority(int which, int who, int niceval)
        switch (which) {
                case PRIO_PROCESS:
                        if (who)
-                               p = find_task_by_pid(who);
+                               p = find_task_by_vpid(who);
                        else
                                p = current;
                        if (p)
@@ -691,12 +166,12 @@ asmlinkage long sys_setpriority(int which, int who, int niceval)
                        break;
                case PRIO_PGRP:
                        if (who)
-                               pgrp = find_pid(who);
+                               pgrp = find_vpid(who);
                        else
                                pgrp = task_pgrp(current);
-                       do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
+                       do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
                                error = set_one_prio(p, niceval, error);
-                       } while_each_pid_task(pgrp, PIDTYPE_PGID, p);
+                       } while_each_pid_thread(pgrp, PIDTYPE_PGID, p);
                        break;
                case PRIO_USER:
                        user = current->user;
@@ -740,7 +215,7 @@ asmlinkage long sys_getpriority(int which, int who)
        switch (which) {
                case PRIO_PROCESS:
                        if (who)
-                               p = find_task_by_pid(who);
+                               p = find_task_by_vpid(who);
                        else
                                p = current;
                        if (p) {
@@ -751,14 +226,14 @@ asmlinkage long sys_getpriority(int which, int who)
                        break;
                case PRIO_PGRP:
                        if (who)
-                               pgrp = find_pid(who);
+                               pgrp = find_vpid(who);
                        else
                                pgrp = task_pgrp(current);
-                       do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
+                       do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
                                niceval = 20 - task_nice(p);
                                if (niceval > retval)
                                        retval = niceval;
-                       } while_each_pid_task(pgrp, PIDTYPE_PGID, p);
+                       } while_each_pid_thread(pgrp, PIDTYPE_PGID, p);
                        break;
                case PRIO_USER:
                        user = current->user;
@@ -799,7 +274,7 @@ void emergency_restart(void)
 }
 EXPORT_SYMBOL_GPL(emergency_restart);
 
-static void kernel_restart_prepare(char *cmd)
+void kernel_restart_prepare(char *cmd)
 {
        blocking_notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd);
        system_state = SYSTEM_RESTART;
@@ -826,27 +301,7 @@ void kernel_restart(char *cmd)
 }
 EXPORT_SYMBOL_GPL(kernel_restart);
 
-/**
- *     kernel_kexec - reboot the system
- *
- *     Move into place and start executing a preloaded standalone
- *     executable.  If nothing was preloaded return an error.
- */
-static void kernel_kexec(void)
-{
-#ifdef CONFIG_KEXEC
-       struct kimage *image;
-       image = xchg(&kexec_image, NULL);
-       if (!image)
-               return;
-       kernel_restart_prepare(NULL);
-       printk(KERN_EMERG "Starting new kernel\n");
-       machine_shutdown();
-       machine_kexec(image);
-#endif
-}
-
-void kernel_shutdown_prepare(enum system_states state)
+static void kernel_shutdown_prepare(enum system_states state)
 {
        blocking_notifier_call_chain(&reboot_notifier_list,
                (state == SYSTEM_HALT)?SYS_HALT:SYS_POWER_OFF, NULL);
@@ -950,10 +405,15 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user
                kernel_restart(buffer);
                break;
 
+#ifdef CONFIG_KEXEC
        case LINUX_REBOOT_CMD_KEXEC:
-               kernel_kexec();
-               unlock_kernel();
-               return -EINVAL;
+               {
+                       int ret;
+                       ret = kernel_kexec();
+                       unlock_kernel();
+                       return ret;
+               }
+#endif
 
 #ifdef CONFIG_HIBERNATION
        case LINUX_REBOOT_CMD_SW_SUSPEND:
@@ -1447,10 +907,11 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
 {
        struct task_struct *p;
        struct task_struct *group_leader = current->group_leader;
-       int err = -EINVAL;
+       struct pid *pgrp;
+       int err;
 
        if (!pid)
-               pid = group_leader->pid;
+               pid = task_pid_vnr(group_leader);
        if (!pgid)
                pgid = pid;
        if (pgid < 0)
@@ -1462,7 +923,7 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
        write_lock_irq(&tasklist_lock);
 
        err = -ESRCH;
-       p = find_task_by_pid(pid);
+       p = find_task_by_vpid(pid);
        if (!p)
                goto out;
 
@@ -1470,7 +931,7 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
        if (!thread_group_leader(p))
                goto out;
 
-       if (p->real_parent->tgid == group_leader->tgid) {
+       if (same_thread_group(p->real_parent, group_leader)) {
                err = -EPERM;
                if (task_session(p) != task_session(group_leader))
                        goto out;
@@ -1487,10 +948,12 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
        if (p->signal->leader)
                goto out;
 
+       pgrp = task_pid(p);
        if (pgid != pid) {
-               struct task_struct *g =
-                       find_task_by_pid_type(PIDTYPE_PGID, pgid);
+               struct task_struct *g;
 
+               pgrp = find_vpid(pgid);
+               g = pid_task(pgrp, PIDTYPE_PGID);
                if (!g || task_session(g) != task_session(group_leader))
                        goto out;
        }
@@ -1499,10 +962,9 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
        if (err)
                goto out;
 
-       if (process_group(p) != pgid) {
-               detach_pid(p, PIDTYPE_PGID);
-               p->signal->pgrp = pgid;
-               attach_pid(p, PIDTYPE_PGID, find_pid(pgid));
+       if (task_pgrp(p) != pgrp) {
+               change_pid(p, PIDTYPE_PGID, pgrp);
+               set_task_pgrp(p, pid_nr(pgrp));
        }
 
        err = 0;
@@ -1514,89 +976,95 @@ out:
 
 asmlinkage long sys_getpgid(pid_t pid)
 {
+       struct task_struct *p;
+       struct pid *grp;
+       int retval;
+
+       rcu_read_lock();
        if (!pid)
-               return process_group(current);
+               grp = task_pgrp(current);
        else {
-               int retval;
-               struct task_struct *p;
-
-               read_lock(&tasklist_lock);
-               p = find_task_by_pid(pid);
-
                retval = -ESRCH;
-               if (p) {
-                       retval = security_task_getpgid(p);
-                       if (!retval)
-                               retval = process_group(p);
-               }
-               read_unlock(&tasklist_lock);
-               return retval;
+               p = find_task_by_vpid(pid);
+               if (!p)
+                       goto out;
+               grp = task_pgrp(p);
+               if (!grp)
+                       goto out;
+
+               retval = security_task_getpgid(p);
+               if (retval)
+                       goto out;
        }
+       retval = pid_vnr(grp);
+out:
+       rcu_read_unlock();
+       return retval;
 }
 
 #ifdef __ARCH_WANT_SYS_GETPGRP
 
 asmlinkage long sys_getpgrp(void)
 {
-       /* SMP - assuming writes are word atomic this is fine */
-       return process_group(current);
+       return sys_getpgid(0);
 }
 
 #endif
 
 asmlinkage long sys_getsid(pid_t pid)
 {
+       struct task_struct *p;
+       struct pid *sid;
+       int retval;
+
+       rcu_read_lock();
        if (!pid)
-               return process_session(current);
+               sid = task_session(current);
        else {
-               int retval;
-               struct task_struct *p;
-
-               read_lock(&tasklist_lock);
-               p = find_task_by_pid(pid);
-
                retval = -ESRCH;
-               if (p) {
-                       retval = security_task_getsid(p);
-                       if (!retval)
-                               retval = process_session(p);
-               }
-               read_unlock(&tasklist_lock);
-               return retval;
+               p = find_task_by_vpid(pid);
+               if (!p)
+                       goto out;
+               sid = task_session(p);
+               if (!sid)
+                       goto out;
+
+               retval = security_task_getsid(p);
+               if (retval)
+                       goto out;
        }
+       retval = pid_vnr(sid);
+out:
+       rcu_read_unlock();
+       return retval;
 }
 
 asmlinkage long sys_setsid(void)
 {
        struct task_struct *group_leader = current->group_leader;
-       pid_t session;
+       struct pid *sid = task_pid(group_leader);
+       pid_t session = pid_vnr(sid);
        int err = -EPERM;
 
        write_lock_irq(&tasklist_lock);
-
        /* Fail if I am already a session leader */
        if (group_leader->signal->leader)
                goto out;
 
-       session = group_leader->pid;
        /* Fail if a process group id already exists that equals the
         * proposed session id.
-        *
-        * Don't check if session id == 1 because kernel threads use this
-        * session id and so the check will always fail and make it so
-        * init cannot successfully call setsid.
         */
-       if (session > 1 && find_task_by_pid_type(PIDTYPE_PGID, session))
+       if (pid_task(sid, PIDTYPE_PGID))
                goto out;
 
        group_leader->signal->leader = 1;
-       __set_special_pids(session, session);
+       __set_special_pids(sid);
 
        spin_lock(&group_leader->sighand->siglock);
        group_leader->signal->tty = NULL;
        spin_unlock(&group_leader->sighand->siglock);
 
-       err = process_group(group_leader);
+       err = session;
 out:
        write_unlock_irq(&tasklist_lock);
        return err;
@@ -1665,16 +1133,16 @@ static int groups_to_user(gid_t __user *grouplist,
     struct group_info *group_info)
 {
        int i;
-       int count = group_info->ngroups;
+       unsigned int count = group_info->ngroups;
 
        for (i = 0; i < group_info->nblocks; i++) {
-               int cp_count = min(NGROUPS_PER_BLOCK, count);
-               int off = i * NGROUPS_PER_BLOCK;
-               int len = cp_count * sizeof(*grouplist);
+               unsigned int cp_count = min(NGROUPS_PER_BLOCK, count);
+               unsigned int len = cp_count * sizeof(*grouplist);
 
-               if (copy_to_user(grouplist+off, group_info->blocks[i], len))
+               if (copy_to_user(grouplist, group_info->blocks[i], len))
                        return -EFAULT;
 
+               grouplist += NGROUPS_PER_BLOCK;
                count -= cp_count;
        }
        return 0;
@@ -1685,16 +1153,16 @@ static int groups_from_user(struct group_info *group_info,
     gid_t __user *grouplist)
 {
        int i;
-       int count = group_info->ngroups;
+       unsigned int count = group_info->ngroups;
 
        for (i = 0; i < group_info->nblocks; i++) {
-               int cp_count = min(NGROUPS_PER_BLOCK, count);
-               int off = i * NGROUPS_PER_BLOCK;
-               int len = cp_count * sizeof(*grouplist);
+               unsigned int cp_count = min(NGROUPS_PER_BLOCK, count);
+               unsigned int len = cp_count * sizeof(*grouplist);
 
-               if (copy_from_user(group_info->blocks[i], grouplist+off, len))
+               if (copy_from_user(group_info->blocks[i], grouplist, len))
                        return -EFAULT;
 
+               grouplist += NGROUPS_PER_BLOCK;
                count -= cp_count;
        }
        return 0;
@@ -1860,8 +1328,6 @@ EXPORT_SYMBOL(in_egroup_p);
 
 DECLARE_RWSEM(uts_sem);
 
-EXPORT_SYMBOL(uts_sem);
-
 asmlinkage long sys_newuname(struct new_utsname __user * name)
 {
        int errno = 0;
@@ -1992,7 +1458,7 @@ asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit __user *rlim)
        if ((new_rlim.rlim_max > old_rlim->rlim_max) &&
            !capable(CAP_SYS_RESOURCE))
                return -EPERM;
-       if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > NR_OPEN)
+       if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > sysctl_nr_open)
                return -EPERM;
 
        retval = security_task_setrlimit(resource, &new_rlim);
@@ -2074,6 +1540,19 @@ out:
  *
  */
 
+static void accumulate_thread_rusage(struct task_struct *t, struct rusage *r,
+                                    cputime_t *utimep, cputime_t *stimep)
+{
+       *utimep = cputime_add(*utimep, t->utime);
+       *stimep = cputime_add(*stimep, t->stime);
+       r->ru_nvcsw += t->nvcsw;
+       r->ru_nivcsw += t->nivcsw;
+       r->ru_minflt += t->min_flt;
+       r->ru_majflt += t->maj_flt;
+       r->ru_inblock += task_io_get_inblock(t);
+       r->ru_oublock += task_io_get_oublock(t);
+}
+
 static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
 {
        struct task_struct *t;
@@ -2083,12 +1562,14 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
        memset((char *) r, 0, sizeof *r);
        utime = stime = cputime_zero;
 
-       rcu_read_lock();
-       if (!lock_task_sighand(p, &flags)) {
-               rcu_read_unlock();
-               return;
+       if (who == RUSAGE_THREAD) {
+               accumulate_thread_rusage(p, r, &utime, &stime);
+               goto out;
        }
 
+       if (!lock_task_sighand(p, &flags))
+               return;
+
        switch (who) {
                case RUSAGE_BOTH:
                case RUSAGE_CHILDREN:
@@ -2115,14 +1596,7 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
                        r->ru_oublock += p->signal->oublock;
                        t = p;
                        do {
-                               utime = cputime_add(utime, t->utime);
-                               stime = cputime_add(stime, t->stime);
-                               r->ru_nvcsw += t->nvcsw;
-                               r->ru_nivcsw += t->nivcsw;
-                               r->ru_minflt += t->min_flt;
-                               r->ru_majflt += t->maj_flt;
-                               r->ru_inblock += task_io_get_inblock(t);
-                               r->ru_oublock += task_io_get_oublock(t);
+                               accumulate_thread_rusage(t, r, &utime, &stime);
                                t = next_thread(t);
                        } while (t != p);
                        break;
@@ -2130,10 +1604,9 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
                default:
                        BUG();
        }
-
        unlock_task_sighand(p, &flags);
-       rcu_read_unlock();
 
+out:
        cputime_to_timeval(utime, &r->ru_utime);
        cputime_to_timeval(stime, &r->ru_stime);
 }
@@ -2147,7 +1620,8 @@ int getrusage(struct task_struct *p, int who, struct rusage __user *ru)
 
 asmlinkage long sys_getrusage(int who, struct rusage __user *ru)
 {
-       if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN)
+       if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN &&
+           who != RUSAGE_THREAD)
                return -EINVAL;
        return getrusage(current, who, ru);
 }
@@ -2157,14 +1631,13 @@ asmlinkage long sys_umask(int mask)
        mask = xchg(&current->fs->umask, mask & S_IRWXUGO);
        return mask;
 }
-    
+
 asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3,
                          unsigned long arg4, unsigned long arg5)
 {
-       long error;
+       long error = 0;
 
-       error = security_task_prctl(option, arg2, arg3, arg4, arg5);
-       if (error)
+       if (security_task_prctl(option, arg2, arg3, arg4, arg5, &error))
                return error;
 
        switch (option) {
@@ -2211,23 +1684,10 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3,
                        error = PR_TIMING_STATISTICAL;
                        break;
                case PR_SET_TIMING:
-                       if (arg2 == PR_TIMING_STATISTICAL)
-                               error = 0;
-                       else
+                       if (arg2 != PR_TIMING_STATISTICAL)
                                error = -EINVAL;
                        break;
 
-               case PR_GET_KEEPCAPS:
-                       if (current->keep_capabilities)
-                               error = 1;
-                       break;
-               case PR_SET_KEEPCAPS:
-                       if (arg2 != 0 && arg2 != 1) {
-                               error = -EINVAL;
-                               break;
-                       }
-                       current->keep_capabilities = arg2;
-                       break;
                case PR_SET_NAME: {
                        struct task_struct *me = current;
                        unsigned char ncomm[sizeof(me->comm)];
@@ -2261,7 +1721,12 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3,
                case PR_SET_SECCOMP:
                        error = prctl_set_seccomp(arg2);
                        break;
-
+               case PR_GET_TSC:
+                       error = GET_TSC_CTL(arg2);
+                       break;
+               case PR_SET_TSC:
+                       error = SET_TSC_CTL(arg2);
+                       break;
                default:
                        error = -EINVAL;
                        break;
@@ -2270,7 +1735,7 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3,
 }
 
 asmlinkage long sys_getcpu(unsigned __user *cpup, unsigned __user *nodep,
-                          struct getcpu_cache __user *cache)
+                          struct getcpu_cache __user *unused)
 {
        int err = 0;
        int cpu = raw_smp_processor_id();
@@ -2278,24 +1743,6 @@ asmlinkage long sys_getcpu(unsigned __user *cpup, unsigned __user *nodep,
                err |= put_user(cpu, cpup);
        if (nodep)
                err |= put_user(cpu_to_node(cpu), nodep);
-       if (cache) {
-               /*
-                * The cache is not needed for this implementation,
-                * but make sure user programs pass something
-                * valid. vsyscall implementations can instead make
-                * good use of the cache. Only use t0 and t1 because
-                * these are available in both 32bit and 64bit ABI (no
-                * need for a compat_getcpu). 32bit has enough
-                * padding
-                */
-               unsigned long t0, t1;
-               get_user(t0, &cache->blob[0]);
-               get_user(t1, &cache->blob[1]);
-               t0++;
-               t1++;
-               put_user(t0, &cache->blob[0]);
-               put_user(t1, &cache->blob[1]);
-       }
        return err ? -EFAULT : 0;
 }
 
@@ -2331,7 +1778,7 @@ int orderly_poweroff(bool force)
                goto out;
        }
 
-       info = call_usermodehelper_setup(argv[0], argv, envp);
+       info = call_usermodehelper_setup(argv[0], argv, envp, GFP_ATOMIC);
        if (info == NULL) {
                argv_free(argv);
                goto out;