diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2006-07-10 07:45:00 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-07-10 16:24:22 -0400 |
commit | 95018f7c94cbe4e78fc014b6ce52004714c06e2a (patch) | |
tree | 2f8434103bc670813120e6d64b1726301a6021ac /kernel/power/snapshot.c | |
parent | 7ba1c6c88c945b065a75094830f6b76f414e42ad (diff) |
[PATCH] swsusp: do not use memcpy for snapshotting memory
swsusp should not use memcpy for snapshotting memory, because on some
architectures memcpy may increase preempt_count (i386 does this when
CONFIG_X86_USE_3DNOW is set). Then, as a result, wrong value of preempt_count
is stored in the image.
Replace memcpy in copy_data_pages with an open-coded loop.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel/power/snapshot.c')
-rw-r--r-- | kernel/power/snapshot.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index 24c96f354231..75d4886e648e 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c | |||
@@ -227,11 +227,17 @@ static void copy_data_pages(struct pbe *pblist) | |||
227 | for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn) { | 227 | for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn) { |
228 | if (saveable(zone, &zone_pfn)) { | 228 | if (saveable(zone, &zone_pfn)) { |
229 | struct page *page; | 229 | struct page *page; |
230 | long *src, *dst; | ||
231 | int n; | ||
232 | |||
230 | page = pfn_to_page(zone_pfn + zone->zone_start_pfn); | 233 | page = pfn_to_page(zone_pfn + zone->zone_start_pfn); |
231 | BUG_ON(!pbe); | 234 | BUG_ON(!pbe); |
232 | pbe->orig_address = (unsigned long)page_address(page); | 235 | pbe->orig_address = (unsigned long)page_address(page); |
233 | /* copy_page is not usable for copying task structs. */ | 236 | /* copy_page and memcpy are not usable for copying task structs. */ |
234 | memcpy((void *)pbe->address, (void *)pbe->orig_address, PAGE_SIZE); | 237 | dst = (long *)pbe->address; |
238 | src = (long *)pbe->orig_address; | ||
239 | for (n = PAGE_SIZE / sizeof(long); n; n--) | ||
240 | *dst++ = *src++; | ||
235 | pbe = pbe->next; | 241 | pbe = pbe->next; |
236 | } | 242 | } |
237 | } | 243 | } |