1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2018-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 #include "rmapi/control.h"
26 
27 #include "ctrl/ctrl0000/ctrl0000gpu.h"
28 #include "ctrl/ctrl0000/ctrl0000nvd.h"
29 #include "ctrl/ctrl0000/ctrl0000system.h"
30 #include "ctrl/ctrl0041.h"
31 #include "ctrl/ctrl0080/ctrl0080dma.h"
32 #include "ctrl/ctrl0080/ctrl0080fb.h"
33 #include "ctrl/ctrl0080/ctrl0080fifo.h"
34 #include "ctrl/ctrl0080/ctrl0080gr.h"
35 #include "ctrl/ctrl0080/ctrl0080gpu.h"
36 #include "ctrl/ctrl0080/ctrl0080host.h"
37 #include "ctrl/ctrl0080/ctrl0080msenc.h"
38 #include "ctrl/ctrl0080/ctrl0080perf.h"
39 #include "ctrl/ctrl2080/ctrl2080bus.h"
40 #include "ctrl/ctrl2080/ctrl2080ce.h"
41 #include "ctrl/ctrl2080/ctrl2080fb.h"
42 #include "ctrl/ctrl2080/ctrl2080gpu.h"
43 #include "ctrl/ctrl2080/ctrl2080i2c.h"
44 #include "ctrl/ctrl2080/ctrl2080mc.h"
45 #include "ctrl/ctrl2080/ctrl2080nvd.h"
46 #include "ctrl/ctrl2080/ctrl2080perf.h"
47 #include "ctrl/ctrl2080/ctrl2080pmgr.h"
48 #include "ctrl/ctrl2080/ctrl2080rc.h"
49 #include "ctrl/ctrl2080/ctrl2080thermal.h"
50 #include "ctrl/ctrl208f/ctrl208fgpu.h"
51 #include "ctrl/ctrl402c.h"
52 #include "ctrl/ctrl0073.h"
53 #include "ctrl/ctrla0bc.h"
54 #include "ctrl/ctrlb06f.h"
55 #include "ctrl/ctrl83de.h"
56 #ifdef USE_AMAPLIB
57 #include "amap_v1.h"
58 #endif
59 
60 //
61 // Validates pRmCtrlParams->pParams is non-NULL and user-provided paramsSize is correct
62 // This check is used in early validation paths outside the resource server lock
63 //
64 #define CHECK_PARAMS_OR_RETURN(pRmCtrlParams, paramsType)            \
65     do {                                                             \
66         NV_CHECK_OR_RETURN(LEVEL_WARNING,                            \
67             (((pRmCtrlParams)->pParams != NULL) &&                   \
68             ((pRmCtrlParams)->paramsSize) == sizeof(paramsType)),    \
69             NV_ERR_INVALID_ARGUMENT);                                \
70     } while(0)
71 
_i2cTransactionCopyIn(RMAPI_PARAM_COPY * paramCopies,RmCtrlParams * pRmCtrlParams)72 static NvBool _i2cTransactionCopyIn(RMAPI_PARAM_COPY *paramCopies, RmCtrlParams *pRmCtrlParams)
73 {
74     NV402C_CTRL_I2C_TRANSACTION_PARAMS *pParams = (NV402C_CTRL_I2C_TRANSACTION_PARAMS*)pRmCtrlParams->pParams;
75     NvBool bCopyInitDone = NV_FALSE;
76 
77     switch (pParams->transType)
78     {
79         case NV402C_CTRL_I2C_TRANSACTION_TYPE_I2C_BLOCK_RW:
80         {
81             RMAPI_PARAM_COPY_INIT(paramCopies[0],
82                             pParams->transData.i2cBlockData.pMessage,
83                             pParams->transData.i2cBlockData.pMessage,
84                             pParams->transData.i2cBlockData.messageLength, 1);
85 
86             bCopyInitDone = NV_TRUE;
87             if (pParams->transData.i2cBlockData.bWrite == NV_TRUE)
88                 paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYOUT;
89             else
90                 paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYIN;
91 
92             break;
93         }
94         case NV402C_CTRL_I2C_TRANSACTION_TYPE_I2C_BUFFER_RW:
95         {
96             RMAPI_PARAM_COPY_INIT(paramCopies[0],
97                             pParams->transData.i2cBufferData.pMessage,
98                             pParams->transData.i2cBufferData.pMessage,
99                             pParams->transData.i2cBufferData.messageLength, 1);
100 
101             bCopyInitDone = NV_TRUE;
102             if (pParams->transData.i2cBufferData.bWrite == NV_TRUE)
103                 paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYOUT;
104             else
105                 paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYIN;
106 
107             break;
108         }
109         case NV402C_CTRL_I2C_TRANSACTION_TYPE_SMBUS_BLOCK_RW:
110         {
111             RMAPI_PARAM_COPY_INIT(paramCopies[0],
112                             pParams->transData.smbusBlockData.pMessage,
113                             pParams->transData.smbusBlockData.pMessage,
114                             pParams->transData.smbusBlockData.messageLength, 1);
115 
116             bCopyInitDone = NV_TRUE;
117             if (pParams->transData.smbusBlockData.bWrite == NV_TRUE)
118                 paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYOUT;
119             else
120                 paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYIN;
121 
122             break;
123         }
124         case NV402C_CTRL_I2C_TRANSACTION_TYPE_SMBUS_MULTIBYTE_REGISTER_BLOCK_RW:
125         {
126             RMAPI_PARAM_COPY_INIT(paramCopies[0],
127                             pParams->transData.smbusMultibyteRegisterData.pMessage,
128                             pParams->transData.smbusMultibyteRegisterData.pMessage,
129                             pParams->transData.smbusMultibyteRegisterData.messageLength, 1);
130 
131             bCopyInitDone = NV_TRUE;
132             if (pParams->transData.smbusMultibyteRegisterData.bWrite == NV_TRUE)
133                 paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYOUT;
134             else
135                 paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYIN;
136 
137             break;
138         }
139         case NV402C_CTRL_I2C_TRANSACTION_TYPE_READ_EDID_DDC:
140         {
141             RMAPI_PARAM_COPY_INIT(paramCopies[0],
142                             pParams->transData.edidData.pMessage,
143                             pParams->transData.edidData.pMessage,
144                             pParams->transData.edidData.messageLength, 1);
145 
146             bCopyInitDone = NV_TRUE;
147             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYIN;
148 
149             break;
150         }
151 
152         default:
153             break;
154     }
155 
156     return bCopyInitDone;
157 }
158 
i2cTransactionCopyOut(RMAPI_PARAM_COPY * paramCopies,RmCtrlParams * pRmCtrlParams)159 static NV_STATUS i2cTransactionCopyOut(RMAPI_PARAM_COPY *paramCopies, RmCtrlParams *pRmCtrlParams)
160 {
161     NV_STATUS status = NV_OK;
162     NV402C_CTRL_I2C_TRANSACTION_PARAMS *pParams = (NV402C_CTRL_I2C_TRANSACTION_PARAMS*)pRmCtrlParams->pParams;
163 
164     switch (pParams->transType)
165     {
166         case NV402C_CTRL_I2C_TRANSACTION_TYPE_I2C_BLOCK_RW:
167         {
168             status = rmapiParamsRelease(&paramCopies[0]);
169             pParams->transData.i2cBlockData.pMessage = paramCopies[0].pUserParams;
170             break;
171         }
172         case NV402C_CTRL_I2C_TRANSACTION_TYPE_I2C_BUFFER_RW:
173         {
174             status = rmapiParamsRelease(&paramCopies[0]);
175             pParams->transData.i2cBufferData.pMessage = paramCopies[0].pUserParams;
176             break;
177         }
178         case NV402C_CTRL_I2C_TRANSACTION_TYPE_SMBUS_BLOCK_RW:
179         {
180             status = rmapiParamsRelease(&paramCopies[0]);
181             pParams->transData.smbusBlockData.pMessage = paramCopies[0].pUserParams;
182             break;
183         }
184         case NV402C_CTRL_I2C_TRANSACTION_TYPE_SMBUS_MULTIBYTE_REGISTER_BLOCK_RW:
185         {
186             status = rmapiParamsRelease(&paramCopies[0]);
187             pParams->transData.smbusMultibyteRegisterData.pMessage = paramCopies[0].pUserParams;
188             break;
189         }
190         case NV402C_CTRL_I2C_TRANSACTION_TYPE_READ_EDID_DDC:
191         {
192             status = rmapiParamsRelease(&paramCopies[0]);
193             pParams->transData.edidData.pMessage = paramCopies[0].pUserParams;
194             break;
195         }
196 
197         default:
198             break;
199     }
200 
201     return status;
202 }
203 
204 /*
205  * Helper routine to handle all embedded pointer user to kernel copies
206  * Top level parameters are already copied to kernel (done in rmControlCmdExecute/dispControlSynchronizedCmdExecute)
207  * After successful execution each embedded pointer within pRmCtrlParams->pParams will be kernel
208  * paramCopies is a 4-element array as we currently have up to 4 embedded pointers in existing RM Controls
209  *
210  * No new RM Controls with embedded pointers should ever be added!
211  *
212  * See bug 1867098 for more reference - [RM Linux/UVM] Fix GPU lock/mmap_sem lock inversion
213  */
embeddedParamCopyIn(RMAPI_PARAM_COPY * paramCopies,RmCtrlParams * pRmCtrlParams)214 NV_STATUS embeddedParamCopyIn(RMAPI_PARAM_COPY *paramCopies, RmCtrlParams *pRmCtrlParams)
215 {
216     NV_STATUS status = NV_OK;
217     void* pParams = pRmCtrlParams->pParams;
218     NvU32 paramsCnt = 1;
219     NvU32 i, j = 0;
220 
221     if ((pRmCtrlParams->secInfo.paramLocation == PARAM_LOCATION_KERNEL) ||
222         (pRmCtrlParams->flags & NVOS54_FLAGS_FINN_SERIALIZED))
223     {
224         return NV_OK;
225     }
226 
227     switch (pRmCtrlParams->cmd)
228     {
229         case NV2080_CTRL_GPU_GET_NVENC_SW_SESSION_INFO:
230         {
231             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_GPU_GET_NVENC_SW_SESSION_INFO_PARAMS);
232 
233             RMAPI_PARAM_COPY_INIT(paramCopies[0],
234                             ((NV2080_CTRL_GPU_GET_NVENC_SW_SESSION_INFO_PARAMS*)pParams)->sessionInfoTbl,
235                             ((NV2080_CTRL_GPU_GET_NVENC_SW_SESSION_INFO_PARAMS*)pParams)->sessionInfoTbl,
236                             ((NV2080_CTRL_GPU_GET_NVENC_SW_SESSION_INFO_PARAMS*)pParams)->sessionInfoTblEntry,
237                             sizeof(NV2080_CTRL_NVENC_SW_SESSION_INFO));
238             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYIN;
239 
240             break;
241         }
242         case NV2080_CTRL_CMD_GPU_GET_ENGINES:
243         {
244             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_GPU_GET_ENGINES_PARAMS);
245 
246             RMAPI_PARAM_COPY_INIT(paramCopies[0],
247                             ((NV2080_CTRL_GPU_GET_ENGINES_PARAMS*)pParams)->engineList,
248                             ((NV2080_CTRL_GPU_GET_ENGINES_PARAMS*)pParams)->engineList,
249                             ((NV2080_CTRL_GPU_GET_ENGINES_PARAMS*)pParams)->engineCount, sizeof(NvU32));
250             break;
251         }
252 #ifdef USE_AMAPLIB
253         case NV2080_CTRL_CMD_FB_GET_AMAP_CONF:
254         {
255             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_CMD_FB_GET_AMAP_CONF_PARAMS);
256 
257             NV2080_CTRL_CMD_FB_GET_AMAP_CONF_PARAMS *userParams = (NV2080_CTRL_CMD_FB_GET_AMAP_CONF_PARAMS*)pParams;
258             NvU32 amapConfParamsSize = (userParams->pAmapConfParams != NvP64_NULL) ?
259                                                                     sizeof(ConfParamsV1) : 0;
260             NvU32 cbcSwizzleParamsSize = (userParams->pCbcSwizzleParams != NvP64_NULL) ?
261                                                                     sizeof(CbcSwizzleParamsV1) : 0;
262 
263             RMAPI_PARAM_COPY_INIT(paramCopies[0],
264                                   userParams->pAmapConfParams,
265                                   userParams->pAmapConfParams,
266                                   1, amapConfParamsSize);
267             RMAPI_PARAM_COPY_INIT(paramCopies[1],
268                                   userParams->pCbcSwizzleParams,
269                                   userParams->pCbcSwizzleParams,
270                                   1, cbcSwizzleParamsSize);
271 
272             paramsCnt++;
273 
274             break;
275         }
276 #endif
277         case NV2080_CTRL_CMD_CE_GET_CAPS:
278         {
279             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_CE_GET_CAPS_PARAMS);
280 
281             RMAPI_PARAM_COPY_INIT(paramCopies[0],
282                             ((NV2080_CTRL_CE_GET_CAPS_PARAMS*)pParams)->capsTbl,
283                             ((NV2080_CTRL_CE_GET_CAPS_PARAMS*)pParams)->capsTbl,
284                             ((NV2080_CTRL_CE_GET_CAPS_PARAMS*)pParams)->capsTblSize, 1);
285             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYIN;
286             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_ZERO_BUFFER;
287 
288             break;
289         }
290         case NV0080_CTRL_CMD_FIFO_GET_CHANNELLIST:
291         {
292             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0080_CTRL_FIFO_GET_CHANNELLIST_PARAMS);
293 
294             RMAPI_PARAM_COPY_INIT(paramCopies[0],
295                             ((NV0080_CTRL_FIFO_GET_CHANNELLIST_PARAMS*)pParams)->pChannelHandleList,
296                             ((NV0080_CTRL_FIFO_GET_CHANNELLIST_PARAMS*)pParams)->pChannelHandleList,
297                             ((NV0080_CTRL_FIFO_GET_CHANNELLIST_PARAMS*)pParams)->numChannels, sizeof(NvU32));
298             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYOUT;
299 
300             RMAPI_PARAM_COPY_INIT(paramCopies[1],
301                             ((NV0080_CTRL_FIFO_GET_CHANNELLIST_PARAMS*)pParams)->pChannelList,
302                             ((NV0080_CTRL_FIFO_GET_CHANNELLIST_PARAMS*)pParams)->pChannelList,
303                             ((NV0080_CTRL_FIFO_GET_CHANNELLIST_PARAMS*)pParams)->numChannels, sizeof(NvU32));
304             paramsCnt++;
305 
306             break;
307         }
308         case NV0000_CTRL_CMD_SYSTEM_EXECUTE_ACPI_METHOD:
309         {
310             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0000_CTRL_SYSTEM_EXECUTE_ACPI_METHOD_PARAMS);
311 
312             RMAPI_PARAM_COPY_INIT(paramCopies[0],
313                             ((NV0000_CTRL_SYSTEM_EXECUTE_ACPI_METHOD_PARAMS*)pParams)->inData,
314                             ((NV0000_CTRL_SYSTEM_EXECUTE_ACPI_METHOD_PARAMS*)pParams)->inData,
315                             ((NV0000_CTRL_SYSTEM_EXECUTE_ACPI_METHOD_PARAMS*)pParams)->inDataSize, 1);
316             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYOUT;
317 
318             RMAPI_PARAM_COPY_INIT(paramCopies[1],
319                             ((NV0000_CTRL_SYSTEM_EXECUTE_ACPI_METHOD_PARAMS*)pParams)->outData,
320                             ((NV0000_CTRL_SYSTEM_EXECUTE_ACPI_METHOD_PARAMS*)pParams)->outData,
321                             ((NV0000_CTRL_SYSTEM_EXECUTE_ACPI_METHOD_PARAMS*)pParams)->outDataSize, 1);
322             paramCopies[1].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYIN;
323             paramCopies[1].flags |= RMAPI_PARAM_COPY_FLAGS_ZERO_BUFFER;
324 
325             paramsCnt++;
326 
327             break;
328         }
329         case NV0073_CTRL_CMD_SYSTEM_EXECUTE_ACPI_METHOD:
330         {
331             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0073_CTRL_SYSTEM_EXECUTE_ACPI_METHOD_PARAMS);
332 
333             RMAPI_PARAM_COPY_INIT(paramCopies[0],
334                             ((NV0073_CTRL_SYSTEM_EXECUTE_ACPI_METHOD_PARAMS*)pParams)->inData,
335                             ((NV0073_CTRL_SYSTEM_EXECUTE_ACPI_METHOD_PARAMS*)pParams)->inData,
336                             ((NV0073_CTRL_SYSTEM_EXECUTE_ACPI_METHOD_PARAMS*)pParams)->inDataSize, 1);
337             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYOUT;
338 
339             RMAPI_PARAM_COPY_INIT(paramCopies[1],
340                             ((NV0073_CTRL_SYSTEM_EXECUTE_ACPI_METHOD_PARAMS*)pParams)->outData,
341                             ((NV0073_CTRL_SYSTEM_EXECUTE_ACPI_METHOD_PARAMS*)pParams)->outData,
342                             ((NV0073_CTRL_SYSTEM_EXECUTE_ACPI_METHOD_PARAMS*)pParams)->outDataSize, 1);
343             paramCopies[1].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYIN;
344             paramCopies[1].flags |= RMAPI_PARAM_COPY_FLAGS_ZERO_BUFFER;
345 
346             paramsCnt++;
347 
348             break;
349         }
350         case NV0080_CTRL_CMD_HOST_GET_CAPS:
351         {
352             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0080_CTRL_HOST_GET_CAPS_PARAMS);
353 
354             RMAPI_PARAM_COPY_INIT(paramCopies[0],
355                             ((NV0080_CTRL_HOST_GET_CAPS_PARAMS*)pParams)->capsTbl,
356                             ((NV0080_CTRL_HOST_GET_CAPS_PARAMS*)pParams)->capsTbl,
357                             ((NV0080_CTRL_HOST_GET_CAPS_PARAMS*)pParams)->capsTblSize, 1);
358             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYIN;
359             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_ZERO_BUFFER;
360 
361             break;
362         }
363         case NV2080_CTRL_CMD_BIOS_GET_INFO:
364         {
365             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_BIOS_GET_INFO_PARAMS);
366 
367             RMAPI_PARAM_COPY_INIT(paramCopies[0],
368                             ((NV2080_CTRL_BIOS_GET_INFO_PARAMS*)pParams)->biosInfoList,
369                             ((NV2080_CTRL_BIOS_GET_INFO_PARAMS*)pParams)->biosInfoList,
370                             ((NV2080_CTRL_BIOS_GET_INFO_PARAMS*)pParams)->biosInfoListSize,
371                             sizeof(NV2080_CTRL_BIOS_INFO));
372             break;
373         }
374         case NV2080_CTRL_CMD_BIOS_GET_NBSI:
375         {
376             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_BIOS_GET_NBSI_PARAMS);
377 
378             RMAPI_PARAM_COPY_INIT(paramCopies[0],
379                             ((NV2080_CTRL_BIOS_GET_NBSI_PARAMS*)pParams)->retBuf,
380                             ((NV2080_CTRL_BIOS_GET_NBSI_PARAMS*)pParams)->retBuf,
381                             ((NV2080_CTRL_BIOS_GET_NBSI_PARAMS*)pParams)->retSize, 1);
382             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYIN;
383             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_ZERO_BUFFER;
384 
385             break;
386         }
387         case NV2080_CTRL_CMD_BIOS_GET_NBSI_OBJ:
388         {
389             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_BIOS_GET_NBSI_OBJ_PARAMS);
390 
391             RMAPI_PARAM_COPY_INIT(paramCopies[0],
392                             ((NV2080_CTRL_BIOS_GET_NBSI_OBJ_PARAMS*)pParams)->retBuf,
393                             ((NV2080_CTRL_BIOS_GET_NBSI_OBJ_PARAMS*)pParams)->retBuf,
394                             ((NV2080_CTRL_BIOS_GET_NBSI_OBJ_PARAMS*)pParams)->retSize, 1);
395             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYIN;
396             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_ZERO_BUFFER;
397 
398             break;
399         }
400         case NV0080_CTRL_CMD_GR_GET_INFO:
401         {
402             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0080_CTRL_GR_GET_INFO_PARAMS);
403 
404             RMAPI_PARAM_COPY_INIT(paramCopies[0],
405                             ((NV0080_CTRL_GR_GET_INFO_PARAMS*)pParams)->grInfoList,
406                             ((NV0080_CTRL_GR_GET_INFO_PARAMS*)pParams)->grInfoList,
407                             ((NV0080_CTRL_GR_GET_INFO_PARAMS*)pParams)->grInfoListSize,
408                             sizeof(NV0080_CTRL_GR_INFO));
409             break;
410         }
411         case NV0080_CTRL_CMD_FIFO_START_SELECTED_CHANNELS:
412         {
413             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0080_CTRL_FIFO_START_SELECTED_CHANNELS_PARAMS);
414 
415             RMAPI_PARAM_COPY_INIT(paramCopies[0],
416                             ((NV0080_CTRL_FIFO_START_SELECTED_CHANNELS_PARAMS*)pParams)->fifoStartChannelList,
417                             ((NV0080_CTRL_FIFO_START_SELECTED_CHANNELS_PARAMS*)pParams)->fifoStartChannelList,
418                             ((NV0080_CTRL_FIFO_START_SELECTED_CHANNELS_PARAMS*)pParams)->fifoStartChannelListCount,
419                             sizeof(NV0080_CTRL_FIFO_CHANNEL));
420             break;
421         }
422         case NV0080_CTRL_CMD_FIFO_GET_CAPS:
423         {
424             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0080_CTRL_FIFO_GET_CAPS_PARAMS);
425 
426             RMAPI_PARAM_COPY_INIT(paramCopies[0],
427                             ((NV0080_CTRL_FIFO_GET_CAPS_PARAMS*)pParams)->capsTbl,
428                             ((NV0080_CTRL_FIFO_GET_CAPS_PARAMS*)pParams)->capsTbl,
429                             ((NV0080_CTRL_FIFO_GET_CAPS_PARAMS*)pParams)->capsTblSize, 1);
430             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYIN;
431             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_ZERO_BUFFER;
432 
433             break;
434         }
435         case NVA0BC_CTRL_CMD_NVENC_SW_SESSION_UPDATE_INFO:
436         {
437             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NVA0BC_CTRL_NVENC_SW_SESSION_UPDATE_INFO_PARAMS);
438 
439             RMAPI_PARAM_COPY_INIT(paramCopies[0],
440                             ((NVA0BC_CTRL_NVENC_SW_SESSION_UPDATE_INFO_PARAMS*)pParams)->timestampBuffer,
441                             ((NVA0BC_CTRL_NVENC_SW_SESSION_UPDATE_INFO_PARAMS*)pParams)->timestampBuffer,
442                             ((NVA0BC_CTRL_NVENC_SW_SESSION_UPDATE_INFO_PARAMS*)pParams)->timestampBufferSize,
443                             sizeof(NVA0BC_CTRL_NVENC_TIMESTAMP));
444             break;
445         }
446         case NV83DE_CTRL_CMD_DEBUG_READ_MEMORY:
447         {
448             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV83DE_CTRL_DEBUG_READ_MEMORY_PARAMS);
449 
450             RMAPI_PARAM_COPY_INIT(paramCopies[0],
451                             ((NV83DE_CTRL_DEBUG_READ_MEMORY_PARAMS*)pParams)->buffer,
452                             ((NV83DE_CTRL_DEBUG_READ_MEMORY_PARAMS*)pParams)->buffer,
453                             ((NV83DE_CTRL_DEBUG_READ_MEMORY_PARAMS*)pParams)->length, 1);
454             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYIN;
455             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_ZERO_BUFFER;
456             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_DISABLE_MAX_SIZE_CHECK;
457             break;
458         }
459         case NV83DE_CTRL_CMD_DEBUG_WRITE_MEMORY:
460         {
461             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV83DE_CTRL_DEBUG_WRITE_MEMORY_PARAMS);
462 
463             RMAPI_PARAM_COPY_INIT(paramCopies[0],
464                             ((NV83DE_CTRL_DEBUG_WRITE_MEMORY_PARAMS*)pParams)->buffer,
465                             ((NV83DE_CTRL_DEBUG_WRITE_MEMORY_PARAMS*)pParams)->buffer,
466                             ((NV83DE_CTRL_DEBUG_WRITE_MEMORY_PARAMS*)pParams)->length, 1);
467             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYOUT;
468             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_DISABLE_MAX_SIZE_CHECK;
469             break;
470         }
471         case NV83DE_CTRL_CMD_DEBUG_READ_BATCH_MEMORY:
472         {
473             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV83DE_CTRL_DEBUG_ACCESS_MEMORY_PARAMS);
474 
475             RMAPI_PARAM_COPY_INIT(paramCopies[0],
476                             ((NV83DE_CTRL_DEBUG_ACCESS_MEMORY_PARAMS*)pParams)->pData,
477                             ((NV83DE_CTRL_DEBUG_ACCESS_MEMORY_PARAMS*)pParams)->pData,
478                             ((NV83DE_CTRL_DEBUG_ACCESS_MEMORY_PARAMS*)pParams)->dataLength, 1);
479             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYIN;
480             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_ZERO_BUFFER;
481             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_DISABLE_MAX_SIZE_CHECK;
482             break;
483         }
484         case NV83DE_CTRL_CMD_DEBUG_WRITE_BATCH_MEMORY:
485         {
486             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV83DE_CTRL_DEBUG_ACCESS_MEMORY_PARAMS);
487 
488             RMAPI_PARAM_COPY_INIT(paramCopies[0],
489                             ((NV83DE_CTRL_DEBUG_ACCESS_MEMORY_PARAMS*)pParams)->pData,
490                             ((NV83DE_CTRL_DEBUG_ACCESS_MEMORY_PARAMS*)pParams)->pData,
491                             ((NV83DE_CTRL_DEBUG_ACCESS_MEMORY_PARAMS*)pParams)->dataLength, 1);
492             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYOUT;
493             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_DISABLE_MAX_SIZE_CHECK;
494             break;
495         }
496         case NV402C_CTRL_CMD_I2C_INDEXED:
497         {
498             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV402C_CTRL_I2C_INDEXED_PARAMS);
499 
500             RMAPI_PARAM_COPY_INIT(paramCopies[0],
501                             ((NV402C_CTRL_I2C_INDEXED_PARAMS*)pParams)->pMessage,
502                             ((NV402C_CTRL_I2C_INDEXED_PARAMS*)pParams)->pMessage,
503                             ((NV402C_CTRL_I2C_INDEXED_PARAMS*)pParams)->messageLength, 1);
504             break;
505         }
506         case NV402C_CTRL_CMD_I2C_TRANSACTION:
507         {
508             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV402C_CTRL_I2C_TRANSACTION_PARAMS);
509 
510             if (!_i2cTransactionCopyIn(paramCopies, pRmCtrlParams))
511             {
512                 return status;
513             }
514 
515             break;
516         }
517         case NV2080_CTRL_CMD_GPU_EXEC_REG_OPS:
518         {
519             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_GPU_EXEC_REG_OPS_PARAMS);
520 
521             RMAPI_PARAM_COPY_INIT(paramCopies[0],
522                             ((NV2080_CTRL_GPU_EXEC_REG_OPS_PARAMS*)pParams)->regOps,
523                             ((NV2080_CTRL_GPU_EXEC_REG_OPS_PARAMS*)pParams)->regOps,
524                             ((NV2080_CTRL_GPU_EXEC_REG_OPS_PARAMS*)pParams)->regOpCount,
525                             sizeof(NV2080_CTRL_GPU_REG_OP));
526             break;
527         }
528         case NV2080_CTRL_CMD_NVD_GET_DUMP:
529         {
530             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_NVD_GET_DUMP_PARAMS);
531 
532             RMAPI_PARAM_COPY_INIT(paramCopies[0],
533                             ((NV2080_CTRL_NVD_GET_DUMP_PARAMS*)pParams)->pBuffer,
534                             ((NV2080_CTRL_NVD_GET_DUMP_PARAMS*)pParams)->pBuffer,
535                             ((NV2080_CTRL_NVD_GET_DUMP_PARAMS*)pParams)->size, 1);
536             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYIN;
537             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_ZERO_BUFFER;
538 
539             break;
540         }
541         case NV0000_CTRL_CMD_NVD_GET_DUMP:
542         {
543             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0000_CTRL_NVD_GET_DUMP_PARAMS);
544 
545             RMAPI_PARAM_COPY_INIT(paramCopies[0],
546                             ((NV0000_CTRL_NVD_GET_DUMP_PARAMS*)pParams)->pBuffer,
547                             ((NV0000_CTRL_NVD_GET_DUMP_PARAMS*)pParams)->pBuffer,
548                             ((NV0000_CTRL_NVD_GET_DUMP_PARAMS*)pParams)->size, 1);
549             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYIN;
550             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_ZERO_BUFFER;
551 
552             break;
553         }
554         case NV0041_CTRL_CMD_GET_SURFACE_INFO:
555         {
556             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0041_CTRL_GET_SURFACE_INFO_PARAMS);
557 
558             RMAPI_PARAM_COPY_INIT(paramCopies[0],
559                             ((NV0041_CTRL_GET_SURFACE_INFO_PARAMS*)pParams)->surfaceInfoList,
560                             ((NV0041_CTRL_GET_SURFACE_INFO_PARAMS*)pParams)->surfaceInfoList,
561                             ((NV0041_CTRL_GET_SURFACE_INFO_PARAMS*)pParams)->surfaceInfoListSize,
562                             sizeof(NV0041_CTRL_SURFACE_INFO));
563             break;
564         }
565 #ifdef NV0000_CTRL_CMD_OS_GET_CAPS
566 // Not defined on all platforms
567         case NV0000_CTRL_CMD_OS_GET_CAPS:
568         {
569             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0000_CTRL_OS_GET_CAPS_PARAMS);
570 
571             RMAPI_PARAM_COPY_INIT(paramCopies[0],
572                             ((NV0000_CTRL_OS_GET_CAPS_PARAMS*)pParams)->capsTbl,
573                             ((NV0000_CTRL_OS_GET_CAPS_PARAMS*)pParams)->capsTbl,
574                             ((NV0000_CTRL_OS_GET_CAPS_PARAMS*)pParams)->capsTblSize, 1);
575             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYIN;
576             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_ZERO_BUFFER;
577 
578             break;
579         }
580 #endif
581         case NV0000_CTRL_CMD_SYSTEM_GET_P2P_CAPS:
582         {
583             NvU32 numEntries = 0;
584 
585             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0000_CTRL_SYSTEM_GET_P2P_CAPS_PARAMS);
586 
587             if (NvP64_VALUE(((NV0000_CTRL_SYSTEM_GET_P2P_CAPS_PARAMS*)pParams)->busPeerIds) != NULL)
588             {
589                 // The handler will check gpuCount * gpuCount against overflow
590                 numEntries = ((NV0000_CTRL_SYSTEM_GET_P2P_CAPS_PARAMS*)pParams)->gpuCount *
591                              ((NV0000_CTRL_SYSTEM_GET_P2P_CAPS_PARAMS*)pParams)->gpuCount;
592             }
593 
594             RMAPI_PARAM_COPY_INIT(paramCopies[0],
595                             ((NV0000_CTRL_SYSTEM_GET_P2P_CAPS_PARAMS*)pParams)->busPeerIds,
596                             ((NV0000_CTRL_SYSTEM_GET_P2P_CAPS_PARAMS*)pParams)->busPeerIds,
597                             numEntries, sizeof(NvU32));
598             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYIN;
599             numEntries = 0;
600 
601             if (NvP64_VALUE(((NV0000_CTRL_SYSTEM_GET_P2P_CAPS_PARAMS*)pParams)->busEgmPeerIds) != NULL)
602             {
603                 // The handler will check gpuCount * gpuCount against overflow
604                 numEntries = ((NV0000_CTRL_SYSTEM_GET_P2P_CAPS_PARAMS*)pParams)->gpuCount *
605                              ((NV0000_CTRL_SYSTEM_GET_P2P_CAPS_PARAMS*)pParams)->gpuCount;
606             }
607 
608             RMAPI_PARAM_COPY_INIT(paramCopies[1],
609                                   ((NV0000_CTRL_SYSTEM_GET_P2P_CAPS_PARAMS*)pParams)->busEgmPeerIds,
610                                   ((NV0000_CTRL_SYSTEM_GET_P2P_CAPS_PARAMS*)pParams)->busEgmPeerIds,
611                                   numEntries, sizeof(NvU32));
612             paramCopies[1].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYIN;
613             paramsCnt++;
614             break;
615         }
616         case NV0080_CTRL_CMD_FB_GET_CAPS:
617         {
618             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0080_CTRL_FB_GET_CAPS_PARAMS);
619 
620             RMAPI_PARAM_COPY_INIT(paramCopies[0],
621                             ((NV0080_CTRL_FB_GET_CAPS_PARAMS*)pParams)->capsTbl,
622                             ((NV0080_CTRL_FB_GET_CAPS_PARAMS*)pParams)->capsTbl,
623                             ((NV0080_CTRL_FB_GET_CAPS_PARAMS*)pParams)->capsTblSize, 1);
624             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYIN;
625             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_ZERO_BUFFER;
626 
627             break;
628         }
629         case NV0080_CTRL_CMD_GPU_GET_CLASSLIST:
630         {
631             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0080_CTRL_GPU_GET_CLASSLIST_PARAMS);
632 
633             RMAPI_PARAM_COPY_INIT(paramCopies[0],
634                             ((NV0080_CTRL_GPU_GET_CLASSLIST_PARAMS*)pParams)->classList,
635                             ((NV0080_CTRL_GPU_GET_CLASSLIST_PARAMS*)pParams)->classList,
636                             ((NV0080_CTRL_GPU_GET_CLASSLIST_PARAMS*)pParams)->numClasses, sizeof(NvU32));
637             break;
638         }
639         case NV2080_CTRL_CMD_GPU_GET_ENGINE_CLASSLIST:
640         {
641             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_GPU_GET_ENGINE_CLASSLIST_PARAMS);
642 
643             RMAPI_PARAM_COPY_INIT(paramCopies[0],
644                             ((NV2080_CTRL_GPU_GET_ENGINE_CLASSLIST_PARAMS*)pParams)->classList,
645                             ((NV2080_CTRL_GPU_GET_ENGINE_CLASSLIST_PARAMS*)pParams)->classList,
646                             ((NV2080_CTRL_GPU_GET_ENGINE_CLASSLIST_PARAMS*)pParams)->numClasses, sizeof(NvU32));
647             break;
648         }
649         case NV0080_CTRL_CMD_GR_GET_CAPS:
650         {
651             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0080_CTRL_GR_GET_CAPS_PARAMS);
652 
653             RMAPI_PARAM_COPY_INIT(paramCopies[0],
654                             ((NV0080_CTRL_GR_GET_CAPS_PARAMS*)pParams)->capsTbl,
655                             ((NV0080_CTRL_GR_GET_CAPS_PARAMS*)pParams)->capsTbl,
656                             ((NV0080_CTRL_GR_GET_CAPS_PARAMS*)pParams)->capsTblSize, 1);
657             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYIN;
658             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_ZERO_BUFFER;
659 
660             break;
661         }
662         case NV2080_CTRL_CMD_I2C_ACCESS:
663         {
664             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_I2C_ACCESS_PARAMS);
665 
666             RMAPI_PARAM_COPY_INIT(paramCopies[0],
667                             ((NV2080_CTRL_I2C_ACCESS_PARAMS*)pParams)->data,
668                             ((NV2080_CTRL_I2C_ACCESS_PARAMS*)pParams)->data,
669                             ((NV2080_CTRL_I2C_ACCESS_PARAMS*)pParams)->dataBuffSize, 1);
670             break;
671         }
672         case NV2080_CTRL_CMD_GR_GET_INFO:
673         {
674             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_GR_GET_INFO_PARAMS);
675 
676             RMAPI_PARAM_COPY_INIT(paramCopies[0],
677                             ((NV2080_CTRL_GR_GET_INFO_PARAMS*)pParams)->grInfoList,
678                             ((NV2080_CTRL_GR_GET_INFO_PARAMS*)pParams)->grInfoList,
679                             ((NV2080_CTRL_GR_GET_INFO_PARAMS*)pParams)->grInfoListSize,
680                             sizeof(NV2080_CTRL_GR_INFO));
681             break;
682         }
683         case NVB06F_CTRL_CMD_MIGRATE_ENGINE_CTX_DATA:
684         {
685             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NVB06F_CTRL_MIGRATE_ENGINE_CTX_DATA_PARAMS);
686 
687             RMAPI_PARAM_COPY_INIT(paramCopies[0],
688                             ((NVB06F_CTRL_MIGRATE_ENGINE_CTX_DATA_PARAMS*)pParams)->pEngineCtxBuff,
689                             ((NVB06F_CTRL_MIGRATE_ENGINE_CTX_DATA_PARAMS*)pParams)->pEngineCtxBuff,
690                             ((NVB06F_CTRL_MIGRATE_ENGINE_CTX_DATA_PARAMS*)pParams)->size, 1);
691             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_DISABLE_MAX_SIZE_CHECK;
692 
693             break;
694         }
695         case NVB06F_CTRL_CMD_GET_ENGINE_CTX_DATA:
696         {
697             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NVB06F_CTRL_GET_ENGINE_CTX_DATA_PARAMS);
698 
699             RMAPI_PARAM_COPY_INIT(paramCopies[0],
700                             ((NVB06F_CTRL_GET_ENGINE_CTX_DATA_PARAMS*)pParams)->pEngineCtxBuff,
701                             ((NVB06F_CTRL_GET_ENGINE_CTX_DATA_PARAMS*)pParams)->pEngineCtxBuff,
702                             ((NVB06F_CTRL_GET_ENGINE_CTX_DATA_PARAMS*)pParams)->size, 1);
703             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYIN;
704             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_DISABLE_MAX_SIZE_CHECK;
705 
706             break;
707         }
708         case NV2080_CTRL_CMD_RC_READ_VIRTUAL_MEM:
709         {
710             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_RC_READ_VIRTUAL_MEM_PARAMS);
711 
712             RMAPI_PARAM_COPY_INIT(paramCopies[0],
713                             ((NV2080_CTRL_RC_READ_VIRTUAL_MEM_PARAMS*)pParams)->bufferPtr,
714                             ((NV2080_CTRL_RC_READ_VIRTUAL_MEM_PARAMS*)pParams)->bufferPtr,
715                             ((NV2080_CTRL_RC_READ_VIRTUAL_MEM_PARAMS*)pParams)->bufferSize, 1);
716             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYIN;
717             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_ZERO_BUFFER;
718 
719             break;
720         }
721         case NV0080_CTRL_CMD_DMA_UPDATE_PDE_2:
722         {
723             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0080_CTRL_DMA_UPDATE_PDE_2_PARAMS);
724 
725             RMAPI_PARAM_COPY_INIT(paramCopies[0],
726                             ((NV0080_CTRL_DMA_UPDATE_PDE_2_PARAMS*)pParams)->pPdeBuffer,
727                             ((NV0080_CTRL_DMA_UPDATE_PDE_2_PARAMS*)pParams)->pPdeBuffer,
728                             1, 0x10/*NV_MMU_VER2_DUAL_PDE__SIZE*/);
729 
730             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYIN;
731             paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_ZERO_BUFFER;
732 
733             break;
734         }
735 
736         default:
737         {
738             return status;
739         }
740     }
741 
742     for (i = 0; i < paramsCnt; i++)
743     {
744         status = rmapiParamsAcquire(&paramCopies[i],
745                                     (pRmCtrlParams->secInfo.paramLocation != PARAM_LOCATION_KERNEL));
746         if (status != NV_OK)
747             break;
748     }
749 
750     // Preserve the original pRmCtrlParams->secInfo.paramLocation value since:
751     // - paramLocation should not be used beyond this point except
752     // - in embeddedParamCopyOut to skip copy-out in case when all parameters were in kernel space
753 
754     // If a single rmapiParamsAcquire() fails release all previous paramCopies
755     if (status != NV_OK)
756     {
757         for (j = 0; j <= i; j++)
758         {
759             paramCopies[j].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYOUT;
760             rmapiParamsRelease(&paramCopies[j]);
761         }
762     }
763 
764     return status;
765 }
766 
embeddedParamCopyOut(RMAPI_PARAM_COPY * paramCopies,RmCtrlParams * pRmCtrlParams)767 NV_STATUS embeddedParamCopyOut(RMAPI_PARAM_COPY *paramCopies, RmCtrlParams *pRmCtrlParams)
768 {
769     NV_STATUS status = NV_OK;
770     void* pParams = pRmCtrlParams->pParams;
771 
772     if ((pRmCtrlParams->secInfo.paramLocation == PARAM_LOCATION_KERNEL) ||
773         (pRmCtrlParams->flags & NVOS54_FLAGS_FINN_SERIALIZED))
774     {
775         return NV_OK;
776     }
777 
778     switch (pRmCtrlParams->cmd)
779     {
780         case NV2080_CTRL_GPU_GET_NVENC_SW_SESSION_INFO:
781         {
782             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_GPU_GET_NVENC_SW_SESSION_INFO_PARAMS);
783 
784             status = rmapiParamsRelease(&paramCopies[0]);
785             ((NV2080_CTRL_GPU_GET_NVENC_SW_SESSION_INFO_PARAMS*)pParams)->sessionInfoTbl = paramCopies[0].pUserParams;
786             break;
787         }
788         case NV2080_CTRL_CMD_GPU_GET_ENGINES:
789         {
790             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_GPU_GET_ENGINES_PARAMS);
791 
792             status = rmapiParamsRelease(&paramCopies[0]);
793             ((NV2080_CTRL_GPU_GET_ENGINES_PARAMS*)pParams)->engineList = paramCopies[0].pUserParams;
794             break;
795         }
796 #ifdef USE_AMAPLIB
797         case NV2080_CTRL_CMD_FB_GET_AMAP_CONF:
798         {
799             NV_STATUS status2;
800 
801             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_CMD_FB_GET_AMAP_CONF_PARAMS);
802 
803             NV2080_CTRL_CMD_FB_GET_AMAP_CONF_PARAMS *pParamsUser =
804                 (NV2080_CTRL_CMD_FB_GET_AMAP_CONF_PARAMS *) pParams;
805 
806             status = rmapiParamsRelease(&paramCopies[0]);
807             status2 = rmapiParamsRelease(&paramCopies[1]);
808             pParamsUser->pAmapConfParams = paramCopies[0].pUserParams;
809             pParamsUser->pCbcSwizzleParams = paramCopies[1].pUserParams;
810 
811             status = (status == NV_OK) ? status2 : status;
812 
813             break;
814         }
815 #endif
816         case NV2080_CTRL_CMD_CE_GET_CAPS:
817         {
818             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_CE_GET_CAPS_PARAMS);
819 
820             status = rmapiParamsRelease(&paramCopies[0]);
821             ((NV2080_CTRL_CE_GET_CAPS_PARAMS*)pParams)->capsTbl = paramCopies[0].pUserParams;
822             break;
823         }
824         case NV0080_CTRL_CMD_FIFO_GET_CHANNELLIST:
825         {
826             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0080_CTRL_FIFO_GET_CHANNELLIST_PARAMS);
827 
828             NV_STATUS handleListParamStatus = rmapiParamsRelease(&paramCopies[0]);
829             ((NV0080_CTRL_FIFO_GET_CHANNELLIST_PARAMS*)pParams)->pChannelHandleList = paramCopies[0].pUserParams;
830 
831             status = rmapiParamsRelease(&paramCopies[1]);
832             ((NV0080_CTRL_FIFO_GET_CHANNELLIST_PARAMS*)pParams)->pChannelList = paramCopies[1].pUserParams;
833 
834             if (handleListParamStatus != NV_OK)
835                 status = handleListParamStatus;
836 
837             break;
838         }
839         case NV0000_CTRL_CMD_SYSTEM_EXECUTE_ACPI_METHOD:
840         {
841             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0000_CTRL_SYSTEM_EXECUTE_ACPI_METHOD_PARAMS);
842 
843             NV_STATUS inParamsStatus = rmapiParamsRelease(&paramCopies[0]);
844             ((NV0000_CTRL_SYSTEM_EXECUTE_ACPI_METHOD_PARAMS*)pParams)->inData = paramCopies[0].pUserParams;
845 
846             status = rmapiParamsRelease(&paramCopies[1]);
847             ((NV0000_CTRL_SYSTEM_EXECUTE_ACPI_METHOD_PARAMS*)pParams)->outData = paramCopies[1].pUserParams;
848 
849             if (inParamsStatus != NV_OK)
850                 status = inParamsStatus;
851             break;
852         }
853         case NV0073_CTRL_CMD_SYSTEM_EXECUTE_ACPI_METHOD:
854         {
855             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0073_CTRL_SYSTEM_EXECUTE_ACPI_METHOD_PARAMS);
856 
857             NV_STATUS inParamsStatus = rmapiParamsRelease(&paramCopies[0]);
858             ((NV0073_CTRL_SYSTEM_EXECUTE_ACPI_METHOD_PARAMS*)pParams)->inData = paramCopies[0].pUserParams;
859 
860             status = rmapiParamsRelease(&paramCopies[1]);
861             ((NV0073_CTRL_SYSTEM_EXECUTE_ACPI_METHOD_PARAMS*)pParams)->outData = paramCopies[1].pUserParams;
862 
863             if (inParamsStatus != NV_OK)
864                 status = inParamsStatus;
865             break;
866         }
867         case NV83DE_CTRL_CMD_DEBUG_READ_MEMORY:
868         {
869             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV83DE_CTRL_DEBUG_READ_MEMORY_PARAMS);
870 
871             status = rmapiParamsRelease(&paramCopies[0]);
872             ((NV83DE_CTRL_DEBUG_READ_MEMORY_PARAMS*)pRmCtrlParams->pParams)->buffer = paramCopies[0].pUserParams;
873             break;
874         }
875         case NV83DE_CTRL_CMD_DEBUG_WRITE_MEMORY:
876         {
877             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV83DE_CTRL_DEBUG_WRITE_MEMORY_PARAMS);
878 
879             status = rmapiParamsRelease(&paramCopies[0]);
880             ((NV83DE_CTRL_DEBUG_WRITE_MEMORY_PARAMS*)pRmCtrlParams->pParams)->buffer = paramCopies[0].pUserParams;
881             break;
882         }
883         case NV83DE_CTRL_CMD_DEBUG_READ_BATCH_MEMORY:
884         {
885             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV83DE_CTRL_DEBUG_ACCESS_MEMORY_PARAMS);
886 
887             status = rmapiParamsRelease(&paramCopies[0]);
888             ((NV83DE_CTRL_DEBUG_ACCESS_MEMORY_PARAMS*)pRmCtrlParams->pParams)->pData = paramCopies[0].pUserParams;
889             break;
890         }
891         case NV83DE_CTRL_CMD_DEBUG_WRITE_BATCH_MEMORY:
892         {
893             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV83DE_CTRL_DEBUG_ACCESS_MEMORY_PARAMS);
894 
895             status = rmapiParamsRelease(&paramCopies[0]);
896             ((NV83DE_CTRL_DEBUG_ACCESS_MEMORY_PARAMS*)pRmCtrlParams->pParams)->pData = paramCopies[0].pUserParams;
897             break;
898         }
899         case NV0080_CTRL_CMD_HOST_GET_CAPS:
900         {
901             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0080_CTRL_HOST_GET_CAPS_PARAMS);
902 
903             status = rmapiParamsRelease(&paramCopies[0]);
904             ((NV0080_CTRL_HOST_GET_CAPS_PARAMS*)pParams)->capsTbl = paramCopies[0].pUserParams;
905             break;
906         }
907         case NV2080_CTRL_CMD_BIOS_GET_INFO:
908         {
909             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_BIOS_GET_INFO_PARAMS);
910 
911             status = rmapiParamsRelease(&paramCopies[0]);
912             ((NV2080_CTRL_BIOS_GET_INFO_PARAMS*)pParams)->biosInfoList = paramCopies[0].pUserParams;
913             break;
914         }
915         case NV2080_CTRL_CMD_BIOS_GET_NBSI:
916         {
917             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_BIOS_GET_NBSI_PARAMS);
918 
919             status = rmapiParamsRelease(&paramCopies[0]);
920             ((NV2080_CTRL_BIOS_GET_NBSI_PARAMS*)pParams)->retBuf = paramCopies[0].pUserParams;
921             break;
922         }
923         case NV2080_CTRL_CMD_BIOS_GET_NBSI_OBJ:
924         {
925             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_BIOS_GET_NBSI_OBJ_PARAMS);
926 
927             if (((NV2080_CTRL_BIOS_GET_NBSI_OBJ_PARAMS*)pParams)->retSize == 0)
928             {
929                 paramCopies[0].flags |= RMAPI_PARAM_COPY_FLAGS_SKIP_COPYOUT;
930             }
931 
932             status = rmapiParamsRelease(&paramCopies[0]);
933             ((NV2080_CTRL_BIOS_GET_NBSI_OBJ_PARAMS*)pParams)->retBuf = paramCopies[0].pUserParams;
934             break;
935         }
936         case NV0080_CTRL_CMD_GR_GET_INFO:
937         {
938             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0080_CTRL_GR_GET_INFO_PARAMS);
939 
940             status = rmapiParamsRelease(&paramCopies[0]);
941             ((NV0080_CTRL_GR_GET_INFO_PARAMS*)pParams)->grInfoList = paramCopies[0].pUserParams;
942             break;
943         }
944         case NV0080_CTRL_CMD_FIFO_START_SELECTED_CHANNELS:
945         {
946             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0080_CTRL_FIFO_START_SELECTED_CHANNELS_PARAMS);
947 
948             status = rmapiParamsRelease(&paramCopies[0]);
949             ((NV0080_CTRL_FIFO_START_SELECTED_CHANNELS_PARAMS*)pParams)->fifoStartChannelList = paramCopies[0].pUserParams;
950             break;
951         }
952         case NV0080_CTRL_CMD_FIFO_GET_CAPS:
953         {
954             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0080_CTRL_FIFO_GET_CAPS_PARAMS);
955 
956             status = rmapiParamsRelease(&paramCopies[0]);
957             ((NV0080_CTRL_FIFO_GET_CAPS_PARAMS*)pParams)->capsTbl = paramCopies[0].pUserParams;
958             break;
959         }
960         case NVA0BC_CTRL_CMD_NVENC_SW_SESSION_UPDATE_INFO:
961         {
962             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NVA0BC_CTRL_NVENC_SW_SESSION_UPDATE_INFO_PARAMS);
963 
964             status = rmapiParamsRelease(&paramCopies[0]);
965             ((NVA0BC_CTRL_NVENC_SW_SESSION_UPDATE_INFO_PARAMS*)pParams)->timestampBuffer = paramCopies[0].pUserParams;
966             break;
967         }
968         case NV402C_CTRL_CMD_I2C_INDEXED:
969         {
970             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV402C_CTRL_I2C_INDEXED_PARAMS);
971 
972             status = rmapiParamsRelease(&paramCopies[0]);
973             ((NV402C_CTRL_I2C_INDEXED_PARAMS*)pParams)->pMessage = paramCopies[0].pUserParams;
974             break;
975         }
976         case NV402C_CTRL_CMD_I2C_TRANSACTION:
977         {
978             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV402C_CTRL_I2C_TRANSACTION_PARAMS);
979 
980             return i2cTransactionCopyOut(paramCopies, pRmCtrlParams);
981         }
982         case NV2080_CTRL_CMD_GPU_EXEC_REG_OPS:
983         {
984             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_GPU_EXEC_REG_OPS_PARAMS);
985 
986             status = rmapiParamsRelease(&paramCopies[0]);
987             ((NV2080_CTRL_GPU_EXEC_REG_OPS_PARAMS*)pParams)->regOps = paramCopies[0].pUserParams;
988             break;
989         }
990         case NV2080_CTRL_CMD_NVD_GET_DUMP:
991         {
992             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_NVD_GET_DUMP_PARAMS);
993 
994             status = rmapiParamsRelease(&paramCopies[0]);
995             ((NV2080_CTRL_NVD_GET_DUMP_PARAMS*)pParams)->pBuffer = paramCopies[0].pUserParams;
996             break;
997         }
998         case NV0000_CTRL_CMD_NVD_GET_DUMP:
999         {
1000             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0000_CTRL_NVD_GET_DUMP_PARAMS);
1001 
1002             status = rmapiParamsRelease(&paramCopies[0]);
1003             ((NV0000_CTRL_NVD_GET_DUMP_PARAMS*)pParams)->pBuffer = paramCopies[0].pUserParams;
1004             break;
1005         }
1006         case NV0041_CTRL_CMD_GET_SURFACE_INFO:
1007         {
1008             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0041_CTRL_GET_SURFACE_INFO_PARAMS);
1009 
1010             status = rmapiParamsRelease(&paramCopies[0]);
1011             ((NV0041_CTRL_GET_SURFACE_INFO_PARAMS*)pParams)->surfaceInfoList = paramCopies[0].pUserParams;
1012             break;
1013         }
1014 #ifdef NV0000_CTRL_CMD_OS_GET_CAPS
1015         // Not defined on all platforms
1016         case NV0000_CTRL_CMD_OS_GET_CAPS:
1017         {
1018             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0000_CTRL_OS_GET_CAPS_PARAMS);
1019 
1020             status = rmapiParamsRelease(&paramCopies[0]);
1021             ((NV0000_CTRL_OS_GET_CAPS_PARAMS*)pParams)->capsTbl = paramCopies[0].pUserParams;
1022             break;
1023         }
1024 #endif
1025         case NV0000_CTRL_CMD_SYSTEM_GET_P2P_CAPS:
1026         {
1027             NV_STATUS peerIdsStatus;
1028             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0000_CTRL_SYSTEM_GET_P2P_CAPS_PARAMS);
1029 
1030             peerIdsStatus = rmapiParamsRelease(&paramCopies[0]);
1031             ((NV0000_CTRL_SYSTEM_GET_P2P_CAPS_PARAMS*)pParams)->busPeerIds = paramCopies[0].pUserParams;
1032 
1033             status = rmapiParamsRelease(&paramCopies[1]);
1034             ((NV0000_CTRL_SYSTEM_GET_P2P_CAPS_PARAMS*)pParams)->busEgmPeerIds = paramCopies[1].pUserParams;
1035 
1036             if (peerIdsStatus != NV_OK)
1037                 status = peerIdsStatus;
1038 
1039             break;
1040         }
1041         case NV0080_CTRL_CMD_FB_GET_CAPS:
1042         {
1043             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0080_CTRL_FB_GET_CAPS_PARAMS);
1044 
1045             status = rmapiParamsRelease(&paramCopies[0]);
1046             ((NV0080_CTRL_FB_GET_CAPS_PARAMS*)pParams)->capsTbl = paramCopies[0].pUserParams;
1047             break;
1048         }
1049         case NV0080_CTRL_CMD_GPU_GET_CLASSLIST:
1050         {
1051             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0080_CTRL_GPU_GET_CLASSLIST_PARAMS);
1052 
1053             status = rmapiParamsRelease(&paramCopies[0]);
1054             ((NV0080_CTRL_GPU_GET_CLASSLIST_PARAMS*)pParams)->classList = paramCopies[0].pUserParams;
1055             break;
1056         }
1057         case NV2080_CTRL_CMD_GPU_GET_ENGINE_CLASSLIST:
1058         {
1059             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_GPU_GET_ENGINE_CLASSLIST_PARAMS);
1060 
1061             status = rmapiParamsRelease(&paramCopies[0]);
1062             ((NV2080_CTRL_GPU_GET_ENGINE_CLASSLIST_PARAMS*)pParams)->classList = paramCopies[0].pUserParams;
1063             break;
1064         }
1065         case NV0080_CTRL_CMD_GR_GET_CAPS:
1066         {
1067             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0080_CTRL_GR_GET_CAPS_PARAMS);
1068 
1069             status = rmapiParamsRelease(&paramCopies[0]);
1070             ((NV0080_CTRL_GR_GET_CAPS_PARAMS*)pParams)->capsTbl = paramCopies[0].pUserParams;
1071             break;
1072         }
1073         case NV2080_CTRL_CMD_I2C_ACCESS:
1074         {
1075             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_I2C_ACCESS_PARAMS);
1076 
1077             status = rmapiParamsRelease(&paramCopies[0]);
1078             ((NV2080_CTRL_I2C_ACCESS_PARAMS*)pParams)->data = paramCopies[0].pUserParams;
1079             break;
1080         }
1081         case NV2080_CTRL_CMD_GR_GET_INFO:
1082         {
1083             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_GR_GET_INFO_PARAMS);
1084 
1085             status = rmapiParamsRelease(&paramCopies[0]);
1086             ((NV2080_CTRL_GR_GET_INFO_PARAMS*)pParams)->grInfoList = paramCopies[0].pUserParams;
1087             break;
1088         }
1089         case NVB06F_CTRL_CMD_MIGRATE_ENGINE_CTX_DATA:
1090         {
1091             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NVB06F_CTRL_MIGRATE_ENGINE_CTX_DATA_PARAMS);
1092 
1093             status = rmapiParamsRelease(&paramCopies[0]);
1094             ((NVB06F_CTRL_MIGRATE_ENGINE_CTX_DATA_PARAMS*)pParams)->pEngineCtxBuff = paramCopies[0].pUserParams;
1095             break;
1096         }
1097         case NVB06F_CTRL_CMD_GET_ENGINE_CTX_DATA:
1098         {
1099             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NVB06F_CTRL_GET_ENGINE_CTX_DATA_PARAMS);
1100 
1101             status = rmapiParamsRelease(&paramCopies[0]);
1102             ((NVB06F_CTRL_GET_ENGINE_CTX_DATA_PARAMS*)pParams)->pEngineCtxBuff = paramCopies[0].pUserParams;
1103             break;
1104         }
1105         case NV2080_CTRL_CMD_RC_READ_VIRTUAL_MEM:
1106         {
1107             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_RC_READ_VIRTUAL_MEM_PARAMS);
1108 
1109             status = rmapiParamsRelease(&paramCopies[0]);
1110             ((NV2080_CTRL_RC_READ_VIRTUAL_MEM_PARAMS*)pRmCtrlParams->pParams)->bufferPtr = paramCopies[0].pUserParams;
1111             break;
1112         }
1113         case NV0080_CTRL_CMD_DMA_UPDATE_PDE_2:
1114         {
1115             CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0080_CTRL_DMA_UPDATE_PDE_2_PARAMS);
1116 
1117             status = rmapiParamsRelease(&paramCopies[0]);
1118             ((NV0080_CTRL_DMA_UPDATE_PDE_2_PARAMS*)pParams)->pPdeBuffer = paramCopies[0].pUserParams;
1119 
1120             break;
1121         }
1122 
1123         default:
1124         {
1125             return NV_OK;
1126         }
1127     }
1128 
1129     return status;
1130 }
1131