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>
Tue, 12 Aug 2025 03:28:04 +0000 (05:28 +0200)
Forwarded: https://lore.kernel.org/all/51d3d738-cdf5-2992-bba5-c3e1f34096c2@infradead.org/

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 and indentation to apply to Linux 6.10]

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

arch/arm64/kernel/acpi.c

index e6f66491fbe932757c5da58391d0db472e5d2c9e..3235e11676db306e2e5b861fa461a15da959c688 100644 (file)
@@ -36,6 +36,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
@@ -257,6 +286,8 @@ done:
 
                if (IS_ENABLED(CONFIG_ACPI_BGRT))
                        acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt);
+       
+               acpi_fixup_m400_quirks();
        }
 }