1/* 2 * Suspend support specific for s390. 3 * 4 * Copyright IBM Corp. 2009 5 * 6 * Author(s): Hans-Joachim Picht <hans@linux.vnet.ibm.com> 7 */ 8 9#include <linux/pfn.h> 10#include <linux/suspend.h> 11#include <linux/mm.h> 12#include <asm/ctl_reg.h> 13#include <asm/ipl.h> 14#include <asm/cio.h> 15#include <asm/pci.h> 16#include <asm/sections.h> 17#include "entry.h" 18 19/* 20 * The restore of the saved pages in an hibernation image will set 21 * the change and referenced bits in the storage key for each page. 22 * Overindication of the referenced bits after an hibernation cycle 23 * does not cause any harm but the overindication of the change bits 24 * would cause trouble. 25 * Use the ARCH_SAVE_PAGE_KEYS hooks to save the storage key of each 26 * page to the most significant byte of the associated page frame 27 * number in the hibernation image. 28 */ 29 30/* 31 * Key storage is allocated as a linked list of pages. 32 * The size of the keys array is (PAGE_SIZE - sizeof(long)) 33 */ 34struct page_key_data { 35 struct page_key_data *next; 36 unsigned char data[]; 37}; 38 39#define PAGE_KEY_DATA_SIZE (PAGE_SIZE - sizeof(struct page_key_data *)) 40 41static struct page_key_data *page_key_data; 42static struct page_key_data *page_key_rp, *page_key_wp; 43static unsigned long page_key_rx, page_key_wx; 44unsigned long suspend_zero_pages; 45 46/* 47 * For each page in the hibernation image one additional byte is 48 * stored in the most significant byte of the page frame number. 49 * On suspend no additional memory is required but on resume the 50 * keys need to be memorized until the page data has been restored. 51 * Only then can the storage keys be set to their old state. 52 */ 53unsigned long page_key_additional_pages(unsigned long pages) 54{ 55 return DIV_ROUND_UP(pages, PAGE_KEY_DATA_SIZE); 56} 57 58/* 59 * Free page_key_data list of arrays. 60 */ 61void page_key_free(void) 62{ 63 struct page_key_data *pkd; 64 65 while (page_key_data) { 66 pkd = page_key_data; 67 page_key_data = pkd->next; 68 free_page((unsigned long) pkd); 69 } 70} 71 72/* 73 * Allocate page_key_data list of arrays with enough room to store 74 * one byte for each page in the hibernation image. 75 */ 76int page_key_alloc(unsigned long pages) 77{ 78 struct page_key_data *pk; 79 unsigned long size; 80 81 size = DIV_ROUND_UP(pages, PAGE_KEY_DATA_SIZE); 82 while (size--) { 83 pk = (struct page_key_data *) get_zeroed_page(GFP_KERNEL); 84 if (!pk) { 85 page_key_free(); 86 return -ENOMEM; 87 } 88 pk->next = page_key_data; 89 page_key_data = pk; 90 } 91 page_key_rp = page_key_wp = page_key_data; 92 page_key_rx = page_key_wx = 0; 93 return 0; 94} 95 96/* 97 * Save the storage key into the upper 8 bits of the page frame number. 98 */ 99void page_key_read(unsigned long *pfn) 100{ 101 unsigned long addr; 102 103 addr = (unsigned long) page_address(pfn_to_page(*pfn)); 104 *(unsigned char *) pfn = (unsigned char) page_get_storage_key(addr); 105} 106 107/* 108 * Extract the storage key from the upper 8 bits of the page frame number 109 * and store it in the page_key_data list of arrays. 110 */ 111void page_key_memorize(unsigned long *pfn) 112{ 113 page_key_wp->data[page_key_wx] = *(unsigned char *) pfn; 114 *(unsigned char *) pfn = 0; 115 if (++page_key_wx < PAGE_KEY_DATA_SIZE) 116 return; 117 page_key_wp = page_key_wp->next; 118 page_key_wx = 0; 119} 120 121/* 122 * Get the next key from the page_key_data list of arrays and set the 123 * storage key of the page referred by @address. If @address refers to 124 * a "safe" page the swsusp_arch_resume code will transfer the storage 125 * key from the buffer page to the original page. 126 */ 127void page_key_write(void *address) 128{ 129 page_set_storage_key((unsigned long) address, 130 page_key_rp->data[page_key_rx], 0); 131 if (++page_key_rx >= PAGE_KEY_DATA_SIZE) 132 return; 133 page_key_rp = page_key_rp->next; 134 page_key_rx = 0; 135} 136 137int pfn_is_nosave(unsigned long pfn) 138{ 139 unsigned long nosave_begin_pfn = PFN_DOWN(__pa(&__nosave_begin)); 140 unsigned long nosave_end_pfn = PFN_DOWN(__pa(&__nosave_end)); 141 unsigned long eshared_pfn = PFN_DOWN(__pa(&_eshared)) - 1; 142 unsigned long stext_pfn = PFN_DOWN(__pa(&_stext)); 143 144 /* Always save lowcore pages (LC protection might be enabled). */ 145 if (pfn <= LC_PAGES) 146 return 0; 147 if (pfn >= nosave_begin_pfn && pfn < nosave_end_pfn) 148 return 1; 149 /* Skip memory holes and read-only pages (NSS, DCSS, ...). */ 150 if (pfn >= stext_pfn && pfn <= eshared_pfn) 151 return ipl_info.type == IPL_TYPE_NSS ? 1 : 0; 152 if (tprot(PFN_PHYS(pfn))) 153 return 1; 154 return 0; 155} 156 157/* 158 * PM notifier callback for suspend 159 */ 160static int suspend_pm_cb(struct notifier_block *nb, unsigned long action, 161 void *ptr) 162{ 163 switch (action) { 164 case PM_SUSPEND_PREPARE: 165 case PM_HIBERNATION_PREPARE: 166 suspend_zero_pages = __get_free_pages(GFP_KERNEL, LC_ORDER); 167 if (!suspend_zero_pages) 168 return NOTIFY_BAD; 169 break; 170 case PM_POST_SUSPEND: 171 case PM_POST_HIBERNATION: 172 free_pages(suspend_zero_pages, LC_ORDER); 173 break; 174 default: 175 return NOTIFY_DONE; 176 } 177 return NOTIFY_OK; 178} 179 180static int __init suspend_pm_init(void) 181{ 182 pm_notifier(suspend_pm_cb, 0); 183 return 0; 184} 185arch_initcall(suspend_pm_init); 186 187void save_processor_state(void) 188{ 189 /* swsusp_arch_suspend() actually saves all cpu register contents. 190 * Machine checks must be disabled since swsusp_arch_suspend() stores 191 * register contents to their lowcore save areas. That's the same 192 * place where register contents on machine checks would be saved. 193 * To avoid register corruption disable machine checks. 194 * We must also disable machine checks in the new psw mask for 195 * program checks, since swsusp_arch_suspend() may generate program 196 * checks. Disabling machine checks for all other new psw masks is 197 * just paranoia. 198 */ 199 local_mcck_disable(); 200 /* Disable lowcore protection */ 201 __ctl_clear_bit(0,28); 202 S390_lowcore.external_new_psw.mask &= ~PSW_MASK_MCHECK; 203 S390_lowcore.svc_new_psw.mask &= ~PSW_MASK_MCHECK; 204 S390_lowcore.io_new_psw.mask &= ~PSW_MASK_MCHECK; 205 S390_lowcore.program_new_psw.mask &= ~PSW_MASK_MCHECK; 206} 207 208void restore_processor_state(void) 209{ 210 S390_lowcore.external_new_psw.mask |= PSW_MASK_MCHECK; 211 S390_lowcore.svc_new_psw.mask |= PSW_MASK_MCHECK; 212 S390_lowcore.io_new_psw.mask |= PSW_MASK_MCHECK; 213 S390_lowcore.program_new_psw.mask |= PSW_MASK_MCHECK; 214 /* Enable lowcore protection */ 215 __ctl_set_bit(0,28); 216 local_mcck_enable(); 217} 218 219/* Called at the end of swsusp_arch_resume */ 220void s390_early_resume(void) 221{ 222 lgr_info_log(); 223 channel_subsystem_reinit(); 224 zpci_rescan(); 225} 226