From patchwork Thu Nov 8 10:29:40 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dongjiu Geng X-Patchwork-Id: 10673973 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6745913AD for ; Thu, 8 Nov 2018 10:42:22 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 57A492CF65 for ; Thu, 8 Nov 2018 10:42:22 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4B6F32D39F; Thu, 8 Nov 2018 10:42:22 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id EA3682D396 for ; Thu, 8 Nov 2018 10:42:21 +0000 (UTC) Received: from localhost ([::1]:55728 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gKhlV-0005gk-5R for patchwork-qemu-devel@patchwork.kernel.org; Thu, 08 Nov 2018 05:42:21 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43833) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gKhcR-0003B5-6r for qemu-devel@nongnu.org; Thu, 08 Nov 2018 05:33:00 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gKhcO-0000Pu-Fn for qemu-devel@nongnu.org; Thu, 08 Nov 2018 05:32:59 -0500 Received: from szxga06-in.huawei.com ([45.249.212.32]:46163 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gKhcK-0000C7-1P; Thu, 08 Nov 2018 05:32:52 -0500 Received: from DGGEMS403-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id 22BA2913DE1EA; Thu, 8 Nov 2018 18:32:36 +0800 (CST) Received: from ros.huawei.com (10.143.28.118) by DGGEMS403-HUB.china.huawei.com (10.3.19.203) with Microsoft SMTP Server id 14.3.408.0; Thu, 8 Nov 2018 18:32:28 +0800 From: Dongjiu Geng To: , , , , , , , , , , , , , , , Date: Thu, 8 Nov 2018 02:29:40 -0800 Message-ID: <1541672989-15967-2-git-send-email-gengdongjiu@huawei.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1541672989-15967-1-git-send-email-gengdongjiu@huawei.com> References: <1541672989-15967-1-git-send-email-gengdongjiu@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.143.28.118] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 45.249.212.32 Subject: [Qemu-devel] [PATCH RESEND v15 01/10] ACPI: add some GHES structures and macros definition X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Add Generic Error Status Block structures and some macros definitions, which is referred to the ACPI 4.0 or ACPI 6.2. The HEST table generation and CPER record will use them. Signed-off-by: Dongjiu Geng --- Change since v14: Thanks Igor's review and comments 1. Update spec comment for AcpiHestNotifyType 2. drop () for the macro definition Change since v13: 1. Clean the new added structures and macros definition Change since v12: 1. Address Igor's comments to to get rid of most structures and use build_append_int_noprefix() API to compose whole error status block and APEI table in [1] [1]: https://lkml.org/lkml/2017/8/29/187 --- include/hw/acpi/acpi-defs.h | 52 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h index af8e023..f85cf98 100644 --- a/include/hw/acpi/acpi-defs.h +++ b/include/hw/acpi/acpi-defs.h @@ -226,6 +226,25 @@ typedef struct AcpiMultipleApicTable AcpiMultipleApicTable; #define ACPI_APIC_RESERVED 16 /* 16 and greater are reserved */ /* + * Values for Hardware Error Notification Type field + */ +enum AcpiHestNotifyType { + ACPI_HEST_NOTIFY_POLLED = 0, + ACPI_HEST_NOTIFY_EXTERNAL = 1, + ACPI_HEST_NOTIFY_LOCAL = 2, + ACPI_HEST_NOTIFY_SCI = 3, + ACPI_HEST_NOTIFY_NMI = 4, + ACPI_HEST_NOTIFY_CMCI = 5, /* ACPI 5.0: 18.3.2.7, Table 18-290 */ + ACPI_HEST_NOTIFY_MCE = 6, /* ACPI 5.0: 18.3.2.7, Table 18-290 */ + ACPI_HEST_NOTIFY_GPIO = 7, /* ACPI 6.0: 18.3.2.7, Table 18-332 */ + ACPI_HEST_NOTIFY_SEA = 8, /* ACPI 6.1: 18.3.2.9, Table 18-345 */ + ACPI_HEST_NOTIFY_SEI = 9, /* ACPI 6.1: 18.3.2.9, Table 18-345 */ + ACPI_HEST_NOTIFY_GSIV = 10, /* ACPI 6.1: 18.3.2.9, Table 18-345 */ + ACPI_HEST_NOTIFY_SDEI = 11, /* ACPI 6.2: 18.3.2.9, Table 18-383 */ + ACPI_HEST_NOTIFY_RESERVED = 12 /* 12 and greater are reserved */ +}; + +/* * MADT sub-structures (Follow MULTIPLE_APIC_DESCRIPTION_TABLE) */ #define ACPI_SUB_HEADER_DEF /* Common ACPI sub-structure header */\ @@ -402,6 +421,39 @@ struct AcpiSystemResourceAffinityTable { } QEMU_PACKED; typedef struct AcpiSystemResourceAffinityTable AcpiSystemResourceAffinityTable; +/* + * Generic Error Status Block + */ +struct AcpiGenericErrorStatus { + /* It is a bitmask composed of ACPI_GEBS_xxx macros */ + uint32_t block_status; + uint32_t raw_data_offset; + uint32_t raw_data_length; + uint32_t data_length; + uint32_t error_severity; +} QEMU_PACKED; +typedef struct AcpiGenericErrorStatus AcpiGenericErrorStatus; + +/* + * Masks for block_status flags above + */ +#define ACPI_GEBS_UNCORRECTABLE 1 + +/* + * Values for error_severity field above + */ +enum AcpiGenericErrorSeverity { + ACPI_CPER_SEV_RECOVERABLE, + ACPI_CPER_SEV_FATAL, + ACPI_CPER_SEV_CORRECTED, + ACPI_CPER_SEV_NONE, +}; + +/* + * Generic Hardware Error Source version 2 + */ +#define ACPI_HEST_SOURCE_GENERIC_ERROR_V2 10 + #define ACPI_SRAT_PROCESSOR_APIC 0 #define ACPI_SRAT_MEMORY 1 #define ACPI_SRAT_PROCESSOR_x2APIC 2 From patchwork Thu Nov 8 10:29:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dongjiu Geng X-Patchwork-Id: 10673959 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6AE9613BF for ; Thu, 8 Nov 2018 10:35:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5DA652D221 for ; Thu, 8 Nov 2018 10:35:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 51B252D268; Thu, 8 Nov 2018 10:35:59 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 00BB02CE70 for ; Thu, 8 Nov 2018 10:35:59 +0000 (UTC) Received: from localhost ([::1]:55689 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gKhfK-0006gx-5N for patchwork-qemu-devel@patchwork.kernel.org; Thu, 08 Nov 2018 05:35:58 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43727) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gKhcM-0002qq-Ui for qemu-devel@nongnu.org; Thu, 08 Nov 2018 05:32:55 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gKhcL-0000NM-D1 for qemu-devel@nongnu.org; Thu, 08 Nov 2018 05:32:54 -0500 Received: from szxga04-in.huawei.com ([45.249.212.190]:2664 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gKhcB-0000CA-PF; Thu, 08 Nov 2018 05:32:45 -0500 Received: from DGGEMS403-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id E0D9D3F317D48; Thu, 8 Nov 2018 18:32:35 +0800 (CST) Received: from ros.huawei.com (10.143.28.118) by DGGEMS403-HUB.china.huawei.com (10.3.19.203) with Microsoft SMTP Server id 14.3.408.0; Thu, 8 Nov 2018 18:32:29 +0800 From: Dongjiu Geng To: , , , , , , , , , , , , , , , Date: Thu, 8 Nov 2018 02:29:41 -0800 Message-ID: <1541672989-15967-3-git-send-email-gengdongjiu@huawei.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1541672989-15967-1-git-send-email-gengdongjiu@huawei.com> References: <1541672989-15967-1-git-send-email-gengdongjiu@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.143.28.118] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 45.249.212.190 Subject: [Qemu-devel] [PATCH RESEND v15 02/10] acpi: add build_append_ghes_notify() helper for Hardware Error Notification X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP It will help to add Hardware Error Notification to ACPI tables without using packed C structures and avoid endianness issues as API doesn't need explicit conversion. Signed-off-by: Dongjiu Geng --- hw/acpi/aml-build.c | 22 ++++++++++++++++++++++ include/hw/acpi/aml-build.h | 8 ++++++++ 2 files changed, 30 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index 1e43cd7..4210c36 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -274,6 +274,28 @@ void build_append_gas(GArray *table, AmlAddressSpace as, build_append_int_noprefix(table, address, 8); } +/* Hardware Error Notification + * ACPI 4.0: 17.3.2.7 Hardware Error Notification + */ +void build_append_ghes_notify(GArray *table, const uint8_t type, + uint8_t length, uint16_t config_write_enable, + uint32_t poll_interval, uint32_t vector, + uint32_t polling_threshold_value, + uint32_t polling_threshold_window, + uint32_t error_threshold_value, + uint32_t error_threshold_window) +{ + build_append_int_noprefix(table, type, 1); /* type */ + build_append_int_noprefix(table, length, 1); + build_append_int_noprefix(table, config_write_enable, 2); + build_append_int_noprefix(table, poll_interval, 4); + build_append_int_noprefix(table, vector, 4); + build_append_int_noprefix(table, polling_threshold_value, 4); + build_append_int_noprefix(table, polling_threshold_window, 4); + build_append_int_noprefix(table, error_threshold_value, 4); + build_append_int_noprefix(table, error_threshold_window, 4); +} + /* * Build NAME(XXXX, 0x00000000) where 0x00000000 is encoded as a dword, * and return the offset to 0x00000000 for runtime patching. diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 6c36903..a005052 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -409,6 +409,14 @@ build_append_gas_from_struct(GArray *table, const struct AcpiGenericAddress *s) s->access_width, s->address); } +void build_append_ghes_notify(GArray *table, const uint8_t type, + uint8_t length, uint16_t config_write_enable, + uint32_t poll_interval, uint32_t vector, + uint32_t polling_threshold_value, + uint32_t polling_threshold_window, + uint32_t error_threshold_value, + uint32_t error_threshold_window); + void build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base, uint64_t len, int node, MemoryAffinityFlags flags); From patchwork Thu Nov 8 10:29:42 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dongjiu Geng X-Patchwork-Id: 10673963 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 852D813BF for ; Thu, 8 Nov 2018 10:37:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 75A5328F02 for ; Thu, 8 Nov 2018 10:37:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6922E2D28C; Thu, 8 Nov 2018 10:37:14 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 06C5D28F02 for ; Thu, 8 Nov 2018 10:37:14 +0000 (UTC) Received: from localhost ([::1]:55699 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gKhgX-0007b0-5K for patchwork-qemu-devel@patchwork.kernel.org; Thu, 08 Nov 2018 05:37:13 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43830) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gKhcR-0003B0-5t for qemu-devel@nongnu.org; Thu, 08 Nov 2018 05:33:00 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gKhcN-0000OY-1a for qemu-devel@nongnu.org; Thu, 08 Nov 2018 05:32:59 -0500 Received: from szxga06-in.huawei.com ([45.249.212.32]:46161 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gKhcI-0000C6-Iy; Thu, 08 Nov 2018 05:32:51 -0500 Received: from DGGEMS403-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id 2BEBA272705F9; Thu, 8 Nov 2018 18:32:36 +0800 (CST) Received: from ros.huawei.com (10.143.28.118) by DGGEMS403-HUB.china.huawei.com (10.3.19.203) with Microsoft SMTP Server id 14.3.408.0; Thu, 8 Nov 2018 18:32:30 +0800 From: Dongjiu Geng To: , , , , , , , , , , , , , , , Date: Thu, 8 Nov 2018 02:29:42 -0800 Message-ID: <1541672989-15967-4-git-send-email-gengdongjiu@huawei.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1541672989-15967-1-git-send-email-gengdongjiu@huawei.com> References: <1541672989-15967-1-git-send-email-gengdongjiu@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.143.28.118] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 45.249.212.32 Subject: [Qemu-devel] [PATCH RESEND v15 03/10] acpi: add build_append_ghes_generic_data() helper for Generic Error Data Entry X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP It will help to add Generic Error Data Entry to ACPI tables without using packed C structures and avoid endianness issues as API doesn't need explicit conversion. Signed-off-by: Dongjiu Geng --- hw/acpi/aml-build.c | 32 ++++++++++++++++++++++++++++++++ include/hw/acpi/aml-build.h | 6 ++++++ 2 files changed, 38 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index 4210c36..00b166e 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -296,6 +296,38 @@ void build_append_ghes_notify(GArray *table, const uint8_t type, build_append_int_noprefix(table, error_threshold_window, 4); } +/* Generic Error Data Entry + * ACPI 4.0: 17.3.2.6.1 Generic Error Data + */ +void build_append_ghes_generic_data(GArray *table, const char *section_type, + uint32_t error_severity, uint16_t revision, + uint8_t validation_bits, uint8_t flags, + uint32_t error_data_length, uint8_t *fru_id, + uint8_t *fru_text, uint64_t time_stamp) +{ + int i; + + for (i = 0; i < 16; i++) { + build_append_int_noprefix(table, section_type[i], 1); + } + + build_append_int_noprefix(table, error_severity, 4); + build_append_int_noprefix(table, revision, 2); + build_append_int_noprefix(table, validation_bits, 1); + build_append_int_noprefix(table, flags, 1); + build_append_int_noprefix(table, error_data_length, 4); + + for (i = 0; i < 16; i++) { + build_append_int_noprefix(table, fru_id[i], 1); + } + + for (i = 0; i < 20; i++) { + build_append_int_noprefix(table, fru_text[i], 1); + } + + build_append_int_noprefix(table, time_stamp, 8); +} + /* * Build NAME(XXXX, 0x00000000) where 0x00000000 is encoded as a dword, * and return the offset to 0x00000000 for runtime patching. diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index a005052..147eb38 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -417,6 +417,12 @@ void build_append_ghes_notify(GArray *table, const uint8_t type, uint32_t error_threshold_value, uint32_t error_threshold_window); +void build_append_ghes_generic_data(GArray *table, const char *section_type, + uint32_t error_severity, uint16_t revision, + uint8_t validation_bits, uint8_t flags, + uint32_t error_data_length, uint8_t *fru_id, + uint8_t *fru_text, uint64_t time_stamp); + void build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base, uint64_t len, int node, MemoryAffinityFlags flags); From patchwork Thu Nov 8 10:29:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dongjiu Geng X-Patchwork-Id: 10673965 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 36EF3109C for ; Thu, 8 Nov 2018 10:37:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 275A828F02 for ; Thu, 8 Nov 2018 10:37:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1B48D2D268; Thu, 8 Nov 2018 10:37:43 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id C14EC28F02 for ; Thu, 8 Nov 2018 10:37:42 +0000 (UTC) Received: from localhost ([::1]:55702 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gKhgz-00089r-Ip for patchwork-qemu-devel@patchwork.kernel.org; Thu, 08 Nov 2018 05:37:41 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43765) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gKhcO-0002wy-5i for qemu-devel@nongnu.org; Thu, 08 Nov 2018 05:32:57 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gKhcN-0000Oj-53 for qemu-devel@nongnu.org; Thu, 08 Nov 2018 05:32:56 -0500 Received: from szxga04-in.huawei.com ([45.249.212.190]:2662 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gKhcJ-0000C9-SC; Thu, 08 Nov 2018 05:32:52 -0500 Received: from DGGEMS403-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id CE341E0E57B8B; Thu, 8 Nov 2018 18:32:35 +0800 (CST) Received: from ros.huawei.com (10.143.28.118) by DGGEMS403-HUB.china.huawei.com (10.3.19.203) with Microsoft SMTP Server id 14.3.408.0; Thu, 8 Nov 2018 18:32:31 +0800 From: Dongjiu Geng To: , , , , , , , , , , , , , , , Date: Thu, 8 Nov 2018 02:29:43 -0800 Message-ID: <1541672989-15967-5-git-send-email-gengdongjiu@huawei.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1541672989-15967-1-git-send-email-gengdongjiu@huawei.com> References: <1541672989-15967-1-git-send-email-gengdongjiu@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.143.28.118] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 45.249.212.190 Subject: [Qemu-devel] [PATCH RESEND v15 04/10] acpi: add build_append_ghes_generic_status() helper for Generic Error Status Block X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP It will help to add Generic Error Status Block to ACPI tables without using packed C structures and avoid endianness issues as API doesn't need explicit conversion. Signed-off-by: Dongjiu Geng --- hw/acpi/aml-build.c | 14 ++++++++++++++ include/hw/acpi/aml-build.h | 6 ++++++ 2 files changed, 20 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index 00b166e..5923248 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -296,6 +296,20 @@ void build_append_ghes_notify(GArray *table, const uint8_t type, build_append_int_noprefix(table, error_threshold_window, 4); } +/* Generic Error Status Block + * ACPI 4.0: 17.3.2.6.1 Generic Error Data + */ +void build_append_ghes_generic_status(GArray *table, uint32_t block_status, + uint32_t raw_data_offset, uint32_t raw_data_length, + uint32_t data_length, uint32_t error_severity) +{ + build_append_int_noprefix(table, block_status, 4); + build_append_int_noprefix(table, raw_data_offset, 4); + build_append_int_noprefix(table, raw_data_length, 4); + build_append_int_noprefix(table, data_length, 4); + build_append_int_noprefix(table, error_severity, 4); +} + /* Generic Error Data Entry * ACPI 4.0: 17.3.2.6.1 Generic Error Data */ diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 147eb38..657a0d5 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -423,6 +423,12 @@ void build_append_ghes_generic_data(GArray *table, const char *section_type, uint32_t error_data_length, uint8_t *fru_id, uint8_t *fru_text, uint64_t time_stamp); +void +build_append_ghes_generic_status(GArray *table, uint32_t block_status, + uint32_t raw_data_offset, + uint32_t raw_data_length, + uint32_t data_length, uint32_t error_severity); + void build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base, uint64_t len, int node, MemoryAffinityFlags flags); From patchwork Thu Nov 8 10:29:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dongjiu Geng X-Patchwork-Id: 10673967 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D994F13BF for ; Thu, 8 Nov 2018 10:39:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AE56D2D396 for ; Thu, 8 Nov 2018 10:39:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9FAAF2D3B1; Thu, 8 Nov 2018 10:39:27 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 48CC22D396 for ; Thu, 8 Nov 2018 10:39:26 +0000 (UTC) Received: from localhost ([::1]:55711 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gKhif-0002Fu-8L for patchwork-qemu-devel@patchwork.kernel.org; Thu, 08 Nov 2018 05:39:25 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43796) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gKhcP-00032R-9U for qemu-devel@nongnu.org; Thu, 08 Nov 2018 05:32:59 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gKhcM-0000OI-Px for qemu-devel@nongnu.org; Thu, 08 Nov 2018 05:32:57 -0500 Received: from szxga06-in.huawei.com ([45.249.212.32]:46162 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gKhc9-0000C5-Td; Thu, 08 Nov 2018 05:32:43 -0500 Received: from DGGEMS403-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id 178866FE2788E; Thu, 8 Nov 2018 18:32:36 +0800 (CST) Received: from ros.huawei.com (10.143.28.118) by DGGEMS403-HUB.china.huawei.com (10.3.19.203) with Microsoft SMTP Server id 14.3.408.0; Thu, 8 Nov 2018 18:32:31 +0800 From: Dongjiu Geng To: , , , , , , , , , , , , , , , Date: Thu, 8 Nov 2018 02:29:44 -0800 Message-ID: <1541672989-15967-6-git-send-email-gengdongjiu@huawei.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1541672989-15967-1-git-send-email-gengdongjiu@huawei.com> References: <1541672989-15967-1-git-send-email-gengdongjiu@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.143.28.118] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 45.249.212.32 Subject: [Qemu-devel] [PATCH RESEND v15 05/10] ACPI: Add APEI GHES table generation and CPER record support X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP This implements APEI GHES Table generation and record CPER in runtime via fw_cfg blobs.Now we only support two types of GHESv2, which are GPIO-Signal and ARMv8 SEA. Afterwards, we can extend the supported types if needed. For the CPER section type, currently it is memory section because kernel mainly wants userspace to handle the memory errors. For GHESv2 error source, the OSPM must acknowledges the error via Read ACK register. So user space must check the ACK value before recording a new CPER to avoid read-write race condition. Suggested-by: Laszlo Ersek Signed-off-by: Dongjiu Geng --- The basic solution is suggested by Laszlo in [1] [1]: https://lkml.org/lkml/2017/3/29/342 --- default-configs/arm-softmmu.mak | 1 + hw/acpi/Makefile.objs | 1 + hw/acpi/acpi_ghes.c | 171 ++++++++++++++++++++++++++++++++++++++++ hw/acpi/aml-build.c | 2 + hw/arm/virt-acpi-build.c | 8 ++ include/hw/acpi/acpi_ghes.h | 82 +++++++++++++++++++ include/hw/acpi/aml-build.h | 1 + 7 files changed, 266 insertions(+) create mode 100644 hw/acpi/acpi_ghes.c create mode 100644 include/hw/acpi/acpi_ghes.h diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak index 2420491..7ea9857 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -159,3 +159,4 @@ CONFIG_PCI_DESIGNWARE=y CONFIG_STRONGARM=y CONFIG_HIGHBANK=y CONFIG_MUSICPAL=y +CONFIG_ACPI_APEI=y diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs index 11c35bc..209febf 100644 --- a/hw/acpi/Makefile.objs +++ b/hw/acpi/Makefile.objs @@ -6,6 +6,7 @@ common-obj-$(CONFIG_ACPI_MEMORY_HOTPLUG) += memory_hotplug.o common-obj-$(CONFIG_ACPI_CPU_HOTPLUG) += cpu.o common-obj-$(CONFIG_ACPI_NVDIMM) += nvdimm.o common-obj-$(CONFIG_ACPI_VMGENID) += vmgenid.o +common-obj-$(CONFIG_ACPI_APEI) += acpi_ghes.o common-obj-$(call lnot,$(CONFIG_ACPI_X86)) += acpi-stub.o common-obj-y += acpi_interface.o diff --git a/hw/acpi/acpi_ghes.c b/hw/acpi/acpi_ghes.c new file mode 100644 index 0000000..d03e797 --- /dev/null +++ b/hw/acpi/acpi_ghes.c @@ -0,0 +1,171 @@ +/* Support for generating APEI tables and record CPER for Guests + * + * Copyright (C) 2017 HuaWei Corporation. + * + * Author: Dongjiu Geng + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + */ + +#include "qemu/osdep.h" +#include "hw/acpi/acpi.h" +#include "hw/acpi/aml-build.h" +#include "hw/acpi/acpi_ghes.h" +#include "hw/nvram/fw_cfg.h" +#include "sysemu/sysemu.h" +#include "qemu/error-report.h" + +/* Build table for the hardware error fw_cfg blob */ +void build_hardware_error_table(GArray *hardware_errors, BIOSLinker *linker) +{ + int i; + + /* + * | +--------------------------+ + * | | error_block_address | + * | | .......... | + * | +--------------------------+ + * | | read_ack_register | + * | | ........... | + * | +--------------------------+ + * | | Error Status Data Block | + * | | ........ | + * | +--------------------------+ + */ + + /* Build error_block_address */ + build_append_int_noprefix((void *)hardware_errors, 0, + GHES_ADDRESS_SIZE * ACPI_HEST_ERROR_SOURCE_COUNT); + + /* Build read_ack_register */ + for (i = 0; i < ACPI_HEST_ERROR_SOURCE_COUNT; i++) + /* Initialize the value of read_ack_register to 1, so GHES can be + * writeable in the first time + */ + build_append_int_noprefix((void *)hardware_errors, 1, GHES_ADDRESS_SIZE); + + /* Build Error Status Data Block */ + build_append_int_noprefix((void *)hardware_errors, 0, + GHES_MAX_RAW_DATA_LENGTH * ACPI_HEST_ERROR_SOURCE_COUNT); + + /* Allocate guest memory for the hardware error fw_cfg blob */ + bios_linker_loader_alloc(linker, GHES_ERRORS_FW_CFG_FILE, hardware_errors, + 1, false); +} + +/* Build Hardware Error Source Table */ +void build_apei_hest(GArray *table_data, GArray *hardware_errors, + BIOSLinker *linker) +{ + uint32_t i, error_status_block_offset, length = table_data->len; + + /* Reserve Hardware Error Source Table header size */ + acpi_data_push(table_data, sizeof(AcpiTableHeader)); + + /* Set the error source counts */ + build_append_int_noprefix(table_data, ACPI_HEST_ERROR_SOURCE_COUNT, 4); + + for (i = 0; i < ACPI_HEST_ERROR_SOURCE_COUNT; i++) { + /* Generic Hardware Error Source version 2(GHESv2 - Type 10) + */ + build_append_int_noprefix(table_data, + ACPI_HEST_SOURCE_GENERIC_ERROR_V2, 2); /* type */ + build_append_int_noprefix(table_data, cpu_to_le16(i), 2); /* source id */ + build_append_int_noprefix(table_data, 0xffff, 2); /* related source id */ + build_append_int_noprefix(table_data, 0, 1); /* flags */ + + build_append_int_noprefix(table_data, 1, 1); /* enabled */ + + /* Number of Records To Pre-allocate */ + build_append_int_noprefix(table_data, 1, 4); + /* Max Sections Per Record */ + build_append_int_noprefix(table_data, 1, 4); + /* Max Raw Data Length */ + build_append_int_noprefix(table_data, GHES_MAX_RAW_DATA_LENGTH, 4); + + /* Build error status address*/ + build_append_gas(table_data, AML_SYSTEM_MEMORY, 0x40, 0, 4 /* QWord access */, 0); + bios_linker_loader_add_pointer(linker, + ACPI_BUILD_TABLE_FILE, ERROR_STATUS_ADDRESS_OFFSET(length, i), + GHES_ADDRESS_SIZE, GHES_ERRORS_FW_CFG_FILE, i * GHES_ADDRESS_SIZE); + + /* Build Hardware Error Notification + * Now only enable GPIO-Signal and ARMv8 SEA notification types + */ + if (i == 0) { + build_append_ghes_notify(table_data, ACPI_HEST_NOTIFY_GPIO, 28, + 0, 0, 0, 0, 0, 0, 0); + } else if (i == 1) { + build_append_ghes_notify(table_data, ACPI_HEST_NOTIFY_SEA, 28, 0, + 0, 0, 0, 0, 0, 0); + } + + /* Error Status Block Length */ + build_append_int_noprefix(table_data, + cpu_to_le32(GHES_MAX_RAW_DATA_LENGTH), 4); + + /* Build Read ACK register + * ACPI 6.1/6.2: 18.3.2.8 Generic Hardware Error Source + * version 2 (GHESv2 - Type 10) + */ + build_append_gas(table_data, AML_SYSTEM_MEMORY, 0x40, 0, 4 /* QWord access */, 0); + bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE, + READ_ACK_REGISTER_ADDRESS_OFFSET(length, i), GHES_ADDRESS_SIZE, + GHES_ERRORS_FW_CFG_FILE, + (ACPI_HEST_ERROR_SOURCE_COUNT + i) * GHES_ADDRESS_SIZE); + + /* Build Read Ack Preserve and Read Ack Writer */ + build_append_int_noprefix(table_data, cpu_to_le64(ReadAckPreserve), 8); + build_append_int_noprefix(table_data, cpu_to_le64(ReadAckWrite), 8); + } + + /* Generic Error Status Block offset in the hardware error fw_cfg blob */ + error_status_block_offset = GHES_ADDRESS_SIZE * 2 * + ACPI_HEST_ERROR_SOURCE_COUNT; + + for (i = 0; i < ACPI_HEST_ERROR_SOURCE_COUNT; i++) + /* Patch address of Error Status Data Block into + * the error_block_address of hardware_errors fw_cfg blob + */ + bios_linker_loader_add_pointer(linker, + GHES_ERRORS_FW_CFG_FILE, GHES_ADDRESS_SIZE * i, GHES_ADDRESS_SIZE, + GHES_ERRORS_FW_CFG_FILE, + error_status_block_offset + i * GHES_MAX_RAW_DATA_LENGTH); + + /* write address of hardware_errors fw_cfg blob into the + * hardware_errors_addr fw_cfg blob. + */ + bios_linker_loader_write_pointer(linker, GHES_DATA_ADDR_FW_CFG_FILE, + 0, GHES_ADDRESS_SIZE, GHES_ERRORS_FW_CFG_FILE, 0); + + build_header(linker, table_data, + (void *)(table_data->data + length), "HEST", + table_data->len - length, 1, NULL, "GHES"); +} + +static GhesState ges; +void ghes_add_fw_cfg(FWCfgState *s, GArray *hardware_error) +{ + + size_t size = 2 * GHES_ADDRESS_SIZE + GHES_MAX_RAW_DATA_LENGTH; + size_t request_block_size = ACPI_HEST_ERROR_SOURCE_COUNT * size; + + /* Create a read-only fw_cfg file for GHES */ + fw_cfg_add_file(s, GHES_ERRORS_FW_CFG_FILE, hardware_error->data, + request_block_size); + + /* Create a read-write fw_cfg file for Address */ + fw_cfg_add_file_callback(s, GHES_DATA_ADDR_FW_CFG_FILE, NULL, NULL, NULL, + &ges.ghes_addr_le, sizeof(ges.ghes_addr_le), false); +} diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index 5923248..4f2478f 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -1645,6 +1645,7 @@ void acpi_build_tables_init(AcpiBuildTables *tables) tables->table_data = g_array_new(false, true /* clear */, 1); tables->tcpalog = g_array_new(false, true /* clear */, 1); tables->vmgenid = g_array_new(false, true /* clear */, 1); + tables->hardware_errors = g_array_new(false, true /* clear */, 1); tables->linker = bios_linker_loader_init(); } @@ -1655,6 +1656,7 @@ void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre) g_array_free(tables->table_data, true); g_array_free(tables->tcpalog, mfre); g_array_free(tables->vmgenid, mfre); + g_array_free(tables->hardware_errors, mfre); } /* Build rsdt table */ diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 5785fb6..19c1b7e 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -45,6 +45,7 @@ #include "hw/arm/virt.h" #include "sysemu/numa.h" #include "kvm_arm.h" +#include "hw/acpi/acpi_ghes.h" #define ARM_SPI_BASE 32 #define ACPI_POWER_BUTTON_DEVICE "PWRB" @@ -835,6 +836,11 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables) acpi_add_table(table_offsets, tables_blob); build_spcr(tables_blob, tables->linker, vms); + acpi_add_table(table_offsets, tables_blob); + build_hardware_error_table(tables->hardware_errors, tables->linker); + build_apei_hest(tables_blob, tables->hardware_errors, tables->linker); + + if (nb_numa_nodes > 0) { acpi_add_table(table_offsets, tables_blob); build_srat(tables_blob, tables->linker, vms); @@ -951,6 +957,8 @@ void virt_acpi_setup(VirtMachineState *vms) fw_cfg_add_file(vms->fw_cfg, ACPI_BUILD_TPMLOG_FILE, tables.tcpalog->data, acpi_data_len(tables.tcpalog)); + ghes_add_fw_cfg(vms->fw_cfg, tables.hardware_errors); + build_state->rsdp_mr = acpi_add_rom_blob(build_state, tables.rsdp, ACPI_BUILD_RSDP_FILE, 0); diff --git a/include/hw/acpi/acpi_ghes.h b/include/hw/acpi/acpi_ghes.h new file mode 100644 index 0000000..0a7c6c2 --- /dev/null +++ b/include/hw/acpi/acpi_ghes.h @@ -0,0 +1,82 @@ +/* Support for generating APEI tables and record CPER for Guests + * + * Copyright (C) 2017 HuaWei Corporation. + * + * Author: Dongjiu Geng + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + */ + +#ifndef ACPI_GHES_H +#define ACPI_GHES_H + +#include "hw/acpi/bios-linker-loader.h" + +#define GHES_ERRORS_FW_CFG_FILE "etc/hardware_errors" +#define GHES_DATA_ADDR_FW_CFG_FILE "etc/hardware_errors_addr" + +/* The size of Address field in Generic Address Structure, ACPI 2.0/3.0: 5.2.3.1 Generic Address + * Structure + */ +#define GHES_ADDRESS_SIZE 8 + +#define GHES_DATA_LENGTH 72 +#define GHES_CPER_LENGTH 80 + +#define ReadAckPreserve 0xfffffffe +#define ReadAckWrite 0x1 + +#define GHES_CPER_OK 1 +#define GHES_CPER_FAIL 0 + +/* The max size in bytes for one error block */ +#define GHES_MAX_RAW_DATA_LENGTH 0x1000 +/* Now only have GPIO-Signal and ARMv8 SEA notification types error sources + */ +#define ACPI_HEST_ERROR_SOURCE_COUNT 2 + +/* + * | +--------------------------+ 0 + * | | Header | + * | +--------------------------+ 40---+- + * | | ................. | | + * | | error_status_address-----+ 60 | + * | | ................. | | + * | | read_ack_register--------+ 104 92 + * | | read_ack_preserve | | + * | | read_ack_write | | + * + +--------------------------+ 132--+- + * + * From above GHES definition, the error status address offset is 60; + * the Read ack register offset is 104, the whole size of GHESv2 is 92 + */ + +/* The error status address offset in GHES */ +#define ERROR_STATUS_ADDRESS_OFFSET(start_addr, n) (start_addr + 60 + \ + offsetof(struct AcpiGenericAddress, address) + n * 92) + +/* The read Ack register offset in GHES */ +#define READ_ACK_REGISTER_ADDRESS_OFFSET(start_addr, n) (start_addr + 104 + \ + offsetof(struct AcpiGenericAddress, address) + n * 92) + +typedef struct GhesState { + uint64_t ghes_addr_le; +} GhesState; + +void build_apei_hest(GArray *table_data, GArray *hardware_error, + BIOSLinker *linker); + +void build_hardware_error_table(GArray *hardware_errors, BIOSLinker *linker); +void ghes_add_fw_cfg(FWCfgState *s, GArray *hardware_errors); +#endif diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 657a0d5..c01b0f3 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -220,6 +220,7 @@ struct AcpiBuildTables { GArray *rsdp; GArray *tcpalog; GArray *vmgenid; + GArray *hardware_errors; BIOSLinker *linker; } AcpiBuildTables; From patchwork Thu Nov 8 10:29:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dongjiu Geng X-Patchwork-Id: 10673997 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1CEEE13BF for ; Thu, 8 Nov 2018 10:48:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0A8EC2B3BF for ; Thu, 8 Nov 2018 10:48:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EFFFA2D210; Thu, 8 Nov 2018 10:48:12 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 52D5D2B3BF for ; Thu, 8 Nov 2018 10:48:12 +0000 (UTC) Received: from localhost ([::1]:55776 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gKhr9-0005A2-9J for patchwork-qemu-devel@patchwork.kernel.org; Thu, 08 Nov 2018 05:48:11 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43890) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gKhcV-0003PQ-QO for qemu-devel@nongnu.org; Thu, 08 Nov 2018 05:33:07 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gKhcP-0000Qw-S1 for qemu-devel@nongnu.org; Thu, 08 Nov 2018 05:33:03 -0500 Received: from szxga05-in.huawei.com ([45.249.212.191]:2571 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gKhcK-0000Fg-3F; Thu, 08 Nov 2018 05:32:52 -0500 Received: from DGGEMS403-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id 7516DD0562E21; Thu, 8 Nov 2018 18:32:40 +0800 (CST) Received: from ros.huawei.com (10.143.28.118) by DGGEMS403-HUB.china.huawei.com (10.3.19.203) with Microsoft SMTP Server id 14.3.408.0; Thu, 8 Nov 2018 18:32:32 +0800 From: Dongjiu Geng To: , , , , , , , , , , , , , , , Date: Thu, 8 Nov 2018 02:29:45 -0800 Message-ID: <1541672989-15967-7-git-send-email-gengdongjiu@huawei.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1541672989-15967-1-git-send-email-gengdongjiu@huawei.com> References: <1541672989-15967-1-git-send-email-gengdongjiu@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.143.28.118] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 45.249.212.191 Subject: [Qemu-devel] [PATCH RESEND v15 06/10] docs: APEI GHES generation and CPER record description X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Add APEI/GHES detailed design document Signed-off-by: Dongjiu Geng --- Address Igor's comments to add a doc --- docs/specs/acpi_hest_ghes.txt | 97 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 docs/specs/acpi_hest_ghes.txt diff --git a/docs/specs/acpi_hest_ghes.txt b/docs/specs/acpi_hest_ghes.txt new file mode 100644 index 0000000..fbfc787 --- /dev/null +++ b/docs/specs/acpi_hest_ghes.txt @@ -0,0 +1,97 @@ +APEI tables generating and CPER record +============================= + +Copyright (C) 2017 HuaWei Corporation. + +Design Details: +------------------- + + etc/acpi/tables etc/hardware_errors + ==================== ========================================== ++ +--------------------------+ +-----------------------+ +| | HEST | | address | +--------------+ +| +--------------------------+ | registers | | Error Status | +| | GHES1 | | +---------------------+ | Data Block 1 | +| +--------------------------+ +--------->| |error_block_address1 |----------->| +------------+ +| | ................. | | | +---------------------+ | | CPER | +| | error_status_address-----+-+ +------->| |error_block_address2 |--------+ | | CPER | +| | ................. | | | +---------------------+ | | | .... | +| | read_ack_register--------+-+ | | | .............. | | | | CPER | +| | read_ack_preserve | | | +-----------------------+ | | +------------+ +| | read_ack_write | | | +----->| |error_block_addressN |------+ | | Error Status | ++ +--------------------------+ | | | | +---------------------+ | | | Data Block 2 | +| | GHES2 | +-+-+----->| |read_ack_register1 | | +-->| +------------+ ++ +--------------------------+ | | | +---------------------+ | | | CPER | +| | ................. | | | +--->| |read_ack_register2 | | | | CPER | +| | error_status_address-----+---+ | | | +---------------------+ | | | .... | +| | ................. | | | | | ............. | | | | CPER | +| | read_ack_register--------+-----+-+ | +---------------------+ | +-+------------+ +| | read_ack_preserve | | +->| |read_ack_registerN | | | |.......... | +| | read_ack_write | | | | +---------------------+ | | +------------+ ++ +--------------------------| | | | | Error Status | +| | ............... | | | | | Data Block N | ++ +--------------------------+ | | +---->| +------------+ +| | GHESN | | | | | CPER | ++ +--------------------------+ | | | | CPER | +| | ................. | | | | | .... | +| | error_status_address-----+-----+ | | | CPER | +| | ................. | | +-+------------+ +| | read_ack_register--------+---------+ +| | read_ack_preserve | +| | read_ack_write | ++ +--------------------------+ + +(1) QEMU generates the ACPI HEST table. This table goes in the current + "etc/acpi/tables" fw_cfg blob. Each error source has different + notification type. + +(2) A new fw_cfg blob called "etc/hardware_errors" is introduced. QEMU + also need to populate this blob. The "etc/hardwre_errors" fw_cfg blob + contains one address registers table and one Error Status Data Block + table, all of which are pre-allocated. + +(3) The address registers table contains N Error Block Address entries + and N Read Ack Address entries, the size for each entry is 8-byte. + The Error Status Data Block table contains N Error Status Data Block + entries, the size for each entry is 4096(0x1000) bytes. The total size + for "etc/hardware_errors" fw_cfg blob is (N * 8 * 2 + N * 4096) bytes. + +(4) QEMU generates the ACPI linker/loader script for the firmware + +(4a) The HEST table is part of "etc/acpi/tables", the firmware already + allocates the memory for it, because QEMU already generates an ALLOCATE + linker/loader command for it + +(4b) QEMU creates another ALLOCATE command for the "etc/hardware_errors" + blob. The firmware allocates memory for this blob and downloads it. + +(5) QEMU generates N ADD_POINTER commands, which patch address in the + "error_status_address" fields of the HEST table with a pointer to the + corresponding "address registers" in the downloaded "etc/hardware_errors" + blob. + +(6) QEMU generates N ADD_POINTER commands, which patch address in the + "read_ack_register" fields of the HEST table with a pointer to the + corresponding "address registers" in the downloaded "etc/hardware_errors" blob. + +(7) QEMU generates N ADD_POINTER commands for the firmware, which patch + address in the " error_block_address" fields with a pointer to the + respective "Error Status Data Block" in the downloaded "etc/hardware_errors" + blob. + +(8) QEMU Defines a third and write-only fw_cfg blob which is called + "etc/hardware_errors_addr". Through that blob, the firmware can send back + the guest-side allocation addresses to QEMU. The "etc/hardware_errors_addr" + blob contains a 8-byte entry. QEMU generates a single WRITE_POINTER commands + for the firmware, the firmware will write back the start address of + "etc/hardware_errors" blob to fw_cfg file "etc/hardware_errors_addr". Then + Qemu will know the Error Status Data Block for every error source. Each of + Error Status Data Block has fixed size which is 4096(0x1000). + +(9) When QEMU gets SIGBUS from the kernel, QEMU formats the CPER right into + guest memory, and then injects whatever interrupt (or assert whatever GPIO line) + as a notification which is necessary for notifying the guest. + +(10) This notification (in virtual hardware) will be handled by guest kernel, + guest APEI driver will read the CPER which is recorded by QEMU and do the + recovery. From patchwork Thu Nov 8 10:29:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dongjiu Geng X-Patchwork-Id: 10673977 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4B10713AD for ; Thu, 8 Nov 2018 10:43:11 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3689C2CF65 for ; Thu, 8 Nov 2018 10:43:11 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 265B12D39F; Thu, 8 Nov 2018 10:43:11 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id AEE072CF65 for ; Thu, 8 Nov 2018 10:43:10 +0000 (UTC) Received: from localhost ([::1]:55742 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gKhmF-0007Pd-Q7 for patchwork-qemu-devel@patchwork.kernel.org; Thu, 08 Nov 2018 05:43:07 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43868) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gKhcS-0003GX-Dw for qemu-devel@nongnu.org; Thu, 08 Nov 2018 05:33:01 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gKhcR-0000Rk-7G for qemu-devel@nongnu.org; Thu, 08 Nov 2018 05:33:00 -0500 Received: from szxga06-in.huawei.com ([45.249.212.32]:46186 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gKhcK-0000Fn-3O; Thu, 08 Nov 2018 05:32:52 -0500 Received: from DGGEMS403-HUB.china.huawei.com (unknown [172.30.72.58]) by Forcepoint Email with ESMTP id 288591C0281A; Thu, 8 Nov 2018 18:32:41 +0800 (CST) Received: from ros.huawei.com (10.143.28.118) by DGGEMS403-HUB.china.huawei.com (10.3.19.203) with Microsoft SMTP Server id 14.3.408.0; Thu, 8 Nov 2018 18:32:33 +0800 From: Dongjiu Geng To: , , , , , , , , , , , , , , , Date: Thu, 8 Nov 2018 02:29:46 -0800 Message-ID: <1541672989-15967-8-git-send-email-gengdongjiu@huawei.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1541672989-15967-1-git-send-email-gengdongjiu@huawei.com> References: <1541672989-15967-1-git-send-email-gengdongjiu@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.143.28.118] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 45.249.212.32 Subject: [Qemu-devel] [PATCH RESEND v15 07/10] KVM: Move related hwpoison page functions to accel/kvm/ folder X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP kvm_hwpoison_page_add() and kvm_unpoison_all() will be used both by X86 and ARM platforms, so move these functions to a common accel/kvm/ folder to avoid duplicate code. Signed-off-by: Dongjiu Geng --- Address Peter's comments to move related hwpoison page function to accel/kvm folder in [1] Address Paolo's comments to move HWPoisonPage definition back to accel/kvm/kvm-all.c [1]: https://lists.gnu.org/archive/html/qemu-arm/2017-09/msg00077.html https://lists.gnu.org/archive/html/qemu-arm/2017-09/msg00152.html --- accel/kvm/kvm-all.c | 33 +++++++++++++++++++++++++++++++++ include/exec/ram_addr.h | 5 +++++ target/i386/kvm.c | 33 --------------------------------- 3 files changed, 38 insertions(+), 33 deletions(-) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 4880a05..003deac 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -625,6 +625,39 @@ int kvm_vm_check_extension(KVMState *s, unsigned int extension) return ret; } +typedef struct HWPoisonPage { + ram_addr_t ram_addr; + QLIST_ENTRY(HWPoisonPage) list; +} HWPoisonPage; + +static QLIST_HEAD(, HWPoisonPage) hwpoison_page_list = + QLIST_HEAD_INITIALIZER(hwpoison_page_list); + +void kvm_unpoison_all(void *param) +{ + HWPoisonPage *page, *next_page; + + QLIST_FOREACH_SAFE(page, &hwpoison_page_list, list, next_page) { + QLIST_REMOVE(page, list); + qemu_ram_remap(page->ram_addr, TARGET_PAGE_SIZE); + g_free(page); + } +} + +void kvm_hwpoison_page_add(ram_addr_t ram_addr) +{ + HWPoisonPage *page; + + QLIST_FOREACH(page, &hwpoison_page_list, list) { + if (page->ram_addr == ram_addr) { + return; + } + } + page = g_new(HWPoisonPage, 1); + page->ram_addr = ram_addr; + QLIST_INSERT_HEAD(&hwpoison_page_list, page, list); +} + static uint32_t adjust_ioeventfd_endianness(uint32_t val, uint32_t size) { #if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN) diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h index 9ecd911..1e02fb9 100644 --- a/include/exec/ram_addr.h +++ b/include/exec/ram_addr.h @@ -115,6 +115,11 @@ void qemu_ram_free(RAMBlock *block); int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp); +/* Add a poisoned page to the list */ +void kvm_hwpoison_page_add(ram_addr_t ram_addr); +/* Free and remove all the poisoned pages in the list */ +void kvm_unpoison_all(void *param); + #define DIRTY_CLIENTS_ALL ((1 << DIRTY_MEMORY_NUM) - 1) #define DIRTY_CLIENTS_NOCODE (DIRTY_CLIENTS_ALL & ~(1 << DIRTY_MEMORY_CODE)) diff --git a/target/i386/kvm.c b/target/i386/kvm.c index 796a049..08b3feb 100644 --- a/target/i386/kvm.c +++ b/target/i386/kvm.c @@ -457,39 +457,6 @@ uint32_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index) } -typedef struct HWPoisonPage { - ram_addr_t ram_addr; - QLIST_ENTRY(HWPoisonPage) list; -} HWPoisonPage; - -static QLIST_HEAD(, HWPoisonPage) hwpoison_page_list = - QLIST_HEAD_INITIALIZER(hwpoison_page_list); - -static void kvm_unpoison_all(void *param) -{ - HWPoisonPage *page, *next_page; - - QLIST_FOREACH_SAFE(page, &hwpoison_page_list, list, next_page) { - QLIST_REMOVE(page, list); - qemu_ram_remap(page->ram_addr, TARGET_PAGE_SIZE); - g_free(page); - } -} - -static void kvm_hwpoison_page_add(ram_addr_t ram_addr) -{ - HWPoisonPage *page; - - QLIST_FOREACH(page, &hwpoison_page_list, list) { - if (page->ram_addr == ram_addr) { - return; - } - } - page = g_new(HWPoisonPage, 1); - page->ram_addr = ram_addr; - QLIST_INSERT_HEAD(&hwpoison_page_list, page, list); -} - static int kvm_get_mce_cap_supported(KVMState *s, uint64_t *mce_cap, int *max_banks) { From patchwork Thu Nov 8 10:29:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dongjiu Geng X-Patchwork-Id: 10673969 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D4E611751 for ; Thu, 8 Nov 2018 10:40:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C02412D396 for ; Thu, 8 Nov 2018 10:40:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AF21B2D3B1; Thu, 8 Nov 2018 10:40:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 17D442D396 for ; Thu, 8 Nov 2018 10:40:16 +0000 (UTC) Received: from localhost ([::1]:55716 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gKhjT-0003yb-BX for patchwork-qemu-devel@patchwork.kernel.org; Thu, 08 Nov 2018 05:40:15 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43843) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gKhcR-0003DJ-L5 for qemu-devel@nongnu.org; Thu, 08 Nov 2018 05:33:00 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gKhcQ-0000R2-3g for qemu-devel@nongnu.org; Thu, 08 Nov 2018 05:32:59 -0500 Received: from szxga05-in.huawei.com ([45.249.212.191]:2572 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gKhcG-0000Fi-0Y; Thu, 08 Nov 2018 05:32:49 -0500 Received: from DGGEMS403-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id 7E8F3C7690A51; Thu, 8 Nov 2018 18:32:40 +0800 (CST) Received: from ros.huawei.com (10.143.28.118) by DGGEMS403-HUB.china.huawei.com (10.3.19.203) with Microsoft SMTP Server id 14.3.408.0; Thu, 8 Nov 2018 18:32:34 +0800 From: Dongjiu Geng To: , , , , , , , , , , , , , , , Date: Thu, 8 Nov 2018 02:29:47 -0800 Message-ID: <1541672989-15967-9-git-send-email-gengdongjiu@huawei.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1541672989-15967-1-git-send-email-gengdongjiu@huawei.com> References: <1541672989-15967-1-git-send-email-gengdongjiu@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.143.28.118] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 45.249.212.191 Subject: [Qemu-devel] [PATCH RESEND v15 08/10] target-arm: kvm64: inject synchronous External Abort X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Add synchronous external abort injection logic, setup exception type and syndrome value. When switch to guest, guest will jump to the synchronous external abort vector table entry. The ESR_ELx.DFSC is set to synchronous external abort(0x10), and ESR_ELx.FnV is set to not valid(0x1), which will tell guest that FAR is not valid and holds an UNKNOWN value. These value will be set to KVM register structures through KVM_SET_ONE_REG IOCTL. Signed-off-by: Dongjiu Geng --- Marc is against that KVM inject the synchronous external abort(SEA) in [1], so user space how to inject it. The test result that injection SEA to guest by Qemu is shown in [2]. [1]: https://lkml.org/lkml/2017/3/2/110 [2]: Taking exception 4 [Data Abort] ...from EL0 to EL1 ...with ESR 0x24/0x92000410 ...with FAR 0x0 ...with ELR 0x40cf04 ...to EL1 PC 0xffffffc000084c00 PSTATE 0x3c5 after kvm_inject_arm_sea Unhandled fault: synchronous external abort (0x92000410) at 0x0000007fa234c12c CPU: 0 PID: 536 Comm: devmem Not tainted 4.1.0+ #20 Hardware name: linux,dummy-virt (DT) task: ffffffc019ab2b00 ti: ffffffc008134000 task.ti: ffffffc008134000 PC is at 0x40cf04 LR is at 0x40cdec pc : [<000000000040cf04>] lr : [<000000000040cdec>] pstate: 60000000 sp : 0000007ff7b24130 x29: 0000007ff7b24260 x28: 0000000000000000 x27: 00000000000000ad x26: 000000000049c000 x25: 000000000048904b x24: 000000000049c000 x23: 0000000040600000 x22: 0000007ff7b243a0 x21: 0000000000000002 x20: 0000000000000000 x19: 0000000000000020 x18: 0000000000000000 x17: 000000000049c6d0 x16: 0000007fa22c85c0 x15: 0000000000005798 x14: 0000007fa2205f1c x13: 0000007fa241ccb0 x12: 0000000000000137 x11: 0000000000000000 x10: 0000000000000000 x9 : 0000000000000000 x8 : 00000000000000de x7 : 0000000000000000 x6 : 0000000000002000 x5 : 0000000040600000 x4 : 0000000000000003 x3 : 0000000000000001 x2 : 0000000000000000 x1 : 0000000000000000 x0 : 0000007fa2418000 --- target/arm/cpu.h | 2 ++ target/arm/helper.c | 23 +++++++++++++++++++++++ target/arm/internals.h | 5 +++-- target/arm/kvm64.c | 39 +++++++++++++++++++++++++++++++++++++++ target/arm/op_helper.c | 2 +- 5 files changed, 68 insertions(+), 3 deletions(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index b5eff79..502507d 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -2331,6 +2331,8 @@ bool write_list_to_cpustate(ARMCPU *cpu); */ bool write_cpustate_to_list(ARMCPU *cpu); +bool write_part_cpustate_to_list(ARMCPU *cpu, ptrdiff_t fieldoffset); + #define ARM_CPUID_TI915T 0x54029152 #define ARM_CPUID_TI925T 0x54029252 diff --git a/target/arm/helper.c b/target/arm/helper.c index 9630193..df078ff 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -263,6 +263,29 @@ static bool raw_accessors_invalid(const ARMCPRegInfo *ri) return true; } +bool write_part_cpustate_to_list(ARMCPU *cpu, ptrdiff_t fieldoffset) +{ + const ARMCPRegInfo *ri; + uint32_t regidx, i; + + for (i = 0; i < cpu->cpreg_array_len; i++) { + regidx = kvm_to_cpreg_id(cpu->cpreg_indexes[i]); + ri = get_arm_cp_reginfo(cpu->cp_regs, regidx); + if (!ri) { + continue; + } + + if (ri->type & ARM_CP_NO_RAW) { + continue; + } + if (ri->fieldoffset == fieldoffset) { + cpu->cpreg_values[i] = read_raw_cp_reg(&cpu->env, ri); + return true; + } + } + return false; +} + bool write_cpustate_to_list(ARMCPU *cpu) { /* Write the coprocessor state from cpu->env to the (index,value) list. */ diff --git a/target/arm/internals.h b/target/arm/internals.h index 6c2bb2d..04ea074 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -415,13 +415,14 @@ static inline uint32_t syn_insn_abort(int same_el, int ea, int s1ptw, int fsc) | ARM_EL_IL | (ea << 9) | (s1ptw << 7) | fsc; } -static inline uint32_t syn_data_abort_no_iss(int same_el, +static inline uint32_t syn_data_abort_no_iss(int same_el, int fnv, int ea, int cm, int s1ptw, int wnr, int fsc) { return (EC_DATAABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT) | ARM_EL_IL - | (ea << 9) | (cm << 8) | (s1ptw << 7) | (wnr << 6) | fsc; + | (fnv << 10) | (ea << 9) | (cm << 8) | (s1ptw << 7) + | (wnr << 6) | fsc; } static inline uint32_t syn_data_abort_with_iss(int same_el, diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index 5de8ff0..0ca2b29 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -594,6 +594,45 @@ int kvm_arm_cpreg_level(uint64_t regidx) return KVM_PUT_RUNTIME_STATE; } +/* Inject synchronous external abort */ +static void kvm_inject_arm_sea(CPUState *c) +{ + ARMCPU *cpu = ARM_CPU(c); + CPUARMState *env = &cpu->env; + CPUClass *cc = CPU_GET_CLASS(c); + uint32_t esr; + int ret; + + /* This exception is synchronous data abort */ + c->exception_index = EXCP_DATA_ABORT; + /* Inject the exception to guest EL1 */ + env->exception.target_el = 1; + + /* Set the DFSC to synchronous external abort and set FnV to not valid, + * this will tell guest the FAR_ELx is UNKNOWN for this abort. + */ + + /* This exception comes from lower or current exception level. */ + if (arm_current_el(env) == PSTATE_MODE_EL0t) { + esr = syn_data_abort_no_iss(0, 1, 0, 0, 0, 0, 0x10); + } else { + esr = syn_data_abort_no_iss(1, 1, 0, 0, 0, 0, 0x10); + } + + env->exception.syndrome = esr; + + cc->do_interrupt(c); + if (kvm_enabled()) { + /* write ESR_EL1 from cpustate to list*/ + ret = write_part_cpustate_to_list(cpu, + offsetof(CPUARMState, cp15.esr_el[1])); + if (!ret) { + fprintf(stderr, "<%s> failed to set esr_el1\n", __func__); + abort(); + } + } +} + #define AARCH64_CORE_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \ KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x)) diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c index 90741f6..3f1d656 100644 --- a/target/arm/op_helper.c +++ b/target/arm/op_helper.c @@ -109,7 +109,7 @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn, * ISV field. */ if (!(template_syn & ARM_EL_ISV) || target_el != 2 || s1ptw) { - syn = syn_data_abort_no_iss(same_el, + syn = syn_data_abort_no_iss(same_el, 0, ea, 0, s1ptw, is_write, fsc); } else { /* Fields: IL, ISV, SAS, SSE, SRT, SF and AR come from the template From patchwork Thu Nov 8 10:29:48 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dongjiu Geng X-Patchwork-Id: 10673971 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 553BA13AD for ; Thu, 8 Nov 2018 10:40:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 42A4A2CF65 for ; Thu, 8 Nov 2018 10:40:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 362D12D39F; Thu, 8 Nov 2018 10:40:57 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id C4D392CF65 for ; Thu, 8 Nov 2018 10:40:56 +0000 (UTC) Received: from localhost ([::1]:55722 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gKhk7-0004bg-Hb for patchwork-qemu-devel@patchwork.kernel.org; Thu, 08 Nov 2018 05:40:55 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43824) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gKhcQ-00039B-P4 for qemu-devel@nongnu.org; Thu, 08 Nov 2018 05:32:59 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gKhcP-0000Qm-Mf for qemu-devel@nongnu.org; Thu, 08 Nov 2018 05:32:58 -0500 Received: from szxga05-in.huawei.com ([45.249.212.191]:2570 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gKhcK-0000Ff-4K; Thu, 08 Nov 2018 05:32:52 -0500 Received: from DGGEMS403-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id 6B820DA419E7C; Thu, 8 Nov 2018 18:32:40 +0800 (CST) Received: from ros.huawei.com (10.143.28.118) by DGGEMS403-HUB.china.huawei.com (10.3.19.203) with Microsoft SMTP Server id 14.3.408.0; Thu, 8 Nov 2018 18:32:35 +0800 From: Dongjiu Geng To: , , , , , , , , , , , , , , , Date: Thu, 8 Nov 2018 02:29:48 -0800 Message-ID: <1541672989-15967-10-git-send-email-gengdongjiu@huawei.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1541672989-15967-1-git-send-email-gengdongjiu@huawei.com> References: <1541672989-15967-1-git-send-email-gengdongjiu@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.143.28.118] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 45.249.212.191 Subject: [Qemu-devel] [PATCH RESEND v15 09/10] hw/arm/virt: Add RAS platform version for migration X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Support this feature since version 2.12, disable it by default in the old version. Signed-off-by: Dongjiu Geng --- Address Shannon's comments to add platform version in [1]. [1]: https://lkml.org/lkml/2017/8/25/821 --- hw/arm/virt-acpi-build.c | 14 +++++++++----- hw/arm/virt.c | 4 ++++ include/hw/arm/virt.h | 1 + 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 19c1b7e..6f50a29 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -836,10 +836,11 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables) acpi_add_table(table_offsets, tables_blob); build_spcr(tables_blob, tables->linker, vms); - acpi_add_table(table_offsets, tables_blob); - build_hardware_error_table(tables->hardware_errors, tables->linker); - build_apei_hest(tables_blob, tables->hardware_errors, tables->linker); - + if (!vmc->no_ras) { + acpi_add_table(table_offsets, tables_blob); + build_hardware_error_table(tables->hardware_errors, tables->linker); + build_apei_hest(tables_blob, tables->hardware_errors, tables->linker); + } if (nb_numa_nodes > 0) { acpi_add_table(table_offsets, tables_blob); @@ -926,6 +927,7 @@ static const VMStateDescription vmstate_virt_acpi_build = { void virt_acpi_setup(VirtMachineState *vms) { + VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms); AcpiBuildTables tables; AcpiBuildState *build_state; @@ -957,7 +959,9 @@ void virt_acpi_setup(VirtMachineState *vms) fw_cfg_add_file(vms->fw_cfg, ACPI_BUILD_TPMLOG_FILE, tables.tcpalog->data, acpi_data_len(tables.tcpalog)); - ghes_add_fw_cfg(vms->fw_cfg, tables.hardware_errors); + if (!vmc->no_ras) { + ghes_add_fw_cfg(vms->fw_cfg, tables.hardware_errors); + } build_state->rsdp_mr = acpi_add_rom_blob(build_state, tables.rsdp, ACPI_BUILD_RSDP_FILE, 0); diff --git a/hw/arm/virt.c b/hw/arm/virt.c index a2b8d8f..367306b 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -1920,6 +1920,10 @@ static void virt_machine_2_11_options(MachineClass *mc) virt_machine_2_12_options(mc); SET_MACHINE_COMPAT(mc, VIRT_COMPAT_2_11); vmc->smbios_old_sys_ver = true; + /* Disable memory recovery feature for 2.11 as RAS support was + * introduced with 2.12. + */ + vmc->no_ras = true; } DEFINE_VIRT_MACHINE(2, 11) diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index 4cc57a7..a4490dd 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -98,6 +98,7 @@ typedef struct { bool disallow_affinity_adjustment; bool no_its; bool no_pmu; + bool no_ras; bool claim_edge_triggered_timers; bool smbios_old_sys_ver; bool no_highmem_ecam; From patchwork Thu Nov 8 10:29:49 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dongjiu Geng X-Patchwork-Id: 10673993 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 660441057 for ; Thu, 8 Nov 2018 10:45:36 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4F3AA2CE3F for ; Thu, 8 Nov 2018 10:45:36 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4348A2CF65; Thu, 8 Nov 2018 10:45:36 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 72E572CE3F for ; Thu, 8 Nov 2018 10:45:35 +0000 (UTC) Received: from localhost ([::1]:55757 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gKhoc-0002E3-In for patchwork-qemu-devel@patchwork.kernel.org; Thu, 08 Nov 2018 05:45:34 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43862) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gKhcS-0003Fm-68 for qemu-devel@nongnu.org; Thu, 08 Nov 2018 05:33:01 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gKhcQ-0000RE-B3 for qemu-devel@nongnu.org; Thu, 08 Nov 2018 05:33:00 -0500 Received: from szxga05-in.huawei.com ([45.249.212.191]:2573 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gKhcK-0000Fl-1w; Thu, 08 Nov 2018 05:32:52 -0500 Received: from DGGEMS403-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id 88868F68A33BC; Thu, 8 Nov 2018 18:32:40 +0800 (CST) Received: from ros.huawei.com (10.143.28.118) by DGGEMS403-HUB.china.huawei.com (10.3.19.203) with Microsoft SMTP Server id 14.3.408.0; Thu, 8 Nov 2018 18:32:35 +0800 From: Dongjiu Geng To: , , , , , , , , , , , , , , , Date: Thu, 8 Nov 2018 02:29:49 -0800 Message-ID: <1541672989-15967-11-git-send-email-gengdongjiu@huawei.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1541672989-15967-1-git-send-email-gengdongjiu@huawei.com> References: <1541672989-15967-1-git-send-email-gengdongjiu@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.143.28.118] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 45.249.212.191 Subject: [Qemu-devel] [PATCH RESEND v15 10/10] target-arm: kvm64: handle SIGBUS signal from kernel or KVM X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Add SIGBUS signal handler. In this handler, it checks the SIGBUS type, translates the host VA delivered by host to guest PA, then fill this PA to guest APEI GHES memory, then notify guest according to the SIGBUS type. There are two kinds of SIGBUS that QEMU needs to handle, which are BUS_MCEERR_AO and BUS_MCEERR_AR. If guest accesses the poisoned memory, it generates Synchronous External Abort(SEA). Then host kernel gets an APEI notification and call memory_failure() to unmapped the affected page from the guest's stage 2, finally return to guest. Guest continues to access PG_hwpoison page, it will trap to KVM as stage2 fault, then a SIGBUS_MCEERR_AR synchronous signal is delivered to Qemu, Qemu record this error into guest APEI GHES memory and notify guest using Synchronous-External-Abort(SEA). Suggested-by: James Morse Signed-off-by: Dongjiu Geng --- Address James's comments to record CPER and notify guest for SIGBUS signal handling. Shown some discussion in [1]. [1]: https://lkml.org/lkml/2017/2/27/246 https://lkml.org/lkml/2017/9/14/241 https://lkml.org/lkml/2017/9/22/499 --- hw/acpi/acpi_ghes.c | 164 ++++++++++++++++++++++++++++++++++++++++++++ include/hw/acpi/acpi_ghes.h | 4 ++ include/sysemu/kvm.h | 2 +- target/arm/kvm.c | 3 + target/arm/kvm64.c | 34 +++++++++ 5 files changed, 206 insertions(+), 1 deletion(-) diff --git a/hw/acpi/acpi_ghes.c b/hw/acpi/acpi_ghes.c index d03e797..ef83c05 100644 --- a/hw/acpi/acpi_ghes.c +++ b/hw/acpi/acpi_ghes.c @@ -26,6 +26,87 @@ #include "sysemu/sysemu.h" #include "qemu/error-report.h" +/* UEFI 2.6: N.2.5 Memory Error Section */ +static void build_append_mem_cper(GArray *table, uint64_t error_physical_addr) +{ + /* + * Memory Error Record + */ + build_append_int_noprefix(table, + (1UL << 14) | /* Type Valid */ + (1UL << 1) /* Physical Address Valid */, + 8); + /* Memory error status information */ + build_append_int_noprefix(table, 0, 8); + /* The physical address at which the memory error occurred */ + build_append_int_noprefix(table, error_physical_addr, 8); + build_append_int_noprefix(table, 0, 48); + build_append_int_noprefix(table, 0 /* Unknown error */, 1); + build_append_int_noprefix(table, 0, 7); +} + +static int ghes_record_mem_error(uint64_t error_block_address, + uint64_t error_physical_addr) +{ + GArray *block; + uint64_t current_block_length; + uint32_t data_length; + /* Memory section */ + char mem_section_id_le[] = {0x14, 0x11, 0xBC, 0xA5, 0x64, 0x6F, 0xDE, + 0x4E, 0xB8, 0x63, 0x3E, 0x83, 0xED, 0x7C, + 0x83, 0xB1}; + uint8_t fru_id[16] = {0}; + uint8_t fru_text[20] = {0}; + + block = g_array_new(false, true /* clear */, 1); + + /* Read the current length in bytes of the generic error data */ + cpu_physical_memory_read(error_block_address + + offsetof(AcpiGenericErrorStatus, data_length), &data_length, 4); + + /* The current whole length in bytes of the generic error status block */ + current_block_length = sizeof(AcpiGenericErrorStatus) + le32_to_cpu(data_length); + + /* Add a new generic error data entry*/ + data_length += GHES_DATA_LENGTH; + data_length += GHES_CPER_LENGTH; + + /* Check whether it will run out of the preallocated memory if adding a new + * generic error data entry + */ + if ((data_length + sizeof(AcpiGenericErrorStatus)) > GHES_MAX_RAW_DATA_LENGTH) { + error_report("Record CPER out of boundary!!!"); + return GHES_CPER_FAIL; + } + /* Build the new generic error status block header */ + build_append_ghes_generic_status(block, cpu_to_le32(ACPI_GEBS_UNCORRECTABLE), 0, 0, + cpu_to_le32(data_length), cpu_to_le32(ACPI_CPER_SEV_RECOVERABLE)); + + /* Write back above generic error status block header to guest memory */ + cpu_physical_memory_write(error_block_address, block->data, + block->len); + + /* Build the generic error data entries */ + + data_length = block->len; + /* Build the new generic error data entry header */ + build_append_ghes_generic_data(block, mem_section_id_le, + cpu_to_le32(ACPI_CPER_SEV_RECOVERABLE), cpu_to_le32(0x300), 0, 0, + cpu_to_le32(80)/* the total size of Memory Error Record */, fru_id, + fru_text, 0); + + /* Build the memory section CPER */ + build_append_mem_cper(block, error_physical_addr); + + /* Write back above whole new generic error data entry to guest memory */ + cpu_physical_memory_write(error_block_address + current_block_length, + block->data + data_length, block->len - data_length); + + g_array_free(block, true); + + return GHES_CPER_OK; +} + /* Build table for the hardware error fw_cfg blob */ void build_hardware_error_table(GArray *hardware_errors, BIOSLinker *linker) { @@ -169,3 +250,86 @@ void ghes_add_fw_cfg(FWCfgState *s, GArray *hardware_error) fw_cfg_add_file_callback(s, GHES_DATA_ADDR_FW_CFG_FILE, NULL, NULL, NULL, &ges.ghes_addr_le, sizeof(ges.ghes_addr_le), false); } + +bool ghes_record_errors(uint32_t notify, uint64_t physical_address) +{ + uint64_t error_block_addr, read_ack_register_addr; + int read_ack_register = 0, loop = 0; + uint64_t start_addr = le32_to_cpu(ges.ghes_addr_le); + bool ret = GHES_CPER_FAIL; + const uint8_t error_source_id[] = { 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0, 1}; + + /* + * | +---------------------+ 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 | + * | +---------------------+ + */ + if (physical_address && notify < ACPI_HEST_NOTIFY_RESERVED) { + /* Find and check the source id for this new CPER */ + if (error_source_id[notify] != 0xff) { + start_addr += error_source_id[notify] * GHES_ADDRESS_SIZE; + } else { + goto out; + } + + cpu_physical_memory_read(start_addr, &error_block_addr, + GHES_ADDRESS_SIZE); + + read_ack_register_addr = start_addr + + ACPI_HEST_ERROR_SOURCE_COUNT * GHES_ADDRESS_SIZE; +retry: + cpu_physical_memory_read(read_ack_register_addr, + &read_ack_register, GHES_ADDRESS_SIZE); + + /* zero means OSPM does not acknowledge the error */ + if (!read_ack_register) { + if (loop < 3) { + usleep(100 * 1000); + loop++; + goto retry; + } else { + 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, GHES_ADDRESS_SIZE); + } + } else { + if (error_block_addr) { + read_ack_register = 0; + cpu_physical_memory_write(read_ack_register_addr, + &read_ack_register, GHES_ADDRESS_SIZE); + ret = ghes_record_mem_error(error_block_addr, physical_address); + } + } + } + +out: + return ret; +} diff --git a/include/hw/acpi/acpi_ghes.h b/include/hw/acpi/acpi_ghes.h index 0a7c6c2..95d22ef 100644 --- a/include/hw/acpi/acpi_ghes.h +++ b/include/hw/acpi/acpi_ghes.h @@ -40,6 +40,9 @@ #define GHES_CPER_OK 1 #define GHES_CPER_FAIL 0 +#define GHES_CPER_OK 1 +#define GHES_CPER_FAIL 0 + /* The max size in bytes for one error block */ #define GHES_MAX_RAW_DATA_LENGTH 0x1000 /* Now only have GPIO-Signal and ARMv8 SEA notification types error sources @@ -79,4 +82,5 @@ void build_apei_hest(GArray *table_data, GArray *hardware_error, void build_hardware_error_table(GArray *hardware_errors, BIOSLinker *linker); void ghes_add_fw_cfg(FWCfgState *s, GArray *hardware_errors); +bool ghes_record_errors(uint32_t notify, uint64_t error_physical_addr); #endif diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index 97d8d9d..fd07d62 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -377,7 +377,7 @@ bool kvm_vcpu_id_is_valid(int vcpu_id); /* Returns VCPU ID to be used on KVM_CREATE_VCPU ioctl() */ unsigned long kvm_arch_vcpu_id(CPUState *cpu); -#ifdef TARGET_I386 +#if defined(TARGET_I386) || defined(TARGET_AARCH64) #define KVM_HAVE_MCE_INJECTION 1 void kvm_arch_on_sigbus_vcpu(CPUState *cpu, int code, void *addr); #endif diff --git a/target/arm/kvm.c b/target/arm/kvm.c index 09a86e2..f22dc4e 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -28,6 +28,7 @@ #include "exec/address-spaces.h" #include "hw/boards.h" #include "qemu/log.h" +#include "exec/ram_addr.h" const KVMCapabilityInfo kvm_arch_required_capabilities[] = { KVM_CAP_LAST_INFO @@ -176,6 +177,8 @@ int kvm_arch_init(MachineState *ms, KVMState *s) cap_has_mp_state = kvm_check_extension(s, KVM_CAP_MP_STATE); + qemu_register_reset(kvm_unpoison_all, NULL); + return 0; } diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index 0ca2b29..913e707 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -27,6 +27,9 @@ #include "kvm_arm.h" #include "internals.h" #include "hw/arm/arm.h" +#include "exec/ram_addr.h" +#include "hw/acpi/acpi-defs.h" +#include "hw/acpi/acpi_ghes.h" static bool have_guest_debug; @@ -929,6 +932,37 @@ int kvm_arch_get_registers(CPUState *cs) return ret; } +void kvm_arch_on_sigbus_vcpu(CPUState *c, int code, void *addr) +{ + ram_addr_t ram_addr; + hwaddr paddr; + + assert(code == BUS_MCEERR_AR || code == BUS_MCEERR_AO); + if (addr) { + ram_addr = qemu_ram_addr_from_host(addr); + if (ram_addr != RAM_ADDR_INVALID && + kvm_physical_memory_addr_from_host(c->kvm_state, addr, &paddr)) { + kvm_hwpoison_page_add(ram_addr); + if (code == BUS_MCEERR_AR) { + kvm_cpu_synchronize_state(c); + if (ghes_record_errors(ACPI_HEST_NOTIFY_SEA, paddr)) { + kvm_inject_arm_sea(c); + } else { + fprintf(stderr, "failed to record the error\n"); + } + } + return; + } + fprintf(stderr, "Hardware memory error for memory used by " + "QEMU itself instead of guest system!\n"); + } + + if (code == BUS_MCEERR_AR) { + fprintf(stderr, "Hardware memory error!\n"); + exit(1); + } +} + /* C6.6.29 BRK instruction */ static const uint32_t brk_insn = 0xd4200000;