return ghes->generic->header.type == ACPI_HEST_TYPE_GENERIC_ERROR_V2;
 }
 
+/*
+ * A platform may describe one error source for the handling of synchronous
+ * errors (e.g. MCE or SEA), or for handling asynchronous errors (e.g. SCI
+ * or External Interrupt). On x86, the HEST notifications are always
+ * asynchronous, so only SEA on ARM is delivered as a synchronous
+ * notification.
+ */
+static inline bool is_hest_sync_notify(struct ghes *ghes)
+{
+       u8 notify_type = ghes->generic->notify.type;
+
+       return notify_type == ACPI_HEST_NOTIFY_SEA;
+}
+
 /*
  * This driver isn't really modular, however for the time being,
  * continuing to use module_param is the easiest way to remain
 }
 
 static bool ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata,
-                                      int sev)
+                                      int sev, bool sync)
 {
        int flags = -1;
        int sec_sev = ghes_severity(gdata->error_severity);
            (gdata->flags & CPER_SEC_ERROR_THRESHOLD_EXCEEDED))
                flags = MF_SOFT_OFFLINE;
        if (sev == GHES_SEV_RECOVERABLE && sec_sev == GHES_SEV_RECOVERABLE)
-               flags = 0;
+               flags = sync ? MF_ACTION_REQUIRED : 0;
 
        if (flags != -1)
                return ghes_do_memory_failure(mem_err->physical_addr, flags);
        return false;
 }
 
-static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata, int sev)
+static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata,
+                                      int sev, bool sync)
 {
        struct cper_sec_proc_arm *err = acpi_hest_get_payload(gdata);
+       int flags = sync ? MF_ACTION_REQUIRED : 0;
        bool queued = false;
        int sec_sev, i;
        char *p;
                 * and don't filter out 'corrected' error here.
                 */
                if (is_cache && has_pa) {
-                       queued = ghes_do_memory_failure(err_info->physical_fault_addr, 0);
+                       queued = ghes_do_memory_failure(err_info->physical_fault_addr, flags);
                        p += err_info->length;
                        continue;
                }
        const guid_t *fru_id = &guid_null;
        char *fru_text = "";
        bool queued = false;
+       bool sync = is_hest_sync_notify(ghes);
 
        sev = ghes_severity(estatus->error_severity);
        apei_estatus_for_each_section(estatus, gdata) {
                        atomic_notifier_call_chain(&ghes_report_chain, sev, mem_err);
 
                        arch_apei_report_mem_error(sev, mem_err);
-                       queued = ghes_handle_memory_failure(gdata, sev);
+                       queued = ghes_handle_memory_failure(gdata, sev, sync);
                }
                else if (guid_equal(sec_type, &CPER_SEC_PCIE)) {
                        ghes_handle_aer(gdata);
                }
                else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) {
-                       queued = ghes_handle_arm_hw_error(gdata, sev);
+                       queued = ghes_handle_arm_hw_error(gdata, sev, sync);
                } else {
                        void *err = acpi_hest_get_payload(gdata);