From patchwork Tue Jul 18 16:58:39 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jintack Lim X-Patchwork-Id: 108173 Delivered-To: patch@linaro.org Received: by 10.140.101.44 with SMTP id t41csp6190058qge; Tue, 18 Jul 2017 10:10:06 -0700 (PDT) X-Received: by 10.99.113.77 with SMTP id b13mr2688569pgn.11.1500397806780; Tue, 18 Jul 2017 10:10:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1500397806; cv=none; d=google.com; s=arc-20160816; b=KUAKwH3Wgr/XFLT8c5C8JrLqq7BCCSTZliyWA9Fnp0IPr7eMawIkR2coG0alolTC9G QMNv3OJuRhHR/nOqkaHrNoOwSBpw/OHH9TgQ8T17vJhO+JWrOMFLs+jyzvd9jGUyxgMl yBaggv53K42yIrEg1CuMJYv8iLMJ3fSt3q/GvNLEtOHHLs86fyGgmfUOC9gD+F/uet6s iYCBy+F5NIsmHeATxafoBaCUKVQZ2SmCPluvi+L6b7qk3GvMVIT4Jutn5BlsPj2vfC2L XhSAtZFv3lcadzgHaThVBnvN6QJ5Gnl1QmaBcAtqVnGMcgvyej1PZmmdolpFVhbAidaW Vq7Q== 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=Dzi5ftaJYrZCPDUJeVqmPGV6OrJXqoJ0k10UZczbrnA=; b=vdOmnkIZVefdhCS3qZfB6pADaKvNawcxIP3aWPupnVEeJyL5cU2IpGpoGktihOfgjw rtFtz5bw312KTLZXYTg/nQ6JHF6xhZ5vU0NYsSKHSAGBzwU3kYpg14WIv85crT09pDJ2 CvTesXS4v3AzMAiLv/2awLa1PMdl2OikQ/vCVxNnMsZ3oKNmDf8//X50zLfA6ab/SBEc NkKTaGpMyHhV545e+CLPcBhDyoHonkdQtB9kY2larveeNztj3D3i2+EAFjKRjmoBWPw0 c6na3t46dcK5GoL8lsAih4FqdMRw8i+lAA4pkbSbVKvQIM2oEMU/+CHWt7wabm0wv6Kc mAng== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.b=ii5BTruz; 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 u18si1225147plj.642.2017.07.18.10.10.06; Tue, 18 Jul 2017 10:10:06 -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=ii5BTruz; 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 S1752315AbdGRRKE (ORCPT + 25 others); Tue, 18 Jul 2017 13:10:04 -0400 Received: from mail-io0-f172.google.com ([209.85.223.172]:35425 "EHLO mail-io0-f172.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752077AbdGRQ75 (ORCPT ); Tue, 18 Jul 2017 12:59:57 -0400 Received: by mail-io0-f172.google.com with SMTP id k71so16779593iod.2 for ; Tue, 18 Jul 2017 09:59:56 -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=Dzi5ftaJYrZCPDUJeVqmPGV6OrJXqoJ0k10UZczbrnA=; b=ii5BTruz7ZLrMF9vED7lvjKUxpWi8mXvXW/ANI8KxcsfcUOCuMXVqsiAJEBlPLJXHl GhbhBEptovLgM+7V5uNhAJP95tJyum/Nc1J2czcRJ50FmQnTDNruAC2dX6093NidEG8K ZSjjuXrXBZs44K+EnrONvZhWze1ENcvxH/tQ8= 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=Dzi5ftaJYrZCPDUJeVqmPGV6OrJXqoJ0k10UZczbrnA=; b=uVqPsN5SNW9fV7QFbuJ6mFTlNkxUOvZ+Z5NkvcRKyC+uecRiSHTQ4KWESPSvlRgyTm kfN5/tJLu1rtWGkTerE5P81lxkJtuZLJ00rylLCpMbq8DcCswxZ6PzVq2rmN3/nhkMxC 0AOmZKDCsmIDRVgbg2eXvGW9DyLPAt9pj0jDwNAkQ4qWIv38rHIsXAbUu35gOwR/7ol/ sxe1tyX59UlnYGTenSlHQITr/Y3MWg8ZuV9FvCrmNveAl4iCENP6gFPObFyRWGHv+W/d 5xw4sb58k2NJy8WGF3T+8chDSrEE6r/Ek1BEhhAgS81DA9b22b/cc28AjrT0eD7cXD4P wiWA== X-Gm-Message-State: AIVw112yDT0EdUdxTC5bGSdgDfz9JxPgQPqQh4Rb298w7APj7qE2k8JP zDTfhZ9RmU91st135UmFYA== X-Received: by 10.107.200.211 with SMTP id y202mr2736463iof.16.1500397196411; Tue, 18 Jul 2017 09:59:56 -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.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 18 Jul 2017 09:59:55 -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 13/38] KVM: arm64: Create shadow EL1 registers Date: Tue, 18 Jul 2017 11:58:39 -0500 Message-Id: <1500397144-16232-14-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 From: Christoffer Dall When entering virtual EL2, we need to reflect virtual EL2 register states to corresponding shadow EL1 registers. We can simply copy them if their formats are identical. Otherwise, we need to convert EL2 register state to EL1 register state. When entering EL1/EL0, we need a special care for MPIDR_EL1. Read of this register returns the value of VMPIDR_EL2, so when a VM has the virtual EL2, the value of MPIDR_EL1 should come from the virtual VMPIDR_EL2. Signed-off-by: Christoffer Dall Signed-off-by: Jintack Lim --- arch/arm64/kvm/context.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) -- 1.9.1 diff --git a/arch/arm64/kvm/context.c b/arch/arm64/kvm/context.c index 2645787..e965049 100644 --- a/arch/arm64/kvm/context.c +++ b/arch/arm64/kvm/context.c @@ -17,6 +17,74 @@ #include #include +#include + +struct el1_el2_map { + enum vcpu_sysreg el1; + enum vcpu_sysreg el2; +}; + +/* + * List of EL2 registers which can be directly applied to EL1 registers to + * emulate running EL2 in EL1. + */ +static const struct el1_el2_map el1_el2_map[] = { + { AMAIR_EL1, AMAIR_EL2 }, + { MAIR_EL1, MAIR_EL2 }, + { TTBR0_EL1, TTBR0_EL2 }, + { ACTLR_EL1, ACTLR_EL2 }, + { AFSR0_EL1, AFSR0_EL2 }, + { AFSR1_EL1, AFSR1_EL2 }, + { SCTLR_EL1, SCTLR_EL2 }, + { VBAR_EL1, VBAR_EL2 }, +}; + +static inline u64 tcr_el2_ips_to_tcr_el1_ps(u64 tcr_el2) +{ + return ((tcr_el2 & TCR_EL2_PS_MASK) >> TCR_EL2_PS_SHIFT) + << TCR_IPS_SHIFT; +} + +static inline u64 cptr_to_cpacr(u64 cptr_el2) +{ + u64 cpacr_el1 = 0; + + if (!(cptr_el2 & CPTR_EL2_TFP)) + cpacr_el1 |= CPACR_EL1_FPEN; + if (cptr_el2 & CPTR_EL2_TTA) + cpacr_el1 |= CPACR_EL1_TTA; + + return cpacr_el1; +} + +static void flush_shadow_el1_sysregs(struct kvm_vcpu *vcpu) +{ + u64 *s_sys_regs = vcpu->arch.ctxt.shadow_sys_regs; + u64 tcr_el2; + int i; + + for (i = 0; i < ARRAY_SIZE(el1_el2_map); i++) { + const struct el1_el2_map *map = &el1_el2_map[i]; + + s_sys_regs[map->el1] = vcpu_sys_reg(vcpu, map->el2); + } + + tcr_el2 = vcpu_sys_reg(vcpu, TCR_EL2); + s_sys_regs[TCR_EL1] = + TCR_EPD1 | /* disable TTBR1_EL1 */ + ((tcr_el2 & TCR_EL2_TBI) ? TCR_TBI0 : 0) | + tcr_el2_ips_to_tcr_el1_ps(tcr_el2) | + (tcr_el2 & TCR_EL2_TG0_MASK) | + (tcr_el2 & TCR_EL2_ORGN0_MASK) | + (tcr_el2 & TCR_EL2_IRGN0_MASK) | + (tcr_el2 & TCR_EL2_T0SZ_MASK); + + /* Rely on separate VMID for VA context, always use ASID 0 */ + s_sys_regs[TTBR0_EL1] &= ~GENMASK_ULL(63, 48); + s_sys_regs[TTBR1_EL1] = 0; + + s_sys_regs[CPACR_EL1] = cptr_to_cpacr(vcpu_sys_reg(vcpu, CPTR_EL2)); +} static void flush_shadow_special_regs(struct kvm_vcpu *vcpu) { @@ -72,6 +140,17 @@ static void sync_special_regs(struct kvm_vcpu *vcpu) ctxt->gp_regs.spsr[KVM_SPSR_EL1] = ctxt->hw_spsr_el1; } +static void setup_mpidr_el1(struct kvm_vcpu *vcpu) +{ + /* + * A non-secure EL0 or EL1 read of MPIDR_EL1 returns + * the value of VMPIDR_EL2. For nested virtualization, + * it comes from the virtual VMPIDR_EL2. + */ + if (nested_virt_in_use(vcpu)) + vcpu_sys_reg(vcpu, MPIDR_EL1) = vcpu_sys_reg(vcpu, VMPIDR_EL2); +} + /** * kvm_arm_setup_shadow_state -- prepare shadow state based on emulated mode * @vcpu: The VCPU pointer @@ -82,9 +161,11 @@ 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); ctxt->hw_sys_regs = ctxt->shadow_sys_regs; } else { flush_special_regs(vcpu); + setup_mpidr_el1(vcpu); ctxt->hw_sys_regs = ctxt->sys_regs; } }