diff options
Diffstat (limited to 'kernel/sys.c')
| -rw-r--r-- | kernel/sys.c | 45 |
1 files changed, 37 insertions, 8 deletions
diff --git a/kernel/sys.c b/kernel/sys.c index 90930b28d2ca..b88806c66244 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> |
| @@ -29,6 +28,7 @@ | |||
| 29 | #include <linux/tty.h> | 28 | #include <linux/tty.h> |
| 30 | #include <linux/signal.h> | 29 | #include <linux/signal.h> |
| 31 | #include <linux/cn_proc.h> | 30 | #include <linux/cn_proc.h> |
| 31 | #include <linux/getcpu.h> | ||
| 32 | 32 | ||
| 33 | #include <linux/compat.h> | 33 | #include <linux/compat.h> |
| 34 | #include <linux/syscalls.h> | 34 | #include <linux/syscalls.h> |
| @@ -137,14 +137,15 @@ static int __kprobes notifier_call_chain(struct notifier_block **nl, | |||
| 137 | unsigned long val, void *v) | 137 | unsigned long val, void *v) |
| 138 | { | 138 | { |
| 139 | int ret = NOTIFY_DONE; | 139 | int ret = NOTIFY_DONE; |
| 140 | struct notifier_block *nb; | 140 | struct notifier_block *nb, *next_nb; |
| 141 | 141 | ||
| 142 | nb = rcu_dereference(*nl); | 142 | nb = rcu_dereference(*nl); |
| 143 | while (nb) { | 143 | while (nb) { |
| 144 | next_nb = rcu_dereference(nb->next); | ||
| 144 | ret = nb->notifier_call(nb, val, v); | 145 | ret = nb->notifier_call(nb, val, v); |
| 145 | if ((ret & NOTIFY_STOP_MASK) == NOTIFY_STOP_MASK) | 146 | if ((ret & NOTIFY_STOP_MASK) == NOTIFY_STOP_MASK) |
| 146 | break; | 147 | break; |
| 147 | nb = rcu_dereference(nb->next); | 148 | nb = next_nb; |
| 148 | } | 149 | } |
| 149 | return ret; | 150 | return ret; |
| 150 | } | 151 | } |
| @@ -588,7 +589,7 @@ void emergency_restart(void) | |||
| 588 | } | 589 | } |
| 589 | EXPORT_SYMBOL_GPL(emergency_restart); | 590 | EXPORT_SYMBOL_GPL(emergency_restart); |
| 590 | 591 | ||
| 591 | void kernel_restart_prepare(char *cmd) | 592 | static void kernel_restart_prepare(char *cmd) |
| 592 | { | 593 | { |
| 593 | blocking_notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd); | 594 | blocking_notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd); |
| 594 | system_state = SYSTEM_RESTART; | 595 | system_state = SYSTEM_RESTART; |
| @@ -611,7 +612,6 @@ void kernel_restart(char *cmd) | |||
| 611 | } else { | 612 | } else { |
| 612 | printk(KERN_EMERG "Restarting system with command '%s'.\n", cmd); | 613 | printk(KERN_EMERG "Restarting system with command '%s'.\n", cmd); |
| 613 | } | 614 | } |
| 614 | printk(".\n"); | ||
| 615 | machine_restart(cmd); | 615 | machine_restart(cmd); |
| 616 | } | 616 | } |
| 617 | EXPORT_SYMBOL_GPL(kernel_restart); | 617 | EXPORT_SYMBOL_GPL(kernel_restart); |
| @@ -622,7 +622,7 @@ EXPORT_SYMBOL_GPL(kernel_restart); | |||
| 622 | * Move into place and start executing a preloaded standalone | 622 | * Move into place and start executing a preloaded standalone |
| 623 | * executable. If nothing was preloaded return an error. | 623 | * executable. If nothing was preloaded return an error. |
| 624 | */ | 624 | */ |
| 625 | void kernel_kexec(void) | 625 | static void kernel_kexec(void) |
| 626 | { | 626 | { |
| 627 | #ifdef CONFIG_KEXEC | 627 | #ifdef CONFIG_KEXEC |
| 628 | struct kimage *image; | 628 | struct kimage *image; |
| @@ -636,7 +636,6 @@ void kernel_kexec(void) | |||
| 636 | machine_kexec(image); | 636 | machine_kexec(image); |
| 637 | #endif | 637 | #endif |
| 638 | } | 638 | } |
| 639 | EXPORT_SYMBOL_GPL(kernel_kexec); | ||
| 640 | 639 | ||
| 641 | void kernel_shutdown_prepare(enum system_states state) | 640 | void kernel_shutdown_prepare(enum system_states state) |
| 642 | { | 641 | { |
| @@ -1984,7 +1983,7 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, | |||
| 1984 | error = current->mm->dumpable; | 1983 | error = current->mm->dumpable; |
| 1985 | break; | 1984 | break; |
| 1986 | case PR_SET_DUMPABLE: | 1985 | case PR_SET_DUMPABLE: |
| 1987 | if (arg2 < 0 || arg2 > 2) { | 1986 | if (arg2 < 0 || arg2 > 1) { |
| 1988 | error = -EINVAL; | 1987 | error = -EINVAL; |
| 1989 | break; | 1988 | break; |
| 1990 | } | 1989 | } |
| @@ -2063,3 +2062,33 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, | |||
| 2063 | } | 2062 | } |
| 2064 | return error; | 2063 | return error; |
| 2065 | } | 2064 | } |
| 2065 | |||
| 2066 | asmlinkage long sys_getcpu(unsigned __user *cpup, unsigned __user *nodep, | ||
| 2067 | struct getcpu_cache __user *cache) | ||
| 2068 | { | ||
| 2069 | int err = 0; | ||
| 2070 | int cpu = raw_smp_processor_id(); | ||
| 2071 | if (cpup) | ||
| 2072 | err |= put_user(cpu, cpup); | ||
| 2073 | if (nodep) | ||
| 2074 | err |= put_user(cpu_to_node(cpu), nodep); | ||
| 2075 | if (cache) { | ||
| 2076 | /* | ||
| 2077 | * The cache is not needed for this implementation, | ||
| 2078 | * but make sure user programs pass something | ||
| 2079 | * valid. vsyscall implementations can instead make | ||
| 2080 | * good use of the cache. Only use t0 and t1 because | ||
| 2081 | * these are available in both 32bit and 64bit ABI (no | ||
| 2082 | * need for a compat_getcpu). 32bit has enough | ||
| 2083 | * padding | ||
| 2084 | */ | ||
| 2085 | unsigned long t0, t1; | ||
| 2086 | get_user(t0, &cache->blob[0]); | ||
| 2087 | get_user(t1, &cache->blob[1]); | ||
| 2088 | t0++; | ||
| 2089 | t1++; | ||
| 2090 | put_user(t0, &cache->blob[0]); | ||
| 2091 | put_user(t1, &cache->blob[1]); | ||
| 2092 | } | ||
| 2093 | return err ? -EFAULT : 0; | ||
| 2094 | } | ||
