From patchwork Mon Jul 22 06:45:53 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: 13738345 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 4A16AC3DA59 for ; Mon, 22 Jul 2024 06:47:19 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sVmoi-0001MO-Ms; Mon, 22 Jul 2024 02:46:40 -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 1sVmoY-00016Z-Ei; Mon, 22 Jul 2024 02:46:31 -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 1sVmoV-0003f9-3h; Mon, 22 Jul 2024 02:46:30 -0400 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by sin.source.kernel.org (Postfix) with ESMTP id DD580CE0A1B; Mon, 22 Jul 2024 06:46:16 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 24E95C116B1; Mon, 22 Jul 2024 06:46:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1721630776; bh=XsNqpMUJB0O6cj3yT/NeTaj5tNxcpWbVl6wxYyGWgio=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UEdxjxKvHvqJG9nY5yYMVZS5k1A8R0r0CgsbhkqHHaLTaGUD8V/UFTeKmWf2O9lYD Fu7CVBD2UTQYKgihYIBTBVHLTf4lvDxZpmxzq0RS2imdQg8uXlvSq7zpaOiTJPp97l KL1koWTU+jiJK2Pt26yofkCSA+7Xp4dxIVmz9IME8/pbhNwkxx77JxNBSz+8oBshXW q4HfyqDFBHIVM/qvk5ah6kRn9uE/i3z8Elyo2jBjtD/Ze+wZrBvLkUNyCJzIRi216U GrI2iR2qZkViHRE1X8ifOU2F3AHSzsbtQ8/OCrVOe48yqruK4gataRLwh+krS3Ui1u dNSnIHSCbghwA== Received: from mchehab by mail.kernel.org with local (Exim 4.97.1) (envelope-from ) id 1sVmoI-00000000WQi-0oQV; Mon, 22 Jul 2024 08:46:14 +0200 From: Mauro Carvalho Chehab To: Cc: Jonathan Cameron , Shiju Jose , Mauro Carvalho Chehab , "Michael S. Tsirkin" , Ani Sinha , Igor Mammedov , Peter Maydell , Shannon Zhao , linux-kernel@vger.kernel.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v3 1/7] arm/virt: place power button pin number on a define Date: Mon, 22 Jul 2024 08:45:53 +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+huawei@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.141, 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 | 7 ++++--- include/hw/arm/virt.h | 3 +++ 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index e10cad86dd73..f76fb117adff 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}; + + 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..c99c8b1713c6 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -1004,7 +1004,7 @@ static void virt_powerdown_req(Notifier *n, void *opaque) if (s->acpi_dev) { acpi_send_event(s->acpi_dev, ACPI_POWER_DOWN_STATUS); } else { - /* use gpio Pin 3 for power button event */ + /* use gpio Pin for power button event */ qemu_set_irq(qdev_get_gpio_in(gpio_key_dev, 0), 1); } } @@ -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"); @@ -1024,7 +1025,7 @@ static void create_gpio_keys(char *fdt, DeviceState *pl061_dev, qemu_fdt_setprop_cell(fdt, "/gpio-keys/poweroff", "linux,code", KEY_POWER); qemu_fdt_setprop_cells(fdt, "/gpio-keys/poweroff", - "gpios", phandle, 3, 0); + "gpios", phandle, GPIO_PIN_POWER_BUTTON, 0); } #define SECURE_GPIO_POWEROFF 0 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 Mon Jul 22 06:45:54 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: 13738349 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 DB6DAC3DA59 for ; Mon, 22 Jul 2024 06:47:56 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sVmoh-0001Jb-LC; Mon, 22 Jul 2024 02:46:39 -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 1sVmoZ-00016b-4n; Mon, 22 Jul 2024 02:46:31 -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 1sVmoV-0003fH-30; Mon, 22 Jul 2024 02:46:30 -0400 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by sin.source.kernel.org (Postfix) with ESMTP id C394ACE0B00; Mon, 22 Jul 2024 06:46:17 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 371C8C4AF0F; Mon, 22 Jul 2024 06:46:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1721630776; bh=5TngikYjgFjtcp97UwnkMRJH/Pu5HAa83aYM1pizKYs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=JME1cRyticsFJaOFrO2Q2tqUVQNKYgdy4qoFAuD0Vb4Jri5g79d8Hu0QCbI16ayng SxeOl7v3x5RoomOsxFXlF4UPQ40LwPGISGY398inb23j7RSjlVCGY49IDWf61uC6VH m5pwD6VBpbJ4uG0jQMlcP5/Z5A7tZouD75pU30qFSPuYnNd8WXoqC8mmbtec+vVWgt VJzhxVnOj/V0zlAYn230VWtCZvVF7GTJOwu2abQYoYBwYb5GTefh0iSRjhPXoLpAek PJhMjlTvU4XK763sEK0Xrclu5dKbEnRgnC3Ihxh+x3szY4XXsqFJLecFMIvNZluCoT lfbzb1JNoACbA== Received: from mchehab by mail.kernel.org with local (Exim 4.97.1) (envelope-from ) id 1sVmoI-00000000WQl-0vYS; Mon, 22 Jul 2024 08:46:14 +0200 From: Mauro Carvalho Chehab To: Cc: Jonathan Cameron , Shiju Jose , "Michael S. Tsirkin" , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , Ani Sinha , Eduardo Habkost , Igor Mammedov , Marcel Apfelbaum , Peter Maydell , Shannon Zhao , Yanan Wang , linux-kernel@vger.kernel.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, Mauro Carvalho Chehab Subject: [PATCH v3 2/7] arm/virt: Wire up GPIO error source for ACPI / GHES Date: Mon, 22 Jul 2024 08:45:54 +0200 Message-ID: <034a7e86761e09996001394c98ffb8201ac52cd2.1721630625.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+huawei@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.141, 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 f76fb117adff..c502ccf40909 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(); - 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 c99c8b1713c6..f81cf3a69961 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 Mon Jul 22 06:45:55 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: 13738351 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 391D0C3DA59 for ; Mon, 22 Jul 2024 06:48:07 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sVmoi-0001Nw-Q9; Mon, 22 Jul 2024 02:46:40 -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 1sVmoW-00014p-Vu; Mon, 22 Jul 2024 02:46:29 -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 1sVmoU-0003f8-Uv; Mon, 22 Jul 2024 02:46:28 -0400 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by sin.source.kernel.org (Postfix) with ESMTP id F3375CE0AFF; Mon, 22 Jul 2024 06:46:16 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4741EC4AF0A; Mon, 22 Jul 2024 06:46:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1721630776; bh=3+tNSaQ8a39Ggzkv/WVrggnD0uGXWcuNnDojR+LSc44=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oVL2WE7OZyykfjc+U2h2ZDFYoXmJtfncWZ00gq3o3UjqBibGgSeFarIwrqFI2rh5F fWU37+OYJd9BVpLWc8QGKcjj26Jl41p3Ixybo90RMiN9czMab0tZjslu8tLdMuy7cb L/5pz4+gZ6qJoNpGuaLvJvneqkTsmM+t4FcCFekjJhgI0hswZ7JhbdoJKtmXcNrHLm pA7bKJzR5nshm4UvQcDZbbyJXKg3clgCcdRQviH+9N9WDQQvwuI6/7WgLWEgJbn2Br w5TTtEMBnbcRyfZlWOtGFkV9U2G1kMSOog/hLMYKZPT32MwV6Gjt5fJpE/u7zw3Wt8 OAesAlhtMmIAA== Received: from mchehab by mail.kernel.org with local (Exim 4.97.1) (envelope-from ) id 1sVmoI-00000000WQo-12C9; Mon, 22 Jul 2024 08:46:14 +0200 From: Mauro Carvalho Chehab To: Cc: Jonathan Cameron , Shiju Jose , "Michael S. Tsirkin" , Ani Sinha , Dongjiu Geng , Igor Mammedov , linux-kernel@vger.kernel.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, Mauro Carvalho Chehab Subject: [PATCH v3 3/7] acpi/ghes: Support GPIO error source. Date: Mon, 22 Jul 2024 08:45:55 +0200 Message-ID: <64a31a09fe6b11bebad1c592ad20071a9d93fee5.1721630625.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+huawei@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.141, 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 Mon Jul 22 06:45:56 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: 13738348 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 AA158C3DA59 for ; Mon, 22 Jul 2024 06:47:49 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sVmol-0001Yr-Fd; Mon, 22 Jul 2024 02:46: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 1sVmoa-00019P-Qo; Mon, 22 Jul 2024 02:46:33 -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 1sVmoW-0003fJ-DS; Mon, 22 Jul 2024 02:46:31 -0400 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by sin.source.kernel.org (Postfix) with ESMTP id C9A82CE0B05; Mon, 22 Jul 2024 06:46:17 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 494C7C4AF12; Mon, 22 Jul 2024 06:46:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1721630776; bh=yjdVpMd5ozOqshPdRctXbXJ90enrbC9UDU0HeS1DIBE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MvlDxdWTJNIFgesjNEmElyiT1BCJ4Fc7+2R5eDRWEGsgrc0qgo7F4OEq2BAkmbKJc IU/iSt8aXg4uqXzGch1LQ4iCDE9uCj4ckaUwAtHcC3IJkr8q0Cj8Ik8DfwzEOK2gTZ GrxFRxuuAaJUTD/p9Sn+4oIxQ/c+IiU1YGzyx/nmZzkmZfCGwchz/QfeTkKQCyrMX6 ZmVNNplV0jtHHUNtKzdPesnGVOseS7vRafK6T5i0s9/U0V+H4pPqzx0u9fpnOSIT9i xtxFtM9GiCZfFwTXktfktPw7KO3wC0GOmx1uoqofWp6HrucPf/8vKmHkVZTKvDcyzH iu2dx80y0D+kg== Received: from mchehab by mail.kernel.org with local (Exim 4.97.1) (envelope-from ) id 1sVmoI-00000000WQu-1ABN; Mon, 22 Jul 2024 08:46:14 +0200 From: Mauro Carvalho Chehab To: Cc: Jonathan Cameron , Shiju Jose , "Michael S. Tsirkin" , Ani Sinha , Dongjiu Geng , Eric Blake , Igor Mammedov , Markus Armbruster , Michael Roth , Paolo Bonzini , Peter Maydell , linux-kernel@vger.kernel.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, Mauro Carvalho Chehab Subject: [PATCH v3 4/7] acpi/ghes: Add a logic to handle block addresses and FW first ARM processor error injection Date: Mon, 22 Jul 2024 08:45:56 +0200 Message-ID: <6a3542a7d8acfbf88c906ec6f6dc5a697257b461.1721630625.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+huawei@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.141, 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 Mon Jul 22 06:45:57 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: 13738342 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 DBD54C3DA59 for ; Mon, 22 Jul 2024 06:47:16 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sVmof-0001C6-EU; Mon, 22 Jul 2024 02:46:37 -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 1sVmoW-00014f-8M; Mon, 22 Jul 2024 02:46:29 -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 1sVmoT-0003er-PI; Mon, 22 Jul 2024 02:46:27 -0400 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by dfw.source.kernel.org (Postfix) with ESMTP id 640E660203; Mon, 22 Jul 2024 06:46:17 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 44259C4AF10; Mon, 22 Jul 2024 06:46:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1721630776; bh=9YH+uN2FpTDfQsql9e3P4xbbtz8E4TbY1G0zlNhC2vc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=egl5sfP2vUcutHSmBLB0tmEwjOTSlzqbEc+dIR/c5tpPcocxInvv+A3asIbKjFOA4 L5ai+QTaZjsqsfpy8a2H6dhdyUBmPW/bfW603ZUoUTMXaO0QO+y6XSrA/Ahhbtt+zk i7122QXfCj558UQboDJd/Bzxq81KUTkfymtvQOsABKy3qpYH0qcXzyVJ1P/0nqHS4h q/Tjk5Loax4EcnTSo8JYFTgRoRjW/tf62UI5fHgj12By0orP245M6QLVHjc2owq36N ErbSpua+irbPZK/+wgqluCFVTod9wnTwBYPfvmOxQhcgLi1OWEH84IpCj4e6PqITi6 FjMP5FLf65ojw== Received: from mchehab by mail.kernel.org with local (Exim 4.97.1) (envelope-from ) id 1sVmoI-00000000WQy-1GvZ; Mon, 22 Jul 2024 08:46:14 +0200 From: Mauro Carvalho Chehab To: Cc: Jonathan Cameron , Shiju Jose , Mauro Carvalho Chehab , Peter Maydell , linux-kernel@vger.kernel.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v3 5/7] target/arm: preserve mpidr value Date: Mon, 22 Jul 2024 08:45:57 +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+huawei@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.141, 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 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 Reviewed-by: Jonathan Cameron --- 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 Mon Jul 22 06:45:58 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: 13738346 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 59CF2C3DA59 for ; Mon, 22 Jul 2024 06:47:30 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sVmol-0001ZT-KP; Mon, 22 Jul 2024 02:46: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 1sVmoY-000166-2i; Mon, 22 Jul 2024 02:46:31 -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 1sVmoU-0003f6-Vr; Mon, 22 Jul 2024 02:46:29 -0400 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by sin.source.kernel.org (Postfix) with ESMTP id E0F3ECE0AFC; Mon, 22 Jul 2024 06:46:16 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 34E80C4AF0E; Mon, 22 Jul 2024 06:46:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1721630776; bh=8fT3iZX4Ak9UXbYdPywtW7xLXPjIWOMseP9okwfRJuM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kNpRBZZsm9mWd6iSI9j3jYworOiHY2yeaDBzIMmsRhBVgsfyLe/BKMCa2M+a7D2j1 +SpV1pEFifQ4EQoqZZlS+7wlnC+o2LihdhDKyfnxCGES7DcUUQv/U3LkklCSHaq3VN bxSHWYImNcUZ0+Fhcu/acfry+UH6Mh/zm/4pKfdYgyAvsfR4ajI+7xHzrN8480zpQ1 Qad5WxpHn/ESnwr4kp8AAz9CDY+5p3+uXBitopiQvR7pYEJnZj/MH1bA4kvbSSPj1S MLzg8uEJEMoIQDJZ/6Hin+GzvTVOyp6l+ptBvWyjzDYavsA1P0YFEKoKHbm8Arrled i7NDbtmtbjZnQ== Received: from mchehab by mail.kernel.org with local (Exim 4.97.1) (envelope-from ) id 1sVmoI-00000000WR2-1NVJ; Mon, 22 Jul 2024 08:46:14 +0200 From: Mauro Carvalho Chehab To: Cc: Jonathan Cameron , Shiju Jose , Mauro Carvalho Chehab , "Michael S. Tsirkin" , Ani Sinha , Dongjiu Geng , Igor Mammedov , linux-kernel@vger.kernel.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v3 6/7] acpi/ghes: update comments to point to newer ACPI specs Date: Mon, 22 Jul 2024 08:45:58 +0200 Message-ID: <66c1ab4988589be99ae925c6361548f55fea58b0.1721630625.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+huawei@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.141, 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 Mon Jul 22 06:45:59 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: 13738350 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 922FAC3DA70 for ; Mon, 22 Jul 2024 06:47:58 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sVmoj-0001Sa-SU; Mon, 22 Jul 2024 02:46:41 -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 1sVmoX-00014r-OD; Mon, 22 Jul 2024 02:46:29 -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 1sVmoT-0003ez-Q8; Mon, 22 Jul 2024 02:46:29 -0400 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by dfw.source.kernel.org (Postfix) with ESMTP id 7AE7A60AE3; Mon, 22 Jul 2024 06:46:17 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 78680C4AF15; Mon, 22 Jul 2024 06:46:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1721630776; bh=1HuMuT1ttMRVD5b3MGs1aDn7/srzeHxA14YchcYnQzg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TP41wM4n9RYEfGjXFDhGygTkFlegHThGtFSL2Bjiej9wk3lOn3jBEp55B1IHH/qUR fleIOlBrxAcqkPI6GjSj8fdnFyz5FfaL6cP/DZULwKwLQ+czlXR2g2kLtVoUMmDAp+ 3eUpL2FS3VJvqRaO2/if7FY58pYFIL8IrOr6F6Uph0yAYIBSFmI/V7d+E/BdbK0ot9 Mcbh/8IixgTwj/FLcmu5eqfJd+eXbNwbB/x4kpe/0ZYWliq3EQ/eM/uItoQxIlsQQP fLrLDTIqch1Lreujcz9DboX9FqSn6f3chtnCFHWkBR9gYJOp19VLX733NJ/qHPIPRK 6+vgUr6okWw9A== Received: from mchehab by mail.kernel.org with local (Exim 4.97.1) (envelope-from ) id 1sVmoI-00000000WR6-1VIg; Mon, 22 Jul 2024 08:46:14 +0200 From: Mauro Carvalho Chehab To: Cc: Jonathan Cameron , Shiju Jose , 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-kernel@vger.kernel.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v3 7/7] acpi/ghes: extend arm error injection logic Date: Mon, 22 Jul 2024 08:45:59 +0200 Message-ID: <89e8a63b5e54409dd9bc4e7f4f4c12290838371b.1721630625.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+huawei@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.141, 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..be6e8be2d0d9 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, + ArmProcessorErrorInformationList *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