From patchwork Thu Jul 11 09:52:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mauro Carvalho Chehab X-Patchwork-Id: 13730268 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 37764C3DA47 for ; Thu, 11 Jul 2024 09:53:31 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sRqTl-000545-BE; Thu, 11 Jul 2024 05:52:45 -0400 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 1sRqTc-0004gb-2U; Thu, 11 Jul 2024 05:52:37 -0400 Received: from sin.source.kernel.org ([2604:1380:40e1:4800::1]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sRqTY-0006Wl-HE; Thu, 11 Jul 2024 05:52:35 -0400 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by sin.source.kernel.org (Postfix) with ESMTP id 594DACE182F; Thu, 11 Jul 2024 09:52:21 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 85B2BC4AF0A; Thu, 11 Jul 2024 09:52:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1720691540; bh=oPxrpTAEvoEtkTNmqS8GMR2oMRzJETZZcVQAB+T3Viw=; h=From:To:List-Id:Cc:Subject:Date:In-Reply-To:References:From; b=qe4YXY+v9IEsXJoyvwYfwUUE5tJKEkbkLOSH65iqoHll3BpSa1n9JdaCE6yGg2czm 4ZaXWQmb7nmYajK0fgqEZ7ko4rKA58Y0Dk45I+sgGNdIEvm8pBgQfX8nuaj6+UWTP3 IBJ3hB1xofkj9jbYj8t7vedwaI39yo852qGykjJ4xyMngYaXg+S35ql4IXVHFEdJ90 utSfSwW/bEnheSC4HNv8ZKROe51DU56fKFWlc22Cmwyq+5OLr6DgUdBprWbymrJhHr ndaTGObokLJtD8WE53UWHcn+R0okVvszAZRY/KjXnUigZ7SK0BkxhRO7geDQcPziTA Zbi8T6wMflbrQ== Received: from mchehab by mail.kernel.org with local (Exim 4.97.1) (envelope-from ) id 1sRqTK-00000002jZd-2RXJ; Thu, 11 Jul 2024 11:52:18 +0200 From: Mauro Carvalho Chehab To: Cc: Jonathan Cameron , "Michael S. Tsirkin" , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , Ani Sinha , Eduardo Habkost , Igor Mammedov , Marcel Apfelbaum , Peter Maydell , Shannon Zhao , Yanan Wang , linux-edac@kernel.org, linux-kernel@vger.kernel.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, Mauro Carvalho Chehab Subject: [PATCH 1/6] arm/virt: Wire up GPIO error source for ACPI / GHES Date: Thu, 11 Jul 2024 11:52:03 +0200 Message-ID: X-Mailer: git-send-email 2.45.2 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=2604:1380:40e1:4800::1; envelope-from=mchehab@kernel.org; helo=sin.source.kernel.org X-Spam_score_int: -44 X-Spam_score: -4.5 X-Spam_bar: ---- X-Spam_report: (-4.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.144, 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 From: Jonathan Cameron Creates a GED - Generic Event Device and set a GPIO to be used or error injection. Signed-off-by: Jonathan Cameron Signed-off-by: Mauro Carvalho Chehab --- hw/arm/virt-acpi-build.c | 29 +++++++++++++++++++++++++---- hw/arm/virt.c | 12 +++++++++++- include/hw/boards.h | 1 + 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index e10cad86dd73..b6f2e55014a2 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -63,6 +63,7 @@ #define ARM_SPI_BASE 32 +#define ACPI_GENERIC_EVENT_DEVICE "GEDD" #define ACPI_BUILD_TABLE_SIZE 0x20000 static void acpi_dsdt_add_cpus(Aml *scope, VirtMachineState *vms) @@ -155,9 +156,14 @@ static void acpi_dsdt_add_gpio(Aml *scope, const MemMapEntry *gpio_memmap, Aml *aei = aml_resource_template(); /* Pin 3 for power button */ - const uint32_t pin_list[1] = {3}; + uint32_t pin = 3; aml_append(aei, aml_gpio_int(AML_CONSUMER, AML_EDGE, AML_ACTIVE_HIGH, - AML_EXCLUSIVE, AML_PULL_UP, 0, pin_list, 1, + AML_EXCLUSIVE, AML_PULL_UP, 0, &pin, 1, + "GPO0", NULL, 0)); + pin = 6; + /* Pin 8 for generic error */ + aml_append(aei, aml_gpio_int(AML_CONSUMER, AML_EDGE, AML_ACTIVE_HIGH, + AML_EXCLUSIVE, AML_PULL_UP, 0, &pin, 1, "GPO0", NULL, 0)); aml_append(dev, aml_name_decl("_AEI", aei)); @@ -166,6 +172,11 @@ static void acpi_dsdt_add_gpio(Aml *scope, const MemMapEntry *gpio_memmap, aml_append(method, aml_notify(aml_name(ACPI_POWER_BUTTON_DEVICE), aml_int(0x80))); aml_append(dev, method); + method = aml_method("_E06", 0, AML_NOTSERIALIZED); + aml_append(method, aml_notify(aml_name(ACPI_GENERIC_EVENT_DEVICE), + aml_int(0x80))); + aml_append(dev, method); + aml_append(scope, dev); } @@ -800,6 +811,15 @@ static void build_fadt_rev6(GArray *table_data, BIOSLinker *linker, build_fadt(table_data, linker, &fadt, vms->oem_id, vms->oem_table_id); } +static void acpi_dsdt_add_generic_event_device(Aml *scope) +{ + Aml *dev = aml_device(ACPI_GENERIC_EVENT_DEVICE); + aml_append(dev, aml_name_decl("_HID", aml_string("PNP0C33"))); + aml_append(dev, aml_name_decl("_UID", aml_int(0))); + aml_append(dev, aml_name_decl("_STA", aml_int(0xF))); + aml_append(scope, dev); +} + /* DSDT */ static void build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) @@ -842,9 +862,9 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) irqmap[VIRT_ACPI_GED] + ARM_SPI_BASE, AML_SYSTEM_MEMORY, memmap[VIRT_ACPI_GED].base); } else { - acpi_dsdt_add_gpio(scope, &memmap[VIRT_GPIO], - (irqmap[VIRT_GPIO] + ARM_SPI_BASE)); } + acpi_dsdt_add_gpio(scope, &memmap[VIRT_GPIO], + (irqmap[VIRT_GPIO] + ARM_SPI_BASE)); if (vms->acpi_dev) { uint32_t event = object_property_get_uint(OBJECT(vms->acpi_dev), @@ -858,6 +878,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) } acpi_dsdt_add_power_button(scope); + acpi_dsdt_add_generic_event_device(scope); #ifdef CONFIG_TPM acpi_dsdt_add_tpm(scope, vms); #endif diff --git a/hw/arm/virt.c b/hw/arm/virt.c index b0c68d66a345..874a8612ef2d 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -997,6 +997,13 @@ static void create_rtc(const VirtMachineState *vms) } static DeviceState *gpio_key_dev; + +static DeviceState *gpio_error_dev; +static void virt_set_error(void) +{ + qemu_set_irq(qdev_get_gpio_in(gpio_error_dev, 0), 1); +} + static void virt_powerdown_req(Notifier *n, void *opaque) { VirtMachineState *s = container_of(n, VirtMachineState, powerdown_notifier); @@ -1014,6 +1021,8 @@ static void create_gpio_keys(char *fdt, DeviceState *pl061_dev, { gpio_key_dev = sysbus_create_simple("gpio-key", -1, qdev_get_gpio_in(pl061_dev, 3)); + gpio_error_dev = sysbus_create_simple("gpio-key", -1, + qdev_get_gpio_in(pl061_dev, 6)); qemu_fdt_add_subnode(fdt, "/gpio-keys"); qemu_fdt_setprop_string(fdt, "/gpio-keys", "compatible", "gpio-keys"); @@ -2385,8 +2394,8 @@ static void machvirt_init(MachineState *machine) if (has_ged && aarch64 && firmware_loaded && virt_is_acpi_enabled(vms)) { vms->acpi_dev = create_acpi_ged(vms); } else { - create_gpio_devices(vms, VIRT_GPIO, sysmem); } + create_gpio_devices(vms, VIRT_GPIO, sysmem); if (vms->secure && !vmc->no_secure_gpio) { create_gpio_devices(vms, VIRT_SECURE_GPIO, secure_sysmem); @@ -3100,6 +3109,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data) mc->default_ram_id = "mach-virt.ram"; mc->default_nic = "virtio-net-pci"; + mc->set_error = virt_set_error; object_class_property_add(oc, "acpi", "OnOffAuto", virt_get_acpi, virt_set_acpi, NULL, NULL); diff --git a/include/hw/boards.h b/include/hw/boards.h index ef6f18f2c1a7..6cf01f3934ae 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -304,6 +304,7 @@ struct MachineClass { const CPUArchIdList *(*possible_cpu_arch_ids)(MachineState *machine); int64_t (*get_default_cpu_node_id)(const MachineState *ms, int idx); ram_addr_t (*fixup_ram_size)(ram_addr_t size); + void (*set_error)(void); }; /** From patchwork Thu Jul 11 09:52:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mauro Carvalho Chehab X-Patchwork-Id: 13730266 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 709D8C3DA41 for ; Thu, 11 Jul 2024 09:52:53 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sRqTj-0004o8-MA; Thu, 11 Jul 2024 05:52:43 -0400 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 1sRqTZ-0004Vv-JX; Thu, 11 Jul 2024 05:52:33 -0400 Received: from dfw.source.kernel.org ([2604:1380:4641:c500::1]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sRqTW-0006Wg-7R; Thu, 11 Jul 2024 05:52:33 -0400 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by dfw.source.kernel.org (Postfix) with ESMTP id D397C61C35; Thu, 11 Jul 2024 09:52:20 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 803F6C116B1; Thu, 11 Jul 2024 09:52:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1720691540; bh=3+tNSaQ8a39Ggzkv/WVrggnD0uGXWcuNnDojR+LSc44=; h=From:To:List-Id:Cc:Subject:Date:In-Reply-To:References:From; b=VIk+8Q3Vgaa7WC4h1rWszKNeWjJebWyRZ5FSwK6v4zG4HJkoovt6uEjZkPRE/Rafh 80cbbe51PIFuCIPSL3h8zM3XcjTW1NomyGnufC/Q7k89lUUnrUwDJ6/bueWu8YXqFA G8L42iM80+wO/twy86CDYAoNBEQzqKKBIfR3LTOqtJQkwB+neaZCaGOgGFYReA1Ca2 XRaGmoW9Tn49w4jkII0pzVb+O8QlY2Pg89Piqfl0c1gsa9rZVgg04A24k8L+ueHKbI EAkT8HXGzuOfLMrOiIuLcf4oSyDXnk4txenoMfugsGqLmO1Sfgl5kM8jasM1aiNnYa BXNUa42SrTiHw== Received: from mchehab by mail.kernel.org with local (Exim 4.97.1) (envelope-from ) id 1sRqTK-00000002jZg-2YEG; Thu, 11 Jul 2024 11:52:18 +0200 From: Mauro Carvalho Chehab To: Cc: Jonathan Cameron , "Michael S. Tsirkin" , Ani Sinha , Dongjiu Geng , Igor Mammedov , linux-edac@kernel.org, linux-kernel@vger.kernel.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, Mauro Carvalho Chehab Subject: [PATCH 2/6] acpi/ghes: Support GPIO error source. Date: Thu, 11 Jul 2024 11:52:04 +0200 Message-ID: <101bc837292c02badd2831ee1070065ff0794842.1720690278.git.mchehab+huawei@kernel.org> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=2604:1380:4641:c500::1; envelope-from=mchehab@kernel.org; helo=dfw.source.kernel.org X-Spam_score_int: -44 X-Spam_score: -4.5 X-Spam_bar: ---- X-Spam_report: (-4.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.144, 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 From: Jonathan Cameron Add error notification to GHES v2 using the GPIO source. Signed-off-by: Jonathan Cameron Signed-off-by: Mauro Carvalho Chehab --- hw/acpi/ghes.c | 8 ++++++-- include/hw/acpi/ghes.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/hw/acpi/ghes.c b/hw/acpi/ghes.c index e9511d9b8f71..5b8bc6eeb437 100644 --- a/hw/acpi/ghes.c +++ b/hw/acpi/ghes.c @@ -34,8 +34,8 @@ /* The max size in bytes for one error block */ #define ACPI_GHES_MAX_RAW_DATA_LENGTH (1 * KiB) -/* Now only support ARMv8 SEA notification type error source */ -#define ACPI_GHES_ERROR_SOURCE_COUNT 1 +/* Support ARMv8 SEA notification type error source and GPIO interrupt. */ +#define ACPI_GHES_ERROR_SOURCE_COUNT 2 /* Generic Hardware Error Source version 2 */ #define ACPI_GHES_SOURCE_GENERIC_ERROR_V2 10 @@ -327,6 +327,9 @@ static void build_ghes_v2(GArray *table_data, int source_id, BIOSLinker *linker) */ build_ghes_hw_error_notification(table_data, ACPI_GHES_NOTIFY_SEA); break; + case ACPI_HEST_SRC_ID_GPIO: + build_ghes_hw_error_notification(table_data, ACPI_GHES_NOTIFY_GPIO); + break; default: error_report("Not support this error source"); abort(); @@ -370,6 +373,7 @@ void acpi_build_hest(GArray *table_data, BIOSLinker *linker, /* Error Source Count */ build_append_int_noprefix(table_data, ACPI_GHES_ERROR_SOURCE_COUNT, 4); build_ghes_v2(table_data, ACPI_HEST_SRC_ID_SEA, linker); + build_ghes_v2(table_data, ACPI_HEST_SRC_ID_GPIO, linker); acpi_table_end(linker, &table); } diff --git a/include/hw/acpi/ghes.h b/include/hw/acpi/ghes.h index 674f6958e905..4f1ab1a73a06 100644 --- a/include/hw/acpi/ghes.h +++ b/include/hw/acpi/ghes.h @@ -58,6 +58,7 @@ enum AcpiGhesNotifyType { enum { ACPI_HEST_SRC_ID_SEA = 0, + ACPI_HEST_SRC_ID_GPIO = 1, /* future ids go here */ ACPI_HEST_SRC_ID_RESERVED, }; From patchwork Thu Jul 11 09:52:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mauro Carvalho Chehab X-Patchwork-Id: 13730272 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 6A113C3DA41 for ; Thu, 11 Jul 2024 09:53:49 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sRqTm-00058Q-Fj; Thu, 11 Jul 2024 05:52:46 -0400 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 1sRqTd-0004kR-VA; Thu, 11 Jul 2024 05:52:40 -0400 Received: from sin.source.kernel.org ([145.40.73.55]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sRqTY-0006Wo-In; Thu, 11 Jul 2024 05:52:37 -0400 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by sin.source.kernel.org (Postfix) with ESMTP id B5CA1CE183D; Thu, 11 Jul 2024 09:52:21 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 818FBC32786; Thu, 11 Jul 2024 09:52:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1720691540; bh=yjdVpMd5ozOqshPdRctXbXJ90enrbC9UDU0HeS1DIBE=; h=From:To:List-Id:Cc:Subject:Date:In-Reply-To:References:From; b=efwuBW4k1HQ6qhdu8FlFKlzv8lu6oJsRi3JTTvxRXw4E/oVnFUNu9YQHNFrg1P8Ai FotI9Xae1T5SL3i5yF6gNNYJOIYgOqs2wrOzPwqfVV9BbrFLI/FJCn7leqptyKMMjR jEqHxwpGw1n0WnEpbgay2LBDU+Aj/kD3lktPkVNy5W040zCuV4mJwl/qKS9wBXr8gp DpJ18ip3HCyonNTZK3Mxot4go61FfoWNEhtRnkr2g3AlrGxuwq1fvq/SngOTc3Mgd4 wIMQvk7GG7pjQI7DBidOMhGx3sQMQWSX/NPoIMPoAaFuB9A5V5HuyUwEETJrLp62t5 WNAwnlbm7G5dA== Received: from mchehab by mail.kernel.org with local (Exim 4.97.1) (envelope-from ) id 1sRqTK-00000002jZj-2fKy; Thu, 11 Jul 2024 11:52:18 +0200 From: Mauro Carvalho Chehab To: Cc: Jonathan Cameron , "Michael S. Tsirkin" , Ani Sinha , Dongjiu Geng , Eric Blake , Igor Mammedov , Markus Armbruster , Michael Roth , Paolo Bonzini , Peter Maydell , linux-edac@kernel.org, linux-kernel@vger.kernel.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, Mauro Carvalho Chehab , Shiju Jose Subject: [PATCH 3/6] acpi/ghes: Add a logic to handle block addresses and FW first ARM processor error injection Date: Thu, 11 Jul 2024 11:52:05 +0200 Message-ID: <0855a7919efb1b7dbd00f7d887b3efda0be83a73.1720690278.git.mchehab+huawei@kernel.org> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=145.40.73.55; envelope-from=mchehab@kernel.org; helo=sin.source.kernel.org X-Spam_score_int: -44 X-Spam_score: -4.5 X-Spam_bar: ---- X-Spam_report: (-4.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.144, 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 From: Jonathan Cameron 1. Some GHES functions require handling addresses. Add a helper function to support it. 2. Add support for ACPI CPER (firmware-first) ARM processor error injection. Compliance with N.2.4.4 ARM Processor Error Section in UEFI 2.6 and upper specs, using error type bit encoding as detailed at UEFI 2.9A errata. Error injection examples: { "execute": "qmp_capabilities" } { "execute": "arm-inject-error", "arguments": { "errortypes": ['cache-error'] } } { "execute": "arm-inject-error", "arguments": { "errortypes": ['tlb-error'] } } { "execute": "arm-inject-error", "arguments": { "errortypes": ['bus-error'] } } { "execute": "arm-inject-error", "arguments": { "errortypes": ['cache-error', 'tlb-error'] } } { "execute": "arm-inject-error", "arguments": { "errortypes": ['cache-error', 'tlb-error', 'bus-error', 'micro-arch-error'] } } ... Co-authored-by: Mauro Carvalho Chehab Co-authored-by: Shiju Jose For Add a logic to handle block addresses, Signed-off-by: Jonathan Cameron Signed-off-by: Mauro Carvalho Chehab For FW first ARM processor error injection, Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Shiju Jose --- configs/targets/aarch64-softmmu.mak | 1 + hw/acpi/ghes.c | 258 ++++++++++++++++++++++++++-- hw/arm/Kconfig | 4 + hw/arm/arm_error_inject.c | 35 ++++ hw/arm/arm_error_inject_stubs.c | 18 ++ hw/arm/meson.build | 3 + include/hw/acpi/ghes.h | 2 + qapi/arm-error-inject.json | 49 ++++++ qapi/meson.build | 1 + qapi/qapi-schema.json | 1 + 10 files changed, 361 insertions(+), 11 deletions(-) create mode 100644 hw/arm/arm_error_inject.c create mode 100644 hw/arm/arm_error_inject_stubs.c create mode 100644 qapi/arm-error-inject.json diff --git a/configs/targets/aarch64-softmmu.mak b/configs/targets/aarch64-softmmu.mak index 84cb32dc2f4f..b4b3cd97934a 100644 --- a/configs/targets/aarch64-softmmu.mak +++ b/configs/targets/aarch64-softmmu.mak @@ -5,3 +5,4 @@ TARGET_KVM_HAVE_GUEST_DEBUG=y TARGET_XML_FILES= gdb-xml/aarch64-core.xml gdb-xml/aarch64-fpu.xml gdb-xml/arm-core.xml gdb-xml/arm-vfp.xml gdb-xml/arm-vfp3.xml gdb-xml/arm-vfp-sysregs.xml gdb-xml/arm-neon.xml gdb-xml/arm-m-profile.xml gdb-xml/arm-m-profile-mve.xml gdb-xml/aarch64-pauth.xml # needed by boot.c TARGET_NEED_FDT=y +CONFIG_ARM_EINJ=y diff --git a/hw/acpi/ghes.c b/hw/acpi/ghes.c index 5b8bc6eeb437..6075ef5893ce 100644 --- a/hw/acpi/ghes.c +++ b/hw/acpi/ghes.c @@ -27,6 +27,7 @@ #include "hw/acpi/generic_event_device.h" #include "hw/nvram/fw_cfg.h" #include "qemu/uuid.h" +#include "qapi/qapi-types-arm-error-inject.h" #define ACPI_GHES_ERRORS_FW_CFG_FILE "etc/hardware_errors" #define ACPI_GHES_DATA_ADDR_FW_CFG_FILE "etc/hardware_errors_addr" @@ -53,6 +54,12 @@ /* The memory section CPER size, UEFI 2.6: N.2.5 Memory Error Section */ #define ACPI_GHES_MEM_CPER_LENGTH 80 +/* + * ARM Processor section CPER size, UEFI 2.10: N.2.4.4 + * ARM Processor Error Section + */ +#define ACPI_GHES_ARM_CPER_LENGTH (72 + 600) + /* Masks for block_status flags */ #define ACPI_GEBS_UNCORRECTABLE 1 @@ -231,6 +238,142 @@ static int acpi_ghes_record_mem_error(uint64_t error_block_address, return 0; } +/* UEFI 2.9: N.2.4.4 ARM Processor Error Section */ +static void acpi_ghes_build_append_arm_cper(uint8_t error_types, GArray *table) +{ + /* + * ARM Processor Error Record + */ + + /* Validation Bits */ + build_append_int_noprefix(table, + (1ULL << 3) | /* Vendor specific info Valid */ + (1ULL << 2) | /* Running status Valid */ + (1ULL << 1) | /* Error affinity level Valid */ + (1ULL << 0), /* MPIDR Valid */ + 4); + /* Error Info Num */ + build_append_int_noprefix(table, 1, 2); + /* Context Info Num */ + build_append_int_noprefix(table, 1, 2); + /* Section length */ + build_append_int_noprefix(table, ACPI_GHES_ARM_CPER_LENGTH, 4); + /* Error affinity level */ + build_append_int_noprefix(table, 2, 1); + /* Reserved */ + build_append_int_noprefix(table, 0, 3); + /* MPIDR_EL1 */ + build_append_int_noprefix(table, 0xAB12, 8); + /* MIDR_EL1 */ + build_append_int_noprefix(table, 0xCD24, 8); + /* Running state */ + build_append_int_noprefix(table, 0x1, 4); + /* PSCI state */ + build_append_int_noprefix(table, 0x1234, 4); + + /* ARM Propcessor error information */ + /* Version */ + build_append_int_noprefix(table, 0, 1); + /* Length */ + build_append_int_noprefix(table, 32, 1); + /* Validation Bits */ + build_append_int_noprefix(table, + (1ULL << 4) | /* Physical fault address Valid */ + (1ULL << 3) | /* Virtual fault address Valid */ + (1ULL << 2) | /* Error information Valid */ + (1ULL << 1) | /* Flags Valid */ + (1ULL << 0), /* Multiple error count Valid */ + 2); + /* Type */ + if (error_types & BIT(ARM_PROCESSOR_ERROR_TYPE_CACHE_ERROR) || + error_types & BIT(ARM_PROCESSOR_ERROR_TYPE_TLB_ERROR) || + error_types & BIT(ARM_PROCESSOR_ERROR_TYPE_BUS_ERROR) || + error_types & BIT(ARM_PROCESSOR_ERROR_TYPE_MICRO_ARCH_ERROR)) { + build_append_int_noprefix(table, error_types, 1); + } else { + return; + } + /* Multiple error count */ + build_append_int_noprefix(table, 2, 2); + /* Flags */ + build_append_int_noprefix(table, 0xD, 1); + /* Error information */ + if (error_types & BIT(ARM_PROCESSOR_ERROR_TYPE_CACHE_ERROR)) { + build_append_int_noprefix(table, 0x0091000F, 8); + } else if (error_types & BIT(ARM_PROCESSOR_ERROR_TYPE_TLB_ERROR)) { + build_append_int_noprefix(table, 0x0054007F, 8); + } else if (error_types & BIT(ARM_PROCESSOR_ERROR_TYPE_BUS_ERROR)) { + build_append_int_noprefix(table, 0x80D6460FFF, 8); + } else if (error_types & BIT(ARM_PROCESSOR_ERROR_TYPE_MICRO_ARCH_ERROR)) { + build_append_int_noprefix(table, 0x78DA03FF, 8); + } else { + return; + } + /* Virtual fault address */ + build_append_int_noprefix(table, 0x67320230, 8); + /* Physical fault address */ + build_append_int_noprefix(table, 0x5CDFD492, 8); + + /* ARM Propcessor error context information */ + /* Version */ + build_append_int_noprefix(table, 0, 2); + /* Validation Bits */ + /* AArch64 EL1 context registers Valid */ + build_append_int_noprefix(table, 5, 2); + /* Register array size */ + build_append_int_noprefix(table, 592, 4); + /* Register array */ + build_append_int_noprefix(table, 0x12ABDE67, 8); +} + +static int acpi_ghes_record_arm_error(uint8_t error_types, + uint64_t error_block_address) +{ + GArray *block; + + /* ARM processor Error Section Type */ + const uint8_t uefi_cper_arm_sec[] = + UUID_LE(0xE19E3D16, 0xBC11, 0x11E4, 0x9C, 0xAA, 0xC2, 0x05, \ + 0x1D, 0x5D, 0x46, 0xB0); + + /* + * Invalid fru id: ACPI 4.0: 17.3.2.6.1 Generic Error Data, + * Table 17-13 Generic Error Data Entry + */ + QemuUUID fru_id = {}; + uint32_t data_length; + + block = g_array_new(false, true /* clear */, 1); + + /* This is the length if adding a new generic error data entry*/ + data_length = ACPI_GHES_DATA_LENGTH + ACPI_GHES_ARM_CPER_LENGTH; + /* + * 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, uefi_cper_arm_sec, + ACPI_CPER_SEV_RECOVERABLE, 0, 0, + ACPI_GHES_ARM_CPER_LENGTH, fru_id, 0); + + /* Build the ARM processor error section CPER */ + acpi_ghes_build_append_arm_cper(error_types, block); + + /* Write the generic error data entry into guest memory */ + cpu_physical_memory_write(error_block_address, block->data, block->len); + + g_array_free(block, true); + + return 0; +} + /* * Build table for the hardware error fw_cfg blob. * Initialize "etc/hardware_errors" and "etc/hardware_errors_addr" fw_cfg blobs. @@ -392,23 +535,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) { if (source_id < ACPI_HEST_SRC_ID_RESERVED) { @@ -448,6 +590,100 @@ 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_ack_register0 | + * | +---------------------+ --+-- + * | | read_ack_register1 | GHES_ADDRESS_SIZE + * | +---------------------+ --+-- + * | | ............. | + * | +---------------------+ + * | | read_ack_registerN | + * | +---------------------+ --+-- + * | | 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_register_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_register_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; +} + +bool ghes_record_arm_errors(uint8_t error_types, uint32_t notify) +{ + int read_ack_register = 0; + uint64_t read_ack_register_addr = 0; + uint64_t error_block_addr = 0; + + if (!ghes_get_addr(notify, &error_block_addr, &read_ack_register_addr)) { + return false; + } + + cpu_physical_memory_read(read_ack_register_addr, + &read_ack_register, sizeof(uint64_t)); + /* zero means OSPM does not acknowledge the error */ + if (!read_ack_register) { + error_report("Last time OSPM does not acknowledge the error," + " record CPER failed this time, set the ack value to" + " avoid blocking next time CPER record! exit"); + read_ack_register = 1; + cpu_physical_memory_write(read_ack_register_addr, + &read_ack_register, sizeof(uint64_t)); + return false; + } + + read_ack_register = cpu_to_le64(0); + cpu_physical_memory_write(read_ack_register_addr, + &read_ack_register, sizeof(uint64_t)); + return acpi_ghes_record_arm_error(error_types, error_block_addr); +} + bool acpi_ghes_present(void) { AcpiGedState *acpi_ged_state; diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index 1ad60da7aa2d..bafac82f9fd3 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -712,3 +712,7 @@ config ARMSSE select UNIMP select SSE_COUNTER select SSE_TIMER + +config ARM_EINJ + bool + default y if AARCH64 diff --git a/hw/arm/arm_error_inject.c b/hw/arm/arm_error_inject.c new file mode 100644 index 000000000000..1da97d5d4fdc --- /dev/null +++ b/hw/arm/arm_error_inject.c @@ -0,0 +1,35 @@ +/* + * ARM Processor 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-commands-arm-error-inject.h" +#include "hw/boards.h" +#include "hw/acpi/ghes.h" + +/* For ARM processor errors */ +void qmp_arm_inject_error(ArmProcessorErrorTypeList *errortypes, Error **errp) +{ + MachineState *machine = MACHINE(qdev_get_machine()); + MachineClass *mc = MACHINE_GET_CLASS(machine); + uint8_t error_types = 0; + + while (errortypes) { + error_types |= BIT(errortypes->value); + errortypes = errortypes->next; + } + + ghes_record_arm_errors(error_types, ACPI_GHES_NOTIFY_GPIO); + if (mc->set_error) { + mc->set_error(); + } + + return; +} diff --git a/hw/arm/arm_error_inject_stubs.c b/hw/arm/arm_error_inject_stubs.c new file mode 100644 index 000000000000..b51f4202fe64 --- /dev/null +++ b/hw/arm/arm_error_inject_stubs.c @@ -0,0 +1,18 @@ +/* + * QMP stub for ARM processor 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-commands-arm-error-inject.h" + +void qmp_arm_inject_error(ArmProcessorErrorTypeList *errortypes, Error **errp) +{ + error_setg(errp, "ARM processor error support is not compiled in"); +} diff --git a/hw/arm/meson.build b/hw/arm/meson.build index 0c07ab522f4c..cb7fe09fc87b 100644 --- a/hw/arm/meson.build +++ b/hw/arm/meson.build @@ -60,6 +60,7 @@ arm_ss.add(when: 'CONFIG_ARM_SMMUV3', if_true: files('smmuv3.c')) arm_ss.add(when: 'CONFIG_FSL_IMX6UL', if_true: files('fsl-imx6ul.c', 'mcimx6ul-evk.c')) arm_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_soc.c')) arm_ss.add(when: 'CONFIG_XEN', if_true: files('xen_arm.c')) +arm_ss.add(when: 'CONFIG_ARM_EINJ', if_true: files('arm_error_inject.c')) system_ss.add(when: 'CONFIG_ARM_SMMUV3', if_true: files('smmu-common.c')) system_ss.add(when: 'CONFIG_CHEETAH', if_true: files('palm.c')) @@ -77,5 +78,7 @@ system_ss.add(when: 'CONFIG_TOSA', if_true: files('tosa.c')) system_ss.add(when: 'CONFIG_VERSATILE', if_true: files('versatilepb.c')) system_ss.add(when: 'CONFIG_VEXPRESS', if_true: files('vexpress.c')) system_ss.add(when: 'CONFIG_Z2', if_true: files('z2.c')) +system_ss.add(when: 'CONFIG_ARM_EINJ', if_false: files('arm_error_inject_stubs.c')) +system_ss.add(when: 'CONFIG_ALL', if_true: files('arm_error_inject_stubs.c')) hw_arch += {'arm': arm_ss} diff --git a/include/hw/acpi/ghes.h b/include/hw/acpi/ghes.h index 4f1ab1a73a06..dc531ffce7ae 100644 --- a/include/hw/acpi/ghes.h +++ b/include/hw/acpi/ghes.h @@ -75,6 +75,8 @@ void acpi_ghes_add_fw_cfg(AcpiGhesState *vms, FWCfgState *s, GArray *hardware_errors); int acpi_ghes_record_errors(uint8_t notify, uint64_t error_physical_addr); +bool ghes_record_arm_errors(uint8_t error_types, uint32_t notify); + /** * acpi_ghes_present: Report whether ACPI GHES table is present * diff --git a/qapi/arm-error-inject.json b/qapi/arm-error-inject.json new file mode 100644 index 000000000000..430e6cea6b60 --- /dev/null +++ b/qapi/arm-error-inject.json @@ -0,0 +1,49 @@ +# -*- Mode: Python -*- +# vim: filetype=python + +## +# = ARM Processor Errors +## + +## +# @ArmProcessorErrorType: +# +# Type of ARM processor error to inject +# +# @unknown-error: Unknown error +# +# @cache-error: Cache error +# +# @tlb-error: TLB error +# +# @bus-error: Bus error. +# +# @micro-arch-error: Micro architectural error. +# +# Since: 9.1 +## +{ 'enum': 'ArmProcessorErrorType', + 'data': ['unknown-error', + 'cache-error', + 'tlb-error', + 'bus-error', + 'micro-arch-error'] +} + +## +# @arm-inject-error: +# +# Inject ARM Processor error. +# +# @errortypes: ARM processor error types to inject +# +# Features: +# +# @unstable: This command is experimental. +# +# Since: 9.1 +## +{ 'command': 'arm-inject-error', + 'data': { 'errortypes': ['ArmProcessorErrorType'] }, + 'features': [ 'unstable' ] +} diff --git a/qapi/meson.build b/qapi/meson.build index e7bc54e5d047..5927932c4be3 100644 --- a/qapi/meson.build +++ b/qapi/meson.build @@ -22,6 +22,7 @@ if have_system or have_tools or have_ga endif qapi_all_modules = [ + 'arm-error-inject', 'authz', 'block', 'block-core', diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json index b1581988e4eb..479a22de7e43 100644 --- a/qapi/qapi-schema.json +++ b/qapi/qapi-schema.json @@ -81,3 +81,4 @@ { 'include': 'vfio.json' } { 'include': 'cryptodev.json' } { 'include': 'cxl.json' } +{ 'include': 'arm-error-inject.json' } From patchwork Thu Jul 11 09:52:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mauro Carvalho Chehab X-Patchwork-Id: 13730273 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 30084C3DA47 for ; Thu, 11 Jul 2024 09:54:03 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sRqTm-00059G-NL; Thu, 11 Jul 2024 05:52:46 -0400 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 1sRqTd-0004gj-3J; Thu, 11 Jul 2024 05:52:37 -0400 Received: from sin.source.kernel.org ([2604:1380:40e1:4800::1]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sRqTY-0006Wk-Hd; Thu, 11 Jul 2024 05:52:34 -0400 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by sin.source.kernel.org (Postfix) with ESMTP id 59796CE1836; Thu, 11 Jul 2024 09:52:21 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8994AC4AF0C; Thu, 11 Jul 2024 09:52:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1720691540; bh=725/tP/GCjlN8Z34GtQNtVt/F4poaFotjr12mxvM/JA=; h=From:To:List-Id:Cc:Subject:Date:In-Reply-To:References:From; b=NpHARU17cFWhRXZKgw9M/i1B71oq7o/mGTGTkf59JV1wTBCqytUmjt1gEzJeAb8yI gCsB+M3lyZiMDWWcwTzYITAhHNQFPLJA5q+e8PT+vQEB4ze2UmJkbsvNFIhy1ZRnv9 mgh/Ydg5LsUCD0I18A/yjSChbPJBrQi7ljDubQZnpjoFtviWYGOKRVXgyeOmOCDNwW TPQ5Fynuu4Cs7JzK7K+Tbi+WNwo2CuQmwq+dq2dyby5T6hVTruvOoX8d3MHg8m63Lx +1hMxo9vUV8Rgd5a1gwVvQAAeik9M5f7wwPofY4bdMMdM3yYIFOMZ0PyH4i9rrZTQS Mzi3/DD/yGMhw== Received: from mchehab by mail.kernel.org with local (Exim 4.97.1) (envelope-from ) id 1sRqTK-00000002jZp-2lwm; Thu, 11 Jul 2024 11:52:18 +0200 From: Mauro Carvalho Chehab To: Cc: Mauro Carvalho Chehab , Peter Maydell , linux-edac@kernel.org, linux-kernel@vger.kernel.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH 4/6] target/arm: preserve mpidr value Date: Thu, 11 Jul 2024 11:52:06 +0200 Message-ID: <60ffdecc1c9a1389182142451afc91ca6bd111dd.1720690278.git.mchehab+huawei@kernel.org> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=2604:1380:40e1:4800::1; envelope-from=mchehab@kernel.org; helo=sin.source.kernel.org X-Spam_score_int: -44 X-Spam_score: -4.5 X-Spam_bar: ---- X-Spam_report: (-4.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.144, 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 There is a logic at helper to properly fill the mpidr information. This is needed for ARM Processor error injection, so store the value inside a cpu opaque value, to allow it to be used. Signed-off-by: Mauro Carvalho Chehab --- target/arm/cpu.h | 1 + target/arm/helper.c | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index d8eb986a047c..2858fef963a9 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1026,6 +1026,7 @@ struct ArchCPU { uint64_t reset_pmcr_el0; } isar; uint64_t midr; + uint64_t mpidr; uint32_t revidr; uint32_t reset_fpsid; uint64_t ctr; diff --git a/target/arm/helper.c b/target/arm/helper.c index ce319572354a..2432b5b09607 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -4692,7 +4692,7 @@ static uint64_t mpidr_read_val(CPUARMState *env) return mpidr; } -static uint64_t mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri) +static uint64_t mpidr_read(CPUARMState *env) { unsigned int cur_el = arm_current_el(env); @@ -4702,6 +4702,11 @@ static uint64_t mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri) return mpidr_read_val(env); } +static uint64_t mpidr_read_ri(CPUARMState *env, const ARMCPRegInfo *ri) +{ + return mpidr_read(env); +} + static const ARMCPRegInfo lpae_cp_reginfo[] = { /* NOP AMAIR0/1 */ { .name = "AMAIR0", .state = ARM_CP_STATE_BOTH, @@ -9723,7 +9728,7 @@ void register_cp_regs_for_features(ARMCPU *cpu) { .name = "MPIDR_EL1", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 5, .fgt = FGT_MPIDR_EL1, - .access = PL1_R, .readfn = mpidr_read, .type = ARM_CP_NO_RAW }, + .access = PL1_R, .readfn = mpidr_read_ri, .type = ARM_CP_NO_RAW }, }; #ifdef CONFIG_USER_ONLY static const ARMCPRegUserSpaceInfo mpidr_user_cp_reginfo[] = { @@ -9733,6 +9738,7 @@ void register_cp_regs_for_features(ARMCPU *cpu) modify_arm_cp_regs(mpidr_cp_reginfo, mpidr_user_cp_reginfo); #endif define_arm_cp_regs(cpu, mpidr_cp_reginfo); + cpu->mpidr = mpidr_read(env); } if (arm_feature(env, ARM_FEATURE_AUXCR)) { From patchwork Thu Jul 11 09:52:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mauro Carvalho Chehab X-Patchwork-Id: 13730267 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 6D292C3DA41 for ; Thu, 11 Jul 2024 09:53:07 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sRqTk-0004zP-Jn; Thu, 11 Jul 2024 05:52:44 -0400 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 1sRqTd-0004gg-32; Thu, 11 Jul 2024 05:52:40 -0400 Received: from sin.source.kernel.org ([145.40.73.55]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sRqTY-0006Wm-HG; Thu, 11 Jul 2024 05:52:35 -0400 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by sin.source.kernel.org (Postfix) with ESMTP id 59502CE1835; Thu, 11 Jul 2024 09:52:21 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8C2DFC4AF07; Thu, 11 Jul 2024 09:52:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1720691540; bh=8fT3iZX4Ak9UXbYdPywtW7xLXPjIWOMseP9okwfRJuM=; h=From:To:List-Id:Cc:Subject:Date:In-Reply-To:References:From; b=N+3mx4UNN8dYWiUIP60+AhLYFaiOhAWuATFMyah3Xq/HI+oD1QiX00VMQFyvjdspr WwGqXqKqlNOOrvS+QJQIM2wRJ9pzmil8TXOA4LtKD1fwuwG1n6WQBd48sgg2tjHGCK XzMUyJh56sMMyO2zK6/ILApmw6UAMvJhyg8wfcXdVfsOrpuCjUpYQ+WcY160GJakgv HcFm2llcvsCuDLyi1s5JWaUg5e1GsnnP0UAjVdwSvTdHKWf4eJgd+3iyOULlElxDjY CiySy3vZDcsfDO+wPjEyNn7PrPnSbdHZ7G1w68zkToLGTKDhbQAq9/XYUQtXA36vS5 uDNjCQbHgd6bQ== Received: from mchehab by mail.kernel.org with local (Exim 4.97.1) (envelope-from ) id 1sRqTK-00000002jZt-2siQ; Thu, 11 Jul 2024 11:52:18 +0200 From: Mauro Carvalho Chehab To: Cc: Mauro Carvalho Chehab , "Michael S. Tsirkin" , Ani Sinha , Dongjiu Geng , Igor Mammedov , linux-edac@kernel.org, linux-kernel@vger.kernel.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH 5/6] acpi/ghes: update comments to point to newer ACPI specs Date: Thu, 11 Jul 2024 11:52:07 +0200 Message-ID: <1ca920c8cebbb5aaac2a9f65ffccf7b4443ea666.1720690278.git.mchehab+huawei@kernel.org> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=145.40.73.55; envelope-from=mchehab@kernel.org; helo=sin.source.kernel.org X-Spam_score_int: -44 X-Spam_score: -4.5 X-Spam_bar: ---- X-Spam_report: (-4.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.144, 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 There is one reference to ACPI 4.0 and several references to ACPI 6.x versions. Update them to point to ACPI 6.5 whenever possible. There's one reference that was kept pointing to ACPI 6.4, though, with HEST revision 1. ACPI 6.5 now defines HEST revision 2, and defined a new way to handle source types starting from 12. According with ACPI 6.5 revision history: 2312 Update to the HEST table and adding new error source descriptor - Table 18.2. Yet, the spec doesn't define yet any new source descriptors. It just defines a different behavior when source type is above 11. I also double-checked GHES implementation on an open source project (Linux Kernel). Currently upstream doesn't currently handle HEST revision, ignoring such field. In any case, revision 2 seems to be backward-compatible with revison 1 when type <= 11 and just one error is contained on a HEST record. So, while it is probably safe to update it, there's no real need. So, let's keep the implementation using an ACPI 6.4 compatible table, e. g. HEST revision 1. Signed-off-by: Mauro Carvalho Chehab --- hw/acpi/ghes.c | 48 ++++++++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/hw/acpi/ghes.c b/hw/acpi/ghes.c index 6075ef5893ce..ebf1b812aaaa 100644 --- a/hw/acpi/ghes.c +++ b/hw/acpi/ghes.c @@ -45,9 +45,9 @@ #define GAS_ADDR_OFFSET 4 /* - * The total size of Generic Error Data Entry - * ACPI 6.1/6.2: 18.3.2.7.1 Generic Error Data, - * Table 18-343 Generic Error Data Entry + * The total size of Generic Error Data Entry before data field + * ACPI 6.5: 18.3.2.7.1 Generic Error Data, + * Table 18.12 Generic Error Data Entry */ #define ACPI_GHES_DATA_LENGTH 72 @@ -65,8 +65,8 @@ /* * Total size for Generic Error Status Block except Generic Error Data Entries - * ACPI 6.2: 18.3.2.7.1 Generic Error Data, - * Table 18-380 Generic Error Status Block + * ACPI 6.5: 18.3.2.7.1 Generic Error Data, + * Table 18.11 Generic Error Status Block */ #define ACPI_GHES_GESB_SIZE 20 @@ -82,7 +82,8 @@ enum AcpiGenericErrorSeverity { /* * Hardware Error Notification - * ACPI 4.0: 17.3.2.7 Hardware Error Notification + * ACPI 6.5: 18.3.2.9 Hardware Error Notification, + * Table 18.14 - Hardware Error Notification Structure * Composes dummy Hardware Error Notification descriptor of specified type */ static void build_ghes_hw_error_notification(GArray *table, const uint8_t type) @@ -112,7 +113,8 @@ static void build_ghes_hw_error_notification(GArray *table, const uint8_t type) /* * Generic Error Data Entry - * ACPI 6.1: 18.3.2.7.1 Generic Error Data + * ACPI 6.5: 18.3.2.7.1 Generic Error Data, + * Table 18.12 - Generic Error Data Entry */ static void acpi_ghes_generic_error_data(GArray *table, const uint8_t *section_type, uint32_t error_severity, @@ -148,7 +150,8 @@ static void acpi_ghes_generic_error_data(GArray *table, /* * Generic Error Status Block - * ACPI 6.1: 18.3.2.7.1 Generic Error Data + * ACPI 6.5: 18.3.2.7.1 Generic Error Data, + * Table 18.11 - Generic Hardware Error Source Structure */ static void acpi_ghes_generic_error_status(GArray *table, uint32_t block_status, uint32_t raw_data_offset, uint32_t raw_data_length, @@ -429,15 +432,18 @@ void build_ghes_error_table(GArray *hardware_errors, BIOSLinker *linker) 0, sizeof(uint64_t), ACPI_GHES_ERRORS_FW_CFG_FILE, 0); } -/* Build Generic Hardware Error Source version 2 (GHESv2) */ +/* + * Build Generic Hardware Error Source version 2 (GHESv2) + * ACPI 6.5: 18.3.2.8 Generic Hardware Error Source version 2 (GHESv2 - Type 10), + * Table 18.13: Generic Hardware Error Source version 2 (GHESv2) + */ static void build_ghes_v2(GArray *table_data, int source_id, BIOSLinker *linker) { uint64_t address_offset; - /* - * Type: - * Generic Hardware Error Source version 2(GHESv2 - Type 10) - */ + /* Type: (GHESv2 - Type 10) */ build_append_int_noprefix(table_data, ACPI_GHES_SOURCE_GENERIC_ERROR_V2, 2); + + /* ACPI 6.5: Table 18.10 - Generic Hardware Error Source Structure */ /* Source Id */ build_append_int_noprefix(table_data, source_id, 2); /* Related Source Id */ @@ -481,11 +487,8 @@ static void build_ghes_v2(GArray *table_data, int source_id, BIOSLinker *linker) /* Error Status Block Length */ build_append_int_noprefix(table_data, ACPI_GHES_MAX_RAW_DATA_LENGTH, 4); - /* - * Read Ack Register - * ACPI 6.1: 18.3.2.8 Generic Hardware Error Source - * version 2 (GHESv2 - Type 10) - */ + /* ACPI 6.5: fields defined at GHESv2 table */ + /* Read Ack Register */ address_offset = table_data->len; build_append_gas(table_data, AML_AS_SYSTEM_MEMORY, 0x40, 0, 4 /* QWord access */, 0); @@ -504,11 +507,16 @@ static void build_ghes_v2(GArray *table_data, int source_id, BIOSLinker *linker) build_append_int_noprefix(table_data, 0x1, 8); } -/* Build Hardware Error Source Table */ +/* + * Build Hardware Error Source Table + * ACPI 6.4: 18.3.2 ACPI Error Source + * Table 18.2: Hardware Error Source Table (HEST) + */ void acpi_build_hest(GArray *table_data, BIOSLinker *linker, const char *oem_id, const char *oem_table_id) { - AcpiTable table = { .sig = "HEST", .rev = 1, + AcpiTable table = { .sig = "HEST", + .rev = 1, /* ACPI 4.0 to 6.4 */ .oem_id = oem_id, .oem_table_id = oem_table_id }; acpi_table_begin(&table, table_data); From patchwork Thu Jul 11 09:52:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Mauro Carvalho Chehab X-Patchwork-Id: 13730271 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 8D98FC3DA47 for ; Thu, 11 Jul 2024 09:53:47 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sRqTl-00053Q-7u; Thu, 11 Jul 2024 05:52:45 -0400 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 1sRqTc-0004ga-2F; Thu, 11 Jul 2024 05:52:37 -0400 Received: from dfw.source.kernel.org ([139.178.84.217]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sRqTW-0006Wf-8D; Thu, 11 Jul 2024 05:52:35 -0400 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by dfw.source.kernel.org (Postfix) with ESMTP id 5132561CD7; Thu, 11 Jul 2024 09:52:21 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8E963C4AF0E; Thu, 11 Jul 2024 09:52:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1720691540; bh=Ybf7OUJPfmsnLr0J4zNeX89cSaIch9LE7Gl5bnjIZWc=; h=From:To:List-Id:Cc:Subject:Date:In-Reply-To:References:From; b=FVcLBUZO5vXDwL+KaQiAHrKMqNQDJNiivGGC4Fb/mm6rlUJeSuW3Die/lUWVbpyDW 2HC39PIJ8WzvhXLFjH2S8yqlwcU6JFJ5vxrcuYIB07sFonDTzw8+k7pUMmP1+flYYX thAMMdtVyu7kI4k1q7W+UtqZ4dgsEDdgL7bwp0YJY1OHMc0K6v4Rz0kJET6SlxPnq9 mrhrZvAf72FDpZPNYROLEGBE+3yIAdy68KC4Rc2HZEz/hDnF3xn4/ZpcNPa2R+eitC sEcRTYvYmrBqf+ep5PqZf0sXN68ItuoFg/FyE/M2jXa5UGUpXsdWQKmiINDOzUp0Rt j2CewveLhiZow== Received: from mchehab by mail.kernel.org with local (Exim 4.97.1) (envelope-from ) id 1sRqTK-00000002jZx-30Cn; Thu, 11 Jul 2024 11:52:18 +0200 From: Mauro Carvalho Chehab To: Cc: Mauro Carvalho Chehab , =?utf-8?q?Alex_Benn?= =?utf-8?q?=C3=A9e?= , "Michael S. Tsirkin" , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , Ani Sinha , Beraldo Leal , Dongjiu Geng , Eric Blake , Igor Mammedov , Markus Armbruster , Peter Maydell , Thomas Huth , Wainer dos Santos Moschetta , linux-edac@kernel.org, linux-kernel@vger.kernel.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH 6/6] acpi/ghes: extend arm error injection logic Date: Thu, 11 Jul 2024 11:52:08 +0200 Message-ID: X-Mailer: git-send-email 2.45.2 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=139.178.84.217; envelope-from=mchehab@kernel.org; helo=dfw.source.kernel.org X-Spam_score_int: -71 X-Spam_score: -7.2 X-Spam_bar: ------- X-Spam_report: (-7.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.144, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_HI=-5, 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 Enrich CPER error injection logic for ARM processor to allow setting values to from UEFI 2.10 tables N.16 and N.17. It should be noticed that, with such change, all arguments are now optional, so, once QMP is negotiated with: { "execute": "qmp_capabilities" } the simplest way to generate a cache error is to use: { "execute": "arm-inject-error" } Also, as now PEI is mapped into an array, it is possible to inject multiple errors at the same CPER record with: { "execute": "arm-inject-error", "arguments": { "error": [ {"type": [ "cache-error" ]}, {"type": [ "tlb-error" ]} ] } } This would generate both cache and TLB errors, using default values for other fields. As all fields from ARM Processor CPER are now mapped, all types of CPER records can be generated with the new QAPI. Signed-off-by: Mauro Carvalho Chehab --- hw/acpi/ghes.c | 168 +++++++------- hw/arm/arm_error_inject.c | 399 +++++++++++++++++++++++++++++++- hw/arm/arm_error_inject_stubs.c | 20 +- include/hw/acpi/ghes.h | 40 +++- qapi/arm-error-inject.json | 250 +++++++++++++++++++- tests/lcitool/libvirt-ci | 2 +- 6 files changed, 778 insertions(+), 101 deletions(-) diff --git a/hw/acpi/ghes.c b/hw/acpi/ghes.c index ebf1b812aaaa..afd1d098a7e3 100644 --- a/hw/acpi/ghes.c +++ b/hw/acpi/ghes.c @@ -55,10 +55,10 @@ #define ACPI_GHES_MEM_CPER_LENGTH 80 /* - * ARM Processor section CPER size, UEFI 2.10: N.2.4.4 - * ARM Processor Error Section + * ARM Processor error section CPER sizes - UEFI 2.10: N.2.4.4 */ -#define ACPI_GHES_ARM_CPER_LENGTH (72 + 600) +#define ACPI_GHES_ARM_CPER_LENGTH 40 +#define ACPI_GHES_ARM_CPER_PEI_LENGTH 32 /* Masks for block_status flags */ #define ACPI_GEBS_UNCORRECTABLE 1 @@ -242,94 +242,98 @@ static int acpi_ghes_record_mem_error(uint64_t error_block_address, } /* UEFI 2.9: N.2.4.4 ARM Processor Error Section */ -static void acpi_ghes_build_append_arm_cper(uint8_t error_types, GArray *table) +static void acpi_ghes_build_append_arm_cper(ArmError err, uint32_t cper_length, + GArray *table) { + unsigned int i, j; + /* * ARM Processor Error Record */ /* Validation Bits */ - build_append_int_noprefix(table, - (1ULL << 3) | /* Vendor specific info Valid */ - (1ULL << 2) | /* Running status Valid */ - (1ULL << 1) | /* Error affinity level Valid */ - (1ULL << 0), /* MPIDR Valid */ - 4); + build_append_int_noprefix(table, err.validation, 4); + /* Error Info Num */ - build_append_int_noprefix(table, 1, 2); + build_append_int_noprefix(table, err.err_info_num, 2); + /* Context Info Num */ - build_append_int_noprefix(table, 1, 2); + build_append_int_noprefix(table, err.context_info_num, 2); + /* Section length */ - build_append_int_noprefix(table, ACPI_GHES_ARM_CPER_LENGTH, 4); + build_append_int_noprefix(table, cper_length, 4); + /* Error affinity level */ - build_append_int_noprefix(table, 2, 1); + build_append_int_noprefix(table, err.affinity_level, 1); + /* Reserved */ build_append_int_noprefix(table, 0, 3); + /* MPIDR_EL1 */ - build_append_int_noprefix(table, 0xAB12, 8); + build_append_int_noprefix(table, err.mpidr_el1, 8); + /* MIDR_EL1 */ - build_append_int_noprefix(table, 0xCD24, 8); + build_append_int_noprefix(table, err.midr_el1, 8); + /* Running state */ - build_append_int_noprefix(table, 0x1, 4); - /* PSCI state */ - build_append_int_noprefix(table, 0x1234, 4); - - /* ARM Propcessor error information */ - /* Version */ - build_append_int_noprefix(table, 0, 1); - /* Length */ - build_append_int_noprefix(table, 32, 1); - /* Validation Bits */ - build_append_int_noprefix(table, - (1ULL << 4) | /* Physical fault address Valid */ - (1ULL << 3) | /* Virtual fault address Valid */ - (1ULL << 2) | /* Error information Valid */ - (1ULL << 1) | /* Flags Valid */ - (1ULL << 0), /* Multiple error count Valid */ - 2); - /* Type */ - if (error_types & BIT(ARM_PROCESSOR_ERROR_TYPE_CACHE_ERROR) || - error_types & BIT(ARM_PROCESSOR_ERROR_TYPE_TLB_ERROR) || - error_types & BIT(ARM_PROCESSOR_ERROR_TYPE_BUS_ERROR) || - error_types & BIT(ARM_PROCESSOR_ERROR_TYPE_MICRO_ARCH_ERROR)) { - build_append_int_noprefix(table, error_types, 1); - } else { - return; + build_append_int_noprefix(table, err.running_state, 4); + + /* PSCI state: only valid when running state is zero */ + build_append_int_noprefix(table, err.psci_state, 4); + + for (i = 0; i < err.err_info_num; i++) { + /* ARM Propcessor error information */ + /* Version */ + build_append_int_noprefix(table, 0, 1); + + /* Length */ + build_append_int_noprefix(table, ACPI_GHES_ARM_CPER_PEI_LENGTH, 1); + + /* Validation Bits */ + build_append_int_noprefix(table, err.pei[i].validation, 2); + + /* Type */ + build_append_int_noprefix(table, err.pei[i].type, 1); + + /* Multiple error count */ + build_append_int_noprefix(table, err.pei[i].multiple_error, 2); + + /* Flags */ + build_append_int_noprefix(table, err.pei[i].flags, 1); + + /* Error information */ + build_append_int_noprefix(table, err.pei[i].error_info, 8); + + /* Virtual fault address */ + build_append_int_noprefix(table, err.pei[i].virt_addr, 8); + + /* Physical fault address */ + build_append_int_noprefix(table, err.pei[i].phy_addr, 8); + } + + for (i = 0; i < err.context_info_num; i++) { + /* ARM Propcessor error context information */ + /* Version */ + build_append_int_noprefix(table, 0, 2); + + /* Validation type */ + build_append_int_noprefix(table, err.context[i].type, 2); + + /* Register array size */ + build_append_int_noprefix(table, err.context[i].size * 8, 4); + + /* Register array (byte 8 of Context info) */ + for (j = 0; j < err.context[i].size; j++) { + build_append_int_noprefix(table, err.context[i].array[j], 8); + } } - /* Multiple error count */ - build_append_int_noprefix(table, 2, 2); - /* Flags */ - build_append_int_noprefix(table, 0xD, 1); - /* Error information */ - if (error_types & BIT(ARM_PROCESSOR_ERROR_TYPE_CACHE_ERROR)) { - build_append_int_noprefix(table, 0x0091000F, 8); - } else if (error_types & BIT(ARM_PROCESSOR_ERROR_TYPE_TLB_ERROR)) { - build_append_int_noprefix(table, 0x0054007F, 8); - } else if (error_types & BIT(ARM_PROCESSOR_ERROR_TYPE_BUS_ERROR)) { - build_append_int_noprefix(table, 0x80D6460FFF, 8); - } else if (error_types & BIT(ARM_PROCESSOR_ERROR_TYPE_MICRO_ARCH_ERROR)) { - build_append_int_noprefix(table, 0x78DA03FF, 8); - } else { - return; + + for (i = 0; i < err.vendor_num; i++) { + build_append_int_noprefix(table, err.vendor[i], 1); } - /* Virtual fault address */ - build_append_int_noprefix(table, 0x67320230, 8); - /* Physical fault address */ - build_append_int_noprefix(table, 0x5CDFD492, 8); - - /* ARM Propcessor error context information */ - /* Version */ - build_append_int_noprefix(table, 0, 2); - /* Validation Bits */ - /* AArch64 EL1 context registers Valid */ - build_append_int_noprefix(table, 5, 2); - /* Register array size */ - build_append_int_noprefix(table, 592, 4); - /* Register array */ - build_append_int_noprefix(table, 0x12ABDE67, 8); } -static int acpi_ghes_record_arm_error(uint8_t error_types, +static int acpi_ghes_record_arm_error(ArmError error, uint64_t error_block_address) { GArray *block; @@ -344,12 +348,18 @@ static int acpi_ghes_record_arm_error(uint8_t error_types, * Table 17-13 Generic Error Data Entry */ QemuUUID fru_id = {}; - uint32_t data_length; + uint32_t cper_length, data_length; block = g_array_new(false, true /* clear */, 1); /* This is the length if adding a new generic error data entry*/ - data_length = ACPI_GHES_DATA_LENGTH + ACPI_GHES_ARM_CPER_LENGTH; + cper_length = ACPI_GHES_ARM_CPER_LENGTH; + cper_length += ACPI_GHES_ARM_CPER_PEI_LENGTH * error.err_info_num; + cper_length += error.context_length; + cper_length += error.vendor_num; + + data_length = ACPI_GHES_DATA_LENGTH + cper_length; + /* * It should not run out of the preallocated memory if adding a new generic * error data entry @@ -363,11 +373,11 @@ static int acpi_ghes_record_arm_error(uint8_t error_types, /* Build this new generic error data entry header */ acpi_ghes_generic_error_data(block, uefi_cper_arm_sec, - ACPI_CPER_SEV_RECOVERABLE, 0, 0, - ACPI_GHES_ARM_CPER_LENGTH, fru_id, 0); + ACPI_CPER_SEV_RECOVERABLE, 0, 0, + cper_length, fru_id, 0); /* Build the ARM processor error section CPER */ - acpi_ghes_build_append_arm_cper(error_types, block); + acpi_ghes_build_append_arm_cper(error, cper_length, block); /* Write the generic error data entry into guest memory */ cpu_physical_memory_write(error_block_address, block->data, block->len); @@ -663,7 +673,7 @@ static bool ghes_get_addr(uint32_t notify, uint64_t *error_block_addr, return true; } -bool ghes_record_arm_errors(uint8_t error_types, uint32_t notify) +bool ghes_record_arm_errors(ArmError error, uint32_t notify) { int read_ack_register = 0; uint64_t read_ack_register_addr = 0; @@ -689,7 +699,7 @@ bool ghes_record_arm_errors(uint8_t error_types, uint32_t notify) read_ack_register = cpu_to_le64(0); cpu_physical_memory_write(read_ack_register_addr, &read_ack_register, sizeof(uint64_t)); - return acpi_ghes_record_arm_error(error_types, error_block_addr); + return acpi_ghes_record_arm_error(error, error_block_addr); } bool acpi_ghes_present(void) diff --git a/hw/arm/arm_error_inject.c b/hw/arm/arm_error_inject.c index 1da97d5d4fdc..67f1c77546b9 100644 --- a/hw/arm/arm_error_inject.c +++ b/hw/arm/arm_error_inject.c @@ -10,23 +10,408 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include "qapi-commands-arm-error-inject.h" #include "hw/boards.h" #include "hw/acpi/ghes.h" +#include "cpu.h" + +#define ACPI_GHES_ARM_CPER_CTX_DEFAULT_NREGS 74 + +/* Handle ARM Processor Error Information (PEI) */ +static const ArmProcessorErrorInformationList *default_pei = { 0 }; + +static ArmPEI *qmp_arm_pei(uint16_t *err_info_num, + bool has_error, + ArmProcessorErrorInformationList const *error_list) +{ + ArmProcessorErrorInformationList const *next; + ArmPeiValidationBitsList const *validation_list; + ArmPEI *pei = NULL; + uint16_t i; + + if (!has_error) { + error_list = default_pei; + } + + *err_info_num = 0; + + for (next = error_list; next; next = next->next) { + (*err_info_num)++; + + if (*err_info_num >= 255) { + break; + } + } + + pei = g_new0(ArmPEI, (*err_info_num)); + + for (next = error_list, i = 0; + i < *err_info_num; i++, next = next->next) { + ArmProcessorErrorTypeList *type_list = next->value->type; + uint16_t pei_validation = 0; + uint8_t flags = 0; + uint8_t type = 0; + + if (next->value->has_validation) { + validation_list = next->value->validation; + + while (validation_list) { + pei_validation |= BIT(next->value->validation->value); + validation_list = validation_list->next; + } + } + + /* + * According with UEFI 2.9A errata, the meaning of this field is + * given by the following bitmap: + * + * +-----|---------------------------+ + * | Bit | Meaning | + * +=====+===========================+ + * | 1 | Cache Error | + * | 2 | TLB Error | + * | 3 | Bus Error | + * | 4 | Micro-architectural Error | + * +-----|---------------------------+ + * + * All other values are reserved. + * + * As bit 0 is reserved, QAPI ArmProcessorErrorType starts from bit 1. + */ + while (type_list) { + type |= BIT(type_list->value + 1); + type_list = type_list->next; + } + if (!has_error) { + type = BIT(ARM_PROCESSOR_ERROR_TYPE_CACHE_ERROR); + } + pei[i].type = type; + + if (next->value->has_flags) { + ArmProcessorFlagsList *flags_list = next->value->flags; + + while (flags_list) { + flags |= BIT(flags_list->value); + flags_list = flags_list->next; + } + } else { + flags = BIT(ARM_PROCESSOR_FLAGS_FIRST_ERROR_CAP) | + BIT(ARM_PROCESSOR_FLAGS_PROPAGATED); + } + pei[i].flags = flags; + + if (next->value->has_multiple_error) { + pei[i].multiple_error = next->value->multiple_error; + pei_validation |= BIT(ARM_PEI_VALIDATION_BITS_MULTIPLE_ERROR_VALID); + } + + if (next->value->has_error_info) { + pei[i].error_info = next->value->error_info; + } else { + switch (type) { + case BIT(ARM_PROCESSOR_ERROR_TYPE_CACHE_ERROR): + pei[i].error_info = 0x0091000F; + break; + case BIT(ARM_PROCESSOR_ERROR_TYPE_TLB_ERROR): + pei[i].error_info = 0x0054007F; + break; + case BIT(ARM_PROCESSOR_ERROR_TYPE_BUS_ERROR): + pei[i].error_info = 0x80D6460FFF; + break; + case BIT(ARM_PROCESSOR_ERROR_TYPE_MICRO_ARCH_ERROR): + pei[i].error_info = 0x78DA03FF; + break; + default: + /* + * UEFI 2.9A/2.10 doesn't define how this should be filled + * when multiple types are there. So, set default to zero, + * causing it to be removed from validation bits. + */ + pei[i].error_info = 0; + } + } + + if (next->value->has_virt_addr) { + pei[i].virt_addr = next->value->virt_addr; + pei_validation |= BIT(ARM_PEI_VALIDATION_BITS_VIRT_ADDR_VALID); + } + + if (next->value->has_phy_addr) { + pei[i].phy_addr = next->value->phy_addr; + pei_validation |= BIT(ARM_PEI_VALIDATION_BITS_PHY_ADDR_VALID); + } + + if (!next->value->has_validation) { + if (pei[i].flags) { + pei_validation |= BIT(ARM_PEI_VALIDATION_BITS_FLAGS_VALID); + } + if (pei[i].error_info) { + pei_validation |= BIT(ARM_PEI_VALIDATION_BITS_ERROR_INFO_VALID); + } + if (next->value->has_virt_addr) { + pei_validation |= BIT(ARM_PEI_VALIDATION_BITS_VIRT_ADDR_VALID); + } + + if (next->value->has_phy_addr) { + pei_validation |= BIT(ARM_PEI_VALIDATION_BITS_PHY_ADDR_VALID); + } + } + + pei[i].validation = pei_validation; + } + + return pei; +} + +/* + * UEFI 2.10 default context register type (See UEFI 2.10 table N.21 for more) + */ +#define CONTEXT_AARCH32_EL1 1 +#define CONTEXT_AARCH64_EL1 5 + +static int get_default_context_type(void) +{ + ARMCPU *cpu = ARM_CPU(qemu_get_cpu(0)); + bool aarch64; + + aarch64 = object_property_get_bool(OBJECT(cpu), "aarch64", NULL); + + if (aarch64) { + return CONTEXT_AARCH64_EL1; + } + return CONTEXT_AARCH32_EL1; +} + +/* Handle ARM Context */ +static ArmContext *qmp_arm_context(uint16_t *context_info_num, + uint32_t *context_length, + bool has_context, + ArmProcessorContextList const *context_list) +{ + ArmProcessorContextList const *next; + ArmContext *context = NULL; + uint16_t i, j, num, default_type; + + default_type = get_default_context_type(); + + if (!has_context) { + *context_info_num = 0; + *context_length = 0; + + return NULL; + } + + /* Calculate sizes */ + num = 0; + for (next = context_list; next; next = next->next) { + uint32_t n_regs = 0; + + if (next->value->has_q_register) { + uint64List *reg = next->value->q_register; + + while (reg) { + n_regs++; + reg = reg->next; + } + + if (next->value->has_minimal_size && + next->value->minimal_size < n_regs) { + n_regs = next->value->minimal_size; + } + } else if (!next->value->has_minimal_size) { + n_regs = ACPI_GHES_ARM_CPER_CTX_DEFAULT_NREGS; + } + + if (!n_regs) { + next->value->minimal_size = 0; + } else { + next->value->minimal_size = (n_regs + 1) % 0xfffe; + } + + num++; + if (num >= 65535) { + break; + } + } + + context = g_new0(ArmContext, num); + + /* Fill context data */ + + *context_length = 0; + *context_info_num = 0; + + next = context_list; + for (i = 0; i < num; i++, next = next->next) { + if (!next->value->minimal_size) { + continue; + } + + if (next->value->has_type) { + context[*context_info_num].type = next->value->type; + } else { + context[*context_info_num].type = default_type; + } + context[*context_info_num].size = next->value->minimal_size; + context[*context_info_num].array = g_malloc0(context[*context_info_num].size * 8); + + (*context_info_num)++; + + /* length = 64 bits * (size of the reg array + context type) */ + *context_length += (context->size + 1) * 8; + + if (!next->value->has_q_register) { + *context->array = 0xDEADBEEF; + } else { + uint64_t *pos = context->array; + uint64List *reg = next->value->q_register; + + for (j = 0; j < context->size; j++) { + if (!reg) { + break; + } + + *(pos++) = reg->value; + reg = reg->next; + } + } + } + + if (!*context_info_num) { + g_free(context); + return NULL; + } + + return context; +} + +static uint8_t *qmp_arm_vendor(uint32_t *vendor_num, bool has_vendor_specific, + uint8List const *vendor_specific_list) +{ + uint8List const *next = vendor_specific_list; + uint8_t *vendor = NULL, *p; + + if (!has_vendor_specific) { + return NULL; + } + + *vendor_num = 0; + + while (next) { + next = next->next; + (*vendor_num)++; + } + + vendor = g_malloc(*vendor_num); + + p = vendor; + next = vendor_specific_list; + while (next) { + *p = next->value; + next = next->next; + p++; + } + + return vendor; +} /* For ARM processor errors */ -void qmp_arm_inject_error(ArmProcessorErrorTypeList *errortypes, Error **errp) +void qmp_arm_inject_error(bool has_validation, + ArmProcessorValidationBitsList *validation_list, + bool has_affinity_level, + uint8_t affinity_level, + bool has_mpidr_el1, + uint64_t mpidr_el1, + bool has_midr_el1, + uint64_t midr_el1, + bool has_running_state, + ArmProcessorRunningStateList *running_state_list, + bool has_psci_state, + uint32_t psci_state, + bool has_context, ArmProcessorContextList *context_list, + bool has_vendor_specific, uint8List *vendor_specific_list, + bool has_error, + ArmProcessorErrorInformationList *error_list, + Error **errp) { MachineState *machine = MACHINE(qdev_get_machine()); MachineClass *mc = MACHINE_GET_CLASS(machine); - uint8_t error_types = 0; + ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(0)); + uint32_t running_state = 0; + uint16_t validation = 0; + ArmError error; + uint16_t i; - while (errortypes) { - error_types |= BIT(errortypes->value); - errortypes = errortypes->next; + /* Handle UEFI 2.0 N.16 specific fields, setting defaults when needed */ + + if (!has_midr_el1) { + mpidr_el1 = armcpu->midr; + } + + if (!has_mpidr_el1) { + mpidr_el1 = armcpu->mpidr; + } + + if (has_running_state) { + while (running_state_list) { + running_state |= BIT(running_state_list->value); + running_state_list = running_state_list; + } + + if (running_state) { + error.psci_state = 0; + } + } + + if (has_validation) { + while (validation_list) { + validation |= BIT(validation_list->value); + validation_list = validation_list->next; + } + } else { + if (has_vendor_specific) { + validation |= BIT(ARM_PROCESSOR_VALIDATION_BITS_VENDOR_SPECIFIC_VALID); + } + + if (has_affinity_level) { + validation |= BIT(ARM_PROCESSOR_VALIDATION_BITS_AFFINITY_VALID); + } + + if (mpidr_el1) { + validation = BIT(ARM_PROCESSOR_VALIDATION_BITS_MPIDR_VALID); + } + + if (!has_running_state) { + validation |= BIT(ARM_PROCESSOR_VALIDATION_BITS_RUNNING_STATE_VALID); + } + } + + /* Fill an error record */ + + error.validation = validation; + error.affinity_level = affinity_level; + error.mpidr_el1 = mpidr_el1; + error.midr_el1 = midr_el1; + error.running_state = running_state; + error.psci_state = psci_state; + + error.pei = qmp_arm_pei(&error.err_info_num, has_error, error_list); + error.context = qmp_arm_context(&error.context_info_num, + &error.context_length, + has_context, context_list); + error.vendor = qmp_arm_vendor(&error.vendor_num, has_vendor_specific, + vendor_specific_list); + + ghes_record_arm_errors(error, ACPI_GHES_NOTIFY_GPIO); + + if (error.context) { + for (i = 0; i < error.context_info_num; i++) { + g_free(error.context[i].array); + } } + g_free(error.context); + g_free(error.pei); + g_free(error.vendor); - ghes_record_arm_errors(error_types, ACPI_GHES_NOTIFY_GPIO); if (mc->set_error) { mc->set_error(); } diff --git a/hw/arm/arm_error_inject_stubs.c b/hw/arm/arm_error_inject_stubs.c index b51f4202fe64..7d7c00ad331b 100644 --- a/hw/arm/arm_error_inject_stubs.c +++ b/hw/arm/arm_error_inject_stubs.c @@ -10,9 +10,25 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include "qapi-commands-arm-error-inject.h" +#include "hw/acpi/ghes.h" -void qmp_arm_inject_error(ArmProcessorErrorTypeList *errortypes, Error **errp) +void qmp_arm_inject_error(bool has_validation, + ArmProcessorValidationBitsList *validation, + bool has_affinity_level, + uint8_t affinity_level, + bool has_mpidr_el1, + uint64_t mpidr_el1, + bool has_midr_el1, + uint64_t midr_el1, + bool has_running_state, + ArmProcessorRunningStateList *running_state, + bool has_psci_state, + uint32_t psci_state, + bool has_context, ArmProcessorContextList *context, + bool has_vendor_specific, uint8List *vendor_specific, + bool has_error, + ArmPeiList *error, + Error **errp) { error_setg(errp, "ARM processor error support is not compiled in"); } diff --git a/include/hw/acpi/ghes.h b/include/hw/acpi/ghes.h index dc531ffce7ae..c591a5fb02c4 100644 --- a/include/hw/acpi/ghes.h +++ b/include/hw/acpi/ghes.h @@ -23,6 +23,7 @@ #define ACPI_GHES_H #include "hw/acpi/bios-linker-loader.h" +#include "qapi/qapi-commands-arm-error-inject.h" /* * Values for Hardware Error Notification Type field @@ -68,6 +69,43 @@ typedef struct AcpiGhesState { bool present; /* True if GHES is present at all on this board */ } AcpiGhesState; +typedef struct ArmPEI { + uint16_t validation; + uint8_t type; + uint16_t multiple_error; + uint8_t flags; + uint64_t error_info; + uint64_t virt_addr; + uint64_t phy_addr; +} ArmPEI; + +typedef struct ArmContext { + uint16_t type; + uint32_t size; + uint64_t *array; +} ArmContext; + +/* ARM processor - UEFI 2.10 table N.16 */ +typedef struct ArmError { + uint16_t validation; + + uint8_t affinity_level; + uint64_t mpidr_el1; + uint64_t midr_el1; + uint32_t running_state; + uint32_t psci_state; + + /* Those are calculated based on the input data */ + uint16_t err_info_num; + uint16_t context_info_num; + uint32_t vendor_num; + uint32_t context_length; + + ArmPEI *pei; + ArmContext *context; + uint8_t *vendor; +} ArmError; + void build_ghes_error_table(GArray *hardware_errors, BIOSLinker *linker); void acpi_build_hest(GArray *table_data, BIOSLinker *linker, const char *oem_id, const char *oem_table_id); @@ -75,7 +113,7 @@ void acpi_ghes_add_fw_cfg(AcpiGhesState *vms, FWCfgState *s, GArray *hardware_errors); int acpi_ghes_record_errors(uint8_t notify, uint64_t error_physical_addr); -bool ghes_record_arm_errors(uint8_t error_types, uint32_t notify); +bool ghes_record_arm_errors(ArmError error, uint32_t notify); /** * acpi_ghes_present: Report whether ACPI GHES table is present diff --git a/qapi/arm-error-inject.json b/qapi/arm-error-inject.json index 430e6cea6b60..2a314830fe60 100644 --- a/qapi/arm-error-inject.json +++ b/qapi/arm-error-inject.json @@ -2,40 +2,258 @@ # vim: filetype=python ## -# = ARM Processor Errors +# = ARM Processor Errors as defined at: +# https://uefi.org/specs/UEFI/2.10/Apx_N_Common_Platform_Error_Record.html +# See tables N.16, N.17 and N.21. ## +## +# @ArmProcessorValidationBits: +# +# Indcates whether or not fields of ARM processor CPER record are valid. +# +# @mpidr-valid: MPIDR Valid +# +# @affinity-valid: Error affinity level Valid +# +# @running-state-valid: Running State +# +# @vendor-specific-valid: Vendor Specific Info Valid +# +# Since: 9.1 +## +{ 'enum': 'ArmProcessorValidationBits', + 'data': ['mpidr-valid', + 'affinity-valid', + 'running-state-valid', + 'vendor-specific-valid'] +} + +## +# @ArmProcessorFlags: +# +# Indicates error attributes at the Error info section. +# +# @first-error-cap: First error captured +# +# @last-error-cap: Last error captured +# +# @propagated: Propagated +# +# @overflow: Overflow +# +# Since: 9.1 +## +{ 'enum': 'ArmProcessorFlags', + 'data': ['first-error-cap', + 'last-error-cap', + 'propagated', + 'overflow'] +} + +## +# @ArmProcessorRunningState: +# +# Indicates if the processor is running. +# +# @processor-running: indicates that the processor is running +# +# Since: 9.1 +## +{ 'enum': 'ArmProcessorRunningState', + 'data': ['processor-running'] +} + ## # @ArmProcessorErrorType: # -# Type of ARM processor error to inject -# -# @unknown-error: Unknown error +# Type of ARM processor error information to inject. # # @cache-error: Cache error # # @tlb-error: TLB error # -# @bus-error: Bus error. +# @bus-error: Bus error # -# @micro-arch-error: Micro architectural error. +# @micro-arch-error: Micro architectural error # # Since: 9.1 ## { 'enum': 'ArmProcessorErrorType', - 'data': ['unknown-error', - 'cache-error', + 'data': ['cache-error', 'tlb-error', 'bus-error', 'micro-arch-error'] + } + +## +# @ArmPeiValidationBits: +# +# Indcates whether or not fields of Processor Error Info section are valid. +# +# @multiple-error-valid: Information at multiple-error field is valid +# +# @flags-valid: Information at flags field is valid +# +# @error-info-valid: Information at error-info field is valid +# +# @virt-addr-valid: Information at virt-addr field is valid +# +# @phy-addr-valid: Information at phy-addr field is valid +# +# Since: 9.1 +## +{ 'enum': 'ArmPeiValidationBits', + 'data': ['multiple-error-valid', + 'flags-valid', + 'error-info-valid', + 'virt-addr-valid', + 'phy-addr-valid'] +} + +## +# @ArmProcessorErrorInformation: +# +# Contains ARM processor error information (PEI) data according with UEFI +# CPER table N.17. +# +# @validation: +# Valid validation bits for error-info section. +# Argument is optional. If not specified, those flags will be enabled: +# first-error-cap and propagated. +# +# @type: +# ARM processor error types to inject. Argument is mandatory. +# +# @multiple-error: +# Indicates whether multiple errors have occurred. +# Argument is optional. If not specified and @validation not enforced, +# this field will be marked as invalid at CPER record.. +# +# @flags: +# Indicates flags that describe the error attributes. +# Argument is optional. If not specified and defaults to +# first-error and propagated. +# +# @error-info: +# Error information structure is specific to each error type. +# Argument is optional, and its value depends on the PEI type(s). +# If not defined, the default depends on the type: +# - for cache-error: 0x0091000F; +# - for tlb-error: 0x0054007F; +# - for bus-error: 0x80D6460FFF; +# - for micro-arch-error: 0x78DA03FF; +# - if multiple types used, this bit is disabled from @validation bits. +# +# @virt-addr: +# Virtual fault address associated with the error. +# Argument is optional. If not specified and @validation not enforced, +# this field will be marked as invalid at CPER record.. +# +# @phy-addr: +# Physical fault address associated with the error. +# Argument is optional. If not specified and @validation not enforced, +# this field will be marked as invalid at CPER record.. +# +# Since: 9.1 +## +{ 'struct': 'ArmProcessorErrorInformation', + 'data': { '*validation': ['ArmPeiValidationBits'], + 'type': ['ArmProcessorErrorType'], + '*multiple-error': 'uint16', + '*flags': ['ArmProcessorFlags'], + '*error-info': 'uint64', + '*virt-addr': 'uint64', + '*phy-addr': 'uint64'} +} + +## +# @ArmProcessorContext: +# +# Provide processor context state specific to the ARM processor architecture, +# According with UEFI 2.10 CPER table N.21. +# Argument is optional.If not specified, no context will be used. +# +# @type: +# Contains an integer value indicating the type of context state being +# reported. +# Argument is optional. If not defined, it will be set to be EL1 register +# for the emulation, e. g.: +# - on arm32: AArch32 EL1 context registers; +# - on arm64: AArch64 EL1 context registers. +# +# @register: +# Provides the contents of the actual registers or raw data, depending +# on the context type. +# Argument is optional. If not defined, it will fill the first register +# with 0xDEADBEEF, and the other ones with zero. +# +# @minimal-size: +# Argument is optional. If provided, define the minimal size of the +# context register array. The actual size is defined by checking the +# number of register values plus the content of this field (if used), +# ensuring that each processor context information structure array is +# padded with zeros if the size is not a multiple of 16 bytes. +# +# Since: 9.1 +## +{ 'struct': 'ArmProcessorContext', + 'data': { '*type': 'uint16', + '*minimal-size': 'uint32', + '*register': ['uint64']} } ## # @arm-inject-error: # -# Inject ARM Processor error. +# Inject ARM Processor error with data to be filled accordign with UEFI 2.10 +# CPER table N.16. # -# @errortypes: ARM processor error types to inject +# @validation: +# Valid validation bits for ARM processor CPER. +# Argument is optional. If not specified, the default is +# calculated based on having the corresponding arguments filled. +# +# @affinity-level: +# Error affinity level for errors that can be attributed to a specific +# affinity level. +# Argument is optional. If not specified and @validation not enforced, +# this field will be marked as invalid at CPER record. +# +# @mpidr-el1: +# Processor’s unique ID in the system. +# Argument is optional. If not specified, it will use the cpu mpidr +# field from the emulation data. If zero and @validation is not +# enforced, this field will be marked as invalid at CPER record. +# +# @midr-el1: Identification info of the chip +# Argument is optional. If not specified, it will use the cpu mpidr +# field from the emulation data. If zero and @validation is not +# enforced, this field will be marked as invalid at CPER record. +# +# @running-state: +# Indicates the running state of the processor. +# Argument is optional. If not specified and @validation not enforced, +# this field will be marked as invalid at CPER record. +# +# @psci-state: +# Provides PSCI state of the processor, as defined in ARM PSCI document. +# Argument is optional. If not specified, it will use the cpu power +# state field from the emulation data. +# +# @context: +# Contains an array of processor context registers. +# Argument is optional. If not specified, no context will be added. +# +# @vendor-specific: +# Contains a byte array of vendor-specific data. +# Argument is optional. If not specified, no vendor-specific data +# will be added. +# +# @error: +# Contains an array of ARM processor error information (PEI) sections. +# Argument is optional. If not specified, defaults to a single +# Program Error Information record defaulting to type=cache-error. # # Features: # @@ -44,6 +262,16 @@ # Since: 9.1 ## { 'command': 'arm-inject-error', - 'data': { 'errortypes': ['ArmProcessorErrorType'] }, + 'data': { + '*validation': ['ArmProcessorValidationBits'], + '*affinity-level': 'uint8', + '*mpidr-el1': 'uint64', + '*midr-el1': 'uint64', + '*running-state': ['ArmProcessorRunningState'], + '*psci-state': 'uint32', + '*context': ['ArmProcessorContext'], + '*vendor-specific': ['uint8'], + '*error': ['ArmProcessorErrorInformation'] + }, 'features': [ 'unstable' ] } diff --git a/tests/lcitool/libvirt-ci b/tests/lcitool/libvirt-ci index 0e9490cebc72..77c800186f34 160000 --- a/tests/lcitool/libvirt-ci +++ b/tests/lcitool/libvirt-ci @@ -1 +1 @@ -Subproject commit 0e9490cebc726ef772b6c9e27dac32e7ae99f9b2 +Subproject commit 77c800186f34b21be7660750577cc5582a914deb