VirtualBox

source: vbox/trunk/src/VBox/Runtime/r0drv/freebsd/alloc-r0drv-freebsd.c@ 19975

Last change on this file since 19975 was 19761, checked in by vboxsync, 16 years ago

Fix allocating memory for code on FreeBSD AMD64. Strip debug symbols from the kernel driver because they cause warnings about unsupported relocation type 10 in the log

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.1 KB
Line 
1/* $Id: alloc-r0drv-freebsd.c 19761 2009-05-17 19:30:52Z vboxsync $ */
2/** @file
3 * IPRT - Memory Allocation, Ring-0 Driver, FreeBSD.
4 */
5
6/*
7 * Copyright (c) 2007 knut st. osmundsen <[email protected]>
8 *
9 * Permission is hereby granted, free of charge, to any person
10 * obtaining a copy of this software and associated documentation
11 * files (the "Software"), to deal in the Software without
12 * restriction, including without limitation the rights to use,
13 * copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following
16 * conditions:
17 *
18 * The above copyright notice and this permission notice shall be
19 * included in all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
23 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28 * OTHER DEALINGS IN THE SOFTWARE.
29 */
30
31/*******************************************************************************
32* Header Files *
33*******************************************************************************/
34#include "the-freebsd-kernel.h"
35
36#include <iprt/alloc.h>
37#include <iprt/assert.h>
38#include <iprt/param.h>
39
40#include "r0drv/alloc-r0drv.h"
41
42
43/*******************************************************************************
44* Global Variables *
45*******************************************************************************/
46/* These two statements will define two globals and add initializers
47 and destructors that will be called at load/unload time (I think). */
48MALLOC_DEFINE(M_IPRTHEAP, "iprtheap", "IPRT - heap");
49MALLOC_DEFINE(M_IPRTCONT, "iprtcont", "IPRT - contiguous");
50
51
52PRTMEMHDR rtMemAlloc(size_t cb, uint32_t fFlags)
53{
54 size_t cbAllocated = cb;
55 PRTMEMHDR pHdr = NULL;
56
57 /*
58 * Things are a bit more complicated on AMD64 for executable memory
59 * because we need to be in the ~2GB..~0 range for code.
60 */
61#ifdef RT_ARCH_AMD64
62 if (fFlags & RTMEMHDR_FLAG_EXEC)
63 {
64 vm_offset_t Addr = KERNBASE;
65 cbAllocated = RT_ALIGN_Z(cb + sizeof(*pHdr), PAGE_SIZE);
66
67 /* Addr contains a start address vm_map_find will start searching for suitable space at. */
68 int rc = vm_map_find(kernel_map, NULL, 0, &Addr,
69 cbAllocated,
70 TRUE, VM_PROT_ALL, VM_PROT_ALL, 0);
71 if (rc == KERN_SUCCESS)
72 {
73 /* Add the pages. */
74 vm_offset_t AddressDst = Addr;
75 bool fSuccess = true;
76
77 do
78 {
79 vm_pindex_t PageIndex = OFF_TO_IDX(AddressDst);
80 vm_page_t pPage;
81
82 pPage = vm_page_alloc(NULL, PageIndex,
83 VM_ALLOC_NOBUSY | VM_ALLOC_SYSTEM |
84 VM_ALLOC_WIRED | VM_ALLOC_NOOBJ);
85 if (pPage)
86 {
87 vm_page_lock_queues();
88 vm_page_wire(pPage);
89 vm_page_unlock_queues();
90 /* Put the page into the page table now. */
91#if __FreeBSD_version >= 701105
92 pmap_enter(kernel_map->pmap, AddressDst, VM_PROT_NONE, pPage,
93 VM_PROT_ALL, TRUE);
94#else
95 pmap_enter(kernel_map->pmap, AddressDst, pPage,
96 VM_PROT_ALL, TRUE);
97#endif
98 }
99 else
100 {
101 /*
102 * Allocation failed. vm_map_remove will remove any
103 * page already allocated.
104 */
105 fSuccess = false;
106 break;
107 }
108 AddressDst += PAGE_SIZE;
109 } while(AddressDst < (Addr + cbAllocated));
110
111 if (fSuccess)
112 {
113 pHdr = (PRTMEMHDR)Addr;
114
115 if (fFlags & RTMEMHDR_FLAG_ZEROED)
116 bzero(pHdr, cbAllocated);
117 }
118 else
119 vm_map_remove(kernel_map,
120 Addr,
121 Addr + cb);
122 }
123 }
124 else
125#endif
126 {
127 pHdr = (PRTMEMHDR)malloc(cb + sizeof(RTMEMHDR), M_IPRTHEAP,
128 fFlags & RTMEMHDR_FLAG_ZEROED ? M_NOWAIT | M_ZERO : M_NOWAIT);
129 }
130
131 if (pHdr)
132 {
133 pHdr->u32Magic = RTMEMHDR_MAGIC;
134 pHdr->fFlags = fFlags;
135 pHdr->cb = cbAllocated;
136 pHdr->cbReq = cb;
137 return pHdr;
138 }
139 return NULL;
140}
141
142
143void rtMemFree(PRTMEMHDR pHdr)
144{
145 pHdr->u32Magic += 1;
146
147#ifdef RT_ARCH_AMD64
148 if (pHdr->fFlags & RTMEMHDR_FLAG_EXEC)
149 vm_map_remove(kernel_map, (vm_offset_t)pHdr, ((vm_offset_t)pHdr) + pHdr->cb);
150 else
151#endif
152 free(pHdr, M_IPRTHEAP);
153}
154
155
156RTR0DECL(void *) RTMemContAlloc(PRTCCPHYS pPhys, size_t cb)
157{
158 void *pv;
159
160 /*
161 * Validate input.
162 */
163 AssertPtr(pPhys);
164 Assert(cb > 0);
165
166 /*
167 * This API works in pages, so no need to do any size aligning.
168 */
169 pv = contigmalloc(cb, /* size */
170 M_IPRTCONT, /* type */
171 M_NOWAIT | M_ZERO, /* flags */
172 0, /* lowest physical address*/
173 _4G-1, /* highest physical address */
174 PAGE_SIZE, /* alignment. */
175 0); /* boundrary */
176 if (pv)
177 {
178 Assert(!((uintptr_t)pv & PAGE_OFFSET_MASK));
179 *pPhys = vtophys(pv);
180 Assert(!(*pPhys & PAGE_OFFSET_MASK));
181 }
182 return pv;
183}
184
185
186RTR0DECL(void) RTMemContFree(void *pv, size_t cb)
187{
188 if (pv)
189 {
190 AssertMsg(!((uintptr_t)pv & PAGE_OFFSET_MASK), ("pv=%p\n", pv));
191 contigfree(pv, cb, M_IPRTCONT);
192 }
193}
194
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette