seg_dev.c revision 44374aae0994350211c68b8974530496edbed4fc
c0c934808d1b7d058148814255f32064a0e09555lin wang - Sun Microsystems - Beijing China * CDDL HEADER START
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * The contents of this file are subject to the terms of the
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * Common Development and Distribution License (the "License").
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * You may not use this file except in compliance with the License.
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * or http://www.opensolaris.org/os/licensing.
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * See the License for the specific language governing permissions
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * and limitations under the License.
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * When distributing Covered Code, include this CDDL HEADER in each
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * If applicable, add the following below this CDDL HEADER, with the
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * fields enclosed by brackets "[]" replaced with your own identifying
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * information: Portions Copyright [yyyy] [name of copyright owner]
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * CDDL HEADER END
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * Use is subject to license terms.
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China/* All Rights Reserved */
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * University Copyright- Copyright (c) 1982, 1986, 1988
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * The Regents of the University of California
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * All Rights Reserved
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * University Acknowledgment- Portions of this document are derived from
c0c934808d1b7d058148814255f32064a0e09555lin wang - Sun Microsystems - Beijing China * software developed by the University of California, Berkeley, and its
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#pragma ident "%Z%%M% %I% %E% SMI"
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * VM - segment of a mapped device.
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * This segment driver is used when mapping character special devices.
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#include <sys/types.h>
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#include <sys/t_lock.h>
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#include <sys/sysmacros.h>
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#include <sys/vtrace.h>
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#include <sys/systm.h>
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#include <sys/vmsystm.h>
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#include <sys/mman.h>
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#include <sys/errno.h>
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#include <sys/kmem.h>
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#include <sys/cmn_err.h>
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#include <sys/vnode.h>
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#include <sys/proc.h>
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#include <sys/conf.h>
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#include <sys/debug.h>
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#include <sys/ddidevmap.h>
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#include <sys/ddi_implfuncs.h>
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#include <sys/lgrp.h>
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#include <vm/page.h>
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#include <vm/hat.h>
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#include <vm/as.h>
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#include <vm/seg.h>
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#include <vm/seg_dev.h>
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#include <vm/seg_kp.h>
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#include <vm/seg_kmem.h>
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#include <vm/vpage.h>
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#include <sys/sunddi.h>
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#include <sys/esunddi.h>
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#include <sys/fs/snode.h>
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinaint segdev_debug;
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#define DEBUGF(level, args) { if (segdev_debug >= (level)) cmn_err args; }
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#define DEBUGF(level, args)
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China/* Default timeout for devmap context management */
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#define CTX_TIMEOUT_VALUE 0
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#define HOLD_DHP_LOCK(dhp) if (dhp->dh_flags & DEVMAP_ALLOW_REMAP) \
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China { mutex_enter(&dhp->dh_lock); }
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#define RELE_DHP_LOCK(dhp) if (dhp->dh_flags & DEVMAP_ALLOW_REMAP) \
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China { mutex_exit(&dhp->dh_lock); }
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#define round_down_p2(a, s) ((a) & ~((s) - 1))
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#define round_up_p2(a, s) (((a) + (s) - 1) & ~((s) - 1))
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * VA_PA_ALIGNED checks to see if both VA and PA are on pgsize boundary
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * VA_PA_PGSIZE_ALIGNED check to see if VA is aligned with PA w.r.t. pgsize
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#define VA_PA_ALIGNED(uvaddr, paddr, pgsize) \
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China (((uvaddr | paddr) & (pgsize - 1)) == 0)
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#define VA_PA_PGSIZE_ALIGNED(uvaddr, paddr, pgsize) \
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China (((uvaddr ^ paddr) & (pgsize - 1)) == 0)
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#define vpgtob(n) ((n) * sizeof (struct vpage)) /* For brevity */
c0c934808d1b7d058148814255f32064a0e09555lin wang - Sun Microsystems - Beijing China#define VTOCVP(vp) (VTOS(vp)->s_commonvp) /* we "know" it's an snode */
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic struct devmap_ctx *devmapctx_list = NULL;
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic struct devmap_softlock *devmap_slist = NULL;
c0c934808d1b7d058148814255f32064a0e09555lin wang - Sun Microsystems - Beijing China * mutex, vnode and page for the page of zeros we use for the trash mappings.
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * One trash page is allocated on the first ddi_umem_setup call that uses it
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * XXX Eventually, we may want to combine this with what segnf does when all
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * hat layers implement HAT_NOFAULT.
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * The trash page is used when the backing store for a userland mapping is
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * removed but the application semantics do not take kindly to a SIGBUS.
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * In that scenario, the applications pages are mapped to some dummy page
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * which returns garbage on read and writes go into a common place.
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * (Perfect for NO_FAULT semantics)
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * The device driver is responsible to communicating to the app with some
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * other mechanism that such remapping has happened and the app should take
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * corrective action.
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * We can also use an anonymous memory page as there is no requirement to
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * keep the page locked, however this complicates the fault code. RFE.
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic struct vnode trashvp;
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic struct page *trashpp;
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China/* Non-pageable kernel memory is allocated from the umem_np_arena. */
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic vmem_t *umem_np_arena;
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China/* Set the cookie to a value we know will never be a valid umem_cookie */
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#define DEVMAP_DEVMEM_COOKIE ((ddi_umem_cookie_t)0x1)
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * Macros to check if type of devmap handle
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#define cookie_is_devmem(c) \
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China ((c) == (struct ddi_umem_cookie *)DEVMAP_DEVMEM_COOKIE)
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#define cookie_is_pmem(c) \
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China ((c) == (struct ddi_umem_cookie *)DEVMAP_PMEM_COOKIE)
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#define cookie_is_kpmem(c) (!cookie_is_devmem(c) && !cookie_is_pmem(c) &&\
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China ((c)->type == KMEM_PAGEABLE))
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#define dhp_is_devmem(dhp) \
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China (cookie_is_devmem((struct ddi_umem_cookie *)((dhp)->dh_cookie)))
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#define dhp_is_pmem(dhp) \
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China (cookie_is_pmem((struct ddi_umem_cookie *)((dhp)->dh_cookie)))
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China#define dhp_is_kpmem(dhp) \
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China (cookie_is_kpmem((struct ddi_umem_cookie *)((dhp)->dh_cookie)))
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * Private seg op routines.
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic int segdev_dup(struct seg *, struct seg *);
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic int segdev_unmap(struct seg *, caddr_t, size_t);
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic void segdev_free(struct seg *);
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic faultcode_t segdev_fault(struct hat *, struct seg *, caddr_t, size_t,
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China enum fault_type, enum seg_rw);
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic faultcode_t segdev_faulta(struct seg *, caddr_t);
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic int segdev_setprot(struct seg *, caddr_t, size_t, uint_t);
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic int segdev_checkprot(struct seg *, caddr_t, size_t, uint_t);
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic void segdev_badop(void);
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic int segdev_sync(struct seg *, caddr_t, size_t, int, uint_t);
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic size_t segdev_incore(struct seg *, caddr_t, size_t, char *);
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic int segdev_lockop(struct seg *, caddr_t, size_t, int, int,
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China ulong_t *, size_t);
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic int segdev_getprot(struct seg *, caddr_t, size_t, uint_t *);
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic u_offset_t segdev_getoffset(struct seg *, caddr_t);
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic int segdev_gettype(struct seg *, caddr_t);
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic int segdev_getvp(struct seg *, caddr_t, struct vnode **);
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic int segdev_advise(struct seg *, caddr_t, size_t, uint_t);
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic void segdev_dump(struct seg *);
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic int segdev_pagelock(struct seg *, caddr_t, size_t,
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China struct page ***, enum lock_type, enum seg_rw);
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic int segdev_setpagesize(struct seg *, caddr_t, size_t, uint_t);
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic int segdev_getmemid(struct seg *, caddr_t, memid_t *);
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic lgrp_mem_policy_info_t *segdev_getpolicy(struct seg *, caddr_t);
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic int segdev_capable(struct seg *, segcapability_t);
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * XXX this struct is used by rootnex_map_fault to identify
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * the segment it has been passed. So if you make it
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * "static" you'll need to fix rootnex_map_fault.
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastruct seg_ops segdev_ops = {
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China segdev_checkprot,
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China (int (*)())segdev_badop, /* kluster */
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China (size_t (*)(struct seg *))NULL, /* swapout */
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China segdev_sync, /* sync */
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China segdev_lockop, /* lockop */
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China segdev_getoffset,
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China segdev_pagelock,
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China segdev_setpagesize,
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China segdev_getmemid,
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China segdev_getpolicy,
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * Private segdev support routines
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic struct segdev_data *sdp_alloc(void);
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing Chinastatic void segdev_softunlock(struct hat *, struct seg *, caddr_t,
c0c934808d1b7d058148814255f32064a0e09555lin wang - Sun Microsystems - Beijing China size_t, enum seg_rw);
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing Chinastatic faultcode_t segdev_faultpage(struct hat *, struct seg *, caddr_t,
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing China struct vpage *, enum fault_type, enum seg_rw, devmap_handle_t *);
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing Chinastatic faultcode_t segdev_faultpages(struct hat *, struct seg *, caddr_t,
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China size_t, enum fault_type, enum seg_rw, devmap_handle_t *);
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic struct devmap_ctx *devmap_ctxinit(dev_t, ulong_t);
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic struct devmap_softlock *devmap_softlock_init(dev_t, ulong_t);
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic void devmap_softlock_rele(devmap_handle_t *);
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic void devmap_ctx_rele(devmap_handle_t *);
c0c934808d1b7d058148814255f32064a0e09555lin wang - Sun Microsystems - Beijing Chinastatic void devmap_ctxto(void *);
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic devmap_handle_t *devmap_find_handle(devmap_handle_t *dhp_head,
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic ulong_t devmap_roundup(devmap_handle_t *dhp, ulong_t offset, size_t len,
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing China ulong_t *opfn, ulong_t *pagesize);
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinastatic void free_devmap_handle(devmap_handle_t *dhp);
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing Chinastatic int devmap_handle_dup(devmap_handle_t *dhp, devmap_handle_t **new_dhp,
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing China struct seg *newseg);
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing Chinastatic devmap_handle_t *devmap_handle_unmap(devmap_handle_t *dhp);
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing Chinastatic void devmap_handle_unmap_head(devmap_handle_t *dhp, size_t len);
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing Chinastatic void devmap_handle_unmap_tail(devmap_handle_t *dhp, caddr_t addr);
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing Chinastatic int devmap_device(devmap_handle_t *dhp, struct as *as, caddr_t *addr,
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing China offset_t off, size_t len, uint_t flags);
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing Chinastatic void devmap_get_large_pgsize(devmap_handle_t *dhp, size_t len,
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing China caddr_t addr, size_t *llen, caddr_t *laddr);
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing Chinastatic void devmap_handle_reduce_len(devmap_handle_t *dhp, size_t len);
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing Chinastatic void *devmap_alloc_pages(vmem_t *vmp, size_t size, int vmflag);
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing Chinastatic void devmap_free_pages(vmem_t *vmp, void *inaddr, size_t size);
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing Chinastatic void *devmap_umem_alloc_np(size_t size, size_t flags);
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing Chinastatic void devmap_umem_free_np(void *addr, size_t size);
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing China * routines to lock and unlock underlying segkp segment for
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing China * KMEM_PAGEABLE type cookies.
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing Chinastatic faultcode_t acquire_kpmem_lock(struct ddi_umem_cookie *, size_t);
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing Chinastatic void release_kpmem_lock(struct ddi_umem_cookie *, size_t);
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing China * Routines to synchronize F_SOFTLOCK and F_INVAL faults for
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing China * drivers with devmap_access callbacks
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing Chinastatic int devmap_softlock_enter(struct devmap_softlock *, size_t,
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing China enum fault_type);
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing Chinastatic void devmap_softlock_exit(struct devmap_softlock *, size_t,
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing China enum fault_type);
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing Chinastatic kmutex_t devmapctx_lock;
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing Chinastatic kmutex_t devmap_slock;
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing China * Initialize the thread callbacks and thread private data.
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing Chinastatic struct devmap_ctx *
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing China struct devmap_ctx *devctx;
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing China struct devmap_ctx *tmp;
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing China dev_info_t *dip;
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing China tmp = kmem_zalloc(sizeof (struct devmap_ctx), KM_SLEEP);
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China mutex_enter(&devmapctx_lock);
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing China dip = e_ddi_hold_devi_by_dev(dev, 0);
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing China ASSERT(dip != NULL);
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing China ddi_release_devi(dip);
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing China for (devctx = devmapctx_list; devctx != NULL; devctx = devctx->next)
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing China if ((devctx->dip == dip) && (devctx->id == id))
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing China if (devctx == NULL) {
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing China devctx->dip = dip;
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China devctx->id = id;
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing China mutex_init(&devctx->lock, NULL, MUTEX_DEFAULT, NULL);
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing China cv_init(&devctx->cv, NULL, CV_DEFAULT, NULL);
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China devctx->next = devmapctx_list;
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing China devmapctx_list = devctx;
c0c934808d1b7d058148814255f32064a0e09555lin wang - Sun Microsystems - Beijing China kmem_free(tmp, sizeof (struct devmap_ctx));
c0c934808d1b7d058148814255f32064a0e09555lin wang - Sun Microsystems - Beijing China mutex_enter(&devctx->lock);
c0c934808d1b7d058148814255f32064a0e09555lin wang - Sun Microsystems - Beijing China devctx->refcnt++;
c0c934808d1b7d058148814255f32064a0e09555lin wang - Sun Microsystems - Beijing China mutex_exit(&devctx->lock);
c0c934808d1b7d058148814255f32064a0e09555lin wang - Sun Microsystems - Beijing China mutex_exit(&devmapctx_lock);
c0c934808d1b7d058148814255f32064a0e09555lin wang - Sun Microsystems - Beijing China return (devctx);
c0c934808d1b7d058148814255f32064a0e09555lin wang - Sun Microsystems - Beijing China * Timeout callback called if a CPU has not given up the device context
c0c934808d1b7d058148814255f32064a0e09555lin wang - Sun Microsystems - Beijing China * within dhp->dh_timeout_length ticks
c0c934808d1b7d058148814255f32064a0e09555lin wang - Sun Microsystems - Beijing Chinadevmap_ctxto(void *data)
c0c934808d1b7d058148814255f32064a0e09555lin wang - Sun Microsystems - Beijing China struct devmap_ctx *devctx = data;
c0c934808d1b7d058148814255f32064a0e09555lin wang - Sun Microsystems - Beijing China TRACE_1(TR_FAC_DEVMAP, TR_DEVMAP_CTXTO,
c0c934808d1b7d058148814255f32064a0e09555lin wang - Sun Microsystems - Beijing China "devmap_ctxto:timeout expired, devctx=%p", (void *)devctx);
c0c934808d1b7d058148814255f32064a0e09555lin wang - Sun Microsystems - Beijing China mutex_enter(&devctx->lock);
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing China * Set oncpu = 0 so the next mapping trying to get the device context
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing China devctx->oncpu = 0;
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing China devctx->timeout = 0;
3ae945c326c1fc078149f2c8b11fac0cc8f6d1d6lin wang - Sun Microsystems - Beijing China cv_signal(&devctx->cv);
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China mutex_exit(&devctx->lock);
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * Create a device segment.
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing Chinasegdev_create(struct seg *seg, void *argsp)
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China struct segdev_data *sdp;
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China struct segdev_crargs *a = (struct segdev_crargs *)argsp;
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China devmap_handle_t *dhp = (devmap_handle_t *)a->devmap_data;
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * Since the address space is "write" locked, we
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China * don't need the segment lock to protect "segdev" data.
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China ASSERT(seg->s_as && AS_WRITE_HELD(seg->s_as, &seg->s_as->a_lock));
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China hat_map(seg->s_as->a_hat, seg->s_base, seg->s_size, HAT_MAP);
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China sdp = sdp_alloc();
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China sdp->mapfunc = a->mapfunc;
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China sdp->offset = a->offset;
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China sdp->prot = a->prot;
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China sdp->maxprot = a->maxprot;
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China sdp->type = a->type;
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China sdp->pageprot = 0;
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China sdp->softlockcnt = 0;
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China sdp->vpage = NULL;
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China if (sdp->mapfunc == NULL)
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China sdp->devmap_data = dhp;
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China sdp->devmap_data = dhp = NULL;
c0c934808d1b7d058148814255f32064a0e09555lin wang - Sun Microsystems - Beijing China sdp->hat_flags = a->hat_flags;
dd1de3740722a4b99a74005255effebbd20a6d70lin wang - Sun Microsystems - Beijing China sdp->hat_attr = a->hat_attr;
if (error != 0) {
return (error);
static struct segdev_data *
sdp_alloc(void)
return (sdp);
int ret;
if (ret != 0) {
return (ret);
int ret;
if (ret != 0) {
(void *)dhp));
return (ret);
return (EAGAIN);
while (slen != 0) {
soff = 0;
static devmap_handle_t *
return (dhpp);
if (maplen == 0) {
maplen = 0;
static faultcode_t
int err = 0;
if (!err) {
return (err);
static int devmap_softlock_enter(
if (npages == 0)
switch (type) {
case F_SOFTLOCK :
return (EINTR);
case F_INVAL :
case F_PROT :
return (EINTR);
ASSERT(0);
static void devmap_softlock_exit(
switch (type) {
case F_SOFTLOCK :
case F_INVAL :
case F_PROT:
ASSERT(0);
while (tlen != 0) {
off = 0;
static faultcode_t
switch (rw) {
case S_READ:
case S_WRITE:
case S_EXEC:
case S_OTHER:
case UMEM_LOCKED :
PAGEOFFSET) == 0);
case UMEM_TRASH :
case KMEM_PAGEABLE:
case KMEM_NON_PAGEABLE:
static faultcode_t
int err;
int err_is_faultcode = 0;
return (FC_NOMAP);
* - determine if the F_INVAL/F_SOFTLOCK syncing
return (FC_PROT);
* Second, a desire to serialize F_INVAL(and F_PROT) calls w.r.t.
* the same loop calling segdev_faultpages/segdev_softunlock
while (slen != 0) {
return (FC_NOSUPPORT);
off = 0;
while (len != 0) {
* call devmap_load/contextmgmt to load the translations
if (err) {
if (err_is_faultcode)
return (err);
off = 0;
static faultcode_t
register caddr_t a;
int err;
return (FC_PROT);
return (err);
switch (rw) {
case S_READ:
case S_WRITE:
case S_EXEC:
case S_OTHER:
return (FC_NOMAP);
vpage++;
if (done > 0) {
return (err);
static faultcode_t
return (EAGAIN);
return (EINVAL);
while (dhp) {
off = 0;
return (EACCES);
KM_SLEEP);
if (tdhp) {
while (slen != 0) {
soff = 0;
register int err;
return (err);
return (EACCES);
if (pgno != 0) {
} while (pgno != 0);
pgno--;
} while (pgno != 0);
static u_offset_t
segdev_badop(void)
static size_t
size_t v = 0;
v += PAGESIZE)
int error, i;
return (ENODEV);
return (EINVAL);
return (ENXIO);
return (ENXIO);
return (ENXIO);
return (ENOMEM);
return (error);
return (ENOTSUP);
return (ENOTSUP);
int err;
return (ENOMEM);
return (err);
int do_timeout = 0;
int ret;
#ifdef lint
return (FC_HWERR);
if (ret) {
return (FC_HWERR);
if (do_timeout) {
return (DDI_SUCCESS);
static ulong_t
register int level;
long rlen;
static devmap_handle_t *
while (dhp) {
return (dhp);
if (len == 0)
*llen = 0;
while ((long)len > 0) {
if (first) {
first = 0;
static struct devmap_softlock *
return (slock);
int rc;
if (len == 0)
return (rc);
int map_flag;
int ret;
#ifdef lint
return (EINVAL);
return (EINVAL);
return (ENXIO);
return (EINVAL);
return (EINVAL);
return (ENOTSUP);
return (ret);
if (ret != 0) {
return (ENXIO);
* Called from devmap_devmem_setup/remap to see if can use large pages for
int level;
int err;
return (DDI_FAILURE);
return (DDI_FAILURE);
return (DDI_FAILURE);
return (DDI_FAILURE);
if (err)
return (DDI_FAILURE);
sizeof (struct devmap_callback_ctl));
return (DDI_SUCCESS);
int err;
return (DDI_FAILURE);
return (DDI_FAILURE);
return (DDI_FAILURE);
return (DDI_FAILURE);
if (err) {
return (DDI_FAILURE);
return (DDI_SUCCESS);
#ifdef lint
return (DDI_FAILURE);
return (DDI_FAILURE);
return (DDI_FAILURE);
return (DDI_FAILURE);
return (DDI_FAILURE);
return (DDI_FAILURE);
sizeof (struct devmap_callback_ctl));
return (DDI_SUCCESS);
#ifdef lint
return (DDI_FAILURE);
if (flags != 0)
return (DDI_FAILURE);
return (DDI_FAILURE);
return (DDI_FAILURE);
return (DDI_FAILURE);
return (DDI_SUCCESS);
#ifdef lint
SE_EXCL);
void *buf;
return (buf);
int iflags = 0;
if (len == 0)
return ((void *)NULL);
return ((void *)NULL);
return ((void *)NULL);
return ((void *)NULL);
return (buf);
case KMEM_PAGEABLE :
(void *)cp);
case KMEM_NON_PAGEABLE :
case UMEM_TRASH :
case UMEM_LOCKED :
static lgrp_mem_policy_info_t *
return (NULL);
segdev_init(void)