On Mon, Jun 27, 2022, Durrant, Paul wrote: > > -----Original Message----- > [snip] > > > > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c > > > > index 00e23dc518e0..8b45f9975e45 100644 > > > > --- a/arch/x86/kvm/x86.c > > > > +++ b/arch/x86/kvm/x86.c > > > > @@ -3123,6 +3123,7 @@ static int kvm_guest_time_update(struct kvm_vcpu *v) > > > > if (vcpu->xen.vcpu_time_info_cache.active) > > > > kvm_setup_guest_pvclock(v, &vcpu->xen.vcpu_time_info_cache, 0); > > > > kvm_hv_setup_tsc_page(v->kvm, &vcpu->hv_clock); > > > > + kvm_xen_setup_tsc_info(v); > > > > > > This can be called inside this if statement, no? > > > > > > if (unlikely(vcpu->hw_tsc_khz != tgt_tsc_khz)) { > > > > > > } > > > > > I think it ought to be done whenever the shared copy of Xen's vcpu_info is > updated (it will always match on real Xen) so unconditionally calling it here > seems reasonable. But isn't the call pointless if the vCPU's hw_tsc_khz is unchanged? E.g if the params were explicitly passed in, then it would look like: if (unlikely(vcpu->hw_tsc_khz != tgt_tsc_khz)) { kvm_get_time_scale(NSEC_PER_SEC, tgt_tsc_khz * 1000LL, &vcpu->hv_clock.tsc_shift, &vcpu->hv_clock.tsc_to_system_mul); vcpu->hw_tsc_khz = tgt_tsc_khz; kvm_xen_setup_tsc_info(vcpu, tgt_tsc_khz, vcpu->hv_clock.tsc_shift, vcpu->hv_clock.tsc_to_system_mul); } Explicitly passing in the arguments probably isn't necessary, just use a more precise name, e.g. kvm_xen_update_tsc_khz(), to make it clear that the update is limited to TSC frequency changes. > > > > +{ > > > > + u32 base = 0; > > > > + u32 function; > > > > + > > > > + for_each_possible_hypervisor_cpuid_base(function) { > > > > + struct kvm_cpuid_entry2 *entry = kvm_find_cpuid_entry(vcpu, function, 0); > > > > + > > > > + if (entry && > > > > + entry->ebx == XEN_CPUID_SIGNATURE_EBX && > > > > + entry->ecx == XEN_CPUID_SIGNATURE_ECX && > > > > + entry->edx == XEN_CPUID_SIGNATURE_EDX) { > > > > + base = function; > > > > + break; > > > > + } > > > > + } > > > > + if (!base) > > > > + return; > > > > + > > > > + function = base | XEN_CPUID_LEAF(3); > > > > + vcpu->arch.xen.tsc_info_1 = kvm_find_cpuid_entry(vcpu, function, 1); > > > > + vcpu->arch.xen.tsc_info_2 = kvm_find_cpuid_entry(vcpu, function, 2); > > > > > > Is it really necessary to cache the leave? Guest CPUID isn't optimized, but it's > > > not _that_ slow, and unless I'm missing something updating the TSC frequency and > > > scaling info should be uncommon, i.e. not performance critical. > > If we're updating the values in the leaves on every entry into the guest (as > with calls to kvm_setup_guest_pvclock()) then I think the cached pointers are > worthwhile. But why would you update on every entry to the guest? Isn't this a rare operation if the update is limited to changes in the host CPU's TSC frequency? Or am I missing something?