summaryrefslogtreecommitdiffstats
path: root/sys/amd64/vmm/vmm_host.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/amd64/vmm/vmm_host.c')
-rw-r--r--sys/amd64/vmm/vmm_host.c39
1 files changed, 38 insertions, 1 deletions
diff --git a/sys/amd64/vmm/vmm_host.c b/sys/amd64/vmm/vmm_host.c
index 8dfef73..9e5b966 100644
--- a/sys/amd64/vmm/vmm_host.c
+++ b/sys/amd64/vmm/vmm_host.c
@@ -38,11 +38,14 @@ __FBSDID("$FreeBSD$");
#include "vmm_host.h"
-static uint64_t vmm_host_efer, vmm_host_pat, vmm_host_cr0, vmm_host_cr4;
+static uint64_t vmm_host_efer, vmm_host_pat, vmm_host_cr0, vmm_host_cr4,
+ vmm_host_xcr0;
+static struct xsave_limits vmm_xsave_limits;
void
vmm_host_state_init(void)
{
+ int regs[4];
vmm_host_efer = rdmsr(MSR_EFER);
vmm_host_pat = rdmsr(MSR_PAT);
@@ -57,6 +60,26 @@ vmm_host_state_init(void)
vmm_host_cr0 = rcr0() | CR0_TS;
vmm_host_cr4 = rcr4();
+
+ /*
+ * Only permit a guest to use XSAVE if the host is using
+ * XSAVE. Only permit a guest to use XSAVE features supported
+ * by the host. This ensures that the FPU state used by the
+ * guest is always a subset of the saved guest FPU state.
+ *
+ * In addition, only permit known XSAVE features where the
+ * rules for which features depend on other features is known
+ * to properly emulate xsetbv.
+ */
+ if (vmm_host_cr4 & CR4_XSAVE) {
+ vmm_xsave_limits.xsave_enabled = 1;
+ vmm_host_xcr0 = rxcr(0);
+ vmm_xsave_limits.xcr0_allowed = vmm_host_xcr0 &
+ (XFEATURE_AVX | XFEATURE_MPX | XFEATURE_AVX512);
+
+ cpuid_count(0xd, 0x0, regs);
+ vmm_xsave_limits.xsave_max_size = regs[1];
+ }
}
uint64_t
@@ -88,6 +111,13 @@ vmm_get_host_cr4(void)
}
uint64_t
+vmm_get_host_xcr0(void)
+{
+
+ return (vmm_host_xcr0);
+}
+
+uint64_t
vmm_get_host_datasel(void)
{
@@ -122,3 +152,10 @@ vmm_get_host_idtrbase(void)
return (r_idt.rd_base);
}
+
+const struct xsave_limits *
+vmm_get_xsave_limits(void)
+{
+
+ return (&vmm_xsave_limits);
+}
OpenPOWER on IntegriCloud