Changeset View
Changeset View
Standalone View
Standalone View
sys/amd64/vmm/vmm_dev.c
| Show First 20 Lines • Show All 91 Lines • ▼ Show 20 Lines | |||||
| static unsigned pr_allow_flag; | static unsigned pr_allow_flag; | ||||
| static struct mtx vmmdev_mtx; | static struct mtx vmmdev_mtx; | ||||
| static MALLOC_DEFINE(M_VMMDEV, "vmmdev", "vmmdev"); | static MALLOC_DEFINE(M_VMMDEV, "vmmdev", "vmmdev"); | ||||
| SYSCTL_DECL(_hw_vmm); | SYSCTL_DECL(_hw_vmm); | ||||
| static int vmm_priv_check(struct ucred *ucred); | static int vmm_priv_check(struct ucred *ucred); | ||||
| static int devmem_create_cdev(const char *vmname, int id, char *devmem); | static int devmem_create_cdev(struct vmmdev_softc *sc, int id, char *devmem); | ||||
| static void devmem_destroy(void *arg); | static void devmem_destroy(void *arg); | ||||
| static int | static int | ||||
| vmm_priv_check(struct ucred *ucred) | vmm_priv_check(struct ucred *ucred) | ||||
| { | { | ||||
| if (jailed(ucred) && | if (jailed(ucred) && | ||||
| !(ucred->cr_prison->pr_allow & pr_allow_flag)) | !(ucred->cr_prison->pr_allow & pr_allow_flag)) | ||||
| ▲ Show 20 Lines • Show All 198 Lines • ▼ Show 20 Lines | if (error) | ||||
| goto done; | goto done; | ||||
| } | } | ||||
| error = vm_alloc_memseg(sc->vm, mseg->segid, mseg->len, sysmem); | error = vm_alloc_memseg(sc->vm, mseg->segid, mseg->len, sysmem); | ||||
| if (error) | if (error) | ||||
| goto done; | goto done; | ||||
| if (VM_MEMSEG_NAME(mseg)) { | if (VM_MEMSEG_NAME(mseg)) { | ||||
| error = devmem_create_cdev(vm_name(sc->vm), mseg->segid, name); | error = devmem_create_cdev(sc, mseg->segid, name); | ||||
| if (error) | if (error) | ||||
| vm_free_memseg(sc->vm, mseg->segid); | vm_free_memseg(sc->vm, mseg->segid); | ||||
| else | else | ||||
| name = NULL; /* freed when 'cdev' is destroyed */ | name = NULL; /* freed when 'cdev' is destroyed */ | ||||
| } | } | ||||
| done: | done: | ||||
| free(name, M_VMMDEV); | free(name, M_VMMDEV); | ||||
| return (error); | return (error); | ||||
| ▲ Show 20 Lines • Show All 889 Lines • ▼ Show 20 Lines | |||||
| static struct cdevsw devmemsw = { | static struct cdevsw devmemsw = { | ||||
| .d_name = "devmem", | .d_name = "devmem", | ||||
| .d_version = D_VERSION, | .d_version = D_VERSION, | ||||
| .d_mmap_single = devmem_mmap_single, | .d_mmap_single = devmem_mmap_single, | ||||
| }; | }; | ||||
| static int | static int | ||||
| devmem_create_cdev(const char *vmname, int segid, char *devname) | devmem_create_cdev(struct vmmdev_softc *sc, int segid, char *devname) | ||||
| { | { | ||||
| struct devmem_softc *dsc; | struct devmem_softc *dsc; | ||||
| struct vmmdev_softc *sc; | |||||
| struct cdev *cdev; | struct cdev *cdev; | ||||
| const char *vmname; | |||||
| int error; | int error; | ||||
| error = make_dev_p(MAKEDEV_CHECKNAME, &cdev, &devmemsw, NULL, | vmname = vm_name(sc->vm); | ||||
| error = make_dev_p(MAKEDEV_CHECKNAME, &cdev, &devmemsw, sc->ucred, | |||||
| UID_ROOT, GID_WHEEL, 0600, "vmm.io/%s.%s", vmname, devname); | UID_ROOT, GID_WHEEL, 0600, "vmm.io/%s.%s", vmname, devname); | ||||
markj: I think it'd be a bit nicer to change devmem_create_cdev() to pass the vmmdev_softc in directly. | |||||
| if (error) | if (error) | ||||
| return (error); | return (error); | ||||
| dsc = malloc(sizeof(struct devmem_softc), M_VMMDEV, M_WAITOK | M_ZERO); | dsc = malloc(sizeof(struct devmem_softc), M_VMMDEV, M_WAITOK | M_ZERO); | ||||
| mtx_lock(&vmmdev_mtx); | |||||
| sc = vmmdev_lookup(vmname); | |||||
| KASSERT(sc != NULL, ("%s: vm %s softc not found", __func__, vmname)); | |||||
| if (sc->cdev == NULL) { | if (sc->cdev == NULL) { | ||||
| /* virtual machine is being created or destroyed */ | /* virtual machine is being created or destroyed */ | ||||
| mtx_unlock(&vmmdev_mtx); | |||||
| free(dsc, M_VMMDEV); | free(dsc, M_VMMDEV); | ||||
| destroy_dev_sched_cb(cdev, NULL, 0); | destroy_dev_sched_cb(cdev, NULL, 0); | ||||
| return (ENODEV); | return (ENODEV); | ||||
| } | } | ||||
| dsc->segid = segid; | dsc->segid = segid; | ||||
| dsc->name = devname; | dsc->name = devname; | ||||
| dsc->cdev = cdev; | dsc->cdev = cdev; | ||||
| dsc->sc = sc; | dsc->sc = sc; | ||||
| mtx_lock(&vmmdev_mtx); | |||||
| SLIST_INSERT_HEAD(&sc->devmem, dsc, link); | SLIST_INSERT_HEAD(&sc->devmem, dsc, link); | ||||
| mtx_unlock(&vmmdev_mtx); | mtx_unlock(&vmmdev_mtx); | ||||
| /* The 'cdev' is ready for use after 'si_drv1' is initialized */ | /* The 'cdev' is ready for use after 'si_drv1' is initialized */ | ||||
| cdev->si_drv1 = dsc; | cdev->si_drv1 = dsc; | ||||
| return (0); | return (0); | ||||
| } | } | ||||
| Show All 9 Lines | |||||
I think it'd be a bit nicer to change devmem_create_cdev() to pass the vmmdev_softc in directly. This function is static, so its usage is confined to this file and there's no real reason to avoid modifying its signature if it makes the code simpler.