diff options
Diffstat (limited to 'kernel/power/snapshot.c')
-rw-r--r-- | kernel/power/snapshot.c | 62 |
1 files changed, 40 insertions, 22 deletions
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index a686590d88c1..78039b477d2b 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c | |||
@@ -1005,11 +1005,12 @@ copy_data_pages(struct memory_bitmap *copy_bm, struct memory_bitmap *orig_bm) | |||
1005 | } | 1005 | } |
1006 | memory_bm_position_reset(orig_bm); | 1006 | memory_bm_position_reset(orig_bm); |
1007 | memory_bm_position_reset(copy_bm); | 1007 | memory_bm_position_reset(copy_bm); |
1008 | do { | 1008 | for(;;) { |
1009 | pfn = memory_bm_next_pfn(orig_bm); | 1009 | pfn = memory_bm_next_pfn(orig_bm); |
1010 | if (likely(pfn != BM_END_OF_MAP)) | 1010 | if (unlikely(pfn == BM_END_OF_MAP)) |
1011 | copy_data_page(memory_bm_next_pfn(copy_bm), pfn); | 1011 | break; |
1012 | } while (pfn != BM_END_OF_MAP); | 1012 | copy_data_page(memory_bm_next_pfn(copy_bm), pfn); |
1013 | } | ||
1013 | } | 1014 | } |
1014 | 1015 | ||
1015 | /* Total number of image pages */ | 1016 | /* Total number of image pages */ |
@@ -1239,17 +1240,39 @@ asmlinkage int swsusp_save(void) | |||
1239 | return 0; | 1240 | return 0; |
1240 | } | 1241 | } |
1241 | 1242 | ||
1242 | static void init_header(struct swsusp_info *info) | 1243 | #ifndef CONFIG_ARCH_HIBERNATION_HEADER |
1244 | static int init_header_complete(struct swsusp_info *info) | ||
1243 | { | 1245 | { |
1244 | memset(info, 0, sizeof(struct swsusp_info)); | 1246 | memcpy(&info->uts, init_utsname(), sizeof(struct new_utsname)); |
1245 | info->version_code = LINUX_VERSION_CODE; | 1247 | info->version_code = LINUX_VERSION_CODE; |
1248 | return 0; | ||
1249 | } | ||
1250 | |||
1251 | static char *check_image_kernel(struct swsusp_info *info) | ||
1252 | { | ||
1253 | if (info->version_code != LINUX_VERSION_CODE) | ||
1254 | return "kernel version"; | ||
1255 | if (strcmp(info->uts.sysname,init_utsname()->sysname)) | ||
1256 | return "system type"; | ||
1257 | if (strcmp(info->uts.release,init_utsname()->release)) | ||
1258 | return "kernel release"; | ||
1259 | if (strcmp(info->uts.version,init_utsname()->version)) | ||
1260 | return "version"; | ||
1261 | if (strcmp(info->uts.machine,init_utsname()->machine)) | ||
1262 | return "machine"; | ||
1263 | return NULL; | ||
1264 | } | ||
1265 | #endif /* CONFIG_ARCH_HIBERNATION_HEADER */ | ||
1266 | |||
1267 | static int init_header(struct swsusp_info *info) | ||
1268 | { | ||
1269 | memset(info, 0, sizeof(struct swsusp_info)); | ||
1246 | info->num_physpages = num_physpages; | 1270 | info->num_physpages = num_physpages; |
1247 | memcpy(&info->uts, init_utsname(), sizeof(struct new_utsname)); | ||
1248 | info->cpus = num_online_cpus(); | ||
1249 | info->image_pages = nr_copy_pages; | 1271 | info->image_pages = nr_copy_pages; |
1250 | info->pages = nr_copy_pages + nr_meta_pages + 1; | 1272 | info->pages = nr_copy_pages + nr_meta_pages + 1; |
1251 | info->size = info->pages; | 1273 | info->size = info->pages; |
1252 | info->size <<= PAGE_SHIFT; | 1274 | info->size <<= PAGE_SHIFT; |
1275 | return init_header_complete(info); | ||
1253 | } | 1276 | } |
1254 | 1277 | ||
1255 | /** | 1278 | /** |
@@ -1303,7 +1326,11 @@ int snapshot_read_next(struct snapshot_handle *handle, size_t count) | |||
1303 | return -ENOMEM; | 1326 | return -ENOMEM; |
1304 | } | 1327 | } |
1305 | if (!handle->offset) { | 1328 | if (!handle->offset) { |
1306 | init_header((struct swsusp_info *)buffer); | 1329 | int error; |
1330 | |||
1331 | error = init_header((struct swsusp_info *)buffer); | ||
1332 | if (error) | ||
1333 | return error; | ||
1307 | handle->buffer = buffer; | 1334 | handle->buffer = buffer; |
1308 | memory_bm_position_reset(&orig_bm); | 1335 | memory_bm_position_reset(&orig_bm); |
1309 | memory_bm_position_reset(©_bm); | 1336 | memory_bm_position_reset(©_bm); |
@@ -1394,22 +1421,13 @@ duplicate_memory_bitmap(struct memory_bitmap *dst, struct memory_bitmap *src) | |||
1394 | } | 1421 | } |
1395 | } | 1422 | } |
1396 | 1423 | ||
1397 | static inline int check_header(struct swsusp_info *info) | 1424 | static int check_header(struct swsusp_info *info) |
1398 | { | 1425 | { |
1399 | char *reason = NULL; | 1426 | char *reason; |
1400 | 1427 | ||
1401 | if (info->version_code != LINUX_VERSION_CODE) | 1428 | reason = check_image_kernel(info); |
1402 | reason = "kernel version"; | 1429 | if (!reason && info->num_physpages != num_physpages) |
1403 | if (info->num_physpages != num_physpages) | ||
1404 | reason = "memory size"; | 1430 | reason = "memory size"; |
1405 | if (strcmp(info->uts.sysname,init_utsname()->sysname)) | ||
1406 | reason = "system type"; | ||
1407 | if (strcmp(info->uts.release,init_utsname()->release)) | ||
1408 | reason = "kernel release"; | ||
1409 | if (strcmp(info->uts.version,init_utsname()->version)) | ||
1410 | reason = "version"; | ||
1411 | if (strcmp(info->uts.machine,init_utsname()->machine)) | ||
1412 | reason = "machine"; | ||
1413 | if (reason) { | 1431 | if (reason) { |
1414 | printk(KERN_ERR "swsusp: Resume mismatch: %s\n", reason); | 1432 | printk(KERN_ERR "swsusp: Resume mismatch: %s\n", reason); |
1415 | return -EPERM; | 1433 | return -EPERM; |