From patchwork Wed Jan 30 18:52:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabien Chouteau X-Patchwork-Id: 10789185 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7B1EA1390 for ; Wed, 30 Jan 2019 18:54:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6D23F2F5C7 for ; Wed, 30 Jan 2019 18:54:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 60D7A2F62F; Wed, 30 Jan 2019 18:54:21 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 90D7A2F5C7 for ; Wed, 30 Jan 2019 18:54:20 +0000 (UTC) Received: from localhost ([127.0.0.1]:42748 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gov07-0001lB-Io for patchwork-qemu-devel@patchwork.kernel.org; Wed, 30 Jan 2019 13:54:19 -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) X-Virus-Scanned: Debian amavisd-new at eu.adacore.com 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) 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+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP 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; uint64_t rtc_r = cpu_riscv_read_rtc(); @@ -54,10 +56,29 @@ static void sifive_clint_write_timecmp(RISCVCPU *cpu, uint64_t value) /* otherwise, set up the future timer interrupt */ riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(0)); diff = cpu->env.timecmp - rtc_r; - /* back to ns (note args switched in muldiv64) */ - next = 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 = muldiv64(diff, + NANOSECONDS_PER_SECOND, + SIFIVE_CLINT_TIMEBASE_FREQ); + + /* Current time in nanoseconds */ + clock_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + + if ((G_MAXINT64 - clock_ns) <= lapse_ns) { + /* + * clock + lapse would overflow on 64bit. The highest 64bit value is + * used as the next trigger time. + */ + next_ns = G_MAXINT64; + } else { + next_ns = clock_ns + lapse_ns; + } + + timer_mod(cpu->env.timer, next_ns); } /*