From patchwork Fri Jan 12 11:30:28 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 859782 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; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="LKd31zbP"; dkim-atps=neutral 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 3zJ0zh6zT0z9s75 for ; Fri, 12 Jan 2018 22:35:28 +1100 (AEDT) Received: from localhost ([::1]:35193 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZxcM-0001j4-RC for incoming@patchwork.ozlabs.org; Fri, 12 Jan 2018 06:35:26 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41426) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZxYW-00079y-1y for qemu-devel@nongnu.org; Fri, 12 Jan 2018 06:31:29 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eZxYU-0004K1-2R for qemu-devel@nongnu.org; Fri, 12 Jan 2018 06:31:28 -0500 Received: from mail-wm0-x242.google.com ([2a00:1450:400c:c09::242]:39723) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eZxYT-0004Hj-T8 for qemu-devel@nongnu.org; Fri, 12 Jan 2018 06:31:26 -0500 Received: by mail-wm0-x242.google.com with SMTP id i11so11126408wmf.4 for ; Fri, 12 Jan 2018 03:31:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=40EbTwWkmyPkQVppTjvj5YXrmDerAnz3eL4HXzRdsus=; b=LKd31zbPSI4AKE23Bz9wqCW1HsJzD0tok8znYADTUSWEo4gdjHudc8lDFLt4DftpJn JYOGPX9TGXc3yzd/fiIkAqi4CCoW3ioq4CdFpyvBL/3wvBJ8EcOphDY8lcPdL8gP0kxP 2ylCetoDJobPnN2eOp0icWGSrWjPtbJejGi06xs9oQ4yo5mvqFz0QEVAP0UCFwlm60x1 jID5CZr5V51ORYR4e+52j1FTpcotODZpQLFCZ/N/hgV8/7r2VEkAm+Z85dhOPRyhf/mz 4nB+1BeANc55Mro2N4GqNFiFtsGeJ2HM2SH30vFfwHIWjVr70c5PvtPfwey79ne73Cq8 NC6g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=40EbTwWkmyPkQVppTjvj5YXrmDerAnz3eL4HXzRdsus=; b=Qipx+heqUL5mPXvlr5JJDIHlLJAQ6NgmaE5PHZnH4Q/Mf7wKECoXqxqyJg94CjYNI7 vkad1PgbaLzYMOHdgDr3K5hA2Q3DfpclkVx8QnESgOJ7gT2DBO/SgUJ1u2zI018H3Il+ VrFmN0sQyiwyYG2BoOR9So6WVVyT5m/My+RaXQvIfuuO7WuV/KQGtxMKxHPyaBK5sEcK abHozuzuDteLrT0fTD+VXh3biU7r82+ck4iI3uh618sBfY+rtwhCK1IuRSom8b0kx72u 7namtv6dst38De08Bly2ISm/T9/fQHYVZf3R/9KFqiPXx6/6mIW15EAaZjjgu32izz9D MGNg== X-Gm-Message-State: AKwxyteOy/P+ttHTLLqODi3kmRG93oUnAokp6D0HaRlZkMuzTjAXjLsb lVhgTpy3xsTe96soinX8bVN5ptbG X-Google-Smtp-Source: ACJfBov/e4lfgg10vmovu6vjNnSxEwwP22sGcXlePcQMpvriLM0yc1BfmbcP3ShAuiip6fOYlWbhhg== X-Received: by 10.28.93.69 with SMTP id r66mr3979460wmb.24.1515756684547; Fri, 12 Jan 2018 03:31:24 -0800 (PST) Received: from 640k.lan (dynamic-adsl-78-12-229-84.clienti.tiscali.it. [78.12.229.84]) by smtp.gmail.com with ESMTPSA id l8sm2732271wmg.46.2018.01.12.03.31.23 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 12 Jan 2018 03:31:23 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Fri, 12 Jan 2018 12:30:28 +0100 Message-Id: <1515756676-3860-5-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1515756676-3860-1-git-send-email-pbonzini@redhat.com> References: <1515756676-3860-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c09::242 Subject: [Qemu-devel] [PULL 04/52] hpet: recover timer offset correctly 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: Maria Klimushenkova , Pavel Dovgalyuk Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Maria Klimushenkova HPET saves its state by calculating the current time and recovers timer offset using this calculated value. But these calculations include divisions and multiplications. Therefore the timer state cannot be recovered precise enough. This patch introduces saving of the original value of the offset to preserve the determinism of the timer. Signed-off-by: Maria Klimushenkova Signed-off-by: Pavel Dovgalyuk Message-Id: <20171220100205.16625.84632.stgit@pasha-VirtualBox> Signed-off-by: Paolo Bonzini --- hw/timer/hpet.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c index 577371b..4904a60 100644 --- a/hw/timer/hpet.c +++ b/hw/timer/hpet.c @@ -70,6 +70,7 @@ typedef struct HPETState { MemoryRegion iomem; uint64_t hpet_offset; + bool hpet_offset_loaded; qemu_irq irqs[HPET_NUM_IRQ_ROUTES]; uint32_t flags; uint8_t rtc_irq_level; @@ -221,7 +222,9 @@ static int hpet_pre_save(void *opaque) HPETState *s = opaque; /* save current counter value */ - s->hpet_counter = hpet_get_ticks(s); + if (hpet_enabled(s)) { + s->hpet_counter = hpet_get_ticks(s); + } return 0; } @@ -232,6 +235,8 @@ static int hpet_pre_load(void *opaque) /* version 1 only supports 3, later versions will load the actual value */ s->num_timers = HPET_MIN_TIMERS; + /* for checking whether the hpet_offset section is loaded */ + s->hpet_offset_loaded = false; return 0; } @@ -252,7 +257,10 @@ static int hpet_post_load(void *opaque, int version_id) HPETState *s = opaque; /* Recalculate the offset between the main counter and guest time */ - s->hpet_offset = ticks_to_ns(s->hpet_counter) - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + if (!s->hpet_offset_loaded) { + s->hpet_offset = ticks_to_ns(s->hpet_counter) + - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + } /* Push number of timers into capability returned via HPET_ID */ s->capability &= ~HPET_ID_NUM_TIM_MASK; @@ -267,6 +275,14 @@ static int hpet_post_load(void *opaque, int version_id) return 0; } +static int hpet_offset_post_load(void *opaque, int version_id) +{ + HPETState *s = opaque; + + s->hpet_offset_loaded = true; + return 0; +} + static bool hpet_rtc_irq_level_needed(void *opaque) { HPETState *s = opaque; @@ -285,6 +301,17 @@ static const VMStateDescription vmstate_hpet_rtc_irq_level = { } }; +static const VMStateDescription vmstate_hpet_offset = { + .name = "hpet/offset", + .version_id = 1, + .minimum_version_id = 1, + .post_load = hpet_offset_post_load, + .fields = (VMStateField[]) { + VMSTATE_UINT64(hpet_offset, HPETState), + VMSTATE_END_OF_LIST() + } +}; + static const VMStateDescription vmstate_hpet_timer = { .name = "hpet_timer", .version_id = 1, @@ -320,6 +347,7 @@ static const VMStateDescription vmstate_hpet = { }, .subsections = (const VMStateDescription*[]) { &vmstate_hpet_rtc_irq_level, + &vmstate_hpet_offset, NULL } };