From patchwork Sun Jul 2 18:04:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Tokarev X-Patchwork-Id: 1802460 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) 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=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4QvH8T6tstz20ZF for ; Mon, 3 Jul 2023 04:07:37 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qG1SI-0000l4-Pl; Sun, 02 Jul 2023 14:05:50 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qG1Ro-0000bZ-A0; Sun, 02 Jul 2023 14:05:23 -0400 Received: from isrv.corpit.ru ([86.62.121.231]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qG1Rl-0005Hz-DL; Sun, 02 Jul 2023 14:05:19 -0400 Received: from tsrv.corpit.ru (tsrv.tls.msk.ru [192.168.177.2]) by isrv.corpit.ru (Postfix) with ESMTP id 75B2110DF0; Sun, 2 Jul 2023 21:04:54 +0300 (MSK) Received: from tls.msk.ru (mjt.wg.tls.msk.ru [192.168.177.130]) by tsrv.corpit.ru (Postfix) with SMTP id A8CC211204; Sun, 2 Jul 2023 21:04:52 +0300 (MSK) Received: (nullmailer pid 2122372 invoked by uid 1000); Sun, 02 Jul 2023 18:04:51 -0000 From: Michael Tokarev To: qemu-devel@nongnu.org, qemu-stable@nongnu.org Cc: Nicholas Piggin , sdicaro@DDCI.com, Daniel Henrique Barboza , Michael Tokarev Subject: [Stable-8.0.3 61/65] target/ppc: Fix decrementer time underflow and infinite timer loop Date: Sun, 2 Jul 2023 21:04:34 +0300 Message-Id: <20230702180439.2122316-7-mjt@tls.msk.ru> X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=86.62.121.231; envelope-from=mjt@tls.msk.ru; helo=isrv.corpit.ru X-Spam_score_int: -68 X-Spam_score: -6.9 X-Spam_bar: ------ X-Spam_report: (-6.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Nicholas Piggin It is possible to store a very large value to the decrementer that it does not raise the decrementer exception so the timer is scheduled, but the next time value wraps and is treated as in the past. This can occur if (u64)-1 is stored on a zero-triggered exception, or (u64)-1 is stored twice on an underflow-triggered exception, for example. If such a value is set in DECAR, it gets stored to the decrementer by the timer function, which then immediately causes another timer, which hangs QEMU. Clamp the decrementer to the implemented width, and use that as the value for the timer calculation, effectively preventing this overflow. Reported-by: sdicaro@DDCI.com Signed-off-by: Nicholas Piggin Reviewed-by: Daniel Henrique Barboza Message-Id: <20230530131214.373524-1-npiggin@gmail.com> Signed-off-by: Daniel Henrique Barboza (cherry picked from commit 09d2db9f46e38e2da990df8ad914d735d764251a) Signed-off-by: Michael Tokarev diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c index 4e816c68c7..d80b0adc6c 100644 --- a/hw/ppc/ppc.c +++ b/hw/ppc/ppc.c @@ -798,6 +798,8 @@ static void __cpu_ppc_store_decr(PowerPCCPU *cpu, uint64_t *nextp, int64_t signed_decr; /* Truncate value to decr_width and sign extend for simplicity */ + value = extract64(value, 0, nr_bits); + decr = extract64(decr, 0, nr_bits); signed_value = sextract64(value, 0, nr_bits); signed_decr = sextract64(decr, 0, nr_bits);