qemu-ppc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-ppc] [RFC 3/4] target-ppc: synchronise tb_offset with KVM host on


From: Mark Cave-Ayland
Subject: [Qemu-ppc] [RFC 3/4] target-ppc: synchronise tb_offset with KVM host on machine start
Date: Thu, 7 Apr 2016 16:23:13 +0100

Recalculate the tb_offset between the guest and host, applying it to all CPUs
when (re)starting the virtual machine. This has the effect of providing a
near-seamless virtual timebase for KVM guests that support
KVM_REG_PPC_TB_OFFSET.

Signed-off-by: Mark Cave-Ayland <address@hidden>
---
 hw/ppc/ppc.c |   41 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 40 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index ccdca5d..39e15b1 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -1345,12 +1345,51 @@ PowerPCCPU *ppc_get_vcpu_by_dt_id(int cpu_dt_id)
 }
 
 /* Generic PPC machine */
+static void _ppc_update_timebase(PPCMachineState *pms)
+{
+    /* Update guest timebase offset with respect to host */
+    int64_t tb_off, new_tb_off;
+    int i;
+    
+    PowerPCCPU *first_ppc_cpu = POWERPC_CPU(first_cpu);    
+    tb_off = first_ppc_cpu->env.tb_env->tb_offset;
+    
+    new_tb_off = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
+                 first_ppc_cpu->env.tb_env->tb_freq, NANOSECONDS_PER_SECOND) +
+                 tb_off - cpu_get_host_ticks();
+    
+    //fprintf(stderr, "tb_off: %" PRIx64 "   new_tb_off: %" PRIx64 "\n", 
tb_off, new_tb_off);
+    
+    /* Set new offset to all CPUs */
+    for (i = 0; i < smp_cpus; i++) {
+        PowerPCCPU *pcpu = POWERPC_CPU(qemu_get_cpu(i));
+        pcpu->env.tb_env->tb_offset = new_tb_off;
+    }
+}
+
+static void ppc_machine_change_state(void *opaque, int running, RunState state)
+{
+    PPCMachineState *s = opaque;
+
+    if (running && kvm_enabled()) {      
+        _ppc_update_timebase(s);
+    }
+}
+
+static void ppc_machine_class_init(ObjectClass *oc, void *data)
+{
+    PPCMachineState *s = g_malloc0(sizeof(PPCMachineState));
+    
+    qemu_add_vm_change_state_handler(ppc_machine_change_state, s);
+}
+
 static const TypeInfo ppc_machine_info = {
     .name = TYPE_PPC_MACHINE,
     .parent = TYPE_MACHINE,
     .abstract = true,
     .instance_size = sizeof(PPCMachineState),
-    .class_size = sizeof(PPCMachineClass)
+    .class_size = sizeof(PPCMachineClass),
+    .class_init = ppc_machine_class_init
 };
 
 static void ppc_machine_register_types(void)
-- 
1.7.10.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]