From patchwork Sat Oct 1 16:23:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 611408 Delivered-To: patch@linaro.org Received: by 2002:a17:522:c983:b0:460:3032:e3c4 with SMTP id kr3csp285210pvb; Sat, 1 Oct 2022 10:00:59 -0700 (PDT) X-Google-Smtp-Source: AMsMyM4IX87F8ALbNIfYZ9r0eOGymKdLIxe+PbHREic+e4cLZyf3SvEHrf9f/9LmRc+0NQWXqZON X-Received: by 2002:a05:620a:1a96:b0:6cd:f115:62dd with SMTP id bl22-20020a05620a1a9600b006cdf11562ddmr8858694qkb.286.1664643659558; Sat, 01 Oct 2022 10:00:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1664643659; cv=none; d=google.com; s=arc-20160816; b=cIMm3fbrr9kkd+VQ1GwoaNytE8dyeKIOXo1PXZ5QnGkLqxcoOeXSsXCkXgwcb71HkF xRzVCtweKP3TeTQncQyGS0e5UW7qLWYefBw2kDpmG+NOOyD54d4n184ABagYhx5PoURo UMbWx4db7qKJsZKGPuhEWgAxdXsQhoX0l37xy7idysKy0pT5dJLzBRQrIWs1ZcpQVCjK 128Xjoy+IhAkEHUVOOmz6U4gXi9E+hLmAr422IfsRp/owMZAKbX7oKJ32ZQ5b0Cb2nBf 2WjE1hbGmUxQQiii5sZ+lhcOxBg/MX9y5rZS73jMUwtmmB+ZC1FUSbcWQHE/5dHrginR QRgw== 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=d9kz4Yl5xD4sEfVOwu1Hh/lMUPctSMFvhkB/+NtfgYo=; b=K4B/2QzMLjwwd6Vq/LxDx5iG0QEuNfCT1izEI5cpT2psoG2cPqWMHtK3julE8A2BOd rOBJGFIR0AmxiTdPMhPCHQLCYi3hw91JF/ul1xJzjhSn42e9BCnnD4D26AuYRQauCK37 4f1l070CRZ4YFrqm0G+jtkVFczPH+s+GBUMlTsPzawErPMt/efwdwEa50uX/9gCI6dms ubKDcK8uvXszElfS2LnlzIKZw9ORf/bM/6uTOmyO1o/HQI93zgwgxSAh3tYRz66fJW92 kaE7jH1DLmU9pn3y/dAy+kJzPAEvjlXp9k+2ENxJqNIeYcE0hShmobScDJvX52DC8pZ2 bsFQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=jem+VTRI; 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 o21-20020ac87c55000000b0035d541b7067si2998810qtv.129.2022.10.01.10.00.59 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Sat, 01 Oct 2022 10:00: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=jem+VTRI; 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]:58580 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oefrH-00025O-24 for patch@linaro.org; Sat, 01 Oct 2022 13:00:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49120) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oefIN-0000cW-G4 for qemu-devel@nongnu.org; Sat, 01 Oct 2022 12:24:55 -0400 Received: from mail-qv1-xf2a.google.com ([2607:f8b0:4864:20::f2a]:34408) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oefIL-0006KI-FE for qemu-devel@nongnu.org; Sat, 01 Oct 2022 12:24:55 -0400 Received: by mail-qv1-xf2a.google.com with SMTP id i9so1134912qvu.1 for ; Sat, 01 Oct 2022 09:24:53 -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; bh=d9kz4Yl5xD4sEfVOwu1Hh/lMUPctSMFvhkB/+NtfgYo=; b=jem+VTRIbnclC7w2eIRNj9BnyCG5P7TvpvULDvgUhoT/S6WgMInQiSEppQf82Ja0kb I09NrhRXI+2gtWSghexSSXgkkzGfIguwzbbX/mquFCwhP1p7V1p+IfwMgE/8m0DjZOuT n2U3BQX8MTAPV/gHnw0MShWWDtPxQAMlx0fUPY6kppRSiSLIXJdnjhLfaNm5oi9tG2eM lL9C1XeK/IUk79rfNcRmmO3LabJfDKcYE5xfenSMv4kz1lYeFh6vzRIQZWGVogCIlpSQ FC3dH0neWNqjQXAegRU9kwUoXQygW1nu1pNnz6l+drrDR0qGRwuu5LdG0l4AWPhuCEuX /klw== 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; bh=d9kz4Yl5xD4sEfVOwu1Hh/lMUPctSMFvhkB/+NtfgYo=; b=4AdXdyhxRbIQVPINboLIwjUyEH/LnD6HFhzbSAMCcvirtJ7Rhim2MfQ7oEkc+xMrtd LitfWL24O050+WH5UUbxe1a/clDDS/z0Ha2nO0Vr+Z42VmRAxLR/TgEJq8u3QzrYTOJE XZDafFJiPwow+8tLHgmM4VBf+PUADUfXseHPkieayhg0vAWFB5j5cDn/l0/AFPDWqzKh ayD0P4i6pd3lhSmNGK3YaEB8nhApupc3g5fEUaAcIzU7yEkrRE9pn+K/pEaCRGY+CQRq 4jJROnsvh1w32EDl8csWwZob5aorYYIDgiAt7z2bPqCDdY5+EgFYABbbkp98W0X1TQeI 4DuA== X-Gm-Message-State: ACrzQf04z/5aNeYWK+SYm/EJ98Zky5Lhfj50i7Gh9jE7aSYHrmrsSQNg IkieroHojQ3tZZ4u1s1efLk9ExKc9BcX+g== X-Received: by 2002:a05:6214:ac1:b0:4af:9cdb:e4f with SMTP id g1-20020a0562140ac100b004af9cdb0e4fmr11176041qvi.40.1664641492713; Sat, 01 Oct 2022 09:24:52 -0700 (PDT) Received: from stoup.. ([2605:ef80:8084:91a4:f7cb:db31:c505:b931]) by smtp.gmail.com with ESMTPSA id t4-20020a37ea04000000b006d1d8fdea8asm4387445qkj.85.2022.10.01.09.24.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 01 Oct 2022 09:24:52 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Cc: qemu-arm@nongnu.org Subject: [PATCH v3 37/42] target/arm: Remove loop from get_phys_addr_lpae Date: Sat, 1 Oct 2022 09:23:13 -0700 Message-Id: <20221001162318.153420-38-richard.henderson@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221001162318.153420-1-richard.henderson@linaro.org> References: <20221001162318.153420-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::f2a; envelope-from=richard.henderson@linaro.org; helo=mail-qv1-xf2a.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: , 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 Reviewed-by: Peter Maydell --- 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 84b55b640b..e6b385a8b1 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -1082,6 +1082,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) { @@ -1280,96 +1283,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, debug, &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, debug, &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.