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: 108171 Delivered-To: patch@linaro.org Received: by 10.140.101.44 with SMTP id t41csp6188460qge; Tue, 18 Jul 2017 10:08:55 -0700 (PDT) X-Received: by 10.99.121.133 with SMTP id u127mr2821937pgc.31.1500397735766; Tue, 18 Jul 2017 10:08:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1500397735; cv=none; d=google.com; s=arc-20160816; b=VCPIBlH99QhqyNuSOcOdxXKt/1rDAU4/ueC2LmRfgW9MgaZYqRPxS4+8X6QA6lo5Fx w8/MiwRjGxPcMv8aPHiA/smZ/fH8PAlflNwN/jvp7G57dbsGLTDcReaeG39CSnowqebX lGf3nYdoZ4QlTNbfR5leneOfoly1BBF4r8oKsOhU1dU5iTZ2bM7j6OZL20z4yy9AcoEQ UgFopobXzWWLp9CoueTNB5kWJ2somVHc/XtJkuU8Oo6Go4/r/1VE/Qo3ClzKTjbMkYwo QLoveQvTYszvkMbV5pJfP3M8xaV4pJYObiPGNaPAwlYWCZ8xKIFs+3QsKFmt7gQgBHhO Z1fQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=OP7AoCD6KD7pkUCxrsUGkVgKCpdo//1VjbXMdmfYWlk=; b=t9z7kalWar3Lu4eSR0C5qVn2nCIS4Rie3pqtU8EVJjglPMHyRyaUbwynvdosWk2InP 1QMXJZIWF+er+7RLNM0mlU0AlEhBZluHE2u+CWWbwJJIns3vKecZxJ8Rt9VceF1zfl6q TrYUm0V8m7sJLzzcYm4FN+uMQRJmdPgjElTqYd/uOu89dPoC16NmLebYO/SobJ0aIfB0 rt/I5U6kGhVqMZQ7M6g6Iy8i3oFq8GjPJ3i2iFUCHSqVUoKvfO471TA9kPQ/wYnpKhAm NML9TO6ns6Zp2XYVZbsEReg7wP7uXvbdeW9pXzfow8BUu0yzwYBxump4L/7LqRf20wuS hItg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.b=DCgW4zXp; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id y14si2192844pgr.587.2017.07.18.10.08.55; Tue, 18 Jul 2017 10:08:55 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.b=DCgW4zXp; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752542AbdGRRIw (ORCPT + 25 others); Tue, 18 Jul 2017 13:08:52 -0400 Received: from mail-io0-f170.google.com ([209.85.223.170]:33495 "EHLO mail-io0-f170.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751551AbdGRRAD (ORCPT ); Tue, 18 Jul 2017 13:00:03 -0400 Received: by mail-io0-f170.google.com with SMTP id 5so16502682iow.0 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=e3F5l1720+2tEeIquIBi2K2FyfltUm8iZkIVR2BhmZsAX2pWepJgry5ovxjwUanFXy /ayhF4ZQNvznW+pdsdp+G1ECD5ALRvSBNxpIMN7I2p9k5/qSKqYn5fdtbOkPCRSJJt5B 8gx6ecoTzdgm2twKBmhlOwIN8T607SudF5HuOuJiv05kP5MzvLZI8oK/hdFPqrKE6Qr1 xJElTJoMYIufuZMZykyAdAI17kxDcOW5uM3ruFWeOL1ohHvqVrCTnH/1G4ZicBb+G942 uWcvAYw936A5loREja37MKkwp1y7x3uzSNhi7/bISxHXt5yHsI0KuAwF63zOynmh4IDV Y1Ew== X-Gm-Message-State: AIVw11056kP2P9W/veQDLVYfsxSdgu1FbpP62Sj0bLCZdedqlRefu63S 982jhBgGGcS3ZgUU 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: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 -- 1.9.1 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