From patchwork Mon Aug 22 15:27:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 599192 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:4388:0:0:0:0 with SMTP id w8csp1879997mae; Mon, 22 Aug 2022 11:38:59 -0700 (PDT) X-Google-Smtp-Source: AA6agR5Oz3sUlRJPE8p/L8JMRME/U/1V7DDA50HetVH8UA3sKruzeikA5gLYm4xdao62t6HbSXQM X-Received: by 2002:a05:6214:c6c:b0:496:8e7:a93b with SMTP id t12-20020a0562140c6c00b0049608e7a93bmr17439452qvj.97.1661193539455; Mon, 22 Aug 2022 11:38:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1661193539; cv=none; d=google.com; s=arc-20160816; b=jM7YS9FRGL1MzDeHXnIpYVW/qjeotPWDa8XP/cgx69Z4WM3Rlw2ox9BbvtGehQzBxw SAfaIeIBZJZCcUSygsRZr6nKWjrPOiMSLyunByuBny9praX7JuY8xQYx42Hep7SzGN+A 1jF3V3o0pU99v/llh9vnnW4bnNmgjI9yIHIP6DL3UU0tFGNgSRI3/2QaWCL02PKrxBbU UwVKIrbMv4QZM/bBS/zQJUT02RccHH8y1tmVY1I3bxQ5noniwFDyibEkdUwVPxIx2EGs Gum8BXTZ31l7dFx6HaOZL+FIm7wWqAvztK3bESeR52Be+ngCjkXdTM5czQ4GpjxouuoD 1PMA== 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:cc:to :from:dkim-signature; bh=ytgICZSLAKF7RSSydO7buGS+w8FoXAg2T8FlAnkcjhg=; b=pgNvGTEi6rIUj1KB67+mKpV0oP1/zmyJx/ZS8Ow3kAFbb+a63uyLZe3kvTvNKGBYZb z2FaqzQ9Kfaam50BSW/L9HK3UJbDfWaxW6w6JhoAaBq48k9GVItFsC0vsZE5/DCVhCJc JcTA+MdWR3AYJH4R/OCs8yXX/zfPG+0/dN72GjbsiL4mgFA/Un7UbOytYicC+8E9BAMG UVKYFu5Aj0XLVRyce/3w5faFbgcrwhfS4GVBysbSfrtdsphayb3p0yHflzjnsx11PhBX nqjc3Xam8tRNGYGxBK8kwmBuFr5TUAuj5IKoTQrquIdlDApFuRrqpO4ETw+4EiTeMGlg oI5Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="E0Hf//ze"; 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 15-20020a37060f000000b006bb9d4ecafasi4097895qkg.74.2022.08.22.11.38.59 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Mon, 22 Aug 2022 11:38:59 -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="E0Hf//ze"; 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]:49842 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oQCK9-0004DW-8e for patch@linaro.org; Mon, 22 Aug 2022 14:38:57 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39446) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oQ9PE-0004yV-Co for qemu-devel@nongnu.org; Mon, 22 Aug 2022 11:32:00 -0400 Received: from mail-pj1-x1031.google.com ([2607:f8b0:4864:20::1031]:55830) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oQ9P0-0001hn-6O for qemu-devel@nongnu.org; Mon, 22 Aug 2022 11:32:00 -0400 Received: by mail-pj1-x1031.google.com with SMTP id pm13so2434936pjb.5 for ; Mon, 22 Aug 2022 08:31:37 -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; bh=ytgICZSLAKF7RSSydO7buGS+w8FoXAg2T8FlAnkcjhg=; b=E0Hf//zePpG0BPKGWJamzh4q+uszOju1qBe/XZyGS3bfXWC7c2oM5jF7dPXyj6nzhN P9O1iNU7cRO7rBH0DvoF5wd90noO7+u9sOhzo/vcV45bJfUZSD21BUKuu6Si0H1rLOXG VQO60v/V1cMHPTqD9EaWJN9pmswzinkc5Ta+D3CgfeTqH9Ra6ZbCpM5iPKCQTstLDRv5 798EeNH3865CZlakXGr8iUswJ/9Lw1aLa61tUa9xZIJvnj5wsEDla02BSbrz8rPT4rKR YKb8cVLTG/x2P5EPptMewWjnvMidBToYKRGd0tlaxJXwGGdwf8ijCox3R2DuGdx/REei gkSg== 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; bh=ytgICZSLAKF7RSSydO7buGS+w8FoXAg2T8FlAnkcjhg=; b=QFDw3mrFReGVIW0OsM+zWyaprTjE1tTd919+zfcHJX1P7f0mbdWiraz1Vz7tpGosHQ Raww62kUHWbdROkzy8EhlBql42fNBJ1mhXcJaJcDyu2Ui7H2FhRQA0gzszPVOpQ0N/Zq JDcz3B1J+D2PxNGc69CXCxmJGTlkhyUd7NVqkEGRVHYRrVBbmuo9QEO/n8+A0EwB69jD Zi3AWp+wa+3r3alhpn4HtBJgYIycpTYdloSZcRCpNgXdp1x6c07hvqkDC8LpiBO6U11K vpbe8Lkdr0jvwhfJGAa0UnKVbouOetQZMj1GmWZlb+cSHsPx5tvMpPMo9Ctpzap2/eFf qAtQ== X-Gm-Message-State: ACgBeo34vy727VvcBNxG23XKdyvuWUzrK5wWl3Y5gulNnaCPclPjuUXv cbNtRCOsYME6tqmFxTRHrubQCnwxJd9T4A== X-Received: by 2002:a17:903:2049:b0:172:eb95:c61e with SMTP id q9-20020a170903204900b00172eb95c61emr5447482pla.74.1661182296209; Mon, 22 Aug 2022 08:31:36 -0700 (PDT) Received: from stoup.. ([71.212.157.236]) by smtp.gmail.com with ESMTPSA id i6-20020a17090a3d8600b001f262f6f717sm10353835pjc.3.2022.08.22.08.31.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Aug 2022 08:31:35 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Cc: qemu-arm@nongnu.org Subject: [PATCH v2 62/66] target/arm: Remove loop from get_phys_addr_lpae Date: Mon, 22 Aug 2022 08:27:37 -0700 Message-Id: <20220822152741.1617527-63-richard.henderson@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220822152741.1617527-1-richard.henderson@linaro.org> References: <20220822152741.1617527-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1031; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x1031.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, T_SCC_BODY_TEXT_LINE=-0.01, T_SPF_TEMPERROR=0.01 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: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" 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. Signed-off-by: Richard Henderson --- target/arm/ptw.c | 176 +++++++++++++++++++++++------------------------ 1 file changed, 88 insertions(+), 88 deletions(-) diff --git a/target/arm/ptw.c b/target/arm/ptw.c index 9ccbc9bd2b..d0981d94d1 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -1032,6 +1032,9 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address, uint64_t descaddrmask; bool aarch64 = arm_el_is_aa64(env, el); bool guarded = false; + S1TranslateResult s1; + uint64_t descriptor; + bool nstable; /* TODO: This code does not support shareability levels. */ if (aarch64) { @@ -1230,96 +1233,93 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address, * bits at each step. */ tableattrs = is_secure ? 0 : (1 << 4); - for (;;) { - S1TranslateResult s1; - uint64_t descriptor; - bool nstable; - descaddr |= (address >> (stride * (4 - level))) & indexmask; - descaddr &= ~7ULL; - nstable = extract32(tableattrs, 4, 1); - if (!S1_ptw_translate(env, mmu_idx, ptw_idx, descaddr, - !nstable, &s1, fi)) { - goto do_fault; - } - descriptor = arm_ldq_ptw(env, &s1, 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; - 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 (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) { - /* 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; + next_level: + descaddr |= (address >> (stride * (4 - level))) & indexmask; + descaddr &= ~7ULL; + nstable = extract32(tableattrs, 4, 1); + if (!S1_ptw_translate(env, mmu_idx, ptw_idx, descaddr, + !nstable, &s1, fi)) { + goto do_fault; } + descriptor = arm_ldq_ptw(env, &s1, 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 &= ~(page_size - 1); + descaddr |= (address & (page_size - 1)); + /* Extract attributes from the descriptor */ + attrs = extract64(descriptor, 2, 10) + | (extract64(descriptor, 52, 12) << 10); + + if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) { + /* 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.