From patchwork Fri Apr 6 12:38:38 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 895693 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=2001:4830:134:3::11; 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=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40HfRP227bz9s0y for ; Fri, 6 Apr 2018 22:40:00 +1000 (AEST) Received: from localhost ([::1]:52351 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f4Qer-00078q-W9 for incoming@patchwork.ozlabs.org; Fri, 06 Apr 2018 08:39:58 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56001) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f4Qdh-0006Rp-Rd for qemu-devel@nongnu.org; Fri, 06 Apr 2018 08:38:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1f4Qdg-00063w-NY for qemu-devel@nongnu.org; Fri, 06 Apr 2018 08:38:45 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:40666) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1f4Qdg-0005xm-FM; Fri, 06 Apr 2018 08:38:44 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1f4Qdb-0001bf-Bf; Fri, 06 Apr 2018 13:38:39 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 6 Apr 2018 13:38:38 +0100 Message-Id: <20180406123838.21249-1-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PATCH for-2.12] cpus.c: ensure running CPU recalculates icount deadlines on timer expiry 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: patches@linaro.org, qemu-stable@nongnu.org, "Emilio G. Cota" , Pavel Dovgalyuk , Paolo Bonzini , =?utf-8?q?Alex_Benn=C3=A9e?= , Richard Henderson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" When we run in TCG icount mode, we calculate the number of instructions to execute using tcg_get_icount_limit(), which ensures that we stop execution at the next timer deadline. However there is a bug where currently we do not recalculate that limit if the guest reprograms a timer so that the next deadline moves closer, and so we will continue execution until the original limit and fire the timer later than we should. Fix this bug in qemu_timer_notify_cb(): if we are currently running a VCPU in icount mode, we simply need to kick it out of the main loop and back to tcg_cpu_exec(), where it will recalculate the icount limit. If we are not currently running a VCPU, then we retain the existing logic for waking up a halted CPU. Cc: qemu-stable@nongnu.org Fixes: https://bugs.launchpad.net/qemu/+bug/1754038 Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Reviewed-by: Alex Bennée --- Thanks to Paolo for tracking down which function needed fixing! cpus.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/cpus.c b/cpus.c index 2e6701795b..38eba8bff3 100644 --- a/cpus.c +++ b/cpus.c @@ -892,11 +892,19 @@ void qemu_timer_notify_cb(void *opaque, QEMUClockType type) return; } - if (!qemu_in_vcpu_thread() && first_cpu) { + if (qemu_in_vcpu_thread()) { + /* A CPU is currently running; kick it back out to the + * tcg_cpu_exec() loop so it will recalculate its + * icount deadline immediately. + */ + qemu_cpu_kick(current_cpu); + } else if (first_cpu) { /* qemu_cpu_kick is not enough to kick a halted CPU out of * qemu_tcg_wait_io_event. async_run_on_cpu, instead, * causes cpu_thread_is_idle to return false. This way, * handle_icount_deadline can run. + * If we have no CPUs at all for some reason, we don't + * need to do anything. */ async_run_on_cpu(first_cpu, do_nothing, RUN_ON_CPU_NULL); }