qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Nicholas Piggin <npiggin@gmail.com>
To: Daniel Henrique Barboza <danielhb413@gmail.com>
Cc: "Nicholas Piggin" <npiggin@gmail.com>,
	"Cédric Le Goater" <clg@kaod.org>,
	"David Gibson" <david@gibson.dropbear.id.au>,
	"Greg Kurz" <groug@kaod.org>,
	"Harsh Prateek Bora" <harshpb@linux.ibm.com>,
	"Pavel Dovgalyuk" <pavel.dovgaluk@ispras.ru>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	qemu-ppc@nongnu.org, qemu-devel@nongnu.org
Subject: [PATCH v2 06/19] hw/ppc: Round up the decrementer interval when converting to ns
Date: Tue,  8 Aug 2023 14:19:48 +1000	[thread overview]
Message-ID: <20230808042001.411094-7-npiggin@gmail.com> (raw)
In-Reply-To: <20230808042001.411094-1-npiggin@gmail.com>

The rule of timers is typically that they should never expire before the
timeout, but some time afterward. Rounding timer intervals up when doing
conversion is the right thing to do.

Under most circumstances it is impossible observe the decrementer
interrupt before the dec register has triggered. However with icount
timing, problems can arise. For example setting DEC to 0 can schedule
the timer for now, causing it to fire before any more instructions
have been executed and DEC is still 0.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 hw/ppc/ppc.c | 31 +++++++++++++++++++------------
 1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index 423a3a117a..13eb45f4b7 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -482,14 +482,26 @@ void ppce500_set_mpic_proxy(bool enabled)
 /*****************************************************************************/
 /* PowerPC time base and decrementer emulation */
 
+/*
+ * Conversion between QEMU_CLOCK_VIRTUAL ns and timebase (TB) ticks:
+ * TB ticks are arrived at by multiplying tb_freq then dividing by
+ * ns per second, and rounding down. TB ticks drive all clocks and
+ * timers in the target machine.
+ *
+ * Converting TB intervals to ns for the purpose of setting a
+ * QEMU_CLOCK_VIRTUAL timer should go the other way, but rounding
+ * up. Rounding down could cause the timer to fire before the TB
+ * value has been reached.
+ */
 static uint64_t ns_to_tb(uint32_t freq, int64_t clock)
 {
     return muldiv64(clock, freq, NANOSECONDS_PER_SECOND);
 }
 
-static int64_t tb_to_ns(uint32_t freq, uint64_t tb)
+/* virtual clock in TB ticks, not adjusted by TB offset */
+static int64_t tb_to_ns_round_up(uint32_t freq, uint64_t tb)
 {
-    return muldiv64(tb, NANOSECONDS_PER_SECOND, freq);
+    return muldiv64_round_up(tb, NANOSECONDS_PER_SECOND, freq);
 }
 
 uint64_t cpu_ppc_get_tb(ppc_tb_t *tb_env, uint64_t vmclk, int64_t tb_offset)
@@ -847,7 +859,7 @@ static void __cpu_ppc_store_decr(PowerPCCPU *cpu, uint64_t *nextp,
 
     /* Calculate the next timer event */
     now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
-    next = now + tb_to_ns(tb_env->decr_freq, value);
+    next = now + tb_to_ns_round_up(tb_env->decr_freq, value);
     *nextp = next;
 
     /* Adjust timer */
@@ -1139,9 +1151,7 @@ static void cpu_4xx_fit_cb (void *opaque)
         /* Cannot occur, but makes gcc happy */
         return;
     }
-    next = now + tb_to_ns(tb_env->tb_freq, next);
-    if (next == now)
-        next++;
+    next = now + tb_to_ns_round_up(tb_env->tb_freq, next);
     timer_mod(ppc40x_timer->fit_timer, next);
     env->spr[SPR_40x_TSR] |= 1 << 26;
     if ((env->spr[SPR_40x_TCR] >> 23) & 0x1) {
@@ -1167,11 +1177,10 @@ static void start_stop_pit (CPUPPCState *env, ppc_tb_t *tb_env, int is_excp)
     } else {
         trace_ppc4xx_pit_start(ppc40x_timer->pit_reload);
         now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
-        next = now + tb_to_ns(tb_env->decr_freq, ppc40x_timer->pit_reload);
+        next = now + tb_to_ns_round_up(tb_env->decr_freq,
+                                       ppc40x_timer->pit_reload);
         if (is_excp)
             next += tb_env->decr_next - now;
-        if (next == now)
-            next++;
         timer_mod(tb_env->decr_timer, next);
         tb_env->decr_next = next;
     }
