Set vcpu's TSC rate to the migrated value (if any). If KVM supports TSC scaling, guest programs will observe TSC increasing in the migrated rate other than the host TSC rate. The loading is controlled by a new cpu option 'load-tsc-freq'. If it is present, then the loading will be enabled and the migrated vcpu's TSC rate will override the value specified by the cpu option 'tsc-freq'. Otherwise, the loading will be disabled. The setting of vcpu's TSC rate in this patch duplicates the code in kvm_arch_init_vcpu(), so we remove the latter one. Signed-off-by: Haozhong Zhang <haozhong.zhang@xxxxxxxxx> --- target-i386/cpu.c | 1 + target-i386/cpu.h | 1 + target-i386/kvm.c | 28 +++++++++++++++++++--------- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/target-i386/cpu.c b/target-i386/cpu.c index b6bb457..763ba4b 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -3144,6 +3144,7 @@ static Property x86_cpu_properties[] = { DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false), DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true), DEFINE_PROP_BOOL("save-tsc-freq", X86CPU, env.save_tsc_khz, true), + DEFINE_PROP_BOOL("load-tsc-freq", X86CPU, env.load_tsc_khz, false), DEFINE_PROP_UINT32("level", X86CPU, env.cpuid_level, 0), DEFINE_PROP_UINT32("xlevel", X86CPU, env.cpuid_xlevel, 0), DEFINE_PROP_UINT32("xlevel2", X86CPU, env.cpuid_xlevel2, 0), diff --git a/target-i386/cpu.h b/target-i386/cpu.h index ba1a289..353f5fb 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -968,6 +968,7 @@ typedef struct CPUX86State { int64_t tsc_khz; int64_t tsc_khz_incoming; bool save_tsc_khz; + bool load_tsc_khz; void *kvm_xsave_buf; uint64_t mcg_cap; diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 698524a..34616f5 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -743,15 +743,6 @@ int kvm_arch_init_vcpu(CPUState *cs) return r; } - r = kvm_check_extension(cs->kvm_state, KVM_CAP_TSC_CONTROL); - if (r && env->tsc_khz) { - r = kvm_vcpu_ioctl(cs, KVM_SET_TSC_KHZ, env->tsc_khz); - if (r < 0) { - fprintf(stderr, "KVM_SET_TSC_KHZ failed\n"); - return r; - } - } - if (kvm_has_xsave()) { env->kvm_xsave_buf = qemu_memalign(4096, sizeof(struct kvm_xsave)); } @@ -2223,6 +2214,25 @@ static int kvm_setup_tsc_khz(X86CPU *cpu, int level) return 0; /* + * If the cpu option 'load-tsc-freq' is present, the vcpu's TSC rate in the + * migrated state will be used and the overrides the user-specified vcpu's + * TSC rate (if any). + */ + if (runstate_check(RUN_STATE_INMIGRATE) && + env->load_tsc_khz && env->tsc_khz_incoming) { + env->tsc_khz = env->tsc_khz_incoming; + } + + r = kvm_check_extension(cs->kvm_state, KVM_CAP_TSC_CONTROL); + if (r && env->tsc_khz) { + r = kvm_vcpu_ioctl(cs, KVM_SET_TSC_KHZ, env->tsc_khz); + if (r < 0) { + fprintf(stderr, "KVM_SET_TSC_KHZ failed\n"); + return r; + } + } + + /* * Prepare the vcpu's TSC rate (ie. env->tsc_khz_incoming) to be migrated. * 1. If no user-specified value is provided, we will use the value from * KVM; -- 2.4.8 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html