From patchwork Sat Jan 6 16:02:57 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dongjiu Geng X-Patchwork-Id: 10147721 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 BEDB060134 for ; Sat, 6 Jan 2018 08:14:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 93095289BB for ; Sat, 6 Jan 2018 08:14:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 85FC3289BF; Sat, 6 Jan 2018 08:14:03 +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=-2.3 required=2.0 tests=BAYES_00, DATE_IN_FUTURE_06_12, DKIM_SIGNED, DKIM_VALID, RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id EA2CE289BB for ; Sat, 6 Jan 2018 08:14:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=8NKKfHIEtZW9RDFCh10VgFYrhl7hhqF0GqJ/A3SLw08=; b=QL/3gi9AnqURiQ dgW4VzP7ilovgwDxHy3EWh1Qoy95Bczn6gy/w+0zFPTqrnaFpVz5w5OMqMAcnejKbXYFkwTLw+gRP //RvfSrbwEDzmcupIDSRouXcc3U/S334SonBoTp/hDlnzoPmQ+S2Lze6pyNMFdWzIyQTqCcTX9H9R SeDmDoUFzTO80E06fG+5aC5Z1kcO/0OTaDIaeRZfiToXirR2OBvNpThYkeQVw/35VL5EQN9RgbSc9 g07AEnayq8diZwSFn7CwtV75wOIFZFJ5enH19TGfvgn2l12Qq4QxHgh+vChMYjuEW2J9z7XW6CDLa pPlp+ZKD/94iYOmm5Vkw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.89 #1 (Red Hat Linux)) id 1eXjc6-0001S6-05; Sat, 06 Jan 2018 08:13:58 +0000 Received: from [45.249.212.32] (helo=huawei.com) by bombadil.infradead.org with esmtps (Exim 4.89 #1 (Red Hat Linux)) id 1eXjN1-0001lv-WB for linux-arm-kernel@lists.infradead.org; Sat, 06 Jan 2018 07:58:27 +0000 Received: from DGGEMS412-HUB.china.huawei.com (unknown [172.30.72.58]) by Forcepoint Email with ESMTP id 31846DC74FBE7; Sat, 6 Jan 2018 15:57:56 +0800 (CST) Received: from localhost.localdomain (10.143.28.90) by DGGEMS412-HUB.china.huawei.com (10.3.19.212) with Microsoft SMTP Server id 14.3.361.1; Sat, 6 Jan 2018 15:57:49 +0800 From: Dongjiu Geng To: , , , , , , , , , , , , , , , , Subject: [PATCH v9 7/7] arm64: kvm: handle guest SError Interrupt by categorization Date: Sun, 7 Jan 2018 00:02:57 +0800 Message-ID: <1515254577-6460-8-git-send-email-gengdongjiu@huawei.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1515254577-6460-1-git-send-email-gengdongjiu@huawei.com> References: <1515254577-6460-1-git-send-email-gengdongjiu@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.143.28.90] X-CFilter-Loop: Reflected X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180105_235824_438585_8CEA4FD3 X-CRM114-Status: GOOD ( 17.66 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: huangshaoyu@huawei.com, gengdongjiu@huawei.com Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP If it is not RAS SError, directly inject virtual SError, which will keep the old way, otherwise firstly let host ACPI kernel driver to handle it. If the ACPI handling is failed, KVM continues categorizing errors by the ESR_ELx. For the recoverable error (UER), it has not been silently propagated and has not (yet) been architecturally consumed by the PE, the exception is precise. In order to make it simple, we temporarily shut down the VM to isolate the error. Signed-off-by: Dongjiu Geng --- change since v8: 1. Check handle_guest_sei()'s return value 2. Temporarily shut down the VM to isolate the error for the recoverable error (UER) 3. Remove some unused macro definitions --- arch/arm64/include/asm/esr.h | 11 ++++++ arch/arm64/include/asm/system_misc.h | 1 + arch/arm64/kvm/handle_exit.c | 68 +++++++++++++++++++++++++++++++++--- arch/arm64/mm/fault.c | 16 +++++++++ 4 files changed, 92 insertions(+), 4 deletions(-) diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h index 66ed8b6..a751e86 100644 --- a/arch/arm64/include/asm/esr.h +++ b/arch/arm64/include/asm/esr.h @@ -102,6 +102,7 @@ #define ESR_ELx_FSC_ACCESS (0x08) #define ESR_ELx_FSC_FAULT (0x04) #define ESR_ELx_FSC_PERM (0x0C) +#define ESR_ELx_FSC_SERROR (0x11) /* ISS field definitions for Data Aborts */ #define ESR_ELx_ISV_SHIFT (24) @@ -119,6 +120,16 @@ #define ESR_ELx_CM_SHIFT (8) #define ESR_ELx_CM (UL(1) << ESR_ELx_CM_SHIFT) +/* ISS field definitions for SError interrupt */ +#define ESR_ELx_AET_SHIFT (10) +#define ESR_ELx_AET (UL(0x7) << ESR_ELx_AET_SHIFT) +/* Restartable error */ +#define ESR_ELx_AET_UEO (UL(2) << ESR_ELx_AET_SHIFT) +/* Recoverable error */ +#define ESR_ELx_AET_UER (UL(3) << ESR_ELx_AET_SHIFT) +/* Corrected error */ +#define ESR_ELx_AET_CE (UL(6) << ESR_ELx_AET_SHIFT) + /* ISS field definitions for exceptions taken in to Hyp */ #define ESR_ELx_CV (UL(1) << 24) #define ESR_ELx_COND_SHIFT (20) diff --git a/arch/arm64/include/asm/system_misc.h b/arch/arm64/include/asm/system_misc.h index 07aa8e3..9ee13ad 100644 --- a/arch/arm64/include/asm/system_misc.h +++ b/arch/arm64/include/asm/system_misc.h @@ -57,6 +57,7 @@ void hook_debug_fault_code(int nr, int (*fn)(unsigned long, unsigned int, }) int handle_guest_sea(phys_addr_t addr, unsigned int esr); +int handle_guest_sei(void); #endif /* __ASSEMBLY__ */ diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c index 7debb74..5b806d4 100644 --- a/arch/arm64/kvm/handle_exit.c +++ b/arch/arm64/kvm/handle_exit.c @@ -28,6 +28,7 @@ #include #include #include +#include #define CREATE_TRACE_POINTS #include "trace.h" @@ -178,6 +179,67 @@ static exit_handle_fn kvm_get_exit_handler(struct kvm_vcpu *vcpu) return arm_exit_handlers[hsr_ec]; } +/** + * kvm_handle_guest_sei - handles SError interrupt or asynchronous aborts + * @vcpu: the VCPU pointer + * @run: access to the kvm_run structure for results + * + * For RAS SError interrupt, firstly let host kernel handle it. If handling + * failed, then categorize the error by the ESR + */ +static int kvm_handle_guest_sei(struct kvm_vcpu *vcpu, struct kvm_run *run) +{ + unsigned int esr = kvm_vcpu_get_hsr(vcpu); + bool impdef_syndrome = esr & ESR_ELx_ISV; /* aka IDS */ + unsigned int aet = esr & ESR_ELx_AET; + + /* + * This is not RAS SError + */ + if (!cpus_have_const_cap(ARM64_HAS_RAS_EXTN)) { + kvm_inject_vabt(vcpu); + return 1; + } + + /* For RAS the host kernel may handle this abort. */ + if (!handle_guest_sei()) + return 1; + + /* + * In below two conditions, it will directly inject the + * virtual SError: + * 1. The Syndrome is IMPLEMENTATION DEFINED + * 2. It is Uncategorized SEI + */ + if (impdef_syndrome || + ((esr & ESR_ELx_FSC) != ESR_ELx_FSC_SERROR)) { + kvm_inject_vabt(vcpu); + return 1; + } + + switch (aet) { + case ESR_ELx_AET_CE: /* corrected error */ + case ESR_ELx_AET_UEO: /* restartable error, not yet consumed */ + return 1; /* continue processing the guest exit */ + case ESR_ELx_AET_UER: /* recoverable error */ + /* + * the exception is precise, not been silently propagated + * and not been consumed by the CPU, temporarily shut down + * the VM to isolated the error, hope not touch it again. + */ + run->exit_reason = KVM_EXIT_EXCEPTION; + return 0; + default: + /* + * Until now, the CPU supports RAS, SError interrupt is fatal + * and host does not successfully handle it. + */ + panic("This Asynchronous SError interrupt is dangerous, panic"); + } + + return 0; +} + /* * Return > 0 to return to guest, < 0 on error, 0 (and set exit_reason) on * proper exit to userspace. @@ -201,8 +263,7 @@ int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run, *vcpu_pc(vcpu) -= adj; } - kvm_inject_vabt(vcpu); - return 1; + return kvm_handle_guest_sei(vcpu, run); } exception_index = ARM_EXCEPTION_CODE(exception_index); @@ -211,8 +272,7 @@ int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run, case ARM_EXCEPTION_IRQ: return 1; case ARM_EXCEPTION_EL1_SERROR: - kvm_inject_vabt(vcpu); - return 1; + return kvm_handle_guest_sei(vcpu, run); case ARM_EXCEPTION_TRAP: /* * See ARM ARM B1.14.1: "Hyp traps on instructions diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index b64958b..8560672 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -728,6 +728,22 @@ int handle_guest_sea(phys_addr_t addr, unsigned int esr) } /* + * Handle SError interrupt that occurred in guest OS. + * + * The return value will be zero if the SEI was successfully handled + * and non-zero if handling is failed. + */ +int handle_guest_sei(void) +{ + int ret = -ENOENT; + + if (IS_ENABLED(CONFIG_ACPI_APEI_SEI)) + ret = ghes_notify_sei(); + + return ret; +} + +/* * Dispatch a data abort to the relevant handler. */ asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr,