From patchwork Mon Sep 4 12:25:41 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 111570 Delivered-To: patch@linaro.org Received: by 10.140.94.166 with SMTP id g35csp1475830qge; Mon, 4 Sep 2017 05:40:53 -0700 (PDT) X-Google-Smtp-Source: ADKCNb7lsbDLvRElX/m4fvjeZKfuSneDMIAnOX/BYu7SUqCc0ig4BwNFkqpHF5eobw2ZAKfAPT2o X-Received: by 10.200.56.238 with SMTP id g43mr382985qtc.249.1504528853079; Mon, 04 Sep 2017 05:40:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1504528853; cv=none; d=google.com; s=arc-20160816; b=rMN7JgED/xjo+kzLi+xKSCt3ebmXPmv/7SewlG8dKI2akyiLtkHswF+DJZPPgwuzZg V75gbmJ9Kt4A9mnGEt4cPmWQnn4FS7/UQzG/09ZTDpDVUMoOP+LcYpmFZkTq5PnSKUxL oUWy3DZ9mIs3PCgTRYBYjFqD6UAzlgmLTre1JMgseDTAprpjkZDZtJ4ohvon48e2WB6R FiM5YYKwW0ln3ADUFoF4/fltKDWakNj4PDlWMNJVLO0F4rBlFDPfu2suUe5tj30J/Dck 4UsLpNuiQX/OhNMvk1OR73rBewdFaF5i/gHg+btia+DDKrr6TuoKuDHj+oJC7YQc2xvz kM2Q== 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=ptbOltEtqXEs1MEv/IEaRE/QjGZyuSdVMrTWsyUsj4g=; b=Ya+m2kqvF/vEe7JkNNfpGQcvawZoMNDKuFszRPG5LRJb+ID6ZnfBdsbiCY0r6GD7hm YTbxRAC6DoKfqN5lcDa4T6pISLNLk8JU4JjWnrriK0u5xTEV/MF2wKJGP27ffNmvMhkM qgAITn8l3IK/YAVKmYTGFs391Mi8dV5C00frVvmwa9xAGwoo+7Bepos2uW9y5rDR3uAq cuVNUKRidfXHo7KGWyymlS8pRuqMRjbcDXDi6Pf3E2R84MxWMr2CsBqcvExy97A/1Hgg 3u6WFpHyaUgd03Iyl9PZdCODxKR5M6yCk5C9qczSgXArUQmSlppXu1NO1bpGHdgVLP2u Lwmw== 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 m3si5896159qkh.262.2017.09.04.05.40.52 for (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 04 Sep 2017 05:40: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]:59613 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1doqgM-00078j-Th for patch@linaro.org; Mon, 04 Sep 2017 08:40:50 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52354) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1doqSG-0004sW-Kt for qemu-devel@nongnu.org; Mon, 04 Sep 2017 08:26:29 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1doqS6-0004gD-8K for qemu-devel@nongnu.org; Mon, 04 Sep 2017 08:26:16 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:37110) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1doqS5-0004ej-W5 for qemu-devel@nongnu.org; Mon, 04 Sep 2017 08:26:06 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1doqS5-0005TQ-18 for qemu-devel@nongnu.org; Mon, 04 Sep 2017 13:26:05 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Date: Mon, 4 Sep 2017 13:25:41 +0100 Message-Id: <1504527967-29248-11-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1504527967-29248-1-git-send-email-peter.maydell@linaro.org> References: <1504527967-29248-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 10/36] target/arm: Don't use cpsr_write/cpsr_read to transfer M profile XPSR 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" For M profile the XPSR is a similar but not identical format to the A profile CPSR/SPSR. (For instance the Thumb bit is in a different place.) For guest accesses we make the M profile code go through xpsr_read() and xpsr_write() which handle the different layout. However for migration we use cpsr_read() and cpsr_write() to marshal state into and out of the migration data stream. This is pretty confusing and works more by luck than anything else. Make M profile migration use xpsr_read() and xpsr_write() instead. The most complicated part of this is handling the possibility that the migration source is an older QEMU which hands us a CPSR format value; helpfully we can always tell the two apart. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 1501692241-23310-11-git-send-email-peter.maydell@linaro.org --- target/arm/machine.c | 49 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 15 deletions(-) -- 2.7.4 diff --git a/target/arm/machine.c b/target/arm/machine.c index 2fb4b762..3193b00 100644 --- a/target/arm/machine.c +++ b/target/arm/machine.c @@ -217,21 +217,37 @@ static int get_cpsr(QEMUFile *f, void *opaque, size_t size, uint32_t val = qemu_get_be32(f); if (arm_feature(env, ARM_FEATURE_M)) { - /* If the I or F bits are set then this is a migration from - * an old QEMU which still stored the M profile FAULTMASK - * and PRIMASK in env->daif. Set v7m.faultmask and v7m.primask - * accordingly, and then clear the bits so they don't confuse - * cpsr_write(). For a new QEMU, the bits here will always be - * clear, and the data is transferred using the - * vmstate_m_faultmask_primask subsection. - */ - if (val & CPSR_F) { - env->v7m.faultmask = 1; - } - if (val & CPSR_I) { - env->v7m.primask = 1; + if (val & XPSR_EXCP) { + /* This is a CPSR format value from an older QEMU. (We can tell + * because values transferred in XPSR format always have zero + * for the EXCP field, and CPSR format will always have bit 4 + * set in CPSR_M.) Rearrange it into XPSR format. The significant + * differences are that the T bit is not in the same place, the + * primask/faultmask info may be in the CPSR I and F bits, and + * we do not want the mode bits. + */ + uint32_t newval = val; + + newval &= (CPSR_NZCV | CPSR_Q | CPSR_IT | CPSR_GE); + if (val & CPSR_T) { + newval |= XPSR_T; + } + /* If the I or F bits are set then this is a migration from + * an old QEMU which still stored the M profile FAULTMASK + * and PRIMASK in env->daif. For a new QEMU, the data is + * transferred using the vmstate_m_faultmask_primask subsection. + */ + if (val & CPSR_F) { + env->v7m.faultmask = 1; + } + if (val & CPSR_I) { + env->v7m.primask = 1; + } + val = newval; } - val &= ~(CPSR_F | CPSR_I); + /* Ignore the low bits, they are handled by vmstate_m. */ + xpsr_write(env, val, ~XPSR_EXCP); + return 0; } env->aarch64 = ((val & PSTATE_nRW) == 0); @@ -252,7 +268,10 @@ static int put_cpsr(QEMUFile *f, void *opaque, size_t size, CPUARMState *env = &cpu->env; uint32_t val; - if (is_a64(env)) { + if (arm_feature(env, ARM_FEATURE_M)) { + /* The low 9 bits are v7m.exception, which is handled by vmstate_m. */ + val = xpsr_read(env) & ~XPSR_EXCP; + } else if (is_a64(env)) { val = pstate_read(env); } else { val = cpsr_read(env);