diff mbox

[RFC,V2,4/5] icount_warp: Take into account initial offset between clocks

Message ID 1402652437-13194-5-git-send-email-sebastian.tanase@openwide.fr
State New
Headers show

Commit Message

Sebastian Tanase June 13, 2014, 9:40 a.m. UTC
On some target architectures (for example x86)  the virtual and real
clocks are not aligned at startup so when qemu_icount_bias is first updated
we have to take into account the offset between the 2 clocks to
properly compute if the guest is ahead or behind the host.
On architectures where we don't have this problem (for example
ARM) the offset will always be 0.

Signed-off-by: Sebastian Tanase <sebastian.tanase@openwide.fr>
Tested-by: Camille Bégué <camille.begue@openwide.fr>
---
 cpu-exec.c            |  2 +-
 cpus.c                | 11 +++++++++++
 include/qemu-common.h |  1 +
 3 files changed, 13 insertions(+), 1 deletion(-)

Comments

Paolo Bonzini June 13, 2014, 10:28 a.m. UTC | #1
Il 13/06/2014 11:40, Sebastian Tanase ha scritto:
> +        /* On x86 target architecture, the PIT reset function (called
> +           by qemu_system_reset) will end up calling qemu_clock_warp
> +           and then icount_warp_rt changing vm_clock_warp_start from 0 (initial
> +           value) to -1. This in turn will make us skip the initial offset
> +           between the real and virtual clocks (initially virtual clock is 0).
> +           Therefore we save it in clocks_offset. On ARM, we don't have this
> +           problem and clocks_offset will be 0. */
> +        if (clocks_offset == -1 && icount_align_option) {
> +            clocks_offset = vm_clock_warp_start;
> +        }

Can we instead just do

clocks_offset = qemu_get_clock(QEMU_CLOCK_REALTIME);

in qemu_tcg_init_vcpu?

Paolo
diff mbox

Patch

diff --git a/cpu-exec.c b/cpu-exec.c
index ccc2c0e..5a3bc5e 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -343,7 +343,7 @@  int cpu_exec(CPUArchState *env)
            what we have to do is sleep until it is 0. As for the
            advance/delay we gain here, we try to fix it next time. */
         diff_clk = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -
-                   qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
+                   qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + clocks_offset;
         original_instr_counter = cpu->icount_extra + cpu->icount_decr.u16.low;
     }
 #endif
diff --git a/cpus.c b/cpus.c
index bbe8743..818231b 100644
--- a/cpus.c
+++ b/cpus.c
@@ -62,6 +62,7 @@ 
 #endif /* CONFIG_LINUX */
 
 static CPUState *next_cpu;
+int64_t clocks_offset = -1;
 
 bool cpu_is_stopped(CPUState *cpu)
 {
@@ -336,6 +337,16 @@  static void icount_warp_rt(void *opaque)
             warp_delta = MIN(warp_delta, delta);
         }
         qemu_icount_bias += warp_delta;
+        /* On x86 target architecture, the PIT reset function (called
+           by qemu_system_reset) will end up calling qemu_clock_warp
+           and then icount_warp_rt changing vm_clock_warp_start from 0 (initial
+           value) to -1. This in turn will make us skip the initial offset
+           between the real and virtual clocks (initially virtual clock is 0).
+           Therefore we save it in clocks_offset. On ARM, we don't have this
+           problem and clocks_offset will be 0. */
+        if (clocks_offset == -1 && icount_align_option) {
+            clocks_offset = vm_clock_warp_start;
+        }
     }
     vm_clock_warp_start = -1;
     seqlock_write_unlock(&timers_state.vm_clock_seqlock);
diff --git a/include/qemu-common.h b/include/qemu-common.h
index 60478fa..fb2aab7 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -110,6 +110,7 @@  void configure_icount(QemuOpts *opts, Error **errp);
 extern int use_icount;
 extern int icount_time_shift;
 extern int icount_align_option;
+extern int64_t clocks_offset;
 
 #include "qemu/osdep.h"
 #include "qemu/bswap.h"