aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sys.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sys.c')
-rw-r--r--kernel/sys.c83
1 files changed, 41 insertions, 42 deletions
diff --git a/kernel/sys.c b/kernel/sys.c
index 0b6ec0e7936f..e236f98f7ec5 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -4,7 +4,6 @@
4 * Copyright (C) 1991, 1992 Linus Torvalds 4 * Copyright (C) 1991, 1992 Linus Torvalds
5 */ 5 */
6 6
7#include <linux/config.h>
8#include <linux/module.h> 7#include <linux/module.h>
9#include <linux/mm.h> 8#include <linux/mm.h>
10#include <linux/utsname.h> 9#include <linux/utsname.h>
@@ -13,7 +12,6 @@
13#include <linux/notifier.h> 12#include <linux/notifier.h>
14#include <linux/reboot.h> 13#include <linux/reboot.h>
15#include <linux/prctl.h> 14#include <linux/prctl.h>
16#include <linux/init.h>
17#include <linux/highuid.h> 15#include <linux/highuid.h>
18#include <linux/fs.h> 16#include <linux/fs.h>
19#include <linux/kernel.h> 17#include <linux/kernel.h>
@@ -57,6 +55,12 @@
57#ifndef GET_FPEXC_CTL 55#ifndef GET_FPEXC_CTL
58# define GET_FPEXC_CTL(a,b) (-EINVAL) 56# define GET_FPEXC_CTL(a,b) (-EINVAL)
59#endif 57#endif
58#ifndef GET_ENDIAN
59# define GET_ENDIAN(a,b) (-EINVAL)
60#endif
61#ifndef SET_ENDIAN
62# define SET_ENDIAN(a,b) (-EINVAL)
63#endif
60 64
61/* 65/*
62 * this is where the system-wide overflow UID and GID are defined, for 66 * this is where the system-wide overflow UID and GID are defined, for
@@ -132,14 +136,15 @@ static int __kprobes notifier_call_chain(struct notifier_block **nl,
132 unsigned long val, void *v) 136 unsigned long val, void *v)
133{ 137{
134 int ret = NOTIFY_DONE; 138 int ret = NOTIFY_DONE;
135 struct notifier_block *nb; 139 struct notifier_block *nb, *next_nb;
136 140
137 nb = rcu_dereference(*nl); 141 nb = rcu_dereference(*nl);
138 while (nb) { 142 while (nb) {
143 next_nb = rcu_dereference(nb->next);
139 ret = nb->notifier_call(nb, val, v); 144 ret = nb->notifier_call(nb, val, v);
140 if ((ret & NOTIFY_STOP_MASK) == NOTIFY_STOP_MASK) 145 if ((ret & NOTIFY_STOP_MASK) == NOTIFY_STOP_MASK)
141 break; 146 break;
142 nb = rcu_dereference(nb->next); 147 nb = next_nb;
143 } 148 }
144 return ret; 149 return ret;
145} 150}
@@ -583,7 +588,7 @@ void emergency_restart(void)
583} 588}
584EXPORT_SYMBOL_GPL(emergency_restart); 589EXPORT_SYMBOL_GPL(emergency_restart);
585 590
586void kernel_restart_prepare(char *cmd) 591static void kernel_restart_prepare(char *cmd)
587{ 592{
588 blocking_notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd); 593 blocking_notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd);
589 system_state = SYSTEM_RESTART; 594 system_state = SYSTEM_RESTART;
@@ -617,7 +622,7 @@ EXPORT_SYMBOL_GPL(kernel_restart);
617 * Move into place and start executing a preloaded standalone 622 * Move into place and start executing a preloaded standalone
618 * executable. If nothing was preloaded return an error. 623 * executable. If nothing was preloaded return an error.
619 */ 624 */
620void kernel_kexec(void) 625static void kernel_kexec(void)
621{ 626{
622#ifdef CONFIG_KEXEC 627#ifdef CONFIG_KEXEC
623 struct kimage *image; 628 struct kimage *image;
@@ -631,7 +636,6 @@ void kernel_kexec(void)
631 machine_kexec(image); 636 machine_kexec(image);
632#endif 637#endif
633} 638}
634EXPORT_SYMBOL_GPL(kernel_kexec);
635 639
636void kernel_shutdown_prepare(enum system_states state) 640void kernel_shutdown_prepare(enum system_states state)
637{ 641{
@@ -1860,23 +1864,20 @@ out:
1860 * fields when reaping, so a sample either gets all the additions of a 1864 * fields when reaping, so a sample either gets all the additions of a
1861 * given child after it's reaped, or none so this sample is before reaping. 1865 * given child after it's reaped, or none so this sample is before reaping.
1862 * 1866 *
1863 * tasklist_lock locking optimisation: 1867 * Locking:
1864 * If we are current and single threaded, we do not need to take the tasklist 1868 * We need to take the siglock for CHILDEREN, SELF and BOTH
1865 * lock or the siglock. No one else can take our signal_struct away, 1869 * for the cases current multithreaded, non-current single threaded
1866 * no one else can reap the children to update signal->c* counters, and 1870 * non-current multithreaded. Thread traversal is now safe with
1867 * no one else can race with the signal-> fields. 1871 * the siglock held.
1868 * If we do not take the tasklist_lock, the signal-> fields could be read 1872 * Strictly speaking, we donot need to take the siglock if we are current and
1869 * out of order while another thread was just exiting. So we place a 1873 * single threaded, as no one else can take our signal_struct away, no one
1870 * read memory barrier when we avoid the lock. On the writer side, 1874 * else can reap the children to update signal->c* counters, and no one else
1871 * write memory barrier is implied in __exit_signal as __exit_signal releases 1875 * can race with the signal-> fields. If we do not take any lock, the
1872 * the siglock spinlock after updating the signal-> fields. 1876 * signal-> fields could be read out of order while another thread was just
1873 * 1877 * exiting. So we should place a read memory barrier when we avoid the lock.
1874 * We don't really need the siglock when we access the non c* fields 1878 * On the writer side, write memory barrier is implied in __exit_signal
1875 * of the signal_struct (for RUSAGE_SELF) even in multithreaded 1879 * as __exit_signal releases the siglock spinlock after updating the signal->
1876 * case, since we take the tasklist lock for read and the non c* signal-> 1880 * fields. But we don't do this yet to keep things simple.
1877 * fields are updated only in __exit_signal, which is called with
1878 * tasklist_lock taken for write, hence these two threads cannot execute
1879 * concurrently.
1880 * 1881 *
1881 */ 1882 */
1882 1883
@@ -1885,35 +1886,25 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
1885 struct task_struct *t; 1886 struct task_struct *t;
1886 unsigned long flags; 1887 unsigned long flags;
1887 cputime_t utime, stime; 1888 cputime_t utime, stime;
1888 int need_lock = 0;
1889 1889
1890 memset((char *) r, 0, sizeof *r); 1890 memset((char *) r, 0, sizeof *r);
1891 utime = stime = cputime_zero; 1891 utime = stime = cputime_zero;
1892 1892
1893 if (p != current || !thread_group_empty(p)) 1893 rcu_read_lock();
1894 need_lock = 1; 1894 if (!lock_task_sighand(p, &flags)) {
1895 1895 rcu_read_unlock();
1896 if (need_lock) { 1896 return;
1897 read_lock(&tasklist_lock); 1897 }
1898 if (unlikely(!p->signal)) {
1899 read_unlock(&tasklist_lock);
1900 return;
1901 }
1902 } else
1903 /* See locking comments above */
1904 smp_rmb();
1905 1898
1906 switch (who) { 1899 switch (who) {
1907 case RUSAGE_BOTH: 1900 case RUSAGE_BOTH:
1908 case RUSAGE_CHILDREN: 1901 case RUSAGE_CHILDREN:
1909 spin_lock_irqsave(&p->sighand->siglock, flags);
1910 utime = p->signal->cutime; 1902 utime = p->signal->cutime;
1911 stime = p->signal->cstime; 1903 stime = p->signal->cstime;
1912 r->ru_nvcsw = p->signal->cnvcsw; 1904 r->ru_nvcsw = p->signal->cnvcsw;
1913 r->ru_nivcsw = p->signal->cnivcsw; 1905 r->ru_nivcsw = p->signal->cnivcsw;
1914 r->ru_minflt = p->signal->cmin_flt; 1906 r->ru_minflt = p->signal->cmin_flt;
1915 r->ru_majflt = p->signal->cmaj_flt; 1907 r->ru_majflt = p->signal->cmaj_flt;
1916 spin_unlock_irqrestore(&p->sighand->siglock, flags);
1917 1908
1918 if (who == RUSAGE_CHILDREN) 1909 if (who == RUSAGE_CHILDREN)
1919 break; 1910 break;
@@ -1941,8 +1932,9 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
1941 BUG(); 1932 BUG();
1942 } 1933 }
1943 1934
1944 if (need_lock) 1935 unlock_task_sighand(p, &flags);
1945 read_unlock(&tasklist_lock); 1936 rcu_read_unlock();
1937
1946 cputime_to_timeval(utime, &r->ru_utime); 1938 cputime_to_timeval(utime, &r->ru_utime);
1947 cputime_to_timeval(stime, &r->ru_stime); 1939 cputime_to_timeval(stime, &r->ru_stime);
1948} 1940}
@@ -1991,7 +1983,7 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3,
1991 error = current->mm->dumpable; 1983 error = current->mm->dumpable;
1992 break; 1984 break;
1993 case PR_SET_DUMPABLE: 1985 case PR_SET_DUMPABLE:
1994 if (arg2 < 0 || arg2 > 2) { 1986 if (arg2 < 0 || arg2 > 1) {
1995 error = -EINVAL; 1987 error = -EINVAL;
1996 break; 1988 break;
1997 } 1989 }
@@ -2057,6 +2049,13 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3,
2057 return -EFAULT; 2049 return -EFAULT;
2058 return 0; 2050 return 0;
2059 } 2051 }
2052 case PR_GET_ENDIAN:
2053 error = GET_ENDIAN(current, arg2);
2054 break;
2055 case PR_SET_ENDIAN:
2056 error = SET_ENDIAN(current, arg2);
2057 break;
2058
2060 default: 2059 default:
2061 error = -EINVAL; 2060 error = -EINVAL;
2062 break; 2061 break;