From 73abae4493782e44a3382b15f5563c3f400bf51f Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Fri, 18 Nov 2022 09:58:56 -0800 Subject: [PATCH] vmm vmx: Add a global bool to indicate if the host has the TSC_AUX MSR. A future commit will remove direct access to vCPU structures from struct vmx, so add a dedicated boolean for this rather than checking the capabilities for vCPU 0. Reviewed by: corvink, markj Differential Revision: https://reviews.freebsd.org/D37269 --- sys/amd64/vmm/intel/vmx.c | 6 +++++- sys/amd64/vmm/intel/vmx.h | 16 ++-------------- sys/amd64/vmm/intel/vmx_msr.c | 6 +++--- 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/sys/amd64/vmm/intel/vmx.c b/sys/amd64/vmm/intel/vmx.c index 7ece03a44952..96e7907622cf 100644 --- a/sys/amd64/vmm/intel/vmx.c +++ b/sys/amd64/vmm/intel/vmx.c @@ -127,6 +127,8 @@ __FBSDID("$FreeBSD$"); static MALLOC_DEFINE(M_VMX, "vmx", "vmx"); static MALLOC_DEFINE(M_VLAPIC, "vlapic", "vlapic"); +bool vmx_have_msr_tsc_aux; + SYSCTL_DECL(_hw_vmm); SYSCTL_NODE(_hw_vmm, OID_AUTO, vmx, CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, NULL); @@ -821,8 +823,10 @@ vmx_modinit(int ipinum) PROCBASED2_ENABLE_RDTSCP, 0, &tmp); cap_rdpid = error == 0 && host_has_rdpid(); cap_rdtscp = error == 0 && host_has_rdtscp(); - if (cap_rdpid || cap_rdtscp) + if (cap_rdpid || cap_rdtscp) { procbased_ctls2 |= PROCBASED2_ENABLE_RDTSCP; + vmx_have_msr_tsc_aux = true; + } cap_unrestricted_guest = (vmx_set_ctlreg(MSR_VMX_PROCBASED_CTLS2, MSR_VMX_PROCBASED_CTLS2, diff --git a/sys/amd64/vmm/intel/vmx.h b/sys/amd64/vmm/intel/vmx.h index 8168b82bfe5c..39594473cd43 100644 --- a/sys/amd64/vmm/intel/vmx.h +++ b/sys/amd64/vmm/intel/vmx.h @@ -142,6 +142,8 @@ struct vmx { long eptgen[MAXCPU]; /* cached pmap->pm_eptgen */ }; +extern bool vmx_have_msr_tsc_aux; + #define VMX_GUEST_VMEXIT 0 #define VMX_VMRESUME_ERROR 1 #define VMX_VMLAUNCH_ERROR 2 @@ -156,18 +158,4 @@ int vmx_set_tsc_offset(struct vmx *vmx, int vcpu, uint64_t offset); extern char vmx_exit_guest[]; extern char vmx_exit_guest_flush_rsb[]; -static inline bool -vmx_have_msr_tsc_aux(struct vmx *vmx) -{ - int rdpid_rdtscp_bits = ((1 << VM_CAP_RDPID) | (1 << VM_CAP_RDTSCP)); - - /* - * Since the values of these bits are uniform across all vCPUs - * (see discussion in vmx_modinit() and initialization of these bits - * in vmx_init()), just always use vCPU-zero's capability set and - * remove the need to require a vcpuid argument. - */ - return ((vmx->vcpus[0].cap.set & rdpid_rdtscp_bits) != 0); -} - #endif diff --git a/sys/amd64/vmm/intel/vmx_msr.c b/sys/amd64/vmm/intel/vmx_msr.c index 0d4e86edf60c..40f0057f2cdd 100644 --- a/sys/amd64/vmm/intel/vmx_msr.c +++ b/sys/amd64/vmm/intel/vmx_msr.c @@ -366,7 +366,7 @@ vmx_msr_guest_enter_tsc_aux(struct vmx *vmx, int vcpuid) uint64_t guest_tsc_aux = vmx_vcpu->guest_msrs[IDX_MSR_TSC_AUX]; uint32_t host_aux = cpu_auxmsr(); - if (vmx_have_msr_tsc_aux(vmx) && guest_tsc_aux != host_aux) + if (vmx_have_msr_tsc_aux && guest_tsc_aux != host_aux) wrmsr(MSR_TSC_AUX, guest_tsc_aux); } @@ -398,7 +398,7 @@ vmx_msr_guest_exit_tsc_aux(struct vmx *vmx, int vcpuid) uint64_t guest_tsc_aux = vmx_vcpu->guest_msrs[IDX_MSR_TSC_AUX]; uint32_t host_aux = cpu_auxmsr(); - if (vmx_have_msr_tsc_aux(vmx) && guest_tsc_aux != host_aux) + if (vmx_have_msr_tsc_aux && guest_tsc_aux != host_aux) /* * Note that it is not necessary to save the guest value * here; vmx->guest_msrs[vcpuid][IDX_MSR_TSC_AUX] always @@ -505,7 +505,7 @@ vmx_wrmsr(struct vmx *vmx, int vcpuid, u_int num, uint64_t val, bool *retu) error = vmx_set_tsc_offset(vmx, vcpuid, val - rdtsc()); break; case MSR_TSC_AUX: - if (vmx_have_msr_tsc_aux(vmx)) + if (vmx_have_msr_tsc_aux) /* * vmx_msr_guest_enter_tsc_aux() will apply this * value when it is called immediately before guest