1 /* 2 * Page Deallocation Table (PDT) support 3 * 4 * The Page Deallocation Table (PDT) is maintained by firmware and holds a 5 * list of memory addresses in which memory errors were detected. 6 * The list contains both single-bit (correctable) and double-bit 7 * (uncorrectable) errors. 8 * 9 * Copyright 2017 by Helge Deller <deller@gmx.de> 10 * 11 * possible future enhancements: 12 * - add userspace interface via procfs or sysfs to clear PDT 13 */ 14 15 #include <linux/memblock.h> 16 #include <linux/seq_file.h> 17 #include <linux/kthread.h> 18 #include <linux/initrd.h> 19 20 #include <asm/pdc.h> 21 #include <asm/pdcpat.h> 22 #include <asm/sections.h> 23 #include <asm/pgtable.h> 24 25 enum pdt_access_type { 26 PDT_NONE, 27 PDT_PDC, 28 PDT_PAT_NEW, 29 PDT_PAT_CELL 30 }; 31 32 static enum pdt_access_type pdt_type; 33 34 /* PDT poll interval: 1 minute if errors, 5 minutes if everything OK. */ 35 #define PDT_POLL_INTERVAL_DEFAULT (5*60*HZ) 36 #define PDT_POLL_INTERVAL_SHORT (1*60*HZ) 37 static unsigned long pdt_poll_interval = PDT_POLL_INTERVAL_DEFAULT; 38 39 /* global PDT status information */ 40 static struct pdc_mem_retinfo pdt_status; 41 42 #define MAX_PDT_TABLE_SIZE PAGE_SIZE 43 #define MAX_PDT_ENTRIES (MAX_PDT_TABLE_SIZE / sizeof(unsigned long)) 44 static unsigned long pdt_entry[MAX_PDT_ENTRIES] __page_aligned_bss; 45 46 /* 47 * Constants for the pdt_entry format: 48 * A pdt_entry holds the physical address in bits 0-57, bits 58-61 are 49 * reserved, bit 62 is the perm bit and bit 63 is the error_type bit. 50 * The perm bit indicates whether the error have been verified as a permanent 51 * error (value of 1) or has not been verified, and may be transient (value 52 * of 0). The error_type bit indicates whether the error is a single bit error 53 * (value of 1) or a multiple bit error. 54 * On non-PAT machines phys_addr is encoded in bits 0-59 and error_type in bit 55 * 63. Those machines don't provide the perm bit. 56 */ 57 58 #define PDT_ADDR_PHYS_MASK (pdt_type != PDT_PDC ? ~0x3f : ~0x0f) 59 #define PDT_ADDR_PERM_ERR (pdt_type != PDT_PDC ? 2UL : 0UL) 60 #define PDT_ADDR_SINGLE_ERR 1UL 61 62 /* report PDT entries via /proc/meminfo */ 63 void arch_report_meminfo(struct seq_file *m) 64 { 65 if (pdt_type == PDT_NONE) 66 return; 67 68 seq_printf(m, "PDT_max_entries: %7lu\n", 69 pdt_status.pdt_size); 70 seq_printf(m, "PDT_cur_entries: %7lu\n", 71 pdt_status.pdt_entries); 72 } 73 74 static int get_info_pat_new(void) 75 { 76 struct pdc_pat_mem_retinfo pat_rinfo; 77 int ret; 78 79 /* newer PAT machines like C8000 report info for all cells */ 80 if (is_pdc_pat()) 81 ret = pdc_pat_mem_pdt_info(&pat_rinfo); 82 else 83 return PDC_BAD_PROC; 84 85 pdt_status.pdt_size = pat_rinfo.max_pdt_entries; 86 pdt_status.pdt_entries = pat_rinfo.current_pdt_entries; 87 pdt_status.pdt_status = 0; 88 pdt_status.first_dbe_loc = pat_rinfo.first_dbe_loc; 89 pdt_status.good_mem = pat_rinfo.good_mem; 90 91 return ret; 92 } 93 94 static int get_info_pat_cell(void) 95 { 96 struct pdc_pat_mem_cell_pdt_retinfo cell_rinfo; 97 int ret; 98 99 /* older PAT machines like rp5470 report cell info only */ 100 if (is_pdc_pat()) 101 ret = pdc_pat_mem_pdt_cell_info(&cell_rinfo, parisc_cell_num); 102 else 103 return PDC_BAD_PROC; 104 105 pdt_status.pdt_size = cell_rinfo.max_pdt_entries; 106 pdt_status.pdt_entries = cell_rinfo.current_pdt_entries; 107 pdt_status.pdt_status = 0; 108 pdt_status.first_dbe_loc = cell_rinfo.first_dbe_loc; 109 pdt_status.good_mem = cell_rinfo.good_mem; 110 111 return ret; 112 } 113 114 static void report_mem_err(unsigned long pde) 115 { 116 struct pdc_pat_mem_phys_mem_location loc; 117 unsigned long addr; 118 char dimm_txt[32]; 119 120 addr = pde & PDT_ADDR_PHYS_MASK; 121 122 /* show DIMM slot description on PAT machines */ 123 if (is_pdc_pat()) { 124 pdc_pat_mem_get_dimm_phys_location(&loc, addr); 125 sprintf(dimm_txt, "DIMM slot %02x, ", loc.dimm_slot); 126 } else 127 dimm_txt[0] = 0; 128 129 pr_warn("PDT: BAD MEMORY at 0x%08lx, %s%s%s-bit error.\n", 130 addr, dimm_txt, 131 pde & PDT_ADDR_PERM_ERR ? "permanent ":"", 132 pde & PDT_ADDR_SINGLE_ERR ? "single":"multi"); 133 } 134 135 136 /* 137 * pdc_pdt_init() 138 * 139 * Initialize kernel PDT structures, read initial PDT table from firmware, 140 * report all current PDT entries and mark bad memory with memblock_reserve() 141 * to avoid that the kernel will use broken memory areas. 142 * 143 */ 144 void __init pdc_pdt_init(void) 145 { 146 int ret, i; 147 unsigned long entries; 148 struct pdc_mem_read_pdt pdt_read_ret; 149 150 pdt_type = PDT_PAT_NEW; 151 ret = get_info_pat_new(); 152 153 if (ret != PDC_OK) { 154 pdt_type = PDT_PAT_CELL; 155 ret = get_info_pat_cell(); 156 } 157 158 if (ret != PDC_OK) { 159 pdt_type = PDT_PDC; 160 /* non-PAT machines provide the standard PDC call */ 161 ret = pdc_mem_pdt_info(&pdt_status); 162 } 163 164 if (ret != PDC_OK) { 165 pdt_type = PDT_NONE; 166 pr_info("PDT: Firmware does not provide any page deallocation" 167 " information.\n"); 168 return; 169 } 170 171 entries = pdt_status.pdt_entries; 172 if (WARN_ON(entries > MAX_PDT_ENTRIES)) 173 entries = pdt_status.pdt_entries = MAX_PDT_ENTRIES; 174 175 pr_info("PDT: type %s, size %lu, entries %lu, status %lu, dbe_loc 0x%lx," 176 " good_mem %lu MB\n", 177 pdt_type == PDT_PDC ? __stringify(PDT_PDC) : 178 pdt_type == PDT_PAT_CELL ? __stringify(PDT_PAT_CELL) 179 : __stringify(PDT_PAT_NEW), 180 pdt_status.pdt_size, pdt_status.pdt_entries, 181 pdt_status.pdt_status, pdt_status.first_dbe_loc, 182 pdt_status.good_mem / 1024 / 1024); 183 184 if (entries == 0) { 185 pr_info("PDT: Firmware reports all memory OK.\n"); 186 return; 187 } 188 189 if (pdt_status.first_dbe_loc && 190 pdt_status.first_dbe_loc <= __pa((unsigned long)&_end)) 191 pr_crit("CRITICAL: Bad memory inside kernel image memory area!\n"); 192 193 pr_warn("PDT: Firmware reports %lu entries of faulty memory:\n", 194 entries); 195 196 if (pdt_type == PDT_PDC) 197 ret = pdc_mem_pdt_read_entries(&pdt_read_ret, pdt_entry); 198 else { 199 #ifdef CONFIG_64BIT 200 struct pdc_pat_mem_read_pd_retinfo pat_pret; 201 202 if (pdt_type == PDT_PAT_CELL) 203 ret = pdc_pat_mem_read_cell_pdt(&pat_pret, pdt_entry, 204 MAX_PDT_ENTRIES); 205 else 206 ret = pdc_pat_mem_read_pd_pdt(&pat_pret, pdt_entry, 207 MAX_PDT_TABLE_SIZE, 0); 208 #else 209 ret = PDC_BAD_PROC; 210 #endif 211 } 212 213 if (ret != PDC_OK) { 214 pdt_type = PDT_NONE; 215 pr_warn("PDT: Get PDT entries failed with %d\n", ret); 216 return; 217 } 218 219 for (i = 0; i < pdt_status.pdt_entries; i++) { 220 unsigned long addr; 221 222 report_mem_err(pdt_entry[i]); 223 224 addr = pdt_entry[i] & PDT_ADDR_PHYS_MASK; 225 if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && 226 addr >= initrd_start && addr < initrd_end) 227 pr_crit("CRITICAL: initrd possibly broken " 228 "due to bad memory!\n"); 229 230 /* mark memory page bad */ 231 memblock_reserve(pdt_entry[i] & PAGE_MASK, PAGE_SIZE); 232 } 233 } 234 235 236 /* 237 * This is the PDT kernel thread main loop. 238 */ 239 240 static int pdt_mainloop(void *unused) 241 { 242 struct pdc_mem_read_pdt pdt_read_ret; 243 struct pdc_pat_mem_read_pd_retinfo pat_pret __maybe_unused; 244 unsigned long old_num_entries; 245 unsigned long *bad_mem_ptr; 246 int num, ret; 247 248 for (;;) { 249 set_current_state(TASK_INTERRUPTIBLE); 250 251 old_num_entries = pdt_status.pdt_entries; 252 253 schedule_timeout(pdt_poll_interval); 254 if (kthread_should_stop()) 255 break; 256 257 /* Do we have new PDT entries? */ 258 switch (pdt_type) { 259 case PDT_PAT_NEW: 260 ret = get_info_pat_new(); 261 break; 262 case PDT_PAT_CELL: 263 ret = get_info_pat_cell(); 264 break; 265 default: 266 ret = pdc_mem_pdt_info(&pdt_status); 267 break; 268 } 269 270 if (ret != PDC_OK) { 271 pr_warn("PDT: unexpected failure %d\n", ret); 272 return -EINVAL; 273 } 274 275 /* if no new PDT entries, just wait again */ 276 num = pdt_status.pdt_entries - old_num_entries; 277 if (num <= 0) 278 continue; 279 280 /* decrease poll interval in case we found memory errors */ 281 if (pdt_status.pdt_entries && 282 pdt_poll_interval == PDT_POLL_INTERVAL_DEFAULT) 283 pdt_poll_interval = PDT_POLL_INTERVAL_SHORT; 284 285 /* limit entries to get */ 286 if (num > MAX_PDT_ENTRIES) { 287 num = MAX_PDT_ENTRIES; 288 pdt_status.pdt_entries = old_num_entries + num; 289 } 290 291 /* get new entries */ 292 switch (pdt_type) { 293 #ifdef CONFIG_64BIT 294 case PDT_PAT_CELL: 295 if (pdt_status.pdt_entries > MAX_PDT_ENTRIES) { 296 pr_crit("PDT: too many entries.\n"); 297 return -ENOMEM; 298 } 299 ret = pdc_pat_mem_read_cell_pdt(&pat_pret, pdt_entry, 300 MAX_PDT_ENTRIES); 301 bad_mem_ptr = &pdt_entry[old_num_entries]; 302 break; 303 case PDT_PAT_NEW: 304 ret = pdc_pat_mem_read_pd_pdt(&pat_pret, 305 pdt_entry, 306 num * sizeof(unsigned long), 307 old_num_entries * sizeof(unsigned long)); 308 bad_mem_ptr = &pdt_entry[0]; 309 break; 310 #endif 311 default: 312 ret = pdc_mem_pdt_read_entries(&pdt_read_ret, 313 pdt_entry); 314 bad_mem_ptr = &pdt_entry[old_num_entries]; 315 break; 316 } 317 318 /* report and mark memory broken */ 319 while (num--) { 320 unsigned long pde = *bad_mem_ptr++; 321 322 report_mem_err(pde); 323 324 #ifdef CONFIG_MEMORY_FAILURE 325 if ((pde & PDT_ADDR_PERM_ERR) || 326 ((pde & PDT_ADDR_SINGLE_ERR) == 0)) 327 memory_failure(pde >> PAGE_SHIFT, 0, 0); 328 else 329 soft_offline_page( 330 pfn_to_page(pde >> PAGE_SHIFT), 0); 331 #else 332 pr_crit("PDT: memory error at 0x%lx ignored.\n" 333 "Rebuild kernel with CONFIG_MEMORY_FAILURE=y " 334 "for real handling.\n", 335 pde & PDT_ADDR_PHYS_MASK); 336 #endif 337 338 } 339 } 340 341 return 0; 342 } 343 344 345 static int __init pdt_initcall(void) 346 { 347 struct task_struct *kpdtd_task; 348 349 if (pdt_type == PDT_NONE) 350 return -ENODEV; 351 352 kpdtd_task = kthread_create(pdt_mainloop, NULL, "kpdtd"); 353 if (IS_ERR(kpdtd_task)) 354 return PTR_ERR(kpdtd_task); 355 356 wake_up_process(kpdtd_task); 357 358 return 0; 359 } 360 361 late_initcall(pdt_initcall); 362