From patchwork Mon Aug 11 20:38:23 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joel Schopp X-Patchwork-Id: 35215 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-qg0-f71.google.com (mail-qg0-f71.google.com [209.85.192.71]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id EEA4A20540 for ; Mon, 11 Aug 2014 20:40:32 +0000 (UTC) Received: by mail-qg0-f71.google.com with SMTP id f51sf26180321qge.2 for ; Mon, 11 Aug 2014 13:40:32 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:subject:from:to:date:message-id :user-agent:mime-version:cc:precedence:list-id:list-unsubscribe :list-archive:list-post:list-help:list-subscribe:sender:errors-to :x-original-sender:x-original-authentication-results:mailing-list :content-type:content-transfer-encoding; bh=dc0sa16aNCHGnXZcTbfFJbVaVZvXI2zPi33FVaB7RsU=; b=M7pW6k7duYFnaY92LsKQyrio7JEidjJ4ANB93hFXxARlBFGH5zwnncTr2Z+MnSWee8 b4KVtp8CyhzTUB1se6D8GUuG3wiqLwPhPH1LnPdVxF63F3kFBD92Bvsprn0+nR23mu5L F/AJ0gwob6L+ZSK+gVJB70YPplPKI64b1ho2wJMjvfyVwIKVF7G1m/wSQKTBH/ZZwk8V ETzmMWHMbNxyoBGDr1GzhGF0kBmGLUpgu7jNH+7lMtPk+oXGfKCZRnzyBKtDbC9NZ300 /V2adZ41FU0GQcbqVUhMGiiuDmJDljITMSkA7aT22e5VRZo7VzZ6lQH3SRat1SUAcRaY VL5A== X-Gm-Message-State: ALoCoQkaoobyICRbon9ox69nzTuUeZ7pdknF1t8oV5IFdnJBeJTUAwBZt2dQOV8GuADHlsuD4rp4 X-Received: by 10.52.182.66 with SMTP id ec2mr15023498vdc.0.1407789632824; Mon, 11 Aug 2014 13:40:32 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.109.117 with SMTP id k108ls1489005qgf.3.gmail; Mon, 11 Aug 2014 13:40:32 -0700 (PDT) X-Received: by 10.220.97.5 with SMTP id j5mr121144vcn.16.1407789632706; Mon, 11 Aug 2014 13:40:32 -0700 (PDT) Received: from mail-vc0-f169.google.com (mail-vc0-f169.google.com [209.85.220.169]) by mx.google.com with ESMTPS id ss10si7084405vcb.92.2014.08.11.13.40.32 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 11 Aug 2014 13:40:32 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.169 as permitted sender) client-ip=209.85.220.169; Received: by mail-vc0-f169.google.com with SMTP id le20so12344802vcb.14 for ; Mon, 11 Aug 2014 13:40:32 -0700 (PDT) X-Received: by 10.220.116.196 with SMTP id n4mr121858vcq.6.1407789632371; Mon, 11 Aug 2014 13:40:32 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.221.37.5 with SMTP id tc5csp193660vcb; Mon, 11 Aug 2014 13:40:31 -0700 (PDT) X-Received: by 10.66.182.10 with SMTP id ea10mr132267pac.123.1407789630808; Mon, 11 Aug 2014 13:40:30 -0700 (PDT) Received: from bombadil.infradead.org (bombadil.infradead.org. [2001:1868:205::9]) by mx.google.com with ESMTPS id hb1si14293860pbd.26.2014.08.11.13.40.30 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 11 Aug 2014 13:40:30 -0700 (PDT) Received-SPF: none (google.com: linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org does not designate permitted sender hosts) client-ip=2001:1868:205::9; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1XGwMs-0005aW-Gk; Mon, 11 Aug 2014 20:38:58 +0000 Received: from mail-by2lp0235.outbound.protection.outlook.com ([207.46.163.235] helo=na01-by2-obe.outbound.protection.outlook.com) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1XGwMp-0005T8-T9 for linux-arm-kernel@lists.infradead.org; Mon, 11 Aug 2014 20:38:56 +0000 Received: from BY1PR0201CA0034.namprd02.prod.outlook.com (25.160.191.172) by BY2PR02MB043.namprd02.prod.outlook.com (10.242.44.23) with Microsoft SMTP Server (TLS) id 15.0.1005.10; Mon, 11 Aug 2014 20:38:28 +0000 Received: from BN1BFFO11FD035.protection.gbl (2a01:111:f400:7c10::1:167) by BY1PR0201CA0034.outlook.office365.com (2a01:111:e400:4814::44) with Microsoft SMTP Server (TLS) id 15.0.1005.10 via Frontend Transport; Mon, 11 Aug 2014 20:38:27 +0000 Received: from atltwp01.amd.com (165.204.84.221) by BN1BFFO11FD035.mail.protection.outlook.com (10.58.144.98) with Microsoft SMTP Server id 15.0.1010.11 via Frontend Transport; Mon, 11 Aug 2014 20:38:27 +0000 X-WSS-ID: 0NA5TC1-07-6Z7-02 X-M-MSG: Received: from satlvexedge01.amd.com (satlvexedge01.amd.com [10.177.96.28]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (No client certificate requested) by atltwp01.amd.com (Axway MailGate 5.3.1) with ESMTPS id 2B635CAE828; Mon, 11 Aug 2014 15:38:24 -0500 (CDT) Received: from SATLEXDAG05.amd.com (10.181.40.11) by satlvexedge01.amd.com (10.177.96.28) with Microsoft SMTP Server (TLS) id 14.3.195.1; Mon, 11 Aug 2014 15:38:27 -0500 Received: from joelaarch64.amd.com (10.180.168.240) by satlexdag05.amd.com (10.181.40.11) with Microsoft SMTP Server (TLS) id 14.3.195.1; Mon, 11 Aug 2014 16:38:23 -0400 Subject: [PATCH v4] arm64: fix VTTBR_BADDR_MASK From: Joel Schopp To: , , Date: Mon, 11 Aug 2014 15:38:23 -0500 Message-ID: <20140811203823.2828.36074.stgit@joelaarch64.amd.com> User-Agent: StGit/0.17.1-4-g4a0c1 MIME-Version: 1.0 X-Originating-IP: [10.180.168.240] X-EOPAttributedMessage: 0 X-Forefront-Antispam-Report: CIP:165.204.84.221; CTRY:US; IPV:NLI; IPV:NLI; EFV:NLI; SFV:NSPM; SFS:(10019004)(6009001)(428002)(199002)(189002)(87936001)(2201001)(85852003)(83072002)(2171001)(4396001)(76482001)(92726001)(92566001)(50466002)(86362001)(103116003)(575784001)(46102001)(74502001)(31966008)(79102001)(97736001)(77982001)(77096002)(97746001)(68736004)(102836001)(101416001)(74662001)(81342001)(19580405001)(19580395003)(80022001)(83322001)(33646002)(44976005)(95666004)(84676001)(107046002)(229853001)(23676002)(64706001)(105586002)(53416004)(85306004)(54356999)(21056001)(81542001)(20776003)(99396002)(50986999)(83506001)(15975445006)(106466001)(47776003)(71626003); DIR:OUT; SFP:1102; SCL:1; SRVR:BY2PR02MB043; H:atltwp01.amd.com; FPR:; MLV:sfv; PTR:InfoDomainNonexistent; MX:1; LANG:en; X-Microsoft-Antispam: BCL:0;PCL:0;RULEID:;UriScan:; X-Forefront-PRVS: 03008837BD Received-SPF: None (protection.outlook.com: amd.com does not designate permitted sender hosts) X-OriginatorOrg: amd4.onmicrosoft.com X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140811_133855_955481_2BD0C66A X-CRM114-Status: GOOD ( 20.69 ) X-Spam-Score: -1.4 (-) X-Spam-Report: SpamAssassin version 3.4.0 on bombadil.infradead.org summary: Content analysis details: (-1.4 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [207.46.163.235 listed in list.dnswl.org] -0.7 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [207.46.163.235 listed in wl.mailspike.net] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record Cc: jungseoklee85@gmail.com, Sungjinn Chung , Jungseok Lee , Christoffer Dall X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: joel.schopp@amd.com X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.169 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 The current VTTBR_BADDR_MASK only masks 39 bits, which is broken on current systems. Rather than just add a bit it seems like a good time to also set things at run-time instead of compile time to accomodate more hardware. This patch sets TCR_EL2.PS, VTCR_EL2.T0SZ and vttbr_baddr_mask in runtime, not compile time. In ARMv8, EL2 physical address size (TCR_EL2.PS) and stage2 input address size (VTCR_EL2.T0SZE) cannot be determined in compile time since they depend on hardware capability. According to Table D4-23 and Table D4-25 in ARM DDI 0487A.b document, vttbr_x is calculated using different fixed values with consideration of T0SZ, granule size and the level of translation tables. Therefore, vttbr_baddr_mask should be determined dynamically. Changes since v3: Another rebase Addressed minor comments from v2 Changes since v2: Rebased on https://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git next branch Changes since v1: Rebased fix on Jungseok Lee's patch https://lkml.org/lkml/2014/5/12/189 to provide better long term fix. Updated that patch to log error instead of silently fail on unaligned vttbr. Cc: Christoffer Dall Cc: Sungjinn Chung Signed-off-by: Jungseok Lee Signed-off-by: Joel Schopp --- arch/arm/kvm/arm.c | 116 +++++++++++++++++++++++++++++++++++++- arch/arm64/include/asm/kvm_arm.h | 17 +----- arch/arm64/kvm/hyp-init.S | 20 +++++-- 3 files changed, 131 insertions(+), 22 deletions(-) diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index 3c82b37..b4859fa 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -61,6 +62,8 @@ static atomic64_t kvm_vmid_gen = ATOMIC64_INIT(1); static u8 kvm_next_vmid; static DEFINE_SPINLOCK(kvm_vmid_lock); +static u64 vttbr_baddr_mask; + static bool vgic_present; static void kvm_arm_set_running_vcpu(struct kvm_vcpu *vcpu) @@ -412,6 +415,103 @@ static bool need_new_vmid_gen(struct kvm *kvm) return unlikely(kvm->arch.vmid_gen != atomic64_read(&kvm_vmid_gen)); } + + + /* + * ARMv8 64K architecture limitations: + * 16 <= T0SZ <= 21 is valid under 3 level of translation tables + * 18 <= T0SZ <= 34 is valid under 2 level of translation tables + * 31 <= T0SZ <= 39 is valid under 1 level of transltaion tables + * + * ARMv8 4K architecture limitations: + * 16 <= T0SZ <= 24 is valid under 4 level of translation tables + * 21 <= T0SZ <= 30 is valid under 3 level of translation tables + * 30 <= T0SZ <= 39 is valid under 2 level of translation tables + * + * + * We further limit T0SZ in ARM64 Linux by not supporting 1 level + * translation tables at all, not supporting 2 level translation + * tables with 4k pages, not supporting different levels of translation + * tables in stage 1 vs stage 2, not supporting different page sizes in + * stage 1 vs stage 2, not supporting less than 40 bit address space + * with 64k pages, and not supporting less than 32 bit address space + * with 4K pages. + * + * See Table D4-23 and Table D4-25 in ARM DDI 0487A.b to figure out + * the origin of the hardcoded values, 38 and 37. + */ + +#ifdef CONFIG_ARM64_64K_PAGES +static inline int t0sz_to_vttbr_x(int t0sz){ + if (t0sz < 16 || t0sz > 24) { + kvm_err("Cannot support %d-bit address space\n", 64 - t0sz); + return -EINVAL; + } + + return 38 - t0sz; +} +#elif CONFIG_ARM64 && !CONFIG_ARM64_64K_PAGES +static inline int t0sz_to_vttbr_x(int t0sz){ + if (t0sz < 16 || t0sz > 32) { + kvm_err("Cannot support %d-bit address space\n", 64 - t0sz); + return -EINVAL; + } + return 37 - t0sz; +} +#endif + + +/** + * set_vttbr_baddr_mask - set mask value for vttbr base address + * + * In ARMv8, vttbr_baddr_mask cannot be determined in compile time since the + * stage2 input address size depends on hardware capability. Thus, we first + * need to read ID_AA64MMFR0_EL1.PARange first and then set vttbr_baddr_mask + * with consideration of both granule size and the level of translation tables. + */ +#ifndef CONFIG_ARM64 +static int set_vttbr_baddr_mask(void) +{ + vttbr_baddr_mask = VTTBR_BADDR_MASK; + return 0; +} +#else +static int set_vttbr_baddr_mask(void) +{ + int pa_range, t0sz, vttbr_x; + + pa_range = read_cpuid(ID_AA64MMFR0_EL1) & 0xf; + + switch (pa_range) { + case 0: + t0sz = VTCR_EL2_T0SZ(32); + break; + case 1: + t0sz = VTCR_EL2_T0SZ(36); + break; + case 2: + t0sz = VTCR_EL2_T0SZ(40); + break; + case 3: + t0sz = VTCR_EL2_T0SZ(42); + break; + case 4: + t0sz = VTCR_EL2_T0SZ(44); + break; + case 5: + t0sz = VTCR_EL2_T0SZ(48); + break; + default: + kvm_err("Invalid EL2 pa_range"); + return -EINVAL; + } + + vttbr_x = t0sz_to_vttbr_x(t0sz); + vttbr_baddr_mask = (((1LLU << (48 - vttbr_x)) - 1) << (vttbr_x - 1)); + + return 0; +} +#endif /** * update_vttbr - Update the VTTBR with a valid VMID before the guest runs * @kvm The guest that we are about to run @@ -466,8 +566,14 @@ static void update_vttbr(struct kvm *kvm) /* update vttbr to be used with the new vmid */ pgd_phys = virt_to_phys(kvm->arch.pgd); vmid = ((u64)(kvm->arch.vmid) << VTTBR_VMID_SHIFT) & VTTBR_VMID_MASK; - kvm->arch.vttbr = pgd_phys & VTTBR_BADDR_MASK; - kvm->arch.vttbr |= vmid; + + /* + * If the VTTBR isn't aligned there is something wrong with the system + * or kernel. + */ + BUG_ON(pgd_phys & ~vttbr_baddr_mask); + + kvm->arch.vttbr = pgd_phys | vmid; spin_unlock(&kvm_vmid_lock); } @@ -1052,6 +1158,12 @@ int kvm_arch_init(void *opaque) } } + err = set_vttbr_baddr_mask(); + if (err) { + kvm_err("Cannot set vttbr_baddr_mask\n"); + return -EINVAL; + } + cpu_notifier_register_begin(); err = init_hyp_mode(); diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h index 3d69030..8dbef70 100644 --- a/arch/arm64/include/asm/kvm_arm.h +++ b/arch/arm64/include/asm/kvm_arm.h @@ -94,7 +94,6 @@ /* TCR_EL2 Registers bits */ #define TCR_EL2_TBI (1 << 20) #define TCR_EL2_PS (7 << 16) -#define TCR_EL2_PS_40B (2 << 16) #define TCR_EL2_TG0 (1 << 14) #define TCR_EL2_SH0 (3 << 12) #define TCR_EL2_ORGN0 (3 << 10) @@ -103,8 +102,6 @@ #define TCR_EL2_MASK (TCR_EL2_TG0 | TCR_EL2_SH0 | \ TCR_EL2_ORGN0 | TCR_EL2_IRGN0 | TCR_EL2_T0SZ) -#define TCR_EL2_FLAGS (TCR_EL2_PS_40B) - /* VTCR_EL2 Registers bits */ #define VTCR_EL2_PS_MASK (7 << 16) #define VTCR_EL2_TG0_MASK (1 << 14) @@ -119,36 +116,28 @@ #define VTCR_EL2_SL0_MASK (3 << 6) #define VTCR_EL2_SL0_LVL1 (1 << 6) #define VTCR_EL2_T0SZ_MASK 0x3f -#define VTCR_EL2_T0SZ_40B 24 +#define VTCR_EL2_T0SZ(bits) (64 - (bits)) #ifdef CONFIG_ARM64_64K_PAGES /* * Stage2 translation configuration: - * 40bits output (PS = 2) - * 40bits input (T0SZ = 24) * 64kB pages (TG0 = 1) * 2 level page tables (SL = 1) */ #define VTCR_EL2_FLAGS (VTCR_EL2_TG0_64K | VTCR_EL2_SH0_INNER | \ VTCR_EL2_ORGN0_WBWA | VTCR_EL2_IRGN0_WBWA | \ - VTCR_EL2_SL0_LVL1 | VTCR_EL2_T0SZ_40B) -#define VTTBR_X (38 - VTCR_EL2_T0SZ_40B) + VTCR_EL2_SL0_LVL1) #else /* * Stage2 translation configuration: - * 40bits output (PS = 2) - * 40bits input (T0SZ = 24) * 4kB pages (TG0 = 0) * 3 level page tables (SL = 1) */ #define VTCR_EL2_FLAGS (VTCR_EL2_TG0_4K | VTCR_EL2_SH0_INNER | \ VTCR_EL2_ORGN0_WBWA | VTCR_EL2_IRGN0_WBWA | \ - VTCR_EL2_SL0_LVL1 | VTCR_EL2_T0SZ_40B) -#define VTTBR_X (37 - VTCR_EL2_T0SZ_40B) + VTCR_EL2_SL0_LVL1) #endif -#define VTTBR_BADDR_SHIFT (VTTBR_X - 1) -#define VTTBR_BADDR_MASK (((1LLU << (40 - VTTBR_X)) - 1) << VTTBR_BADDR_SHIFT) #define VTTBR_VMID_SHIFT (48LLU) #define VTTBR_VMID_MASK (0xffLLU << VTTBR_VMID_SHIFT) diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S index d968796..c0f7634 100644 --- a/arch/arm64/kvm/hyp-init.S +++ b/arch/arm64/kvm/hyp-init.S @@ -63,17 +63,21 @@ __do_hyp_init: mrs x4, tcr_el1 ldr x5, =TCR_EL2_MASK and x4, x4, x5 - ldr x5, =TCR_EL2_FLAGS - orr x4, x4, x5 - msr tcr_el2, x4 - - ldr x4, =VTCR_EL2_FLAGS /* * Read the PARange bits from ID_AA64MMFR0_EL1 and set the PS bits in - * VTCR_EL2. + * TCR_EL2 and both PS bits and T0SZ bits in VTCR_EL2. */ mrs x5, ID_AA64MMFR0_EL1 bfi x4, x5, #16, #3 + msr tcr_el2, x4 + + ldr x4, =VTCR_EL2_FLAGS + bfi x4, x5, #16, #3 + and x5, x5, #0xf + adr x6, t0sz + add x6, x6, x5, lsl #2 + ldr w5, [x6] + orr x4, x4, x5 msr vtcr_el2, x4 mrs x4, mair_el1 @@ -109,6 +113,10 @@ target: /* We're now in the trampoline code, switch page tables */ /* Hello, World! */ eret + +t0sz: + .word VTCR_EL2_T0SZ(32), VTCR_EL2_T0SZ(36), VTCR_EL2_T0SZ(40) + .word VTCR_EL2_T0SZ(42), VTCR_EL2_T0SZ(44), VTCR_EL2_T0SZ(48) ENDPROC(__kvm_hyp_init) .ltorg