1 
2 #ifndef _G_RS_SERVER_NVOC_H_
3 #define _G_RS_SERVER_NVOC_H_
4 #include "nvoc/runtime.h"
5 
6 // Version of generated metadata structures
7 #ifdef NVOC_METADATA_VERSION
8 #undef NVOC_METADATA_VERSION
9 #endif
10 #define NVOC_METADATA_VERSION 0
11 
12 #ifdef __cplusplus
13 extern "C" {
14 #endif
15 
16 /*
17  * SPDX-FileCopyrightText: Copyright (c) 2015-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
18  * SPDX-License-Identifier: MIT
19  *
20  * Permission is hereby granted, free of charge, to any person obtaining a
21  * copy of this software and associated documentation files (the "Software"),
22  * to deal in the Software without restriction, including without limitation
23  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
24  * and/or sell copies of the Software, and to permit persons to whom the
25  * Software is furnished to do so, subject to the following conditions:
26  *
27  * The above copyright notice and this permission notice shall be included in
28  * all copies or substantial portions of the Software.
29  *
30  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
31  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
32  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
33  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
34  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
35  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
36  * DEALINGS IN THE SOFTWARE.
37  */
38 
39 #pragma once
40 #include "g_rs_server_nvoc.h"
41 
42 #ifndef _RS_SERVER_H_
43 #define _RS_SERVER_H_
44 
45 #include "nvport/nvport.h"
46 #include "resserv/resserv.h"
47 #include "resserv/rs_client.h"
48 #include "nvoc/runtime.h"
49 
50 #ifdef __cplusplus
51 extern "C" {
52 #endif
53 
54 enum CLIENT_LOCK_TYPE
55 {
56     CLIENT_LOCK_SPECIFIC, // For locking specific RM clients encoded in the API
57     CLIENT_LOCK_ALL       // For locking all RM clients currently in use
58 };
59 
60 /**
61  * @defgroup RsServer
62  * @addtogroup RsServer
63  * @{*/
64 
65 /**
66  * Book-keeping for individual client locks
67  */
68 struct CLIENT_ENTRY
69 {
70     PORT_RWLOCK    *pLock;
71     struct RsClient       *pClient;
72     NvHandle        hClient;
73     NvU64           lockOwnerTid; ///< Thread id of the lock owner
74     NvU32           refCount;
75     NvBool          bPendingFree;
76     ListNode        node;
77 
78 #if LOCK_VAL_ENABLED
79     LOCK_VAL_LOCK   lockVal;
80 #endif
81 };
82 
83 MAKE_INTRUSIVE_LIST(RsClientList, CLIENT_ENTRY, node);
84 MAKE_LIST(RsLockedClientList, CLIENT_ENTRY*);
85 
86 /**
87  * Base-class for objects that are shared among multiple
88  * RsResources (including RsResources from other clients)
89  */
90 
91 // Private field names are wrapped in PRIVATE_FIELD, which does nothing for
92 // the matching C source file, but causes diagnostics to be issued if another
93 // source file references the field.
94 #ifdef NVOC_RS_SERVER_H_PRIVATE_ACCESS_ALLOWED
95 #define PRIVATE_FIELD(x) x
96 #else
97 #define PRIVATE_FIELD(x) NVOC_PRIVATE_FIELD(x)
98 #endif
99 
100 
101 struct RsShared {
102 
103     // Metadata
104     const struct NVOC_RTTI *__nvoc_rtti;
105 
106     // Parent (i.e. superclass or base class) object pointers
107     struct Object __nvoc_base_Object;
108 
109     // Ancestor object pointers for `staticCast` feature
110     struct Object *__nvoc_pbase_Object;    // obj super
111     struct RsShared *__nvoc_pbase_RsShared;    // shr
112 
113     // Data members
114     NvS32 refCount;
115     struct MapNode node;
116 };
117 
118 #ifndef __NVOC_CLASS_RsShared_TYPEDEF__
119 #define __NVOC_CLASS_RsShared_TYPEDEF__
120 typedef struct RsShared RsShared;
121 #endif /* __NVOC_CLASS_RsShared_TYPEDEF__ */
122 
123 #ifndef __nvoc_class_id_RsShared
124 #define __nvoc_class_id_RsShared 0x830542
125 #endif /* __nvoc_class_id_RsShared */
126 
127 // Casting support
128 extern const struct NVOC_CLASS_DEF __nvoc_class_def_RsShared;
129 
130 #define __staticCast_RsShared(pThis) \
131     ((pThis)->__nvoc_pbase_RsShared)
132 
133 #ifdef __nvoc_rs_server_h_disabled
134 #define __dynamicCast_RsShared(pThis) ((RsShared*)NULL)
135 #else //__nvoc_rs_server_h_disabled
136 #define __dynamicCast_RsShared(pThis) \
137     ((RsShared*)__nvoc_dynamicCast(staticCast((pThis), Dynamic), classInfo(RsShared)))
138 #endif //__nvoc_rs_server_h_disabled
139 
140 NV_STATUS __nvoc_objCreateDynamic_RsShared(RsShared**, Dynamic*, NvU32, va_list);
141 
142 NV_STATUS __nvoc_objCreate_RsShared(RsShared**, Dynamic*, NvU32);
143 #define __objCreate_RsShared(ppNewObj, pParent, createFlags) \
144     __nvoc_objCreate_RsShared((ppNewObj), staticCast((pParent), Dynamic), (createFlags))
145 
146 
147 // Wrapper macros
148 
149 // Dispatch functions
150 NV_STATUS shrConstruct_IMPL(struct RsShared *arg_pShared);
151 
152 #define __nvoc_shrConstruct(arg_pShared) shrConstruct_IMPL(arg_pShared)
153 void shrDestruct_IMPL(struct RsShared *pShared);
154 
155 #define __nvoc_shrDestruct(pShared) shrDestruct_IMPL(pShared)
156 #undef PRIVATE_FIELD
157 
158 MAKE_INTRUSIVE_MAP(RsSharedMap, RsShared, node);
159 
160 /**
161  * Utility class for objects that can reference
162  * multiple client handle spaces. Free's and control calls
163  * that occur on objects which reference an RsSession will
164  * need to acquire pLock first.
165  */
166 
167 // Private field names are wrapped in PRIVATE_FIELD, which does nothing for
168 // the matching C source file, but causes diagnostics to be issued if another
169 // source file references the field.
170 #ifdef NVOC_RS_SERVER_H_PRIVATE_ACCESS_ALLOWED
171 #define PRIVATE_FIELD(x) x
172 #else
173 #define PRIVATE_FIELD(x) NVOC_PRIVATE_FIELD(x)
174 #endif
175 
176 
177 struct RsSession {
178 
179     // Metadata
180     const struct NVOC_RTTI *__nvoc_rtti;
181 
182     // Parent (i.e. superclass or base class) object pointers
183     struct RsShared __nvoc_base_RsShared;
184 
185     // Ancestor object pointers for `staticCast` feature
186     struct Object *__nvoc_pbase_Object;    // obj super^2
187     struct RsShared *__nvoc_pbase_RsShared;    // shr super
188     struct RsSession *__nvoc_pbase_RsSession;    // session
189 
190     // Vtable with 2 per-object function pointers
191     void (*__sessionRemoveDependant__)(struct RsSession * /*this*/, struct RsResourceRef *);  // virtual
192     void (*__sessionRemoveDependency__)(struct RsSession * /*this*/, struct RsResourceRef *);  // virtual
193 
194     // Data members
195     PORT_RWLOCK *pLock;
196     NvBool bValid;
197     RsResourceRefList dependencies;
198     RsResourceRefList dependants;
199 };
200 
201 #ifndef __NVOC_CLASS_RsSession_TYPEDEF__
202 #define __NVOC_CLASS_RsSession_TYPEDEF__
203 typedef struct RsSession RsSession;
204 #endif /* __NVOC_CLASS_RsSession_TYPEDEF__ */
205 
206 #ifndef __nvoc_class_id_RsSession
207 #define __nvoc_class_id_RsSession 0x830d90
208 #endif /* __nvoc_class_id_RsSession */
209 
210 // Casting support
211 extern const struct NVOC_CLASS_DEF __nvoc_class_def_RsSession;
212 
213 #define __staticCast_RsSession(pThis) \
214     ((pThis)->__nvoc_pbase_RsSession)
215 
216 #ifdef __nvoc_rs_server_h_disabled
217 #define __dynamicCast_RsSession(pThis) ((RsSession*)NULL)
218 #else //__nvoc_rs_server_h_disabled
219 #define __dynamicCast_RsSession(pThis) \
220     ((RsSession*)__nvoc_dynamicCast(staticCast((pThis), Dynamic), classInfo(RsSession)))
221 #endif //__nvoc_rs_server_h_disabled
222 
223 NV_STATUS __nvoc_objCreateDynamic_RsSession(RsSession**, Dynamic*, NvU32, va_list);
224 
225 NV_STATUS __nvoc_objCreate_RsSession(RsSession**, Dynamic*, NvU32);
226 #define __objCreate_RsSession(ppNewObj, pParent, createFlags) \
227     __nvoc_objCreate_RsSession((ppNewObj), staticCast((pParent), Dynamic), (createFlags))
228 
229 
230 // Wrapper macros
231 #define sessionRemoveDependant_FNPTR(pSession) pSession->__sessionRemoveDependant__
232 #define sessionRemoveDependant(pSession, pResourceRef) sessionRemoveDependant_DISPATCH(pSession, pResourceRef)
233 #define sessionRemoveDependency_FNPTR(pSession) pSession->__sessionRemoveDependency__
234 #define sessionRemoveDependency(pSession, pResourceRef) sessionRemoveDependency_DISPATCH(pSession, pResourceRef)
235 
236 // Dispatch functions
sessionRemoveDependant_DISPATCH(struct RsSession * pSession,struct RsResourceRef * pResourceRef)237 static inline void sessionRemoveDependant_DISPATCH(struct RsSession *pSession, struct RsResourceRef *pResourceRef) {
238     pSession->__sessionRemoveDependant__(pSession, pResourceRef);
239 }
240 
sessionRemoveDependency_DISPATCH(struct RsSession * pSession,struct RsResourceRef * pResourceRef)241 static inline void sessionRemoveDependency_DISPATCH(struct RsSession *pSession, struct RsResourceRef *pResourceRef) {
242     pSession->__sessionRemoveDependency__(pSession, pResourceRef);
243 }
244 
245 void sessionRemoveDependant_IMPL(struct RsSession *pSession, struct RsResourceRef *pResourceRef);
246 
247 void sessionRemoveDependency_IMPL(struct RsSession *pSession, struct RsResourceRef *pResourceRef);
248 
249 NV_STATUS sessionConstruct_IMPL(struct RsSession *arg_pSession);
250 
251 #define __nvoc_sessionConstruct(arg_pSession) sessionConstruct_IMPL(arg_pSession)
252 void sessionDestruct_IMPL(struct RsSession *pSession);
253 
254 #define __nvoc_sessionDestruct(pSession) sessionDestruct_IMPL(pSession)
255 NV_STATUS sessionAddDependant_IMPL(struct RsSession *pSession, struct RsResourceRef *pResourceRef);
256 
257 #ifdef __nvoc_rs_server_h_disabled
sessionAddDependant(struct RsSession * pSession,struct RsResourceRef * pResourceRef)258 static inline NV_STATUS sessionAddDependant(struct RsSession *pSession, struct RsResourceRef *pResourceRef) {
259     NV_ASSERT_FAILED_PRECOMP("RsSession was disabled!");
260     return NV_ERR_NOT_SUPPORTED;
261 }
262 #else //__nvoc_rs_server_h_disabled
263 #define sessionAddDependant(pSession, pResourceRef) sessionAddDependant_IMPL(pSession, pResourceRef)
264 #endif //__nvoc_rs_server_h_disabled
265 
266 NV_STATUS sessionAddDependency_IMPL(struct RsSession *pSession, struct RsResourceRef *pResourceRef);
267 
268 #ifdef __nvoc_rs_server_h_disabled
sessionAddDependency(struct RsSession * pSession,struct RsResourceRef * pResourceRef)269 static inline NV_STATUS sessionAddDependency(struct RsSession *pSession, struct RsResourceRef *pResourceRef) {
270     NV_ASSERT_FAILED_PRECOMP("RsSession was disabled!");
271     return NV_ERR_NOT_SUPPORTED;
272 }
273 #else //__nvoc_rs_server_h_disabled
274 #define sessionAddDependency(pSession, pResourceRef) sessionAddDependency_IMPL(pSession, pResourceRef)
275 #endif //__nvoc_rs_server_h_disabled
276 
277 NV_STATUS sessionCheckLocksForAdd_IMPL(struct RsSession *pSession, struct RsResourceRef *pResourceRef);
278 
279 #ifdef __nvoc_rs_server_h_disabled
sessionCheckLocksForAdd(struct RsSession * pSession,struct RsResourceRef * pResourceRef)280 static inline NV_STATUS sessionCheckLocksForAdd(struct RsSession *pSession, struct RsResourceRef *pResourceRef) {
281     NV_ASSERT_FAILED_PRECOMP("RsSession was disabled!");
282     return NV_ERR_NOT_SUPPORTED;
283 }
284 #else //__nvoc_rs_server_h_disabled
285 #define sessionCheckLocksForAdd(pSession, pResourceRef) sessionCheckLocksForAdd_IMPL(pSession, pResourceRef)
286 #endif //__nvoc_rs_server_h_disabled
287 
288 void sessionCheckLocksForRemove_IMPL(struct RsSession *pSession, struct RsResourceRef *pResourceRef);
289 
290 #ifdef __nvoc_rs_server_h_disabled
sessionCheckLocksForRemove(struct RsSession * pSession,struct RsResourceRef * pResourceRef)291 static inline void sessionCheckLocksForRemove(struct RsSession *pSession, struct RsResourceRef *pResourceRef) {
292     NV_ASSERT_FAILED_PRECOMP("RsSession was disabled!");
293 }
294 #else //__nvoc_rs_server_h_disabled
295 #define sessionCheckLocksForRemove(pSession, pResourceRef) sessionCheckLocksForRemove_IMPL(pSession, pResourceRef)
296 #endif //__nvoc_rs_server_h_disabled
297 
298 #undef PRIVATE_FIELD
299 
300 
301 // Iterator data structure to save state while walking through a map
302 struct RS_SHARE_ITERATOR
303 {
304     RsSharedMapIter mapIt;
305     NvU32 internalClassId;
306     struct RsShared *pShared;          ///< Share that is being iterated over
307 };
308 
309 /**
310  * Top-level structure that RMAPI and RM interface with
311  *
312  * This class is all that needs to be allocated to use the resource server
313  * library.
314  *
315  * The RsServer interface should be kept as narrow as possible. Map and
316  * MapTo are added because <1> the unmap variants operate in addresses and not
317  * handles and <2> having explicit knowledge of map operations in the server is
318  * helpful when dealing with multiple levels of address spaces (e.g., guest
319  * user-mode, guest kernel-mode, host kernel-mode).
320  */
321 struct RsServer
322 {
323     /**
324      * Privilege level determines what objects a server is allowed to allocate, and
325      * also determines whether additional handle validation needs to be performed.
326      */
327     RS_PRIV_LEVEL             privilegeLevel;
328 
329     RsClientList             *pClientSortedList; ///< Bucket if linked List of clients (and their locks) owned by this server
330     NvU32                     clientCurrentHandleIndex;
331 
332     NvBool                    bConstructed; ///< Determines whether the server is ready to be used
333     PORT_MEM_ALLOCATOR       *pAllocator; ///< Allocator to use for all objects allocated by the server
334 
335     PORT_SPINLOCK            *pClientListLock; ///< Lock that needs to be taken when accessing the client list
336 
337     PORT_SPINLOCK            *pShareMapLock; ///< Lock that needs to be taken when accessing the shared resource map
338     RsSharedMap               shareMap; ///< Map of shared resources
339 
340 #if (RS_STANDALONE)
341     NvU64                     topLockOwnerTid; ///< Thread id of top-lock owner
342     PORT_RWLOCK              *pTopLock; ///< Top-level resource server lock
343     PORT_RWLOCK              *pResLock; ///< Resource-level resource server lock
344 #if LOCK_VAL_ENABLED
345     LOCK_VAL_LOCK             topLockVal;
346     LOCK_VAL_LOCK             resLockVal;
347 #endif
348 #endif
349 
350     /// Print out a list of all resources that will be freed when a free request is made
351     NvBool                    bDebugFreeList;
352 
353     /// If true, control call param copies will be performed outside the top/api lock
354     NvBool                    bUnlockedParamCopy;
355 
356     // If true, calls annotated with ROUTE_TO_PHYISCAL will not grab global gpu locks
357     // (and the readonly API lock).
358     NvBool                    bRouteToPhysicalLockBypass;
359 
360     /**
361      * Setting this flag to false disables any attempts to
362      * automatically acquire access rights or to control access to resources by
363      * checking for access rights.
364      */
365     NvBool                    bRsAccessEnabled;
366 
367     /**
368      * Set to thread ID of the thread that locked all clients.
369      */
370     NvU64                     allClientLockOwnerTid;
371 
372     /**
373      * Mask of interfaces (RS_API_*) that will use a read-only top lock by default
374      */
375     NvU32                     roTopLockApiMask;
376 
377     /// Share policies which clients default to when no other policies are used
378     RsShareList               defaultInheritedSharePolicyList;
379     /// Share policies to apply to all shares, regardless of other policies
380     RsShareList               globalInternalSharePolicyList;
381 
382     NvU32                     internalHandleBase;
383     NvU32                     clientHandleBase;
384 
385     NvU32                     activeClientCount;
386     NvU64                     activeResourceCount;
387 
388     /// List of clients that are de-activated and pending free
389     RsDisabledClientList      disabledClientList;
390     struct RsClient                 *pNextDisabledClient;
391     PORT_SPINLOCK            *pDisabledClientListLock;
392 
393     /**
394      * List of client entries locked by serverLockAllClients
395      * This list is required for locking all clients in order to avoid races with
396      * other paths creating/destroying paths in parallel WITHOUT holding the API lock.
397      * Ideally, there shouldn't be any other such paths but the RTD3/PM path does do
398      * this. CORERM-6052 tracks investigating that and potentially fixing the locking
399      * there.
400      */
401     RsLockedClientList        lockedClientList;
402 };
403 
404 /**
405  * Construct a server instance. This must be performed before any other server
406  * operation.
407  *
408  * @param[in]   pServer This server instance
409  * @param[in]   privilegeLevel Privilege level for this resource server instance
410  * @param[in]   maxDomains Maximum number of domains to support, or 0 for the default
411  */
412 NV_STATUS serverConstruct(RsServer *pServer, RS_PRIV_LEVEL privilegeLevel, NvU32 maxDomains);
413 
414 /**
415  * Destroy a server instance. Destructing a server does not guarantee that child domains
416  * and clients will be appropriately freed. serverFreeDomain should be explicitly called
417  * on all allocated domains to ensure all clients and resources get cleaned up.
418  *
419  * @param[in]   pServer This server instance
420  */
421 NV_STATUS serverDestruct(RsServer *pServer);
422 
423 /**
424  * Allocate a domain handle. Domain handles are used to track clients created by a domain.
425  *
426  * @param[in]   pServer This server instance
427  * @param[in]   hParentDomain
428  * @param[in]   pAccessControl
429  * @param[out]  phDomain
430  *
431  */
432 NV_STATUS serverAllocDomain(RsServer *pServer, NvU32 hParentDomain, ACCESS_CONTROL *pAccessControl, NvHandle *phDomain);
433 
434 /**
435  * Verify that the calling user is allowed to perform the access. This check only
436  * applies to calls from RING_USER or RING_KERNEL. No check is performed in
437  * RING_HOST.
438  *
439  * @param[in]   pServer This server instance
440  * @param[in]   hDomain
441  * @param[in]   hClient
442  *
443  */
444 NV_STATUS serverValidate(RsServer *pServer, NvU32 hDomain, NvHandle hClient);
445 
446 /**
447  * Verify that the domain has sufficient permission to allocate the given class.
448  * @param[in] pServer
449  * @param[in] hDomain
450  * @param[in] externalClassId External resource class id
451  */
452 NV_STATUS serverValidateAlloc(RsServer *pServer, NvU32 hDomain, NvU32 externalClassId);
453 
454 /**
455  * Free a domain handle. All clients of this domain will be freed.
456  *
457  * @param[in]   pServer This server instance
458  * @param[in]   hDomain The handle of the domain to free
459  */
460 NV_STATUS serverFreeDomain(RsServer *pServer, NvHandle hDomain);
461 
462 /**
463  * Allocate a client handle. A client handle is required to allocate resources.
464  *
465  * @param[in]    pServer This server instance
466  * @param[inout] pParams Client allocation parameters
467  */
468 NV_STATUS serverAllocClient(RsServer *pServer, RS_RES_ALLOC_PARAMS_INTERNAL *pParams);
469 
470 /**
471  * Free a client handle. All resources references owned by the client will be
472  * freed.
473  *
474  * It is invalid to attempt to free a client from a user other than the one
475  * that allocated it.
476  *
477  * @param[in]   pServer This server instance
478  * @param[in]   pParams Client free params
479  */
480 NV_STATUS serverFreeClient(RsServer *pServer, RS_CLIENT_FREE_PARAMS* pParams);
481 
482 /**
483  * Mark a list of client handles as disabled. All CPU mappings owned by that
484  * client will be unmapped immediate, and the client will be marked as disabled.
485  * A call to @ref serverFreeDisabledClients will then free all such clients.
486  *
487  * It is invalid to attempt to free a client from a user other than the one
488  * that allocated it.
489  *
490  * @param[in]   pServer This server instance
491  * @param[in]   phClientList The list of client handles to disable
492  * @param[in]   numClients The number of clients in the list
493  * @param[in]   freeState User-defined free state
494  * @param[in]   pSecInfo Security Info
495  *
496  */
497 NV_STATUS serverMarkClientListDisabled(RsServer *pServer, NvHandle *phClientList, NvU32 numClients, NvU32 freeState, API_SECURITY_INFO *pSecInfo);
498 
499 /**
500  * Frees all currently disabled clients. All resources references owned by
501  * any of the clients will be freed.
502  * All priority resources will be freed first across all listed clients.
503  *
504  * NOTE: may return NV_WARN_MORE_PROCESSING_REQUIRED if not all clients were freed
505  *
506  * @param[in]   pServer   This server instance
507  * @param[in]   freeState User-defined free state
508  * @param[in]   limit     Max number of iterations to make returning; 0 means no limit
509  *
510  */
511 NV_STATUS serverFreeDisabledClients(RsServer *pServer, NvU32 freeState, NvU32 limit);
512 
513 /**
514  * Allocate a resource.
515  *
516  * It is invalid to attempt to allocate a client from a user other than the one
517  * that allocated it.
518  *
519  * @param[in]    pServer This server instance
520  * @param[inout] pParams The allocation parameters
521  */
522 NV_STATUS serverAllocResource(RsServer *pServer, RS_RES_ALLOC_PARAMS *params);
523 
524 /**
525  * Allocate a ref-counted resource share.
526  *
527  * @param[in] pServer
528  * @param[in] pClassInfo NVOC class info for the shared class (must derive from RsShared)
529  * @param[out] ppShare Allocated share
530  */
531 NV_STATUS serverAllocShare(RsServer *pServer, const NVOC_CLASS_INFO* pClassInfo, struct RsShared **ppShare);
532 
533 /**
534  * Allocate a ref-counted resource share with Halspec parent.
535  *
536  * @param[in] pServer
537  * @param[in] pClassInfo NVOC class info for the shared class (must derive from RsShared)
538  * @param[out] ppShare Allocated share
539  * @param[in] pHalspecParent Parent object whose Halspec can be used for the shared class object
540  */
541 NV_STATUS serverAllocShareWithHalspecParent(RsServer *pServer, const NVOC_CLASS_INFO* pClassInfo, struct RsShared **ppShare, struct Object *pHalspecParent);
542 
543 /**
544  * Get the ref-count of a resource share.
545  *
546  * @param[in] pServer
547  * @param[in] pShare Resource share
548  */
549 NvS32 serverGetShareRefCount(RsServer *pServer, struct RsShared *pShare);
550 
551 /**
552  * Increment the ref-count of a resource share.
553  *
554  * @param[in] pServer
555  * @param[in] pShare Resource share
556  */
557 NV_STATUS serverRefShare(RsServer *pServer, struct RsShared *pShare);
558 
559 /**
560  * Decrement the ref-count of a resource share. If the ref-count
561  * has reached zero, the resource share will be freed.
562  *
563  * @param[in] pServer
564  * @param[in] pShare Resource share
565  */
566 NV_STATUS serverFreeShare(RsServer *pServer, struct RsShared *pShare);
567 
568 /**
569  * Get an iterator to the elements in the server's shared object map
570  * @param[in] pServer
571  * @param[in] internalClassId If non-zero, only RsShared that are (or can be
572  *                            derived from) the specified class will be returned
573  */
574 RS_SHARE_ITERATOR serverShareIter(RsServer *pServer, NvU32 internalClassId);
575 
576 /**
577  * Get an iterator to the elements in the server's shared object map
578  */
579 NvBool serverShareIterNext(RS_SHARE_ITERATOR*);
580 
581 /**
582  * Set fixed client handle base in case clients wants to use a different
583  * base for client allocations
584  * @param[in] pServer
585  * @param[in] clientHandleBase
586  */
587 NV_STATUS serverSetClientHandleBase(RsServer *pServer, NvU32 clientHandleBase);
588 
589 /**
590  * Deserialize parameters for servicing command
591  *
592  * @param[in] pCallContext
593  * @param[in] cmd
594  * @param[in/out] ppParams
595  * @param[in/out] pParamsSize
596  * @param[in] flags
597  */
598 NV_STATUS serverDeserializeCtrlDown(CALL_CONTEXT *pCallContext, NvU32 cmd, void **ppParams, NvU32 *pParamsSize, NvU32 *flags);
599 
600 /**
601  * Serialize parameters for servicing command
602  *
603  * @param[in] pCallContext
604  * @param[in] cmd
605  * @param[in/out] ppParams
606  * @param[in/out] pParamsSize
607  * @param[in] flags
608  */
609 NV_STATUS serverSerializeCtrlDown(CALL_CONTEXT *pCallContext, NvU32 cmd, void **ppParams, NvU32 *pParamsSize, NvU32 *flags);
610 
611 /**
612  * Deserialize parameters for returning from command
613  *
614  * @param[in] pCallContext
615  * @param[in] cmd
616  * @param[out] ppParams
617  * @param[out] pParamsSize
618  * @param[in] flags
619  */
620 NV_STATUS serverDeserializeCtrlUp(CALL_CONTEXT *pCallContext, NvU32 cmd, void **ppParams, NvU32 *pParamsSize, NvU32 *flags);
621 
622 /**
623  * Serialize parameters for returning from command
624  *
625  * @param[in] pCallContext
626  * @param[in] cmd
627  * @param[out] ppParams
628  * @param[out] pParamsSize
629  * @param[in] flags
630  */
631 NV_STATUS serverSerializeCtrlUp(CALL_CONTEXT *pCallContext, NvU32 cmd, void **ppParams, NvU32 *pParamsSize, NvU32 *flags);
632 
633 /**
634  * Unset flag for reserializing control before going to GSP
635  * Used if kernel control servicing passes params to GSP without changing them
636  *
637  * @param[in] pCallContext
638  */
639 void serverDisableReserializeControl(CALL_CONTEXT *pCallContext);
640 
641 /**
642  * Serialize parameters for allocating
643  *
644  * @param[in] pCallContext
645  * @param[in] classId
646  * @param[in/out] ppParams
647  * @param[out] pParamsSize
648  * @param[in] flags
649  */
650 NV_STATUS serverSerializeAllocDown(CALL_CONTEXT *pCallContext, NvU32 classId, void **ppParams, NvU32 *pParamsSize, NvU32 *flags);
651 
652 /**
653  * Deserialize parameters for allocating
654  *
655  * @param[in] pCallContext
656  * @param[in] classId
657  * @param[in/out] ppParams
658  * @param[in/out] pParamsSize
659  * @param[in] flags
660  */
661 NV_STATUS serverDeserializeAllocDown(CALL_CONTEXT *pCallContext, NvU32 classId, void **ppParams, NvU32 *pParamsSize, NvU32 *flags);
662 
663 /**
664  * Serialize parameters for returning from allocating
665  *
666  * @param[in] pCallContext
667  * @param[in] classId
668  * @param[out] ppParams
669  * @param[out] pParamsSize
670  * @param[in] flags
671  */
672 NV_STATUS serverSerializeAllocUp(CALL_CONTEXT *pCallContext, NvU32 classId, void **ppParams, NvU32 *pParamsSize, NvU32 *flags);
673 
674 /**
675  * Deserialize parameters for returning from allocating
676  *
677  * @param[in] pCallContext
678  * @param[in] classId
679  * @param[out] ppParams
680  * @param[out] pParamsSize
681  * @param[in] flags
682  */
683 NV_STATUS serverDeserializeAllocUp(CALL_CONTEXT *pCallContext, NvU32 classId, void **ppParams, NvU32 *pParamsSize, NvU32 *flags);
684 
685 /**
686  * Free finn structures allocated for serializing/deserializing
687  *
688  * @param[in] pCallContext
689  * @param[in] pParams
690  */
691 void serverFreeSerializeStructures(CALL_CONTEXT *pCallContext, void *pParams);
692 
693 /**
694  * Return an available client handle for new client allocation
695  *
696  * @param[in] pServer This server instance
697  * @param[in] bInternalHandle Client is an RM internal client
698  * @param[in] pSecInfo Security context of this client allocation
699  */
700 extern NvU32 serverAllocClientHandleBase(RsServer *pServer, NvBool bInternalHandle, API_SECURITY_INFO *pSecInfo);
701 
702 /**
703  * Allocate a resource. Assumes top-level lock has been taken.
704  *
705  * It is invalid to attempt to allocate a client from a user other than the one
706  * that allocated it. User-implemented.
707  *
708  * @param[in]    pServer This server instance
709  * @param[inout] pParams The allocation parameters
710  */
711 extern NV_STATUS serverAllocResourceUnderLock(RsServer *pServer, RS_RES_ALLOC_PARAMS *pAllocParams);
712 
713 /**
714  * Call Free RPC for given resource. Assumes top-level lock has been taken.
715  *
716  * @param[in]    pServer This server instance
717  * @param[inout] pFreeParams The Free parameters
718  */
719 extern NV_STATUS serverFreeResourceRpcUnderLock(RsServer *pServer, RS_RES_FREE_PARAMS *pFreeParams);
720 
721 /**
722  * Copy-in parameters supplied by caller, and initialize API state. User-implemented.
723  * @param[in]   pServer
724  * @param[in]   pAllocParams    Resource allocation parameters
725  * @param[out]  ppApiState      User-defined API_STATE; should be allocated by this function
726  */
727 extern NV_STATUS serverAllocApiCopyIn(RsServer *pServer, RS_RES_ALLOC_PARAMS_INTERNAL *pAllocParams, API_STATE **ppApiState);
728 
729 /**
730  * Copy-out parameters supplied by caller, and release API state. User-implemented.
731  * @param[in]   pServer
732  * @param[in]   status      Status of allocation request
733  * @param[in]   pApiState   API_STATE for the allocation
734  */
735 extern NV_STATUS serverAllocApiCopyOut(RsServer *pServer, NV_STATUS status, API_STATE *pApiState);
736 
737 /**
738  * Obtain a second client handle to lock if required for the allocation.
739  * @param[in]   externalClassId External class ID of resource
740  * @param[in]   pAllocParams    Class-specific allocation parameters
741  * @param[out]  phSecondClient  Second client handle to lock on success
742  *
743  * @return NV_OK on success
744            NV_ERR_INVALID_STATE if allocation is incorrectly configured with RS_FLAGS_DUAL_CLIENT_LOCK without having updated this function.
745  */
746 extern NV_STATUS serverAllocLookupSecondClient(NvU32 externalClassId, void *pAllocParams, NvHandle *phSecondClient);
747 
748 /**
749  * Obtain a second client handle to lock if required for the control (DISCOURAGED).
750  * @param[in]    cmd            Control call ID
751  * @param[in]    pControlParams Control-specific parameters
752  * @param[in]    pCookie        Control call cookie to check flags for
753  * @param[out]   phSecondClient Second client handle to lock on success
754  *
755  * @return NV_OK on success
756            NV_ERR_INVALID_STATE if allocation is incorrectly configured with RMCTRL_FLAGS_DUAL_CLIENT_LOCK without having updated this function.
757  */
758 extern NV_STATUS serverControlLookupSecondClient(NvU32 cmd, void *pControlParams, RS_CONTROL_COOKIE *pCookie, NvHandle *phSecondClient);
759 
760 /**
761  * Acquires a top-level lock. User-implemented.
762  * @param[in]       pServer
763  * @param[in]       access          LOCK_ACCESS_READ or LOCK_ACCESS_WRITE
764  * @param[inout]    pLockInfo       Lock state
765  * @param[inout]    pReleaseFlags   Output flags indicating the locks that need to be released
766  */
767 extern NV_STATUS serverTopLock_Prologue(RsServer *pServer, LOCK_ACCESS_TYPE access, RS_LOCK_INFO *pLockInfo, NvU32 *pReleaseFlags);
768 
769 /**
770  * Releases a top-level lock. User-implemented.
771  * @param[in]       pServer
772  * @param[in]       access          LOCK_ACCESS_READ or LOCK_ACCESS_WRITE
773  * @param[inout]    pLockInfo       Lock state
774  * @param[inout]    pReleaseFlags   Flags indicating the locks that need to be released
775  */
776 extern void serverTopLock_Epilogue(RsServer *pServer, LOCK_ACCESS_TYPE access, RS_LOCK_INFO *pLockInfo, NvU32 *pReleaseFlags);
777 
778 /**
779  * Acquires a session lock.
780  * @param[in]       access          LOCK_ACCESS_READ or LOCK_ACCESS_WRITE
781  * @param[in]       pResourceRef    Resource reference to take session locks on
782  * @param[inout]    pLockInfo       Lock state
783  */
784 extern NV_STATUS serverSessionLock_Prologue(LOCK_ACCESS_TYPE access, RsResourceRef *pResourceRef, RS_LOCK_INFO *pLockInfo, NvU32 *pReleaseFlags);
785 
786 /**
787  * Releases a session lock.
788  * @param[in]       pServer
789  * @param[in]       access          LOCK_ACCESS_READ or LOCK_ACCESS_WRITE
790  * @param[inout]    pLockInfo       Lock state
791  * @param[inout]    pReleaseFlags   Flags indicating the locks that need to be released
792  */
793 extern void serverSessionLock_Epilogue(RsServer *pServer, LOCK_ACCESS_TYPE access, RS_LOCK_INFO *pLockInfo, NvU32 *pReleaseFlags);
794 
795 /**
796  * Acquires a resource-level lock. User-implemented.
797  * @param[in]       pServer
798  * @param[in]       access          LOCK_ACCESS_READ or LOCK_ACCESS_WRITE
799  * @param[inout]    pLockInfo       Lock state
800  * @param[inout]    pReleaseFlags   Output flags indicating the locks that need to be released
801  */
802 extern NV_STATUS serverResLock_Prologue(RsServer *pServer, LOCK_ACCESS_TYPE access, RS_LOCK_INFO *pLockInfo, NvU32 *pReleaseFlags);
803 
804 /**
805  * Releases a resource-level lock. User-implemented.
806  * @param[in]       pServer
807  * @param[in]       access          LOCK_ACCESS_READ or LOCK_ACCESS_WRITE
808  * @param[inout]    pLockInfo       Lock state
809  * @param[inout]    pReleaseFlags   Flags indicating the locks that need to be released
810  */
811 extern void serverResLock_Epilogue(RsServer *pServer, LOCK_ACCESS_TYPE access, RS_LOCK_INFO *pLockInfo, NvU32 *pReleaseFlags);
812 
813 /**
814  * Acquire the client list lock. The caller is responsible for
815  * ensuring that lock ordering is not violated (otherwise there can be
816  * deadlock): the client list lock must always be released without acquiring any
817  * subsequent locks.
818  *
819  * @param[in]   pServer This server instance
820  */
821 void serverAcquireClientListLock(RsServer *pServer);
822 
823 /**
824  * Release the client list lock.
825  *
826  * @param[in]   pServer This server instance
827  */
828 void serverReleaseClientListLock(RsServer *pServer);
829 
830 /**
831  * WAR for additional tasks that must be performed after resource-level locks are released. User-implemented.
832  * @param[inout]    status       Allocation status
833  * @param[in]       bClientAlloc Caller is attempting to allocate a client
834  * @param[inout]    pParams      Allocation parameters
835  */
836 extern NV_STATUS serverAllocEpilogue_WAR(RsServer *pServer, NV_STATUS status, NvBool bClientAlloc, RS_RES_ALLOC_PARAMS_INTERNAL *pAllocParams);
837 
838 /**
839  * Free a resource reference and all of its descendants. This will decrease the
840  * resource's reference count. The resource itself will only be freed if there
841  * are no more references to it.
842  *
843  * It is invalid to attempt to free a resource from a user other than the one that allocated it.
844  *
845  * @param[in]   pServer This server instance
846  * @param[in]   pParams Free parameters
847  */
848 NV_STATUS   serverFreeResourceTree(RsServer *pServer, RS_RES_FREE_PARAMS *pParams);
849 
850 /**
851  * Same as serverFreeResourceTree except the top-level lock is assumed to have been taken.
852  *
853  * @param[in]   pServer This server instance
854  * @param[in]   pParams Free parameters
855  */
856 NV_STATUS   serverFreeResourceTreeUnderLock(RsServer *pServer, RS_RES_FREE_PARAMS *pParams);
857 
858 /**
859  * Updates the lock flags in the dup parameters
860  *
861  * @param[in]   pServer This server instance
862  * @param[in]   pParams Dup parameters
863  */
864 extern NV_STATUS   serverUpdateLockFlagsForCopy(RsServer *pServer, RS_RES_DUP_PARAMS *pParams);
865 
866 /**
867  * Updates the lock flags in the free parameters
868  *
869  * @param[in]   pServer This server instance
870  * @param[in]   pParams Free parameters
871  */
872 extern NV_STATUS   serverUpdateLockFlagsForFree(RsServer *pServer, RS_RES_FREE_PARAMS *pParams);
873 
874 /**
875  * Updates the lock flags for automatic inter-unmap during free
876  *
877  * @param[in]    pServer This server instance
878  * @param[inout] pParams Unmap params, contained pLockInfo will be modified
879  */
880 extern NV_STATUS serverUpdateLockFlagsForInterAutoUnmap(RsServer *pServer, RS_INTER_UNMAP_PARAMS *pParams);
881 
882 /**
883  * Initialize parameters for a recursive call to serverFreeResourceTree. User-implemented.
884  * @param[in]       hClient
885  * @param[in]       hResource
886  * @param[inout]    pParams
887  */
888 extern NV_STATUS   serverInitFreeParams_Recursive(NvHandle hClient, NvHandle hResource, RS_LOCK_INFO *pLockInfo, RS_RES_FREE_PARAMS *pParams);
889 
890 /**
891  * Common operations performed after top locks and client locks are taken, but before
892  * the control call is executed. This includes validating the control call cookie,
893  * looking up locking flags, parameter copy-in, and taking resource locks.
894  *
895  * @param[in]       pServer ResServ instance
896  * @param[in]       pParams Control call parameters
897  * @param[in]       pAccess Lock access type
898  * @param[inout]    pReleaseFlags Flags that indicate which locks were taken
899  */
900 NV_STATUS serverControl_Prologue(RsServer *pServer, RS_RES_CONTROL_PARAMS_INTERNAL *pParams, LOCK_ACCESS_TYPE *pAccess, NvU32 *pReleaseFlags);
901 
902 /**
903  * Common operations performed after the control call is executed. This
904  * includes releasing locks and parameter copy-out.
905  *
906  * @param[in]       pServer ResServ instance
907  * @param[in]       pParams Control call parameters
908  * @param[in]       pAccess Lock access type
909  * @param[inout]    pReleaseFlags Flags that indicate which locks were taken
910  * @param[in]       status Control call status
911  */
912 NV_STATUS serverControl_Epilogue(RsServer *pServer, RS_RES_CONTROL_PARAMS_INTERNAL *pParams, LOCK_ACCESS_TYPE access, NvU32 *pReleaseFlags, NV_STATUS status);
913 
914 /**
915  * Initialize a NVOC export control call cookie
916  *
917  * @param[in]       pExportedEntry
918  * @param[inout]    pCookie
919  */
920 extern void      serverControl_InitCookie(const struct NVOC_EXPORTED_METHOD_DEF *pExportedEntry, RS_CONTROL_COOKIE *pCookie);
921 
922 /**
923  * Validate a NVOC export control call cookie
924  *
925  * @param[in]       pParams
926  * @param[inout]    pCookie
927  */
928 extern NV_STATUS serverControl_ValidateCookie(RS_RES_CONTROL_PARAMS_INTERNAL *pParams, RS_CONTROL_COOKIE *pCookie);
929 
930 /**
931  * Copy-in control call parameters
932  *
933  * @param[in]       pServer ResServ instance
934  * @param[in]       pParams Control call parameters
935  * @param[inout]    pCookie Control call cookie
936  */
937 extern NV_STATUS serverControlApiCopyIn(RsServer *pServer,
938                                         RS_RES_CONTROL_PARAMS_INTERNAL *pParams,
939                                         RS_CONTROL_COOKIE *pCookie);
940 
941 /**
942  * Copy-out control call parameters
943  *
944  * @param[in]       pServer ResServ instance
945  * @param[in]       pParams Control call parameters
946  * @param[inout]    pCookie Control call cookie
947  */
948 extern NV_STATUS serverControlApiCopyOut(RsServer *pServer,
949                                          RS_RES_CONTROL_PARAMS_INTERNAL *pParams,
950                                          RS_CONTROL_COOKIE *pCookie,
951                                          NV_STATUS rmStatus);
952 
953 /**
954  * Determine whether an API supports a read-only lock for a given lock
955  * @param[in]       pServer ResServ instance
956  * @param[in]       lock    RS_LOCK_*
957  * @param[in]       api     RS_API*
958  */
959 NvBool serverSupportsReadOnlyLock(RsServer *pServer, RS_LOCK_ENUM lock, RS_API_ENUM api);
960 
961 /**
962  * Determine whether the current thread has taken the RW API lock
963  * @param[in]       pServer ResServ instance
964  */
965 extern NvBool serverRwApiLockIsOwner(RsServer *pServer);
966 
967 /**
968  * Lookup locking flags for a resource alloc
969  *
970  * @param[in]       pServer ResServ instance
971  * @param[in]       lock    RS_LOCK_*
972  * @param[in]       pParams Allocation parameters
973  * @param[out]      pAccess Computed lock access
974  */
975 extern NV_STATUS serverAllocResourceLookupLockFlags(RsServer *pServer,
976                                                     RS_LOCK_ENUM lock,
977                                                     RS_RES_ALLOC_PARAMS_INTERNAL *pParams,
978                                                     LOCK_ACCESS_TYPE *pAccess);
979 /**
980  *
981  * Lookup level locking flags for a resource free
982  *
983  * @param[in]       pServer ResServ instance
984  * @param[in]       lock    RS_LOCK_*
985  * @param[in]       pParams Allocation parameters
986  * @param[out]      pAccess Computed lock access
987  */
988 extern NV_STATUS serverFreeResourceLookupLockFlags(RsServer *pServer,
989                                                    RS_LOCK_ENUM lock,
990                                                    RS_RES_FREE_PARAMS_INTERNAL *pParams,
991                                                    LOCK_ACCESS_TYPE *pAccess);
992 
993 /**
994  * Lookup locking flags for a resource copy
995  *
996  * @param[in]       pServer ResServ instance
997  * @param[in]       lock    RS_LOCK_*
998  * @param[in]       pParams Allocation parameters
999  * @param[out]      pAccess Computed lock access
1000  */
1001 extern NV_STATUS serverCopyResourceLookupLockFlags(RsServer *pServer,
1002                                                    RS_LOCK_ENUM lock,
1003                                                    RS_RES_DUP_PARAMS *pParams,
1004                                                    LOCK_ACCESS_TYPE *pAccess);
1005 
1006 /**
1007  * Lookup locking flags for a resource access share
1008  *
1009  * @param[in]       pServer ResServ instance
1010  * @param[in]       lock    RS_LOCK_*
1011  * @param[in]       pParams Share parameters
1012  * @param[out]      pAccess Computed lock access
1013  */
1014 extern NV_STATUS serverShareResourceLookupLockFlags(RsServer *pServer,
1015                                                     RS_LOCK_ENUM lock,
1016                                                     RS_RES_SHARE_PARAMS *pParams,
1017                                                     LOCK_ACCESS_TYPE *pAccess);
1018 
1019 /**
1020  * Lookup locking flags for a control call
1021  *
1022  * @param[in]       pServer ResServ instance
1023  * @param[in]       lock    RS_LOCK_*
1024  * @param[in]       pParams Control call parameters
1025  * @param[in]       pCookie Control call cookie
1026  * @param[out]      pAccess Computed lock access
1027  */
1028 extern NV_STATUS serverControlLookupLockFlags(RsServer *pServer,
1029                                               RS_LOCK_ENUM lock,
1030                                               RS_RES_CONTROL_PARAMS_INTERNAL *pParams,
1031                                               RS_CONTROL_COOKIE *pCookie,
1032                                               LOCK_ACCESS_TYPE *pAccess);
1033 
1034 /**
1035  * Lookup client locking flags for a control call
1036  *
1037  * @param[in]       pCookie         Control call cookie
1038  * @param[out]      pClientLockType Client lock type
1039  */
1040 extern NV_STATUS serverControlLookupClientLockFlags(RS_CONTROL_COOKIE *pCookie,
1041                                                     enum CLIENT_LOCK_TYPE *pClientLockType);
1042 
1043 /**
1044  *
1045  * Lookup locking flags for a map call
1046  *
1047  * @param[in]       pServer ResServ instance
1048  * @param[in]       lock    RS_LOCK_*
1049  * @param[in]       pParams CPU map parameters
1050  * @param[out]      pAccess Computed lock access
1051  */
1052 extern NV_STATUS serverMapLookupLockFlags(RsServer *pServer,
1053                                           RS_LOCK_ENUM lock,
1054                                           RS_CPU_MAP_PARAMS *pParams,
1055                                           LOCK_ACCESS_TYPE *pAccess);
1056 
1057 /**
1058  * Lookup locking flags for an unmap call
1059  *
1060  * @param[in]       pServer ResServ instance
1061  * @param[in]       lock    RS_LOCK_*
1062  * @param[in]       pParams CPU unmap parameters
1063  * @param[out]      pAccess Computed lock access
1064  */
1065 extern NV_STATUS serverUnmapLookupLockFlags(RsServer *pServer,
1066                                             RS_LOCK_ENUM lock,
1067                                             RS_CPU_UNMAP_PARAMS *pParams,
1068                                             LOCK_ACCESS_TYPE *pAccess);
1069 
1070 /**
1071  *
1072  * Lookup locking flags for an inter-resource map call
1073  *
1074  * @param[in]       pServer ResServ instance
1075  * @param[in]       lock    RS_LOCK_*
1076  * @param[in]       pParams Inter-resource map parameters
1077  * @param[out]      pAccess Computed lock access
1078  */
1079 extern NV_STATUS serverInterMapLookupLockFlags(RsServer *pServer,
1080                                                RS_LOCK_ENUM lock,
1081                                                RS_INTER_MAP_PARAMS *pParams,
1082                                                LOCK_ACCESS_TYPE *pAccess);
1083 
1084 /**
1085  *
1086  * Lookup locking flags for an inter-resource unmap call
1087  *
1088  * @param[in]       pServer ResServ instance
1089  * @param[in]       lock    RS_LOCK_*
1090  * @param[in]       pParams Inter-resource unmap parameters
1091  * @param[out]      pAccess Computed lock access
1092  */
1093 extern NV_STATUS serverInterUnmapLookupLockFlags(RsServer *pServer,
1094                                                  RS_LOCK_ENUM lock,
1095                                                  RS_INTER_UNMAP_PARAMS *pParams,
1096                                                  LOCK_ACCESS_TYPE *pAccess);
1097 
1098 /**
1099  * Fill the server's share policy lists with any default or global policies needed
1100  */
1101 extern NV_STATUS serverInitGlobalSharePolicies(RsServer *pServer);
1102 
1103 /**
1104  * Issue a control command to a resource
1105  *
1106  * @param[in]   pServer This server instance
1107  * @param[in]   pParams Control parameters
1108  */
1109 NV_STATUS serverControl(RsServer *pServer, RS_RES_CONTROL_PARAMS *pParams);
1110 
1111 /**
1112  * Copy a resource owned by one client into another client.
1113  *
1114  * The clients must be in the same client handle space. The underlying
1115  * resource is not duplicated, but it is refcounted so the resource will
1116  * not be freed until the reference count hits zero.
1117  *
1118  * Copying a resource will fail if the user making the call does not own
1119  * the source client.
1120  *
1121  * @param[in]    pServer This server instance
1122  * @param[inout] pParams Resource sharing parameters
1123  */
1124 NV_STATUS serverCopyResource(RsServer *pServer, RS_RES_DUP_PARAMS *pParams);
1125 
1126 /**
1127  * Share certain access rights to a resource with other clients using the provided share policy
1128  *
1129  * The policy entry passed in will be added to the object's share policy list.
1130  * If the bRevoke is true, the policy will be removed instead.
1131  *
1132  * Sharing will fail if the user making the call does not own the source client.
1133  *
1134  * @param[in]    pServer This server instance
1135  * @param[in] pParams Resource sharing parameters
1136  */
1137 NV_STATUS serverShareResourceAccess(RsServer *pServer, RS_RES_SHARE_PARAMS *pParams);
1138 
1139 /**
1140  * Creates a CPU mapping of the resource in the virtual address space of the process.
1141  *
1142  * Not all resources support mapping.
1143  *
1144  * @param[in]   pServer This server instance
1145  * @param[in]   hClient Client handle of the resource to map
1146  * @param[in]   hResource Handle of the resource to map
1147  * @param[inout] pParams CPU mapping parameters
1148  */
1149 NV_STATUS serverMap(RsServer *pServer, NvHandle hClient, NvHandle hResource, RS_CPU_MAP_PARAMS *pParams);
1150 
1151 /**
1152  * Release a CPU virtual address unmapping
1153  *
1154  * @param[in]   pServer This server instance
1155  * @param[in]   hClient Client handle of the resource to map
1156  * @param[in]   hResource Handle of the resource to map
1157  * @param[in]   pParams CPU unmapping parameters
1158  */
1159 NV_STATUS serverUnmap(RsServer *pServer, NvHandle hClient, NvHandle hResource, RS_CPU_UNMAP_PARAMS *pParams);
1160 
1161 /**
1162  * Pre-map operations. Called with top/client locks acquired
1163  * but not resource locks.
1164  *
1165  * @param[in] pServer
1166  * @param[inout] pParams CPU mapping parameters
1167  */
1168 NV_STATUS serverMap_Prologue(RsServer *pServer, RS_CPU_MAP_PARAMS *pMapParams);
1169 
1170 /**
1171  * Post-map operations. Called with top/client locks acquired
1172  * but not resource locks.
1173  *
1174  * @param[in] pServer
1175  * @param[inout] pParams CPU mapping parameters
1176  */
1177 void serverMap_Epilogue(RsServer *pServer, RS_CPU_MAP_PARAMS *pMapParams);
1178 
1179 /**
1180  * Pre-unmap operations. Called with top/client locks acquired
1181  * but not resource locks.
1182  *
1183  * @param[in] pServer
1184  * @param[inout] pParams CPU mapping parameters
1185  */
1186 NV_STATUS serverUnmap_Prologue(RsServer *pServer, RS_CPU_UNMAP_PARAMS *pUnmapParams);
1187 
1188 /**
1189  * Post-unmap operations. Called with top/client locks acquired
1190  * but not resource locks.
1191  *
1192  * @param[in] pServer
1193  * @param[inout] pParams CPU mapping parameters
1194  */
1195 void serverUnmap_Epilogue(RsServer *pServer, RS_CPU_UNMAP_PARAMS *pUnmapParams);
1196 
1197 /**
1198  * Creates an inter-mapping between two resources
1199  *
1200  * Not all resources support mapping.
1201  *
1202  * @param[in]   pServer This server instance
1203  * @param[inout] pParams mapping parameters
1204  */
1205 NV_STATUS serverInterMap(RsServer *pServer, RS_INTER_MAP_PARAMS *pParams);
1206 
1207 /**
1208  * Release an inter-mapping between two resources
1209  *
1210  * @param[in]   pServer This server instance
1211  * @param[in]   pParams unmapping parameters
1212  */
1213 NV_STATUS serverInterUnmap(RsServer *pServer, RS_INTER_UNMAP_PARAMS *pParams);
1214 
1215 /**
1216  * Pre-inter-map operations. Called with top/client locks acquired.
1217  * This function acquires resource locks.
1218  *
1219  * @param[in] pServer
1220  * @param[in]  pMapperRef The resource that can be used to create the mapping
1221  * @param[in]  pMappableRef The resource that can be mapped
1222  * @param[inout] pMapParams mapping parameters
1223  * @param[inout] pReleaseFlags Flags that indicate which locks were taken
1224  */
1225 NV_STATUS serverInterMap_Prologue(RsServer *pServer, RsResourceRef *pMapperRef, RsResourceRef *pMappableRef, RS_INTER_MAP_PARAMS *pMapParams, NvU32 *pReleaseFlags);
1226 
1227 /**
1228  * Post-inter-map operations. Called with top, client, and resource locks acquired.
1229  * This function releases resource locks.
1230  *
1231  * @param[in] pServer
1232  * @param[inout] pMapParams mapping parameters
1233  * @param[inout] pReleaseFlags Flags that indicate which locks were taken
1234  */
1235 void serverInterMap_Epilogue(RsServer *pServer, RS_INTER_MAP_PARAMS *pMapParams, NvU32 *pReleaseFlags);
1236 
1237 /**
1238  * Pre-inter-unmap operations. Called with top, client, and resource locks acquired.
1239  *
1240  * @param[in] pServer
1241  * @param[inout] pParams mapping parameters
1242  */
1243 NV_STATUS serverInterUnmap_Prologue(RsServer *pServer, RS_INTER_UNMAP_PARAMS *pUnmapParams);
1244 
1245 /**
1246  * Post-inter-unmap operations. Called with top, client, and resource locks acquired.
1247  *
1248  * @param[in] pServer
1249  * @param[inout] pParams mapping parameters
1250  */
1251 void serverInterUnmap_Epilogue(RsServer *pServer, RS_INTER_UNMAP_PARAMS *pUnmapParams);
1252 
1253 /**
1254  * Acquire a client pointer from a client handle. The caller is responsible for
1255  * ensuring that lock ordering is not violated (otherwise there can be
1256  * deadlock): clients must be locked in increasing order of client index (not
1257  * handle).
1258  *
1259  * @param[in]   pServer This server instance
1260  * @param[in]   hClient The client to acquire
1261  * @param[in]   lockAccess LOCK_ACCESS_READ or LOCK_ACCESS_WRITE
1262  * @param[out]  ppClientEntry Pointer to the CLIENT_ENTRY
1263  */
1264 NV_STATUS serverAcquireClient(RsServer *pServer, NvHandle hClient, LOCK_ACCESS_TYPE lockAccess, CLIENT_ENTRY **ppClientEntry);
1265 
1266 /**
1267  * Release a client pointer
1268  *
1269  * @param[in]  pServer This server instance
1270  * @param[in]  lockAccess LOCK_ACCESS_READ or LOCK_ACCESS_WRITE
1271  * @param[in]  pClientEntry Pointer to the CLIENT_ENTRY
1272  */
1273 void serverReleaseClient(RsServer *pServer, LOCK_ACCESS_TYPE lockAccess, CLIENT_ENTRY *pClientEntry);
1274 
1275 /**
1276  * Test is a client handle is currently locked for LOCK_ACCESS_WRITE or not.
1277  *
1278  * @param[in]   pServer This server instance
1279  * @param[in]   hClient The client to acquire
1280  */
1281 NvBool serverIsClientLocked(RsServer *pServer, NvHandle hClient);
1282 
1283 /**
1284  * Test if a client handle is internal or not
1285  *
1286  * @param[in]  hClient The client handle to test
1287  */
1288 NvBool serverIsClientInternal(RsServer *pServer, NvHandle hClient);
1289 
1290 /**
1291  * Lock all clients currently in use. While this function will lock the client handles
1292  * in the correct order, the caller is responsible for ensuring that lock ordering
1293  * is not violated (otherwise there can be a deadlock) with respect to other types
1294  * of locks. NOTE that this CANNOT be called when already holding one or more client
1295  * locks!
1296  *
1297  * @param[in]  pServer This server instance
1298  */
1299 NV_STATUS serverLockAllClients(RsServer *pServer);
1300 
1301 /**
1302  * Release locks on all clients.
1303  *
1304  * @param[in] pServer This server instance
1305  */
1306 NV_STATUS serverUnlockAllClients(RsServer *pServer);
1307 
1308 /**
1309  * Check if we locked all clients
1310  *
1311  * @param[in] pServer This server instance
1312  */
serverAllClientsLockIsOwner(RsServer * pServer)1313 static NV_INLINE NvBool serverAllClientsLockIsOwner(RsServer *pServer)
1314 {
1315     return (pServer->allClientLockOwnerTid == portThreadGetCurrentThreadId());
1316 }
1317 
1318 /**
1319  * Get a client pointer from a client handle without taking any locks.
1320  *
1321  * @param[in]   pServer This server instance
1322  * @param[in]   hClient The client to acquire
1323  * @param[out]  ppClient Pointer to the RsClient
1324  */
1325 NV_STATUS serverGetClientUnderLock(RsServer *pServer, NvHandle hClient, struct RsClient **ppClient);
1326 
1327 /**
1328  * Get the count of clients allocated under this resource server
1329  *
1330  * @param[in]   pServer This server instance
1331  */
1332 NvU32 serverGetClientCount(RsServer *pServer);
1333 
1334 /**
1335  * Get the count of resources allocated under this resource server
1336  *
1337  * @param[in]   pServer This server instance
1338  */
1339 NvU64 serverGetResourceCount(RsServer *pServer);
1340 
1341 /**
1342  * Swap a TLS call context entry and increment the TLS entry refcount.
1343  * A new TLS entry for call context will be allocated if necessary.
1344  *
1345  * @note This should be paired with a corresponding resservRestoreTlsCallContext call
1346  */
1347 NV_STATUS resservSwapTlsCallContext(CALL_CONTEXT **ppOldCallContext, CALL_CONTEXT *pNewCallContext);
1348 
1349 /**
1350  * Get the current TLS call context. This will not increment a refcount on the TLS entry.
1351  */
1352 CALL_CONTEXT *resservGetTlsCallContext(void);
1353 
1354 /**
1355  * Set a TLS call context entry and decrement the TLS entry refcount.
1356  * @note This should be paired with a corresponding resservSwapTlsCallContext call
1357  */
1358 NV_STATUS resservRestoreTlsCallContext(CALL_CONTEXT *pOldCallContext);
1359 
1360 /**
1361  * Find a resource reference of a given type from the TLS call context
1362  * @param[in]   internalClassId  Only return a reference if it matches this type
1363  * @param[in]   bSearchAncestors Search parents of the call context resource ref
1364  */
1365 RsResourceRef *resservGetContextRefByType(NvU32 internalClassId, NvBool bSearchAncestors);
1366 
1367 #ifdef __cplusplus
1368 }
1369 #endif
1370 
1371 #endif
1372 
1373 #ifdef __cplusplus
1374 } // extern "C"
1375 #endif
1376 
1377 #endif // _G_RS_SERVER_NVOC_H_
1378