summaryrefslogtreecommitdiffstats
path: root/debian/patches/bugfix/arm64/arm64-acpi-Add-fixup-for-HPE-m400-quirks.patch
blob: fc1e76a02bbc25c8606def596996ccccdb7abeed (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
From: Geoff Levand <geoff@infradead.org>
Date: Wed, 13 Jun 2018 10:56:08 -0700
Subject: arm64/acpi: Add fixup for HPE m400 quirks
Forwarded: https://patchwork.codeaurora.org/patch/547277/

Adds a new ACPI init routine acpi_fixup_m400_quirks that adds
a work-around for HPE ProLiant m400 APEI firmware problems.

The work-around disables APEI when CONFIG_ACPI_APEI is set and
m400 firmware is detected.  Without this fixup m400 systems
experience errors like these on startup:

  [Hardware Error]: Hardware error from APEI Generic Hardware Error Source: 2
  [Hardware Error]: event severity: fatal
  [Hardware Error]:  Error 0, type: fatal
  [Hardware Error]:   section_type: memory error
  [Hardware Error]:   error_status: 0x0000000000001300
  [Hardware Error]:   error_type: 10, invalid address
  Kernel panic - not syncing: Fatal hardware error!

Signed-off-by: Geoff Levand <geoff@infradead.org>
[bwh: Adjust context to apply to Linux 4.19]
---
 arch/arm64/kernel/acpi.c | 40 ++++++++++++++++++++++++++++++++++++----
 1 file changed, 36 insertions(+), 4 deletions(-)

Index: linux/arch/arm64/kernel/acpi.c
===================================================================
--- linux.orig/arch/arm64/kernel/acpi.c
+++ linux/arch/arm64/kernel/acpi.c
@@ -32,6 +32,8 @@
 #include <asm/daifflags.h>
 #include <asm/smp_plat.h>
 
+#include <acpi/apei.h>
+
 int acpi_noirq = 1;		/* skip ACPI IRQ initialization */
 int acpi_disabled = 1;
 EXPORT_SYMBOL(acpi_disabled);
@@ -178,6 +180,33 @@ out:
 }
 
 /*
+ * acpi_fixup_m400_quirks - Work-around for HPE ProLiant m400 APEI firmware
+ * problems.
+ */
+static void __init acpi_fixup_m400_quirks(void)
+{
+	acpi_status status;
+	struct acpi_table_header *header;
+#if !defined(CONFIG_ACPI_APEI)
+	int hest_disable = HEST_DISABLED;
+#endif
+
+	if (!IS_ENABLED(CONFIG_ACPI_APEI) || hest_disable != HEST_ENABLED)
+		return;
+
+	status = acpi_get_table(ACPI_SIG_HEST, 0, &header);
+
+	if (ACPI_SUCCESS(status) && !strncmp(header->oem_id, "HPE   ", 6) &&
+		!strncmp(header->oem_table_id, "ProLiant", 8) &&
+		MIDR_IMPLEMENTOR(read_cpuid_id()) == ARM_CPU_IMP_APM) {
+		hest_disable = HEST_DISABLED;
+		pr_info("Disabled APEI for m400.\n");
+	}
+
+	acpi_put_table(header);
+}
+
+/*
  * acpi_boot_table_init() called from setup_arch(), always.
  *	1. find RSDP and get its address, and then find XSDT
  *	2. extract all tables and checksums them all
@@ -232,11 +261,14 @@ done:
 	if (acpi_disabled) {
 		if (earlycon_acpi_spcr_enable)
 			early_init_dt_scan_chosen_stdout();
-	} else {
-		acpi_parse_spcr(earlycon_acpi_spcr_enable, true);
-		if (IS_ENABLED(CONFIG_ACPI_BGRT))
-			acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt);
+		return;
 	}
+
+	acpi_parse_spcr(earlycon_acpi_spcr_enable, true);
+	if (IS_ENABLED(CONFIG_ACPI_BGRT))
+		acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt);
+
+	acpi_fixup_m400_quirks();
 }
 
 static pgprot_t __acpi_get_writethrough_mem_attribute(void)