From patchwork Fri Oct 6 15:59:34 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 115103 Delivered-To: patch@linaro.org Received: by 10.140.22.163 with SMTP id 32csp2006052qgn; Fri, 6 Oct 2017 09:52:53 -0700 (PDT) X-Google-Smtp-Source: AOwi7QB1gskU1J2G66WP1nm3uie/a8bfO4e/xbYyLjX+Q/DUkNRrB3SNtDVoJylEBZbtRCZN8K4S X-Received: by 10.55.21.30 with SMTP id f30mr38363347qkh.335.1507308773806; Fri, 06 Oct 2017 09:52:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1507308773; cv=none; d=google.com; s=arc-20160816; b=LbY3Hj0+0NjYZTejivGyrgdXHqzMxEcewjogsvVqfDOeE0b2F3L7DE2yHb2TGlhPLr Y9uqAIIY5YrQWyPwT6maYE6s8X9azgqIMyvJdI4CgMgj4+yQRbn15U6QG9R91itoUDkM xtawxcXjxmkiBapZx1bbntNLxWDxddjDzPpOkbA/H2M/Onw+K34w19OXhcS0PMd7buon pxGwGSr9JqPhQF7/1F5jGwSozewooH7i0hzlUpnqGm6U3D1zm96b1tRj7+JWSq8tEj+C XX/OU8hiDFbXj4SWFciSmn6fSrL1yttne0fakcw/sT50wyU/0G/ICFcvPJht66jgVy4F HvMw== 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:subject:references:in-reply-to :message-id:date:to:from:arc-authentication-results; bh=e8XSPcm3zctDMMAepp88G+rx3DlRaDL4hak9iAOM5WE=; b=n8l67fKKgsbHBtH7q5FkylqOL+ZmhKdhYKtmkWvjQ0z5JLpYa1eyo1eKtqy1GS/Eey 3F2A8ulkfL0VveJ7Ij/oBwevlpb9AWXZNF6Ai6hw4sduujDh1J+8v+uPu/z9q3dFyMYi kePtZGMsakCBCVcHGgmDeRmRRYx2du7gHY7vbSNQae5FKg/idxrlGbO5Ec3HdMgGlw47 D/njmDPDaKSBLtimypEOkCPc95uY+j3NGfPnBB37cwE6sq0qY3gd0nxpA7ErK2GpVeMt lvIc3Jy1JwyctJbWIqyxuGuLTfy+zGd6WF0zYMeu9uaaK+9Qy9t7iiFu6188Uiy3BdDI mBwQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id j19si916528qkh.286.2017.10.06.09.52.53 for (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 06 Oct 2017 09:52:53 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:45969 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e0Vrp-0000fa-FE for patch@linaro.org; Fri, 06 Oct 2017 12:52:53 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58092) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e0V1k-0004DQ-VN for qemu-devel@nongnu.org; Fri, 06 Oct 2017 11:59:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e0V1j-0007o9-MX for qemu-devel@nongnu.org; Fri, 06 Oct 2017 11:59:05 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:37712) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e0V1j-0007eF-F2 for qemu-devel@nongnu.org; Fri, 06 Oct 2017 11:59:03 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1e0V1c-0002ut-Vs for qemu-devel@nongnu.org; Fri, 06 Oct 2017 16:58:56 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 6 Oct 2017 16:59:34 +0100 Message-Id: <1507305585-20608-10-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1507305585-20608-1-git-send-email-peter.maydell@linaro.org> References: <1507305585-20608-1-git-send-email-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 09/20] target/arm: Check for xPSR mismatch usage faults earlier for v8M X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 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" ARM v8M specifies that the INVPC usage fault for mismatched xPSR exception field and handler mode bit should be checked before updating the PSR and SP, so that the fault is taken with the existing stack frame rather than by pushing a new one. Perform this check in the right place for v8M. Since v7M specifies in its pseudocode that this usage fault check should happen later, we have to retain the original code for that check rather than being able to merge the two. (The distinction is architecturally visible but only in very obscure corner cases like attempting an invalid exception return with an exception frame in read only memory.) Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 1506092407-26985-7-git-send-email-peter.maydell@linaro.org --- target/arm/helper.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) -- 2.7.4 diff --git a/target/arm/helper.c b/target/arm/helper.c index 1bab86c..bee0f5d 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -6436,6 +6436,29 @@ static void do_v7m_exception_exit(ARMCPU *cpu) } xpsr = ldl_phys(cs->as, frameptr + 0x1c); + if (arm_feature(env, ARM_FEATURE_V8)) { + /* For v8M we have to check whether the xPSR exception field + * matches the EXCRET value for return to handler/thread + * before we commit to changing the SP and xPSR. + */ + bool will_be_handler = (xpsr & XPSR_EXCP) != 0; + if (return_to_handler != will_be_handler) { + /* Take an INVPC UsageFault on the current stack. + * By this point we will have switched to the security state + * for the background state, so this UsageFault will target + * that state. + */ + armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, + env->v7m.secure); + env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVPC_MASK; + v7m_exception_taken(cpu, excret); + qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on existing " + "stackframe: failed exception return integrity " + "check\n"); + return; + } + } + /* Commit to consuming the stack frame */ frameptr += 0x20; /* Undo stack alignment (the SPREALIGN bit indicates that the original @@ -6455,12 +6478,13 @@ static void do_v7m_exception_exit(ARMCPU *cpu) /* The restored xPSR exception field will be zero if we're * resuming in Thread mode. If that doesn't match what the * exception return excret specified then this is a UsageFault. + * v7M requires we make this check here; v8M did it earlier. */ if (return_to_handler != arm_v7m_is_handler_mode(env)) { - /* Take an INVPC UsageFault by pushing the stack again. - * TODO: the v8M version of this code should target the - * background state for this exception. + /* Take an INVPC UsageFault by pushing the stack again; + * we know we're v7M so this is never a Secure UsageFault. */ + assert(!arm_feature(env, ARM_FEATURE_V8)); armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, false); env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVPC_MASK; v7m_push_stack(cpu);