1 /*
2 * SPDX-FileCopyrightText: Copyright (c) 2004-2024 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 /*!
25 * @file
26 * @brief This module contains the gpu control interfaces for the
27 * subdevice (NV20_SUBDEVICE_0) class. Subdevice-level control calls
28 * are directed unicast to the associated GPU.
29 * File contains ctrls related to general GPU
30 */
31
32 #include "core/core.h"
33 #include "core/locks.h"
34 #include "gpu/subdevice/subdevice.h"
35 #include "gpu/gpu.h"
36 #include "gpu_mgr/gpu_db.h"
37 #include "nvrm_registry.h"
38 #include "nvVer.h"
39 #include "gpu/bif/kernel_bif.h"
40 #include "gpu/bus/kern_bus.h"
41 #include "gpu/gsp/gsp_static_config.h"
42 #include "gpu/disp/kern_disp.h"
43 #include "disp/nvfbc_session.h"
44 #include "gpu/mmu/kern_gmmu.h"
45 #include "kernel/gpu/intr/intr.h"
46 #include "kernel/gpu/mc/kernel_mc.h"
47 #include "kernel/gpu/nvlink/kernel_nvlink.h"
48 #include "gpu/gpu_fabric_probe.h"
49 #include "gpu/timer/objtmr.h"
50 #include "platform/chipset/chipset.h"
51 #include "kernel/gpu/gr/kernel_graphics.h"
52 #include "kernel/gpu/mig_mgr/kernel_mig_manager.h"
53 #include "kernel/gpu/gr/kernel_graphics_manager.h"
54 #include "vgpu/rpc.h"
55 #include "gpu/mem_mgr/mem_mgr.h"
56 #include "virtualization/hypervisor/hypervisor.h"
57 #include "gpu/mem_sys/kern_mem_sys.h"
58 #include "gpu/nvenc/nvencsession.h"
59 #include "kernel/gpu/fifo/kernel_fifo.h"
60 #include "gpu/ce/kernel_ce_shared.h"
61 #include "rmapi/resource_fwd_decls.h"
62 #include "rmapi/client.h"
63
64 #include "class/cl900e.h"
65
66
67
68 // bit to set when telling physical to fill in an info entry
69 #define INDEX_FORWARD_TO_PHYSICAL 0x80000000
70 ct_assert(INDEX_FORWARD_TO_PHYSICAL == DRF_NUM(2080, _CTRL_GPU_INFO_INDEX, _RESERVED, 1));
71
72 static NV_STATUS
getGpuInfos(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_INFO_V2_PARAMS * pParams,NvBool bCanAccessHw)73 getGpuInfos(Subdevice *pSubdevice, NV2080_CTRL_GPU_GET_INFO_V2_PARAMS *pParams, NvBool bCanAccessHw)
74 {
75 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
76 NV_STATUS status = NV_OK;
77 NvU32 i = 0;
78 NvU32 data = 0;
79 NvBool bPhysicalForward = NV_FALSE;
80
81 if ((pParams->gpuInfoListSize > NV2080_CTRL_GPU_INFO_MAX_LIST_SIZE) ||
82 (pParams->gpuInfoListSize == 0))
83 {
84 return NV_ERR_INVALID_ARGUMENT;
85 }
86
87 for (i = 0; i < pParams->gpuInfoListSize; i++)
88 {
89
90 const NvU32 index = DRF_VAL(2080, _CTRL_GPU_INFO_INDEX, _INDEX, pParams->gpuInfoList[i].index);
91
92 if (index >= NV2080_CTRL_GPU_INFO_MAX_LIST_SIZE)
93 {
94 return NV_ERR_INVALID_ARGUMENT;
95 }
96
97 const NvU32 groupId = DRF_VAL(2080, _CTRL_GPU_INFO_INDEX, _GROUP_ID, pParams->gpuInfoList[i].index);
98
99 if (groupId >= pGpu->gpuGroupCount)
100 {
101 NV_PRINTF(LEVEL_WARNING, "invalid groupId\n");
102 return NV_ERR_INVALID_ARGUMENT;
103 }
104
105 data = 0;
106
107 switch (index)
108 {
109 case NV2080_CTRL_GPU_INFO_INDEX_ECID_LO32:
110 {
111 if (IS_GSP_CLIENT(pGpu))
112 {
113 GspStaticConfigInfo *pGSCI = GPU_GET_GSP_STATIC_INFO(pGpu);
114 data = pGSCI->ecidInfo[groupId].ecidLow;
115 break;
116 }
117 data = 0;
118 status = NV_ERR_NOT_SUPPORTED;
119 break;
120 }
121 case NV2080_CTRL_GPU_INFO_INDEX_ECID_HI32:
122 {
123 if (IS_GSP_CLIENT(pGpu))
124 {
125 GspStaticConfigInfo *pGSCI = GPU_GET_GSP_STATIC_INFO(pGpu);
126 data = pGSCI->ecidInfo[groupId].ecidHigh;
127 break;
128 }
129 data = 0;
130 status = NV_ERR_NOT_SUPPORTED;
131 break;
132 }
133 case NV2080_CTRL_GPU_INFO_INDEX_ECID_EXTENDED:
134 {
135 if (IS_GSP_CLIENT(pGpu))
136 {
137 GspStaticConfigInfo *pGSCI = GPU_GET_GSP_STATIC_INFO(pGpu);
138 data = pGSCI->ecidInfo[groupId].ecidExtended;
139 break;
140 }
141 data = 0;
142 status = NV_ERR_NOT_SUPPORTED;
143 break;
144 }
145 case NV2080_CTRL_GPU_INFO_INDEX_GPU_FLA_CAPABILITY:
146 {
147 KernelBus *pKernelBus = GPU_GET_KERNEL_BUS(pGpu);
148
149 if (kbusIsFlaSupported(pKernelBus))
150 {
151 data = NV2080_CTRL_GPU_INFO_INDEX_GPU_FLA_CAPABILITY_YES;
152 }
153 else
154 {
155 data = NV2080_CTRL_GPU_INFO_INDEX_GPU_FLA_CAPABILITY_NO;
156 }
157 break;
158 }
159 case NV2080_CTRL_GPU_INFO_INDEX_MINOR_REVISION_EXT:
160 {
161 data = gpuGetChipMinExtRev(pGpu);
162 break;
163 }
164 case NV2080_CTRL_GPU_INFO_INDEX_NETLIST_REV0:
165 {
166 data = 0;
167 break;
168 }
169 case NV2080_CTRL_GPU_INFO_INDEX_NETLIST_REV1:
170 {
171 data = 0;
172 break;
173 }
174 case NV2080_CTRL_GPU_INFO_INDEX_SYSMEM_ACCESS:
175 {
176 data = NV2080_CTRL_GPU_INFO_SYSMEM_ACCESS_YES;
177 break;
178 }
179 case NV2080_CTRL_GPU_INFO_INDEX_GEMINI_BOARD:
180 {
181 data = !!pGpu->getProperty(pGpu, PDB_PROP_GPU_IS_GEMINI);
182 break;
183 }
184 case NV2080_CTRL_GPU_INFO_INDEX_SURPRISE_REMOVAL_POSSIBLE:
185 {
186 OBJSYS *pSys = SYS_GET_INSTANCE();
187 OBJCL *pCl = SYS_GET_CL(pSys);
188 data = !!pCl->getProperty(pCl, PDB_PROP_CL_IS_EXTERNAL_GPU);
189 break;
190 }
191 case NV2080_CTRL_GPU_INFO_INDEX_IBMNPU_RELAXED_ORDERING:
192 {
193 NvBool mode = NV_FALSE;
194 data = NV2080_CTRL_GPU_INFO_IBMNPU_RELAXED_ORDERING_UNSUPPORTED;
195
196 if (osGetIbmnpuRelaxedOrderingMode(pGpu->pOsGpuInfo, &mode) == NV_OK)
197 {
198 data = NV2080_CTRL_GPU_INFO_IBMNPU_RELAXED_ORDERING_DISABLED;
199
200 if (mode)
201 {
202 data = NV2080_CTRL_GPU_INFO_IBMNPU_RELAXED_ORDERING_ENABLED;
203 }
204 }
205 break;
206 }
207 case NV2080_CTRL_GPU_INFO_INDEX_GLOBAL_POISON_FUSE_ENABLED:
208 {
209 if (gpuIsGlobalPoisonFuseEnabled(pGpu))
210 {
211 data = NV2080_CTRL_GPU_INFO_INDEX_GLOBAL_POISON_FUSE_ENABLED_YES;
212 }
213 else
214 {
215 data = NV2080_CTRL_GPU_INFO_INDEX_GLOBAL_POISON_FUSE_ENABLED_NO;
216 }
217 break;
218 }
219 case NV2080_CTRL_GPU_INFO_INDEX_NVSWITCH_PROXY_DETECTED:
220 {
221 NV_CHECK_OR_ELSE(LEVEL_WARNING, bCanAccessHw,
222 { data = 0; status = NV_ERR_INVALID_ARGUMENT; break; });
223
224 KernelNvlink *pKernelNvlink = GPU_GET_KERNEL_NVLINK(pGpu);
225
226 data = NV2080_CTRL_GPU_INFO_NVSWITCH_PROXY_DETECTED_NO;
227
228 if (pKernelNvlink != NULL &&
229 knvlinkIsNvswitchProxyPresent(pGpu, pKernelNvlink))
230 {
231 data = NV2080_CTRL_GPU_INFO_NVSWITCH_PROXY_DETECTED_YES;
232 }
233 break;
234 }
235 case NV2080_CTRL_GPU_INFO_INDEX_GPU_SMC_MODE:
236 {
237 NV_CHECK_OR_ELSE(LEVEL_WARNING, bCanAccessHw,
238 { data = 0; status = NV_ERR_INVALID_ARGUMENT; break; });
239
240 RM_API *pRmApi = GPU_GET_PHYSICAL_RMAPI(pGpu);
241 NV2080_CTRL_INTERNAL_GPU_GET_SMC_MODE_PARAMS params;
242
243 if (IS_VIRTUAL(pGpu))
244 {
245 KernelMIGManager *pKernelMIGManager = GPU_GET_KERNEL_MIG_MANAGER(pGpu);
246
247 if ((pKernelMIGManager == NULL) || !kmigmgrIsMIGSupported(pGpu, pKernelMIGManager))
248 {
249 data = NV2080_CTRL_GPU_INFO_GPU_SMC_MODE_UNSUPPORTED;
250 break;
251 }
252
253 data = IS_MIG_ENABLED(pGpu) ?
254 NV2080_CTRL_GPU_INFO_GPU_SMC_MODE_ENABLED :
255 NV2080_CTRL_GPU_INFO_GPU_SMC_MODE_DISABLED;
256
257 break;
258 }
259
260 portMemSet(¶ms, 0x0, sizeof(params));
261 status = pRmApi->Control(pRmApi,
262 pGpu->hInternalClient,
263 pGpu->hInternalSubdevice,
264 NV2080_CTRL_CMD_INTERNAL_GPU_GET_SMC_MODE,
265 ¶ms,
266 sizeof(params));
267 data = params.smcMode;
268 break;
269 }
270 case NV2080_CTRL_GPU_INFO_INDEX_SPLIT_VAS_MGMT_SERVER_CLIENT_RM:
271 {
272 if (gpuIsSplitVasManagementServerClientRmEnabled(pGpu))
273 {
274 data = NV2080_CTRL_GPU_INFO_SPLIT_VAS_MGMT_SERVER_CLIENT_RM_YES;
275 }
276 else
277 {
278 data = NV2080_CTRL_GPU_INFO_SPLIT_VAS_MGMT_SERVER_CLIENT_RM_NO;
279 }
280 break;
281 }
282 case NV2080_CTRL_GPU_INFO_INDEX_GPU_SM_VERSION:
283 {
284 KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
285
286 if ((pKernelGraphicsManager == NULL) ||
287 !kgrmgrGetLegacyKGraphicsStaticInfo(pGpu, pKernelGraphicsManager)->bInitialized ||
288 (kgrmgrGetLegacyKGraphicsStaticInfo(pGpu, pKernelGraphicsManager)->pGrInfo == NULL))
289 {
290 NV_PRINTF(LEVEL_ERROR, "Unable to retrieve SM version!\n");
291 data = NV2080_CTRL_GR_INFO_SM_VERSION_NONE;
292 status = NV_ERR_INVALID_STATE;
293 }
294 else
295 {
296 data = kgrmgrGetLegacyKGraphicsStaticInfo(pGpu, pKernelGraphicsManager)->pGrInfo->infoList[NV2080_CTRL_GR_INFO_INDEX_SM_VERSION].data;
297 }
298 break;
299 }
300 case NV2080_CTRL_GPU_INFO_INDEX_PER_RUNLIST_CHANNEL_RAM:
301 {
302 KernelFifo *pKernelFifo = GPU_GET_KERNEL_FIFO(pGpu);
303
304 if (kfifoIsPerRunlistChramEnabled(pKernelFifo))
305 {
306 data = NV2080_CTRL_GPU_INFO_INDEX_PER_RUNLIST_CHANNEL_RAM_ENABLED;
307 }
308 else
309 {
310 data = NV2080_CTRL_GPU_INFO_INDEX_PER_RUNLIST_CHANNEL_RAM_DISABLED;
311 }
312 break;
313 }
314 case NV2080_CTRL_GPU_INFO_INDEX_GPU_ATS_CAPABILITY:
315 {
316 if (pGpu->getProperty(pGpu, PDB_PROP_GPU_ATS_SUPPORTED))
317 {
318 data = NV2080_CTRL_GPU_INFO_INDEX_GPU_ATS_CAPABILITY_YES;
319 }
320 else
321 {
322 data = NV2080_CTRL_GPU_INFO_INDEX_GPU_ATS_CAPABILITY_NO;
323 }
324 break;
325 }
326 case NV2080_CTRL_GPU_INFO_INDEX_NVENC_STATS_REPORTING_STATE:
327 {
328 if (IS_VIRTUAL(pGpu))
329 {
330 // On vGPU, if encoding is supported then we need to keep the NvEnc stats reporting state enabled
331 // all the time so that NvEnc UMD keeps pushing the raw timestamp data.
332 // This is to handle the migration case where on source host the NvEnc stats reporting was disabled,
333 // but on target host the NvEnc stats reporting is enabled. If UMD doesn't keep pushing raw data
334 // even if stats reporting was disabled on source host, we won't be able to report NvEnc stats on
335 // target host data reporting is enabled.
336 if (pGpu->encSessionStatsReportingState == NV2080_CTRL_GPU_INFO_NVENC_STATS_REPORTING_STATE_NOT_SUPPORTED)
337 {
338 data = NV2080_CTRL_GPU_INFO_NVENC_STATS_REPORTING_STATE_NOT_SUPPORTED;
339 }
340 else
341 {
342 data = NV2080_CTRL_GPU_INFO_NVENC_STATS_REPORTING_STATE_ENABLED;
343 }
344 }
345 else
346 {
347 data = pGpu->encSessionStatsReportingState;
348 }
349 break;
350 }
351 case NV2080_CTRL_GPU_INFO_INDEX_4K_PAGE_ISOLATION_REQUIRED:
352 {
353 if (pGpu->bNeed4kPageIsolation)
354 {
355 data = NV2080_CTRL_GPU_INFO_INDEX_4K_PAGE_ISOLATION_REQUIRED_YES;
356 }
357 else
358 {
359 data = NV2080_CTRL_GPU_INFO_INDEX_4K_PAGE_ISOLATION_REQUIRED_NO;
360 }
361 break;
362 }
363 case NV2080_CTRL_GPU_INFO_INDEX_DISPLAY_ENABLED:
364 {
365 if (GPU_GET_KERNEL_DISPLAY(pGpu) != NULL)
366 {
367 data = NV2080_CTRL_GPU_INFO_DISPLAY_ENABLED_YES;
368 }
369 else
370 {
371 data = NV2080_CTRL_GPU_INFO_DISPLAY_ENABLED_NO;
372 }
373 break;
374 }
375 case NV2080_CTRL_GPU_INFO_INDEX_MOBILE_CONFIG_ENABLED:
376 {
377 if (IsMobile(pGpu))
378 {
379 data = NV2080_CTRL_GPU_INFO_INDEX_MOBILE_CONFIG_ENABLED_YES;
380 }
381 else
382 {
383 data = NV2080_CTRL_GPU_INFO_INDEX_MOBILE_CONFIG_ENABLED_NO;
384 }
385 break;
386 }
387 case NV2080_CTRL_GPU_INFO_INDEX_GPU_PROFILING_CAPABILITY:
388 {
389 if (IS_VIRTUAL(pGpu))
390 {
391 VGPU_STATIC_INFO *pVSI = GPU_GET_STATIC_INFO(pGpu);
392 if (pVSI)
393 {
394 data = pVSI->vgpuStaticProperties.bProfilingTracingEnabled ?
395 NV2080_CTRL_GPU_INFO_INDEX_GPU_PROFILING_CAPABILITY_ENABLED :
396 NV2080_CTRL_GPU_INFO_INDEX_GPU_PROFILING_CAPABILITY_DISABLED;
397 }
398 else
399 {
400 data = NV2080_CTRL_GPU_INFO_INDEX_GPU_PROFILING_CAPABILITY_DISABLED;
401 }
402 }
403 else
404 {
405 // Always return ENABLED for Baremetal/Host
406 data = NV2080_CTRL_GPU_INFO_INDEX_GPU_PROFILING_CAPABILITY_ENABLED;
407 }
408 break;
409 }
410 case NV2080_CTRL_GPU_INFO_INDEX_GPU_DEBUGGING_CAPABILITY:
411 {
412 if (IS_VIRTUAL(pGpu))
413 {
414 VGPU_STATIC_INFO *pVSI = GPU_GET_STATIC_INFO(pGpu);
415 if (pVSI)
416 {
417 data = pVSI->vgpuStaticProperties.bDebuggingEnabled ?
418 NV2080_CTRL_GPU_INFO_INDEX_GPU_DEBUGGING_CAPABILITY_ENABLED :
419 NV2080_CTRL_GPU_INFO_INDEX_GPU_DEBUGGING_CAPABILITY_DISABLED;
420 }
421 else
422 {
423 data = NV2080_CTRL_GPU_INFO_INDEX_GPU_DEBUGGING_CAPABILITY_DISABLED;
424 }
425 }
426 else
427 {
428 // Always return ENABLED for Baremetal/Host
429 data = NV2080_CTRL_GPU_INFO_INDEX_GPU_DEBUGGING_CAPABILITY_ENABLED;
430 }
431 break;
432 }
433 case NV2080_CTRL_GPU_INFO_INDEX_GPU_LOCAL_EGM_CAPABILITY:
434 {
435 MemoryManager *pMemoryManager = GPU_GET_MEMORY_MANAGER(pGpu);
436 if (memmgrIsLocalEgmEnabled(pMemoryManager))
437 {
438 data = NV2080_CTRL_GPU_INFO_INDEX_GPU_LOCAL_EGM_CAPABILITY_YES;
439 data = FLD_SET_DRF_NUM(2080_CTRL_GPU_INFO, _INDEX_GPU_LOCAL_EGM, _PEERID, pMemoryManager->localEgmPeerId, data);
440 }
441 else
442 {
443 data = NV2080_CTRL_GPU_INFO_INDEX_GPU_LOCAL_EGM_CAPABILITY_NO;
444 }
445 break;
446 }
447 case NV2080_CTRL_GPU_INFO_INDEX_GPU_SELF_HOSTED_CAPABILITY:
448 {
449 KernelBif *pKernelBif = GPU_GET_KERNEL_BIF(pGpu);
450
451 if (gpuIsSelfHosted(pGpu) &&
452 pKernelBif->getProperty(pKernelBif, PDB_PROP_KBIF_IS_C2C_LINK_UP))
453 {
454 data = NV2080_CTRL_GPU_INFO_INDEX_GPU_SELF_HOSTED_CAPABILITY_YES;
455 }
456 else
457 {
458 data = NV2080_CTRL_GPU_INFO_INDEX_GPU_SELF_HOSTED_CAPABILITY_NO;
459 }
460 break;
461 }
462 case NV2080_CTRL_GPU_INFO_INDEX_CMP_SKU:
463 {
464 if (gpuGetChipInfo(pGpu) && gpuGetChipInfo(pGpu)->isCmpSku)
465 {
466 data = NV2080_CTRL_GPU_INFO_INDEX_CMP_SKU_YES;
467 }
468 else
469 {
470 data = NV2080_CTRL_GPU_INFO_INDEX_CMP_SKU_NO;
471 }
472 break;
473 }
474 case NV2080_CTRL_GPU_INFO_INDEX_DMABUF_CAPABILITY:
475 {
476 data = NV2080_CTRL_GPU_INFO_INDEX_DMABUF_CAPABILITY_NO;
477
478 if (osDmabufIsSupported() &&
479 (!IS_VIRTUAL(pGpu)) &&
480 (!gpuIsApmFeatureEnabled(pGpu)) &&
481 (!NVCPU_IS_PPC64LE))
482 {
483 data = NV2080_CTRL_GPU_INFO_INDEX_DMABUF_CAPABILITY_YES;
484 }
485 break;
486 }
487 case NV2080_CTRL_GPU_INFO_INDEX_IS_RESETLESS_MIG_SUPPORTED:
488 {
489 data = NV2080_CTRL_GPU_INFO_INDEX_IS_RESETLESS_MIG_SUPPORTED_NO;
490
491 if (pGpu->getProperty(pGpu, PDB_PROP_GPU_RESETLESS_MIG_SUPPORTED))
492 {
493 data = NV2080_CTRL_GPU_INFO_INDEX_IS_RESETLESS_MIG_SUPPORTED_YES;
494 }
495 break;
496 }
497 default:
498 {
499 // Only forward to physical if we're in the HW-access-enabled control
500 if ((IS_GSP_CLIENT(pGpu) || IS_VIRTUAL(pGpu)) && bCanAccessHw)
501 {
502 pParams->gpuInfoList[i].index |= INDEX_FORWARD_TO_PHYSICAL;
503 bPhysicalForward = NV_TRUE;
504 }
505 else
506 {
507 data = 0;
508 status = NV_ERR_INVALID_ARGUMENT;
509 }
510 break;
511 }
512 }
513
514 if (status != NV_OK)
515 {
516 break;
517 }
518
519 // save off data value
520 pParams->gpuInfoList[i].data = data;
521 }
522
523 if ((IS_GSP_CLIENT(pGpu) || IS_VIRTUAL(pGpu)) && bPhysicalForward && (status == NV_OK))
524 {
525 NV_RM_RPC_CONTROL(pGpu,
526 RES_GET_CLIENT_HANDLE(pSubdevice),
527 RES_GET_HANDLE(pSubdevice),
528 NV2080_CTRL_CMD_GPU_GET_INFO_V2,
529 pParams, sizeof(*pParams), status);
530 }
531
532 return status;
533 }
534
535 #undef INDEX_FORWARD_TO_PHYSICAL
536
537 NV_STATUS
subdeviceCtrlCmdGpuGetInfoV2_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_INFO_V2_PARAMS * pGpuInfoParams)538 subdeviceCtrlCmdGpuGetInfoV2_IMPL
539 (
540 Subdevice *pSubdevice,
541 NV2080_CTRL_GPU_GET_INFO_V2_PARAMS *pGpuInfoParams
542 )
543 {
544 return getGpuInfos(pSubdevice, pGpuInfoParams, NV_TRUE);
545 }
546
547 NV_STATUS
subdeviceCtrlCmdGpuGetVfCaps_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_VF_CAPS_PARAMS * pParams)548 subdeviceCtrlCmdGpuGetVfCaps_IMPL
549 (
550 Subdevice *pSubdevice,
551 NV2080_CTRL_GPU_GET_VF_CAPS_PARAMS *pParams
552 )
553 {
554 return NV_ERR_NOT_SUPPORTED;
555 }
556
557 //
558 // subdeviceCtrlCmdGpuGetCachedInfo: As subdeviceCtrlCmdGpuGetInfoV2, except
559 // does not perform any HW access (NO_GPUS_ACCESS and NO_GPUS_LOCK flags)
560 //
561 NV_STATUS
subdeviceCtrlCmdGpuGetCachedInfo_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_INFO_V2_PARAMS * pGpuInfoParams)562 subdeviceCtrlCmdGpuGetCachedInfo_IMPL
563 (
564 Subdevice *pSubdevice,
565 NV2080_CTRL_GPU_GET_INFO_V2_PARAMS *pGpuInfoParams
566 )
567 {
568 return getGpuInfos(pSubdevice, pGpuInfoParams, NV_FALSE);
569 }
570
571 static OBJHWBC *
getBridgeObject(OBJHWBC * pHWBC,NvU32 hwbcId)572 getBridgeObject(OBJHWBC *pHWBC, NvU32 hwbcId)
573 {
574 OBJHWBC *pBridgeObject = NULL;
575 if (NULL != pHWBC)
576 {
577 if (hwbcId == pHWBC->hwbcId)
578 {
579 pBridgeObject = pHWBC;
580 }
581 else
582 {
583 pBridgeObject = getBridgeObject(pHWBC->pSibling, hwbcId);
584 if (NULL == pBridgeObject)
585 {
586 pBridgeObject = getBridgeObject(pHWBC->pFirstChild, hwbcId);
587 }
588 }
589 }
590 return pBridgeObject;
591 }
592
593 static NV_STATUS
getPlxFirmwareAndBusInfo(OBJHWBC * pHWBC,NvU32 * domainId,NvU8 * busId,NvU8 * deviceId,NvU8 * funcId,NvU32 * fwVersion,NvU8 * oemVersion,NvU8 * siliconRevision,NvU8 * bcRes)594 getPlxFirmwareAndBusInfo
595 (
596 OBJHWBC *pHWBC,
597 NvU32 *domainId,
598 NvU8 *busId,
599 NvU8 *deviceId,
600 NvU8 *funcId,
601 NvU32 *fwVersion,
602 NvU8 *oemVersion,
603 NvU8 *siliconRevision,
604 NvU8 *bcRes
605 )
606 {
607 if (NULL == pHWBC)
608 {
609 return NV_ERR_INVALID_ARGUMENT;
610 }
611
612 if (domainId)
613 *domainId = pHWBC->ctrlDev.domain;
614 if (busId)
615 *busId = pHWBC->ctrlDev.bus;
616 if (deviceId)
617 *deviceId = pHWBC->ctrlDev.device;
618 if (funcId)
619 *funcId = pHWBC->ctrlDev.func;
620 if (fwVersion)
621 *fwVersion = pHWBC->fwVersion;
622 if (oemVersion)
623 *oemVersion = pHWBC->fwOemVersion;
624 if (siliconRevision)
625 *siliconRevision = pHWBC->plxRevision;
626 if (bcRes)
627 *bcRes = (NvU8)pHWBC->bcRes;
628 return NV_OK;
629 }
630
631 static NV_STATUS
getPlxFirmwareVersion(NvU32 hwbcId,NvU32 * fwVersion,NvU8 * oemVersion,NvU8 * siliconRevision,NvU8 * bcRes)632 getPlxFirmwareVersion
633 (
634 NvU32 hwbcId,
635 NvU32 *fwVersion,
636 NvU8 *oemVersion,
637 NvU8 *siliconRevision,
638 NvU8 *bcRes
639 )
640 {
641 OBJSYS *pSys = SYS_GET_INSTANCE();
642 OBJCL *pCl = SYS_GET_CL(pSys);
643 OBJHWBC *pHWBC = getBridgeObject(pCl->pHWBC, hwbcId);
644
645 return getPlxFirmwareAndBusInfo(pHWBC, NULL, NULL, NULL, NULL, fwVersion,
646 oemVersion, siliconRevision, bcRes);
647 }
648
649 static NvU8
getBridgeCountAndId(OBJHWBC * pHWBC,NvU32 pBridgeId[],NvU32 * bridgeIndex)650 getBridgeCountAndId(OBJHWBC *pHWBC, NvU32 pBridgeId[], NvU32 *bridgeIndex)
651 {
652 NvU8 count = 0;
653 if ((NULL == bridgeIndex) ||
654 (*bridgeIndex >= NV2080_CTRL_MAX_PHYSICAL_BRIDGE))
655 {
656 return count;
657 }
658 if (NULL != pHWBC)
659 {
660 if ((HWBC_PLX_PEX8747 == pHWBC->bcRes) || (HWBC_NVIDIA_BR04 == pHWBC->bcRes))
661 {
662 pBridgeId[*bridgeIndex] = pHWBC->hwbcId;
663 (*bridgeIndex)++;
664 count++;
665 }
666 count += getBridgeCountAndId(pHWBC->pSibling, pBridgeId, bridgeIndex);
667 count += getBridgeCountAndId(pHWBC->pFirstChild, pBridgeId, bridgeIndex);
668 }
669 return count;
670 }
671
672 static NV_STATUS
getBridgeData(NvU8 * pPlxCount,NvU32 pBridgeId[])673 getBridgeData
674 (
675 NvU8 *pPlxCount,
676 NvU32 pBridgeId[]
677 )
678 {
679 OBJSYS *pSys = SYS_GET_INSTANCE();
680 OBJCL *pCl = SYS_GET_CL(pSys);
681 NvU32 bridgeIndex = 0;
682
683 if (NULL == pPlxCount)
684 {
685 return NV_ERR_INVALID_ARGUMENT;
686 }
687
688 *pPlxCount = getBridgeCountAndId(pCl->pHWBC, pBridgeId, &bridgeIndex);
689 NV_ASSERT_OR_RETURN(*pPlxCount < NV2080_CTRL_MAX_PHYSICAL_BRIDGE,
690 NV_ERR_OUT_OF_RANGE);
691 return NV_OK;
692 }
693
694 static NV_STATUS
getUpstreamBridgeIds(OBJGPU * pGpu,NvU8 * pPlxCount,NvU32 pBridgeId[])695 getUpstreamBridgeIds
696 (
697 OBJGPU *pGpu,
698 NvU8 *pPlxCount,
699 NvU32 pBridgeId[]
700 )
701 {
702 HWBC_LIST *pGpuHWBCList;
703 NvU8 bridgeIndex = 0;
704
705 if (NULL == pPlxCount)
706 {
707 return NV_ERR_INVALID_ARGUMENT;
708 }
709
710 pGpuHWBCList = pGpu->pHWBCList;
711 while(pGpuHWBCList)
712 {
713 NV_ASSERT_OR_RETURN(pGpuHWBCList->pHWBC != NULL, NV_ERR_INVALID_POINTER);
714 pBridgeId[bridgeIndex] = pGpuHWBCList->pHWBC->hwbcId;
715 pGpuHWBCList = pGpuHWBCList->pNext;
716 bridgeIndex++;
717 NV_ASSERT_OR_RETURN(bridgeIndex < NV2080_CTRL_MAX_PHYSICAL_BRIDGE,
718 NV_ERR_OUT_OF_RANGE);
719 }
720 *pPlxCount = bridgeIndex;
721
722 return NV_OK;
723 }
724
725 NV_STATUS
subdeviceCtrlCmdGpuGetPhysicalBridgeVersionInfo_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_PHYSICAL_BRIDGE_VERSION_INFO_PARAMS * pBridgeInfoParams)726 subdeviceCtrlCmdGpuGetPhysicalBridgeVersionInfo_IMPL
727 (
728 Subdevice *pSubdevice,
729 NV2080_CTRL_GPU_GET_PHYSICAL_BRIDGE_VERSION_INFO_PARAMS *pBridgeInfoParams
730 )
731 {
732 NV_STATUS status = NV_OK;
733 NvU8 bridgeIndex;
734 status = getBridgeData(&pBridgeInfoParams->bridgeCount,
735 pBridgeInfoParams->hPhysicalBridges);
736 if (status == NV_OK)
737 {
738 NV2080_CTRL_GPU_PHYSICAL_BRIDGE_VERSION_PARAMS *pBridgeVersionParams =
739 pBridgeInfoParams->bridgeList;
740 for (bridgeIndex = 0;
741 bridgeIndex < pBridgeInfoParams->bridgeCount;
742 bridgeIndex++)
743 {
744 status = getPlxFirmwareVersion(pBridgeInfoParams->hPhysicalBridges[bridgeIndex],
745 &pBridgeVersionParams->fwVersion,
746 &pBridgeVersionParams->oemVersion,
747 &pBridgeVersionParams->siliconRevision,
748 &pBridgeVersionParams->hwbcResourceType);
749 if (status != NV_OK)
750 {
751 break;
752 }
753 pBridgeVersionParams++;
754 }
755 }
756 return status;
757 }
758
759 NV_STATUS
subdeviceCtrlCmdGpuGetAllBridgesUpstreamOfGpu_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_ALL_BRIDGES_UPSTREAM_OF_GPU_PARAMS * pBridgeInfoParams)760 subdeviceCtrlCmdGpuGetAllBridgesUpstreamOfGpu_IMPL
761 (
762 Subdevice *pSubdevice,
763 NV2080_CTRL_GPU_GET_ALL_BRIDGES_UPSTREAM_OF_GPU_PARAMS *pBridgeInfoParams
764 )
765 {
766 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
767 NV_STATUS status = NV_OK;
768 NvU8 bridgeIndex;
769 HWBC_LIST *pGpuHWBCList;
770 status = getUpstreamBridgeIds(pGpu,
771 &pBridgeInfoParams->bridgeCount,
772 pBridgeInfoParams->physicalBridgeIds);
773 if (status == NV_OK)
774 {
775 NV2080_CTRL_GPU_BRIDGE_VERSION_PARAMS *pBridgeVersionParams =
776 pBridgeInfoParams->bridgeList;
777 pGpuHWBCList = pGpu->pHWBCList;
778 for (bridgeIndex = 0;
779 bridgeIndex < pBridgeInfoParams->bridgeCount && pGpuHWBCList;
780 bridgeIndex++)
781 {
782 status = getPlxFirmwareAndBusInfo(pGpuHWBCList->pHWBC,
783 &pBridgeVersionParams->domain,
784 &pBridgeVersionParams->bus,
785 &pBridgeVersionParams->device,
786 &pBridgeVersionParams->func,
787 &pBridgeVersionParams->fwVersion,
788 &pBridgeVersionParams->oemVersion,
789 &pBridgeVersionParams->siliconRevision,
790 &pBridgeVersionParams->hwbcResourceType);
791 if (status != NV_OK)
792 {
793 break;
794 }
795 pGpuHWBCList = pGpuHWBCList->pNext;
796 pBridgeVersionParams++;
797 }
798 }
799 return status;
800 }
801
802 /*!
803 * @brief This command can be used for Optimus enabled system.
804 *
805 * @return :
806 * NV_OK
807 */
808 NV_STATUS
subdeviceCtrlCmdGpuSetOptimusInfo_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_OPTIMUS_INFO_PARAMS * pGpuOptimusInfoParams)809 subdeviceCtrlCmdGpuSetOptimusInfo_IMPL
810 (
811 Subdevice *pSubdevice,
812 NV2080_CTRL_GPU_OPTIMUS_INFO_PARAMS *pGpuOptimusInfoParams
813 )
814 {
815 NvU32 status = NV_OK;
816 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
817
818 if (pGpuOptimusInfoParams->isOptimusEnabled)
819 {
820 //
821 // Setting pMemoryManager->bPersistentStandbyBuffer for Optimus system.
822 // It is used for sys_mem allocation which is pinned across
823 // S3 transitions.Sys_mem allocations are done at first S3 cycle
824 // and release during driver unload, which reduces system
825 // VM fragmentation, which was a problem in optimus system.
826 // For more details refer bug 754122.
827 //
828 GPU_GET_MEMORY_MANAGER(pGpu)->bPersistentStandbyBuffer = NV_TRUE;
829 }
830 return status;
831 }
832
833 // RM reports dynamic encoder capacity as a percentage (0-100) of the encoders fixed
834 // capacity. Fixed capacity is readable via NvEncode API and is defined in
835 // drivers/video/encode/src/CNVVAEncoder.cpp#200
836 //
837 // Dynamic capacity of 0x0 indicates that encoder performance may be minimal for this
838 // GPU and software should fall back to CPU-based encode.
839 //
840
841 #define NV_ENC_CAPACITY_MAX_VALUE 100
842 //
843 // subdeviceCtrlCmdGpuGetEncoderCapacity
844 //
845 // Lock Requirements:
846 // Assert that API lock and GPUs lock held on entry
847 //
848 NV_STATUS
subdeviceCtrlCmdGpuGetEncoderCapacity_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_ENCODER_CAPACITY_PARAMS * pEncoderCapacityParams)849 subdeviceCtrlCmdGpuGetEncoderCapacity_IMPL
850 (
851 Subdevice *pSubdevice,
852 NV2080_CTRL_GPU_GET_ENCODER_CAPACITY_PARAMS *pEncoderCapacityParams
853 )
854 {
855 NV_STATUS rmStatus = NV_OK;
856 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
857 NvHandle hClient = RES_GET_CLIENT_HANDLE(pSubdevice);
858 NvHandle hObject = RES_GET_HANDLE(pSubdevice);
859
860 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmGpuLockIsOwner());
861
862 if (pEncoderCapacityParams->queryType == NV2080_CTRL_GPU_GET_ENCODER_CAPACITY_AV1)
863 {
864 if (pGpu->bGpuNvEncAv1Supported == NV_FALSE)
865 {
866 return NV_ERR_NOT_SUPPORTED;
867 }
868 }
869 else if ((pEncoderCapacityParams->queryType != NV2080_CTRL_GPU_GET_ENCODER_CAPACITY_H264) &&
870 (pEncoderCapacityParams->queryType != NV2080_CTRL_GPU_GET_ENCODER_CAPACITY_HEVC))
871 {
872 return NV_ERR_INVALID_ARGUMENT;
873 }
874
875 pEncoderCapacityParams->encoderCapacity = NV_ENC_CAPACITY_MAX_VALUE;
876
877 //
878 // vGPU: Since vGPU does all real hardware management
879 // in the host, there is nothing to do at this point in
880 // the guest OS (where IS_VIRTUAL(pGpu) is true).
881 //
882 if (IS_VIRTUAL(pGpu)) // Otherwise default for vGPU host/baremetal/NMOS/GSP_CLIENT
883 {
884 NV_RM_RPC_GET_ENCODER_CAPACITY(pGpu,
885 hClient,
886 hObject,
887 &pEncoderCapacityParams->encoderCapacity,
888 rmStatus);
889 }
890 return rmStatus;
891 }
892
893 //
894 // subdeviceCtrlCmdGpuGetNvencSwSessionStats
895 //
896 // Lock Requirements:
897 // Assert that API lock and GPUs lock held on entry
898 //
899 NV_STATUS
subdeviceCtrlCmdGpuGetNvencSwSessionStats_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_NVENC_SW_SESSION_STATS_PARAMS * pParams)900 subdeviceCtrlCmdGpuGetNvencSwSessionStats_IMPL
901 (
902 Subdevice *pSubdevice,
903 NV2080_CTRL_GPU_GET_NVENC_SW_SESSION_STATS_PARAMS *pParams
904 )
905 {
906
907 NvU32 averageEncodeFps = 0, averageEncodeLatency = 0;
908 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
909 NvencSession *pNvencSession = NULL;
910 PNVENC_SESSION_LIST_ITEM pNvencSessionListItem = NULL;
911
912 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmGpuLockIsOwner());
913
914 //
915 // For GSP vGPU host, get the data from GSP RM for CPU RM and it's client
916 //
917 if (IS_GSP_CLIENT(pGpu) && IS_VGPU_GSP_PLUGIN_OFFLOAD_ENABLED(pGpu))
918 {
919 CALL_CONTEXT *pCallContext = resservGetTlsCallContext();
920 RmCtrlParams *pRmCtrlParams = pCallContext->pControlParams;
921 RM_API *pRmApi = GPU_GET_PHYSICAL_RMAPI(pGpu);
922
923 return pRmApi->Control(pRmApi,
924 pRmCtrlParams->hClient,
925 pRmCtrlParams->hObject,
926 pRmCtrlParams->cmd,
927 pRmCtrlParams->pParams,
928 pRmCtrlParams->paramsSize);
929 }
930
931 if (listCount(&(pGpu->nvencSessionList)) == 0)
932 {
933 pParams->encoderSessionCount = 0;
934 pParams->averageEncodeFps = 0;
935 pParams->averageEncodeLatency = 0;
936 return NV_OK;
937 }
938
939 pParams->encoderSessionCount = listCount(&(pGpu->nvencSessionList));
940
941 for (pNvencSessionListItem = listHead(&(pGpu->nvencSessionList));
942 pNvencSessionListItem != NULL;
943 pNvencSessionListItem = listNext(&(pGpu->nvencSessionList), pNvencSessionListItem))
944 {
945 if (pNvencSessionListItem->sessionPtr)
946 {
947 pNvencSession = pNvencSessionListItem->sessionPtr;
948
949 averageEncodeFps += pNvencSession->nvencSessionEntry.averageEncodeFps;
950 averageEncodeLatency += pNvencSession->nvencSessionEntry.averageEncodeLatency;
951 }
952 }
953
954 // average FPS and latency over all active sessions on this GPU.
955 pParams->averageEncodeFps = averageEncodeFps / listCount(&(pGpu->nvencSessionList));
956 pParams->averageEncodeLatency = averageEncodeLatency / listCount(&(pGpu->nvencSessionList));
957
958 return NV_OK;
959 }
960
961 NV_STATUS
_subdeviceCtrlCmdGpuGetNvencSwSessionInfo(OBJGPU * pGpu,NvU32 sessionInfoTblEntry,NV2080_CTRL_NVENC_SW_SESSION_INFO * pSessionInfo,NvU32 * entryCount)962 _subdeviceCtrlCmdGpuGetNvencSwSessionInfo
963 (
964 OBJGPU *pGpu,
965 NvU32 sessionInfoTblEntry,
966 NV2080_CTRL_NVENC_SW_SESSION_INFO *pSessionInfo,
967 NvU32 *entryCount
968 )
969 {
970
971 NvencSession *pNvencSession = NULL;
972 PNVENC_SESSION_LIST_ITEM pNvencSessionListItem = NULL;
973 NvU32 i = 0;
974 NV2080_CTRL_NVENC_SW_SESSION_INFO *pSession;
975
976 NV_ASSERT_OR_RETURN(sessionInfoTblEntry ==
977 NV2080_CTRL_GPU_NVENC_SESSION_INFO_MAX_COPYOUT_ENTRIES,
978 NV_ERR_INVALID_ARGUMENT);
979
980 portMemSet(pSessionInfo, 0, sizeof(NV2080_CTRL_NVENC_SW_SESSION_INFO) * sessionInfoTblEntry);
981
982 for (pNvencSessionListItem = listHead(&(pGpu->nvencSessionList));
983 pNvencSessionListItem != NULL;
984 pNvencSessionListItem = listNext(&(pGpu->nvencSessionList), pNvencSessionListItem))
985 {
986 if (pNvencSessionListItem->sessionPtr)
987 {
988 pNvencSession = pNvencSessionListItem->sessionPtr;
989 pSession = &pSessionInfo[i];
990
991 pSession->sessionId = pNvencSession->nvencSessionEntry.sessionId;
992 pSession->processId = pNvencSession->nvencSessionEntry.processId;
993 pSession->subProcessId = pNvencSession->nvencSessionEntry.subProcessId;
994 pSession->codecType = pNvencSession->nvencSessionEntry.codecType;
995 pSession->hResolution = pNvencSession->nvencSessionEntry.hResolution;
996 pSession->vResolution = pNvencSession->nvencSessionEntry.vResolution;
997 pSession->averageEncodeFps = pNvencSession->nvencSessionEntry.averageEncodeFps;
998 pSession->averageEncodeLatency = pNvencSession->nvencSessionEntry.averageEncodeLatency;
999
1000 i++;
1001
1002 if (i == NV2080_CTRL_GPU_NVENC_SESSION_INFO_MAX_COPYOUT_ENTRIES)
1003 {
1004 // Stop copying beyond max size otherwise we might corrupt other kernel data
1005 break;
1006 }
1007 }
1008 }
1009
1010 //
1011 // Copy the data only if sessionInfoTbl entry is equals or greater
1012 // than current active sessions i.e. listCount(&(pGpu->nvencSessionList))
1013 //
1014 *entryCount = i;
1015
1016 return NV_OK;
1017 }
1018
1019 //
1020 // subdeviceCtrlCmdGpuGetNvencSwSessionInfo
1021 //
1022 // Lock Requirements:
1023 // Assert that API lock and GPUs lock held on entry
1024 //
1025
1026 NV_STATUS
subdeviceCtrlCmdGpuGetNvencSwSessionInfo_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_NVENC_SW_SESSION_INFO_PARAMS * pParams)1027 subdeviceCtrlCmdGpuGetNvencSwSessionInfo_IMPL
1028 (
1029 Subdevice *pSubdevice,
1030 NV2080_CTRL_GPU_GET_NVENC_SW_SESSION_INFO_PARAMS *pParams
1031 )
1032 {
1033 NV_STATUS status = NV_OK;
1034 NV2080_CTRL_NVENC_SW_SESSION_INFO *pSessionInfo = NvP64_VALUE(pParams->sessionInfoTbl);
1035 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
1036 NvU32 entryCount = 0;
1037
1038 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmGpuLockIsOwner());
1039
1040 if ((!IS_VIRTUAL(pGpu)) && (pGpu->encSessionStatsReportingState != NV2080_CTRL_GPU_INFO_NVENC_STATS_REPORTING_STATE_ENABLED))
1041 {
1042 pParams->sessionInfoTblEntry = 0;
1043 return status;
1044 }
1045
1046 if (pParams->sessionInfoTbl == NvP64_NULL || listCount(&(pGpu->nvencSessionList)) == 0)
1047 {
1048 pParams->sessionInfoTblEntry = listCount(&(pGpu->nvencSessionList));
1049 return status;
1050 }
1051
1052 status = _subdeviceCtrlCmdGpuGetNvencSwSessionInfo(pGpu, pParams->sessionInfoTblEntry, pSessionInfo, &entryCount);
1053 if (status != NV_OK)
1054 return status;
1055
1056 pParams->sessionInfoTblEntry = entryCount;
1057
1058 return status;
1059 }
1060
1061 NV_STATUS
subdeviceCtrlCmdGpuGetNvencSwSessionInfoV2_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_NVENC_SW_SESSION_INFO_V2_PARAMS * pParams)1062 subdeviceCtrlCmdGpuGetNvencSwSessionInfoV2_IMPL
1063 (
1064 Subdevice *pSubdevice,
1065 NV2080_CTRL_GPU_GET_NVENC_SW_SESSION_INFO_V2_PARAMS *pParams
1066 )
1067 {
1068 NV_STATUS status = NV_OK;
1069 NV2080_CTRL_NVENC_SW_SESSION_INFO *pSessionInfo = pParams->sessionInfoTbl;
1070 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
1071 NvU32 entryCount = 0;
1072
1073 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmGpuLockIsOwner());
1074
1075 if ((!IS_VIRTUAL(pGpu)) && (pGpu->encSessionStatsReportingState != NV2080_CTRL_GPU_INFO_NVENC_STATS_REPORTING_STATE_ENABLED))
1076 {
1077 pParams->sessionInfoTblEntry = 0;
1078 return status;
1079 }
1080
1081 if (pParams->sessionInfoTblEntry == 0 || listCount(&(pGpu->nvencSessionList)) == 0)
1082 {
1083 pParams->sessionInfoTblEntry = listCount(&(pGpu->nvencSessionList));
1084 return status;
1085 }
1086
1087 status = _subdeviceCtrlCmdGpuGetNvencSwSessionInfo(pGpu, pParams->sessionInfoTblEntry, pSessionInfo, &entryCount);
1088 if (status != NV_OK)
1089 return status;
1090
1091 pParams->sessionInfoTblEntry = entryCount;
1092
1093 return status;
1094 }
1095
1096 //
1097 // subdeviceCtrlCmdGpuGetNvfbcSwSessionStats
1098 //
1099 // Lock Requirements:
1100 // Assert that API lock and GPUs lock held on entry
1101 //
1102 NV_STATUS
subdeviceCtrlCmdGpuGetNvfbcSwSessionStats_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_NVFBC_SW_SESSION_STATS_PARAMS * pParams)1103 subdeviceCtrlCmdGpuGetNvfbcSwSessionStats_IMPL
1104 (
1105 Subdevice *pSubdevice,
1106 NV2080_CTRL_GPU_GET_NVFBC_SW_SESSION_STATS_PARAMS *pParams
1107 )
1108 {
1109
1110 NvU32 averageFPS = 0, averageLatency = 0, localSessionCount = 0;
1111 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
1112 NvfbcSession *pNvfbcSession = NULL;
1113 PNVFBC_SESSION_LIST_ITEM pNvfbcSessionListItem = NULL;
1114
1115 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmGpuLockIsOwner());
1116
1117 if (listCount(&(pGpu->nvfbcSessionList)) == 0)
1118 {
1119 pParams->sessionCount = 0;
1120 pParams->averageFPS = 0;
1121 pParams->averageLatency = 0;
1122 return NV_OK;
1123 }
1124
1125 for (pNvfbcSessionListItem = listHead(&(pGpu->nvfbcSessionList));
1126 pNvfbcSessionListItem != NULL;
1127 pNvfbcSessionListItem = listNext(&(pGpu->nvfbcSessionList), pNvfbcSessionListItem))
1128 {
1129 if (pNvfbcSessionListItem->sessionPtr)
1130 {
1131 pNvfbcSession = pNvfbcSessionListItem->sessionPtr;
1132
1133 averageFPS += pNvfbcSession->nvfbcSessionEntry.averageFPS;
1134 averageLatency += pNvfbcSession->nvfbcSessionEntry.averageLatency;
1135
1136 localSessionCount++;
1137 }
1138 }
1139
1140 // average FPS and latency over all active sessions on this GPU.
1141 pParams->averageFPS = localSessionCount == 0 ? 0 : (averageFPS / localSessionCount);
1142 pParams->averageLatency = localSessionCount == 0 ? 0 : (averageLatency / localSessionCount);
1143
1144 pParams->sessionCount = localSessionCount;
1145
1146 return NV_OK;
1147 }
1148
1149 //
1150 // subdeviceCtrlCmdGpuGetNvfbcSwSessionInfo
1151 //
1152 // Lock Requirements:
1153 // Assert that API lock and GPUs lock held on entry
1154 //
1155
1156 NV_STATUS
subdeviceCtrlCmdGpuGetNvfbcSwSessionInfo_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_NVFBC_SW_SESSION_INFO_PARAMS * pParams)1157 subdeviceCtrlCmdGpuGetNvfbcSwSessionInfo_IMPL
1158 (
1159 Subdevice *pSubdevice,
1160 NV2080_CTRL_GPU_GET_NVFBC_SW_SESSION_INFO_PARAMS *pParams
1161 )
1162 {
1163
1164 NV2080_CTRL_NVFBC_SW_SESSION_INFO *pSession, *pSessionInfo = pParams->sessionInfoTbl;
1165 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
1166 NvU32 i = 0;
1167 NvfbcSession *pNvfbcSession = NULL;
1168 PNVFBC_SESSION_LIST_ITEM pNvfbcSessionListItem = NULL;
1169
1170 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmGpuLockIsOwner());
1171
1172 portMemSet(pParams, 0, sizeof(NV2080_CTRL_GPU_GET_NVFBC_SW_SESSION_INFO_PARAMS));
1173
1174 for (pNvfbcSessionListItem = listHead(&(pGpu->nvfbcSessionList));
1175 pNvfbcSessionListItem != NULL;
1176 pNvfbcSessionListItem = listNext(&(pGpu->nvfbcSessionList), pNvfbcSessionListItem))
1177 {
1178 if (pNvfbcSessionListItem->sessionPtr)
1179 {
1180 pNvfbcSession = pNvfbcSessionListItem->sessionPtr;
1181 pSession = &pSessionInfo[i];
1182
1183 pSession->processId = pNvfbcSession->nvfbcSessionEntry.processId;
1184 pSession->vgpuInstanceId = pNvfbcSession->nvfbcSessionEntry.vgpuInstanceId;
1185 pSession->sessionId = pNvfbcSession->nvfbcSessionEntry.sessionId;
1186 pSession->displayOrdinal = pNvfbcSession->nvfbcSessionEntry.displayOrdinal;
1187 pSession->sessionType = pNvfbcSession->nvfbcSessionEntry.sessionType;
1188 pSession->sessionFlags = pNvfbcSession->nvfbcSessionEntry.sessionFlags;
1189 pSession->hMaxResolution = pNvfbcSession->nvfbcSessionEntry.hMaxResolution;
1190 pSession->vMaxResolution = pNvfbcSession->nvfbcSessionEntry.vMaxResolution;
1191
1192 // All the following fields are dynamic fields.
1193 // We will return these as 0 if these are stale values.
1194 if (nvfbcIsSessionDataStale(pNvfbcSession->nvfbcSessionEntry.lastUpdateTimeStamp))
1195 {
1196 pSession->hResolution = 0;
1197 pSession->vResolution = 0;
1198 pSession->averageFPS = 0;
1199 pSession->averageLatency = 0;
1200 }
1201 else
1202 {
1203 pSession->hResolution = pNvfbcSession->nvfbcSessionEntry.hResolution;
1204 pSession->vResolution = pNvfbcSession->nvfbcSessionEntry.vResolution;
1205 pSession->averageFPS = pNvfbcSession->nvfbcSessionEntry.averageFPS;
1206 pSession->averageLatency = pNvfbcSession->nvfbcSessionEntry.averageLatency;
1207 }
1208
1209 i++;
1210
1211 if (i == NV2080_GPU_NVFBC_MAX_SESSION_COUNT)
1212 {
1213 NV_ASSERT(0);
1214 NV_PRINTF(LEVEL_ERROR,
1215 "more entries in pGpu->nvencSessionList than "
1216 "NV2080_CTRL_GPU_NVENC_SESSION_INFO_MAX_COPYOUT_ENTRIES\n");
1217
1218 // Stop copying beyond max size otherwise we might corrupt other kernel data.
1219 break;
1220 }
1221 }
1222 }
1223
1224 pParams->sessionInfoCount = i;
1225
1226 return NV_OK;
1227 }
1228
1229 //
1230 // subdeviceCtrlCmdGpuGetSdm
1231 //
1232 // Lock Requirements:
1233 // Assert that API lock held on entry
1234 //
1235 NV_STATUS
subdeviceCtrlCmdGpuGetSdm_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_SDM_PARAMS * pSdmParams)1236 subdeviceCtrlCmdGpuGetSdm_IMPL
1237 (
1238 Subdevice *pSubdevice,
1239 NV2080_CTRL_GPU_GET_SDM_PARAMS *pSdmParams
1240 )
1241 {
1242 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
1243
1244 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner());
1245
1246 pSdmParams->subdeviceMask = gpuGetSubdeviceMask(pGpu);
1247
1248 return NV_OK;
1249 }
1250
1251 //
1252 // subdeviceCtrlCmdGpuSetSdm
1253 //
1254 // Lock Requirements:
1255 // Assert that API lock held on entry
1256 //
1257 NV_STATUS
subdeviceCtrlCmdGpuSetSdm_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_SET_SDM_PARAMS * pSdmParams)1258 subdeviceCtrlCmdGpuSetSdm_IMPL
1259 (
1260 Subdevice* pSubdevice,
1261 NV2080_CTRL_GPU_SET_SDM_PARAMS* pSdmParams
1262 )
1263 {
1264 NV_STATUS status = NV_OK;
1265 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
1266 NvU32 subdeviceInstance;
1267
1268 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner());
1269
1270 if (!ONEBITSET(pSdmParams->subdeviceMask))
1271 {
1272 NV_PRINTF(LEVEL_ERROR, "Subdevice mask has none or more than one bit set");
1273 return NV_ERR_INVALID_DATA;
1274 }
1275
1276 if (gpuIsStateLoaded(pGpu))
1277 {
1278 NV_PRINTF(LEVEL_ERROR, "NV2080_CTRL_CMD_GPU_SET_SDM cannot be called after the GPU is loaded");
1279 return NV_ERR_INVALID_STATE;
1280 }
1281
1282 subdeviceInstance = BIT_IDX_32(pSdmParams->subdeviceMask);
1283
1284 if (subdeviceInstance >= NV_MAX_SUBDEVICES)
1285 {
1286 NV_PRINTF(LEVEL_ERROR, "Subdevice mask exceeds the max count of subdevices");
1287 return NV_ERR_INVALID_DATA;
1288 }
1289
1290 pGpu->subdeviceInstance = subdeviceInstance;
1291
1292 return status;
1293 }
1294
1295 //
1296 // subdeviceCtrlCmdGpuGetSimulationInfo
1297 //
1298 // Lock Requirements:
1299 // Assert that API lock held on entry
1300 //
1301 NV_STATUS
subdeviceCtrlCmdGpuGetSimulationInfo_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_SIMULATION_INFO_PARAMS * pGpuSimulationInfoParams)1302 subdeviceCtrlCmdGpuGetSimulationInfo_IMPL
1303 (
1304 Subdevice *pSubdevice,
1305 NV2080_CTRL_GPU_GET_SIMULATION_INFO_PARAMS *pGpuSimulationInfoParams
1306 )
1307 {
1308 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
1309
1310 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner());
1311
1312 if (IS_SILICON(pGpu))
1313 {
1314 pGpuSimulationInfoParams->type = NV2080_CTRL_GPU_GET_SIMULATION_INFO_TYPE_NONE;
1315 }
1316 else
1317 {
1318 pGpuSimulationInfoParams->type = NV2080_CTRL_GPU_GET_SIMULATION_INFO_TYPE_UNKNOWN;
1319 }
1320
1321 return NV_OK;
1322 }
1323
1324 //
1325 // subdeviceCtrlCmdGpuGetEngines
1326 //
1327 // Lock Requirements:
1328 // Assert that API lock held on entry
1329 //
1330 NV_STATUS
subdeviceCtrlCmdGpuGetEngines_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_ENGINES_PARAMS * pParams)1331 subdeviceCtrlCmdGpuGetEngines_IMPL
1332 (
1333 Subdevice *pSubdevice,
1334 NV2080_CTRL_GPU_GET_ENGINES_PARAMS *pParams
1335 )
1336 {
1337 NV2080_CTRL_GPU_GET_ENGINES_V2_PARAMS getEngineParamsV2;
1338 NvU32 *pKernelEngineList = NvP64_VALUE(pParams->engineList);
1339 NV_STATUS status = NV_OK;
1340
1341 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner());
1342
1343 portMemSet(&getEngineParamsV2, 0, sizeof(getEngineParamsV2));
1344
1345 status = subdeviceCtrlCmdGpuGetEnginesV2(pSubdevice, &getEngineParamsV2);
1346 NV_CHECK_OR_RETURN(LEVEL_INFO, NV_OK == status, status);
1347
1348 // NULL clients just want an engine count
1349 if (NULL != pKernelEngineList)
1350 {
1351 NV_CHECK_OR_RETURN(LEVEL_INFO, pParams->engineCount >= getEngineParamsV2.engineCount,
1352 NV_ERR_BUFFER_TOO_SMALL);
1353 portMemCopy(pKernelEngineList,
1354 getEngineParamsV2.engineCount * sizeof(*getEngineParamsV2.engineList), getEngineParamsV2.engineList,
1355 getEngineParamsV2.engineCount * sizeof(*getEngineParamsV2.engineList));
1356 }
1357
1358 pParams->engineCount = getEngineParamsV2.engineCount;
1359
1360 return status;
1361 }
1362
1363 //
1364 // subdeviceCtrlCmdGpuGetEnginesV2
1365 //
1366 // Lock Requirements:
1367 // Assert that API lock held on entry
1368 //
1369 NV_STATUS
subdeviceCtrlCmdGpuGetEnginesV2_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_ENGINES_V2_PARAMS * pEngineParams)1370 subdeviceCtrlCmdGpuGetEnginesV2_IMPL
1371 (
1372 Subdevice *pSubdevice,
1373 NV2080_CTRL_GPU_GET_ENGINES_V2_PARAMS *pEngineParams
1374 )
1375 {
1376 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
1377 NV_STATUS status = NV_OK;
1378
1379 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner());
1380
1381 // Update the engine Database
1382 NV_ASSERT_OK_OR_RETURN(gpuUpdateEngineTable(pGpu));
1383
1384 // Validate engine count
1385 if (pGpu->engineDB.size > NV2080_GPU_MAX_ENGINES_LIST_SIZE)
1386 {
1387 NV_PRINTF(LEVEL_ERROR, "The engine database's size (0x%x) exceeds NV2080_GPU_MAX_ENGINES_LIST_SIZE (0x%x)!\n",
1388 pGpu->engineDB.size, NV2080_GPU_MAX_ENGINES_LIST_SIZE);
1389 DBG_BREAKPOINT();
1390 return NV_ERR_INVALID_STATE;
1391 }
1392
1393 {
1394 // Need this null check in case object doesn't exist when using Orin trimmed profile
1395 KernelMIGManager *pKernelMIGManager = GPU_GET_KERNEL_MIG_MANAGER(pGpu);
1396 if (pKernelMIGManager != NULL)
1397 {
1398 RM_ENGINE_TYPE rmEngineTypeList[NV2080_GPU_MAX_ENGINES_LIST_SIZE];
1399
1400 // Filter engines based on current partitioning scheme
1401 status = kmigmgrFilterEngineList(pGpu,
1402 pKernelMIGManager,
1403 pSubdevice,
1404 rmEngineTypeList,
1405 &pEngineParams->engineCount);
1406
1407 if (status == NV_OK)
1408 {
1409 // Convert the RM_ENGINE_TYPE list to NV2080_ENGINE_TYPE list
1410 gpuGetNv2080EngineTypeList(rmEngineTypeList,
1411 pEngineParams->engineCount,
1412 pEngineParams->engineList);
1413 }
1414
1415 // Validate engine count
1416 if (pEngineParams->engineCount > NV2080_GPU_MAX_ENGINES_LIST_SIZE)
1417 {
1418 NV_PRINTF(LEVEL_ERROR, "The engine count (0x%x) exceeds NV2080_GPU_MAX_ENGINES_LIST_SIZE (0x%x)!\n",
1419 pEngineParams->engineCount, NV2080_GPU_MAX_ENGINES_LIST_SIZE);
1420 DBG_BREAKPOINT();
1421 return NV_ERR_INVALID_STATE;
1422 }
1423 }
1424 }
1425
1426 // removal tracking bug: 3748354
1427 NvBool bOwnsLock = NV_FALSE;
1428 if (!rmDeviceGpuLockIsOwner(pGpu->gpuInstance))
1429 {
1430 status = rmDeviceGpuLocksAcquire(pGpu, GPU_LOCK_FLAGS_SAFE_LOCK_UPGRADE, RM_LOCK_MODULES_NONE);
1431 NV_ASSERT_OK_OR_RETURN(status);
1432
1433 bOwnsLock = NV_TRUE;
1434 NvU32 i;
1435
1436 for (i = 0; i < pEngineParams->engineCount; i++)
1437 {
1438 NvU32 nv2080EngineId;
1439 nv2080EngineId = pEngineParams->engineList[i];
1440
1441 if (NV2080_ENGINE_TYPE_IS_COPY(nv2080EngineId))
1442 {
1443 // Check if this is a decomp LCE
1444 if (ceIsDecompLce(pGpu, nv2080EngineId))
1445 {
1446 NvU32 ceInstanceId;
1447 ceInstanceId = NV2080_ENGINE_TYPE_COPY_IDX(nv2080EngineId);
1448 pEngineParams->engineList[i] = NV2080_ENGINE_TYPE_COMP_DECOMP_COPY(ceInstanceId);
1449 }
1450 }
1451 }
1452
1453
1454 if (bOwnsLock == NV_TRUE)
1455 rmDeviceGpuLocksRelease(pGpu, GPU_LOCK_FLAGS_SAFE_LOCK_UPGRADE, NULL);
1456 }
1457
1458 return status;
1459 }
1460
1461 //
1462 // subdeviceCtrlCmdGpuGetEngineClasslist
1463 //
1464 // Lock Requirements:
1465 // Assert that API lock held on entry
1466 //
1467 NV_STATUS
subdeviceCtrlCmdGpuGetEngineClasslist_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_ENGINE_CLASSLIST_PARAMS * pClassParams)1468 subdeviceCtrlCmdGpuGetEngineClasslist_IMPL
1469 (
1470 Subdevice *pSubdevice,
1471 NV2080_CTRL_GPU_GET_ENGINE_CLASSLIST_PARAMS *pClassParams
1472 )
1473 {
1474 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
1475 ENGDESCRIPTOR engDesc;
1476 NV_STATUS status = NV_OK;
1477 RM_ENGINE_TYPE rmEngineType = gpuGetRmEngineType(pClassParams->engineType);
1478
1479 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner());
1480
1481 {
1482 if (IS_MIG_IN_USE(pGpu))
1483 {
1484 KernelMIGManager *pKernelMIGManager = GPU_GET_KERNEL_MIG_MANAGER(pGpu);
1485 MIG_INSTANCE_REF ref;
1486
1487 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
1488 kmigmgrGetInstanceRefFromDevice(pGpu, pKernelMIGManager, GPU_RES_GET_DEVICE(pSubdevice), &ref));
1489
1490 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
1491 kmigmgrGetLocalToGlobalEngineType(pGpu, pKernelMIGManager, ref,
1492 rmEngineType,
1493 &rmEngineType));
1494 }
1495 }
1496
1497 status = gpuXlateClientEngineIdToEngDesc(pGpu, rmEngineType, &engDesc);
1498
1499 NV_ASSERT(status == NV_OK);
1500
1501 if (status != NV_OK)
1502 {
1503 NV_PRINTF(LEVEL_ERROR,
1504 "NV2080_CTRL_CMD_GPU_GET_ENGINE_CLASSLIST Invalid engine ID 0x%x\n",
1505 pClassParams->engineType);
1506 DBG_BREAKPOINT();
1507 return status;
1508 }
1509
1510 status = gpuGetClassList(pGpu, &pClassParams->numClasses, NvP64_VALUE(pClassParams->classList), engDesc);
1511
1512 if (status != NV_OK)
1513 {
1514 NV_PRINTF(LEVEL_ERROR,
1515 "NV2080_CTRL_CMD_GPU_GET_ENGINE_CLASSLIST Class List query failed\n");
1516 }
1517
1518 return status;
1519 }
1520
1521 //
1522 // subdeviceCtrlCmdGpuGetEnginePartnerList
1523 //
1524 // Lock Requirements:
1525 // Assert that API lock held on entry
1526 //
1527 NV_STATUS
subdeviceCtrlCmdGpuGetEnginePartnerList_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_ENGINE_PARTNERLIST_PARAMS * pPartnerListParams)1528 subdeviceCtrlCmdGpuGetEnginePartnerList_IMPL
1529 (
1530 Subdevice *pSubdevice,
1531 NV2080_CTRL_GPU_GET_ENGINE_PARTNERLIST_PARAMS *pPartnerListParams
1532 )
1533 {
1534 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
1535 KernelMIGManager *pKernelMIGManager = GPU_GET_KERNEL_MIG_MANAGER(pGpu);
1536 ENGDESCRIPTOR engDesc;
1537 NvU32 nv2080EngineType;
1538 RM_ENGINE_TYPE rmEngineType;
1539 NvU32 i;
1540 PCLASSDESCRIPTOR pClass;
1541 NV_STATUS status = NV_OK;
1542
1543 pPartnerListParams->numPartners = 0;
1544
1545 rmEngineType = gpuGetRmEngineType(pPartnerListParams->engineType);
1546
1547 status = gpuXlateClientEngineIdToEngDesc(pGpu, rmEngineType, &engDesc);
1548 if (NV_OK != status)
1549 {
1550 NV_PRINTF(LEVEL_ERROR, "Invalid engine ID 0x%x (0x%x)\n",
1551 pPartnerListParams->engineType, rmEngineType);
1552 return status;
1553 }
1554
1555 // find class in class db
1556 status = gpuGetClassByClassId(pGpu, pPartnerListParams->partnershipClassId, &pClass);
1557 if (NV_OK != status)
1558 {
1559 NV_PRINTF(LEVEL_ERROR, "Invalid class ID 0x%x\n",
1560 pPartnerListParams->partnershipClassId);
1561 return status;
1562 }
1563
1564 // Make sure that the engine related to this class is FIFO...
1565 if (pClass->engDesc != ENG_KERNEL_FIFO)
1566 {
1567 NV_PRINTF(LEVEL_ERROR,
1568 "Class 0x%x is not considered a partnership class.\n",
1569 pPartnerListParams->partnershipClassId);
1570 return NV_ERR_NOT_SUPPORTED;
1571 }
1572
1573 nv2080EngineType = pPartnerListParams->engineType;
1574
1575 // Translate the instance-local engine type to the global engine type in MIG mode
1576 if (IS_MIG_IN_USE(pGpu))
1577 {
1578 Device *pDevice = GPU_RES_GET_DEVICE(pSubdevice);
1579 MIG_INSTANCE_REF ref;
1580
1581 NV_CHECK_OK_OR_RETURN(
1582 LEVEL_ERROR,
1583 kmigmgrGetInstanceRefFromDevice(pGpu, pKernelMIGManager, pDevice, &ref));
1584
1585 NV_CHECK_OK_OR_RETURN(
1586 LEVEL_ERROR,
1587 kmigmgrGetLocalToGlobalEngineType(pGpu, pKernelMIGManager, ref,
1588 rmEngineType,
1589 &rmEngineType));
1590
1591 pPartnerListParams->engineType = gpuGetNv2080EngineType(rmEngineType);
1592 }
1593
1594 // See if the hal wants to handle this
1595 KernelFifo *pKernelFifo = GPU_GET_KERNEL_FIFO(pGpu);
1596 status = kfifoGetEnginePartnerList_HAL(pGpu, pKernelFifo, pPartnerListParams);
1597
1598 // Restore the client's passed engineType
1599 pPartnerListParams->engineType = nv2080EngineType;
1600
1601 if (NV_OK == status)
1602 {
1603 goto subdeviceCtrlCmdGpuGetEnginePartnerList_filter;
1604 }
1605
1606 //
1607 // For channels that the hal didn't handle, we should just return
1608 // all of the supported engines except for the target engine.
1609 //
1610
1611 // Update the engine Database
1612 NV_ASSERT_OK_OR_RETURN(gpuUpdateEngineTable(pGpu));
1613
1614 // Make sure it all will fit
1615 if (pGpu->engineDB.size > NV2080_CTRL_GPU_MAX_ENGINE_PARTNERS)
1616 {
1617 NV_PRINTF(LEVEL_ERROR,
1618 "partnerList space is too small, time to increase. This is fatal\n");
1619 DBG_BREAKPOINT();
1620 return status;
1621 }
1622
1623 // Copy over all of the engines except the target
1624 for (i = 0; i < pGpu->engineDB.size; i++)
1625 {
1626 nv2080EngineType = gpuGetNv2080EngineType(pGpu->engineDB.pType[i]);
1627
1628 // Skip the engine handed in
1629 if (nv2080EngineType != pPartnerListParams->engineType )
1630 {
1631 pPartnerListParams->partnerList[pPartnerListParams->numPartners++] = nv2080EngineType;
1632 }
1633 }
1634
1635 subdeviceCtrlCmdGpuGetEnginePartnerList_filter:
1636 if (IS_MIG_IN_USE(pGpu))
1637 {
1638 Device *pDevice = GPU_RES_GET_DEVICE(pSubdevice);
1639 MIG_INSTANCE_REF ref;
1640
1641 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
1642 kmigmgrGetInstanceRefFromDevice(pGpu, pKernelMIGManager, pDevice, &ref));
1643 // Remove entries which don't exist in this client's GPU instance
1644 status = kmigmgrFilterEnginePartnerList(pGpu, pKernelMIGManager,
1645 pSubdevice,
1646 pPartnerListParams);
1647
1648 }
1649
1650 return status;
1651 }
1652
1653 //
1654 // subdeviceCtrlCmdGpuGetEngineFaultInfo
1655 //
1656 // Lock Requirements:
1657 // Assert that API lock held on entry
1658 //
1659 NV_STATUS
subdeviceCtrlCmdGpuGetEngineFaultInfo_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_ENGINE_FAULT_INFO_PARAMS * pParams)1660 subdeviceCtrlCmdGpuGetEngineFaultInfo_IMPL
1661 (
1662 Subdevice *pSubdevice,
1663 NV2080_CTRL_GPU_GET_ENGINE_FAULT_INFO_PARAMS *pParams
1664 )
1665 {
1666 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
1667 KernelFifo *pKernelFifo = GPU_GET_KERNEL_FIFO(pGpu);
1668 NV_STATUS status = NV_OK;
1669 RM_ENGINE_TYPE rmEngineType = gpuGetRmEngineType(pParams->engineType);
1670
1671 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner());
1672
1673 //
1674 // When MIG is enabled, clients pass in their instance-specific engineId
1675 // rather than physical engineId since each client only sees engines available in
1676 // its own instance. So we need to convert this local engineId to physical engineId
1677 //
1678 if (IS_MIG_IN_USE(pGpu))
1679 {
1680 KernelMIGManager *pKernelMIGManager = GPU_GET_KERNEL_MIG_MANAGER(pGpu);
1681 Device *pDevice = GPU_RES_GET_DEVICE(pSubdevice);
1682 MIG_INSTANCE_REF ref;
1683
1684 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
1685 kmigmgrGetInstanceRefFromDevice(pGpu, pKernelMIGManager, pDevice, &ref));
1686
1687 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
1688 kmigmgrGetLocalToGlobalEngineType(pGpu, pKernelMIGManager, ref,
1689 rmEngineType,
1690 &rmEngineType));
1691 }
1692
1693 // Populate HW info for SW engine entry
1694 status = kfifoEngineInfoXlate_HAL(pGpu, pKernelFifo, ENGINE_INFO_TYPE_RM_ENGINE_TYPE,
1695 (NvU32)rmEngineType, ENGINE_INFO_TYPE_MMU_FAULT_ID,
1696 &pParams->mmuFaultId);
1697 if (status != NV_OK)
1698 {
1699 NV_PRINTF(LEVEL_ERROR,
1700 "NV2080_CTRL_CMD_GPU_GET_ENGINE_INFO failed\n");
1701 return status;
1702 }
1703
1704 // Only GR engine supports subcontext faulting on Volta+ chips
1705 pParams->bSubcontextSupported = (RM_ENGINE_TYPE_IS_GR(rmEngineType) &&
1706 kfifoIsSubcontextSupported(pKernelFifo));
1707
1708 return status;
1709 }
1710
1711 ct_assert(NV2080_CTRL_INTERNAL_MAX_TPC_PER_GPC_COUNT ==
1712 NV2080_CTRL_CMD_GPU_GET_PES_INFO_MAX_TPC_PER_GPC_COUNT);
1713
1714 //
1715 // subdeviceCtrlCmdGpuGetFermiGpcInfo
1716 //
1717 // Lock Requirements:
1718 // Assert that API lock and GPUs lock held on entry
1719 //
1720 NV_STATUS
subdeviceCtrlCmdGpuGetFermiGpcInfo_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_FERMI_GPC_INFO_PARAMS * pParams)1721 subdeviceCtrlCmdGpuGetFermiGpcInfo_IMPL
1722 (
1723 Subdevice *pSubdevice,
1724 NV2080_CTRL_GPU_GET_FERMI_GPC_INFO_PARAMS *pParams
1725 )
1726 {
1727 NV2080_CTRL_GR_GET_GPC_MASK_PARAMS gpcMaskParams;
1728 RM_API *pRmApi = rmapiGetInterface(RMAPI_GPU_LOCK_INTERNAL);
1729 NvHandle hClient = RES_GET_CLIENT_HANDLE(pSubdevice);
1730 NvHandle hSubdevice = RES_GET_HANDLE(pSubdevice);
1731
1732 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmDeviceGpuLockIsOwner(GPU_RES_GET_GPU(pSubdevice)->gpuInstance));
1733
1734 portMemSet(&gpcMaskParams, 0, sizeof(gpcMaskParams));
1735
1736 NV_CHECK_OK_OR_RETURN(
1737 LEVEL_ERROR,
1738 pRmApi->Control(pRmApi,
1739 hClient,
1740 hSubdevice,
1741 NV2080_CTRL_CMD_GR_GET_GPC_MASK,
1742 &gpcMaskParams,
1743 sizeof(gpcMaskParams)));
1744
1745 pParams->gpcMask = gpcMaskParams.gpcMask;
1746 return NV_OK;
1747 }
1748
1749 //
1750 // subdeviceCtrlCmdGpuGetFermiTpcInfo
1751 //
1752 // Lock Requirements:
1753 // Assert that API lock and GPUs lock held on entry
1754 //
1755 NV_STATUS
subdeviceCtrlCmdGpuGetFermiTpcInfo_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_FERMI_TPC_INFO_PARAMS * pParams)1756 subdeviceCtrlCmdGpuGetFermiTpcInfo_IMPL
1757 (
1758 Subdevice *pSubdevice,
1759 NV2080_CTRL_GPU_GET_FERMI_TPC_INFO_PARAMS *pParams
1760 )
1761 {
1762 NV2080_CTRL_GR_GET_TPC_MASK_PARAMS tpcMaskParams;
1763 RM_API *pRmApi = rmapiGetInterface(RMAPI_GPU_LOCK_INTERNAL);
1764 NvHandle hClient = RES_GET_CLIENT_HANDLE(pSubdevice);
1765 NvHandle hSubdevice = RES_GET_HANDLE(pSubdevice);
1766
1767 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmDeviceGpuLockIsOwner(GPU_RES_GET_GPU(pSubdevice)->gpuInstance));
1768
1769 portMemSet(&tpcMaskParams, 0, sizeof(tpcMaskParams));
1770 tpcMaskParams.gpcId = pParams->gpcId;
1771
1772 NV_CHECK_OK_OR_RETURN(
1773 LEVEL_ERROR,
1774 pRmApi->Control(pRmApi,
1775 hClient,
1776 hSubdevice,
1777 NV2080_CTRL_CMD_GR_GET_TPC_MASK,
1778 &tpcMaskParams,
1779 sizeof(tpcMaskParams)));
1780
1781 pParams->tpcMask = tpcMaskParams.tpcMask;
1782 return NV_OK;
1783 }
1784
1785 //
1786 // subdeviceCtrlCmdGpuGetFermiZcullInfo
1787 //
1788 // Lock Requirements:
1789 // Assert that API lock and GPUs lock held on entry
1790 //
1791 // WARNING: This control call is deprecated.
1792 //
1793 NV_STATUS
subdeviceCtrlCmdGpuGetFermiZcullInfo_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_FERMI_ZCULL_INFO_PARAMS * pParams)1794 subdeviceCtrlCmdGpuGetFermiZcullInfo_IMPL
1795 (
1796 Subdevice *pSubdevice,
1797 NV2080_CTRL_GPU_GET_FERMI_ZCULL_INFO_PARAMS *pParams
1798 )
1799 {
1800 NV2080_CTRL_GR_GET_ZCULL_MASK_PARAMS zcullMaskParams;
1801 RM_API *pRmApi = rmapiGetInterface(RMAPI_GPU_LOCK_INTERNAL);
1802 NvHandle hClient = RES_GET_CLIENT_HANDLE(pSubdevice);
1803 NvHandle hSubdevice = RES_GET_HANDLE(pSubdevice);
1804
1805 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmDeviceGpuLockIsOwner(GPU_RES_GET_GPU(pSubdevice)->gpuInstance));
1806
1807 portMemSet(&zcullMaskParams, 0, sizeof(zcullMaskParams));
1808 zcullMaskParams.gpcId = pParams->gpcId;
1809
1810 NV_CHECK_OK_OR_RETURN(
1811 LEVEL_ERROR,
1812 pRmApi->Control(pRmApi,
1813 hClient,
1814 hSubdevice,
1815 NV2080_CTRL_CMD_GR_GET_ZCULL_MASK,
1816 &zcullMaskParams,
1817 sizeof(zcullMaskParams)));
1818
1819 pParams->zcullMask = zcullMaskParams.zcullMask;
1820
1821 return NV_OK;
1822 }
1823
1824 /*!
1825 * @brief Get graphics engine PES configuration
1826 *
1827 * This can be called before floor sweeping is determined, so we cannot use cached
1828 * values.
1829 */
1830 NV_STATUS
subdeviceCtrlCmdGpuGetPesInfo_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_PES_INFO_PARAMS * pParams)1831 subdeviceCtrlCmdGpuGetPesInfo_IMPL
1832 (
1833 Subdevice *pSubdevice,
1834 NV2080_CTRL_GPU_GET_PES_INFO_PARAMS *pParams
1835 )
1836 {
1837 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
1838 NvHandle hClient = RES_GET_CLIENT_HANDLE(pSubdevice);
1839 KernelGraphics *pKernelGraphics;
1840 const KGRAPHICS_STATIC_INFO *pKernelGraphicsStaticInfo;
1841 RsClient *pRsClient;
1842 NvU32 gpcId = pParams->gpcId;
1843 NvU32 maxGpcCount;
1844
1845 //
1846 // XXX Bug 2681931 - GET_PES_INFO overloads interpretation of gpcId parameter
1847 // This ctrl call is due for deprecation and should not be used.
1848 //
1849
1850 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmGpuLockIsOwner());
1851
1852 NV_ASSERT_OK_OR_RETURN(
1853 serverGetClientUnderLock(&g_resServ, hClient, &pRsClient));
1854
1855 NV_CHECK_OR_RETURN(LEVEL_INFO, !IS_MIG_IN_USE(pGpu), NV_ERR_NOT_SUPPORTED);
1856 pKernelGraphics = GPU_GET_KERNEL_GRAPHICS(pGpu, 0);
1857 pKernelGraphicsStaticInfo = kgraphicsGetStaticInfo(pGpu, pKernelGraphics);
1858 NV_ASSERT_OR_RETURN(pKernelGraphicsStaticInfo != NULL, NV_ERR_INVALID_STATE);
1859
1860 maxGpcCount = gpuGetLitterValues_HAL(pGpu, NV2080_CTRL_GR_INFO_INDEX_LITTER_NUM_GPCS);
1861 if (gpcId >= maxGpcCount)
1862 {
1863 return NV_ERR_INVALID_ARGUMENT;
1864 }
1865
1866 pParams->numPesInGpc = pKernelGraphicsStaticInfo->floorsweepingMasks.numPesPerGpc[gpcId];
1867
1868 NV_CHECK_OR_RETURN(LEVEL_SILENT, pKernelGraphicsStaticInfo->pPpcMasks != NULL, NV_ERR_NOT_SUPPORTED);
1869 pParams->activePesMask = pKernelGraphicsStaticInfo->pPpcMasks->mask[gpcId];
1870
1871 pParams->maxTpcPerGpcCount = pKernelGraphicsStaticInfo->pGrInfo->infoList[NV2080_CTRL_GR_INFO_INDEX_LITTER_NUM_TPC_PER_GPC].data;
1872 portMemCopy(pParams->tpcToPesMap, sizeof(pParams->tpcToPesMap),
1873 pKernelGraphicsStaticInfo->floorsweepingMasks.tpcToPesMap, sizeof(pKernelGraphicsStaticInfo->floorsweepingMasks.tpcToPesMap));
1874
1875 return NV_OK;
1876 }
1877
1878 //
1879 // subdeviceCtrlCmdGpuQueryMode_IMPL
1880 //
1881 // Lock Requirements:
1882 // Assert that API and GPUs lock held on entry
1883 //
1884 NV_STATUS
subdeviceCtrlCmdGpuQueryMode_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_QUERY_MODE_PARAMS * pQueryMode)1885 subdeviceCtrlCmdGpuQueryMode_IMPL
1886 (
1887 Subdevice *pSubdevice,
1888 NV2080_CTRL_GPU_QUERY_MODE_PARAMS *pQueryMode
1889 )
1890 {
1891 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
1892
1893 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmGpuLockIsOwner());
1894
1895 switch (gpuGetMode(pGpu))
1896 {
1897 case NV_GPU_MODE_GRAPHICS_MODE:
1898 {
1899 pQueryMode->mode = NV2080_CTRL_GPU_QUERY_MODE_GRAPHICS_MODE;
1900 break;
1901 }
1902 case NV_GPU_MODE_COMPUTE_MODE:
1903 {
1904 pQueryMode->mode = NV2080_CTRL_GPU_QUERY_MODE_COMPUTE_MODE;
1905 break;
1906 }
1907 default:
1908 {
1909 pQueryMode->mode = NV2080_CTRL_GPU_QUERY_MODE_UNKNOWN_MODE;
1910 break;
1911 }
1912 }
1913
1914 return NV_OK;
1915 }
1916
1917 //
1918 // subdeviceCtrlCmdGpuHandleGpuSR
1919 //
1920 // Lock Requirements:
1921 // Assert that API lock held on entry
1922 //
1923 NV_STATUS
subdeviceCtrlCmdGpuHandleGpuSR_IMPL(Subdevice * pSubdevice)1924 subdeviceCtrlCmdGpuHandleGpuSR_IMPL
1925 (
1926 Subdevice *pSubdevice
1927 )
1928 {
1929 return NV_OK;
1930 }
1931
1932 //
1933 // subdeviceCtrlCmdGpuSetComputeModeRules
1934 //
1935 // Lock Requirements:
1936 // Assert that API lock held on entry
1937 //
1938 NV_STATUS
subdeviceCtrlCmdGpuSetComputeModeRules_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_SET_COMPUTE_MODE_RULES_PARAMS * pSetRulesParams)1939 subdeviceCtrlCmdGpuSetComputeModeRules_IMPL
1940 (
1941 Subdevice *pSubdevice,
1942 NV2080_CTRL_GPU_SET_COMPUTE_MODE_RULES_PARAMS *pSetRulesParams
1943 )
1944 {
1945 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
1946
1947 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner());
1948
1949 if (IS_GSP_CLIENT(pGpu))
1950 {
1951 CALL_CONTEXT *pCallContext = resservGetTlsCallContext();
1952 RmCtrlParams *pRmCtrlParams = pCallContext->pControlParams;
1953 RM_API *pRmApi = GPU_GET_PHYSICAL_RMAPI(pGpu);
1954
1955 //
1956 // Client RM still needs to set its value and update the registry,
1957 // so don't return unless there was an error.
1958 //
1959 NV_ASSERT_OK_OR_RETURN(pRmApi->Control(pRmApi,
1960 pRmCtrlParams->hClient,
1961 pRmCtrlParams->hObject,
1962 pRmCtrlParams->cmd,
1963 pRmCtrlParams->pParams,
1964 pRmCtrlParams->paramsSize));
1965 }
1966
1967 //TODO Bug 2718406 will extend compute mode support for MIG
1968 if (IS_MIG_ENABLED(pGpu))
1969 {
1970 return NV_ERR_NOT_SUPPORTED;
1971 }
1972
1973 // Setting compute mode for cuda non supported vGPU profiles
1974 // is not supported.
1975 // Exclude GSP environment for that rule.
1976 VGPU_STATIC_INFO *pVSI = GPU_GET_STATIC_INFO(pGpu);
1977 if (pVSI && !IS_GSP_CLIENT(pGpu) && pVSI->vgpuConfig.cudaEnabled == 0)
1978 {
1979 return NV_ERR_NOT_SUPPORTED;
1980 }
1981
1982 switch(pSetRulesParams->rules)
1983 {
1984 case NV2080_CTRL_GPU_COMPUTE_MODE_RULES_NONE:
1985 case NV2080_CTRL_GPU_COMPUTE_MODE_RULES_EXCLUSIVE_COMPUTE:
1986 case NV2080_CTRL_GPU_COMPUTE_MODE_RULES_COMPUTE_PROHIBITED:
1987 case NV2080_CTRL_GPU_COMPUTE_MODE_RULES_EXCLUSIVE_COMPUTE_PROCESS:
1988 pGpu->computeModeRules = pSetRulesParams->rules;
1989
1990 //
1991 // Store this setting in the registry so that it persists even
1992 // after the last client disconnects.
1993 // Client RM handles this so skip on GSP.
1994 //
1995 if (NV_OK !=
1996 osWriteRegistryDword(pGpu,
1997 NV_REG_STR_RM_COMPUTE_MODE_RULES,
1998 pGpu->computeModeRules))
1999 {
2000 // Non-fatal but worth reporting
2001 NV_PRINTF(LEVEL_ERROR,
2002 "Could not store compute mode rule in the registry, current setting may not persist if all clients disconnect!\n");
2003 }
2004 break;
2005
2006 default:
2007 return NV_ERR_INVALID_ARGUMENT;
2008 }
2009
2010 return NV_OK;
2011 }
2012
2013 //
2014 // subdeviceCtrlCmdGpuQueryComputeModeRules
2015 //
2016 // Lock Requirements:
2017 // Assert that API lock held on entry
2018 //
2019 // TODO Bug 2718406 will extend compute mode support for MIG
2020 //
2021 NV_STATUS
subdeviceCtrlCmdGpuQueryComputeModeRules_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_QUERY_COMPUTE_MODE_RULES_PARAMS * pQueryRulesParams)2022 subdeviceCtrlCmdGpuQueryComputeModeRules_IMPL
2023 (
2024 Subdevice *pSubdevice,
2025 NV2080_CTRL_GPU_QUERY_COMPUTE_MODE_RULES_PARAMS *pQueryRulesParams
2026 )
2027 {
2028 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
2029
2030 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner());
2031
2032 //
2033 // vGPU specific check to assign compute mode as 'Prohibited'
2034 // for cuda non supported vGPU profiles.
2035 // Exclude GSP environment for that rule.
2036 //
2037 VGPU_STATIC_INFO *pVSI = GPU_GET_STATIC_INFO(pGpu);
2038 if ((pVSI != NULL) && !IS_GSP_CLIENT(pGpu) && (pVSI->vgpuConfig.cudaEnabled == 0))
2039 {
2040 pQueryRulesParams->rules = NV2080_CTRL_GPU_COMPUTE_MODE_RULES_COMPUTE_PROHIBITED;
2041 }
2042 else
2043 {
2044 pQueryRulesParams->rules = pGpu->computeModeRules;
2045 }
2046
2047 return NV_OK;
2048 }
2049
2050 NV_STATUS
subdeviceCtrlCmdGpuAcquireComputeModeReservation_IMPL(Subdevice * pSubdevice)2051 subdeviceCtrlCmdGpuAcquireComputeModeReservation_IMPL
2052 (
2053 Subdevice *pSubdevice
2054 )
2055 {
2056 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
2057 NvHandle hClient = RES_GET_CLIENT_HANDLE(pSubdevice);
2058
2059 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner());
2060
2061 //TODO Bug 2718406 will extend compute mode support for MIG
2062 if (IS_MIG_ENABLED(pGpu))
2063 {
2064 return NV_ERR_NOT_SUPPORTED;
2065 }
2066
2067 switch (pGpu->computeModeRules)
2068 {
2069 case NV2080_CTRL_GPU_COMPUTE_MODE_RULES_NONE:
2070 {
2071 // If a GPU is in "normal" mode, then the caller can always get the reservation:
2072 pGpu->hComputeModeReservation = hClient;
2073 }
2074 return NV_OK;
2075 break; // For the Coverity code checker.
2076
2077 case NV2080_CTRL_GPU_COMPUTE_MODE_RULES_EXCLUSIVE_COMPUTE:
2078 case NV2080_CTRL_GPU_COMPUTE_MODE_RULES_EXCLUSIVE_COMPUTE_PROCESS:
2079 {
2080 //
2081 // If a GPU is in "cuda exclusive" mode, then the caller can only get the
2082 // reservation if no other client holds the reservation:
2083 //
2084 if (NV01_NULL_OBJECT == pGpu->hComputeModeReservation)
2085 {
2086 pGpu->hComputeModeReservation = hClient;
2087 return NV_OK;
2088 }
2089 else
2090 {
2091 // Someone else holds the reservation:
2092 return NV_ERR_STATE_IN_USE;
2093 }
2094 }
2095 break;
2096
2097 case NV2080_CTRL_GPU_COMPUTE_MODE_RULES_COMPUTE_PROHIBITED:
2098 //
2099 // If a GPU is in "cuda prohibited" mode, then the caller can never get the
2100 // reservation:
2101 //
2102 return NV_ERR_STATE_IN_USE;
2103 break;
2104
2105 default:
2106 NV_ASSERT(0); // This *should* be unreachable code.
2107 break;
2108 }
2109
2110 return NV_OK;
2111 }
2112
2113 NV_STATUS
subdeviceCtrlCmdGpuReleaseComputeModeReservation_IMPL(Subdevice * pSubdevice)2114 subdeviceCtrlCmdGpuReleaseComputeModeReservation_IMPL
2115 (
2116 Subdevice *pSubdevice
2117 )
2118 {
2119 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
2120 NvHandle hClient = RES_GET_CLIENT_HANDLE(pSubdevice);
2121
2122 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner());
2123
2124 //TODO Bug 2718406 will extend compute mode support for MIG
2125 if (IS_MIG_ENABLED(pGpu))
2126 {
2127 return NV_ERR_NOT_SUPPORTED;
2128 }
2129
2130 // Release the reservation ONLY IF we had the reservation to begin with. Otherwise,
2131 // leave it alone, because someone else has acquired it:
2132 if (pGpu->hComputeModeReservation == hClient)
2133 {
2134 pGpu->hComputeModeReservation = NV01_NULL_OBJECT;
2135 }
2136 else
2137 {
2138 return NV_ERR_STATE_IN_USE;
2139 }
2140
2141 return NV_OK;
2142 }
2143
2144 //
2145 // subdeviceCtrlCmdGpuGetId
2146 //
2147 // Lock Requirements:
2148 // Assert that API lock held on entry
2149 //
2150 NV_STATUS
subdeviceCtrlCmdGpuGetId_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_ID_PARAMS * pIdParams)2151 subdeviceCtrlCmdGpuGetId_IMPL
2152 (
2153 Subdevice *pSubdevice,
2154 NV2080_CTRL_GPU_GET_ID_PARAMS *pIdParams
2155 )
2156 {
2157 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
2158
2159 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner());
2160
2161 pIdParams->gpuId = pGpu->gpuId;
2162
2163 return NV_OK;
2164 }
2165
2166 //
2167 // nv2080CtrlCmdGpuGetPids
2168 //
2169 // Lock Requirements:
2170 // Assert that API and GPUs lock held on entry
2171 //
2172 NV_STATUS
subdeviceCtrlCmdGpuGetPids_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_PIDS_PARAMS * pGetPidsParams)2173 subdeviceCtrlCmdGpuGetPids_IMPL
2174 (
2175 Subdevice *pSubdevice,
2176 NV2080_CTRL_GPU_GET_PIDS_PARAMS *pGetPidsParams
2177 )
2178 {
2179 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
2180 NvU32 internalClassId;
2181 NV_STATUS status;
2182 MIG_INSTANCE_REF *pRef = NULL;
2183
2184 NV_ASSERT_OR_RETURN(RMCFG_FEATURE_KERNEL_RM, NV_ERR_NOT_SUPPORTED);
2185
2186 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmGpuLockIsOwner());
2187
2188 switch (pGetPidsParams->idType)
2189 {
2190 case (NV2080_CTRL_GPU_GET_PIDS_ID_TYPE_CLASS):
2191 {
2192 if (pGetPidsParams->id == NV20_SUBDEVICE_0)
2193 {
2194 internalClassId = classId(Subdevice);
2195 }
2196 else if (pGetPidsParams->id == MPS_COMPUTE)
2197 {
2198 internalClassId = classId(MpsApi);
2199 }
2200 else
2201 {
2202 internalClassId = classId(ChannelDescendant);
2203 }
2204 break;
2205 }
2206 case (NV2080_CTRL_GPU_GET_PIDS_ID_TYPE_VGPU_GUEST):
2207 {
2208 internalClassId = classId(KernelHostVgpuDeviceApi);
2209 break;
2210 }
2211
2212 default:
2213 return NV_ERR_INVALID_ARGUMENT;
2214 }
2215
2216 //
2217 // With MIG GPU instancing enabled, get associated instance ref
2218 // Clients with MIG_MONITOR capability are allowed to get full device
2219 // info
2220 //
2221 KernelMIGManager *pKernelMIGManager = GPU_GET_KERNEL_MIG_MANAGER(pGpu);
2222 NvHandle hClient = RES_GET_CLIENT_HANDLE(pSubdevice);
2223 MIG_INSTANCE_REF partitionRef = kmigmgrMakeNoMIGReference();
2224 pRef = &partitionRef;
2225 if (IS_MIG_IN_USE(pGpu) &&
2226 !rmclientIsCapableByHandle(hClient, NV_RM_CAP_SYS_SMC_MONITOR))
2227 {
2228 Device *pDevice = GPU_RES_GET_DEVICE(pSubdevice);
2229 //
2230 // Check instanceSubscription to limit the scope of the call
2231 // Clients with mig-monitor capability are allowed to get full device
2232 // info
2233 //
2234 NV_CHECK_OR_RETURN(LEVEL_INFO, (kmigmgrGetInstanceRefFromDevice(pGpu, pKernelMIGManager,
2235 pDevice, pRef) == NV_OK),
2236 NV_ERR_INSUFFICIENT_PERMISSIONS);
2237 }
2238
2239 //
2240 // Search over all clients to see if any contain objects of type = id.
2241 // If they do, then add their PID to the PIDArray param and also
2242 // return the amount of valid entries in the Array through pidTblCount.
2243 //
2244 status = gpuGetProcWithObject(pGpu, pGetPidsParams->id, internalClassId,
2245 pGetPidsParams->pidTbl, &pGetPidsParams->pidTblCount,
2246 pRef);
2247 return status;
2248 }
2249
2250 //
2251 // subdeviceCtrlCmdGpuGetPidInfo
2252 //
2253 // Lock Requirements:
2254 // Assert that API and GPUs lock held on entry
2255 //
2256 NV_STATUS
subdeviceCtrlCmdGpuGetPidInfo_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_PID_INFO_PARAMS * pGetPidInfoParams)2257 subdeviceCtrlCmdGpuGetPidInfo_IMPL
2258 (
2259 Subdevice *pSubdevice,
2260 NV2080_CTRL_GPU_GET_PID_INFO_PARAMS *pGetPidInfoParams
2261 )
2262 {
2263 NV2080_CTRL_GPU_PID_INFO_DATA *pPidInfoData;
2264 NV2080_CTRL_SMC_SUBSCRIPTION_INFO *pSmcInfo;
2265 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
2266 NV2080_CTRL_GPU_PID_INFO *pPidInfo;
2267 NvU32 internalClassId;
2268 NvU32 i;
2269 MIG_INSTANCE_REF *pRef = NULL;
2270 NvBool bGlobalInfo = NV_TRUE;
2271
2272 NV_ASSERT_OR_RETURN(RMCFG_FEATURE_KERNEL_RM, NV_ERR_NOT_SUPPORTED);
2273
2274 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmGpuLockIsOwner());
2275
2276 if ((pGetPidInfoParams->pidInfoListCount <= 0) ||
2277 (pGetPidInfoParams->pidInfoListCount >
2278 NV2080_CTRL_GPU_GET_PID_INFO_MAX_COUNT))
2279 {
2280 return NV_ERR_INVALID_ARGUMENT;
2281 }
2282
2283 //
2284 // With MIG GPU instancing enabled, get associated instance ref
2285 // Clients with MIG_MONITOR capability are allowed to get full device
2286 // info
2287 //
2288 KernelMIGManager *pKernelMIGManager = GPU_GET_KERNEL_MIG_MANAGER(pGpu);
2289 NvHandle hClient = RES_GET_CLIENT_HANDLE(pSubdevice);
2290 MIG_INSTANCE_REF ref = kmigmgrMakeNoMIGReference();
2291 pRef = &ref;
2292 if (IS_MIG_IN_USE(pGpu) &&
2293 !rmclientIsCapableByHandle(hClient, NV_RM_CAP_SYS_SMC_MONITOR))
2294 {
2295 Device *pDevice = GPU_RES_GET_DEVICE(pSubdevice);
2296 //
2297 // Check instanceSubscription to limit the scope of the call
2298 // Clients with mig-monitor capability are allowed to get full device
2299 // info
2300 //
2301 NV_CHECK_OR_RETURN(LEVEL_INFO, (kmigmgrGetInstanceRefFromDevice(pGpu, pKernelMIGManager,
2302 pDevice, pRef) == NV_OK),
2303 NV_ERR_INSUFFICIENT_PERMISSIONS);
2304 bGlobalInfo = NV_FALSE;
2305 }
2306
2307 for (i = 0; i < pGetPidInfoParams->pidInfoListCount; ++i)
2308 {
2309 pPidInfo = &pGetPidInfoParams->pidInfoList[i];
2310
2311 pSmcInfo = &pPidInfo->smcSubscription;
2312 pSmcInfo->computeInstanceId = PARTITIONID_INVALID;
2313 pSmcInfo->gpuInstanceId = PARTITIONID_INVALID;
2314
2315 switch (pPidInfo->index)
2316 {
2317 case (NV2080_CTRL_GPU_PID_INFO_INDEX_VIDEO_MEMORY_USAGE):
2318 {
2319 internalClassId = classId(Memory);
2320
2321 pPidInfoData = &pPidInfo->data;
2322 portMemSet(pPidInfoData, 0, sizeof(NV2080_CTRL_GPU_PID_INFO_DATA));
2323 pPidInfo->result = gpuFindClientInfoWithPidIterator(pGpu, pPidInfo->pid, 0,
2324 internalClassId,
2325 pPidInfoData,
2326 pSmcInfo,
2327 pRef,
2328 bGlobalInfo);
2329 break;
2330 }
2331 default:
2332 {
2333 pPidInfo->result = NV_ERR_INVALID_ARGUMENT;
2334 break;
2335 }
2336 }
2337 }
2338
2339 return NV_OK;
2340 }
2341
2342 // Control call to fetch the Runlist pri base for the engine(s) specified
2343 NV_STATUS
subdeviceCtrlCmdGpuGetEngineRunlistPriBase_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_ENGINE_RUNLIST_PRI_BASE_PARAMS * pParams)2344 subdeviceCtrlCmdGpuGetEngineRunlistPriBase_IMPL
2345 (
2346 Subdevice *pSubdevice,
2347 NV2080_CTRL_GPU_GET_ENGINE_RUNLIST_PRI_BASE_PARAMS *pParams
2348 )
2349 {
2350 NV_STATUS status = NV_OK;
2351 NV_STATUS tmpStatus = NV_OK;
2352 NvU32 i;
2353 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
2354 KernelFifo *pKernelFifo = GPU_GET_KERNEL_FIFO(pGpu);
2355
2356 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmGpuLockIsOwner());
2357
2358 if (!kfifoIsHostEngineExpansionSupported(pKernelFifo))
2359 {
2360 status = NV_ERR_NOT_SUPPORTED;
2361 return status;
2362 }
2363
2364 for (i = 0; i < NV2080_GPU_MAX_ENGINES_LIST_SIZE; i++)
2365 {
2366 RM_ENGINE_TYPE rmEngineType;
2367
2368 // Check if input is NULL or a SW engine; return a NULL value since SW engine does not have a runlist pri base
2369 // and this should not be returned as an error
2370 if ((pParams->engineList[i] == NV2080_ENGINE_TYPE_NULL) || (pParams->engineList[i] == NV2080_ENGINE_TYPE_SW))
2371 {
2372 pParams->runlistPriBase[i] = NV2080_CTRL_GPU_GET_ENGINE_RUNLIST_PRI_BASE_NULL;
2373 continue;
2374 }
2375
2376 rmEngineType = gpuGetRmEngineType(pParams->engineList[i]);
2377
2378 //
2379 // See if MIG is enabled. If yes, then we have to convert instanceLocal
2380 // engine to global engine before moving ahead
2381 //
2382 if (IS_MIG_IN_USE(pGpu))
2383 {
2384 KernelMIGManager *pKernelMIGManager = GPU_GET_KERNEL_MIG_MANAGER(pGpu);
2385 Device *pDevice = GPU_RES_GET_DEVICE(pSubdevice);
2386 MIG_INSTANCE_REF ref;
2387
2388 NV_CHECK_OK_OR_RETURN(
2389 LEVEL_ERROR,
2390 kmigmgrGetInstanceRefFromDevice(pGpu, pKernelMIGManager,
2391 pDevice, &ref));
2392
2393 NV_CHECK_OK_OR_RETURN(
2394 LEVEL_ERROR,
2395 kmigmgrGetLocalToGlobalEngineType(pGpu, pKernelMIGManager, ref,
2396 rmEngineType,
2397 &rmEngineType));
2398 }
2399
2400 tmpStatus = kfifoEngineInfoXlate_HAL(pGpu, pKernelFifo, ENGINE_INFO_TYPE_RM_ENGINE_TYPE,
2401 rmEngineType, ENGINE_INFO_TYPE_RUNLIST_PRI_BASE,
2402 &pParams->runlistPriBase[i]);
2403
2404 if (tmpStatus != NV_OK)
2405 {
2406 pParams->runlistPriBase[i] = NV2080_CTRL_GPU_GET_ENGINE_RUNLIST_PRI_BASE_ERROR;
2407 status = tmpStatus;
2408 }
2409 }
2410 return status;
2411 }
2412
2413 // Control call to fetch the HW engine ID for the engine(s) specified
2414 NV_STATUS
subdeviceCtrlCmdGpuGetHwEngineId_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_HW_ENGINE_ID_PARAMS * pParams)2415 subdeviceCtrlCmdGpuGetHwEngineId_IMPL
2416 (
2417 Subdevice *pSubdevice,
2418 NV2080_CTRL_GPU_GET_HW_ENGINE_ID_PARAMS *pParams
2419 )
2420 {
2421 NV_STATUS status = NV_OK;
2422 NV_STATUS tmpStatus = NV_OK;
2423 NvU32 i;
2424 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
2425 KernelFifo *pKernelFifo = GPU_GET_KERNEL_FIFO(pGpu);
2426
2427 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmGpuLockIsOwner());
2428
2429 if (!kfifoIsHostEngineExpansionSupported(pKernelFifo))
2430 {
2431 status = NV_ERR_NOT_SUPPORTED;
2432 return status;
2433 }
2434
2435 for (i = 0; i < NV2080_GPU_MAX_ENGINES_LIST_SIZE; i++)
2436 {
2437 RM_ENGINE_TYPE rmEngineType;
2438
2439 // Check if input is NULL or a SW engine; return a NULL value since SW engine does not have a runlist pri base
2440 // and this should not be returned as an error
2441 if (pParams->engineList[i] == NV2080_ENGINE_TYPE_NULL || (pParams->engineList[i] == NV2080_ENGINE_TYPE_SW))
2442 {
2443 pParams->hwEngineID[i] = NV2080_CTRL_GPU_GET_HW_ENGINE_ID_NULL;
2444 continue;
2445 }
2446
2447 rmEngineType = gpuGetRmEngineType(pParams->engineList[i]);
2448
2449 //
2450 // See if MIG is enabled. If yes, then we have to convert instanceLocal
2451 // engine to global engine before moving ahead
2452 //
2453 if (IS_MIG_IN_USE(pGpu))
2454 {
2455 KernelMIGManager *pKernelMIGManager = GPU_GET_KERNEL_MIG_MANAGER(pGpu);
2456 Device *pDevice = GPU_RES_GET_DEVICE(pSubdevice);
2457 MIG_INSTANCE_REF ref;
2458
2459 NV_CHECK_OK_OR_RETURN(
2460 LEVEL_ERROR,
2461 kmigmgrGetInstanceRefFromDevice(pGpu, pKernelMIGManager,
2462 pDevice, &ref));
2463
2464 NV_CHECK_OK_OR_RETURN(
2465 LEVEL_ERROR,
2466 kmigmgrGetLocalToGlobalEngineType(pGpu, pKernelMIGManager, ref,
2467 rmEngineType,
2468 &rmEngineType));
2469 }
2470
2471 tmpStatus = kfifoEngineInfoXlate_HAL(pGpu, pKernelFifo, ENGINE_INFO_TYPE_RM_ENGINE_TYPE,
2472 (NvU32)rmEngineType,
2473 ENGINE_INFO_TYPE_FIFO_TAG,
2474 &pParams->hwEngineID[i]);
2475
2476 if (tmpStatus != NV_OK)
2477 {
2478 pParams->hwEngineID[i] = NV2080_CTRL_GPU_GET_HW_ENGINE_ID_ERROR;
2479 status = tmpStatus;
2480 }
2481 }
2482 return status;
2483 }
2484
2485 NV_STATUS
subdeviceCtrlCmdGpuGetMaxSupportedPageSize_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_MAX_SUPPORTED_PAGE_SIZE_PARAMS * pParams)2486 subdeviceCtrlCmdGpuGetMaxSupportedPageSize_IMPL
2487 (
2488 Subdevice *pSubdevice,
2489 NV2080_CTRL_GPU_GET_MAX_SUPPORTED_PAGE_SIZE_PARAMS *pParams
2490 )
2491 {
2492 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
2493 NV_STATUS status = NV_OK;
2494
2495 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmDeviceGpuLockIsOwner(pGpu->gpuInstance));
2496
2497 // Default to minimal page size (4k)
2498 pParams->maxSupportedPageSize = RM_PAGE_SIZE;
2499
2500 if (IS_VIRTUAL_WITHOUT_SRIOV(pGpu) || IS_VIRTUAL_WITH_HEAVY_SRIOV(pGpu))
2501 {
2502 VGPU_STATIC_INFO *pVSI = GPU_GET_STATIC_INFO(pGpu);
2503
2504 pParams->maxSupportedPageSize = pVSI->maxSupportedPageSize;
2505
2506 return status;
2507 }
2508
2509 KernelGmmu *pKernelGmmu = GPU_GET_KERNEL_GMMU(pGpu);
2510
2511 if (kgmmuIsPageSize256gbSupported(pKernelGmmu))
2512 {
2513 pParams->maxSupportedPageSize = RM_PAGE_SIZE_256G;
2514 }
2515 else
2516 if (kgmmuIsPageSize512mbSupported(pKernelGmmu))
2517 {
2518 pParams->maxSupportedPageSize = RM_PAGE_SIZE_512M;
2519 }
2520 else if (kgmmuIsHugePageSupported(pKernelGmmu))
2521 {
2522 pParams->maxSupportedPageSize = RM_PAGE_SIZE_HUGE;
2523 }
2524 else
2525 {
2526 pParams->maxSupportedPageSize = (NvU32)kgmmuGetMaxBigPageSize_HAL(pKernelGmmu);
2527 }
2528
2529 if (gpuIsSriovEnabled(pGpu) || IS_VIRTUAL_WITH_SRIOV(pGpu)
2530 || gpuIsCCFeatureEnabled(pGpu)
2531 )
2532 {
2533 NvU64 vmmuSegmentSize = gpuGetVmmuSegmentSize(pGpu);
2534 if (vmmuSegmentSize > 0 &&
2535 vmmuSegmentSize < NV2080_CTRL_GPU_VMMU_SEGMENT_SIZE_512MB)
2536 {
2537 pParams->maxSupportedPageSize = RM_PAGE_SIZE_HUGE;
2538 }
2539 }
2540
2541 return status;
2542 }
2543
2544 #if (defined(DEBUG) || defined(DEVELOP) || RMCFG_FEATURE_MODS_FEATURES) && RMCFG_MODULE_KERNEL_GRAPHICS
2545 NV_STATUS
subdeviceCtrlCmdGpuGetNumMmusPerGpc_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_NUM_MMUS_PER_GPC_PARAMS * pParams)2546 subdeviceCtrlCmdGpuGetNumMmusPerGpc_IMPL
2547 (
2548 Subdevice *pSubdevice,
2549 NV2080_CTRL_GPU_GET_NUM_MMUS_PER_GPC_PARAMS *pParams
2550 )
2551 {
2552 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
2553 KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
2554 KernelGraphics *pKernelGraphics;
2555 const KGRAPHICS_STATIC_INFO *pKernelGraphicsStaticInfo;
2556 NvU32 count;
2557 NvU32 maxGpcCount;
2558
2559 // Ensure that the gpcId is within range
2560 maxGpcCount = gpuGetLitterValues_HAL(pGpu, NV2080_CTRL_GR_INFO_INDEX_LITTER_NUM_GPCS);
2561 if (pParams->gpcId >= maxGpcCount)
2562 {
2563 return NV_ERR_INVALID_ARGUMENT;
2564 }
2565
2566 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
2567 kgrmgrCtrlRouteKGRWithDevice(pGpu, pKernelGraphicsManager,
2568 GPU_RES_GET_DEVICE(pSubdevice),
2569 &pParams->grRouteInfo, &pKernelGraphics));
2570
2571 pKernelGraphicsStaticInfo = kgraphicsGetStaticInfo(pGpu, pKernelGraphics);
2572 NV_ASSERT_OR_RETURN(pKernelGraphicsStaticInfo != NULL, NV_ERR_INVALID_STATE);
2573
2574 count = pKernelGraphicsStaticInfo->floorsweepingMasks.mmuPerGpc[pParams->gpcId];
2575
2576 // If the litter value doesn't exist (pre Ampere) than default to 1 gpcmmu
2577 pParams->count = ((count != 0) ? count : 1);
2578
2579 return NV_OK;
2580 }
2581 #endif
2582
2583 // Stubbed for Orin
2584
2585 /*
2586 * @brief Update/Set the compute policy config for a GPU
2587 *
2588 * @param[in] pSubdevice
2589 * @param[in] pParams pointer to control parameters
2590 *
2591 * @return
2592 * NV_OK Success
2593 * NV_ERR_NOT_SUPPORTED Setting policy is not supported on requested GPU
2594 * NV_ERR_INVALID_ARGUMENT Invalid config type/value specified
2595 * else appropriate error code.
2596 */
2597 NV_STATUS
subdeviceCtrlCmdGpuSetComputePolicyConfig_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_SET_COMPUTE_POLICY_CONFIG_PARAMS * pParams)2598 subdeviceCtrlCmdGpuSetComputePolicyConfig_IMPL
2599 (
2600 Subdevice *pSubdevice,
2601 NV2080_CTRL_GPU_SET_COMPUTE_POLICY_CONFIG_PARAMS *pParams
2602 )
2603 {
2604 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
2605 GPU_COMPUTE_POLICY_INFO policyInfo;
2606 NvU32 gidFlags;
2607 NV_STATUS status = NV_OK;
2608
2609 switch(pParams->config.type)
2610 {
2611 case NV2080_CTRL_GPU_COMPUTE_POLICY_TIMESLICE:
2612 if (!gpuIsComputePolicyTimesliceSupported(pGpu))
2613 {
2614 NV_PRINTF(LEVEL_ERROR, "Setting the timeslice policy is not supported for gpu with pci id 0x%llx\n",
2615 gpuGetDBDF(pGpu));
2616 return NV_ERR_NOT_SUPPORTED;
2617
2618 }
2619
2620 if (pParams->config.data.timeslice >= NV2080_CTRL_CMD_GPU_COMPUTE_TIMESLICE_MAX)
2621 {
2622 NV_PRINTF(LEVEL_ERROR, "Unsupported timeslice value %u specified for gpu with pci id 0x%llx\n",
2623 pParams->config.data.timeslice, gpuGetDBDF(pGpu));
2624 return NV_ERR_INVALID_ARGUMENT;
2625 }
2626
2627 policyInfo.timeslice = pParams->config.data.timeslice;
2628 break;
2629 default:
2630 NV_PRINTF(LEVEL_ERROR, "Unsupported compute policy %u specified for gpu id 0x%llx\n",
2631 pParams->config.type, gpuGetDBDF(pGpu));
2632 return NV_ERR_INVALID_ARGUMENT;
2633 }
2634
2635 gidFlags = DRF_DEF(2080_GPU_CMD, _GPU_GET_GID_FLAGS, _TYPE, _SHA1) |
2636 DRF_DEF(2080_GPU_CMD, _GPU_GET_GID_FLAGS, _FORMAT, _BINARY);
2637 status = gpuGetGidInfo(pGpu, NULL, NULL, gidFlags);
2638 if (status != NV_OK)
2639 {
2640 return status;
2641 }
2642
2643 NV_ASSERT(pGpu->gpuUuid.isInitialized);
2644 status = gpudbSetGpuComputePolicyConfig(pGpu->gpuUuid.uuid, pParams->config.type,
2645 &policyInfo);
2646
2647 return status;
2648 }
2649
2650 //
2651 // Make sure number of compute policies per GPU is always less than or equal
2652 // to the number of policy configs that can be handled by the
2653 // NV2080_CTRL_CMD_GPU_GET_COMPUTE_POLICY_CONFIG command.
2654 //
2655 ct_assert(NV2080_CTRL_GPU_COMPUTE_POLICY_MAX <= NV2080_CTRL_GPU_COMPUTE_POLICY_CONFIG_LIST_MAX);
2656
2657 /*
2658 * @brief Get all compute policy configs for a GPU
2659 *
2660 * @param[in] pSubdevice
2661 * @param[in] pParams pointer to control parameters
2662 *
2663 * @return
2664 * NV_OK on success
2665 * else appropriate error code.
2666 */
2667 NV_STATUS
subdeviceCtrlCmdGpuGetComputePolicyConfig_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_COMPUTE_POLICY_CONFIG_PARAMS * pParams)2668 subdeviceCtrlCmdGpuGetComputePolicyConfig_IMPL
2669 (
2670 Subdevice *pSubdevice,
2671 NV2080_CTRL_GPU_GET_COMPUTE_POLICY_CONFIG_PARAMS *pParams
2672 )
2673 {
2674 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
2675 GPU_COMPUTE_POLICY_INFO policyInfo;
2676 NvU32 policyId;
2677 NvU32 gidFlags;
2678 NV_STATUS status = NV_OK;
2679
2680 gidFlags = DRF_DEF(2080_GPU_CMD, _GPU_GET_GID_FLAGS, _TYPE, _SHA1) |
2681 DRF_DEF(2080_GPU_CMD, _GPU_GET_GID_FLAGS, _FORMAT, _BINARY);
2682 status = gpuGetGidInfo(pGpu, NULL, NULL, gidFlags);
2683 if (status != NV_OK)
2684 {
2685 return status;
2686 }
2687
2688 NV_ASSERT(pGpu->gpuUuid.isInitialized);
2689 status = gpudbGetGpuComputePolicyConfigs(pGpu->gpuUuid.uuid, &policyInfo);
2690 if (status != NV_OK)
2691 {
2692 return status;
2693 }
2694
2695 pParams->numConfigs = 0;
2696 // Loop through all compute policies and retrieve the configured settings
2697 for (policyId = NV2080_CTRL_GPU_COMPUTE_POLICY_TIMESLICE;
2698 policyId < NV2080_CTRL_GPU_COMPUTE_POLICY_MAX;
2699 policyId++)
2700 {
2701 switch (policyId)
2702 {
2703 case NV2080_CTRL_GPU_COMPUTE_POLICY_TIMESLICE:
2704 pParams->configList[policyId].type = NV2080_CTRL_GPU_COMPUTE_POLICY_TIMESLICE;
2705 pParams->configList[policyId].data.timeslice = policyInfo.timeslice;
2706 pParams->numConfigs++;
2707 break;
2708 default:
2709 NV_ASSERT(0);
2710 break;
2711 }
2712 }
2713
2714 return status;
2715 }
2716
2717 /*!
2718 * @brief Check if address range is within the provided limits
2719 *
2720 * @param[in] addrStart Staring address of address range
2721 * @param[in] addrLength Size of address range
2722 * @param[in] limitStart Staring address of limit
2723 * @param[in] limitLength Size of limit
2724 *
2725 * @return
2726 * NV_TRUE, if address range is within the provided limits
2727 * NV_FALSE, if address range is outside the provided limits
2728 *
2729 */
isAddressWithinLimits(NvU64 addrStart,NvU64 addrLength,NvU64 limitStart,NvU64 limitLength)2730 static NvBool isAddressWithinLimits
2731 (
2732 NvU64 addrStart,
2733 NvU64 addrLength,
2734 NvU64 limitStart,
2735 NvU64 limitLength
2736 )
2737 {
2738 NvU64 addrEnd = 0;
2739 NvU64 limitEnd = 0;
2740
2741 //
2742 // Calculate End address of address range and limit,
2743 // Return NV_FALSE in case of 64-bit addition overflow
2744 //
2745 if (!portSafeAddU64(addrStart, addrLength - 1, &addrEnd) ||
2746 !portSafeAddU64(limitStart, limitLength - 1, &limitEnd))
2747 {
2748 return NV_FALSE;
2749 }
2750
2751 return ((addrStart >= limitStart) && (addrEnd <= limitEnd));
2752 }
2753
2754 /*!
2755 * @brief Validate the address range for Memory Map request by comparing the
2756 * user supplied address range with GPU BAR0/BAR1 range.
2757 *
2758 * Lock Requirements:
2759 * Assert that API and GPUs lock held on entry
2760 *
2761 * @param[in] pSubdevice
2762 * @param[in] pParams pointer to control parameters
2763 *
2764 * Possible status values returned are:
2765 * NV_OK
2766 * NV_ERR_PROTECTION_FAULT
2767 *
2768 */
subdeviceCtrlCmdValidateMemMapRequest_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_VALIDATE_MEM_MAP_REQUEST_PARAMS * pParams)2769 NV_STATUS subdeviceCtrlCmdValidateMemMapRequest_IMPL
2770 (
2771 Subdevice *pSubdevice,
2772 NV2080_CTRL_GPU_VALIDATE_MEM_MAP_REQUEST_PARAMS *pParams
2773 )
2774 {
2775 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
2776 NvU64 start = pParams->addressStart;
2777 NvU64 length = pParams->addressLength;
2778 NV_STATUS rmStatus;
2779 NvU32 bar0MapSize;
2780 NvU64 bar0MapOffset;
2781
2782 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmDeviceGpuLockIsOwner(GPU_RES_GET_GPU(pSubdevice)->gpuInstance));
2783
2784 pParams->protection = NV_PROTECT_READ_WRITE;
2785
2786 if (isAddressWithinLimits(start, length, pGpu->busInfo.gpuPhysAddr,
2787 pGpu->deviceMappings[0].gpuNvLength))
2788 {
2789 start -= pGpu->busInfo.gpuPhysAddr;
2790
2791 OBJTMR *pTmr = GPU_GET_TIMER(pGpu);
2792 rmStatus = tmrGetTimerBar0MapInfo_HAL(pGpu, pTmr,
2793 &bar0MapOffset, &bar0MapSize);
2794 if ((rmStatus == NV_OK) &&
2795 isAddressWithinLimits(start, length, bar0MapOffset, bar0MapSize))
2796 {
2797 pParams->protection = NV_PROTECT_READABLE;
2798 return NV_OK;
2799 }
2800
2801 KernelFifo *pKernelFifo = GPU_GET_KERNEL_FIFO(pGpu);
2802 rmStatus = kfifoGetUsermodeMapInfo_HAL(pGpu, pKernelFifo,
2803 &bar0MapOffset, &bar0MapSize);
2804 if ((rmStatus == NV_OK) &&
2805 isAddressWithinLimits(start, length, bar0MapOffset, bar0MapSize))
2806 {
2807 return NV_OK;
2808 }
2809
2810 KernelMc *pKernelMc = GPU_GET_KERNEL_MC(pGpu);
2811 rmStatus = kmcGetMcBar0MapInfo_HAL(pGpu, pKernelMc,
2812 &bar0MapOffset, &bar0MapSize);
2813 if ((rmStatus == NV_OK) &&
2814 isAddressWithinLimits(start, length, bar0MapOffset, bar0MapSize))
2815 {
2816 pParams->protection = NV_PROTECT_READABLE;
2817 return NV_OK;
2818 }
2819
2820 //
2821 // If the kernel side does not know about the object being mapped,
2822 // fall-through to GSP and see if it knows anything.
2823 //
2824 if (IS_GSP_CLIENT(pGpu))
2825 {
2826 RM_API *pRmApi = GPU_GET_PHYSICAL_RMAPI(pGpu);
2827
2828 return pRmApi->Control(pRmApi,
2829 pGpu->hInternalClient,
2830 pGpu->hInternalSubdevice,
2831 NV2080_CTRL_CMD_GPU_VALIDATE_MEM_MAP_REQUEST,
2832 pParams, sizeof(*pParams));
2833 }
2834
2835 return NV_ERR_PROTECTION_FAULT;
2836 }
2837 // See bug 1784955
2838 else if (isAddressWithinLimits(start, length, pGpu->busInfo.gpuPhysFbAddr, pGpu->fbLength)
2839 || GPU_GET_KERNEL_MEMORY_SYSTEM(pGpu)->coherentCpuFbBase)
2840 {
2841 return NV_OK;
2842 }
2843
2844 return NV_ERR_PROTECTION_FAULT;
2845 }
2846
2847 /*!
2848 * @brief Computes the GFID (GPU Function ID) for a given SR-IOV
2849 * Virtual Function (VF) of the physical GPU based on the
2850 * BDF parameters provided by the caller.
2851 *
2852 * Lock Requirements:
2853 * Assert that API and GPUs lock held on entry
2854 *
2855 * @param[in] pSubdevice
2856 * @param[in] pParams pointer to control parameters
2857 *
2858 * Possible status values returned are:
2859 * NV_OK on successful computation of a valid GFID
2860 * NV_ERR_NOT_SUPPORTED if ctrl call is made when
2861 * SRIOV is not enabled OR
2862 * caller is not FM from Host RM
2863 * NV_ERR_INVALID_STATE if computed GFID is greater than
2864 * max GFID that is expected/allowed
2865 */
2866 NV_STATUS
subdeviceCtrlCmdGpuGetGfid_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_GFID_PARAMS * pParams)2867 subdeviceCtrlCmdGpuGetGfid_IMPL
2868 (
2869 Subdevice *pSubdevice,
2870 NV2080_CTRL_GPU_GET_GFID_PARAMS *pParams
2871 )
2872 {
2873 OBJSYS *pSys = SYS_GET_INSTANCE();
2874 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
2875 NvU32 pciFunction, gfid;
2876
2877 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmGpuLockIsOwner());
2878
2879 if (!gpuIsSriovEnabled(pGpu))
2880 return NV_ERR_NOT_SUPPORTED;
2881
2882 // Host RM && FM
2883 if ((!IS_VIRTUAL(pGpu)) &&
2884 (pSys->getProperty(pSys, PDB_PROP_SYS_FABRIC_IS_EXTERNALLY_MANAGED)))
2885 {
2886 //
2887 // In unix based systems, OS uses lspci format which is "ssss:bb:dd.f",
2888 // so device is 5 bits and function 3 bits.
2889 // for SR-IOV when ARI is enabled, device and function gets combined and
2890 // we need to consider 8 bits function.
2891 //
2892 pciFunction = (pParams->device << 3) | pParams->func;
2893 gfid = (pciFunction - pGpu->sriovState.firstVFOffset) + 1;
2894
2895 if (gfid > pGpu->sriovState.maxGfid)
2896 {
2897 NV_PRINTF(LEVEL_ERROR, "Computed GFID %d greater than max supported GFID\n", gfid);
2898 return NV_ERR_INVALID_STATE;
2899 }
2900
2901 pParams->gfid = gfid;
2902 // Also set the mask for max gfid supported currently in the driver
2903 pParams->gfidMask = (pGpu->sriovState.maxGfid - 1);
2904 }
2905 else
2906 {
2907 return NV_ERR_NOT_SUPPORTED;
2908 }
2909
2910 return NV_OK;
2911 }
2912
2913 /*!
2914 * @brief Sets or unsets the SW state to inform the GPU driver that the GPU instance
2915 * associated with input GFID has been activated or de-activated respectively.
2916 *
2917 * Lock Requirements:
2918 * Assert that API and GPUs lock held on entry
2919 *
2920 * @param[in] pSubdevice
2921 * @param[in] pParams pointer to control parameters
2922 *
2923 * Possible status values returned are:
2924 * NV_OK on success
2925 * NV_ERR_INVALID_STATE if SRIOV state for P2P in driver is not setup
2926 * NV_ERR_INVALID_ARGUMENT if input GFID is greater than the max GFID allowed
2927 * NV_ERR_NOT_SUPPORTED if ctrl call is made when
2928 * SRIOV is not enabled OR
2929 * caller is not FM from Host RM
2930 * NV_ERR_IN_USE If MAX_NUM_P2P_GFIDS have already been enabled for P2P
2931 */
2932 NV_STATUS
gpuUpdateGfidP2pCapability(OBJGPU * pGpu,NV2080_CTRL_CMD_GPU_UPDATE_GFID_P2P_CAPABILITY_PARAMS * pParams)2933 gpuUpdateGfidP2pCapability
2934 (
2935 OBJGPU *pGpu,
2936 NV2080_CTRL_CMD_GPU_UPDATE_GFID_P2P_CAPABILITY_PARAMS *pParams
2937 )
2938 {
2939 OBJSYS *pSys = SYS_GET_INSTANCE();
2940 PSRIOV_P2P_INFO pP2PInfo = pGpu->sriovState.pP2PInfo;
2941 NvBool bSetP2PAccess = NV_FALSE;
2942 NvU32 idx;
2943
2944 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmGpuLockIsOwner());
2945
2946 if (!gpuIsSriovEnabled(pGpu))
2947 return NV_ERR_NOT_SUPPORTED;
2948
2949 NV_ASSERT_OR_RETURN(pP2PInfo != NULL, NV_ERR_INVALID_STATE);
2950
2951 // Ctrl call should only be called by the FM from Host RM
2952 if ((!IS_VIRTUAL(pGpu)) &&
2953 (pSys->getProperty(pSys, PDB_PROP_SYS_FABRIC_IS_EXTERNALLY_MANAGED)))
2954 {
2955 if (pParams->gfid > pGpu->sriovState.maxGfid)
2956 {
2957 NV_PRINTF(LEVEL_ERROR, "Input GFID %d greater than max allowed GFID\n", pParams->gfid);
2958 return NV_ERR_INVALID_ARGUMENT;
2959 }
2960
2961 for (idx = 0; idx < pGpu->sriovState.maxP2pGfid; idx++)
2962 {
2963 //
2964 // Check if Host RM is already using a GFID for P2P,
2965 // Since only "MAX_NUM_P2P_GFIDS" GFID(s) is(are) allowed to do P2P at any time,
2966 // we should fail here if a GFID greater than supported number is being enabled
2967 //
2968 if (pParams->bEnable)
2969 {
2970 if (pP2PInfo[idx].gfid == INVALID_P2P_GFID)
2971 {
2972 pP2PInfo[idx].gfid = pParams->gfid;
2973 pGpu->sriovState.p2pFabricPartitionId = pParams->fabricPartitionId;
2974 bSetP2PAccess = NV_TRUE;
2975 break;
2976 }
2977 }
2978 else
2979 {
2980 if (pP2PInfo[idx].gfid == pParams->gfid)
2981 {
2982 pP2PInfo[idx].gfid = INVALID_P2P_GFID;
2983 pGpu->sriovState.p2pFabricPartitionId = INVALID_FABRIC_PARTITION_ID;
2984 bSetP2PAccess = NV_TRUE;
2985 break;
2986 }
2987 }
2988 }
2989
2990 if (bSetP2PAccess == NV_TRUE)
2991 {
2992 pP2PInfo[idx].bAllowP2pAccess = pParams->bEnable;
2993 }
2994 else
2995 {
2996 // Some other GFID(s) has already been enabled to do P2P
2997 // Fail the call
2998 return NV_ERR_IN_USE;
2999 }
3000 }
3001 else
3002 {
3003 return NV_ERR_NOT_SUPPORTED;
3004 }
3005
3006 return NV_OK;
3007 }
3008
3009 NV_STATUS
subdeviceCtrlCmdUpdateGfidP2pCapability_IMPL(Subdevice * pSubdevice,NV2080_CTRL_CMD_GPU_UPDATE_GFID_P2P_CAPABILITY_PARAMS * pParams)3010 subdeviceCtrlCmdUpdateGfidP2pCapability_IMPL
3011 (
3012 Subdevice *pSubdevice,
3013 NV2080_CTRL_CMD_GPU_UPDATE_GFID_P2P_CAPABILITY_PARAMS *pParams
3014 )
3015 {
3016 return gpuUpdateGfidP2pCapability(GPU_RES_GET_GPU(pSubdevice), pParams);
3017 }
3018
3019 /*
3020 * Set the EGM fabric base address
3021 */
3022 NV_STATUS
subdeviceCtrlCmdGpuSetEgmGpaFabricAddr_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_SET_EGM_GPA_FABRIC_BASE_ADDR_PARAMS * pParams)3023 subdeviceCtrlCmdGpuSetEgmGpaFabricAddr_IMPL
3024 (
3025 Subdevice *pSubdevice,
3026 NV2080_CTRL_GPU_SET_EGM_GPA_FABRIC_BASE_ADDR_PARAMS *pParams
3027 )
3028 {
3029 return NV_OK;
3030 }
3031
3032 /*!
3033 * @brief: This command returns the load time (latency) of each engine,
3034 * implementing NV2080_CTRL_CMD_GPU_GET_ENGINE_LOAD_TIMES control call.
3035 *
3036 * @param[in] pSubdevice
3037 * @param[in] pParams
3038 *
3039 * @return
3040 * NV_OK Success
3041 */
3042 NV_STATUS
subdeviceCtrlCmdGpuGetEngineLoadTimes_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_ENGINE_LOAD_TIMES_PARAMS * pParams)3043 subdeviceCtrlCmdGpuGetEngineLoadTimes_IMPL
3044 (
3045 Subdevice *pSubdevice,
3046 NV2080_CTRL_GPU_GET_ENGINE_LOAD_TIMES_PARAMS *pParams
3047 )
3048 {
3049 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
3050 PENGDESCRIPTOR engDescriptorList = gpuGetInitEngineDescriptors(pGpu);
3051 NvU32 numEngDescriptors = gpuGetNumEngDescriptors(pGpu);
3052 NvU32 curEngDescIdx;
3053
3054 NV_ASSERT_OR_RETURN(numEngDescriptors < NV2080_CTRL_GPU_MAX_ENGINE_OBJECTS, NV_ERR_BUFFER_TOO_SMALL);
3055
3056 pParams->engineCount = numEngDescriptors;
3057 for (curEngDescIdx = 0; curEngDescIdx < numEngDescriptors; curEngDescIdx++)
3058 {
3059 ENGDESCRIPTOR curEngDescriptor = engDescriptorList[curEngDescIdx];
3060 OBJENGSTATE *pEngstate = gpuGetEngstate(pGpu, curEngDescriptor);
3061
3062 if (pEngstate == NULL)
3063 {
3064 pParams->engineIsInit[curEngDescIdx] = NV_FALSE;
3065 continue;
3066 }
3067
3068 pParams->engineList[curEngDescIdx] = pEngstate->engDesc;
3069 pParams->engineStateLoadTime[curEngDescIdx] = pEngstate->stats[ENGSTATE_STATE_LOAD].transitionTimeUs * 1000;
3070 pParams->engineIsInit[curEngDescIdx] = NV_TRUE;
3071 }
3072
3073 return NV_OK;
3074 }
3075
3076 //
3077 // subdeviceCtrlCmdGpuSetFabricAddr
3078 //
3079 // Lock Requirements:
3080 // Assert that API lock and GPUs lock held on entry
3081 //
3082 NV_STATUS
subdeviceCtrlCmdGpuSetFabricAddr_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_SET_FABRIC_BASE_ADDR_PARAMS * pParams)3083 subdeviceCtrlCmdGpuSetFabricAddr_IMPL
3084 (
3085 Subdevice *pSubdevice,
3086 NV2080_CTRL_GPU_SET_FABRIC_BASE_ADDR_PARAMS *pParams
3087 )
3088 {
3089 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
3090 NvHandle hClient = RES_GET_CLIENT_HANDLE(pSubdevice);
3091 CALL_CONTEXT *pCallContext = resservGetTlsCallContext();
3092
3093 NV_ASSERT_OR_RETURN(RMCFG_FEATURE_KERNEL_RM, NV_ERR_NOT_SUPPORTED);
3094 NV_ASSERT_OR_RETURN(pCallContext != NULL, NV_ERR_INVALID_STATE);
3095
3096 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmGpuLockIsOwner());
3097
3098 if (!rmclientIsCapableOrAdminByHandle(hClient,
3099 NV_RM_CAP_EXT_FABRIC_MGMT,
3100 pCallContext->secInfo.privLevel))
3101 {
3102 NV_PRINTF(LEVEL_ERROR, "Non-privileged context issued privileged cmd\n");
3103 return NV_ERR_INSUFFICIENT_PERMISSIONS;
3104 }
3105
3106 KernelNvlink *pKernelNvlink = GPU_GET_KERNEL_NVLINK(pGpu);
3107
3108 if (pKernelNvlink == NULL)
3109 return NV_ERR_NOT_SUPPORTED;
3110
3111 return knvlinkSetUniqueFabricBaseAddress(pGpu, pKernelNvlink, pParams->fabricBaseAddr);
3112 }
3113
3114 static NvU64
_convertGpuFabricProbeInfoCaps(NvU64 fmCaps)3115 _convertGpuFabricProbeInfoCaps
3116 (
3117 NvU64 fmCaps
3118 )
3119 {
3120 NvU64 fabricCaps = 0;
3121 NvU32 i = 0;
3122
3123 FOR_EACH_INDEX_IN_MASK(64, i, fmCaps)
3124 {
3125 switch (NVBIT64(i))
3126 {
3127 case NVLINK_INBAND_FM_CAPS_MC_TEAM_SETUP_V1:
3128 case NVLINK_INBAND_FM_CAPS_MC_TEAM_RELEASE_V1:
3129 {
3130 fabricCaps |= NV2080_CTRL_GPU_FABRIC_PROBE_CAP_MC_SUPPORTED;
3131 break;
3132 }
3133 case NVLINK_INBAND_FM_CAPS_MC_TEAM_SETUP_V2:
3134 {
3135 fabricCaps |= NV2080_CTRL_GPU_FABRIC_PROBE_CAP_MC_SUPPORTED;
3136 #ifdef NV2080_CTRL_GPU_FABRIC_PROBE_CAP_MC_MUTLINODE_SUPPORTED
3137 fabricCaps |=
3138 NV2080_CTRL_GPU_FABRIC_PROBE_CAP_MC_MUTLINODE_SUPPORTED;
3139 #endif
3140 break;
3141 }
3142 default:
3143 {
3144 break;
3145 }
3146 }
3147 }
3148 FOR_EACH_INDEX_IN_MASK_END;
3149
3150 return fabricCaps;
3151 }
3152
3153 NV_STATUS
subdeviceCtrlCmdGetGpuFabricProbeInfo_IMPL(Subdevice * pSubdevice,NV2080_CTRL_CMD_GET_GPU_FABRIC_PROBE_INFO_PARAMS * pParams)3154 subdeviceCtrlCmdGetGpuFabricProbeInfo_IMPL
3155 (
3156 Subdevice *pSubdevice,
3157 NV2080_CTRL_CMD_GET_GPU_FABRIC_PROBE_INFO_PARAMS *pParams
3158 )
3159 {
3160 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
3161 NV_STATUS status;
3162 NvU64 numProbeReqs = 0;
3163 NvU64 fmCaps = 0;
3164 NvUuid *pClusterUuid = (NvUuid*) pParams->clusterUuid;
3165 NvU32 mask = 0, healthMask = 0;
3166
3167 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() &&
3168 rmDeviceGpuLockIsOwner(gpuGetInstance(pGpu)));
3169
3170 // Probe is not supported - Ex - Direct connected etc.
3171 if (!gpuFabricProbeIsSupported(pGpu))
3172 {
3173 pParams->state = NV2080_CTRL_GPU_FABRIC_PROBE_STATE_UNSUPPORTED;
3174 return NV_OK;
3175 }
3176
3177 // Probe is not supported - Ex - GPU is degraded etc.
3178 if (pGpu->pGpuFabricProbeInfoKernel == NULL)
3179 {
3180 pParams->state = NV2080_CTRL_GPU_FABRIC_PROBE_STATE_COMPLETE;
3181 pParams->status = NV_ERR_NOT_SUPPORTED; // Due to degradation etc.
3182 return NV_OK;
3183 }
3184
3185 status = gpuFabricProbeGetNumProbeReqs(pGpu->pGpuFabricProbeInfoKernel,
3186 &numProbeReqs);
3187 if (status != NV_OK)
3188 {
3189 NV_PRINTF(LEVEL_ERROR, "Error while retrieving numProbeReqs\n");
3190 return status;
3191 }
3192
3193 pParams->state = (numProbeReqs == 0) ?
3194 NV2080_CTRL_GPU_FABRIC_PROBE_STATE_NOT_STARTED :
3195 NV2080_CTRL_GPU_FABRIC_PROBE_STATE_IN_PROGRESS;
3196
3197 if (!gpuFabricProbeIsReceived(pGpu->pGpuFabricProbeInfoKernel))
3198 {
3199 return NV_OK;
3200 }
3201
3202 pParams->state = NV2080_CTRL_GPU_FABRIC_PROBE_STATE_COMPLETE;
3203 pParams->status = gpuFabricProbeGetFmStatus(pGpu->pGpuFabricProbeInfoKernel);
3204 if (pParams->status != NV_OK)
3205 {
3206 // Nothing needs to be done as probe response status is not success
3207 return NV_OK;
3208 }
3209
3210 ct_assert(NV2080_GPU_FABRIC_CLUSTER_UUID_LEN == NV_UUID_LEN);
3211
3212 status = gpuFabricProbeGetClusterUuid(pGpu->pGpuFabricProbeInfoKernel, pClusterUuid);
3213 NV_ASSERT_OK_OR_RETURN(status);
3214
3215 status = gpuFabricProbeGetFabricPartitionId(pGpu->pGpuFabricProbeInfoKernel,
3216 &pParams->fabricPartitionId);
3217 NV_ASSERT_OK_OR_RETURN(status);
3218
3219 status = gpuFabricProbeGetfmCaps(pGpu->pGpuFabricProbeInfoKernel, &fmCaps);
3220 NV_ASSERT_OK_OR_RETURN(status);
3221
3222 if (!gpuIsCCFeatureEnabled(pGpu) || !gpuIsCCMultiGpuProtectedPcieModeEnabled(pGpu))
3223 {
3224 pParams->fabricCaps = _convertGpuFabricProbeInfoCaps(fmCaps);
3225 }
3226
3227 status = gpuFabricProbeGetFabricCliqueId(pGpu->pGpuFabricProbeInfoKernel,
3228 &pParams->fabricCliqueId);
3229 NV_ASSERT_OK_OR_RETURN(status);
3230
3231 status = gpuFabricProbeGetFabricHealthStatus(pGpu->pGpuFabricProbeInfoKernel,
3232 &mask);
3233 NV_ASSERT_OK_OR_RETURN(status);
3234
3235 if (FLD_TEST_DRF(LINK, _INBAND_FABRIC_HEALTH_MASK, _DEGRADED_BW, _TRUE, mask))
3236 {
3237 healthMask |= FLD_SET_DRF(2080, _CTRL_GPU_FABRIC_HEALTH_MASK,
3238 _DEGRADED_BW, _TRUE, healthMask);
3239 }
3240 else if (FLD_TEST_DRF(LINK, _INBAND_FABRIC_HEALTH_MASK, _DEGRADED_BW,
3241 _FALSE, mask))
3242 {
3243 healthMask |= FLD_SET_DRF(2080, _CTRL_GPU_FABRIC_HEALTH_MASK,
3244 _DEGRADED_BW, _FALSE, healthMask);
3245 }
3246 else if (FLD_TEST_DRF(LINK, _INBAND_FABRIC_HEALTH_MASK, _DEGRADED_BW,
3247 _NOT_SUPPORTED, mask))
3248 {
3249 healthMask |= FLD_SET_DRF(2080, _CTRL_GPU_FABRIC_HEALTH_MASK,
3250 _DEGRADED_BW, _NOT_SUPPORTED, healthMask);
3251 }
3252
3253 pParams->fabricHealthMask = healthMask;
3254
3255 return NV_OK;
3256 }
3257
3258 /*!
3259 * @brief This command is used to determine which GSP features are
3260 * supported on this GPU.
3261 *
3262 * @param[in] pSubdevice
3263 * @param[in,out] pGspFeaturesParams
3264 *
3265 * @return Returns NV_STATUS
3266 * NV_OK Success
3267 */
3268 NV_STATUS
subdeviceCtrlCmdGspGetFeatures_KERNEL(Subdevice * pSubdevice,NV2080_CTRL_GSP_GET_FEATURES_PARAMS * pGspFeaturesParams)3269 subdeviceCtrlCmdGspGetFeatures_KERNEL
3270 (
3271 Subdevice *pSubdevice,
3272 NV2080_CTRL_GSP_GET_FEATURES_PARAMS *pGspFeaturesParams
3273 )
3274 {
3275 pGspFeaturesParams->bValid = NV_FALSE;
3276 return NV_OK;
3277 }
3278
3279 //
3280 // Lock Requirements:
3281 // Assert that API lock and GPUs lock held on entry
3282 //
3283 NV_STATUS
subdeviceCtrlCmdGpuGetNameString_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_NAME_STRING_PARAMS * pNameStringParams)3284 subdeviceCtrlCmdGpuGetNameString_IMPL
3285 (
3286 Subdevice *pSubdevice,
3287 NV2080_CTRL_GPU_GET_NAME_STRING_PARAMS *pNameStringParams
3288 )
3289 {
3290 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
3291
3292 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmGpuLockIsOwner());
3293
3294 return gpuGetNameString(pGpu,
3295 pNameStringParams->gpuNameStringFlags,
3296 (void *)&pNameStringParams->gpuNameString);
3297 }
3298
3299 //
3300 // subdeviceCtrlCmdGpuGetShortNameString
3301 //
3302 // Lock Requirements:
3303 // Assert that API lock and GPUs lock held on entry
3304 //
3305 NV_STATUS
subdeviceCtrlCmdGpuGetShortNameString_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_SHORT_NAME_STRING_PARAMS * pShortNameStringParams)3306 subdeviceCtrlCmdGpuGetShortNameString_IMPL
3307 (
3308 Subdevice *pSubdevice,
3309 NV2080_CTRL_GPU_GET_SHORT_NAME_STRING_PARAMS *pShortNameStringParams
3310 )
3311 {
3312 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
3313
3314 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmGpuLockIsOwner());
3315
3316 return gpuGetShortNameString(pGpu, (void *)&pShortNameStringParams->gpuShortNameString);
3317 }
3318
3319 //
3320 // subdeviceCtrlCmdGpuGetGidInfo
3321 //
3322 // Lock Requirements:
3323 // Assert that API lock held on entry
3324 //
3325 NV_STATUS
subdeviceCtrlCmdGpuGetGidInfo_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_GID_INFO_PARAMS * pGidInfoParams)3326 subdeviceCtrlCmdGpuGetGidInfo_IMPL
3327 (
3328 Subdevice *pSubdevice,
3329 NV2080_CTRL_GPU_GET_GID_INFO_PARAMS *pGidInfoParams
3330 )
3331 {
3332 NV_STATUS rmStatus = NV_OK;
3333 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
3334 NvU8 *pGidString;
3335 NvU32 flags = pGidInfoParams->flags;
3336 NvU32 gidStrlen;
3337
3338 rmStatus = gpuGetGidInfo(pGpu, &pGidString, &gidStrlen, flags);
3339 if (rmStatus == NV_OK)
3340 {
3341 if (sizeof(pGidInfoParams->data) >= gidStrlen)
3342 {
3343 portMemCopy(pGidInfoParams->data, gidStrlen, pGidString, gidStrlen);
3344 pGidInfoParams->length = gidStrlen;
3345 }
3346 else
3347 {
3348 rmStatus = NV_ERR_INSUFFICIENT_RESOURCES;
3349 }
3350
3351 portMemFree(pGidString);
3352 }
3353
3354 return rmStatus;
3355 }
3356
3357 // Control call to report a nonreplayable fault from UVM
3358 NV_STATUS
subdeviceCtrlCmdGpuReportNonReplayableFault_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_REPORT_NON_REPLAYABLE_FAULT_PARAMS * pParams)3359 subdeviceCtrlCmdGpuReportNonReplayableFault_IMPL
3360 (
3361 Subdevice *pSubdevice,
3362 NV2080_CTRL_GPU_REPORT_NON_REPLAYABLE_FAULT_PARAMS *pParams
3363 )
3364 {
3365 NV_STATUS status = NV_OK;
3366 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
3367 KernelGmmu *pKernelGmmu = GPU_GET_KERNEL_GMMU(pGpu);
3368 GMMU_FAULT_PACKET *pFaultPacket = (GMMU_FAULT_PACKET *)(NvUPtr)&pParams->faultPacket.data;
3369
3370 ct_assert(sizeof(GMMU_FAULT_PACKET) == NV2080_CTRL_GPU_FAULT_PACKET_SIZE);
3371
3372 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmGpuLockIsOwner());
3373
3374 status = kgmmuHandleNonReplayableFaultPacket_HAL(pGpu, pKernelGmmu, pFaultPacket);
3375
3376 return status;
3377 }
3378
3379 NV_STATUS
subdeviceCtrlCmdGpuGetChipDetails_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GPU_GET_CHIP_DETAILS_PARAMS * pParams)3380 subdeviceCtrlCmdGpuGetChipDetails_IMPL
3381 (
3382 Subdevice *pSubdevice,
3383 NV2080_CTRL_GPU_GET_CHIP_DETAILS_PARAMS *pParams
3384 )
3385 {
3386 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
3387
3388 return gpuGetChipDetails(pGpu, pParams);
3389 }
3390
3391 NV_STATUS
subdeviceCtrlCmdBiosGetSKUInfo_KERNEL(Subdevice * pSubdevice,NV2080_CTRL_BIOS_GET_SKU_INFO_PARAMS * pBiosGetSKUInfoParams)3392 subdeviceCtrlCmdBiosGetSKUInfo_KERNEL
3393 (
3394 Subdevice *pSubdevice,
3395 NV2080_CTRL_BIOS_GET_SKU_INFO_PARAMS *pBiosGetSKUInfoParams
3396 )
3397 {
3398 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
3399 GspStaticConfigInfo *pGSCI = GPU_GET_GSP_STATIC_INFO(pGpu);
3400
3401 NV_ASSERT_OR_RETURN(pGSCI != NULL, NV_ERR_INVALID_STATE);
3402
3403 portMemCopy(pBiosGetSKUInfoParams,
3404 sizeof(NV2080_CTRL_BIOS_GET_SKU_INFO_PARAMS),
3405 &pGSCI->SKUInfo,
3406 sizeof(NV2080_CTRL_BIOS_GET_SKU_INFO_PARAMS));
3407
3408 return NV_OK;
3409 }
3410
3411 /*!
3412 * @brief This Command is used to set a new value for the specified logo illumination
3413 * attribute on the specified GPU
3414 *
3415 * @param[in,out] pConfigParams
3416 * attribute: The attribute whose support is to be determined.
3417 * value: The new value of the specified attribute to be applied.
3418 *
3419 * @return Returns NV_STATUS
3420 * NV_ERR_INVALID_ARGUMENT Invalid value for attribute
3421 * NV_ERR_NOT_SUPPORTED Invalid Attribute for specified GPU
3422 * NV_OK Success
3423 *
3424 */
3425 NV_STATUS
subdeviceCtrlCmdGpuSetIllum_IMPL(Subdevice * pSubdevice,NV2080_CTRL_CMD_GPU_ILLUM_PARAMS * pConfigParams)3426 subdeviceCtrlCmdGpuSetIllum_IMPL
3427 (
3428 Subdevice *pSubdevice,
3429 NV2080_CTRL_CMD_GPU_ILLUM_PARAMS *pConfigParams
3430 )
3431 {
3432 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
3433 NV_STATUS status = NV_OK;
3434 RM_API *pRmApi = rmapiGetInterface(RMAPI_GPU_LOCK_INTERNAL);
3435 NvHandle hClient = RES_GET_CLIENT_HANDLE(pSubdevice);
3436 NvHandle hSubdevice = RES_GET_HANDLE(pSubdevice);
3437 NV2080_CTRL_INTERNAL_GPU_SET_ILLUM_PARAMS *pConfigParamsInternal = (NV2080_CTRL_INTERNAL_GPU_SET_ILLUM_PARAMS*)pConfigParams;
3438
3439 status = pRmApi->Control(pRmApi, hClient, hSubdevice,
3440 NV2080_CTRL_CMD_INTERNAL_GPU_SET_ILLUM,
3441 pConfigParamsInternal, sizeof(*pConfigParamsInternal));
3442
3443 if (NV_OK == status)
3444 {
3445 // convert the attribute to the GPIO function.
3446 switch(pConfigParams->attribute)
3447 {
3448 case NV2080_CTRL_GPU_ILLUM_ATTRIB_LOGO_BRIGHTNESS:
3449 {
3450 osWriteRegistryDword(pGpu, NV_REG_STR_ILLUM_ATTRIB_LOGO_BRIGHTNESS, pConfigParams->value);
3451 break;
3452 }
3453 case NV2080_CTRL_GPU_ILLUM_ATTRIB_SLI_BRIGHTNESS:
3454 {
3455 osWriteRegistryDword(pGpu, NV_REG_STR_ILLUM_ATTRIB_SLI_BRIGHTNESS, pConfigParams->value);
3456 break;
3457 }
3458 }
3459 }
3460
3461 return status;
3462 }
3463
3464