Changeset 4817 in vbox for trunk/src/VBox/HostDrivers/Support/darwin
- Timestamp:
- Sep 14, 2007 8:14:53 PM (18 years ago)
- svn:sync-xref-src-repo-rev:
- 24524
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp
r4800 r4817 20 20 * Header Files * 21 21 *******************************************************************************/ 22 /* Deal with conflicts first. 23 * (This is mess inherited from BSD. The *BSDs has clean this up long ago.) */ 22 /* 23 * Deal with conflicts first. 24 * PVM - BSD mess, that FreeBSD has correct a long time ago. 25 * iprt/types.h before sys/param.h - prevents UINT32_C and friends. 26 */ 27 #include <iprt/types.h> 24 28 #include <sys/param.h> 25 29 #undef PVM 30 26 31 #include <IOKit/IOLib.h> /* Assert as function */ 27 32 28 33 #include "SUPDRV.h" 29 34 #include <VBox/version.h> 30 #include <iprt/types.h>31 35 #include <iprt/initterm.h> 32 36 #include <iprt/assert.h> … … 60 64 *******************************************************************************/ 61 65 __BEGIN_DECLS 62 static kern_return_t VBox SupDrvStart(struct kmod_info *pKModInfo, void *pvData);63 static kern_return_t VBox SupDrvStop(struct kmod_info *pKModInfo, void *pvData);64 65 static int VBox SupDrvOpen(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess);66 static int VBox SupDrvClose(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess);67 static int VBox SupDrvIOCtl(dev_t Dev, u_long iCmd, caddr_t pData, int fFlags, struct proc *pProcess);68 static int VBox SupDrvIOCtlSlow(PSUPDRVSESSION pSession, u_long iCmd, caddr_t pData, struct proc *pProcess);69 70 static int VBox SupDrvErr2DarwinErr(int rc);66 static kern_return_t VBoxDrvDarwinStart(struct kmod_info *pKModInfo, void *pvData); 67 static kern_return_t VBoxDrvDarwinStop(struct kmod_info *pKModInfo, void *pvData); 68 69 static int VBoxDrvDarwinOpen(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess); 70 static int VBoxDrvDarwinClose(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess); 71 static int VBoxDrvDarwinIOCtl(dev_t Dev, u_long iCmd, caddr_t pData, int fFlags, struct proc *pProcess); 72 static int VBoxDrvDarwinIOCtlSlow(PSUPDRVSESSION pSession, u_long iCmd, caddr_t pData, struct proc *pProcess); 73 74 static int VBoxDrvDarwinErr2DarwinErr(int rc); 71 75 __END_DECLS 72 76 … … 136 140 137 141 KMOD_EXPLICIT_DECL(VBoxDrv, VBOX_VERSION_STRING, _start, _stop) 138 kmod_start_func_t *_realmain = VBox SupDrvStart;139 kmod_stop_func_t *_antimain = VBox SupDrvStop;142 kmod_start_func_t *_realmain = VBoxDrvDarwinStart; 143 kmod_stop_func_t *_antimain = VBoxDrvDarwinStop; 140 144 int _kext_apple_cc = __APPLE_CC__; 141 145 __END_DECLS … … 153 157 { 154 158 /** @todo g++ doesn't like this syntax - it worked with gcc before renaming to .cpp. */ 155 /*.d_open = */VBox SupDrvOpen,156 /*.d_close = */VBox SupDrvClose,159 /*.d_open = */VBoxDrvDarwinOpen, 160 /*.d_close = */VBoxDrvDarwinClose, 157 161 /*.d_read = */eno_rdwrt, 158 162 /*.d_write = */eno_rdwrt, 159 /*.d_ioctl = */VBox SupDrvIOCtl,163 /*.d_ioctl = */VBoxDrvDarwinIOCtl, 160 164 /*.d_stop = */eno_stop, 161 165 /*.d_reset = */eno_reset, … … 185 189 * Start the kernel module. 186 190 */ 187 static kern_return_t VBox SupDrvStart(struct kmod_info *pKModInfo, void *pvData)191 static kern_return_t VBoxDrvDarwinStart(struct kmod_info *pKModInfo, void *pvData) 188 192 { 189 193 int rc; 190 dprintf(("VBox SupDrvStart\n"));194 dprintf(("VBoxDrvDarwinStart\n")); 191 195 192 196 /* … … 253 257 * Stop the kernel module. 254 258 */ 255 static kern_return_t VBox SupDrvStop(struct kmod_info *pKModInfo, void *pvData)259 static kern_return_t VBoxDrvDarwinStop(struct kmod_info *pKModInfo, void *pvData) 256 260 { 257 261 int rc; 258 dprintf(("VBox SupDrvStop\n"));262 dprintf(("VBoxDrvDarwinStop\n")); 259 263 260 264 /** @todo I've got a nagging feeling that we'll have to keep track of users and refuse … … 280 284 281 285 memset(&g_DevExt, 0, sizeof(g_DevExt)); 282 dprintf(("VBox SupDrvStop - done\n"));286 dprintf(("VBoxDrvDarwinStop - done\n")); 283 287 return KMOD_RETURN_SUCCESS; 284 288 } … … 291 295 * @param pFilp Associated file pointer. 292 296 */ 293 static int VBox SupDrvOpen(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess)297 static int VBoxDrvDarwinOpen(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess) 294 298 { 295 299 int rc; … … 299 303 szName[0] = '\0'; 300 304 proc_name(proc_pid(pProcess), szName, sizeof(szName)); 301 dprintf(("VBox SupDrvOpen: pid=%d '%s'\n", proc_pid(pProcess), szName));305 dprintf(("VBoxDrvDarwinOpen: pid=%d '%s'\n", proc_pid(pProcess), szName)); 302 306 #endif 303 307 … … 330 334 331 335 #ifdef DEBUG_DARWIN_GIP 332 OSDBGPRINT(("VBox SupDrvOpen: pid=%d '%s' pSession=%p rc=%d\n", proc_pid(pProcess), szName, pSession, rc));336 OSDBGPRINT(("VBoxDrvDarwinOpen: pid=%d '%s' pSession=%p rc=%d\n", proc_pid(pProcess), szName, pSession, rc)); 333 337 #else 334 dprintf(("VBox SupDrvOpen: g_DevExt=%p pSession=%p rc=%d pid=%d\n", &g_DevExt, pSession, rc, proc_pid(pProcess)));338 dprintf(("VBoxDrvDarwinOpen: g_DevExt=%p pSession=%p rc=%d pid=%d\n", &g_DevExt, pSession, rc, proc_pid(pProcess))); 335 339 #endif 336 return VBox SupDrvErr2DarwinErr(rc);340 return VBoxDrvDarwinErr2DarwinErr(rc); 337 341 } 338 342 … … 341 345 * Close device. 342 346 */ 343 static int VBox SupDrvClose(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess)347 static int VBoxDrvDarwinClose(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess) 344 348 { 345 349 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; … … 348 352 PSUPDRVSESSION pSession; 349 353 350 dprintf(("VBox SupDrvClose: pid=%d\n", (int)Process));354 dprintf(("VBoxDrvDarwinClose: pid=%d\n", (int)Process)); 351 355 352 356 /* … … 384 388 if (!pSession) 385 389 { 386 OSDBGPRINT(("VBox SupDrvClose: WHAT?!? pSession == NULL! This must be a mistake... pid=%d (close)\n",390 OSDBGPRINT(("VBoxDrvDarwinClose: WHAT?!? pSession == NULL! This must be a mistake... pid=%d (close)\n", 387 391 (int)Process)); 388 392 return EINVAL; … … 407 411 * @param pProcess The process issuing this request. 408 412 */ 409 static int VBox SupDrvIOCtl(dev_t Dev, u_long iCmd, caddr_t pData, int fFlags, struct proc *pProcess)413 static int VBoxDrvDarwinIOCtl(dev_t Dev, u_long iCmd, caddr_t pData, int fFlags, struct proc *pProcess) 410 414 { 411 415 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; … … 427 431 if (!pSession) 428 432 { 429 OSDBGPRINT(("VBox SupDrvIOCtl: WHAT?!? pSession == NULL! This must be a mistake... pid=%d iCmd=%#x\n",433 OSDBGPRINT(("VBoxDrvDarwinIOCtl: WHAT?!? pSession == NULL! This must be a mistake... pid=%d iCmd=%#x\n", 430 434 (int)Process, iCmd)); 431 435 return EINVAL; … … 440 444 || iCmd == SUP_IOCTL_FAST_DO_NOP) 441 445 return supdrvIOCtlFast(iCmd, &g_DevExt, pSession); 442 return VBox SupDrvIOCtlSlow(pSession, iCmd, pData, pProcess);443 } 444 445 446 /** 447 * Worker for VBox SupDrvIOCtl that takes the slow IOCtl functions.446 return VBoxDrvDarwinIOCtlSlow(pSession, iCmd, pData, pProcess); 447 } 448 449 450 /** 451 * Worker for VBoxDrvDarwinIOCtl that takes the slow IOCtl functions. 448 452 * 449 453 * @returns Darwin errno. … … 454 458 * @param pProcess The calling process. 455 459 */ 456 static int VBoxSupDrvIOCtlSlow(PSUPDRVSESSION pSession, u_long iCmd, caddr_t pData, struct proc *pProcess) 457 { 458 int rc; 459 void *pvPageBuf = NULL; 460 void *pvBuf = NULL; 461 unsigned long cbBuf = 0; 462 unsigned cbOut = 0; 463 PSUPDRVIOCTLDATA pArgs = (PSUPDRVIOCTLDATA)pData; 464 dprintf(("VBoxSupDrvIOCtlSlow: pSession=%p iCmd=%p pData=%p pProcess=%p\n", pSession, iCmd, pData, pProcess)); 465 466 /* 467 * Copy ioctl data structure from user space. 468 */ 469 if (IOCPARM_LEN(iCmd) != sizeof(SUPDRVIOCTLDATA)) 470 { 471 dprintf(("VBoxSupDrvIOCtlSlow: incorrect input length! cbArgs=%d\n", IOCPARM_LEN(iCmd))); 472 return EINVAL; 473 } 474 475 /* 476 * Allocate and copy user space input data buffer to kernel space. 477 */ 478 if (pArgs->cbIn > 0 || pArgs->cbOut > 0) 479 { 480 cbBuf = max(pArgs->cbIn, pArgs->cbOut); 481 pvBuf = RTMemTmpAlloc(cbBuf); 482 if (pvBuf == NULL) 483 pvPageBuf = pvBuf = IOMallocAligned(cbBuf, 8); 484 if (pvBuf == NULL) 485 { 486 dprintf(("VBoxSupDrvIOCtlSlow: failed to allocate buffer of %d bytes.\n", cbBuf)); 460 static int VBoxDrvDarwinIOCtlSlow(PSUPDRVSESSION pSession, u_long iCmd, caddr_t pData, struct proc *pProcess) 461 { 462 dprintf(("VBoxDrvDarwinIOCtlSlow: pSession=%p iCmd=%p pData=%p pProcess=%p\n", pSession, iCmd, pData, pProcess)); 463 464 465 /* 466 * Buffered or unbuffered? 467 */ 468 void *pvPageBuf = NULL; 469 PSUPREQHDR pHdr; 470 uint32_t cb = IOCPARM_LEN(iCmd); 471 if (cb) 472 { 473 pHdr = (PSUPREQHDR)pData; 474 if (RT_UNLIKELY(cb < sizeof(*pHdr))) 475 { 476 OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: cb=%#x < %#x; iCmd=%#lx\n", cb, (int)sizeof(*pHdr), iCmd)); 477 return EINVAL; 478 } 479 if (RT_UNLIKELY((pHdr->fFlags & SUPREQHDR_FLAGS_MAGIC_MASK) != SUPREQHDR_FLAGS_MAGIC)) 480 { 481 OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: bad magic fFlags=%#x; iCmd=%#lx\n", pHdr->fFlags, iCmd)); 482 return EINVAL; 483 } 484 if (RT_UNLIKELY(RT_MAX(pHdr->cbIn, pHdr->cbOut) != cb)) 485 { 486 OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: max(%#x,%#x) != %#x; iCmd=%#lx\n", pHdr->cbIn, pHdr->cbOut, cb, iCmd)); 487 return EINVAL; 488 } 489 } 490 else 491 { 492 /* 493 * Get the header and figure out how much we're gonna have to read. 494 */ 495 SUPREQHDR Hdr; 496 int rc = copyin((const user_addr_t)pData, &Hdr, sizeof(Hdr)); 497 if (RT_UNLIKELY(rc)) 498 { 499 OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: copyin(%lx,Hdr,) -> %#x; iCmd=%#lx\n", pData, rc, iCmd)); 500 return rc; 501 } 502 if (RT_UNLIKELY((Hdr.fFlags & SUPREQHDR_FLAGS_MAGIC_MASK) != SUPREQHDR_FLAGS_MAGIC)) 503 { 504 OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: bad magic fFlags=%#x; iCmd=%#lx\n", Hdr.fFlags, iCmd)); 505 return EINVAL; 506 } 507 cb = RT_MAX(Hdr.cbIn, Hdr.cbOut); 508 if (RT_UNLIKELY(cb < sizeof(Hdr) || cb > _1M*16)) 509 { 510 OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: max(%#x,%#x); iCmd=%#lx\n", Hdr.cbIn, Hdr.cbOut, iCmd)); 511 return EINVAL; 512 } 513 514 /* 515 * Allocate buffer and copy in the data. 516 */ 517 pHdr = (PSUPREQHDR)RTMemTmpAlloc(cb); 518 if (!pHdr) 519 pvPageBuf = pHdr = (PSUPREQHDR)IOMallocAligned(RT_ALIGN_Z(cb, PAGE_SIZE), 8); 520 if (RT_UNLIKELY(!pHdr)) 521 { 522 OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: failed to allocate buffer of %d bytes; iCmd=%#lx\n", cb, iCmd)); 487 523 return ENOMEM; 488 524 } 489 rc = copyin((const user_addr_t)p Args->pvIn, pvBuf, pArgs->cbIn);490 if ( rc)491 { 492 dprintf(("VBoxSupDrvIOCtlSlow: copyin(%p,,%d) failed.\n", pArgs->pvIn, cbBuf));525 rc = copyin((const user_addr_t)pData, pHdr, Hdr.cbIn); 526 if (RT_UNLIKELY(rc)) 527 { 528 OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: copyin(%lx,,%#x) -> %#x; iCmd=%#lx\n", pData, Hdr.cbIn, rc, iCmd)); 493 529 if (pvPageBuf) 494 IOFreeAligned(pvPageBuf, cbBuf);530 IOFreeAligned(pvPageBuf, RT_ALIGN_Z(cb, PAGE_SIZE)); 495 531 else 496 RTMemTmpFree(p vBuf);532 RTMemTmpFree(pHdr); 497 533 return rc; 498 534 } … … 502 538 * Process the IOCtl. 503 539 */ 504 rc = supdrvIOCtl(iCmd, &g_DevExt, pSession, 505 pvBuf, pArgs->cbIn, pvBuf, pArgs->cbOut, &cbOut); 506 507 /* 508 * Copy ioctl data and output buffer back to user space. 509 */ 510 if (rc) 511 { 512 dprintf(("VBoxSupDrvIOCtlSlow: pid=%d iCmd=%x pData=%p failed, rc=%d (darwin rc=%d)\n", 513 proc_pid(pProcess), iCmd, (void *)pData, rc, VBoxSupDrvErr2DarwinErr(rc))); 514 rc = VBoxSupDrvErr2DarwinErr(rc); 515 } 516 else if (cbOut > 0) 517 { 518 if (pvBuf != NULL && cbOut <= cbBuf) 519 { 520 int rc2 = copyout(pvBuf, (user_addr_t)pArgs->pvOut, cbOut); 521 if (rc2) 540 int rc = supdrvIOCtl(iCmd, &g_DevExt, pSession, pHdr); 541 if (RT_LIKELY(!rc)) 542 { 543 /* 544 * If not buffered, copy back the buffer before returning. 545 */ 546 if (!IOCPARM_LEN(iCmd)) 547 { 548 uint32_t cbOut = pHdr->cbOut; 549 if (cbOut > cb) 522 550 { 523 dprintf(("VBoxSupDrvIOCtlSlow: copyout(,%p,%d) failed.\n", pArgs->pvOut, cbBuf));524 rc = rc2;551 OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: too much output! %#x > %#x; uCmd=%#lx!\n", cbOut, cb, iCmd)); 552 cbOut = cb; 525 553 } 526 } 527 else 528 { 529 dprintf(("WHAT!?! supdrvIOCtl messed up! cbOut=%d cbBuf=%d pvBuf=%p\n", cbOut, cbBuf, pvBuf)); 530 rc = EPERM; 531 } 532 } 533 534 if (pvPageBuf) 535 IOFreeAligned(pvPageBuf, cbBuf); 536 else if (pvBuf) 537 RTMemTmpFree(pvBuf); 538 539 dprintf2(("VBoxSupDrvIOCtlSlow: returns %d\n", rc)); 554 rc = copyout(pHdr, (user_addr_t)pData, cbOut); 555 if (RT_UNLIKELY(rc)) 556 OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: copyout(,%p,%#x) -> %d; uCmd=%#lx!\n", pData, cbOut, rc, iCmd)); 557 558 /* cleanup */ 559 if (pvPageBuf) 560 IOFreeAligned(pvPageBuf, RT_ALIGN_Z(cb, PAGE_SIZE)); 561 else 562 RTMemTmpFree(pHdr); 563 } 564 } 565 else 566 { 567 /* 568 * The request failed, just clean up. 569 */ 570 if (!IOCPARM_LEN(iCmd)) 571 { 572 if (pvPageBuf) 573 IOFreeAligned(pvPageBuf, RT_ALIGN_Z(cb, PAGE_SIZE)); 574 else 575 RTMemTmpFree(pHdr); 576 } 577 578 dprintf(("VBoxDrvDarwinIOCtlSlow: pid=%d iCmd=%lx pData=%p failed, rc=%d\n", proc_pid(pProcess), iCmd, (void *)pData, rc)); 579 rc = EINVAL; 580 } 581 582 dprintf2(("VBoxDrvDarwinIOCtlSlow: returns %d\n", rc)); 540 583 return rc; 541 584 } … … 580 623 * @param rc supdrv error code (SUPDRV_ERR_* defines). 581 624 */ 582 static int VBox SupDrvErr2DarwinErr(int rc)625 static int VBoxDrvDarwinErr2DarwinErr(int rc) 583 626 { 584 627 switch (rc)
Note:
See TracChangeset
for help on using the changeset viewer.