8361 * after the locking is done.
8362 * Doing this after as_pagelock guarantees persistence of the as; if
8363 * an unacceptable segment is found, the cleanup includes calling
8364 * as_pageunlock before returning EFAULT.
8365 *
8366 * segdev is allowed here as it is already locked. This allows
8367 * for memory exported by drivers through mmap() (which is already
8368 * locked) to be allowed for LONGTERM.
8369 */
8370 if (flags & DDI_UMEMLOCK_LONGTERM) {
8371 extern struct seg_ops segspt_shmops;
8372 extern struct seg_ops segdev_ops;
8373 AS_LOCK_ENTER(as, &as->a_lock, RW_READER);
8374 for (seg = as_segat(as, addr); ; seg = AS_SEGNEXT(as, seg)) {
8375 if (seg == NULL || seg->s_base > addr + len)
8376 break;
8377 if (seg->s_ops == &segdev_ops)
8378 continue;
8379 if (((seg->s_ops != &segvn_ops) &&
8380 (seg->s_ops != &segspt_shmops)) ||
8381 ((SEGOP_GETVP(seg, addr, &vp) == 0 &&
8382 vp != NULL && vp->v_type == VREG) &&
8383 (SEGOP_GETTYPE(seg, addr) & MAP_SHARED))) {
8384 as_pageunlock(as, p->pparray,
8385 addr, len, p->s_flags);
8386 AS_LOCK_EXIT(as, &as->a_lock);
8387 umem_decr_devlockmem(p);
8388 kmem_free(p, sizeof (struct ddi_umem_cookie));
8389 *cookie = (ddi_umem_cookie_t)NULL;
8390 return (EFAULT);
8391 }
8392 }
8393 AS_LOCK_EXIT(as, &as->a_lock);
8394 }
8395
8396
8397 /* Initialize the fields in the ddi_umem_cookie */
8398 p->cvaddr = addr;
8399 p->type = UMEM_LOCKED;
8400 if (driver_callback != NULL) {
8401 /* i_ddi_umem_unlock and umem_lock_undo may need the cookie */
8402 p->cook_refcnt = 2;
8403 p->callbacks = *ops_vector;
|
8361 * after the locking is done.
8362 * Doing this after as_pagelock guarantees persistence of the as; if
8363 * an unacceptable segment is found, the cleanup includes calling
8364 * as_pageunlock before returning EFAULT.
8365 *
8366 * segdev is allowed here as it is already locked. This allows
8367 * for memory exported by drivers through mmap() (which is already
8368 * locked) to be allowed for LONGTERM.
8369 */
8370 if (flags & DDI_UMEMLOCK_LONGTERM) {
8371 extern struct seg_ops segspt_shmops;
8372 extern struct seg_ops segdev_ops;
8373 AS_LOCK_ENTER(as, &as->a_lock, RW_READER);
8374 for (seg = as_segat(as, addr); ; seg = AS_SEGNEXT(as, seg)) {
8375 if (seg == NULL || seg->s_base > addr + len)
8376 break;
8377 if (seg->s_ops == &segdev_ops)
8378 continue;
8379 if (((seg->s_ops != &segvn_ops) &&
8380 (seg->s_ops != &segspt_shmops)) ||
8381 ((segop_getvp(seg, addr, &vp) == 0 &&
8382 vp != NULL && vp->v_type == VREG) &&
8383 (segop_gettype(seg, addr) & MAP_SHARED))) {
8384 as_pageunlock(as, p->pparray,
8385 addr, len, p->s_flags);
8386 AS_LOCK_EXIT(as, &as->a_lock);
8387 umem_decr_devlockmem(p);
8388 kmem_free(p, sizeof (struct ddi_umem_cookie));
8389 *cookie = (ddi_umem_cookie_t)NULL;
8390 return (EFAULT);
8391 }
8392 }
8393 AS_LOCK_EXIT(as, &as->a_lock);
8394 }
8395
8396
8397 /* Initialize the fields in the ddi_umem_cookie */
8398 p->cvaddr = addr;
8399 p->type = UMEM_LOCKED;
8400 if (driver_callback != NULL) {
8401 /* i_ddi_umem_unlock and umem_lock_undo may need the cookie */
8402 p->cook_refcnt = 2;
8403 p->callbacks = *ops_vector;
|