From patchwork Thu Oct 20 22:35:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 616810 Delivered-To: patch@linaro.org Received: by 2002:a17:522:c983:b0:460:3032:e3c4 with SMTP id kr3csp578450pvb; Thu, 20 Oct 2022 15:52:45 -0700 (PDT) X-Google-Smtp-Source: AMsMyM4FiSZGUqm2ewqN4+mkXY6H34SQh4c/By2gPZP5383Vgt6eepcybe/1UI1XxdRUJ3V+Ctfn X-Received: by 2002:a05:6214:27e1:b0:4b2:cbc8:8d8c with SMTP id jt1-20020a05621427e100b004b2cbc88d8cmr13496395qvb.110.1666306365452; Thu, 20 Oct 2022 15:52:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666306365; cv=none; d=google.com; s=arc-20160816; b=V+Jk/kTevCI0copb6MqDJrm+BFINp9KOxArSUHr1yqEA4/Zf/4IlWkZKn4hy+2FTPC zTe7BaTNsRPxeHkkTctciO6foYHHaiyJ5SwED4NlrGEDtF7K3DnqXBFKs9BOhEwayIoU JtrDzPp+sEcIt13PncxLDvSufmq6mJjF8PYJYfPcI9oHIdEmO4HM6RRWhEsS87EcywOa Q9Rsad1uMUVHrYTX3RVZP7IzrbMankhUpn1zN9KZPDB4SkhZNE+dEMAK8mRPWEk2nJap XoWIR3gUKJxZLIQalyH6uOPWSStJWhlroNu6coJ4oK/1BTFTcbCvpqov8P+pOuYMQQ7d JTmQ== 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=/GiKSj2DI/fM8k5gjQPIZReGKnYnqJ3VPV7yF0e0HWE=; b=Ns/A1b/eAShG8pNqMoKysriPYm+wjdfh0Nifdsf8MvbE8mtsaD+DXOmW6osBtasGmv ZjYZQWEXNP3qeDUhpMTRaJ0ehAM70/4hHN2/9498XcKr5NT9DteMkHX8O/AD4xiBV0Be yM4XJZa3LZgxmRpdBtSGt7bv1K3rLQgkXacouf0nB/jdAHzyaix+DKvVzzGdRfeu6XzT x+NRCbTOCeBISBuMTuG5ADJQOVZpztBewKQ94pXHh6APprlr7T0EGbBwHI5mNWUQnCH3 91d929AXrm4WOOuHfNl2vOtdO6vAVEt4C0ksdgSJrRh4p+RA55HGHFrsjFTSs8URFeXq WUGw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=DKK3gWdF; 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 t18-20020a05620a451200b006eedc0101c9si9334098qkp.142.2022.10.20.15.52.45 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 20 Oct 2022 15:52:45 -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=DKK3gWdF; 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=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oleP6-0008ID-Rh for patch@linaro.org; Thu, 20 Oct 2022 18:52:44 -0400 Received: from [::1] (helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ole9q-0006wg-EX for patch@linaro.org; Thu, 20 Oct 2022 18:36:58 -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 1ole9l-0006op-Bx for qemu-devel@nongnu.org; Thu, 20 Oct 2022 18:36:53 -0400 Received: from mail-pj1-x102d.google.com ([2607:f8b0:4864:20::102d]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1ole9j-00012R-CD for qemu-devel@nongnu.org; Thu, 20 Oct 2022 18:36:53 -0400 Received: by mail-pj1-x102d.google.com with SMTP id ez6so767845pjb.1 for ; Thu, 20 Oct 2022 15:36:50 -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=DKK3gWdF+U1NMsoHizqjrnyvKi5MXXBEUCBLJjVOtuIwfMXwLZu1b3MtQdTYjWbqVB zGpqu2RutpjjF5jSgJluCsrhVudnM3QBXlQUYPkr51pPcn3fxlF77MCZ/jAdmrlcGTgu 6EBKDkSouqW0h6OaRUzVzq2M0IMZbgcfyVnr/yxs6/vZ1u/O22FSTSUqf6xyXGkESQDE f8GzAG8oSllQXvMpz6IE+8UIUejXjB9GprymkN26hg8YnL9AS3znYkg5gUmGk+FANDr6 aX3/iol0e7F8fYFm0VR4qdC9zGsgjcADVifwo+g2EUP9pALvcTJHiJTWq1Hsai/NNeLd DvOg== 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=bPOk3N3b4ecm/UvKNab/hPXDGIFRvYYO8C3oYmB0WRFFwCBzObAtpjKdmagTbOiWeh Vt/lJ4BQ7U+lqGJoLv/iscB0dGu5Sj9uZYUz176M1mRhvZ7Ato2ZLo00WRmG04kXLO+9 x/pldD03pBM0FRU2Rq4fFMjlADFyUAe5ATrbyoF0rueZ6Ev7FU+yzM80klU2YQ2pogdh uRWFVYLoCdyUmdqcmoFqDeKl+jNKv5npywl2rCpMEI+duJMHdUF0SOe6Ixa/J9BfeE7N jpXKSqRMTkbSBD3/mSlGNB2HmbqylRbAeYpuoUEI1zUd4vzo7xQ7EcgdHwvoN3aNdVb6 FOEw== X-Gm-Message-State: ACrzQf1QvnMozgJGSpu41zVtUYwVAnpoazgvJO4Q2Y7Ygv0Tdol6Mw2j SNLkjbBp8o5W1XMu9o+X8EoBAmiwUphoLxdL X-Received: by 2002:a17:902:9f97:b0:184:983f:11c5 with SMTP id g23-20020a1709029f9700b00184983f11c5mr16062093plq.89.1666305409460; Thu, 20 Oct 2022 15:36:49 -0700 (PDT) Received: from localhost.localdomain ([149.135.10.35]) by smtp.gmail.com with ESMTPSA id r10-20020aa7988a000000b0054cd16c9f6bsm13753841pfl.200.2022.10.20.15.36.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Oct 2022 15:36:49 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Cc: qemu-arm@nongnu.org, Peter Maydell Subject: [PATCH v5 07/14] target/arm: Remove loop from get_phys_addr_lpae Date: Fri, 21 Oct 2022 08:35:41 +1000 Message-Id: <20221020223548.2310496-8-richard.henderson@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221020223548.2310496-1-richard.henderson@linaro.org> References: <20221020223548.2310496-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102d; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x102d.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=unavailable 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. 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.