Skip to content

Commit b21f18e

Browse files
Pavankumar Kondetirafaeljw
authored andcommitted
PM: hibernate: Fix copying the zero bitmap to safe pages
The following crash is observed 100% of the time during resume from the hibernation on a x86 QEMU system. [ 12.931887] ? __die_body+0x1a/0x60 [ 12.932324] ? page_fault_oops+0x156/0x420 [ 12.932824] ? search_exception_tables+0x37/0x50 [ 12.933389] ? fixup_exception+0x21/0x300 [ 12.933889] ? exc_page_fault+0x69/0x150 [ 12.934371] ? asm_exc_page_fault+0x26/0x30 [ 12.934869] ? get_buffer.constprop.0+0xac/0x100 [ 12.935428] snapshot_write_next+0x7c/0x9f0 [ 12.935929] ? submit_bio_noacct_nocheck+0x2c2/0x370 [ 12.936530] ? submit_bio_noacct+0x44/0x2c0 [ 12.937035] ? hib_submit_io+0xa5/0x110 [ 12.937501] load_image+0x83/0x1a0 [ 12.937919] swsusp_read+0x17f/0x1d0 [ 12.938355] ? create_basic_memory_bitmaps+0x1b7/0x240 [ 12.938967] load_image_and_restore+0x45/0xc0 [ 12.939494] software_resume+0x13c/0x180 [ 12.939994] resume_store+0xa3/0x1d0 The commit being fixed introduced a bug in copying the zero bitmap to safe pages. A temporary bitmap is allocated with PG_ANY flag in prepare_image() to make a copy of zero bitmap after the unsafe pages are marked. Freeing this temporary bitmap with PG_UNSAFE_KEEP later results in an inconsistent state of unsafe pages. Since free bit is left as is for this temporary bitmap after free, these pages are treated as unsafe pages when they are allocated again. This results in incorrect calculation of the number of pages pre-allocated for the image. nr_pages = (nr_zero_pages + nr_copy_pages) - nr_highmem - allocated_unsafe_pages; The allocate_unsafe_pages is estimated to be higher than the actual which results in running short of pages in safe_pages_list. Hence the crash is observed in get_buffer() due to NULL pointer access of safe_pages_list. Fix this issue by creating the temporary zero bitmap from safe pages (free bit not set) so that the corresponding free bits can be cleared while freeing this bitmap. Fixes: 005e8dd ("PM: hibernate: don't store zero pages in the image file") Suggested-by:: Brian Geffon <bgeffon@google.com> Signed-off-by: Pavankumar Kondeti <quic_pkondeti@quicinc.com> Reviewed-by: Brian Geffon <bgeffon@google.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
1 parent 8a749fd commit b21f18e

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

kernel/power/snapshot.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2647,7 +2647,7 @@ static int prepare_image(struct memory_bitmap *new_bm, struct memory_bitmap *bm,
26472647
memory_bm_free(bm, PG_UNSAFE_KEEP);
26482648

26492649
/* Make a copy of zero_bm so it can be created in safe pages */
2650-
error = memory_bm_create(&tmp, GFP_ATOMIC, PG_ANY);
2650+
error = memory_bm_create(&tmp, GFP_ATOMIC, PG_SAFE);
26512651
if (error)
26522652
goto Free;
26532653

@@ -2660,7 +2660,7 @@ static int prepare_image(struct memory_bitmap *new_bm, struct memory_bitmap *bm,
26602660
goto Free;
26612661

26622662
duplicate_memory_bitmap(zero_bm, &tmp);
2663-
memory_bm_free(&tmp, PG_UNSAFE_KEEP);
2663+
memory_bm_free(&tmp, PG_UNSAFE_CLEAR);
26642664
/* At this point zero_bm is in safe pages and it can be used for restoring. */
26652665

26662666
if (nr_highmem > 0) {

0 commit comments

Comments
 (0)