@@ -738,6 +738,13 @@ struct kvm_queued_exception {
bool has_payload;
};
+struct kvm_vcpu_aperfmperf {
+ u64 guest_aperf;
+ u64 guest_mperf;
+ u64 host_tsc;
+ bool loaded_while_running;
+};
+
struct kvm_vcpu_arch {
/*
* rip and regs accesses must go through
@@ -1040,6 +1047,8 @@ struct kvm_vcpu_arch {
#if IS_ENABLED(CONFIG_HYPERV)
hpa_t hv_root_tdp;
#endif
+
+ struct kvm_vcpu_aperfmperf aperfmperf;
};
struct kvm_lpage_info {
@@ -12476,6 +12476,13 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
__kvm_set_xcr(vcpu, 0, XFEATURE_MASK_FP);
__kvm_set_msr(vcpu, MSR_IA32_XSS, 0, true);
+
+ /*
+ * IA32_MPERF should start running now. Record the host TSC
+ * so that we can add the host TSC delta the next time that
+ * we load the guest [am]perf values into the hardware MSRs.
+ */
+ vcpu->arch.aperfmperf.host_tsc = rdtsc();
}
/* All GPRs except RDX (handled below) are zeroed on RESET/INIT. */