1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 1993-2023 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 /***************************** HW State Routines ***************************\
25 *                                                                           *
26 *         System Object Function Definitions.                               *
27 *                                                                           *
28 \***************************************************************************/
29 
30 #include "core/core.h"
31 #include "core/system.h"
32 #include "gpu/gpu.h"
33 #include "gpu_mgr/gpu_mgr.h"
34 #include "core/locks.h"
35 #include "os/os.h"
36 #include "nvrm_registry.h"
37 #include "core/thread_state.h"
38 #include "diagnostics/tracer.h"
39 #include "rmosxfac.h"
40 #include "tls/tls.h"
41 #include "rmapi/rmapi.h"
42 #include "rmapi/client.h"
43 #include "core/hal_mgr.h"
44 #include "nvoc/rtti.h"
45 
46 #include "platform/chipset/chipset.h"
47 #include "platform/cpu.h"
48 #include "platform/platform.h"
49 #include "diagnostics/gpu_acct.h"
50 #include "platform/platform_request_handler.h"
51 #include "gpu/external_device/gsync.h"
52 #include "virtualization/kernel_vgpu_mgr.h"
53 #include "mem_mgr/virt_mem_mgr.h"
54 #include "diagnostics/journal.h"
55 #include "virtualization/hypervisor/hypervisor.h"
56 #include "power/gpu_boost_mgr.h"
57 #include "compute/fabric.h"
58 #include "gpu_mgr/gpu_db.h"
59 #include "core/bin_data.h"
60 
61 // local static functions
62 static NV_STATUS    _sysCreateOs(OBJSYS *);
63 static NV_STATUS    _sysCreateChildObjects(OBJSYS *);
64 static void         _sysDeleteChildObjects(OBJSYS *);
65 static void         _sysNvSwitchDetection(OBJSYS *pSys);
66 static void         _sysInitStaticConfig(OBJSYS *pSys);;
67 
68 // Global pointer to instance of OBJSYS
69 OBJSYS *g_pSys = NULL;
70 
71 typedef struct
72 {
73     NvLength               childOffset;
74     const NVOC_CLASS_INFO *pClassInfo;
75     NvBool                 bDynamicConstruct;
76 } sysChildObject;
77 
78 static sysChildObject sysChildObjects[] =
79 {
80     { NV_OFFSETOF(OBJSYS, pHalMgr),         classInfo(OBJHALMGR),       NV_TRUE },
81     { NV_OFFSETOF(OBJSYS, pPfm),            classInfo(OBJPFM),          NV_TRUE },
82     { NV_OFFSETOF(OBJSYS, pHypervisor),     classInfo(OBJHYPERVISOR),   NV_TRUE },
83     { NV_OFFSETOF(OBJSYS, pOS),             classInfo(OBJOS),           NV_FALSE }, //  OS: Wrapper macros must be enabled to use :CONSTRUCT.
84     { NV_OFFSETOF(OBJSYS, pCl),             classInfo(OBJCL),           NV_TRUE },
85     { NV_OFFSETOF(OBJSYS, pGpuMgr),         classInfo(OBJGPUMGR),       NV_TRUE },
86     { NV_OFFSETOF(OBJSYS, pGsyncMgr),       classInfo(OBJGSYNCMGR),     NV_TRUE },
87     { NV_OFFSETOF(OBJSYS, pGpuAcct),        classInfo(GpuAccounting),   NV_TRUE },
88     { NV_OFFSETOF(OBJSYS, pPlatformRequestHandler), classInfo(PlatformRequestHandler),  NV_TRUE },
89     { NV_OFFSETOF(OBJSYS, pRcDB),           classInfo(OBJRCDB),         NV_TRUE },
90     { NV_OFFSETOF(OBJSYS, pVmm),            classInfo(OBJVMM),          NV_TRUE },
91     { NV_OFFSETOF(OBJSYS, pKernelVgpuMgr),  classInfo(KernelVgpuMgr),   NV_TRUE },
92     { NV_OFFSETOF(OBJSYS, pGpuBoostMgr),    classInfo(OBJGPUBOOSTMGR),  NV_TRUE },
93     { NV_OFFSETOF(OBJSYS, pFabric),         classInfo(Fabric),          NV_TRUE },
94     { NV_OFFSETOF(OBJSYS, pGpuDb),          classInfo(GpuDb),           NV_TRUE },
95 };
96 
97 static void
98 _sysDestroyMemExportCache(OBJSYS *pSys)
99 {
100     if (pSys->pSysMemExportModuleLock != NULL)
101     {
102         portSyncRwLockDestroy(pSys->pSysMemExportModuleLock);
103         pSys->pSysMemExportModuleLock = NULL;
104     }
105 
106     NV_ASSERT(multimapCountItems(&pSys->sysMemExportCache) == 0);
107 
108     multimapDestroy(&pSys->sysMemExportCache);
109 }
110 
111 static NV_STATUS
112 _sysInitMemExportCache(OBJSYS *pSys)
113 {
114     multimapInit(&pSys->sysMemExportCache, portMemAllocatorGetGlobalNonPaged());
115 
116     pSys->pSysMemExportModuleLock =
117                     portSyncRwLockCreate(portMemAllocatorGetGlobalNonPaged());
118     if (pSys->pSysMemExportModuleLock == NULL)
119     {
120         _sysDestroyMemExportCache(pSys);
121         return NV_ERR_NO_MEMORY;
122     }
123 
124     return NV_OK;
125 }
126 
127 static void
128 _sysDestroyMemExportClient(OBJSYS *pSys)
129 {
130     RM_API *pRmApi;
131 
132     if (pSys->hSysMemExportClient == 0)
133         return;
134 
135     // Acquire lock to keep rmapiGetInterface() happy.
136     NV_ASSERT(rmapiLockAcquire(API_LOCK_FLAGS_NONE,
137                                RM_LOCK_MODULES_DESTROY) == NV_OK);
138 
139     pRmApi = rmapiGetInterface(RMAPI_GPU_LOCK_INTERNAL);
140 
141     NV_ASSERT(pRmApi->Free(pRmApi, pSys->hSysMemExportClient,
142                            pSys->hSysMemExportClient) == NV_OK);
143 
144     rmapiLockRelease();
145 
146     pSys->hSysMemExportClient = 0;
147 }
148 
149 static NV_STATUS
150 _sysInitMemExportClient(OBJSYS *pSys)
151 {
152     RM_API *pRmApi;
153     NV_STATUS status;
154 
155     // Acquire lock to keep rmapiGetInterface() happy.
156     status = rmapiLockAcquire(API_LOCK_FLAGS_NONE, RM_LOCK_MODULES_INIT);
157     if (status != NV_OK)
158         return status;
159 
160     pRmApi = rmapiGetInterface(RMAPI_GPU_LOCK_INTERNAL);
161 
162     status = pRmApi->AllocWithHandle(pRmApi, NV01_NULL_OBJECT,
163                                      NV01_NULL_OBJECT, NV01_NULL_OBJECT,
164                                      NV01_ROOT, &pSys->hSysMemExportClient,
165                                      sizeof(pSys->hSysMemExportClient));
166 
167     rmapiLockRelease();
168 
169     return status;
170 }
171 
172 NV_STATUS
173 sysConstruct_IMPL(OBJSYS *pSys)
174 {
175     NV_STATUS          status;
176     OBJOS             *pOS;
177     NvU32              sec = 0;
178     NvU32              uSec = 0;
179 
180     g_pSys = pSys;
181 
182     RMTRACE_INIT();
183     RMTRACE_INIT_NEW();
184 
185     _sysInitStaticConfig(pSys);
186 
187     status = _sysCreateChildObjects(pSys);
188     if (status != NV_OK)
189     {
190         goto failed;
191     }
192 
193     // Use the monotonic system clock for a unique value
194     pOS = SYS_GET_OS(pSys);
195     osGetCurrentTime(&sec, &uSec);
196     pSys->rmInstanceId = (NvU64)sec * 1000000 + (NvU64)uSec;
197 
198     {
199         // Using Hypervisor native interface to detect
200         OBJHYPERVISOR *pHypervisor = SYS_GET_HYPERVISOR(pSys);
201         if (pHypervisor)
202             hypervisorDetection(pHypervisor, pOS);
203     }
204 
205     if (!pOS->osRmInitRm(pOS))
206     {
207         status = NV_ERR_GENERIC;
208         goto failed;
209     }
210 
211     _sysNvSwitchDetection(pSys);
212 
213     // init cpu state
214     RmInitCpuInfo();
215 
216     // allocate locks, semaphores, whatever
217     status = rmLocksAlloc(pSys);
218     if (status != NV_OK)
219         goto failed;
220 
221     status = threadStateGlobalAlloc();
222     if (status != NV_OK)
223         goto failed;
224 
225     status = rmapiInitialize();
226     if (status != NV_OK)
227         goto failed;
228 
229     status = _sysInitMemExportCache(pSys);
230     if (status != NV_OK)
231         goto failed;
232 
233     status = _sysInitMemExportClient(pSys);
234     if (status != NV_OK)
235         goto failed;
236 
237     bindataInitialize();
238 
239     return NV_OK;
240 
241 failed:
242 
243     _sysDestroyMemExportCache(pSys);
244 
245     _sysDeleteChildObjects(pSys);
246 
247     g_pSys = NULL;
248 
249     threadStateGlobalFree();
250 
251     rmapiShutdown();
252     rmLocksFree(pSys);
253 
254     return status;
255 }
256 
257 void
258 sysDestruct_IMPL(OBJSYS *pSys)
259 {
260     _sysDestroyMemExportCache(pSys);
261 
262     _sysDestroyMemExportClient(pSys);
263 
264     //
265     // Any of these operations might fail but go ahead and
266     // attempt to free remaining resources before complaining.
267     //
268     listDestroy(&g_clientListBehindGpusLock);
269     listDestroy(&g_userInfoList);
270     multimapDestroy(&g_osInfoList);
271 
272     rmapiShutdown();
273     osSyncWithRmDestroy();
274     threadStateGlobalFree();
275     rmLocksFree(pSys);
276 
277     //
278     // Free child objects
279     //
280     _sysDeleteChildObjects(pSys);
281 
282     g_pSys = NULL;
283 
284     RMTRACE_DESTROY();
285     RMTRACE_DESTROY_NEW();
286 
287     bindataDestroy();
288 }
289 
290 //
291 // Create static system object offspring.
292 //
293 static NV_STATUS
294 _sysCreateChildObjects(OBJSYS *pSys)
295 {
296     NV_STATUS status = NV_OK;
297     NvU32 i, n;
298 
299     n = NV_ARRAY_ELEMENTS(sysChildObjects);
300 
301     for (i = 0; i < n; i++)
302     {
303         if (sysChildObjects[i].bDynamicConstruct)
304         {
305             NvLength offset = sysChildObjects[i].childOffset;
306             Dynamic **ppChild = reinterpretCast(reinterpretCast(pSys, NvU8*) + offset, Dynamic**);
307             Dynamic *pNewObj;
308             status = objCreateDynamic(&pNewObj, pSys, sysChildObjects[i].pClassInfo);
309 
310             if (status == NV_OK)
311             {
312                 *ppChild = pNewObj;
313             }
314         }
315         else
316         {
317             //
318             // More cases should NOT be added to this list. OBJOS needs to be
319             // cleaned up to use the bDynamicConstruct path then this hack can
320             // be removed.
321             //
322             switch (sysChildObjects[i].pClassInfo->classId)
323             {
324                 case classId(OBJOS):
325                     status = _sysCreateOs(pSys);
326                     break;
327                 default:
328                     NV_ASSERT(0);
329                     status = NV_ERR_INVALID_ARGUMENT;
330                     break;
331             }
332         }
333 
334         // RMCONFIG:  Bail on errors unless the feature/object/engine/class
335         //            is simply unsupported
336         if (status == NV_ERR_NOT_SUPPORTED)
337             status = NV_OK;
338         if (status != NV_OK) break;
339     }
340 
341     return status;
342 }
343 
344 static void
345 _sysDeleteChildObjects(OBJSYS *pSys)
346 {
347     int i;
348 
349     osRmCapUnregister(&pSys->pOsRmCaps);
350 
351     for (i = NV_ARRAY_ELEMENTS(sysChildObjects) - 1; i >= 0; i--)
352     {
353         NvLength offset = sysChildObjects[i].childOffset;
354         Dynamic **ppChild = reinterpretCast(reinterpretCast(pSys, NvU8*) + offset, Dynamic**);
355         objDelete(*ppChild);
356         *ppChild = NULL;
357     }
358 }
359 
360 static void
361 _sysRegistryOverrideResourceServer
362 (
363     OBJSYS *pSys,
364     OBJGPU *pGpu
365 )
366 {
367     NvU32 data32;
368 
369     // Set read-only API lock override
370     if (osReadRegistryDword(pGpu, NV_REG_STR_RM_READONLY_API_LOCK,
371                             &data32) == NV_OK)
372     {
373         NvU32 apiMask = 0;
374 
375         if (FLD_TEST_DRF(_REG_STR_RM, _READONLY_API_LOCK, _ALLOC_RESOURCE, _ENABLE, data32))
376             apiMask |= NVBIT(RS_API_ALLOC_RESOURCE);
377 
378         if (FLD_TEST_DRF(_REG_STR_RM, _READONLY_API_LOCK, _FREE_RESOURCE, _ENABLE, data32))
379             apiMask |= NVBIT(RS_API_FREE_RESOURCE);
380 
381         if (FLD_TEST_DRF(_REG_STR_RM, _READONLY_API_LOCK, _MAP, _ENABLE, data32))
382             apiMask |= NVBIT(RS_API_MAP);
383 
384         if (FLD_TEST_DRF(_REG_STR_RM, _READONLY_API_LOCK, _UNMAP, _ENABLE, data32))
385             apiMask |= NVBIT(RS_API_UNMAP);
386 
387         if (FLD_TEST_DRF(_REG_STR_RM, _READONLY_API_LOCK, _INTER_MAP, _ENABLE, data32))
388             apiMask |= NVBIT(RS_API_INTER_MAP);
389 
390         if (FLD_TEST_DRF(_REG_STR_RM, _READONLY_API_LOCK, _INTER_UNMAP, _ENABLE, data32))
391             apiMask |= NVBIT(RS_API_INTER_UNMAP);
392 
393         if (FLD_TEST_DRF(_REG_STR_RM, _READONLY_API_LOCK, _CTRL, _ENABLE, data32))
394             apiMask |= NVBIT(RS_API_CTRL);
395 
396         if (FLD_TEST_DRF(_REG_STR_RM, _READONLY_API_LOCK, _COPY, _ENABLE, data32))
397             apiMask |= NVBIT(RS_API_COPY);
398 
399         if (FLD_TEST_DRF(_REG_STR_RM, _READONLY_API_LOCK, _SHARE, _ENABLE, data32))
400             apiMask |= NVBIT(RS_API_SHARE);
401 
402         pSys->apiLockMask = apiMask;
403     }
404     else
405     {
406         pSys->apiLockMask = NVBIT(RS_API_CTRL);
407     }
408 
409     if (osReadRegistryDword(pGpu, NV_REG_STR_RM_READONLY_API_LOCK_MODULE,
410                             &data32) == NV_OK)
411     {
412         pSys->apiLockModuleMask = data32;
413     }
414     else
415     {
416         pSys->apiLockModuleMask = RM_LOCK_MODULE_GRP(RM_LOCK_MODULES_CLIENT);
417     }
418 
419     if (osReadRegistryDword(pGpu, NV_REG_STR_RM_CLIENT_HANDLE_LOOKUP,
420                             &data32) == NV_OK)
421     {
422         pSys->setProperty(pSys, PDB_PROP_SYS_CLIENT_HANDLE_LOOKUP, !!data32);
423     }
424 
425     if (osReadRegistryDword(pGpu, NV_REG_STR_RM_LOCK_TIME_COLLECT,
426                             &data32) == NV_OK)
427     {
428         pSys->setProperty(pSys, PDB_PROP_SYS_RM_LOCK_TIME_COLLECT, !!data32);
429     }
430 
431     if (osReadRegistryDword(pGpu, NV_REG_STR_RM_CLIENT_LIST_DEFERRED_FREE,
432                             &data32) == NV_OK)
433     {
434         pSys->bUseDeferredClientListFree = !!data32;
435     }
436 
437     if (osReadRegistryDword(pGpu, NV_REG_STR_RM_CLIENT_LIST_DEFERRED_FREE_LIMIT,
438                             &data32) == NV_OK)
439     {
440         pSys->clientListDeferredFreeLimit = data32;
441     }
442 
443     if (osReadRegistryDword(pGpu, NV_REG_STR_RM_UUID_BASED_MEMORY_SHARING,
444                             &data32) == NV_OK)
445     {
446         pSys->bSysUuidBasedMemExportSupport = !!data32;
447     }
448 }
449 
450 static void
451 _sysRegistryOverrideExternalFabricMgmt
452 (
453     OBJSYS *pSys,
454     OBJGPU *pGpu
455 )
456 {
457     NvU32 data32;
458 
459     // Set external fabric management property
460     if (osReadRegistryDword(pGpu, NV_REG_STR_RM_EXTERNAL_FABRIC_MGMT,
461                             &data32) == NV_OK)
462     {
463         if (FLD_TEST_DRF(_REG_STR_RM, _EXTERNAL_FABRIC_MGMT, _MODE, _ENABLE, data32))
464         {
465             NV_PRINTF(LEVEL_INFO,
466                       "Enabling external fabric management.\n");
467 
468             pSys->setProperty(pSys, PDB_PROP_SYS_FABRIC_IS_EXTERNALLY_MANAGED, NV_TRUE);
469         }
470 
471         if (FLD_TEST_DRF(_REG_STR_RM, _EXTERNAL_FABRIC_MGMT, _MODE, _DISABLE, data32))
472         {
473             NV_PRINTF(LEVEL_INFO,
474                       "Disabling external fabric management.\n");
475 
476             pSys->setProperty(pSys, PDB_PROP_SYS_FABRIC_IS_EXTERNALLY_MANAGED, NV_FALSE);
477         }
478     }
479 }
480 
481 void
482 sysEnableExternalFabricMgmt_IMPL
483 (
484     OBJSYS *pSys
485 )
486 {
487     pSys->setProperty(pSys, PDB_PROP_SYS_FABRIC_IS_EXTERNALLY_MANAGED, NV_TRUE);
488 
489     NV_PRINTF(LEVEL_INFO,
490               "Enabling external fabric management for Proxy NvSwitch systems.\n");
491 }
492 
493 void
494 sysForceInitFabricManagerState_IMPL
495 (
496     OBJSYS *pSys
497 )
498 {
499     //
500     // We should only allow force init if there is not way to run fabric
501     // manager. For example, HGX-2 virtualization use-case.
502     //
503     if (pSys->getProperty(pSys, PDB_PROP_SYS_NVSWITCH_IS_PRESENT) ||
504         pSys->getProperty(pSys, PDB_PROP_SYS_FABRIC_MANAGER_IS_REGISTERED))
505     {
506         NV_ASSERT(0);
507         return;
508     }
509 
510     pSys->setProperty(pSys, PDB_PROP_SYS_FABRIC_MANAGER_IS_INITIALIZED, NV_TRUE);
511 
512     NV_PRINTF(LEVEL_INFO,
513               "Forcing fabric manager's state as initialized to unblock clients.\n");
514 }
515 
516 static void
517 _sysNvSwitchDetection
518 (
519     OBJSYS *pSys
520 )
521 {
522 
523     if (osIsNvswitchPresent())
524     {
525         pSys->setProperty(pSys, PDB_PROP_SYS_NVSWITCH_IS_PRESENT, NV_TRUE);
526 
527         NV_PRINTF(LEVEL_INFO, "NvSwitch is found in the system\n");
528 
529         sysEnableExternalFabricMgmt(pSys);
530     }
531 }
532 
533 /*!
534  * @brief Initialize static system configuration data.
535  *
536  * @param[in]   pSys    SYSTEM object pointer
537  */
538 static void
539 _sysInitStaticConfig(OBJSYS *pSys)
540 {
541     portMemSet(&pSys->staticConfig, 0, sizeof(pSys->staticConfig));
542     osInitSystemStaticConfig(&pSys->staticConfig);
543 }
544 
545 NV_STATUS
546 coreInitializeRm(void)
547 {
548     NV_STATUS  status;
549     OBJSYS    *pSys = NULL;
550 
551     //
552     // Initialize libraries used by RM
553     //
554 
555     // Portable runtime init
556     status = portInitialize();
557     if (status != NV_OK)
558         return status;
559 
560     // Required before any NvLog (NV_PRINTF) calls
561     NVLOG_INIT(NULL);
562 
563     // Required before any NV_PRINTF() calls
564     if (!DBG_INIT())
565     {
566         status = NV_ERR_GENERIC;
567         return status;
568     }
569 
570     //
571     // Initialize OBJSYS which spawns all the RM internal modules
572     //
573     status = objCreate(&pSys, NVOC_NULL_OBJECT, OBJSYS);
574 
575     nvAssertInit();
576 
577     return status;
578  }
579 
580 void
581 coreShutdownRm(void)
582 {
583     OBJSYS *pSys = SYS_GET_INSTANCE();
584 
585     //
586     // Destruct OBJSYS which frees all the RM internal modules
587     //
588     objDelete(pSys);
589 
590     //
591     // Deinitialize libraries used by RM
592     //
593     nvAssertDestroy();
594 
595     DBG_DESTROY();
596 
597     NVLOG_DESTROY();
598 
599     portShutdown();
600 }
601 
602 // Obsolete RM init function -- code should migrate to new interfaces
603 NvS32
604 RmInitRm(void)
605 {
606     return (coreInitializeRm() == NV_OK);
607 }
608 
609 // Obsolete RM destroy function -- code should migrate to new interfaces
610 NvS32
611 RmDestroyRm(void)
612 {
613     coreShutdownRm();
614     return NV_TRUE;
615 }
616 
617 static NV_STATUS
618 _sysCreateOs(OBJSYS *pSys)
619 {
620     OBJOS      *pOS;
621     NV_STATUS   status;
622 
623     // RMCONFIG: only if OS is enabled :-)
624     RMCFG_MODULE_ENABLED_OR_BAIL(OS);
625 
626     status = objCreate(&pOS, pSys, OBJOS);
627     if (status != NV_OK)
628     {
629         return status;
630     }
631 
632     status = constructObjOS(pOS);
633     if (status != NV_OK)
634     {
635         objDelete(pOS);
636         return status;
637     }
638 
639     status = osRmCapRegisterSys(&pSys->pOsRmCaps);
640     if (status != NV_OK)
641     {
642         //
643         // Device objects needed for some access rights failed
644         // This is not system-critical since access rights are currently disabled,
645         // so continue booting, just log error.
646         //
647         // RS-TODO make this fail once RM Capabilities are enabled (Bug 2549938)
648         //
649         NV_PRINTF(LEVEL_ERROR, "RM Access Sys Cap creation failed: 0x%x\n", status);
650     }
651 
652     pSys->pOS = pOS;
653 
654     return NV_OK;
655 }
656 
657 NV_STATUS
658 sysCaptureState_IMPL(OBJSYS *pSys)
659 {
660     return NV_OK;
661 }
662 
663 OBJOS*
664 sysGetOs_IMPL(OBJSYS *pSys)
665 {
666     if (pSys->pOS)
667         return pSys->pOS;
668 
669     //
670     // A special case for any early 'get-object' calls for the OS
671     // object before there is an OS object. Some RC code called on
672     // DBG_BREAKPOINT assumes an OS object exists, and can cause a crash.
673     //
674     PORT_BREAKPOINT_ALWAYS();
675 
676     return NULL;
677 }
678 
679 void
680 sysInitRegistryOverrides_IMPL
681 (
682     OBJSYS         *pSys
683 )
684 {
685     OBJGPU         *pGpu      = NULL;
686     NvU32           data32    = 0;
687 
688     if (pSys->getProperty(pSys,
689                 PDB_PROP_SYS_REGISTRY_OVERRIDES_INITIALIZED))
690     {
691         // The registry overrides, if any, have already been applied.
692         return;
693     }
694 
695     // Get some GPU - as of now we need some gpu to read registry.
696     pGpu = gpumgrGetSomeGpu();
697     if (pGpu == NULL)
698     {
699         // Too early call ! we can not read the registry.
700         return;
701     }
702 
703     if ((osReadRegistryDword(pGpu,
704             NV_REG_STR_RM_ENABLE_EVENT_TRACER, &data32) == NV_OK) && data32 )
705     {
706         RMTRACE_ENABLE(data32);
707     }
708 
709     if (osReadRegistryDword(pGpu,
710             NV_REG_STR_RM_CLIENT_DATA_VALIDATION, &data32) == NV_OK)
711     {
712         if (FLD_TEST_DRF(_REG_STR_RM, _CLIENT_DATA_VALIDATION, _KERNEL_BUFFERS, _ENABLED, data32))
713         {
714             pSys->setProperty(pSys, PDB_PROP_SYS_VALIDATE_KERNEL_BUFFERS, NV_TRUE);
715         }
716         else if (FLD_TEST_DRF(_REG_STR_RM, _CLIENT_DATA_VALIDATION, _KERNEL_BUFFERS, _DISABLED, data32))
717         {
718             pSys->setProperty(pSys, PDB_PROP_SYS_VALIDATE_KERNEL_BUFFERS, NV_FALSE);
719         }
720 
721         if (FLD_TEST_DRF(_REG_STR_RM, _CLIENT_DATA_VALIDATION, _HANDLE, _ENABLED, data32))
722         {
723             pSys->setProperty(pSys, PDB_PROP_SYS_VALIDATE_CLIENT_HANDLE, NV_TRUE);
724         }
725         else  if (FLD_TEST_DRF(_REG_STR_RM, _CLIENT_DATA_VALIDATION, _HANDLE, _DISABLED, data32))
726         {
727             pSys->setProperty(pSys, PDB_PROP_SYS_VALIDATE_CLIENT_HANDLE, NV_FALSE);
728         }
729 
730         if (FLD_TEST_DRF(_REG_STR_RM, _CLIENT_DATA_VALIDATION, _STRICT_CLIENT, _ENABLED, data32))
731         {
732             pSys->setProperty(pSys, PDB_PROP_SYS_VALIDATE_CLIENT_HANDLE_STRICT, NV_TRUE);
733         }
734         else if (FLD_TEST_DRF(_REG_STR_RM, _CLIENT_DATA_VALIDATION, _STRICT_CLIENT, _DISABLED, data32))
735         {
736             pSys->setProperty(pSys, PDB_PROP_SYS_VALIDATE_CLIENT_HANDLE_STRICT, NV_FALSE);
737         }
738 
739         if (FLD_TEST_DRF(_REG_STR_RM, _CLIENT_DATA_VALIDATION, _ALL, _ENABLED, data32))
740         {
741             pSys->setProperty(pSys, PDB_PROP_SYS_VALIDATE_CLIENT_HANDLE, NV_TRUE);
742             pSys->setProperty(pSys, PDB_PROP_SYS_VALIDATE_KERNEL_BUFFERS, NV_TRUE);
743             pSys->setProperty(pSys, PDB_PROP_SYS_VALIDATE_CLIENT_HANDLE_STRICT, NV_TRUE);
744         }
745         else  if (FLD_TEST_DRF(_REG_STR_RM, _CLIENT_DATA_VALIDATION, _ALL, _DISABLED, data32))
746         {
747             pSys->setProperty(pSys, PDB_PROP_SYS_VALIDATE_CLIENT_HANDLE, NV_FALSE);
748             pSys->setProperty(pSys, PDB_PROP_SYS_VALIDATE_KERNEL_BUFFERS, NV_FALSE);
749             pSys->setProperty(pSys, PDB_PROP_SYS_VALIDATE_CLIENT_HANDLE_STRICT, NV_FALSE);
750         }
751     }
752 
753     pSys->setProperty(pSys, PDB_PROP_SYS_REGISTRY_OVERRIDES_INITIALIZED, NV_TRUE);
754 
755     if (osReadRegistryDword(pGpu, NV_REG_STR_RM_STREAM_MEMOPS,
756                             &data32) == NV_OK)
757     {
758         if (FLD_TEST_DRF(_REG_STR_RM, _STREAM_MEMOPS, _ENABLE, _YES, data32))
759         {
760             pSys->setProperty(pSys, PDB_PROP_SYS_ENABLE_STREAM_MEMOPS, NV_TRUE);
761         }
762     }
763 
764     if (osReadRegistryDword(pGpu, NV_REG_STR_RM_PRIORITY_BOOST,
765                             &data32) == NV_OK)
766     {
767         if (data32 == NV_REG_STR_RM_PRIORITY_BOOST_DISABLE)
768             pSys->setProperty(pSys, PDB_PROP_SYS_PRIORITY_BOOST, NV_FALSE);
769         else
770             pSys->setProperty(pSys, PDB_PROP_SYS_PRIORITY_BOOST, NV_TRUE);
771     }
772 
773     if (osReadRegistryDword(pGpu, NV_REG_STR_RM_PRIORITY_THROTTLE_DELAY,
774                             &data32) == NV_OK)
775     {
776         pSys->setProperty(pSys, PDB_PROP_SYS_PRIORITY_THROTTLE_DELAY_US, data32);
777     }
778 
779     _sysRegistryOverrideExternalFabricMgmt(pSys, pGpu);
780     _sysRegistryOverrideResourceServer(pSys, pGpu);
781 
782     if (osBugCheckOnTimeoutEnabled())
783     {
784         pSys->setProperty(pSys, PDB_PROP_SYS_BUGCHECK_ON_TIMEOUT, NV_TRUE);
785     }
786 
787     if (osReadRegistryDword(pGpu, NV_REG_STR_RM_ENABLE_ROUTE_TO_PHYSICAL_LOCK_BYPASS,
788                             &data32) == NV_OK)
789     {
790         pSys->setProperty(pSys, PDB_PROP_SYS_ROUTE_TO_PHYSICAL_LOCK_BYPASS, !!data32);
791     }
792 
793     if (osReadRegistryDword(pGpu, NV_REG_STR_RM_GPU_LOCK_MIDPATH, &data32) == NV_OK)
794     {
795         pSys->setProperty(pSys, PDB_PROP_SYS_GPU_LOCK_MIDPATH_ENABLED, !!data32);
796     }
797 
798     gpumgrSetGpuNvlinkBwModeFromRegistry(pGpu);
799 }
800 
801 void
802 sysApplyLockingPolicy_IMPL(OBJSYS *pSys)
803 {
804     g_resServ.bRouteToPhysicalLockBypass = pSys->getProperty(pSys, PDB_PROP_SYS_ROUTE_TO_PHYSICAL_LOCK_BYPASS);
805     g_resServ.roTopLockApiMask = pSys->apiLockMask;
806 }
807 
808 NV_STATUS
809 sysSyncExternalFabricMgmtWAR_IMPL
810 (
811     OBJSYS  *pSys,
812     OBJGPU  *pGpu
813 )
814 {
815     NV0000_CTRL_CMD_SYSTEM_SYNC_EXTERNAL_FABRIC_MGMT_PARAMS params;
816     RM_API    *pRmApi = GPU_GET_PHYSICAL_RMAPI(pGpu);
817     NV_STATUS  status = NV_OK;
818 
819     params.bExternalFabricMgmt = pSys->getProperty(pSys,
820                                      PDB_PROP_SYS_FABRIC_IS_EXTERNALLY_MANAGED);
821 
822     status = pRmApi->Control(pRmApi, pGpu->hInternalClient, pGpu->hInternalClient,
823                              NV0000_CTRL_CMD_SYSTEM_SYNC_EXTERNAL_FABRIC_MGMT,
824                              &params, sizeof(params));
825 
826     return status;
827 }
828