[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 16/31] acpi/ghes: Use HEST table offsets when preparing GHES reco
From: |
Mauro Carvalho Chehab |
Subject: |
[PATCH 16/31] acpi/ghes: Use HEST table offsets when preparing GHES records |
Date: |
Fri, 6 Dec 2024 18:12:38 +0100 |
There are two pointers that are needed during error injection:
1. The start address of the CPER block to be stored;
2. The address of the ack, which needs a reset before next error.
It is preferable to calculate them from the HEST table. This allows
checking the source ID, the size of the table and the type of the
HEST error block structures.
Yet, keep the old code, as this is needed for migration purposes.
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
hw/acpi/ghes.c | 106 ++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 96 insertions(+), 10 deletions(-)
diff --git a/hw/acpi/ghes.c b/hw/acpi/ghes.c
index 4a826c8ca6d4..af55bfe106bf 100644
--- a/hw/acpi/ghes.c
+++ b/hw/acpi/ghes.c
@@ -61,6 +61,25 @@
*/
#define ACPI_GHES_GESB_SIZE 20
+/*
+ * Offsets with regards to the start of the HEST table stored at
+ * ags->hest_addr_le, according with the memory layout map at
+ * docs/specs/acpi_hest_ghes.rst.
+ */
+
+/*
+ * ACPI 6.2: 18.3.2.8 Generic Hardware Error Source version 2
+ * Table 18-382 Generic Hardware Error Source version 2 (GHESv2) Structure
+ */
+#define HEST_GHES_V2_TABLE_SIZE 92
+#define GHES_ACK_OFFSET (64 + GAS_ADDR_OFFSET)
+
+/*
+ * ACPI 6.2: 18.3.2.7: Generic Hardware Error Source
+ * Table 18-380: 'Error Status Address' field
+ */
+#define GHES_ERR_ST_ADDR_OFFSET (20 + GAS_ADDR_OFFSET)
+
/*
* Values for error_severity field
*/
@@ -212,14 +231,6 @@ static void build_ghes_error_table(GArray
*hardware_errors, BIOSLinker *linker,
{
int i, error_status_block_offset;
- /*
- * TODO: Current version supports only one source.
- * A further patch will drop this check, after adding a proper migration
- * code, as, for the code to work, we need to store a bios pointer to the
- * HEST table.
- */
- assert(num_sources == 1);
-
/* Build error_block_address */
for (i = 0; i < num_sources; i++) {
build_append_int_noprefix(hardware_errors, 0, sizeof(uint64_t));
@@ -419,6 +430,76 @@ static void get_hw_error_offsets(uint64_t ghes_addr,
*read_ack_register_addr = ghes_addr + sizeof(uint64_t);
}
+static void get_ghes_source_offsets(uint16_t source_id, uint64_t hest_addr,
+ uint64_t *cper_addr,
+ uint64_t *read_ack_start_addr,
+ Error **errp)
+{
+ uint64_t hest_err_block_addr, hest_read_ack_addr;
+ uint64_t err_source_struct, error_block_addr;
+ uint32_t num_sources, i;
+
+ if (!hest_addr) {
+ return;
+ }
+
+ cpu_physical_memory_read(hest_addr, &num_sources, sizeof(num_sources));
+ num_sources = le32_to_cpu(num_sources);
+
+ err_source_struct = hest_addr + sizeof(num_sources);
+
+ /*
+ * Currently, HEST Error source navigates only for GHESv2 tables
+ */
+
+ for (i = 0; i < num_sources; i++) {
+ uint64_t addr = err_source_struct;
+ uint16_t type, src_id;
+
+ cpu_physical_memory_read(addr, &type, sizeof(type));
+ type = le16_to_cpu(type);
+
+ /* For now, we only know the size of GHESv2 table */
+ if (type != ACPI_GHES_SOURCE_GENERIC_ERROR_V2) {
+ error_setg(errp, "HEST: type %d not supported.", type);
+ return;
+ }
+
+ /* Compare CPER source address at the GHESv2 structure */
+ addr += sizeof(type);
+ cpu_physical_memory_read(addr, &src_id, sizeof(src_id));
+
+ if (src_id == source_id) {
+ break;
+ }
+
+ err_source_struct += HEST_GHES_V2_TABLE_SIZE;
+ }
+ if (i == num_sources) {
+ error_setg(errp, "HEST: Source %d not found.", source_id);
+ return;
+ }
+
+ /* Navigate though table address pointers */
+ hest_err_block_addr = err_source_struct + GHES_ERR_ST_ADDR_OFFSET;
+ hest_read_ack_addr = err_source_struct + GHES_ACK_OFFSET;
+
+ cpu_physical_memory_read(hest_err_block_addr, &error_block_addr,
+ sizeof(error_block_addr));
+
+ error_block_addr = le64_to_cpu(error_block_addr);
+
+ cpu_physical_memory_read(error_block_addr, cper_addr,
+ sizeof(*cper_addr));
+
+ *cper_addr = le64_to_cpu(*cper_addr);
+
+ cpu_physical_memory_read(hest_read_ack_addr, read_ack_start_addr,
+ sizeof(*read_ack_start_addr));
+
+ *read_ack_start_addr = le64_to_cpu(*read_ack_start_addr);
+}
+
void ghes_record_cper_errors(const void *cper, size_t len,
uint16_t source_id, Error **errp)
{
@@ -439,8 +520,13 @@ void ghes_record_cper_errors(const void *cper, size_t len,
}
ags = &acpi_ged_state->ghes_state;
- get_hw_error_offsets(le64_to_cpu(ags->hw_error_le),
- &cper_addr, &read_ack_register_addr);
+ if (!ags->hest_addr_le) {
+ get_hw_error_offsets(le64_to_cpu(ags->hw_error_le),
+ &cper_addr, &read_ack_register_addr);
+ } else {
+ get_ghes_source_offsets(source_id, le64_to_cpu(ags->hest_addr_le),
+ &cper_addr, &read_ack_register_addr, errp);
+ }
if (!cper_addr) {
error_setg(errp, "can not find Generic Error Status Block");
--
2.47.1
- [PATCH 01/31] acpi/ghes: get rid of ACPI_HEST_SRC_ID_RESERVED, (continued)
- [PATCH 01/31] acpi/ghes: get rid of ACPI_HEST_SRC_ID_RESERVED, Mauro Carvalho Chehab, 2024/12/06
- [PATCH 04/31] acpi/ghes: better handle source_id and notification, Mauro Carvalho Chehab, 2024/12/06
- [PATCH 06/31] acpi/ghes: Remove a duplicated out of bounds check, Mauro Carvalho Chehab, 2024/12/06
- [PATCH 12/31] acpi/ghes: rename etc/hardware_error file macros, Mauro Carvalho Chehab, 2024/12/06
- [PATCH 10/31] acpi/ghes: better name GHES memory error function, Mauro Carvalho Chehab, 2024/12/06
- [PATCH 15/31] acpi/ghes: add a firmware file with HEST address, Mauro Carvalho Chehab, 2024/12/06
- [PATCH 08/31] acpi/ghes: don't check if physical_address is not zero, Mauro Carvalho Chehab, 2024/12/06
- [PATCH 05/31] acpi/ghes: Fix acpi_ghes_record_errors() argument, Mauro Carvalho Chehab, 2024/12/06
- [PATCH 29/31] HACK: use GPIO as source ID for virt-9.1 machines, Mauro Carvalho Chehab, 2024/12/06
- [PATCH 03/31] acpi/ghes: simplify the per-arch caller to build HEST table, Mauro Carvalho Chehab, 2024/12/06
- [PATCH 16/31] acpi/ghes: Use HEST table offsets when preparing GHES records,
Mauro Carvalho Chehab <=
- [PATCH 19/31] acpi/ghes: add a notifier to notify when error data is ready, Mauro Carvalho Chehab, 2024/12/06
- [PATCH 07/31] acpi/ghes: Change the type for source_id, Mauro Carvalho Chehab, 2024/12/06
- [PATCH 11/31] acpi/ghes: don't crash QEMU if ghes GED is not found, Mauro Carvalho Chehab, 2024/12/06
- [PATCH 18/31] acpi/generic_event_device: add logic to detect if HEST addr is available, Mauro Carvalho Chehab, 2024/12/06
- [PATCH 31/31] FIXME: acpi/ghes: properly set data record size, Mauro Carvalho Chehab, 2024/12/06
- [PATCH 21/31] arm/virt: Wire up a GED error device for ACPI / GHES, Mauro Carvalho Chehab, 2024/12/06
- [PATCH 27/31] DEBUG, Mauro Carvalho Chehab, 2024/12/06