apei_unmap_generic_address(&ghes->generic_v2->read_ack_register);
}
+static void ghes_ack_error(struct acpi_hest_generic_v2 *gv2)
+{
+ int rc;
+ u64 val = 0;
+
+ rc = apei_read(&val, &gv2->read_ack_register);
+ if (rc)
+ return;
+
+ val &= gv2->read_ack_preserve << gv2->read_ack_register.bit_offset;
+ val |= gv2->read_ack_write << gv2->read_ack_register.bit_offset;
+
+ apei_write(val, &gv2->read_ack_register);
+}
+
static struct ghes *ghes_new(struct acpi_hest_generic *generic)
{
struct ghes *ghes;
ghes_copy_tofrom_phys(ghes->estatus, buf_paddr,
sizeof(ghes->estatus->block_status), 0);
+
+ /*
+ * GHESv2 type HEST entries introduce support for error acknowledgment,
+ * so only acknowledge the error if this support is present.
+ */
+ if (is_hest_type_generic_v2(ghes))
+ ghes_ack_error(ghes->generic_v2);
}
static void ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, int sev)
rcu_read_unlock();
}
-static int ghes_ack_error(struct acpi_hest_generic_v2 *gv2)
-{
- int rc;
- u64 val = 0;
-
- rc = apei_read(&val, &gv2->read_ack_register);
- if (rc)
- return rc;
-
- val &= gv2->read_ack_preserve << gv2->read_ack_register.bit_offset;
- val |= gv2->read_ack_write << gv2->read_ack_register.bit_offset;
-
- return apei_write(val, &gv2->read_ack_register);
-}
-
static void __ghes_panic(struct ghes *ghes, u64 buf_paddr)
{
__ghes_print_estatus(KERN_EMERG, ghes->generic, ghes->estatus);
out:
ghes_clear_estatus(ghes, buf_paddr);
- if (rc == -ENOENT)
- return rc;
-
- /*
- * GHESv2 type HEST entries introduce support for error acknowledgment,
- * so only acknowledge the error if this support is present.
- */
- if (is_hest_type_generic_v2(ghes))
- return ghes_ack_error(ghes->generic_v2);
-
return rc;
}