H A D | ghes.c | 48 #include <acpi/ghes.h> 237 static struct ghes *ghes_new(struct acpi_hest_generic *generic) ghes_new() 239 struct ghes *ghes; ghes_new() local 243 ghes = kzalloc(sizeof(*ghes), GFP_KERNEL); ghes_new() 244 if (!ghes) ghes_new() 246 ghes->generic = generic; ghes_new() 258 ghes->estatus = kmalloc(error_block_length, GFP_KERNEL); ghes_new() 259 if (!ghes->estatus) { ghes_new() 264 return ghes; ghes_new() 269 kfree(ghes); ghes_new() 273 static void ghes_fini(struct ghes *ghes) ghes_fini() argument 275 kfree(ghes->estatus); ghes_fini() 276 apei_unmap_generic_address(&ghes->generic->error_status_address); ghes_fini() 333 static int ghes_read_estatus(struct ghes *ghes, int silent) ghes_read_estatus() argument 335 struct acpi_hest_generic *g = ghes->generic; ghes_read_estatus() 351 ghes_copy_tofrom_phys(ghes->estatus, buf_paddr, ghes_read_estatus() 352 sizeof(*ghes->estatus), 1); ghes_read_estatus() 353 if (!ghes->estatus->block_status) ghes_read_estatus() 356 ghes->buffer_paddr = buf_paddr; ghes_read_estatus() 357 ghes->flags |= GHES_TO_CLEAR; ghes_read_estatus() 360 len = cper_estatus_len(ghes->estatus); ghes_read_estatus() 361 if (len < sizeof(*ghes->estatus)) ghes_read_estatus() 363 if (len > ghes->generic->error_block_length) ghes_read_estatus() 365 if (cper_estatus_check_header(ghes->estatus)) ghes_read_estatus() 367 ghes_copy_tofrom_phys(ghes->estatus + 1, ghes_read_estatus() 368 buf_paddr + sizeof(*ghes->estatus), ghes_read_estatus() 369 len - sizeof(*ghes->estatus), 1); ghes_read_estatus() 370 if (cper_estatus_check(ghes->estatus)) ghes_read_estatus() 381 static void ghes_clear_estatus(struct ghes *ghes) ghes_clear_estatus() argument 383 ghes->estatus->block_status = 0; ghes_clear_estatus() 384 if (!(ghes->flags & GHES_TO_CLEAR)) ghes_clear_estatus() 386 ghes_copy_tofrom_phys(ghes->estatus, ghes->buffer_paddr, ghes_clear_estatus() 387 sizeof(ghes->estatus->block_status), 0); ghes_clear_estatus() 388 ghes->flags &= ~GHES_TO_CLEAR; ghes_clear_estatus() 423 static void ghes_do_proc(struct ghes *ghes, ghes_do_proc() argument 436 ghes_edac_report_mem_error(ghes, sev, mem_err); apei_estatus_for_each_section() 646 static int ghes_proc(struct ghes *ghes) ghes_proc() argument 650 rc = ghes_read_estatus(ghes, 0); ghes_proc() 653 if (!ghes_estatus_cached(ghes->estatus)) { ghes_proc() 654 if (ghes_print_estatus(NULL, ghes->generic, ghes->estatus)) ghes_proc() 655 ghes_estatus_cache_add(ghes->generic, ghes->estatus); ghes_proc() 657 ghes_do_proc(ghes, ghes->estatus); ghes_proc() 659 ghes_clear_estatus(ghes); ghes_proc() 663 static void ghes_add_timer(struct ghes *ghes) ghes_add_timer() argument 665 struct acpi_hest_generic *g = ghes->generic; ghes_add_timer() 674 ghes->timer.expires = round_jiffies_relative(expire); ghes_add_timer() 675 add_timer(&ghes->timer); ghes_add_timer() 680 struct ghes *ghes = (void *)data; ghes_poll_func() local 682 ghes_proc(ghes); ghes_poll_func() 683 if (!(ghes->flags & GHES_EXITING)) ghes_poll_func() 684 ghes_add_timer(ghes); ghes_poll_func() 689 struct ghes *ghes = data; ghes_irq_func() local 692 rc = ghes_proc(ghes); ghes_irq_func() 702 struct ghes *ghes; ghes_notify_sci() local 706 list_for_each_entry_rcu(ghes, &ghes_sci, list) { ghes_notify_sci() 707 if (!ghes_proc(ghes)) ghes_notify_sci() 762 ghes_do_proc(estatus_node->ghes, estatus); ghes_proc_in_irq() 801 static void __process_error(struct ghes *ghes) __process_error() argument 808 if (ghes_estatus_cached(ghes->estatus)) __process_error() 811 len = cper_estatus_len(ghes->estatus); __process_error() 818 estatus_node->ghes = ghes; __process_error() 819 estatus_node->generic = ghes->generic; __process_error() 821 memcpy(estatus, ghes->estatus, len); __process_error() 826 static void __ghes_panic(struct ghes *ghes) __ghes_panic() argument 830 __ghes_print_estatus(KERN_EMERG, ghes->generic, ghes->estatus); __ghes_panic() 840 struct ghes *ghes; ghes_notify_nmi() local 846 list_for_each_entry_rcu(ghes, &ghes_nmi, list) { ghes_notify_nmi() 847 if (ghes_read_estatus(ghes, 1)) { ghes_notify_nmi() 848 ghes_clear_estatus(ghes); ghes_notify_nmi() 852 sev = ghes_severity(ghes->estatus->error_severity); ghes_notify_nmi() 854 __ghes_panic(ghes); ghes_notify_nmi() 856 if (!(ghes->flags & GHES_TO_CLEAR)) ghes_notify_nmi() 859 __process_error(ghes); ghes_notify_nmi() 860 ghes_clear_estatus(ghes); ghes_notify_nmi() 892 static void ghes_nmi_add(struct ghes *ghes) ghes_nmi_add() argument 896 len = ghes_esource_prealloc_size(ghes->generic); ghes_nmi_add() 900 register_nmi_handler(NMI_LOCAL, ghes_notify_nmi, 0, "ghes"); ghes_nmi_add() 901 list_add_rcu(&ghes->list, &ghes_nmi); ghes_nmi_add() 905 static void ghes_nmi_remove(struct ghes *ghes) ghes_nmi_remove() argument 910 list_del_rcu(&ghes->list); ghes_nmi_remove() 912 unregister_nmi_handler(NMI_LOCAL, "ghes"); ghes_nmi_remove() 915 * To synchronize with NMI handler, ghes can only be ghes_nmi_remove() 919 len = ghes_esource_prealloc_size(ghes->generic); ghes_nmi_remove() 928 static inline void ghes_nmi_add(struct ghes *ghes) ghes_nmi_add() argument 931 ghes->generic->header.source_id); ghes_nmi_add() 935 static inline void ghes_nmi_remove(struct ghes *ghes) ghes_nmi_remove() argument 938 ghes->generic->header.source_id); ghes_nmi_remove() 950 struct ghes *ghes = NULL; ghes_probe() local 988 ghes = ghes_new(generic); ghes_probe() 989 if (IS_ERR(ghes)) { ghes_probe() 990 rc = PTR_ERR(ghes); ghes_probe() 991 ghes = NULL; ghes_probe() 995 rc = ghes_edac_register(ghes, &ghes_dev->dev); ghes_probe() 1001 ghes->timer.function = ghes_poll_func; ghes_probe() 1002 ghes->timer.data = (unsigned long)ghes; ghes_probe() 1003 init_timer_deferrable(&ghes->timer); ghes_probe() 1004 ghes_add_timer(ghes); ghes_probe() 1008 rc = acpi_gsi_to_irq(generic->notify.vector, &ghes->irq); ghes_probe() 1014 rc = request_irq(ghes->irq, ghes_irq_func, 0, "GHES IRQ", ghes); ghes_probe() 1025 list_add_rcu(&ghes->list, &ghes_sci); ghes_probe() 1029 ghes_nmi_add(ghes); ghes_probe() 1034 platform_set_drvdata(ghes_dev, ghes); ghes_probe() 1038 ghes_edac_unregister(ghes); ghes_probe() 1040 if (ghes) { ghes_probe() 1041 ghes_fini(ghes); ghes_probe() 1042 kfree(ghes); ghes_probe() 1049 struct ghes *ghes; ghes_remove() local 1052 ghes = platform_get_drvdata(ghes_dev); ghes_remove() 1053 generic = ghes->generic; ghes_remove() 1055 ghes->flags |= GHES_EXITING; ghes_remove() 1058 del_timer_sync(&ghes->timer); ghes_remove() 1061 free_irq(ghes->irq, ghes); ghes_remove() 1065 list_del_rcu(&ghes->list); ghes_remove() 1071 ghes_nmi_remove(ghes); ghes_remove() 1078 ghes_fini(ghes); ghes_remove() 1080 ghes_edac_unregister(ghes); ghes_remove() 1082 kfree(ghes); ghes_remove()
|