From patchwork Thu Aug 13 10:44:42 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 52357 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-la0-f70.google.com (mail-la0-f70.google.com [209.85.215.70]) by patches.linaro.org (Postfix) with ESMTPS id 47D3322EC6 for ; Thu, 13 Aug 2015 10:46:28 +0000 (UTC) Received: by lagz9 with SMTP id z9sf15445096lag.3 for ; Thu, 13 Aug 2015 03:46:27 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:date :message-id:in-reply-to:references:subject:precedence:list-id :list-unsubscribe:list-archive:list-post:list-help:list-subscribe :errors-to:sender:x-original-sender :x-original-authentication-results:mailing-list; bh=iL2nDEtVnPq+4qZ+RhcOJXFEaIEr4r6V7ovuVYwNTbk=; b=HLTHAItSjcak8fl0VnZ0UzevJRNr4+GB7lYrkHC4tgMuAQBsjNYEjSubfJXWLNGM6W aqIiimENjO+udvvqJDQkDFbHRNXsd8KWw3C1fKR0LmT8Izhj2C5rYdi5JnsxlTCirPx4 qTIDUPPkHR2uIAM/HgwOuB555LXW2PVFiGk3uwOcmU1PGNI/mOaXP7HUlW9Zux/WMsu/ bpFWzYWjN2NCQWyWE4NneYvyH3+xDtOdQS/6RyD5qF9rfIL2FPx//2H+E6g1Z6x6Sm7Q pCcQr7/e/4BMtHECgvomBhGsTYFU5smsgKMJw5LbQYBqs4oIsHpH0W+vZm4d7K+qfWsy /4+w== X-Gm-Message-State: ALoCoQkXUXEtH0hhkV1+TEqKuXY3u6N7/jrpkTbhv6JKKUyogtVk9Ngj4AlCrsbVEL6tVgr3UcXZ X-Received: by 10.180.100.71 with SMTP id ew7mr574941wib.0.1439462787214; Thu, 13 Aug 2015 03:46:27 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.21.194 with SMTP id x2ls161018lae.33.gmail; Thu, 13 Aug 2015 03:46:26 -0700 (PDT) X-Received: by 10.152.5.130 with SMTP id s2mr36099413las.31.1439462786794; Thu, 13 Aug 2015 03:46:26 -0700 (PDT) Received: from mail-la0-f41.google.com (mail-la0-f41.google.com. [209.85.215.41]) by mx.google.com with ESMTPS id yo1si1756377lbb.167.2015.08.13.03.46.26 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 13 Aug 2015 03:46:26 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.41 as permitted sender) client-ip=209.85.215.41; Received: by lalv9 with SMTP id v9so23824976lal.0 for ; Thu, 13 Aug 2015 03:46:26 -0700 (PDT) X-Received: by 10.152.88.78 with SMTP id be14mr35315840lab.29.1439462786684; Thu, 13 Aug 2015 03:46:26 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.7.198 with SMTP id l6csp858011lba; Thu, 13 Aug 2015 03:46:25 -0700 (PDT) X-Received: by 10.50.62.46 with SMTP id v14mr28271638igr.79.1439462778361; Thu, 13 Aug 2015 03:46:18 -0700 (PDT) Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id g78si1198299iod.20.2015.08.13.03.46.17 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Thu, 13 Aug 2015 03:46:18 -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; Received: from localhost ([::1]:41638 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZPq1Z-0006mr-7D for patch@linaro.org; Thu, 13 Aug 2015 06:46:17 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35944) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZPq0K-0005QR-Qe for qemu-devel@nongnu.org; Thu, 13 Aug 2015 06:45:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZPq0H-0005HK-5a for qemu-devel@nongnu.org; Thu, 13 Aug 2015 06:45:00 -0400 Received: from mnementh.archaic.org.uk ([2001:8b0:1d0::1]:34909) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZPq0G-0005DT-VG for qemu-devel@nongnu.org; Thu, 13 Aug 2015 06:44:57 -0400 Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.80) (envelope-from ) id 1ZPq08-00071o-9p for qemu-devel@nongnu.org; Thu, 13 Aug 2015 11:44:48 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Date: Thu, 13 Aug 2015 11:44:42 +0100 Message-Id: <1439462687-26903-23-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1439462687-26903-1-git-send-email-peter.maydell@linaro.org> References: <1439462687-26903-1-git-send-email-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2001:8b0:1d0::1 Subject: [Qemu-devel] [PULL 22/27] target-arm: Add debug check for mismatched cpreg resets X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 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 X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: peter.maydell@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.41 as permitted sender) smtp.mailfrom=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 It's easy to accidentally define two cpregs which both try to reset the same underlying state field (for instance a clash between an AArch64 EL3 definition and an AArch32 banked register definition). if the two definitions disagree about the reset value then the result is dependent on which one happened to be reached last in the hashtable enumeration. Add a consistency check to detect and assert in these cases: after reset, we run a second pass where we check that the reset operation doesn't change the value of the register. Signed-off-by: Peter Maydell Reviewed-by: Edgar E. Iglesias Message-id: 1436797559-20835-1-git-send-email-peter.maydell@linaro.org --- target-arm/cpu.c | 23 +++++++++++++++++++++++ target-arm/cpu.h | 3 +++ target-arm/helper.c | 2 +- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/target-arm/cpu.c b/target-arm/cpu.c index 3525348..3c84f72 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -79,6 +79,27 @@ static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque) } } +static void cp_reg_check_reset(gpointer key, gpointer value, gpointer opaque) +{ + /* Purely an assertion check: we've already done reset once, + * so now check that running the reset for the cpreg doesn't + * change its value. This traps bugs where two different cpregs + * both try to reset the same state field but to different values. + */ + ARMCPRegInfo *ri = value; + ARMCPU *cpu = opaque; + uint64_t oldvalue, newvalue; + + if (ri->type & (ARM_CP_SPECIAL | ARM_CP_ALIAS | ARM_CP_NO_RAW)) { + return; + } + + oldvalue = read_raw_cp_reg(&cpu->env, ri); + cp_reg_reset(key, value, opaque); + newvalue = read_raw_cp_reg(&cpu->env, ri); + assert(oldvalue == newvalue); +} + /* CPUClass::reset() */ static void arm_cpu_reset(CPUState *s) { @@ -90,6 +111,8 @@ static void arm_cpu_reset(CPUState *s) memset(env, 0, offsetof(CPUARMState, features)); g_hash_table_foreach(cpu->cp_regs, cp_reg_reset, cpu); + g_hash_table_foreach(cpu->cp_regs, cp_reg_check_reset, cpu); + env->vfp.xregs[ARM_VFP_FPSID] = cpu->reset_fpsid; env->vfp.xregs[ARM_VFP_MVFR0] = cpu->mvfr0; env->vfp.xregs[ARM_VFP_MVFR1] = cpu->mvfr1; diff --git a/target-arm/cpu.h b/target-arm/cpu.h index 7346c5f..ebca342 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -1448,6 +1448,9 @@ static inline bool cp_access_ok(int current_el, return (ri->access >> ((current_el * 2) + isread)) & 1; } +/* Raw read of a coprocessor register (as needed for migration, etc) */ +uint64_t read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri); + /** * write_list_to_cpustate * @cpu: ARMCPU diff --git a/target-arm/helper.c b/target-arm/helper.c index 4a7dd24..49ce612 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -144,7 +144,7 @@ static void *raw_ptr(CPUARMState *env, const ARMCPRegInfo *ri) return (char *)env + ri->fieldoffset; } -static uint64_t read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri) +uint64_t read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri) { /* Raw read of a coprocessor register (as needed for migration, etc). */ if (ri->type & ARM_CP_CONST) {