diff options
| author | Russell King <rmk@flint.arm.linux.org.uk> | 2004-09-20 20:22:26 +0100 |
|---|---|---|
| committer | Russell King <rmk@flint.arm.linux.org.uk> | 2004-09-20 20:22:26 +0100 |
| commit | efb4cd1196d066f8c345f1935c53246db7641c8a (patch) | |
| tree | b7d0438b9ccf9f4e129e5ee70dd1a831564b6cd5 /arch | |
| parent | e7f10a52f7682ddf818bd793b56a587aae1bc160 (diff) | |
[ARM] Prevent state machine leakage in ARM APM emulation.
Don't allow threads which are acking a suspend request to leave
the APM ioctl call. This prevents the state machine breaking.
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/arm/kernel/apm.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/arch/arm/kernel/apm.c b/arch/arm/kernel/apm.c index 267f6971082e..70aade05b50d 100644 --- a/arch/arm/kernel/apm.c +++ b/arch/arm/kernel/apm.c @@ -202,7 +202,7 @@ static void apm_suspend(void) } up_read(&user_list_lock); - wake_up_interruptible(&apm_suspend_waitqueue); + wake_up(&apm_suspend_waitqueue); } static ssize_t apm_read(struct file *fp, char __user *buf, size_t count, loff_t *ppos) @@ -306,7 +306,15 @@ apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg) flags = current->flags; current->flags |= PF_NOFREEZE; - wait_event_interruptible(apm_suspend_waitqueue, + /* + * Note: do not allow a thread which is acking the suspend + * to escape until the resume is complete. + */ + if (as->suspend_state == SUSPEND_ACKED) + wait_event(apm_suspend_waitqueue, + as->suspend_state == SUSPEND_DONE); + else + wait_event_interruptible(apm_suspend_waitqueue, as->suspend_state == SUSPEND_DONE); current->flags = flags; |
