From patchwork Thu Jan 24 03:47:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Filippov X-Patchwork-Id: 1030261 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="flZB//OT"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43lTB33Yy6z9s3l for ; Thu, 24 Jan 2019 15:06:50 +1100 (AEDT) Received: from localhost ([127.0.0.1]:46041 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gmWHt-0008Bm-FR for incoming@patchwork.ozlabs.org; Wed, 23 Jan 2019 23:06:45 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58118) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gmWDZ-0005Rh-JS for qemu-devel@nongnu.org; Wed, 23 Jan 2019 23:02:18 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gmVzg-0001Sf-Gm for qemu-devel@nongnu.org; Wed, 23 Jan 2019 22:47:57 -0500 Received: from mail-lj1-x242.google.com ([2a00:1450:4864:20::242]:36956) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gmVzg-0001O5-9T for qemu-devel@nongnu.org; Wed, 23 Jan 2019 22:47:56 -0500 Received: by mail-lj1-x242.google.com with SMTP id t18-v6so3951538ljd.4 for ; Wed, 23 Jan 2019 19:47:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=aXM2W8VoiopxchxWK+RA1AXsQhs4ccHopWKpZMkKjdw=; b=flZB//OTROuSqOnSZAOomELvk8Kw5HJfHaZ12OrT2gXcN1wskOieCnSprKiuWnUCt4 gTOOEQP+Fd+HLelE3D4nUgBqTqoAoMDv1c6d855K3NmZosuDuZBuczeCAuoEvkZ4s+Uh 0rVFUvH4PbvyihsR2ydD2DLVhgeW/Uw5JnCGK8hQdQTQ94j6rWeNqMXJfNW5/NanW5I5 sg1JGaTScXKtOM0eom5lCVzBeNWc3NA+VsVrG2RyVaI39dlDpllw0lUMzI6v7yBBrjSK tQPP+gczEEReBo3dAp42HfIhR4PqExFa1i+IxEWMu/yEzBwr41U9xV8HOPjMDACRDz+C Te8w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=aXM2W8VoiopxchxWK+RA1AXsQhs4ccHopWKpZMkKjdw=; b=VqXsuPGdxiWsWSjC0EvJaSub5Bg65yzvNHvEjScqOgqqdIYDdxHBSlZKCRdN76H1oe MyXiju3fPbqrXm4bGY7+sS2ER/wmcoUXFmL2vFP/NRskbCiVWnIDe8zl1yu+WcGnqTBU qLwQLBSPjcqU1wqh975ys9aOQMNku2XjiMqMm3o3X58nS2QebveE6HrDR6xsk44uaawI ZSV48QMeBBNYQUZTeQJJA8OPcdWIO6u/5HBcpULhoSWN2Uc7XjVNR/uaLJ2rX3OkdnNX PIHxtsaR7cf8C0STngetfh+OL3XKfgwnRQ9SJbnawA2PE60FGNL/CUkGoTpCE0VffSrt XLmQ== X-Gm-Message-State: AJcUukeVWT5z9wHyA4RbIG+zaXnndpDqWNhQ86BWhAyzmp+h+9pgRJ/J IamCCqsGjo+mx6/w6dNgcgwY0O5m X-Google-Smtp-Source: ALg8bN5Tzh+gD5/6iyDGBDjM4pgygPSKWW0Kl5c78zjTdYWgxOPOF0HVc+JbP1gsj/RiXI4P6kDiqQ== X-Received: by 2002:a2e:6f11:: with SMTP id k17-v6mr3981190ljc.94.1548301673277; Wed, 23 Jan 2019 19:47:53 -0800 (PST) Received: from octofox.cadence.com (jcmvbkbc-1-pt.tunnel.tserv24.sto1.ipv6.he.net. [2001:470:27:1fa::2]) by smtp.gmail.com with ESMTPSA id d15-v6sm789961lja.38.2019.01.23.19.47.50 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 23 Jan 2019 19:47:52 -0800 (PST) From: Max Filippov To: qemu-devel@nongnu.org Date: Wed, 23 Jan 2019 19:47:36 -0800 Message-Id: <20190124034736.23125-1-jcmvbkbc@gmail.com> X-Mailer: git-send-email 2.11.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::242 Subject: [Qemu-devel] [PATCH] target/xtensa: fix access to the INTERRUPT SR 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: , Cc: Max Filippov Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" INTERRUPT special register may be changed both by the core (by writing to INTSET and INTCLEAR registers) and by external events (by triggering and clearing HW IRQs). In MTTCG this state must be protected from concurrent access, otherwise interrupts may be lost or spurious interrupts may be detected. Move manipulation of INTSET SR to helpers and protect it with BQL. Fix wsr.intset: it may not clear any bits. Fix wsr.intclear: it may not clear bit that corresponds to NMI. Signed-off-by: Max Filippov --- target/xtensa/exc_helper.c | 15 +++++++++++++++ target/xtensa/helper.h | 2 ++ target/xtensa/op_helper.c | 3 +++ target/xtensa/translate.c | 14 ++------------ 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/target/xtensa/exc_helper.c b/target/xtensa/exc_helper.c index 371a32ba5ad9..3e430a5da383 100644 --- a/target/xtensa/exc_helper.c +++ b/target/xtensa/exc_helper.c @@ -127,6 +127,21 @@ void HELPER(check_interrupts)(CPUXtensaState *env) qemu_mutex_unlock_iothread(); } +void HELPER(intset)(CPUXtensaState *env, uint32_t v) +{ + qemu_mutex_lock_iothread(); + env->sregs[INTSET] |= v & env->config->inttype_mask[INTTYPE_SOFTWARE]; + qemu_mutex_unlock_iothread(); +} + +void HELPER(intclear)(CPUXtensaState *env, uint32_t v) +{ + qemu_mutex_lock_iothread(); + env->sregs[INTSET] &= ~(v & (env->config->inttype_mask[INTTYPE_SOFTWARE] | + env->config->inttype_mask[INTTYPE_EDGE])); + qemu_mutex_unlock_iothread(); +} + static uint32_t relocated_vector(CPUXtensaState *env, uint32_t vector) { if (xtensa_option_enabled(env->config, diff --git a/target/xtensa/helper.h b/target/xtensa/helper.h index 89eb97e26514..2a7db35874fe 100644 --- a/target/xtensa/helper.h +++ b/target/xtensa/helper.h @@ -22,6 +22,8 @@ DEF_HELPER_1(update_ccount, void, env) DEF_HELPER_2(wsr_ccount, void, env, i32) DEF_HELPER_2(update_ccompare, void, env, i32) DEF_HELPER_1(check_interrupts, void, env) +DEF_HELPER_2(intset, void, env, i32) +DEF_HELPER_2(intclear, void, env, i32) DEF_HELPER_3(check_atomctl, void, env, i32, i32) DEF_HELPER_2(wsr_memctl, void, env, i32) diff --git a/target/xtensa/op_helper.c b/target/xtensa/op_helper.c index 1865f46c4b5f..b1b162b01b19 100644 --- a/target/xtensa/op_helper.c +++ b/target/xtensa/op_helper.c @@ -62,6 +62,9 @@ void HELPER(update_ccompare)(CPUXtensaState *env, uint32_t i) { uint64_t dcc; + qemu_mutex_lock_iothread(); + env->sregs[INTSET] &= ~(1u << env->config->timerint[i]); + qemu_mutex_unlock_iothread(); HELPER(update_ccount)(env); dcc = (uint64_t)(env->sregs[CCOMPARE + i] - env->sregs[CCOUNT] - 1) + 1; timer_mod(env->ccompare[i].timer, diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c index a435d9c36cf1..d1e9f59b31bd 100644 --- a/target/xtensa/translate.c +++ b/target/xtensa/translate.c @@ -646,20 +646,12 @@ static void gen_check_interrupts(DisasContext *dc) static void gen_wsr_intset(DisasContext *dc, uint32_t sr, TCGv_i32 v) { - tcg_gen_andi_i32(cpu_SR[sr], v, - dc->config->inttype_mask[INTTYPE_SOFTWARE]); + gen_helper_intset(cpu_env, v); } static void gen_wsr_intclear(DisasContext *dc, uint32_t sr, TCGv_i32 v) { - TCGv_i32 tmp = tcg_temp_new_i32(); - - tcg_gen_andi_i32(tmp, v, - dc->config->inttype_mask[INTTYPE_EDGE] | - dc->config->inttype_mask[INTTYPE_NMI] | - dc->config->inttype_mask[INTTYPE_SOFTWARE]); - tcg_gen_andc_i32(cpu_SR[INTSET], cpu_SR[INTSET], tmp); - tcg_temp_free(tmp); + gen_helper_intclear(cpu_env, v); } static void gen_wsr_intenable(DisasContext *dc, uint32_t sr, TCGv_i32 v) @@ -706,12 +698,10 @@ static void gen_wsr_icountlevel(DisasContext *dc, uint32_t sr, TCGv_i32 v) static void gen_wsr_ccompare(DisasContext *dc, uint32_t sr, TCGv_i32 v) { uint32_t id = sr - CCOMPARE; - uint32_t int_bit = 1 << dc->config->timerint[id]; TCGv_i32 tmp = tcg_const_i32(id); assert(id < dc->config->nccompare); tcg_gen_mov_i32(cpu_SR[sr], v); - tcg_gen_andi_i32(cpu_SR[INTSET], cpu_SR[INTSET], ~int_bit); if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { gen_io_start(); }