1 /******************************************************************************* 2 Copyright (c) 2021-2023 NVIDIA Corporation 3 4 Permission is hereby granted, free of charge, to any person obtaining a copy 5 of this software and associated documentation files (the "Software"), to 6 deal in the Software without restriction, including without limitation the 7 rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 sell copies of the Software, and to permit persons to whom the Software is 9 furnished to do so, subject to the following conditions: 10 11 The above copyright notice and this permission notice shall be 12 included in all copies or substantial portions of the Software. 13 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 DEALINGS IN THE SOFTWARE. 21 22 *******************************************************************************/ 23 24 #ifndef __UVM_CONF_COMPUTING_H__ 25 #define __UVM_CONF_COMPUTING_H__ 26 27 #include "nv_uvm_types.h" 28 #include "uvm_forward_decl.h" 29 #include "uvm_lock.h" 30 #include "uvm_tracker.h" 31 #include "uvm_va_block_types.h" 32 33 #include "linux/list.h" 34 35 #define UVM_CONF_COMPUTING_AUTH_TAG_SIZE (UVM_CSL_CRYPT_AUTH_TAG_SIZE_BYTES) 36 37 // An authentication tag pointer is required by HW to be 16-bytes aligned. 38 #define UVM_CONF_COMPUTING_AUTH_TAG_ALIGNMENT 16 39 40 // An IV pointer is required by HW to be 16-bytes aligned. 41 // 42 // Use sizeof(UvmCslIv) to refer to the IV size. 43 #define UVM_CONF_COMPUTING_IV_ALIGNMENT 16 44 45 // SEC2 decrypt operation buffers are required to be 16-bytes aligned. 46 #define UVM_CONF_COMPUTING_SEC2_BUF_ALIGNMENT 16 47 48 // CE encrypt/decrypt can be unaligned if the entire buffer lies in a single 49 // 32B segment. Otherwise, it needs to be 32B aligned. 50 #define UVM_CONF_COMPUTING_BUF_ALIGNMENT 32 51 52 #define UVM_CONF_COMPUTING_DMA_BUFFER_SIZE UVM_VA_BLOCK_SIZE 53 54 // SEC2 supports at most a stream of 64 entries in the method stream for 55 // signing. Each entry is made of the method address and method data, therefore 56 // the maximum buffer size is: UVM_METHOD_SIZE * 2 * 64 = 512. 57 // UVM, however, won't use this amount of entries, in the worst case scenario, 58 // we push a semaphore_releases or a decrypt. A SEC2 semaphore_release uses 6 1U 59 // entries, whereas a SEC2 decrypt uses 10 1U entries. For 10 entries, 60 // UVM_METHOD_SIZE * 2 * 10 = 80. 61 #define UVM_CONF_COMPUTING_SIGN_BUF_MAX_SIZE 80 62 63 // All GPUs derive confidential computing status from their parent. 64 // By current policy all parent GPUs have identical confidential 65 // computing status. 66 NV_STATUS uvm_conf_computing_init_parent_gpu(const uvm_parent_gpu_t *parent); 67 bool uvm_conf_computing_mode_enabled_parent(const uvm_parent_gpu_t *parent); 68 bool uvm_conf_computing_mode_enabled(const uvm_gpu_t *gpu); 69 bool uvm_conf_computing_mode_is_hcc(const uvm_gpu_t *gpu); 70 71 typedef struct 72 { 73 // List of free DMA buffers (uvm_conf_computing_dma_buffer_t). 74 // A free DMA buffer can be grabbed anytime, though the tracker 75 // inside it may still have pending work. 76 struct list_head free_dma_buffers; 77 78 // Used to grow the pool when full. 79 size_t num_dma_buffers; 80 81 // Lock protecting the dma_buffer_pool 82 uvm_mutex_t lock; 83 } uvm_conf_computing_dma_buffer_pool_t; 84 85 typedef struct 86 { 87 // Backing DMA allocation 88 uvm_mem_t *alloc; 89 90 // Used internally by the pool management code to track the state of 91 // a free buffer. 92 uvm_tracker_t tracker; 93 94 // When the DMA buffer is used as the destination of a GPU encryption, SEC2 95 // writes the authentication tag here. Later when the buffer is decrypted 96 // on the CPU the authentication tag is used again (read) for CSL to verify 97 // the authenticity. The allocation is big enough for one authentication 98 // tag per PAGE_SIZE page in the alloc buffer. 99 uvm_mem_t *auth_tag; 100 101 // CSL supports out-of-order decryption, the decrypt IV is used similarly 102 // to the authentication tag. The allocation is big enough for one IV per 103 // PAGE_SIZE page in the alloc buffer. The granularity between the decrypt 104 // IV and authentication tag must match. 105 UvmCslIv decrypt_iv[(UVM_CONF_COMPUTING_DMA_BUFFER_SIZE / PAGE_SIZE)]; 106 107 // Bitmap of the encrypted pages in the backing allocation 108 uvm_page_mask_t encrypted_page_mask; 109 110 // See uvm_conf_computing_dma_pool lists 111 struct list_head node; 112 } uvm_conf_computing_dma_buffer_t; 113 114 // Retrieve a DMA buffer from the given DMA allocation pool. 115 // NV_OK Stage buffer successfully retrieved 116 // NV_ERR_NO_MEMORY No free DMA buffers are available for grab, and 117 // expanding the memory pool to get new ones failed. 118 // 119 // out_dma_buffer is only valid if NV_OK is returned. The caller is responsible 120 // for calling uvm_conf_computing_dma_buffer_free once the operations on this 121 // buffer are done. 122 // When out_tracker is passed to the function, the buffer's dependencies are 123 // added to the tracker. The caller is guaranteed that all pending tracker 124 // entries come from the same GPU as the pool's owner. Before being able to use 125 // the DMA buffer, the caller is responsible for either acquiring or waiting 126 // on out_tracker. If out_tracker is NULL, the wait happens in the allocation 127 // itself. 128 // Upon success the encrypted_page_mask is cleared as part of the allocation. 129 NV_STATUS uvm_conf_computing_dma_buffer_alloc(uvm_conf_computing_dma_buffer_pool_t *dma_buffer_pool, 130 uvm_conf_computing_dma_buffer_t **out_dma_buffer, 131 uvm_tracker_t *out_tracker); 132 133 // Free a DMA buffer to the DMA allocation pool. All DMA buffers must be freed 134 // prior to GPU deinit. 135 // 136 // The tracker is optional and a NULL tracker indicates that no new operation 137 // has been pushed for the buffer. A non-NULL tracker indicates any additional 138 // pending operations on the buffer pushed by the caller that need to be 139 // synchronized before freeing or re-using the buffer. 140 void uvm_conf_computing_dma_buffer_free(uvm_conf_computing_dma_buffer_pool_t *dma_buffer_pool, 141 uvm_conf_computing_dma_buffer_t *dma_buffer, 142 uvm_tracker_t *tracker); 143 144 // Synchronize trackers in all entries in the GPU's DMA pool 145 void uvm_conf_computing_dma_buffer_pool_sync(uvm_conf_computing_dma_buffer_pool_t *dma_buffer_pool); 146 147 148 // Initialization and deinitialization of Confidential Computing data structures 149 // for the given GPU. 150 NV_STATUS uvm_conf_computing_gpu_init(uvm_gpu_t *gpu); 151 void uvm_conf_computing_gpu_deinit(uvm_gpu_t *gpu); 152 153 // Logs encryption information from the GPU and returns the IV. 154 void uvm_conf_computing_log_gpu_encryption(uvm_channel_t *channel, UvmCslIv *iv); 155 156 // Acquires next CPU encryption IV and returns it. 157 void uvm_conf_computing_acquire_encryption_iv(uvm_channel_t *channel, UvmCslIv *iv); 158 159 // CPU side encryption helper with explicit IV, which is obtained from 160 // uvm_conf_computing_acquire_encryption_iv. Without an explicit IV 161 // the function uses the next IV in order. Encrypts data in src_plain and 162 // write the cipher text in dst_cipher. src_plain and dst_cipher can't overlap. 163 // The IV is invalidated and can't be used again after this operation. 164 void uvm_conf_computing_cpu_encrypt(uvm_channel_t *channel, 165 void *dst_cipher, 166 const void *src_plain, 167 UvmCslIv *encrypt_iv, 168 size_t size, 169 void *auth_tag_buffer); 170 171 // CPU side decryption helper. Decrypts data from src_cipher and writes the 172 // plain text in dst_plain. src_cipher and dst_plain can't overlap. IV obtained 173 // from uvm_conf_computing_log_gpu_encryption() needs to be be passed to src_iv. 174 NV_STATUS uvm_conf_computing_cpu_decrypt(uvm_channel_t *channel, 175 void *dst_plain, 176 const void *src_cipher, 177 const UvmCslIv *src_iv, 178 size_t size, 179 const void *auth_tag_buffer); 180 #endif // __UVM_CONF_COMPUTING_H__ 181