From patchwork Tue Jul 18 16:58:40 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jintack Lim X-Patchwork-Id: 108145 Delivered-To: patch@linaro.org Received: by 10.182.45.195 with SMTP id p3csp6148618obm; Tue, 18 Jul 2017 10:00:13 -0700 (PDT) X-Received: by 10.84.169.36 with SMTP id g33mr2936825plb.52.1500397213235; Tue, 18 Jul 2017 10:00:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1500397213; cv=none; d=google.com; s=arc-20160816; b=zM972WMStH0d/aVXw/IT/29L8Zeb0A7E4YZgJOP2/I3wYrvsmOJc3JJwkTv78At/1v AstW2bkp2cTYwInTcSRPc6PKxk0Dd6Txqgc2QlAMSQGJChcD71NfTMSmbWnuC6CmsLVO 9UTImtAhBSj9MBIDRLVzKbYmsRHTKV11YgVX0AmhhgVmsNpuOmW0FrV+SORwVZSdyYWT /0OZuOgMfH3D9NGT59sQsE7QdXWdTR5eTcvq3hJeYV7nmV4Nc0+m2VX9aRBHM7CzcjsD d2eeejuVIFy8VRRTAbg/EBJ8XtFGv66uA+btj0fbcRrRIp6qIB7SMOUo2v3uffSWmvxS zF3Q== 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=FRi4V9u1gbS0dP/ydCmVVbCmWKtSV9AdAFrgkp+PwsQ=; b=EctBMRV1oqiy0r5QboIJLXTu7vmgRoyhpFQrhmTkUO5SabvlSf7fklMzVJa+H9ZTtE ANSyKNnxge7h7TmnE2QqhareQw+kmAElAiy7KaIZMUB/HAHN6SJ5AgnvDdy1wgrqzyMa XKRX/bSr0vz+Qz7O7EgpWlTOU3h/AlHJrYd0ZKB5HES5T3G4i74I/HP9lZo5ns5SY3Si NP+7MbotlArBLt0Etjn3DI1Fb0n+0yANcrEd55eYRwcEcEranYbu7u5DXtSMI51XiUBx QZGNpj3NdKLyZoFHl7316ZnwSi701uLBYRo3Mqa3BDq4/haVt5uLkJiLc59WnQyYKEz5 CxVw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.b=biDmBbyP; 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 o187si2115656pfb.37.2017.07.18.10.00.12; Tue, 18 Jul 2017 10:00:13 -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=biDmBbyP; 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 S1752244AbdGRRAI (ORCPT + 25 others); Tue, 18 Jul 2017 13:00:08 -0400 Received: from mail-it0-f42.google.com ([209.85.214.42]:38173 "EHLO mail-it0-f42.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752156AbdGRQ77 (ORCPT ); Tue, 18 Jul 2017 12:59:59 -0400 Received: by mail-it0-f42.google.com with SMTP id h199so16521512ith.1 for ; Tue, 18 Jul 2017 09:59:58 -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=FRi4V9u1gbS0dP/ydCmVVbCmWKtSV9AdAFrgkp+PwsQ=; b=biDmBbyPoK7PTV/MrB3RIMGbm1ugYgRzfxlKKwWm/IyXHRI3HeVBZDBPHGXw3+oJtS Fpmiw+3bJvHTdWvOTzJcNtq391iu4hcTxhW0zyPoo/7pIObKD4pl5CNOkuxkEkc61XX6 MxABx1awVNY9Npq2gDoFqUN/Mqbx+VqRibRFo= 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=FRi4V9u1gbS0dP/ydCmVVbCmWKtSV9AdAFrgkp+PwsQ=; b=XRhzHxAvldTMaq3irCqP7GN/eRV0m7I5XHAK+AcTDmDtOOMW58JB4Q801qOiZRWwpf LnaJrVE30lGpZP1YfSUn91RMG4/hWvLZhh344SkwU+0n9AnFLOTkBdoxhHHt6PtCBtxV PhnpiTY/gn0rhSp+W633/be/yUHWYhqZ2UGY79bXf4aA4uM7hxFaA+jJIbqRDwBdrbRd Mz9RqZxpx6SsPkHC+KSaBCASBzzoBs06da0ckLk9/2Rdcsx/N8gvXAT888zLMqjslTTz oD7oP6EY0GmXuG/mK0eVEApa1a2sCZArzUpzA8oMRLQ6PTHdVcvLXvDJ2CYTKT5RgAwO Nsew== X-Gm-Message-State: AIVw111MS4ckZ7Dsg13mMlirl7pER6aWMTRT7fd3RK3e6A/oSea7nTCU JhH4ZxBK5GWMEEbC X-Received: by 10.36.33.213 with SMTP id e204mr2956181ita.119.1500397198318; Tue, 18 Jul 2017 09:59:58 -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.09.59.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 18 Jul 2017 09:59:57 -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 14/38] KVM: arm64: Synchronize EL1 system registers on virtual EL2 entry and exit Date: Tue, 18 Jul 2017 11:58:40 -0500 Message-Id: <1500397144-16232-15-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 When running in virtual EL2 we use the shadow EL1 systerm register array for the save/restore process, so that hardware and especially the memory subsystem behaves as code written for EL2 expects while really running in EL1. This works great for EL1 system register accesses that we trap, because these accesses will be written into the virtual state for the EL1 system registers used when eventually switching the VCPU mode to EL1. However, there was a collection of EL1 system registers which we do not trap, and as a consequence all save/restore operations of these registers were happening locally in the shadow array, with no benefit to software actually running in virtual EL1 at all. To fix this, simply synchronize the shadow and real EL1 state for these registers on entry/exit to/from virtual EL2 state. Signed-off-by: Christoffer Dall Signed-off-by: Jintack Lim --- arch/arm64/kvm/context.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) -- 1.9.1 diff --git a/arch/arm64/kvm/context.c b/arch/arm64/kvm/context.c index e965049..e1bc753 100644 --- a/arch/arm64/kvm/context.c +++ b/arch/arm64/kvm/context.c @@ -86,6 +86,58 @@ static void flush_shadow_el1_sysregs(struct kvm_vcpu *vcpu) s_sys_regs[CPACR_EL1] = cptr_to_cpacr(vcpu_sys_reg(vcpu, CPTR_EL2)); } + +/* + * List of EL0 and EL1 registers which we allow the virtual EL2 mode to access + * directly without trapping. This is possible because the impact of + * accessing those registers are the same regardless of the exception + * levels that are allowed. + */ +static const int el1_non_trap_regs[] = { + CNTKCTL_EL1, + CSSELR_EL1, + PAR_EL1, + TPIDR_EL0, + TPIDR_EL1, + TPIDRRO_EL0 +}; + +/** + * copy_shadow_non_trap_el1_state + * @vcpu: The VCPU pointer + * @setup: True, if on the way to the guest (called from setup) + * False, if returning form the guet (calld from restore) + * + * Some EL1 registers are accessed directly by the virtual EL2 mode because + * they in no way affect execution state in virtual EL2. However, we must + * still ensure that virtual EL2 observes the same state of the EL1 registers + * as the normal VM's EL1 mode, so copy this state as needed on setup/restore. + */ +static void copy_shadow_non_trap_el1_state(struct kvm_vcpu *vcpu, bool setup) +{ + u64 *s_sys_regs = vcpu->arch.ctxt.shadow_sys_regs; + int i; + + for (i = 0; i < ARRAY_SIZE(el1_non_trap_regs); i++) { + const int sr = el1_non_trap_regs[i]; + + if (setup) + s_sys_regs[sr] = vcpu_sys_reg(vcpu, sr); + else + vcpu_sys_reg(vcpu, sr) = s_sys_regs[sr]; + } +} + +static void sync_shadow_non_trap_el1_state(struct kvm_vcpu *vcpu) +{ + copy_shadow_non_trap_el1_state(vcpu, false); +} + +static void flush_shadow_non_trap_el1_state(struct kvm_vcpu *vcpu) +{ + copy_shadow_non_trap_el1_state(vcpu, true); +} + static void flush_shadow_special_regs(struct kvm_vcpu *vcpu) { struct kvm_cpu_context *ctxt = &vcpu->arch.ctxt; @@ -162,6 +214,7 @@ void kvm_arm_setup_shadow_state(struct kvm_vcpu *vcpu) if (unlikely(vcpu_mode_el2(vcpu))) { flush_shadow_special_regs(vcpu); flush_shadow_el1_sysregs(vcpu); + flush_shadow_non_trap_el1_state(vcpu); ctxt->hw_sys_regs = ctxt->shadow_sys_regs; } else { flush_special_regs(vcpu); @@ -176,9 +229,10 @@ void kvm_arm_setup_shadow_state(struct kvm_vcpu *vcpu) */ void kvm_arm_restore_shadow_state(struct kvm_vcpu *vcpu) { - if (unlikely(vcpu_mode_el2(vcpu))) + if (unlikely(vcpu_mode_el2(vcpu))) { sync_shadow_special_regs(vcpu); - else + sync_shadow_non_trap_el1_state(vcpu); + } else sync_special_regs(vcpu); }