On 04/04/2016 06:49, David Gibson wrote: > There are currently 3 calls to qemu_system_reset() in vl.c. Two of them > are immediately preceded by a cpu_synchronize_all_states9) and the > remaining one should be. > > The one which doesn't is the very first reset called directly from main(). > Without a cpu_synchronize_all_states(), kvm_vcpu_dirty is false at this > point from the earlier cpu_synchronize_all_post_init(). That's incorrect > because the reset path is quite likely to update the CPU state, and that > updated state should be pushed back to KVM, not overwritten with stale > data pushed to KVM immediately after init. > > This patch moves the call to cpu_synchronize_all_states() into > qemu_system_reset() for safety, so it is always called. AFAICT this should > be safe for the handful of callers outside vl.c - these all appear to be in > places where the cpu state is already synchronized so the extra call > will be a no-op. > > Signed-off-by: David Gibson <da...@gibson.dropbear.id.au> > --- > vl.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > This fixes a real but on ppc - the incorrect state of kvm_vcpu_dirty > means that an extra cpu_synchronize_state() in revised code for > updating the MSR is not a no-op as expected and loads a stale MSR > value, resulting in an incorrect MSR value on entry to the guest. > > Therefore, I'm hoping to apply this ASAP to 2.6. > > Laurent, could you please verify that this does indeed address the > problem with an incorrect MSR on entry. > > diff --git a/vl.c b/vl.c > index bd81ea9..3629336 100644 > --- a/vl.c > +++ b/vl.c > @@ -1745,6 +1745,8 @@ void qemu_system_reset(bool report) > > mc = current_machine ? MACHINE_GET_CLASS(current_machine) : NULL; > > + cpu_synchronize_all_states(); > + > if (mc && mc->reset) { > mc->reset(); > } else { > @@ -1893,7 +1895,6 @@ static bool main_loop_should_exit(void) > } > if (qemu_reset_requested()) { > pause_all_vcpus(); > - cpu_synchronize_all_states(); > qemu_system_reset(VMRESET_REPORT); > resume_all_vcpus(); > if (!runstate_check(RUN_STATE_RUNNING) && > @@ -1903,7 +1904,6 @@ static bool main_loop_should_exit(void) > } > if (qemu_wakeup_requested()) { > pause_all_vcpus(); > - cpu_synchronize_all_states(); > qemu_system_reset(VMRESET_SILENT); > notifier_list_notify(&wakeup_notifiers, &wakeup_reason); > wakeup_reason = QEMU_WAKEUP_REASON_NONE; >
Acked-by: Paolo Bonzini <pbonz...@redhat.com>