1 /*******************************************************************************
2 Copyright (c) 2016-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_HAL_TYPES_H__
25 #define __UVM_HAL_TYPES_H__
26
27 #include "uvm_common.h"
28 #include "uvm_forward_decl.h"
29 #include "uvm_processors.h"
30
31 #define UVM_GPU_MMU_MAX_FAULT_PACKET_SIZE 32
32
33 typedef enum
34 {
35 UVM_APERTURE_PEER_0,
36 UVM_APERTURE_PEER_1,
37 UVM_APERTURE_PEER_2,
38 UVM_APERTURE_PEER_3,
39 UVM_APERTURE_PEER_4,
40 UVM_APERTURE_PEER_5,
41 UVM_APERTURE_PEER_6,
42 UVM_APERTURE_PEER_7,
43 UVM_APERTURE_PEER_MAX,
44 UVM_APERTURE_SYS,
45 UVM_APERTURE_VID,
46
47 // DEFAULT is a special value to let MMU pick the location of page tables
48 UVM_APERTURE_DEFAULT,
49
50 UVM_APERTURE_MAX
51 } uvm_aperture_t;
52
53 const char *uvm_aperture_string(uvm_aperture_t aperture);
54
uvm_aperture_is_peer(uvm_aperture_t aperture)55 static bool uvm_aperture_is_peer(uvm_aperture_t aperture)
56 {
57 return (aperture >= UVM_APERTURE_PEER_0) && (aperture < UVM_APERTURE_PEER_MAX);
58 }
59
UVM_APERTURE_PEER_ID(uvm_aperture_t aperture)60 static inline NvU32 UVM_APERTURE_PEER_ID(uvm_aperture_t aperture)
61 {
62 UVM_ASSERT(uvm_aperture_is_peer(aperture));
63
64 return (NvU32)aperture;
65 }
66
UVM_APERTURE_PEER(NvU32 id)67 static inline uvm_aperture_t UVM_APERTURE_PEER(NvU32 id)
68 {
69 uvm_aperture_t aperture = (uvm_aperture_t)id;
70
71 UVM_ASSERT(UVM_APERTURE_PEER_ID(aperture) == id);
72
73 return aperture;
74 }
75
76 // A physical GPU address
77 typedef struct
78 {
79 NvU64 address;
80
81 uvm_aperture_t aperture;
82 } uvm_gpu_phys_address_t;
83
84 // Create a physical GPU address
uvm_gpu_phys_address(uvm_aperture_t aperture,NvU64 address)85 static uvm_gpu_phys_address_t uvm_gpu_phys_address(uvm_aperture_t aperture, NvU64 address)
86 {
87 return (uvm_gpu_phys_address_t){ address, aperture };
88 }
89
90 // Compare two gpu physical addresses
uvm_gpu_phys_addr_cmp(uvm_gpu_phys_address_t a,uvm_gpu_phys_address_t b)91 static int uvm_gpu_phys_addr_cmp(uvm_gpu_phys_address_t a, uvm_gpu_phys_address_t b)
92 {
93 int result = UVM_CMP_DEFAULT(a.aperture, b.aperture);
94 if (result != 0)
95 return result;
96
97 return UVM_CMP_DEFAULT(a.address, b.address);
98 }
99
100 // A physical or virtual address directly accessible by a GPU.
101 // This implies that the address already went through identity mapping and IOMMU
102 // translations and is only valid for a specific GPU.
103 typedef struct
104 {
105 // Physical or virtual address
106 // In general, only valid for a specific GPU
107 NvU64 address;
108
109 // Aperture for a physical address
110 uvm_aperture_t aperture;
111
112 // Whether the address is virtual
113 bool is_virtual;
114
115 // Whether the address resides in a non-protected memory region when the
116 // Confidential Computing feature is enabled. Default is protected.
117 // Ignored if the feature is disabled and should not be used.
118 bool is_unprotected;
119 } uvm_gpu_address_t;
120
121 // Create a virtual GPU address
uvm_gpu_address_virtual(NvU64 va)122 static uvm_gpu_address_t uvm_gpu_address_virtual(NvU64 va)
123 {
124 uvm_gpu_address_t address = {0};
125 address.address = va;
126 address.aperture = UVM_APERTURE_MAX;
127 address.is_virtual = true;
128 return address;
129 }
130
uvm_gpu_address_virtual_unprotected(NvU64 va)131 static uvm_gpu_address_t uvm_gpu_address_virtual_unprotected(NvU64 va)
132 {
133 uvm_gpu_address_t address = uvm_gpu_address_virtual(va);
134 address.is_unprotected = true;
135 return address;
136 }
137
138 // Create a physical GPU address
uvm_gpu_address_physical(uvm_aperture_t aperture,NvU64 pa)139 static uvm_gpu_address_t uvm_gpu_address_physical(uvm_aperture_t aperture, NvU64 pa)
140 {
141 uvm_gpu_address_t address = {0};
142 address.aperture = aperture;
143 address.address = pa;
144 return address;
145 }
146
147 // Create a GPU address from a physical GPU address
uvm_gpu_address_from_phys(uvm_gpu_phys_address_t phys_address)148 static uvm_gpu_address_t uvm_gpu_address_from_phys(uvm_gpu_phys_address_t phys_address)
149 {
150 return uvm_gpu_address_physical(phys_address.aperture, phys_address.address);
151 }
152
uvm_gpu_address_aperture_string(uvm_gpu_address_t addr)153 static const char *uvm_gpu_address_aperture_string(uvm_gpu_address_t addr)
154 {
155 if (addr.is_virtual)
156 return "VIRTUAL";
157 return uvm_aperture_string(addr.aperture);
158 }
159
160 // Compare two gpu addresses
uvm_gpu_addr_cmp(uvm_gpu_address_t a,uvm_gpu_address_t b)161 static int uvm_gpu_addr_cmp(uvm_gpu_address_t a, uvm_gpu_address_t b)
162 {
163 int result = UVM_CMP_DEFAULT(a.is_virtual, b.is_virtual);
164 if (result != 0)
165 return result;
166
167 if (a.is_virtual) {
168 return UVM_CMP_DEFAULT(a.address, b.address);
169 }
170 else {
171 uvm_gpu_phys_address_t phys_a = { a.address, a.aperture };
172 uvm_gpu_phys_address_t phys_b = { b.address, b.aperture };
173
174 return uvm_gpu_phys_addr_cmp(phys_a, phys_b);
175 }
176 }
177
178 // For processors with no concept of an atomic fault (the CPU and pre-Pascal
179 // GPUs), UVM_PROT_READ_WRITE and UVM_PROT_READ_WRITE_ATOMIC are
180 // interchangeable.
181 typedef enum
182 {
183 UVM_PROT_NONE,
184 UVM_PROT_READ_ONLY,
185 UVM_PROT_READ_WRITE,
186 UVM_PROT_READ_WRITE_ATOMIC,
187 UVM_PROT_MAX
188 } uvm_prot_t;
189
190 const char *uvm_prot_string(uvm_prot_t prot);
191
192 typedef enum
193 {
194 UVM_MEMBAR_NONE,
195 UVM_MEMBAR_GPU,
196 UVM_MEMBAR_SYS,
197 } uvm_membar_t;
198
199 const char *uvm_membar_string(uvm_membar_t membar);
200
201 // Types of memory accesses that can cause a replayable fault on the GPU. They
202 // are ordered by access "intrusiveness" to simplify fault preprocessing (e.g.
203 // to implement fault coalescing)
204 typedef enum
205 {
206 UVM_FAULT_ACCESS_TYPE_PREFETCH = 0,
207 UVM_FAULT_ACCESS_TYPE_READ,
208 UVM_FAULT_ACCESS_TYPE_WRITE,
209 UVM_FAULT_ACCESS_TYPE_ATOMIC_WEAK,
210 UVM_FAULT_ACCESS_TYPE_ATOMIC_STRONG,
211 UVM_FAULT_ACCESS_TYPE_COUNT
212 } uvm_fault_access_type_t;
213
214 const char *uvm_fault_access_type_string(uvm_fault_access_type_t fault_access_type);
215
uvm_fault_access_type_mask_bit(uvm_fault_access_type_t fault_access_type)216 static NvU32 uvm_fault_access_type_mask_bit(uvm_fault_access_type_t fault_access_type)
217 {
218 BUILD_BUG_ON(UVM_FAULT_ACCESS_TYPE_COUNT >= 32);
219
220 UVM_ASSERT(fault_access_type >= 0);
221 UVM_ASSERT(fault_access_type < UVM_FAULT_ACCESS_TYPE_COUNT);
222
223 return (NvU32)1 << fault_access_type;
224 }
225
uvm_fault_access_type_mask_test(NvU32 mask,uvm_fault_access_type_t fault_access_type)226 static bool uvm_fault_access_type_mask_test(NvU32 mask, uvm_fault_access_type_t fault_access_type)
227 {
228 return uvm_fault_access_type_mask_bit(fault_access_type) & mask;
229 }
230
uvm_fault_access_type_mask_set(NvU32 * mask,uvm_fault_access_type_t fault_access_type)231 static void uvm_fault_access_type_mask_set(NvU32 *mask, uvm_fault_access_type_t fault_access_type)
232 {
233 *mask |= uvm_fault_access_type_mask_bit(fault_access_type);
234 }
235
uvm_fault_access_type_mask_highest(NvU32 mask)236 static uvm_fault_access_type_t uvm_fault_access_type_mask_highest(NvU32 mask)
237 {
238 int pos;
239
240 UVM_ASSERT((1 << UVM_FAULT_ACCESS_TYPE_COUNT) > mask);
241 UVM_ASSERT(mask != 0);
242
243 pos = __fls(mask);
244 UVM_ASSERT(pos < UVM_FAULT_ACCESS_TYPE_COUNT);
245
246 return pos;
247 }
248
uvm_fault_access_type_mask_lowest(NvU32 mask)249 static uvm_fault_access_type_t uvm_fault_access_type_mask_lowest(NvU32 mask)
250 {
251 int pos;
252
253 UVM_ASSERT((1 << UVM_FAULT_ACCESS_TYPE_COUNT) > mask);
254 UVM_ASSERT(mask != 0);
255
256 pos = __ffs(mask);
257 UVM_ASSERT(pos < UVM_FAULT_ACCESS_TYPE_COUNT);
258
259 return pos;
260 }
261
262 typedef enum
263 {
264 // Cancel all accesses on the page
265 UVM_FAULT_CANCEL_VA_MODE_ALL = 0,
266
267 // Cancel write and atomic accesses on the page
268 UVM_FAULT_CANCEL_VA_MODE_WRITE_AND_ATOMIC,
269
270 UVM_FAULT_CANCEL_VA_MODE_COUNT,
271 } uvm_fault_cancel_va_mode_t;
272
273 // Types of faults that can show up in the fault buffer. Non-UVM related faults
274 // are grouped in FATAL category since we don't care about the specific type.
275 typedef enum
276 {
277 UVM_FAULT_TYPE_INVALID_PDE = 0,
278 UVM_FAULT_TYPE_INVALID_PTE,
279 UVM_FAULT_TYPE_ATOMIC,
280
281 // WRITE to READ-ONLY
282 UVM_FAULT_TYPE_WRITE,
283
284 // READ to WRITE-ONLY (ATS)
285 UVM_FAULT_TYPE_READ,
286
287 // The next values are considered fatal and are not handled by the UVM
288 // driver
289 UVM_FAULT_TYPE_FATAL,
290
291 // Values required for tools
292 UVM_FAULT_TYPE_PDE_SIZE = UVM_FAULT_TYPE_FATAL,
293 UVM_FAULT_TYPE_VA_LIMIT_VIOLATION,
294 UVM_FAULT_TYPE_UNBOUND_INST_BLOCK,
295 UVM_FAULT_TYPE_PRIV_VIOLATION,
296 UVM_FAULT_TYPE_PITCH_MASK_VIOLATION,
297 UVM_FAULT_TYPE_WORK_CREATION,
298 UVM_FAULT_TYPE_UNSUPPORTED_APERTURE,
299 UVM_FAULT_TYPE_COMPRESSION_FAILURE,
300 UVM_FAULT_TYPE_UNSUPPORTED_KIND,
301 UVM_FAULT_TYPE_REGION_VIOLATION,
302 UVM_FAULT_TYPE_POISONED,
303
304 UVM_FAULT_TYPE_COUNT
305 } uvm_fault_type_t;
306
307 const char *uvm_fault_type_string(uvm_fault_type_t fault_type);
308
309 // Main MMU client type that triggered the fault
310 typedef enum
311 {
312 UVM_FAULT_CLIENT_TYPE_GPC = 0,
313 UVM_FAULT_CLIENT_TYPE_HUB,
314 UVM_FAULT_CLIENT_TYPE_COUNT
315 } uvm_fault_client_type_t;
316
317 const char *uvm_fault_client_type_string(uvm_fault_client_type_t fault_client_type);
318
319 typedef enum
320 {
321 UVM_MMU_ENGINE_TYPE_GRAPHICS = 0,
322 UVM_MMU_ENGINE_TYPE_HOST,
323 UVM_MMU_ENGINE_TYPE_CE,
324 UVM_MMU_ENGINE_TYPE_COUNT,
325 } uvm_mmu_engine_type_t;
326
327 typedef enum
328 {
329 // Allow entry to be fetched before the previous entry finishes ESCHED
330 // execution.
331 UVM_GPFIFO_SYNC_PROCEED = 0,
332
333 // Fetch of this entry has to wait until the previous entry has finished
334 // executing by ESCHED.
335 // For a complete engine sync the previous entry needs to include
336 // WAIT_FOR_IDLE command or other engine synchronization.
337 UVM_GPFIFO_SYNC_WAIT,
338 } uvm_gpfifo_sync_t;
339
340 const char *uvm_mmu_engine_type_string(uvm_mmu_engine_type_t mmu_engine_type);
341
342 // HW unit that triggered the fault. We include the fields required for fault
343 // cancelling. Including more information might be useful for performance
344 // heuristics in the future.
345 typedef struct
346 {
347 uvm_fault_client_type_t client_type : order_base_2(UVM_FAULT_CLIENT_TYPE_COUNT) + 1;
348
349 uvm_mmu_engine_type_t mmu_engine_type : order_base_2(UVM_MMU_ENGINE_TYPE_COUNT) + 1;
350
351 NvU16 client_id;
352
353 NvU16 mmu_engine_id;
354
355 union
356 {
357 struct
358 {
359 NvU16 utlb_id;
360
361 NvU8 gpc_id;
362 };
363
364 // TODO: Bug 3283289: the channel ID, which is only populated for
365 // non-replayable faults, is never consumed.
366 NvU16 channel_id;
367 };
368
369
370 // Identifier of the subcontext that caused the fault. HW uses it as an
371 // offset in the instance block to obtain the GPU VA space PDB of the
372 // faulting process.
373 NvU8 ve_id;
374 } uvm_fault_source_t;
375
376 struct uvm_fault_buffer_entry_struct
377 {
378 //
379 // The next fields are filled by the fault buffer parsing code
380 //
381
382 // Virtual address of the faulting request aligned to CPU page size
383 NvU64 fault_address;
384
385 // GPU timestamp in (nanoseconds) when the fault was inserted in the fault
386 // buffer
387 NvU64 timestamp;
388
389 uvm_gpu_phys_address_t instance_ptr;
390
391 uvm_fault_source_t fault_source;
392
393 uvm_fault_type_t fault_type : order_base_2(UVM_FAULT_TYPE_COUNT) + 1;
394
395 uvm_fault_access_type_t fault_access_type : order_base_2(UVM_FAULT_ACCESS_TYPE_COUNT) + 1;
396
397 //
398 // The next fields are managed by the fault handling code
399 //
400
401 uvm_va_space_t *va_space;
402
403 // This is set to true when some fault could not be serviced and a
404 // cancel command needs to be issued
405 bool is_fatal : 1;
406
407 // This is set to true for all GPU faults on a page that is thrashing
408 bool is_throttled : 1;
409
410 // This is set to true if the fault has prefetch access type and the
411 // address or the access privileges are not valid
412 bool is_invalid_prefetch : 1;
413
414 bool is_replayable : 1;
415
416 bool is_virtual : 1;
417
418 bool in_protected_mode : 1;
419
420 bool filtered : 1;
421
422 // Reason for the fault to be fatal
423 UvmEventFatalReason fatal_reason : order_base_2(UvmEventNumFatalReasons) + 1;
424
425 // Mode to be used to cancel faults. This must be set according to the
426 // fatal fault reason and the fault access types of the merged fault
427 // instances.
428 union
429 {
430 struct
431 {
432 uvm_fault_cancel_va_mode_t cancel_va_mode : order_base_2(UVM_FAULT_CANCEL_VA_MODE_COUNT) + 1;
433 } replayable;
434
435 struct
436 {
437 NvU32 buffer_index;
438 } non_replayable;
439 };
440
441 // List of duplicate fault buffer entries that have been merged into this
442 // one
443 struct list_head merged_instances_list;
444
445 // Access types to this page for all accesses that have been coalesced at
446 // fetch time. It must include, at least, fault_access_type
447 NvU32 access_type_mask;
448
449 // Number of faults with the same properties that have been coalesced at
450 // fetch time
451 NvU16 num_instances;
452 };
453
454 typedef enum
455 {
456 // Completes when all fault replays are in-flight
457 UVM_FAULT_REPLAY_TYPE_START = 0,
458
459 // Completes when all faulting accesses have been correctly translated or
460 // faulted again
461 UVM_FAULT_REPLAY_TYPE_START_ACK_ALL,
462
463 UVM_FAULT_REPLAY_TYPE_MAX
464 } uvm_fault_replay_type_t;
465
uvm_membar_max(uvm_membar_t membar_1,uvm_membar_t membar_2)466 static uvm_membar_t uvm_membar_max(uvm_membar_t membar_1, uvm_membar_t membar_2)
467 {
468 BUILD_BUG_ON(UVM_MEMBAR_NONE >= UVM_MEMBAR_GPU);
469 BUILD_BUG_ON(UVM_MEMBAR_GPU >= UVM_MEMBAR_SYS);
470 return max(membar_1, membar_2);
471 }
472
473 typedef enum
474 {
475 UVM_ACCESS_COUNTER_TYPE_MIMC = 0,
476 UVM_ACCESS_COUNTER_TYPE_MOMC,
477
478 UVM_ACCESS_COUNTER_TYPE_MAX,
479 } uvm_access_counter_type_t;
480
481 const char *uvm_access_counter_type_string(uvm_access_counter_type_t access_counter_type);
482
483 struct uvm_access_counter_buffer_entry_struct
484 {
485 // Whether this counter refers to outbound accesses to remote GPUs or
486 // sysmem (MIMC), or it refers to inbound accesses from CPU or a non-peer
487 // GPU (whose accesses are routed through the CPU, too) to vidmem (MOMC)
488 uvm_access_counter_type_t counter_type;
489
490 // Address of the region for which a notification was sent
491 uvm_gpu_address_t address;
492
493 // These fields are only valid if address.is_virtual is true
494 union
495 {
496 struct
497 {
498 // Instance pointer of one of the channels in the TSG that triggered
499 // the notification.
500 uvm_gpu_phys_address_t instance_ptr;
501
502 uvm_mmu_engine_type_t mmu_engine_type;
503
504 NvU32 mmu_engine_id;
505
506 // Identifier of the subcontext that performed the memory accesses
507 // that triggered the notification. This value, combined with the
508 // instance_ptr, is needed to obtain the GPU VA space of the process
509 // that triggered the notification.
510 NvU32 ve_id;
511
512 // VA space for the address that triggered the notification
513 uvm_va_space_t *va_space;
514 } virtual_info;
515
516 // These fields are only valid if address.is_virtual is false
517 struct
518 {
519 // Processor id where data is resident
520 //
521 // Although this information is not tied to a VA space, we can use
522 // a regular processor id because P2P is not allowed between
523 // partitioned GPUs.
524 uvm_processor_id_t resident_id;
525 } physical_info;
526 };
527
528 // Number of times the tracked region was accessed since the last time it
529 // was cleared. Counter values saturate at the maximum value supported by
530 // the GPU (2^16 - 1 in Volta)
531 NvU32 counter_value;
532
533 // When the granularity of the tracked regions is greater than 64KB, the
534 // region is split into 32 equal subregions. Each bit in this field
535 // represents one of those subregions. 1 means that the subregion has been
536 // accessed
537 NvU32 sub_granularity;
538
539 // Opaque fields provided by HW, required for targeted clear of a counter
540 NvU32 bank;
541 NvU32 tag;
542 };
543
uvm_fault_access_type_to_prot(uvm_fault_access_type_t access_type)544 static uvm_prot_t uvm_fault_access_type_to_prot(uvm_fault_access_type_t access_type)
545 {
546 switch (access_type) {
547 case UVM_FAULT_ACCESS_TYPE_ATOMIC_STRONG:
548 return UVM_PROT_READ_WRITE_ATOMIC;
549
550 case UVM_FAULT_ACCESS_TYPE_ATOMIC_WEAK:
551 case UVM_FAULT_ACCESS_TYPE_WRITE:
552 return UVM_PROT_READ_WRITE;
553
554 default:
555 // Prefetch faults, if not ignored, are handled like read faults and
556 // requirea mapping with, at least, READ_ONLY access permission.
557 return UVM_PROT_READ_ONLY;
558 }
559 }
560
561 #endif // __UVM_HAL_TYPES_H__
562