11739a20eSAndy Ritger /*
2*91676d66SBernhard Stoeckner  * SPDX-FileCopyrightText: Copyright (c) 2011-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
31739a20eSAndy Ritger  * SPDX-License-Identifier: MIT
41739a20eSAndy Ritger  *
51739a20eSAndy Ritger  * Permission is hereby granted, free of charge, to any person obtaining a
61739a20eSAndy Ritger  * copy of this software and associated documentation files (the "Software"),
71739a20eSAndy Ritger  * to deal in the Software without restriction, including without limitation
81739a20eSAndy Ritger  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
91739a20eSAndy Ritger  * and/or sell copies of the Software, and to permit persons to whom the
101739a20eSAndy Ritger  * Software is furnished to do so, subject to the following conditions:
111739a20eSAndy Ritger  *
121739a20eSAndy Ritger  * The above copyright notice and this permission notice shall be included in
131739a20eSAndy Ritger  * all copies or substantial portions of the Software.
141739a20eSAndy Ritger  *
151739a20eSAndy Ritger  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
161739a20eSAndy Ritger  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
171739a20eSAndy Ritger  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
181739a20eSAndy Ritger  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
191739a20eSAndy Ritger  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
201739a20eSAndy Ritger  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
211739a20eSAndy Ritger  * DEALINGS IN THE SOFTWARE.
221739a20eSAndy Ritger  */
231739a20eSAndy Ritger 
241739a20eSAndy Ritger #include "core/core.h"
251739a20eSAndy Ritger #include "gpu/gpu.h"
26b5bf85a8SAndy Ritger #include "gpu/subdevice/subdevice.h"
271739a20eSAndy Ritger #include <class/cl90f1.h>  // FERMI_VASPACE_A
281739a20eSAndy Ritger #include <rmp2pdefines.h>
291739a20eSAndy Ritger #include "gpu/bus/third_party_p2p.h"
301739a20eSAndy Ritger #include "mem_mgr/mem.h"
311739a20eSAndy Ritger #include "rmapi/rs_utils.h"
321739a20eSAndy Ritger #include "vgpu/rpc.h"
331739a20eSAndy Ritger 
341739a20eSAndy Ritger NV_STATUS
thirdpartyp2pCtrlCmdRegisterVaSpace_IMPL(ThirdPartyP2P * pThirdPartyP2P,NV503C_CTRL_REGISTER_VA_SPACE_PARAMS * pRegisterVaSpaceParams)351739a20eSAndy Ritger thirdpartyp2pCtrlCmdRegisterVaSpace_IMPL
361739a20eSAndy Ritger (
371739a20eSAndy Ritger     ThirdPartyP2P *pThirdPartyP2P,
381739a20eSAndy Ritger     NV503C_CTRL_REGISTER_VA_SPACE_PARAMS *pRegisterVaSpaceParams
391739a20eSAndy Ritger )
401739a20eSAndy Ritger {
411739a20eSAndy Ritger     NvU32     vaSpaceToken;
421739a20eSAndy Ritger     NV_STATUS status;
431739a20eSAndy Ritger     OBJGPU *pGpu;
441739a20eSAndy Ritger 
451739a20eSAndy Ritger     pGpu = GPU_RES_GET_GPU(pThirdPartyP2P);
461739a20eSAndy Ritger     if (pGpu == NULL)
471739a20eSAndy Ritger         return NV_ERR_INVALID_OBJECT_PARENT;
481739a20eSAndy Ritger 
491739a20eSAndy Ritger 
50eb5c7665SAndy Ritger     status = CliAddThirdPartyP2PVASpace(pThirdPartyP2P,
511739a20eSAndy Ritger                                         pRegisterVaSpaceParams->hVASpace,
521739a20eSAndy Ritger                                         &vaSpaceToken);
531739a20eSAndy Ritger     if (status == NV_OK)
541739a20eSAndy Ritger     {
551739a20eSAndy Ritger         {
561739a20eSAndy Ritger             pRegisterVaSpaceParams->vaSpaceToken = vaSpaceToken;
571739a20eSAndy Ritger         }
581739a20eSAndy Ritger     }
591739a20eSAndy Ritger 
601739a20eSAndy Ritger     return status;
611739a20eSAndy Ritger }
621739a20eSAndy Ritger 
631739a20eSAndy Ritger NV_STATUS
thirdpartyp2pCtrlCmdUnregisterVaSpace_IMPL(ThirdPartyP2P * pThirdPartyP2P,NV503C_CTRL_UNREGISTER_VA_SPACE_PARAMS * pUnregisterVaSpaceParams)641739a20eSAndy Ritger thirdpartyp2pCtrlCmdUnregisterVaSpace_IMPL
651739a20eSAndy Ritger (
661739a20eSAndy Ritger     ThirdPartyP2P *pThirdPartyP2P,
671739a20eSAndy Ritger     NV503C_CTRL_UNREGISTER_VA_SPACE_PARAMS *pUnregisterVaSpaceParams
681739a20eSAndy Ritger )
691739a20eSAndy Ritger {
701739a20eSAndy Ritger     NV_STATUS status = NV_OK;
711739a20eSAndy Ritger     OBJGPU *pGpu;
721739a20eSAndy Ritger 
731739a20eSAndy Ritger     pGpu = GPU_RES_GET_GPU(pThirdPartyP2P);
741739a20eSAndy Ritger     if (pGpu == NULL)
751739a20eSAndy Ritger         return NV_ERR_INVALID_OBJECT_PARENT;
761739a20eSAndy Ritger 
771739a20eSAndy Ritger     status = CliDelThirdPartyP2PVASpace(pThirdPartyP2P,
781739a20eSAndy Ritger                                         pUnregisterVaSpaceParams->hVASpace);
791739a20eSAndy Ritger 
801739a20eSAndy Ritger     return status;
811739a20eSAndy Ritger }
821739a20eSAndy Ritger 
831739a20eSAndy Ritger NV_STATUS
thirdpartyp2pCtrlCmdRegisterVidmem_IMPL(ThirdPartyP2P * pThirdPartyP2P,NV503C_CTRL_REGISTER_VIDMEM_PARAMS * pRegisterVidmemParams)841739a20eSAndy Ritger thirdpartyp2pCtrlCmdRegisterVidmem_IMPL
851739a20eSAndy Ritger (
861739a20eSAndy Ritger     ThirdPartyP2P *pThirdPartyP2P,
871739a20eSAndy Ritger     NV503C_CTRL_REGISTER_VIDMEM_PARAMS *pRegisterVidmemParams
881739a20eSAndy Ritger )
891739a20eSAndy Ritger {
901739a20eSAndy Ritger     Memory    *pMemory;
911739a20eSAndy Ritger     RsClient  *pClient = RES_GET_CLIENT(pThirdPartyP2P);
921739a20eSAndy Ritger     NvHandle   hDevice;
931739a20eSAndy Ritger     NvU64      address = pRegisterVidmemParams->address;
941739a20eSAndy Ritger     NvU64      size    = pRegisterVidmemParams->size;
951739a20eSAndy Ritger     NvU64      offset  = pRegisterVidmemParams->offset;
961739a20eSAndy Ritger     NV_STATUS status = NV_OK;
971739a20eSAndy Ritger     OBJGPU *pGpu;
981739a20eSAndy Ritger 
991739a20eSAndy Ritger     pGpu = GPU_RES_GET_GPU(pThirdPartyP2P);
1001739a20eSAndy Ritger     if (pGpu == NULL)
1011739a20eSAndy Ritger         return NV_ERR_INVALID_OBJECT_PARENT;
1021739a20eSAndy Ritger 
1031739a20eSAndy Ritger     hDevice = RES_GET_PARENT_HANDLE(pThirdPartyP2P->pSubdevice);
1041739a20eSAndy Ritger 
1051739a20eSAndy Ritger     status = memGetByHandleAndDevice(pClient,
1061739a20eSAndy Ritger                                      pRegisterVidmemParams->hMemory,
1071739a20eSAndy Ritger                                      hDevice,
1081739a20eSAndy Ritger                                      &pMemory);
1091739a20eSAndy Ritger     if (status != NV_OK)
1101739a20eSAndy Ritger     {
1111739a20eSAndy Ritger         return status;
1121739a20eSAndy Ritger     }
1131739a20eSAndy Ritger 
1141739a20eSAndy Ritger     if (memdescGetAddressSpace(pMemory->pMemDesc) != ADDR_FBMEM)
1151739a20eSAndy Ritger     {
1161739a20eSAndy Ritger         return NV_ERR_NOT_SUPPORTED;
1171739a20eSAndy Ritger     }
1181739a20eSAndy Ritger 
1191739a20eSAndy Ritger     if (size == 0)
1201739a20eSAndy Ritger         return NV_ERR_INVALID_ARGUMENT;
1211739a20eSAndy Ritger 
1221739a20eSAndy Ritger     if (size & (NVRM_P2P_PAGESIZE_BIG_64K - 1))
1231739a20eSAndy Ritger         return NV_ERR_INVALID_ARGUMENT;
1241739a20eSAndy Ritger 
1251739a20eSAndy Ritger     if (address & (NVRM_P2P_PAGESIZE_BIG_64K - 1))
1261739a20eSAndy Ritger         return NV_ERR_INVALID_ARGUMENT;
1271739a20eSAndy Ritger 
1281739a20eSAndy Ritger     if (offset & (NVRM_P2P_PAGESIZE_BIG_64K - 1))
1291739a20eSAndy Ritger         return NV_ERR_INVALID_ARGUMENT;
1301739a20eSAndy Ritger 
1311739a20eSAndy Ritger     // Check for overflow
1321739a20eSAndy Ritger     if (address + size < address || size + offset < size)
1331739a20eSAndy Ritger         return NV_ERR_INVALID_ARGUMENT;
1341739a20eSAndy Ritger 
1351739a20eSAndy Ritger     if (memdescGetSize(pMemory->pMemDesc) < offset + size)
1361739a20eSAndy Ritger         return NV_ERR_INVALID_ARGUMENT;
1371739a20eSAndy Ritger 
138eb5c7665SAndy Ritger     status = CliAddThirdPartyP2PVidmemInfo(pThirdPartyP2P,
1391739a20eSAndy Ritger                                            pRegisterVidmemParams->hMemory,
1401739a20eSAndy Ritger                                            address,
1411739a20eSAndy Ritger                                            size,
1421739a20eSAndy Ritger                                            offset,
1431739a20eSAndy Ritger                                            pMemory);
1441739a20eSAndy Ritger     if (status != NV_OK)
1451739a20eSAndy Ritger     {
1461739a20eSAndy Ritger         return status;
1471739a20eSAndy Ritger     }
1481739a20eSAndy Ritger 
1491739a20eSAndy Ritger     return status;
1501739a20eSAndy Ritger }
1511739a20eSAndy Ritger 
1521739a20eSAndy Ritger NV_STATUS
thirdpartyp2pCtrlCmdUnregisterVidmem_IMPL(ThirdPartyP2P * pThirdPartyP2P,NV503C_CTRL_UNREGISTER_VIDMEM_PARAMS * pUnregisterVidmemParams)1531739a20eSAndy Ritger thirdpartyp2pCtrlCmdUnregisterVidmem_IMPL
1541739a20eSAndy Ritger (
1551739a20eSAndy Ritger     ThirdPartyP2P *pThirdPartyP2P,
1561739a20eSAndy Ritger     NV503C_CTRL_UNREGISTER_VIDMEM_PARAMS *pUnregisterVidmemParams
1571739a20eSAndy Ritger )
1581739a20eSAndy Ritger {
1591739a20eSAndy Ritger     NV_STATUS status = NV_OK;
1601739a20eSAndy Ritger     OBJGPU *pGpu;
1611739a20eSAndy Ritger 
1621739a20eSAndy Ritger     pGpu = GPU_RES_GET_GPU(pThirdPartyP2P);
1631739a20eSAndy Ritger     if (pGpu == NULL)
1641739a20eSAndy Ritger         return NV_ERR_INVALID_OBJECT_PARENT;
1651739a20eSAndy Ritger 
1661739a20eSAndy Ritger     status = CliDelThirdPartyP2PVidmemInfo(pThirdPartyP2P,
1671739a20eSAndy Ritger                                            pUnregisterVidmemParams->hMemory);
1681739a20eSAndy Ritger     return status;
1691739a20eSAndy Ritger }
1701739a20eSAndy Ritger 
1711739a20eSAndy Ritger NV_STATUS
thirdpartyp2pCtrlCmdRegisterPid_IMPL(ThirdPartyP2P * pThirdPartyP2P,NV503C_CTRL_REGISTER_PID_PARAMS * pRegisterPidParams)1721739a20eSAndy Ritger thirdpartyp2pCtrlCmdRegisterPid_IMPL
1731739a20eSAndy Ritger (
1741739a20eSAndy Ritger     ThirdPartyP2P *pThirdPartyP2P,
1751739a20eSAndy Ritger     NV503C_CTRL_REGISTER_PID_PARAMS *pRegisterPidParams
1761739a20eSAndy Ritger )
1771739a20eSAndy Ritger {
1781739a20eSAndy Ritger     NvHandle  hClient = RES_GET_CLIENT_HANDLE(pThirdPartyP2P);
1791739a20eSAndy Ritger     NvHandle  hObject = RES_GET_HANDLE(pThirdPartyP2P);
1801739a20eSAndy Ritger     RmClient *pClient;
1811739a20eSAndy Ritger     NvU32     pid;
1821739a20eSAndy Ritger     NV_STATUS status;
1831739a20eSAndy Ritger 
184eb5c7665SAndy Ritger     pClient = serverutilGetClientUnderLock(pRegisterPidParams->hClient);
185eb5c7665SAndy Ritger     NV_ASSERT_OR_RETURN(pClient != NULL, NV_ERR_INVALID_CLIENT);
186eb5c7665SAndy Ritger 
1871739a20eSAndy Ritger     pid = pClient->ProcID;
1881739a20eSAndy Ritger 
1891739a20eSAndy Ritger     status = CliAddThirdPartyP2PClientPid(hClient,
1901739a20eSAndy Ritger                                           hObject,
1911739a20eSAndy Ritger                                           pid,
1921739a20eSAndy Ritger                                           pRegisterPidParams->hClient);
1931739a20eSAndy Ritger     return status;
1941739a20eSAndy Ritger }
195