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