From patchwork Sat Mar 15 06:17:46 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Tokarev X-Patchwork-Id: 873840 Delivered-To: patch@linaro.org Received: by 2002:a5d:4308:0:b0:38f:210b:807b with SMTP id h8csp1062519wrq; Fri, 14 Mar 2025 23:27:40 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCWOE9J2KLAA+ja1fn0vTSJR7qSBYOzaFa5nxzRdt0kPg740V6COLRtzGL/9MM0sKS/6GuwbTQ==@linaro.org X-Google-Smtp-Source: AGHT+IEsSqY+D5KbM2LqJ6rwjOv1PmbHe1iqionxroPw0kz/0NHU1AJ+E+UnuFUUHydsvI78jY/X X-Received: by 2002:a05:6214:1250:b0:6e4:2e12:3a0c with SMTP id 6a1803df08f44-6eaeaabd2bcmr76066536d6.39.1742020060647; Fri, 14 Mar 2025 23:27:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1742020060; cv=none; d=google.com; s=arc-20240605; b=d1KMIg2TAQvtzgkJei3HGFsR1F8LMx3s69grQimjcjKs4YWThu0N/RD3DdBcTZpQOM qyTLVv8RFf3weJ9fiKTEbFeSlF2pd8PCjSK0B7HzUHHUu4krTO0+XlNEKnXjAjNuzpoR 4wWs3aP9qHl9WvERkMuSokc24C73P/tvJQESPExa290UbHJihubpWXj/1cW9YiQV61vO 4mJqrQJP3RbDQeG0TUzqwmav6dNCjoA1t7Z6PL6Nhfc5Vw1lIJsGW87VfAgezAA6ZIOQ NRGE4nBD5q98+RONRlQd2NRgdC9nmAbS5UK51FQA2fQavilBt5eie3aG59IntfzcL+7f PyYQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; 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; bh=3Cw1aDEMv4h5pQLkvbB+PEQP4Ao0RzUyrZef507q7JY=; fh=xJ1URYKcMN3TM0/XAv5v+aCN+5tIbzAdcfBx5UNgoLw=; b=UJi8Hk8iROlxuZyMbYxPObk2JDPSENx++rDwxTBRR+AafO7uvd5djVTbt35ncpils1 8mX9oKZ51NWwjdnKbBY6oEENrUaG6qtpGP5NFI8npmrubDbJKRWMgX3ulbYRVthb4t45 thhyxspiFHPB6pveTZsOrFhIr3dwLVYd6ubbTfCnXq3wmizPpznkFZPOg25PJFFfsr1a LlUPkF/jc5GkILBnC+y3o1fJJnFYiiRvSuOTHqtlvJcx0sdT+qqW3l6ZHcF1awEUwcxE bVPipAH3Tqvjf1An6I8nzftQ++TZ2Rfb6jvbFcmqVV5LiJnUACqQC9ueyCG9IgrlSEf1 kfXQ==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; 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" Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id d75a77b69052e-476bb856775si54544061cf.507.2025.03.14.23.27.40 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Fri, 14 Mar 2025 23:27:40 -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; 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" Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ttKy2-0008EX-RY; Sat, 15 Mar 2025 02:25:55 -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 1ttKuQ-0001DI-Ou; Sat, 15 Mar 2025 02:22:11 -0400 Received: from isrv.corpit.ru ([86.62.121.231]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ttKuN-0003ly-Fu; Sat, 15 Mar 2025 02:22:09 -0400 Received: from tsrv.corpit.ru (tsrv.tls.msk.ru [192.168.177.2]) by isrv.corpit.ru (Postfix) with ESMTP id 0F080FF9F4; Sat, 15 Mar 2025 09:17:08 +0300 (MSK) Received: from gandalf.tls.msk.ru (mjt.wg.tls.msk.ru [192.168.177.130]) by tsrv.corpit.ru (Postfix) with ESMTP id DA9C51CAC5D; Sat, 15 Mar 2025 09:18:01 +0300 (MSK) Received: by gandalf.tls.msk.ru (Postfix, from userid 1000) id 8B6CE558FF; Sat, 15 Mar 2025 09:18:01 +0300 (MSK) From: Michael Tokarev To: qemu-devel@nongnu.org Cc: qemu-stable@nongnu.org, Peter Maydell , Richard Henderson , Michael Tokarev Subject: [Stable-9.2.3 40/51] target/arm: Correct STRD atomicity Date: Sat, 15 Mar 2025 09:17:46 +0300 Message-Id: <20250315061801.622606-40-mjt@tls.msk.ru> X-Mailer: git-send-email 2.39.5 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=86.62.121.231; envelope-from=mjt@tls.msk.ru; helo=isrv.corpit.ru X-Spam_score_int: -68 X-Spam_score: -6.9 X-Spam_bar: ------ X-Spam_report: (-6.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, 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-bounces+patch=linaro.org@nongnu.org From: Peter Maydell Our STRD implementation doesn't correctly implement the requirement: * if the address is 8-aligned the access must be a 64-bit single-copy atomic access, not two 32-bit accesses Rewrite the handling of STRD to use a single tcg_gen_qemu_st_i64() of a value produced by concatenating the two 32 bit source registers. This allows us to get the atomicity right. As with the LDRD change, now that we don't update 'addr' in the course of performing the store we need to adjust the offset we pass to op_addr_ri_post() and op_addr_rr_post(). Cc: qemu-stable@nongnu.org Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20250227142746.1698904-3-peter.maydell@linaro.org (cherry picked from commit ee786ca115045a2b7e86ac3073b0761cb99e0d49) Signed-off-by: Michael Tokarev diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c index a2933f1c36..4eba3d1c8d 100644 --- a/target/arm/tcg/translate.c +++ b/target/arm/tcg/translate.c @@ -5063,10 +5063,42 @@ static bool trans_LDRD_rr(DisasContext *s, arg_ldst_rr *a) return true; } -static bool trans_STRD_rr(DisasContext *s, arg_ldst_rr *a) +static void do_strd_store(DisasContext *s, TCGv_i32 addr, int rt, int rt2) { + /* + * STRD is required to be an atomic 64-bit access if the + * address is 8-aligned, two atomic 32-bit accesses if + * it's only 4-aligned, and to give an alignment fault + * if it's not 4-aligned. + * Rt is always the word from the lower address, and Rt2 the + * data from the higher address, regardless of endianness. + * So (like gen_store_exclusive) we avoid gen_aa32_ld_i64() + * so we don't get its SCTLR_B check, and instead do a 64-bit access + * using MO_BE if appropriate, using a value constructed + * by putting the two halves together in the right order. + * + * As with LDRD, the 64-bit atomicity is not required for + * M-profile, or for A-profile before LPAE, and we provide + * the higher guarantee always for simplicity. + */ int mem_idx = get_mem_index(s); - TCGv_i32 addr, tmp; + MemOp opc = MO_64 | MO_ALIGN_4 | MO_ATOM_SUBALIGN | s->be_data; + TCGv taddr = gen_aa32_addr(s, addr, opc); + TCGv_i32 t1 = load_reg(s, rt); + TCGv_i32 t2 = load_reg(s, rt2); + TCGv_i64 t64 = tcg_temp_new_i64(); + + if (s->be_data == MO_BE) { + tcg_gen_concat_i32_i64(t64, t2, t1); + } else { + tcg_gen_concat_i32_i64(t64, t1, t2); + } + tcg_gen_qemu_st_i64(t64, taddr, mem_idx, opc); +} + +static bool trans_STRD_rr(DisasContext *s, arg_ldst_rr *a) +{ + TCGv_i32 addr; if (!ENABLE_ARCH_5TE) { return false; @@ -5077,15 +5109,9 @@ static bool trans_STRD_rr(DisasContext *s, arg_ldst_rr *a) } addr = op_addr_rr_pre(s, a); - tmp = load_reg(s, a->rt); - gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN); + do_strd_store(s, addr, a->rt, a->rt + 1); - tcg_gen_addi_i32(addr, addr, 4); - - tmp = load_reg(s, a->rt + 1); - gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN); - - op_addr_rr_post(s, a, addr, -4); + op_addr_rr_post(s, a, addr, 0); return true; } @@ -5213,20 +5239,13 @@ static bool trans_LDRD_ri_t32(DisasContext *s, arg_ldst_ri2 *a) static bool op_strd_ri(DisasContext *s, arg_ldst_ri *a, int rt2) { - int mem_idx = get_mem_index(s); - TCGv_i32 addr, tmp; + TCGv_i32 addr; addr = op_addr_ri_pre(s, a); - tmp = load_reg(s, a->rt); - gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN); - - tcg_gen_addi_i32(addr, addr, 4); - - tmp = load_reg(s, rt2); - gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN); + do_strd_store(s, addr, a->rt, rt2); - op_addr_ri_post(s, a, addr, -4); + op_addr_ri_post(s, a, addr, 0); return true; }