1 #ifndef _G_RESSERV_NVOC_H_
2 #define _G_RESSERV_NVOC_H_
3 #include "nvoc/runtime.h"
4 
5 #ifdef __cplusplus
6 extern "C" {
7 #endif
8 
9 /*
10  * SPDX-FileCopyrightText: Copyright (c) 2015-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
11  * SPDX-License-Identifier: MIT
12  *
13  * Permission is hereby granted, free of charge, to any person obtaining a
14  * copy of this software and associated documentation files (the "Software"),
15  * to deal in the Software without restriction, including without limitation
16  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
17  * and/or sell copies of the Software, and to permit persons to whom the
18  * Software is furnished to do so, subject to the following conditions:
19  *
20  * The above copyright notice and this permission notice shall be included in
21  * all copies or substantial portions of the Software.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29  * DEALINGS IN THE SOFTWARE.
30  */
31 
32 #include "g_resserv_nvoc.h"
33 
34 #ifndef _RESSERV_H_
35 #define _RESSERV_H_
36 
37 #include "nvoc/object.h"
38 
39 #include "containers/list.h"
40 #include "containers/map.h"
41 #include "containers/multimap.h"
42 
43 #include "nvtypes.h"
44 #include "nvstatus.h"
45 #include "nvos.h"
46 #include "nvsecurityinfo.h"
47 #include "rs_access.h"
48 
49 #if LOCK_VAL_ENABLED
50 #include "lockval/lockval.h"
51 #endif
52 
53 #ifdef __cplusplus
54 extern "C" {
55 #endif
56 
57 #if (RS_STANDALONE)
58 #include <stddef.h>
59 
60 #ifndef NV_PRINTF
61 extern int g_debugLevel;
62 #define NV_PRINTF(level, format, ...) if (g_debugLevel) { printf(format, ##__VA_ARGS__); }
63 #endif
64 #include "utils/nvprintf.h"
65 #endif
66 
67 //
68 // Forward declarations
69 //
70 typedef struct RsServer RsServer;
71 typedef struct RsDomain RsDomain;
72 typedef struct CLIENT_ENTRY CLIENT_ENTRY;
73 typedef struct RsResourceDep RsResourceDep;
74 typedef struct RsResourceRef RsResourceRef;
75 typedef struct RsInterMapping RsInterMapping;
76 typedef struct RsCpuMapping RsCpuMapping;
77 
78 // RS-TODO INTERNAL and EXTERNAL params should be different structures
79 typedef struct RS_CLIENT_FREE_PARAMS_INTERNAL RS_CLIENT_FREE_PARAMS_INTERNAL;
80 typedef struct RS_CLIENT_FREE_PARAMS_INTERNAL RS_CLIENT_FREE_PARAMS;
81 typedef struct RS_RES_ALLOC_PARAMS_INTERNAL RS_RES_ALLOC_PARAMS_INTERNAL;
82 typedef struct RS_RES_ALLOC_PARAMS_INTERNAL RS_RES_ALLOC_PARAMS;
83 typedef struct RS_RES_DUP_PARAMS_INTERNAL RS_RES_DUP_PARAMS_INTERNAL;
84 typedef struct RS_RES_DUP_PARAMS_INTERNAL RS_RES_DUP_PARAMS;
85 typedef struct RS_RES_SHARE_PARAMS_INTERNAL RS_RES_SHARE_PARAMS_INTERNAL;
86 typedef struct RS_RES_SHARE_PARAMS_INTERNAL RS_RES_SHARE_PARAMS;
87 typedef struct RS_RES_ALLOC_PARAMS_INTERNAL RS_CLIENT_ALLOC_PARAMS_INTERNAL;
88 typedef struct RS_RES_ALLOC_PARAMS_INTERNAL RS_CLIENT_ALLOC_PARAMS;
89 typedef struct RS_RES_FREE_PARAMS_INTERNAL RS_RES_FREE_PARAMS_INTERNAL;
90 typedef struct RS_RES_FREE_PARAMS_INTERNAL RS_RES_FREE_PARAMS;
91 typedef struct RS_RES_CONTROL_PARAMS_INTERNAL RS_RES_CONTROL_PARAMS_INTERNAL;
92 typedef struct RS_RES_CONTROL_PARAMS_INTERNAL RS_RES_CONTROL_PARAMS;
93 typedef struct RS_RES_CONTROL_PARAMS_INTERNAL RS_LEGACY_CONTROL_PARAMS;
94 typedef struct RS_LEGACY_ALLOC_PARAMS RS_LEGACY_ALLOC_PARAMS;
95 typedef struct RS_LEGACY_FREE_PARAMS RS_LEGACY_FREE_PARAMS;
96 
97 typedef struct RS_CPU_MAP_PARAMS RS_CPU_MAP_PARAMS;
98 typedef struct RS_CPU_UNMAP_PARAMS RS_CPU_UNMAP_PARAMS;
99 typedef struct RS_INTER_MAP_PARAMS RS_INTER_MAP_PARAMS;
100 typedef struct RS_INTER_UNMAP_PARAMS RS_INTER_UNMAP_PARAMS;
101 
102 // Forward declarations for structs defined by user
103 typedef struct RS_RES_MAP_TO_PARAMS RS_RES_MAP_TO_PARAMS;
104 typedef struct RS_RES_UNMAP_FROM_PARAMS RS_RES_UNMAP_FROM_PARAMS;
105 typedef struct RS_INTER_MAP_PRIVATE RS_INTER_MAP_PRIVATE;
106 typedef struct RS_INTER_UNMAP_PRIVATE RS_INTER_UNMAP_PRIVATE;
107 typedef struct RS_CPU_MAPPING_PRIVATE RS_CPU_MAPPING_PRIVATE;
108 
109 typedef struct RS_CPU_MAPPING_BACK_REF RS_CPU_MAPPING_BACK_REF;
110 typedef struct RS_INTER_MAPPING_BACK_REF RS_INTER_MAPPING_BACK_REF;
111 typedef struct RS_FREE_STACK RS_FREE_STACK;
112 typedef struct CALL_CONTEXT CALL_CONTEXT;
113 typedef struct ACCESS_CONTROL ACCESS_CONTROL;
114 typedef struct RS_ITERATOR RS_ITERATOR;
115 typedef struct RS_ORDERED_ITERATOR RS_ORDERED_ITERATOR;
116 typedef struct RS_SHARE_ITERATOR RS_SHARE_ITERATOR;
117 typedef struct API_STATE API_STATE;
118 typedef struct RS_LOCK_INFO RS_LOCK_INFO;
119 typedef struct RS_CONTROL_COOKIE RS_CONTROL_COOKIE;
120 typedef NV_STATUS RsCtrlFunc(struct RS_RES_CONTROL_PARAMS_INTERNAL*);
121 
122 struct RsClient;
123 
124 #ifndef __NVOC_CLASS_RsClient_TYPEDEF__
125 #define __NVOC_CLASS_RsClient_TYPEDEF__
126 typedef struct RsClient RsClient;
127 #endif /* __NVOC_CLASS_RsClient_TYPEDEF__ */
128 
129 #ifndef __nvoc_class_id_RsClient
130 #define __nvoc_class_id_RsClient 0x8f87e5
131 #endif /* __nvoc_class_id_RsClient */
132 
133 
134 struct RsResource;
135 
136 #ifndef __NVOC_CLASS_RsResource_TYPEDEF__
137 #define __NVOC_CLASS_RsResource_TYPEDEF__
138 typedef struct RsResource RsResource;
139 #endif /* __NVOC_CLASS_RsResource_TYPEDEF__ */
140 
141 #ifndef __nvoc_class_id_RsResource
142 #define __nvoc_class_id_RsResource 0xd551cb
143 #endif /* __nvoc_class_id_RsResource */
144 
145 
146 struct RsShared;
147 
148 #ifndef __NVOC_CLASS_RsShared_TYPEDEF__
149 #define __NVOC_CLASS_RsShared_TYPEDEF__
150 typedef struct RsShared RsShared;
151 #endif /* __NVOC_CLASS_RsShared_TYPEDEF__ */
152 
153 #ifndef __nvoc_class_id_RsShared
154 #define __nvoc_class_id_RsShared 0x830542
155 #endif /* __nvoc_class_id_RsShared */
156 
157 
158 
159 MAKE_LIST(RsResourceRefList, RsResourceRef*);
160 MAKE_LIST(RsResourceList, RsResource*);
161 MAKE_LIST(RsHandleList, NvHandle);
162 MAKE_LIST(RsClientList, CLIENT_ENTRY*);
163 MAKE_LIST(RsShareList, RS_SHARE_POLICY);
164 MAKE_MULTIMAP(RsIndex, RsResourceRef*);
165 
166 typedef NV_STATUS (*CtrlImpl_t)(struct RsClient*, struct RsResource*, void*);
167 
168 typedef void *PUID_TOKEN;
169 
170 //
171 // Defines
172 //
173 
174 /// Domain handles must start at this base value
175 #define RS_DOMAIN_HANDLE_BASE           0xD0D00000
176 
177 /// Client handles must start at this base value
178 #define RS_CLIENT_HANDLE_BASE           0xC1D00000
179 
180 /// Internal Client handles start at this base value
181 #define RS_CLIENT_INTERNAL_HANDLE_BASE  0xC1E00000
182 
183 /// VF Client handles start at this base value
184 #define RS_CLIENT_VF_HANDLE_BASE        0xE0000000
185 
186 /// Get the VF client handle range for gfid
187 #define RS_CLIENT_GET_VF_HANDLE_BASE(gfid) (RS_CLIENT_VF_HANDLE_BASE + ((gfid) - 1) * RS_CLIENT_HANDLE_MAX)
188 
189 //
190 // Print a warning if any client's resource count exceeds this
191 // threshold. Unless this was intentional, this is likely a client bug.
192 //
193 #define RS_CLIENT_RESOURCE_WARNING_THRESHOLD 100000
194 
195 #define RS_CLIENT_HANDLE_MAX            0x100000 // Must be power of two
196 #define RS_CLIENT_HANDLE_BUCKET_COUNT   0x400  // 1024
197 #define RS_CLIENT_HANDLE_BUCKET_MASK    0x3FF
198 
199 
200 /// The default maximum number of domains a resource server can allocate
201 #define RS_MAX_DOMAINS_DEFAULT          4096
202 
203 /// The maximum length of a line of ancestry for resource references
204 #define RS_MAX_RESOURCE_DEPTH           6
205 
206 /// RS_LOCK_FLAGS
207 #define RS_LOCK_FLAGS_NO_TOP_LOCK               NVBIT(0)
208 #define RS_LOCK_FLAGS_NO_CLIENT_LOCK            NVBIT(1)
209 #define RS_LOCK_FLAGS_NO_CUSTOM_LOCK_1          NVBIT(2)
210 #define RS_LOCK_FLAGS_NO_CUSTOM_LOCK_2          NVBIT(3)
211 #define RS_LOCK_FLAGS_NO_CUSTOM_LOCK_3          NVBIT(4)
212 #define RS_LOCK_FLAGS_NO_DEPENDANT_SESSION_LOCK NVBIT(5)
213 #define RS_LOCK_FLAGS_FREE_SESSION_LOCK         NVBIT(6)
214 #define RS_LOCK_FLAGS_LOW_PRIORITY              NVBIT(7)
215 
216 /// RS_LOCK_STATE
217 #define RS_LOCK_STATE_TOP_LOCK_ACQUIRED        NVBIT(0)
218 #define RS_LOCK_STATE_CUSTOM_LOCK_1_ACQUIRED   NVBIT(1)
219 #define RS_LOCK_STATE_CUSTOM_LOCK_2_ACQUIRED   NVBIT(2)
220 #define RS_LOCK_STATE_CUSTOM_LOCK_3_ACQUIRED   NVBIT(3)
221 #define RS_LOCK_STATE_ALLOW_RECURSIVE_RES_LOCK NVBIT(6)
222 #define RS_LOCK_STATE_CLIENT_LOCK_ACQUIRED     NVBIT(7)
223 #define RS_LOCK_STATE_SESSION_LOCK_ACQUIRED    NVBIT(8)
224 
225 /// RS_LOCK_RELEASE
226 #define RS_LOCK_RELEASE_TOP_LOCK               NVBIT(0)
227 #define RS_LOCK_RELEASE_CLIENT_LOCK            NVBIT(1)
228 #define RS_LOCK_RELEASE_CUSTOM_LOCK_1          NVBIT(2)
229 #define RS_LOCK_RELEASE_CUSTOM_LOCK_2          NVBIT(3)
230 #define RS_LOCK_RELEASE_CUSTOM_LOCK_3          NVBIT(4)
231 #define RS_LOCK_RELEASE_SESSION_LOCK           NVBIT(5)
232 
233 /// API enumerations used for locking knobs
234 typedef enum
235 {
236     RS_LOCK_CLIENT      =0,
237     RS_LOCK_TOP         =1,
238     RS_LOCK_RESOURCE    =2,
239     RS_LOCK_CUSTOM_3    =3,
240 } RS_LOCK_ENUM;
241 
242 typedef enum
243 {
244     RS_API_ALLOC_CLIENT     = 0,
245     RS_API_ALLOC_RESOURCE   = 1,
246     RS_API_FREE_RESOURCE    = 2,
247     RS_API_MAP              = 3,
248     RS_API_UNMAP            = 4,
249     RS_API_INTER_MAP        = 5,
250     RS_API_INTER_UNMAP      = 6,
251     RS_API_COPY             = 7,
252     RS_API_SHARE            = 8,
253     RS_API_CTRL             = 9,
254     RS_API_MAX,
255 } RS_API_ENUM;
256 
257 NV_STATUS indexAdd(RsIndex *pIndex, NvU32 index, RsResourceRef *pResourceRef);
258 NV_STATUS indexRemove(RsIndex *pIndex, NvU32 index, RsResourceRef *pResourceRef);
259 
260 //
261 // Externs
262 //
263 /**
264  * NVOC wrapper for constructing resources of a given type
265  *
266  * @param[in]    pAllocator    Allocator for the resource object
267  * @param[in]    pCallContext  Caller context passed to resource constructor
268  * @param[inout] pParams       Resource allocation parameters
269  * @param[out]   ppResource    New resource object
270  */
271 extern NV_STATUS resservResourceFactory(PORT_MEM_ALLOCATOR *pAllocator, CALL_CONTEXT *pCallContext,
272                                         RS_RES_ALLOC_PARAMS_INTERNAL *pParams, struct RsResource **ppResource);
273 
274 /**
275  * NVOC wrapper for constructing an application-specific client.
276  */
277 extern NV_STATUS resservClientFactory(PORT_MEM_ALLOCATOR *pAllocator, RS_RES_ALLOC_PARAMS_INTERNAL *pParams, struct RsClient **ppRsClient);
278 
279 /**
280  *  Validate the UID/PID security token of the current user against a client's security token.
281  *
282  *  This will be obsolete after phase 1.
283  *
284  *  @param[in]  pClientToken
285  *  @param[in]  pCurrentToken
286  *
287  *  @returns NV_OK if the current user's security token matches the client's security token
288  */
289 extern NV_STATUS osValidateClientTokens(PSECURITY_TOKEN pClientToken, PSECURITY_TOKEN pCurrentToken);
290 
291 /**
292  *  Get the security token of the current user for the UID/PID security model.
293  *
294  *  This will be obsolete after phase 1.
295  */
296 extern PSECURITY_TOKEN osGetSecurityToken(void);
297 
298 /**
299  * TLS entry id for call contexts. All servers will use the same id.
300  */
301 #define TLS_ENTRY_ID_RESSERV_CALL_CONTEXT TLS_ENTRY_ID_RESSERV_1
302 
303 //
304 // Structs
305 //
306 struct RS_FREE_STACK
307 {
308     RS_FREE_STACK *pPrev;
309     RsResourceRef *pResourceRef;
310 };
311 
312 struct CALL_CONTEXT
313 {
314     RsServer *pServer;              ///< The resource server instance that owns the client
315     struct RsClient *pClient;              ///< Client that was the target of the call
316     RsResourceRef *pResourceRef;    ///< Reference that was the target of the call
317     RsResourceRef *pContextRef;     ///< Reference that may be used to provide more context [optional]
318     RS_LOCK_INFO  *pLockInfo;       ///< Saved locking context information for the call
319     API_SECURITY_INFO secInfo;
320     RS_RES_CONTROL_PARAMS_INTERNAL  *pControlParams; ///< parameters of the call [optional]
321 
322     void *pSerializedParams;        ///< Serialized version of the params
323     void *pDeserializedParams;      ///< Deserialized version of the params
324     NvU32 serializedSize;           ///< Serialized size
325     NvU32 deserializedSize;         ///< Deserialized size
326     NvBool bReserialize;            ///< Reserialize before calling into GSP
327     NvBool bRestoreParams;          ///< Need to restore pParams
328 };
329 
330 typedef enum {
331     RS_ITERATE_CHILDREN,    ///< Iterate over a RsResourceRef's children
332     RS_ITERATE_DESCENDANTS, ///< Iterate over a RsResourceRef's children, grandchildren, etc. (unspecified order)
333     RS_ITERATE_CACHED,      ///< Iterate over a RsResourceRef's cache
334     RS_ITERATE_DEPENDANTS,  ///< Iterate over a RsResourceRef's dependants
335 } RS_ITER_TYPE;
336 
337 typedef enum
338 {
339     LOCK_ACCESS_READ,
340     LOCK_ACCESS_WRITE,
341 } LOCK_ACCESS_TYPE;
342 
343 
344 
345 /**
346  * Access control information. This information will be filled out by the user
347  * of the Resource Server when allocating a client or resource.
348  */
349 struct ACCESS_CONTROL
350 {
351     /**
352      * The privilege level of this access control
353      */
354     RS_PRIV_LEVEL privilegeLevel;
355 
356     /**
357      * Opaque pointer for storing a security token
358      */
359     PSECURITY_TOKEN pSecurityToken;
360 };
361 
362 //
363 // Utility wrappers for locking validator
364 //
365 #if LOCK_VAL_ENABLED
366 #define RS_LOCK_VALIDATOR_INIT(lock, lockClass, inst) \
367     do { NV_ASSERT_OK(lockvalLockInit((lock), (lockClass), (inst))); } while(0)
368 
369 #define RS_RWLOCK_ACQUIRE_READ(lock, validator)              do \
370 {                                                               \
371     NV_ASSERT_OK(lockvalPreAcquire((validator)));               \
372     portSyncRwLockAcquireRead((lock));                          \
373     lockvalPostAcquire((validator), LOCK_VAL_RLOCK);            \
374 } while(0)
375 
376 #define RS_RWLOCK_ACQUIRE_WRITE(lock, validator)             do \
377 {                                                               \
378     NV_ASSERT_OK(lockvalPreAcquire((validator)));               \
379     portSyncRwLockAcquireWrite((lock));                         \
380     lockvalPostAcquire((validator), LOCK_VAL_WLOCK);            \
381 } while(0)
382 
383 #define RS_RWLOCK_RELEASE_READ_EXT(lock, validator, bOutOfOrder)                                                 do \
384 {                                                                                                                   \
385     void *pLockValTlsEntry, *pReleasedLockNode;                                                                     \
386     if (bOutOfOrder)                                                                                                \
387         NV_ASSERT_OK(lockvalReleaseOutOfOrder((validator), LOCK_VAL_RLOCK, &pLockValTlsEntry, &pReleasedLockNode)); \
388     else                                                                                                            \
389         NV_ASSERT_OK(lockvalRelease((validator), LOCK_VAL_RLOCK, &pLockValTlsEntry, &pReleasedLockNode));           \
390     portSyncRwLockReleaseRead((lock));                                                                              \
391     lockvalMemoryRelease(pLockValTlsEntry, pReleasedLockNode);                                                      \
392 } while(0)
393 
394 #define RS_RWLOCK_RELEASE_WRITE_EXT(lock, validator, bOutOfOrder)                                                do \
395 {                                                                                                                   \
396     void *pLockValTlsEntry, *pReleasedLockNode;                                                                     \
397     if (bOutOfOrder)                                                                                                \
398         NV_ASSERT_OK(lockvalReleaseOutOfOrder((validator), LOCK_VAL_WLOCK, &pLockValTlsEntry, &pReleasedLockNode)); \
399     else                                                                                                            \
400         NV_ASSERT_OK(lockvalRelease((validator), LOCK_VAL_WLOCK, &pLockValTlsEntry, &pReleasedLockNode));           \
401     portSyncRwLockReleaseWrite((lock));                                                                             \
402     lockvalMemoryRelease(pLockValTlsEntry, pReleasedLockNode);                                                      \
403 } while(0)
404 
405 #else
406 #define RS_LOCK_VALIDATOR_INIT(lock, lockClass, inst)
407 #define RS_RWLOCK_ACQUIRE_READ(lock, validator)                     do { portSyncRwLockAcquireRead((lock)); } while(0)
408 #define RS_RWLOCK_ACQUIRE_WRITE(lock, validator)                    do { portSyncRwLockAcquireWrite((lock)); } while(0)
409 #define RS_RWLOCK_RELEASE_READ_EXT(lock, validator, bOutOfOrder)    do { portSyncRwLockReleaseRead((lock)); } while(0)
410 #define RS_RWLOCK_RELEASE_WRITE_EXT(lock, validator, bOutOfOrder)   do { portSyncRwLockReleaseWrite((lock)); } while(0)
411 #endif
412 
413 #define RS_RWLOCK_RELEASE_READ(lock, validator)    RS_RWLOCK_RELEASE_READ_EXT(lock, validator, NV_FALSE)
414 #define RS_RWLOCK_RELEASE_WRITE(lock, validator)   RS_RWLOCK_RELEASE_WRITE_EXT(lock, validator, NV_FALSE)
415 
416 
417 #ifdef __cplusplus
418 }
419 #endif
420 
421 #endif
422 
423 #ifdef __cplusplus
424 } // extern "C"
425 #endif
426 #endif // _G_RESSERV_NVOC_H_
427