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(¶ms, 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 ¶ms, 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(¶ms, 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 ¶ms, 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