FreeBSD/Linux Kernel Cross Reference
sys/vm/vm_kern.c
1 /*
2 * Mach Operating System
3 * Copyright (c) 1993,1992,1991,1990,1989,1988,1987 Carnegie Mellon University
4 * All Rights Reserved.
5 *
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
11 *
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15 *
16 * Carnegie Mellon requests users of this software to return to
17 *
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
22 *
23 * any improvements or extensions that they make and grant Carnegie Mellon
24 * the rights to redistribute these changes.
25 */
26 /*
27 * HISTORY
28 * $Log: vm_kern.c,v $
29 * Revision 2.25 93/11/17 18:54:21 dbg
30 * Conditionalized projected buffer support under NET_ATM.
31 * [93/09/10 dbg]
32 * Added ANSI function prototypes.
33 * [93/06/16 dbg]
34 *
35 * Revision 2.24 93/08/10 15:12:33 mrt
36 * Included support for projected buffers: projected_buffer_allocate,
37 * projected_buffer_map, projected_buffer_deallocate,
38 * projected_buffer_collect
39 * and projected_buffer_in_range. Projected buffers are buffers shared
40 * between the kernel and user tasks, and which may be persistent or not
41 * (be deallocated from the kernel map automatically when the last user
42 * reference is deallocated). The intended use is for device drivers.
43 * The user is denied direct manipulation of these map entries.
44 * [93/02/16 09:28:21 jcb]
45 *
46 * Revision 2.23 93/01/14 18:01:03 danner
47 * 64bit cleanup.
48 * [92/12/01 af]
49 *
50 * Revision 2.22 92/08/03 18:00:41 jfriedl
51 * removed silly prototypes
52 * [92/08/02 jfriedl]
53 *
54 * Revision 2.21 92/05/21 17:26:02 jfriedl
55 * Added types for functions that didn't have them explicitly.
56 * [92/05/16 jfriedl]
57 *
58 * Revision 2.20 92/04/01 19:36:35 rpd
59 * Change kmem_io_map_copyout to handle multiple page lists.
60 * Don't call pmap_change_wiring from kmem_io_map_deallocate.
61 * [92/03/20 14:13:50 dlb]
62 *
63 * Revision 2.19 92/02/23 19:50:53 elf
64 * kmem_io_map_deallocate() now calls pmap_remove() -- VM
65 * code optimization makes this necessary. Optimized
66 * out kmem_alloc_pageable() call from kmem_io_map_copyout().
67 * [92/01/07 16:37:38 dlb]
68 *
69 * Revision 2.18 92/01/14 16:47:57 rpd
70 * Added copyinmap and copyoutmap.
71 * [91/12/16 rpd]
72 *
73 * Revision 2.17 91/08/28 11:18:00 jsb
74 * Delete kmem_fault_wire, io_wire, io_unwire - Replaced by
75 * kmem_io_{copyout,deallocate}.
76 * [91/08/06 17:17:40 dlb]
77 *
78 * Make kmem_io_map_deallocate return void.
79 * [91/08/05 17:45:39 dlb]
80 *
81 * New interfaces for kmem_io_map routines.
82 * [91/08/02 17:07:40 dlb]
83 *
84 * New and improved io wiring support based on vm page lists:
85 * kmem_io_map_{copyout,deallocate}. io_wire and io_unwire will
86 * go away when the device logic fully supports this.
87 * [91/07/31 15:12:02 dlb]
88 *
89 * Revision 2.16 91/07/30 15:47:20 rvb
90 * Fixed io_wire to allocate an object when the entry doesn't have one.
91 * [91/06/27 rpd]
92 *
93 * Revision 2.15 91/05/18 14:40:31 rpd
94 * Added kmem_alloc_aligned.
95 * [91/05/02 rpd]
96 * Added VM_FAULT_FICTITIOUS_SHORTAGE.
97 * Revised vm_map_find_entry to allow coalescing of entries.
98 * Fixed deadlock problem in kmem_alloc.
99 * [91/03/29 rpd]
100 * Fixed kmem_init to not create a zero-size entry.
101 * [91/03/25 rpd]
102 *
103 * Revision 2.14 91/05/14 17:49:15 mrt
104 * Correcting copyright
105 *
106 * Revision 2.13 91/03/16 15:05:20 rpd
107 * Fixed kmem_alloc_pages and kmem_remap_pages
108 * to not hold locks across pmap_enter.
109 * [91/03/11 rpd]
110 * Added kmem_realloc. Changed kmem_alloc, kmem_alloc_wired, and
111 * kmem_alloc_pageable to return error codes. Changed kmem_alloc
112 * to not use the kernel object and to not zero memory.
113 * Changed kmem_alloc_wired to use the kernel object.
114 * [91/03/07 16:49:52 rpd]
115 *
116 * Added resume, continuation arguments to vm_fault_page.
117 * Added continuation argument to VM_PAGE_WAIT.
118 * [91/02/05 rpd]
119 *
120 * Revision 2.12 91/02/05 17:58:22 mrt
121 * Changed to new Mach copyright
122 * [91/02/01 16:32:19 mrt]
123 *
124 * Revision 2.11 91/01/08 16:44:59 rpd
125 * Changed VM_WAIT to VM_PAGE_WAIT.
126 * [90/11/13 rpd]
127 *
128 * Revision 2.10 90/10/12 13:05:35 rpd
129 * Only activate the page returned by vm_fault_page if it isn't
130 * already on a pageout queue.
131 * [90/10/09 22:33:09 rpd]
132 *
133 * Revision 2.9 90/06/19 23:01:54 rpd
134 * Picked up vm_submap_object.
135 * [90/06/08 rpd]
136 *
137 * Revision 2.8 90/06/02 15:10:43 rpd
138 * Purged MACH_XP_FPD.
139 * [90/03/26 23:12:33 rpd]
140 *
141 * Revision 2.7 90/02/22 20:05:39 dbg
142 * Update to vm_map.h.
143 * Remove kmem_alloc_wait, kmem_free_wakeup, vm_move.
144 * Fix copy_user_to_physical_page to test for kernel tasks.
145 * Simplify v_to_p allocation.
146 * Change PAGE_WAKEUP to PAGE_WAKEUP_DONE to reflect the
147 * fact that it clears the busy flag.
148 * [90/01/25 dbg]
149 *
150 * Revision 2.6 90/01/22 23:09:12 af
151 * Undone VM_PROT_DEFAULT change, moved to vm_prot.h
152 * [90/01/20 17:28:57 af]
153 *
154 * Revision 2.5 90/01/19 14:35:57 rwd
155 * Get new version from rfr
156 * [90/01/10 rwd]
157 *
158 * Revision 2.4 90/01/11 11:47:44 dbg
159 * Remove kmem_mb_alloc and mb_map.
160 * [89/12/11 dbg]
161 *
162 * Revision 2.3 89/11/29 14:17:43 af
163 * Redefine VM_PROT_DEFAULT locally for mips.
164 * Might migrate in the final place sometimes.
165 *
166 * Revision 2.2 89/09/08 11:28:19 dbg
167 * Add special wiring code for IO memory.
168 * [89/08/10 dbg]
169 *
170 * Add keep_wired argument to vm_move.
171 * [89/07/14 dbg]
172 *
173 * 28-Apr-89 David Golub (dbg) at Carnegie-Mellon University
174 * Changes for MACH_KERNEL:
175 * . Optimize kmem_alloc. Add kmem_alloc_wired.
176 * . Remove non-MACH include files.
177 * . Change vm_move to call vm_map_move.
178 * . Clean up fast_pager_data option.
179 *
180 * Revision 2.14 89/04/22 15:35:28 gm0w
181 * Added code in kmem_mb_alloc to verify that requested allocation
182 * will fit in the map.
183 * [89/04/14 gm0w]
184 *
185 * Revision 2.13 89/04/18 21:25:45 mwyoung
186 * Recent history:
187 * Add call to vm_map_simplify to reduce kernel map fragmentation.
188 * History condensation:
189 * Added routines for copying user data to physical
190 * addresses. [rfr, mwyoung]
191 * Added routines for sleep/wakeup forms, interrupt-time
192 * allocation. [dbg]
193 * Created. [avie, mwyoung, dbg]
194 *
195 */
196 /*
197 * File: vm/vm_kern.c
198 * Author: Avadis Tevanian, Jr., Michael Wayne Young
199 * Date: 1985
200 *
201 * Kernel memory management.
202 */
203 #include <net_atm.h> /* projected buffers */
204
205 #include <mach/kern_return.h>
206 #include <mach/vm_param.h>
207 #include <kern/assert.h>
208 #include <kern/memory.h>
209 #include <kern/lock.h>
210 #include <kern/thread.h>
211 #include <vm/vm_fault.h>
212 #include <vm/vm_kern.h>
213 #include <vm/vm_map.h>
214 #include <vm/vm_object.h>
215 #include <vm/vm_page.h>
216 #include <vm/vm_pageout.h>
217
218
219
220 /*
221 * Variables exported by this module.
222 */
223
224 vm_map_t kernel_map;
225 vm_map_t kernel_pageable_map;
226
227 void kmem_alloc_pages(
228 vm_object_t object,
229 vm_offset_t offset,
230 vm_offset_t start,
231 vm_offset_t end,
232 vm_prot_t protection); /* forward */
233 void kmem_remap_pages(
234 vm_object_t object,
235 vm_offset_t offset,
236 vm_offset_t start,
237 vm_offset_t end,
238 vm_prot_t protection); /* forward */
239
240
241 #if NET_ATM
242 /*
243 * projected_buffer_allocate
244 *
245 * Allocate a wired-down buffer shared between kernel and user task.
246 * Fresh, zero-filled memory is allocated.
247 * If persistence is false, this buffer can only be deallocated from
248 * user task using projected_buffer_deallocate, and deallocation
249 * from user task also deallocates the buffer from the kernel map.
250 * projected_buffer_collect is called from vm_map_deallocate to
251 * automatically deallocate projected buffers on task_deallocate.
252 * Sharing with more than one user task is achieved by using
253 * projected_buffer_map for the second and subsequent tasks.
254 * The user is precluded from manipulating the VM entry of this buffer
255 * (i.e. changing protection, inheritance or machine attributes).
256 */
257
258 kern_return_t
259 projected_buffer_allocate(
260 vm_map_t map,
261 vm_size_t size,
262 int persistence,
263 vm_offset_t *kernel_p,
264 vm_offset_t *user_p,
265 vm_prot_t protection,
266 vm_inherit_t inheritance) /*Currently only VM_INHERIT_NONE supported*/
267 {
268 vm_object_t object;
269 vm_map_entry_t u_entry, k_entry;
270 vm_offset_t addr;
271 vm_size_t r_size;
272 kern_return_t kr;
273
274 if (map == VM_MAP_NULL || map == kernel_map)
275 return(KERN_INVALID_ARGUMENT);
276
277 /*
278 * Allocate a new object.
279 */
280
281 size = round_page(size);
282 object = vm_object_allocate(size);
283
284 vm_map_lock(kernel_map);
285 kr = vm_map_find_entry(kernel_map, &addr, size, (vm_offset_t) 0,
286 VM_OBJECT_NULL, &k_entry);
287 if (kr != KERN_SUCCESS) {
288 vm_map_unlock(kernel_map);
289 vm_object_deallocate(object);
290 return kr;
291 }
292
293 k_entry->object.vm_object = object;
294 if (!persistence)
295 k_entry->projected_on = (vm_map_entry_t) -1;
296 /*Mark entry so as to automatically deallocate it when
297 last corresponding user entry is deallocated*/
298 vm_map_unlock(kernel_map);
299 *kernel_p = addr;
300
301 vm_map_lock(map);
302 kr = vm_map_find_entry(map, &addr, size, (vm_offset_t) 0,
303 VM_OBJECT_NULL, &u_entry);
304 if (kr != KERN_SUCCESS) {
305 vm_map_unlock(map);
306 vm_map_lock(kernel_map);
307 vm_map_entry_delete(kernel_map, k_entry);
308 vm_map_unlock(kernel_map);
309 vm_object_deallocate(object);
310 return kr;
311 }
312
313 u_entry->object.vm_object = object;
314 vm_object_reference(object);
315 u_entry->projected_on = k_entry;
316 /*Creates coupling with kernel mapping of the buffer, and
317 also guarantees that user cannot directly manipulate
318 buffer VM entry*/
319 u_entry->protection = protection;
320 u_entry->max_protection = protection;
321 u_entry->inheritance = inheritance;
322 vm_map_unlock(map);
323 *user_p = addr;
324
325 /*
326 * Allocate wired-down memory in the object,
327 * and enter it in the kernel pmap.
328 */
329 kmem_alloc_pages(object, 0,
330 *kernel_p, *kernel_p + size,
331 VM_PROT_READ | VM_PROT_WRITE);
332 bzero(*kernel_p, size); /*Zero fill*/
333
334 /* Set up physical mappings for user pmap */
335
336 pmap_pageable(map->pmap, *user_p, *user_p + size, FALSE);
337 for (r_size = 0; r_size < size; r_size += PAGE_SIZE) {
338 addr = pmap_extract(kernel_pmap, *kernel_p + r_size);
339 pmap_enter(map->pmap, *user_p + r_size, addr,
340 protection, TRUE);
341 }
342
343 return(KERN_SUCCESS);
344 }
345
346
347 /*
348 * projected_buffer_map
349 *
350 * Map an area of kernel memory onto a task's address space.
351 * No new memory is allocated; the area must previously exist in the
352 * kernel memory map.
353 */
354
355 kern_return_t
356 projected_buffer_map(
357 vm_map_t map,
358 vm_offset_t kernel_addr,
359 vm_size_t size,
360 vm_offset_t *user_p,
361 vm_prot_t protection,
362 vm_inherit_t inheritance) /*Currently only VM_INHERIT_NONE supported*/
363 {
364 vm_object_t object;
365 vm_map_entry_t u_entry, k_entry;
366 vm_offset_t physical_addr, user_addr;
367 vm_size_t r_size;
368 kern_return_t kr;
369
370 /*
371 * Find entry in kernel map
372 */
373
374 size = round_page(size);
375 if (map == VM_MAP_NULL || map == kernel_map ||
376 !vm_map_lookup_entry(kernel_map, kernel_addr, &k_entry) ||
377 kernel_addr + size > k_entry->vme_end)
378 return(KERN_INVALID_ARGUMENT);
379
380
381 /*
382 * Create entry in user task
383 */
384
385 vm_map_lock(map);
386 kr = vm_map_find_entry(map, &user_addr, size, (vm_offset_t) 0,
387 VM_OBJECT_NULL, &u_entry);
388 if (kr != KERN_SUCCESS) {
389 vm_map_unlock(map);
390 return kr;
391 }
392
393 u_entry->object.vm_object = k_entry->object.vm_object;
394 vm_object_reference(k_entry->object.vm_object);
395 u_entry->offset = kernel_addr - k_entry->vme_start + k_entry->offset;
396 u_entry->projected_on = k_entry;
397 /*Creates coupling with kernel mapping of the buffer, and
398 also guarantees that user cannot directly manipulate
399 buffer VM entry*/
400 u_entry->protection = protection;
401 u_entry->max_protection = protection;
402 u_entry->inheritance = inheritance;
403 u_entry->wired_count = k_entry->wired_count;
404 vm_map_unlock(map);
405 *user_p = user_addr;
406
407 /* Set up physical mappings for user pmap */
408
409 pmap_pageable(map->pmap, user_addr, user_addr + size,
410 !k_entry->wired_count);
411 for (r_size = 0; r_size < size; r_size += PAGE_SIZE) {
412 physical_addr = pmap_extract(kernel_pmap, kernel_addr + r_size);
413 pmap_enter(map->pmap, user_addr + r_size, physical_addr,
414 protection, k_entry->wired_count);
415 }
416
417 return(KERN_SUCCESS);
418 }
419
420
421 /*
422 * projected_buffer_deallocate
423 *
424 * Unmap projected buffer from task's address space.
425 * May also unmap buffer from kernel map, if buffer is not
426 * persistent and only the kernel reference remains.
427 */
428
429 kern_return_t
430 projected_buffer_deallocate(
431 vm_map_t map,
432 vm_offset_t start,
433 vm_offset_t end)
434 {
435 vm_map_entry_t entry, k_entry;
436
437 vm_map_lock(map);
438 if (map == VM_MAP_NULL || map == kernel_map ||
439 !vm_map_lookup_entry(map, start, &entry) ||
440 end > entry->vme_end ||
441 /*Check corresponding kernel entry*/
442 (k_entry = entry->projected_on) == 0) {
443 vm_map_unlock(map);
444 return(KERN_INVALID_ARGUMENT);
445 }
446
447 /*Prepare for deallocation*/
448 if (entry->vme_start < start)
449 _vm_map_clip_start(map, entry, start);
450 if (entry->vme_end > end)
451 _vm_map_clip_end(map, entry, end);
452 if (map->first_free == entry) /*Adjust first_free hint*/
453 map->first_free = entry->vme_prev;
454 entry->projected_on = 0; /*Needed to allow deletion*/
455 entry->wired_count = 0; /*Avoid unwire fault*/
456 vm_map_entry_delete(map, entry);
457 vm_map_unlock(map);
458
459 /*Check if the buffer is not persistent and only the
460 kernel mapping remains, and if so delete it*/
461 vm_map_lock(kernel_map);
462 if (k_entry->projected_on == (vm_map_entry_t) -1 &&
463 k_entry->object.vm_object->ref_count == 1) {
464 if (kernel_map->first_free == k_entry)
465 kernel_map->first_free = k_entry->vme_prev;
466 k_entry->projected_on = 0; /*Allow unwire fault*/
467 vm_map_entry_delete(kernel_map, k_entry);
468 }
469 vm_map_unlock(kernel_map);
470 return(KERN_SUCCESS);
471 }
472
473
474 /*
475 * projected_buffer_collect
476 *
477 * Unmap all projected buffers from task's address space.
478 */
479
480 kern_return_t
481 projected_buffer_collect(
482 vm_map_t map)
483 {
484 vm_map_entry_t entry, next;
485
486 if (map == VM_MAP_NULL || map == kernel_map)
487 return(KERN_INVALID_ARGUMENT);
488
489 for (entry = vm_map_first_entry(map);
490 entry != vm_map_to_entry(map);
491 entry = next) {
492 next = entry->vme_next;
493 if (entry->projected_on != 0)
494 projected_buffer_deallocate(map, entry->vme_start, entry->vme_end);
495 }
496 return(KERN_SUCCESS);
497 }
498
499
500 /*
501 * projected_buffer_in_range
502 *
503 * Verifies whether a projected buffer exists in the address range
504 * given.
505 */
506
507 boolean_t
508 projected_buffer_in_range(
509 vm_map_t map,
510 vm_offset_t start,
511 vm_offset_t end)
512 {
513 vm_map_entry_t entry;
514
515 if (map == VM_MAP_NULL || map == kernel_map)
516 return(FALSE);
517
518 /*Find first entry*/
519 if (!vm_map_lookup_entry(map, start, &entry))
520 entry = entry->vme_next;
521
522 while (entry != vm_map_to_entry(map) && entry->projected_on == 0 &&
523 entry->vme_start <= end) {
524 entry = entry->vme_next;
525 }
526 return(entry != vm_map_to_entry(map) && entry->vme_start <= end);
527 }
528 #endif /* NET_ATM */
529
530 /*
531 * kmem_alloc:
532 *
533 * Allocate wired-down memory in the kernel's address map
534 * or a submap. The memory is not zero-filled.
535 */
536
537 kern_return_t
538 kmem_alloc(
539 vm_map_t map,
540 vm_offset_t *addrp,
541 vm_size_t size)
542 {
543 vm_object_t object;
544 vm_map_entry_t entry;
545 vm_offset_t addr;
546 kern_return_t kr;
547
548 /*
549 * Allocate a new object. We must do this before locking
550 * the map, lest we risk deadlock with the default pager:
551 * device_read_alloc uses kmem_alloc,
552 * which tries to allocate an object,
553 * which uses kmem_alloc_wired to get memory,
554 * which blocks for pages.
555 * then the default pager needs to read a block
556 * to process a memory_object_data_write,
557 * and device_read_alloc calls kmem_alloc
558 * and deadlocks on the map lock.
559 */
560
561 size = round_page(size);
562 object = vm_object_allocate(size);
563
564 vm_map_lock(map);
565 kr = vm_map_find_entry(map, &addr, size, (vm_offset_t) 0,
566 VM_OBJECT_NULL, &entry);
567 if (kr != KERN_SUCCESS) {
568 vm_map_unlock(map);
569 vm_object_deallocate(object);
570 return kr;
571 }
572
573 entry->object.vm_object = object;
574 entry->offset = 0;
575
576 /*
577 * Since we have not given out this address yet,
578 * it is safe to unlock the map.
579 */
580 vm_map_unlock(map);
581
582 /*
583 * Allocate wired-down memory in the kernel_object,
584 * for this entry, and enter it in the kernel pmap.
585 */
586 kmem_alloc_pages(object, 0,
587 addr, addr + size,
588 VM_PROT_DEFAULT);
589
590 /*
591 * Return the memory, not zeroed.
592 */
593 *addrp = addr;
594 return KERN_SUCCESS;
595 }
596
597 /*
598 * kmem_realloc:
599 *
600 * Reallocate wired-down memory in the kernel's address map
601 * or a submap. Newly allocated pages are not zeroed.
602 * This can only be used on regions allocated with kmem_alloc.
603 *
604 * If successful, the pages in the old region are mapped twice.
605 * The old region is unchanged. Use kmem_free to get rid of it.
606 */
607 kern_return_t kmem_realloc(
608 vm_map_t map,
609 vm_offset_t oldaddr,
610 vm_size_t oldsize,
611 vm_offset_t *newaddrp,
612 vm_size_t newsize)
613 {
614 vm_offset_t oldmin, oldmax;
615 vm_offset_t newaddr;
616 vm_object_t object;
617 vm_map_entry_t oldentry, newentry;
618 kern_return_t kr;
619
620 oldmin = trunc_page(oldaddr);
621 oldmax = round_page(oldaddr + oldsize);
622 oldsize = oldmax - oldmin;
623 newsize = round_page(newsize);
624
625 /*
626 * Find space for the new region.
627 */
628
629 vm_map_lock(map);
630 kr = vm_map_find_entry(map, &newaddr, newsize, (vm_offset_t) 0,
631 VM_OBJECT_NULL, &newentry);
632 if (kr != KERN_SUCCESS) {
633 vm_map_unlock(map);
634 return kr;
635 }
636
637 /*
638 * Find the VM object backing the old region.
639 */
640
641 if (!vm_map_lookup_entry(map, oldmin, &oldentry))
642 panic("kmem_realloc");
643 object = oldentry->object.vm_object;
644
645 /*
646 * Increase the size of the object and
647 * fill in the new region.
648 */
649
650 vm_object_reference(object);
651 vm_object_lock(object);
652 if (object->size != oldsize)
653 panic("kmem_realloc");
654 object->size = newsize;
655 vm_object_unlock(object);
656
657 newentry->object.vm_object = object;
658 newentry->offset = 0;
659
660 /*
661 * Since we have not given out this address yet,
662 * it is safe to unlock the map. We are trusting
663 * that nobody will play with either region.
664 */
665
666 vm_map_unlock(map);
667
668 /*
669 * Remap the pages in the old region and
670 * allocate more pages for the new region.
671 */
672
673 kmem_remap_pages(object, 0,
674 newaddr, newaddr + oldsize,
675 VM_PROT_DEFAULT);
676 kmem_alloc_pages(object, oldsize,
677 newaddr + oldsize, newaddr + newsize,
678 VM_PROT_DEFAULT);
679
680 *newaddrp = newaddr;
681 return KERN_SUCCESS;
682 }
683
684 /*
685 * kmem_alloc_wired:
686 *
687 * Allocate wired-down memory in the kernel's address map
688 * or a submap. The memory is not zero-filled.
689 *
690 * The memory is allocated in the kernel_object.
691 * It may not be copied with vm_map_copy, and
692 * it may not be reallocated with kmem_realloc.
693 */
694
695 kern_return_t
696 kmem_alloc_wired(
697 vm_map_t map,
698 vm_offset_t *addrp,
699 vm_size_t size)
700 {
701 vm_map_entry_t entry;
702 vm_offset_t offset;
703 vm_offset_t addr;
704 kern_return_t kr;
705
706 /*
707 * Use the kernel object for wired-down kernel pages.
708 * Assume that no region of the kernel object is
709 * referenced more than once. We want vm_map_find_entry
710 * to extend an existing entry if possible.
711 */
712
713 size = round_page(size);
714 vm_map_lock(map);
715 kr = vm_map_find_entry(map, &addr, size, (vm_offset_t) 0,
716 kernel_object, &entry);
717 if (kr != KERN_SUCCESS) {
718 vm_map_unlock(map);
719 return kr;
720 }
721
722 /*
723 * Since we didn't know where the new region would
724 * start, we couldn't supply the correct offset into
725 * the kernel object. We only initialize the entry
726 * if we aren't extending an existing entry.
727 */
728
729 offset = addr - VM_MIN_KERNEL_ADDRESS;
730
731 if (entry->object.vm_object == VM_OBJECT_NULL) {
732 vm_object_reference(kernel_object);
733
734 entry->object.vm_object = kernel_object;
735 entry->offset = offset;
736 }
737
738 /*
739 * Since we have not given out this address yet,
740 * it is safe to unlock the map.
741 */
742 vm_map_unlock(map);
743
744 /*
745 * Allocate wired-down memory in the kernel_object,
746 * for this entry, and enter it in the kernel pmap.
747 */
748 kmem_alloc_pages(kernel_object, offset,
749 addr, addr + size,
750 VM_PROT_DEFAULT);
751
752 /*
753 * Return the memory, not zeroed.
754 */
755 *addrp = addr;
756 return KERN_SUCCESS;
757 }
758
759 /*
760 * kmem_alloc_aligned:
761 *
762 * Like kmem_alloc_wired, except that the memory is aligned.
763 * The size should be a power-of-2.
764 */
765
766 kern_return_t
767 kmem_alloc_aligned(
768 vm_map_t map,
769 vm_offset_t *addrp,
770 vm_size_t size)
771 {
772 vm_map_entry_t entry;
773 vm_offset_t offset;
774 vm_offset_t addr;
775 kern_return_t kr;
776
777 if ((size & (size - 1)) != 0)
778 panic("kmem_alloc_aligned");
779
780 /*
781 * Use the kernel object for wired-down kernel pages.
782 * Assume that no region of the kernel object is
783 * referenced more than once. We want vm_map_find_entry
784 * to extend an existing entry if possible.
785 */
786
787 size = round_page(size);
788 vm_map_lock(map);
789 kr = vm_map_find_entry(map, &addr, size, size - 1,
790 kernel_object, &entry);
791 if (kr != KERN_SUCCESS) {
792 vm_map_unlock(map);
793 return kr;
794 }
795
796 /*
797 * Since we didn't know where the new region would
798 * start, we couldn't supply the correct offset into
799 * the kernel object. We only initialize the entry
800 * if we aren't extending an existing entry.
801 */
802
803 offset = addr - VM_MIN_KERNEL_ADDRESS;
804
805 if (entry->object.vm_object == VM_OBJECT_NULL) {
806 vm_object_reference(kernel_object);
807
808 entry->object.vm_object = kernel_object;
809 entry->offset = offset;
810 }
811
812 /*
813 * Since we have not given out this address yet,
814 * it is safe to unlock the map.
815 */
816 vm_map_unlock(map);
817
818 /*
819 * Allocate wired-down memory in the kernel_object,
820 * for this entry, and enter it in the kernel pmap.
821 */
822 kmem_alloc_pages(kernel_object, offset,
823 addr, addr + size,
824 VM_PROT_DEFAULT);
825
826 /*
827 * Return the memory, not zeroed.
828 */
829 *addrp = addr;
830 return KERN_SUCCESS;
831 }
832
833 /*
834 * kmem_alloc_pageable:
835 *
836 * Allocate pageable memory in the kernel's address map.
837 */
838
839 kern_return_t
840 kmem_alloc_pageable(
841 vm_map_t map,
842 vm_offset_t *addrp,
843 vm_size_t size)
844 {
845 vm_offset_t addr;
846 kern_return_t kr;
847
848 addr = vm_map_min(map);
849 kr = vm_map_enter(map, &addr, round_page(size),
850 (vm_offset_t) 0, TRUE,
851 VM_OBJECT_NULL, (vm_offset_t) 0, FALSE,
852 VM_PROT_DEFAULT, VM_PROT_ALL, VM_INHERIT_DEFAULT);
853 if (kr != KERN_SUCCESS)
854 return kr;
855
856 *addrp = addr;
857 return KERN_SUCCESS;
858 }
859
860 /*
861 * kmem_free:
862 *
863 * Release a region of kernel virtual memory allocated
864 * with kmem_alloc, kmem_alloc_wired, or kmem_alloc_pageable,
865 * and return the physical pages associated with that region.
866 */
867
868 void
869 kmem_free(
870 vm_map_t map,
871 vm_offset_t addr,
872 vm_size_t size)
873 {
874 kern_return_t kr;
875
876 kr = vm_map_remove(map, trunc_page(addr), round_page(addr + size));
877 if (kr != KERN_SUCCESS)
878 panic("kmem_free");
879 }
880
881 /*
882 * Allocate new wired pages in an object.
883 * The object is assumed to be mapped into the kernel map or
884 * a submap.
885 */
886 void
887 kmem_alloc_pages(
888 register vm_object_t object,
889 register vm_offset_t offset,
890 register vm_offset_t start,
891 register vm_offset_t end,
892 vm_prot_t protection)
893 {
894 /*
895 * Mark the pmap region as not pageable.
896 */
897 pmap_pageable(kernel_pmap, start, end, FALSE);
898
899 while (start < end) {
900 register vm_page_t mem;
901
902 vm_object_lock(object);
903
904 /*
905 * Allocate a page
906 */
907 while ((mem = vm_page_alloc(object, offset))
908 == VM_PAGE_NULL) {
909 vm_object_unlock(object);
910 VM_PAGE_WAIT(CONTINUE_NULL);
911 vm_object_lock(object);
912 }
913
914 /*
915 * Wire it down
916 */
917 vm_page_lock_queues();
918 vm_page_wire(mem);
919 vm_page_unlock_queues();
920 vm_object_unlock(object);
921
922 /*
923 * Enter it in the kernel pmap
924 */
925 PMAP_ENTER(kernel_pmap, start, mem,
926 protection, TRUE);
927
928 vm_object_lock(object);
929 PAGE_WAKEUP_DONE(mem);
930 vm_object_unlock(object);
931
932 start += PAGE_SIZE;
933 offset += PAGE_SIZE;
934 }
935 }
936
937 /*
938 * Remap wired pages in an object into a new region.
939 * The object is assumed to be mapped into the kernel map or
940 * a submap.
941 */
942 void
943 kmem_remap_pages(
944 register vm_object_t object,
945 register vm_offset_t offset,
946 register vm_offset_t start,
947 register vm_offset_t end,
948 vm_prot_t protection)
949 {
950 /*
951 * Mark the pmap region as not pageable.
952 */
953 pmap_pageable(kernel_pmap, start, end, FALSE);
954
955 while (start < end) {
956 register vm_page_t mem;
957
958 vm_object_lock(object);
959
960 /*
961 * Find a page
962 */
963 if ((mem = vm_page_lookup(object, offset)) == VM_PAGE_NULL)
964 panic("kmem_remap_pages");
965
966 /*
967 * Wire it down (again)
968 */
969 vm_page_lock_queues();
970 vm_page_wire(mem);
971 vm_page_unlock_queues();
972 vm_object_unlock(object);
973
974 /*
975 * Enter it in the kernel pmap. The page isn't busy,
976 * but this shouldn't be a problem because it is wired.
977 */
978 PMAP_ENTER(kernel_pmap, start, mem,
979 protection, TRUE);
980
981 start += PAGE_SIZE;
982 offset += PAGE_SIZE;
983 }
984 }
985
986 /*
987 * kmem_suballoc:
988 *
989 * Allocates a map to manage a subrange
990 * of the kernel virtual address space.
991 *
992 * Arguments are as follows:
993 *
994 * parent Map to take range from
995 * size Size of range to find
996 * min, max Returned endpoints of map
997 * pageable Can the region be paged
998 */
999
1000 vm_map_t
1001 kmem_suballoc(
1002 vm_map_t parent,
1003 vm_offset_t *min,
1004 vm_offset_t *max,
1005 vm_size_t size,
1006 boolean_t pageable)
1007 {
1008 vm_map_t map;
1009 vm_offset_t addr;
1010 kern_return_t kr;
1011
1012 size = round_page(size);
1013
1014 /*
1015 * Need reference on submap object because it is internal
1016 * to the vm_system. vm_object_enter will never be called
1017 * on it (usual source of reference for vm_map_enter).
1018 */
1019 vm_object_reference(vm_submap_object);
1020
1021 addr = (vm_offset_t) vm_map_min(parent);
1022 kr = vm_map_enter(parent, &addr, size,
1023 (vm_offset_t) 0, TRUE,
1024 vm_submap_object, (vm_offset_t) 0, FALSE,
1025 VM_PROT_DEFAULT, VM_PROT_ALL, VM_INHERIT_DEFAULT);
1026 if (kr != KERN_SUCCESS)
1027 panic("kmem_suballoc");
1028
1029 pmap_reference(vm_map_pmap(parent));
1030 map = vm_map_create(vm_map_pmap(parent), addr, addr + size, pageable);
1031 if (map == VM_MAP_NULL)
1032 panic("kmem_suballoc");
1033
1034 kr = vm_map_submap(parent, addr, addr + size, map);
1035 if (kr != KERN_SUCCESS)
1036 panic("kmem_suballoc");
1037
1038 *min = addr;
1039 *max = addr + size;
1040 return map;
1041 }
1042
1043 /*
1044 * kmem_init:
1045 *
1046 * Initialize the kernel's virtual memory map, taking
1047 * into account all memory allocated up to this time.
1048 */
1049 void kmem_init(
1050 vm_offset_t start,
1051 vm_offset_t end)
1052 {
1053 kernel_map = vm_map_create(pmap_kernel(),
1054 VM_MIN_KERNEL_ADDRESS, end,
1055 FALSE);
1056
1057 /*
1058 * Reserve virtual memory allocated up to this time.
1059 */
1060
1061 if (start != VM_MIN_KERNEL_ADDRESS) {
1062 vm_offset_t addr = VM_MIN_KERNEL_ADDRESS;
1063 (void) vm_map_enter(kernel_map,
1064 &addr, start - VM_MIN_KERNEL_ADDRESS,
1065 (vm_offset_t) 0, TRUE,
1066 VM_OBJECT_NULL, (vm_offset_t) 0, FALSE,
1067 VM_PROT_DEFAULT, VM_PROT_ALL,
1068 VM_INHERIT_DEFAULT);
1069 }
1070 }
1071
1072 /*
1073 * New and improved IO wiring support.
1074 */
1075
1076 /*
1077 * kmem_io_map_copyout:
1078 *
1079 * Establish temporary mapping in designated map for the memory
1080 * passed in. Memory format must be a page_list vm_map_copy.
1081 * Mapping is READ-ONLY.
1082 */
1083
1084 kern_return_t
1085 kmem_io_map_copyout(
1086 vm_map_t map,
1087 vm_offset_t *addr, /* actual addr of data */
1088 vm_offset_t *alloc_addr, /* page aligned addr */
1089 vm_size_t *alloc_size, /* size allocated */
1090 vm_map_copy_t copy,
1091 vm_size_t min_size) /* Do at least this much */
1092 {
1093 vm_offset_t myaddr, offset;
1094 vm_size_t mysize, copy_size;
1095 kern_return_t ret;
1096 register
1097 vm_page_t *page_list;
1098 vm_map_copy_t new_copy;
1099 register
1100 int i;
1101
1102 assert(copy->type == VM_MAP_COPY_PAGE_LIST);
1103 assert(min_size != 0);
1104
1105 /*
1106 * Figure out the size in vm pages.
1107 */
1108 min_size += copy->offset - trunc_page(copy->offset);
1109 min_size = round_page(min_size);
1110 mysize = round_page(copy->offset + copy->size) -
1111 trunc_page(copy->offset);
1112
1113 /*
1114 * If total size is larger than one page list and
1115 * we don't have to do more than one page list, then
1116 * only do one page list.
1117 *
1118 * XXX Could be much smarter about this ... like trimming length
1119 * XXX if we need more than one page list but not all of them.
1120 */
1121
1122 copy_size = ptoa(copy->cpy_npages);
1123 if (mysize > copy_size && copy_size > min_size)
1124 mysize = copy_size;
1125
1126 /*
1127 * Allocate some address space in the map (must be kernel
1128 * space).
1129 */
1130 myaddr = vm_map_min(map);
1131 ret = vm_map_enter(map, &myaddr, mysize,
1132 (vm_offset_t) 0, TRUE,
1133 VM_OBJECT_NULL, (vm_offset_t) 0, FALSE,
1134 VM_PROT_DEFAULT, VM_PROT_ALL, VM_INHERIT_DEFAULT);
1135
1136 if (ret != KERN_SUCCESS)
1137 return ret;
1138
1139 /*
1140 * Tell the pmap module that this will be wired, and
1141 * enter the mappings.
1142 */
1143 pmap_pageable(vm_map_pmap(map), myaddr, myaddr + mysize, TRUE);
1144
1145 *addr = myaddr + (copy->offset - trunc_page(copy->offset));
1146 *alloc_addr = myaddr;
1147 *alloc_size = mysize;
1148
1149 offset = myaddr;
1150 page_list = ©->cpy_page_list[0];
1151 while (TRUE) {
1152 for ( i = 0; i < copy->cpy_npages; i++, offset += PAGE_SIZE) {
1153 PMAP_ENTER(vm_map_pmap(map), offset, *page_list,
1154 VM_PROT_READ, TRUE);
1155 page_list++;
1156 }
1157
1158 if (offset == (myaddr + mysize))
1159 break;
1160
1161 /*
1162 * Onward to the next page_list. The extend_cont
1163 * leaves the current page list's pages alone;
1164 * they'll be cleaned up at discard. Reset this
1165 * copy's continuation to discard the next one.
1166 */
1167 vm_map_copy_invoke_extend_cont(copy, &new_copy, &ret);
1168
1169 if (ret != KERN_SUCCESS) {
1170 kmem_io_map_deallocate(map, myaddr, mysize);
1171 return ret;
1172 }
1173 copy->cpy_cont = vm_map_copy_discard_cont;
1174 copy->cpy_cont_args = (char *) new_copy;
1175 copy = new_copy;
1176 page_list = ©->cpy_page_list[0];
1177 }
1178
1179 return(ret);
1180 }
1181
1182 /*
1183 * kmem_io_map_deallocate:
1184 *
1185 * Get rid of the mapping established by kmem_io_map_copyout.
1186 * Assumes that addr and size have been rounded to page boundaries.
1187 * (e.g., the alloc_addr and alloc_size returned by kmem_io_map_copyout)
1188 */
1189
1190 void
1191 kmem_io_map_deallocate(
1192 vm_map_t map,
1193 vm_offset_t addr,
1194 vm_size_t size)
1195 {
1196 /*
1197 * Remove the mappings. The pmap_remove is needed.
1198 */
1199
1200 pmap_remove(vm_map_pmap(map), addr, addr + size);
1201 vm_map_remove(map, addr, addr + size);
1202 }
1203
1204 /*
1205 * Routine: copyinmap
1206 * Purpose:
1207 * Like copyin, except that fromaddr is an address
1208 * in the specified VM map. This implementation
1209 * is incomplete; it handles the current user map
1210 * and the kernel map/submaps.
1211 */
1212
1213 int copyinmap(
1214 vm_map_t map,
1215 void * fromaddr,
1216 void * *toaddr,
1217 unsigned int length)
1218 {
1219 if (vm_map_pmap(map) == kernel_pmap) {
1220 /* assume a correct copy */
1221 bcopy(fromaddr, toaddr, length);
1222 return 0;
1223 }
1224
1225 if (current_map() == map)
1226 return copyin( fromaddr, toaddr, length);
1227
1228 return 1;
1229 }
1230
1231 /*
1232 * Routine: copyoutmap
1233 * Purpose:
1234 * Like copyout, except that toaddr is an address
1235 * in the specified VM map. This implementation
1236 * is incomplete; it handles the current user map
1237 * and the kernel map/submaps.
1238 */
1239
1240 int copyoutmap(
1241 vm_map_t map,
1242 void * fromaddr,
1243 void * *toaddr,
1244 unsigned int length)
1245 {
1246 if (vm_map_pmap(map) == kernel_pmap) {
1247 /* assume a correct copy */
1248 bcopy(fromaddr, toaddr, length);
1249 return 0;
1250 }
1251
1252 if (current_map() == map)
1253 return copyout(fromaddr, toaddr, length);
1254
1255 return 1;
1256 }
Cache object: 4d7c237c2b7deb4278a0eed06df1be18
|