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