1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 1993-2020 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 #include "deprecated/rmapi_deprecated.h"
25 
26 
27 #include "class/cl003e.h" // NV01_MEMORY_SYSTEM
28 #include "class/cl0071.h" // NV01_MEMORY_SYSTEM_OS_DESCRIPTOR
29 #include "class/cl0070.h" // NV01_MEMORY_SYSTEM_DYNAMIC
30 #include "class/cl003f.h" // NV01_MEMORY_LOCAL_PRIVILEGED
31 #include "class/cl0040.h" // NV01_MEMORY_LOCAL_USER
32 #include "class/cl00c2.h" // NV01_MEMORY_LOCAL_PHYSICAL
33 #include "class/cl84a0.h" // NV01_MEMORY_LIST_XXX
34 #include "class/cl0076.h" // NV01_MEMORY_FRAMEBUFFER_CONSOLE
35 #include "class/cl00f3.h" // NV01_MEMORY_FLA
36 
37 #include "ctrl/ctrl2080/ctrl2080fb.h" // NV2080_CTRL_FB_INFO
38 
39 #include <stddef.h>
40 
41 typedef NV_STATUS RmAllocMemoryFunc(
42     DEPRECATED_CONTEXT *pContext,
43     NvHandle            hClient,
44     NvHandle            hParent,
45     NvHandle            hMemory,
46     NvU32               hClass,
47     NvU32               flags,
48     NvP64              *pAddress,
49     NvU64              *pLimit
50 );
51 
52 typedef struct {
53     NvU32                   hclass;         // hClass value
54     RmAllocMemoryFunc       *pFunc;         // pointer to handler
55 } RmAllocMemoryEntry;
56 
57 static NV_STATUS _rmAllocMemorySystem(DEPRECATED_CONTEXT *, NvHandle, NvHandle, NvHandle, NvU32,
58                                    NvU32, NvP64 *, NvU64 *);
59 static NV_STATUS _rmAllocMemorySystemDynamic(DEPRECATED_CONTEXT *, NvHandle, NvHandle, NvHandle, NvU32,
60                                           NvU32, NvP64 *, NvU64 *);
61 static NV_STATUS _rmAllocMemorySystemOsDescriptor(DEPRECATED_CONTEXT *, NvHandle, NvHandle, NvHandle, NvU32,
62                                                NvU32, NvP64 *, NvU64 *);
63 static NV_STATUS _rmAllocMemoryLocalUser(DEPRECATED_CONTEXT *, NvHandle, NvHandle, NvHandle, NvU32,
64                                       NvU32, NvP64 *, NvU64 *);
65 static NV_STATUS _rmAllocMemoryLocalPrivileged(DEPRECATED_CONTEXT *, NvHandle, NvHandle, NvHandle, NvU32,
66                                             NvU32, NvP64 *, NvU64 *);
67 static NV_STATUS _rmAllocMemoryList(DEPRECATED_CONTEXT *, NvHandle, NvHandle, NvHandle, NvU32,
68                                  NvU32, NvP64 *, NvU64 *);
69 static NV_STATUS _rmAllocMemoryFramebufferConsole(DEPRECATED_CONTEXT *, NvHandle, NvHandle,
70                                                   NvHandle, NvU32, NvU32,
71                                                   NvP64 *, NvU64 *);
72 
73 static NV_STATUS _rmAllocMemoryFromFlaObject(DEPRECATED_CONTEXT *, NvHandle, NvHandle,
74                                              NvHandle, NvU32, NvU32,
75                                              NvP64 *, NvU64 *);
76 
77 static const RmAllocMemoryEntry rmAllocMemoryTable[] =
78 {
79     { NV01_MEMORY_SYSTEM,                   _rmAllocMemorySystem },
80     { NV01_MEMORY_SYSTEM_DYNAMIC,           _rmAllocMemorySystemDynamic },
81     { NV01_MEMORY_SYSTEM_OS_DESCRIPTOR,     _rmAllocMemorySystemOsDescriptor },
82     { NV01_MEMORY_LOCAL_USER,               _rmAllocMemoryLocalUser },
83     { NV01_MEMORY_LOCAL_PRIVILEGED,         _rmAllocMemoryLocalPrivileged },
84     { NV01_MEMORY_LIST_SYSTEM,              _rmAllocMemoryList },
85     { NV01_MEMORY_LIST_FBMEM,               _rmAllocMemoryList },
86     { NV01_MEMORY_LIST_OBJECT,              _rmAllocMemoryList },
87     { NV01_MEMORY_FRAMEBUFFER_CONSOLE,      _rmAllocMemoryFramebufferConsole },
88     { NV01_MEMORY_FLA,                      _rmAllocMemoryFromFlaObject },
89 };
90 
91 static NvU32 rmAllocMemoryTableSize = sizeof(rmAllocMemoryTable) / sizeof(rmAllocMemoryTable[0]);
92 
93 void
RmDeprecatedAllocMemory(DEPRECATED_CONTEXT * pContext,NVOS02_PARAMETERS * pArgs)94 RmDeprecatedAllocMemory
95 (
96     DEPRECATED_CONTEXT *pContext,
97     NVOS02_PARAMETERS  *pArgs
98 )
99 {
100     NV_STATUS status = NV_OK;
101     NvU32     i;
102 
103     // traverse through the table to match the hClass
104     for (i = 0; i < rmAllocMemoryTableSize; i++)
105     {
106         if (pArgs->hClass == rmAllocMemoryTable[i].hclass)
107         {
108             break;
109         }
110     }
111 
112     // check that we have a valid handler
113     if (i == rmAllocMemoryTableSize)
114     {
115         status = NV_ERR_INVALID_CLASS;
116         goto done;
117     }
118 
119     // call the function in rmAllocMemoryTable corresponding to hClass
120     status = rmAllocMemoryTable[i].pFunc(pContext,
121                                          pArgs->hRoot,
122                                          pArgs->hObjectParent,
123                                          pArgs->hObjectNew,
124                                          pArgs->hClass,
125                                          pArgs->flags,
126                                          &pArgs->pMemory,
127                                          &pArgs->limit);
128 
129 done:
130     pArgs->status = status;
131 }
132 
133 static NV_STATUS
_rmAllocMemorySystem(DEPRECATED_CONTEXT * pContext,NvHandle hClient,NvHandle hParent,NvHandle hMemory,NvU32 hClass,NvU32 flags,NvP64 * pAddress,NvU64 * pLimit)134 _rmAllocMemorySystem
135 (
136     DEPRECATED_CONTEXT *pContext,
137     NvHandle            hClient,
138     NvHandle            hParent,
139     NvHandle            hMemory,
140     NvU32               hClass,
141     NvU32               flags,
142     NvP64              *pAddress,
143     NvU64              *pLimit
144 )
145 {
146     NV_STATUS                   status;
147     NV_MEMORY_ALLOCATION_PARAMS allocParams = {0};
148 
149     if (DRF_VAL(OS02, _FLAGS, _LOCATION, flags) != NVOS02_FLAGS_LOCATION_PCI ||
150         DRF_VAL(OS02, _FLAGS, _ALLOC, flags) == NVOS02_FLAGS_ALLOC_NONE)
151     {
152         return NV_ERR_INVALID_FLAGS;
153     }
154 
155     allocParams.owner = 0x7368696D; // 'shim'
156     allocParams.size = *pLimit + 1;
157 
158     if (FLD_TEST_DRF(OS02, _FLAGS, _KERNEL_MAPPING, _MAP, flags))
159         allocParams.type = NVOS32_TYPE_NOTIFIER;
160     else
161         allocParams.type = NVOS32_TYPE_IMAGE;
162 
163     if (RmDeprecatedConvertOs02ToOs32Flags(flags, &allocParams.attr, &allocParams.attr2, &allocParams.flags))
164     {
165         return NV_ERR_INVALID_FLAGS;
166     }
167 
168     *pAddress = NvP64_NULL;
169 
170     status = pContext->RmAlloc(pContext, hClient, hParent, &hMemory, hClass, &allocParams, sizeof(allocParams));
171 
172     if (status != NV_OK)
173         return status;
174 
175     // RmAllocMemory creates mappings by default
176     if (FLD_TEST_DRF(OS02, _FLAGS, _MAPPING, _DEFAULT, flags))
177     {
178         status = pContext->RmMapMemory(pContext, hClient, hParent, hMemory, 0, *pLimit + 1,
179                                        pAddress, NV04_MAP_MEMORY_FLAGS_NONE);
180 
181         if (status != NV_OK)
182         {
183             pContext->RmFree(pContext, hClient, hMemory);
184         }
185     }
186 
187     return status;
188 }
189 
190 static NV_STATUS
_rmAllocMemorySystemDynamic(DEPRECATED_CONTEXT * pContext,NvHandle hClient,NvHandle hParent,NvHandle hMemory,NvU32 hClass,NvU32 flags,NvP64 * pAddress,NvU64 * pLimit)191 _rmAllocMemorySystemDynamic
192 (
193     DEPRECATED_CONTEXT *pContext,
194     NvHandle            hClient,
195     NvHandle            hParent,
196     NvHandle            hMemory,
197     NvU32               hClass,
198     NvU32               flags,
199     NvP64              *pAddress,
200     NvU64              *pLimit
201 )
202 {
203     NV_MEMORY_VIRTUAL_ALLOCATION_PARAMS allocParams = {0};
204     NV_STATUS                           status;
205 
206     //
207     // NvRmAllocMemory(NV01_MEMORY_SYSTEM_DYNAMIC) is used to allocate a hMemory
208     // under NV01_DEVICE_0.
209     //
210     // NvRmAlloc exposes the Device version with class
211     // NV01_MEMORY_SYSTEM_DYNAMIC.
212     //
213 
214     // This class does not allow DMA mappings.  Use an illegal hVASpace handle.
215     allocParams.hVASpace = NV_MEMORY_VIRTUAL_SYSMEM_DYNAMIC_HVASPACE;
216 
217     // Try with NV01_MEMORY_SYSTEM_DYNAMIC for NV01_DEVICE_0 parents
218     status = pContext->RmAlloc(pContext, hClient, hParent, &hMemory,
219                                NV01_MEMORY_SYSTEM_DYNAMIC, &allocParams, sizeof(allocParams));
220 
221     *pLimit = allocParams.limit;
222 
223     return status;
224 }
225 
226 static NV_STATUS
_rmAllocMemorySystemOsDescriptor(DEPRECATED_CONTEXT * pContext,NvHandle hClient,NvHandle hParent,NvHandle hMemory,NvU32 hClass,NvU32 flags,NvP64 * pAddress,NvU64 * pLimit)227 _rmAllocMemorySystemOsDescriptor
228 (
229     DEPRECATED_CONTEXT *pContext,
230     NvHandle            hClient,
231     NvHandle            hParent,
232     NvHandle            hMemory,
233     NvU32               hClass,
234     NvU32               flags,
235     NvP64              *pAddress,
236     NvU64              *pLimit
237 )
238 {
239     NV_STATUS status;
240     NV_OS_DESC_MEMORY_ALLOCATION_PARAMS allocParams = {0};
241 
242     // Don't support anything but PCI memory at the moment.
243     // Don't support default mappings, since they make no sense.
244     if (DRF_VAL(OS02, _FLAGS, _LOCATION, flags) != NVOS02_FLAGS_LOCATION_PCI ||
245         DRF_VAL(OS02, _FLAGS, _MAPPING,  flags) != NVOS02_FLAGS_MAPPING_NO_MAP)
246     {
247         return NV_ERR_INVALID_FLAGS;
248     }
249 
250     allocParams.type = NVOS32_TYPE_IMAGE;
251     allocParams.descriptor = *pAddress;
252     allocParams.descriptorType = NVOS32_DESCRIPTOR_TYPE_VIRTUAL_ADDRESS;
253     allocParams.limit = *pLimit;
254 
255     if (RmDeprecatedConvertOs02ToOs32Flags(flags, &allocParams.attr, &allocParams.attr2, &allocParams.flags))
256     {
257         return NV_ERR_INVALID_FLAGS;
258     }
259 
260     status = pContext->RmAlloc(pContext, hClient, hParent, &hMemory, hClass, &allocParams, sizeof(allocParams));
261 
262     return status;
263 }
264 
_rmAllocGetHeapSize(DEPRECATED_CONTEXT * pContext,NvHandle hClient,NvHandle hDevice,NvU64 * pHeapSize)265 static NV_STATUS _rmAllocGetHeapSize
266 (
267     DEPRECATED_CONTEXT *pContext,
268     NvHandle            hClient,
269     NvHandle            hDevice,
270     NvU64              *pHeapSize
271 )
272 {
273     NV2080_CTRL_FB_GET_INFO_V2_PARAMS  fbInfoParams = {0};
274     NV_STATUS                       status;
275     NvHandle                        hSubDevice;
276     NvBool                          bMustFreeSubDevice;
277 
278     status = RmDeprecatedFindOrCreateSubDeviceHandle(pContext, hClient, hDevice,
279                                                      &hSubDevice, &bMustFreeSubDevice);
280 
281     if (status != NV_OK)
282         return status;
283 
284     fbInfoParams.fbInfoListSize = 1;
285     fbInfoParams.fbInfoList[0].index = NV2080_CTRL_FB_INFO_INDEX_TOTAL_RAM_SIZE;
286 
287     status = pContext->RmControl(pContext, hClient, hSubDevice,
288                                  NV2080_CTRL_CMD_FB_GET_INFO_V2,
289                                  &fbInfoParams,
290                                  sizeof(fbInfoParams));
291 
292     *pHeapSize = ((NvU64)fbInfoParams.fbInfoList[0].data << 10);
293 
294     if (bMustFreeSubDevice)
295     {
296         pContext->RmFree(pContext, hClient, hSubDevice);
297     }
298 
299     return status;
300 }
301 
302 static NV_STATUS
_rmAllocMemoryLocalUser(DEPRECATED_CONTEXT * pContext,NvHandle hClient,NvHandle hParent,NvHandle hMemory,NvU32 hClass,NvU32 flags,NvP64 * pAddress,NvU64 * pLimit)303 _rmAllocMemoryLocalUser
304 (
305     DEPRECATED_CONTEXT *pContext,
306     NvHandle            hClient,
307     NvHandle            hParent,
308     NvHandle            hMemory,
309     NvU32               hClass,
310     NvU32               flags,
311     NvP64              *pAddress,
312     NvU64              *pLimit
313 )
314 {
315     NV_STATUS                            status;
316     NV_PHYSICAL_MEMORY_ALLOCATION_PARAMS allocParams = {0};
317 
318     //
319     // This was a poorly designed API. Non-root clients used it to query the
320     // heap size where we shouldn't have a hMemory and root clients used it to
321     // read/write offsets within video memory.
322     //
323 
324     // First attempt: try to allocate NV01_MEMORY_LOCAL_PHYSICAL
325     status = pContext->RmAlloc(pContext, hClient, hParent, &hMemory, NV01_MEMORY_LOCAL_PHYSICAL, &allocParams, sizeof(allocParams));
326 
327     if (status == NV_OK)
328     {
329         *pLimit = allocParams.memSize - 1;
330         return status;
331     }
332     else if (status == NV_ERR_INSUFFICIENT_PERMISSIONS)
333     {
334         //
335         // Second attempt: If client doesn't have permission (non-root) to view
336         // entire FB, query heap size with RmControls and allocate a dummy
337         // hMemory. We use NV01_MEMORY_SYSTEM_DYNAMIC because that API results
338         // in no underlying heap allocation.
339         //
340 
341         NvU64                               memSize;
342         NV_MEMORY_VIRTUAL_ALLOCATION_PARAMS virtAllocParams = {0};
343 
344         virtAllocParams.hVASpace = NV_MEMORY_VIRTUAL_SYSMEM_DYNAMIC_HVASPACE;
345 
346         status = _rmAllocGetHeapSize(pContext, hClient, hParent, &memSize);
347 
348         if (status != NV_OK)
349             return status;
350 
351         *pLimit = memSize - 1;
352 
353         //
354         // Alloc dummy memory handle to keep client happy (non-root
355         // user-mode clients previously received hMemory of entire FB)
356         //
357         status = pContext->RmAlloc(pContext, hClient, hParent, &hMemory,
358                                    NV01_MEMORY_SYSTEM_DYNAMIC, &virtAllocParams, sizeof(virtAllocParams));
359     }
360 
361     return status;
362 }
363 
364 static NV_STATUS
_rmAllocMemoryLocalPrivileged(DEPRECATED_CONTEXT * pContext,NvHandle hClient,NvHandle hParent,NvHandle hMemory,NvU32 hClass,NvU32 flags,NvP64 * pAddress,NvU64 * pLimit)365 _rmAllocMemoryLocalPrivileged
366 (
367     DEPRECATED_CONTEXT *pContext,
368     NvHandle            hClient,
369     NvHandle            hParent,
370     NvHandle            hMemory,
371     NvU32               hClass,
372     NvU32               flags,
373     NvP64              *pAddress,
374     NvU64              *pLimit
375 )
376 {
377     if (DRF_VAL(OS02, _FLAGS, _ALLOC, flags) != NVOS02_FLAGS_ALLOC_NONE)
378         return NV_ERR_INVALID_FLAGS;
379 
380     *pLimit = 0xFFFFFFFF; // not used by clients
381 
382     return pContext->RmAlloc(pContext, hClient, hParent, &hMemory, hClass, NULL, 0);
383 }
384 
385 static NV_STATUS
_rmAllocMemoryList(DEPRECATED_CONTEXT * pContext,NvHandle hClient,NvHandle hParent,NvHandle hMemory,NvU32 hClass,NvU32 flags,NvP64 * pAddress,NvU64 * pLimit)386 _rmAllocMemoryList
387 (
388     DEPRECATED_CONTEXT *pContext,
389     NvHandle            hClient,
390     NvHandle            hParent,
391     NvHandle            hMemory,
392     NvU32               hClass,
393     NvU32               flags,
394     NvP64              *pAddress,
395     NvU64              *pLimit
396 )
397 {
398     NV_MEMORY_LIST_ALLOCATION_PARAMS  allocParams = {0};
399     Nv01MemoryList                   *pMemoryList = 0;
400     void                             *pPageArray = 0;
401     NvP64                             pageArrayBase = NvP64_NULL;
402     NvU32                             pageArraySize = 0;
403     NV_STATUS                         status;
404 
405     status = pContext->CopyUser(pContext, RMAPI_DEPRECATED_COPYIN, RMAPI_DEPRECATED_BUFFER_ALLOCATE,
406                                 *pAddress, sizeof(Nv01MemoryList), (void**)&pMemoryList);
407     if (status != NV_OK)
408         goto done;
409 
410     pageArrayBase = NvP64_PLUS_OFFSET(*pAddress, NV_OFFSETOF(Nv01MemoryList, pageNumber));
411 
412     // Prevent integer overflow when calculating pageArraySize
413     if (pMemoryList->pageCount > NV_U32_MAX / sizeof(NvU64))
414     {
415         status = NV_ERR_INVALID_ARGUMENT;
416         goto done;
417     }
418 
419     pageArraySize = sizeof(NvU64) * pMemoryList->pageCount;
420 
421     status = pContext->CopyUser(pContext, RMAPI_DEPRECATED_COPYIN, RMAPI_DEPRECATED_BUFFER_ALLOCATE,
422                                 pageArrayBase, pageArraySize, &pPageArray);
423     if (status != NV_OK)
424         goto done;
425 
426     allocParams.pageNumberList = NV_PTR_TO_NvP64(pPageArray);
427     allocParams.limit = *pLimit;
428     allocParams.flagsOs02 = flags;
429 
430 #define COPY_FIELD(field) allocParams.field = pMemoryList->field
431     COPY_FIELD(hClient);
432     COPY_FIELD(hParent);
433     COPY_FIELD(hObject);
434     COPY_FIELD(hHwResClient);
435     COPY_FIELD(hHwResDevice);
436     COPY_FIELD(hHwResHandle);
437     COPY_FIELD(pteAdjust);
438     COPY_FIELD(type);
439     COPY_FIELD(flags);
440     COPY_FIELD(attr);
441     COPY_FIELD(attr2);
442     COPY_FIELD(height);
443     COPY_FIELD(width);
444     COPY_FIELD(format);
445     COPY_FIELD(comprcovg);
446     COPY_FIELD(zcullcovg);
447     COPY_FIELD(pageCount);
448     COPY_FIELD(heapOwner);
449     COPY_FIELD(guestId);
450     COPY_FIELD(rangeBegin);
451     COPY_FIELD(rangeEnd);
452     COPY_FIELD(pitch);
453     COPY_FIELD(ctagOffset);
454     COPY_FIELD(size);
455     COPY_FIELD(align);
456 
457     status = pContext->RmAlloc(pContext, hClient, hParent, &hMemory, hClass, &allocParams, sizeof(allocParams));
458 
459 done:
460     if (pPageArray)
461     {
462         pContext->CopyUser(pContext, RMAPI_DEPRECATED_COPYRELEASE, RMAPI_DEPRECATED_BUFFER_ALLOCATE,
463                            pageArrayBase, pageArraySize, &pPageArray);
464     }
465 
466     if (pMemoryList)
467     {
468         pContext->CopyUser(pContext, RMAPI_DEPRECATED_COPYRELEASE, RMAPI_DEPRECATED_BUFFER_ALLOCATE,
469                            *pAddress, sizeof(Nv01MemoryList), (void**)&pMemoryList);
470     }
471 
472     return status;
473 }
474 
475 static NV_STATUS
_rmAllocMemoryFromFlaObject(DEPRECATED_CONTEXT * pContext,NvHandle hClient,NvHandle hParent,NvHandle hMemory,NvU32 hClass,NvU32 flags,NvP64 * pAddress,NvU64 * pLimit)476 _rmAllocMemoryFromFlaObject
477 (
478     DEPRECATED_CONTEXT *pContext,
479     NvHandle            hClient,
480     NvHandle            hParent,
481     NvHandle            hMemory,
482     NvU32               hClass,
483     NvU32               flags,
484     NvP64              *pAddress,
485     NvU64              *pLimit
486 )
487 {
488     NV_FLA_MEMORY_ALLOCATION_PARAMS  allocParams = {0};
489     NV_FLA_MEMORY_ALLOCATION_PARAMS *pMemoryFla = 0;
490     NV_STATUS                        status;
491 
492     status = pContext->CopyUser(pContext,
493                                RMAPI_DEPRECATED_COPYIN,
494                                RMAPI_DEPRECATED_BUFFER_ALLOCATE,
495                                *pAddress, sizeof(NV_FLA_MEMORY_ALLOCATION_PARAMS),
496                                (void**)&pMemoryFla);
497     if (status != NV_OK)
498         goto done;
499 
500     allocParams.limit = *pLimit;
501     allocParams.flagsOs02 = flags;
502 
503 #define COPY_FLA_FIELD(field) allocParams.field = pMemoryFla->field
504     COPY_FLA_FIELD(type);
505     COPY_FLA_FIELD(flags);
506     COPY_FLA_FIELD(attr);
507     COPY_FLA_FIELD(attr2);
508     COPY_FLA_FIELD(base);
509     COPY_FLA_FIELD(align);
510     COPY_FLA_FIELD(hExportSubdevice);
511     COPY_FLA_FIELD(hExportHandle);
512     COPY_FLA_FIELD(hExportClient);
513 
514     status = pContext->RmAlloc(pContext, hClient, hParent, &hMemory, hClass, &allocParams, sizeof(allocParams));
515 
516 done:
517     if (pMemoryFla)
518     {
519         pContext->CopyUser(pContext,
520                            RMAPI_DEPRECATED_COPYRELEASE,
521                            RMAPI_DEPRECATED_BUFFER_ALLOCATE,
522                            *pAddress, sizeof(NV_FLA_MEMORY_ALLOCATION_PARAMS),
523                            (void**)&pMemoryFla);
524     }
525 
526     return status;
527 }
528 
529 static NV_STATUS
_rmAllocMemoryFramebufferConsole(DEPRECATED_CONTEXT * pContext,NvHandle hClient,NvHandle hParent,NvHandle hMemory,NvU32 hClass,NvU32 flags,NvP64 * pAddress,NvU64 * pLimit)530 _rmAllocMemoryFramebufferConsole
531 (
532     DEPRECATED_CONTEXT *pContext,
533     NvHandle            hClient,
534     NvHandle            hParent,
535     NvHandle            hMemory,
536     NvU32               hClass,
537     NvU32               flags,
538     NvP64              *pAddress,
539     NvU64              *pLimit
540 )
541 {
542     return pContext->RmAlloc(pContext, hClient, hParent, &hMemory, hClass, NULL, 0);
543 }
544