1 /* 2 * SPDX-FileCopyrightText: Copyright (c) 2023-2024 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 #define NVOC_CONF_COMPUTE_H_PRIVATE_ACCESS_ALLOWED 25 26 #include "kernel/gpu/conf_compute/conf_compute.h" 27 #include "class/cl2080.h" 28 29 #include "kernel/gpu/mem_mgr/mem_mgr.h" 30 #include "class/clc86fsw.h" 31 #include "ctrl/ctrl2080/ctrl2080internal.h" 32 #include "nvrm_registry.h" 33 34 static void initKeyRotationRegistryOverrides(OBJGPU *pGpu, ConfidentialCompute *pConfCompute); 35 static void getKeyPairForKeySpace(NvU32 keySpace, NvBool bKernel, NvU32 *pGlobalH2DKey, NvU32 *pGlobalD2HKey); 36 static NV_STATUS triggerKeyRotationByKeyPair(OBJGPU *pGpu, ConfidentialCompute *pConfCompute, NvU32 h2dKey, NvU32 d2hKey); 37 static NV_STATUS calculateEncryptionStatsByKeyPair(OBJGPU *pGpu, ConfidentialCompute *pConfCompute, NvU32 h2dKey, NvU32 d2hKey); 38 static NV_STATUS notifyKeyRotationByKeyPair(OBJGPU *pGpu, ConfidentialCompute *pConfCompute, NvU32 h2dKey); 39 static NvBool isLowerThresholdCrossed(ConfidentialCompute *pConfCompute, KEY_ROTATION_STATS_INFO *pH2DInfo, 40 KEY_ROTATION_STATS_INFO *pD2HInfo); 41 static NvBool isUpperThresholdCrossed(ConfidentialCompute *pConfCompute, KEY_ROTATION_STATS_INFO *pH2DInfo, 42 KEY_ROTATION_STATS_INFO *pD2HInfo); 43 static NV_STATUS keyRotationTimeoutCallback(OBJGPU *pGpu, OBJTMR *pTmr, TMR_EVENT *pTmrEvent); 44 45 /*! 46 * Conditionally enables key rotation support 47 * 48 * @param[in] pGpu : OBJGPU Pointer 49 * @param[in] pConfCompute : ConfidentialCompute pointer 50 */ 51 NV_STATUS 52 confComputeEnableKeyRotationSupport_GH100 53 ( 54 OBJGPU *pGpu, 55 ConfidentialCompute *pConfCompute 56 ) 57 { 58 59 if (pConfCompute->getProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_ENABLED) && 60 pConfCompute->getProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_CC_FEATURE_ENABLED)) 61 { 62 pConfCompute->setProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_KEY_ROTATION_SUPPORTED, NV_TRUE); 63 64 // 65 // TODO: sbellock default values need to be defined and set separately 66 // for prod flow based on attacker advantage table. 67 // 68 pConfCompute->lowerThreshold.totalBytesEncrypted = NV_U64_MAX; 69 pConfCompute->lowerThreshold.totalEncryptOps = 500; 70 pConfCompute->upperThreshold.totalBytesEncrypted = NV_U64_MAX; 71 pConfCompute->upperThreshold.totalEncryptOps = 1000; 72 initKeyRotationRegistryOverrides(pGpu, pConfCompute); 73 } 74 return NV_OK; 75 } 76 77 /*! 78 * Enables/disables key rotation by setting up the 1 sec callback for key rotation 79 * 80 * @param[in] pGpu : OBJGPU Pointer 81 * @param[in] pConfCompute : ConfidentialCompute pointer 82 * @param[in] bEnable : If key rotation should be enabled 83 */ 84 NV_STATUS 85 confComputeEnableKeyRotationCallback_GH100 86 ( 87 OBJGPU *pGpu, 88 ConfidentialCompute *pConfCompute, 89 NvBool bEnable 90 ) 91 { 92 if (bEnable) 93 { 94 // Hook into the 1 Hz OS timer 95 osSchedule1HzCallback(pGpu, 96 confComputeKeyRotationCallback, 97 NULL /* pData */, 98 NV_OS_1HZ_REPEAT); 99 } 100 else 101 { 102 osRemove1HzCallback(pGpu, 103 confComputeKeyRotationCallback, 104 NULL /* pData */); 105 } 106 return NV_OK; 107 } 108 109 /*! 110 * Calculates encryption statistics and triggers key rotation if thresholds are crossed. 111 * 112 * @param[in] pGpu : OBJGPU Pointer 113 * @param[in] pConfCompute : ConfidentialCompute pointer 114 */ 115 NV_STATUS 116 confComputeTriggerKeyRotation_GH100 117 ( 118 OBJGPU *pGpu, 119 ConfidentialCompute *pConfCompute 120 ) 121 { 122 NV_STATUS tempStatus, status = NV_OK; 123 NvU32 globalD2HKey, globalH2DKey, keySpace; 124 125 if ((pConfCompute->getProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_DUMMY_KEY_ROTATION_ENABLED)) && 126 (pConfCompute->keyRotationChannelRefCount > 0)) 127 { 128 pConfCompute->keyRotationCallbackCount++; 129 NV_PRINTF(LEVEL_ERROR, "DUMMY KR: COUNT = %d\n", pConfCompute->keyRotationCallbackCount); 130 } 131 for (keySpace = 0; keySpace < CC_KEYSPACE_SIZE; keySpace++) 132 { 133 if (keySpace == CC_KEYSPACE_GSP) 134 continue; 135 136 if ((pConfCompute->getProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_DUMMY_KEY_ROTATION_ENABLED)) && 137 !(pConfCompute->keyRotationEnableMask & NVBIT(keySpace))) 138 { 139 NV_PRINTF(LEVEL_INFO, "Skipping keyspace = %d since mask = 0x%x\n", keySpace, pConfCompute->keyRotationEnableMask); 140 continue; 141 } 142 143 // calculate kernel channels stats for keyspace 144 if ((!pConfCompute->getProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_DUMMY_KEY_ROTATION_ENABLED)) || 145 (FLD_TEST_DRF(_REG_STR, _RM_CONF_COMPUTE_DUMMY_KEY_ROTATION, _KERNEL_KEYS, _YES, pConfCompute->keyRotationEnableMask))) 146 { 147 getKeyPairForKeySpace(keySpace, NV_TRUE, &globalH2DKey, &globalD2HKey); 148 tempStatus = triggerKeyRotationByKeyPair(pGpu, pConfCompute, globalH2DKey, globalD2HKey); 149 if (tempStatus != NV_OK) 150 { 151 NV_ASSERT(tempStatus == NV_OK); 152 NV_PRINTF(LEVEL_ERROR, "Failed to calculate encryption statistics for H2D key 0x%x with status 0x%x\n", globalH2DKey, tempStatus); 153 status = tempStatus; 154 } 155 } 156 157 // calculate user channels stats for keyspace 158 if ((!pConfCompute->getProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_DUMMY_KEY_ROTATION_ENABLED)) || 159 (FLD_TEST_DRF(_REG_STR, _RM_CONF_COMPUTE_DUMMY_KEY_ROTATION, _USER_KEYS, _YES, pConfCompute->keyRotationEnableMask))) 160 { 161 getKeyPairForKeySpace(keySpace, NV_FALSE, &globalH2DKey, &globalD2HKey); 162 tempStatus = triggerKeyRotationByKeyPair(pGpu, pConfCompute, globalH2DKey, globalD2HKey); 163 if (tempStatus != NV_OK) 164 { 165 NV_ASSERT(tempStatus == NV_OK); 166 NV_PRINTF(LEVEL_ERROR, "Failed to calculate encryption statistics for H2D key 0x%x with status 0x%x\n", globalH2DKey, tempStatus); 167 status = tempStatus; 168 } 169 } 170 } 171 return status; 172 } 173 174 static NV_STATUS 175 triggerKeyRotationByKeyPair 176 ( 177 OBJGPU *pGpu, 178 ConfidentialCompute *pConfCompute, 179 NvU32 h2dKey, 180 NvU32 d2hKey 181 ) 182 { 183 KEY_ROTATION_STATUS state; 184 NV_ASSERT_OK_OR_RETURN(confComputeGetKeyRotationStatus(pConfCompute, h2dKey, &state)); 185 CHANNEL_ITERATOR iter = {0}; 186 KernelChannel *pKernelChannel = NULL; 187 NvU32 h2dIndex, d2hIndex; 188 189 // we won't need this once we have encryption statistics since unused keys will have stats = 0 190 if (pConfCompute->getProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_DUMMY_KEY_ROTATION_ENABLED)) 191 { 192 NV_ASSERT_OK_OR_RETURN(confComputeInitChannelIterForKey(pGpu, pConfCompute, h2dKey, &iter)); 193 if (confComputeGetNextChannelForKey(pGpu, pConfCompute, &iter, h2dKey, &pKernelChannel) != NV_OK) 194 { 195 // 196 // If this is the last key and we haven't done KR yet even after crossing upper threshold then 197 // it means there are no channels alive and we need to manually reset our counter 198 // 199 if ((h2dKey == CC_GKEYID_GEN(CC_KEYSPACE_LCE7, CC_LKEYID_LCE_H2D_USER)) && 200 (pConfCompute->keyRotationCallbackCount > pConfCompute->upperThreshold.totalEncryptOps)) 201 { 202 pConfCompute->keyRotationCallbackCount = 1; 203 } 204 return NV_OK; 205 } 206 } 207 208 // 209 // If key rotation is alredy scheduled because we crossed upper threshold or hit timeout 210 // then we dont need to update encryption statistics as they will be zeroed out soon. 211 // 212 if ((state == KEY_ROTATION_STATUS_FAILED_THRESHOLD) || 213 (state == KEY_ROTATION_STATUS_FAILED_TIMEOUT)) 214 { 215 return NV_OK; 216 } 217 218 // 219 // CC session doesn't exist if key rotation failed 220 // TODO CONFCOMP-984: RC all channels and other cleanup (kpadwal is working on adding this call) 221 // 222 if (state == KEY_ROTATION_STATUS_FAILED_ROTATION) 223 return NV_ERR_INVALID_STATE; 224 225 NV_ASSERT_OK_OR_RETURN(calculateEncryptionStatsByKeyPair(pGpu, pConfCompute, h2dKey, d2hKey)); 226 227 NV_ASSERT_OK_OR_RETURN(confComputeGetKeySlotFromGlobalKeyId(pConfCompute, h2dKey, &h2dIndex)); 228 NV_ASSERT_OK_OR_RETURN(confComputeGetKeySlotFromGlobalKeyId(pConfCompute, d2hKey, &d2hIndex)); 229 230 if (isUpperThresholdCrossed(pConfCompute, &pConfCompute->aggregateStats[h2dIndex], 231 &pConfCompute->aggregateStats[d2hIndex])) 232 { 233 NV_PRINTF(LEVEL_ERROR, "Crossed UPPER threshold for key = 0x%x\n", h2dKey); 234 NV_ASSERT_OK_OR_RETURN(confComputeSetKeyRotationStatus(pConfCompute, h2dKey, KEY_ROTATION_STATUS_FAILED_THRESHOLD)); 235 NV_ASSERT_OK_OR_RETURN(confComputeScheduleKeyRotationWorkItem(pGpu, pConfCompute, h2dKey, d2hKey)); 236 } 237 else if (isLowerThresholdCrossed(pConfCompute, &pConfCompute->aggregateStats[h2dIndex], 238 &pConfCompute->aggregateStats[d2hIndex])) 239 { 240 NV_PRINTF(LEVEL_INFO, "Crossed LOWER threshold for key = 0x%x\n", h2dKey); 241 if (state == KEY_ROTATION_STATUS_IDLE) 242 { 243 NV_ASSERT_OK_OR_RETURN(confComputeSetKeyRotationStatus(pConfCompute, h2dKey, KEY_ROTATION_STATUS_PENDING)); 244 245 // 246 // Start the timeout timer once lower threshold is crossed. 247 // 248 // If timer is not already created then create it now. Else, just schedule a callback. 249 // make sure callback is canceled if we schedule the KR task (after crossing lower or upper threshold) 250 // make sure all these timer events are deleted as part of RM shutdown 251 // 252 OBJTMR *pTmr = GPU_GET_TIMER(pGpu); 253 if (pConfCompute->ppKeyRotationTimer[h2dIndex] == NULL) 254 { 255 NvU32 *pH2DKey = portMemAllocNonPaged(sizeof(NvU32)); 256 *pH2DKey = h2dKey; 257 NV_ASSERT_OK_OR_RETURN(tmrEventCreate(pTmr, &pConfCompute->ppKeyRotationTimer[h2dIndex], 258 keyRotationTimeoutCallback, (void*)pH2DKey, TMR_FLAGS_NONE)); 259 } 260 261 // 262 // Schedule first callback. 263 // TODO sbellock: don't use hardcoded 12.5 sec vaule 264 // 265 NV_ASSERT_OK_OR_RETURN(tmrEventScheduleRelSec(pTmr, pConfCompute->ppKeyRotationTimer[h2dIndex], 12.5)); 266 267 // 268 // Notify clients of pending KR 269 // We can't schedule a workitem for this since it may get scheduled too late and 270 // we might have already crossed the upper threshold by then. 271 // 272 NV_ASSERT_OK_OR_RETURN(notifyKeyRotationByKeyPair(pGpu, pConfCompute, h2dKey)); 273 } 274 } 275 return NV_OK; 276 } 277 278 static NV_STATUS 279 keyRotationTimeoutCallback 280 ( 281 OBJGPU *pGpu, 282 OBJTMR *pTmr, 283 TMR_EVENT *pEvent 284 ) 285 { 286 ConfidentialCompute *pConfCompute = GPU_GET_CONF_COMPUTE(pGpu); 287 NvU32 h2dKey, d2hKey; 288 NvU32 key = *(NvU32*)pEvent->pUserData; 289 confComputeGetKeyPairByKey(pConfCompute, key, &h2dKey, &d2hKey); 290 NV_ASSERT_OK_OR_RETURN(confComputeSetKeyRotationStatus(pConfCompute, h2dKey, KEY_ROTATION_STATUS_FAILED_TIMEOUT)); 291 return confComputeScheduleKeyRotationWorkItem(pGpu, pConfCompute, h2dKey, d2hKey); 292 } 293 294 static NV_STATUS 295 calculateEncryptionStatsByKeyPair 296 ( 297 OBJGPU *pGpu, 298 ConfidentialCompute *pConfCompute, 299 NvU32 h2dKey, 300 NvU32 d2hKey 301 ) 302 { 303 CHANNEL_ITERATOR iter = {0}; 304 NvU64 totalH2Dbytes = 0; 305 NvU64 totalD2Hbytes = 0; 306 NvU64 totalEncryptOpsH2D = 0; 307 NvU64 totalEncryptOpsD2H = 0; 308 NvU32 h2dIndex, d2hIndex; 309 310 // Iterate through all channels using the key pair and compute totals 311 KernelChannel *pKernelChannel = NULL; 312 313 NV_ASSERT_OK_OR_RETURN(confComputeGetKeySlotFromGlobalKeyId(pConfCompute, h2dKey, &h2dIndex)); 314 NV_ASSERT_OK_OR_RETURN(confComputeGetKeySlotFromGlobalKeyId(pConfCompute, d2hKey, &d2hIndex)); 315 316 NV_ASSERT_OK_OR_RETURN(confComputeInitChannelIterForKey(pGpu, pConfCompute, h2dKey, &iter)); 317 while(confComputeGetNextChannelForKey(pGpu, pConfCompute, &iter, h2dKey, &pKernelChannel) == NV_OK) 318 { 319 // TODO: Make this fatal 320 if (pKernelChannel->pEncStatsBufMemDesc == NULL) 321 continue; 322 323 CC_CRYPTOBUNDLE_STATS *pEncStats = pKernelChannel->pEncStatsBuf; 324 if (pEncStats == NULL) 325 { 326 NV_ASSERT(pEncStats != NULL); 327 NV_PRINTF(LEVEL_ERROR, "Failed to get stats for chid = 0x%x RM engineId = 0x%x\n", 328 kchannelGetDebugTag(pKernelChannel), kchannelGetEngineType(pKernelChannel)); 329 return NV_ERR_INVALID_STATE; 330 } 331 totalH2Dbytes += pEncStats->bytesEncryptedH2D; 332 totalD2Hbytes += pEncStats->bytesEncryptedD2H; 333 totalEncryptOpsH2D += pEncStats->numEncryptionsH2D; 334 totalEncryptOpsD2H += pEncStats->numEncryptionsD2H; 335 NV_PRINTF(LEVEL_INFO, "Encryption stats for chid 0x%x with h2dKey 0x%x\n", kchannelGetDebugTag(pKernelChannel), h2dKey); 336 NV_PRINTF(LEVEL_INFO, "Total h2d bytes encrypted = 0x%llx\n", pEncStats->bytesEncryptedH2D); 337 NV_PRINTF(LEVEL_INFO, "Total d2h bytes encrypted = 0x%llx\n", pEncStats->bytesEncryptedD2H); 338 NV_PRINTF(LEVEL_INFO, "Total h2d encrypt ops = 0x%llx\n", pEncStats->numEncryptionsH2D); 339 NV_PRINTF(LEVEL_INFO, "Total d2h encrypt ops = 0x%llx\n", pEncStats->numEncryptionsD2H); 340 } 341 342 // Add stats for freed channels 343 totalH2Dbytes += pConfCompute->freedChannelAggregateStats[h2dIndex].totalBytesEncrypted; 344 totalEncryptOpsH2D += pConfCompute->freedChannelAggregateStats[h2dIndex].totalEncryptOps; 345 totalD2Hbytes += pConfCompute->freedChannelAggregateStats[d2hIndex].totalBytesEncrypted; 346 totalEncryptOpsD2H += pConfCompute->freedChannelAggregateStats[d2hIndex].totalEncryptOps; 347 348 pConfCompute->aggregateStats[h2dIndex].totalBytesEncrypted = totalH2Dbytes; 349 pConfCompute->aggregateStats[h2dIndex].totalEncryptOps = totalEncryptOpsH2D; 350 pConfCompute->aggregateStats[d2hIndex].totalBytesEncrypted = totalD2Hbytes; 351 pConfCompute->aggregateStats[d2hIndex].totalEncryptOps = totalEncryptOpsD2H; 352 353 if ((pConfCompute->aggregateStats[h2dIndex].totalBytesEncrypted > 0) || 354 (pConfCompute->aggregateStats[d2hIndex].totalBytesEncrypted > 0)) 355 { 356 NV_PRINTF(LEVEL_INFO, "Aggregate stats for h2dKey 0x%x and d2hKey 0x%x\n", h2dKey, d2hKey); 357 NV_PRINTF(LEVEL_INFO, "Total h2d bytes encrypted = 0x%llx\n", pConfCompute->aggregateStats[h2dIndex].totalBytesEncrypted); 358 NV_PRINTF(LEVEL_INFO, "Total d2h bytes encrypted = 0x%llx\n", pConfCompute->aggregateStats[h2dIndex].totalEncryptOps); 359 NV_PRINTF(LEVEL_INFO, "Total h2d encrypt ops = 0x%llx\n", pConfCompute->aggregateStats[d2hIndex].totalBytesEncrypted); 360 NV_PRINTF(LEVEL_INFO, "Total d2h encrypt ops = 0x%llx\n", pConfCompute->aggregateStats[d2hIndex].totalEncryptOps); 361 } 362 return NV_OK; 363 } 364 365 static NvBool 366 isUpperThresholdCrossed 367 ( 368 ConfidentialCompute *pConfCompute, 369 KEY_ROTATION_STATS_INFO *pH2DInfo, 370 KEY_ROTATION_STATS_INFO *pD2HInfo 371 ) 372 { 373 if (pConfCompute->getProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_DUMMY_KEY_ROTATION_ENABLED)) 374 { 375 return (pConfCompute->keyRotationCallbackCount > pConfCompute->upperThreshold.totalEncryptOps); 376 } 377 else 378 { 379 return (confComputeIsUpperThresholdCrossed(pConfCompute, pH2DInfo) || 380 confComputeIsUpperThresholdCrossed(pConfCompute, pD2HInfo)); 381 } 382 } 383 384 static NvBool 385 isLowerThresholdCrossed 386 ( 387 ConfidentialCompute *pConfCompute, 388 KEY_ROTATION_STATS_INFO *pH2DInfo, 389 KEY_ROTATION_STATS_INFO *pD2HInfo 390 ) 391 { 392 if (pConfCompute->getProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_DUMMY_KEY_ROTATION_ENABLED)) 393 { 394 return (pConfCompute->keyRotationCallbackCount > pConfCompute->lowerThreshold.totalEncryptOps); 395 } 396 else 397 { 398 return (confComputeIsLowerThresholdCrossed(pConfCompute, pH2DInfo) || 399 confComputeIsLowerThresholdCrossed(pConfCompute, pD2HInfo)); 400 } 401 } 402 403 static void 404 getKeyPairForKeySpace(NvU32 keySpace, NvBool bKernel, NvU32 *pGlobalH2DKey, NvU32 *pGlobalD2HKey) 405 { 406 NvU32 localH2DKey, localD2HKey; 407 if (keySpace == CC_KEYSPACE_SEC2) 408 { 409 if (bKernel) 410 { 411 localH2DKey = CC_LKEYID_CPU_SEC2_DATA_KERN; 412 localD2HKey = CC_LKEYID_CPU_SEC2_HMAC_KERN; 413 } 414 else 415 { 416 localH2DKey = CC_LKEYID_CPU_SEC2_DATA_USER; 417 localD2HKey = CC_LKEYID_CPU_SEC2_HMAC_USER; 418 } 419 } 420 else 421 { 422 if (bKernel) 423 { 424 localH2DKey = CC_LKEYID_LCE_H2D_KERN; 425 localD2HKey = CC_LKEYID_LCE_D2H_KERN; 426 } 427 else 428 { 429 localH2DKey = CC_LKEYID_LCE_H2D_USER; 430 localD2HKey = CC_LKEYID_LCE_D2H_USER; 431 } 432 } 433 *pGlobalH2DKey = CC_GKEYID_GEN(keySpace, localH2DKey); 434 *pGlobalD2HKey = CC_GKEYID_GEN(keySpace, localD2HKey); 435 } 436 437 static NV_STATUS 438 notifyKeyRotationByKeyPair 439 ( 440 OBJGPU *pGpu, 441 ConfidentialCompute *pConfCompute, 442 NvU32 h2dKey 443 ) 444 { 445 KEY_ROTATION_STATUS status; 446 CHANNEL_ITERATOR iter = {0}; 447 KernelChannel *pKernelChannel = NULL; 448 NvU32 notifyStatus = 0; 449 NV_ASSERT_OK_OR_RETURN(confComputeGetKeyRotationStatus(pConfCompute, h2dKey, &status)); 450 // 451 // We expect this work item to be called soon after RM detects lower threshold is 452 // crossed and schedules this. 453 // 454 NV_ASSERT_OR_RETURN(status == KEY_ROTATION_STATUS_PENDING, NV_ERR_INVALID_STATE); 455 456 // notify all channels 457 NV_ASSERT_OK_OR_RETURN(confComputeInitChannelIterForKey(pGpu, pConfCompute, h2dKey, &iter)); 458 while(confComputeGetNextChannelForKey(pGpu, pConfCompute, &iter, h2dKey, &pKernelChannel) == NV_OK) 459 { 460 // update notifier memory 461 notifyStatus = 462 FLD_SET_DRF(_CHANNELGPFIFO, _NOTIFICATION_STATUS, _IN_PROGRESS, _TRUE, notifyStatus); 463 464 notifyStatus = 465 FLD_SET_DRF_NUM(_CHANNELGPFIFO, _NOTIFICATION_STATUS, _VALUE, status, notifyStatus); 466 467 NV_ASSERT_OK_OR_RETURN(kchannelUpdateNotifierMem(pKernelChannel, NV_CHANNELGPFIFO_NOTIFICATION_TYPE_KEY_ROTATION_STATUS, 468 0, 0, notifyStatus)); 469 NV_PRINTF(LEVEL_INFO, "chid 0x%x has pending key rotation, writing notifier with val 0x%x\n", kchannelGetDebugTag(pKernelChannel), (NvU32)notifyStatus); 470 471 // send events to clients if registered 472 kchannelNotifyEvent(pKernelChannel, NVC86F_NOTIFIERS_KEY_ROTATION, 0, status, NULL, 0); 473 } 474 return NV_OK; 475 } 476 477 static void 478 initKeyRotationRegistryOverrides 479 ( 480 OBJGPU *pGpu, 481 ConfidentialCompute *pConfCompute 482 ) 483 { 484 // 485 // Temp CONFCOMP-984: This will be removed once all RM clients support 486 // key rotation by default. 487 // 488 if (pConfCompute->getProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_KEY_ROTATION_SUPPORTED)) 489 { 490 NvU32 data; 491 if (osReadRegistryDword(pGpu, NV_REG_STR_RM_CONF_COMPUTE_DUMMY_KEY_ROTATION, &data) == NV_OK) 492 { 493 if (FLD_TEST_DRF(_REG_STR, _RM_CONF_COMPUTE_DUMMY_KEY_ROTATION, _ENABLED, _YES, data)) 494 { 495 NV_PRINTF(LEVEL_INFO, "Confidential Compute dummy key rotation enabled via regkey override.\n"); 496 pConfCompute->setProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_DUMMY_KEY_ROTATION_ENABLED, NV_TRUE); 497 } 498 else if (FLD_TEST_DRF(_REG_STR, _RM_CONF_COMPUTE_DUMMY_KEY_ROTATION, _ENABLED, _NO, data)) 499 { 500 NV_PRINTF(LEVEL_INFO, "Confidential Compute dummy key rotation disabled via regkey override.\n"); 501 pConfCompute->setProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_DUMMY_KEY_ROTATION_ENABLED, NV_FALSE); 502 } 503 if (pConfCompute->getProperty(pConfCompute, PDB_PROP_CONFCOMPUTE_DUMMY_KEY_ROTATION_ENABLED)) 504 { 505 pConfCompute->keyRotationEnableMask = data; 506 507 // 508 // Set lower and upper thresholds to default values 509 // this will go away once we stop supporting dummy KR 510 // 511 pConfCompute->lowerThreshold.totalBytesEncrypted = NV_U64_MAX; 512 pConfCompute->lowerThreshold.totalEncryptOps = KEY_ROTATION_LOWER_THRESHOLD; 513 pConfCompute->upperThreshold.totalBytesEncrypted = NV_U64_MAX; 514 pConfCompute->upperThreshold.totalEncryptOps = KEY_ROTATION_UPPER_THRESHOLD; 515 516 if (osReadRegistryDword(pGpu, NV_REG_STR_RM_CONF_COMPUTE_DUMMY_KEY_ROTATION_LOWER_THRESHOLD, &data) == NV_OK) 517 { 518 pConfCompute->lowerThreshold.totalEncryptOps = data; 519 } 520 521 if (osReadRegistryDword(pGpu, NV_REG_STR_RM_CONF_COMPUTE_DUMMY_KEY_ROTATION_UPPER_THRESHOLD, &data) == NV_OK) 522 { 523 pConfCompute->upperThreshold.totalEncryptOps = data; 524 } 525 } 526 } 527 } 528 }