@@ -1226,9 +1235,7 @@ static void cpu_4xx_wdt_cb (void *opaque)
         /* Cannot occur, but makes gcc happy */
         return;
     }
-    next = now + tb_to_ns(tb_env->decr_freq, next);
-    if (next == now)
-        next++;
+    next = now + tb_to_ns_round_up(tb_env->decr_freq, next);
     trace_ppc4xx_wdt(env->spr[SPR_40x_TCR], env->spr[SPR_40x_TSR]);
     switch ((env->spr[SPR_40x_TSR] >> 30) & 0x3) {
     case 0x0:
-- 
2.40.1



  parent reply	other threads:[~2023-08-08  4:21 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-08  4:19 [PATCH v2 for-8.2 00/19] ppc: record-replay enablement and fixes Nicholas Piggin
2023-08-08  4:19 ` [PATCH v2 01/19] ppc/vhyp: reset exception state when handling vhyp hcall Nicholas Piggin
2023-08-08  4:19 ` [PATCH v2 02/19] ppc/vof: Fix missed fields in VOF cleanup Nicholas Piggin
2023-08-17  2:57   ` Alexey Kardashevskiy
2023-08-08  4:19 ` [PATCH v2 03/19] hw/ppc/ppc.c: Tidy over-long lines Nicholas Piggin
2023-08-08  4:19 ` [PATCH v2 04/19] hw/ppc: Introduce functions for conversion between timebase and nanoseconds Nicholas Piggin
2023-08-08  4:19 ` [PATCH v2 05/19] host-utils: Add muldiv64_round_up Nicholas Piggin
2023-09-01 11:51   ` Cédric Le Goater
2023-09-01 17:02     ` Richard Henderson
2023-09-04 13:07       ` Nicholas Piggin
2023-09-04 13:30         ` Cédric Le Goater
2023-09-05  3:56           ` Nicholas Piggin
2023-09-05  6:48             ` Cédric Le Goater
2023-09-05  9:09             ` Philippe Mathieu-Daudé
2023-09-06  9:21         ` Cédric Le Goater
2023-08-08  4:19 ` Nicholas Piggin [this message]
2023-08-08  4:19 ` [PATCH v2 07/19] hw/ppc: Avoid decrementer rounding errors Nicholas Piggin
2023-08-08  4:19 ` [PATCH v2 08/19] target/ppc: Sign-extend large decrementer to 64-bits Nicholas Piggin
2023-09-01 12:25   ` Cédric Le Goater
2023-09-04 13:09     ` Nicholas Piggin
2023-08-08  4:19 ` [PATCH v2 09/19] hw/ppc: Always store the decrementer value Nicholas Piggin
2023-08-08  4:19 ` [PATCH v2 10/19] target/ppc: Migrate DECR SPR Nicholas Piggin
2023-08-09 12:56   ` Cédric Le Goater
2023-08-10  1:12     ` Nicholas Piggin
2023-08-08  4:19 ` [PATCH v2 11/19] hw/ppc: Reset timebase facilities on machine reset Nicholas Piggin
2023-08-08  4:19 ` [PATCH v2 12/19] hw/ppc: Read time only once to perform decrementer write Nicholas Piggin
2023-08-08  4:19 ` [PATCH v2 13/19] target/ppc: Fix CPU reservation migration for record-replay Nicholas Piggin
2023-08-08  4:19 ` [PATCH v2 14/19] target/ppc: Fix timebase reset with record-replay Nicholas Piggin
2023-08-08  4:19 ` [PATCH v2 15/19] spapr: Fix machine reset deadlock from replay-record Nicholas Piggin
2023-08-08  4:19 ` [PATCH v2 16/19] spapr: Fix record-replay machine reset consuming too many events Nicholas Piggin
2023-08-08  4:19 ` [PATCH v2 17/19] tests/avocado: boot ppc64 pseries replay-record test to Linux VFS mount Nicholas Piggin
2023-08-08  4:20 ` [PATCH v2 18/19] tests/avocado: reverse-debugging cope with re-executing breakpoints Nicholas Piggin
2023-08-08  4:20 ` [PATCH v2 19/19] tests/avocado: ppc64 reverse debugging tests for pseries and powernv Nicholas Piggin
2023-08-29 16:43 ` [PATCH v2 for-8.2 00/19] ppc: record-replay enablement and fixes Cédric Le Goater

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230808042001.411094-7-npiggin@gmail.com \
    --to=npiggin@gmail.com \
    --cc=clg@kaod.org \
    --cc=danielhb413@gmail.com \
    --cc=david@gibson.dropbear.id.au \
    --cc=groug@kaod.org \
    --cc=harshpb@linux.ibm.com \
    --cc=pavel.dovgaluk@ispras.ru \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).