diff options
Diffstat (limited to 'kernel/power')
-rw-r--r-- | kernel/power/swap.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/kernel/power/swap.c b/kernel/power/swap.c index 12cd989dadf6..160e1006640d 100644 --- a/kernel/power/swap.c +++ b/kernel/power/swap.c | |||
@@ -37,6 +37,14 @@ | |||
37 | #define HIBERNATE_SIG "S1SUSPEND" | 37 | #define HIBERNATE_SIG "S1SUSPEND" |
38 | 38 | ||
39 | /* | 39 | /* |
40 | * When reading an {un,}compressed image, we may restore pages in place, | ||
41 | * in which case some architectures need these pages cleaning before they | ||
42 | * can be executed. We don't know which pages these may be, so clean the lot. | ||
43 | */ | ||
44 | static bool clean_pages_on_read; | ||
45 | static bool clean_pages_on_decompress; | ||
46 | |||
47 | /* | ||
40 | * The swap map is a data structure used for keeping track of each page | 48 | * The swap map is a data structure used for keeping track of each page |
41 | * written to a swap partition. It consists of many swap_map_page | 49 | * written to a swap partition. It consists of many swap_map_page |
42 | * structures that contain each an array of MAP_PAGE_ENTRIES swap entries. | 50 | * structures that contain each an array of MAP_PAGE_ENTRIES swap entries. |
@@ -241,6 +249,9 @@ static void hib_end_io(struct bio *bio) | |||
241 | 249 | ||
242 | if (bio_data_dir(bio) == WRITE) | 250 | if (bio_data_dir(bio) == WRITE) |
243 | put_page(page); | 251 | put_page(page); |
252 | else if (clean_pages_on_read) | ||
253 | flush_icache_range((unsigned long)page_address(page), | ||
254 | (unsigned long)page_address(page) + PAGE_SIZE); | ||
244 | 255 | ||
245 | if (bio->bi_error && !hb->error) | 256 | if (bio->bi_error && !hb->error) |
246 | hb->error = bio->bi_error; | 257 | hb->error = bio->bi_error; |
@@ -1049,6 +1060,7 @@ static int load_image(struct swap_map_handle *handle, | |||
1049 | 1060 | ||
1050 | hib_init_batch(&hb); | 1061 | hib_init_batch(&hb); |
1051 | 1062 | ||
1063 | clean_pages_on_read = true; | ||
1052 | printk(KERN_INFO "PM: Loading image data pages (%u pages)...\n", | 1064 | printk(KERN_INFO "PM: Loading image data pages (%u pages)...\n", |
1053 | nr_to_read); | 1065 | nr_to_read); |
1054 | m = nr_to_read / 10; | 1066 | m = nr_to_read / 10; |
@@ -1124,6 +1136,10 @@ static int lzo_decompress_threadfn(void *data) | |||
1124 | d->unc_len = LZO_UNC_SIZE; | 1136 | d->unc_len = LZO_UNC_SIZE; |
1125 | d->ret = lzo1x_decompress_safe(d->cmp + LZO_HEADER, d->cmp_len, | 1137 | d->ret = lzo1x_decompress_safe(d->cmp + LZO_HEADER, d->cmp_len, |
1126 | d->unc, &d->unc_len); | 1138 | d->unc, &d->unc_len); |
1139 | if (clean_pages_on_decompress) | ||
1140 | flush_icache_range((unsigned long)d->unc, | ||
1141 | (unsigned long)d->unc + d->unc_len); | ||
1142 | |||
1127 | atomic_set(&d->stop, 1); | 1143 | atomic_set(&d->stop, 1); |
1128 | wake_up(&d->done); | 1144 | wake_up(&d->done); |
1129 | } | 1145 | } |
@@ -1189,6 +1205,8 @@ static int load_image_lzo(struct swap_map_handle *handle, | |||
1189 | } | 1205 | } |
1190 | memset(crc, 0, offsetof(struct crc_data, go)); | 1206 | memset(crc, 0, offsetof(struct crc_data, go)); |
1191 | 1207 | ||
1208 | clean_pages_on_decompress = true; | ||
1209 | |||
1192 | /* | 1210 | /* |
1193 | * Start the decompression threads. | 1211 | * Start the decompression threads. |
1194 | */ | 1212 | */ |