summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMike Larkin <mlarkin@cvs.openbsd.org>2017-01-13 02:38:42 +0000
committerMike Larkin <mlarkin@cvs.openbsd.org>2017-01-13 02:38:42 +0000
commitb6adca3dae638741e54dab82c7f4f462db66badb (patch)
tree59ec9e50c4f02f5221c42e882ed7d1d2396bd312 /sys
parent377354e17a1152a384f06fe676f20c50d53d5f68 (diff)
SVM/RVI: vm_impl_init_svm implementation, create pmap for RVI VMs
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/amd64/amd64/vmm.c63
-rw-r--r--sys/arch/i386/i386/vmm.c63
2 files changed, 120 insertions, 6 deletions
diff --git a/sys/arch/amd64/amd64/vmm.c b/sys/arch/amd64/amd64/vmm.c
index 7e3ae7a51a2..d785682d2ef 100644
--- a/sys/arch/amd64/amd64/vmm.c
+++ b/sys/arch/amd64/amd64/vmm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmm.c,v 1.105 2017/01/12 09:02:47 mlarkin Exp $ */
+/* $OpenBSD: vmm.c,v 1.106 2017/01/13 02:38:41 mlarkin Exp $ */
/*
* Copyright (c) 2014 Mike Larkin <mlarkin@openbsd.org>
*
@@ -1139,12 +1139,69 @@ vm_impl_init_vmx(struct vm *vm, struct proc *p)
* vm_impl_init_svm
*
* AMD SVM specific VM initialization routine
+ *
+ * Parameters:
+ * vm: the VM being initialized
+ * p: vmd process owning the VM
+ *
+ * Return values:
+ * 0: the initialization was successful
+ * ENOMEM: the initialization failed (lack of resources)
*/
int
vm_impl_init_svm(struct vm *vm, struct proc *p)
{
- /* XXX removed due to rot */
- return (-1);
+ int i, ret;
+ vaddr_t mingpa, maxgpa;
+ struct pmap *pmap;
+ struct vm_mem_range *vmr;
+
+ /* If not RVI, nothing to do here */
+ if (vmm_softc->mode != VMM_MODE_RVI)
+ return (0);
+
+ /* Create a new pmap for this VM */
+ pmap = pmap_create();
+ if (!pmap) {
+ printf("vm_impl_init_svm: pmap_create failed\n");
+ return (ENOMEM);
+ }
+
+ /*
+ * Create a new UVM map for this VM, and assign it the pmap just
+ * created.
+ */
+ vmr = &vm->vm_memranges[0];
+ mingpa = vmr->vmr_gpa;
+ vmr = &vm->vm_memranges[vm->vm_nmemranges - 1];
+ maxgpa = vmr->vmr_gpa + vmr->vmr_size;
+ vm->vm_map = uvm_map_create(pmap, mingpa, maxgpa,
+ VM_MAP_ISVMSPACE | VM_MAP_PAGEABLE);
+
+ if (!vm->vm_map) {
+ printf("vm_impl_init_svm: uvm_map_create failed\n");
+ pmap_destroy(pmap);
+ return (ENOMEM);
+ }
+
+ /* Map the new map with an anon */
+ DPRINTF("vm_impl_init_svm: created vm_map @ %p\n", vm->vm_map);
+ for (i = 0; i < vm->vm_nmemranges; i++) {
+ vmr = &vm->vm_memranges[i];
+ ret = uvm_share(vm->vm_map, vmr->vmr_gpa,
+ PROT_READ | PROT_WRITE | PROT_EXEC,
+ &p->p_vmspace->vm_map, vmr->vmr_va, vmr->vmr_size);
+ if (ret) {
+ printf("vm_impl_init_svm: uvm_share failed (%d)\n",
+ ret);
+ /* uvm_map_deallocate calls pmap_destroy for us */
+ uvm_map_deallocate(vm->vm_map);
+ vm->vm_map = NULL;
+ return (ENOMEM);
+ }
+ }
+
+ return (0);
}
/*
diff --git a/sys/arch/i386/i386/vmm.c b/sys/arch/i386/i386/vmm.c
index 2dfedaf1d46..333fdbb6ef2 100644
--- a/sys/arch/i386/i386/vmm.c
+++ b/sys/arch/i386/i386/vmm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmm.c,v 1.12 2017/01/12 09:02:47 mlarkin Exp $ */
+/* $OpenBSD: vmm.c,v 1.13 2017/01/13 02:38:41 mlarkin Exp $ */
/*
* Copyright (c) 2014 Mike Larkin <mlarkin@openbsd.org>
*
@@ -1148,12 +1148,69 @@ vm_impl_init_vmx(struct vm *vm, struct proc *p)
* vm_impl_init_svm
*
* AMD SVM specific VM initialization routine
+ *
+ * Parameters:
+ * vm: the VM being initialized
+ * p: vmd process owning the VM
+ *
+ * Return values:
+ * 0: the initialization was successful
+ * ENOMEM: the initialization failed (lack of resources)
*/
int
vm_impl_init_svm(struct vm *vm, struct proc *p)
{
- /* XXX removed due to rot */
- return (-1);
+ int i, ret;
+ vaddr_t mingpa, maxgpa;
+ struct pmap *pmap;
+ struct vm_mem_range *vmr;
+
+ /* If not RVI, nothing to do here */
+ if (vmm_softc->mode != VMM_MODE_RVI)
+ return (0);
+
+ /* Create a new pmap for this VM */
+ pmap = pmap_create();
+ if (!pmap) {
+ printf("vm_impl_init_svm: pmap_create failed\n");
+ return (ENOMEM);
+ }
+
+ /*
+ * Create a new UVM map for this VM, and assign it the pmap just
+ * created.
+ */
+ vmr = &vm->vm_memranges[0];
+ mingpa = vmr->vmr_gpa;
+ vmr = &vm->vm_memranges[vm->vm_nmemranges - 1];
+ maxgpa = vmr->vmr_gpa + vmr->vmr_size;
+ vm->vm_map = uvm_map_create(pmap, mingpa, maxgpa,
+ VM_MAP_ISVMSPACE | VM_MAP_PAGEABLE);
+
+ if (!vm->vm_map) {
+ printf("vm_impl_init_svm: uvm_map_create failed\n");
+ pmap_destroy(pmap);
+ return (ENOMEM);
+ }
+
+ /* Map the new map with an anon */
+ DPRINTF("vm_impl_init_svm: created vm_map @ %p\n", vm->vm_map);
+ for (i = 0; i < vm->vm_nmemranges; i++) {
+ vmr = &vm->vm_memranges[i];
+ ret = uvm_share(vm->vm_map, vmr->vmr_gpa,
+ PROT_READ | PROT_WRITE | PROT_EXEC,
+ &p->p_vmspace->vm_map, vmr->vmr_va, vmr->vmr_size);
+ if (ret) {
+ printf("vm_impl_init_svm: uvm_share failed (%d)\n",
+ ret);
+ /* uvm_map_deallocate calls pmap_destroy for us */
+ uvm_map_deallocate(vm->vm_map);
+ vm->vm_map = NULL;
+ return (ENOMEM);
+ }
+ }
+
+ return (0);
}
/*