Lines Matching +full:gpa +full:- +full:0

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
80 !(ucred->cr_prison->pr_allow & pr_allow_flag)) in vmm_priv_check()
83 return (0); in vmm_priv_check()
113 error = 0; in vcpu_lock_all()
114 vm_slock_vcpus(sc->vm); in vcpu_lock_all()
115 maxcpus = vm_get_maxcpus(sc->vm); in vcpu_lock_all()
116 for (i = 0; i < maxcpus; i++) { in vcpu_lock_all()
117 vcpu = vm_vcpu(sc->vm, i); in vcpu_lock_all()
126 for (j = 0; j < i; j++) { in vcpu_lock_all()
127 vcpu = vm_vcpu(sc->vm, j); in vcpu_lock_all()
132 vm_unlock_vcpus(sc->vm); in vcpu_lock_all()
144 maxcpus = vm_get_maxcpus(sc->vm); in vcpu_unlock_all()
145 for (i = 0; i < maxcpus; i++) { in vcpu_unlock_all()
146 vcpu = vm_vcpu(sc->vm, i); in vcpu_unlock_all()
151 vm_unlock_vcpus(sc->vm); in vcpu_unlock_all()
162 if (strcmp(name, vm_name(sc->vm)) == 0) in vmmdev_lookup()
169 if (cr_cansee(cred, sc->ucred)) in vmmdev_lookup()
178 return (cdev->si_drv1); in vmmdev_lookup2()
185 vm_paddr_t gpa, maxaddr; in vmmdev_rw() local
196 vm_slock_memsegs(sc->vm); in vmmdev_rw()
198 prot = (uio->uio_rw == UIO_WRITE ? VM_PROT_WRITE : VM_PROT_READ); in vmmdev_rw()
199 maxaddr = vmm_sysmem_maxaddr(sc->vm); in vmmdev_rw()
200 while (uio->uio_resid > 0 && error == 0) { in vmmdev_rw()
201 gpa = uio->uio_offset; in vmmdev_rw()
202 off = gpa & PAGE_MASK; in vmmdev_rw()
203 c = min(uio->uio_resid, PAGE_SIZE - off); in vmmdev_rw()
213 hpa = vm_gpa_hold_global(sc->vm, gpa, c, prot, &cookie); in vmmdev_rw()
215 if (uio->uio_rw == UIO_READ && gpa < maxaddr) in vmmdev_rw()
225 vm_unlock_memsegs(sc->vm); in vmmdev_rw()
229 CTASSERT(sizeof(((struct vm_memseg *)0)->name) >= VM_MAX_SUFFIXLEN + 1);
238 error = vm_get_memseg(sc->vm, mseg->segid, &mseg->len, &sysmem, NULL); in get_memseg()
239 if (error || mseg->len == 0) in get_memseg()
243 SLIST_FOREACH(dsc, &sc->devmem, link) { in get_memseg()
244 if (dsc->segid == mseg->segid) in get_memseg()
248 __func__, mseg->segid)); in get_memseg()
249 error = copystr(dsc->name, mseg->name, len, NULL); in get_memseg()
251 bzero(mseg->name, len); in get_memseg()
264 error = 0; in alloc_memseg()
275 error = copystr(mseg->name, name, len, NULL); in alloc_memseg()
280 error = vm_alloc_memseg(sc->vm, mseg->segid, mseg->len, sysmem); in alloc_memseg()
285 error = devmem_create_cdev(sc, mseg->segid, name); in alloc_memseg()
287 vm_free_memseg(sc->vm, mseg->segid); in alloc_memseg()
302 error = 0; in vm_get_register_set()
303 for (i = 0; i < count; i++) { in vm_get_register_set()
317 error = 0; in vm_set_register_set()
318 for (i = 0; i < count; i++) { in vm_set_register_set()
335 error = vmm_priv_check(td->td_ucred); in vmmdev_open()
336 if (error != 0) in vmmdev_open()
339 return (0); in vmmdev_open()
375 VMMDEV_IOCTL(VM_SUSPEND, 0),
376 VMMDEV_IOCTL(VM_GET_CPUS, 0),
377 VMMDEV_IOCTL(VM_GET_TOPOLOGY, 0),
378 VMMDEV_IOCTL(VM_SET_TOPOLOGY, 0),
395 for (size_t i = 0; i < nitems(vmmdev_ioctls); i++) { in vmmdev_ioctl()
402 for (size_t i = 0; i < vmmdev_machdep_ioctl_count; i++) { in vmmdev_ioctl()
412 if ((ioctl->flags & VMMDEV_IOCTL_XLOCK_MEMSEGS) != 0) in vmmdev_ioctl()
413 vm_xlock_memsegs(sc->vm); in vmmdev_ioctl()
414 else if ((ioctl->flags & VMMDEV_IOCTL_SLOCK_MEMSEGS) != 0) in vmmdev_ioctl()
415 vm_slock_memsegs(sc->vm); in vmmdev_ioctl()
418 vcpuid = -1; in vmmdev_ioctl()
419 if ((ioctl->flags & (VMMDEV_IOCTL_LOCK_ONE_VCPU | in vmmdev_ioctl()
420 VMMDEV_IOCTL_ALLOC_VCPU | VMMDEV_IOCTL_MAYBE_ALLOC_VCPU)) != 0) { in vmmdev_ioctl()
422 if (vcpuid == -1) { in vmmdev_ioctl()
423 if ((ioctl->flags & in vmmdev_ioctl()
424 VMMDEV_IOCTL_MAYBE_ALLOC_VCPU) == 0) { in vmmdev_ioctl()
429 vcpu = vm_alloc_vcpu(sc->vm, vcpuid); in vmmdev_ioctl()
434 if ((ioctl->flags & VMMDEV_IOCTL_LOCK_ONE_VCPU) != 0) { in vmmdev_ioctl()
441 if ((ioctl->flags & VMMDEV_IOCTL_LOCK_ALL_VCPUS) != 0) { in vmmdev_ioctl()
452 error = vm_suspend(sc->vm, vmsuspend->how); in vmmdev_ioctl()
456 error = vm_reinit(sc->vm); in vmmdev_ioctl()
462 error = vmm_stat_desc_copy(statdesc->index, statdesc->desc, in vmmdev_ioctl()
463 sizeof(statdesc->desc)); in vmmdev_ioctl()
470 getmicrotime(&vmstats->tv); in vmmdev_ioctl()
471 error = vmm_stat_copy(vcpu, vmstats->index, in vmmdev_ioctl()
472 nitems(vmstats->statbuf), &vmstats->num_entries, in vmmdev_ioctl()
473 vmstats->statbuf); in vmmdev_ioctl()
480 error = vm_mmap_getnext(sc->vm, &mm->gpa, &mm->segid, in vmmdev_ioctl()
481 &mm->segoff, &mm->len, &mm->prot, &mm->flags); in vmmdev_ioctl()
488 error = vm_mmap_memseg(sc->vm, mm->gpa, mm->segid, mm->segoff, in vmmdev_ioctl()
489 mm->len, mm->prot, mm->flags); in vmmdev_ioctl()
496 error = vm_munmap_memseg(sc->vm, mu->gpa, mu->len); in vmmdev_ioctl()
502 sizeof(((struct vm_memseg_12 *)0)->name)); in vmmdev_ioctl()
506 sizeof(((struct vm_memseg_12 *)0)->name)); in vmmdev_ioctl()
511 sizeof(((struct vm_memseg *)0)->name)); in vmmdev_ioctl()
515 sizeof(((struct vm_memseg *)0)->name)); in vmmdev_ioctl()
521 error = vm_get_register(vcpu, vmreg->regnum, &vmreg->regval); in vmmdev_ioctl()
528 error = vm_set_register(vcpu, vmreg->regnum, vmreg->regval); in vmmdev_ioctl()
537 if (vmregset->count > VM_REG_LAST) { in vmmdev_ioctl()
541 regvals = malloc(sizeof(regvals[0]) * vmregset->count, M_VMMDEV, in vmmdev_ioctl()
543 regnums = malloc(sizeof(regnums[0]) * vmregset->count, M_VMMDEV, in vmmdev_ioctl()
545 error = copyin(vmregset->regnums, regnums, sizeof(regnums[0]) * in vmmdev_ioctl()
546 vmregset->count); in vmmdev_ioctl()
547 if (error == 0) in vmmdev_ioctl()
549 vmregset->count, regnums, regvals); in vmmdev_ioctl()
550 if (error == 0) in vmmdev_ioctl()
551 error = copyout(regvals, vmregset->regvals, in vmmdev_ioctl()
552 sizeof(regvals[0]) * vmregset->count); in vmmdev_ioctl()
563 if (vmregset->count > VM_REG_LAST) { in vmmdev_ioctl()
567 regvals = malloc(sizeof(regvals[0]) * vmregset->count, M_VMMDEV, in vmmdev_ioctl()
569 regnums = malloc(sizeof(regnums[0]) * vmregset->count, M_VMMDEV, in vmmdev_ioctl()
571 error = copyin(vmregset->regnums, regnums, sizeof(regnums[0]) * in vmmdev_ioctl()
572 vmregset->count); in vmmdev_ioctl()
573 if (error == 0) in vmmdev_ioctl()
574 error = copyin(vmregset->regvals, regvals, in vmmdev_ioctl()
575 sizeof(regvals[0]) * vmregset->count); in vmmdev_ioctl()
576 if (error == 0) in vmmdev_ioctl()
578 vmregset->count, regnums, regvals); in vmmdev_ioctl()
587 error = vm_get_capability(vcpu, vmcap->captype, &vmcap->capval); in vmmdev_ioctl()
594 error = vm_set_capability(vcpu, vmcap->captype, vmcap->capval); in vmmdev_ioctl()
605 error = 0; in vmmdev_ioctl()
607 size = vm_cpuset->cpusetsize; in vmmdev_ioctl()
614 if (vm_cpuset->which == VM_ACTIVE_CPUS) in vmmdev_ioctl()
615 *cpuset = vm_active_cpus(sc->vm); in vmmdev_ioctl()
616 else if (vm_cpuset->which == VM_SUSPENDED_CPUS) in vmmdev_ioctl()
617 *cpuset = vm_suspended_cpus(sc->vm); in vmmdev_ioctl()
618 else if (vm_cpuset->which == VM_DEBUG_CPUS) in vmmdev_ioctl()
619 *cpuset = vm_debug_cpus(sc->vm); in vmmdev_ioctl()
622 if (error == 0 && size < howmany(CPU_FLS(cpuset), NBBY)) in vmmdev_ioctl()
624 if (error == 0) in vmmdev_ioctl()
625 error = copyout(cpuset, vm_cpuset->cpus, size); in vmmdev_ioctl()
630 error = vm_suspend_cpu(sc->vm, vcpu); in vmmdev_ioctl()
633 error = vm_resume_cpu(sc->vm, vcpu); in vmmdev_ioctl()
639 error = vm_set_topology(sc->vm, topology->sockets, in vmmdev_ioctl()
640 topology->cores, topology->threads, topology->maxcpus); in vmmdev_ioctl()
647 vm_get_topology(sc->vm, &topology->sockets, &topology->cores, in vmmdev_ioctl()
648 &topology->threads, &topology->maxcpus); in vmmdev_ioctl()
649 error = 0; in vmmdev_ioctl()
653 error = vmmdev_machdep_ioctl(sc->vm, vcpu, cmd, data, fflag, in vmmdev_ioctl()
658 if ((ioctl->flags & in vmmdev_ioctl()
659 (VMMDEV_IOCTL_XLOCK_MEMSEGS | VMMDEV_IOCTL_SLOCK_MEMSEGS)) != 0) in vmmdev_ioctl()
660 vm_unlock_memsegs(sc->vm); in vmmdev_ioctl()
661 if ((ioctl->flags & VMMDEV_IOCTL_LOCK_ALL_VCPUS) != 0) in vmmdev_ioctl()
663 else if ((ioctl->flags & VMMDEV_IOCTL_LOCK_ONE_VCPU) != 0) in vmmdev_ioctl()
667 * Make sure that no handler returns a kernel-internal in vmmdev_ioctl()
670 KASSERT(error == ERESTART || error >= 0, in vmmdev_ioctl()
675 if ((ioctl->flags & in vmmdev_ioctl()
676 (VMMDEV_IOCTL_XLOCK_MEMSEGS | VMMDEV_IOCTL_SLOCK_MEMSEGS)) != 0) in vmmdev_ioctl()
677 vm_unlock_memsegs(sc->vm); in vmmdev_ioctl()
686 vm_paddr_t gpa; in vmmdev_mmap_single() local
694 if ((nprot & PROT_EXEC) || first < 0 || first >= last) in vmmdev_mmap_single()
706 vm_slock_memsegs(sc->vm); in vmmdev_mmap_single()
708 gpa = 0; in vmmdev_mmap_single()
709 found = 0; in vmmdev_mmap_single()
711 error = vm_mmap_getnext(sc->vm, &gpa, &segid, &segoff, &len, in vmmdev_mmap_single()
716 if (first >= gpa && last <= gpa + len) in vmmdev_mmap_single()
719 gpa += len; in vmmdev_mmap_single()
723 error = vm_get_memseg(sc->vm, segid, &len, &sysmem, objp); in vmmdev_mmap_single()
724 KASSERT(error == 0 && *objp != NULL, in vmmdev_mmap_single()
728 *offset = segoff + (first - gpa); in vmmdev_mmap_single()
733 vm_unlock_memsegs(sc->vm); in vmmdev_mmap_single()
743 KASSERT(sc->cdev == NULL, ("%s: cdev not free", __func__)); in vmmdev_destroy()
748 * - any new operations on the 'cdev' will return an error (ENXIO). in vmmdev_destroy()
750 * - the 'devmem' cdevs are destroyed before the virtual machine 'cdev' in vmmdev_destroy()
752 SLIST_FOREACH(dsc, &sc->devmem, link) { in vmmdev_destroy()
753 KASSERT(dsc->cdev != NULL, ("devmem cdev already destroyed")); in vmmdev_destroy()
757 vm_disable_vcpu_creation(sc->vm); in vmmdev_destroy()
759 KASSERT(error == 0, ("%s: error %d freezing vcpus", __func__, error)); in vmmdev_destroy()
760 vm_unlock_vcpus(sc->vm); in vmmdev_destroy()
762 while ((dsc = SLIST_FIRST(&sc->devmem)) != NULL) { in vmmdev_destroy()
763 KASSERT(dsc->cdev == NULL, ("%s: devmem not free", __func__)); in vmmdev_destroy()
764 SLIST_REMOVE_HEAD(&sc->devmem, link); in vmmdev_destroy()
765 free(dsc->name, M_VMMDEV); in vmmdev_destroy()
769 if (sc->vm != NULL) in vmmdev_destroy()
770 vm_destroy(sc->vm); in vmmdev_destroy()
772 if (sc->ucred != NULL) in vmmdev_destroy()
773 crfree(sc->ucred); in vmmdev_destroy()
789 if (sc == NULL || sc->cdev == NULL) { in vmmdev_lookup_and_destroy()
795 * Setting 'sc->cdev' to NULL is used to indicate that the VM in vmmdev_lookup_and_destroy()
798 cdev = sc->cdev; in vmmdev_lookup_and_destroy()
799 sc->cdev = NULL; in vmmdev_lookup_and_destroy()
805 return (0); in vmmdev_lookup_and_destroy()
814 error = vmm_priv_check(req->td->td_ucred); in sysctl_vmm_destroy()
822 if (error == 0 && req->newptr != NULL) in sysctl_vmm_destroy()
823 error = vmmdev_lookup_and_destroy(buf, req->td->td_ucred); in sysctl_vmm_destroy()
829 NULL, 0, sysctl_vmm_destroy, "A",
848 SLIST_INIT(&sc->devmem); in vmmdev_alloc()
849 sc->vm = vm; in vmmdev_alloc()
850 sc->ucred = crhold(cred); in vmmdev_alloc()
871 if (error != 0) { in vmmdev_create()
880 mda.mda_cr = sc->ucred; in vmmdev_create()
887 if (error != 0) { in vmmdev_create()
892 sc->cdev = cdev; in vmmdev_create()
894 return (0); in vmmdev_create()
903 error = vmm_priv_check(req->td->td_ucred); in sysctl_vmm_create()
904 if (error != 0) in sysctl_vmm_create()
911 if (error == 0 && req->newptr != NULL) in sysctl_vmm_create()
912 error = vmmdev_create(buf, req->td->td_ucred); in sysctl_vmm_create()
918 NULL, 0, sysctl_vmm_create, "A",
926 error = vmm_priv_check(td->td_ucred); in vmmctl_open()
927 if (error != 0) in vmmctl_open()
930 if ((flags & FWRITE) == 0) in vmmctl_open()
933 return (0); in vmmctl_open()
947 vmc->name[VM_MAX_NAMELEN] = '\0'; in vmmctl_ioctl()
948 for (size_t i = 0; i < nitems(vmc->reserved); i++) { in vmmctl_ioctl()
949 if (vmc->reserved[i] != 0) { in vmmctl_ioctl()
955 error = vmmdev_create(vmc->name, td->td_ucred); in vmmctl_ioctl()
962 vmd->name[VM_MAX_NAMELEN] = '\0'; in vmmctl_ioctl()
963 for (size_t i = 0; i < nitems(vmd->reserved); i++) { in vmmctl_ioctl()
964 if (vmd->reserved[i] != 0) { in vmmctl_ioctl()
970 error = vmmdev_lookup_and_destroy(vmd->name, td->td_ucred); in vmmctl_ioctl()
1002 return (0); in vmmdev_init()
1011 error = 0; in vmmdev_cleanup()
1028 dsc = cdev->si_drv1; in devmem_mmap_single()
1036 if ((nprot & PROT_EXEC) || first < 0 || first >= last) in devmem_mmap_single()
1039 vm_slock_memsegs(dsc->sc->vm); in devmem_mmap_single()
1041 error = vm_get_memseg(dsc->sc->vm, dsc->segid, &seglen, &sysmem, objp); in devmem_mmap_single()
1042 KASSERT(error == 0 && !sysmem && *objp != NULL, in devmem_mmap_single()
1043 ("%s: invalid devmem segment %d", __func__, dsc->segid)); in devmem_mmap_single()
1050 vm_unlock_memsegs(dsc->sc->vm); in devmem_mmap_single()
1070 dsc->segid = segid; in devmem_create_cdev()
1071 dsc->name = devname; in devmem_create_cdev()
1072 dsc->sc = sc; in devmem_create_cdev()
1073 SLIST_INSERT_HEAD(&sc->devmem, dsc, link); in devmem_create_cdev()
1077 mda.mda_cr = sc->ucred; in devmem_create_cdev()
1083 error = make_dev_s(&mda, &dsc->cdev, "vmm.io/%s.%s", vm_name(sc->vm), in devmem_create_cdev()
1085 if (error != 0) { in devmem_create_cdev()
1086 SLIST_REMOVE(&sc->devmem, dsc, devmem_softc, link); in devmem_create_cdev()
1087 free(dsc->name, M_VMMDEV); in devmem_create_cdev()
1101 destroy_dev(dsc->cdev); in devmem_destroy()
1102 dsc->cdev = NULL; in devmem_destroy()
1103 dsc->sc = NULL; in devmem_destroy()