Changeset 35294 in vbox for trunk/src/VBox/Runtime
- Timestamp:
- Dec 22, 2010 12:13:10 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r0drv/linux/alloc-r0drv-linux.c
r32708 r35294 58 58 *******************************************************************************/ 59 59 #ifdef RTMEMALLOC_EXEC_HEAP 60 61 # ifdef CONFIG_DEBUG_SET_MODULE_RONX 62 # define RTMEMALLOC_EXEC_HEAP_VM_AREA 1 63 # endif 60 64 /** The heap. */ 61 65 static RTHEAPSIMPLE g_HeapExec = NIL_RTHEAPSIMPLE; 62 66 /** Spinlock protecting the heap. */ 63 67 static RTSPINLOCK g_HeapExecSpinlock = NIL_RTSPINLOCK; 68 # ifdef RTMEMALLOC_EXEC_HEAP_VM_AREA 69 static struct page **g_apPages; 70 static void *g_pvHeap; 71 static size_t g_cPages; 72 # endif 64 73 65 74 … … 70 79 void rtR0MemExecCleanup(void) 71 80 { 81 # ifdef RTMEMALLOC_EXEC_HEAP_VM_AREA 82 unsigned i; 83 84 /* according to linux/drivers/lguest/core.c this function undoes 85 * map_vm_area() as well as __get_vm_area(). */ 86 if (g_pvHeap) 87 vunmap(g_pvHeap); 88 for (i = 0; i < g_cPages; i++) 89 __free_page(g_apPages[i]); 90 kfree(g_apPages); 91 # endif 92 72 93 RTSpinlockDestroy(g_HeapExecSpinlock); 73 94 g_HeapExecSpinlock = NIL_RTSPINLOCK; … … 75 96 76 97 98 # ifndef RTMEMALLOC_EXEC_HEAP_VM_AREA 77 99 /** 78 100 * Donate read+write+execute memory to the exec heap. … … 105 127 } 106 128 RT_EXPORT_SYMBOL(RTR0MemExecDonate); 129 130 # else /* !RTMEMALLOC_EXEC_HEAP_VM_AREA */ 131 132 /** 133 * RTR0MemExecDonate() does not work if CONFIG_DEBUG_SET_MODULE_RONX is enabled. 134 * In that case, allocate a VM area in the modules range and back it with kernel 135 * memory. Unfortunately __vmalloc_area() is not exported so we have to emulate 136 * it. 137 */ 138 RTR0DECL(int) RTR0MemExecInit(size_t cb) 139 { 140 int rc; 141 struct vm_struct *area; 142 size_t cPages; 143 size_t cbPages; 144 unsigned i; 145 struct page **ppPages; 146 147 AssertReturn(g_HeapExec == NIL_RTHEAPSIMPLE, VERR_WRONG_ORDER); 148 149 rc = RTSpinlockCreate(&g_HeapExecSpinlock); 150 if (RT_SUCCESS(rc)) 151 { 152 cb = RT_ALIGN(cb, PAGE_SIZE); 153 area = __get_vm_area(cb, VM_ALLOC, MODULES_VADDR, MODULES_END); 154 if (!area) 155 { 156 rtR0MemExecCleanup(); 157 return VERR_NO_MEMORY; 158 } 159 g_pvHeap = area->addr; 160 cPages = cb >> PAGE_SHIFT; 161 area->nr_pages = 0; 162 cbPages = cPages * sizeof(struct page *); 163 g_apPages = kmalloc(cbPages, GFP_KERNEL); 164 area->pages = g_apPages; 165 if (!g_apPages) 166 { 167 rtR0MemExecCleanup(); 168 return VERR_NO_MEMORY; 169 } 170 memset(area->pages, 0, cbPages); 171 for (i = 0; i < cPages; i++) 172 { 173 g_apPages[i] = alloc_page(GFP_KERNEL | __GFP_HIGHMEM); 174 if (!g_apPages[i]) 175 { 176 area->nr_pages = i; 177 g_cPages = i; 178 rtR0MemExecCleanup(); 179 return VERR_NO_MEMORY; 180 } 181 } 182 area->nr_pages = cPages; 183 g_cPages = i; 184 ppPages = g_apPages; 185 if (map_vm_area(area, PAGE_KERNEL_EXEC, &ppPages)) 186 { 187 rtR0MemExecCleanup(); 188 return VERR_NO_MEMORY; 189 } 190 191 rc = RTHeapSimpleInit(&g_HeapExec, g_pvHeap, cb); 192 if (RT_FAILURE(rc)) 193 rtR0MemExecCleanup(); 194 } 195 return rc; 196 } 197 RT_EXPORT_SYMBOL(RTR0MemExecInit); 198 # endif /* RTMEMALLOC_EXEC_HEAP_VM_AREA */ 107 199 #endif /* RTMEMALLOC_EXEC_HEAP */ 108 200
Note:
See TracChangeset
for help on using the changeset viewer.