1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2021-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  *                                                                          *
26  *      Confidential Compute API Object Module                              *
27  *                                                                          *
28  \**************************************************************************/
29 
30 #include "core/locks.h"
31 #include "rmapi/rs_utils.h"
32 #include "core/system.h"
33 #include "gpu/gpu.h"
34 #include "gpu/mem_mgr/mem_mgr.h"
35 #include "gpu/mem_mgr/heap.h"
36 #include "kernel/gpu/mig_mgr/kernel_mig_manager.h"
37 #include "kernel/gpu/fifo/kernel_fifo.h"
38 #include "gpu/conf_compute/conf_compute_api.h"
39 #include "gpu/subdevice/subdevice.h"
40 #include "class/clcb33.h" // NV_CONFIDENTIAL_COMPUTE
41 
42 NV_STATUS
43 confComputeApiConstruct_IMPL
44 (
45     ConfidentialComputeApi       *pConfComputeApi,
46     CALL_CONTEXT                 *pCallContext,
47     RS_RES_ALLOC_PARAMS_INTERNAL *pParams
48 )
49 {
50     OBJSYS    *pSys = SYS_GET_INSTANCE();
51     OBJGPUMGR *pGpuMgr = SYS_GET_GPUMGR(pSys);
52 
53     pConfComputeApi->pCcCaps = &pGpuMgr->ccCaps;
54 
55     return NV_OK;
56 }
57 
58 void
59 confComputeApiDestruct_IMPL
60 (
61     ConfidentialComputeApi *pConfComputeApi
62 )
63 {
64 }
65 
66 NV_STATUS
67 confComputeApiCtrlCmdSystemGetCapabilities_IMPL
68 (
69     ConfidentialComputeApi                                  *pConfComputeApi,
70     NV_CONF_COMPUTE_CTRL_CMD_SYSTEM_GET_CAPABILITIES_PARAMS *pParams
71 )
72 {
73     OBJSYS    *pSys = SYS_GET_INSTANCE();
74     CONF_COMPUTE_CAPS *pCcCaps = pConfComputeApi->pCcCaps;
75 
76     LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmGpuLockIsOwner());
77 
78     pParams->cpuCapability = NV_CONF_COMPUTE_SYSTEM_CPU_CAPABILITY_NONE;
79     if ((sysGetStaticConfig(pSys))->bOsSevEnabled)
80     {
81         pParams->cpuCapability = NV_CONF_COMPUTE_SYSTEM_CPU_CAPABILITY_AMD_SEV;
82     }
83 
84     pParams->gpusCapability = NV_CONF_COMPUTE_SYSTEM_GPUS_CAPABILITY_NONE;
85     pParams->environment = NV_CONF_COMPUTE_SYSTEM_ENVIRONMENT_UNAVAILABLE;
86     pParams->ccFeature = NV_CONF_COMPUTE_SYSTEM_FEATURE_DISABLED;
87     pParams->devToolsMode = NV_CONF_COMPUTE_SYSTEM_DEVTOOLS_MODE_DISABLED;
88 
89     if (pCcCaps->bApmFeatureCapable)
90     {
91         pParams->gpusCapability = NV_CONF_COMPUTE_SYSTEM_GPUS_CAPABILITY_APM;
92     }
93     else if (pCcCaps->bHccFeatureCapable)
94     {
95         pParams->gpusCapability = NV_CONF_COMPUTE_SYSTEM_GPUS_CAPABILITY_HCC;
96     }
97 
98     if (pCcCaps->bCCFeatureEnabled)
99     {
100         if (pCcCaps->bApmFeatureCapable)
101         {
102             pParams->ccFeature = NV_CONF_COMPUTE_SYSTEM_FEATURE_APM_ENABLED;
103         }
104         else if (pCcCaps->bHccFeatureCapable)
105         {
106             pParams->ccFeature = NV_CONF_COMPUTE_SYSTEM_FEATURE_HCC_ENABLED;
107         }
108     }
109 
110     if (pCcCaps->bDevToolsModeEnabled)
111     {
112         pParams->devToolsMode = NV_CONF_COMPUTE_SYSTEM_DEVTOOLS_MODE_ENABLED;
113     }
114 
115     if (pParams->ccFeature != NV_CONF_COMPUTE_SYSTEM_FEATURE_DISABLED)
116     {
117         pParams->environment = NV_CONF_COMPUTE_SYSTEM_ENVIRONMENT_SIM;
118     }
119 
120     return NV_OK;
121 }
122 
123 NV_STATUS
124 confComputeApiCtrlCmdSystemGetGpusState_IMPL
125 (
126     ConfidentialComputeApi                                *pConfComputeApi,
127     NV_CONF_COMPUTE_CTRL_CMD_SYSTEM_GET_GPUS_STATE_PARAMS *pParams
128 )
129 {
130     LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmGpuLockIsOwner());
131 
132     pParams->bAcceptClientRequest = pConfComputeApi->pCcCaps->bAcceptClientRequest;
133 
134     return NV_OK;
135 }
136 
137 NV_STATUS
138 confComputeApiCtrlCmdSystemSetGpusState_IMPL
139 (
140     ConfidentialComputeApi                                *pConfComputeApi,
141     NV_CONF_COMPUTE_CTRL_CMD_SYSTEM_SET_GPUS_STATE_PARAMS *pParams
142 )
143 {
144     LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmGpuLockIsOwner());
145 
146     pConfComputeApi->pCcCaps->bAcceptClientRequest = pParams->bAcceptClientRequest;
147 
148     return NV_OK;
149 }
150 
151 NV_STATUS
152 confComputeApiCtrlCmdGpuGetVidmemSize_IMPL
153 (
154     ConfidentialComputeApi                              *pConfComputeApi,
155     NV_CONF_COMPUTE_CTRL_CMD_GPU_GET_VIDMEM_SIZE_PARAMS *pParams
156 )
157 {
158     Subdevice        *pSubdevice            = NULL;
159     OBJGPU           *pGpu                  = NULL;
160     Heap             *pHeap                 = NULL;
161     Heap             *pMemoryPartitionHeap  = NULL;
162     KernelMIGManager *pKernelMIGManager     = NULL;
163     NvU64             totalProtectedBytes   = 0;
164     NvU64             totalUnprotectedBytes = 0;
165 
166     LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmGpuLockIsOwner());
167 
168     NV_CHECK_OK_OR_RETURN(LEVEL_INFO,
169         subdeviceGetByHandle(RES_GET_CLIENT(pConfComputeApi),
170                              pParams->hSubDevice, &pSubdevice));
171 
172     pGpu = GPU_RES_GET_GPU(pSubdevice);
173     pHeap = GPU_GET_HEAP(pGpu);
174     pKernelMIGManager = GPU_GET_KERNEL_MIG_MANAGER(pGpu);
175 
176     //
177     // If MIG-GPU-Instancing is enabled, we check for GPU instance subscription
178     // and provide GPU instance local info
179     //
180     if (IS_MIG_IN_USE(pGpu))
181     {
182         NV_CHECK_OK_OR_RETURN(LEVEL_INFO,
183             kmigmgrGetMemoryPartitionHeapFromDevice(pGpu, pKernelMIGManager,
184                                                     GPU_RES_GET_DEVICE(pSubdevice),
185                                                     &pMemoryPartitionHeap));
186         //
187         // If client is associated with a GPU instance then point pHeap
188         // to client's memory partition heap
189         //
190         if (pMemoryPartitionHeap != NULL)
191              pHeap = pMemoryPartitionHeap;
192     }
193 
194     pmaGetTotalProtectedMemory(&pHeap->pmaObject, &totalProtectedBytes);
195     pmaGetTotalUnprotectedMemory(&pHeap->pmaObject, &totalUnprotectedBytes);
196 
197     pParams->protectedMemSizeInKb = totalProtectedBytes >> 10;
198     pParams->unprotectedMemSizeInKb = totalUnprotectedBytes >> 10;
199 
200     return NV_OK;
201 }
202 
203 NV_STATUS
204 confComputeApiCtrlCmdGpuSetVidmemSize_IMPL
205 (
206     ConfidentialComputeApi                              *pConfComputeApi,
207     NV_CONF_COMPUTE_CTRL_CMD_GPU_SET_VIDMEM_SIZE_PARAMS *pParams
208 )
209 {
210     LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmGpuLockIsOwner());
211 
212     return NV_OK;
213 }
214 
215 NV_STATUS
216 confComputeApiCtrlCmdGetGpuCertificate_IMPL
217 (
218     ConfidentialComputeApi                              *pConfComputeApi,
219     NV_CONF_COMPUTE_CTRL_CMD_GET_GPU_CERTIFICATE_PARAMS *pParams
220 )
221 {
222     Subdevice           *pSubdevice   = NULL;
223     OBJGPU              *pGpu         = NULL;
224     ConfidentialCompute *pConfCompute = NULL;
225 
226     LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmGpuLockIsOwner());
227 
228     NV_CHECK_OK_OR_RETURN(LEVEL_INFO,
229         subdeviceGetByHandle(RES_GET_CLIENT(pConfComputeApi),
230                              pParams->hSubDevice, &pSubdevice));
231     pGpu         = GPU_RES_GET_GPU(pSubdevice);
232     pConfCompute = GPU_GET_CONF_COMPUTE(pGpu);
233 
234     if (pConfCompute != NULL)
235     {
236         // Set max size of certificate buffers before calling SPDM.
237         pParams->certChainSize            = NV_CONF_COMPUTE_CERT_CHAIN_MAX_SIZE;
238         pParams->attestationCertChainSize = NV_CONF_COMPUTE_ATTESTATION_CERT_CHAIN_MAX_SIZE;
239 
240         return spdmGetCertChains_HAL(pGpu,
241                                  pConfCompute->pSpdm,
242                                  pParams->certChain,
243                                  &pParams->certChainSize,
244                                  pParams->attestationCertChain,
245                                  &pParams->attestationCertChainSize);
246     }
247 
248     return NV_ERR_OBJECT_NOT_FOUND;
249 }
250 
251 NV_STATUS
252 confComputeApiCtrlCmdGetGpuAttestationReport_IMPL
253 (
254     ConfidentialComputeApi                                     *pConfComputeApi,
255     NV_CONF_COMPUTE_CTRL_CMD_GET_GPU_ATTESTATION_REPORT_PARAMS *pParams
256 )
257 {
258     Subdevice           *pSubdevice   = NULL;
259     OBJGPU              *pGpu         = NULL;
260     ConfidentialCompute *pConfCompute = NULL;
261 
262     LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmGpuLockIsOwner());
263 
264     NV_CHECK_OK_OR_RETURN(LEVEL_INFO,
265         subdeviceGetByHandle(RES_GET_CLIENT(pConfComputeApi),
266                              pParams->hSubDevice, &pSubdevice));
267     pGpu         = GPU_RES_GET_GPU(pSubdevice);
268     pConfCompute = GPU_GET_CONF_COMPUTE(pGpu);
269 
270     if (pConfCompute != NULL)
271     {
272         // Set max size of report buffers before calling SPDM.
273         pParams->attestationReportSize    = NV_CONF_COMPUTE_GPU_ATTESTATION_REPORT_MAX_SIZE;
274         pParams->cecAttestationReportSize = NV_CONF_COMPUTE_GPU_CEC_ATTESTATION_REPORT_MAX_SIZE;
275 
276         return spdmGetAttestationReport(pGpu,
277                                         pConfCompute->pSpdm,
278                                         pParams->nonce,
279                                         pParams->attestationReport,
280                                         &pParams->attestationReportSize,
281                                         &pParams->isCecAttestationReportPresent,
282                                         pParams->cecAttestationReport,
283                                         &pParams->cecAttestationReportSize);
284     }
285 
286     return NV_ERR_OBJECT_NOT_FOUND;
287 }
288 
289 NV_STATUS
290 confComputeApiCtrlCmdGpuGetNumSecureChannels_IMPL
291 (
292     ConfidentialComputeApi                                     *pConfComputeApi,
293     NV_CONF_COMPUTE_CTRL_CMD_GPU_GET_NUM_SECURE_CHANNELS_PARAMS *pParams
294 )
295 {
296     Subdevice  *pSubdevice;
297     OBJGPU     *pGpu;
298     KernelFifo *pKernelFifo;
299 
300     LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmGpuLockIsOwner());
301 
302     NV_CHECK_OK_OR_RETURN(LEVEL_INFO,
303         subdeviceGetByHandle(RES_GET_CLIENT(pConfComputeApi),
304         pParams->hSubDevice, &pSubdevice));
305 
306     pGpu = GPU_RES_GET_GPU(pSubdevice);
307     pKernelFifo = GPU_GET_KERNEL_FIFO(pGpu);
308 
309     pParams->maxSec2Channels = pKernelFifo->maxSec2SecureChannels;
310     pParams->maxCeChannels = pKernelFifo->maxCeSecureChannels;
311 
312     return NV_OK;
313 }
314