From nobody Sun Nov 24 14:34:43 2024 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 186271ABEB7 for ; Fri, 2 Aug 2024 21:44:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722635064; cv=none; b=DGrOlJoo/hWz5bG2irtk1CE/Nt3N5D6BX6TJDG+DNHutic189ihtOU1otk6nInl5XvBbIznA2nMu+j4+5fmkt76c3eCS++rv2COeKB0mo/vbY07kanxOQuXXSqrt621sN6UbT7l0RlnIoVLdYtLvjUjuLJx7XghUoTCl2MCgtJY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722635064; c=relaxed/simple; bh=wmX5BOavDV5A0y4JGTIfwXXXDCYeYux2q4KKf6xw9vs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=myUOAcJ3KG1yTXZzDGntP/j1gGbVUFVbFDayDVktX8EVRgIH4b5o1jIXoOHhCiBE2gUOMU6f9soYO6vCq1FaB6ElGcaVP2Sj75q/eVxnElCoPh/kDmZHAcfIPe9uPzYjWQmNmmmkpR64fHIyXQbu2LNzZ0i9ZHFhlXmCVl3I2hw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=E34VGHam; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="E34VGHam" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C2175C4AF11; Fri, 2 Aug 2024 21:44:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1722635063; bh=wmX5BOavDV5A0y4JGTIfwXXXDCYeYux2q4KKf6xw9vs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=E34VGHamkEFAsuv6m6ZKnXZVpDvel53+0WGEuomQDdXsiNOY7IlOGo+NEWMqfWSnV UIz2EsZ6/FjAg5o6/jOZ6+GMVI7QmQGuW9gR4odCeELqyWkE9nS4Zm1otbIE4q4N6A BpKIrZM4fUOApvdDrXdGhh4eSUnTpa66JbQxEKcVgVz88ebRWL1toHdCWj9VRajlQU SdCzqGu409bHWlNojB2k3TSUJF49smY2qxBx+r8IMQ8aoE0xQKUzg1oLAZ4oSVhh2B 1pC/xuHFMyiJAS19E9a+2NmQ3+vONULZcqlloUdaTBW1yCng8jvrjIVm4eQRspdgEy eZQp0oz87Hlcw== Received: from mchehab by mail.kernel.org with local (Exim 4.98) (envelope-from ) id 1sa04T-00000002naD-2eiE; Fri, 02 Aug 2024 23:44:21 +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 v5 1/7] arm/virt: place power button pin number on a define Date: Fri, 2 Aug 2024 23:43:56 +0200 Message-ID: X-Mailer: git-send-email 2.45.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab Content-Type: text/plain; charset="utf-8" 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 Reviewed-by: Igor Mammedov --- 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 MemM= apEntry *gpio_memmap, aml_append(dev, aml_name_decl("_CRS", crs)); =20 Aml *aei =3D aml_resource_template(); - /* Pin 3 for power button */ - const uint32_t pin_list[1] =3D {3}; + + const uint32_t pin =3D 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)); =20 diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 719e83e6a1e7..687fe0bb8bc9 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -1004,7 +1004,7 @@ static void virt_powerdown_req(Notifier *n, void *opa= que) 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 =3D sysbus_create_simple("gpio-key", -1, - qdev_get_gpio_in(pl061_dev, 3)); + qdev_get_gpio_in(pl061_dev, + GPIO_PIN_POWER_BU= TTON)); =20 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); } =20 #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 =20 +/* GPIO pins */ +#define GPIO_PIN_POWER_BUTTON 3 + enum { VIRT_FLASH, VIRT_MEM, --=20 2.45.2 From nobody Sun Nov 24 14:34:43 2024 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 186EB81727 for ; Fri, 2 Aug 2024 21:44:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722635064; cv=none; b=dXlCz95b/dVhQNSZo70nKrq/StAaRqfLFNZMLqN8PIHVid5LW2W3BQr02tX2U19+J94RWQUyolBXd1NFsmEMloqROF6UthqvjgQTo9tkyGeKTmriHX0GjGtYY9iLN98hldEQcUglAbo427UxzrtYYlMcv7mxyEWolxotQnjrCqI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722635064; c=relaxed/simple; bh=lzZeLSx62/9+XmtaXqmWuty+3/8CulkJ9V68HTTwfN0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=EgVLN/r+RQZ/ca6wjmcLmPSbZ6ZYDRHPncTxemkWadjhgMM+8+WB4+yp6C//Lr0Gv+zn36vgbBGUMzrJd7Te1Gzl6a+JvxQi1BmHt79yJA6sb6ayemwyaLTxyMNm4vYq4JACDwJvgrMDywDUHMApWbVqhoeB5Q9tSIGWW536rAw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rQLuyKyU; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="rQLuyKyU" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BB15FC4AF0E; Fri, 2 Aug 2024 21:44:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1722635063; bh=lzZeLSx62/9+XmtaXqmWuty+3/8CulkJ9V68HTTwfN0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rQLuyKyUCRd/IQHZcat6NUYgzcSczLY+8tA+dgXRW45MHl1CVSRhJsQjxqSJzcEPV XPn31ifRdjVuhHvvd58t5c2ldt+hkt+l+Iww25f6YnxrCNgqWjuWljCUvZBj+Rw/p5 G3TqDYnhJehu1NqAqWZfGL/v1njwh6YjrpNZEqYPhTRIXTKMhz3lnfg3/E0jaiSn4A m0ECiezzZoP+ZU5SoIXZKAwQv0sV/XlS5ddmIe7ylChE2lAwaaZDddQl7A4DfntD4m RUWAa3GhoR5JgJJaF4lEbL0j5l5hRPTvivIUD7E6wAyftIBfdhlsWG9Ix5pYt2fdBY /ZYlxgmR3n8vg== Received: from mchehab by mail.kernel.org with local (Exim 4.98) (envelope-from ) id 1sa04T-00000002naG-2lLc; Fri, 02 Aug 2024 23:44:21 +0200 From: Mauro Carvalho Chehab To: Cc: Jonathan Cameron , Shiju Jose , Mauro Carvalho Chehab , "Michael S. Tsirkin" , Ani Sinha , Igor Mammedov , linux-kernel@vger.kernel.org, qemu-devel@nongnu.org Subject: [PATCH v5 2/7] acpi/generic_event_device: add an APEI error device Date: Fri, 2 Aug 2024 23:43:57 +0200 Message-ID: <5dfb5fb31afa249e06e0f849b37a7cb525f81215.1722634602.git.mchehab+huawei@kernel.org> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab Content-Type: text/plain; charset="utf-8" Adds a Generic Event Device to handle generic hardware error events, supporting General Purpose Event (GPE) as specified at ACPI 6.5 specification at 18.3.2.7.2: https://uefi.org/specs/ACPI/6.5/18_Platform_Error_Interfaces.html#event-not= ification-for-generic-error-sources using HID PNP0C33. The PNP0C33 device is used to report hardware errors to the bios via ACPI APEI Generic Hardware Error Source (GHES). Co-authored-by: Mauro Carvalho Chehab Co-authored-by: Jonathan Cameron Cc: Jonathan Cameron Signed-off-by: Mauro Carvalho Chehab --- hw/acpi/generic_event_device.c | 17 +++++++++++++++++ include/hw/acpi/acpi_dev_interface.h | 1 + include/hw/acpi/generic_event_device.h | 3 +++ 3 files changed, 21 insertions(+) diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c index 15b4c3ebbf24..b9ad05e98c05 100644 --- a/hw/acpi/generic_event_device.c +++ b/hw/acpi/generic_event_device.c @@ -26,6 +26,7 @@ static const uint32_t ged_supported_events[] =3D { ACPI_GED_PWR_DOWN_EVT, ACPI_GED_NVDIMM_HOTPLUG_EVT, ACPI_GED_CPU_HOTPLUG_EVT, + ACPI_GED_ERROR_EVT }; =20 /* @@ -116,6 +117,11 @@ void build_ged_aml(Aml *table, const char *name, Hotpl= ugHandler *hotplug_dev, aml_notify(aml_name(ACPI_POWER_BUTTON_DEVICE), aml_int(0x80))); break; + case ACPI_GED_ERROR_EVT: + aml_append(if_ctx, + aml_notify(aml_name(ACPI_APEI_ERROR_DEVICE), + aml_int(0x80))); + break; case ACPI_GED_NVDIMM_HOTPLUG_EVT: aml_append(if_ctx, aml_notify(aml_name("\\_SB.NVDR"), @@ -153,6 +159,15 @@ void acpi_dsdt_add_power_button(Aml *scope) aml_append(scope, dev); } =20 +void acpi_dsdt_add_error_device(Aml *scope) +{ + Aml *dev =3D aml_device(ACPI_APEI_ERROR_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); +} + /* Memory read by the GED _EVT AML dynamic method */ static uint64_t ged_evt_read(void *opaque, hwaddr addr, unsigned size) { @@ -295,6 +310,8 @@ static void acpi_ged_send_event(AcpiDeviceIf *adev, Acp= iEventStatusBits ev) sel =3D ACPI_GED_MEM_HOTPLUG_EVT; } else if (ev & ACPI_POWER_DOWN_STATUS) { sel =3D ACPI_GED_PWR_DOWN_EVT; + } else if (ev & ACPI_GENERIC_ERROR) { + sel =3D ACPI_GED_ERROR_EVT; } else if (ev & ACPI_NVDIMM_HOTPLUG_STATUS) { sel =3D ACPI_GED_NVDIMM_HOTPLUG_EVT; } else if (ev & ACPI_CPU_HOTPLUG_STATUS) { diff --git a/include/hw/acpi/acpi_dev_interface.h b/include/hw/acpi/acpi_de= v_interface.h index 68d9d15f50aa..8294f8f0ccca 100644 --- a/include/hw/acpi/acpi_dev_interface.h +++ b/include/hw/acpi/acpi_dev_interface.h @@ -13,6 +13,7 @@ typedef enum { ACPI_NVDIMM_HOTPLUG_STATUS =3D 16, ACPI_VMGENID_CHANGE_STATUS =3D 32, ACPI_POWER_DOWN_STATUS =3D 64, + ACPI_GENERIC_ERROR =3D 128, } AcpiEventStatusBits; =20 #define TYPE_ACPI_DEVICE_IF "acpi-device-interface" diff --git a/include/hw/acpi/generic_event_device.h b/include/hw/acpi/gener= ic_event_device.h index 40af3550b56d..b8f2f1328e0c 100644 --- a/include/hw/acpi/generic_event_device.h +++ b/include/hw/acpi/generic_event_device.h @@ -66,6 +66,7 @@ #include "qom/object.h" =20 #define ACPI_POWER_BUTTON_DEVICE "PWRB" +#define ACPI_APEI_ERROR_DEVICE "GEDD" =20 #define TYPE_ACPI_GED "acpi-ged" OBJECT_DECLARE_SIMPLE_TYPE(AcpiGedState, ACPI_GED) @@ -98,6 +99,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(AcpiGedState, ACPI_GED) #define ACPI_GED_PWR_DOWN_EVT 0x2 #define ACPI_GED_NVDIMM_HOTPLUG_EVT 0x4 #define ACPI_GED_CPU_HOTPLUG_EVT 0x8 +#define ACPI_GED_ERROR_EVT 0x10 =20 typedef struct GEDState { MemoryRegion evt; @@ -120,5 +122,6 @@ struct AcpiGedState { void build_ged_aml(Aml *table, const char* name, HotplugHandler *hotplug_d= ev, uint32_t ged_irq, AmlRegionSpace rs, hwaddr ged_base); void acpi_dsdt_add_power_button(Aml *scope); +void acpi_dsdt_add_error_device(Aml *scope); =20 #endif --=20 2.45.2 From nobody Sun Nov 24 14:34:43 2024 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1866E73446 for ; Fri, 2 Aug 2024 21:44:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722635064; cv=none; b=NAntT0xYgc/sytAip/laEbuBBfVub9eax7bB9mQDoRpNOsD/XUxgu8JBa/VChla1LCTrTWnmfUVOK5JU4+rpR1nmd3Vpw+cXEkJXl/ivhEllM1xtu9Kmcmr1MRXS+w5iIqNOnFEDLz2IZ7nab9JOp8hM76Dpz2J2TW+kH9J1OVI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722635064; c=relaxed/simple; bh=oBrmRMT6eVkZhSBwJ/tCQXBFfP8uBbfVpOcor3ldlVA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tZjOLdtM/r8wmpdI40eVl35Sr7mJxLwoCaG2hBgDmUaBXb4hn0r0zQncmr5d+Y0sxvXBGsFiM7einZQ+mYaEPjkdK7MOJn6w1orcOzdzX2ztGTCZCSXDbuHaP3MHQbbUMZp42MkwnzTyWKWKbuV7R5Ph2weS0hKAxlAPH3a98r4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=P+GR71yS; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="P+GR71yS" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BF9E5C4AF09; Fri, 2 Aug 2024 21:44:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1722635063; bh=oBrmRMT6eVkZhSBwJ/tCQXBFfP8uBbfVpOcor3ldlVA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=P+GR71ySO4elhXHLcBnJY5xs7O1P+RAm2L5b5NPqDn/+LOJAXp6bzkLZduF/0HWBO IqpYVcn2/bexTq+s1risYu7u9OKAx247lEgTkyV1YYKHpRy5wY0WnvKqpCObnezwiR YQnn9aNIBdYbXJnuMElohcL6mMS9DnzjdnLjyx0nx8FFnhbkpmQ2FkxJ5ewlU4m228 pc6VHXb3zm9Zr/D2K+HwRKDIwIiCO0PWA02eFLqE8Grtzyl1YhAPm44yHLuRQOpdnA 1RQSD9G1fTlOtWsBoHlv9QR8D1iNqVKDC5Lb2bSTMMusUT+303X1p/pB9naf1niVD1 2WZ93wpP1Zicw== Received: from mchehab by mail.kernel.org with local (Exim 4.98) (envelope-from ) id 1sa04T-00000002naJ-2sEj; Fri, 02 Aug 2024 23:44:21 +0200 From: Mauro Carvalho Chehab To: Cc: Jonathan Cameron , Shiju Jose , Mauro Carvalho Chehab , "Michael S. Tsirkin" , Ani Sinha , Dongjiu Geng , Igor Mammedov , Peter Maydell , Shannon Zhao , linux-kernel@vger.kernel.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v5 3/7] arm/virt: Wire up GPIO error source for ACPI / GHES Date: Fri, 2 Aug 2024 23:43:58 +0200 Message-ID: X-Mailer: git-send-email 2.45.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab Content-Type: text/plain; charset="utf-8" Adds support to ARM virtualization to allow handling a General Purpose Event (GPE) via GED error device. It is aligned with Linux Kernel patch: https://lore.kernel.org/lkml/1272350481-27951-8-git-send-email-ying.huang@i= ntel.com/ Co-authored-by: Mauro Carvalho Chehab Co-authored-by: Jonathan Cameron Cc: Jonathan Cameron Signed-off-by: Mauro Carvalho Chehab --- hw/acpi/ghes.c | 3 +++ hw/arm/virt-acpi-build.c | 1 + hw/arm/virt.c | 16 +++++++++++++++- include/hw/acpi/ghes.h | 3 +++ include/hw/arm/virt.h | 1 + 5 files changed, 23 insertions(+), 1 deletion(-) diff --git a/hw/acpi/ghes.c b/hw/acpi/ghes.c index e9511d9b8f71..8d0262e6c1aa 100644 --- a/hw/acpi/ghes.c +++ b/hw/acpi/ghes.c @@ -444,6 +444,9 @@ int acpi_ghes_record_errors(uint8_t source_id, uint64_t= physical_address) return ret; } =20 +NotifierList generic_error_notifiers =3D + NOTIFIER_LIST_INITIALIZER(error_device_notifiers); + bool acpi_ghes_present(void) { AcpiGedState *acpi_ged_state; diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index f76fb117adff..f8bbe3e7a0b8 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -858,6 +858,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, Virt= MachineState *vms) } =20 acpi_dsdt_add_power_button(scope); + acpi_dsdt_add_error_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 687fe0bb8bc9..8b315328154f 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -73,6 +73,7 @@ #include "standard-headers/linux/input.h" #include "hw/arm/smmuv3.h" #include "hw/acpi/acpi.h" +#include "hw/acpi/ghes.h" #include "target/arm/cpu-qom.h" #include "target/arm/internals.h" #include "target/arm/multiprocessing.h" @@ -677,7 +678,7 @@ static inline DeviceState *create_acpi_ged(VirtMachineS= tate *vms) DeviceState *dev; MachineState *ms =3D MACHINE(vms); int irq =3D vms->irqmap[VIRT_ACPI_GED]; - uint32_t event =3D ACPI_GED_PWR_DOWN_EVT; + uint32_t event =3D ACPI_GED_PWR_DOWN_EVT | ACPI_GED_ERROR_EVT; =20 if (ms->ram_slots) { event |=3D ACPI_GED_MEM_HOTPLUG_EVT; @@ -1009,6 +1010,15 @@ static void virt_powerdown_req(Notifier *n, void *op= aque) } } =20 +static void virt_generic_error_req(Notifier *n, void *opaque) +{ + VirtMachineState *s =3D container_of(n, VirtMachineState, generic_erro= r_notifier); + + if (s->acpi_dev) { + acpi_send_event(s->acpi_dev, ACPI_GENERIC_ERROR); + } +} + static void create_gpio_keys(char *fdt, DeviceState *pl061_dev, uint32_t phandle) { @@ -2397,6 +2407,10 @@ static void machvirt_init(MachineState *machine) vms->powerdown_notifier.notify =3D virt_powerdown_req; qemu_register_powerdown_notifier(&vms->powerdown_notifier); =20 + vms->generic_error_notifier.notify =3D virt_generic_error_req; + notifier_list_add(&generic_error_notifiers, + &vms->generic_error_notifier); + /* Create mmio transports, so the user can create virtio backends * (which will be automatically plugged in to the transports). If * no backend is created the transport will just sit harmlessly idle. diff --git a/include/hw/acpi/ghes.h b/include/hw/acpi/ghes.h index 674f6958e905..6891eafff5ab 100644 --- a/include/hw/acpi/ghes.h +++ b/include/hw/acpi/ghes.h @@ -23,6 +23,9 @@ #define ACPI_GHES_H =20 #include "hw/acpi/bios-linker-loader.h" +#include "qemu/notify.h" + +extern NotifierList generic_error_notifiers; =20 /* * Values for Hardware Error Notification Type field diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index a4d937ed45ac..ad9f6e94dcc5 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -175,6 +175,7 @@ struct VirtMachineState { DeviceState *gic; DeviceState *acpi_dev; Notifier powerdown_notifier; + Notifier generic_error_notifier; PCIBus *bus; char *oem_id; char *oem_table_id; --=20 2.45.2 From nobody Sun Nov 24 14:34:43 2024 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 186A87A13A for ; Fri, 2 Aug 2024 21:44:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722635064; cv=none; b=GblPEVUE2il8RPVNqY134tbr/sXjRRrQ7602FcEgTEPj1ZUj8ECMhxgJ3nXUUBlUNDX89ubXLYHlPgbTKSuOqkZtFQJI0l03Si6+kO9vTznRjikOrG0dF6psozfjAtAalK/ttYTAM9/S2l7QMKvzgOuyqAhw64jwc50yhdNlusk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722635064; c=relaxed/simple; bh=ZSlU9yW3n4NevgGhDHVq1qOszSSTbSe+VJ0pqN5i5yU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=XmXiP3k87Ry9/HhiuCMOFZGmU/TcR2BsH0b7THHrtnTy1fvh2doXVWdFW95WybmIxVrgGYCyvqnFM5BOijFedxCdWS807E8Zbq7hxK0PuwtlXsbfC01TW+Efb5ovHpgnsOK5/71Sm9Rq78PPCie8CR94S+7oKueZiqyNF5/YzUc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=k23NbhNc; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="k23NbhNc" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BD3F1C4AF0F; Fri, 2 Aug 2024 21:44:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1722635063; bh=ZSlU9yW3n4NevgGhDHVq1qOszSSTbSe+VJ0pqN5i5yU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=k23NbhNcvr7qcW0xNGW/lpc063Ke8p+T3amvRCJSiFCEVRb4H7p9pBQPO4OJZjc02 53j4U8mzbsz+hPg8IgcdmW8yhjJ0vaCvj2dpLFta0vt9caHzuWJiQ1imY+Y+6gOVhC Wcs6+zgkYqfLB2ebYMcPy/zpjTAyyi7UYUcsVRSxtA74T/qeBsMtWSSfnZWb10wW7l A8P8LlShEqoplvkwGKaAOe53Zfi/oadN4z6Exx8NDvjC7dLBgEA2uL1+ec4o4T6C+J qtJ0c+7W7CPQy9V+SS4KX8b/U1pk0fQaJD+/UynF0GUD+kbgw+gGNrVbCHbUt6k+F9 GsePxlR5709Vw== Received: from mchehab by mail.kernel.org with local (Exim 4.98) (envelope-from ) id 1sa04T-00000002naP-2z0m; Fri, 02 Aug 2024 23:44:21 +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 v5 4/7] acpi/ghes: Support GPIO error source Date: Fri, 2 Aug 2024 23:43:59 +0200 Message-ID: <5d53042ebc5bc73bbc71f600e1ec1dea41f346b9.1722634602.git.mchehab+huawei@kernel.org> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab Content-Type: text/plain; charset="utf-8" From: Jonathan Cameron Add error notification to GHES v2 using the GPIO source. [mchehab: do some cleanups at ACPI_HEST_SRC_ID_* checks] Signed-off-by: Jonathan Cameron Signed-off-by: Mauro Carvalho Chehab --- hw/acpi/ghes.c | 16 ++++++++++------ include/hw/acpi/ghes.h | 3 ++- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/hw/acpi/ghes.c b/hw/acpi/ghes.c index 8d0262e6c1aa..a745dcc7be5e 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) =20 -/* 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 =20 /* Generic Hardware Error Source version 2 */ #define ACPI_GHES_SOURCE_GENERIC_ERROR_V2 10 @@ -290,6 +290,9 @@ void build_ghes_error_table(GArray *hardware_errors, BI= OSLinker *linker) static void build_ghes_v2(GArray *table_data, int source_id, BIOSLinker *l= inker) { uint64_t address_offset; + + assert(source_id < ACPI_HEST_SRC_ID_RESERVED); + /* * Type: * Generic Hardware Error Source version 2(GHESv2 - Type 10) @@ -327,6 +330,9 @@ static void build_ghes_v2(GArray *table_data, int sourc= e_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 +376,7 @@ void acpi_build_hest(GArray *table_data, BIOSLinker *li= nker, /* 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); =20 acpi_table_end(linker, &table); } @@ -406,10 +413,7 @@ int acpi_ghes_record_errors(uint8_t source_id, uint64_= t physical_address) start_addr =3D le64_to_cpu(ags->ghes_addr_le); =20 if (physical_address) { - - if (source_id < ACPI_HEST_SRC_ID_RESERVED) { - start_addr +=3D source_id * sizeof(uint64_t); - } + start_addr +=3D source_id * sizeof(uint64_t); =20 cpu_physical_memory_read(start_addr, &error_block_addr, sizeof(error_block_addr)); diff --git a/include/hw/acpi/ghes.h b/include/hw/acpi/ghes.h index 6891eafff5ab..33be1eb5acf4 100644 --- a/include/hw/acpi/ghes.h +++ b/include/hw/acpi/ghes.h @@ -59,9 +59,10 @@ enum AcpiGhesNotifyType { ACPI_GHES_NOTIFY_RESERVED =3D 12 }; =20 +/* Those are used as table indexes when building GHES tables */ enum { ACPI_HEST_SRC_ID_SEA =3D 0, - /* future ids go here */ + ACPI_HEST_SRC_ID_GPIO, ACPI_HEST_SRC_ID_RESERVED, }; =20 --=20 2.45.2 From nobody Sun Nov 24 14:34:43 2024 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 44A65130A7C for ; Fri, 2 Aug 2024 21:44:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722635064; cv=none; b=C92lJB9DASj+255zGREPcNKqLLE7mcoXS3u5JY5IQvmw8Z0bgyHwNmgo3SeSVwkIZsPvG/kUhDUVjzxl+5LZB0pFxwyF+HxxGM99b9gAtASk+RKUfnmoiGsCLeYWHQ0VAhnvlFyMiyG5kdjUJShHkXFR+loKmG6pCnfs2GBAH34= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722635064; c=relaxed/simple; bh=GnUXlC1iZIgwbN3LEYc4i/jTC5ISOQaQxV76+UJ2Bvg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BKPlxVqnZeUVW4Tw9dHBFbLSMgDKSEiVmjK4aSwI5e66P1+4kmZr5r7pWCsYzGknzNCW/Q4SBVLwRC1AfCriuTwViYc1uvgrhTvrLmWa7KIoAwkzVKUcIywYCV4qcyT8ylSJSpnTmtRtQIqLMXDZhYVu5BtuJ34N99Zy+tXdpw4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=tNahGYBM; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="tNahGYBM" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B4A50C32782; Fri, 2 Aug 2024 21:44:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1722635063; bh=GnUXlC1iZIgwbN3LEYc4i/jTC5ISOQaQxV76+UJ2Bvg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tNahGYBMQdlFaaKnXJnsNdhZ56yhScx/2bY+QMKd5CtFRUfGGb5HvUCDrDd/02+Kh YrW0C4boN/WszsbR7u5eHlHfwYji14eVdCf1i//6S5Y7gnhMEhKVMQm/HJjdiqOY3q dMI1TGbTzTNHan8vq1ARdY/fOYQN8y0HGNb52RMVj4oX9PVcqq270YsyodcnTCE8Cj eYvnFBc+SovP0U+cjMxBjZg+we330zqm2Cy/QUwDGdf3fOwBY5RpZCuV4hJ1BzJksp s9xMxP0V/NiV+OYBLgRvEHR5bips4ft4okDEvWd+NIlJsY7pu64QxNBUztYprEKBZu GvUwBvoNg+0uQ== Received: from mchehab by mail.kernel.org with local (Exim 4.98) (envelope-from ) id 1sa04T-00000002naT-35wP; Fri, 02 Aug 2024 23:44:21 +0200 From: Mauro Carvalho Chehab To: Cc: Jonathan Cameron , Shiju Jose , Mauro Carvalho Chehab , "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 Subject: [PATCH v5 5/7] qapi/ghes-cper: add an interface to do generic CPER error injection Date: Fri, 2 Aug 2024 23:44:00 +0200 Message-ID: <51cbdc8a53e58c69ee17b15c398feeeeeeb64f34.1722634602.git.mchehab+huawei@kernel.org> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab Content-Type: text/plain; charset="utf-8" Creates a QMP command to be used for generic ACPI APEI hardware error injection (HEST) via GHESv2. The actual GHES code will be added at the followup patch. Signed-off-by: Mauro Carvalho Chehab Reviewed-by: Jonathan Cameron --- MAINTAINERS | 7 +++++ hw/acpi/Kconfig | 5 ++++ hw/acpi/ghes_cper.c | 45 ++++++++++++++++++++++++++++++++ hw/acpi/ghes_cper_stub.c | 18 +++++++++++++ hw/acpi/meson.build | 2 ++ hw/arm/Kconfig | 5 ++++ include/hw/acpi/ghes.h | 7 +++++ qapi/ghes-cper.json | 55 ++++++++++++++++++++++++++++++++++++++++ qapi/meson.build | 1 + qapi/qapi-schema.json | 1 + 10 files changed, 146 insertions(+) create mode 100644 hw/acpi/ghes_cper.c create mode 100644 hw/acpi/ghes_cper_stub.c create mode 100644 qapi/ghes-cper.json diff --git a/MAINTAINERS b/MAINTAINERS index 98eddf7ae155..655edcb6688c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2075,6 +2075,13 @@ F: hw/acpi/ghes.c F: include/hw/acpi/ghes.h F: docs/specs/acpi_hest_ghes.rst =20 +ACPI/HEST/GHES/ARM processor CPER +R: Mauro Carvalho Chehab +S: Maintained +F: hw/arm/ghes_cper.c +F: hw/acpi/ghes_cper_stub.c +F: qapi/ghes-cper.json + ppc4xx L: qemu-ppc@nongnu.org S: Orphan diff --git a/hw/acpi/Kconfig b/hw/acpi/Kconfig index e07d3204eb36..73ffbb82c150 100644 --- a/hw/acpi/Kconfig +++ b/hw/acpi/Kconfig @@ -51,6 +51,11 @@ config ACPI_APEI bool depends on ACPI =20 +config GHES_CPER + bool + depends on ACPI_APEI + default y + config ACPI_PCI bool depends on ACPI && PCI diff --git a/hw/acpi/ghes_cper.c b/hw/acpi/ghes_cper.c new file mode 100644 index 000000000000..7aa7e71e90dc --- /dev/null +++ b/hw/acpi/ghes_cper.c @@ -0,0 +1,45 @@ +/* + * 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 "qemu/base64.h" +#include "qemu/error-report.h" +#include "qemu/uuid.h" +#include "qapi/qapi-commands-ghes-cper.h" +#include "hw/acpi/ghes.h" + +void qmp_ghes_cper(CommonPlatformErrorRecord *qmp_cper, + Error **errp) +{ + int rc; + AcpiGhesCper cper; + QemuUUID be_uuid, le_uuid; + + rc =3D qemu_uuid_parse(qmp_cper->notification_type, &be_uuid); + if (rc) { + error_setg(errp, "GHES: Invalid UUID: %s", + qmp_cper->notification_type); + return; + } + + le_uuid =3D qemu_uuid_bswap(be_uuid); + cper.guid =3D le_uuid.data; + + cper.data =3D qbase64_decode(qmp_cper->raw_data, -1, + &cper.data_len, errp); + if (!cper.data) { + return; + } + + /* TODO: call a function at ghes */ + + g_free(cper.data); +} diff --git a/hw/acpi/ghes_cper_stub.c b/hw/acpi/ghes_cper_stub.c new file mode 100644 index 000000000000..7ce6ed70a265 --- /dev/null +++ b/hw/acpi/ghes_cper_stub.c @@ -0,0 +1,18 @@ +/* + * 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/qapi-commands-ghes-cper.h" +#include "hw/acpi/ghes.h" + +void qmp_ghes_cper(CommonPlatformErrorRecord *cper, Error **errp) +{ +} diff --git a/hw/acpi/meson.build b/hw/acpi/meson.build index fa5c07db9068..6cbf430eb66d 100644 --- a/hw/acpi/meson.build +++ b/hw/acpi/meson.build @@ -34,4 +34,6 @@ endif system_ss.add(when: 'CONFIG_ACPI', if_false: files('acpi-stub.c', 'aml-bui= ld-stub.c', 'ghes-stub.c', 'acpi_interface.c')) system_ss.add(when: 'CONFIG_ACPI_PCI_BRIDGE', if_false: files('pci-bridge-= stub.c')) system_ss.add_all(when: 'CONFIG_ACPI', if_true: acpi_ss) +system_ss.add(when: 'CONFIG_GHES_CPER', if_true: files('ghes_cper.c')) +system_ss.add(when: 'CONFIG_GHES_CPER', if_false: files('ghes_cper_stub.c'= )) system_ss.add(files('acpi-qmp-cmds.c')) diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index 1ad60da7aa2d..bed6ba27d715 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -712,3 +712,8 @@ config ARMSSE select UNIMP select SSE_COUNTER select SSE_TIMER + +config GHES_CPER + bool + depends on ARM + default y if AARCH64 diff --git a/include/hw/acpi/ghes.h b/include/hw/acpi/ghes.h index 33be1eb5acf4..06a5b8820cd5 100644 --- a/include/hw/acpi/ghes.h +++ b/include/hw/acpi/ghes.h @@ -23,6 +23,7 @@ #define ACPI_GHES_H =20 #include "hw/acpi/bios-linker-loader.h" +#include "qapi/error.h" #include "qemu/notify.h" =20 extern NotifierList generic_error_notifiers; @@ -78,6 +79,12 @@ 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); =20 +typedef struct AcpiGhesCper { + uint8_t *guid; + uint8_t *data; + size_t data_len; +} AcpiGhesCper; + /** * acpi_ghes_present: Report whether ACPI GHES table is present * diff --git a/qapi/ghes-cper.json b/qapi/ghes-cper.json new file mode 100644 index 000000000000..3cc4f9f2aaa9 --- /dev/null +++ b/qapi/ghes-cper.json @@ -0,0 +1,55 @@ +# -*- Mode: Python -*- +# vim: filetype=3Dpython + +## +# =3D GHESv2 CPER Error Injection +# +# These are defined at +# ACPI 6.2: 18.3.2.8 Generic Hardware Error Source version 2 +# (GHESv2 - Type 10) +## + +## +# @CommonPlatformErrorRecord: +# +# Common Platform Error Record - CPER - as defined at the UEFI +# specification. See +# https://uefi.org/specs/UEFI/2.10/Apx_N_Common_Platform_Error_Record.html= #record-header +# for more details. +# +# @notification-type: pre-assigned GUID string indicating the record +# association with an error event notification type, as defined +# at https://uefi.org/specs/UEFI/2.10/Apx_N_Common_Platform_Error_Record= .html#record-header +# +# @raw-data: Contains a base64 encoded string with the payload of +# the CPER. +# +# Since: 9.2 +## +{ 'struct': 'CommonPlatformErrorRecord', + 'data': { + 'notification-type': 'str', + 'raw-data': 'str' + } +} + +## +# @ghes-cper: +# +# Inject ARM Processor error with data to be filled according with +# ACPI 6.2 GHESv2 spec. +# +# @cper: a single CPER record to be sent to the guest OS. +# +# Features: +# +# @unstable: This command is experimental. +# +# Since: 9.2 +## +{ 'command': 'ghes-cper', + 'data': { + 'cper': 'CommonPlatformErrorRecord' + }, + 'features': [ 'unstable' ] +} diff --git a/qapi/meson.build b/qapi/meson.build index e7bc54e5d047..bd13cd7d40c9 100644 --- a/qapi/meson.build +++ b/qapi/meson.build @@ -35,6 +35,7 @@ qapi_all_modules =3D [ 'dump', 'ebpf', 'error', + 'ghes-cper', 'introspect', 'job', 'machine-common', diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json index b1581988e4eb..c1a267399fe5 100644 --- a/qapi/qapi-schema.json +++ b/qapi/qapi-schema.json @@ -75,6 +75,7 @@ { 'include': 'misc-target.json' } { 'include': 'audio.json' } { 'include': 'acpi.json' } +{ 'include': 'ghes-cper.json' } { 'include': 'pci.json' } { 'include': 'stats.json' } { 'include': 'virtio.json' } --=20 2.45.2 From nobody Sun Nov 24 14:34:43 2024 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 35F4082486 for ; Fri, 2 Aug 2024 21:44:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722635064; cv=none; b=aUiEplLVT11NfP15NPZYLJb+YBYGYMsK+WgGEAR3rfhbaFpI32AsWHL4DBU9xCDmJLGUs9d0xnZ+cvLEx+Ih2X/CGzXSobPBIl5sY2WUDLHA5XRTxSo73x6bgYx3zwHG52wuwi6M+yRIFBiEyvluQDwF4hd3VUPuFXvaFuPYn7E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722635064; c=relaxed/simple; bh=tBLbaTxDMIbrJ1ZF80aRktOv/E8tCJykpKL5ilb5tVo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=vAaqnYf9M2llLePDSFvm6ahHTHa7dY7qraVDW5ZDUH1LuYSTYr/JrU3B0jNSTmqUr6fe7nZI40MbJ9LWt9ytHK4NnOgc694alx2/i/cg2LN07G3AZ9DVvf4Kq/hpx2VByE1EKbQYMQkn8oP2qSMZQM5J/5w62eV/dTfu4awtC4k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=RZ2d+f2Z; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="RZ2d+f2Z" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B696CC4AF0A; Fri, 2 Aug 2024 21:44:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1722635063; bh=tBLbaTxDMIbrJ1ZF80aRktOv/E8tCJykpKL5ilb5tVo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RZ2d+f2ZdBQH+uBVTT71p5zOXnZ3E3BKViG9mwQBIVz8IZ8uV8i/4I6m7ROwF7BTl onKGwKUFPDKZ63VXS6oARY5bgE9J/zMh1kj/3LuGe+1I7vFLbQuyJR5tVveUMB3x9i L4sZ/VCqdzbe4nKHsRaICWn8VGj4YAVX4f1CeJ/5w9swq3ERDvWK33W1f29u4yPgrI HBc3vUk8j9Qiu0Fld8ZB8o+BHg3tTtM1Hoa4o+qL3J6gU7yRDHYicpfOG46EEfvuaJ GUq/Zymlh3EtZDbMV+EMZVDxdMtDAAtd5Mc4zfWV4SfRHNz2xci8C/NviIxAvuExRz aGgnj+k7dEAAA== Received: from mchehab by mail.kernel.org with local (Exim 4.98) (envelope-from ) id 1sa04T-00000002naX-3Ctt; Fri, 02 Aug 2024 23:44:21 +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 v5 6/7] acpi/ghes: add support for generic error injection via QAPI Date: Fri, 2 Aug 2024 23:44:01 +0200 Message-ID: <20c491e357340e0062b6ff09867c1661ed4d2479.1722634602.git.mchehab+huawei@kernel.org> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab Content-Type: text/plain; charset="utf-8" Provide a generic interface for error injection via GHESv2. This patch is co-authored: - original ghes logic to inject a simple ARM record by Shiju Jose; - generic logic to handle block addresses by Jonathan Cameron; - generic GHESv2 error inject by Mauro Carvalho Chehab; Co-authored-by: Jonathan Cameron Co-authored-by: Shiju Jose Co-authored-by: Mauro Carvalho Chehab Cc: Jonathan Cameron Cc: Shiju Jose Signed-off-by: Mauro Carvalho Chehab --- hw/acpi/ghes.c | 159 ++++++++++++++++++++++++++++++++++++++--- hw/acpi/ghes_cper.c | 2 +- include/hw/acpi/ghes.h | 3 + 3 files changed, 152 insertions(+), 12 deletions(-) diff --git a/hw/acpi/ghes.c b/hw/acpi/ghes.c index a745dcc7be5e..e125c9475773 100644 --- a/hw/acpi/ghes.c +++ b/hw/acpi/ghes.c @@ -395,23 +395,22 @@ void acpi_ghes_add_fw_cfg(AcpiGhesState *ags, FWCfgSt= ate *s, ags->present =3D true; } =20 +static uint64_t ghes_get_state_start_address(void) +{ + AcpiGedState *acpi_ged_state =3D + ACPI_GED(object_resolve_path_type("", TYPE_ACPI_GED, NULL)); + AcpiGhesState *ags =3D &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 = =3D 0; - uint64_t start_addr; + uint64_t start_addr =3D ghes_get_state_start_address(); bool ret =3D -1; - AcpiGedState *acpi_ged_state; - AcpiGhesState *ags; - assert(source_id < ACPI_HEST_SRC_ID_RESERVED); =20 - acpi_ged_state =3D ACPI_GED(object_resolve_path_type("", TYPE_ACPI_GED, - NULL)); - g_assert(acpi_ged_state); - ags =3D &acpi_ged_state->ghes_state; - - start_addr =3D le64_to_cpu(ags->ghes_addr_le); - if (physical_address) { start_addr +=3D source_id * sizeof(uint64_t); =20 @@ -448,9 +447,147 @@ int acpi_ghes_record_errors(uint8_t source_id, uint64= _t physical_address) return ret; } =20 +/* + * Error register block data layout + * + * | +---------------------+ ges.ghes_addr_le + * | |error_block_address0 | + * | +---------------------+ + * | |error_block_address1 | + * | +---------------------+ --+-- + * | | ............. | GHES_ADDRESS_SIZE + * | +---------------------+ --+-- + * | |error_block_addressN | + * | +---------------------+ + * | | read_ack0 | + * | +---------------------+ --+-- + * | | read_ack1 | GHES_ADDRESS_SIZE + * | +---------------------+ --+-- + * | | ............. | + * | +---------------------+ + * | | read_ackN | + * | +---------------------+ --+-- + * | | CPER | | + * | | .... | GHES_MAX_RAW_DATA_LENGT + * | | CPER | | + * | +---------------------+ --+-- + * | | .......... | + * | +---------------------+ + * | | CPER | + * | | .... | + * | | CPER | + * | +---------------------+ + */ + +/* Map from uint32_t notify to entry offset in GHES */ +static const uint8_t error_source_to_index[] =3D { 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 1, 0}; + +static bool ghes_get_addr(uint32_t notify, uint64_t *error_block_addr, + uint64_t *read_ack_addr) +{ + uint64_t base; + + if (notify >=3D ACPI_GHES_NOTIFY_RESERVED) { + return false; + } + + /* Find and check the source id for this new CPER */ + if (error_source_to_index[notify] =3D=3D 0xff) { + return false; + } + + base =3D ghes_get_state_start_address(); + + *read_ack_addr =3D 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 =3D base + + ACPI_GHES_ERROR_SOURCE_COUNT * sizeof(uint64_t) + + ACPI_GHES_ERROR_SOURCE_COUNT * sizeof(uint64_t) + + error_source_to_index[notify] * ACPI_GHES_MAX_RAW_DATA_LENGTH; + + return true; +} + NotifierList generic_error_notifiers =3D NOTIFIER_LIST_INITIALIZER(error_device_notifiers); =20 +void ghes_record_cper_errors(AcpiGhesCper *cper, Error **errp, + uint32_t notify) +{ + int read_ack =3D 0; + uint32_t i; + uint64_t read_ack_addr =3D 0; + uint64_t error_block_addr =3D 0; + uint32_t data_length; + GArray *block; + + if (!ghes_get_addr(notify, &error_block_addr, &read_ack_addr)) { + error_setg(errp, "GHES: Invalid error block/ack address(es)"); + return; + } + + cpu_physical_memory_read(read_ack_addr, + &read_ack, sizeof(uint64_t)); + + /* zero means OSPM does not acknowledge the error */ + if (!read_ack) { + error_setg(errp, + "Last CPER record was not acknowledged yet"); + read_ack =3D 1; + cpu_physical_memory_write(read_ack_addr, + &read_ack, sizeof(uint64_t)); + return; + } + + read_ack =3D cpu_to_le64(0); + cpu_physical_memory_write(read_ack_addr, + &read_ack, sizeof(uint64_t)); + + /* Build CPER record */ + + /* + * Invalid fru id: ACPI 4.0: 17.3.2.6.1 Generic Error Data, + * Table 17-13 Generic Error Data Entry + */ + QemuUUID fru_id =3D {}; + + block =3D g_array_new(false, true /* clear */, 1); + data_length =3D ACPI_GHES_DATA_LENGTH + cper->data_len; + + /* + * It should not run out of the preallocated memory if + * adding a new generic error data entry + */ + assert((data_length + ACPI_GHES_GESB_SIZE) <=3D + ACPI_GHES_MAX_RAW_DATA_LENGTH); + + /* Build the new generic error status block header */ + acpi_ghes_generic_error_status(block, ACPI_GEBS_UNCORRECTABLE, + 0, 0, data_length, + ACPI_CPER_SEV_RECOVERABLE); + + /* Build this new generic error data entry header */ + acpi_ghes_generic_error_data(block, cper->guid, + ACPI_CPER_SEV_RECOVERABLE, 0, 0, + cper->data_len, fru_id, 0); + + /* Add CPER data */ + for (i =3D 0; i < cper->data_len; i++) { + build_append_int_noprefix(block, cper->data[i], 1); + } + + /* Write the generic error data entry into guest memory */ + cpu_physical_memory_write(error_block_addr, block->data, block->len); + + g_array_free(block, true); + + notifier_list_notify(&generic_error_notifiers, NULL); +} + bool acpi_ghes_present(void) { AcpiGedState *acpi_ged_state; diff --git a/hw/acpi/ghes_cper.c b/hw/acpi/ghes_cper.c index 7aa7e71e90dc..d7ff7debee74 100644 --- a/hw/acpi/ghes_cper.c +++ b/hw/acpi/ghes_cper.c @@ -39,7 +39,7 @@ void qmp_ghes_cper(CommonPlatformErrorRecord *qmp_cper, return; } =20 - /* TODO: call a function at ghes */ + ghes_record_cper_errors(&cper, errp, ACPI_GHES_NOTIFY_GPIO); =20 g_free(cper.data); } diff --git a/include/hw/acpi/ghes.h b/include/hw/acpi/ghes.h index 06a5b8820cd5..ee6f6cd96911 100644 --- a/include/hw/acpi/ghes.h +++ b/include/hw/acpi/ghes.h @@ -85,6 +85,9 @@ typedef struct AcpiGhesCper { size_t data_len; } AcpiGhesCper; =20 +void ghes_record_cper_errors(AcpiGhesCper *cper, Error **errp, + uint32_t notify); + /** * acpi_ghes_present: Report whether ACPI GHES table is present * --=20 2.45.2 From nobody Sun Nov 24 14:34:43 2024 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 63BDA1339A4 for ; Fri, 2 Aug 2024 21:44:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722635064; cv=none; b=vEqYLyOkEGsZ0JTq+NNRVSnknT6Sg4Enjz0BS0knoYJr5fImuNlpHbclr2jfO83b1fdybITCQjbM1FEV5eZYnC58zzJjrWbZ5mkfhdSgatLRtVKoG4IMJ5DXLd35qyKnQt9Ov/gm1CwnRxFyQV3GoqVIG8OWRklMpr4ZzxFaKks= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722635064; c=relaxed/simple; bh=GvF76Wnyaa2ZX97QUnoTwLcGlEiWPu4cqIv2rVnp4IM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=u1QINvhwzAu/QIP7WH1HUwNW2MtJOV8OpVBM9QcysZHAOyNoBiKSMfF+s6PN7pbdYar9PGcXAb+QVs5rwx+XL/4Elv3HhodlOV+UEKTeKAFvJTQoUI6X/PfO/QdPXKsPOY00C5PMDCpHkfspORASXVbQeJ1b+EMvyTsGSj8T9Gc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=sjefhyql; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="sjefhyql" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C43BDC4AF12; Fri, 2 Aug 2024 21:44:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1722635064; bh=GvF76Wnyaa2ZX97QUnoTwLcGlEiWPu4cqIv2rVnp4IM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sjefhyqlFGnLEVW+siFrtn1j8w0FBJKwENvs4HHAPGsaZNk5QydDoncLygsuTbqV1 JK0XMiWC3ASLu8jzx0Y9JE5ms6jjEJNX6B9jnJTVpXn6kzlrY081NcRCLEOo3a9Vq5 aLzTlaaD1oW+LlTpAdsExhXkaJZJf62RnSFnc5fQXOXuaVZzroIfcjIfe0htpc4cVg Sr7CvVmaoeRzMz6iJO3WUDrYdVPVBcqUxUgOfR5ey9EeaioKvZkr71LKkIbh3dcJjN Q2M7/GVJk92RoZXeA5ArrlP+67gEH+1+ev1ZvKgwOzU8LrvVk5hkx6kOz03cUPdJvI t+08hJTHjFeOA== Received: from mchehab by mail.kernel.org with local (Exim 4.98) (envelope-from ) id 1sa04T-00000002nab-3JbO; Fri, 02 Aug 2024 23:44:21 +0200 From: Mauro Carvalho Chehab To: Cc: Jonathan Cameron , Shiju Jose , Mauro Carvalho Chehab , Cleber Rosa , John Snow , linux-kernel@vger.kernel.org, qemu-devel@nongnu.org Subject: [PATCH v5 7/7] scripts/ghes_inject: add a script to generate GHES error inject Date: Fri, 2 Aug 2024 23:44:02 +0200 Message-ID: <0654a89fe24f4343016b9cecc0752594ad1cd49f.1722634602.git.mchehab+huawei@kernel.org> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab Content-Type: text/plain; charset="utf-8" Using the QMP GHESv2 API requires preparing a raw data array containing a CPER record. Add a helper script with subcommands to prepare such data. Currently, only ARM Processor error CPER record is supported. Signed-off-by: Mauro Carvalho Chehab --- MAINTAINERS | 3 + scripts/arm_processor_error.py | 352 +++++++++++++++++++++++++++++++++ scripts/ghes_inject.py | 59 ++++++ scripts/qmp_helper.py | 249 +++++++++++++++++++++++ 4 files changed, 663 insertions(+) create mode 100644 scripts/arm_processor_error.py create mode 100755 scripts/ghes_inject.py create mode 100644 scripts/qmp_helper.py diff --git a/MAINTAINERS b/MAINTAINERS index 655edcb6688c..e490f69da1de 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2081,6 +2081,9 @@ S: Maintained F: hw/arm/ghes_cper.c F: hw/acpi/ghes_cper_stub.c F: qapi/ghes-cper.json +F: scripts/ghes_inject.py +F: scripts/arm_processor_error.py +F: scripts/qmp_helper.py =20 ppc4xx L: qemu-ppc@nongnu.org diff --git a/scripts/arm_processor_error.py b/scripts/arm_processor_error.py new file mode 100644 index 000000000000..df4efa508790 --- /dev/null +++ b/scripts/arm_processor_error.py @@ -0,0 +1,352 @@ +#!/usr/bin/env python3 +# +# pylint: disable=3DC0301, C0114, R0912, R0913, R0914, R0915, W0511 +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (C) 2024 Mauro Carvalho Chehab + +# TODO: current implementation has dummy defaults. +# +# For a better implementation, a QMP addition/call is needed to +# retrieve some data for ARM Processor Error injection: +# +# - machine emulation architecture, as ARM current default is +# for AArch64; +# - ARM registers: power_state, midr, mpidr. + +import argparse +import json + +from qmp_helper import (qmp_command, get_choice, get_mult_array, + get_mult_choices, get_mult_int, bit, + data_add, to_guid) + +# Arm processor EINJ logic +# +ACPI_GHES_ARM_CPER_LENGTH =3D 40 +ACPI_GHES_ARM_CPER_PEI_LENGTH =3D 32 + +# TODO: query it from emulation. Current default valid only for Aarch64 +CONTEXT_AARCH64_EL1 =3D 5 + +class ArmProcessorEinj: + """ + Implements ARM Processor Error injection via GHES + """ + + def __init__(self): + """Initialize the error injection class""" + + # Valid choice values + self.arm_valid_bits =3D { + "mpidr": bit(0), + "affinity": bit(1), + "running": bit(2), + "vendor": bit(3), + } + + self.pei_flags =3D { + "first": bit(0), + "last": bit(1), + "propagated": bit(2), + "overflow": bit(3), + } + + self.pei_error_types =3D { + "cache": bit(1), + "tlb": bit(2), + "bus": bit(3), + "micro-arch": bit(4), + } + + self.pei_valid_bits =3D { + "multiple-error": bit(0), + "flags": bit(1), + "error-info": bit(2), + "virt-addr": bit(3), + "phy-addr": bit(4), + } + + self.data =3D bytearray() + + def create_subparser(self, subparsers): + """Add a subparser to handle for the error fields""" + + parser =3D subparsers.add_parser("arm", + help=3D"Generate an ARM processor C= PER") + + arm_valid_bits =3D ",".join(self.arm_valid_bits.keys()) + flags =3D ",".join(self.pei_flags.keys()) + error_types =3D ",".join(self.pei_error_types.keys()) + pei_valid_bits =3D ",".join(self.arm_valid_bits.keys()) + + # UEFI N.16 ARM Validation bits + g_arm =3D parser.add_argument_group("ARM processor") + g_arm.add_argument("--arm", "--arm-valid", + help=3Df"ARM valid bits: {arm_valid_bits}") + g_arm.add_argument("-a", "--affinity", "--level", "--affinity-lev= el", + type=3Dlambda x: int(x, 0), + help=3D"Affinity level (when multiple levels ap= ply)") + g_arm.add_argument("-l", "--mpidr", type=3Dlambda x: int(x, 0), + help=3D"Multiprocessor Affinity Register") + g_arm.add_argument("-i", "--midr", type=3Dlambda x: int(x, 0), + help=3D"Main ID Register") + g_arm.add_argument("-r", "--running", + action=3Dargparse.BooleanOptionalAction, + default=3DNone, + help=3D"Indicates if the processor is running o= r not") + g_arm.add_argument("--psci", "--psci-state", + type=3Dlambda x: int(x, 0), + help=3D"Power State Coordination Interface - PS= CI state") + + # TODO: Add vendor-specific support + + # UEFI N.17 bitmaps (type and flags) + g_pei =3D parser.add_argument_group("ARM Processor Error Info (PEI= )") + g_pei.add_argument("-t", "--type", nargs=3D"+", + help=3Df"one or more error types: {error_types}") + g_pei.add_argument("-f", "--flags", nargs=3D"*", + help=3Df"zero or more error flags: {flags}") + g_pei.add_argument("-V", "--pei-valid", "--error-valid", nargs=3D"= *", + help=3Df"zero or more PEI valid bits: {pei_valid_b= its}") + + # UEFI N.17 Integer values + g_pei.add_argument("-m", "--multiple-error", nargs=3D"+", + help=3D"Number of errors: 0: Single error, 1: Mult= iple errors, 2-65535: Error count if known") + g_pei.add_argument("-e", "--error-info", nargs=3D"+", + help=3D"Error information (UEFI 2.10 tables N.18 t= o N.20)") + g_pei.add_argument("-p", "--physical-address", nargs=3D"+", + help=3D"Physical address") + g_pei.add_argument("-v", "--virtual-address", nargs=3D"+", + help=3D"Virtual address") + + # UEFI N.21 Context + g_ctx =3D parser.add_argument_group("Processor Context") + g_ctx.add_argument("--ctx-type", "--context-type", nargs=3D"*", + help=3D"Type of the context (0=3DARM32 GPR, 5=3DAR= M64 EL1, other values supported)") + g_ctx.add_argument("--ctx-size", "--context-size", nargs=3D"*", + help=3D"Minimal size of the context") + g_ctx.add_argument("--ctx-array", "--context-array", nargs=3D"*", + help=3D"Comma-separated arrays for each context") + + # Vendor-specific data + g_vendor =3D parser.add_argument_group("Vendor-specific data") + g_vendor.add_argument("--vendor", "--vendor-specific", nargs=3D"+", + help=3D"Vendor-specific byte arrays of data") + + def parse_args(self, args): + """Parse subcommand arguments""" + + cper =3D {} + pei =3D {} + ctx =3D {} + vendor =3D {} + + arg =3D vars(args) + + # Handle global parameters + if args.arm: + arm_valid_init =3D False + cper["valid"] =3D get_choice(name=3D"valid", + value=3Dargs.arm, + choices=3Dself.arm_valid_bits, + suffixes=3D["-error", "-err"]) + else: + cper["valid"] =3D 0 + arm_valid_init =3D True + + if "running" in arg: + if args.running: + cper["running-state"] =3D bit(0) + else: + cper["running-state"] =3D 0 + else: + cper["running-state"] =3D 0 + + if arm_valid_init: + if args.affinity: + cper["valid"] |=3D self.arm_valid_bits["affinity"] + + if args.mpidr: + cper["valid"] |=3D self.arm_valid_bits["mpidr"] + + if "running-state" in cper: + cper["valid"] |=3D self.arm_valid_bits["running"] + + if args.psci: + cper["valid"] |=3D self.arm_valid_bits["running"] + + # Handle PEI + if not args.type: + args.type =3D ["cache-error"] + + get_mult_choices( + pei, + name=3D"valid", + values=3Dargs.pei_valid, + choices=3Dself.pei_valid_bits, + suffixes=3D["-valid", "-info", "--information", "--addr"], + ) + get_mult_choices( + pei, + name=3D"type", + values=3Dargs.type, + choices=3Dself.pei_error_types, + suffixes=3D["-error", "-err"], + ) + get_mult_choices( + pei, + name=3D"flags", + values=3Dargs.flags, + choices=3Dself.pei_flags, + suffixes=3D["-error", "-cap"], + ) + get_mult_int(pei, "error-info", args.error_info) + get_mult_int(pei, "multiple-error", args.multiple_error) + get_mult_int(pei, "phy-addr", args.physical_address) + get_mult_int(pei, "virt-addr", args.virtual_address) + + # Handle context + get_mult_int(ctx, "type", args.ctx_type, allow_zero=3DTrue) + get_mult_int(ctx, "minimal-size", args.ctx_size, allow_zero=3DTrue) + get_mult_array(ctx, "register", args.ctx_array, allow_zero=3DTrue) + + get_mult_array(vendor, "bytes", args.vendor, max_val=3D255) + + # Store PEI + pei_data =3D bytearray() + default_flags =3D self.pei_flags["first"] + default_flags |=3D self.pei_flags["last"] + + error_info_num =3D 0 + + for i, p in pei.items(): # pylint: disable=3DW0612 + error_info_num +=3D 1 + + # UEFI 2.10 doesn't define how to encode error information + # when multiple types are raised. So, provide a default only + # if a single type is there + if "error-info" not in p: + if p["type"] =3D=3D bit(1): + p["error-info"] =3D 0x0091000F + if p["type"] =3D=3D bit(2): + p["error-info"] =3D 0x0054007F + if p["type"] =3D=3D bit(3): + p["error-info"] =3D 0x80D6460FFF + if p["type"] =3D=3D bit(4): + p["error-info"] =3D 0x78DA03FF + + if "valid" not in p: + p["valid"] =3D 0 + if "multiple-error" in p: + p["valid"] |=3D self.pei_valid_bits["multiple-error"] + + if "flags" in p: + p["valid"] |=3D self.pei_valid_bits["flags"] + + if "error-info" in p: + p["valid"] |=3D self.pei_valid_bits["error-info"] + + if "phy-addr" in p: + p["valid"] |=3D self.pei_valid_bits["phy-addr"] + + if "virt-addr" in p: + p["valid"] |=3D self.pei_valid_bits["virt-addr"] + + # Version + data_add(pei_data, 0, 1) + + data_add(pei_data, ACPI_GHES_ARM_CPER_PEI_LENGTH, 1) + + data_add(pei_data, p["valid"], 2) + data_add(pei_data, p["type"], 1) + data_add(pei_data, p.get("multiple-error", 1), 2) + data_add(pei_data, p.get("flags", default_flags), 1) + data_add(pei_data, p.get("error-info", 0), 8) + data_add(pei_data, p.get("virt-addr", 0xDEADBEEF), 8) + data_add(pei_data, p.get("phy-addr", 0xABBA0BAD), 8) + + # Store Context + ctx_data =3D bytearray() + context_info_num =3D 0 + + if ctx: + for k in sorted(ctx.keys()): + context_info_num +=3D 1 + + if "type" not in ctx: + ctx[k]["type"] =3D CONTEXT_AARCH64_EL1 + + if "register" not in ctx: + ctx[k]["register"] =3D [] + + reg_size =3D len(ctx[k]["register"]) + size =3D 0 + + if "minimal-size" in ctx: + size =3D ctx[k]["minimal-size"] + + size =3D max(size, reg_size) + + size =3D (size + 1) % 0xFFFE + + # Version + data_add(ctx_data, 0, 2) + + data_add(ctx_data, ctx[k]["type"], 2) + + data_add(ctx_data, 8 * size, 4) + + for r in ctx[k]["register"]: + data_add(ctx_data, r, 8) + + for i in range(reg_size, size): # pylint: disable=3DW0612 + data_add(ctx_data, 0, 8) + + # Vendor-specific bytes are not grouped + vendor_data =3D bytearray() + if vendor: + for k in sorted(vendor.keys()): + for b in vendor[k]["bytes"]: + data_add(vendor_data, b, 1) + + # Encode ARM Processor Error + data =3D bytearray() + + data_add(data, cper["valid"], 4) + + data_add(data, error_info_num, 2) + data_add(data, context_info_num, 2) + + # Calculate the length of the CPER data + cper_length =3D ACPI_GHES_ARM_CPER_LENGTH + cper_length +=3D len(pei_data) + cper_length +=3D len(vendor_data) + cper_length +=3D len(ctx_data) + data_add(data, cper_length, 4) + + data_add(data, arg.get("affinity-level", 0), 1) + + # Reserved + data_add(data, 0, 3) + + data_add(data, arg.get("mpidr-el1", 0), 8) + data_add(data, arg.get("midr-el1", 0), 8) + data_add(data, cper["running-state"], 4) + data_add(data, arg.get("psci-state", 0), 4) + + # Add PEI + data.extend(pei_data) + data.extend(ctx_data) + data.extend(vendor_data) + + self.data =3D data + + def run(self, host, port): + """Execute QMP commands""" + + guid =3D to_guid(0xE19E3D16, 0xBC11, 0x11E4, + [0x9C, 0xAA, 0xC2, 0x05, + 0x1D, 0x5D, 0x46, 0xB0]) + + qmp_command(host, port, guid, self.data) diff --git a/scripts/ghes_inject.py b/scripts/ghes_inject.py new file mode 100755 index 000000000000..8415ccbbc53d --- /dev/null +++ b/scripts/ghes_inject.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 +# +# pylint: disable=3DC0301, C0114 +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (C) 2024 Mauro Carvalho Chehab + +import argparse + +from arm_processor_error import ArmProcessorEinj + +EINJ_DESCRIPTION =3D """ +Handle ACPI GHESv2 error injection logic QEMU QMP interface.\n + +It allows using UEFI BIOS EINJ features to generate GHES records. + +It helps testing Linux CPER and GHES drivers and to test rasdaemon +error handling logic. + +Currently, it support ARM processor error injection for ARM processor +events, being compatible with UEFI 2.9A Errata. + +This small utility works together with those QEMU additions: +- https://gitlab.com/mchehab_kernel/qemu/-/tree/arm-error-inject-v2 +""" + +def main(): + """Main program""" + + # Main parser - handle generic args like QEMU QMP TCP socket options + parser =3D argparse.ArgumentParser(prog=3D"einj.py", + formatter_class=3Dargparse.RawDescrip= tionHelpFormatter, + usage=3D"%(prog)s [options]", + description=3DEINJ_DESCRIPTION, + epilog=3D"If a field is not defined, = a default value will be applied by QEMU.") + + g_options =3D parser.add_argument_group("QEMU QMP socket options") + g_options.add_argument("-H", "--host", default=3D"localhost", type=3Ds= tr, + help=3D"host name") + g_options.add_argument("-P", "--port", default=3D4445, type=3Dint, + help=3D"TCP port number") + + arm_einj =3D ArmProcessorEinj() + + # Call subparsers + subparsers =3D parser.add_subparsers(dest=3D'command') + + arm_einj.create_subparser(subparsers) + + args =3D parser.parse_args() + + # Handle subparser commands + if args.command =3D=3D "arm": + arm_einj.parse_args(args) + arm_einj.run(args.host, args.port) + + +if __name__ =3D=3D "__main__": + main() diff --git a/scripts/qmp_helper.py b/scripts/qmp_helper.py new file mode 100644 index 000000000000..13fae7a7af0e --- /dev/null +++ b/scripts/qmp_helper.py @@ -0,0 +1,249 @@ +#!/usr/bin/env python3 +# +# pylint: disable=3DC0301, C0114, R0912, R0913, R0915, W0511 +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (C) 2024 Mauro Carvalho Chehab + +import json +import socket +import sys + +from base64 import b64encode + +# +# Socket QMP send command +# +def qmp_command(host, port, guid, data): + """Send commands to QEMU though QMP TCP socket""" + + # Fill the commands to be sent + commands =3D [] + + # Needed to negotiate QMP and for QEMU to accept the command + commands.append('{ "execute": "qmp_capabilities" } ') + + base64_data =3D b64encode(bytes(data)).decode('ascii') + + cmd_arg =3D { + 'cper': { + 'notification-type': guid, + "raw-data": base64_data + } + } + + command =3D '{ "execute": "ghes-cper", ' + command +=3D '"arguments": ' + json.dumps(cmd_arg) + " }" + + commands.append(command) + + s =3D socket.socket(socket.AF_INET, socket.SOCK_STREAM) + try: + s.connect((host, port)) + except ConnectionRefusedError: + sys.exit(f"Can't connect to QMP host {host}:{port}") + + data =3D s.recv(1024) + try: + obj =3D json.loads(data.decode("utf-8")) + except json.JSONDecodeError as e: + print(f"Invalid QMP answer: {e}") + s.close() + return + + if "QMP" not in obj: + print(f"Invalid QMP answer: {data.decode("utf-8")}") + s.close() + return + + for i, command in enumerate(commands): + s.sendall(command.encode("utf-8")) + data =3D s.recv(1024) + try: + obj =3D json.loads(data.decode("utf-8")) + except json.JSONDecodeError as e: + print(f"Invalid QMP answer: {e}") + s.close() + return + + if isinstance(obj.get("return"), dict): + if obj["return"]: + print(json.dumps(obj["return"])) + elif i > 0: + print("Error injected.") + elif isinstance(obj.get("error"), dict): + error =3D obj["error"] + print(f'{error["class"]}: {error["desc"]}') + else: + print(json.dumps(obj)) + + s.shutdown(socket.SHUT_WR) + while 1: + data =3D s.recv(1024) + if data =3D=3D b"": + break + try: + obj =3D json.loads(data.decode("utf-8")) + except json.JSONDecodeError as e: + print(f"Invalid QMP answer: {e}") + s.close() + return + + if isinstance(obj.get("return"), dict): + print(json.dumps(obj["return"])) + if isinstance(obj.get("error"), dict): + error =3D obj["error"] + print(f'{error["class"]}: {error["desc"]}') + else: + print(json.dumps(obj)) + + s.close() + + +# +# Helper routines to handle multiple choice arguments +# +def get_choice(name, value, choices, suffixes=3DNone): + """Produce a list from multiple choice argument""" + + new_values =3D 0 + + if not value: + return new_values + + for val in value.split(","): + val =3D val.lower() + + if suffixes: + for suffix in suffixes: + val =3D val.removesuffix(suffix) + + if val not in choices.keys(): + sys.exit(f"Error on '{name}': choice {val} is invalid.") + + val =3D choices[val] + + new_values |=3D val + + return new_values + + +def get_mult_array(mult, name, values, allow_zero=3DFalse, max_val=3DNone): + """Add numbered hashes from integer lists""" + + if not allow_zero: + if not values: + return + else: + if values is None: + return + + if not values: + i =3D 0 + if i not in mult: + mult[i] =3D {} + + mult[i][name] =3D [] + return + + i =3D 0 + for value in values: + for val in value.split(","): + try: + val =3D int(val, 0) + except ValueError: + sys.exit(f"Error on '{name}': {val} is not an integer") + + if val < 0: + sys.exit(f"Error on '{name}': {val} is not unsigned") + + if max_val and val > max_val: + sys.exit(f"Error on '{name}': {val} is too little") + + if i not in mult: + mult[i] =3D {} + + if name not in mult[i]: + mult[i][name] =3D [] + + mult[i][name].append(val) + + i +=3D 1 + + +def get_mult_choices(mult, name, values, choices, + suffixes=3DNone, allow_zero=3DFalse): + """Add numbered hashes from multiple choice arguments""" + + if not allow_zero: + if not values: + return + else: + if values is None: + return + + i =3D 0 + for val in values: + new_values =3D get_choice(name, val, choices, suffixes) + + if i not in mult: + mult[i] =3D {} + + mult[i][name] =3D new_values + i +=3D 1 + + +def get_mult_int(mult, name, values, allow_zero=3DFalse): + """Add numbered hashes from integer arguments""" + if not allow_zero: + if not values: + return + else: + if values is None: + return + + i =3D 0 + for val in values: + try: + val =3D int(val, 0) + except ValueError: + sys.exit(f"Error on '{name}': {val} is not an integer") + + if val < 0: + sys.exit(f"Error on '{name}': {val} is not unsigned") + + if i not in mult: + mult[i] =3D {} + + mult[i][name] =3D val + i +=3D 1 + + +# +# Data encode helper functions +# +def bit(b): + """Simple macro to define a bit on a bitmask""" + return 1 << b + + +def data_add(data, value, num_bytes): + """Adds bytes from value inside a bitarray""" + + data.extend(value.to_bytes(num_bytes, byteorder=3D"little")) + +def to_guid(time_low, time_mid, time_high, nodes): + """Create an GUID string""" + + assert(len(nodes) =3D=3D 8) + + clock =3D nodes[0] << 8 | nodes[1] + + node =3D 0 + for i in range(2, len(nodes)): + node =3D node << 8 | nodes[i] + + s =3D f"{time_low:08x}-{time_mid:04x}-" + s +=3D f"{time_high:04x}-{clock:04x}-{node:012x}" + + return s --=20 2.45.2