From patchwork Tue Oct 2 16:35:51 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 148005 Delivered-To: patches@linaro.org Received: by 2002:a2e:8595:0:0:0:0:0 with SMTP id b21-v6csp5372253lji; Tue, 2 Oct 2018 09:36:08 -0700 (PDT) X-Google-Smtp-Source: ACcGV63nBbYTDrOd6uwjeaezdW5va9YBL+SPxuH8zc+BwDth619EmI/HefUOQckifRjcBrFDkvdC X-Received: by 2002:a1c:2dc5:: with SMTP id t188-v6mr2305835wmt.94.1538498168608; Tue, 02 Oct 2018 09:36:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1538498168; cv=none; d=google.com; s=arc-20160816; b=YvP3UAF/ITB7wzst/20u5wHeYTvXuZFhK0PcGf2E9GkXgO1fEOyqjnZgykEo1X2eAy pMp/FB7JE+NcBa7AsrC2TZLOMWcFi9tIZ88hZAwaFjoAfqw7QO7hofppwt66Z2AXT5MJ N4FPtWf0gGCXtNzx/p0H2WhnrP5knoUlbHHUShz0IUcVMPnAMhX0JMzLJr21A4HGXWYO 3wnybwo1Xqb2LJhWDUUpRDJbPBlX9iaoaFW8TKu+ViSgTmqwRDfhH1KpOQRVRiVaFSvd /CxNdW1wR8XbUtaETXCPWbEbXD3l1RKEBGTAMJcdeNkYXeEXO3AW0ZCb8eiy79kblxaE NRNQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from; bh=+BBRoBKd1PzIfqZ6OzyMndwspOUn42qv//t383wrQvw=; b=pgdoGa2MQMs1cPpOImUlIWVqjE3t8cKLCfvHeRmkHvbK31UhlKy7lqNg76vTVjPZHS +cxpJD+d87jsojfFrBRAbHGHJsZpZg8vcJzoXHgwXSC/PhWKsXkePCwTQn5Kb+GcFyF4 DTHc9emrfiz+3Q/xCyXeG3jc+VLhXbXNFhQ4eeiw/VvmEAfsq97qe9KHdECs7fN/MxS9 N3daizZfdUK3NjPL/ebJnXnwSzwLqmCynjir8pK1HiumDltH5YicuF7zJm7R8/WemBEh YzMm2hEOE25wn6HDfCw+hMyT/VmMkWAkXPSIluREMKCssefqP/cYaJ7UgIW0pcLO431u fo1Q== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id k5-v6si13604731wrr.49.2018.10.02.09.36.08 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 02 Oct 2018 09:36:08 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1g7Nea-0007IO-4Y; Tue, 02 Oct 2018 17:36:08 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 08/13] target/arm: Add v8M stack checks for LDRD/STRD (imm) Date: Tue, 2 Oct 2018 17:35:51 +0100 Message-Id: <20181002163556.10279-9-peter.maydell@linaro.org> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181002163556.10279-1-peter.maydell@linaro.org> References: <20181002163556.10279-1-peter.maydell@linaro.org> MIME-Version: 1.0 Add the v8M stack checks for: * LDRD (immediate) * STRD (immediate) Loads and stores are more complicated than ADD/SUB/MOV, because we must ensure that memory accesses below the stack limit are not performed, so we can't simply do the check when we actually update SP. For these instructions, if the stack limit check triggers we must not: * perform any memory access below the SP limit * update PC, SP or the load/store base register but it is IMPDEF whether we: * perform any accesses above or equal to the SP limit * update destination registers for loads For QEMU we choose to always check the limit before doing any other part of the load or store, so we won't update any registers or perform any memory accesses. It is UNKNOWN whether the limit check triggers for a load or store where the initial SP value is below the limit and one of the stores would be below the limit, but the writeback moves SP to above the limit. For QEMU we choose to trigger the check in this situation. Note that limit checks happen only for loads and stores which update SP via writeback; they do not happen for loads and stores which simply use SP as a base register. Signed-off-by: Peter Maydell --- target/arm/translate.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) -- 2.19.0 Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson diff --git a/target/arm/translate.c b/target/arm/translate.c index fcb33b8a503..c16d6075d94 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -10278,6 +10278,8 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn) * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx * - load/store dual (pre-indexed) */ + bool wback = extract32(insn, 21, 1); + if (rn == 15) { if (insn & (1 << 21)) { /* UNPREDICTABLE */ @@ -10289,8 +10291,29 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn) addr = load_reg(s, rn); } offset = (insn & 0xff) * 4; - if ((insn & (1 << 23)) == 0) + if ((insn & (1 << 23)) == 0) { offset = -offset; + } + + if (s->v8m_stackcheck && rn == 13 && wback) { + /* + * Here 'addr' is the current SP; if offset is +ve we're + * moving SP up, else down. It is UNKNOWN whether the limit + * check triggers when SP starts below the limit and ends + * up above it; check whichever of the current and final + * SP is lower, so QEMU will trigger in that situation. + */ + if ((int32_t)offset < 0) { + TCGv_i32 newsp = tcg_temp_new_i32(); + + tcg_gen_addi_i32(newsp, addr, offset); + gen_helper_v8m_stackcheck(cpu_env, newsp); + tcg_temp_free_i32(newsp); + } else { + gen_helper_v8m_stackcheck(cpu_env, addr); + } + } + if (insn & (1 << 24)) { tcg_gen_addi_i32(addr, addr, offset); offset = 0; @@ -10314,7 +10337,7 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn) gen_aa32_st32(s, tmp, addr, get_mem_index(s)); tcg_temp_free_i32(tmp); } - if (insn & (1 << 21)) { + if (wback) { /* Base writeback. */ tcg_gen_addi_i32(addr, addr, offset - 4); store_reg(s, rn, addr);