diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/kexec.c | 7 | ||||
| -rw-r--r-- | kernel/power/disk.c | 11 | ||||
| -rw-r--r-- | kernel/power/main.c | 8 | ||||
| -rw-r--r-- | kernel/seccomp.c | 7 | ||||
| -rw-r--r-- | kernel/user_namespace.c | 21 |
5 files changed, 45 insertions, 9 deletions
diff --git a/kernel/kexec.c b/kernel/kexec.c index 8a6d7b08864e..483899578259 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c | |||
| @@ -1465,6 +1465,11 @@ int kernel_kexec(void) | |||
| 1465 | error = device_power_down(PMSG_FREEZE); | 1465 | error = device_power_down(PMSG_FREEZE); |
| 1466 | if (error) | 1466 | if (error) |
| 1467 | goto Enable_irqs; | 1467 | goto Enable_irqs; |
| 1468 | |||
| 1469 | /* Suspend system devices */ | ||
| 1470 | error = sysdev_suspend(PMSG_FREEZE); | ||
| 1471 | if (error) | ||
| 1472 | goto Power_up_devices; | ||
| 1468 | } else | 1473 | } else |
| 1469 | #endif | 1474 | #endif |
| 1470 | { | 1475 | { |
| @@ -1477,6 +1482,8 @@ int kernel_kexec(void) | |||
| 1477 | 1482 | ||
| 1478 | #ifdef CONFIG_KEXEC_JUMP | 1483 | #ifdef CONFIG_KEXEC_JUMP |
| 1479 | if (kexec_image->preserve_context) { | 1484 | if (kexec_image->preserve_context) { |
| 1485 | sysdev_resume(); | ||
| 1486 | Power_up_devices: | ||
| 1480 | device_power_up(PMSG_RESTORE); | 1487 | device_power_up(PMSG_RESTORE); |
| 1481 | Enable_irqs: | 1488 | Enable_irqs: |
| 1482 | local_irq_enable(); | 1489 | local_irq_enable(); |
diff --git a/kernel/power/disk.c b/kernel/power/disk.c index 7b40e94b1d42..4a4a206b1979 100644 --- a/kernel/power/disk.c +++ b/kernel/power/disk.c | |||
| @@ -227,6 +227,12 @@ static int create_image(int platform_mode) | |||
| 227 | "aborting hibernation\n"); | 227 | "aborting hibernation\n"); |
| 228 | goto Enable_irqs; | 228 | goto Enable_irqs; |
| 229 | } | 229 | } |
| 230 | sysdev_suspend(PMSG_FREEZE); | ||
| 231 | if (error) { | ||
| 232 | printk(KERN_ERR "PM: Some devices failed to power down, " | ||
| 233 | "aborting hibernation\n"); | ||
| 234 | goto Power_up_devices; | ||
| 235 | } | ||
| 230 | 236 | ||
| 231 | if (hibernation_test(TEST_CORE)) | 237 | if (hibernation_test(TEST_CORE)) |
| 232 | goto Power_up; | 238 | goto Power_up; |
| @@ -242,9 +248,11 @@ static int create_image(int platform_mode) | |||
| 242 | if (!in_suspend) | 248 | if (!in_suspend) |
| 243 | platform_leave(platform_mode); | 249 | platform_leave(platform_mode); |
| 244 | Power_up: | 250 | Power_up: |
| 251 | sysdev_resume(); | ||
| 245 | /* NOTE: device_power_up() is just a resume() for devices | 252 | /* NOTE: device_power_up() is just a resume() for devices |
| 246 | * that suspended with irqs off ... no overall powerup. | 253 | * that suspended with irqs off ... no overall powerup. |
| 247 | */ | 254 | */ |
| 255 | Power_up_devices: | ||
| 248 | device_power_up(in_suspend ? | 256 | device_power_up(in_suspend ? |
| 249 | (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE); | 257 | (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE); |
| 250 | Enable_irqs: | 258 | Enable_irqs: |
| @@ -335,6 +343,7 @@ static int resume_target_kernel(void) | |||
| 335 | "aborting resume\n"); | 343 | "aborting resume\n"); |
| 336 | goto Enable_irqs; | 344 | goto Enable_irqs; |
| 337 | } | 345 | } |
| 346 | sysdev_suspend(PMSG_QUIESCE); | ||
| 338 | /* We'll ignore saved state, but this gets preempt count (etc) right */ | 347 | /* We'll ignore saved state, but this gets preempt count (etc) right */ |
| 339 | save_processor_state(); | 348 | save_processor_state(); |
| 340 | error = restore_highmem(); | 349 | error = restore_highmem(); |
| @@ -357,6 +366,7 @@ static int resume_target_kernel(void) | |||
| 357 | swsusp_free(); | 366 | swsusp_free(); |
| 358 | restore_processor_state(); | 367 | restore_processor_state(); |
| 359 | touch_softlockup_watchdog(); | 368 | touch_softlockup_watchdog(); |
| 369 | sysdev_resume(); | ||
| 360 | device_power_up(PMSG_RECOVER); | 370 | device_power_up(PMSG_RECOVER); |
| 361 | Enable_irqs: | 371 | Enable_irqs: |
| 362 | local_irq_enable(); | 372 | local_irq_enable(); |
| @@ -440,6 +450,7 @@ int hibernation_platform_enter(void) | |||
| 440 | local_irq_disable(); | 450 | local_irq_disable(); |
| 441 | error = device_power_down(PMSG_HIBERNATE); | 451 | error = device_power_down(PMSG_HIBERNATE); |
| 442 | if (!error) { | 452 | if (!error) { |
| 453 | sysdev_suspend(PMSG_HIBERNATE); | ||
| 443 | hibernation_ops->enter(); | 454 | hibernation_ops->enter(); |
| 444 | /* We should never get here */ | 455 | /* We should never get here */ |
| 445 | while (1); | 456 | while (1); |
diff --git a/kernel/power/main.c b/kernel/power/main.c index b4d219016b6c..c9632f841f64 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c | |||
| @@ -298,8 +298,12 @@ static int suspend_enter(suspend_state_t state) | |||
| 298 | goto Done; | 298 | goto Done; |
| 299 | } | 299 | } |
| 300 | 300 | ||
| 301 | if (!suspend_test(TEST_CORE)) | 301 | error = sysdev_suspend(PMSG_SUSPEND); |
| 302 | error = suspend_ops->enter(state); | 302 | if (!error) { |
| 303 | if (!suspend_test(TEST_CORE)) | ||
| 304 | error = suspend_ops->enter(state); | ||
| 305 | sysdev_resume(); | ||
| 306 | } | ||
| 303 | 307 | ||
| 304 | device_power_up(PMSG_RESUME); | 308 | device_power_up(PMSG_RESUME); |
| 305 | Done: | 309 | Done: |
diff --git a/kernel/seccomp.c b/kernel/seccomp.c index ad64fcb731f2..57d4b13b631d 100644 --- a/kernel/seccomp.c +++ b/kernel/seccomp.c | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | 8 | ||
| 9 | #include <linux/seccomp.h> | 9 | #include <linux/seccomp.h> |
| 10 | #include <linux/sched.h> | 10 | #include <linux/sched.h> |
| 11 | #include <linux/compat.h> | ||
| 11 | 12 | ||
| 12 | /* #define SECCOMP_DEBUG 1 */ | 13 | /* #define SECCOMP_DEBUG 1 */ |
| 13 | #define NR_SECCOMP_MODES 1 | 14 | #define NR_SECCOMP_MODES 1 |
| @@ -22,7 +23,7 @@ static int mode1_syscalls[] = { | |||
| 22 | 0, /* null terminated */ | 23 | 0, /* null terminated */ |
| 23 | }; | 24 | }; |
| 24 | 25 | ||
| 25 | #ifdef TIF_32BIT | 26 | #ifdef CONFIG_COMPAT |
| 26 | static int mode1_syscalls_32[] = { | 27 | static int mode1_syscalls_32[] = { |
| 27 | __NR_seccomp_read_32, __NR_seccomp_write_32, __NR_seccomp_exit_32, __NR_seccomp_sigreturn_32, | 28 | __NR_seccomp_read_32, __NR_seccomp_write_32, __NR_seccomp_exit_32, __NR_seccomp_sigreturn_32, |
| 28 | 0, /* null terminated */ | 29 | 0, /* null terminated */ |
| @@ -37,8 +38,8 @@ void __secure_computing(int this_syscall) | |||
| 37 | switch (mode) { | 38 | switch (mode) { |
| 38 | case 1: | 39 | case 1: |
| 39 | syscall = mode1_syscalls; | 40 | syscall = mode1_syscalls; |
| 40 | #ifdef TIF_32BIT | 41 | #ifdef CONFIG_COMPAT |
| 41 | if (test_thread_flag(TIF_32BIT)) | 42 | if (is_compat_task()) |
| 42 | syscall = mode1_syscalls_32; | 43 | syscall = mode1_syscalls_32; |
| 43 | #endif | 44 | #endif |
| 44 | do { | 45 | do { |
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c index 79084311ee57..076c7c8215b0 100644 --- a/kernel/user_namespace.c +++ b/kernel/user_namespace.c | |||
| @@ -60,12 +60,25 @@ int create_user_ns(struct cred *new) | |||
| 60 | return 0; | 60 | return 0; |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | void free_user_ns(struct kref *kref) | 63 | /* |
| 64 | * Deferred destructor for a user namespace. This is required because | ||
| 65 | * free_user_ns() may be called with uidhash_lock held, but we need to call | ||
| 66 | * back to free_uid() which will want to take the lock again. | ||
| 67 | */ | ||
| 68 | static void free_user_ns_work(struct work_struct *work) | ||
| 64 | { | 69 | { |
| 65 | struct user_namespace *ns; | 70 | struct user_namespace *ns = |
| 66 | 71 | container_of(work, struct user_namespace, destroyer); | |
| 67 | ns = container_of(kref, struct user_namespace, kref); | ||
| 68 | free_uid(ns->creator); | 72 | free_uid(ns->creator); |
| 69 | kfree(ns); | 73 | kfree(ns); |
| 70 | } | 74 | } |
| 75 | |||
| 76 | void free_user_ns(struct kref *kref) | ||
| 77 | { | ||
| 78 | struct user_namespace *ns = | ||
| 79 | container_of(kref, struct user_namespace, kref); | ||
| 80 | |||
| 81 | INIT_WORK(&ns->destroyer, free_user_ns_work); | ||
| 82 | schedule_work(&ns->destroyer); | ||
| 83 | } | ||
| 71 | EXPORT_SYMBOL(free_user_ns); | 84 | EXPORT_SYMBOL(free_user_ns); |
