arm64/acpi: Add fixup for HPE m400 quirks
authorGeoff Levand <geoff@infradead.org>
Wed, 13 Jun 2018 17:56:08 +0000 (10:56 -0700)
committerSalvatore Bonaccorso <carnil@debian.org>
Wed, 8 Dec 2021 16:21:12 +0000 (16:21 +0000)
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]

Gbp-Pq: Topic bugfix/arm64
Gbp-Pq: Name arm64-acpi-Add-fixup-for-HPE-m400-quirks.patch

arch/arm64/kernel/acpi.c

index cada0b816c8a35a084d86e97797e39b8b1fa6d51..52badb8f542387c13943d6342f74e1adfd3ba3d8 100644 (file)
@@ -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);
@@ -177,6 +179,33 @@ out:
        return ret;
 }
 
+/*
+ * 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
@@ -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();
 }
 
 pgprot_t __acpi_get_mem_attribute(phys_addr_t addr)