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