[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <e41d0c8cc8b54643adc318c1bb7bd26c@huawei.com>
Date: Tue, 6 Aug 2024 11:13:25 +0000
From: Shiju Jose <shiju.jose@...wei.com>
To: Mauro Carvalho Chehab <mchehab+huawei@...nel.org>
CC: Jonathan Cameron <jonathan.cameron@...wei.com>, "Michael S. Tsirkin"
<mst@...hat.com>, Ani Sinha <anisinha@...hat.com>, Dongjiu Geng
<gengdongjiu1@...il.com>, Igor Mammedov <imammedo@...hat.com>,
"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
"qemu-arm@...gnu.org" <qemu-arm@...gnu.org>, "qemu-devel@...gnu.org"
<qemu-devel@...gnu.org>
Subject: RE: [PATCH v5 6/7] acpi/ghes: add support for generic error injection
via QAPI
>-----Original Message-----
>From: Mauro Carvalho Chehab <mchehab+huawei@...nel.org>
>Sent: 02 August 2024 22:44
>Cc: Jonathan Cameron <jonathan.cameron@...wei.com>; Shiju Jose
><shiju.jose@...wei.com>; Mauro Carvalho Chehab
><mchehab+huawei@...nel.org>; Michael S. Tsirkin <mst@...hat.com>; Ani
>Sinha <anisinha@...hat.com>; Dongjiu Geng <gengdongjiu1@...il.com>; Igor
>Mammedov <imammedo@...hat.com>; linux-kernel@...r.kernel.org; qemu-
>arm@...gnu.org; qemu-devel@...gnu.org
>Subject: [PATCH v5 6/7] acpi/ghes: add support for generic error injection via
>QAPI
>
>Provide a generic interface for error injection via GHESv2.
>
>This patch is co-authored:
> - original ghes logic to inject a simple ARM record by Shiju Jose;
> - generic logic to handle block addresses by Jonathan Cameron;
> - generic GHESv2 error inject by Mauro Carvalho Chehab;
>
>Co-authored-by: Jonathan Cameron <Jonathan.Cameron@...wei.com>
>Co-authored-by: Shiju Jose <shiju.jose@...wei.com>
>Co-authored-by: Mauro Carvalho Chehab <mchehab+huawei@...nel.org>
>Cc: Jonathan Cameron <Jonathan.Cameron@...wei.com>
>Cc: Shiju Jose <shiju.jose@...wei.com>
>Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@...nel.org>
Signed-off-by: Shiju Jose <shiju.jose@...wei.com>
>---
> hw/acpi/ghes.c | 159 ++++++++++++++++++++++++++++++++++++++---
> hw/acpi/ghes_cper.c | 2 +-
> include/hw/acpi/ghes.h | 3 +
> 3 files changed, 152 insertions(+), 12 deletions(-)
>
>diff --git a/hw/acpi/ghes.c b/hw/acpi/ghes.c index
>a745dcc7be5e..e125c9475773 100644
>--- a/hw/acpi/ghes.c
>+++ b/hw/acpi/ghes.c
>@@ -395,23 +395,22 @@ void acpi_ghes_add_fw_cfg(AcpiGhesState *ags,
>FWCfgState *s,
> ags->present = true;
> }
>
>+static uint64_t ghes_get_state_start_address(void)
>+{
>+ AcpiGedState *acpi_ged_state =
>+ ACPI_GED(object_resolve_path_type("", TYPE_ACPI_GED, NULL));
>+ AcpiGhesState *ags = &acpi_ged_state->ghes_state;
>+
>+ return le64_to_cpu(ags->ghes_addr_le); }
>+
> int acpi_ghes_record_errors(uint8_t source_id, uint64_t physical_address) {
> uint64_t error_block_addr, read_ack_register_addr, read_ack_register = 0;
>- uint64_t start_addr;
>+ uint64_t start_addr = ghes_get_state_start_address();
> bool ret = -1;
>- AcpiGedState *acpi_ged_state;
>- AcpiGhesState *ags;
>-
> assert(source_id < ACPI_HEST_SRC_ID_RESERVED);
>
>- acpi_ged_state = ACPI_GED(object_resolve_path_type("", TYPE_ACPI_GED,
>- NULL));
>- g_assert(acpi_ged_state);
>- ags = &acpi_ged_state->ghes_state;
>-
>- start_addr = le64_to_cpu(ags->ghes_addr_le);
>-
> if (physical_address) {
> start_addr += source_id * sizeof(uint64_t);
>
>@@ -448,9 +447,147 @@ int acpi_ghes_record_errors(uint8_t source_id,
>uint64_t physical_address)
> return ret;
> }
>
>+/*
>+ * Error register block data layout
>+ *
>+ * | +---------------------+ ges.ghes_addr_le
>+ * | |error_block_address0 |
>+ * | +---------------------+
>+ * | |error_block_address1 |
>+ * | +---------------------+ --+--
>+ * | | ............. | GHES_ADDRESS_SIZE
>+ * | +---------------------+ --+--
>+ * | |error_block_addressN |
>+ * | +---------------------+
>+ * | | read_ack0 |
>+ * | +---------------------+ --+--
>+ * | | read_ack1 | GHES_ADDRESS_SIZE
>+ * | +---------------------+ --+--
>+ * | | ............. |
>+ * | +---------------------+
>+ * | | read_ackN |
>+ * | +---------------------+ --+--
>+ * | | CPER | |
>+ * | | .... | GHES_MAX_RAW_DATA_LENGT
>+ * | | CPER | |
>+ * | +---------------------+ --+--
>+ * | | .......... |
>+ * | +---------------------+
>+ * | | CPER |
>+ * | | .... |
>+ * | | CPER |
>+ * | +---------------------+
>+ */
>+
>+/* Map from uint32_t notify to entry offset in GHES */ static const
>+uint8_t error_source_to_index[] = { 0xff, 0xff, 0xff, 0xff,
>+ 0xff, 0xff, 0xff, 1,
>+0};
>+
>+static bool ghes_get_addr(uint32_t notify, uint64_t *error_block_addr,
>+ uint64_t *read_ack_addr) {
>+ uint64_t base;
>+
>+ if (notify >= ACPI_GHES_NOTIFY_RESERVED) {
>+ return false;
>+ }
>+
>+ /* Find and check the source id for this new CPER */
>+ if (error_source_to_index[notify] == 0xff) {
>+ return false;
>+ }
>+
>+ base = ghes_get_state_start_address();
>+
>+ *read_ack_addr = base +
>+ ACPI_GHES_ERROR_SOURCE_COUNT * sizeof(uint64_t) +
>+ error_source_to_index[notify] * sizeof(uint64_t);
>+
>+ /* Could also be read back from the error_block_address register */
>+ *error_block_addr = base +
>+ ACPI_GHES_ERROR_SOURCE_COUNT * sizeof(uint64_t) +
>+ ACPI_GHES_ERROR_SOURCE_COUNT * sizeof(uint64_t) +
>+ error_source_to_index[notify] * ACPI_GHES_MAX_RAW_DATA_LENGTH;
>+
>+ return true;
>+}
>+
> NotifierList generic_error_notifiers =
> NOTIFIER_LIST_INITIALIZER(error_device_notifiers);
>
>+void ghes_record_cper_errors(AcpiGhesCper *cper, Error **errp,
>+ uint32_t notify) {
>+ int read_ack = 0;
>+ uint32_t i;
>+ uint64_t read_ack_addr = 0;
>+ uint64_t error_block_addr = 0;
>+ uint32_t data_length;
>+ GArray *block;
>+
>+ if (!ghes_get_addr(notify, &error_block_addr, &read_ack_addr)) {
>+ error_setg(errp, "GHES: Invalid error block/ack address(es)");
>+ return;
>+ }
>+
>+ cpu_physical_memory_read(read_ack_addr,
>+ &read_ack, sizeof(uint64_t));
>+
>+ /* zero means OSPM does not acknowledge the error */
>+ if (!read_ack) {
>+ error_setg(errp,
>+ "Last CPER record was not acknowledged yet");
>+ read_ack = 1;
>+ cpu_physical_memory_write(read_ack_addr,
>+ &read_ack, sizeof(uint64_t));
>+ return;
>+ }
>+
>+ read_ack = cpu_to_le64(0);
>+ cpu_physical_memory_write(read_ack_addr,
>+ &read_ack, sizeof(uint64_t));
>+
>+ /* Build CPER record */
>+
>+ /*
>+ * Invalid fru id: ACPI 4.0: 17.3.2.6.1 Generic Error Data,
>+ * Table 17-13 Generic Error Data Entry
>+ */
>+ QemuUUID fru_id = {};
>+
>+ block = g_array_new(false, true /* clear */, 1);
>+ data_length = ACPI_GHES_DATA_LENGTH + cper->data_len;
>+
>+ /*
>+ * It should not run out of the preallocated memory if
>+ * adding a new generic error data entry
>+ */
>+ assert((data_length + ACPI_GHES_GESB_SIZE) <=
>+ ACPI_GHES_MAX_RAW_DATA_LENGTH);
>+
>+ /* Build the new generic error status block header */
>+ acpi_ghes_generic_error_status(block, ACPI_GEBS_UNCORRECTABLE,
>+ 0, 0, data_length,
>+ ACPI_CPER_SEV_RECOVERABLE);
>+
>+ /* Build this new generic error data entry header */
>+ acpi_ghes_generic_error_data(block, cper->guid,
>+ ACPI_CPER_SEV_RECOVERABLE, 0, 0,
>+ cper->data_len, fru_id, 0);
>+
>+ /* Add CPER data */
>+ for (i = 0; i < cper->data_len; i++) {
>+ build_append_int_noprefix(block, cper->data[i], 1);
>+ }
>+
>+ /* Write the generic error data entry into guest memory */
>+ cpu_physical_memory_write(error_block_addr, block->data,
>+ block->len);
>+
>+ g_array_free(block, true);
>+
>+ notifier_list_notify(&generic_error_notifiers, NULL); }
>+
> bool acpi_ghes_present(void)
> {
> AcpiGedState *acpi_ged_state;
>diff --git a/hw/acpi/ghes_cper.c b/hw/acpi/ghes_cper.c index
>7aa7e71e90dc..d7ff7debee74 100644
>--- a/hw/acpi/ghes_cper.c
>+++ b/hw/acpi/ghes_cper.c
>@@ -39,7 +39,7 @@ void qmp_ghes_cper(CommonPlatformErrorRecord
>*qmp_cper,
> return;
> }
>
>- /* TODO: call a function at ghes */
>+ ghes_record_cper_errors(&cper, errp, ACPI_GHES_NOTIFY_GPIO);
>
> g_free(cper.data);
> }
>diff --git a/include/hw/acpi/ghes.h b/include/hw/acpi/ghes.h index
>06a5b8820cd5..ee6f6cd96911 100644
>--- a/include/hw/acpi/ghes.h
>+++ b/include/hw/acpi/ghes.h
>@@ -85,6 +85,9 @@ typedef struct AcpiGhesCper {
> size_t data_len;
> } AcpiGhesCper;
>
>+void ghes_record_cper_errors(AcpiGhesCper *cper, Error **errp,
>+ uint32_t notify);
>+
> /**
> * acpi_ghes_present: Report whether ACPI GHES table is present
> *
>--
>2.45.2
Powered by blists - more mailing lists