static int quantis_copyout_uint(intptr_t arg, int flags, unsigned int src) { uint32_t src32; switch (ddi_model_convert_from(flags & FMODELS)) { case DDI_MODEL_ILP32: src32 = src; if (ddi_copyout(&src32, (void *)arg, sizeof(src32), flags) < 0) { return -1; } return 0; case DDI_MODEL_NONE: if (ddi_copyout(&src, (void *)arg, sizeof(src), flags) < 0) { return -1; } return 0; default: return -1; } }
static int sckm_copyout_ioctl_getreq(sckm_ioctl_getreq_t *driverarg, intptr_t userarg, int flag) { #ifdef _MULTI_DATAMODEL switch (ddi_model_convert_from(flag & FMODELS)) { case DDI_MODEL_ILP32: { sckm_ioctl_getreq32_t driverarg32; driverarg32.transid = driverarg->transid; driverarg32.type = driverarg->type; driverarg32.buf = (caddr32_t)(uintptr_t)driverarg->buf; driverarg32.buf_len = driverarg->buf_len; if (ddi_copyout(&driverarg32, (caddr_t)userarg, sizeof (sckm_ioctl_getreq32_t), flag)) { return (EFAULT); } break; } case DDI_MODEL_NONE: if (ddi_copyout(driverarg, (caddr_t)userarg, sizeof (sckm_ioctl_getreq_t), flag)) { return (EFAULT); } break; } #else /* ! _MULTI_DATAMODEL */ if (ddi_copyout(driverarg, (caddr_t)userarg, sizeof (sckm_ioctl_getreq_t), flag)) { return (EFAULT); } #endif /* _MULTI_DATAMODEL */ return (0); }
static int hci1394_ioctl_hbainfo(hci1394_state_t *soft_state, void *arg, int mode) { hci1394_ioctl_hbainfo_t hbainfo; int status; ASSERT(soft_state != NULL); ASSERT(arg != NULL); TNF_PROBE_0_DEBUG(hci1394_ioctl_hbainfo_enter, HCI1394_TNF_HAL_STACK, ""); hbainfo.pci_vendor_id = soft_state->vendor_info.vendor_id; hbainfo.pci_device_id = soft_state->vendor_info.device_id; hbainfo.pci_revision_id = soft_state->vendor_info.revision_id; hbainfo.ohci_version = soft_state->vendor_info.ohci_version; hbainfo.ohci_vendor_id = soft_state->vendor_info.ohci_vendor_id; hbainfo.ohci_vregset_cnt = soft_state->vendor_info.vendor_reg_count; status = ddi_copyout(&hbainfo, arg, sizeof (hci1394_ioctl_hbainfo_t), mode); if (status != 0) { TNF_PROBE_0(hci1394_ioctl_hbainfo_co_fail, HCI1394_TNF_HAL_ERROR, ""); TNF_PROBE_0_DEBUG(hci1394_ioctl_hbainfo_exit, HCI1394_TNF_HAL_STACK, ""); return (EFAULT); } TNF_PROBE_0_DEBUG(hci1394_ioctl_hbainfo_exit, HCI1394_TNF_HAL_STACK, ""); return (0); }
static int hci1394_ioctl_selfid_cnt(hci1394_state_t *soft_state, void *arg, int mode) { hci1394_ioctl_selfid_cnt_t selfid_cnt; int status; ASSERT(soft_state != NULL); ASSERT(arg != NULL); TNF_PROBE_0_DEBUG(hci1394_ioctl_selfid_cnt_enter, HCI1394_TNF_HAL_STACK, ""); selfid_cnt.count = soft_state->drvinfo.di_stats.st_selfid_count; status = ddi_copyout(&selfid_cnt, arg, sizeof (hci1394_ioctl_selfid_cnt_t), mode); if (status != 0) { TNF_PROBE_0(hci1394_ioctl_selfid_cnt_co_fail, HCI1394_TNF_HAL_ERROR, ""); TNF_PROBE_0_DEBUG(hci1394_ioctl_selfid_cnt_exit, HCI1394_TNF_HAL_STACK, ""); return (EFAULT); } TNF_PROBE_0_DEBUG(hci1394_ioctl_selfid_cnt_exit, HCI1394_TNF_HAL_STACK, ""); return (0); }
static int hci1394_ioctl_busgen_cnt(hci1394_state_t *soft_state, void *arg, int mode) { hci1394_ioctl_busgen_cnt_t busgen_cnt; int status; ASSERT(soft_state != NULL); ASSERT(arg != NULL); TNF_PROBE_0_DEBUG(hci1394_ioctl_busgen_cnt_enter, HCI1394_TNF_HAL_STACK, ""); busgen_cnt.count = hci1394_ohci_current_busgen(soft_state->ohci); status = ddi_copyout(&busgen_cnt, arg, sizeof (hci1394_ioctl_busgen_cnt_t), mode); if (status != 0) { TNF_PROBE_0(hci1394_ioctl_busgen_cnt_co_fail, HCI1394_TNF_HAL_ERROR, ""); TNF_PROBE_0_DEBUG(hci1394_ioctl_busgen_cnt_exit, HCI1394_TNF_HAL_STACK, ""); return (EFAULT); } TNF_PROBE_0_DEBUG(hci1394_ioctl_busgen_cnt_exit, HCI1394_TNF_HAL_STACK, ""); return (0); }
static int hci1394_ioctl_rdreg(hci1394_state_t *soft_state, void *arg, int mode) { hci1394_ioctl_rdreg_t rdreg; int status; ASSERT(soft_state != NULL); ASSERT(arg != NULL); TNF_PROBE_0_DEBUG(hci1394_ioctl_rdreg_enter, HCI1394_TNF_HAL_STACK, ""); status = ddi_copyin(arg, &rdreg, sizeof (hci1394_ioctl_rdreg_t), mode); if (status != 0) { TNF_PROBE_0(hci1394_ioctl_rdreg_ci_fail, HCI1394_TNF_HAL_ERROR, ""); TNF_PROBE_0_DEBUG(hci1394_ioctl_rdreg_exit, HCI1394_TNF_HAL_STACK, ""); return (EFAULT); } hci1394_ohci_reg_read(soft_state->ohci, rdreg.addr, &rdreg.data); status = ddi_copyout(&rdreg, arg, sizeof (hci1394_ioctl_rdreg_t), mode); if (status != 0) { TNF_PROBE_0(hci1394_ioctl_rdreg_c0_fail, HCI1394_TNF_HAL_ERROR, ""); TNF_PROBE_0_DEBUG(hci1394_ioctl_rdreg_exit, HCI1394_TNF_HAL_STACK, ""); return (EFAULT); } TNF_PROBE_0_DEBUG(hci1394_ioctl_rdreg_exit, HCI1394_TNF_HAL_STACK, ""); return (0); }
static int zfs_ioctl_compat_put_nvlist(zfs_cmd_t *zc, nvlist_t *nvl) { char *packed = NULL; int error = 0; size_t size; VERIFY(nvlist_size(nvl, &size, NV_ENCODE_NATIVE) == 0); #ifdef _KERNEL packed = kmem_alloc(size, KM_SLEEP); VERIFY(nvlist_pack(nvl, &packed, &size, NV_ENCODE_NATIVE, KM_SLEEP) == 0); if (ddi_copyout(packed, (void *)(uintptr_t)zc->zc_nvlist_dst, size, zc->zc_iflags) != 0) error = EFAULT; kmem_free(packed, size); #else packed = (void *)(uintptr_t)zc->zc_nvlist_dst; VERIFY(nvlist_pack(nvl, &packed, &size, NV_ENCODE_NATIVE, 0) == 0); #endif zc->zc_nvlist_dst_size = size; return (error); }
static void export_buffer(import_export_t *iep, int *error) { int copy_err = 0; if (iep->ie_size == 0 || iep->ie_uaddr == NULL) return; /* * If the buffer was marked for export initially, and if the * hypercall completed successfully, resync the user-space buffer * with our in-kernel buffer. */ if ((iep->ie_flags & IE_EXPORT) && (*error >= 0) && (ddi_copyout(iep->ie_kaddr, iep->ie_uaddr, iep->ie_size, 0) != 0)) copy_err = -X_EFAULT; if (iep->ie_flags & IE_FREE) { kmem_free(iep->ie_kaddr, iep->ie_size); iep->ie_kaddr = NULL; iep->ie_flags = 0; } if (copy_err != 0 && *error >= 0) *error = copy_err; }
static int fcoe_copyout_iocdata(intptr_t data, int mode, fcoeio_t *fcoeio, void *obuf) { if (fcoeio->fcoeio_olen) { if (ddi_copyout(obuf, (void *)(unsigned long)fcoeio->fcoeio_obuf, fcoeio->fcoeio_olen, mode) != 0) { return (EFAULT); } } if (ddi_copyout(fcoeio, (void *)data, sizeof (fcoeio_t), mode) != 0) { return (EFAULT); } return (0); }
RTR0DECL(int) RTR0MemUserCopyTo(RTR3PTR R3PtrDst, void const *pvSrc, size_t cb) { int rc; RT_ASSERT_INTS_ON(); rc = ddi_copyout(pvSrc, (void *)R3PtrDst, cb, 0 /*flags*/); if (RT_LIKELY(rc == 0)) return VINF_SUCCESS; return VERR_ACCESS_DENIED; }
/* * iscsi_ioctl_copyout - */ int iscsi_ioctl_copyout(void *data, size_t size, caddr_t arg, int mode) { int rtn; rtn = EFAULT; if (ddi_copyout(data, arg, size, mode) == 0) { rtn = 0; } kmem_free(data, size); return (rtn); }
static int hci1394_ioctl_read_selfid32(hci1394_state_t *soft_state, hci1394_ioctl_readselfid32_t *read_selfid, int mode) { int status; uint_t offset; uint32_t data; ASSERT(soft_state != NULL); ASSERT(read_selfid != NULL); TNF_PROBE_0_DEBUG(hci1394_ioctl_read_selfid32_enter, HCI1394_TNF_HAL_STACK, ""); /* * make sure we are not trying to copy more data than the selfid buffer * can hold. count is in quadlets and max_selfid_size is in bytes. */ if ((read_selfid->count * 4) > OHCI_MAX_SELFID_SIZE) { TNF_PROBE_0(hci1394_ioctl_read_selfid32_cnt_fail, HCI1394_TNF_HAL_ERROR, ""); TNF_PROBE_0_DEBUG(hci1394_ioctl_read_selfid32_exit, HCI1394_TNF_HAL_STACK, ""); return (EINVAL); } /* * copy the selfid buffer one word at a time into the user buffer. The * combination between having to do ddi_get32's (for endian reasons) and * a ddi_copyout() make it easier to do it one word at a time. */ for (offset = 0; offset < read_selfid->count; offset++) { /* read word from selfid buffer */ hci1394_ohci_selfid_read(soft_state->ohci, offset, &data); /* copy the selfid word into the user buffer */ status = ddi_copyout(&data, (void *)(uintptr_t)(read_selfid->buf + (offset * 4)), 4, mode); if (status != 0) { TNF_PROBE_0(hci1394_ioctl_read_selfid32_co_fail, HCI1394_TNF_HAL_ERROR, ""); TNF_PROBE_0_DEBUG(hci1394_ioctl_read_selfid32_exit, HCI1394_TNF_HAL_STACK, ""); return (EFAULT); } } TNF_PROBE_0_DEBUG(hci1394_ioctl_read_selfid32_exit, HCI1394_TNF_HAL_STACK, ""); return (0); }
static void scopyout(spcs_s_pinfo_t *kstatus, spcs_s_pinfo_t *ustatus) { int mode = 0; #ifdef UNISTAT_TRACE cmn_err(CE_WARN, "!scopyout entry"); #endif /* * If tdata is in use, blow up: asynch data is not intended for ioctls. * How would we ship it back? (the user hasn't given us any place to * put it!) */ if (kstatus->tcount) cmn_err(_CELEVEL, "!SPCS: Unistat async data in ioctl status!"); /* * Gently, Bentley * Have to copy all the header stuff even though there is no need for * some items like the revisions. This is unavoidable without making * the structure more complex or guessing about alignment and the true * size of the part of the structure sitting ahead of the {i,s,t}data * arrays. */ (void) ddi_copyout((void *) kstatus, (void *) ustatus, sizeof (spcs_s_pinfo_t) - (sizeof (kstatus->idata) + sizeof (kstatus->sdata) + sizeof (kstatus->tdata)), mode); (void) ddi_copyout((void *)kstatus->idata, (void *) ustatus->idata, (kstatus->icount * sizeof (kstatus->idata[0])), mode); (void) ddi_copyout((void *)kstatus->sdata, (void *) ustatus->sdata, (kstatus->scount * sizeof (kstatus->sdata[0])), mode); (void) ddi_copyout((void *)kstatus->tdata, (void *) ustatus->tdata, (kstatus->tcount * sizeof (kstatus->tdata[0])), mode); #ifdef UNISTAT_TRACE cmn_err(CE_WARN, "!scopyout exit"); #endif }
static int get_hsp( void *d, int mode ) { hot_spare_pool_t *hsp; get_hsp_t *ghsp; size_t size; set_t setno; int err = 0; md_i_get_t *migp = (md_i_get_t *)d; setno = migp->md_driver.md_setno; mdclrerror(&migp->mde); /* Scan the hot spare pool list */ hsp = find_hot_spare_pool(setno, migp->id); if (hsp == NULL) { return (mdhsperror(&migp->mde, MDE_INVAL_HSP, migp->id)); } size = (sizeof (ghsp->ghsp_hs_keys[0]) * (hsp->hsp_nhotspares - 1)) + sizeof (get_hsp_t); if (migp->size == 0) { migp->size = (int)size; return (0); } if (migp->size < size) return (EFAULT); ghsp = kmem_alloc(size, KM_SLEEP); ghsp->ghsp_id = hsp->hsp_self_id; ghsp->ghsp_refcount = hsp->hsp_refcount; ghsp->ghsp_nhotspares = hsp->hsp_nhotspares; build_key_list(setno, hsp, ghsp->ghsp_hs_keys); if (ddi_copyout(ghsp, (caddr_t)(uintptr_t)migp->mdp, size, mode)) err = EFAULT; kmem_free(ghsp, size); return (err); }
static int hci1394_ioctl_rdvreg(hci1394_state_t *soft_state, void *arg, int mode) { hci1394_ioctl_rdvreg_t rdvreg; int status; ASSERT(soft_state != NULL); ASSERT(arg != NULL); TNF_PROBE_0_DEBUG(hci1394_ioctl_rdvreg_enter, HCI1394_TNF_HAL_STACK, ""); status = ddi_copyin(arg, &rdvreg, sizeof (hci1394_ioctl_rdvreg_t), mode); if (status != 0) { TNF_PROBE_0(hci1394_ioctl_rdvreg_ci_fail, HCI1394_TNF_HAL_ERROR, ""); TNF_PROBE_0_DEBUG(hci1394_ioctl_rdvreg_exit, HCI1394_TNF_HAL_STACK, ""); return (EFAULT); } status = hci1394_vendor_reg_read(soft_state->vendor, rdvreg.regset, rdvreg.addr, &rdvreg.data); if (status != DDI_SUCCESS) { TNF_PROBE_0(hci1394_ioctl_rdvreg_vrr_fail, HCI1394_TNF_HAL_ERROR, ""); TNF_PROBE_0_DEBUG(hci1394_ioctl_rdvreg_exit, HCI1394_TNF_HAL_STACK, ""); return (EINVAL); } status = ddi_copyout(&rdvreg, arg, sizeof (hci1394_ioctl_rdvreg_t), mode); if (status != 0) { TNF_PROBE_0(hci1394_ioctl_rdvreg_co_fail, HCI1394_TNF_HAL_ERROR, ""); TNF_PROBE_0_DEBUG(hci1394_ioctl_rdvreg_exit, HCI1394_TNF_HAL_STACK, ""); return (EFAULT); } TNF_PROBE_0_DEBUG(hci1394_ioctl_rdvreg_exit, HCI1394_TNF_HAL_STACK, ""); return (0); }
static int notify_fillin_empty_ioctl(void *data, void *ioctl_in, size_t sz, int mode) { int err; md_event_ioctl_t *ioctl = (md_event_ioctl_t *)data; ioctl->mdn_event = EQ_EMPTY; ioctl->mdn_tag = TAG_EMPTY; ioctl->mdn_set = MD_ALLSETS; ioctl->mdn_dev = MD_ALLDEVS; uniqtime32(&ioctl->mdn_time); ioctl->mdn_user = (u_longlong_t)0; err = ddi_copyout(data, ioctl_in, sz, mode); return (err); }
/*ARGSUSED*/ static int av1394_ioctl_arq_get_ibuf_size(av1394_inst_t *avp, void *arg, int mode) { av1394_async_t *ap = &avp->av_a; int sz; int ret = 0; AV1394_TNF_ENTER(av1394_ioctl_arq_get_ibuf_size); sz = av1394_getmaxq(&ap->a_rq); if (ddi_copyout(&sz, arg, sizeof (sz), mode) != 0) { ret = EFAULT; } AV1394_TNF_EXIT(av1394_ioctl_arq_get_ibuf_size); return (ret); }
static int hci1394_ioctl_rdphy(hci1394_state_t *soft_state, void *arg, int mode) { hci1394_ioctl_rdphy_t rdphy; int status; ASSERT(soft_state != NULL); ASSERT(arg != NULL); TNF_PROBE_0_DEBUG(hci1394_ioctl_rdphy_enter, HCI1394_TNF_HAL_STACK, ""); status = ddi_copyin(arg, &rdphy, sizeof (hci1394_ioctl_rdphy_t), mode); if (status != 0) { TNF_PROBE_0(hci1394_ioctl_rdphy_ci_fail, HCI1394_TNF_HAL_ERROR, ""); TNF_PROBE_0_DEBUG(hci1394_ioctl_rdphy_exit, HCI1394_TNF_HAL_STACK, ""); return (EFAULT); } status = hci1394_ohci_phy_read(soft_state->ohci, rdphy.addr, &rdphy.data); if (status != DDI_SUCCESS) { TNF_PROBE_0(hci1394_ioctl_rdphy_pr_fail, HCI1394_TNF_HAL_ERROR, ""); TNF_PROBE_0_DEBUG(hci1394_ioctl_rdphy_exit, HCI1394_TNF_HAL_STACK, ""); return (EINVAL); } status = ddi_copyout(&rdphy, arg, sizeof (hci1394_ioctl_rdphy_t), mode); if (status != 0) { TNF_PROBE_0(hci1394_ioctl_rdphy_co_fail, HCI1394_TNF_HAL_ERROR, ""); TNF_PROBE_0_DEBUG(hci1394_ioctl_rdphy_exit, HCI1394_TNF_HAL_STACK, ""); return (EFAULT); } TNF_PROBE_0_DEBUG(hci1394_ioctl_rdphy_exit, HCI1394_TNF_HAL_STACK, ""); return (0); }
/*ARGSUSED*/ static int foo_ioctl(dev_t dev, int cmd, intptr_t arg, int flags, /* model.h */ cred_t *cr, int *rvalp) { int err; err = 0; switch (cmd) { case FOO_IOC_GETCNT: atomic_inc_32(&foo_count); if (ddi_copyout(&foo_count, (void *)arg, sizeof (foo_count), flags)) err = EFAULT; break; default: err = ENOTTY; break; } return (err); }
/* * iscsi_conn_list_get_copyout - */ int iscsi_ioctl_conn_oid_list_get_copyout(iscsi_conn_list_t *cl, caddr_t arg, int mode) { size_t alloc_len; int rtn; ASSERT(cl != NULL); ASSERT(arg != NULL); rtn = EFAULT; alloc_len = sizeof (*cl); if (cl->cl_in_cnt != 0) { alloc_len += ((cl->cl_in_cnt - 1) * sizeof (iscsi_if_conn_t)); } if (ddi_copyout(cl, arg, alloc_len, mode) == 0) { rtn = 0; } kmem_free(cl, alloc_len); return (rtn); }
/*ARGSUSED*/ static int stripe_get(void *d, int mode, IOLOCK *lock) { minor_t mnum; mdi_unit_t *ui; ms_unit_t *un; md_error_t *mdep; md_i_get_t *migp = d; mnum = migp->id; mdep = &migp->mde; mdclrerror(mdep); if ((MD_MIN2SET(mnum) >= md_nsets) || (MD_MIN2UNIT(mnum) >= md_nunits)) return (mdmderror(mdep, MDE_INVAL_UNIT, mnum)); if ((ui = MDI_UNIT(mnum)) == NULL) { return (mdmderror(mdep, MDE_UNIT_NOT_SETUP, mnum)); } un = (ms_unit_t *)md_ioctl_readerlock(lock, ui); if (migp->size == 0) { migp->size = un->c.un_size; return (0); } if (migp->size < un->c.un_size) { return (EFAULT); } if (ddi_copyout(un, (void *)(uintptr_t)migp->mdp, un->c.un_size, mode)) return (EFAULT); return (0); }
/*ARGSUSED*/ static int cpuid_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *cr, int *rval) { char areq[16]; void *ustr; switch (cmd) { case CPUID_GET_HWCAP: { STRUCT_DECL(cpuid_get_hwcap, h); STRUCT_INIT(h, mode); if (ddi_copyin((void *)arg, STRUCT_BUF(h), STRUCT_SIZE(h), mode)) return (EFAULT); if ((ustr = STRUCT_FGETP(h, cgh_archname)) != NULL && copyinstr(ustr, areq, sizeof (areq), NULL) != 0) return (EFAULT); areq[sizeof (areq) - 1] = '\0'; if (strcmp(areq, architecture) == 0) STRUCT_FSET(h, cgh_hwcap, auxv_hwcap); #if defined(_SYSCALL32_IMPL) else if (strcmp(areq, architecture_32) == 0) STRUCT_FSET(h, cgh_hwcap, auxv_hwcap32); #endif else STRUCT_FSET(h, cgh_hwcap, 0); if (ddi_copyout(STRUCT_BUF(h), (void *)arg, STRUCT_SIZE(h), mode)) return (EFAULT); return (0); } default: return (ENOTTY); } }
int _nscpartsize(dev_t dev, intptr_t arg, int mode) { struct nscioc_partsize partsize; minor_t mindev = getminor(dev); nsc_size_t size; int rc, resv; nsc_fd_t *fd; if ((fd = _nsc_minor_fd[mindev]) == 0) return (EIO); mutex_enter(_nsc_minor_slp[mindev]); resv = (nsc_held(fd) == 0); if (resv && (rc = nsc_reserve(fd, NSC_PCATCH)) != 0) { mutex_exit(_nsc_minor_slp[mindev]); return (rc); } rc = nsc_partsize(fd, &size); partsize.partsize = (uint64_t)size; if (resv) nsc_release(fd); mutex_exit(_nsc_minor_slp[mindev]); if (ddi_copyout((void *)&partsize, (void *)arg, sizeof (partsize), mode) < 0) { return (EFAULT); } return (rc); }
static int VBoxUSBMonSolarisIOCtl(dev_t Dev, int Cmd, intptr_t pArg, int Mode, cred_t *pCred, int *pVal) { LogFunc((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl Dev=%d Cmd=%d pArg=%p Mode=%d\n", Dev, Cmd, pArg)); /* * Get the session from the soft state item. */ vboxusbmon_state_t *pState = ddi_get_soft_state(g_pVBoxUSBMonSolarisState, getminor(Dev)); if (!pState) { LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: no state data for %d\n", getminor(Dev))); return EINVAL; } /* * Read the request wrapper. Though We don't really need wrapper struct. now * it's room for the future as Solaris isn't generous regarding the size. */ VBOXUSBREQ ReqWrap; if (IOCPARM_LEN(Cmd) != sizeof(ReqWrap)) { LogRel((DEVICE_NAME ": VBoxUSBMonSolarisIOCtl: bad request %#x size=%d expected=%d\n", Cmd, IOCPARM_LEN(Cmd), sizeof(ReqWrap))); return ENOTTY; } int rc = ddi_copyin((void *)pArg, &ReqWrap, sizeof(ReqWrap), Mode); if (RT_UNLIKELY(rc)) { LogRel((DEVICE_NAME ": VBoxUSBMonSolarisIOCtl: ddi_copyin failed to read header pArg=%p Cmd=%d. rc=%d.\n", pArg, Cmd, rc)); return EINVAL; } if (ReqWrap.u32Magic != VBOXUSBMON_MAGIC) { LogRel((DEVICE_NAME ": VBoxUSBMonSolarisIOCtl: bad magic %#x; pArg=%p Cmd=%d.\n", ReqWrap.u32Magic, pArg, Cmd)); return EINVAL; } if (RT_UNLIKELY( ReqWrap.cbData == 0 || ReqWrap.cbData > _1M*16)) { LogRel((DEVICE_NAME ": VBoxUSBMonSolarisIOCtl: bad size %#x; pArg=%p Cmd=%d.\n", ReqWrap.cbData, pArg, Cmd)); return EINVAL; } /* * Read the request. */ void *pvBuf = RTMemTmpAlloc(ReqWrap.cbData); if (RT_UNLIKELY(!pvBuf)) { LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: RTMemTmpAlloc failed to alloc %d bytes.\n", ReqWrap.cbData)); return ENOMEM; } rc = ddi_copyin((void *)(uintptr_t)ReqWrap.pvDataR3, pvBuf, ReqWrap.cbData, Mode); if (RT_UNLIKELY(rc)) { RTMemTmpFree(pvBuf); LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: ddi_copyin failed; pvBuf=%p pArg=%p Cmd=%d. rc=%d\n", pvBuf, pArg, Cmd, rc)); return EFAULT; } if (RT_UNLIKELY( ReqWrap.cbData != 0 && !VALID_PTR(pvBuf))) { RTMemTmpFree(pvBuf); LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: pvBuf invalid pointer %p\n", pvBuf)); return EINVAL; } Log((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: pid=%d.\n", (int)RTProcSelf())); /* * Process the IOCtl. */ size_t cbDataReturned; rc = vboxUSBMonSolarisProcessIOCtl(Cmd, pState, pvBuf, ReqWrap.cbData, &cbDataReturned); ReqWrap.rc = rc; rc = 0; if (RT_UNLIKELY(cbDataReturned > ReqWrap.cbData)) { LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: too much output data %d expected %d\n", cbDataReturned, ReqWrap.cbData)); cbDataReturned = ReqWrap.cbData; } ReqWrap.cbData = cbDataReturned; /* * Copy the request back to user space. */ rc = ddi_copyout(&ReqWrap, (void *)pArg, sizeof(ReqWrap), Mode); if (RT_LIKELY(!rc)) { /* * Copy the payload (if any) back to user space. */ if (cbDataReturned > 0) { rc = ddi_copyout(pvBuf, (void *)(uintptr_t)ReqWrap.pvDataR3, cbDataReturned, Mode); if (RT_UNLIKELY(rc)) { LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: ddi_copyout failed; pvBuf=%p pArg=%p Cmd=%d. rc=%d\n", pvBuf, pArg, Cmd, rc)); rc = EFAULT; } } } else { LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: ddi_copyout(1) failed pArg=%p Cmd=%d\n", pArg, Cmd)); rc = EFAULT; } *pVal = rc; RTMemTmpFree(pvBuf); return rc; }
/* ARGSUSED */ static int sdpfp_ioctl(sock_lower_handle_t handle, int cmd, intptr_t arg, int mod, int32_t *rval, struct cred *cr) { #if defined(_SYSCALL32) struct timeval32 tival; #else struct timeval tival; #endif mac_client_promisc_type_t mtype; datalink_id_t linkid; struct lifreq lifreq; struct ifreq ifreq; struct pfpsock *ps; mac_handle_t mh; timespec_t tv; int error; switch (cmd) { /* * ioctls that work on "struct lifreq" */ case SIOCSLIFFLAGS : case SIOCGLIFINDEX : case SIOCGLIFFLAGS : case SIOCGLIFMTU : error = pfp_lifreq_getlinkid(arg, &lifreq, &linkid); if (error != 0) return (error); break; /* * ioctls that work on "struct ifreq". * Not all of these have a "struct lifreq" partner, for example * SIOCGIFHWADDR, for the simple reason that the logical interface * does not have a hardware address. */ case SIOCSIFFLAGS : case SIOCGIFINDEX : case SIOCGIFFLAGS : case SIOCGIFMTU : case SIOCGIFHWADDR : error = pfp_ifreq_getlinkid(arg, &ifreq, &linkid); if (error != 0) return (error); break; } error = mac_open_by_linkid(linkid, &mh); if (error != 0) return (error); ps = (struct pfpsock *)handle; switch (cmd) { case SIOCGLIFINDEX : lifreq.lifr_index = linkid; break; case SIOCGIFINDEX : ifreq.ifr_index = linkid; break; case SIOCGIFFLAGS : ifreq.ifr_flags = IFF_RUNNING; if (ps->ps_promisc == MAC_CLIENT_PROMISC_ALL) ifreq.ifr_flags |= IFF_PROMISC; break; case SIOCGLIFFLAGS : lifreq.lifr_flags = IFF_RUNNING; if (ps->ps_promisc == MAC_CLIENT_PROMISC_ALL) lifreq.lifr_flags |= IFF_PROMISC; break; case SIOCSIFFLAGS : if (linkid != ps->ps_linkid) { error = EINVAL; } else { if ((ifreq.ifr_flags & IFF_PROMISC) != 0) mtype = MAC_CLIENT_PROMISC_ALL; else mtype = MAC_CLIENT_PROMISC_FILTERED; error = pfp_set_promisc(ps, mtype); } break; case SIOCSLIFFLAGS : if (linkid != ps->ps_linkid) { error = EINVAL; } else { if ((lifreq.lifr_flags & IFF_PROMISC) != 0) mtype = MAC_CLIENT_PROMISC_ALL; else mtype = MAC_CLIENT_PROMISC_FILTERED; error = pfp_set_promisc(ps, mtype); } break; case SIOCGIFMTU : mac_sdu_get(mh, NULL, &ifreq.ifr_mtu); break; case SIOCGLIFMTU : mac_sdu_get(mh, NULL, &lifreq.lifr_mtu); break; case SIOCGIFHWADDR : mac_unicast_primary_get(mh, (uint8_t *)ifreq.ifr_addr.sa_data); ifreq.ifr_addr.sa_family = pfp_dl_to_arphrd(mac_type(mh)); break; case SIOCGSTAMP : (void) gethrestime(&tv); tival.tv_sec = (time_t)tv.tv_sec; tival.tv_usec = tv.tv_nsec / 1000; error = ddi_copyout(&tival, (void *)arg, sizeof (tival), 0); break; default : break; } mac_close(mh); if (error == 0) { /* * Only the "GET" ioctls need to copy data back to userace. */ switch (cmd) { case SIOCGLIFINDEX : case SIOCGLIFFLAGS : case SIOCGLIFMTU : error = ddi_copyout(&lifreq, (void *)arg, sizeof (lifreq), 0); break; case SIOCGIFINDEX : case SIOCGIFFLAGS : case SIOCGIFMTU : case SIOCGIFHWADDR : error = ddi_copyout(&ifreq, (void *)arg, sizeof (ifreq), 0); break; default : break; } } return (error); }
int nskernd_command(intptr_t arg, int mode, int *rvalp) { struct nskernd *udata = NULL; uint64_t arg1, arg2; int rc; *rvalp = 0; rc = 0; udata = kmem_alloc(sizeof (*udata), KM_SLEEP); if (ddi_copyin((void *)arg, udata, sizeof (*udata), mode) < 0) { kmem_free(udata, sizeof (*udata)); return (EFAULT); } switch (udata->command) { case NSKERND_START: /* User program start */ *rvalp = nskernd_start(udata->data1); break; case NSKERND_STOP: /* User program requesting stop */ mutex_enter(&nskernd_lock); nskernd_cleanup(); mutex_exit(&nskernd_lock); break; case NSKERND_WAIT: mutex_enter(&nskernd_lock); bcopy(udata, &nskernd_kdata, sizeof (*udata)); if (nskernd_ask > 0) cv_signal(&nskernd_ask_cv); nskernd_u_wait++; if (cv_wait_sig(&nskernd_u_cv, &nskernd_lock) != 0) { /* * woken by cv_signal() or cv_broadcast() */ bcopy(&nskernd_kdata, udata, sizeof (*udata)); } else { /* * signal - the user process has blocked all * signals except for SIGTERM and the * uncatchables, so the process is about to die * and we need to clean up. */ udata->command = NSKERND_STOP; udata->data1 = (uint64_t)1; /* cleanup done */ nskernd_cleanup(); } nskernd_u_wait--; mutex_exit(&nskernd_lock); if (ddi_copyout(udata, (void *)arg, sizeof (*udata), mode) < 0) { rc = EFAULT; break; } break; case NSKERND_NEWLWP: /* save kmem by freeing the udata structure */ arg1 = udata->data1; kmem_free(udata, sizeof (*udata)); udata = NULL; nsc_runlwp(arg1); break; case NSKERND_LOCK: /* save kmem by freeing the udata structure */ arg1 = udata->data1; arg2 = udata->data2; kmem_free(udata, sizeof (*udata)); udata = NULL; nsc_lockchild(arg1, arg2); break; default: cmn_err(CE_WARN, "nskernd: unknown command %d", udata->command); rc = EINVAL; break; } if (udata != NULL) { kmem_free(udata, sizeof (*udata)); udata = NULL; } return (rc); }
/*ARGSUSED*/ static int ntwdt_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp, int *rvalp) { int instance = getminor(dev); int retval = 0; ntwdt_state_t *ntwdt_ptr = NULL; ntwdt_runstate_t *ntwdt_state; lom_dogstate_t lom_dogstate; lom_dogctl_t lom_dogctl; uint32_t lom_dogtime; if ((ntwdt_ptr = getstate(instance)) == NULL) { return (ENXIO); } ntwdt_state = ntwdt_ptr->ntwdt_run_state; switch (cmd) { case LOMIOCDOGSTATE: mutex_enter(&ntwdt_state->ntwdt_runstate_mutex); lom_dogstate.reset_enable = ntwdt_state->ntwdt_reset_enabled; lom_dogstate.dog_enable = ntwdt_state->ntwdt_watchdog_enabled; lom_dogstate.dog_timeout = ntwdt_state->ntwdt_watchdog_timeout; mutex_exit(&ntwdt_state->ntwdt_runstate_mutex); if (ddi_copyout((caddr_t)&lom_dogstate, (caddr_t)arg, sizeof (lom_dogstate_t), mode) != 0) { retval = EFAULT; } break; case LOMIOCDOGCTL: if (ddi_copyin((caddr_t)arg, (caddr_t)&lom_dogctl, sizeof (lom_dogctl_t), mode) != 0) { retval = EFAULT; break; } NTWDT_DBG(NTWDT_DBG_IOCTL, ("reset_enable: %d, and dog_enable: " "%d, watchdog_timeout %d", lom_dogctl.reset_enable, lom_dogctl.dog_enable, ntwdt_state->ntwdt_watchdog_timeout)); /* * ignore request to enable reset while disabling watchdog. */ if (!lom_dogctl.dog_enable && lom_dogctl.reset_enable) { NTWDT_DBG(NTWDT_DBG_IOCTL, ("invalid combination of " "reset_enable: %d, and dog_enable: %d", lom_dogctl.reset_enable, lom_dogctl.dog_enable)); retval = EINVAL; break; } mutex_enter(&ntwdt_state->ntwdt_runstate_mutex); if (ntwdt_state->ntwdt_watchdog_timeout == 0) { /* * the LOMIOCDOGTIME has never been used to setup * a valid timeout. */ NTWDT_DBG(NTWDT_DBG_IOCTL, ("timeout has not been set" "watchdog_timeout: %d", ntwdt_state->ntwdt_watchdog_timeout)); retval = EINVAL; goto end; } /* * Store the user specified state in the softstate. */ ntwdt_state->ntwdt_reset_enabled = lom_dogctl.reset_enable; ntwdt_state->ntwdt_watchdog_enabled = lom_dogctl.dog_enable; if (ntwdt_state->ntwdt_watchdog_enabled != 0) { /* * The user wants to enable the watchdog. * Arm the watchdog and start the cyclic. */ ntwdt_arm_watchdog(ntwdt_state); if (ntwdt_state->ntwdt_timer_running == 0) { ntwdt_start_timer(ntwdt_ptr); } NTWDT_DBG(NTWDT_DBG_IOCTL, ("AWDT is enabled")); } else { /* * The user wants to disable the watchdog. */ if (ntwdt_state->ntwdt_timer_running != 0) { ntwdt_stop_timer(ntwdt_ptr); } NTWDT_DBG(NTWDT_DBG_IOCTL, ("AWDT is disabled")); } mutex_exit(&ntwdt_state->ntwdt_runstate_mutex); break; case LOMIOCDOGTIME: if (ddi_copyin((caddr_t)arg, (caddr_t)&lom_dogtime, sizeof (uint32_t), mode) != 0) { retval = EFAULT; break; } NTWDT_DBG(NTWDT_DBG_IOCTL, ("user set timeout: %d", lom_dogtime)); /* * Ensure specified timeout is valid. */ if ((lom_dogtime == 0) || (lom_dogtime > (uint32_t)NTWDT_MAX_TIMEOUT)) { retval = EINVAL; NTWDT_DBG(NTWDT_DBG_IOCTL, ("user set invalid " "timeout: %d", (int)TICK_TO_MSEC(lom_dogtime))); break; } mutex_enter(&ntwdt_state->ntwdt_runstate_mutex); ntwdt_state->ntwdt_watchdog_timeout = lom_dogtime; /* * If awdt is currently running, re-arm it with the * newly-specified timeout value. */ if (ntwdt_state->ntwdt_timer_running != 0) { ntwdt_arm_watchdog(ntwdt_state); } mutex_exit(&ntwdt_state->ntwdt_runstate_mutex); break; case LOMIOCDOGPAT: /* * Allow user to pat the watchdog timer. */ NTWDT_DBG(NTWDT_DBG_IOCTL, ("DOGPAT is invoked")); mutex_enter(&ntwdt_state->ntwdt_runstate_mutex); /* * If awdt is not enabled or underlying cyclic is not * running, exit. */ if (!(ntwdt_state->ntwdt_watchdog_enabled && ntwdt_state->ntwdt_timer_running)) { NTWDT_DBG(NTWDT_DBG_IOCTL, ("PAT: AWDT not enabled")); goto end; } if (ntwdt_state->ntwdt_watchdog_expired == 0) { /* * re-arm the awdt. */ ntwdt_arm_watchdog(ntwdt_state); NTWDT_DBG(NTWDT_DBG_IOCTL, ("AWDT patted, " "remainning seconds: %d", ntwdt_state->ntwdt_time_remaining)); } mutex_exit(&ntwdt_state->ntwdt_runstate_mutex); break; default: retval = EINVAL; break; } return (retval); end: mutex_exit(&ntwdt_state->ntwdt_runstate_mutex); return (retval); }
/** * Worker for VBoxSupDrvIOCtl that takes the slow IOCtl functions. * * @returns Solaris errno. * * @param pSession The session. * @param Cmd The IOCtl command. * @param Mode Information bitfield (for specifying ownership of data) * @param iArg User space address of the request buffer. */ static int VBoxDrvSolarisIOCtlSlow(PSUPDRVSESSION pSession, int iCmd, int Mode, intptr_t iArg) { int rc; uint32_t cbBuf = 0; union { SUPREQHDR Hdr; uint8_t abBuf[64]; } StackBuf; PSUPREQHDR pHdr; /* * Read the header. */ if (RT_UNLIKELY(IOCPARM_LEN(iCmd) != sizeof(StackBuf.Hdr))) { LogRel(("VBoxDrvSolarisIOCtlSlow: iCmd=%#x len %d expected %d\n", iCmd, IOCPARM_LEN(iCmd), sizeof(StackBuf.Hdr))); return EINVAL; } rc = ddi_copyin((void *)iArg, &StackBuf.Hdr, sizeof(StackBuf.Hdr), Mode); if (RT_UNLIKELY(rc)) { LogRel(("VBoxDrvSolarisIOCtlSlow: ddi_copyin(,%#lx,) failed; iCmd=%#x. rc=%d\n", iArg, iCmd, rc)); return EFAULT; } if (RT_UNLIKELY((StackBuf.Hdr.fFlags & SUPREQHDR_FLAGS_MAGIC_MASK) != SUPREQHDR_FLAGS_MAGIC)) { LogRel(("VBoxDrvSolarisIOCtlSlow: bad header magic %#x; iCmd=%#x\n", StackBuf.Hdr.fFlags & SUPREQHDR_FLAGS_MAGIC_MASK, iCmd)); return EINVAL; } cbBuf = RT_MAX(StackBuf.Hdr.cbIn, StackBuf.Hdr.cbOut); if (RT_UNLIKELY( StackBuf.Hdr.cbIn < sizeof(StackBuf.Hdr) || StackBuf.Hdr.cbOut < sizeof(StackBuf.Hdr) || cbBuf > _1M*16)) { LogRel(("VBoxDrvSolarisIOCtlSlow: max(%#x,%#x); iCmd=%#x\n", StackBuf.Hdr.cbIn, StackBuf.Hdr.cbOut, iCmd)); return EINVAL; } /* * Buffer the request. */ if (cbBuf <= sizeof(StackBuf)) pHdr = &StackBuf.Hdr; else { pHdr = RTMemTmpAlloc(cbBuf); if (RT_UNLIKELY(!pHdr)) { LogRel(("VBoxDrvSolarisIOCtlSlow: failed to allocate buffer of %d bytes for iCmd=%#x.\n", cbBuf, iCmd)); return ENOMEM; } } rc = ddi_copyin((void *)iArg, pHdr, cbBuf, Mode); if (RT_UNLIKELY(rc)) { LogRel(("VBoxDrvSolarisIOCtlSlow: copy_from_user(,%#lx, %#x) failed; iCmd=%#x. rc=%d\n", iArg, cbBuf, iCmd, rc)); if (pHdr != &StackBuf.Hdr) RTMemFree(pHdr); return EFAULT; } /* * Process the IOCtl. */ rc = supdrvIOCtl(iCmd, &g_DevExt, pSession, pHdr, cbBuf); /* * Copy ioctl data and output buffer back to user space. */ if (RT_LIKELY(!rc)) { uint32_t cbOut = pHdr->cbOut; if (RT_UNLIKELY(cbOut > cbBuf)) { LogRel(("VBoxDrvSolarisIOCtlSlow: too much output! %#x > %#x; iCmd=%#x!\n", cbOut, cbBuf, iCmd)); cbOut = cbBuf; } rc = ddi_copyout(pHdr, (void *)iArg, cbOut, Mode); if (RT_UNLIKELY(rc != 0)) { /* this is really bad */ LogRel(("VBoxDrvSolarisIOCtlSlow: ddi_copyout(,%p,%d) failed. rc=%d\n", (void *)iArg, cbBuf, rc)); rc = EFAULT; } } else rc = EINVAL; if (pHdr != &StackBuf.Hdr) RTMemTmpFree(pHdr); return rc; }
/* * Perform register accesses on the nexus device itself. */ int pxtool_bus_reg_ops(dev_info_t *dip, void *arg, int cmd, int mode) { pcitool_reg_t prg; size_t size; px_t *px_p = DIP_TO_STATE(dip); boolean_t is_write = B_FALSE; uint32_t rval = 0; if (cmd == PCITOOL_NEXUS_SET_REG) is_write = B_TRUE; DBG(DBG_TOOLS, dip, "pxtool_bus_reg_ops set/get reg\n"); /* Read data from userland. */ if (ddi_copyin(arg, &prg, sizeof (pcitool_reg_t), mode) != DDI_SUCCESS) { DBG(DBG_TOOLS, dip, "Error reading arguments\n"); return (EFAULT); } size = PCITOOL_ACC_ATTR_SIZE(prg.acc_attr); DBG(DBG_TOOLS, dip, "raw bus:0x%x, dev:0x%x, func:0x%x\n", prg.bus_no, prg.dev_no, prg.func_no); DBG(DBG_TOOLS, dip, "barnum:0x%x, offset:0x%" PRIx64 ", acc:0x%x\n", prg.barnum, prg.offset, prg.acc_attr); DBG(DBG_TOOLS, dip, "data:0x%" PRIx64 ", phys_addr:0x%" PRIx64 "\n", prg.data, prg.phys_addr); /* * If bank num == ff, base phys addr passed in from userland. * * Normal bank specification is invalid, as there is no OBP property to * back it up. */ if (prg.barnum != PCITOOL_BASE) { prg.status = PCITOOL_OUT_OF_RANGE; rval = EINVAL; goto done; } /* Allow only size of 8-bytes. */ if (size != sizeof (uint64_t)) { prg.status = PCITOOL_INVALID_SIZE; rval = EINVAL; goto done; } /* Alignment checking. */ if (!IS_P2ALIGNED(prg.offset, size)) { DBG(DBG_TOOLS, dip, "not aligned.\n"); prg.status = PCITOOL_NOT_ALIGNED; rval = EINVAL; goto done; } prg.phys_addr += prg.offset; /* * Only the hypervisor can access nexus registers. As a result, there * can be no error recovery in the OS. If there is an error, the * system will go down, but with a trap type 7f. The OS cannot * intervene with this kind of trap. */ /* Access device. prg.status is modified. */ rval = pxtool_phys_access(px_p, prg.phys_addr, &prg.data, PCITOOL_ACC_IS_BIG_ENDIAN(prg.acc_attr), is_write); done: prg.drvr_version = PCITOOL_VERSION; if (ddi_copyout(&prg, arg, sizeof (pcitool_reg_t), mode) != DDI_SUCCESS) { DBG(DBG_TOOLS, dip, "Copyout failed.\n"); return (EFAULT); } return (rval); }
static int do_gfx_ioctl(int cmd, intptr_t data, int mode, struct vgatext_softc *softc) { static char kernel_only[] = "gfxp_vgatext_ioctl: %s is a kernel only ioctl"; int err; int kd_mode; switch (cmd) { case KDSETMODE: return (vgatext_kdsetmode(softc, (int)data)); case KDGETMODE: kd_mode = softc->mode; if (ddi_copyout(&kd_mode, (void *)data, sizeof (int), mode)) return (EFAULT); break; case VIS_DEVINIT: if (!(mode & FKIOCTL)) { cmn_err(CE_CONT, kernel_only, "VIS_DEVINIT"); return (ENXIO); } err = vgatext_devinit(softc, (struct vis_devinit *)data); if (err != 0) { cmn_err(CE_WARN, "gfxp_vgatext_ioctl: could not" " initialize console"); return (err); } break; case VIS_CONSCOPY: /* move */ { struct vis_conscopy pma; if (ddi_copyin((void *)data, &pma, sizeof (struct vis_conscopy), mode)) return (EFAULT); vgatext_cons_copy(softc, &pma); break; } case VIS_CONSDISPLAY: /* display */ { struct vis_consdisplay display_request; if (ddi_copyin((void *)data, &display_request, sizeof (display_request), mode)) return (EFAULT); vgatext_cons_display(softc, &display_request); break; } case VIS_CONSCURSOR: { struct vis_conscursor cursor_request; if (ddi_copyin((void *)data, &cursor_request, sizeof (cursor_request), mode)) return (EFAULT); vgatext_cons_cursor(softc, &cursor_request); if (cursor_request.action == VIS_GET_CURSOR && ddi_copyout(&cursor_request, (void *)data, sizeof (cursor_request), mode)) return (EFAULT); break; } case VIS_GETCMAP: case VIS_PUTCMAP: case FBIOPUTCMAP: case FBIOGETCMAP: /* * At the moment, text mode is not considered to have * a color map. */ return (EINVAL); case FBIOGATTR: if (copyout(&vgatext_attr, (void *)data, sizeof (struct fbgattr))) return (EFAULT); break; case FBIOGTYPE: if (copyout(&vgatext_attr.fbtype, (void *)data, sizeof (struct fbtype))) return (EFAULT); break; default: return (ENXIO); } return (0); }