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