Commit f422f853 authored by Paul Durrant's avatar Paul Durrant Committed by Sean Christopherson
Browse files

KVM: x86/xen: update Xen CPUID Leaf 4 (tsc info) sub-leaves, if present



The scaling information in subleaf 1 should match the values set by KVM in
the 'vcpu_info' sub-structure 'time_info' (a.k.a. pvclock_vcpu_time_info)
which is shared with the guest, but is not directly available to the VMM.
The offset values are not set since a TSC offset is already applied.
The TSC frequency should also be set in sub-leaf 2.

Signed-off-by: default avatarPaul Durrant <pdurrant@amazon.com>
Reviewed-by: default avatarDavid Woodhouse <dwmw@amazon.co.uk>
Link: https://lore.kernel.org/r/20230106103600.528-3-pdurrant@amazon.com


Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
parent 48639df8
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -703,6 +703,7 @@ struct kvm_vcpu_xen {
	struct hrtimer timer;
	int poll_evtchn;
	struct timer_list poll_timer;
	struct kvm_hypervisor_cpuid cpuid;
};

struct kvm_queued_exception {
+3 −1
Original line number Diff line number Diff line
@@ -38,9 +38,11 @@ extern struct start_info *xen_start_info;

#include <asm/processor.h>

#define XEN_SIGNATURE "XenVMMXenVMM"

static inline uint32_t xen_cpuid_base(void)
{
	return hypervisor_cpuid_base("XenVMMXenVMM", 2);
	return hypervisor_cpuid_base(XEN_SIGNATURE, 2);
}

struct pci_dev;
+2 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include "mmu.h"
#include "trace.h"
#include "pmu.h"
#include "xen.h"

/*
 * Unlike "struct cpuinfo_x86.x86_capability", kvm_cpu_caps doesn't need to be
@@ -443,6 +444,7 @@ static int kvm_set_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid_entry2 *e2,
	vcpu->arch.cpuid_nent = nent;

	vcpu->arch.kvm_cpuid = kvm_get_hypervisor_cpuid(vcpu, KVM_SIGNATURE);
	vcpu->arch.xen.cpuid = kvm_get_hypervisor_cpuid(vcpu, XEN_SIGNATURE);
	kvm_vcpu_after_set_cpuid(vcpu);

	return 0;
+1 −0
Original line number Diff line number Diff line
@@ -3161,6 +3161,7 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
				   &vcpu->hv_clock.tsc_shift,
				   &vcpu->hv_clock.tsc_to_system_mul);
		vcpu->hw_tsc_khz = tgt_tsc_khz;
		kvm_xen_update_tsc_info(v);
	}

	vcpu->hv_clock.tsc_timestamp = tsc_timestamp;
+26 −0
Original line number Diff line number Diff line
@@ -23,6 +23,9 @@
#include <xen/interface/event_channel.h>
#include <xen/interface/sched.h>

#include <asm/xen/cpuid.h>

#include "cpuid.h"
#include "trace.h"

static int kvm_xen_set_evtchn(struct kvm_xen_evtchn *xe, struct kvm *kvm);
@@ -2077,6 +2080,29 @@ void kvm_xen_destroy_vcpu(struct kvm_vcpu *vcpu)
	del_timer_sync(&vcpu->arch.xen.poll_timer);
}

void kvm_xen_update_tsc_info(struct kvm_vcpu *vcpu)
{
	struct kvm_cpuid_entry2 *entry;
	u32 function;

	if (!vcpu->arch.xen.cpuid.base)
		return;

	function = vcpu->arch.xen.cpuid.base | XEN_CPUID_LEAF(3);
	if (function > vcpu->arch.xen.cpuid.limit)
		return;

	entry = kvm_find_cpuid_entry_index(vcpu, function, 1);
	if (entry) {
		entry->ecx = vcpu->arch.hv_clock.tsc_to_system_mul;
		entry->edx = vcpu->arch.hv_clock.tsc_shift;
	}

	entry = kvm_find_cpuid_entry_index(vcpu, function, 2);
	if (entry)
		entry->eax = vcpu->arch.hw_tsc_khz;
}

void kvm_xen_init_vm(struct kvm *kvm)
{
	mutex_init(&kvm->arch.xen.xen_lock);
Loading