2 * Copyright (c) 2017-2018 François Tigeot <ftigeot@wolfpond.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice unmodified, this list of conditions, and the following
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include <sys/_null.h>
28 #include <sys/queue.h>
29 #include <vm/vm_extern.h>
31 #include <linux/vmalloc.h>
32 #include <linux/slab.h>
38 SLIST_ENTRY(vmap
) vm_vmaps
;
41 SLIST_HEAD(vmap_list_head
, vmap
) vmap_list
= SLIST_HEAD_INITIALIZER(vmap_list
);
43 /* vmap: map an array of pages into virtually contiguous space */
45 vmap(struct page
**pages
, unsigned int count
,
46 unsigned long flags
, unsigned long prot
)
52 vmp
= kmalloc(sizeof(struct vmap
), M_DRM
, M_WAITOK
| M_ZERO
);
54 size
= count
* PAGE_SIZE
;
55 off
= kmem_alloc_nofault(&kernel_map
, size
,
56 VM_SUBSYS_DRM_VMAP
, PAGE_SIZE
);
60 vmp
->addr
= (void *)off
;
62 pmap_qenter(off
, (struct vm_page
**)pages
, count
);
63 SLIST_INSERT_HEAD(&vmap_list
, vmp
, vm_vmaps
);
69 vunmap(const void *addr
)
71 struct vmap
*vmp
, *tmp_vmp
;
74 SLIST_FOREACH_MUTABLE(vmp
, &vmap_list
, vm_vmaps
, tmp_vmp
) {
75 if (vmp
->addr
== addr
) {
76 size
= vmp
->npages
* PAGE_SIZE
;
78 pmap_qremove((vm_offset_t
)addr
, vmp
->npages
);
79 kmem_free(&kernel_map
, (vm_offset_t
)addr
, size
);
85 SLIST_REMOVE(&vmap_list
, vmp
, vmap
, vm_vmaps
);
90 is_vmalloc_addr(const void *x
)
92 struct vmap
*vmp
, *tmp_vmp
;
94 SLIST_FOREACH_MUTABLE(vmp
, &vmap_list
, vm_vmaps
, tmp_vmp
) {
102 /* allocate zeroed virtually contiguous memory for userspace */
104 vmalloc_user(unsigned long size
)
106 return kmalloc(size
, M_DRM
, M_WAITOK
| M_ZERO
);
110 vfree(const void *addr
)
114 memcpy(&nc_addr
, &addr
, sizeof(void *));