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