From patchwork Wed Mar 2 20:52:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 547537 Delivered-To: patch@linaro.org Received: by 2002:ac0:f585:0:0:0:0:0 with SMTP id s5csp43263imq; Wed, 2 Mar 2022 13:17:39 -0800 (PST) X-Google-Smtp-Source: ABdhPJyMfP5gY1G8ijZx5TyE86N1OYadNJVn4XJk1jfZZkCFyEU2ONJgBxOsLcvygIFnd333LHgm X-Received: by 2002:a67:f7d6:0:b0:31c:1ffc:8a91 with SMTP id a22-20020a67f7d6000000b0031c1ffc8a91mr14354468vsp.66.1646255859394; Wed, 02 Mar 2022 13:17:39 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1646255859; cv=none; d=google.com; s=arc-20160816; b=Pz/sWnzhA1ii70bXGwlaPwE1FNLCmyazcqdLmaeZUj3dPmPxR3inqlG+84jKGN7D8P UkiWXIFGNXOTlnrMjAQ3KChTAqIadE6mkhLmDiBBeMEe2Yib7OMQE9vCRYnrjlO8lmI/ 1XGLTixC7OOXGa5vdWJY1o65r2bQU/fmccnesb1M9cZf4BQbqSyR2GPVwl8GrakaWsOO A87YXTIw1QsvrAw8K69BugSR1/TnTHbSGzy54zHr+7jgINi4jcZGgLhg6uUR9/0S9pDO 8X9c+aoVmpysb9IrTBX9JF0aUgCfSwEM8Ve9aBmF5ErjzbuEmzk7R4dVsQ/RRw/C/HcL af+A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=Ktp5JrOUqDuz2WM1tRsh4muMal7IsNgv1POHAYYvYgA=; b=OLQlvsvY+7PK9whuLrWzQ0d4+4l0Fc0irXFtAPHpRFtzSq/1vxPF/EnhgHXBkSaQtL +g35uMfLE2cE/zvQ/cyiapRDu7ycHdwB/IpZganacQLO8GEvlOTwhmYheVZMoSZL5PF8 +wl858TNjWKJ92OcZkHrC1xClk/LOEVYNvwmNlJAjjAvUbqaqXGCY7pM1Av6NOKp3n0S P2x17HFQ273qvd3NSo0Ci6iLSFyztEwQtJo/XxUAx4YydBq+2WZ6Gpq5uvz1uorZibWi 92Ac8Oj3H1MN6rB7DYaomBcUAhD5XrQR4n4KPOJL3OMociHnBIfFfYRpIknH0Vjj7Tt2 G6cA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="lYkS/cYo"; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id y17-20020a67d211000000b0031b8a4d28f4si9282vsi.438.2022.03.02.13.17.39 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 02 Mar 2022 13:17:39 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="lYkS/cYo"; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:34762 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nPWLq-00039F-TQ for patch@linaro.org; Wed, 02 Mar 2022 16:17:38 -0500 Received: from eggs.gnu.org ([209.51.188.92]:43478) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nPVxo-0005r9-4M for qemu-devel@nongnu.org; Wed, 02 Mar 2022 15:52:49 -0500 Received: from [2a00:1450:4864:20::42d] (port=44922 helo=mail-wr1-x42d.google.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1nPVxm-00089h-CO for qemu-devel@nongnu.org; Wed, 02 Mar 2022 15:52:47 -0500 Received: by mail-wr1-x42d.google.com with SMTP id u1so4654805wrg.11 for ; Wed, 02 Mar 2022 12:52:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=Ktp5JrOUqDuz2WM1tRsh4muMal7IsNgv1POHAYYvYgA=; b=lYkS/cYo41UJ+5y8cc62xCe5xnK62mpDsv5QF3v27Ig/V75+sM/WNnC7ozKkpemUOA pJ8Qcdrxs5YlPZxMqHmGlYv0Y1MA6gsfTtLqTGhgvjhLwqjMGFKh9nr+Q9wr+xmQR1W5 P2xL5oYFTmdkFXXZaeJr9CU9Yg2yqJxPy2gotbQswWcdKqZStu3qxZGtbe1TGa1ARc30 E1GCxxN4YcyJeDpwrm0xDEthJNou+uQhBKKxyO01fQ8zx+bCadu4LJ3Io/GF2KV6SCeY pysv0Zx/e4sYRe/Oj6cbWxVY6BmBFeaLunRA7iewO+q0bl2FDni5OfsvB3KZ4nJhboM0 oTHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Ktp5JrOUqDuz2WM1tRsh4muMal7IsNgv1POHAYYvYgA=; b=nDCRJaP0mK5hNbQ7s3UjJ9OEDOKUqK0d1I6LlSU4nlgLlEafFHgbN7NOcyOSALe+tE /jHdJ+LiPlTzlKZF05H5QEaqKTbOf34q3buNFn/zoz/IIR38CWCbdmr9Zyw4E4Ql33au kIsrw23V7B+csVXeWUVnx06EquxdkZFk+R5gSPTfsoj1Gc2AT+ZGyntZCtkSO4T0aoyF fT7sPAsY+RxSY4dvMDB4UWx5zlDW7P3BN20LA0VPZWUJ/JmNbOCaz73pn+mOy7tyVQ4R kaQfnF9NZvTZw6Rwr5lA8+iKJPDinuxsqyScX0YzJUtiwTp3rsfCHOe7ISPYfG4l2yl4 L/zA== X-Gm-Message-State: AOAM5331XiLP/fu9PmCACe32NGdNAomtFCfD2U/Sq4c30qPyhnWET3Yx AnqGSny0JmQ98wmtq47VZbGz4AX0yiLb3w== X-Received: by 2002:a5d:6d0a:0:b0:1ef:f01c:9e with SMTP id e10-20020a5d6d0a000000b001eff01c009emr10327432wrq.486.1646254364998; Wed, 02 Mar 2022 12:52:44 -0800 (PST) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by smtp.gmail.com with ESMTPSA id x13-20020adfec0d000000b001e31279cc38sm90801wrn.11.2022.03.02.12.52.44 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Mar 2022 12:52:44 -0800 (PST) From: Peter Maydell To: qemu-devel@nongnu.org Subject: [PULL 14/26] target/arm: Honor TCR_ELx.{I}PS Date: Wed, 2 Mar 2022 20:52:18 +0000 Message-Id: <20220302205230.2122390-15-peter.maydell@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220302205230.2122390-1-peter.maydell@linaro.org> References: <20220302205230.2122390-1-peter.maydell@linaro.org> MIME-Version: 1.0 X-Host-Lookup-Failed: Reverse DNS lookup failed for 2a00:1450:4864:20::42d (failed) Received-SPF: pass client-ip=2a00:1450:4864:20::42d; envelope-from=peter.maydell@linaro.org; helo=mail-wr1-x42d.google.com X-Spam_score_int: -6 X-Spam_score: -0.7 X-Spam_bar: / X-Spam_report: (-0.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, PDS_HP_HELO_NORDNS=0.659, RCVD_IN_DNSWL_NONE=-0.0001, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson This field controls the output (intermediate) physical address size of the translation process. V8 requires to raise an AddressSize fault if the page tables are programmed incorrectly, such that any intermediate descriptor address, or the final translated address, is out of range. Add a PS field to ARMVAParameters, and properly compute outputsize in get_phys_addr_lpae. Test the descaddr as extracted from TTBR and from page table entries. Restrict descaddrmask so that we won't raise the fault for v7. Reviewed-by: Peter Maydell Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson Message-id: 20220301215958.157011-8-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/internals.h | 1 + target/arm/helper.c | 72 ++++++++++++++++++++++++++++++++---------- 2 files changed, 57 insertions(+), 16 deletions(-) diff --git a/target/arm/internals.h b/target/arm/internals.h index fefd1fb8d88..3d3d41ba2b7 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -1032,6 +1032,7 @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id) */ typedef struct ARMVAParameters { unsigned tsz : 8; + unsigned ps : 3; unsigned select : 1; bool tbi : 1; bool epd : 1; diff --git a/target/arm/helper.c b/target/arm/helper.c index 675aec4bf30..c002100979f 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -11149,17 +11149,19 @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs) } #endif /* !CONFIG_USER_ONLY */ +/* This mapping is common between ID_AA64MMFR0.PARANGE and TCR_ELx.{I}PS. */ +static const uint8_t pamax_map[] = { + [0] = 32, + [1] = 36, + [2] = 40, + [3] = 42, + [4] = 44, + [5] = 48, +}; + /* The cpu-specific constant value of PAMax; also used by hw/arm/virt. */ unsigned int arm_pamax(ARMCPU *cpu) { - static const unsigned int pamax_map[] = { - [0] = 32, - [1] = 36, - [2] = 40, - [3] = 42, - [4] = 44, - [5] = 48, - }; unsigned int parange = FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE); @@ -11210,7 +11212,7 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va, { uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr; bool epd, hpd, using16k, using64k, tsz_oob; - int select, tsz, tbi, max_tsz, min_tsz; + int select, tsz, tbi, max_tsz, min_tsz, ps; if (!regime_has_2_ranges(mmu_idx)) { select = 0; @@ -11224,6 +11226,7 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va, hpd = extract32(tcr, 24, 1); } epd = false; + ps = extract32(tcr, 16, 3); } else { /* * Bit 55 is always between the two regions, and is canonical for @@ -11244,6 +11247,7 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va, epd = extract32(tcr, 23, 1); hpd = extract64(tcr, 42, 1); } + ps = extract64(tcr, 32, 3); } if (cpu_isar_feature(aa64_st, env_archcpu(env))) { @@ -11272,6 +11276,7 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va, return (ARMVAParameters) { .tsz = tsz, + .ps = ps, .select = select, .tbi = tbi, .epd = epd, @@ -11399,6 +11404,8 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address, /* TODO: This code does not support shareability levels. */ if (aarch64) { + int ps; + param = aa64_va_parameters(env, address, mmu_idx, access_type != MMU_INST_FETCH); level = 0; @@ -11419,7 +11426,16 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address, addrsize = 64 - 8 * param.tbi; inputsize = 64 - param.tsz; - outputsize = arm_pamax(cpu); + + /* + * Bound PS by PARANGE to find the effective output address size. + * ID_AA64MMFR0 is a read-only register so values outside of the + * supported mappings can be considered an implementation error. + */ + ps = FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE); + ps = MIN(ps, param.ps); + assert(ps < ARRAY_SIZE(pamax_map)); + outputsize = pamax_map[ps]; } else { param = aa32_va_parameters(env, address, mmu_idx); level = 1; @@ -11523,19 +11539,38 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address, /* Now we can extract the actual base address from the TTBR */ descaddr = extract64(ttbr, 0, 48); + + /* + * If the base address is out of range, raise AddressSizeFault. + * In the pseudocode, this is !IsZero(baseregister<47:outputsize>), + * but we've just cleared the bits above 47, so simplify the test. + */ + if (descaddr >> outputsize) { + level = 0; + fault_type = ARMFault_AddressSize; + goto do_fault; + } + /* * We rely on this masking to clear the RES0 bits at the bottom of the TTBR * and also to mask out CnP (bit 0) which could validly be non-zero. */ descaddr &= ~indexmask; - /* The address field in the descriptor goes up to bit 39 for ARMv7 - * but up to bit 47 for ARMv8, but we use the descaddrmask - * up to bit 39 for AArch32, because we don't need other bits in that case - * to construct next descriptor address (anyway they should be all zeroes). + /* + * For AArch32, the address field in the descriptor goes up to bit 39 + * for both v7 and v8. However, for v8 the SBZ bits [47:40] must be 0 + * or an AddressSize fault is raised. So for v8 we extract those SBZ + * bits as part of the address, which will be checked via outputsize. + * For AArch64, the address field always goes up to bit 47 (with extra + * bits for FEAT_LPA placed elsewhere). AArch64 implies v8. */ - descaddrmask = ((1ull << (aarch64 ? 48 : 40)) - 1) & - ~indexmask_grainsize; + if (arm_feature(env, ARM_FEATURE_V8)) { + descaddrmask = MAKE_64BIT_MASK(0, 48); + } else { + descaddrmask = MAKE_64BIT_MASK(0, 40); + } + descaddrmask &= ~indexmask_grainsize; /* Secure accesses start with the page table in secure memory and * can be downgraded to non-secure at any step. Non-secure accesses @@ -11560,7 +11595,12 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address, /* Invalid, or the Reserved level 3 encoding */ goto do_fault; } + descaddr = descriptor & descaddrmask; + if (descaddr >> outputsize) { + fault_type = ARMFault_AddressSize; + goto do_fault; + } if ((descriptor & 2) && (level < 3)) { /* Table entry. The top five bits are attributes which may