Author: grehan
Date: Tue Aug 18 07:23:47 2020
New Revision: 364340
URL: https://svnweb.freebsd.org/changeset/base/364340
Log:
Support guest rdtscp and rdpid instructions on Intel VT-x
Enable any of rdtscp and/or rdpid for bhyve guests on Intel-based hosts
that support the "enable RDTSCP" VM-execution control.
Submitted by: adam_fenn.io
Reported by: chuck
Reviewed by: chuck, grehan, jhb
Approved by: jhb (bhyve), grehan
MFC after:3 weeks
Relnotes: Yes
Differential Revision:https://reviews.freebsd.org/D26003
Modified:
head/sys/amd64/include/vmm.h
head/sys/amd64/vmm/intel/vmx.c
head/sys/amd64/vmm/intel/vmx.h
head/sys/amd64/vmm/intel/vmx_msr.c
head/sys/amd64/vmm/intel/vmx_msr.h
head/sys/amd64/vmm/x86.c
Modified: head/sys/amd64/include/vmm.h
==
--- head/sys/amd64/include/vmm.hTue Aug 18 07:08:17 2020
(r364339)
+++ head/sys/amd64/include/vmm.hTue Aug 18 07:23:47 2020
(r364340)
@@ -481,6 +481,8 @@ enum vm_cap_type {
VM_CAP_UNRESTRICTED_GUEST,
VM_CAP_ENABLE_INVPCID,
VM_CAP_BPT_EXIT,
+ VM_CAP_RDPID,
+ VM_CAP_RDTSCP,
VM_CAP_MAX
};
Modified: head/sys/amd64/vmm/intel/vmx.c
==
--- head/sys/amd64/vmm/intel/vmx.c Tue Aug 18 07:08:17 2020
(r364339)
+++ head/sys/amd64/vmm/intel/vmx.c Tue Aug 18 07:23:47 2020
(r364340)
@@ -167,6 +167,14 @@ static int cap_pause_exit;
SYSCTL_INT(_hw_vmm_vmx_cap, OID_AUTO, pause_exit, CTLFLAG_RD, _pause_exit,
0, "PAUSE triggers a VM-exit");
+static int cap_rdpid;
+SYSCTL_INT(_hw_vmm_vmx_cap, OID_AUTO, rdpid, CTLFLAG_RD, _rdpid, 0,
+"Guests are allowed to use RDPID");
+
+static int cap_rdtscp;
+SYSCTL_INT(_hw_vmm_vmx_cap, OID_AUTO, rdtscp, CTLFLAG_RD, _rdtscp, 0,
+"Guests are allowed to use RDTSCP");
+
static int cap_unrestricted_guest;
SYSCTL_INT(_hw_vmm_vmx_cap, OID_AUTO, unrestricted_guest, CTLFLAG_RD,
_unrestricted_guest, 0, "Unrestricted guests");
@@ -303,6 +311,18 @@ static void vmx_inject_pir(struct vlapic *vlapic);
static int vmx_restore_tsc(void *arg, int vcpu, uint64_t now);
#endif
+static inline bool
+host_has_rdpid(void)
+{
+ return ((cpu_stdext_feature2 & CPUID_STDEXT2_RDPID) != 0);
+}
+
+static inline bool
+host_has_rdtscp(void)
+{
+ return ((amd_feature & AMDID_RDTSCP) != 0);
+}
+
#ifdef KTR
static const char *
exit_reason_to_str(int reason)
@@ -755,6 +775,43 @@ vmx_init(int ipinum)
PROCBASED_PAUSE_EXITING, 0,
) == 0);
+ /*
+* Check support for RDPID and/or RDTSCP.
+*
+* Support a pass-through-based implementation of these via the
+* "enable RDTSCP" VM-execution control and the "RDTSC exiting"
+* VM-execution control.
+*
+* The "enable RDTSCP" VM-execution control applies to both RDPID
+* and RDTSCP (see SDM volume 3, section 25.3, "Changes to
+* Instruction Behavior in VMX Non-root operation"); this is why
+* only this VM-execution control needs to be enabled in order to
+* enable passing through whichever of RDPID and/or RDTSCP are
+* supported by the host.
+*
+* The "RDTSC exiting" VM-execution control applies to both RDTSC
+* and RDTSCP (again, per SDM volume 3, section 25.3), and is
+* already set up for RDTSC and RDTSCP pass-through by the current
+* implementation of RDTSC.
+*
+* Although RDPID and RDTSCP are optional capabilities, since there
+* does not currently seem to be a use case for enabling/disabling
+* these via libvmmapi, choose not to support this and, instead,
+* just statically always enable or always disable this support
+* across all vCPUs on all VMs. (Note that there may be some
+* complications to providing this functionality, e.g., the MSR
+* bitmap is currently per-VM rather than per-vCPU while the
+* capability API wants to be able to control capabilities on a
+* per-vCPU basis).
+*/
+ error = vmx_set_ctlreg(MSR_VMX_PROCBASED_CTLS2,
+ MSR_VMX_PROCBASED_CTLS2,
+ PROCBASED2_ENABLE_RDTSCP, 0, );
+ cap_rdpid = error == 0 && host_has_rdpid();
+ cap_rdtscp = error == 0 && host_has_rdtscp();
+ if (cap_rdpid || cap_rdtscp)
+ procbased_ctls2 |= PROCBASED2_ENABLE_RDTSCP;
+
cap_unrestricted_guest = (vmx_set_ctlreg(MSR_VMX_PROCBASED_CTLS2,
MSR_VMX_PROCBASED_CTLS2,
PROCBASED2_UNRESTRICTED_GUEST, 0,
@@ -1007,6 +1064,15 @@ vmx_vminit(struct vm *vm, pmap_t pmap)
* the "use TSC offsetting" execution control is enabled