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 Object Module                                  *
27  *                                                                          *
28  \**************************************************************************/
29 
30 #define NVOC_CONF_COMPUTE_H_PRIVATE_ACCESS_ALLOWED
31 
32 #include "nvrm_registry.h"
33 #include "gpu/conf_compute/conf_compute.h"
34 #include "gpu/conf_compute/conf_compute_keystore.h"
35 #include "spdm/rmspdmvendordef.h"
36 #include "gsp/gsp_proxy_reg.h"
37 #include "gpu_mgr/gpu_mgr.h"
38 #include "gpu/gpu.h"
39 #include "ctrl/ctrl2080/ctrl2080internal.h"
40 #include "ctrl/ctrl2080/ctrl2080spdm.h"
41 #include "kernel/gpu/conf_compute/ccsl.h"
42 
43 /*!
44  * Local object related functions
45  */
46 static void _confComputeInitRegistryOverrides(OBJGPU *, ConfidentialCompute*);
47 
48 
49 NV_STATUS
50 confComputeConstructEngine_IMPL(OBJGPU                  *pGpu,
51                                 ConfidentialCompute     *pConfCompute,
52                                 ENGDESCRIPTOR           engDesc)
53 {
54     OBJSYS *pSys = SYS_GET_INSTANCE();
55     NvU32 data = 0;
56     NvBool bForceEnableCC = 0;
57     pConfCompute->pSpdm = NULL;
58     portMemSet(&pConfCompute->ccStaticInfo, 0, sizeof(pConfCompute->ccStaticInfo));
59     pConfCompute->gspProxyRegkeys = 0;
60 
61     pConfCompute->pRpcCcslCtx                = NULL;
62     pConfCompute->pDmaCcslCtx                = NULL;
63     pConfCompute->pReplayableFaultCcslCtx    = NULL;
64     pConfCompute->pNonReplayableFaultCcslCtx = NULL;
65 
66     if (gpuIsCCEnabledInHw_HAL(pGpu))
67     {
68         pConfCompute->setProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_ENABLED, NV_TRUE);
69     }
70 
71     if (gpuIsDevModeEnabledInHw_HAL(pGpu))
72     {
73         pConfCompute->setProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_DEVTOOLS_MODE_ENABLED, NV_TRUE);
74     }
75 
76     _confComputeInitRegistryOverrides(pGpu, pConfCompute);
77 
78     if (pConfCompute->getProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_ENABLED))
79     {
80         bForceEnableCC = (osReadRegistryDword(pGpu, NV_REG_STR_RM_CONFIDENTIAL_COMPUTE, &data) == NV_OK) &&
81          FLD_TEST_DRF(_REG_STR, _RM_CONFIDENTIAL_COMPUTE, _ENABLED, _YES, data);
82 
83         if (!RMCFG_FEATURE_PLATFORM_GSP && !RMCFG_FEATURE_PLATFORM_MODS && !bForceEnableCC)
84         {
85             if (!(sysGetStaticConfig(pSys)->bOsCCEnabled))
86             {
87                 NV_PRINTF(LEVEL_ERROR, "CPU does not support confidential compute.\n");
88                 NV_ASSERT(0);
89                 pConfCompute->setProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_ENABLED, NV_FALSE);
90                 return NV_ERR_INVALID_OPERATION;
91             }
92         }
93 
94         NV_CHECK_OR_RETURN(LEVEL_ERROR, confComputeIsGpuCcCapable_HAL(pGpu, pConfCompute), NV_ERR_INVALID_OPERATION);
95 
96         if (pGpu->getProperty(pGpu, PDB_PROP_GPU_APM_FEATURE_CAPABLE))
97         {
98             pConfCompute->setProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_APM_FEATURE_ENABLED, NV_TRUE);
99 
100             // Forcing DEV_MODE to False for APM
101             NV_PRINTF(LEVEL_INFO, "Confidential Compute devtools mode DISABLED in APM.\n");
102             pConfCompute->setProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_DEVTOOLS_MODE_ENABLED, NV_FALSE);
103             pConfCompute->gspProxyRegkeys |= DRF_DEF(GSP, _PROXY_REG, _CONF_COMPUTE_DEV_MODE, _DISABLE);
104         }
105         else if (pGpu->getProperty(pGpu, PDB_PROP_GPU_CC_FEATURE_CAPABLE))
106         {
107             pConfCompute->setProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_CC_FEATURE_ENABLED, NV_TRUE);
108             pGpu->setProperty(pGpu, PDB_PROP_GPU_FASTPATH_SEQ_ENABLED, NV_TRUE);
109         }
110         else
111         {
112             NV_PRINTF(LEVEL_ERROR, "GPU does not support confidential compute.\n");
113             NV_ASSERT(0);
114             return NV_ERR_INVALID_OPERATION;
115         }
116     }
117 
118     return NV_OK;
119 }
120 
121 /*!
122  * Initialize all registry overrides for this object
123  *
124  * @param[in]  pGpu              GPU object pointer
125  * @param[in]  pConfCompute      ConfidentialCompute pointer
126  */
127 static void
128 _confComputeInitRegistryOverrides
129 (
130     OBJGPU                *pGpu,
131     ConfidentialCompute   *pConfCompute
132 )
133 {
134     NvU32 data = 0;
135 
136     if ((osReadRegistryDword(pGpu, NV_REG_STR_RM_CONFIDENTIAL_COMPUTE, &data) == NV_OK) &&
137          FLD_TEST_DRF(_REG_STR, _RM_CONFIDENTIAL_COMPUTE, _ENABLED, _YES, data))
138     {
139         NV_PRINTF(LEVEL_INFO, "Confidential Compute enabled via regkey override.\n");
140         pConfCompute->setProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_ENABLED, NV_TRUE);
141         pConfCompute->gspProxyRegkeys |= DRF_DEF(GSP, _PROXY_REG, _CONFIDENTIAL_COMPUTE, _ENABLE);
142 
143         if (FLD_TEST_DRF(_REG_STR, _RM_CONFIDENTIAL_COMPUTE, _GPUS_READY_CHECK, _DISABLED, data))
144         {
145             pConfCompute->setProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_GPUS_READY_CHECK_ENABLED, NV_FALSE);
146         }
147 
148         if ((osReadRegistryDword(pGpu, NV_REG_STR_RM_CONF_COMPUTE_EARLY_INIT, &data)
149             == NV_OK) && (data == NV_REG_STR_RM_CONF_COMPUTE_EARLY_INIT_ENABLED))
150         {
151             NV_PRINTF(LEVEL_INFO, "Confidential Compute early init enabled via regkey override.\n");
152             pConfCompute->setProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_ENABLE_EARLY_INIT, NV_TRUE);
153             pConfCompute->gspProxyRegkeys |= DRF_DEF(GSP, _PROXY_REG, _CONF_COMPUTE_EARLY_INIT, _ENABLE);
154         }
155 
156         if (FLD_TEST_DRF(_REG_STR, _RM_CONFIDENTIAL_COMPUTE, _DEV_MODE_ENABLED, _YES, data))
157         {
158             NV_PRINTF(LEVEL_INFO, "Confidential Compute dev mode enabled via regkey override.\n");
159             pConfCompute->setProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_DEVTOOLS_MODE_ENABLED, NV_TRUE);
160             pConfCompute->gspProxyRegkeys |= DRF_DEF(GSP, _PROXY_REG, _CONF_COMPUTE_DEV_MODE, _ENABLE);
161         }
162     }
163 
164     if (pConfCompute->getProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_ENABLED))
165     {
166         if (confComputeIsSpdmEnabled(pGpu, pConfCompute))
167         {
168             NV_PRINTF(LEVEL_INFO, "SPDM is enabled by default.\n");
169             pConfCompute->setProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_SPDM_ENABLED, NV_TRUE);
170         }
171 
172         // Allow override of whatever default settings are.
173         if (osReadRegistryDword(pGpu, NV_REG_STR_RM_CONF_COMPUTE_SPDM_POLICY, &data) == NV_OK)
174         {
175             if (FLD_TEST_DRF(_REG_STR, _RM_CONF_COMPUTE_SPDM_POLICY, _ENABLED, _YES, data))
176             {
177                 NV_PRINTF(LEVEL_INFO, "Confidential Compute SPDM enabled via regkey override.\n");
178                 pConfCompute->setProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_SPDM_ENABLED, NV_TRUE);
179             }
180             else if (FLD_TEST_DRF(_REG_STR, _RM_CONF_COMPUTE_SPDM_POLICY, _ENABLED, _NO, data))
181             {
182                 // OPENRM-TODO: Always enable SPDM for debug.
183                 NV_PRINTF(LEVEL_INFO, "Confidential Compute SPDM disabled via regkey override.\n");
184                 pConfCompute->setProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_SPDM_ENABLED, NV_FALSE);
185             }
186         }
187     }
188 
189     if (pConfCompute->getProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_ENABLED))
190     {
191         if (osReadRegistryDword(pGpu, NV_REG_STR_RM_GSP_OWNED_FAULT_BUFFERS_ENABLE, &data) == NV_OK)
192         {
193             pGpu->bIsGspOwnedFaultBuffersEnabled = data;
194         }
195         else
196         {
197             if (IS_GSP_CLIENT(pGpu) || RMCFG_FEATURE_PLATFORM_GSP)
198             {
199                 pGpu->bIsGspOwnedFaultBuffersEnabled = NV_REG_STR_RM_GSP_OWNED_FAULT_BUFFERS_ENABLE_YES;
200             }
201             else
202             {
203                 pGpu->bIsGspOwnedFaultBuffersEnabled = NV_REG_STR_RM_GSP_OWNED_FAULT_BUFFERS_ENABLE_NO;
204             }
205         }
206     }
207 }
208 
209 /*!
210  * Establish the SPDM session with the GPU Responder.
211  * After establishing the session, initialize all keys required
212  * for the Confidential Compute session.
213  *
214  * Note: This assumes that Confidential Compute is the first object
215  * to be initialized in the GPU child order list, and therefore
216  * SPDM session establishment is the first thing to happen. If another
217  * object precedes Confidential Compute - it will be initialized before
218  * SPDM session establishment.
219  *
220  * @param[in]  pGpu              GPU object pointer
221  * @param[in]  pConfCompute      ConfidentialCompute pointer
222  */
223 NV_STATUS
224 confComputeEstablishSpdmSessionAndKeys_KERNEL
225 (
226     OBJGPU              *pGpu,
227     ConfidentialCompute *pConfCompute
228 )
229 {
230     NV_STATUS status = NV_OK;
231 
232     if (IS_FMODEL(pGpu))
233     {
234         // Skip SPDM support on fmodel due to bugs 3553627 and 3556621.
235         return NV_OK;
236     }
237 
238     //
239     // Initialize SPDM session between Guest RM and SPDM Responder on GPU.
240     // The session lifetime will track Confidential Compute object state lifetime.
241     //
242     if (pConfCompute->getProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_SPDM_ENABLED))
243     {
244         status = objCreate(&pConfCompute->pSpdm, pConfCompute, Spdm);
245         if (status != NV_OK)
246         {
247             return status;
248         }
249 
250         NV_ASSERT(pConfCompute->pSpdm);
251 
252         // Initialize SPDM context & begin session.
253         NV_CHECK_OK_OR_GOTO(status, LEVEL_ERROR,
254                             spdmContextInit(pGpu, pConfCompute->pSpdm),
255                             ErrorExit);
256         NV_CHECK_OK_OR_GOTO(status, LEVEL_ERROR,
257                             spdmStart(pGpu, pConfCompute->pSpdm),
258                             ErrorExit);
259 
260         //
261         // Now that SPDM session is established, we must initialize
262         // keystore for any session-derived keys.
263         //
264         NV_CHECK_OK_OR_GOTO(status, LEVEL_ERROR,
265                             confComputeKeyStoreInit_HAL(pConfCompute),
266                             ErrorExit);
267 
268         // Store the export master secret in the keystore.
269         NV_CHECK_OK_OR_GOTO(status, LEVEL_ERROR,
270                             spdmRetrieveExportSecret(pGpu, pConfCompute->pSpdm,
271                                                      CC_EXPORT_MASTER_KEY_SIZE_BYTES,
272                                                      confComputeKeyStoreGetExportMasterKey(pConfCompute)),
273                             ErrorExit);
274 
275         // Derive secrets for encrypted communication
276         NV_CHECK_OK_OR_GOTO(status, LEVEL_ERROR,
277                             confComputeDeriveSecrets_HAL(pConfCompute, MC_ENGINE_IDX_GSP),
278                             ErrorExit);
279 
280         // Enable encryption for all traffic between CPU and GPU
281         status = confComputeStartEncryption_HAL(pGpu, pConfCompute);
282         if (status != NV_OK)
283         {
284             NV_PRINTF(LEVEL_ERROR, "ConfCompute : Failed enabling encryption!");
285             return status;
286         }
287     }
288 ErrorExit:
289 
290     return status;
291 }
292 
293 /*!
294  * Deinitialize the SPDM context with the GPU Responder.
295  *
296  * Note: This assumes that Confidential Compute is the first object
297  * to be initialized in the GPU child order list, and therefore
298  * SPDM deinitialization is the last thing to happen. If another
299  * object precedes Confidential Compute - it will be deinitialized
300  * before SPDM.
301  *
302  * @param[in]  pGpu              GPU object pointer
303  * @param[in]  pConfCompute      ConfidentialCompute pointer
304  */
305 static NV_STATUS
306 _confComputeDeinitSpdmSession
307 (
308     OBJGPU              *pGpu,
309     ConfidentialCompute *pConfCompute
310 )
311 {
312     NV_STATUS status = NV_OK;
313 
314     if (IS_FMODEL(pGpu))
315     {
316         // Skip SPDM support on fmodel due to bugs 3553627 and 3556621.
317         return NV_OK;
318     }
319 
320     //
321     // Tear down SPDM session between Guest RM and SPDM Responder on GPU.
322     // We must do in pre-unload, before Responder is torn down entirely.
323     //
324     if (pConfCompute->getProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_SPDM_ENABLED))
325     {
326         if (pConfCompute->pSpdm == NULL)
327         {
328             //
329             // If SPDM object doesn't exist, we must have failed earlier.
330             // Alert in logs and move on.
331             //
332             NV_PRINTF(LEVEL_ERROR, "SPDM teardown did not occur, as SPDM object is null!\n");
333             return NV_OK;
334         }
335 
336         status = spdmContextDeinit(pGpu, pConfCompute->pSpdm, NV_TRUE);
337 
338         objDelete(pConfCompute->pSpdm);
339         pConfCompute->pSpdm = NULL;
340     }
341 
342     return status;
343 }
344 
345 
346 /*!
347  * Perform any work that must be done before GPU initialization.
348  *
349  * @param[in]  pGpu              GPU object pointer
350  * @param[in]  pConfCompute      ConfidentialCompute pointer
351  */
352 NV_STATUS
353 confComputeStatePreInitLocked_IMPL
354 (
355     OBJGPU              *pGpu,
356     ConfidentialCompute *pConfCompute
357 )
358 {
359     return confComputeEstablishSpdmSessionAndKeys_HAL(pGpu, pConfCompute);
360 }
361 
362 /*!
363  * Perform any init that must occur after GPU state load.
364  *
365  * @param[in]  pGpu          GPU object pointer
366  * @param[in]  pConfCompute  ConfidentialCompute pointer
367  * @param[in]  flags         Optional flags describing state load conditions
368  */
369 NV_STATUS
370 confComputeStatePostLoad_IMPL
371 (
372     OBJGPU              *pGpu,
373     ConfidentialCompute *pConfCompute,
374     NvU32                flags
375 )
376 {
377     NV_STATUS status = NV_OK;
378     RM_API   *pRmApi = GPU_GET_PHYSICAL_RMAPI(pGpu);
379 
380     NV_ASSERT_OK_OR_RETURN(pRmApi->Control(pRmApi,
381                                     pGpu->hInternalClient,
382                                     pGpu->hInternalSubdevice,
383                                     NV2080_CTRL_CMD_INTERNAL_CONF_COMPUTE_GET_STATIC_INFO,
384                                     &pConfCompute->ccStaticInfo,
385                                     sizeof(pConfCompute->ccStaticInfo)));
386 
387     if (!IS_GSP_CLIENT(pGpu) && !RMCFG_FEATURE_PLATFORM_GSP)
388     {
389         NV_PRINTF(LEVEL_INFO, "Performing late SPDM initialization!\n");
390         status = confComputeEstablishSpdmSessionAndKeys_HAL(pGpu, pConfCompute);
391     }
392 
393     return status;
394 }
395 
396 /*!
397  * Perform any deinit that must occur before GPU state unload.
398  *
399  * @param[in]  pGpu          GPU object pointer
400  * @param[in]  pConfCompute  ConfidentialCompute pointer
401  * @param[in]  flags         Optional flags describing state unload conditions
402  */
403 NV_STATUS
404 confComputeStatePreUnload_IMPL
405 (
406     OBJGPU              *pGpu,
407     ConfidentialCompute *pConfCompute,
408     NvU32                flags
409 )
410 {
411     NV_PRINTF(LEVEL_INFO, "Performing SPDM deinitialization in Pre Unload!\n");
412     return _confComputeDeinitSpdmSession(pGpu, pConfCompute);
413 }
414 
415 NvBool
416 confComputeAcceptClientRequest_IMPL
417 (
418     OBJGPU                *pGpu,
419     ConfidentialCompute   *pConfCompute
420 )
421 {
422     OBJSYS    *pSys = SYS_GET_INSTANCE();
423     OBJGPUMGR *pGpuMgr = SYS_GET_GPUMGR(pSys);
424 
425     if (pConfCompute->getProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_GPUS_READY_CHECK_ENABLED))
426     {
427         return pGpuMgr->ccCaps.bAcceptClientRequest;
428     }
429     else
430     {
431         return NV_TRUE;
432     }
433 }
434 
435 NV_STATUS
436 confComputeStateInitLocked_IMPL
437 (
438     OBJGPU              *pGpu,
439     ConfidentialCompute *pConfCompute
440 )
441 {
442     RM_API *pRmApi = IS_GSP_CLIENT(pGpu) ? GPU_GET_PHYSICAL_RMAPI(pGpu) :
443                                            rmapiGetInterface(RMAPI_GPU_LOCK_INTERNAL);
444 
445     NV_ASSERT_OK_OR_RETURN(pRmApi->Control(pRmApi,
446                                            pGpu->hInternalClient,
447                                            pGpu->hInternalSubdevice,
448                                            NV2080_CTRL_CMD_INTERNAL_CONF_COMPUTE_GET_STATIC_INFO,
449                                            &pConfCompute->ccStaticInfo,
450                                            sizeof(pConfCompute->ccStaticInfo)));
451 
452     NV_PRINTF(LEVEL_INFO, "BAR1 Trusted: 0x%x PCIE Trusted: 0x%x\n",
453               pConfCompute->ccStaticInfo.bIsBar1Trusted, pConfCompute->ccStaticInfo.bIsPcieTrusted);
454 
455     return NV_OK;
456 }
457 
458 NV_STATUS
459 confComputeStartEncryption_KERNEL
460 (
461     OBJGPU              *pGpu,
462     ConfidentialCompute *pConfCompute
463 )
464 {
465     NV_STATUS                                                        status = NV_OK;
466     RM_API                                                          *pRmApi = GPU_GET_PHYSICAL_RMAPI(pGpu);
467     NV2080_CTRL_CMD_INTERNAL_CONF_COMPUTE_ENCRYPTION_CONTROL_PARAMS  params;
468 
469     if (!IS_GSP_CLIENT(pGpu))
470     {
471         return NV_ERR_INVALID_STATE;
472     }
473 
474     if ((pConfCompute->getProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_ENCRYPT_READY) ==  NV_FALSE) &&
475         (pConfCompute->getProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_ENCRYPT_ENABLED) ==  NV_FALSE))
476     {
477         NV_PRINTF(LEVEL_INFO, "ConfCompute: Enabling encryption on Kernel-RM!\n");
478 
479         pConfCompute->setProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_ENCRYPT_READY,   NV_TRUE);
480         pConfCompute->setProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_ENCRYPT_ENABLED, NV_TRUE);
481 
482         //
483         // GSP-RM has already initialized all its secrets successfully.
484         // We must initialize our own before we attempt to start encryption.
485         //
486         NV_ASSERT_OK_OR_RETURN(ccslContextInitViaKeyId(pConfCompute,
487                                                        &pConfCompute->pRpcCcslCtx,
488                                                        CC_GKEYID_GEN(CC_KEYSPACE_GSP, CC_LKEYID_CPU_GSP_LOCKED_RPC)));
489         NV_ASSERT_OK_OR_RETURN(ccslContextInitViaKeyId(pConfCompute,
490                                                        &pConfCompute->pDmaCcslCtx,
491                                                        CC_GKEYID_GEN(CC_KEYSPACE_GSP, CC_LKEYID_CPU_GSP_DMA)));
492         NV_ASSERT_OK_OR_RETURN(ccslContextInitViaKeyId(pConfCompute,
493                                                        &pConfCompute->pReplayableFaultCcslCtx,
494                                                        CC_GKEYID_GEN(CC_KEYSPACE_GSP, CC_LKEYID_GSP_CPU_REPLAYABLE_FAULT)));
495         NV_ASSERT_OK_OR_RETURN(ccslContextInitViaKeyId(pConfCompute,
496                                                        &pConfCompute->pNonReplayableFaultCcslCtx,
497                                                        CC_GKEYID_GEN(CC_KEYSPACE_GSP, CC_LKEYID_GSP_CPU_NON_REPLAYABLE_FAULT)));
498 
499         portMemSet(&params, 0, sizeof(params));
500         params.bEncryptionControl = NV_TRUE;
501 
502         // Tell GSP-RM to start encrypting its responses.
503         NV_ASSERT_OK_OR_RETURN(status = pRmApi->Control(pRmApi,
504                                         pGpu->hInternalClient,
505                                         pGpu->hInternalSubdevice,
506                                         NV2080_CTRL_CMD_INTERNAL_CONF_COMPUTE_ENCRYPTION_CONTROL,
507                                         &params,
508                                         sizeof(params)));
509     }
510     else
511     {
512         return NV_ERR_INVALID_STATE;
513     }
514 
515     return NV_OK;
516 }
517 
518 NV_STATUS
519 confComputeStopEncryption_KERNEL
520 (
521     OBJGPU              *pGpu,
522     ConfidentialCompute *pConfCompute
523 )
524 {
525     RM_API                                                         *pRmApi = GPU_GET_PHYSICAL_RMAPI(pGpu);
526     NV2080_CTRL_CMD_INTERNAL_CONF_COMPUTE_ENCRYPTION_CONTROL_PARAMS params;
527     NV_STATUS                                                       status = NV_OK;
528 
529     if (pConfCompute->getProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_SPDM_ENABLED))
530     {
531         if (!IS_GSP_CLIENT(pGpu))
532         {
533             return NV_ERR_INVALID_STATE;
534         }
535 
536         if (pConfCompute->getProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_ENCRYPT_READY))
537         {
538             NV_PRINTF(LEVEL_INFO, "ConfCompute: Turning off receive encryption on Kernel-RM!\n");
539             pConfCompute->setProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_ENCRYPT_READY, NV_FALSE);
540         }
541 
542         portMemSet(&params, 0, sizeof(params));
543         params.bEncryptionControl = NV_FALSE;
544 
545         //
546         // Tell GSP-RM to stop encrypting its data.
547         // Always have GPU delete secrets, regardless of CPU-RM state.
548         //
549         status = pRmApi->Control(pRmApi,
550             pGpu->hInternalClient,
551             pGpu->hInternalSubdevice,
552             NV2080_CTRL_CMD_INTERNAL_CONF_COMPUTE_ENCRYPTION_CONTROL,
553             &params,
554             sizeof(params));
555 
556         // Regardless of response, be sure to disable and clear all encryption secrets from kernel side.
557         if (pConfCompute->getProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_ENCRYPT_ENABLED))
558         {
559             NV_PRINTF(LEVEL_INFO, "ConfCompute: Turning off send encryption on Kernel-RM!\n");
560             pConfCompute->setProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_ENCRYPT_ENABLED, NV_FALSE);
561         }
562 
563         // Deinitialize CCSL contexts.
564         ccslContextClear(pConfCompute->pRpcCcslCtx);
565         ccslContextClear(pConfCompute->pDmaCcslCtx);
566         ccslContextClear(pConfCompute->pReplayableFaultCcslCtx);
567         ccslContextClear(pConfCompute->pNonReplayableFaultCcslCtx);
568 
569         pConfCompute->pRpcCcslCtx = NULL;
570         pConfCompute->pDmaCcslCtx = NULL;
571         pConfCompute->pReplayableFaultCcslCtx = NULL;
572         pConfCompute->pNonReplayableFaultCcslCtx = NULL;
573     }
574 
575     return status;
576 }
577 
578 /*!
579  * Deinitialize all keys required for the Confidential Compute session.
580  *
581  * Note: This assumes that Confidential Compute is the first object
582  * to be initialized in the GPU child order list, and therefore
583  * SPDM deinitialization is the last thing to happen. If another
584  * object precedes Confidential Compute - it will be deinitialized
585  * before SPDM.
586  *
587  * @param[in]  pGpu              GPU object pointer
588  * @param[in]  pConfCompute      ConfidentialCompute pointer
589  */
590 void
591 confComputeStateDestroy_IMPL
592 (
593     OBJGPU              *pGpu,
594     ConfidentialCompute *pConfCompute
595 )
596 {
597     NV_STATUS status = NV_OK;
598 
599     status = _confComputeDeinitSpdmSession(pGpu, pConfCompute);
600     if (status != NV_OK)
601     {
602         NV_PRINTF(LEVEL_ERROR, "ConfCompute: Failed deinitializing SPDM: 0x%x!\n", status);
603     }
604 
605     status = confComputeStopEncryption_HAL(pGpu, pConfCompute);
606     if (status != NV_OK)
607     {
608         NV_PRINTF(LEVEL_ERROR, "ConfCompute: Failed disabling encryption: 0x%x!\n", status);
609     }
610 
611     confComputeKeyStoreDeinit_HAL(pConfCompute);
612 
613     return;
614 }
615