diff options
Diffstat (limited to 'kernel/power')
-rw-r--r-- | kernel/power/Kconfig | 3 | ||||
-rw-r--r-- | kernel/power/snapshot.c | 18 |
2 files changed, 21 insertions, 0 deletions
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index 3744c594b19b..e01e6899592c 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig | |||
@@ -65,6 +65,9 @@ config HIBERNATION | |||
65 | 65 | ||
66 | For more information take a look at <file:Documentation/power/swsusp.txt>. | 66 | For more information take a look at <file:Documentation/power/swsusp.txt>. |
67 | 67 | ||
68 | config ARCH_SAVE_PAGE_KEYS | ||
69 | bool | ||
70 | |||
68 | config PM_STD_PARTITION | 71 | config PM_STD_PARTITION |
69 | string "Default resume partition" | 72 | string "Default resume partition" |
70 | depends on HIBERNATION | 73 | depends on HIBERNATION |
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index 06efa54f93d6..cbe2c1441392 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c | |||
@@ -1339,6 +1339,9 @@ int hibernate_preallocate_memory(void) | |||
1339 | count += highmem; | 1339 | count += highmem; |
1340 | count -= totalreserve_pages; | 1340 | count -= totalreserve_pages; |
1341 | 1341 | ||
1342 | /* Add number of pages required for page keys (s390 only). */ | ||
1343 | size += page_key_additional_pages(saveable); | ||
1344 | |||
1342 | /* Compute the maximum number of saveable pages to leave in memory. */ | 1345 | /* Compute the maximum number of saveable pages to leave in memory. */ |
1343 | max_size = (count - (size + PAGES_FOR_IO)) / 2 | 1346 | max_size = (count - (size + PAGES_FOR_IO)) / 2 |
1344 | - 2 * DIV_ROUND_UP(reserved_size, PAGE_SIZE); | 1347 | - 2 * DIV_ROUND_UP(reserved_size, PAGE_SIZE); |
@@ -1662,6 +1665,8 @@ pack_pfns(unsigned long *buf, struct memory_bitmap *bm) | |||
1662 | buf[j] = memory_bm_next_pfn(bm); | 1665 | buf[j] = memory_bm_next_pfn(bm); |
1663 | if (unlikely(buf[j] == BM_END_OF_MAP)) | 1666 | if (unlikely(buf[j] == BM_END_OF_MAP)) |
1664 | break; | 1667 | break; |
1668 | /* Save page key for data page (s390 only). */ | ||
1669 | page_key_read(buf + j); | ||
1665 | } | 1670 | } |
1666 | } | 1671 | } |
1667 | 1672 | ||
@@ -1821,6 +1826,9 @@ static int unpack_orig_pfns(unsigned long *buf, struct memory_bitmap *bm) | |||
1821 | if (unlikely(buf[j] == BM_END_OF_MAP)) | 1826 | if (unlikely(buf[j] == BM_END_OF_MAP)) |
1822 | break; | 1827 | break; |
1823 | 1828 | ||
1829 | /* Extract and buffer page key for data page (s390 only). */ | ||
1830 | page_key_memorize(buf + j); | ||
1831 | |||
1824 | if (memory_bm_pfn_present(bm, buf[j])) | 1832 | if (memory_bm_pfn_present(bm, buf[j])) |
1825 | memory_bm_set_bit(bm, buf[j]); | 1833 | memory_bm_set_bit(bm, buf[j]); |
1826 | else | 1834 | else |
@@ -2223,6 +2231,11 @@ int snapshot_write_next(struct snapshot_handle *handle) | |||
2223 | if (error) | 2231 | if (error) |
2224 | return error; | 2232 | return error; |
2225 | 2233 | ||
2234 | /* Allocate buffer for page keys. */ | ||
2235 | error = page_key_alloc(nr_copy_pages); | ||
2236 | if (error) | ||
2237 | return error; | ||
2238 | |||
2226 | } else if (handle->cur <= nr_meta_pages + 1) { | 2239 | } else if (handle->cur <= nr_meta_pages + 1) { |
2227 | error = unpack_orig_pfns(buffer, ©_bm); | 2240 | error = unpack_orig_pfns(buffer, ©_bm); |
2228 | if (error) | 2241 | if (error) |
@@ -2243,6 +2256,8 @@ int snapshot_write_next(struct snapshot_handle *handle) | |||
2243 | } | 2256 | } |
2244 | } else { | 2257 | } else { |
2245 | copy_last_highmem_page(); | 2258 | copy_last_highmem_page(); |
2259 | /* Restore page key for data page (s390 only). */ | ||
2260 | page_key_write(handle->buffer); | ||
2246 | handle->buffer = get_buffer(&orig_bm, &ca); | 2261 | handle->buffer = get_buffer(&orig_bm, &ca); |
2247 | if (IS_ERR(handle->buffer)) | 2262 | if (IS_ERR(handle->buffer)) |
2248 | return PTR_ERR(handle->buffer); | 2263 | return PTR_ERR(handle->buffer); |
@@ -2264,6 +2279,9 @@ int snapshot_write_next(struct snapshot_handle *handle) | |||
2264 | void snapshot_write_finalize(struct snapshot_handle *handle) | 2279 | void snapshot_write_finalize(struct snapshot_handle *handle) |
2265 | { | 2280 | { |
2266 | copy_last_highmem_page(); | 2281 | copy_last_highmem_page(); |
2282 | /* Restore page key for data page (s390 only). */ | ||
2283 | page_key_write(handle->buffer); | ||
2284 | page_key_free(); | ||
2267 | /* Free only if we have loaded the image entirely */ | 2285 | /* Free only if we have loaded the image entirely */ |
2268 | if (handle->cur > 1 && handle->cur > nr_meta_pages + nr_copy_pages) { | 2286 | if (handle->cur > 1 && handle->cur > nr_meta_pages + nr_copy_pages) { |
2269 | memory_bm_free(&orig_bm, PG_UNSAFE_CLEAR); | 2287 | memory_bm_free(&orig_bm, PG_UNSAFE_CLEAR); |