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 #include "mem_mgr_internal.h"
25 #include "mem_mgr/os_desc_mem.h"
26 #include "rmapi/client.h"
27 #include "rmapi/mapping_list.h"
28 #include "gpu/mem_mgr/mem_desc.h"
29 #include "os/os.h"
30 #include "gpu/device/device.h"
31 #include "vgpu/rpc.h"
32 #include "mem_mgr/mem.h"
33 #include "gpu/mem_mgr/mem_mgr.h"
34 #include "deprecated/rmapi_deprecated.h"
35 
36 #include "class/cl0071.h" // NV01_MEMORY_SYSTEM_OS_DESCRIPTOR
37 
38 NV_STATUS
39 osdescConstruct_IMPL
40 (
41     OsDescMemory                 *pOsDescMemory,
42     CALL_CONTEXT                 *pCallContext,
43     RS_RES_ALLOC_PARAMS_INTERNAL *pRmAllocParams
44 )
45 {
46     Memory            *pMemory = staticCast(pOsDescMemory, Memory);
47     NV_OS_DESC_MEMORY_ALLOCATION_PARAMS *pUserParams;
48     OBJGPU            *pGpu = pMemory->pGpu;
49     MemoryManager     *pMemoryManager    = GPU_GET_MEMORY_MANAGER(pGpu);
50     MEMORY_DESCRIPTOR *pMemDesc = NULL;
51     NV_STATUS          status;
52     NvU64              limit;
53     NvU32              os02Flags;
54     NvHandle           hClient = pCallContext->pClient->hClient;
55     NvHandle           hParent = pCallContext->pResourceRef->pParentRef->hResource;
56     NvHandle           hMemory = pCallContext->pResourceRef->hResource;
57 
58     // Copy-construction has already been done by the base Memory class
59     if (RS_IS_COPY_CTOR(pRmAllocParams))
60         return NV_OK;
61 
62     pUserParams = pRmAllocParams->pAllocParams;
63 
64     limit = pUserParams->limit;
65 
66     //
67     // Bug 860684: osCreateMemFromOsDescriptor expects OS02 flags
68     // from the old NvRmAllocMemory64() interface so we need to
69     // translate the OS32_ATTR flags to OS02 flags.
70     //
71     status = RmDeprecatedConvertOs32ToOs02Flags(pUserParams->attr,
72                                                 pUserParams->attr2,
73                                                 pUserParams->flags,
74                                                 &os02Flags);
75 
76     if (status != NV_OK)
77     {
78         return status;
79     }
80 
81     // Only kernel user is allowed to register physical address with RM
82     if (pUserParams->descriptorType == NVOS32_DESCRIPTOR_TYPE_OS_PHYS_ADDR)
83     {
84         if (pCallContext->secInfo.privLevel < RS_PRIV_LEVEL_KERNEL)
85         {
86             return NV_ERR_NOT_SUPPORTED;
87         }
88     }
89 
90     if (pUserParams->descriptorType == NVOS32_DESCRIPTOR_TYPE_OS_IO_MEMORY)
91     {
92         //
93         // We currently allow RmMapMemory on external IO resources which are
94         // safe to share across processes. For example, NpuResource.
95         //
96         // Otherwise we would be affected by the security issues like Bug 1630288.
97         //
98         os02Flags = FLD_SET_DRF(OS02, _FLAGS, _MAPPING, _NEVER_MAP, os02Flags);
99 
100         //
101         // Force peerMappingOverride check for IO memory registration through
102         // RmVidHeapCtrl. See Bug 1630288 "[PeerSync] threat related to GPU.." for
103         // more details.
104         //
105         os02Flags = FLD_SET_DRF(OS02, _FLAGS, _PEER_MAP_OVERRIDE, _REQUIRED, os02Flags);
106     }
107 
108     //
109     // Create and fill in the memory descriptor based on the current
110     // state of the OS descriptor.
111     //
112     status = osCreateMemFromOsDescriptor(pGpu,
113                                          pUserParams->descriptor,
114                                          hClient,
115                                          os02Flags,
116                                          &limit,
117                                          &pMemDesc,
118                                          pUserParams->descriptorType,
119                                          pRmAllocParams->pSecInfo->privLevel);
120 
121     if (status != NV_OK)
122     {
123         return status;
124     }
125 
126     if (pMemoryManager->bAllowSysmemHugePages && pMemDesc->bForceHugePages)
127     {
128         pUserParams->attr = DRF_DEF(OS32, _ATTR, _PAGE_SIZE, _HUGE);
129         pUserParams->attr2 = DRF_DEF(OS32, _ATTR2, _PAGE_SIZE_HUGE, _DEFAULT);
130     }
131 
132     status = memConstructCommon(pMemory, NV01_MEMORY_SYSTEM_OS_DESCRIPTOR, pUserParams->flags,
133                                 pMemDesc, 0, NULL, pUserParams->attr, pUserParams->attr2, 0, 0,
134                                 pUserParams->tag, (HWRESOURCE_INFO *)NULL);
135 
136     if (status == NV_OK)
137     {
138         RsResourceRef *pResourceRef = RES_GET_REF(pMemory);
139         RsCpuMapping   *pCpuMapping = NULL;
140         NvU32 flags = 0;
141         flags = FLD_SET_DRF(OS33, _FLAGS, _OS_DESCRIPTOR, _ENABLE, flags);
142         RS_CPU_MAP_PARAMS dummyParams;
143         portMemSet(&dummyParams, 0, sizeof(dummyParams));
144 
145         NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
146             refAddMapping(pResourceRef, &dummyParams, pResourceRef->pParentRef, &pCpuMapping));
147 
148         NV_ASSERT_OK_OR_RETURN(CliUpdateMemoryMappingInfo(pCpuMapping,
149                                                           pCallContext->secInfo.privLevel >= RS_PRIV_LEVEL_KERNEL,
150                                                           pUserParams->descriptor, NvP64_NULL,
151                                                           limit+1, flags));
152         pCpuMapping->pPrivate->pGpu = pGpu;
153 
154         //
155         // vGPU:
156         //
157         // Since vGPU does all real hardware management in the
158         // host, if we are in guest OS (where IS_VIRTUAL(pGpu) is true),
159         // do an RPC to the host to do the hardware update.
160         //
161         if (IS_VIRTUAL(pGpu))
162         {
163             NV_RM_RPC_ALLOC_MEMORY(pGpu,
164                                    hClient,
165                                    hParent,
166                                    hMemory,
167                                    NV01_MEMORY_SYSTEM_OS_DESCRIPTOR,
168                                    os02Flags,
169                                    pMemDesc,
170                                    status);
171             if (status == NV_OK)
172                 pMemory->bRpcAlloc = NV_TRUE;
173 
174         }
175     }
176 
177     //
178     // RM support for MODS PTE kind in external allocations
179     // bug 1858656
180     //
181 
182     // failure case
183     if (status != NV_OK)
184     {
185         memdescFree(pMemDesc);
186         memdescDestroy(pMemDesc);
187     }
188 
189     return status;
190 }
191 
192 NvBool
193 osdescCanCopy_IMPL
194 (
195     OsDescMemory *pOsDescMemory
196 )
197 {
198     return RMCFG_FEATURE_PLATFORM_UNIX;
199 }
200