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.c43
1 files changed, 32 insertions, 11 deletions
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index 5d2ab836e998..955c8cc91838 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -519,6 +519,14 @@ static int memory_bm_test_bit(struct memory_bitmap *bm, unsigned long pfn)
519 return test_bit(bit, addr); 519 return test_bit(bit, addr);
520} 520}
521 521
522static bool memory_bm_pfn_present(struct memory_bitmap *bm, unsigned long pfn)
523{
524 void *addr;
525 unsigned int bit;
526
527 return !memory_bm_find_bit(bm, pfn, &addr, &bit);
528}
529
522/** 530/**
523 * memory_bm_next_pfn - find the pfn that corresponds to the next set bit 531 * memory_bm_next_pfn - find the pfn that corresponds to the next set bit
524 * in the bitmap @bm. If the pfn cannot be found, BM_END_OF_MAP is 532 * in the bitmap @bm. If the pfn cannot be found, BM_END_OF_MAP is
@@ -1459,9 +1467,7 @@ load_header(struct swsusp_info *info)
1459 * unpack_orig_pfns - for each element of @buf[] (1 page at a time) set 1467 * unpack_orig_pfns - for each element of @buf[] (1 page at a time) set
1460 * the corresponding bit in the memory bitmap @bm 1468 * the corresponding bit in the memory bitmap @bm
1461 */ 1469 */
1462 1470static int unpack_orig_pfns(unsigned long *buf, struct memory_bitmap *bm)
1463static inline void
1464unpack_orig_pfns(unsigned long *buf, struct memory_bitmap *bm)
1465{ 1471{
1466 int j; 1472 int j;
1467 1473
@@ -1469,8 +1475,13 @@ unpack_orig_pfns(unsigned long *buf, struct memory_bitmap *bm)
1469 if (unlikely(buf[j] == BM_END_OF_MAP)) 1475 if (unlikely(buf[j] == BM_END_OF_MAP))
1470 break; 1476 break;
1471 1477
1472 memory_bm_set_bit(bm, buf[j]); 1478 if (memory_bm_pfn_present(bm, buf[j]))
1479 memory_bm_set_bit(bm, buf[j]);
1480 else
1481 return -EFAULT;
1473 } 1482 }
1483
1484 return 0;
1474} 1485}
1475 1486
1476/* List of "safe" pages that may be used to store data loaded from the suspend 1487/* List of "safe" pages that may be used to store data loaded from the suspend
@@ -1608,7 +1619,7 @@ get_highmem_page_buffer(struct page *page, struct chain_allocator *ca)
1608 pbe = chain_alloc(ca, sizeof(struct highmem_pbe)); 1619 pbe = chain_alloc(ca, sizeof(struct highmem_pbe));
1609 if (!pbe) { 1620 if (!pbe) {
1610 swsusp_free(); 1621 swsusp_free();
1611 return NULL; 1622 return ERR_PTR(-ENOMEM);
1612 } 1623 }
1613 pbe->orig_page = page; 1624 pbe->orig_page = page;
1614 if (safe_highmem_pages > 0) { 1625 if (safe_highmem_pages > 0) {
@@ -1677,7 +1688,7 @@ prepare_highmem_image(struct memory_bitmap *bm, unsigned int *nr_highmem_p)
1677static inline void * 1688static inline void *
1678get_highmem_page_buffer(struct page *page, struct chain_allocator *ca) 1689get_highmem_page_buffer(struct page *page, struct chain_allocator *ca)
1679{ 1690{
1680 return NULL; 1691 return ERR_PTR(-EINVAL);
1681} 1692}
1682 1693
1683static inline void copy_last_highmem_page(void) {} 1694static inline void copy_last_highmem_page(void) {}
@@ -1788,8 +1799,13 @@ prepare_image(struct memory_bitmap *new_bm, struct memory_bitmap *bm)
1788static void *get_buffer(struct memory_bitmap *bm, struct chain_allocator *ca) 1799static void *get_buffer(struct memory_bitmap *bm, struct chain_allocator *ca)
1789{ 1800{
1790 struct pbe *pbe; 1801 struct pbe *pbe;
1791 struct page *page = pfn_to_page(memory_bm_next_pfn(bm)); 1802 struct page *page;
1803 unsigned long pfn = memory_bm_next_pfn(bm);
1792 1804
1805 if (pfn == BM_END_OF_MAP)
1806 return ERR_PTR(-EFAULT);
1807
1808 page = pfn_to_page(pfn);
1793 if (PageHighMem(page)) 1809 if (PageHighMem(page))
1794 return get_highmem_page_buffer(page, ca); 1810 return get_highmem_page_buffer(page, ca);
1795 1811
@@ -1805,7 +1821,7 @@ static void *get_buffer(struct memory_bitmap *bm, struct chain_allocator *ca)
1805 pbe = chain_alloc(ca, sizeof(struct pbe)); 1821 pbe = chain_alloc(ca, sizeof(struct pbe));
1806 if (!pbe) { 1822 if (!pbe) {
1807 swsusp_free(); 1823 swsusp_free();
1808 return NULL; 1824 return ERR_PTR(-ENOMEM);
1809 } 1825 }
1810 pbe->orig_address = page_address(page); 1826 pbe->orig_address = page_address(page);
1811 pbe->address = safe_pages_list; 1827 pbe->address = safe_pages_list;
@@ -1868,7 +1884,10 @@ int snapshot_write_next(struct snapshot_handle *handle, size_t count)
1868 return error; 1884 return error;
1869 1885
1870 } else if (handle->prev <= nr_meta_pages) { 1886 } else if (handle->prev <= nr_meta_pages) {
1871 unpack_orig_pfns(buffer, &copy_bm); 1887 error = unpack_orig_pfns(buffer, &copy_bm);
1888 if (error)
1889 return error;
1890
1872 if (handle->prev == nr_meta_pages) { 1891 if (handle->prev == nr_meta_pages) {
1873 error = prepare_image(&orig_bm, &copy_bm); 1892 error = prepare_image(&orig_bm, &copy_bm);
1874 if (error) 1893 if (error)
@@ -1879,12 +1898,14 @@ int snapshot_write_next(struct snapshot_handle *handle, size_t count)
1879 restore_pblist = NULL; 1898 restore_pblist = NULL;
1880 handle->buffer = get_buffer(&orig_bm, &ca); 1899 handle->buffer = get_buffer(&orig_bm, &ca);
1881 handle->sync_read = 0; 1900 handle->sync_read = 0;
1882 if (!handle->buffer) 1901 if (IS_ERR(handle->buffer))
1883 return -ENOMEM; 1902 return PTR_ERR(handle->buffer);
1884 } 1903 }
1885 } else { 1904 } else {
1886 copy_last_highmem_page(); 1905 copy_last_highmem_page();
1887 handle->buffer = get_buffer(&orig_bm, &ca); 1906 handle->buffer = get_buffer(&orig_bm, &ca);
1907 if (IS_ERR(handle->buffer))
1908 return PTR_ERR(handle->buffer);
1888 if (handle->buffer != buffer) 1909 if (handle->buffer != buffer)
1889 handle->sync_read = 0; 1910 handle->sync_read = 0;
1890 } 1911 }