xref: /illumos-gate/usr/src/uts/common/sys/ddidevmap.h (revision 598f4ceed9327d2d6c2325dd67cae3aa06f7fea6)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
23  */
24 
25 #ifndef	_SYS_DDIDEVMAP_H
26 #define	_SYS_DDIDEVMAP_H
27 
28 #ifdef	__cplusplus
29 extern "C" {
30 #endif
31 
32 #ifdef	_KERNEL
33 
34 #include <sys/mman.h>
35 
36 struct devmap_info {
37 	size_t	length;		/* and this length */
38 	size_t	page_size;	/* pte page size selected by framework */
39 	size_t	offset;		/* optimal page size based on this offset */
40 	ushort_t valid_flag;	/* flag to indicate the validity of data */
41 	uchar_t	byte_order;	/* the  endian characteristics of the mapping */
42 
43 	/*
44 	 * describes  order in which the CPU will reference data.
45 	 */
46 	uchar_t	data_order;
47 };
48 
49 typedef void * ddi_umem_cookie_t;
50 
51 /*
52  * umem callback function vector for drivers
53  *
54  * NOTE: IMPORTANT!  When umem_lockmemory is called with a valid
55  * umem_callback_ops and DDI_UMEMLOCK_LONGTERM set, the 'cleanup'
56  * callback function may be called AFTER a call to ddi_umem_lock.
57  * It is the users responsibility to make sure that ddi_umem_lock is
58  * called ONLY once for each ddi_umem_lock/umem_lockmemory cookie.
59  */
60 #define	UMEM_CALLBACK_VERSION 1
61 struct umem_callback_ops {
62 	int	cbo_umem_callback_version;	/* version number */
63 	void (*cbo_umem_lock_cleanup)(ddi_umem_cookie_t *);
64 };
65 
66 struct ddi_umem_cookie {
67 	size_t	size;	/* size of allocation */
68 	caddr_t	cvaddr;	/* cookie virtual address. */
69 			/* KMEM - kvaddr returned from ddi_umem_alloc() */
70 			/* For LOCKEDUMEM - user address of backing store */
71 			/* For TRASH_UMEM - unused */
72 	kmutex_t	lock;
73 	uint_t		type;	/* see below for umem_cookie types */
74 	/*
75 	 * Following 4 members are used for UMEM_LOCKED cookie type
76 	 */
77 	page_t		**pparray;	/* shadow list from as_pagelock */
78 	void		*procp;		/* user process owning backing store */
79 	struct as	*asp;		/* as ptr for use by ddi_umem_unlock */
80 	enum seg_rw	s_flags;	/* flags used during pagelock/fault */
81 	/*
82 	 * locked indicates underlying memory locked for KMEM_PAGEABLE
83 	 * locked is a count of for how many pages this has been locked
84 	 */
85 	uint_t		locked;
86 	struct umem_callback_ops callbacks;
87 	/*
88 	 * cook_refcnt used in UMEM_LOCKED type
89 	 */
90 	ulong_t		cook_refcnt;	/* cookie reference count */
91 	struct ddi_umem_cookie *unl_forw;   /* list ptr for unlock cookies */
92 	ulong_t		upd_max_lock_rctl;  /* track max-locked mem rctl? */
93 };
94 
95 typedef struct as *ddi_as_handle_t;
96 
97 
98 /*
99  * type of umem_cookie:
100  *    pageable memory allocated from segkp segment driver
101  *    non-pageable memory allocated from kmem_getpages()
102  *    locked umem allocated from ddi_umem_lock
103  *    trash umem maps all user virtual addresses to a common trash page
104  */
105 #define	KMEM_PAGEABLE		0x100	/* un-locked kernel memory */
106 #define	KMEM_NON_PAGEABLE	0x200	/* locked kernel memeory */
107 #define	UMEM_LOCKED		0x400	/* locked user process memeory */
108 #define	UMEM_TRASH		0x800	/* trash page mapping */
109 
110 typedef struct __devmap_pmem_cookie *devmap_pmem_cookie_t;
111 
112 typedef void *devmap_cookie_t;
113 
114 struct devmap_callback_ctl {
115 	int	devmap_rev;		/* devmap_callback_ctl version number */
116 	int	(*devmap_map)(devmap_cookie_t dhp, dev_t dev, uint_t flags,
117 				offset_t off, size_t len, void **pvtp);
118 	int	(*devmap_access)(devmap_cookie_t dhp, void *pvtp, offset_t off,
119 				size_t len, uint_t type, uint_t rw);
120 	int	(*devmap_dup)(devmap_cookie_t dhp, void *pvtp,
121 				devmap_cookie_t new_dhp, void **new_pvtp);
122 	void	(*devmap_unmap)(devmap_cookie_t dhp, void *pvtp, offset_t off,
123 				size_t len, devmap_cookie_t new_dhp1,
124 				void **new_pvtp1, devmap_cookie_t new_dhp2,
125 				void **new_pvtp2);
126 };
127 
128 struct devmap_softlock {
129 	ulong_t		id;	/* handle grouping id */
130 	dev_t		dev; /* Device to which we are mapping */
131 	struct		devmap_softlock	*next;
132 	kmutex_t	lock;
133 	kcondvar_t	cv;
134 	int		refcnt;	/* Number of threads with mappings */
135 	ssize_t		softlocked;
136 };
137 
138 struct devmap_ctx {
139 	ulong_t		id; /* handle grouping id */
140 	dev_info_t	*dip; /* Device info struct for tracing context */
141 	struct devmap_ctx *next;
142 	kmutex_t	lock;
143 	kcondvar_t	cv;
144 	int		refcnt; /* Number of threads with mappings */
145 	uint_t		oncpu; /* this context is running on a cpu */
146 	timeout_id_t	timeout; /* Timeout ID */
147 };
148 
149 /*
150  * Fault information passed to the driver fault handling routine.
151  * The DEVMAP_LOCK and DEVMAP_UNLOCK are used by software
152  * to lock and unlock pages for physical I/O.
153  */
154 enum devmap_fault_type {
155 	DEVMAP_ACCESS,		/* invalid page */
156 	DEVMAP_PROT,		/* protection fault */
157 	DEVMAP_LOCK,		/* software requested locking */
158 	DEVMAP_UNLOCK		/* software requested unlocking */
159 };
160 
161 /*
162  * seg_rw gives the access type for a fault operation
163  */
164 enum devmap_rw {
165 	DEVMAP_OTHER,		/* unknown or not touched */
166 	DEVMAP_READ,		/* read access attempted */
167 	DEVMAP_WRITE,		/* write access attempted */
168 	DEVMAP_EXEC,		/* execution access attempted */
169 	DEVMAP_CREATE		/* create if page doesn't exist */
170 };
171 
172 typedef struct devmap_handle {
173 
174 	/*
175 	 * physical offset at the beginning of mapping.
176 	 */
177 	offset_t	dh_roff;
178 
179 	/*
180 	 * user offset at the beginning of mapping.
181 	 */
182 	offset_t	dh_uoff;
183 	size_t		dh_len;		/* length of mapping */
184 	dev_t		dh_dev;		/* dev_t for this mapping */
185 	caddr_t		dh_cvaddr;  /* cookie virtual address */
186 	caddr_t		dh_uvaddr;  /* user address within dh_seg */
187 
188 	/*
189 	 * Lock protects fields that can change during remap
190 	 * dh_roff, dh_cookie, dh_flags, dh_mmulevel, dh_maxprot,
191 	 * dh_pfn, dh_hat_attr
192 	 */
193 	kmutex_t	dh_lock;
194 
195 	/*
196 	 * to sync. faults for remap and unlocked kvaddr.
197 	 */
198 	struct seg		*dh_seg; /* segment created for this mapping */
199 	void			*dh_pvtp; /* device mapping private data */
200 	struct devmap_handle	*dh_next;
201 	struct devmap_softlock	*dh_softlock;
202 	struct devmap_ctx	*dh_ctx;
203 	ddi_umem_cookie_t	dh_cookie;	/* kmem cookie */
204 	devmap_pmem_cookie_t	dh_pcookie;	/* pmem cookie */
205 
206 	/*
207 	 * protection flag possible for attempted mapping.
208 	 */
209 	uint_t		dh_prot;
210 
211 	/*
212 	 * Current maximum protection flag for attempted mapping.
213 	 * This controls how dh_prot can be changed in segdev_setprot
214 	 * See dh_orig_maxprot below also
215 	 */
216 	uint_t		dh_maxprot;
217 
218 	/*
219 	 * mmu level corresponds to the Max page size can be use for
220 	 * the mapping.
221 	 */
222 	uint_t		dh_mmulevel;
223 	uint_t		dh_flags;   /* see defines below */
224 	pfn_t		dh_pfn;		/* pfn corresponds to dh_reg_off */
225 	uint_t		dh_hat_attr;
226 	clock_t		dh_timeout_length;
227 	struct devmap_callback_ctl dh_callbackops;
228 
229 	/*
230 	 * orig_maxprot is what the original mmap set maxprot to.
231 	 * This is never modified once it is setup during mmap(2)
232 	 * This is different from the current dh_maxprot which can
233 	 * be changed in devmap_*_setup/remap
234 	 */
235 	uint_t		dh_orig_maxprot;
236 } devmap_handle_t;
237 
238 #endif	/* _KERNEL */
239 
240 /*
241  * define for devmap_rev
242  */
243 #define	DEVMAP_OPS_REV 1
244 
245 /*
246  * defines for devmap_*_setup flag, called by drivers
247  */
248 #define	DEVMAP_DEFAULTS			0x00
249 #define	DEVMAP_MAPPING_INVALID		0x01 	/* mapping is invalid */
250 #define	DEVMAP_ALLOW_REMAP		0x02	/* allow remap */
251 #define	DEVMAP_USE_PAGESIZE		0x04	/* use pagesize for mmu load */
252 
253 /* flags used by drivers */
254 #define	DEVMAP_SETUP_FLAGS	\
255 	(DEVMAP_MAPPING_INVALID | DEVMAP_ALLOW_REMAP | DEVMAP_USE_PAGESIZE)
256 
257 /*
258  * defines for dh_flags, these are used internally in devmap
259  */
260 #define	DEVMAP_SETUP_DONE		0x100	/* mapping setup is done */
261 #define	DEVMAP_LOCK_INITED		0x200	/* locks are initailized */
262 #define	DEVMAP_LOCKED			0x800	/* dhp is locked. */
263 #define	DEVMAP_FLAG_LARGE		0x1000  /* cal. optimal pgsize */
264 
265 /*
266  * Flags to pass to ddi_umem_alloc and ddi_umem_iosetup
267  */
268 #define	DDI_UMEM_SLEEP		0x0
269 #define	DDI_UMEM_NOSLEEP	0x01
270 #define	DDI_UMEM_PAGEABLE	0x02
271 #define	DDI_UMEM_TRASH		0x04
272 
273 /*
274  * Flags to pass to ddi_umem_lock to indicate expected access pattern
275  * DDI_UMEMLOCK_READ implies the memory being locked will be read
276  * (e.g., data read from memory is written out to the disk or network)
277  * DDI_UMEMLOCK_WRITE implies the memory being locked will be written
278  * (e.g., data from the disk or network is written to memory)
279  * Both flags may be set in the call to ddi_umem_lock,
280  * Note that this corresponds to the VM subsystem definition of read/write
281  * and also correspond to the prots set in devmap
282  * When doing I/O, B_READ/B_WRITE are used which have exactly the opposite
283  * meaning. Be careful when using it both for I/O and devmap
284  *
285  *
286  */
287 #define	DDI_UMEMLOCK_READ	0x01
288 #define	DDI_UMEMLOCK_WRITE	0x02
289 
290 #ifdef	__cplusplus
291 }
292 #endif
293 
294 #endif	/* _SYS_DDIDEVMAP_H */
295