On Tue, 2023-12-19 at 00:34 -0800, Isaku Yamahata wrote: > Introduce the VM variable of the APIC cycles per nano second as the > preparation to make the APIC APIC bus frequency configurable. > > The TDX architecture hard-codes the APIC bus frequency to 25MHz in the > CPUID leaf 0x15. The TDX mandates it to be exposed and doesn't allow the > VMM to override its value. The KVM APIC timer emulation hard-codes the > frequency to 1GHz. To ensure that the guest doesn't have a conflicting > view of the APIC bus frequency, allow the userspace to tell KVM to use the > same frequency that TDX mandates instead of the default 1Ghz. > > Signed-off-by: Isaku Yamahata <isaku.yamahata@xxxxxxxxx> > --- > Changes v3: > - Update commit message. > - Dropped apic_bus_frequency according to Maxim Levitsky. Looks good to me, thanks! > > Changes v2: > - no change. > --- > arch/x86/include/asm/kvm_host.h | 1 + > arch/x86/kvm/hyperv.c | 3 ++- > arch/x86/kvm/lapic.c | 6 ++++-- > arch/x86/kvm/lapic.h | 2 +- > arch/x86/kvm/x86.c | 1 + > 5 files changed, 9 insertions(+), 4 deletions(-) > > diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h > index d7036982332e..45ee7a1d13f6 100644 > --- a/arch/x86/include/asm/kvm_host.h > +++ b/arch/x86/include/asm/kvm_host.h > @@ -1334,6 +1334,7 @@ struct kvm_arch { > > u32 default_tsc_khz; > bool user_set_tsc; > + u64 apic_bus_cycle_ns; > > seqcount_raw_spinlock_t pvclock_sc; > bool use_master_clock; > diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c > index a40ca2fef58c..37ff31c18ad1 100644 > --- a/arch/x86/kvm/hyperv.c > +++ b/arch/x86/kvm/hyperv.c > @@ -1687,7 +1687,8 @@ static int kvm_hv_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata, > data = (u64)vcpu->arch.virtual_tsc_khz * 1000; > break; > case HV_X64_MSR_APIC_FREQUENCY: > - data = div64_u64(1000000000ULL, APIC_BUS_CYCLE_NS); > + data = div64_u64(1000000000ULL, > + vcpu->kvm->arch.apic_bus_cycle_ns); > break; > default: > kvm_pr_unimpl_rdmsr(vcpu, msr); > diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c > index 245b20973cae..73956b0ac1f1 100644 > --- a/arch/x86/kvm/lapic.c > +++ b/arch/x86/kvm/lapic.c > @@ -1542,7 +1542,8 @@ static u32 apic_get_tmcct(struct kvm_lapic *apic) > remaining = 0; > > ns = mod_64(ktime_to_ns(remaining), apic->lapic_timer.period); > - return div64_u64(ns, (APIC_BUS_CYCLE_NS * apic->divide_count)); > + return div64_u64(ns, (apic->vcpu->kvm->arch.apic_bus_cycle_ns * > + apic->divide_count)); > } > > static void __report_tpr_access(struct kvm_lapic *apic, bool write) > @@ -1960,7 +1961,8 @@ static void start_sw_tscdeadline(struct kvm_lapic *apic) > > static inline u64 tmict_to_ns(struct kvm_lapic *apic, u32 tmict) > { > - return (u64)tmict * APIC_BUS_CYCLE_NS * (u64)apic->divide_count; > + return (u64)tmict * apic->vcpu->kvm->arch.apic_bus_cycle_ns * > + (u64)apic->divide_count; > } > > static void update_target_expiration(struct kvm_lapic *apic, uint32_t old_divisor) > diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h > index a20cb006b6c8..51e09f5a7fc5 100644 > --- a/arch/x86/kvm/lapic.h > +++ b/arch/x86/kvm/lapic.h > @@ -16,7 +16,7 @@ > #define APIC_DEST_NOSHORT 0x0 > #define APIC_DEST_MASK 0x800 > > -#define APIC_BUS_CYCLE_NS 1 > +#define APIC_BUS_CYCLE_NS_DEFAULT 1 > > #define APIC_BROADCAST 0xFF > #define X2APIC_BROADCAST 0xFFFFFFFFul > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c > index 1a3aaa7dafae..d7d865f7c847 100644 > --- a/arch/x86/kvm/x86.c > +++ b/arch/x86/kvm/x86.c > @@ -12466,6 +12466,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) > raw_spin_unlock_irqrestore(&kvm->arch.tsc_write_lock, flags); > > kvm->arch.default_tsc_khz = max_tsc_khz ? : tsc_khz; > + kvm->arch.apic_bus_cycle_ns = APIC_BUS_CYCLE_NS_DEFAULT; > kvm->arch.guest_can_read_msr_platform_info = true; > kvm->arch.enable_pmu = enable_pmu; > Reviewed-by: Maxim Levitsky <mlevitsk@xxxxxxxxxx> Best regards, Maxim Levitsky