summaryrefslogtreecommitdiffstats
path: root/sys/amd64
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2014-01-29 21:23:37 +0000
committerjhb <jhb@FreeBSD.org>2014-01-29 21:23:37 +0000
commit080d62f93d7c8004e0f06800adb9eb671a15c656 (patch)
treeaaeb609acf09f813a3e0705dffb98eeec21f8312 /sys/amd64
parent63fe90dcd8b2fc3d5acd50b81ae0ed650e09329a (diff)
downloadFreeBSD-src-080d62f93d7c8004e0f06800adb9eb671a15c656.zip
FreeBSD-src-080d62f93d7c8004e0f06800adb9eb671a15c656.tar.gz
MFC 259782:
Add a resume hook for bhyve that runs a function on all CPUs during resume. For Intel CPUs, invoke vmxon for CPUs that were in VMX mode at the time of suspend.
Diffstat (limited to 'sys/amd64')
-rw-r--r--sys/amd64/amd64/machdep.c2
-rw-r--r--sys/amd64/amd64/mp_machdep.c2
-rw-r--r--sys/amd64/include/cpu.h3
-rw-r--r--sys/amd64/include/vmm.h2
-rw-r--r--sys/amd64/vmm/amd/amdv.c6
-rw-r--r--sys/amd64/vmm/intel/vmx.c9
-rw-r--r--sys/amd64/vmm/vmm.c10
7 files changed, 34 insertions, 0 deletions
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index 7f05d58..ad7b5fc 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -216,6 +216,8 @@ struct mem_range_softc mem_range_softc;
struct mtx dt_lock; /* lock for GDT and LDT */
+void (*vmm_resume_p)(void);
+
static void
cpu_startup(dummy)
void *dummy;
diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c
index 4ef4b3d..4af4f8f 100644
--- a/sys/amd64/amd64/mp_machdep.c
+++ b/sys/amd64/amd64/mp_machdep.c
@@ -1483,6 +1483,8 @@ cpususpend_handler(void)
if (cpu_ops.cpu_resume)
cpu_ops.cpu_resume();
+ if (vmm_resume_p)
+ vmm_resume_p();
/* Resume MCA and local APIC */
mca_resume();
diff --git a/sys/amd64/include/cpu.h b/sys/amd64/include/cpu.h
index 3d9ff531..3c5d5df 100644
--- a/sys/amd64/include/cpu.h
+++ b/sys/amd64/include/cpu.h
@@ -70,6 +70,9 @@ extern struct cpu_ops cpu_ops;
extern char btext[];
extern char etext[];
+/* Resume hook for VMM. */
+extern void (*vmm_resume_p)(void);
+
void cpu_halt(void);
void cpu_reset(void);
void fork_trampoline(void);
diff --git a/sys/amd64/include/vmm.h b/sys/amd64/include/vmm.h
index b6bb309..f7acb62 100644
--- a/sys/amd64/include/vmm.h
+++ b/sys/amd64/include/vmm.h
@@ -49,6 +49,7 @@ enum x2apic_state;
typedef int (*vmm_init_func_t)(void);
typedef int (*vmm_cleanup_func_t)(void);
+typedef void (*vmm_resume_func_t)(void);
typedef void * (*vmi_init_func_t)(struct vm *vm, struct pmap *pmap);
typedef int (*vmi_run_func_t)(void *vmi, int vcpu, register_t rip,
struct pmap *pmap);
@@ -72,6 +73,7 @@ typedef void (*vmi_vmspace_free)(struct vmspace *vmspace);
struct vmm_ops {
vmm_init_func_t init; /* module wide initialization */
vmm_cleanup_func_t cleanup;
+ vmm_resume_func_t resume;
vmi_init_func_t vminit; /* vm-specific initialization */
vmi_run_func_t vmrun;
diff --git a/sys/amd64/vmm/amd/amdv.c b/sys/amd64/vmm/amd/amdv.c
index 1cc130f..6c87901 100644
--- a/sys/amd64/vmm/amd/amdv.c
+++ b/sys/amd64/vmm/amd/amdv.c
@@ -53,6 +53,11 @@ amdv_cleanup(void)
return (ENXIO);
}
+static void
+amdv_resume(void)
+{
+}
+
static void *
amdv_vminit(struct vm *vm, struct pmap *pmap)
{
@@ -153,6 +158,7 @@ amdv_vmspace_free(struct vmspace *vmspace)
struct vmm_ops vmm_ops_amd = {
amdv_init,
amdv_cleanup,
+ amdv_resume,
amdv_vminit,
amdv_vmrun,
amdv_vmcleanup,
diff --git a/sys/amd64/vmm/intel/vmx.c b/sys/amd64/vmm/intel/vmx.c
index c89c397..c564dcd 100644
--- a/sys/amd64/vmm/intel/vmx.c
+++ b/sys/amd64/vmm/intel/vmx.c
@@ -526,6 +526,14 @@ vmx_enable(void *arg __unused)
vmxon_enabled[curcpu] = 1;
}
+static void
+vmx_restore(void)
+{
+
+ if (vmxon_enabled[curcpu])
+ vmxon(vmxon_region[curcpu]);
+}
+
static int
vmx_init(void)
{
@@ -2053,6 +2061,7 @@ vmx_setcap(void *arg, int vcpu, int type, int val)
struct vmm_ops vmm_ops_intel = {
vmx_init,
vmx_cleanup,
+ vmx_restore,
vmx_vminit,
vmx_run,
vmx_vmcleanup,
diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c
index 8da66b2..da71f56 100644
--- a/sys/amd64/vmm/vmm.c
+++ b/sys/amd64/vmm/vmm.c
@@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_extern.h>
#include <vm/vm_param.h>
+#include <machine/cpu.h>
#include <machine/vm.h>
#include <machine/pcb.h>
#include <machine/smp.h>
@@ -131,6 +132,7 @@ static int vmm_initialized;
static struct vmm_ops *ops;
#define VMM_INIT() (ops != NULL ? (*ops->init)() : 0)
#define VMM_CLEANUP() (ops != NULL ? (*ops->cleanup)() : 0)
+#define VMM_RESUME() (ops != NULL ? (*ops->resume)() : 0)
#define VMINIT(vm, pmap) (ops != NULL ? (*ops->vminit)(vm, pmap): NULL)
#define VMRUN(vmi, vcpu, rip, pmap) \
@@ -202,6 +204,12 @@ vm_exitinfo(struct vm *vm, int cpuid)
return (&vcpu->exitinfo);
}
+static void
+vmm_resume(void)
+{
+ VMM_RESUME();
+}
+
static int
vmm_init(void)
{
@@ -222,6 +230,7 @@ vmm_init(void)
return (ENXIO);
vmm_msr_init();
+ vmm_resume_p = vmm_resume;
return (VMM_INIT());
}
@@ -242,6 +251,7 @@ vmm_handler(module_t mod, int what, void *arg)
case MOD_UNLOAD:
error = vmmdev_cleanup();
if (error == 0) {
+ vmm_resume_p = NULL;
iommu_cleanup();
vmm_ipi_cleanup();
error = VMM_CLEANUP();
OpenPOWER on IntegriCloud