* Vitaly Kuznetsov (vkuzn...@redhat.com) wrote: > KVM doesn't fully support Hyper-V reenlightenment notifications on > migration. In particular, it doesn't support emulating TSC frequency > of the source host by trapping all TSC accesses so unless TSC scaling > is supported on the destination host and KVM_SET_TSC_KHZ succeeds, it > is unsafe to proceed with migration. > > Normally, we only require KVM_SET_TSC_KHZ to succeed when 'user_tsc_khz' > was set and just 'try' KVM_SET_TSC_KHZ without otherwise. > > Introduce a new vmstate section (which is added when the guest has > reenlightenment feature enabled) and add env.tsc_khz to it. We already > have env.tsc_khz packed in 'cpu/tsc_khz' but we don't want to be dependent > on the section order. > > Signed-off-by: Vitaly Kuznetsov <vkuzn...@redhat.com> > --- > target/i386/kvm/hyperv.h | 1 + > target/i386/kvm/kvm.c | 11 +++++++++++ > target/i386/machine.c | 37 +++++++++++++++++++++++++++++++++++++ > 3 files changed, 49 insertions(+) > > diff --git a/target/i386/kvm/hyperv.h b/target/i386/kvm/hyperv.h > index 67543296c3a4..c65e5c85c4d3 100644 > --- a/target/i386/kvm/hyperv.h > +++ b/target/i386/kvm/hyperv.h > @@ -20,6 +20,7 @@ > > #ifdef CONFIG_KVM > int kvm_hv_handle_exit(X86CPU *cpu, struct kvm_hyperv_exit *exit); > +int kvm_hv_tsc_frequency_loaded(X86CPU *cpu); > #endif > > int hyperv_x86_synic_add(X86CPU *cpu); > diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c > index 7fe9f527103c..f6c4093778e9 100644 > --- a/target/i386/kvm/kvm.c > +++ b/target/i386/kvm/kvm.c > @@ -1460,6 +1460,17 @@ static int hyperv_init_vcpu(X86CPU *cpu) > return 0; > } > > +int kvm_hv_tsc_frequency_loaded(X86CPU *cpu) > +{ > + CPUState *cs = CPU(cpu); > + > + /* > + * KVM doens't fully support re-enlightenment notifications so we need to ^^ tpyo
Dave > + * make sure TSC frequency doesn't change upon migration. > + */ > + return kvm_arch_set_tsc_khz(cs); > +} > + > static Error *invtsc_mig_blocker; > > #define KVM_MAX_CPUID_ENTRIES 100 > diff --git a/target/i386/machine.c b/target/i386/machine.c > index 715620c58809..369a8f1e7a7a 100644 > --- a/target/i386/machine.c > +++ b/target/i386/machine.c > @@ -896,6 +896,42 @@ static const VMStateDescription > vmstate_msr_hyperv_reenlightenment = { > VMSTATE_END_OF_LIST() > } > }; > + > +static bool hyperv_tsc_frequency_needed(void *opaque) > +{ > + X86CPU *cpu = opaque; > + CPUX86State *env = &cpu->env; > + > + return env->tsc_khz != 0 && (env->msr_hv_reenlightenment_control || > + env->msr_hv_tsc_emulation_control); > +} > + > +static int hyperv_tsc_frequency_post_load(void *opaque, int version_id) > +{ > + X86CPU *cpu = opaque; > + int r; > + > + r = kvm_hv_tsc_frequency_loaded(cpu); > + if (r) { > + error_report("Failed to set the desired TSC frequency and " > + "reenlightenment was exposed"); > + return -EINVAL; > + } > + > + return 0; > +} > + > +static const VMStateDescription vmstate_msr_hyperv_tsc_frequency = { > + .name = "cpu/msr_hyperv_tsc_frequency", > + .version_id = 1, > + .minimum_version_id = 1, > + .needed = hyperv_tsc_frequency_needed, > + .post_load = hyperv_tsc_frequency_post_load, > + .fields = (VMStateField[]) { > + VMSTATE_INT64(env.tsc_khz, X86CPU), > + VMSTATE_END_OF_LIST() > + } > +}; > #endif > > static bool avx512_needed(void *opaque) > @@ -1495,6 +1531,7 @@ VMStateDescription vmstate_x86_cpu = { > &vmstate_msr_hyperv_synic, > &vmstate_msr_hyperv_stimer, > &vmstate_msr_hyperv_reenlightenment, > + &vmstate_msr_hyperv_tsc_frequency, > #endif > &vmstate_avx512, > &vmstate_xss, > -- > 2.30.2 > -- Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK