Changeset 1890 in vbox for trunk/src/VBox/HostDrivers/Support/linux/SUPLib-linux.cpp
- Timestamp:
- Apr 3, 2007 4:04:19 PM (18 years ago)
- svn:sync-xref-src-repo-rev:
- 20136
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/linux/SUPLib-linux.cpp
r1 r1890 27 27 #include <sys/fcntl.h> 28 28 #include <sys/ioctl.h> 29 #include <sys/mman.h> 29 30 #include <errno.h> 30 31 #include <unistd.h> … … 35 36 #include <VBox/sup.h> 36 37 #include <VBox/types.h> 38 #include <VBox/log.h> 37 39 #include <iprt/path.h> 38 40 #include <iprt/assert.h> … … 49 51 #define DEVICE_NAME "/dev/vboxdrv" 50 52 53 #ifndef MADV_DONTFORK 54 #define MADV_DONTFORK 10 55 #endif 51 56 52 57 … … 58 63 /** Flags whether or not we've loaded the kernel module. */ 59 64 static bool g_fLoadedModule = false; 65 /** Checks */ 66 static bool g_fSysMadviseWorks = false; 60 67 61 68 … … 125 132 126 133 /* 134 * Check if madvise works. 135 */ 136 void *pv = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 137 if (!pv) 138 return VERR_NO_MEMORY; 139 g_fSysMadviseWorks = (0 == madvise(pv, PAGE_SIZE, MADV_DONTFORK)); 140 munmap(pv, PAGE_SIZE); 141 142 /* 127 143 * We're done. 128 144 */ … … 249 265 return RTErrConvertFromErrno(rc); 250 266 #else 251 *ppvPages = memalign(PAGE_SIZE, cPages << PAGE_SHIFT); 252 if (*ppvPages) 253 { 267 size_t cbMmap = (g_fSysMadviseWorks ? cPages : cPages + 2) << PAGE_SHIFT; 268 char *pvPages = (char*)mmap(NULL, cbMmap, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 269 if (pvPages) 270 { 271 if (g_fSysMadviseWorks) 272 { 273 /* 274 * It is not fatal if we fail here but a forked child (e.g. the ALSA sound server) 275 * could crash. Linux < 2.6.16 does not implement madvise(MADV_DONTFORK) but the 276 * kernel seems to split bigger VMAs and that is all that we want -- later we set the 277 * VM_DONTCOPY attribute in supdrvOSLockMemOne(). 278 */ 279 if (madvise (pvPages, cbMmap, MADV_DONTFORK)) 280 LogRel(("SUPLib: madvise %p-%p failed\n", pvPages, cbMmap)); 281 *ppvPages = pvPages; 282 } 283 else 284 { 285 /* 286 * madvise(MADV_DONTFORK) is not available (most probably Linux 2.4). Enclose any 287 * mmapped region by two unmapped pages to guarantee that there is exactly one VM 288 * area struct of the very same size as the mmap area. 289 */ 290 mprotect(pvPages, PAGE_SIZE, PROT_NONE); 291 mprotect(pvPages + cbMmap - PAGE_SIZE, PAGE_SIZE, PROT_NONE); 292 *ppvPages = pvPages + PAGE_SIZE; 293 } 254 294 memset(*ppvPages, 0, cPages << PAGE_SHIFT); 255 295 return VINF_SUCCESS; … … 266 306 * @param pvPages Pointer to pages. 267 307 */ 268 int suplibOsPageFree(void *pvPages )269 { 270 free(pvPages);308 int suplibOsPageFree(void *pvPages, size_t cPages) 309 { 310 munmap(pvPages, cPages << PAGE_SHIFT); 271 311 return VINF_SUCCESS; 272 312 } 273 274 275 276 277
Note:
See TracChangeset
for help on using the changeset viewer.