summaryrefslogtreecommitdiffstats
path: root/sys/amd64
diff options
context:
space:
mode:
authorneel <neel@FreeBSD.org>2013-04-12 01:16:52 +0000
committerneel <neel@FreeBSD.org>2013-04-12 01:16:52 +0000
commitcbd874121f7cb0e400ce616aece1e54f73d09cfb (patch)
tree3eb0b17bf3ad3699d913400eb7a26ac54cda0596 /sys/amd64
parent5f0af63a3ffd1c7e77dbd701f1eeee90e4c34206 (diff)
downloadFreeBSD-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.h2
-rw-r--r--sys/amd64/vmm/vmm.c21
-rw-r--r--sys/amd64/vmm/vmm_dev.c6
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;
OpenPOWER on IntegriCloud