From patchwork Fri Nov 10 19:19:51 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dongjiu Geng X-Patchwork-Id: 10052871 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id CBF6C60365 for ; Fri, 10 Nov 2017 11:24:38 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A749C2B0DC for ; Fri, 10 Nov 2017 11:24:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 999772B0E5; Fri, 10 Nov 2017 11:24:38 +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=-5.0 required=2.0 tests=BAYES_00, DATE_IN_FUTURE_06_12, 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 172D42B0DC for ; Fri, 10 Nov 2017 11:24:38 +0000 (UTC) Received: from localhost ([::1]:41162 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eD7QL-0008TG-2A for patchwork-qemu-devel@patchwork.kernel.org; Fri, 10 Nov 2017 06:24:37 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55382) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eD7Ho-0002CA-CU for qemu-devel@nongnu.org; Fri, 10 Nov 2017 06:15:51 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eD7Hm-0001dq-RL for qemu-devel@nongnu.org; Fri, 10 Nov 2017 06:15:48 -0500 Received: from szxga05-in.huawei.com ([45.249.212.191]:2288) by eggs.gnu.org with esmtps (TLS1.0:RSA_ARCFOUR_SHA1:16) (Exim 4.71) (envelope-from ) id 1eD7He-0001RP-RR; Fri, 10 Nov 2017 06:15:39 -0500 Received: from 172.30.72.58 (EHLO DGGEMS403-HUB.china.huawei.com) ([172.30.72.58]) by dggrg05-dlp.huawei.com (MOS 4.4.6-GA FastPath queued) with ESMTP id DKR46945; Fri, 10 Nov 2017 19:15:19 +0800 (CST) Received: from localhost.localdomain (10.143.28.90) by DGGEMS403-HUB.china.huawei.com (10.3.19.203) with Microsoft SMTP Server id 14.3.361.1; Fri, 10 Nov 2017 19:14:09 +0800 From: Dongjiu Geng To: , , , , , , , , , , , , , , , , , , , , Date: Sat, 11 Nov 2017 03:19:51 +0800 Message-ID: <1510341591-22817-13-git-send-email-gengdongjiu@huawei.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1510341591-22817-1-git-send-email-gengdongjiu@huawei.com> References: <1510341591-22817-1-git-send-email-gengdongjiu@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.143.28.90] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A090205.5A058A47.00BD, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2014-11-16 11:51:01, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: ce6af62c67a0fc83ab373918bc2e679c X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x-2.6.x [generic] [fuzzy] X-Received-From: 45.249.212.191 Subject: [Qemu-devel] [PATCH v12 12/12] 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, translate the host VA which is delivered by host to guest PA, then fill this PA to CPER and fill the CPER to guest APEI GHES memory, finally notify guest according the SIGBUS type. There are two kinds of SIGBUS that QEMU need to handle, which are BUS_MCEERR_AO and BUS_MCEERR_AR. Guest access device type poisoned memory, generate SError interrupt, so it reports it to host firmware. Host kernel gets an APEI notification and memory_failure() causes the affected page to be unmapped from the guest's stage2, and SIGBUS_MCEERR_AO is sent to user-space. Here Qemu will create a new CPER and add it to guest APEI GHES memory, and notify the guest with a GPIO-Signal notification. When guest hit a PG_hwpoison page, it will trap to KVM as stage2 fault, here a SIGBUS_MCEERR_AR synchronous signal is delivered to user-space, 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 Signed-off-by: Quanming Wu --- QEMU handing the SIGBUS is discussed here: https://lkml.org/lkml/2017/2/27/246 Using which error notification to notify guest is discussed here: https://lkml.org/lkml/2017/9/14/241 https://lkml.org/lkml/2017/9/22/499 --- include/sysemu/kvm.h | 2 +- target/arm/kvm.c | 2 ++ target/arm/kvm64.c | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index 3a458f5..90c1605 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -361,7 +361,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 d85e36a..8523158 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -26,6 +26,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 @@ -182,6 +183,7 @@ 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); type_register_static(&host_arm_cpu_type_info); return 0; diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index 7f662e9..3b532e1 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/hest_ghes.h" static bool have_guest_debug; @@ -943,6 +946,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_cpu_synchronize_state(c); + kvm_hwpoison_page_add(ram_addr); + if (code == BUS_MCEERR_AR) { + ghes_update_guest(ACPI_HEST_NOTIFY_SEA, paddr); + kvm_inject_arm_sea(c); + } else if (code == BUS_MCEERR_AO) { + ghes_update_guest(ACPI_HEST_NOTIFY_GPIO, paddr); + qemu_hardware_error_notify(); + } + 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;