1 /* 2 * SPDX-FileCopyrightText: Copyright (c) 2015-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 * SPDX-License-Identifier: MIT 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be included in 13 * all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 */ 23 24 #include "g_rs_server_nvoc.h" 25 26 #ifndef _RS_SERVER_H_ 27 #define _RS_SERVER_H_ 28 29 #include "nvport/nvport.h" 30 #include "resserv/resserv.h" 31 #include "resserv/rs_client.h" 32 #include "nvoc/runtime.h" 33 34 #ifdef __cplusplus 35 extern "C" { 36 #endif 37 38 /** 39 * @defgroup RsServer 40 * @addtogroup RsServer 41 * @{*/ 42 43 /** 44 * Book-keeping for individual client locks 45 */ 46 struct CLIENT_ENTRY 47 { 48 PORT_RWLOCK *pLock; 49 RsClient *pClient; 50 NvHandle hClient; 51 NvU64 lockOwnerTid; ///< Thread id of the lock owner 52 53 #if LOCK_VAL_ENABLED 54 LOCK_VAL_LOCK lockVal; 55 #endif 56 }; 57 58 /** 59 * Base-class for objects that are shared among multiple 60 * RsResources (including RsResources from other clients) 61 */ 62 NVOC_PREFIX(shr) class RsShared : Object 63 { 64 public: 65 NV_STATUS shrConstruct(RsShared *pShared); 66 void shrDestruct(RsShared *pShared); 67 68 NvS32 refCount; 69 MapNode node; 70 }; 71 MAKE_INTRUSIVE_MAP(RsSharedMap, RsShared, node); 72 73 /** 74 * Utility class for objects that can reference 75 * multiple client handle spaces. Free's and control calls 76 * that occur on objects which reference an RsSession will 77 * need to acquire pLock first. 78 */ 79 NVOC_PREFIX(session) class RsSession : RsShared 80 { 81 public: 82 NV_STATUS sessionConstruct(RsSession *pSession); 83 void sessionDestruct(RsSession *pSession); 84 85 NV_STATUS sessionAddDependant(RsSession *pSession, RsResourceRef *pResourceRef); 86 NV_STATUS sessionAddDependency(RsSession *pSession, RsResourceRef *pResourceRef); 87 virtual void sessionRemoveDependant(RsSession *pSession, RsResourceRef *pResourceRef); 88 virtual void sessionRemoveDependency(RsSession *pSession, RsResourceRef *pResourceRef); 89 90 PORT_RWLOCK *pLock; 91 #if LOCK_VAL_ENABLED 92 LOCK_VAL_LOCK lockVal; 93 #endif 94 95 NvBool bValid; 96 97 RsResourceRefList dependencies; 98 RsResourceRefList dependants; 99 // private: 100 NV_STATUS sessionCheckLocksForAdd(RsSession *pSession, RsResourceRef *pResourceRef); 101 void sessionCheckLocksForRemove(RsSession *pSession, RsResourceRef *pResourceRef); 102 }; 103 104 // Iterator data structure to save state while walking through a map 105 struct RS_SHARE_ITERATOR 106 { 107 RsSharedMapIter mapIt; 108 NvU32 internalClassId; 109 RsShared *pShared; ///< Share that is being iterated over 110 }; 111 112 /** 113 * Top-level structure that RMAPI and RM interface with 114 * 115 * This class is all that needs to be allocated to use the resource server 116 * library. 117 * 118 * The RsServer interface should be kept as narrow as possible. Map and 119 * MapTo are added because <1> the unmap variants operate in addresses and not 120 * handles and <2> having explicit knowledge of map operations in the server is 121 * helpful when dealing with multiple levels of address spaces (e.g., guest 122 * user-mode, guest kernel-mode, host kernel-mode). 123 */ 124 struct RsServer 125 { 126 /** 127 * Privilege level determines what objects a server is allowed to allocate, and 128 * also determines whether additional handle validation needs to be performed. 129 */ 130 RS_PRIV_LEVEL privilegeLevel; 131 132 RsClientList *pClientSortedList; ///< Bucket if linked List of clients (and their locks) owned by this server 133 NvU32 clientCurrentHandleIndex; 134 135 NvBool bConstructed; ///< Determines whether the server is ready to be used 136 PORT_MEM_ALLOCATOR *pAllocator; ///< Allocator to use for all objects allocated by the server 137 138 PORT_RWLOCK *pClientListLock; ///< Lock that needs to be taken when accessing the client list 139 140 PORT_SPINLOCK *pShareMapLock; ///< Lock that needs to be taken when accessing the shared resource map 141 RsSharedMap shareMap; ///< Map of shared resources 142 143 #if (RS_STANDALONE) 144 NvU64 topLockOwnerTid; ///< Thread id of top-lock owner 145 PORT_RWLOCK *pTopLock; ///< Top-level resource server lock 146 PORT_RWLOCK *pResLock; ///< Resource-level resource server lock 147 #if LOCK_VAL_ENABLED 148 LOCK_VAL_LOCK topLockVal; 149 LOCK_VAL_LOCK resLockVal; 150 #endif 151 #endif 152 153 /// Print out a list of all resources that will be freed when a free request is made 154 NvBool bDebugFreeList; 155 156 /// If true, control call param copies will be performed outside the top/api lock 157 NvBool bUnlockedParamCopy; 158 159 // If true, calls annotated with ROUTE_TO_PHYISCAL will not grab global gpu locks 160 // (and the readonly API lock). 161 NvBool bRouteToPhysicalLockBypass; 162 163 /** 164 * Setting this flag to false disables any attempts to 165 * automatically acquire access rights or to control access to resources by 166 * checking for access rights. 167 */ 168 NvBool bRsAccessEnabled; 169 170 /** 171 * Mask of interfaces (RS_API_*) that will use a read-only top lock by default 172 */ 173 NvU32 roTopLockApiMask; 174 175 /// Share policies which clients default to when no other policies are used 176 RsShareList defaultInheritedSharePolicyList; 177 /// Share policies to apply to all shares, regardless of other policies 178 RsShareList globalInternalSharePolicyList; 179 180 NvU32 internalHandleBase; 181 NvU32 clientHandleBase; 182 183 NvU32 activeClientCount; 184 NvU64 activeResourceCount; 185 186 /// List of clients that are de-activated and pending free 187 RsDisabledClientList disabledClientList; 188 RsClient *pNextDisabledClient; 189 PORT_SPINLOCK *pDisabledClientListLock; 190 }; 191 192 /** 193 * Construct a server instance. This must be performed before any other server 194 * operation. 195 * 196 * @param[in] pServer This server instance 197 * @param[in] privilegeLevel Privilege level for this resource server instance 198 * @param[in] maxDomains Maximum number of domains to support, or 0 for the default 199 */ 200 NV_STATUS serverConstruct(RsServer *pServer, RS_PRIV_LEVEL privilegeLevel, NvU32 maxDomains); 201 202 /** 203 * Destroy a server instance. Destructing a server does not guarantee that child domains 204 * and clients will be appropriately freed. serverFreeDomain should be explicitly called 205 * on all allocated domains to ensure all clients and resources get cleaned up. 206 * 207 * @param[in] pServer This server instance 208 */ 209 NV_STATUS serverDestruct(RsServer *pServer); 210 211 /** 212 * Allocate a domain handle. Domain handles are used to track clients created by a domain. 213 * 214 * @param[in] pServer This server instance 215 * @param[in] hParentDomain 216 * @param[in] pAccessControl 217 * @param[out] phDomain 218 * 219 */ 220 NV_STATUS serverAllocDomain(RsServer *pServer, NvU32 hParentDomain, ACCESS_CONTROL *pAccessControl, NvHandle *phDomain); 221 222 /** 223 * Verify that the calling user is allowed to perform the access. This check only 224 * applies to calls from RING_USER or RING_KERNEL. No check is performed in 225 * RING_HOST. 226 * 227 * @param[in] pServer This server instance 228 * @param[in] hDomain 229 * @param[in] hClient 230 * 231 */ 232 NV_STATUS serverValidate(RsServer *pServer, NvU32 hDomain, NvHandle hClient); 233 234 /** 235 * Verify that the domain has sufficient permission to allocate the given class. 236 * @param[in] pServer 237 * @param[in] hDomain 238 * @param[in] externalClassId External resource class id 239 */ 240 NV_STATUS serverValidateAlloc(RsServer *pServer, NvU32 hDomain, NvU32 externalClassId); 241 242 /** 243 * Free a domain handle. All clients of this domain will be freed. 244 * 245 * @param[in] pServer This server instance 246 * @param[in] hDomain The handle of the domain to free 247 */ 248 NV_STATUS serverFreeDomain(RsServer *pServer, NvHandle hDomain); 249 250 /** 251 * Allocate a client handle. A client handle is required to allocate resources. 252 * 253 * @param[in] pServer This server instance 254 * @param[inout] pParams Client allocation parameters 255 */ 256 NV_STATUS serverAllocClient(RsServer *pServer, RS_RES_ALLOC_PARAMS_INTERNAL *pParams); 257 258 /** 259 * Free a client handle. All resources references owned by the client will be 260 * freed. 261 * 262 * It is invalid to attempt to free a client from a user other than the one 263 * that allocated it. 264 * 265 * @param[in] pServer This server instance 266 * @param[in] pParams Client free params 267 */ 268 NV_STATUS serverFreeClient(RsServer *pServer, RS_CLIENT_FREE_PARAMS* pParams); 269 270 /** 271 * Mark a list of client handles as disabled. All CPU mappings owned by that 272 * client will be unmapped immediate, and the client will be marked as disabled. 273 * A call to @ref serverFreeDisabledClients will then free all such clients. 274 * 275 * It is invalid to attempt to free a client from a user other than the one 276 * that allocated it. 277 * 278 * @param[in] pServer This server instance 279 * @param[in] phClientList The list of client handles to disable 280 * @param[in] numClients The number of clients in the list 281 * @param[in] freeState User-defined free state 282 * @param[in] pSecInfo Security Info 283 * 284 */ 285 NV_STATUS serverMarkClientListDisabled(RsServer *pServer, NvHandle *phClientList, NvU32 numClients, NvU32 freeState, API_SECURITY_INFO *pSecInfo); 286 287 /** 288 * Frees all currently disabled clients. All resources references owned by 289 * any of the clients will be freed. 290 * All priority resources will be freed first across all listed clients. 291 * 292 * NOTE: may return NV_WARN_MORE_PROCESSING_REQUIRED if not all clients were freed 293 * 294 * @param[in] pServer This server instance 295 * @param[in] freeState User-defined free state 296 * @param[in] limit Max number of iterations to make returning; 0 means no limit 297 * 298 */ 299 NV_STATUS serverFreeDisabledClients(RsServer *pServer, NvU32 freeState, NvU32 limit); 300 301 /** 302 * Allocate a resource. 303 * 304 * It is invalid to attempt to allocate a client from a user other than the one 305 * that allocated it. 306 * 307 * @param[in] pServer This server instance 308 * @param[inout] pParams The allocation parameters 309 */ 310 NV_STATUS serverAllocResource(RsServer *pServer, RS_RES_ALLOC_PARAMS *params); 311 312 /** 313 * Allocate a ref-counted resource share. 314 * 315 * @param[in] pServer 316 * @param[in] pClassInfo NVOC class info for the shared class (must derive from RsShared) 317 * @param[out] ppShare Allocated share 318 */ 319 NV_STATUS serverAllocShare(RsServer *pServer, const NVOC_CLASS_INFO* pClassInfo, RsShared **ppShare); 320 321 /** 322 * Allocate a ref-counted resource share with Halspec parent. 323 * 324 * @param[in] pServer 325 * @param[in] pClassInfo NVOC class info for the shared class (must derive from RsShared) 326 * @param[out] ppShare Allocated share 327 * @param[in] pHalspecParent Parent object whose Halspec can be used for the shared class object 328 */ 329 NV_STATUS serverAllocShareWithHalspecParent(RsServer *pServer, const NVOC_CLASS_INFO* pClassInfo, RsShared **ppShare, Object *pHalspecParent); 330 331 /** 332 * Get the ref-count of a resource share. 333 * 334 * @param[in] pServer 335 * @param[in] pShare Resource share 336 */ 337 NvS32 serverGetShareRefCount(RsServer *pServer, RsShared *pShare); 338 339 /** 340 * Increment the ref-count of a resource share. 341 * 342 * @param[in] pServer 343 * @param[in] pShare Resource share 344 */ 345 NV_STATUS serverRefShare(RsServer *pServer, RsShared *pShare); 346 347 /** 348 * Decrement the ref-count of a resource share. If the ref-count 349 * has reached zero, the resource share will be freed. 350 * 351 * @param[in] pServer 352 * @param[in] pShare Resource share 353 */ 354 NV_STATUS serverFreeShare(RsServer *pServer, RsShared *pShare); 355 356 /** 357 * Get an iterator to the elements in the server's shared object map 358 * @param[in] pServer 359 * @param[in] internalClassId If non-zero, only RsShared that are (or can be 360 * derived from) the specified class will be returned 361 */ 362 RS_SHARE_ITERATOR serverShareIter(RsServer *pServer, NvU32 internalClassId); 363 364 /** 365 * Get an iterator to the elements in the server's shared object map 366 */ 367 NvBool serverShareIterNext(RS_SHARE_ITERATOR*); 368 369 /** 370 * Set fixed client handle base in case clients wants to use a different 371 * base for client allocations 372 * @param[in] pServer 373 * @param[in] clientHandleBase 374 */ 375 NV_STATUS serverSetClientHandleBase(RsServer *pServer, NvU32 clientHandleBase); 376 377 /** 378 * Deserialize parameters for servicing command 379 * 380 * @param[in] pCallContext 381 * @param[in] cmd 382 * @param[in] pParams 383 * @param[in] paramsSize 384 * @param[in] flags 385 */ 386 NV_STATUS serverDeserializeCtrlDown(CALL_CONTEXT *pCallContext, NvU32 cmd, void *pParams, NvU32 paramsSize, NvU32 *flags); 387 388 /** 389 * Serialize parameters for servicing command 390 * 391 * @param[in] pCallContext 392 * @param[in] cmd 393 * @param[in] pParams 394 * @param[in] paramsSize 395 * @param[in] flags 396 */ 397 NV_STATUS serverSerializeCtrlDown(CALL_CONTEXT *pCallContext, NvU32 cmd, void *pParams, NvU32 paramsSize, NvU32 *flags); 398 399 /** 400 * Deserialize parameters for returning from command 401 * 402 * @param[in] pCallContext 403 * @param[in] cmd 404 * @param[in] pParams 405 * @param[in] paramsSize 406 * @param[in] flags 407 */ 408 NV_STATUS serverDeserializeCtrlUp(CALL_CONTEXT *pCallContext, NvU32 cmd, void *pParams, NvU32 paramsSize, NvU32 *flags); 409 410 /** 411 * Serialize parameters for returning from command 412 * 413 * @param[in] pCallContext 414 * @param[in] cmd 415 * @param[in] pParams 416 * @param[in] paramsSize 417 * @param[in] flags 418 */ 419 NV_STATUS serverSerializeCtrlUp(CALL_CONTEXT *pCallContext, NvU32 cmd, void *pParams, NvU32 paramsSize, NvU32 *flags); 420 421 /** 422 * Unset flag for reserializing control before going to GSP 423 * Used if kernel control servicing passes params to GSP without changing them 424 * 425 * @param[in] pCallContext 426 */ 427 void serverDisableReserializeControl(CALL_CONTEXT *pCallContext); 428 429 /** 430 * Free finn structures allocated for serializing/deserializing 431 * 432 * @param[in] pCallContext 433 * @param[in] pParams 434 */ 435 void serverFreeSerializeStructures(CALL_CONTEXT *pCallContext, void *pParams); 436 437 /** 438 * Return an available client handle for new client allocation 439 * 440 * @param[in] pServer This server instance 441 * @param[in] bInternalHandle Client is an RM internal client 442 * @param[in] pSecInfo Security context of this client allocation 443 */ 444 extern NvU32 serverAllocClientHandleBase(RsServer *pServer, NvBool bInternalHandle, API_SECURITY_INFO *pSecInfo); 445 446 /** 447 * Allocate a resource. Assumes top-level lock has been taken. 448 * 449 * It is invalid to attempt to allocate a client from a user other than the one 450 * that allocated it. User-implemented. 451 * 452 * @param[in] pServer This server instance 453 * @param[inout] pParams The allocation parameters 454 */ 455 extern NV_STATUS serverAllocResourceUnderLock(RsServer *pServer, RS_RES_ALLOC_PARAMS *pAllocParams); 456 457 /** 458 * Call Free RPC for given resource. Assumes top-level lock has been taken. 459 * 460 * @param[in] pServer This server instance 461 * @param[inout] pFreeParams The Free parameters 462 */ 463 extern NV_STATUS serverFreeResourceRpcUnderLock(RsServer *pServer, RS_RES_FREE_PARAMS *pFreeParams); 464 465 /** 466 * Copy-in parameters supplied by caller, and initialize API state. User-implemented. 467 * @param[in] pServer 468 * @param[in] pAllocParams Resource allocation parameters 469 * @param[out] ppApiState User-defined API_STATE; should be allocated by this function 470 */ 471 extern NV_STATUS serverAllocApiCopyIn(RsServer *pServer, RS_RES_ALLOC_PARAMS_INTERNAL *pAllocParams, API_STATE **ppApiState); 472 473 /** 474 * Copy-out parameters supplied by caller, and release API state. User-implemented. 475 * @param[in] pServer 476 * @param[in] status Status of allocation request 477 * @param[in] pApiState API_STATE for the allocation 478 */ 479 extern NV_STATUS serverAllocApiCopyOut(RsServer *pServer, NV_STATUS status, API_STATE *pApiState); 480 481 /** 482 * Obtain a second client handle to lock if required for the allocation. 483 * @param[in] pParams Resource allocation parameters 484 * @param[in] phClient Client to lock, if any 485 */ 486 extern NV_STATUS serverLookupSecondClient(RS_RES_ALLOC_PARAMS_INTERNAL *pParams, NvHandle *phClient); 487 488 /** 489 * Acquires a top-level lock. User-implemented. 490 * @param[in] pServer 491 * @param[in] access LOCK_ACCESS_READ or LOCK_ACCESS_WRITE 492 * @param[inout] pLockInfo Lock state 493 * @param[inout] pReleaseFlags Output flags indicating the locks that need to be released 494 */ 495 extern NV_STATUS serverTopLock_Prologue(RsServer *pServer, LOCK_ACCESS_TYPE access, RS_LOCK_INFO *pLockInfo, NvU32 *pReleaseFlags); 496 497 /** 498 * Releases a top-level lock. User-implemented. 499 * @param[in] pServer 500 * @param[in] access LOCK_ACCESS_READ or LOCK_ACCESS_WRITE 501 * @param[inout] pLockInfo Lock state 502 * @param[inout] pReleaseFlags Flags indicating the locks that need to be released 503 */ 504 extern void serverTopLock_Epilogue(RsServer *pServer, LOCK_ACCESS_TYPE access, RS_LOCK_INFO *pLockInfo, NvU32 *pReleaseFlags); 505 506 /** 507 * Acquires a session lock. 508 * @param[in] access LOCK_ACCESS_READ or LOCK_ACCESS_WRITE 509 * @param[in] pResourceRef Resource reference to take session locks on 510 * @param[inout] pLockInfo Lock state 511 */ 512 extern NV_STATUS serverSessionLock_Prologue(LOCK_ACCESS_TYPE access, RsResourceRef *pResourceRef, RS_LOCK_INFO *pLockInfo, NvU32 *pReleaseFlags); 513 514 /** 515 * Releases a session lock. 516 * @param[in] pServer 517 * @param[in] access LOCK_ACCESS_READ or LOCK_ACCESS_WRITE 518 * @param[inout] pLockInfo Lock state 519 * @param[inout] pReleaseFlags Flags indicating the locks that need to be released 520 */ 521 extern void serverSessionLock_Epilogue(RsServer *pServer, LOCK_ACCESS_TYPE access, RS_LOCK_INFO *pLockInfo, NvU32 *pReleaseFlags); 522 523 /** 524 * Acquires a resource-level lock. User-implemented. 525 * @param[in] pServer 526 * @param[in] access LOCK_ACCESS_READ or LOCK_ACCESS_WRITE 527 * @param[inout] pLockInfo Lock state 528 * @param[inout] pReleaseFlags Output flags indicating the locks that need to be released 529 */ 530 extern NV_STATUS serverResLock_Prologue(RsServer *pServer, LOCK_ACCESS_TYPE access, RS_LOCK_INFO *pLockInfo, NvU32 *pReleaseFlags); 531 532 /** 533 * Releases a resource-level lock. User-implemented. 534 * @param[in] pServer 535 * @param[in] access LOCK_ACCESS_READ or LOCK_ACCESS_WRITE 536 * @param[inout] pLockInfo Lock state 537 * @param[inout] pReleaseFlags Flags indicating the locks that need to be released 538 */ 539 extern void serverResLock_Epilogue(RsServer *pServer, LOCK_ACCESS_TYPE access, RS_LOCK_INFO *pLockInfo, NvU32 *pReleaseFlags); 540 541 /** 542 * WAR for additional tasks that must be performed after resource-level locks are released. User-implemented. 543 * @param[inout] status Allocation status 544 * @param[in] bClientAlloc Caller is attempting to allocate a client 545 * @param[inout] pParams Allocation parameters 546 */ 547 extern NV_STATUS serverAllocEpilogue_WAR(RsServer *pServer, NV_STATUS status, NvBool bClientAlloc, RS_RES_ALLOC_PARAMS_INTERNAL *pAllocParams); 548 549 /** 550 * Free a resource reference and all of its descendants. This will decrease the 551 * resource's reference count. The resource itself will only be freed if there 552 * are no more references to it. 553 * 554 * It is invalid to attempt to free a resource from a user other than the one that allocated it. 555 * 556 * @param[in] pServer This server instance 557 * @param[in] pParams Free parameters 558 */ 559 NV_STATUS serverFreeResourceTree(RsServer *pServer, RS_RES_FREE_PARAMS *pParams); 560 561 /** 562 * Same as serverFreeResourceTree except the top-level lock is assumed to have been taken. 563 * 564 * @param[in] pServer This server instance 565 * @param[in] pParams Free parameters 566 */ 567 NV_STATUS serverFreeResourceTreeUnderLock(RsServer *pServer, RS_RES_FREE_PARAMS *pParams); 568 569 /** 570 * Updates the lock flags in the dup parameters 571 * 572 * @param[in] pServer This server instance 573 * @param[in] pParams Dup parameters 574 */ 575 extern NV_STATUS serverUpdateLockFlagsForCopy(RsServer *pServer, RS_RES_DUP_PARAMS *pParams); 576 577 /** 578 * Updates the lock flags in the free parameters 579 * 580 * @param[in] pServer This server instance 581 * @param[in] pParams Free parameters 582 */ 583 extern NV_STATUS serverUpdateLockFlagsForFree(RsServer *pServer, RS_RES_FREE_PARAMS *pParams); 584 585 /** 586 * Updates the lock flags for automatic inter-unmap during free 587 * 588 * @param[in] pServer This server instance 589 * @param[inout] pParams Unmap params, contained pLockInfo will be modified 590 */ 591 extern NV_STATUS serverUpdateLockFlagsForInterAutoUnmap(RsServer *pServer, RS_INTER_UNMAP_PARAMS *pParams); 592 593 /** 594 * Initialize parameters for a recursive call to serverFreeResourceTree. User-implemented. 595 * @param[in] hClient 596 * @param[in] hResource 597 * @param[inout] pParams 598 */ 599 extern NV_STATUS serverInitFreeParams_Recursive(NvHandle hClient, NvHandle hResource, RS_LOCK_INFO *pLockInfo, RS_RES_FREE_PARAMS *pParams); 600 601 /** 602 * Common operations performed after top locks and client locks are taken, but before 603 * the control call is executed. This includes validating the control call cookie, 604 * looking up locking flags, parameter copy-in, and taking resource locks. 605 * 606 * @param[in] pServer ResServ instance 607 * @param[in] pParams Control call parameters 608 * @param[in] pAccess Lock access type 609 * @param[inout] pReleaseFlags Flags that indicate which locks were taken 610 */ 611 NV_STATUS serverControl_Prologue(RsServer *pServer, RS_RES_CONTROL_PARAMS_INTERNAL *pParams, LOCK_ACCESS_TYPE *pAccess, NvU32 *pReleaseFlags); 612 613 /** 614 * Common operations performed after the control call is executed. This 615 * includes releasing locks and parameter copy-out. 616 * 617 * @param[in] pServer ResServ instance 618 * @param[in] pParams Control call parameters 619 * @param[in] pAccess Lock access type 620 * @param[inout] pReleaseFlags Flags that indicate which locks were taken 621 * @param[in] status Control call status 622 */ 623 NV_STATUS serverControl_Epilogue(RsServer *pServer, RS_RES_CONTROL_PARAMS_INTERNAL *pParams, LOCK_ACCESS_TYPE access, NvU32 *pReleaseFlags, NV_STATUS status); 624 625 /** 626 * Initialize a NVOC export control call cookie 627 * 628 * @param[in] pExportedEntry 629 * @param[inout] pCookie 630 */ 631 extern void serverControl_InitCookie(const struct NVOC_EXPORTED_METHOD_DEF *pExportedEntry, RS_CONTROL_COOKIE *pCookie); 632 633 /** 634 * Validate a NVOC export control call cookie 635 * 636 * @param[in] pParams 637 * @param[inout] pCookie 638 */ 639 extern NV_STATUS serverControl_ValidateCookie(RS_RES_CONTROL_PARAMS_INTERNAL *pParams, RS_CONTROL_COOKIE *pCookie); 640 641 /** 642 * Copy-in control call parameters 643 * 644 * @param[in] pServer ResServ instance 645 * @param[in] pParams Control call parameters 646 * @param[inout] pCookie Control call cookie 647 */ 648 extern NV_STATUS serverControlApiCopyIn(RsServer *pServer, 649 RS_RES_CONTROL_PARAMS_INTERNAL *pParams, 650 RS_CONTROL_COOKIE *pCookie); 651 652 /** 653 * Copy-out control call parameters 654 * 655 * @param[in] pServer ResServ instance 656 * @param[in] pParams Control call parameters 657 * @param[inout] pCookie Control call cookie 658 */ 659 extern NV_STATUS serverControlApiCopyOut(RsServer *pServer, 660 RS_RES_CONTROL_PARAMS_INTERNAL *pParams, 661 RS_CONTROL_COOKIE *pCookie, 662 NV_STATUS rmStatus); 663 664 /** 665 * Determine whether an API supports a read-only lock for a given lock 666 * @param[in] pServer ResServ instance 667 * @param[in] lock RS_LOCK_* 668 * @param[in] api RS_API* 669 */ 670 NvBool serverSupportsReadOnlyLock(RsServer *pServer, RS_LOCK_ENUM lock, RS_API_ENUM api); 671 672 /** 673 * Determine whether the current thread has taken the RW API lock 674 * @param[in] pServer ResServ instance 675 */ 676 extern NvBool serverRwApiLockIsOwner(RsServer *pServer); 677 678 /** 679 * Lookup locking flags for a resource alloc 680 * 681 * @param[in] pServer ResServ instance 682 * @param[in] lock RS_LOCK_* 683 * @param[in] pParams Allocation parameters 684 * @param[out] pAccess Computed lock access 685 */ 686 extern NV_STATUS serverAllocResourceLookupLockFlags(RsServer *pServer, 687 RS_LOCK_ENUM lock, 688 RS_RES_ALLOC_PARAMS_INTERNAL *pParams, 689 LOCK_ACCESS_TYPE *pAccess); 690 /** 691 * 692 * Lookup level locking flags for a resource free 693 * 694 * @param[in] pServer ResServ instance 695 * @param[in] lock RS_LOCK_* 696 * @param[in] pParams Allocation parameters 697 * @param[out] pAccess Computed lock access 698 */ 699 extern NV_STATUS serverFreeResourceLookupLockFlags(RsServer *pServer, 700 RS_LOCK_ENUM lock, 701 RS_RES_FREE_PARAMS_INTERNAL *pParams, 702 LOCK_ACCESS_TYPE *pAccess); 703 704 /** 705 * Lookup locking flags for a resource copy 706 * 707 * @param[in] pServer ResServ instance 708 * @param[in] lock RS_LOCK_* 709 * @param[in] pParams Allocation parameters 710 * @param[out] pAccess Computed lock access 711 */ 712 extern NV_STATUS serverCopyResourceLookupLockFlags(RsServer *pServer, 713 RS_LOCK_ENUM lock, 714 RS_RES_DUP_PARAMS *pParams, 715 LOCK_ACCESS_TYPE *pAccess); 716 717 /** 718 * Lookup locking flags for a resource access share 719 * 720 * @param[in] pServer ResServ instance 721 * @param[in] lock RS_LOCK_* 722 * @param[in] pParams Share parameters 723 * @param[out] pAccess Computed lock access 724 */ 725 extern NV_STATUS serverShareResourceLookupLockFlags(RsServer *pServer, 726 RS_LOCK_ENUM lock, 727 RS_RES_SHARE_PARAMS *pParams, 728 LOCK_ACCESS_TYPE *pAccess); 729 730 /** 731 * Lookup locking flags for a control call 732 * 733 * @param[in] pServer ResServ instance 734 * @param[in] lock RS_LOCK_* 735 * @param[in] pParams Control call parameters 736 * @param[in] pCookie Control call cookie 737 * @param[out] pAccess Computed lock access 738 */ 739 extern NV_STATUS serverControlLookupLockFlags(RsServer *pServer, 740 RS_LOCK_ENUM lock, 741 RS_RES_CONTROL_PARAMS_INTERNAL *pParams, 742 RS_CONTROL_COOKIE *pCookie, 743 LOCK_ACCESS_TYPE *pAccess); 744 745 /** 746 * 747 * Lookup locking flags for a map call 748 * 749 * @param[in] pServer ResServ instance 750 * @param[in] lock RS_LOCK_* 751 * @param[in] pParams CPU map parameters 752 * @param[out] pAccess Computed lock access 753 */ 754 extern NV_STATUS serverMapLookupLockFlags(RsServer *pServer, 755 RS_LOCK_ENUM lock, 756 RS_CPU_MAP_PARAMS *pParams, 757 LOCK_ACCESS_TYPE *pAccess); 758 759 /** 760 * Lookup locking flags for an unmap call 761 * 762 * @param[in] pServer ResServ instance 763 * @param[in] lock RS_LOCK_* 764 * @param[in] pParams CPU unmap parameters 765 * @param[out] pAccess Computed lock access 766 */ 767 extern NV_STATUS serverUnmapLookupLockFlags(RsServer *pServer, 768 RS_LOCK_ENUM lock, 769 RS_CPU_UNMAP_PARAMS *pParams, 770 LOCK_ACCESS_TYPE *pAccess); 771 772 /** 773 * 774 * Lookup locking flags for an inter-resource map call 775 * 776 * @param[in] pServer ResServ instance 777 * @param[in] lock RS_LOCK_* 778 * @param[in] pParams Inter-resource map parameters 779 * @param[out] pAccess Computed lock access 780 */ 781 extern NV_STATUS serverInterMapLookupLockFlags(RsServer *pServer, 782 RS_LOCK_ENUM lock, 783 RS_INTER_MAP_PARAMS *pParams, 784 LOCK_ACCESS_TYPE *pAccess); 785 786 /** 787 * 788 * Lookup locking flags for an inter-resource unmap call 789 * 790 * @param[in] pServer ResServ instance 791 * @param[in] lock RS_LOCK_* 792 * @param[in] pParams Inter-resource unmap parameters 793 * @param[out] pAccess Computed lock access 794 */ 795 extern NV_STATUS serverInterUnmapLookupLockFlags(RsServer *pServer, 796 RS_LOCK_ENUM lock, 797 RS_INTER_UNMAP_PARAMS *pParams, 798 LOCK_ACCESS_TYPE *pAccess); 799 800 /** 801 * Fill the server's share policy lists with any default or global policies needed 802 */ 803 extern NV_STATUS serverInitGlobalSharePolicies(RsServer *pServer); 804 805 /** 806 * Issue a control command to a resource 807 * 808 * @param[in] pServer This server instance 809 * @param[in] pParams Control parameters 810 */ 811 NV_STATUS serverControl(RsServer *pServer, RS_RES_CONTROL_PARAMS *pParams); 812 813 /** 814 * Copy a resource owned by one client into another client. 815 * 816 * The clients must be in the same client handle space. The underlying 817 * resource is not duplicated, but it is refcounted so the resource will 818 * not be freed until the reference count hits zero. 819 * 820 * Copying a resource will fail if the user making the call does not own 821 * the source client. 822 * 823 * @param[in] pServer This server instance 824 * @param[inout] pParams Resource sharing parameters 825 */ 826 NV_STATUS serverCopyResource(RsServer *pServer, RS_RES_DUP_PARAMS *pParams); 827 828 /** 829 * Share certain access rights to a resource with other clients using the provided share policy 830 * 831 * The policy entry passed in will be added to the object's share policy list. 832 * If the bRevoke is true, the policy will be removed instead. 833 * 834 * Sharing will fail if the user making the call does not own the source client. 835 * 836 * @param[in] pServer This server instance 837 * @param[in] pParams Resource sharing parameters 838 */ 839 NV_STATUS serverShareResourceAccess(RsServer *pServer, RS_RES_SHARE_PARAMS *pParams); 840 841 /** 842 * Creates a CPU mapping of the resource in the virtual address space of the process. 843 * 844 * Not all resources support mapping. 845 * 846 * @param[in] pServer This server instance 847 * @param[in] hClient Client handle of the resource to map 848 * @param[in] hResource Handle of the resource to map 849 * @param[inout] pParams CPU mapping parameters 850 */ 851 NV_STATUS serverMap(RsServer *pServer, NvHandle hClient, NvHandle hResource, RS_CPU_MAP_PARAMS *pParams); 852 853 /** 854 * Release a CPU virtual address unmapping 855 * 856 * @param[in] pServer This server instance 857 * @param[in] hClient Client handle of the resource to map 858 * @param[in] hResource Handle of the resource to map 859 * @param[in] pParams CPU unmapping parameters 860 */ 861 NV_STATUS serverUnmap(RsServer *pServer, NvHandle hClient, NvHandle hResource, RS_CPU_UNMAP_PARAMS *pParams); 862 863 /** 864 * Pre-map operations. Called with top/client locks acquired 865 * but not resource locks. 866 * 867 * @param[in] pServer 868 * @param[inout] pParams CPU mapping parameters 869 */ 870 NV_STATUS serverMap_Prologue(RsServer *pServer, RS_CPU_MAP_PARAMS *pMapParams); 871 872 /** 873 * Post-map operations. Called with top/client locks acquired 874 * but not resource locks. 875 * 876 * @param[in] pServer 877 * @param[inout] pParams CPU mapping parameters 878 */ 879 void serverMap_Epilogue(RsServer *pServer, RS_CPU_MAP_PARAMS *pMapParams); 880 881 /** 882 * Pre-unmap operations. Called with top/client locks acquired 883 * but not resource locks. 884 * 885 * @param[in] pServer 886 * @param[inout] pParams CPU mapping parameters 887 */ 888 NV_STATUS serverUnmap_Prologue(RsServer *pServer, RS_CPU_UNMAP_PARAMS *pUnmapParams); 889 890 /** 891 * Post-unmap operations. Called with top/client locks acquired 892 * but not resource locks. 893 * 894 * @param[in] pServer 895 * @param[inout] pParams CPU mapping parameters 896 */ 897 void serverUnmap_Epilogue(RsServer *pServer, RS_CPU_UNMAP_PARAMS *pUnmapParams); 898 899 /** 900 * Creates an inter-mapping between two resources 901 * 902 * Not all resources support mapping. 903 * 904 * @param[in] pServer This server instance 905 * @param[inout] pParams mapping parameters 906 */ 907 NV_STATUS serverInterMap(RsServer *pServer, RS_INTER_MAP_PARAMS *pParams); 908 909 /** 910 * Release an inter-mapping between two resources 911 * 912 * @param[in] pServer This server instance 913 * @param[in] pParams unmapping parameters 914 */ 915 NV_STATUS serverInterUnmap(RsServer *pServer, RS_INTER_UNMAP_PARAMS *pParams); 916 917 /** 918 * Pre-inter-map operations. Called with top/client locks acquired. 919 * This function acquires resource locks. 920 * 921 * @param[in] pServer 922 * @param[in] pMapperRef The resource that can be used to create the mapping 923 * @param[in] pMappableRef The resource that can be mapped 924 * @param[inout] pMapParams mapping parameters 925 * @param[inout] pReleaseFlags Flags that indicate which locks were taken 926 */ 927 NV_STATUS serverInterMap_Prologue(RsServer *pServer, RsResourceRef *pMapperRef, RsResourceRef *pMappableRef, RS_INTER_MAP_PARAMS *pMapParams, NvU32 *pReleaseFlags); 928 929 /** 930 * Post-inter-map operations. Called with top, client, and resource locks acquired. 931 * This function releases resource locks. 932 * 933 * @param[in] pServer 934 * @param[inout] pMapParams mapping parameters 935 * @param[inout] pReleaseFlags Flags that indicate which locks were taken 936 */ 937 void serverInterMap_Epilogue(RsServer *pServer, RS_INTER_MAP_PARAMS *pMapParams, NvU32 *pReleaseFlags); 938 939 /** 940 * Pre-inter-unmap operations. Called with top, client, and resource locks acquired. 941 * 942 * @param[in] pServer 943 * @param[inout] pParams mapping parameters 944 */ 945 NV_STATUS serverInterUnmap_Prologue(RsServer *pServer, RS_INTER_UNMAP_PARAMS *pUnmapParams); 946 947 /** 948 * Post-inter-unmap operations. Called with top, client, and resource locks acquired. 949 * 950 * @param[in] pServer 951 * @param[inout] pParams mapping parameters 952 */ 953 void serverInterUnmap_Epilogue(RsServer *pServer, RS_INTER_UNMAP_PARAMS *pUnmapParams); 954 955 /** 956 * Acquire a client pointer from a client handle. The caller is responsible for 957 * ensuring that lock ordering is not violated (otherwise there can be 958 * deadlock): clients must be locked in increasing order of client index (not 959 * handle). 960 * 961 * @param[in] pServer This server instance 962 * @param[in] hClient The client to acquire 963 * @param[in] lockAccess LOCK_ACCESS_READ or LOCK_ACCESS_WRITE 964 * @param[out] ppClient Pointer to the RsClient 965 */ 966 NV_STATUS serverAcquireClient(RsServer *pServer, NvHandle hClient, LOCK_ACCESS_TYPE lockAccess, RsClient **ppClient); 967 968 /** 969 * Release a client pointer 970 * 971 * @param[in] pServer This server instance 972 * @param[in] lockAccess LOCK_ACCESS_READ or LOCK_ACCESS_WRITE 973 * @param[in] pClient Pointer to the RsClient 974 */ 975 NV_STATUS serverReleaseClient(RsServer *pServer, LOCK_ACCESS_TYPE lockAccess, RsClient *pClient); 976 977 /** 978 * Get a client pointer from a client handle without taking any locks. 979 * 980 * @param[in] pServer This server instance 981 * @param[in] hClient The client to acquire 982 * @param[out] ppClient Pointer to the RsClient 983 */ 984 NV_STATUS serverGetClientUnderLock(RsServer *pServer, NvHandle hClient, RsClient **ppClient); 985 986 /** 987 * Get the count of clients allocated under this resource server 988 * 989 * @param[in] pServer This server instance 990 */ 991 NvU32 serverGetClientCount(RsServer *pServer); 992 993 /** 994 * Get the count of resources allocated under this resource server 995 * 996 * @param[in] pServer This server instance 997 */ 998 NvU64 serverGetResourceCount(RsServer *pServer); 999 1000 /** 1001 * Swap a TLS call context entry and increment the TLS entry refcount. 1002 * A new TLS entry for call context will be allocated if necessary. 1003 * 1004 * @note This should be paired with a corresponding resservRestoreTlsCallContext call 1005 */ 1006 NV_STATUS resservSwapTlsCallContext(CALL_CONTEXT **ppOldCallContext, CALL_CONTEXT *pNewCallContext); 1007 1008 /** 1009 * Get the current TLS call context. This will not increment a refcount on the TLS entry. 1010 */ 1011 CALL_CONTEXT *resservGetTlsCallContext(void); 1012 1013 /** 1014 * Set a TLS call context entry and decrement the TLS entry refcount. 1015 * @note This should be paired with a corresponding resservSwapTlsCallContext call 1016 */ 1017 NV_STATUS resservRestoreTlsCallContext(CALL_CONTEXT *pOldCallContext); 1018 1019 /** 1020 * Find a resource reference of a given type from the TLS call context 1021 * @param[in] internalClassId Only return a reference if it matches this type 1022 * @param[in] bSearchAncestors Search parents of the call context resource ref 1023 */ 1024 RsResourceRef *resservGetContextRefByType(NvU32 internalClassId, NvBool bSearchAncestors); 1025 1026 #ifdef __cplusplus 1027 } 1028 #endif 1029 1030 #endif 1031