aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan (Zhixiong) Zhang <zjzhang@codeaurora.org>2017-06-21 14:17:10 -0400
committerWill Deacon <will.deacon@arm.com>2017-06-22 13:22:04 -0400
commit2fb5853e4442334cb66fc2ab33a51c91d4434769 (patch)
treeaeebdca1c62f8e899043b5918d1c45b578136c4c
parent7edda0886bc3d1e5418951558a2555af1bc73b0a (diff)
acpi: apei: panic OS with fatal error status block
Even if an error status block's severity is fatal, the kernel does not honor the severity level and panic. With the firmware first model, the platform could inform the OS about a fatal hardware error through the non-NMI GHES notification type. The OS should panic when a hardware error record is received with this severity. Call panic() after CPER data in error status block is printed if severity is fatal, before each error section is handled. Signed-off-by: Jonathan (Zhixiong) Zhang <zjzhang@codeaurora.org> Signed-off-by: Tyler Baicar <tbaicar@codeaurora.org> Reviewed-by: James Morse <james.morse@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
-rw-r--r--drivers/acpi/apei/ghes.c36
1 files changed, 21 insertions, 15 deletions
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 42ddc0eff25b..7a91ac7d6b75 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -135,6 +135,8 @@ static unsigned long ghes_estatus_pool_size_request;
135static struct ghes_estatus_cache *ghes_estatus_caches[GHES_ESTATUS_CACHES_SIZE]; 135static struct ghes_estatus_cache *ghes_estatus_caches[GHES_ESTATUS_CACHES_SIZE];
136static atomic_t ghes_estatus_cache_alloced; 136static atomic_t ghes_estatus_cache_alloced;
137 137
138static int ghes_panic_timeout __read_mostly = 30;
139
138static int ghes_ioremap_init(void) 140static int ghes_ioremap_init(void)
139{ 141{
140 ghes_ioremap_area = __get_vm_area(PAGE_SIZE * GHES_IOREMAP_PAGES, 142 ghes_ioremap_area = __get_vm_area(PAGE_SIZE * GHES_IOREMAP_PAGES,
@@ -691,6 +693,16 @@ static int ghes_ack_error(struct acpi_hest_generic_v2 *gv2)
691 return apei_write(val, &gv2->read_ack_register); 693 return apei_write(val, &gv2->read_ack_register);
692} 694}
693 695
696static void __ghes_panic(struct ghes *ghes)
697{
698 __ghes_print_estatus(KERN_EMERG, ghes->generic, ghes->estatus);
699
700 /* reboot to log the error! */
701 if (!panic_timeout)
702 panic_timeout = ghes_panic_timeout;
703 panic("Fatal hardware error!");
704}
705
694static int ghes_proc(struct ghes *ghes) 706static int ghes_proc(struct ghes *ghes)
695{ 707{
696 int rc; 708 int rc;
@@ -698,6 +710,11 @@ static int ghes_proc(struct ghes *ghes)
698 rc = ghes_read_estatus(ghes, 0); 710 rc = ghes_read_estatus(ghes, 0);
699 if (rc) 711 if (rc)
700 goto out; 712 goto out;
713
714 if (ghes_severity(ghes->estatus->error_severity) >= GHES_SEV_PANIC) {
715 __ghes_panic(ghes);
716 }
717
701 if (!ghes_estatus_cached(ghes->estatus)) { 718 if (!ghes_estatus_cached(ghes->estatus)) {
702 if (ghes_print_estatus(NULL, ghes->generic, ghes->estatus)) 719 if (ghes_print_estatus(NULL, ghes->generic, ghes->estatus))
703 ghes_estatus_cache_add(ghes->generic, ghes->estatus); 720 ghes_estatus_cache_add(ghes->generic, ghes->estatus);
@@ -838,8 +855,6 @@ static atomic_t ghes_in_nmi = ATOMIC_INIT(0);
838 855
839static LIST_HEAD(ghes_nmi); 856static LIST_HEAD(ghes_nmi);
840 857
841static int ghes_panic_timeout __read_mostly = 30;
842
843static void ghes_proc_in_irq(struct irq_work *irq_work) 858static void ghes_proc_in_irq(struct irq_work *irq_work)
844{ 859{
845 struct llist_node *llnode, *next; 860 struct llist_node *llnode, *next;
@@ -925,18 +940,6 @@ static void __process_error(struct ghes *ghes)
925#endif 940#endif
926} 941}
927 942
928static void __ghes_panic(struct ghes *ghes)
929{
930 oops_begin();
931 ghes_print_queued_estatus();
932 __ghes_print_estatus(KERN_EMERG, ghes->generic, ghes->estatus);
933
934 /* reboot to log the error! */
935 if (panic_timeout == 0)
936 panic_timeout = ghes_panic_timeout;
937 panic("Fatal hardware error!");
938}
939
940static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs) 943static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs)
941{ 944{
942 struct ghes *ghes; 945 struct ghes *ghes;
@@ -954,8 +957,11 @@ static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs)
954 } 957 }
955 958
956 sev = ghes_severity(ghes->estatus->error_severity); 959 sev = ghes_severity(ghes->estatus->error_severity);
957 if (sev >= GHES_SEV_PANIC) 960 if (sev >= GHES_SEV_PANIC) {
961 oops_begin();
962 ghes_print_queued_estatus();
958 __ghes_panic(ghes); 963 __ghes_panic(ghes);
964 }
959 965
960 if (!(ghes->flags & GHES_TO_CLEAR)) 966 if (!(ghes->flags & GHES_TO_CLEAR))
961 continue; 967 continue;