From patchwork Tue Jul 18 16:58:42 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jintack Lim X-Patchwork-Id: 9849101 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 C24E4600CC for ; Tue, 18 Jul 2017 17:09:37 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A696228583 for ; Tue, 18 Jul 2017 17:09:37 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9B2BB285C2; Tue, 18 Jul 2017 17:09:37 +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=-6.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,RCVD_IN_DNSWL_HI,RCVD_IN_SORBS_SPAM autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id ED15A28583 for ; Tue, 18 Jul 2017 17:09:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752376AbdGRRIt (ORCPT ); Tue, 18 Jul 2017 13:08:49 -0400 Received: from mail-io0-f178.google.com ([209.85.223.178]:35459 "EHLO mail-io0-f178.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751518AbdGRRAD (ORCPT ); Tue, 18 Jul 2017 13:00:03 -0400 Received: by mail-io0-f178.google.com with SMTP id k71so16781162iod.2 for ; Tue, 18 Jul 2017 10:00:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=OP7AoCD6KD7pkUCxrsUGkVgKCpdo//1VjbXMdmfYWlk=; b=DCgW4zXpJi13Qu+nuwn0Dil+DqfBTOlRqPabqxOg0tObvo7pZET1f7srZqNC+/dI+E Q/rXFAlxuX8Lh1zct7TVXoYPOuIvj91Qljw5SaDiguWiwxczEr4zbETaSLVcNLJOSlYv uZsqvLg8aYK7fXUa2kqaMWdofwidX5YnrAWjM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=OP7AoCD6KD7pkUCxrsUGkVgKCpdo//1VjbXMdmfYWlk=; b=nEX9PEnMrpD0pRS02gxt+k/VvOCGZg1xgrC5cTNR7TEch/PGdEfe6gwDAoijjfcY96 FMfhIP18yz5E7LAWw2RmAyZ9CMq+UeQieCrVtErVduO3e/+1CALdhKLgvIkP/AmYPyLd SlMTOA2igGkY7T0b8BhYEisPMKu5lpnXmSr1zWuUwRskKkJtPtCjWW8sE0wj2XjZ+3aE B1hw/ylCF5eKNWgGEBT8AN/yk4AjppRxtVt3x86XjXsYlZLsZeYXJ+l6aSJMoszWEWq9 CsUjQS07AySDHsysh1hTr9tCjedxInr9V7nN7JHX0B5zn+ydb1YxkzQVGXoTBuoV+8F8 U7RA== X-Gm-Message-State: AIVw113VsDbHMW+Zh6rHBOoNYKO+hUq7kRVESWlBL7SzGtOxlMg9Ypqc UNmJTayN+Zn0p1uQ X-Received: by 10.107.10.205 with SMTP id 74mr2535764iok.80.1500397202309; Tue, 18 Jul 2017 10:00:02 -0700 (PDT) Received: from node.jintackl-qv26972.kvmarm-pg0.wisc.cloudlab.us (c220g1-030822.wisc.cloudlab.us. [128.104.222.82]) by smtp.gmail.com with ESMTPSA id j96sm1413075ioo.49.2017.07.18.10.00.00 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 18 Jul 2017 10:00:01 -0700 (PDT) From: Jintack Lim To: kvmarm@lists.cs.columbia.edu, christoffer.dall@linaro.org, marc.zyngier@arm.com Cc: corbet@lwn.net, pbonzini@redhat.com, rkrcmar@redhat.com, linux@armlinux.org.uk, catalin.marinas@arm.com, will.deacon@arm.com, akpm@linux-foundation.org, mchehab@kernel.org, cov@codeaurora.org, daniel.lezcano@linaro.org, david.daney@cavium.com, mark.rutland@arm.com, suzuki.poulose@arm.com, stefan@hello-penguin.com, andy.gross@linaro.org, wcohen@redhat.com, ard.biesheuvel@linaro.org, shankerd@codeaurora.org, vladimir.murzin@arm.com, james.morse@arm.com, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Jintack Lim Subject: [RFC PATCH v2 16/38] KVM: arm64: Support to inject exceptions to the virtual EL2 Date: Tue, 18 Jul 2017 11:58:42 -0500 Message-Id: <1500397144-16232-17-git-send-email-jintack.lim@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1500397144-16232-1-git-send-email-jintack.lim@linaro.org> References: <1500397144-16232-1-git-send-email-jintack.lim@linaro.org> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Support inject synchronous exceptions to the virtual EL2 as described in ARM ARM AArch64.TakeException(). This can be easily extended to support to inject asynchronous exceptions to the virtual EL2, but it will be added in a later patch when appropriate. Signed-off-by: Jintack Lim --- arch/arm/include/asm/kvm_emulate.h | 7 +++ arch/arm64/include/asm/kvm_emulate.h | 2 + arch/arm64/kvm/Makefile | 1 + arch/arm64/kvm/emulate-nested.c | 83 ++++++++++++++++++++++++++++++++++++ arch/arm64/kvm/trace.h | 20 +++++++++ 5 files changed, 113 insertions(+) create mode 100644 arch/arm64/kvm/emulate-nested.c diff --git a/arch/arm/include/asm/kvm_emulate.h b/arch/arm/include/asm/kvm_emulate.h index 0a03b7d..29a4dec 100644 --- a/arch/arm/include/asm/kvm_emulate.h +++ b/arch/arm/include/asm/kvm_emulate.h @@ -47,6 +47,13 @@ static inline void vcpu_set_reg(struct kvm_vcpu *vcpu, u8 reg_num, void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr); void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr); +static inline int kvm_inject_nested_sync(struct kvm_vcpu *vcpu, u64 esr_el2) +{ + kvm_err("Unexpected call to %s for the non-nesting configuration\n", + __func__); + return -EINVAL; +} + static inline void kvm_arm_setup_shadow_state(struct kvm_vcpu *vcpu) { }; static inline void kvm_arm_restore_shadow_state(struct kvm_vcpu *vcpu) { }; static inline void kvm_arm_init_cpu_context(kvm_cpu_context_t *cpu_ctxt) { }; diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h index 94f98cc..3017234 100644 --- a/arch/arm64/include/asm/kvm_emulate.h +++ b/arch/arm64/include/asm/kvm_emulate.h @@ -54,6 +54,8 @@ enum exception_type { void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr); void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr); +int kvm_inject_nested_sync(struct kvm_vcpu *vcpu, u64 esr_el2); + void kvm_arm_setup_shadow_state(struct kvm_vcpu *vcpu); void kvm_arm_restore_shadow_state(struct kvm_vcpu *vcpu); void kvm_arm_init_cpu_context(kvm_cpu_context_t *cpu_ctxt); diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile index 5762337..0263ef0 100644 --- a/arch/arm64/kvm/Makefile +++ b/arch/arm64/kvm/Makefile @@ -37,3 +37,4 @@ kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/arch_timer.o kvm-$(CONFIG_KVM_ARM_PMU) += $(KVM)/arm/pmu.o kvm-$(CONFIG_KVM_ARM_HOST) += nested.o +kvm-$(CONFIG_KVM_ARM_HOST) += emulate-nested.o diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c new file mode 100644 index 0000000..48b84cc --- /dev/null +++ b/arch/arm64/kvm/emulate-nested.c @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2016 - Linaro and Columbia University + * Author: Jintack Lim + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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 +#include + +#include + +#include "trace.h" + +/* This is borrowed from get_except_vector in inject_fault.c */ +static u64 get_el2_except_vector(struct kvm_vcpu *vcpu, + enum exception_type type) +{ + u64 exc_offset; + + switch (*vcpu_cpsr(vcpu) & (PSR_MODE_MASK | PSR_MODE32_BIT)) { + case PSR_MODE_EL2t: + exc_offset = CURRENT_EL_SP_EL0_VECTOR; + break; + case PSR_MODE_EL2h: + exc_offset = CURRENT_EL_SP_ELx_VECTOR; + break; + case PSR_MODE_EL1t: + case PSR_MODE_EL1h: + case PSR_MODE_EL0t: + exc_offset = LOWER_EL_AArch64_VECTOR; + break; + default: + kvm_err("Unexpected previous exception level: aarch32\n"); + exc_offset = LOWER_EL_AArch32_VECTOR; + } + + return vcpu_sys_reg(vcpu, VBAR_EL2) + exc_offset + type; +} + +/* + * Emulate taking an exception to EL2. + * See ARM ARM J8.1.2 AArch64.TakeException() + */ +static int kvm_inject_nested(struct kvm_vcpu *vcpu, u64 esr_el2, + enum exception_type type) +{ + int ret = 1; + + if (!nested_virt_in_use(vcpu)) { + kvm_err("Unexpected call to %s for the non-nesting configuration\n", + __func__); + return -EINVAL; + } + + vcpu_el2_sreg(vcpu, SPSR_EL2) = *vcpu_cpsr(vcpu); + vcpu_el2_sreg(vcpu, ELR_EL2) = *vcpu_pc(vcpu); + vcpu_sys_reg(vcpu, ESR_EL2) = esr_el2; + + *vcpu_pc(vcpu) = get_el2_except_vector(vcpu, type); + /* On an exception, PSTATE.SP becomes 1 */ + *vcpu_cpsr(vcpu) = PSR_MODE_EL2h; + *vcpu_cpsr(vcpu) |= (PSR_A_BIT | PSR_F_BIT | PSR_I_BIT | PSR_D_BIT); + + trace_kvm_inject_nested_exception(vcpu, esr_el2, *vcpu_pc(vcpu)); + + return ret; +} + +int kvm_inject_nested_sync(struct kvm_vcpu *vcpu, u64 esr_el2) +{ + return kvm_inject_nested(vcpu, esr_el2, except_type_sync); +} diff --git a/arch/arm64/kvm/trace.h b/arch/arm64/kvm/trace.h index 7fb0008..7c86cfb 100644 --- a/arch/arm64/kvm/trace.h +++ b/arch/arm64/kvm/trace.h @@ -167,6 +167,26 @@ ); +TRACE_EVENT(kvm_inject_nested_exception, + TP_PROTO(struct kvm_vcpu *vcpu, unsigned long esr_el2, + unsigned long pc), + TP_ARGS(vcpu, esr_el2, pc), + + TP_STRUCT__entry( + __field(struct kvm_vcpu *, vcpu) + __field(unsigned long, esr_el2) + __field(unsigned long, pc) + ), + + TP_fast_assign( + __entry->vcpu = vcpu; + __entry->esr_el2 = esr_el2; + __entry->pc = pc; + ), + + TP_printk("vcpu: %p, inject exception to vEL2: ESR_EL2 0x%lx, vector: 0x%016lx", + __entry->vcpu, __entry->esr_el2, __entry->pc) +); #endif /* _TRACE_ARM64_KVM_H */ #undef TRACE_INCLUDE_PATH