* [Qemu-devel] [RFC 0/4] target-ppc: handle KVM timebase migration
@ 2016-04-07 15:23 Mark Cave-Ayland
2016-04-07 15:23 ` [Qemu-devel] [RFC 1/4] target-ppc: introduce PPCMachineClass and PPCMachineState Mark Cave-Ayland
` (4 more replies)
0 siblings, 5 replies; 9+ messages in thread
From: Mark Cave-Ayland @ 2016-04-07 15:23 UTC (permalink / raw)
To: david, aik, agraf, qemu-ppc, qemu-devel
This RFC series follows on from discussions in the "Migrating decrementer"
thread relating to handling migration of the timebase and decrementer
registers for both TCG and KVM. The aim is to provide a consistent virtual
clock when migrating PPC machines TCG-TCG (already handled) and
KVM-KVM with both paused and live VMs in a unified manner for all PPC
machine types.
The existing code to handle timebase migration on PPC has a few issues:
1) It uses cpu_get_host_ticks() which doesn't work correctly on TCG with
different host architectures
2) tb_offset is calculated from the difference in the host clock between
source and destination. Thus if the guest is paused then the resulting
offset is calculated incorrectly since the host clock still runs, regardless
of the state of the virtual clock.
3) Due to a typo in the existing implementation (MIN instead of MAX) then
guest_tb never takes migration_duration_tb into account
Patches 1-2 introduce a new PPCMachineClass and derive all the PPC machine
classes from it, not dissimilar to x86's PCMachineClass.
Patch 3 adds a VM state change hook into PCMachineClass and updates the
tb_offset from the host when the machine (re)starts as discussed in the
thread. Note that it may be possible to add the hook to specific machine
types, however using PPCMachineClass allows all PPC machines to pick up
this functionality automatically.
Patch 4 temporarily disables the existing timebase migration code to allow
testing.
Note that this has only been compile-tested on x86 as I have no KVM PPC
hardware and so it's really an RFC to determine whether this approach can
work, and to invite testing and discussion from existing KVM PPC users.
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Mark Cave-Ayland (4):
target-ppc: introduce PPCMachineClass and PPCMachineState
target-ppc: derive all PPC machine classes to have PPCMachineClass as
their superclass
target-ppc: synchronise tb_offset with KVM host on machine start
target-ppc: hack to remove existing timebase migration code for
testing
hw/ppc/e500plat.c | 7 +++-
hw/ppc/mac_newworld.c | 17 ++------
hw/ppc/mac_oldworld.c | 6 ++-
hw/ppc/mpc8544ds.c | 7 +++-
hw/ppc/ppc.c | 100 +++++++++++++++++++++++++++++------------------
hw/ppc/ppc405_boards.c | 28 +++----------
hw/ppc/ppc440_bamboo.c | 6 ++-
hw/ppc/prep.c | 6 ++-
hw/ppc/spapr.c | 2 +-
hw/ppc/virtex_ml507.c | 6 ++-
include/hw/ppc/ppc.h | 35 +++++++++++++++++
include/qemu/typedefs.h | 2 +
12 files changed, 135 insertions(+), 87 deletions(-)
--
1.7.10.4
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Qemu-devel] [RFC 1/4] target-ppc: introduce PPCMachineClass and PPCMachineState
2016-04-07 15:23 [Qemu-devel] [RFC 0/4] target-ppc: handle KVM timebase migration Mark Cave-Ayland
@ 2016-04-07 15:23 ` Mark Cave-Ayland
2016-04-15 5:13 ` David Gibson
2016-04-07 15:23 ` [Qemu-devel] [RFC 2/4] target-ppc: derive all PPC machine classes to have PPCMachineClass as their superclass Mark Cave-Ayland
` (3 subsequent siblings)
4 siblings, 1 reply; 9+ messages in thread
From: Mark Cave-Ayland @ 2016-04-07 15:23 UTC (permalink / raw)
To: david, aik, agraf, qemu-ppc, qemu-devel
Introduce PPCMachineClass in anticipation of making it the superclass for
all PPC machines.
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
hw/ppc/ppc.c | 16 ++++++++++++++++
include/hw/ppc/ppc.h | 16 ++++++++++++++++
include/qemu/typedefs.h | 2 ++
3 files changed, 34 insertions(+)
diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index 38ff2e1..ccdca5d 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -1343,3 +1343,19 @@ PowerPCCPU *ppc_get_vcpu_by_dt_id(int cpu_dt_id)
return NULL;
}
+
+/* Generic PPC machine */
+static const TypeInfo ppc_machine_info = {
+ .name = TYPE_PPC_MACHINE,
+ .parent = TYPE_MACHINE,
+ .abstract = true,
+ .instance_size = sizeof(PPCMachineState),
+ .class_size = sizeof(PPCMachineClass)
+};
+
+static void ppc_machine_register_types(void)
+{
+ type_register_static(&ppc_machine_info);
+}
+
+type_init(ppc_machine_register_types)
diff --git a/include/hw/ppc/ppc.h b/include/hw/ppc/ppc.h
index 14efd0c..f1be147 100644
--- a/include/hw/ppc/ppc.h
+++ b/include/hw/ppc/ppc.h
@@ -1,6 +1,22 @@
#ifndef HW_PPC_H
#define HW_PPC_H 1
+#include "hw/boards.h"
+
+struct PPCMachineState {
+ /*< private >*/
+ MachineState parent_obj;
+};
+
+struct PPCMachineClass {
+ /*< private >*/
+ MachineClass parent_class;
+};
+
+#define TYPE_PPC_MACHINE "generic-ppc-machine"
+#define PPC_MACHINE(obj) \
+ OBJECT_CHECK(PPCMachineState, (obj), TYPE_PPC_MACHINE)
+
void ppc_set_irq(PowerPCCPU *cpu, int n_IRQ, int level);
/* PowerPC hardware exceptions management helpers */
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
index 1dcf6f5..73fbad5 100644
--- a/include/qemu/typedefs.h
+++ b/include/qemu/typedefs.h
@@ -73,6 +73,8 @@ typedef struct PCMachineState PCMachineState;
typedef struct PCMCIACardState PCMCIACardState;
typedef struct PixelFormat PixelFormat;
typedef struct PostcopyDiscardState PostcopyDiscardState;
+typedef struct PPCMachineClass PPCMachineClass;
+typedef struct PPCMachineState PPCMachineState;
typedef struct Property Property;
typedef struct PropertyInfo PropertyInfo;
typedef struct QEMUBH QEMUBH;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [RFC 2/4] target-ppc: derive all PPC machine classes to have PPCMachineClass as their superclass
2016-04-07 15:23 [Qemu-devel] [RFC 0/4] target-ppc: handle KVM timebase migration Mark Cave-Ayland
2016-04-07 15:23 ` [Qemu-devel] [RFC 1/4] target-ppc: introduce PPCMachineClass and PPCMachineState Mark Cave-Ayland
@ 2016-04-07 15:23 ` Mark Cave-Ayland
2016-04-15 5:17 ` David Gibson
2016-04-07 15:23 ` [Qemu-devel] [RFC 3/4] target-ppc: synchronise tb_offset with KVM host on machine start Mark Cave-Ayland
` (2 subsequent siblings)
4 siblings, 1 reply; 9+ messages in thread
From: Mark Cave-Ayland @ 2016-04-07 15:23 UTC (permalink / raw)
To: david, aik, agraf, qemu-ppc, qemu-devel
Using a new DEFINE_PPC_MACHINE macro, make sure that all PPC machines now derive from
the new PPCMachineClass.
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
hw/ppc/e500plat.c | 7 +++++--
hw/ppc/mac_newworld.c | 17 +++--------------
hw/ppc/mac_oldworld.c | 6 ++++--
hw/ppc/mpc8544ds.c | 7 +++++--
hw/ppc/ppc405_boards.c | 28 ++++++----------------------
hw/ppc/ppc440_bamboo.c | 6 ++++--
hw/ppc/prep.c | 6 ++++--
hw/ppc/spapr.c | 2 +-
hw/ppc/virtex_ml507.c | 6 ++++--
include/hw/ppc/ppc.h | 21 ++++++++++++++++++++-
10 files changed, 56 insertions(+), 50 deletions(-)
diff --git a/hw/ppc/e500plat.c b/hw/ppc/e500plat.c
index b00565c..6e4cf05 100644
--- a/hw/ppc/e500plat.c
+++ b/hw/ppc/e500plat.c
@@ -15,6 +15,7 @@
#include "hw/boards.h"
#include "sysemu/device_tree.h"
#include "hw/pci/pci.h"
+#include "hw/ppc/ppc.h"
#include "hw/ppc/openpic.h"
#include "kvm_ppc.h"
@@ -57,12 +58,14 @@ static void e500plat_init(MachineState *machine)
ppce500_init(machine, ¶ms);
}
-static void e500plat_machine_init(MachineClass *mc)
+static void e500plat_machine_init(PPCMachineClass *pmc)
{
+ MachineClass *mc = MACHINE_CLASS(pmc);
+
mc->desc = "generic paravirt e500 platform";
mc->init = e500plat_init;
mc->max_cpus = 32;
mc->has_dynamic_sysbus = true;
}
-DEFINE_MACHINE("ppce500", e500plat_machine_init)
+DEFINE_PPC_MACHINE("ppce500", e500plat_machine_init)
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index 32e88b3..40c050d 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -510,9 +510,9 @@ static int core99_kvm_type(const char *arg)
return 2;
}
-static void core99_machine_class_init(ObjectClass *oc, void *data)
+static void core99_machine_init(PPCMachineClass *pmc)
{
- MachineClass *mc = MACHINE_CLASS(oc);
+ MachineClass *mc = MACHINE_CLASS(pmc);
mc->desc = "Mac99 based PowerMAC";
mc->init = ppc_core99_init;
@@ -521,15 +521,4 @@ static void core99_machine_class_init(ObjectClass *oc, void *data)
mc->kvm_type = core99_kvm_type;
}
-static const TypeInfo core99_machine_info = {
- .name = MACHINE_TYPE_NAME("mac99"),
- .parent = TYPE_MACHINE,
- .class_init = core99_machine_class_init,
-};
-
-static void mac_machine_register_types(void)
-{
- type_register_static(&core99_machine_info);
-}
-
-type_init(mac_machine_register_types)
+DEFINE_PPC_MACHINE("mac99", core99_machine_init)
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index a9bb1c2..334768a 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -363,8 +363,10 @@ static int heathrow_kvm_type(const char *arg)
return 2;
}
-static void heathrow_machine_init(MachineClass *mc)
+static void heathrow_machine_init(PPCMachineClass *pmc)
{
+ MachineClass *mc = MACHINE_CLASS(pmc);
+
mc->desc = "Heathrow based PowerMAC";
mc->init = ppc_heathrow_init;
mc->max_cpus = MAX_CPUS;
@@ -376,4 +378,4 @@ static void heathrow_machine_init(MachineClass *mc)
mc->kvm_type = heathrow_kvm_type;
}
-DEFINE_MACHINE("g3beige", heathrow_machine_init)
+DEFINE_PPC_MACHINE("g3beige", heathrow_machine_init)
diff --git a/hw/ppc/mpc8544ds.c b/hw/ppc/mpc8544ds.c
index 27b8289..09af3b1 100644
--- a/hw/ppc/mpc8544ds.c
+++ b/hw/ppc/mpc8544ds.c
@@ -14,6 +14,7 @@
#include "e500.h"
#include "hw/boards.h"
#include "sysemu/device_tree.h"
+#include "hw/ppc/ppc.h"
#include "hw/ppc/openpic.h"
#include "qemu/error-report.h"
@@ -50,11 +51,13 @@ static void mpc8544ds_init(MachineState *machine)
}
-static void ppce500_machine_init(MachineClass *mc)
+static void ppce500_machine_init(PPCMachineClass *pmc)
{
+ MachineClass *mc = MACHINE_CLASS(pmc);
+
mc->desc = "mpc8544ds";
mc->init = mpc8544ds_init;
mc->max_cpus = 15;
}
-DEFINE_MACHINE("mpc8544ds", ppce500_machine_init)
+DEFINE_PPC_MACHINE("mpc8544ds", ppce500_machine_init)
diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index 4b2f07a..05d9578 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -373,19 +373,15 @@ static void ref405ep_init(MachineState *machine)
#endif
}
-static void ref405ep_class_init(ObjectClass *oc, void *data)
+static void ref405ep_machine_init(PPCMachineClass *pmc)
{
- MachineClass *mc = MACHINE_CLASS(oc);
+ MachineClass *mc = MACHINE_CLASS(pmc);
mc->desc = "ref405ep";
mc->init = ref405ep_init;
}
-static const TypeInfo ref405ep_type = {
- .name = MACHINE_TYPE_NAME("ref405ep"),
- .parent = TYPE_MACHINE,
- .class_init = ref405ep_class_init,
-};
+DEFINE_PPC_MACHINE("ref405ep", ref405ep_machine_init)
/*****************************************************************************/
/* AMCC Taihu evaluation board */
@@ -641,24 +637,12 @@ static void taihu_405ep_init(MachineState *machine)
#endif
}
-static void taihu_class_init(ObjectClass *oc, void *data)
+static void taihu_machine_init(PPCMachineClass *pmc)
{
- MachineClass *mc = MACHINE_CLASS(oc);
+ MachineClass *mc = MACHINE_CLASS(pmc);
mc->desc = "taihu";
mc->init = taihu_405ep_init;
}
-static const TypeInfo taihu_type = {
- .name = MACHINE_TYPE_NAME("taihu"),
- .parent = TYPE_MACHINE,
- .class_init = taihu_class_init,
-};
-
-static void ppc405_machine_init(void)
-{
- type_register_static(&ref405ep_type);
- type_register_static(&taihu_type);
-}
-
-type_init(ppc405_machine_init)
+DEFINE_PPC_MACHINE("taihu", taihu_machine_init)
diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
index 5c535b1..1aa6011 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -291,10 +291,12 @@ static void bamboo_init(MachineState *machine)
}
}
-static void bamboo_machine_init(MachineClass *mc)
+static void bamboo_machine_init(PPCMachineClass *pmc)
{
+ MachineClass *mc = MACHINE_CLASS(pmc);
+
mc->desc = "bamboo";
mc->init = bamboo_init;
}
-DEFINE_MACHINE("bamboo", bamboo_machine_init)
+DEFINE_PPC_MACHINE("bamboo", bamboo_machine_init)
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index 3ffb85e..70c671e 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -668,12 +668,14 @@ static void ppc_prep_init(MachineState *machine)
graphic_width, graphic_height, graphic_depth);
}
-static void prep_machine_init(MachineClass *mc)
+static void prep_machine_init(PPCMachineClass *pmc)
{
+ MachineClass *mc = MACHINE_CLASS(pmc);
+
mc->desc = "PowerPC PREP platform";
mc->init = ppc_prep_init;
mc->max_cpus = MAX_CPUS;
mc->default_boot_order = "cad";
}
-DEFINE_MACHINE("prep", prep_machine_init)
+DEFINE_PPC_MACHINE("prep", prep_machine_init)
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index e7be21e..71f0821 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -2296,7 +2296,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
static const TypeInfo spapr_machine_info = {
.name = TYPE_SPAPR_MACHINE,
- .parent = TYPE_MACHINE,
+ .parent = TYPE_PPC_MACHINE,
.abstract = true,
.instance_size = sizeof(sPAPRMachineState),
.instance_init = spapr_machine_initfn,
diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c
index b807a08..865328a 100644
--- a/hw/ppc/virtex_ml507.c
+++ b/hw/ppc/virtex_ml507.c
@@ -299,10 +299,12 @@ static void virtex_init(MachineState *machine)
env->load_info = &boot_info;
}
-static void virtex_machine_init(MachineClass *mc)
+static void virtex_machine_init(PPCMachineClass *pmc)
{
+ MachineClass *mc = MACHINE_CLASS(pmc);
+
mc->desc = "Xilinx Virtex ML507 reference design";
mc->init = virtex_init;
}
-DEFINE_MACHINE("virtex-ml507", virtex_machine_init)
+DEFINE_PPC_MACHINE("virtex-ml507", virtex_machine_init)
diff --git a/include/hw/ppc/ppc.h b/include/hw/ppc/ppc.h
index f1be147..dd085e9 100644
--- a/include/hw/ppc/ppc.h
+++ b/include/hw/ppc/ppc.h
@@ -16,7 +16,26 @@ struct PPCMachineClass {
#define TYPE_PPC_MACHINE "generic-ppc-machine"
#define PPC_MACHINE(obj) \
OBJECT_CHECK(PPCMachineState, (obj), TYPE_PPC_MACHINE)
-
+#define PPC_MACHINE_CLASS(klass) \
+ OBJECT_CLASS_CHECK(PPCMachineClass, (klass), TYPE_PPC_MACHINE)
+
+#define DEFINE_PPC_MACHINE(namestr, machine_initfn) \
+ static void machine_initfn##_class_init(ObjectClass *oc, void *data) \
+ { \
+ PPCMachineClass *mc = PPC_MACHINE_CLASS(oc); \
+ machine_initfn(mc); \
+ } \
+ static const TypeInfo machine_initfn##_typeinfo = { \
+ .name = MACHINE_TYPE_NAME(namestr), \
+ .parent = TYPE_PPC_MACHINE, \
+ .class_init = machine_initfn##_class_init, \
+ }; \
+ static void machine_initfn##_register_types(void) \
+ { \
+ type_register_static(&machine_initfn##_typeinfo); \
+ } \
+ type_init(machine_initfn##_register_types)
+
void ppc_set_irq(PowerPCCPU *cpu, int n_IRQ, int level);
/* PowerPC hardware exceptions management helpers */
--
1.7.10.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [RFC 3/4] target-ppc: synchronise tb_offset with KVM host on machine start
2016-04-07 15:23 [Qemu-devel] [RFC 0/4] target-ppc: handle KVM timebase migration Mark Cave-Ayland
2016-04-07 15:23 ` [Qemu-devel] [RFC 1/4] target-ppc: introduce PPCMachineClass and PPCMachineState Mark Cave-Ayland
2016-04-07 15:23 ` [Qemu-devel] [RFC 2/4] target-ppc: derive all PPC machine classes to have PPCMachineClass as their superclass Mark Cave-Ayland
@ 2016-04-07 15:23 ` Mark Cave-Ayland
2016-04-15 5:23 ` David Gibson
2016-04-07 15:23 ` [Qemu-devel] [RFC 4/4] target-ppc: hack to remove existing timebase migration code for testing Mark Cave-Ayland
2016-04-15 5:27 ` [Qemu-devel] [RFC 0/4] target-ppc: handle KVM timebase migration David Gibson
4 siblings, 1 reply; 9+ messages in thread
From: Mark Cave-Ayland @ 2016-04-07 15:23 UTC (permalink / raw)
To: david, aik, agraf, qemu-ppc, qemu-devel
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 <mark.cave-ayland@ilande.co.uk>
---
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
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [RFC 4/4] target-ppc: hack to remove existing timebase migration code for testing
2016-04-07 15:23 [Qemu-devel] [RFC 0/4] target-ppc: handle KVM timebase migration Mark Cave-Ayland
` (2 preceding siblings ...)
2016-04-07 15:23 ` [Qemu-devel] [RFC 3/4] target-ppc: synchronise tb_offset with KVM host on machine start Mark Cave-Ayland
@ 2016-04-07 15:23 ` Mark Cave-Ayland
2016-04-15 5:27 ` [Qemu-devel] [RFC 0/4] target-ppc: handle KVM timebase migration David Gibson
4 siblings, 0 replies; 9+ messages in thread
From: Mark Cave-Ayland @ 2016-04-07 15:23 UTC (permalink / raw)
To: david, aik, agraf, qemu-ppc, qemu-devel
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
hw/ppc/ppc.c | 45 +++++++--------------------------------------
1 file changed, 7 insertions(+), 38 deletions(-)
diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index 39e15b1..053e600 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -858,47 +858,15 @@ static void timebase_pre_save(void *opaque)
static int timebase_post_load(void *opaque, int version_id)
{
- PPCTimebase *tb_remote = opaque;
- CPUState *cpu;
- PowerPCCPU *first_ppc_cpu = POWERPC_CPU(first_cpu);
- int64_t tb_off_adj, tb_off, ns_diff;
- int64_t migration_duration_ns, migration_duration_tb, guest_tb, host_ns;
- unsigned long freq;
-
- if (!first_ppc_cpu->env.tb_env) {
- error_report("No timebase object");
- return -1;
- }
-
- freq = first_ppc_cpu->env.tb_env->tb_freq;
- /*
- * Calculate timebase on the destination side of migration.
- * The destination timebase must be not less than the source timebase.
- * We try to adjust timebase by downtime if host clocks are not
- * too much out of sync (1 second for now).
- */
- host_ns = qemu_clock_get_ns(QEMU_CLOCK_HOST);
- ns_diff = MAX(0, host_ns - tb_remote->time_of_the_day_ns);
- migration_duration_ns = MIN(NANOSECONDS_PER_SECOND, ns_diff);
- migration_duration_tb = muldiv64(migration_duration_ns, freq,
- NANOSECONDS_PER_SECOND);
- guest_tb = tb_remote->guest_timebase + MIN(0, migration_duration_tb);
-
- tb_off_adj = guest_tb - cpu_get_host_ticks();
-
- tb_off = first_ppc_cpu->env.tb_env->tb_offset;
- trace_ppc_tb_adjust(tb_off, tb_off_adj, tb_off_adj - tb_off,
- (tb_off_adj - tb_off) / freq);
-
- /* Set new offset to all CPUs */
- CPU_FOREACH(cpu) {
- PowerPCCPU *pcpu = POWERPC_CPU(cpu);
- pcpu->env.tb_env->tb_offset = tb_off_adj;
- }
-
+ /* Now handled via ppc_machine_change_state() */
return 0;
}
+static bool timebase_needed(void *opaque)
+{
+ return false;
+}
+
const VMStateDescription vmstate_ppc_timebase = {
.name = "timebase",
.version_id = 1,
@@ -906,6 +874,7 @@ const VMStateDescription vmstate_ppc_timebase = {
.minimum_version_id_old = 1,
.pre_save = timebase_pre_save,
.post_load = timebase_post_load,
+ .needed = timebase_needed,
.fields = (VMStateField []) {
VMSTATE_UINT64(guest_timebase, PPCTimebase),
VMSTATE_INT64(time_of_the_day_ns, PPCTimebase),
--
1.7.10.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [RFC 1/4] target-ppc: introduce PPCMachineClass and PPCMachineState
2016-04-07 15:23 ` [Qemu-devel] [RFC 1/4] target-ppc: introduce PPCMachineClass and PPCMachineState Mark Cave-Ayland
@ 2016-04-15 5:13 ` David Gibson
0 siblings, 0 replies; 9+ messages in thread
From: David Gibson @ 2016-04-15 5:13 UTC (permalink / raw)
To: Mark Cave-Ayland; +Cc: aik, agraf, qemu-ppc, qemu-devel
[-- Attachment #1: Type: text/plain, Size: 2901 bytes --]
On Thu, Apr 07, 2016 at 04:23:11PM +0100, Mark Cave-Ayland wrote:
> Introduce PPCMachineClass in anticipation of making it the superclass for
> all PPC machines.
>
> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
> ---
> hw/ppc/ppc.c | 16 ++++++++++++++++
> include/hw/ppc/ppc.h | 16 ++++++++++++++++
> include/qemu/typedefs.h | 2 ++
> 3 files changed, 34 insertions(+)
>
> diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
> index 38ff2e1..ccdca5d 100644
> --- a/hw/ppc/ppc.c
> +++ b/hw/ppc/ppc.c
> @@ -1343,3 +1343,19 @@ PowerPCCPU *ppc_get_vcpu_by_dt_id(int cpu_dt_id)
>
> return NULL;
> }
> +
> +/* Generic PPC machine */
> +static const TypeInfo ppc_machine_info = {
> + .name = TYPE_PPC_MACHINE,
> + .parent = TYPE_MACHINE,
> + .abstract = true,
> + .instance_size = sizeof(PPCMachineState),
> + .class_size = sizeof(PPCMachineClass)
> +};
> +
> +static void ppc_machine_register_types(void)
> +{
> + type_register_static(&ppc_machine_info);
> +}
> +
> +type_init(ppc_machine_register_types)
> diff --git a/include/hw/ppc/ppc.h b/include/hw/ppc/ppc.h
> index 14efd0c..f1be147 100644
> --- a/include/hw/ppc/ppc.h
> +++ b/include/hw/ppc/ppc.h
> @@ -1,6 +1,22 @@
> #ifndef HW_PPC_H
> #define HW_PPC_H 1
>
> +#include "hw/boards.h"
> +
> +struct PPCMachineState {
> + /*< private >*/
> + MachineState parent_obj;
> +};
> +
> +struct PPCMachineClass {
> + /*< private >*/
> + MachineClass parent_class;
> +};
It's normal QOM practice not to create actual typedefs if there's
nothing in them except the parent object. I believe you're adding
something to one of these in subsequent patches, in which case it's ok
to create it here, but I don't think that's true for both of them.
> +#define TYPE_PPC_MACHINE "generic-ppc-machine"
> +#define PPC_MACHINE(obj) \
> + OBJECT_CHECK(PPCMachineState, (obj), TYPE_PPC_MACHINE)
> +
> void ppc_set_irq(PowerPCCPU *cpu, int n_IRQ, int level);
>
> /* PowerPC hardware exceptions management helpers */
> diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
> index 1dcf6f5..73fbad5 100644
> --- a/include/qemu/typedefs.h
> +++ b/include/qemu/typedefs.h
> @@ -73,6 +73,8 @@ typedef struct PCMachineState PCMachineState;
> typedef struct PCMCIACardState PCMCIACardState;
> typedef struct PixelFormat PixelFormat;
> typedef struct PostcopyDiscardState PostcopyDiscardState;
> +typedef struct PPCMachineClass PPCMachineClass;
> +typedef struct PPCMachineState PPCMachineState;
> typedef struct Property Property;
> typedef struct PropertyInfo PropertyInfo;
> typedef struct QEMUBH QEMUBH;
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [RFC 2/4] target-ppc: derive all PPC machine classes to have PPCMachineClass as their superclass
2016-04-07 15:23 ` [Qemu-devel] [RFC 2/4] target-ppc: derive all PPC machine classes to have PPCMachineClass as their superclass Mark Cave-Ayland
@ 2016-04-15 5:17 ` David Gibson
0 siblings, 0 replies; 9+ messages in thread
From: David Gibson @ 2016-04-15 5:17 UTC (permalink / raw)
To: Mark Cave-Ayland; +Cc: aik, agraf, qemu-ppc, qemu-devel
[-- Attachment #1: Type: text/plain, Size: 10649 bytes --]
On Thu, Apr 07, 2016 at 04:23:12PM +0100, Mark Cave-Ayland wrote:
> Using a new DEFINE_PPC_MACHINE macro, make sure that all PPC machines now derive from
> the new PPCMachineClass.
> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Hmm.. I'm a little bit dubious about this, since the timebase sync
will be pretty much the *only* thing in common between ppc machine
times, and even that's only by convention, not anything fundamental to
the ISA. (And I want to discourage the misconception - all too common
in x86 land - that platform details are largely determined by ISA).
I might be convinced, but I'd like to also consider the option of just
making the timebase sync stuff a bunch of helpers that each machine
type can use.
> ---
> hw/ppc/e500plat.c | 7 +++++--
> hw/ppc/mac_newworld.c | 17 +++--------------
> hw/ppc/mac_oldworld.c | 6 ++++--
> hw/ppc/mpc8544ds.c | 7 +++++--
> hw/ppc/ppc405_boards.c | 28 ++++++----------------------
> hw/ppc/ppc440_bamboo.c | 6 ++++--
> hw/ppc/prep.c | 6 ++++--
> hw/ppc/spapr.c | 2 +-
> hw/ppc/virtex_ml507.c | 6 ++++--
> include/hw/ppc/ppc.h | 21 ++++++++++++++++++++-
> 10 files changed, 56 insertions(+), 50 deletions(-)
>
> diff --git a/hw/ppc/e500plat.c b/hw/ppc/e500plat.c
> index b00565c..6e4cf05 100644
> --- a/hw/ppc/e500plat.c
> +++ b/hw/ppc/e500plat.c
> @@ -15,6 +15,7 @@
> #include "hw/boards.h"
> #include "sysemu/device_tree.h"
> #include "hw/pci/pci.h"
> +#include "hw/ppc/ppc.h"
> #include "hw/ppc/openpic.h"
> #include "kvm_ppc.h"
>
> @@ -57,12 +58,14 @@ static void e500plat_init(MachineState *machine)
> ppce500_init(machine, ¶ms);
> }
>
> -static void e500plat_machine_init(MachineClass *mc)
> +static void e500plat_machine_init(PPCMachineClass *pmc)
> {
> + MachineClass *mc = MACHINE_CLASS(pmc);
> +
> mc->desc = "generic paravirt e500 platform";
> mc->init = e500plat_init;
> mc->max_cpus = 32;
> mc->has_dynamic_sysbus = true;
> }
>
> -DEFINE_MACHINE("ppce500", e500plat_machine_init)
> +DEFINE_PPC_MACHINE("ppce500", e500plat_machine_init)
> diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
> index 32e88b3..40c050d 100644
> --- a/hw/ppc/mac_newworld.c
> +++ b/hw/ppc/mac_newworld.c
> @@ -510,9 +510,9 @@ static int core99_kvm_type(const char *arg)
> return 2;
> }
>
> -static void core99_machine_class_init(ObjectClass *oc, void *data)
> +static void core99_machine_init(PPCMachineClass *pmc)
> {
> - MachineClass *mc = MACHINE_CLASS(oc);
> + MachineClass *mc = MACHINE_CLASS(pmc);
>
> mc->desc = "Mac99 based PowerMAC";
> mc->init = ppc_core99_init;
> @@ -521,15 +521,4 @@ static void core99_machine_class_init(ObjectClass *oc, void *data)
> mc->kvm_type = core99_kvm_type;
> }
>
> -static const TypeInfo core99_machine_info = {
> - .name = MACHINE_TYPE_NAME("mac99"),
> - .parent = TYPE_MACHINE,
> - .class_init = core99_machine_class_init,
> -};
> -
> -static void mac_machine_register_types(void)
> -{
> - type_register_static(&core99_machine_info);
> -}
> -
> -type_init(mac_machine_register_types)
> +DEFINE_PPC_MACHINE("mac99", core99_machine_init)
> diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
> index a9bb1c2..334768a 100644
> --- a/hw/ppc/mac_oldworld.c
> +++ b/hw/ppc/mac_oldworld.c
> @@ -363,8 +363,10 @@ static int heathrow_kvm_type(const char *arg)
> return 2;
> }
>
> -static void heathrow_machine_init(MachineClass *mc)
> +static void heathrow_machine_init(PPCMachineClass *pmc)
> {
> + MachineClass *mc = MACHINE_CLASS(pmc);
> +
> mc->desc = "Heathrow based PowerMAC";
> mc->init = ppc_heathrow_init;
> mc->max_cpus = MAX_CPUS;
> @@ -376,4 +378,4 @@ static void heathrow_machine_init(MachineClass *mc)
> mc->kvm_type = heathrow_kvm_type;
> }
>
> -DEFINE_MACHINE("g3beige", heathrow_machine_init)
> +DEFINE_PPC_MACHINE("g3beige", heathrow_machine_init)
> diff --git a/hw/ppc/mpc8544ds.c b/hw/ppc/mpc8544ds.c
> index 27b8289..09af3b1 100644
> --- a/hw/ppc/mpc8544ds.c
> +++ b/hw/ppc/mpc8544ds.c
> @@ -14,6 +14,7 @@
> #include "e500.h"
> #include "hw/boards.h"
> #include "sysemu/device_tree.h"
> +#include "hw/ppc/ppc.h"
> #include "hw/ppc/openpic.h"
> #include "qemu/error-report.h"
>
> @@ -50,11 +51,13 @@ static void mpc8544ds_init(MachineState *machine)
> }
>
>
> -static void ppce500_machine_init(MachineClass *mc)
> +static void ppce500_machine_init(PPCMachineClass *pmc)
> {
> + MachineClass *mc = MACHINE_CLASS(pmc);
> +
> mc->desc = "mpc8544ds";
> mc->init = mpc8544ds_init;
> mc->max_cpus = 15;
> }
>
> -DEFINE_MACHINE("mpc8544ds", ppce500_machine_init)
> +DEFINE_PPC_MACHINE("mpc8544ds", ppce500_machine_init)
> diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
> index 4b2f07a..05d9578 100644
> --- a/hw/ppc/ppc405_boards.c
> +++ b/hw/ppc/ppc405_boards.c
> @@ -373,19 +373,15 @@ static void ref405ep_init(MachineState *machine)
> #endif
> }
>
> -static void ref405ep_class_init(ObjectClass *oc, void *data)
> +static void ref405ep_machine_init(PPCMachineClass *pmc)
> {
> - MachineClass *mc = MACHINE_CLASS(oc);
> + MachineClass *mc = MACHINE_CLASS(pmc);
>
> mc->desc = "ref405ep";
> mc->init = ref405ep_init;
> }
>
> -static const TypeInfo ref405ep_type = {
> - .name = MACHINE_TYPE_NAME("ref405ep"),
> - .parent = TYPE_MACHINE,
> - .class_init = ref405ep_class_init,
> -};
> +DEFINE_PPC_MACHINE("ref405ep", ref405ep_machine_init)
>
> /*****************************************************************************/
> /* AMCC Taihu evaluation board */
> @@ -641,24 +637,12 @@ static void taihu_405ep_init(MachineState *machine)
> #endif
> }
>
> -static void taihu_class_init(ObjectClass *oc, void *data)
> +static void taihu_machine_init(PPCMachineClass *pmc)
> {
> - MachineClass *mc = MACHINE_CLASS(oc);
> + MachineClass *mc = MACHINE_CLASS(pmc);
>
> mc->desc = "taihu";
> mc->init = taihu_405ep_init;
> }
>
> -static const TypeInfo taihu_type = {
> - .name = MACHINE_TYPE_NAME("taihu"),
> - .parent = TYPE_MACHINE,
> - .class_init = taihu_class_init,
> -};
> -
> -static void ppc405_machine_init(void)
> -{
> - type_register_static(&ref405ep_type);
> - type_register_static(&taihu_type);
> -}
> -
> -type_init(ppc405_machine_init)
> +DEFINE_PPC_MACHINE("taihu", taihu_machine_init)
> diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
> index 5c535b1..1aa6011 100644
> --- a/hw/ppc/ppc440_bamboo.c
> +++ b/hw/ppc/ppc440_bamboo.c
> @@ -291,10 +291,12 @@ static void bamboo_init(MachineState *machine)
> }
> }
>
> -static void bamboo_machine_init(MachineClass *mc)
> +static void bamboo_machine_init(PPCMachineClass *pmc)
> {
> + MachineClass *mc = MACHINE_CLASS(pmc);
> +
> mc->desc = "bamboo";
> mc->init = bamboo_init;
> }
>
> -DEFINE_MACHINE("bamboo", bamboo_machine_init)
> +DEFINE_PPC_MACHINE("bamboo", bamboo_machine_init)
> diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
> index 3ffb85e..70c671e 100644
> --- a/hw/ppc/prep.c
> +++ b/hw/ppc/prep.c
> @@ -668,12 +668,14 @@ static void ppc_prep_init(MachineState *machine)
> graphic_width, graphic_height, graphic_depth);
> }
>
> -static void prep_machine_init(MachineClass *mc)
> +static void prep_machine_init(PPCMachineClass *pmc)
> {
> + MachineClass *mc = MACHINE_CLASS(pmc);
> +
> mc->desc = "PowerPC PREP platform";
> mc->init = ppc_prep_init;
> mc->max_cpus = MAX_CPUS;
> mc->default_boot_order = "cad";
> }
>
> -DEFINE_MACHINE("prep", prep_machine_init)
> +DEFINE_PPC_MACHINE("prep", prep_machine_init)
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index e7be21e..71f0821 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -2296,7 +2296,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
>
> static const TypeInfo spapr_machine_info = {
> .name = TYPE_SPAPR_MACHINE,
> - .parent = TYPE_MACHINE,
> + .parent = TYPE_PPC_MACHINE,
> .abstract = true,
> .instance_size = sizeof(sPAPRMachineState),
> .instance_init = spapr_machine_initfn,
> diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c
> index b807a08..865328a 100644
> --- a/hw/ppc/virtex_ml507.c
> +++ b/hw/ppc/virtex_ml507.c
> @@ -299,10 +299,12 @@ static void virtex_init(MachineState *machine)
> env->load_info = &boot_info;
> }
>
> -static void virtex_machine_init(MachineClass *mc)
> +static void virtex_machine_init(PPCMachineClass *pmc)
> {
> + MachineClass *mc = MACHINE_CLASS(pmc);
> +
> mc->desc = "Xilinx Virtex ML507 reference design";
> mc->init = virtex_init;
> }
>
> -DEFINE_MACHINE("virtex-ml507", virtex_machine_init)
> +DEFINE_PPC_MACHINE("virtex-ml507", virtex_machine_init)
> diff --git a/include/hw/ppc/ppc.h b/include/hw/ppc/ppc.h
> index f1be147..dd085e9 100644
> --- a/include/hw/ppc/ppc.h
> +++ b/include/hw/ppc/ppc.h
> @@ -16,7 +16,26 @@ struct PPCMachineClass {
> #define TYPE_PPC_MACHINE "generic-ppc-machine"
> #define PPC_MACHINE(obj) \
> OBJECT_CHECK(PPCMachineState, (obj), TYPE_PPC_MACHINE)
> -
> +#define PPC_MACHINE_CLASS(klass) \
> + OBJECT_CLASS_CHECK(PPCMachineClass, (klass), TYPE_PPC_MACHINE)
> +
> +#define DEFINE_PPC_MACHINE(namestr, machine_initfn) \
> + static void machine_initfn##_class_init(ObjectClass *oc, void *data) \
> + { \
> + PPCMachineClass *mc = PPC_MACHINE_CLASS(oc); \
> + machine_initfn(mc); \
> + } \
> + static const TypeInfo machine_initfn##_typeinfo = { \
> + .name = MACHINE_TYPE_NAME(namestr), \
> + .parent = TYPE_PPC_MACHINE, \
> + .class_init = machine_initfn##_class_init, \
> + }; \
> + static void machine_initfn##_register_types(void) \
> + { \
> + type_register_static(&machine_initfn##_typeinfo); \
> + } \
> + type_init(machine_initfn##_register_types)
> +
> void ppc_set_irq(PowerPCCPU *cpu, int n_IRQ, int level);
>
> /* PowerPC hardware exceptions management helpers */
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [RFC 3/4] target-ppc: synchronise tb_offset with KVM host on machine start
2016-04-07 15:23 ` [Qemu-devel] [RFC 3/4] target-ppc: synchronise tb_offset with KVM host on machine start Mark Cave-Ayland
@ 2016-04-15 5:23 ` David Gibson
0 siblings, 0 replies; 9+ messages in thread
From: David Gibson @ 2016-04-15 5:23 UTC (permalink / raw)
To: Mark Cave-Ayland; +Cc: aik, agraf, qemu-ppc, qemu-devel
[-- Attachment #1: Type: text/plain, Size: 3503 bytes --]
On Thu, Apr 07, 2016 at 04:23:13PM +0100, Mark Cave-Ayland wrote:
> 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 <mark.cave-ayland@ilande.co.uk>
The upshot of this is to make the timebase effectively stop when the
guest is stopped, yes? It's not entirely clear that that's the
correct choice.
The timebase is supposed to represent wall clock time. For debugging
of a virtual machine it's sometimes useful to stop it, but I don't
know that that should be the default behaviour.
I'm also not clear if this includes stops due to migration or
savevm/restore or anything else not explicitly requested as a stop by
the user / management layer. Those cases absolutely should not stop
the timebase, since that will cause the guest's system clock to get
out of sync with wall clock time.
I'm wondering if we're going to need another option that controls if
the timebase is tied to QEMU_CLOCK_REALTIME or QEMU_CLOCK_VIRTUAL
(analagous to clock=host or clock=vm for the RTC).
> ---
> 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)
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [RFC 0/4] target-ppc: handle KVM timebase migration
2016-04-07 15:23 [Qemu-devel] [RFC 0/4] target-ppc: handle KVM timebase migration Mark Cave-Ayland
` (3 preceding siblings ...)
2016-04-07 15:23 ` [Qemu-devel] [RFC 4/4] target-ppc: hack to remove existing timebase migration code for testing Mark Cave-Ayland
@ 2016-04-15 5:27 ` David Gibson
4 siblings, 0 replies; 9+ messages in thread
From: David Gibson @ 2016-04-15 5:27 UTC (permalink / raw)
To: Mark Cave-Ayland; +Cc: aik, agraf, qemu-ppc, qemu-devel
[-- Attachment #1: Type: text/plain, Size: 3515 bytes --]
On Thu, Apr 07, 2016 at 04:23:10PM +0100, Mark Cave-Ayland wrote:
> This RFC series follows on from discussions in the "Migrating decrementer"
> thread relating to handling migration of the timebase and decrementer
> registers for both TCG and KVM. The aim is to provide a consistent virtual
> clock when migrating PPC machines TCG-TCG (already handled) and
> KVM-KVM with both paused and live VMs in a unified manner for all PPC
> machine types.
>
> The existing code to handle timebase migration on PPC has a few issues:
>
> 1) It uses cpu_get_host_ticks() which doesn't work correctly on TCG with
> different host architectures
Yeah, that's just wrong. We should be using qemu_clock_get_ns()
instead.
> 2) tb_offset is calculated from the difference in the host clock between
> source and destination. Thus if the guest is paused then the resulting
> offset is calculated incorrectly since the host clock still runs, regardless
> of the state of the virtual clock.
>
> 3) Due to a typo in the existing implementation (MIN instead of MAX) then
> guest_tb never takes migration_duration_tb into account
The statement above is not correct. The problem is not MIN vs. MAX.
The problem is that it was assuming a 1s limit on downtime during
migration which is Just Plain Wrong - especialy in the case where it's
actually a savevm / restore rather than a live migration.
Having a long downtime shouldn't break the guest's timebase sync with
realtime.
> Patches 1-2 introduce a new PPCMachineClass and derive all the PPC machine
> classes from it, not dissimilar to x86's PCMachineClass.
>
> Patch 3 adds a VM state change hook into PCMachineClass and updates the
> tb_offset from the host when the machine (re)starts as discussed in the
> thread. Note that it may be possible to add the hook to specific machine
> types, however using PPCMachineClass allows all PPC machines to pick up
> this functionality automatically.
>
> Patch 4 temporarily disables the existing timebase migration code to allow
> testing.
>
> Note that this has only been compile-tested on x86 as I have no KVM PPC
> hardware and so it's really an RFC to determine whether this approach can
> work, and to invite testing and discussion from existing KVM PPC users.
>
> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
>
>
> Mark Cave-Ayland (4):
> target-ppc: introduce PPCMachineClass and PPCMachineState
> target-ppc: derive all PPC machine classes to have PPCMachineClass as
> their superclass
> target-ppc: synchronise tb_offset with KVM host on machine start
> target-ppc: hack to remove existing timebase migration code for
> testing
>
> hw/ppc/e500plat.c | 7 +++-
> hw/ppc/mac_newworld.c | 17 ++------
> hw/ppc/mac_oldworld.c | 6 ++-
> hw/ppc/mpc8544ds.c | 7 +++-
> hw/ppc/ppc.c | 100 +++++++++++++++++++++++++++++------------------
> hw/ppc/ppc405_boards.c | 28 +++----------
> hw/ppc/ppc440_bamboo.c | 6 ++-
> hw/ppc/prep.c | 6 ++-
> hw/ppc/spapr.c | 2 +-
> hw/ppc/virtex_ml507.c | 6 ++-
> include/hw/ppc/ppc.h | 35 +++++++++++++++++
> include/qemu/typedefs.h | 2 +
> 12 files changed, 135 insertions(+), 87 deletions(-)
>
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2016-04-15 8:01 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-04-07 15:23 [Qemu-devel] [RFC 0/4] target-ppc: handle KVM timebase migration Mark Cave-Ayland
2016-04-07 15:23 ` [Qemu-devel] [RFC 1/4] target-ppc: introduce PPCMachineClass and PPCMachineState Mark Cave-Ayland
2016-04-15 5:13 ` David Gibson
2016-04-07 15:23 ` [Qemu-devel] [RFC 2/4] target-ppc: derive all PPC machine classes to have PPCMachineClass as their superclass Mark Cave-Ayland
2016-04-15 5:17 ` David Gibson
2016-04-07 15:23 ` [Qemu-devel] [RFC 3/4] target-ppc: synchronise tb_offset with KVM host on machine start Mark Cave-Ayland
2016-04-15 5:23 ` David Gibson
2016-04-07 15:23 ` [Qemu-devel] [RFC 4/4] target-ppc: hack to remove existing timebase migration code for testing Mark Cave-Ayland
2016-04-15 5:27 ` [Qemu-devel] [RFC 0/4] target-ppc: handle KVM timebase migration David Gibson
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).