Esempio n. 1
0
File: vmm.c Progetto: anandab/akaros
/* Initializes a process to run virtual machine contexts, returning the number
 * initialized, optionally setting errno */
int vmm_struct_init(struct proc *p, unsigned int nr_guest_pcores,
                    struct vmm_gpcore_init *u_gpcis, int flags)
{
	struct vmm *vmm = &p->vmm;
	unsigned int i;
	struct vmm_gpcore_init gpci;

	if (flags & ~VMM_ALL_FLAGS) {
		set_errstr("%s: flags is 0x%lx, VMM_ALL_FLAGS is 0x%lx\n", __func__,
		           flags, VMM_ALL_FLAGS);
		set_errno(EINVAL);
		return 0;
	}
	vmm->flags = flags;
	if (!x86_supports_vmx) {
		set_errno(ENODEV);
		return 0;
	}
	qlock(&vmm->qlock);
	if (vmm->vmmcp) {
		set_errno(EINVAL);
		qunlock(&vmm->qlock);
		return 0;
	}
	/* Set this early, so cleanup checks the gpc array */
	vmm->vmmcp = TRUE;
	nr_guest_pcores = MIN(nr_guest_pcores, num_cores);
	vmm->amd = 0;
	vmm->guest_pcores = kzmalloc(sizeof(void*) * nr_guest_pcores, KMALLOC_WAIT);
	for (i = 0; i < nr_guest_pcores; i++) {
		if (copy_from_user(&gpci, &u_gpcis[i],
		                   sizeof(struct vmm_gpcore_init))) {
			set_error(EINVAL, "Bad pointer %p for gps", u_gpcis);
			break;
		}
		vmm->guest_pcores[i] = create_guest_pcore(p, &gpci);
		/* If we failed, we'll clean it up when the process dies */
		if (!vmm->guest_pcores[i]) {
			set_errno(ENOMEM);
			break;
		}
	}
	vmm->nr_guest_pcores = i;
	for (int i = 0; i < VMM_VMEXIT_NR_TYPES; i++)
		vmm->vmexits[i] = 0;
	qunlock(&vmm->qlock);
	return i;
}
Esempio n. 2
0
/* Initializes a process to run virtual machine contexts, returning the number
 * initialized, throwing on error. */
int vmm_struct_init(struct proc *p, unsigned int nr_guest_pcores,
                    struct vmm_gpcore_init *u_gpcis, int flags)
{
	ERRSTACK(1);
	struct vmm *vmm = &p->vmm;
	struct vmm_gpcore_init gpci;

	if (flags & ~VMM_ALL_FLAGS)
		error(EINVAL, "%s: flags is 0x%lx, VMM_ALL_FLAGS is 0x%lx\n", __func__,
		      flags, VMM_ALL_FLAGS);
	vmm->flags = flags;
	if (!x86_supports_vmx)
		error(ENODEV, "This CPU does not support VMX");
	qlock(&vmm->qlock);
	if (waserror()) {
		qunlock(&vmm->qlock);
		nexterror();
	}

	/* TODO: just use an atomic test instead of all this locking stuff? */
	if (vmm->vmmcp)
		error(EAGAIN, "We're already running a vmmcp?");
	/* Set this early, so cleanup checks the gpc array */
	vmm->vmmcp = TRUE;
	nr_guest_pcores = MIN(nr_guest_pcores, num_cores);
	vmm->amd = 0;
	vmm->guest_pcores = kzmalloc(sizeof(void *) * nr_guest_pcores, MEM_WAIT);
	if (!vmm->guest_pcores)
		error(ENOMEM, "Allocation of vmm->guest_pcores failed");

	for (int i = 0; i < nr_guest_pcores; i++) {
		if (copy_from_user(&gpci, &u_gpcis[i], sizeof(struct vmm_gpcore_init)))
			error(EINVAL, "Bad pointer %p for gps", u_gpcis);
		vmm->guest_pcores[i] = create_guest_pcore(p, &gpci);
		vmm->nr_guest_pcores = i + 1;
	}
	for (int i = 0; i < VMM_VMEXIT_NR_TYPES; i++)
		vmm->vmexits[i] = 0;
	qunlock(&vmm->qlock);
	poperror();
	return vmm->nr_guest_pcores;
}