From: David Gibson <david@gibson.dropbear.id.au>
To: peter.maydell@linaro.org
Cc: agraf@suse.de, qemu-ppc@nongnu.org, qemu-devel@nongnu.org,
mdroth@linux.vnet.ibm.com,
David Gibson <david@gibson.dropbear.id.au>,
Juan Quintela <quintela@redhat.com>,
Dave Gilbert <dgilbert@redhat.com>
Subject: [Qemu-devel] [PULL 02/17] migration: Mark CPU states dirty before incoming migration/loadvm
Date: Tue, 6 Jun 2017 12:51:20 +1000 [thread overview]
Message-ID: <20170606025135.2685-3-david@gibson.dropbear.id.au> (raw)
In-Reply-To: <20170606025135.2685-1-david@gibson.dropbear.id.au>
As a rule, CPU internal state should never be updated when
!cpu->kvm_vcpu_dirty (or the HAX equivalent). If that is done, then
subsequent calls to cpu_synchronize_state() - usually safe and idempotent -
will clobber state.
However, we routinely do this during a loadvm or incoming migration.
Usually this is called shortly after a reset, which will clear all the cpu
dirty flags with cpu_synchronize_all_post_reset(). Nothing is expected
to set the dirty flags again before the cpu state is loaded from the
incoming stream.
This means that it isn't safe to call cpu_synchronize_state() from a
post_load handler, which is non-obvious and potentially inconvenient.
We could cpu_synchronize_all_state() before the loadvm, but that would be
overkill since a) we expect the state to already be synchronized from the
reset and b) we expect to completely rewrite the state with a call to
cpu_synchronize_all_post_init() at the end of qemu_loadvm_state().
To clear this up, this patch introduces cpu_synchronize_pre_loadvm() and
associated helpers, which simply marks the cpu state as dirty without
actually changing anything. i.e. it says we want to discard any existing
KVM (or HAX) state and replace it with what we're going to load.
Cc: Juan Quintela <quintela@redhat.com>
Cc: Dave Gilbert <dgilbert@redhat.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Juan Quintela <quintela@redhat.com>
---
cpus.c | 9 +++++++++
include/sysemu/cpus.h | 1 +
include/sysemu/hax.h | 1 +
include/sysemu/hw_accel.h | 10 ++++++++++
include/sysemu/kvm.h | 1 +
kvm-all.c | 10 ++++++++++
migration/savevm.c | 2 ++
target/i386/hax-all.c | 10 ++++++++++
8 files changed, 44 insertions(+)
diff --git a/cpus.c b/cpus.c
index 516e5cb..6398439 100644
--- a/cpus.c
+++ b/cpus.c
@@ -921,6 +921,15 @@ void cpu_synchronize_all_post_init(void)
}
}
+void cpu_synchronize_all_pre_loadvm(void)
+{
+ CPUState *cpu;
+
+ CPU_FOREACH(cpu) {
+ cpu_synchronize_pre_loadvm(cpu);
+ }
+}
+
static int do_vm_stop(RunState state)
{
int ret = 0;
diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h
index a8053f1..731756d 100644
--- a/include/sysemu/cpus.h
+++ b/include/sysemu/cpus.h
@@ -27,6 +27,7 @@ void qemu_timer_notify_cb(void *opaque, QEMUClockType type);
void cpu_synchronize_all_states(void);
void cpu_synchronize_all_post_reset(void);
void cpu_synchronize_all_post_init(void);
+void cpu_synchronize_all_pre_loadvm(void);
void qtest_clock_warp(int64_t dest);
diff --git a/include/sysemu/hax.h b/include/sysemu/hax.h
index d9f0239..232a68a 100644
--- a/include/sysemu/hax.h
+++ b/include/sysemu/hax.h
@@ -33,6 +33,7 @@ int hax_populate_ram(uint64_t va, uint32_t size);
void hax_cpu_synchronize_state(CPUState *cpu);
void hax_cpu_synchronize_post_reset(CPUState *cpu);
void hax_cpu_synchronize_post_init(CPUState *cpu);
+void hax_cpu_synchronize_pre_loadvm(CPUState *cpu);
#ifdef CONFIG_HAX
diff --git a/include/sysemu/hw_accel.h b/include/sysemu/hw_accel.h
index c9b3105..469ffda 100644
--- a/include/sysemu/hw_accel.h
+++ b/include/sysemu/hw_accel.h
@@ -45,4 +45,14 @@ static inline void cpu_synchronize_post_init(CPUState *cpu)
}
}
+static inline void cpu_synchronize_pre_loadvm(CPUState *cpu)
+{
+ if (kvm_enabled()) {
+ kvm_cpu_synchronize_pre_loadvm(cpu);
+ }
+ if (hax_enabled()) {
+ hax_cpu_synchronize_pre_loadvm(cpu);
+ }
+}
+
#endif /* QEMU_HW_ACCEL_H */
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 5cc83f2..a45c145 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -459,6 +459,7 @@ int kvm_physical_memory_addr_from_host(KVMState *s, void *ram_addr,
void kvm_cpu_synchronize_state(CPUState *cpu);
void kvm_cpu_synchronize_post_reset(CPUState *cpu);
void kvm_cpu_synchronize_post_init(CPUState *cpu);
+void kvm_cpu_synchronize_pre_loadvm(CPUState *cpu);
void kvm_init_cpu_signals(CPUState *cpu);
diff --git a/kvm-all.c b/kvm-all.c
index 7df27c8..494b925 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1896,6 +1896,16 @@ void kvm_cpu_synchronize_post_init(CPUState *cpu)
run_on_cpu(cpu, do_kvm_cpu_synchronize_post_init, RUN_ON_CPU_NULL);
}
+static void do_kvm_cpu_synchronize_pre_loadvm(CPUState *cpu, run_on_cpu_data arg)
+{
+ cpu->kvm_vcpu_dirty = true;
+}
+
+void kvm_cpu_synchronize_pre_loadvm(CPUState *cpu)
+{
+ run_on_cpu(cpu, do_kvm_cpu_synchronize_pre_loadvm, RUN_ON_CPU_NULL);
+}
+
#ifdef KVM_HAVE_MCE_INJECTION
static __thread void *pending_sigbus_addr;
static __thread int pending_sigbus_code;
diff --git a/migration/savevm.c b/migration/savevm.c
index 035c127..1993ca2 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -1999,6 +1999,8 @@ int qemu_loadvm_state(QEMUFile *f)
}
}
+ cpu_synchronize_all_pre_loadvm();
+
ret = qemu_loadvm_state_main(f, mis);
qemu_event_set(&mis->main_thread_load_event);
diff --git a/target/i386/hax-all.c b/target/i386/hax-all.c
index 7346931..097db5c 100644
--- a/target/i386/hax-all.c
+++ b/target/i386/hax-all.c
@@ -635,6 +635,16 @@ void hax_cpu_synchronize_post_init(CPUState *cpu)
run_on_cpu(cpu, do_hax_cpu_synchronize_post_init, RUN_ON_CPU_NULL);
}
+static void do_hax_cpu_synchronize_pre_loadvm(CPUState *cpu, run_on_cpu_data arg)
+{
+ cpu->hax_vcpu_dirty = true;
+}
+
+void hax_cpu_synchronize_pre_loadvm(CPUState *cpu)
+{
+ run_on_cpu(cpu, do_hax_cpu_synchronize_pre_loadvm, RUN_ON_CPU_NULL);
+}
+
int hax_smp_cpu_exec(CPUState *cpu)
{
CPUArchState *env = (CPUArchState *) (cpu->env_ptr);
--
2.9.4
next prev parent reply other threads:[~2017-06-06 2:51 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-06-06 2:51 [Qemu-devel] [PULL 00/17] ppc-for-2.10 queue 20170606 David Gibson
2017-06-06 2:51 ` [Qemu-devel] [PULL 01/17] migration: remove register_savevm() David Gibson
2017-06-06 17:49 ` Peter Maydell
2017-06-06 22:14 ` Paolo Bonzini
2017-06-07 8:07 ` Juan Quintela
2017-06-06 2:51 ` David Gibson [this message]
2017-06-06 2:51 ` [Qemu-devel] [PULL 03/17] spapr: Move DRC RTAS calls into spapr_drc.c David Gibson
2017-06-06 2:51 ` [Qemu-devel] [PULL 04/17] spapr: Abolish DRC get_fdt method David Gibson
2017-06-06 2:51 ` [Qemu-devel] [PULL 05/17] spapr: Abolish DRC set_configured method David Gibson
2017-06-06 2:51 ` [Qemu-devel] [PULL 06/17] spapr: Make DRC get_index and get_type methods into plain functions David Gibson
2017-06-06 2:51 ` [Qemu-devel] [PULL 07/17] target-ppc: Fix openpic timer read register offset David Gibson
2017-06-06 2:51 ` [Qemu-devel] [PULL 08/17] target/ppc: Fixup set_spr error in h_register_process_table David Gibson
2017-06-06 2:51 ` [Qemu-devel] [PULL 09/17] spapr_nvram: Check return value from blk_getlength() David Gibson
2017-06-06 2:51 ` [Qemu-devel] [PULL 10/17] ppc/pnv: check the return value of fdt_setprop() David Gibson
2017-06-06 2:51 ` [Qemu-devel] [PULL 11/17] spapr: Allow boot from vhost-*-scsi backends David Gibson
2017-06-06 2:51 ` [Qemu-devel] [PULL 12/17] spapr/drc: don't migrate DRC of cold-plugged CPUs and LMBs David Gibson
2017-06-06 2:51 ` [Qemu-devel] [PULL 13/17] spapr: Introduce DRC subclasses David Gibson
2017-06-06 2:51 ` [Qemu-devel] [PULL 14/17] spapr: Clean up spapr_dr_connector_by_*() David Gibson
2017-06-06 2:51 ` [Qemu-devel] [PULL 15/17] spapr: Move configure-connector state into DRC David Gibson
2017-06-06 2:51 ` [Qemu-devel] [PULL 16/17] spapr: Eliminate spapr_drc_get_type_str() David Gibson
2017-06-06 2:51 ` [Qemu-devel] [PULL 17/17] spapr: Remove some non-useful properties on DRC objects David Gibson
2017-06-06 14:37 ` [Qemu-devel] [PULL 00/17] ppc-for-2.10 queue 20170606 Peter Maydell
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=20170606025135.2685-3-david@gibson.dropbear.id.au \
--to=david@gibson.dropbear.id.au \
--cc=agraf@suse.de \
--cc=dgilbert@redhat.com \
--cc=mdroth@linux.vnet.ibm.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=qemu-ppc@nongnu.org \
--cc=quintela@redhat.com \
/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).