From patchwork Fri Jul 12 13:15:08 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: 13731756 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 D476AC2BD09 for ; Fri, 12 Jul 2024 13:18:13 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sSG8R-0006Uv-MX; Fri, 12 Jul 2024 09:16:27 -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 1sSG7c-0004zI-DZ; Fri, 12 Jul 2024 09:15:37 -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 1sSG7Z-0001EC-1j; Fri, 12 Jul 2024 09:15:36 -0400 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by dfw.source.kernel.org (Postfix) with ESMTP id 6D0CB61F0A; Fri, 12 Jul 2024 13:15:22 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1F75DC4AF0E; Fri, 12 Jul 2024 13:15:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1720790122; bh=raCX3FLzfIuotLZqJ3wF6jjKTcaaKJ8KCg82aZWFMgw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=AJIRJKxwF3Al8DHIp0C6poetpPMQ937gL6rxbyAZGsO1ZgiNFlru29F5jCXXXebSB dYQlKMUXTwtx2oZtKmfh+NPPoBUhtbX26Zu8SLxC4FJhSetA0SVTpsUKddo96GMlhh llpBV7GbJ8sSF+OQ/7ONKPZhgaXkohzuBl/wb6da7CI5t5+MN6fP//uYyc3kONhSe2 tI0dxH3qWoYqFS6o2bhFFx11VN3WRKGZq+x4P1yPRQ4LZ/0XbG5wdp7pw/YKXQhyzq jLZ2SyMBKEqDj3lz5rlJIkVSunGBPTPGWhxyG866ZZiUkDk0sWa5mo8e2v9MzeIZuC ctU2w1nKd7CDA== Received: from mchehab by mail.kernel.org with local (Exim 4.97.1) (envelope-from ) id 1sSG7K-00000003iDx-130C; Fri, 12 Jul 2024 15:15:18 +0200 From: Mauro Carvalho Chehab To: Cc: Mauro Carvalho Chehab , "Jonathan Cameron" , "Michael S. Tsirkin" , "Shiju Jose" , Ani Sinha , Igor Mammedov , Peter Maydell , Shannon Zhao , linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v2 1/7] arm/virt: place power button pin number on a define Date: Fri, 12 Jul 2024 15:15:08 +0200 Message-ID: <88fcd8947095ec6dff8ea709c8ceffa72b16f686.1720789921.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.138, 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 Having magic numbers inside the code is not a good idea, as it is error-prone. So, instead, create a macro with the number definition. Signed-off-by: Mauro Carvalho Chehab Reviewed-by: Jonathan Cameron --- hw/arm/virt-acpi-build.c | 6 +++--- hw/arm/virt.c | 3 ++- include/hw/arm/virt.h | 3 +++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index e10cad86dd73..ad0a0bcec310 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -154,10 +154,10 @@ static void acpi_dsdt_add_gpio(Aml *scope, const MemMapEntry *gpio_memmap, aml_append(dev, aml_name_decl("_CRS", crs)); Aml *aei = aml_resource_template(); - /* Pin 3 for power button */ - const uint32_t pin_list[1] = {3}; + /* Pin for power button */ + const uint32_t pin = GPIO_PIN_POWER_BUTTON; 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)); aml_append(dev, aml_name_decl("_AEI", aei)); diff --git a/hw/arm/virt.c b/hw/arm/virt.c index b0c68d66a345..7b886f3477b6 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -1013,7 +1013,8 @@ static void create_gpio_keys(char *fdt, DeviceState *pl061_dev, uint32_t phandle) { gpio_key_dev = sysbus_create_simple("gpio-key", -1, - qdev_get_gpio_in(pl061_dev, 3)); + qdev_get_gpio_in(pl061_dev, + GPIO_PIN_POWER_BUTTON)); qemu_fdt_add_subnode(fdt, "/gpio-keys"); qemu_fdt_setprop_string(fdt, "/gpio-keys", "compatible", "gpio-keys"); diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index ab961bb6a9b8..a4d937ed45ac 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -47,6 +47,9 @@ /* See Linux kernel arch/arm64/include/asm/pvclock-abi.h */ #define PVTIME_SIZE_PER_CPU 64 +/* GPIO pins */ +#define GPIO_PIN_POWER_BUTTON 3 + enum { VIRT_FLASH, VIRT_MEM, From patchwork Fri Jul 12 13:15:09 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: 13731753 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 063D2C3DA4B for ; Fri, 12 Jul 2024 13:17:22 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sSG8D-0005nf-Cj; Fri, 12 Jul 2024 09:16:18 -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 1sSG7d-0004zL-06; Fri, 12 Jul 2024 09:15: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 1sSG7a-0001Es-CY; Fri, 12 Jul 2024 09:15:36 -0400 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by sin.source.kernel.org (Postfix) with ESMTP id 05875CE1AF6; Fri, 12 Jul 2024 13:15:23 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1854EC32782; Fri, 12 Jul 2024 13:15:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1720790122; bh=SAEGdrf246FkKPr4lSy9UNGxgkwkh9lZq9CgAdRPGs8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=shNvFlPN5cmM/QoEDMuvnWpqO5uG6Wezy2jJe0abL+dfNMqtxpZvnQeFfOR9aY9tI HthJyhey366fTKS9UJp123GgIy/w9YHrvMT01xFYptV64Rxf//37EzsNSI+9Xsfscd h+/A3SqytBIL8w67lgSzyabBALG7gs4UbSO1j3lziTNdtm3KN0+fMGg5VLfpiWY86x aYeLB98FC5Wx8EeogqIPo6TLGb4uKRRTtTpWZpKP1W3sYSpc+WEg8ZiHnqk4JONgYT R7sYhlkfQQxd1mEk1/f1IvcdnWE5DA7WvBv3MtwMFi+FjoJ1x1AZDab6FgPK08evzz vKzP1hQW0qSQA== Received: from mchehab by mail.kernel.org with local (Exim 4.97.1) (envelope-from ) id 1sSG7K-00000003iE0-1A0n; Fri, 12 Jul 2024 15:15:18 +0200 From: Mauro Carvalho Chehab To: Cc: Jonathan Cameron , "Michael S. Tsirkin" , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , "Shiju Jose" , Ani Sinha , Eduardo Habkost , Igor Mammedov , Marcel Apfelbaum , Peter Maydell , Shannon Zhao , Yanan Wang , linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, Mauro Carvalho Chehab Subject: [PATCH v2 2/7] arm/virt: Wire up GPIO error source for ACPI / GHES Date: Fri, 12 Jul 2024 15:15:09 +0200 Message-ID: <1306bcb4294a73525e2dbb775ec29c0e73f509e6.1720789922.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.138, 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. [mchehab: use a define for the generic event pin number and do some cleanups] Signed-off-by: Jonathan Cameron Signed-off-by: Mauro Carvalho Chehab --- hw/arm/virt-acpi-build.c | 30 ++++++++++++++++++++++++++---- hw/arm/virt.c | 14 ++++++++++++-- include/hw/arm/virt.h | 1 + include/hw/boards.h | 1 + 4 files changed, 40 insertions(+), 6 deletions(-) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index ad0a0bcec310..98b980e2443e 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) @@ -142,6 +143,8 @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap, static void acpi_dsdt_add_gpio(Aml *scope, const MemMapEntry *gpio_memmap, uint32_t gpio_irq) { + uint32_t pin; + Aml *dev = aml_device("GPO0"); aml_append(dev, aml_name_decl("_HID", aml_string("ARMH0061"))); aml_append(dev, aml_name_decl("_UID", aml_int(0))); @@ -155,7 +158,12 @@ static void acpi_dsdt_add_gpio(Aml *scope, const MemMapEntry *gpio_memmap, Aml *aei = aml_resource_template(); /* Pin for power button */ - const uint32_t pin = GPIO_PIN_POWER_BUTTON; + pin = GPIO_PIN_POWER_BUTTON; + aml_append(aei, aml_gpio_int(AML_CONSUMER, AML_EDGE, AML_ACTIVE_HIGH, + AML_EXCLUSIVE, AML_PULL_UP, 0, &pin, 1, + "GPO0", NULL, 0)); + /* Pin for generic error */ + pin = GPIO_PIN_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)); @@ -166,6 +174,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 +813,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) @@ -841,10 +863,9 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) HOTPLUG_HANDLER(vms->acpi_dev), 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 +879,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 7b886f3477b6..e470c6c33352 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); @@ -1015,6 +1022,9 @@ 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, GPIO_PIN_POWER_BUTTON)); + gpio_error_dev = sysbus_create_simple("gpio-key", -1, + qdev_get_gpio_in(pl061_dev, + GPIO_PIN_GENERIC_ERROR)); qemu_fdt_add_subnode(fdt, "/gpio-keys"); qemu_fdt_setprop_string(fdt, "/gpio-keys", "compatible", "gpio-keys"); @@ -2385,9 +2395,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); @@ -3101,6 +3110,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/arm/virt.h b/include/hw/arm/virt.h index a4d937ed45ac..c9769d7d4d7f 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -49,6 +49,7 @@ /* GPIO pins */ #define GPIO_PIN_POWER_BUTTON 3 +#define GPIO_PIN_GENERIC_ERROR 6 enum { VIRT_FLASH, 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 Fri Jul 12 13:15:10 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: 13731750 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 00293C2BD09 for ; Fri, 12 Jul 2024 13:17:20 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sSG85-0005IS-Iu; Fri, 12 Jul 2024 09:16:06 -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 1sSG7b-0004xZ-33; Fri, 12 Jul 2024 09:15:35 -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 1sSG7Z-0001EB-2N; Fri, 12 Jul 2024 09:15:34 -0400 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by dfw.source.kernel.org (Postfix) with ESMTP id 6D0B061F06; Fri, 12 Jul 2024 13:15:22 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1AD06C32786; Fri, 12 Jul 2024 13:15:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1720790122; bh=3+tNSaQ8a39Ggzkv/WVrggnD0uGXWcuNnDojR+LSc44=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=r9FDkA/VxWgd+FqGoKZiXw2m/ArYZ12lDH/lIUDB/KCWYuNLRY0kpWd3QOvCz6pUA miCHeYbCTJR8UVK13P0GtbacHKqcayNGDWk/T2Pzkm5Wt8PkUSt+VpNPGwl78mz+C8 9B07lEUFKvoZRAAz9KiVmZ4nYxb9or+qJ5TelcZc19UCPQFvL8FLJOFr//JuBIdgnH biqRjcHDmIWmZiNprlYZ030Io69ctXQkJ7f9agimzMInFPu78UxVTFfVR+UhnKsr7a YfYcYB7Idf3Wz9jrQf89dmP280e1Quk4SJAdMHY+P6xulsHQF+QIN2uOYLDZnAyL8q i5yZJB9EEpBRQ== Received: from mchehab by mail.kernel.org with local (Exim 4.97.1) (envelope-from ) id 1sSG7K-00000003iE3-1GoG; Fri, 12 Jul 2024 15:15:18 +0200 From: Mauro Carvalho Chehab To: Cc: Jonathan Cameron , "Michael S. Tsirkin" , "Shiju Jose" , Ani Sinha , Dongjiu Geng , Igor Mammedov , linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, Mauro Carvalho Chehab Subject: [PATCH v2 3/7] acpi/ghes: Support GPIO error source. Date: Fri, 12 Jul 2024 15:15:10 +0200 Message-ID: <90ee117d9950262a9efee1429ae2ecea5fd8a6a4.1720789922.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=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.138, 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 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 Fri Jul 12 13:15:11 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: 13731755 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 82C94C2BD09 for ; Fri, 12 Jul 2024 13:17:30 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sSG8z-0000LG-OZ; Fri, 12 Jul 2024 09:17:02 -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 1sSG7e-000527-Cr; Fri, 12 Jul 2024 09:15:39 -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 1sSG7Z-0001EK-2P; Fri, 12 Jul 2024 09:15:37 -0400 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by dfw.source.kernel.org (Postfix) with ESMTP id A397361F11; Fri, 12 Jul 2024 13:15:22 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1CFB0C4AF0B; Fri, 12 Jul 2024 13:15:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1720790122; bh=yjdVpMd5ozOqshPdRctXbXJ90enrbC9UDU0HeS1DIBE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=vFkd4JS6mSgTM2kI+Gq4+VJFd18DVAzhpjmZHNpTTMN9sT49IEf+6hS+Nw1kZWEpC nQoazMn4oKIQNeVmZgBVhgSf2FHXtuMmDsh8v8ASgGml94uEpp/7qKOFTynw1KROLz Re0m7EwhBM5g5evGf2Enn2w1efniwuh2Q+YF69WkbC8PqKtnuBSde1Oyvl37NiwaGk KdqbaU25GgP6dK/FwacWC4N2JR42dgpldmb6LBxgTHb8nYpIxV1nRLObzN/FSFZpBV OuFrTZ8/lDuzcXbFjFD7afsOLx7yQL0qaXus3DcDq68NdvWp91km0FmaPDLxPV700+ 7TzN6ehaXb0Ew== Received: from mchehab by mail.kernel.org with local (Exim 4.97.1) (envelope-from ) id 1sSG7K-00000003iE9-1OBn; Fri, 12 Jul 2024 15:15:18 +0200 From: Mauro Carvalho Chehab To: Cc: Jonathan Cameron , "Michael S. Tsirkin" , "Shiju Jose" , Ani Sinha , Dongjiu Geng , Eric Blake , Igor Mammedov , Markus Armbruster , Michael Roth , Paolo Bonzini , Peter Maydell , linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, Mauro Carvalho Chehab Subject: [PATCH v2 4/7] acpi/ghes: Add a logic to handle block addresses and FW first ARM processor error injection Date: Fri, 12 Jul 2024 15:15:11 +0200 Message-ID: <75c58d17a14b2c3dabcde790e0bdfbdbf8909025.1720789922.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.138, 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 Fri Jul 12 13:15:12 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: 13731752 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 9F9C7C3DA4D for ; Fri, 12 Jul 2024 13:17:21 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sSG8D-0005nT-Bq; Fri, 12 Jul 2024 09:16:18 -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 1sSG7c-0004zK-H6; Fri, 12 Jul 2024 09:15:37 -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 1sSG7a-0001Eu-0x; Fri, 12 Jul 2024 09:15:36 -0400 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by sin.source.kernel.org (Postfix) with ESMTP id 800BECE1AF5; Fri, 12 Jul 2024 13:15:22 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 24CAEC4AF10; Fri, 12 Jul 2024 13:15:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1720790122; bh=9YH+uN2FpTDfQsql9e3P4xbbtz8E4TbY1G0zlNhC2vc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eapYYC1YsFxVkG74Ij9c7WPxBrDik6Dqz5rJDE067AbX4V7pyvKO6RY/TBroOU5cb i9NYFBukMQs8CJKDCGCMSpuGTmIf7zD1x4HHEBoPVzh0viqR3CR3jRddADhVMzc7JS nwlpJuMzv4wokjqYHdC82c7TxO8JXL1HVST+t1toy0fvyEJvMR09s9E5G/pSfkDgAH hLpFOKLu4dIMADQInwO6h5sLrv6HK2ganuIdozDycsvr2CWfOg+J3AyJ9Fc20wMXEA KsBQmLZYMeB8i/t4aqRJhEosxKpNjU1Lb/E+7mNwsrgAVjqpERP0203NQMYHluXqQ3 mPWoOMxPRO5jg== Received: from mchehab by mail.kernel.org with local (Exim 4.97.1) (envelope-from ) id 1sSG7K-00000003iED-1V73; Fri, 12 Jul 2024 15:15:18 +0200 From: Mauro Carvalho Chehab To: Cc: Mauro Carvalho Chehab , "Jonathan Cameron" , "Shiju Jose" , Peter Maydell , linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v2 5/7] target/arm: preserve mpidr value Date: Fri, 12 Jul 2024 15:15:12 +0200 Message-ID: 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.138, 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 a12859fc5335..d2e86f0877cc 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1033,6 +1033,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 Fri Jul 12 13:15:13 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: 13731754 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 3B7D8C3DA50 for ; Fri, 12 Jul 2024 13:17:22 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sSG83-0005DX-Ej; Fri, 12 Jul 2024 09:16:06 -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 1sSG7b-0004xb-6W; Fri, 12 Jul 2024 09:15:35 -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 1sSG7Z-0001Ex-1T; Fri, 12 Jul 2024 09:15:34 -0400 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by dfw.source.kernel.org (Postfix) with ESMTP id 583C461F12; Fri, 12 Jul 2024 13:15:24 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 29EB5C4AF0E; Fri, 12 Jul 2024 13:15:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1720790124; bh=8fT3iZX4Ak9UXbYdPywtW7xLXPjIWOMseP9okwfRJuM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=U2EqWA7CHtiDiiyTRgXZU7WHF3m0LWOjFPJPY81n2Nd11kwBzZ/GxNWTzFBGamcu1 zdH8uqTMneNnuxECk5b6dEzbihDQGBlOM2XdrmIjaMoRVAKZpU7G464DS3mRzF/5hg x8yF5h2mWrJlLhyX3S7MqYhL3L3OUPg6CGeo480MhtkU3THgm3Ve67nL+1nXouIwBy eifKOq8k0Q62gnKCZTx/xRqqgY365VwIxXEnU0h7ftPTp5+GE2RvBKJ0aE9q5cjDvV EXGIR5ruwIwUi47FgnFkbrjaW1na6T3HbvHn2MVZek8t+PE9nYJPtu+aEU2QwD/185 uG0mqUOV5WUZw== Received: from mchehab by mail.kernel.org with local (Exim 4.97.1) (envelope-from ) id 1sSG7K-00000003iEH-1bpp; Fri, 12 Jul 2024 15:15:18 +0200 From: Mauro Carvalho Chehab To: Cc: Mauro Carvalho Chehab , "Jonathan Cameron" , "Michael S. Tsirkin" , "Shiju Jose" , Ani Sinha , Dongjiu Geng , Igor Mammedov , linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v2 6/7] acpi/ghes: update comments to point to newer ACPI specs Date: Fri, 12 Jul 2024 15:15:13 +0200 Message-ID: <0cdc463665c98c017020d791d36659a879372c1f.1720789922.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.138, 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 Fri Jul 12 13:15:14 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: 13731751 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 13439C41513 for ; Fri, 12 Jul 2024 13:17:20 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sSG8S-0006bf-Pr; Fri, 12 Jul 2024 09:16:28 -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 1sSG7e-00052C-Mi; Fri, 12 Jul 2024 09:15:40 -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 1sSG7Z-0001F6-GZ; Fri, 12 Jul 2024 09:15:38 -0400 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by dfw.source.kernel.org (Postfix) with ESMTP id AD8E661F0F; Fri, 12 Jul 2024 13:15:24 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 29E84C32786; Fri, 12 Jul 2024 13:15:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1720790124; bh=Ybf7OUJPfmsnLr0J4zNeX89cSaIch9LE7Gl5bnjIZWc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jBmNpTdzZPZK0UwtFCXisX4NZTnOauztUc8vw3vmtb9eHvDgearmUahTQbpxqRKFj AtylDSLofXGo4XGZ7iJUWrSkoWGtsYZd01DxUVgMosgGa3QiDyu0gMPWsIFoL8tzh1 hfVQJYeDHbbXEuQnhv5lGO5vXyAG4SpiIR7rtkEyLlcjyfdJUfHHtgdI1/lMMHDc1S RphnBMsILjCIsj6hj95/dZOxhgy3/SEF4n4xGhOoCJ3q0jrRw4WSQa9C3XH4X1NkE4 02pc2QUCGbauyADL5uADVg+ID4MmIDo0M17CUvR9/EO9a7z/3/6/9/PC4cmj7U9Rn8 kRKIfr6x58vsg== Received: from mchehab by mail.kernel.org with local (Exim 4.97.1) (envelope-from ) id 1sSG7K-00000003iEL-1jI8; Fri, 12 Jul 2024 15:15:18 +0200 From: Mauro Carvalho Chehab To: Cc: Mauro Carvalho Chehab , =?utf-8?q?Alex_Benn?= =?utf-8?q?=C3=A9e?= , "Jonathan Cameron" , "Michael S. Tsirkin" , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , "Shiju Jose" , Ani Sinha , Beraldo Leal , Dongjiu Geng , Eric Blake , Igor Mammedov , Markus Armbruster , Peter Maydell , Thomas Huth , Wainer dos Santos Moschetta , linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v2 7/7] acpi/ghes: extend arm error injection logic Date: Fri, 12 Jul 2024 15:15:14 +0200 Message-ID: <8e054d0eb8702ec340eb77e4ccfdd4e80c24a822.1720789922.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=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.138, 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