From 5bd0190bf3d7e53043a048e809ffa29d41b9d6ac Mon Sep 17 00:00:00 2001 From: David Gibson Date: Tue, 29 Nov 2005 19:34:32 -0800 Subject: [PATCH] Fix crash when ptrace poking hugepage areas set_page_dirty() will not cope with being handed a page * which is part of a compound page, but not the master page in that compound page. This case can occur via access_process_vm() if you attemp to write to another process's hugepage memory area using ptrace() (causing an oops or hang). This patch fixes the bug by only calling set_page_dirty() from access_process_vm() if the page is not a compound page. We already use a similar fix in bio_set_pages_dirty() for the case of direct io to hugepages. Signed-off-by: David Gibson Acked-by: William Irwin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/ptrace.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 17ee7e5a3451..656476eedb1b 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -241,7 +241,8 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, in if (write) { copy_to_user_page(vma, page, addr, maddr + offset, buf, bytes); - set_page_dirty_lock(page); + if (!PageCompound(page)) + set_page_dirty_lock(page); } else { copy_from_user_page(vma, page, addr, buf, maddr + offset, bytes); -- cgit v1.2.3 From 123d3c13e2853a11b4d599d754b356acb12886e2 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Tue, 29 Nov 2005 19:34:37 -0800 Subject: [PATCH] fix swsusp on machines not supporting S4 Fix swsusp on machines not supporting S4. With recent changes, it is not possible to trigger it using /sys filesystem. Swsusp does not really need any support from low-level code, it is possible to reboot or halt at the end of suspend. Signed-off-by: Pavel Machek Cc: "Brown, Len" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/power/main.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'kernel') diff --git a/kernel/power/main.c b/kernel/power/main.c index 6ee2cad530e8..d253f3ae2fa5 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -24,7 +24,7 @@ DECLARE_MUTEX(pm_sem); -struct pm_ops * pm_ops = NULL; +struct pm_ops *pm_ops; suspend_disk_method_t pm_disk_mode = PM_DISK_SHUTDOWN; /** @@ -151,6 +151,18 @@ static char *pm_states[PM_SUSPEND_MAX] = { #endif }; +static inline int valid_state(suspend_state_t state) +{ + /* Suspend-to-disk does not really need low-level support. + * It can work with reboot if needed. */ + if (state == PM_SUSPEND_DISK) + return 1; + + if (pm_ops && pm_ops->valid && !pm_ops->valid(state)) + return 0; + return 1; +} + /** * enter_state - Do common work of entering low-power state. @@ -167,7 +179,7 @@ static int enter_state(suspend_state_t state) { int error; - if (pm_ops && pm_ops->valid && !pm_ops->valid(state)) + if (!valid_state(state)) return -ENODEV; if (down_trylock(&pm_sem)) return -EBUSY; @@ -238,9 +250,8 @@ static ssize_t state_show(struct subsystem * subsys, char * buf) char * s = buf; for (i = 0; i < PM_SUSPEND_MAX; i++) { - if (pm_states[i] && pm_ops && (!pm_ops->valid - ||(pm_ops->valid && pm_ops->valid(i)))) - s += sprintf(s,"%s ",pm_states[i]); + if (pm_states[i] && valid_state(i)) + s += sprintf(s,"%s ", pm_states[i]); } s += sprintf(s,"\n"); return (s - buf); -- cgit v1.2.3