static int saveable(unsigned long * pfn) { struct page * page = pfn_to_page(*pfn); if (PageNosave(page)) return 0; if (!PageReserved(page)) { int chunk_size; if ((chunk_size = is_head_of_free_region(page))) { *pfn += chunk_size - 1; return 0; } } else if (PageReserved(page)) { /* Just copy whole code segment. * Hopefully it is not that big. */ if ((ADDRESS(*pfn) >= (unsigned long) ADDRESS2(&__nosave_begin)) && (ADDRESS(*pfn) < (unsigned long) ADDRESS2(&__nosave_end))) { pr_debug("[nosave %lx]\n", ADDRESS(*pfn)); return 0; } /* Hmm, perhaps copying all reserved pages is not * too healthy as they may contain * critical bios data? */ } return 1; }
/* if pagedir_p != NULL it also copies the counted pages */ static int count_and_copy_data_pages(struct pbe *pagedir_p) { int chunk_size; int nr_copy_pages = 0; int pfn; struct page *page; #ifdef CONFIG_DISCONTIGMEM panic("Discontingmem not supported"); #else BUG_ON (max_pfn != num_physpages); #endif for (pfn = 0; pfn < max_pfn; pfn++) { page = pfn_to_page(pfn); if (PageHighMem(page)) panic("Swsusp not supported on highmem boxes. Send 1GB of RAM to <*****@*****.**> and try again ;-)."); if (!PageReserved(page)) { if (PageNosave(page)) continue; if ((chunk_size=is_head_of_free_region(page))!=0) { pfn += chunk_size - 1; continue; } } else if (PageReserved(page)) { BUG_ON (PageNosave(page)); /* * Just copy whole code segment. Hopefully it is not that big. */ if ((ADDRESS(pfn) >= (unsigned long) ADDRESS2(&__nosave_begin)) && (ADDRESS(pfn) < (unsigned long) ADDRESS2(&__nosave_end))) { PRINTK("[nosave %lx]", ADDRESS(pfn)); continue; } /* Hmm, perhaps copying all reserved pages is not too healthy as they may contain critical bios data? */ } else BUG(); nr_copy_pages++; if (pagedir_p) { pagedir_p->orig_address = ADDRESS(pfn); copy_page((void *) pagedir_p->address, (void *) pagedir_p->orig_address); pagedir_p++; } } return nr_copy_pages; }