VirtualBox

Changeset 14825 in vbox for trunk/src/VBox/HostDrivers


Ignore:
Timestamp:
Nov 30, 2008 7:54:21 AM (16 years ago)
Author:
vboxsync
Message:

SUPDrv: Permit userland to make kernel mappings of SUPR0PageAllocEx allocations. (darwin + VGA + VT-x, #1865/#3202)

Location:
trunk/src/VBox/HostDrivers/Support
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/SUPDrv.c

    r14798 r14825  
    190190DECLASM(int)    UNWIND_WRAP(RTR0MemObjLockUser)(PRTR0MEMOBJ pMemObj, RTR3PTR R3Ptr, size_t cb, RTR0PROCESS R0Process);
    191191DECLASM(int)    UNWIND_WRAP(RTR0MemObjMapKernel)(PRTR0MEMOBJ pMemObj, RTR0MEMOBJ MemObjToMap, void *pvFixed, size_t uAlignment, unsigned fProt);
     192DECLASM(int)    UNWIND_WRAP(RTR0MemObjMapKernelEx)(PRTR0MEMOBJ pMemObj, RTR0MEMOBJ MemObjToMap, void *pvFixed, size_t uAlignment, unsigned fProt, size_t offSub, size_t cbSub);
    192193DECLASM(int)    UNWIND_WRAP(RTR0MemObjMapUser)(PRTR0MEMOBJ pMemObj, RTR0MEMOBJ MemObjToMap, RTR3PTR R3PtrFixed, size_t uAlignment, unsigned fProt, RTR0PROCESS R0Process);
    193194/*DECLASM(void *) UNWIND_WRAP(RTR0MemObjAddress)(RTR0MEMOBJ MemObj); - not necessary */
     
    325326    { "RTR0MemObjLockUser",                     (void *)UNWIND_WRAP(RTR0MemObjLockUser) },
    326327    { "RTR0MemObjMapKernel",                    (void *)UNWIND_WRAP(RTR0MemObjMapKernel) },
     328    { "RTR0MemObjMapKernelEx",                  (void *)UNWIND_WRAP(RTR0MemObjMapKernelEx) },
    327329    { "RTR0MemObjMapUser",                      (void *)UNWIND_WRAP(RTR0MemObjMapUser) },
    328330    { "RTR0MemObjAddress",                      (void *)RTR0MemObjAddress },
     
    781783                    pBundle->aMem[i].MapObjR3 = NIL_RTR0MEMOBJ;
    782784                }
    783                 rc = RTR0MemObjFree(pBundle->aMem[i].MemObj, false);
     785                rc = RTR0MemObjFree(pBundle->aMem[i].MemObj, true /* fFreeMappings */);
    784786                AssertRC(rc); /** @todo figure out how to handle this. */
    785787                pBundle->aMem[i].MemObj = NIL_RTR0MEMOBJ;
     
    14391441                                            pReq->u.In.fKernelMapping ? &pReq->u.Out.pvR0 : NULL,
    14401442                                            &pReq->u.Out.aPages[0]);
     1443            if (RT_FAILURE(pReq->Hdr.rc))
     1444                pReq->Hdr.cbOut = sizeof(pReq->Hdr);
     1445            return 0;
     1446        }
     1447
     1448        case SUP_CTL_CODE_NO_SIZE(SUP_IOCTL_PAGE_MAP_KERNEL):
     1449        {
     1450            /* validate */
     1451            PSUPPAGEMAPKERNEL pReq = (PSUPPAGEMAPKERNEL)pReqHdr;
     1452            REQ_CHECK_SIZES(SUP_IOCTL_PAGE_MAP_KERNEL);
     1453            REQ_CHECK_EXPR_FMT(!pReq->u.In.fFlags, ("SUP_IOCTL_PAGE_MAP_KERNEL: fFlags=%#x! MBZ\n", pReq->u.In.fFlags));
     1454            REQ_CHECK_EXPR_FMT(!(pReq->u.In.offSub & PAGE_OFFSET_MASK), ("SUP_IOCTL_PAGE_MAP_KERNEL: offSub=%#x\n", pReq->u.In.offSub));
     1455            REQ_CHECK_EXPR_FMT(pReq->u.In.cbSub && !(pReq->u.In.cbSub & PAGE_OFFSET_MASK),
     1456                               ("SUP_IOCTL_PAGE_MAP_KERNEL: cbSub=%#x\n", pReq->u.In.cbSub));
     1457
     1458            /* execute */
     1459            pReq->Hdr.rc = SUPR0PageMapKernel(pSession, pReq->u.In.pvR3, pReq->u.In.offSub, pReq->u.In.cbSub,
     1460                                              pReq->u.In.fFlags, &pReq->u.Out.pvR0);
    14411461            if (RT_FAILURE(pReq->Hdr.rc))
    14421462                pReq->Hdr.cbOut = sizeof(pReq->Hdr);
     
    22992319                return VINF_SUCCESS;
    23002320            }
     2321
    23012322            rc2 = RTR0MemObjFree(Mem.MapObjR3, false);
    23022323            AssertRC(rc2);
     
    24882509
    24892510
     2511/**
     2512 * Allocates a chunk of memory with a kernel or/and a user mode mapping.
     2513 *
     2514 * The memory is fixed and it's possible to query the physical addresses using
     2515 * SUPR0MemGetPhys().
     2516 *
     2517 * @returns IPRT status code.
     2518 * @param   pSession    The session to associated the allocation with.
     2519 * @param   cPages      The number of pages to allocate.
     2520 * @param   fFlags      Flags, reserved for the future. Must be zero.
     2521 * @param   ppvR3       Where to store the address of the Ring-3 mapping.
     2522 *                      NULL if no ring-3 mapping.
     2523 * @param   ppvR3       Where to store the address of the Ring-0 mapping.
     2524 *                      NULL if no ring-0 mapping.
     2525 * @param   paPages     Where to store the addresses of the pages. Optional.
     2526 */
     2527SUPR0DECL(int) SUPR0PageMapKernel(PSUPDRVSESSION pSession, RTR3PTR pvR3, uint32_t offSub, uint32_t cbSub,
     2528                                  uint32_t fFlags, PRTR0PTR ppvR0)
     2529{
     2530    int             rc;
     2531    PSUPDRVBUNDLE   pBundle;
     2532    RTSPINLOCKTMP   SpinlockTmp = RTSPINLOCKTMP_INITIALIZER;
     2533    RTR0MEMOBJ      hMemObj = NIL_RTR0MEMOBJ;
     2534    LogFlow(("SUPR0PageMapKernel: pSession=%p pvR3=%p offSub=%#x cbSub=%#x\n", pSession, pvR3, offSub, cbSub));
     2535
     2536    /*
     2537     * Validate input. The allowed allocation size must be at least equal to the maximum guest VRAM size.
     2538     */
     2539    AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER);
     2540SUPR0Printf("SUPR0PageMapKernel: 1\n");
     2541    AssertPtrNullReturn(ppvR0, VERR_INVALID_POINTER);
     2542    AssertReturn(!fFlags, VERR_INVALID_PARAMETER);
     2543SUPR0Printf("SUPR0PageMapKernel: 2\n");
     2544    AssertReturn(!(offSub & PAGE_OFFSET_MASK), VERR_INVALID_PARAMETER);
     2545SUPR0Printf("SUPR0PageMapKernel: 3\n");
     2546    AssertReturn(!(cbSub & PAGE_OFFSET_MASK), VERR_INVALID_PARAMETER);
     2547SUPR0Printf("SUPR0PageMapKernel: 4\n");
     2548    AssertReturn(cbSub, VERR_INVALID_PARAMETER);
     2549SUPR0Printf("SUPR0PageMapKernel: 5 - ok\n");
     2550
     2551    /*
     2552     * Find the memory object.
     2553     */
     2554    RTSpinlockAcquire(pSession->Spinlock, &SpinlockTmp);
     2555    for (pBundle = &pSession->Bundle; pBundle; pBundle = pBundle->pNext)
     2556    {
     2557        if (pBundle->cUsed > 0)
     2558        {
     2559            unsigned i;
     2560            for (i = 0; i < RT_ELEMENTS(pBundle->aMem); i++)
     2561            {
     2562                if (    (   pBundle->aMem[i].eType == MEMREF_TYPE_PAGE
     2563                         && pBundle->aMem[i].MemObj != NIL_RTR0MEMOBJ
     2564                         && pBundle->aMem[i].MapObjR3 != NIL_RTR0MEMOBJ
     2565                         && RTR0MemObjAddressR3(pBundle->aMem[i].MapObjR3) == pvR3)
     2566                    ||  (   pBundle->aMem[i].eType == MEMREF_TYPE_LOCKED
     2567                         && pBundle->aMem[i].MemObj != NIL_RTR0MEMOBJ
     2568                         && pBundle->aMem[i].MapObjR3 == NIL_RTR0MEMOBJ
     2569                         && RTR0MemObjAddressR3(pBundle->aMem[i].MemObj) == pvR3))
     2570                {
     2571                    hMemObj = pBundle->aMem[i].MemObj;
     2572                    break;
     2573                }
     2574            }
     2575        }
     2576    }
     2577    RTSpinlockRelease(pSession->Spinlock, &SpinlockTmp);
     2578SUPR0Printf("SUPR0PageMapKernel: hMemObj=%p\n", hMemObj);
     2579
     2580    rc = VERR_INVALID_PARAMETER;
     2581    if (hMemObj != NIL_RTR0MEMOBJ)
     2582    {
     2583        /*
     2584         * Do some furter input validations before calling IPRT.
     2585         * (Cleanup is done indirectly by telling RTR0MemObjFree to include mappings.)
     2586         */
     2587        size_t cbMemObj = RTR0MemObjSize(hMemObj);
     2588        if (    offSub < cbMemObj
     2589            &&  cbSub <= cbMemObj
     2590            &&  offSub + cbSub <= cbMemObj)
     2591        {
     2592            RTR0MEMOBJ hMapObj;
     2593SUPR0Printf("RTR0MemObjMapKernelEx: hMemObj=%p\n", hMemObj);
     2594            rc = RTR0MemObjMapKernelEx(&hMapObj, hMemObj, (void *)-1, 0,
     2595                                       RTMEM_PROT_READ | RTMEM_PROT_WRITE, offSub, cbSub);
     2596            if (RT_SUCCESS(rc))
     2597                *ppvR0 = RTR0MemObjAddress(hMapObj);
     2598        }
     2599        else
     2600            SUPR0Printf("SUPR0PageMapKernel: cbMemObj=%#x offSub=%#x cbSub=%#x\n", cbMemObj, offSub, cbSub);
     2601
     2602    }
     2603    return rc;
     2604}
     2605
     2606
     2607
    24902608#ifdef RT_OS_WINDOWS
    24912609/**
     
    30823200                    if (Mem.MemObj != NIL_RTR0MEMOBJ)
    30833201                    {
    3084                         int rc = RTR0MemObjFree(Mem.MemObj, false);
     3202                        int rc = RTR0MemObjFree(Mem.MemObj, true /* fFreeMappings */);
    30853203                        AssertRC(rc); /** @todo figure out how to handle this. */
    30863204                    }
  • trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h

    r14798 r14825  
    188188 *            and renaming the related IOCtls too.
    189189 */
    190 #define SUPDRV_IOC_VERSION                              0x000a0005
     190#define SUPDRV_IOC_VERSION                              0x000a0006
    191191
    192192/** SUP_IOCTL_COOKIE. */
     
    941941
    942942
     943/** @name SUP_IOCTL_PAGE_MAP_KERNEL
     944 * Maps a portion of memory allocated by SUP_IOCTL_PAGE_ALLOC_EX /
     945 * SUPR0PageAllocEx into kernel space for use by a device or similar.
     946 *
     947 * The mapping will be freed together with the ring-3 mapping when
     948 * SUP_IOCTL_PAGE_FREE or SUPR0PageFree is called.
     949 *
     950 * @remarks Not necessarily supported on all platforms.
     951 *
     952 * @{
     953 */
     954#define SUP_IOCTL_PAGE_MAP_KERNEL                     SUP_CTL_CODE_SIZE(24, SUP_IOCTL_PAGE_MAP_KERNEL_SIZE)
     955#define SUP_IOCTL_PAGE_MAP_KERNEL_SIZE                sizeof(SUPPAGEMAPKERNEL)
     956#define SUP_IOCTL_PAGE_MAP_KERNEL_SIZE_IN             sizeof(SUPPAGEMAPKERNEL)
     957#define SUP_IOCTL_PAGE_MAP_KERNEL_SIZE_OUT            sizeof(SUPPAGEMAPKERNEL)
     958typedef struct SUPPAGEMAPKERNEL
     959{
     960    /** The header. */
     961    SUPREQHDR               Hdr;
     962    union
     963    {
     964        struct
     965        {
     966            /** The pointer of to the previously allocated memory. */
     967            RTR3PTR         pvR3;
     968            /** The offset to start mapping from. */
     969            uint32_t        offSub;
     970            /** Size of the section to map. */
     971            uint32_t        cbSub;
     972            /** Flags reserved for future fun. */
     973            uint32_t        fFlags;
     974        } In;
     975        struct
     976        {
     977            /** The ring-0 address corresponding to pvR3 + offSub. */
     978            RTR0PTR         pvR0;
     979        } Out;
     980    } u;
     981} SUPPAGEMAPKERNEL, *PSUPPAGEMAPKERNEL;
     982/** @} */
     983
     984
    943985#pragma pack()                          /* paranoia */
    944986
  • trunk/src/VBox/HostDrivers/Support/SUPLib.cpp

    r14798 r14825  
    261261        CookieReq.u.In.u32ReqVersion = SUPDRV_IOC_VERSION;
    262262        const uint32_t MinVersion = (SUPDRV_IOC_VERSION & 0xffff0000) == 0x000a0000
    263                                   ? 0x000a0005
     263                                  ? 0x000a0006
    264264                                  :  SUPDRV_IOC_VERSION & 0xffff0000;
    265265        CookieReq.u.In.u32MinVersion = MinVersion;
     
    413413        { "RTR0MemObjGetPagePhysAddr",              0xefef0016 },
    414414        { "RTR0MemObjMapUser",                      0xefef0017 },
     415        { "RTR0MemObjMapKernel",                    0xefef0017 },
     416        { "RTR0MemObjMapKernelEx",                  0xefef0017 },
    415417        { "RTProcSelf",                             0xefef0038 },
    416418        { "RTR0ProcHandleSelf",                     0xefef0039 },
     
    10001002    return rc;
    10011003
     1004}
     1005
     1006
     1007SUPR3DECL(int) SUPR3PageMapKernel(void *pvR3, uint32_t off, uint32_t cb, uint32_t fFlags, PRTR0PTR pR0Ptr)
     1008{
     1009    /*
     1010     * Validate.
     1011     */
     1012    AssertPtrReturn(pvR3, VERR_INVALID_POINTER);
     1013    AssertPtrReturn(pR0Ptr, VERR_INVALID_POINTER);
     1014    Assert(!(off & PAGE_OFFSET_MASK));
     1015    Assert(!(cb & PAGE_OFFSET_MASK) && cb);
     1016    Assert(!fFlags);
     1017    *pR0Ptr = NIL_RTR0PTR;
     1018
     1019    /* fake */
     1020    if (RT_UNLIKELY(g_u32FakeMode))
     1021        return VERR_NOT_SUPPORTED;
     1022
     1023    /*
     1024     * Issue IOCtl to the SUPDRV kernel module.
     1025     */
     1026    SUPPAGEMAPKERNEL Req;
     1027    Req.Hdr.u32Cookie = g_u32Cookie;
     1028    Req.Hdr.u32SessionCookie = g_u32SessionCookie;
     1029    Req.Hdr.cbIn = SUP_IOCTL_PAGE_MAP_KERNEL_SIZE_IN;
     1030    Req.Hdr.cbOut = SUP_IOCTL_PAGE_MAP_KERNEL_SIZE_OUT;
     1031    Req.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT;
     1032    Req.Hdr.rc = VERR_INTERNAL_ERROR;
     1033    Req.u.In.pvR3 = pvR3;
     1034    Req.u.In.offSub = off;
     1035    Req.u.In.cbSub = cb;
     1036    Req.u.In.fFlags = fFlags;
     1037    int rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_PAGE_MAP_KERNEL, &Req, SUP_IOCTL_PAGE_MAP_KERNEL_SIZE);
     1038    if (RT_SUCCESS(rc))
     1039        rc = Req.Hdr.rc;
     1040    if (RT_SUCCESS(rc))
     1041        *pR0Ptr = Req.u.Out.pvR0;
     1042    return rc;
    10021043}
    10031044
  • trunk/src/VBox/HostDrivers/Support/win/SUPDrvA-win.asm

    r14497 r14825  
    8989NtWrapDyn2DrvFunctionWithAllRegParams  supdrvNtWrap, RTR0MemObjLockUser
    9090NtWrapDyn2DrvFunctionWith5Params       supdrvNtWrap, RTR0MemObjMapKernel
     91NtWrapDyn2DrvFunctionWith7Params       supdrvNtWrap, RTR0MemObjMapKernelEx
    9192NtWrapDyn2DrvFunctionWith6Params       supdrvNtWrap, RTR0MemObjMapUser
    9293;NtWrapDyn2DrvFunctionWithAllRegParams  supdrvNtWrap, RTR0MemObjAddress      - not necessary
Note: See TracChangeset for help on using the changeset viewer.

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