1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2023 Intel Corporation 4 */ 5 6 #include <linux/align.h> 7 8 #include <drm/drm_managed.h> 9 10 #include "regs/xe_gt_regs.h" 11 #include "regs/xe_mert_regs.h" 12 13 #include "xe_assert.h" 14 #include "xe_bo.h" 15 #include "xe_tlb_inval.h" 16 #include "xe_lmtt.h" 17 #include "xe_map.h" 18 #include "xe_mert.h" 19 #include "xe_mmio.h" 20 #include "xe_res_cursor.h" 21 #include "xe_sriov.h" 22 #include "xe_tile.h" 23 #include "xe_tile_sriov_printk.h" 24 25 /** 26 * DOC: Local Memory Translation Table 27 * 28 * The Local Memory Translation Table (LMTT) provides additional abstraction 29 * when Virtual Function (VF) is accessing device Local Memory (VRAM). 30 * 31 * The Root LMTT Page Directory contains one entry for each VF. Entries are 32 * indexed by the function number (1-based, index 0 is unused). 33 * 34 * See `Two-Level LMTT Structure`_ and `Multi-Level LMTT Structure`_. 35 */ 36 37 #define lmtt_assert(lmtt, condition) xe_tile_assert(lmtt_to_tile(lmtt), condition) 38 #define lmtt_debug(lmtt, msg...) xe_tile_sriov_dbg_verbose(lmtt_to_tile(lmtt), "LMTT: " msg) 39 40 static bool xe_has_multi_level_lmtt(struct xe_device *xe) 41 { 42 return GRAPHICS_VERx100(xe) >= 1260; 43 } 44 45 static struct xe_tile *lmtt_to_tile(struct xe_lmtt *lmtt) 46 { 47 return container_of(lmtt, struct xe_tile, sriov.pf.lmtt); 48 } 49 50 static struct xe_device *lmtt_to_xe(struct xe_lmtt *lmtt) 51 { 52 return tile_to_xe(lmtt_to_tile(lmtt)); 53 } 54 55 static u64 lmtt_page_size(struct xe_lmtt *lmtt) 56 { 57 return BIT_ULL(lmtt->ops->lmtt_pte_shift(0)); 58 } 59 60 static struct xe_lmtt_pt *lmtt_pt_alloc(struct xe_lmtt *lmtt, unsigned int level) 61 { 62 unsigned int num_entries = level ? lmtt->ops->lmtt_pte_num(level) : 0; 63 struct xe_lmtt_pt *pt; 64 struct xe_bo *bo; 65 int err; 66 67 pt = kzalloc(struct_size(pt, entries, num_entries), GFP_KERNEL); 68 if (!pt) { 69 err = -ENOMEM; 70 goto out; 71 } 72 73 bo = xe_bo_create_pin_map_novm(lmtt_to_xe(lmtt), lmtt_to_tile(lmtt), 74 PAGE_ALIGN(lmtt->ops->lmtt_pte_size(level) * 75 lmtt->ops->lmtt_pte_num(level)), 76 ttm_bo_type_kernel, 77 XE_BO_FLAG_VRAM_IF_DGFX(lmtt_to_tile(lmtt)) | 78 XE_BO_FLAG_NEEDS_64K, false); 79 if (IS_ERR(bo)) { 80 err = PTR_ERR(bo); 81 goto out_free_pt; 82 } 83 84 lmtt_assert(lmtt, xe_bo_is_vram(bo)); 85 lmtt_debug(lmtt, "level=%u addr=%#llx\n", level, (u64)xe_bo_main_addr(bo, XE_PAGE_SIZE)); 86 87 xe_map_memset(lmtt_to_xe(lmtt), &bo->vmap, 0, 0, xe_bo_size(bo)); 88 89 pt->level = level; 90 pt->bo = bo; 91 return pt; 92 93 out_free_pt: 94 kfree(pt); 95 out: 96 return ERR_PTR(err); 97 } 98 99 static void lmtt_pt_free(struct xe_lmtt_pt *pt) 100 { 101 lmtt_debug(&pt->bo->tile->sriov.pf.lmtt, "level=%u addr=%llx\n", 102 pt->level, (u64)xe_bo_main_addr(pt->bo, XE_PAGE_SIZE)); 103 104 xe_bo_unpin_map_no_vm(pt->bo); 105 kfree(pt); 106 } 107 108 static int lmtt_init_pd(struct xe_lmtt *lmtt) 109 { 110 struct xe_lmtt_pt *pd; 111 112 lmtt_assert(lmtt, !lmtt->pd); 113 lmtt_assert(lmtt, lmtt->ops->lmtt_root_pd_level()); 114 115 pd = lmtt_pt_alloc(lmtt, lmtt->ops->lmtt_root_pd_level()); 116 if (IS_ERR(pd)) 117 return PTR_ERR(pd); 118 119 lmtt->pd = pd; 120 return 0; 121 } 122 123 static void lmtt_fini_pd(struct xe_lmtt *lmtt) 124 { 125 struct xe_lmtt_pt *pd = lmtt->pd; 126 unsigned int num_entries = lmtt->ops->lmtt_pte_num(pd->level); 127 unsigned int n = 0; 128 129 /* make sure we don't leak */ 130 for (n = 0; n < num_entries; n++) 131 lmtt_assert(lmtt, !pd->entries[n]); 132 133 lmtt->pd = NULL; 134 lmtt_pt_free(pd); 135 } 136 137 static void fini_lmtt(struct drm_device *drm, void *arg) 138 { 139 struct xe_lmtt *lmtt = arg; 140 141 lmtt_assert(lmtt, !(!!lmtt->ops ^ !!lmtt->pd)); 142 143 if (!lmtt->pd) 144 return; 145 146 lmtt_fini_pd(lmtt); 147 lmtt->ops = NULL; 148 } 149 150 /** 151 * xe_lmtt_init - LMTT software initialization. 152 * @lmtt: the &xe_lmtt to initialize 153 * 154 * The LMTT initialization requires two steps. 155 * 156 * The xe_lmtt_init() checks if LMTT is required on current device and selects 157 * and initialize proper variant of the LMTT Root Directory. Currently supported 158 * variants are `Two-Level LMTT Structure`_ and `Multi-Level LMTT Structure`_. 159 * 160 * In next step xe_lmtt_init_hw() will register this directory on the hardware. 161 * 162 * Notes: 163 * The LMTT allocations are managed and will be implicitly released on driver unload. 164 * This function shall be called only once and only when running as a PF driver. 165 * Any LMTT initialization failure should block VFs enabling. 166 * 167 * Return: 0 on success or a negative error code on failure. 168 */ 169 int xe_lmtt_init(struct xe_lmtt *lmtt) 170 { 171 struct xe_device *xe = lmtt_to_xe(lmtt); 172 int err; 173 174 lmtt_assert(lmtt, IS_SRIOV_PF(xe)); 175 lmtt_assert(lmtt, !lmtt->ops); 176 177 if (!xe_device_has_lmtt(xe)) 178 return 0; 179 180 if (xe_has_multi_level_lmtt(xe)) 181 lmtt->ops = &lmtt_ml_ops; 182 else 183 lmtt->ops = &lmtt_2l_ops; 184 185 err = lmtt_init_pd(lmtt); 186 if (unlikely(err)) 187 goto fail; 188 189 return drmm_add_action_or_reset(&xe->drm, fini_lmtt, lmtt); 190 191 fail: 192 lmtt->ops = NULL; 193 return err; 194 } 195 196 static void lmtt_setup_dir_ptr(struct xe_lmtt *lmtt) 197 { 198 struct xe_tile *tile = lmtt_to_tile(lmtt); 199 struct xe_device *xe = tile_to_xe(tile); 200 dma_addr_t offset = xe_bo_main_addr(lmtt->pd->bo, XE_PAGE_SIZE); 201 struct xe_gt *gt; 202 u32 config; 203 u8 id; 204 205 lmtt_debug(lmtt, "DIR offset %pad\n", &offset); 206 lmtt_assert(lmtt, xe_bo_is_vram(lmtt->pd->bo)); 207 lmtt_assert(lmtt, IS_ALIGNED(offset, SZ_64K)); 208 209 config = LMEM_EN | REG_FIELD_PREP(LMTT_DIR_PTR, offset / SZ_64K); 210 211 for_each_gt_on_tile(gt, tile, id) 212 xe_mmio_write32(>->mmio, 213 GRAPHICS_VER(xe) >= 20 ? XE2_LMEM_CFG : LMEM_CFG, 214 config); 215 216 if (xe_device_has_mert(xe) && xe_tile_is_root(tile)) 217 xe_mmio_write32(&tile->mmio, MERT_LMEM_CFG, config); 218 } 219 220 /** 221 * xe_lmtt_init_hw - Perform LMTT hardware initialization. 222 * @lmtt: the &xe_lmtt to initialize 223 * 224 * This function is a second step of the LMTT initialization. 225 * This function registers LMTT Root Directory prepared in xe_lmtt_init(). 226 * 227 * This function shall be called after every hardware reset. 228 * This function shall be called only when running as a PF driver. 229 */ 230 void xe_lmtt_init_hw(struct xe_lmtt *lmtt) 231 { 232 if (!lmtt->pd) 233 return; 234 235 lmtt_setup_dir_ptr(lmtt); 236 } 237 238 static int lmtt_invalidate_hw(struct xe_lmtt *lmtt) 239 { 240 struct xe_tlb_inval_fence fences[XE_MAX_GT_PER_TILE]; 241 struct xe_tlb_inval_fence *fence = fences; 242 struct xe_tile *tile = lmtt_to_tile(lmtt); 243 struct xe_gt *gt; 244 int result = 0; 245 int err; 246 u8 id; 247 248 for_each_gt_on_tile(gt, tile, id) { 249 xe_tlb_inval_fence_init(>->tlb_inval, fence, true); 250 err = xe_tlb_inval_all(>->tlb_inval, fence); 251 result = result ?: err; 252 fence++; 253 } 254 255 lmtt_debug(lmtt, "num_fences=%d err=%d\n", (int)(fence - fences), result); 256 257 /* 258 * It is fine to wait for all fences, even for those which covers the 259 * invalidation request that failed, as such fence should be already 260 * marked as signaled. 261 */ 262 fence = fences; 263 for_each_gt_on_tile(gt, tile, id) 264 xe_tlb_inval_fence_wait(fence++); 265 266 return result; 267 } 268 269 /** 270 * xe_lmtt_invalidate_hw - Invalidate LMTT hardware. 271 * @lmtt: the &xe_lmtt to invalidate 272 * 273 * Send requests to all GuCs on this tile to invalidate all TLBs. 274 * If the platform has a standalone MERT, also invalidate MERT's TLB. 275 * 276 * This function should be called only when running as a PF driver. 277 */ 278 void xe_lmtt_invalidate_hw(struct xe_lmtt *lmtt) 279 { 280 struct xe_tile *tile = lmtt_to_tile(lmtt); 281 struct xe_device *xe = lmtt_to_xe(lmtt); 282 int err; 283 284 lmtt_assert(lmtt, IS_SRIOV_PF(xe)); 285 286 err = lmtt_invalidate_hw(lmtt); 287 if (err) 288 xe_tile_sriov_err(tile, "LMTT invalidation failed (%pe)", 289 ERR_PTR(err)); 290 291 if (xe_device_has_mert(xe) && xe_tile_is_root(tile)) { 292 err = xe_mert_invalidate_lmtt(xe); 293 if (err) 294 xe_tile_sriov_err(tile, "MERT LMTT invalidation failed (%pe)", 295 ERR_PTR(err)); 296 } 297 } 298 299 static void lmtt_write_pte(struct xe_lmtt *lmtt, struct xe_lmtt_pt *pt, 300 u64 pte, unsigned int idx) 301 { 302 unsigned int level = pt->level; 303 304 lmtt_assert(lmtt, idx <= lmtt->ops->lmtt_pte_num(level)); 305 lmtt_debug(lmtt, "WRITE level=%u index=%u pte=%#llx\n", level, idx, pte); 306 307 switch (lmtt->ops->lmtt_pte_size(level)) { 308 case sizeof(u32): 309 lmtt_assert(lmtt, !overflows_type(pte, u32)); 310 lmtt_assert(lmtt, !pte || !iosys_map_rd(&pt->bo->vmap, idx * sizeof(u32), u32)); 311 312 xe_map_wr(lmtt_to_xe(lmtt), &pt->bo->vmap, idx * sizeof(u32), u32, pte); 313 break; 314 case sizeof(u64): 315 lmtt_assert(lmtt, !pte || !iosys_map_rd(&pt->bo->vmap, idx * sizeof(u64), u64)); 316 317 xe_map_wr(lmtt_to_xe(lmtt), &pt->bo->vmap, idx * sizeof(u64), u64, pte); 318 break; 319 default: 320 lmtt_assert(lmtt, !!!"invalid pte size"); 321 } 322 } 323 324 static void lmtt_destroy_pt(struct xe_lmtt *lmtt, struct xe_lmtt_pt *pd) 325 { 326 unsigned int num_entries = pd->level ? lmtt->ops->lmtt_pte_num(pd->level) : 0; 327 struct xe_lmtt_pt *pt; 328 unsigned int i; 329 330 for (i = 0; i < num_entries; i++) { 331 pt = pd->entries[i]; 332 pd->entries[i] = NULL; 333 if (!pt) 334 continue; 335 336 lmtt_destroy_pt(lmtt, pt); 337 } 338 339 lmtt_pt_free(pd); 340 } 341 342 static void lmtt_drop_pages(struct xe_lmtt *lmtt, unsigned int vfid) 343 { 344 struct xe_lmtt_pt *pd = lmtt->pd; 345 struct xe_lmtt_pt *pt; 346 347 pt = pd->entries[vfid]; 348 pd->entries[vfid] = NULL; 349 if (!pt) 350 return; 351 352 lmtt_write_pte(lmtt, pd, LMTT_PTE_INVALID, vfid); 353 lmtt_invalidate_hw(lmtt); 354 355 lmtt_assert(lmtt, pd->level > 0); 356 lmtt_assert(lmtt, pt->level == pd->level - 1); 357 lmtt_destroy_pt(lmtt, pt); 358 } 359 360 static int __lmtt_alloc_range(struct xe_lmtt *lmtt, struct xe_lmtt_pt *pd, 361 u64 start, u64 end) 362 { 363 u64 pte_addr_shift = BIT_ULL(lmtt->ops->lmtt_pte_shift(pd->level)); 364 u64 offset; 365 int err; 366 367 lmtt_assert(lmtt, pd->level > 0); 368 369 offset = start; 370 while (offset < end) { 371 struct xe_lmtt_pt *pt; 372 u64 next, pde, pt_addr; 373 unsigned int idx; 374 375 pt = lmtt_pt_alloc(lmtt, pd->level - 1); 376 if (IS_ERR(pt)) 377 return PTR_ERR(pt); 378 379 pt_addr = xe_bo_main_addr(pt->bo, XE_PAGE_SIZE); 380 381 idx = lmtt->ops->lmtt_pte_index(offset, pd->level); 382 pde = lmtt->ops->lmtt_pte_encode(pt_addr, pd->level); 383 384 lmtt_write_pte(lmtt, pd, pde, idx); 385 386 pd->entries[idx] = pt; 387 388 next = min(end, round_up(offset + 1, pte_addr_shift)); 389 390 if (pt->level != 0) { 391 err = __lmtt_alloc_range(lmtt, pt, offset, next); 392 if (err) 393 return err; 394 } 395 396 offset = next; 397 } 398 399 return 0; 400 } 401 402 static int lmtt_alloc_range(struct xe_lmtt *lmtt, unsigned int vfid, u64 start, u64 end) 403 { 404 struct xe_lmtt_pt *pd = lmtt->pd; 405 struct xe_lmtt_pt *pt; 406 u64 pt_addr; 407 u64 pde; 408 int err; 409 410 lmtt_assert(lmtt, pd->level > 0); 411 lmtt_assert(lmtt, vfid <= lmtt->ops->lmtt_pte_num(pd->level)); 412 lmtt_assert(lmtt, IS_ALIGNED(start, lmtt_page_size(lmtt))); 413 lmtt_assert(lmtt, IS_ALIGNED(end, lmtt_page_size(lmtt))); 414 415 if (pd->entries[vfid]) 416 return -ENOTEMPTY; 417 418 pt = lmtt_pt_alloc(lmtt, pd->level - 1); 419 if (IS_ERR(pt)) 420 return PTR_ERR(pt); 421 422 pt_addr = xe_bo_main_addr(pt->bo, XE_PAGE_SIZE); 423 424 pde = lmtt->ops->lmtt_pte_encode(pt_addr, pd->level); 425 426 lmtt_write_pte(lmtt, pd, pde, vfid); 427 428 pd->entries[vfid] = pt; 429 430 if (pt->level != 0) { 431 err = __lmtt_alloc_range(lmtt, pt, start, end); 432 if (err) 433 goto out_free_pt; 434 } 435 436 return 0; 437 438 out_free_pt: 439 lmtt_pt_free(pt); 440 return err; 441 } 442 443 static struct xe_lmtt_pt *lmtt_leaf_pt(struct xe_lmtt *lmtt, unsigned int vfid, u64 addr) 444 { 445 struct xe_lmtt_pt *pd = lmtt->pd; 446 struct xe_lmtt_pt *pt; 447 448 lmtt_assert(lmtt, vfid <= lmtt->ops->lmtt_pte_num(pd->level)); 449 pt = pd->entries[vfid]; 450 451 while (pt->level) { 452 lmtt_assert(lmtt, lmtt->ops->lmtt_pte_index(addr, pt->level) <= 453 lmtt->ops->lmtt_pte_num(pt->level)); 454 455 pt = pt->entries[lmtt->ops->lmtt_pte_index(addr, pt->level)]; 456 457 addr >>= lmtt->ops->lmtt_pte_shift(pt->level); 458 } 459 460 lmtt_assert(lmtt, lmtt->ops->lmtt_pte_index(addr, pt->level) <= 461 lmtt->ops->lmtt_pte_num(pt->level)); 462 lmtt_assert(lmtt, pt->level != pd->level); 463 lmtt_assert(lmtt, pt->level == 0); 464 return pt; 465 } 466 467 static void lmtt_insert_bo(struct xe_lmtt *lmtt, unsigned int vfid, struct xe_bo *bo, u64 start) 468 { 469 u64 page_size = lmtt_page_size(lmtt); 470 struct xe_res_cursor cur; 471 struct xe_lmtt_pt *pt; 472 u64 addr, vram_offset; 473 474 lmtt_assert(lmtt, IS_ALIGNED(start, page_size)); 475 lmtt_assert(lmtt, IS_ALIGNED(xe_bo_size(bo), page_size)); 476 lmtt_assert(lmtt, xe_bo_is_vram(bo)); 477 478 vram_offset = vram_region_gpu_offset(bo->ttm.resource); 479 xe_res_first(bo->ttm.resource, 0, xe_bo_size(bo), &cur); 480 while (cur.remaining) { 481 addr = xe_res_dma(&cur); 482 addr += vram_offset; /* XXX */ 483 484 pt = lmtt_leaf_pt(lmtt, vfid, start); 485 486 lmtt_write_pte(lmtt, pt, lmtt->ops->lmtt_pte_encode(addr, 0), 487 lmtt->ops->lmtt_pte_index(start, 0)); 488 489 xe_res_next(&cur, page_size); 490 start += page_size; 491 } 492 } 493 494 /** 495 * xe_lmtt_prepare_pages - Create VF's LMTT Page Tables. 496 * @lmtt: the &xe_lmtt to update 497 * @vfid: the VF identifier (1-based) 498 * @range: top range of LMEM offset to be supported 499 * 500 * This function creates empty LMTT page tables for given VF to support 501 * up to maximum #range LMEM offset. The LMTT page tables created by this 502 * function must be released using xe_lmtt_drop_pages() function. 503 * 504 * Notes: 505 * This function shall be called only after successful LMTT initialization. 506 * See xe_lmtt_init(). 507 * 508 * Return: 0 on success or a negative error code on failure. 509 */ 510 int xe_lmtt_prepare_pages(struct xe_lmtt *lmtt, unsigned int vfid, u64 range) 511 { 512 lmtt_assert(lmtt, lmtt->pd); 513 lmtt_assert(lmtt, vfid); 514 515 return lmtt_alloc_range(lmtt, vfid, 0, range); 516 } 517 518 /** 519 * xe_lmtt_populate_pages - Update VF's LMTT Page Table Entries. 520 * @lmtt: the &xe_lmtt to update 521 * @vfid: the VF identifier (1-based) 522 * @bo: the buffer object with LMEM allocation to be mapped 523 * @offset: the offset at which #bo should be mapped 524 * 525 * This function updates VF's LMTT entries to use given buffer object as a backstore. 526 * 527 * Notes: 528 * This function shall be called only after successful preparation of the 529 * VF's LMTT Page Tables. See xe_lmtt_prepare(). 530 * 531 * Return: 0 on success or a negative error code on failure. 532 */ 533 int xe_lmtt_populate_pages(struct xe_lmtt *lmtt, unsigned int vfid, struct xe_bo *bo, u64 offset) 534 { 535 lmtt_assert(lmtt, lmtt->pd); 536 lmtt_assert(lmtt, vfid); 537 538 lmtt_insert_bo(lmtt, vfid, bo, offset); 539 return 0; 540 } 541 542 /** 543 * xe_lmtt_drop_pages - Remove VF's LMTT Pages. 544 * @lmtt: the &xe_lmtt to update 545 * @vfid: the VF identifier (1-based) 546 * 547 * This function removes all LMTT Page Tables prepared by xe_lmtt_prepare_pages(). 548 * 549 * This function shall be called only after successful LMTT initialization. 550 * See xe_lmtt_init(). 551 */ 552 void xe_lmtt_drop_pages(struct xe_lmtt *lmtt, unsigned int vfid) 553 { 554 lmtt_assert(lmtt, lmtt->pd); 555 lmtt_assert(lmtt, vfid); 556 557 lmtt_drop_pages(lmtt, vfid); 558 } 559 560 /** 561 * xe_lmtt_estimate_pt_size - Estimate size of LMTT PT allocations. 562 * @lmtt: the &xe_lmtt 563 * @size: the size of the LMEM to be mapped over LMTT (including any offset) 564 * 565 * This function shall be called only by PF. 566 * 567 * Return: size of the PT allocation(s) needed to support given LMEM size. 568 */ 569 u64 xe_lmtt_estimate_pt_size(struct xe_lmtt *lmtt, u64 size) 570 { 571 unsigned int level = 0; 572 u64 pt_size; 573 574 lmtt_assert(lmtt, IS_SRIOV_PF(lmtt_to_xe(lmtt))); 575 lmtt_assert(lmtt, xe_device_has_lmtt(lmtt_to_xe(lmtt))); 576 lmtt_assert(lmtt, lmtt->ops); 577 578 pt_size = PAGE_ALIGN(lmtt->ops->lmtt_pte_size(level) * 579 lmtt->ops->lmtt_pte_num(level)); 580 581 while (++level < lmtt->ops->lmtt_root_pd_level()) { 582 pt_size *= lmtt->ops->lmtt_pte_index(size, level) + 1; 583 pt_size += PAGE_ALIGN(lmtt->ops->lmtt_pte_size(level) * 584 lmtt->ops->lmtt_pte_num(level)); 585 } 586 587 return pt_size; 588 } 589 590 #if IS_BUILTIN(CONFIG_DRM_XE_KUNIT_TEST) 591 #include "tests/xe_lmtt_test.c" 592 #endif 593