From patchwork Tue Aug 12 16:05:21 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoffer Dall X-Patchwork-Id: 35281 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-pd0-f199.google.com (mail-pd0-f199.google.com [209.85.192.199]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 0D5FA203C5 for ; Tue, 12 Aug 2014 16:07:52 +0000 (UTC) Received: by mail-pd0-f199.google.com with SMTP id v10sf38491840pde.6 for ; Tue, 12 Aug 2014 09:07:52 -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:date:from:to:subject:message-id :references:mime-version:in-reply-to:user-agent: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-disposition :content-type:content-transfer-encoding; bh=6O6BCPbGe8FB9MwbikPrrn0f1mTRbELqlIqKR5YGsPc=; b=YhoyT7RX+2z1yqdTr5xZCvU7vPTJ+cI2fuA+rPPu6kNu1RcfLvoWfjp/gwiY0U9ufh eTWjjxLT52xFcdO4hmQOfWVlVIgdocSudRPl4dkVNf32lqGUj85F+ZR0xEogmJ6mUAag lODAWA4QVtZNraSGFRVU2SnF+kLwYLM3LpQsX1WDgNUhrbxPmB6bDE+cRrl7Sr7jWeY2 ZecvqHNiAeHOwRr8aK5+RMzGzxmkqUIEPxJiQN15SFUjct3zK/RyqEqWGRry6P3Rgr7u vCi+yre8BWAlkLAPbJCx6RtUEHN23QIW5KocydIGmUZxD/jdLzwfYy9TwYBsgsM8jZtu ZesA== X-Gm-Message-State: ALoCoQlH9lma71Q7g16l+A+or8Ocbv6xOhWzn9Ya4Bi8rFJndPU7wTlaibhc/bvAh2sf5IVXQV8I X-Received: by 10.70.90.47 with SMTP id bt15mr2788739pdb.4.1407859672365; Tue, 12 Aug 2014 09:07:52 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.38.80 with SMTP id s74ls149806qgs.64.gmail; Tue, 12 Aug 2014 09:07:52 -0700 (PDT) X-Received: by 10.52.89.211 with SMTP id bq19mr1407957vdb.93.1407859672250; Tue, 12 Aug 2014 09:07:52 -0700 (PDT) Received: from mail-vc0-f178.google.com (mail-vc0-f178.google.com [209.85.220.178]) by mx.google.com with ESMTPS id z17si8491949vct.60.2014.08.12.09.07.52 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 12 Aug 2014 09:07:52 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.178 as permitted sender) client-ip=209.85.220.178; Received: by mail-vc0-f178.google.com with SMTP id la4so13707591vcb.9 for ; Tue, 12 Aug 2014 09:07:52 -0700 (PDT) X-Received: by 10.221.5.137 with SMTP id og9mr4941421vcb.18.1407859672096; Tue, 12 Aug 2014 09:07:52 -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 tc5csp261087vcb; Tue, 12 Aug 2014 09:07:51 -0700 (PDT) X-Received: by 10.66.228.202 with SMTP id sk10mr1963595pac.150.1407859670147; Tue, 12 Aug 2014 09:07:50 -0700 (PDT) Received: from bombadil.infradead.org (bombadil.infradead.org. [2001:1868:205::9]) by mx.google.com with ESMTPS id vr7si16389528pab.71.2014.08.12.09.07.49 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 12 Aug 2014 09:07:50 -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 1XHEa3-0007DA-Oi; Tue, 12 Aug 2014 16:05:47 +0000 Received: from mail-la0-f54.google.com ([209.85.215.54]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1XHEZz-00079b-Go for linux-arm-kernel@lists.infradead.org; Tue, 12 Aug 2014 16:05:45 +0000 Received: by mail-la0-f54.google.com with SMTP id hz20so8213448lab.27 for ; Tue, 12 Aug 2014 09:05:19 -0700 (PDT) X-Received: by 10.152.206.9 with SMTP id lk9mr5204131lac.21.1407859519059; Tue, 12 Aug 2014 09:05:19 -0700 (PDT) Received: from localhost (188-178-240-98-static.dk.customer.tdc.net. [188.178.240.98]) by mx.google.com with ESMTPSA id pv6sm23528268lbb.32.2014.08.12.09.05.14 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Tue, 12 Aug 2014 09:05:18 -0700 (PDT) Date: Tue, 12 Aug 2014 18:05:21 +0200 From: Christoffer Dall To: Joel Schopp Subject: Re: [PATCH v4] arm64: fix VTTBR_BADDR_MASK Message-ID: <20140812160521.GO10550@cbox> References: <20140811203823.2828.36074.stgit@joelaarch64.amd.com> MIME-Version: 1.0 In-Reply-To: <20140811203823.2828.36074.stgit@joelaarch64.amd.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140812_090543_968766_9470A358 X-CRM114-Status: GOOD ( 39.80 ) X-Spam-Score: -0.7 (/) X-Spam-Report: SpamAssassin version 3.4.0 on bombadil.infradead.org summary: Content analysis details: (-0.7 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [209.85.215.54 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -0.0 RCVD_IN_MSPIKE_H3 RBL: Good reputation (+3) [209.85.215.54 listed in wl.mailspike.net] -0.0 RCVD_IN_MSPIKE_WL Mailspike good senders Cc: jungseoklee85@gmail.com, kvm@vger.kernel.org, Jungseok Lee , Sungjinn Chung , kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org 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: christoffer.dall@linaro.org 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.178 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 Content-Disposition: inline On Mon, Aug 11, 2014 at 03:38:23PM -0500, Joel Schopp wrote: > 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 this is still wrong, as I pointed out, it should be 21 <= T0SZ <= 30 > + * 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. > + */ nit: why is this block indented one level? > + > +#ifdef CONFIG_ARM64_64K_PAGES > +static inline int t0sz_to_vttbr_x(int t0sz){ > + if (t0sz < 16 || t0sz > 24) { How are you getting at this? The comment above is now almost useless, the whole point of listing the options with the various levels of translation tables given a page size is to show how we get to these limits. I think what you mean here, is: if (t0sz < 18 || t0sz > 34) { > + 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) { And here: if (t0sz < 21 || t0sz > 33) > + kvm_err("Cannot support %d-bit address space\n", 64 - t0sz); > + return -EINVAL; > + } > + return 37 - t0sz; > +} > +#endif I'd really much more like to see these two with the comment in arch/arm64/include/asm/kvm_mmu.h as that is the scheme we've used for all the other KVM code. > + > + > +/** > + * 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 nit: drop second 'first' (sorry, this is a result of my fist review) > + * with consideration of both granule size and the level of translation tables. the granule... > + */ > +#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; wrong indentation > + > + 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 I actually do think it's more consistent if we move this to the header files as well. But to make sure our allocation is correct and reuse some of this code, how about we fefactor it to be kvm_get_phys_addr_shift() instead? See my example below which should be blended into this patch. > /** > * 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); > + I think we should introduce a nice run-time check along with this in kvm_alloc_stage2_pgd, see below. > + 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 > So I'm thinking that we should have something like this (completely untested and not-even-compile-tested-shoot-me-now) as part of this patch. Apologies for not mentioning this in the first round of review: diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h index 5cc0b0f..5cf7aa5 100644 --- a/arch/arm/include/asm/kvm_mmu.h +++ b/arch/arm/include/asm/kvm_mmu.h @@ -178,6 +178,11 @@ static inline void coherent_cache_guest_page(struct kvm_vcpu *vcpu, hva_t hva, void stage2_flush_vm(struct kvm *kvm); +static inline int kvm_get_phys_addr_shift(void) +{ + return KVM_PHYS_SHIFT; +} + #endif /* !__ASSEMBLY__ */ #endif /* __ARM_KVM_MMU_H__ */ diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index 16e7994..70f0f02 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c @@ -521,6 +521,7 @@ int create_hyp_io_mappings(void *from, void *to, phys_addr_t phys_addr) */ int kvm_alloc_stage2_pgd(struct kvm *kvm) { + unsigned int s2_pgds, s2_pgd_order; pgd_t *pgd; if (kvm->arch.pgd != NULL) { @@ -528,10 +529,18 @@ int kvm_alloc_stage2_pgd(struct kvm *kvm) return -EINVAL; } - pgd = (pgd_t *)__get_free_pages(GFP_KERNEL, S2_PGD_ORDER); + s2_pgds = (1 << (kvm_get_phys_addr_shift() - PGDIR_SHIFT)); + s2_pgd_order = get_order(s2_pgds * sizeof(pgd_t)); + + pgd = (pgd_t *)__get_free_pages(GFP_KERNEL, s2_pgd_order); if (!pgd) return -ENOMEM; + if ((unsigned long)pgd & ~vttbr_baddr_mask) { + kvm_err("Stage-2 pgd not correctly aligned: %p\n", pgd); + return -EFAULT; + } + memset(pgd, 0, PTRS_PER_S2_PGD * sizeof(pgd_t)); kvm_clean_pgd(pgd); kvm->arch.pgd = pgd; diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h index 8e138c7..4341806 100644 --- a/arch/arm64/include/asm/kvm_mmu.h +++ b/arch/arm64/include/asm/kvm_mmu.h @@ -167,5 +167,23 @@ static inline void coherent_cache_guest_page(struct kvm_vcpu *vcpu, hva_t hva, void stage2_flush_vm(struct kvm *kvm); + +static inline int kvm_get_phys_addr_shift(void) +{ + pa_range = read_cpuid(ID_AA64MMFR0_EL1) & 0xf; + + switch (pa_range) { + case 0: return 32; + case 1: return 36; + case 2: return 40; + case 3: return 42; + case 4: return 44; + case 5: return 48; + default: + BUG(); + return 0; + } +} + #endif /* __ASSEMBLY__ */ #endif /* __ARM64_KVM_MMU_H__ */