From patchwork Wed Jan 22 15:46:27 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mauro Carvalho Chehab X-Patchwork-Id: 13947469 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A68C1C02181 for ; Wed, 22 Jan 2025 15:48:55 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tacwy-00054d-Mp; Wed, 22 Jan 2025 10:47:28 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tacwR-0004wI-BR; Wed, 22 Jan 2025 10:46:55 -0500 Received: from nyc.source.kernel.org ([2604:1380:45d1:ec00::3]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tacwM-0006qz-Cf; Wed, 22 Jan 2025 10:46:55 -0500 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by nyc.source.kernel.org (Postfix) with ESMTP id 53657A427E8; Wed, 22 Jan 2025 15:44:53 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id CBE71C4CED3; Wed, 22 Jan 2025 15:46:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1737560800; bh=gNd/oien5ab4E+a/S+M7dtTjBLqG3TRj5B0MchMTDzs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qUHYT1h/lO8bI1I3n444Mk5xsRWYWI8spgje0IA/kvf+AU6uS8O3JQwaKbK8kNACU A0MfF3IjTDUutGptDWHO4++z2hdzIQIubS5Jdg6BcdpMXM8tRS//HW2G0bYYx8d6WS opd/kcAXTQ5rYD2yMYlt2mh7g4/5/UQzxUC5SIIT9IzAWiXoLAehQXBBxrOQn8XHcs h4Ez2w6fYpWa4xjF2ZJ90vlHoTv8TdocfCpAPLB93ec583C4UA86909GsN7pjYDILm R3blRpMmolFCl4zD46L/laiFThcvOxgcem3LMCldmTF1E0Ge0z3GzOhaFYxw8GMtHw Zlh0+bzT1iRCg== Received: from mchehab by mail.kernel.org with local (Exim 4.98) (envelope-from ) id 1tacwA-00000008ogs-06Jd; Wed, 22 Jan 2025 16:46:38 +0100 From: Mauro Carvalho Chehab To: Igor Mammedov , "Michael S . Tsirkin" Cc: Jonathan Cameron , Shiju Jose , qemu-arm@nongnu.org, qemu-devel@nongnu.org, Mauro Carvalho Chehab , Ani Sinha , Dongjiu Geng , Eric Blake , Markus Armbruster , Michael Roth , Paolo Bonzini , Peter Maydell , Shannon Zhao , linux-kernel@vger.kernel.org Subject: [PATCH 10/11] qapi/acpi-hest: add an interface to do generic CPER error injection Date: Wed, 22 Jan 2025 16:46:27 +0100 Message-ID: <769b68a3192cc921fec4c0e5e925552920fdbe71.1737560101.git.mchehab+huawei@kernel.org> X-Mailer: git-send-email 2.48.1 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=2604:1380:45d1:ec00::3; envelope-from=mchehab+huawei@kernel.org; helo=nyc.source.kernel.org X-Spam_score_int: -73 X-Spam_score: -7.4 X-Spam_bar: ------- X-Spam_report: (-7.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-2.996, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Creates a QMP command to be used for generic ACPI APEI hardware error injection (HEST) via GHESv2, and add support for it for ARM guests. Error injection uses ACPI_HEST_SRC_ID_QMP source ID to be platform independent. This is mapped at arch virt bindings, depending on the types supported by QEMU and by the BIOS. So, on ARM, this is supported via ACPI_GHES_NOTIFY_GPIO notification type. 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 Co-authored-by: Shiju Jose Co-authored-by: Mauro Carvalho Chehab Signed-off-by: Jonathan Cameron Signed-off-by: Shiju Jose Signed-off-by: Mauro Carvalho Chehab --- Changes since v9: - ARM source IDs renamed to reflect SYNC/ASYNC; - command name changed to better reflect what it does; - some improvements at JSON documentation; - add a check for QMP source at the notification logic. Signed-off-by: Mauro Carvalho Chehab --- MAINTAINERS | 7 +++++++ hw/acpi/Kconfig | 5 +++++ hw/acpi/ghes.c | 2 +- hw/acpi/ghes_cper.c | 32 ++++++++++++++++++++++++++++++++ hw/acpi/ghes_cper_stub.c | 19 +++++++++++++++++++ hw/acpi/meson.build | 2 ++ hw/arm/virt-acpi-build.c | 1 + hw/arm/virt.c | 7 +++++++ include/hw/acpi/ghes.h | 1 + include/hw/arm/virt.h | 1 + qapi/acpi-hest.json | 35 +++++++++++++++++++++++++++++++++++ qapi/meson.build | 1 + qapi/qapi-schema.json | 1 + 13 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 hw/acpi/ghes_cper.c create mode 100644 hw/acpi/ghes_cper_stub.c create mode 100644 qapi/acpi-hest.json diff --git a/MAINTAINERS b/MAINTAINERS index 846b81e3ec03..8e1f662fa0e0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2075,6 +2075,13 @@ F: hw/acpi/ghes.c F: include/hw/acpi/ghes.h F: docs/specs/acpi_hest_ghes.rst +ACPI/HEST/GHES/ARM processor CPER +R: Mauro Carvalho Chehab +S: Maintained +F: hw/arm/ghes_cper.c +F: hw/acpi/ghes_cper_stub.c +F: qapi/acpi-hest.json + ppc4xx L: qemu-ppc@nongnu.org S: Orphan diff --git a/hw/acpi/Kconfig b/hw/acpi/Kconfig index 1d4e9f0845c0..daabbe6cd11e 100644 --- a/hw/acpi/Kconfig +++ b/hw/acpi/Kconfig @@ -51,6 +51,11 @@ config ACPI_APEI bool depends on ACPI +config GHES_CPER + bool + depends on ACPI_APEI + default y + config ACPI_PCI bool depends on ACPI && PCI diff --git a/hw/acpi/ghes.c b/hw/acpi/ghes.c index 5d29db3918dd..cf83c959b5ef 100644 --- a/hw/acpi/ghes.c +++ b/hw/acpi/ghes.c @@ -547,7 +547,7 @@ void ghes_record_cper_errors(const void *cper, size_t len, /* Write the generic error data entry into guest memory */ cpu_physical_memory_write(cper_addr, cper, len); - notifier_list_notify(&acpi_generic_error_notifiers, NULL); + notifier_list_notify(&acpi_generic_error_notifiers, &source_id); } int acpi_ghes_memory_errors(uint16_t source_id, uint64_t physical_address) diff --git a/hw/acpi/ghes_cper.c b/hw/acpi/ghes_cper.c new file mode 100644 index 000000000000..02c47b41b990 --- /dev/null +++ b/hw/acpi/ghes_cper.c @@ -0,0 +1,32 @@ +/* + * CPER payload parser for error injection + * + * Copyright(C) 2024 Huawei LTD. + * + * This code is licensed under the GPL version 2 or later. See the + * COPYING file in the top-level directory. + * + */ + +#include "qemu/osdep.h" + +#include "qemu/base64.h" +#include "qemu/error-report.h" +#include "qemu/uuid.h" +#include "qapi/qapi-commands-acpi-hest.h" +#include "hw/acpi/ghes.h" + +void qmp_inject_ghes_error(const char *qmp_cper, Error **errp) +{ + + uint8_t *cper; + size_t len; + + cper = qbase64_decode(qmp_cper, -1, &len, errp); + if (!cper) { + error_setg(errp, "missing GHES CPER payload"); + return; + } + + ghes_record_cper_errors(cper, len, ACPI_HEST_SRC_ID_QMP, errp); +} diff --git a/hw/acpi/ghes_cper_stub.c b/hw/acpi/ghes_cper_stub.c new file mode 100644 index 000000000000..8782e2c02fa8 --- /dev/null +++ b/hw/acpi/ghes_cper_stub.c @@ -0,0 +1,19 @@ +/* + * Stub interface for CPER payload parser for error injection + * + * Copyright(C) 2024 Huawei LTD. + * + * This code is licensed under the GPL version 2 or later. See the + * COPYING file in the top-level directory. + * + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "qapi/qapi-commands-acpi-hest.h" +#include "hw/acpi/ghes.h" + +void qmp_inject_ghes_error(const char *cper, Error **errp) +{ + error_setg(errp, "GHES QMP error inject is not compiled in"); +} diff --git a/hw/acpi/meson.build b/hw/acpi/meson.build index 73f02b96912b..56b5d1ec9691 100644 --- a/hw/acpi/meson.build +++ b/hw/acpi/meson.build @@ -34,4 +34,6 @@ endif system_ss.add(when: 'CONFIG_ACPI', if_false: files('acpi-stub.c', 'aml-build-stub.c', 'ghes-stub.c', 'acpi_interface.c')) system_ss.add(when: 'CONFIG_ACPI_PCI_BRIDGE', if_false: files('pci-bridge-stub.c')) system_ss.add_all(when: 'CONFIG_ACPI', if_true: acpi_ss) +system_ss.add(when: 'CONFIG_GHES_CPER', if_true: files('ghes_cper.c')) +system_ss.add(when: 'CONFIG_GHES_CPER', if_false: files('ghes_cper_stub.c')) system_ss.add(files('acpi-qmp-cmds.c')) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index ae60268bdcc2..d094212ce584 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -896,6 +896,7 @@ static void acpi_align_size(GArray *blob, unsigned align) static const AcpiNotificationSourceId hest_ghes_notify[] = { { ACPI_HEST_SRC_ID_SYNC, ACPI_GHES_NOTIFY_SEA }, + { ACPI_HEST_SRC_ID_QMP, ACPI_GHES_NOTIFY_GPIO }, }; static const AcpiNotificationSourceId hest_ghes_notify_9_2[] = { diff --git a/hw/arm/virt.c b/hw/arm/virt.c index e272b35ea114..9074a540197d 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -1012,6 +1012,13 @@ static void virt_powerdown_req(Notifier *n, void *opaque) static void virt_generic_error_req(Notifier *n, void *opaque) { + uint16_t *source_id = opaque; + + /* Currently, only QMP source ID is async */ + if (*source_id != ACPI_HEST_SRC_ID_QMP) { + return; + } + VirtMachineState *s = container_of(n, VirtMachineState, generic_error_notifier); acpi_send_event(s->acpi_dev, ACPI_GENERIC_ERROR); diff --git a/include/hw/acpi/ghes.h b/include/hw/acpi/ghes.h index 64fe2b5bea65..078d78666f91 100644 --- a/include/hw/acpi/ghes.h +++ b/include/hw/acpi/ghes.h @@ -72,6 +72,7 @@ typedef struct AcpiGhesState { */ enum AcpiGhesSourceID { ACPI_HEST_SRC_ID_SYNC, + ACPI_HEST_SRC_ID_QMP, /* Use it only for QMP injected errors */ }; typedef struct AcpiNotificationSourceId { diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index f3cf28436770..56f270f61cf5 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -33,6 +33,7 @@ #include "exec/hwaddr.h" #include "qemu/notify.h" #include "hw/boards.h" +#include "hw/acpi/ghes.h" #include "hw/arm/boot.h" #include "hw/arm/bsa.h" #include "hw/block/flash.h" diff --git a/qapi/acpi-hest.json b/qapi/acpi-hest.json new file mode 100644 index 000000000000..d58fba485180 --- /dev/null +++ b/qapi/acpi-hest.json @@ -0,0 +1,35 @@ +# -*- Mode: Python -*- +# vim: filetype=python + +## +# == GHESv2 CPER Error Injection +# +# Defined since ACPI Specification 6.1, +# section 18.3.2.8 Generic Hardware Error Source version 2. See: +# +# https://uefi.org/sites/default/files/resources/ACPI_6_1.pdf +## + + +## +# @inject-ghes-error: +# +# Inject an error with additional ACPI 6.1 GHESv2 error information +# +# @cper: contains a base64 encoded string with raw data for a single +# CPER record with Generic Error Status Block, Generic Error Data +# Entry and generic error data payload, as described at +# https://uefi.org/specs/UEFI/2.10/Apx_N_Common_Platform_Error_Record.html#format +# +# Features: +# +# @unstable: This command is experimental. +# +# Since: 9.2 +## +{ 'command': 'inject-ghes-error', + 'data': { + 'cper': 'str' + }, + 'features': [ 'unstable' ] +} diff --git a/qapi/meson.build b/qapi/meson.build index e7bc54e5d047..35cea6147262 100644 --- a/qapi/meson.build +++ b/qapi/meson.build @@ -59,6 +59,7 @@ qapi_all_modules = [ if have_system qapi_all_modules += [ 'acpi', + 'acpi-hest', 'audio', 'cryptodev', 'qdev', diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json index b1581988e4eb..baf19ab73afe 100644 --- a/qapi/qapi-schema.json +++ b/qapi/qapi-schema.json @@ -75,6 +75,7 @@ { 'include': 'misc-target.json' } { 'include': 'audio.json' } { 'include': 'acpi.json' } +{ 'include': 'acpi-hest.json' } { 'include': 'pci.json' } { 'include': 'stats.json' } { 'include': 'virtio.json' }