From patchwork Mon Oct 24 05:18:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 617852 Delivered-To: patch@linaro.org Received: by 2002:a17:522:c983:b0:460:3032:e3c4 with SMTP id kr3csp2524432pvb; Sun, 23 Oct 2022 23:39:22 -0700 (PDT) X-Google-Smtp-Source: AMsMyM5AjGcaLNTQUojRutmpKcTxuLJEEKu2CvdHHWnleXnFGT09+g1K/5+3UOQQmQHoscKB434t X-Received: by 2002:a05:6214:ac1:b0:4bb:67f6:930f with SMTP id g1-20020a0562140ac100b004bb67f6930fmr4969393qvi.79.1666593562814; Sun, 23 Oct 2022 23:39:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666593562; cv=none; d=google.com; s=arc-20160816; b=J4Z/d4cQUVWK4OLDh7GneJYrzbmbaeQOZhvUEYNJ/zRlMfbmu+904gK6ZFOUvCnKDD pPbh90Lut/RKRYjxEsTyt3pnaXCWru55mCSX9TaEwW7RdFg/hVodCoFFvmZsOMumWqZl DoZ+PWiJTkHflswKQtETq0ZmKj1m7PZxoWeVw4Tqfen/WhvSNFzL11FbyLVGQA5pjn16 9Gqo6rZvSIUh8g3sIaOKP/wTpQ5zWLsZEgDU3GMEknljQXKFeHhXd36u7PU4nVo3aL27 d3NKtpRsINl3wttIP9/9T/YHituN9/jmI+Rnws8PL+mQesFMqX1VsWTSwDo4lfwNtAvf nLdw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:sender: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:cc:to :from:dkim-signature; bh=/GiKSj2DI/fM8k5gjQPIZReGKnYnqJ3VPV7yF0e0HWE=; b=wy9DqY+xtKcP4e1d3yfto2njmzC6ys9biWjlEaEnc/CC5Jk+3EV1Kgm9koboPizQ4S eNeHSRyd2ea0YHC2kTFioMnVevURt+lt6aw5sPwfkPhNwvn8/HPAA0Vzk+8WSC60KNPf 1K/vVRc/YN2zh6DPQ421ONyeglj2qvuJFv3Fiiwu7FAEjBTvFT65AqLIafWZTTxdi6qQ vae4ev21ecatn/CB4FsaAiUVdRtWSclVQG/HoNndhr6bzbnxNEo2Hm850hN0iQMRZw1t 8fhMKPakbJImewNj/uqeDalzkLUiC7XCu1k1ehdb5VaL+vOmxehH6XyTHwK/eazYJDI8 qwfg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=QYO+VEO8; 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 fv25-20020a05622a4a1900b0039cc530c012si16700881qtb.21.2022.10.23.23.39.22 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Sun, 23 Oct 2022 23:39:22 -0700 (PDT) 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=QYO+VEO8; 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] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ompsq-0007Ts-Jr; Mon, 24 Oct 2022 01:20:20 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1omprt-0006cG-FM for qemu-devel@nongnu.org; Mon, 24 Oct 2022 01:19:21 -0400 Received: from mail-pf1-x430.google.com ([2607:f8b0:4864:20::430]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1omprq-0002NY-QM for qemu-devel@nongnu.org; Mon, 24 Oct 2022 01:19:20 -0400 Received: by mail-pf1-x430.google.com with SMTP id g16so2677445pfr.12 for ; Sun, 23 Oct 2022 22:19:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=/GiKSj2DI/fM8k5gjQPIZReGKnYnqJ3VPV7yF0e0HWE=; b=QYO+VEO8fbfNr2JY9OFpe90J6FHqGZOGl65keY3OMjec7Kobfrj9EJx3+MVvU42wmt zPsX+fL9OELfTIuFyzptmt8Mlrvyt4KPfMHOMKZ308SIxh6Q82k3wWkpq8G1Qf5CNzSR 3m4M81RESX9fbc9+vb0zoIt0QZs4pGeqylHDrQ3WDHawHNaiWo7rklKJ59a23u4boxhU oEvjFzdIWXh2zSixkHVsBFY2R9KJS/159ODxhHjg31FULWDPSrfE9Vdx75Z56rvunT90 2GfPx3g2ApA8NDj/IcdGspTgckgXsRmzLVILKQWrsUL3ob2s6ncoz0W8JruZ2IvyI4Nz 00SA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/GiKSj2DI/fM8k5gjQPIZReGKnYnqJ3VPV7yF0e0HWE=; b=UaYhuNRQs10aok2dMY7Xs5bkRzeaSaF0eFa1xHQN93KS8qbM+WGfbJxge2DjGqSY78 FEWa/1EHEwDiBsNyzj51HVhxWq6IV3861XjZVHu5ahf2uLFSHurbrds5D31pHpzXlBfp AxHEPti29gJw7triXTgadCVBEwzoxLzpf0F91cjPR2LIklDdUAT6IER2pdxNvfZSWf/p e2pVv1/VrHD2i0ph+byORSKUwnRHBKicQOXd30ScpdeuV2UQ9XgnNShqKVKtoXmPzvxe qKR5rd/F0MoQCkCP9/pO3io2Qcv/UpNwFKWavK4HlfT+6NeZe9zNEHQ4bS21FoAImamA UW+A== X-Gm-Message-State: ACrzQf2OE55/FNGbfGz4Cc7dt8HgvSpOrqZa1/oR1s8xPMyhe1vAJpC6 X3oPwKh7ZTCvZFLh5KnQAlNHF5N738FZZ/wP X-Received: by 2002:a63:3fce:0:b0:45a:2bab:6002 with SMTP id m197-20020a633fce000000b0045a2bab6002mr27214309pga.454.1666588757369; Sun, 23 Oct 2022 22:19:17 -0700 (PDT) Received: from stoup.. ([103.100.225.182]) by smtp.gmail.com with ESMTPSA id q12-20020a170902f34c00b00172951ddb12sm1895231ple.42.2022.10.23.22.19.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Oct 2022 22:19:16 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Cc: qemu-arm@nongnu.org, Peter Maydell Subject: [PATCH v6 07/14] target/arm: Remove loop from get_phys_addr_lpae Date: Mon, 24 Oct 2022 15:18:44 +1000 Message-Id: <20221024051851.3074715-8-richard.henderson@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221024051851.3074715-1-richard.henderson@linaro.org> References: <20221024051851.3074715-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::430; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x430.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham 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: , Sender: "Qemu-devel" Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org The unconditional loop was used both to iterate over levels and to control parsing of attributes. Use an explicit goto in both cases. While this appears less clean for iterating over levels, we will need to jump back into the middle of this loop for atomic updates, which is even uglier. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson --- target/arm/ptw.c | 192 +++++++++++++++++++++++------------------------ 1 file changed, 96 insertions(+), 96 deletions(-) diff --git a/target/arm/ptw.c b/target/arm/ptw.c index 36524b35ef..615471699e 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -1080,6 +1080,8 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, uint64_t descaddrmask; bool aarch64 = arm_el_is_aa64(env, el); bool guarded = false; + uint64_t descriptor; + bool nstable; /* TODO: This code does not support shareability levels. */ if (aarch64) { @@ -1272,106 +1274,104 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, * bits at each step. */ tableattrs = is_secure ? 0 : (1 << 4); - for (;;) { - uint64_t descriptor; - bool nstable; - - descaddr |= (address >> (stride * (4 - level))) & indexmask; - descaddr &= ~7ULL; - nstable = extract32(tableattrs, 4, 1); - if (!nstable) { - /* - * Stage2_S -> Stage2 or Phys_S -> Phys_NS - * Assert that the non-secure idx are even, and relative order. - */ - QEMU_BUILD_BUG_ON((ARMMMUIdx_Phys_NS & 1) != 0); - QEMU_BUILD_BUG_ON((ARMMMUIdx_Stage2 & 1) != 0); - QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_NS + 1 != ARMMMUIdx_Phys_S); - QEMU_BUILD_BUG_ON(ARMMMUIdx_Stage2 + 1 != ARMMMUIdx_Stage2_S); - ptw->in_ptw_idx &= ~1; - ptw->in_secure = false; - } - if (!S1_ptw_translate(env, ptw, descaddr, fi)) { - goto do_fault; - } - descriptor = arm_ldq_ptw(env, ptw, fi); - if (fi->type != ARMFault_None) { - goto do_fault; - } - - if (!(descriptor & 1) || - (!(descriptor & 2) && (level == 3))) { - /* Invalid, or the Reserved level 3 encoding */ - goto do_fault; - } - - descaddr = descriptor & descaddrmask; + next_level: + descaddr |= (address >> (stride * (4 - level))) & indexmask; + descaddr &= ~7ULL; + nstable = extract32(tableattrs, 4, 1); + if (!nstable) { /* - * For FEAT_LPA and PS=6, bits [51:48] of descaddr are in [15:12] - * of descriptor. For FEAT_LPA2 and effective DS, bits [51:50] of - * descaddr are in [9:8]. Otherwise, if descaddr is out of range, - * raise AddressSizeFault. + * Stage2_S -> Stage2 or Phys_S -> Phys_NS + * Assert that the non-secure idx are even, and relative order. */ - if (outputsize > 48) { - if (param.ds) { - descaddr |= extract64(descriptor, 8, 2) << 50; - } else { - descaddr |= extract64(descriptor, 12, 4) << 48; - } - } else 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 - * propagate down through lower levels of the table (and - * which are all arranged so that 0 means "no effect", so - * we can gather them up by ORing in the bits at each level). - */ - tableattrs |= extract64(descriptor, 59, 5); - level++; - indexmask = indexmask_grainsize; - continue; - } - /* - * Block entry at level 1 or 2, or page entry at level 3. - * These are basically the same thing, although the number - * of bits we pull in from the vaddr varies. Note that although - * descaddrmask masks enough of the low bits of the descriptor - * to give a correct page or table address, the address field - * in a block descriptor is smaller; so we need to explicitly - * clear the lower bits here before ORing in the low vaddr bits. - */ - page_size = (1ULL << ((stride * (4 - level)) + 3)); - descaddr &= ~(hwaddr)(page_size - 1); - descaddr |= (address & (page_size - 1)); - /* Extract attributes from the descriptor */ - attrs = extract64(descriptor, 2, 10) - | (extract64(descriptor, 52, 12) << 10); - - if (regime_is_stage2(mmu_idx)) { - /* Stage 2 table descriptors do not include any attribute fields */ - break; - } - /* Merge in attributes from table descriptors */ - attrs |= nstable << 3; /* NS */ - guarded = extract64(descriptor, 50, 1); /* GP */ - if (param.hpd) { - /* HPD disables all the table attributes except NSTable. */ - break; - } - attrs |= extract32(tableattrs, 0, 2) << 11; /* XN, PXN */ - /* - * The sense of AP[1] vs APTable[0] is reversed, as APTable[0] == 1 - * means "force PL1 access only", which means forcing AP[1] to 0. - */ - attrs &= ~(extract32(tableattrs, 2, 1) << 4); /* !APT[0] => AP[1] */ - attrs |= extract32(tableattrs, 3, 1) << 5; /* APT[1] => AP[2] */ - break; + QEMU_BUILD_BUG_ON((ARMMMUIdx_Phys_NS & 1) != 0); + QEMU_BUILD_BUG_ON((ARMMMUIdx_Stage2 & 1) != 0); + QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_NS + 1 != ARMMMUIdx_Phys_S); + QEMU_BUILD_BUG_ON(ARMMMUIdx_Stage2 + 1 != ARMMMUIdx_Stage2_S); + ptw->in_ptw_idx &= ~1; + ptw->in_secure = false; } + if (!S1_ptw_translate(env, ptw, descaddr, fi)) { + goto do_fault; + } + descriptor = arm_ldq_ptw(env, ptw, fi); + if (fi->type != ARMFault_None) { + goto do_fault; + } + + if (!(descriptor & 1) || (!(descriptor & 2) && (level == 3))) { + /* Invalid, or the Reserved level 3 encoding */ + goto do_fault; + } + + descaddr = descriptor & descaddrmask; + + /* + * For FEAT_LPA and PS=6, bits [51:48] of descaddr are in [15:12] + * of descriptor. For FEAT_LPA2 and effective DS, bits [51:50] of + * descaddr are in [9:8]. Otherwise, if descaddr is out of range, + * raise AddressSizeFault. + */ + if (outputsize > 48) { + if (param.ds) { + descaddr |= extract64(descriptor, 8, 2) << 50; + } else { + descaddr |= extract64(descriptor, 12, 4) << 48; + } + } else 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 + * propagate down through lower levels of the table (and + * which are all arranged so that 0 means "no effect", so + * we can gather them up by ORing in the bits at each level). + */ + tableattrs |= extract64(descriptor, 59, 5); + level++; + indexmask = indexmask_grainsize; + goto next_level; + } + + /* + * Block entry at level 1 or 2, or page entry at level 3. + * These are basically the same thing, although the number + * of bits we pull in from the vaddr varies. Note that although + * descaddrmask masks enough of the low bits of the descriptor + * to give a correct page or table address, the address field + * in a block descriptor is smaller; so we need to explicitly + * clear the lower bits here before ORing in the low vaddr bits. + */ + page_size = (1ULL << ((stride * (4 - level)) + 3)); + descaddr &= ~(hwaddr)(page_size - 1); + descaddr |= (address & (page_size - 1)); + /* Extract attributes from the descriptor */ + attrs = extract64(descriptor, 2, 10) + | (extract64(descriptor, 52, 12) << 10); + + if (regime_is_stage2(mmu_idx)) { + /* Stage 2 table descriptors do not include any attribute fields */ + goto skip_attrs; + } + /* Merge in attributes from table descriptors */ + attrs |= nstable << 3; /* NS */ + guarded = extract64(descriptor, 50, 1); /* GP */ + if (param.hpd) { + /* HPD disables all the table attributes except NSTable. */ + goto skip_attrs; + } + attrs |= extract32(tableattrs, 0, 2) << 11; /* XN, PXN */ + /* + * The sense of AP[1] vs APTable[0] is reversed, as APTable[0] == 1 + * means "force PL1 access only", which means forcing AP[1] to 0. + */ + attrs &= ~(extract32(tableattrs, 2, 1) << 4); /* !APT[0] => AP[1] */ + attrs |= extract32(tableattrs, 3, 1) << 5; /* APT[1] => AP[2] */ + skip_attrs: + /* * Here descaddr is the final physical address, and attributes * are all in attrs.