Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F164281529
D27375.id80000.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
15 KB
Referenced Files
None
Subscribers
None
D27375.id80000.diff
View Options
Index: sys/amd64/include/vmm.h
===================================================================
--- sys/amd64/include/vmm.h
+++ sys/amd64/include/vmm.h
@@ -162,9 +162,9 @@
int *iptr; /* reqidle cookie */
};
-typedef int (*vmm_init_func_t)(int ipinum);
-typedef int (*vmm_cleanup_func_t)(void);
-typedef void (*vmm_resume_func_t)(void);
+typedef int (*vmm_modinit_func_t)(int ipinum);
+typedef int (*vmm_modcleanup_func_t)(void);
+typedef void (*vmm_modresume_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, struct vm_eventinfo *info);
@@ -189,28 +189,28 @@
typedef int (*vmi_restore_tsc_t)(void *vmi, int vcpuid, uint64_t now);
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;
- vmi_cleanup_func_t vmcleanup;
- vmi_get_register_t vmgetreg;
- vmi_set_register_t vmsetreg;
- vmi_get_desc_t vmgetdesc;
- vmi_set_desc_t vmsetdesc;
- vmi_get_cap_t vmgetcap;
- vmi_set_cap_t vmsetcap;
+ vmm_modinit_func_t modinit; /* module wide initialization */
+ vmm_modcleanup_func_t modcleanup;
+ vmm_modresume_func_t modresume;
+
+ vmi_init_func_t init; /* vm-specific initialization */
+ vmi_run_func_t run;
+ vmi_cleanup_func_t cleanup;
+ vmi_get_register_t getreg;
+ vmi_set_register_t setreg;
+ vmi_get_desc_t getdesc;
+ vmi_set_desc_t setdesc;
+ vmi_get_cap_t getcap;
+ vmi_set_cap_t setcap;
vmi_vmspace_alloc vmspace_alloc;
vmi_vmspace_free vmspace_free;
vmi_vlapic_init vlapic_init;
vmi_vlapic_cleanup vlapic_cleanup;
/* checkpoint operations */
- vmi_snapshot_t vmsnapshot;
+ vmi_snapshot_t snapshot;
vmi_snapshot_vmcx_t vmcx_snapshot;
- vmi_restore_tsc_t vm_restore_tsc;
+ vmi_restore_tsc_t restore_tsc;
};
extern struct vmm_ops vmm_ops_intel;
Index: sys/amd64/vmm/amd/svm.c
===================================================================
--- sys/amd64/vmm/amd/svm.c
+++ sys/amd64/vmm/amd/svm.c
@@ -2673,25 +2673,25 @@
#endif
struct vmm_ops vmm_ops_amd = {
- .init = svm_init,
- .cleanup = svm_cleanup,
- .resume = svm_restore,
- .vminit = svm_vminit,
- .vmrun = svm_vmrun,
- .vmcleanup = svm_vmcleanup,
- .vmgetreg = svm_getreg,
- .vmsetreg = svm_setreg,
- .vmgetdesc = vmcb_getdesc,
- .vmsetdesc = vmcb_setdesc,
- .vmgetcap = svm_getcap,
- .vmsetcap = svm_setcap,
+ .modinit = svm_init,
+ .modcleanup = svm_cleanup,
+ .modresume = svm_restore,
+ .init = svm_vminit,
+ .run = svm_vmrun,
+ .cleanup = svm_vmcleanup,
+ .getreg = svm_getreg,
+ .setreg = svm_setreg,
+ .getdesc = vmcb_getdesc,
+ .setdesc = vmcb_setdesc,
+ .getcap = svm_getcap,
+ .setcap = svm_setcap,
.vmspace_alloc = svm_npt_alloc,
.vmspace_free = svm_npt_free,
.vlapic_init = svm_vlapic_init,
.vlapic_cleanup = svm_vlapic_cleanup,
#ifdef BHYVE_SNAPSHOT
- .vmsnapshot = svm_snapshot_vmi,
+ .snapshot = svm_snapshot_vmi,
.vmcx_snapshot = svm_snapshot_vmcx,
- .vm_restore_tsc = svm_restore_tsc,
+ .restore_tsc = svm_restore_tsc,
#endif
};
Index: sys/amd64/vmm/intel/vmx.c
===================================================================
--- sys/amd64/vmm/intel/vmx.c
+++ sys/amd64/vmm/intel/vmx.c
@@ -4178,25 +4178,25 @@
#endif
struct vmm_ops vmm_ops_intel = {
- .init = vmx_init,
- .cleanup = vmx_cleanup,
- .resume = vmx_restore,
- .vminit = vmx_vminit,
- .vmrun = vmx_run,
- .vmcleanup = vmx_vmcleanup,
- .vmgetreg = vmx_getreg,
- .vmsetreg = vmx_setreg,
- .vmgetdesc = vmx_getdesc,
- .vmsetdesc = vmx_setdesc,
- .vmgetcap = vmx_getcap,
- .vmsetcap = vmx_setcap,
+ .modinit = vmx_init,
+ .modcleanup = vmx_cleanup,
+ .modresume = vmx_restore,
+ .init = vmx_vminit,
+ .run = vmx_run,
+ .cleanup = vmx_vmcleanup,
+ .getreg = vmx_getreg,
+ .setreg = vmx_setreg,
+ .getdesc = vmx_getdesc,
+ .setdesc = vmx_setdesc,
+ .getcap = vmx_getcap,
+ .setcap = vmx_setcap,
.vmspace_alloc = ept_vmspace_alloc,
.vmspace_free = ept_vmspace_free,
.vlapic_init = vmx_vlapic_init,
.vlapic_cleanup = vmx_vlapic_cleanup,
#ifdef BHYVE_SNAPSHOT
- .vmsnapshot = vmx_snapshot_vmi,
+ .snapshot = vmx_snapshot_vmi,
.vmcx_snapshot = vmx_snapshot_vmcx,
- .vm_restore_tsc = vmx_restore_tsc,
+ .restore_tsc = vmx_restore_tsc,
#endif
};
Index: sys/amd64/vmm/vmm.c
===================================================================
--- sys/amd64/vmm/vmm.c
+++ sys/amd64/vmm/vmm.c
@@ -67,6 +67,7 @@
#include <machine/md_var.h>
#include <x86/psl.h>
#include <x86/apicreg.h>
+#include <x86/ifunc.h>
#include <machine/vmm.h>
#include <machine/vmm_dev.h>
@@ -184,42 +185,53 @@
static int vmm_initialized;
-static struct vmm_ops *ops;
-#define VMM_INIT(num) (ops != NULL ? (*ops->init)(num) : 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, evinfo) \
- (ops != NULL ? (*ops->vmrun)(vmi, vcpu, rip, pmap, evinfo) : ENXIO)
-#define VMCLEANUP(vmi) (ops != NULL ? (*ops->vmcleanup)(vmi) : NULL)
-#define VMSPACE_ALLOC(min, max) \
- (ops != NULL ? (*ops->vmspace_alloc)(min, max) : NULL)
-#define VMSPACE_FREE(vmspace) \
- (ops != NULL ? (*ops->vmspace_free)(vmspace) : ENXIO)
-#define VMGETREG(vmi, vcpu, num, retval) \
- (ops != NULL ? (*ops->vmgetreg)(vmi, vcpu, num, retval) : ENXIO)
-#define VMSETREG(vmi, vcpu, num, val) \
- (ops != NULL ? (*ops->vmsetreg)(vmi, vcpu, num, val) : ENXIO)
-#define VMGETDESC(vmi, vcpu, num, desc) \
- (ops != NULL ? (*ops->vmgetdesc)(vmi, vcpu, num, desc) : ENXIO)
-#define VMSETDESC(vmi, vcpu, num, desc) \
- (ops != NULL ? (*ops->vmsetdesc)(vmi, vcpu, num, desc) : ENXIO)
-#define VMGETCAP(vmi, vcpu, num, retval) \
- (ops != NULL ? (*ops->vmgetcap)(vmi, vcpu, num, retval) : ENXIO)
-#define VMSETCAP(vmi, vcpu, num, val) \
- (ops != NULL ? (*ops->vmsetcap)(vmi, vcpu, num, val) : ENXIO)
-#define VLAPIC_INIT(vmi, vcpu) \
- (ops != NULL ? (*ops->vlapic_init)(vmi, vcpu) : NULL)
-#define VLAPIC_CLEANUP(vmi, vlapic) \
- (ops != NULL ? (*ops->vlapic_cleanup)(vmi, vlapic) : NULL)
+static void vmmops_panic(void);
+
+static void
+vmmops_panic(void)
+{
+ panic("vmm_ops func called when !vmm_is_intel() && !vmm_is_svm()");
+}
+
+#define DEFINE_VMMOPS_IFUNC(ret_type, opname, args) \
+ DEFINE_IFUNC(static, ret_type, vmmops_##opname, args) \
+ { \
+ if (vmm_is_intel()) \
+ return (vmm_ops_intel.opname); \
+ else if (vmm_is_svm()) \
+ return (vmm_ops_amd.opname); \
+ else \
+ return ((ret_type (*)args)vmmops_panic); \
+ }
+
+DEFINE_VMMOPS_IFUNC(int, modinit, (int ipinum))
+DEFINE_VMMOPS_IFUNC(int, modcleanup, (void))
+DEFINE_VMMOPS_IFUNC(void, modresume, (void))
+DEFINE_VMMOPS_IFUNC(void *, init, (struct vm *vm, struct pmap *pmap))
+DEFINE_VMMOPS_IFUNC(int, run, (void *vmi, int vcpu, register_t rip,
+ struct pmap *pmap, struct vm_eventinfo *info))
+DEFINE_VMMOPS_IFUNC(void, cleanup, (void *vmi))
+DEFINE_VMMOPS_IFUNC(int, getreg, (void *vmi, int vcpu, int num,
+ uint64_t *retval))
+DEFINE_VMMOPS_IFUNC(int, setreg, (void *vmi, int vcpu, int num,
+ uint64_t val))
+DEFINE_VMMOPS_IFUNC(int, getdesc, (void *vmi, int vcpu, int num,
+ struct seg_desc *desc))
+DEFINE_VMMOPS_IFUNC(int, setdesc, (void *vmi, int vcpu, int num,
+ struct seg_desc *desc))
+DEFINE_VMMOPS_IFUNC(int, getcap, (void *vmi, int vcpu, int num, int *retval))
+DEFINE_VMMOPS_IFUNC(int, setcap, (void *vmi, int vcpu, int num, int val))
+DEFINE_VMMOPS_IFUNC(struct vmspace *, vmspace_alloc, (vm_offset_t min,
+ vm_offset_t max))
+DEFINE_VMMOPS_IFUNC(void, vmspace_free, (struct vmspace *vmspace))
+DEFINE_VMMOPS_IFUNC(struct vlapic *, vlapic_init, (void *vmi, int vcpu))
+DEFINE_VMMOPS_IFUNC(void, vlapic_cleanup, (void *vmi, struct vlapic *vlapic))
#ifdef BHYVE_SNAPSHOT
-#define VM_SNAPSHOT_VMI(vmi, meta) \
- (ops != NULL ? (*ops->vmsnapshot)(vmi, meta) : ENXIO)
-#define VM_SNAPSHOT_VMCX(vmi, meta, vcpuid) \
- (ops != NULL ? (*ops->vmcx_snapshot)(vmi, meta, vcpuid) : ENXIO)
-#define VM_RESTORE_TSC(vmi, vcpuid, offset) \
- (ops != NULL ? (*ops->vm_restore_tsc)(vmi, vcpuid, offset) : ENXIO)
+DEFINE_VMMOPS_IFUNC(int, snapshot, (void *vmi, struct vm_snapshot_meta
+ *meta))
+DEFINE_VMMOPS_IFUNC(int, vmcx_snapshot, (void *vmi, struct vm_snapshot_meta
+ *meta, int vcpu))
+DEFINE_VMMOPS_IFUNC(int, restore_tsc, (void *vmi, int vcpuid, uint64_t now))
#endif
#define fpu_start_emulating() load_cr0(rcr0() | CR0_TS)
@@ -282,7 +294,7 @@
{
struct vcpu *vcpu = &vm->vcpu[i];
- VLAPIC_CLEANUP(vm->cookie, vcpu->vlapic);
+ vmmops_vlapic_cleanup(vm->cookie, vcpu->vlapic);
if (destroy) {
vmm_stat_free(vcpu->stats);
fpu_save_area_free(vcpu->guestfpu);
@@ -310,7 +322,7 @@
vcpu->tsc_offset = 0;
}
- vcpu->vlapic = VLAPIC_INIT(vm->cookie, vcpu_id);
+ vcpu->vlapic = vmmops_vlapic_init(vm->cookie, vcpu_id);
vm_set_x2apic_state(vm, vcpu_id, X2APIC_DISABLED);
vcpu->reqidle = 0;
vcpu->exitintinfo = 0;
@@ -342,17 +354,14 @@
return (&vcpu->exitinfo);
}
-static void
-vmm_resume(void)
-{
- VMM_RESUME();
-}
-
static int
vmm_init(void)
{
int error;
+ if (!vmm_is_hw_supported())
+ return (ENXIO);
+
vmm_host_state_init();
vmm_ipinum = lapic_ipi_alloc(pti ? &IDTVEC(justreturn1_pti) :
@@ -364,16 +373,9 @@
if (error)
return (error);
- if (vmm_is_intel())
- ops = &vmm_ops_intel;
- else if (vmm_is_svm())
- ops = &vmm_ops_amd;
- else
- return (ENXIO);
-
- vmm_resume_p = vmm_resume;
+ vmm_resume_p = vmmops_modresume;
- return (VMM_INIT(vmm_ipinum));
+ return (vmmops_modinit(vmm_ipinum));
}
static int
@@ -383,25 +385,33 @@
switch (what) {
case MOD_LOAD:
- vmmdev_init();
- error = vmm_init();
- if (error == 0)
- vmm_initialized = 1;
+ if (vmm_is_hw_supported()) {
+ vmmdev_init();
+ error = vmm_init();
+ if (error == 0)
+ vmm_initialized = 1;
+ } else {
+ error = ENXIO;
+ }
break;
case MOD_UNLOAD:
- error = vmmdev_cleanup();
- if (error == 0) {
- vmm_resume_p = NULL;
- iommu_cleanup();
- if (vmm_ipinum != IPI_AST)
- lapic_ipi_free(vmm_ipinum);
- error = VMM_CLEANUP();
- /*
- * Something bad happened - prevent new
- * VMs from being created
- */
- if (error)
- vmm_initialized = 0;
+ if (vmm_is_hw_supported()) {
+ error = vmmdev_cleanup();
+ if (error == 0) {
+ vmm_resume_p = NULL;
+ iommu_cleanup();
+ if (vmm_ipinum != IPI_AST)
+ lapic_ipi_free(vmm_ipinum);
+ error = vmmops_modcleanup();
+ /*
+ * Something bad happened - prevent new
+ * VMs from being created
+ */
+ if (error)
+ vmm_initialized = 0;
+ }
+ } else {
+ error = 0;
}
break;
default:
@@ -431,7 +441,7 @@
{
int i;
- vm->cookie = VMINIT(vm, vmspace_pmap(vm->vmspace));
+ vm->cookie = vmmops_init(vm, vmspace_pmap(vm->vmspace));
vm->iommu = NULL;
vm->vioapic = vioapic_init(vm);
vm->vhpet = vhpet_init(vm);
@@ -473,7 +483,7 @@
if (name == NULL || strlen(name) >= VM_MAX_NAMELEN)
return (EINVAL);
- vmspace = VMSPACE_ALLOC(0, VM_MAXUSER_ADDRESS);
+ vmspace = vmmops_vmspace_alloc(0, VM_MAXUSER_ADDRESS);
if (vmspace == NULL)
return (ENOMEM);
@@ -549,7 +559,7 @@
for (i = 0; i < vm->maxcpus; i++)
vcpu_cleanup(vm, i, destroy);
- VMCLEANUP(vm->cookie);
+ vmmops_cleanup(vm->cookie);
/*
* System memory is removed from the guest address space only when
@@ -569,7 +579,7 @@
for (i = 0; i < VM_MAX_MEMSEGS; i++)
vm_free_memseg(vm, i);
- VMSPACE_FREE(vm->vmspace);
+ vmmops_vmspace_free(vm->vmspace);
vm->vmspace = NULL;
}
}
@@ -1033,7 +1043,7 @@
if (reg >= VM_REG_LAST)
return (EINVAL);
- return (VMGETREG(vm->cookie, vcpu, reg, retval));
+ return (vmmops_getreg(vm->cookie, vcpu, reg, retval));
}
int
@@ -1048,7 +1058,7 @@
if (reg >= VM_REG_LAST)
return (EINVAL);
- error = VMSETREG(vm->cookie, vcpuid, reg, val);
+ error = vmmops_setreg(vm->cookie, vcpuid, reg, val);
if (error || reg != VM_REG_GUEST_RIP)
return (error);
@@ -1102,7 +1112,7 @@
if (!is_segment_register(reg) && !is_descriptor_table(reg))
return (EINVAL);
- return (VMGETDESC(vm->cookie, vcpu, reg, desc));
+ return (vmmops_getdesc(vm->cookie, vcpu, reg, desc));
}
int
@@ -1115,7 +1125,7 @@
if (!is_segment_register(reg) && !is_descriptor_table(reg))
return (EINVAL);
- return (VMSETDESC(vm->cookie, vcpu, reg, desc));
+ return (vmmops_setdesc(vm->cookie, vcpu, reg, desc));
}
static void
@@ -1333,7 +1343,7 @@
* software events that would cause this vcpu to wakeup.
*
* These interrupts/events could have happened after the
- * vcpu returned from VMRUN() and before it acquired the
+ * vcpu returned from vmmops_run() and before it acquired the
* vcpu lock above.
*/
if (vm->rendezvous_func != NULL || vm->suspend || vcpu->reqidle)
@@ -1730,7 +1740,7 @@
restore_guest_fpustate(vcpu);
vcpu_require_state(vm, vcpuid, VCPU_RUNNING);
- error = VMRUN(vm->cookie, vcpuid, vcpu->nextrip, pmap, &evinfo);
+ error = vmmops_run(vm->cookie, vcpuid, vcpu->nextrip, pmap, &evinfo);
vcpu_require_state(vm, vcpuid, VCPU_FROZEN);
save_guest_fpustate(vcpu);
@@ -1819,9 +1829,9 @@
} else if (state == VCPU_FROZEN) {
/*
* When a vcpu is "frozen" it is outside the critical section
- * around VMRUN() and 'nextrip' points to the next instruction.
- * Thus instruction restart is achieved by setting 'nextrip'
- * to the vcpu's %rip.
+ * around vmmops_run() and 'nextrip' points to the next
+ * instruction. Thus instruction restart is achieved by setting
+ * 'nextrip' to the vcpu's %rip.
*/
error = vm_get_register(vm, vcpuid, VM_REG_GUEST_RIP, &rip);
KASSERT(!error, ("%s: error %d getting rip", __func__, error));
@@ -2226,7 +2236,7 @@
if (type < 0 || type >= VM_CAP_MAX)
return (EINVAL);
- return (VMGETCAP(vm->cookie, vcpu, type, retval));
+ return (vmmops_getcap(vm->cookie, vcpu, type, retval));
}
int
@@ -2238,7 +2248,7 @@
if (type < 0 || type >= VM_CAP_MAX)
return (EINVAL);
- return (VMSETCAP(vm->cookie, vcpu, type, val));
+ return (vmmops_setcap(vm->cookie, vcpu, type, val));
}
struct vlapic *
@@ -2824,7 +2834,7 @@
error = 0;
for (i = 0; i < VM_MAXCPU; i++) {
- error = VM_SNAPSHOT_VMCX(vm->cookie, meta, i);
+ error = vmmops_vmcx_snapshot(vm->cookie, meta, i);
if (error != 0) {
printf("%s: failed to snapshot vmcs/vmcb data for "
"vCPU: %d; error: %d\n", __func__, i, error);
@@ -2846,7 +2856,7 @@
switch (meta->dev_req) {
case STRUCT_VMX:
- ret = VM_SNAPSHOT_VMI(vm->cookie, meta);
+ ret = vmmops_snapshot(vm->cookie, meta);
break;
case STRUCT_VMCX:
ret = vm_snapshot_vmcx(vm, meta);
@@ -2913,7 +2923,8 @@
for (i = 0; i < nitems(vm->vcpu); i++) {
vcpu = &vm->vcpu[i];
- error = VM_RESTORE_TSC(vm->cookie, i, vcpu->tsc_offset - now);
+ error = vmmops_restore_tsc(vm->cookie, i, vcpu->tsc_offset -
+ now);
if (error)
return (error);
}
Index: sys/amd64/vmm/vmm_util.h
===================================================================
--- sys/amd64/vmm/vmm_util.h
+++ sys/amd64/vmm/vmm_util.h
@@ -33,6 +33,7 @@
struct trapframe;
+bool vmm_is_hw_supported(void);
bool vmm_is_intel(void);
bool vmm_is_svm(void);
bool vmm_supports_1G_pages(void);
Index: sys/amd64/vmm/vmm_util.c
===================================================================
--- sys/amd64/vmm/vmm_util.c
+++ sys/amd64/vmm/vmm_util.c
@@ -38,6 +38,12 @@
#include "vmm_util.h"
+bool
+vmm_is_hw_supported(void)
+{
+ return (vmm_is_intel() || vmm_is_svm());
+}
+
bool
vmm_is_intel(void)
{
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jul 31, 8:47 AM (2 h, 12 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35778076
Default Alt Text
D27375.id80000.diff (15 KB)
Attached To
Mode
D27375: vmm: Convert vmm_ops calls to IFUNC
Attached
Detach File
Event Timeline
Log In to Comment