From nobody Sun May 5 17:14:07 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1548874486924318.8759245006688; Wed, 30 Jan 2019 10:54:46 -0800 (PST) Received: from localhost ([127.0.0.1]:42748 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gov0Q-0001lB-VY for importer@patchew.org; Wed, 30 Jan 2019 13:54:39 -0500 Received: from eggs.gnu.org ([209.51.188.92]:55934) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gouyw-0000n2-Bq for qemu-devel@nongnu.org; Wed, 30 Jan 2019 13:53:07 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gouyv-0002lm-GW for qemu-devel@nongnu.org; Wed, 30 Jan 2019 13:53:06 -0500 Received: from mel.act-europe.fr ([2a02:2ab8:224:1::a0a:d2]:48912 helo=smtp.eu.adacore.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gouyv-0002dP-Aa; Wed, 30 Jan 2019 13:53:05 -0500 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 637618138F; Wed, 30 Jan 2019 19:53:01 +0100 (CET) Received: from smtp.eu.adacore.com ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Da-BbiOoYIBc; Wed, 30 Jan 2019 19:53:01 +0100 (CET) Received: from ledoue.act-europe.fr (unknown [IPv6:2a02:2ab8:224:1:d8fe:6e57:5bc4:202f]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.eu.adacore.com (Postfix) with ESMTPSA id D156681345; Wed, 30 Jan 2019 19:53:00 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at eu.adacore.com From: Fabien Chouteau To: Date: Wed, 30 Jan 2019 19:52:42 +0100 Message-Id: <20190130185242.12490-1-chouteau@adacore.com> X-Mailer: git-send-email 2.17.1 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 2a02:2ab8:224:1::a0a:d2 Subject: [Qemu-devel] [PATCH] hw/riscv/sifive_clint.c: avoid integer overflow in timecmp write 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: "open list:RISC-V" , Sagar Karandikar , Bastian Koppelmann , Palmer Dabbelt , "open list:All patches CC here" , Fabien Chouteau , Michael Clark , Alistair Francis Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Writing a high value in timecmp leads to an integer overflow. This patch modifies the code to detect such case, and use the maximum integer value as the next trigger for the timer. Signed-off-by: Fabien Chouteau Reviewed-by: Alistair Francis --- hw/riscv/sifive_clint.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/hw/riscv/sifive_clint.c b/hw/riscv/sifive_clint.c index d4c159e937..1ca1f8c75e 100644 --- a/hw/riscv/sifive_clint.c +++ b/hw/riscv/sifive_clint.c @@ -38,8 +38,10 @@ static uint64_t cpu_riscv_read_rtc(void) */ static void sifive_clint_write_timecmp(RISCVCPU *cpu, uint64_t value) { - uint64_t next; uint64_t diff; + uint64_t lapse_ns; + uint64_t clock_ns; + int64_t next_ns; =20 uint64_t rtc_r =3D cpu_riscv_read_rtc(); =20 @@ -54,10 +56,29 @@ static void sifive_clint_write_timecmp(RISCVCPU *cpu, u= int64_t value) /* otherwise, set up the future timer interrupt */ riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(0)); diff =3D cpu->env.timecmp - rtc_r; - /* back to ns (note args switched in muldiv64) */ - next =3D qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - muldiv64(diff, NANOSECONDS_PER_SECOND, SIFIVE_CLINT_TIMEBASE_FREQ); - timer_mod(cpu->env.timer, next); + + /* + * How many nanoseconds until the next trigger (note args switched in + * muldiv64) + */ + lapse_ns =3D muldiv64(diff, + NANOSECONDS_PER_SECOND, + SIFIVE_CLINT_TIMEBASE_FREQ); + + /* Current time in nanoseconds */ + clock_ns =3D qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + + if ((G_MAXINT64 - clock_ns) <=3D lapse_ns) { + /* + * clock + lapse would overflow on 64bit. The highest 64bit value = is + * used as the next trigger time. + */ + next_ns =3D G_MAXINT64; + } else { + next_ns =3D clock_ns + lapse_ns; + } + + timer_mod(cpu->env.timer, next_ns); } =20 /* --=20 2.17.1