diff options
author | neel <neel@FreeBSD.org> | 2013-04-12 01:16:52 +0000 |
---|---|---|
committer | neel <neel@FreeBSD.org> | 2013-04-12 01:16:52 +0000 |
commit | cbd874121f7cb0e400ce616aece1e54f73d09cfb (patch) | |
tree | 3eb0b17bf3ad3699d913400eb7a26ac54cda0596 /sys/amd64 | |
parent | 5f0af63a3ffd1c7e77dbd701f1eeee90e4c34206 (diff) | |
download | FreeBSD-src-cbd874121f7cb0e400ce616aece1e54f73d09cfb.zip FreeBSD-src-cbd874121f7cb0e400ce616aece1e54f73d09cfb.tar.gz |
If vmm.ko could not be initialized correctly then prevent the creation of
virtual machines subsequently.
Submitted by: Chris Torek
Diffstat (limited to 'sys/amd64')
-rw-r--r-- | sys/amd64/include/vmm.h | 2 | ||||
-rw-r--r-- | sys/amd64/vmm/vmm.c | 21 | ||||
-rw-r--r-- | sys/amd64/vmm/vmm_dev.c | 6 |
3 files changed, 21 insertions, 8 deletions
diff --git a/sys/amd64/include/vmm.h b/sys/amd64/include/vmm.h index 6bd3566..9a3063e 100644 --- a/sys/amd64/include/vmm.h +++ b/sys/amd64/include/vmm.h @@ -87,7 +87,7 @@ struct vmm_ops { extern struct vmm_ops vmm_ops_intel; extern struct vmm_ops vmm_ops_amd; -struct vm *vm_create(const char *name); +int vm_create(const char *name, struct vm **retvm); void vm_destroy(struct vm *vm); const char *vm_name(struct vm *vm); int vm_malloc(struct vm *vm, vm_paddr_t gpa, size_t len); diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c index 1de4470..f21bddd 100644 --- a/sys/amd64/vmm/vmm.c +++ b/sys/amd64/vmm/vmm.c @@ -103,6 +103,8 @@ struct vm { cpuset_t active_cpus; }; +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) @@ -213,6 +215,8 @@ vmm_handler(module_t mod, int what, void *arg) vmmdev_init(); iommu_init(); error = vmm_init(); + if (error == 0) + vmm_initialized = 1; break; case MOD_UNLOAD: error = vmmdev_cleanup(); @@ -221,6 +225,7 @@ vmm_handler(module_t mod, int what, void *arg) vmm_ipi_cleanup(); error = VMM_CLEANUP(); } + vmm_initialized = 0; break; default: error = 0; @@ -249,8 +254,8 @@ MODULE_VERSION(vmm, 1); SYSCTL_NODE(_hw, OID_AUTO, vmm, CTLFLAG_RW, NULL, NULL); -struct vm * -vm_create(const char *name) +int +vm_create(const char *name, struct vm **retvm) { int i; struct vm *vm; @@ -258,8 +263,15 @@ vm_create(const char *name) const int BSP = 0; + /* + * If vmm.ko could not be successfully initialized then don't attempt + * to create the virtual machine. + */ + if (!vmm_initialized) + return (ENXIO); + if (name == NULL || strlen(name) >= VM_MAX_NAMELEN) - return (NULL); + return (EINVAL); vm = malloc(sizeof(struct vm), M_VM, M_WAITOK | M_ZERO); strcpy(vm->name, name); @@ -274,7 +286,8 @@ vm_create(const char *name) vm->iommu = iommu_create_domain(maxaddr); vm_activate_cpu(vm, BSP); - return (vm); + *retvm = vm; + return (0); } static void diff --git a/sys/amd64/vmm/vmm_dev.c b/sys/amd64/vmm/vmm_dev.c index 95527ae..7608d5c 100644 --- a/sys/amd64/vmm/vmm_dev.c +++ b/sys/amd64/vmm/vmm_dev.c @@ -475,9 +475,9 @@ sysctl_vmm_create(SYSCTL_HANDLER_ARGS) if (sc != NULL) return (EEXIST); - vm = vm_create(buf); - if (vm == NULL) - return (EINVAL); + error = vm_create(buf, &vm); + if (error != 0) + return (error); sc = malloc(sizeof(struct vmmdev_softc), M_VMMDEV, M_WAITOK | M_ZERO); sc->vm = vm; |