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