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