VirtualBox

Changeset 97046 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Oct 7, 2022 12:57:59 PM (2 years ago)
Author:
vboxsync
Message:

Devices/DrvIntNet,NetworkServices,Installer/darwin: First rough attempt at making the internal networking option work on macOS after all KEXTs got removed, bugref:10297

Location:
trunk/src/VBox/Devices
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Makefile.kmk

    r96910 r97046  
    172172        VBOX_WITH_DMI_OEMSTRINGS \
    173173        $(if $(VBOX_WITH_IOMMU_AMD),VBOX_WITH_IOMMU_AMD,) \
    174         $(if $(VBOX_WITH_IOMMU_INTEL),VBOX_WITH_IOMMU_INTEL,)
     174        $(if $(VBOX_WITH_IOMMU_INTEL),VBOX_WITH_IOMMU_INTEL,) \
     175        $(if $(VBOX_WITH_INTNET_SERVICE_IN_R3),VBOX_WITH_INTNET_SERVICE_IN_R3,)
    175176 VBoxDD_DEFS.win         = _WIN32_WINNT=0x0510
    176177 ifeq ($(KBUILD_TARGET_ARCH),x86)
  • trunk/src/VBox/Devices/Network/DrvIntNet.cpp

    r96407 r97046  
    3131*********************************************************************************************************************************/
    3232#define LOG_GROUP LOG_GROUP_DRV_INTNET
     33#if defined(RT_OS_DARWIN) && defined(VBOX_WITH_INTNET_SERVICE_IN_R3)
     34# include <xpc/xpc.h> /* This needs to be here because it drags PVM in and cdefs.h needs to undefine it... */
     35#endif
     36#include <iprt/cdefs.h>
     37
    3338#include <VBox/vmm/pdmdrv.h>
    3439#include <VBox/vmm/pdmnetinline.h>
     
    195200    uint64_t                        u64LastReceiveTS;
    196201#endif
     202#if defined(RT_OS_DARWIN) && defined(VBOX_WITH_INTNET_SERVICE_IN_R3)
     203    /** XPC connection handle to the R3 internal network switch service. */
     204    xpc_connection_t                hXpcCon;
     205    /** Flag whether the R3 internal network service is being used. */
     206    bool                            fIntNetR3Svc;
     207    /** Size of the communication buffer in bytes. */
     208    size_t                          cbBuf;
     209#endif
    197210} DRVINTNET;
    198211AssertCompileMemberAlignment(DRVINTNET, XmitLock, 8);
     
    219232
    220233/**
     234 * Calls the internal networking switch service living in either R0 or in another R3 process.
     235 *
     236 * @returns VBox status code.
     237 * @param   pThis           The internal network driver instance data.
     238 * @param   uOperation      The operation to execute.
     239 * @param   pvArg           Pointer to the argument data.
     240 * @param   cbArg           Size of the argument data in bytes.
     241 */
     242static int drvR3IntNetCallSvc(PDRVINTNET pThis, uint32_t uOperation, void *pvArg, unsigned cbArg)
     243{
     244#if defined(RT_OS_DARWIN) && defined(VBOX_WITH_INTNET_SERVICE_IN_R3)
     245    if (pThis->fIntNetR3Svc)
     246    {
     247        xpc_object_t hObj = xpc_dictionary_create_empty();
     248        xpc_dictionary_set_uint64(hObj, "req-id", uOperation);
     249        xpc_dictionary_set_data(hObj, "req", pvArg, cbArg);
     250        xpc_object_t hObjReply = xpc_connection_send_message_with_reply_sync(pThis->hXpcCon, hObj);
     251        int rc = (int)xpc_dictionary_get_int64(hObjReply, "rc");
     252
     253        size_t cbReply = 0;
     254        const void *pvData = xpc_dictionary_get_data(hObjReply, "reply", &cbReply);
     255        AssertRelease(cbReply == cbArg);
     256        memcpy(pvArg, pvData, cbArg);
     257        xpc_release(hObjReply);
     258
     259        return rc;
     260    }
     261    else
     262#endif
     263        return PDMDrvHlpSUPCallVMMR0Ex(pThis->pDrvInsR3, uOperation, pvArg, cbArg);
     264}
     265
     266
     267/**
     268 * Calls the internal networking switch service living in either R0 or in another R3 process.
     269 *
     270 * @returns VBox status code.
     271 * @param   pThis           The internal network driver instance data.
     272 * @param   uOperation      The operation to execute.
     273 * @param   pvArg           Pointer to the argument data.
     274 * @param   cbArg           Size of the argument data in bytes.
     275 */
     276static int drvR3IntNetCallSvcAsync(PDRVINTNET pThis, uint32_t uOperation, void *pvArg, unsigned cbArg)
     277{
     278#if defined(RT_OS_DARWIN) && defined(VBOX_WITH_INTNET_SERVICE_IN_R3)
     279    if (pThis->fIntNetR3Svc)
     280    {
     281        xpc_object_t hObj = xpc_dictionary_create_empty();
     282        xpc_dictionary_set_uint64(hObj, "req-id", uOperation);
     283        xpc_dictionary_set_data(hObj, "req", pvArg, cbArg);
     284        xpc_connection_send_message(pThis->hXpcCon, hObj);
     285        return VINF_SUCCESS;
     286    }
     287    else
     288#endif
     289        return PDMDrvHlpSUPCallVMMR0Ex(pThis->pDrvInsR3, uOperation, pvArg, cbArg);
     290}
     291
     292
     293/**
     294 * Map the ring buffer pointer into this process R3 address space.
     295 *
     296 * @returns VBox status code.
     297 * @param   pThis           The internal network driver instance data.
     298 */
     299static int drvR3IntNetMapBufferPointers(PDRVINTNET pThis)
     300{
     301    int rc = VINF_SUCCESS;
     302
     303    INTNETIFGETBUFFERPTRSREQ GetBufferPtrsReq;
     304    GetBufferPtrsReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
     305    GetBufferPtrsReq.Hdr.cbReq = sizeof(GetBufferPtrsReq);
     306    GetBufferPtrsReq.pSession = NIL_RTR0PTR;
     307    GetBufferPtrsReq.hIf = pThis->hIf;
     308    GetBufferPtrsReq.pRing3Buf = NULL;
     309    GetBufferPtrsReq.pRing0Buf = NIL_RTR0PTR;
     310
     311#if defined(RT_OS_DARWIN) && defined(VBOX_WITH_INTNET_SERVICE_IN_R3)
     312    if (pThis->fIntNetR3Svc)
     313    {
     314        xpc_object_t hObj = xpc_dictionary_create_empty();
     315        xpc_dictionary_set_uint64(hObj, "req-id", VMMR0_DO_INTNET_IF_GET_BUFFER_PTRS);
     316        xpc_dictionary_set_data(hObj, "req", &GetBufferPtrsReq, sizeof(GetBufferPtrsReq));
     317        xpc_object_t hObjReply = xpc_connection_send_message_with_reply_sync(pThis->hXpcCon, hObj);
     318        rc = (int)xpc_dictionary_get_int64(hObjReply, "rc");
     319        if (RT_SUCCESS(rc))
     320        {
     321            /* Get the shared memory object. */
     322            xpc_object_t hObjShMem = xpc_dictionary_get_value(hObjReply, "buf-ptr");
     323            size_t cbMem = xpc_shmem_map(hObjShMem, (void **)&pThis->pBufR3);
     324            if (!cbMem)
     325                rc = VERR_NO_MEMORY;
     326            else
     327                pThis->cbBuf = cbMem;
     328        }
     329        xpc_release(hObjReply);
     330    }
     331    else
     332#endif
     333    {
     334        rc = PDMDrvHlpSUPCallVMMR0Ex(pThis->pDrvInsR3, VMMR0_DO_INTNET_IF_GET_BUFFER_PTRS, &GetBufferPtrsReq, sizeof(GetBufferPtrsReq));
     335        if (RT_SUCCESS(rc))
     336        {
     337            AssertRelease(RT_VALID_PTR(GetBufferPtrsReq.pRing3Buf));
     338            pThis->pBufR3 = GetBufferPtrsReq.pRing3Buf;
     339#ifdef VBOX_WITH_DRVINTNET_IN_R0
     340            pThis->pBufR0 = GetBufferPtrsReq.pRing0Buf;
     341#endif
     342        }
     343    }
     344
     345    return rc;
     346}
     347
     348
     349/**
    221350 * Updates the MAC address on the kernel side.
    222351 *
     
    236365    int rc = pThis->pIAboveConfigR3->pfnGetMac(pThis->pIAboveConfigR3, &SetMacAddressReq.Mac);
    237366    if (RT_SUCCESS(rc))
    238         rc = PDMDrvHlpSUPCallVMMR0Ex(pThis->pDrvInsR3, VMMR0_DO_INTNET_IF_SET_MAC_ADDRESS,
    239                                      &SetMacAddressReq, sizeof(SetMacAddressReq));
     367        rc = drvR3IntNetCallSvc(pThis, VMMR0_DO_INTNET_IF_SET_MAC_ADDRESS,
     368                                &SetMacAddressReq, sizeof(SetMacAddressReq));
    240369
    241370    Log(("drvR3IntNetUpdateMacAddress: %.*Rhxs rc=%Rrc\n", sizeof(SetMacAddressReq.Mac), &SetMacAddressReq.Mac, rc));
     
    264393    SetActiveReq.hIf = pThis->hIf;
    265394    SetActiveReq.fActive = fActive;
    266     int rc = PDMDrvHlpSUPCallVMMR0Ex(pThis->pDrvInsR3, VMMR0_DO_INTNET_IF_SET_ACTIVE,
    267                                      &SetActiveReq, sizeof(SetActiveReq));
     395    int rc = drvR3IntNetCallSvc(pThis, VMMR0_DO_INTNET_IF_SET_ACTIVE,
     396                                &SetActiveReq, sizeof(SetActiveReq));
    268397
    269398    Log(("drvR3IntNetSetActive: fActive=%d rc=%Rrc\n", fActive, rc));
     
    314443    SendReq.pSession = NIL_RTR0PTR;
    315444    SendReq.hIf = pThis->hIf;
    316     int rc = PDMDrvHlpSUPCallVMMR0Ex(pThis->pDrvInsR3, VMMR0_DO_INTNET_IF_SEND, &SendReq, sizeof(SendReq));
     445    int rc = drvR3IntNetCallSvc(pThis, VMMR0_DO_INTNET_IF_SEND, &SendReq, sizeof(SendReq));
    317446#else
    318447    int rc = IntNetR0IfSend(pThis->hIf, pThis->pSupDrvSession);
     
    560689    Req.hIf             = pThis->hIf;
    561690    Req.fPromiscuous    = fPromiscuous;
    562     int rc = PDMDrvHlpSUPCallVMMR0Ex(pThis->pDrvInsR3, VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE, &Req, sizeof(Req));
     691    int rc = drvR3IntNetCallSvc(pThis, VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE, &Req, sizeof(Req));
    563692#else  /* IN_RING0 */
    564693    int rc = IntNetR0IfSetPromiscuousMode(pThis->hIf, pThis->pSupDrvSession, fPromiscuous);
     
    692821static int drvR3IntNetRecvRun(PDRVINTNET pThis)
    693822{
    694     PPDMDRVINS pDrvIns = pThis->pDrvInsR3;
    695823    LogFlow(("drvR3IntNetRecvRun: pThis=%p\n", pThis));
    696824
     
    869997        WaitReq.cMillies     = 30000; /* 30s - don't wait forever, timeout now and then. */
    870998        STAM_PROFILE_ADV_STOP(&pThis->StatReceive, a);
    871         int rc = PDMDrvHlpSUPCallVMMR0Ex(pDrvIns, VMMR0_DO_INTNET_IF_WAIT, &WaitReq, sizeof(WaitReq));
    872         if (    RT_FAILURE(rc)
    873             &&  rc != VERR_TIMEOUT
    874             &&  rc != VERR_INTERRUPTED)
     999
     1000#if defined(RT_OS_DARWIN) && defined(VBOX_WITH_INTNET_SERVICE_IN_R3)
     1001        if (pThis->fIntNetR3Svc)
    8751002        {
    876             LogFlow(("drvR3IntNetRecvRun: returns %Rrc\n", rc));
    877             return rc;
     1003            /* Send an asynchronous message. */
     1004            int rc = drvR3IntNetCallSvcAsync(pThis, VMMR0_DO_INTNET_IF_WAIT, &WaitReq, sizeof(WaitReq));
     1005            if (RT_SUCCESS(rc))
     1006            {
     1007                /* Wait on the receive semaphore. */
     1008                rc = RTSemEventWait(pThis->hRecvEvt, 30 * RT_MS_1SEC);
     1009                if (    RT_FAILURE(rc)
     1010                    &&  rc != VERR_TIMEOUT
     1011                    &&  rc != VERR_INTERRUPTED)
     1012                {
     1013                    LogFlow(("drvR3IntNetRecvRun: returns %Rrc\n", rc));
     1014                    return rc;
     1015                }
     1016            }
     1017        }
     1018        else
     1019#endif
     1020        {
     1021            int rc = PDMDrvHlpSUPCallVMMR0Ex(pThis->pDrvInsR3, VMMR0_DO_INTNET_IF_WAIT, &WaitReq, sizeof(WaitReq));
     1022            if (    RT_FAILURE(rc)
     1023                &&  rc != VERR_TIMEOUT
     1024                &&  rc != VERR_INTERRUPTED)
     1025            {
     1026                LogFlow(("drvR3IntNetRecvRun: returns %Rrc\n", rc));
     1027                return rc;
     1028            }
    8781029        }
    8791030        STAM_PROFILE_ADV_START(&pThis->StatReceive, a);
     
    10291180        SendReq.pSession = NIL_RTR0PTR;
    10301181        SendReq.hIf = pThis->hIf;
    1031         PDMDrvHlpSUPCallVMMR0Ex(pThis->pDrvInsR3, VMMR0_DO_INTNET_IF_SEND, &SendReq, sizeof(SendReq));
     1182        drvR3IntNetCallSvc(pThis, VMMR0_DO_INTNET_IF_SEND, &SendReq, sizeof(SendReq));
    10321183
    10331184        rc = IntNetRingWriteFrame(&pThis->pBufR3->Send, pvBuf, (uint32_t)cb);
     
    10411192        SendReq.pSession = NIL_RTR0PTR;
    10421193        SendReq.hIf = pThis->hIf;
    1043         rc = PDMDrvHlpSUPCallVMMR0Ex(pThis->pDrvInsR3, VMMR0_DO_INTNET_IF_SEND, &SendReq, sizeof(SendReq));
     1194        rc = drvR3IntNetCallSvc(pThis, VMMR0_DO_INTNET_IF_SEND, &SendReq, sizeof(SendReq));
    10441195    }
    10451196
     
    12011352    if (pThis->hIf != INTNET_HANDLE_INVALID)
    12021353    {
    1203         INTNETIFABORTWAITREQ AbortWaitReq;
    1204         AbortWaitReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
    1205         AbortWaitReq.Hdr.cbReq    = sizeof(AbortWaitReq);
    1206         AbortWaitReq.pSession     = NIL_RTR0PTR;
    1207         AbortWaitReq.hIf          = pThis->hIf;
    1208         AbortWaitReq.fNoMoreWaits = true;
    1209         int rc = PDMDrvHlpSUPCallVMMR0Ex(pDrvIns, VMMR0_DO_INTNET_IF_ABORT_WAIT, &AbortWaitReq, sizeof(AbortWaitReq));
    1210         AssertMsg(RT_SUCCESS(rc) || rc == VERR_SEM_DESTROYED, ("%Rrc\n", rc)); RT_NOREF_PV(rc);
     1354#if defined(RT_OS_DARWIN) && defined(VBOX_WITH_INTNET_SERVICE_IN_R3)
     1355        if (!pThis->fIntNetR3Svc) /* The R3 service case is handled b the hRecEvt event semaphore. */
     1356#endif
     1357        {
     1358            INTNETIFABORTWAITREQ AbortWaitReq;
     1359            AbortWaitReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
     1360            AbortWaitReq.Hdr.cbReq    = sizeof(AbortWaitReq);
     1361            AbortWaitReq.pSession     = NIL_RTR0PTR;
     1362            AbortWaitReq.hIf          = pThis->hIf;
     1363            AbortWaitReq.fNoMoreWaits = true;
     1364            int rc = drvR3IntNetCallSvc(pThis, VMMR0_DO_INTNET_IF_ABORT_WAIT, &AbortWaitReq, sizeof(AbortWaitReq));
     1365            AssertMsg(RT_SUCCESS(rc) || rc == VERR_SEM_DESTROYED, ("%Rrc\n", rc)); RT_NOREF_PV(rc);
     1366        }
    12111367    }
    12121368
     
    12701426        CloseReq.hIf = pThis->hIf;
    12711427        pThis->hIf = INTNET_HANDLE_INVALID;
    1272         int rc = PDMDrvHlpSUPCallVMMR0Ex(pDrvIns, VMMR0_DO_INTNET_IF_CLOSE, &CloseReq, sizeof(CloseReq));
     1428        int rc = drvR3IntNetCallSvc(pThis, VMMR0_DO_INTNET_IF_CLOSE, &CloseReq, sizeof(CloseReq));
    12731429        AssertRC(rc);
    12741430    }
    12751431
     1432#if defined(RT_OS_DARWIN) && defined(VBOX_WITH_INTNET_SERVICE_IN_R3)
     1433    if (pThis->fIntNetR3Svc)
     1434    {
     1435        /* Unmap the shared buffer. */
     1436        munmap(pThis->pBufR3, pThis->cbBuf);
     1437        xpc_connection_cancel(pThis->hXpcCon);
     1438        pThis->fIntNetR3Svc = false;
     1439        pThis->hXpcCon      = NULL;
     1440    }
     1441#endif
    12761442
    12771443    /*
     
    17651931     * Create the interface.
    17661932     */
    1767     if (SUPR3IsDriverless()) /** @todo This is probably not good enough for doing fuzz testing, but later... */
     1933    if (SUPR3IsDriverless())
     1934    {
     1935#if defined(RT_OS_DARWIN) && defined(VBOX_WITH_INTNET_SERVICE_IN_R3)
     1936        xpc_connection_t hXpcCon = xpc_connection_create(INTNET_R3_SVC_NAME, NULL);
     1937        xpc_connection_set_event_handler(hXpcCon, ^(xpc_object_t hObj) {
     1938            if (xpc_get_type(hObj) == XPC_TYPE_ERROR)
     1939            {
     1940                /** @todo Error handling - reconnecting. */               
     1941            }
     1942            else
     1943            {
     1944                /* Out of band messages should only come when there is something to receive. */
     1945                RTSemEventSignal(pThis->hRecvEvt);
     1946            }
     1947        });
     1948
     1949        xpc_connection_activate(hXpcCon);
     1950        pThis->hXpcCon      = hXpcCon;
     1951        pThis->fIntNetR3Svc = true;
     1952#else
     1953        /** @todo This is probably not good enough for doing fuzz testing, but later... */
    17681954        return PDMDrvHlpVMSetError(pDrvIns, VERR_SUP_DRIVERLESS, RT_SRC_POS,
    17691955                                   N_("Cannot attach to '%s' in driverless mode"), pThis->szNetwork);
     1956#endif
     1957    }
    17701958    OpenReq.hIf = INTNET_HANDLE_INVALID;
    1771     rc = PDMDrvHlpSUPCallVMMR0Ex(pDrvIns, VMMR0_DO_INTNET_OPEN, &OpenReq, sizeof(OpenReq));
     1959    rc = drvR3IntNetCallSvc(pThis, VMMR0_DO_INTNET_OPEN, &OpenReq, sizeof(OpenReq));
    17721960    if (RT_FAILURE(rc))
    17731961    {
     
    17981986     * Get default buffer.
    17991987     */
    1800     INTNETIFGETBUFFERPTRSREQ GetBufferPtrsReq;
    1801     GetBufferPtrsReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
    1802     GetBufferPtrsReq.Hdr.cbReq = sizeof(GetBufferPtrsReq);
    1803     GetBufferPtrsReq.pSession = NIL_RTR0PTR;
    1804     GetBufferPtrsReq.hIf = pThis->hIf;
    1805     GetBufferPtrsReq.pRing3Buf = NULL;
    1806     GetBufferPtrsReq.pRing0Buf = NIL_RTR0PTR;
    1807     rc = PDMDrvHlpSUPCallVMMR0Ex(pDrvIns, VMMR0_DO_INTNET_IF_GET_BUFFER_PTRS, &GetBufferPtrsReq, sizeof(GetBufferPtrsReq));
     1988    rc = drvR3IntNetMapBufferPointers(pThis);
    18081989    if (RT_FAILURE(rc))
    18091990        return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS,
    18101991                                   N_("Failed to get ring-3 buffer for the newly created interface to '%s'"), pThis->szNetwork);
    1811     AssertRelease(RT_VALID_PTR(GetBufferPtrsReq.pRing3Buf));
    1812     pThis->pBufR3 = GetBufferPtrsReq.pRing3Buf;
    1813 #ifdef VBOX_WITH_DRVINTNET_IN_R0
    1814     pThis->pBufR0 = GetBufferPtrsReq.pRing0Buf;
    1815 #endif
    18161992
    18171993    /*
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