diff options
Diffstat (limited to 'kernel/sys.c')
| -rw-r--r-- | kernel/sys.c | 60 |
1 files changed, 36 insertions, 24 deletions
diff --git a/kernel/sys.c b/kernel/sys.c index 255475d163e0..585d6cd10040 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
| @@ -8,7 +8,6 @@ | |||
| 8 | #include <linux/mm.h> | 8 | #include <linux/mm.h> |
| 9 | #include <linux/utsname.h> | 9 | #include <linux/utsname.h> |
| 10 | #include <linux/mman.h> | 10 | #include <linux/mman.h> |
| 11 | #include <linux/smp_lock.h> | ||
| 12 | #include <linux/notifier.h> | 11 | #include <linux/notifier.h> |
| 13 | #include <linux/reboot.h> | 12 | #include <linux/reboot.h> |
| 14 | #include <linux/prctl.h> | 13 | #include <linux/prctl.h> |
| @@ -349,6 +348,9 @@ void kernel_power_off(void) | |||
| 349 | machine_power_off(); | 348 | machine_power_off(); |
| 350 | } | 349 | } |
| 351 | EXPORT_SYMBOL_GPL(kernel_power_off); | 350 | EXPORT_SYMBOL_GPL(kernel_power_off); |
| 351 | |||
| 352 | static DEFINE_MUTEX(reboot_mutex); | ||
| 353 | |||
| 352 | /* | 354 | /* |
| 353 | * Reboot system call: for obvious reasons only root may call it, | 355 | * Reboot system call: for obvious reasons only root may call it, |
| 354 | * and even root needs to set up some magic numbers in the registers | 356 | * and even root needs to set up some magic numbers in the registers |
| @@ -381,7 +383,7 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd, | |||
| 381 | if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off) | 383 | if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off) |
| 382 | cmd = LINUX_REBOOT_CMD_HALT; | 384 | cmd = LINUX_REBOOT_CMD_HALT; |
| 383 | 385 | ||
| 384 | lock_kernel(); | 386 | mutex_lock(&reboot_mutex); |
| 385 | switch (cmd) { | 387 | switch (cmd) { |
| 386 | case LINUX_REBOOT_CMD_RESTART: | 388 | case LINUX_REBOOT_CMD_RESTART: |
| 387 | kernel_restart(NULL); | 389 | kernel_restart(NULL); |
| @@ -397,20 +399,18 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd, | |||
| 397 | 399 | ||
| 398 | case LINUX_REBOOT_CMD_HALT: | 400 | case LINUX_REBOOT_CMD_HALT: |
| 399 | kernel_halt(); | 401 | kernel_halt(); |
| 400 | unlock_kernel(); | ||
| 401 | do_exit(0); | 402 | do_exit(0); |
| 402 | panic("cannot halt"); | 403 | panic("cannot halt"); |
| 403 | 404 | ||
| 404 | case LINUX_REBOOT_CMD_POWER_OFF: | 405 | case LINUX_REBOOT_CMD_POWER_OFF: |
| 405 | kernel_power_off(); | 406 | kernel_power_off(); |
| 406 | unlock_kernel(); | ||
| 407 | do_exit(0); | 407 | do_exit(0); |
| 408 | break; | 408 | break; |
| 409 | 409 | ||
| 410 | case LINUX_REBOOT_CMD_RESTART2: | 410 | case LINUX_REBOOT_CMD_RESTART2: |
| 411 | if (strncpy_from_user(&buffer[0], arg, sizeof(buffer) - 1) < 0) { | 411 | if (strncpy_from_user(&buffer[0], arg, sizeof(buffer) - 1) < 0) { |
| 412 | unlock_kernel(); | 412 | ret = -EFAULT; |
| 413 | return -EFAULT; | 413 | break; |
| 414 | } | 414 | } |
| 415 | buffer[sizeof(buffer) - 1] = '\0'; | 415 | buffer[sizeof(buffer) - 1] = '\0'; |
| 416 | 416 | ||
| @@ -433,7 +433,7 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd, | |||
| 433 | ret = -EINVAL; | 433 | ret = -EINVAL; |
| 434 | break; | 434 | break; |
| 435 | } | 435 | } |
| 436 | unlock_kernel(); | 436 | mutex_unlock(&reboot_mutex); |
| 437 | return ret; | 437 | return ret; |
| 438 | } | 438 | } |
| 439 | 439 | ||
| @@ -911,16 +911,15 @@ change_okay: | |||
| 911 | 911 | ||
| 912 | void do_sys_times(struct tms *tms) | 912 | void do_sys_times(struct tms *tms) |
| 913 | { | 913 | { |
| 914 | struct task_cputime cputime; | 914 | cputime_t tgutime, tgstime, cutime, cstime; |
| 915 | cputime_t cutime, cstime; | ||
| 916 | 915 | ||
| 917 | thread_group_cputime(current, &cputime); | ||
| 918 | spin_lock_irq(¤t->sighand->siglock); | 916 | spin_lock_irq(¤t->sighand->siglock); |
| 917 | thread_group_times(current, &tgutime, &tgstime); | ||
| 919 | cutime = current->signal->cutime; | 918 | cutime = current->signal->cutime; |
| 920 | cstime = current->signal->cstime; | 919 | cstime = current->signal->cstime; |
| 921 | spin_unlock_irq(¤t->sighand->siglock); | 920 | spin_unlock_irq(¤t->sighand->siglock); |
| 922 | tms->tms_utime = cputime_to_clock_t(cputime.utime); | 921 | tms->tms_utime = cputime_to_clock_t(tgutime); |
| 923 | tms->tms_stime = cputime_to_clock_t(cputime.stime); | 922 | tms->tms_stime = cputime_to_clock_t(tgstime); |
| 924 | tms->tms_cutime = cputime_to_clock_t(cutime); | 923 | tms->tms_cutime = cputime_to_clock_t(cutime); |
| 925 | tms->tms_cstime = cputime_to_clock_t(cstime); | 924 | tms->tms_cstime = cputime_to_clock_t(cstime); |
| 926 | } | 925 | } |
| @@ -1110,6 +1109,8 @@ SYSCALL_DEFINE0(setsid) | |||
| 1110 | err = session; | 1109 | err = session; |
| 1111 | out: | 1110 | out: |
| 1112 | write_unlock_irq(&tasklist_lock); | 1111 | write_unlock_irq(&tasklist_lock); |
| 1112 | if (err > 0) | ||
| 1113 | proc_sid_connector(group_leader); | ||
| 1113 | return err; | 1114 | return err; |
| 1114 | } | 1115 | } |
| 1115 | 1116 | ||
| @@ -1336,16 +1337,14 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r) | |||
| 1336 | { | 1337 | { |
| 1337 | struct task_struct *t; | 1338 | struct task_struct *t; |
| 1338 | unsigned long flags; | 1339 | unsigned long flags; |
| 1339 | cputime_t utime, stime; | 1340 | cputime_t tgutime, tgstime, utime, stime; |
| 1340 | struct task_cputime cputime; | ||
| 1341 | unsigned long maxrss = 0; | 1341 | unsigned long maxrss = 0; |
| 1342 | 1342 | ||
| 1343 | memset((char *) r, 0, sizeof *r); | 1343 | memset((char *) r, 0, sizeof *r); |
| 1344 | utime = stime = cputime_zero; | 1344 | utime = stime = cputime_zero; |
| 1345 | 1345 | ||
| 1346 | if (who == RUSAGE_THREAD) { | 1346 | if (who == RUSAGE_THREAD) { |
| 1347 | utime = task_utime(current); | 1347 | task_times(current, &utime, &stime); |
| 1348 | stime = task_stime(current); | ||
| 1349 | accumulate_thread_rusage(p, r); | 1348 | accumulate_thread_rusage(p, r); |
| 1350 | maxrss = p->signal->maxrss; | 1349 | maxrss = p->signal->maxrss; |
| 1351 | goto out; | 1350 | goto out; |
| @@ -1371,9 +1370,9 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r) | |||
| 1371 | break; | 1370 | break; |
| 1372 | 1371 | ||
| 1373 | case RUSAGE_SELF: | 1372 | case RUSAGE_SELF: |
| 1374 | thread_group_cputime(p, &cputime); | 1373 | thread_group_times(p, &tgutime, &tgstime); |
| 1375 | utime = cputime_add(utime, cputime.utime); | 1374 | utime = cputime_add(utime, tgutime); |
| 1376 | stime = cputime_add(stime, cputime.stime); | 1375 | stime = cputime_add(stime, tgstime); |
| 1377 | r->ru_nvcsw += p->signal->nvcsw; | 1376 | r->ru_nvcsw += p->signal->nvcsw; |
| 1378 | r->ru_nivcsw += p->signal->nivcsw; | 1377 | r->ru_nivcsw += p->signal->nivcsw; |
| 1379 | r->ru_minflt += p->signal->min_flt; | 1378 | r->ru_minflt += p->signal->min_flt; |
| @@ -1546,24 +1545,37 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, | |||
| 1546 | if (arg4 | arg5) | 1545 | if (arg4 | arg5) |
| 1547 | return -EINVAL; | 1546 | return -EINVAL; |
| 1548 | switch (arg2) { | 1547 | switch (arg2) { |
| 1549 | case 0: | 1548 | case PR_MCE_KILL_CLEAR: |
| 1550 | if (arg3 != 0) | 1549 | if (arg3 != 0) |
| 1551 | return -EINVAL; | 1550 | return -EINVAL; |
| 1552 | current->flags &= ~PF_MCE_PROCESS; | 1551 | current->flags &= ~PF_MCE_PROCESS; |
| 1553 | break; | 1552 | break; |
| 1554 | case 1: | 1553 | case PR_MCE_KILL_SET: |
| 1555 | current->flags |= PF_MCE_PROCESS; | 1554 | current->flags |= PF_MCE_PROCESS; |
| 1556 | if (arg3 != 0) | 1555 | if (arg3 == PR_MCE_KILL_EARLY) |
| 1557 | current->flags |= PF_MCE_EARLY; | 1556 | current->flags |= PF_MCE_EARLY; |
| 1558 | else | 1557 | else if (arg3 == PR_MCE_KILL_LATE) |
| 1559 | current->flags &= ~PF_MCE_EARLY; | 1558 | current->flags &= ~PF_MCE_EARLY; |
| 1559 | else if (arg3 == PR_MCE_KILL_DEFAULT) | ||
| 1560 | current->flags &= | ||
| 1561 | ~(PF_MCE_EARLY|PF_MCE_PROCESS); | ||
| 1562 | else | ||
| 1563 | return -EINVAL; | ||
| 1560 | break; | 1564 | break; |
| 1561 | default: | 1565 | default: |
| 1562 | return -EINVAL; | 1566 | return -EINVAL; |
| 1563 | } | 1567 | } |
| 1564 | error = 0; | 1568 | error = 0; |
| 1565 | break; | 1569 | break; |
| 1566 | 1570 | case PR_MCE_KILL_GET: | |
| 1571 | if (arg2 | arg3 | arg4 | arg5) | ||
| 1572 | return -EINVAL; | ||
| 1573 | if (current->flags & PF_MCE_PROCESS) | ||
| 1574 | error = (current->flags & PF_MCE_EARLY) ? | ||
| 1575 | PR_MCE_KILL_EARLY : PR_MCE_KILL_LATE; | ||
| 1576 | else | ||
| 1577 | error = PR_MCE_KILL_DEFAULT; | ||
| 1578 | break; | ||
| 1567 | default: | 1579 | default: |
| 1568 | error = -EINVAL; | 1580 | error = -EINVAL; |
| 1569 | break; | 1581 | break; |
