int svm_create_vmcb(struct vcpu *v) { struct nestedvcpu *nv = &vcpu_nestedhvm(v); struct arch_svm_struct *arch_svm = &v->arch.hvm_svm; int rc; if ( (nv->nv_n1vmcx == NULL) && (nv->nv_n1vmcx = alloc_vmcb()) == NULL ) { printk("Failed to create a new VMCB\n"); return -ENOMEM; } arch_svm->vmcb = nv->nv_n1vmcx; rc = construct_vmcb(v); if ( rc != 0 ) { free_vmcb(nv->nv_n1vmcx); nv->nv_n1vmcx = NULL; arch_svm->vmcb = NULL; return rc; } arch_svm->vmcb_pa = nv->nv_n1vmcx_pa = virt_to_maddr(arch_svm->vmcb); return 0; }
void vm_create ( struct vm *vm, unsigned long guest_image_start, unsigned long guest_image_size, unsigned long vm_pmem_size ) { struct vmcb *vmcb; /* Allocate a new page for storing VMCB. */ vmcb = alloc_vmcb ( ); vm->vmcb = vmcb; set_control_area ( vm->vmcb ); set_state_save_area ( vm->vmcb ); /* Allocate new pages for physical memory of the guest OS. */ const unsigned long vm_pmem_start = alloc_vm_pmem ( vm_pmem_size ); /* Set Host-level CR3 to use for nested paging. */ vm->h_cr3 = create_vm_pmem_mapping_table ( vm_pmem_start, vm_pmem_size ); vmcb->h_cr3 = vm->h_cr3; /* Copy the OS image to the specified region by interpreting the ELF format. */ vmcb->rip = load_elf_image ( guest_image_start, guest_image_size, vm_pmem_start ); /* Setup multiboot info. */ vm->mbi = init_vm_mbi ( vm_pmem_start ); create_temp_page_table ( vm_pmem_start, vmcb->cr3 ); printf ( "New virtual machine created.\n" ); }