aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/power/snapshot.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/power/snapshot.c')
-rw-r--r--kernel/power/snapshot.c62
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
1242static void init_header(struct swsusp_info *info) 1243#ifndef CONFIG_ARCH_HIBERNATION_HEADER
1244static 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
1251static 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
1267static 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(&copy_bm); 1336 memory_bm_position_reset(&copy_bm);
@@ -1394,22 +1421,13 @@ duplicate_memory_bitmap(struct memory_bitmap *dst, struct memory_bitmap *src)
1394 } 1421 }
1395} 1422}
1396 1423
1397static inline int check_header(struct swsusp_info *info) 1424static 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;