History

Merge tag 'drm-xe-next-2026-03-25' of https://gitlab.freedesktop.org/drm/xe/kernel into drm-next

Hi Dave and Sima, Here goes our third, perhaps, final drm-xe-next PR towards 7.1. In the big things we have: - THP support in drm_pagemap - xe_vm_get_property_ioctl Thanks, Matt UAPI Changes: - Implement xe_vm_get_property_ioctl (Jonathan) Cross-subsystem Changes: - Enable THP support in drm_pagemap (Francois, Brost) Core Changes: - Improve VF FLR synchronization for Xe VFIO (Piotr) Driver Changes: - Fix confusion with locals on context creation (Tomasz, Fixes) - Add new SVM copy GT stats per size (Francois) - always keep track of remap prev/next (Auld, Fixes) - AuxCCS handling and render compression modifiers (Tvrtko) - Implement recent spec updates to Wa_16025250150 (Roper) - xe3p_lpg: L2 flush optimization (Tejas) - vf: Improve getting clean NULL context (Wajdeczko) - pf: Fix use-after-free in migration restore (Winiarski. Fixes) - Fix format specifier for printing pointer differences (Nathan Chancellor, Fixes) - Extend Wa_14026781792 for xe3lpg (Niton) - xe3p_lpg: Add Wa_16029437861 (Varun) - Fix spelling mistakes and comment style in ttm_resource.c (Varun) - Merge drm/drm-next into drm-xe-next (Thomas) - Fix missing runtime PM reference in ccs_mode_store (Sanjay, Fixes) - Fix uninitialized new_ts when capturing context timestamp (Umesh) - Allow reading after disabling OA stream (Ashutosh) - Page Reclamation Fixes (Brian Nguyen, Fixes) - Include running dword offset in default_lrc dumps (Roper) - Assert/Deassert I2C IRQ (Raag) - Fixup reset, wedge, unload corner cases (Zhanjun, Brost) - Fail immediately on GuC load error (Daniele) - Fix kernel-doc for DRM_XE_VM_BIND_FLAG_DECOMPRESS (Niton, Fixes) - Drop redundant entries for Wa_16021867713 & Wa_14019449301 (Roper, Fixes)

Dave Airlie committed 7 months ago

Commit 72b585d2 parents 3f42072 3d4939c56 files · +1337 −290Browse files

Unified · Split

56 files
  1. drivers/gpu/drm/drm_gpusvm.c +5 −2
  2. drivers/gpu/drm/drm_pagemap.c +128 −29
  3. drivers/gpu/drm/ttm/ttm_resource.c +14 −14
  4. drivers/gpu/drm/xe/display/intel_fbdev_fb.c +8 −4
  5. drivers/gpu/drm/xe/display/xe_display.c +8 −0
  6. drivers/gpu/drm/xe/display/xe_display_bo.c +3 −3
  7. drivers/gpu/drm/xe/display/xe_dsb_buffer.c +3 −1
  8. drivers/gpu/drm/xe/display/xe_fb_pin.c +82 −30
  9. drivers/gpu/drm/xe/display/xe_initial_plane.c +1 −1
  10. drivers/gpu/drm/xe/instructions/xe_mi_commands.h +19 −0
  11. drivers/gpu/drm/xe/regs/xe_engine_regs.h +8 −0
  12. drivers/gpu/drm/xe/regs/xe_gt_regs.h +1 −0
  13. drivers/gpu/drm/xe/xe_bo.c +15 −9
  14. drivers/gpu/drm/xe/xe_bo.h +1 −1
  15. drivers/gpu/drm/xe/xe_device.c +33 −0
  16. drivers/gpu/drm/xe/xe_device.h +1 −0
  17. drivers/gpu/drm/xe/xe_ggtt.c +9 −6
  18. drivers/gpu/drm/xe/xe_gt.c +6 −3
  19. drivers/gpu/drm/xe/xe_gt_ccs_mode.c +2 −0
  20. drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c +62 −16
  21. drivers/gpu/drm/xe/xe_gt_sriov_pf_control.h +1 −0
  22. drivers/gpu/drm/xe/xe_gt_sriov_pf_control_types.h +2 −0
  23. drivers/gpu/drm/xe/xe_gt_stats.c +6 −0
  24. drivers/gpu/drm/xe/xe_gt_stats_types.h +6 −0
  25. drivers/gpu/drm/xe/xe_guc.c +30 −5
  26. drivers/gpu/drm/xe/xe_guc.h +1 −0
  27. drivers/gpu/drm/xe/xe_guc_ct.c +9 −15
  28. drivers/gpu/drm/xe/xe_guc_fwif.h +1 −0
  29. drivers/gpu/drm/xe/xe_guc_submit.c +62 −25
  30. drivers/gpu/drm/xe/xe_i2c.c +12 −3
  31. drivers/gpu/drm/xe/xe_lrc.c +66 −30
  32. drivers/gpu/drm/xe/xe_oa.c +5 −2
  33. drivers/gpu/drm/xe/xe_page_reclaim.c +26 −0
  34. drivers/gpu/drm/xe/xe_page_reclaim.h +3 −0
  35. drivers/gpu/drm/xe/xe_pagefault.c +32 −0
  36. drivers/gpu/drm/xe/xe_pat.c +7 −7
  37. drivers/gpu/drm/xe/xe_pat.h +3 −2
  38. drivers/gpu/drm/xe/xe_pt.c +35 −15
  39. drivers/gpu/drm/xe/xe_ring_ops.c +122 −21
  40. drivers/gpu/drm/xe/xe_ring_ops_types.h +7 −1
  41. drivers/gpu/drm/xe/xe_sched_job_types.h +2 −0
  42. drivers/gpu/drm/xe/xe_sriov_packet.c +2 −0
  43. drivers/gpu/drm/xe/xe_sriov_pf_control.c +24 −0
  44. drivers/gpu/drm/xe/xe_sriov_pf_control.h +1 −0
  45. drivers/gpu/drm/xe/xe_sriov_vfio.c +1 −0
  46. drivers/gpu/drm/xe/xe_svm.c +25 −2
  47. drivers/gpu/drm/xe/xe_uc.c +7 −15
  48. drivers/gpu/drm/xe/xe_vm.c +218 −5
  49. drivers/gpu/drm/xe/xe_vm.h +12 −0
  50. drivers/gpu/drm/xe/xe_vm_madvise.c +24 −1
  51. drivers/gpu/drm/xe/xe_vm_types.h +33 −0
  52. drivers/gpu/drm/xe/xe_wa.c +7 −20
  53. drivers/vfio/pci/xe/main.c +14 −0
  54. include/drm/drm_pagemap.h +21 −0
  55. include/drm/intel/xe_sriov_vfio.h +11 −0
  56. include/uapi/drm/xe_drm.h +90 −2
drivers/gpu/drm/drm_gpusvm.c+5−2
@@ -1488,12 +1488,15 @@ map_pages: · 1487 unmodified lines
14881488 order = drm_gpusvm_hmm_pfn_to_order(pfns[i], i, npages);
14891489 if (is_device_private_page(page) ||
14901490 is_device_coherent_page(page)) {
1491+ struct drm_pagemap_zdd *__zdd =
1492+ drm_pagemap_page_zone_device_data(page);
1493+
14911494 if (!ctx->allow_mixed &&
1492− zdd != page->zone_device_data && i > 0) {
1495+ zdd != __zdd && i > 0) {
14931496 err = -EOPNOTSUPP;
14941497 goto err_unmap;
14951498 }
1496− zdd = page->zone_device_data;
1499+ zdd = __zdd;
14971500 if (pagemap != page_pgmap(page)) {
14981501 if (pagemap) {
14991502 err = -EOPNOTSUPP;
drivers/gpu/drm/drm_pagemap.c+128−29
@@ -154,15 +154,15 @@ static void drm_pagemap_zdd_put(struct drm_pagemap_zdd *zdd) · 153 unmodified lines
154154 }
155155
156156 /**
157− * drm_pagemap_migration_unlock_put_page() - Put a migration page
158− * @page: Pointer to the page to put
157+ * drm_pagemap_migration_unlock_put_folio() - Put a migration folio
158+ * @folio: Pointer to the folio to put
159159 *
160− * This function unlocks and puts a page.
160+ * This function unlocks and puts a folio.
161161 */
162−static void drm_pagemap_migration_unlock_put_page(struct page *page)
162+static void drm_pagemap_migration_unlock_put_folio(struct folio *folio)
163163 {
164− unlock_page(page);
165− put_page(page);
164+ folio_unlock(folio);
165+ folio_put(folio);
166166 }
167167
168168 /**
@@ -177,31 +177,42 @@ static void drm_pagemap_migration_unlock_put_pages(unsigned long npages, · 8 unmodified lines
177177 {
178178 unsigned long i;
179179
180− for (i = 0; i < npages; ++i) {
180+ for (i = 0; i < npages;) {
181181 struct page *page;
182+ struct folio *folio;
183+ unsigned int order = 0;
182184
183185 if (!migrate_pfn[i])
184− continue;
186+ goto next;
185187
186188 page = migrate_pfn_to_page(migrate_pfn[i]);
187− drm_pagemap_migration_unlock_put_page(page);
189+ folio = page_folio(page);
190+ order = folio_order(folio);
191+
192+ drm_pagemap_migration_unlock_put_folio(folio);
188193 migrate_pfn[i] = 0;
194+
195+next:
196+ i += NR_PAGES(order);
189197 }
190198 }
191199
192200 /**
193201 * drm_pagemap_get_devmem_page() - Get a reference to a device memory page
194202 * @page: Pointer to the page
203+ * @order: Order
195204 * @zdd: Pointer to the GPU SVM zone device data
196205 *
197206 * This function associates the given page with the specified GPU SVM zone
198207 * device data and initializes it for zone device usage.
199208 */
200209 static void drm_pagemap_get_devmem_page(struct page *page,
210+ unsigned int order,
201211 struct drm_pagemap_zdd *zdd)
202212 {
203− page->zone_device_data = drm_pagemap_zdd_get(zdd);
204− zone_device_page_init(page, page_pgmap(page), 0);
213+ zone_device_folio_init((struct folio *)page, zdd->dpagemap->pagemap,
214+ order);
215+ folio_set_zone_device_data(page_folio(page), drm_pagemap_zdd_get(zdd));
205216 }
206217
207218 /**
@@ -244,7 +255,7 @@ static int drm_pagemap_migrate_map_pages(struct device *dev, · 36 unmodified lines
244255 order = folio_order(folio);
245256
246257 if (is_device_private_page(page)) {
247− struct drm_pagemap_zdd *zdd = page->zone_device_data;
258+ struct drm_pagemap_zdd *zdd = drm_pagemap_page_zone_device_data(page);
248259 struct drm_pagemap *dpagemap = zdd->dpagemap;
249260 struct drm_pagemap_addr addr;
250261
@@ -315,7 +326,7 @@ static void drm_pagemap_migrate_unmap_pages(struct device *dev, · 64 unmodified lines
315326 goto next;
316327
317328 if (is_zone_device_page(page)) {
318− struct drm_pagemap_zdd *zdd = page->zone_device_data;
329+ struct drm_pagemap_zdd *zdd = drm_pagemap_page_zone_device_data(page);
319330 struct drm_pagemap *dpagemap = zdd->dpagemap;
320331
321332 dpagemap->ops->device_unmap(dpagemap, dev, &pagemap_addr[i]);
@@ -444,6 +455,41 @@ out: · 122 unmodified lines
444455 return ret;
445456 }
446457
458+/**
459+ * drm_pagemap_cpages() - Count collected pages
460+ * @migrate_pfn: Array of migrate_pfn entries to account
461+ * @npages: Number of entries in @migrate_pfn
462+ *
463+ * Compute the total number of minimum-sized pages represented by the
464+ * collected entries in @migrate_pfn. The total is derived from the
465+ * order encoded in each entry.
466+ *
467+ * Return: Total number of minimum-sized pages.
468+ */
469+static int drm_pagemap_cpages(unsigned long *migrate_pfn, unsigned long npages)
470+{
471+ unsigned long i, cpages = 0;
472+
473+ for (i = 0; i < npages;) {
474+ struct page *page = migrate_pfn_to_page(migrate_pfn[i]);
475+ struct folio *folio;
476+ unsigned int order = 0;
477+
478+ if (page) {
479+ folio = page_folio(page);
480+ order = folio_order(folio);
481+ cpages += NR_PAGES(order);
482+ } else if (migrate_pfn[i] & MIGRATE_PFN_COMPOUND) {
483+ order = HPAGE_PMD_ORDER;
484+ cpages += NR_PAGES(order);
485+ }
486+
487+ i += NR_PAGES(order);
488+ }
489+
490+ return cpages;
491+}
492+
447493 /**
448494 * drm_pagemap_migrate_to_devmem() - Migrate a struct mm_struct range to device memory
449495 * @devmem_allocation: The device memory allocation to migrate to.
@@ -481,7 +527,7 @@ int drm_pagemap_migrate_to_devmem(struct drm_pagemap_devmem *devmem_allocation, · 31 unmodified lines
481527 .end = end,
482528 .pgmap_owner = pagemap->owner,
483529 .flags = MIGRATE_VMA_SELECT_SYSTEM | MIGRATE_VMA_SELECT_DEVICE_COHERENT |
484− MIGRATE_VMA_SELECT_DEVICE_PRIVATE,
530+ MIGRATE_VMA_SELECT_DEVICE_PRIVATE | MIGRATE_VMA_SELECT_COMPOUND,
485531 };
486532 unsigned long i, npages = npages_in_range(start, end);
487533 unsigned long own_pages = 0, migrated_pages = 0;
@@ -546,7 +592,8 @@ int drm_pagemap_migrate_to_devmem(struct drm_pagemap_devmem *devmem_allocation, · 58 unmodified lines
546592 goto err_free;
547593 }
548594
549− if (migrate.cpages != npages) {
595+ if (migrate.cpages != npages &&
596+ drm_pagemap_cpages(migrate.src, npages) != npages) {
550597 /*
551598 * Some pages to migrate. But we want to migrate all or
552599 * nothing. Raced or unknown device pages.
@@ -586,20 +633,23 @@ int drm_pagemap_migrate_to_devmem(struct drm_pagemap_devmem *devmem_allocation, · 33 unmodified lines
586633
587634 own_pages = 0;
588635
589− for (i = 0; i < npages; ++i) {
636+ for (i = 0; i < npages;) {
637+ unsigned long j;
590638 struct page *page = pfn_to_page(migrate.dst[i]);
591639 struct page *src_page = migrate_pfn_to_page(migrate.src[i]);
592− cur.start = i;
640+ unsigned int order = 0;
593641
642+ cur.start = i;
594643 pages[i] = NULL;
595644 if (src_page && is_device_private_page(src_page)) {
596− struct drm_pagemap_zdd *src_zdd = src_page->zone_device_data;
645+ struct drm_pagemap_zdd *src_zdd =
646+ drm_pagemap_page_zone_device_data(src_page);
597647
598648 if (page_pgmap(src_page) == pagemap &&
599649 !mdetails->can_migrate_same_pagemap) {
600650 migrate.dst[i] = 0;
601651 own_pages++;
602− continue;
652+ goto next;
603653 }
604654 if (mdetails->source_peer_migrates) {
605655 cur.dpagemap = src_zdd->dpagemap;
@@ -615,7 +665,20 @@ int drm_pagemap_migrate_to_devmem(struct drm_pagemap_devmem *devmem_allocation, · 9 unmodified lines
615665 pages[i] = page;
616666 }
617667 migrate.dst[i] = migrate_pfn(migrate.dst[i]);
618− drm_pagemap_get_devmem_page(page, zdd);
668+
669+ if (migrate.src[i] & MIGRATE_PFN_COMPOUND) {
670+ drm_WARN_ONCE(dpagemap->drm, src_page &&
671+ folio_order(page_folio(src_page)) != HPAGE_PMD_ORDER,
672+ "Unexpected folio order\n");
673+
674+ order = HPAGE_PMD_ORDER;
675+ migrate.dst[i] |= MIGRATE_PFN_COMPOUND;
676+
677+ for (j = 1; j < NR_PAGES(order) && i + j < npages; j++)
678+ migrate.dst[i + j] = 0;
679+ }
680+
681+ drm_pagemap_get_devmem_page(page, order, zdd);
619682
620683 /* If we switched the migrating drm_pagemap, migrate previous pages now */
621684 err = drm_pagemap_migrate_range(devmem_allocation, migrate.src, migrate.dst,
@@ -625,7 +688,11 @@ int drm_pagemap_migrate_to_devmem(struct drm_pagemap_devmem *devmem_allocation, · 3 unmodified lines
625688 npages = i + 1;
626689 goto err_finalize;
627690 }
691+
692+next:
693+ i += NR_PAGES(order);
628694 }
695+
629696 cur.start = npages;
630697 cur.ops = NULL; /* Force migration */
631698 err = drm_pagemap_migrate_range(devmem_allocation, migrate.src, migrate.dst,
@@ -715,8 +782,8 @@ static int drm_pagemap_migrate_populate_ram_pfn(struct vm_area_struct *vas, · 83 unmodified lines
715782 goto next;
716783
717784 if (fault_page) {
718− if (src_page->zone_device_data !=
719− fault_page->zone_device_data)
785+ if (drm_pagemap_page_zone_device_data(src_page) !=
786+ drm_pagemap_page_zone_device_data(fault_page))
720787 goto next;
721788 }
722789
@@ -734,6 +801,8 @@ static int drm_pagemap_migrate_populate_ram_pfn(struct vm_area_struct *vas, · 11 unmodified lines
734801 page = folio_page(folio, 0);
735802 mpfn[i] = migrate_pfn(page_to_pfn(page));
736803
804+ if (order)
805+ mpfn[i] |= MIGRATE_PFN_COMPOUND;
737806 next:
738807 if (page)
739808 addr += page_size(page);
@@ -989,8 +1058,15 @@ retry: · 249 unmodified lines
9891058 if (err)
9901059 goto err_finalize;
9911060
992− for (i = 0; i < npages; ++i)
1061+ for (i = 0; i < npages;) {
1062+ unsigned int order = 0;
1063+
9931064 pages[i] = migrate_pfn_to_page(src[i]);
1065+ if (pages[i])
1066+ order = folio_order(page_folio(pages[i]));
1067+
1068+ i += NR_PAGES(order);
1069+ }
9941070
9951071 err = ops->copy_to_ram(pages, pagemap_addr, npages, NULL);
9961072 if (err)
@@ -1043,7 +1119,8 @@ static int __drm_pagemap_migrate_to_ram(struct vm_area_struct *vas, · 46 unmodified lines
10431119 .vma = vas,
10441120 .pgmap_owner = page_pgmap(page)->owner,
10451121 .flags = MIGRATE_VMA_SELECT_DEVICE_PRIVATE |
1046− MIGRATE_VMA_SELECT_DEVICE_COHERENT,
1122+ MIGRATE_VMA_SELECT_DEVICE_COHERENT |
1123+ MIGRATE_VMA_SELECT_COMPOUND,
10471124 .fault_page = page,
10481125 };
10491126 struct drm_pagemap_migrate_details mdetails = {};
@@ -1057,7 +1134,7 @@ static int __drm_pagemap_migrate_to_ram(struct vm_area_struct *vas, · 7 unmodified lines
10571134 void *buf;
10581135 int i, err = 0;
10591136
1060− zdd = page->zone_device_data;
1137+ zdd = drm_pagemap_page_zone_device_data(page);
10611138 if (time_before64(get_jiffies_64(), zdd->devmem_allocation->timeslice_expiration))
10621139 return 0;
10631140
@@ -1109,8 +1186,15 @@ static int __drm_pagemap_migrate_to_ram(struct vm_area_struct *vas, · 45 unmodified lines
11091186 if (err)
11101187 goto err_finalize;
11111188
1112− for (i = 0; i < npages; ++i)
1189+ for (i = 0; i < npages;) {
1190+ unsigned int order = 0;
1191+
11131192 pages[i] = migrate_pfn_to_page(migrate.src[i]);
1193+ if (pages[i])
1194+ order = folio_order(page_folio(pages[i]));
1195+
1196+ i += NR_PAGES(order);
1197+ }
11141198
11151199 err = ops->copy_to_ram(pages, pagemap_addr, npages, NULL);
11161200 if (err)
@@ -1140,7 +1224,9 @@ err_out: · 23 unmodified lines
11401224 */
11411225 static void drm_pagemap_folio_free(struct folio *folio)
11421226 {
1143− drm_pagemap_zdd_put(folio->page.zone_device_data);
1227+ struct page *page = folio_page(folio, 0);
1228+
1229+ drm_pagemap_zdd_put(drm_pagemap_page_zone_device_data(page));
11441230 }
11451231
11461232 /**
@@ -1156,7 +1242,7 @@ static void drm_pagemap_folio_free(struct folio *folio) · 9 unmodified lines
11561242 */
11571243 static vm_fault_t drm_pagemap_migrate_to_ram(struct vm_fault *vmf)
11581244 {
1159− struct drm_pagemap_zdd *zdd = vmf->page->zone_device_data;
1245+ struct drm_pagemap_zdd *zdd = drm_pagemap_page_zone_device_data(vmf->page);
11601246 int err;
11611247
11621248 err = __drm_pagemap_migrate_to_ram(vmf->vma,
@@ -1166,9 +1252,22 @@ static vm_fault_t drm_pagemap_migrate_to_ram(struct vm_fault *vmf) · 3 unmodified lines
11661252 return err ? VM_FAULT_SIGBUS : 0;
11671253 }
11681254
1255+static void drm_pagemap_folio_split(struct folio *orig_folio, struct folio *new_folio)
1256+{
1257+ struct drm_pagemap_zdd *zdd;
1258+
1259+ if (!new_folio)
1260+ return;
1261+
1262+ new_folio->pgmap = orig_folio->pgmap;
1263+ zdd = folio_zone_device_data(orig_folio);
1264+ folio_set_zone_device_data(new_folio, drm_pagemap_zdd_get(zdd));
1265+}
1266+
11691267 static const struct dev_pagemap_ops drm_pagemap_pagemap_ops = {
11701268 .folio_free = drm_pagemap_folio_free,
11711269 .migrate_to_ram = drm_pagemap_migrate_to_ram,
1270+ .folio_split = drm_pagemap_folio_split,
11721271 };
11731272
11741273 /**
@@ -1222,7 +1321,7 @@ EXPORT_SYMBOL_GPL(drm_pagemap_devmem_init); · 47 unmodified lines
12221321 */
12231322 struct drm_pagemap *drm_pagemap_page_to_dpagemap(struct page *page)
12241323 {
1225− struct drm_pagemap_zdd *zdd = page->zone_device_data;
1324+ struct drm_pagemap_zdd *zdd = drm_pagemap_page_zone_device_data(page);
12261325
12271326 return zdd->devmem_allocation->dpagemap;
12281327 }
drivers/gpu/drm/ttm/ttm_resource.c+14−14
@@ -37,7 +37,7 @@ · 36 unmodified lines
3737 #include <drm/drm_print.h>
3838 #include <drm/drm_util.h>
3939
40−/* Detach the cursor from the bulk move list*/
40+/* Detach the cursor from the bulk move list */
4141 static void
4242 ttm_resource_cursor_clear_bulk(struct ttm_resource_cursor *cursor)
4343 {
@@ -105,9 +105,9 @@ void ttm_resource_cursor_init(struct ttm_resource_cursor *cursor, · 61 unmodified lines
105105 * ttm_resource_cursor_fini() - Finalize the LRU list cursor usage
106106 * @cursor: The struct ttm_resource_cursor to finalize.
107107 *
108− * The function pulls the LRU list cursor off any lists it was previusly
108+ * The function pulls the LRU list cursor off any lists it was previously
109109 * attached to. Needs to be called with the LRU lock held. The function
110− * can be called multiple times after eachother.
110+ * can be called multiple times after each other.
111111 */
112112 void ttm_resource_cursor_fini(struct ttm_resource_cursor *cursor)
113113 {
@@ -317,10 +317,10 @@ void ttm_resource_move_to_lru_tail(struct ttm_resource *res) · 203 unmodified lines
317317 }
318318
319319 /**
320− * ttm_resource_init - resource object constructure
321− * @bo: buffer object this resources is allocated for
320+ * ttm_resource_init - resource object constructor
321+ * @bo: buffer object this resource is allocated for
322322 * @place: placement of the resource
323− * @res: the resource object to inistilize
323+ * @res: the resource object to initialize
324324 *
325325 * Initialize a new resource object. Counterpart of ttm_resource_fini().
326326 */
@@ -435,7 +435,7 @@ EXPORT_SYMBOL(ttm_resource_free); · 108 unmodified lines
435435 * @size: How many bytes the new allocation needs.
436436 *
437437 * Test if @res intersects with @place and @size. Used for testing if evictions
438− * are valueable or not.
438+ * are valuable or not.
439439 *
440440 * Returns true if the res placement intersects with @place and @size.
441441 */
@@ -513,7 +513,7 @@ void ttm_resource_set_bo(struct ttm_resource *res, · 71 unmodified lines
513513 * @bdev: ttm device this manager belongs to
514514 * @size: size of managed resources in arbitrary units
515515 *
516− * Initialise core parts of a manager object.
516+ * Initialize core parts of a manager object.
517517 */
518518 void ttm_resource_manager_init(struct ttm_resource_manager *man,
519519 struct ttm_device *bdev,
@@ -536,8 +536,8 @@ EXPORT_SYMBOL(ttm_resource_manager_init); · 16 unmodified lines
536536 /*
537537 * ttm_resource_manager_evict_all
538538 *
539− * @bdev - device to use
540− * @man - manager to use
539+ * @bdev: device to use
540+ * @man: manager to use
541541 *
542542 * Evict all the objects out of a memory manager until it is empty.
543543 * Part of memory manager cleanup sequence.
@@ -882,7 +882,7 @@ out_err: · 338 unmodified lines
882882
883883 /**
884884 * ttm_kmap_iter_linear_io_fini - Clean up an iterator for linear io memory
885− * @iter_io: The iterator to initialize
885+ * @iter_io: The iterator to finalize
886886 * @bdev: The TTM device
887887 * @mem: The ttm resource representing the iomap.
888888 *
@@ -921,15 +921,15 @@ DEFINE_SHOW_ATTRIBUTE(ttm_resource_manager); · 32 unmodified lines
921921 /**
922922 * ttm_resource_manager_create_debugfs - Create debugfs entry for specified
923923 * resource manager.
924− * @man: The TTM resource manager for which the debugfs stats file be creates
924+ * @man: The TTM resource manager for which the debugfs stats file to be created
925925 * @parent: debugfs directory in which the file will reside
926926 * @name: The filename to create.
927927 *
928− * This function setups up a debugfs file that can be used to look
928+ * This function sets up a debugfs file that can be used to look
929929 * at debug statistics of the specified ttm_resource_manager.
930930 */
931931 void ttm_resource_manager_create_debugfs(struct ttm_resource_manager *man,
932− struct dentry * parent,
932+ struct dentry *parent,
933933 const char *name)
934934 {
935935 #if defined(CONFIG_DEBUG_FS)
drivers/gpu/drm/xe/display/intel_fbdev_fb.c+8−4
@@ -56,9 +56,11 @@ struct drm_gem_object *intel_fbdev_fb_bo_create(struct drm_device *drm, int size · 55 unmodified lines
5656 if (intel_fbdev_fb_prefer_stolen(drm, size)) {
5757 obj = xe_bo_create_pin_map_novm(xe, xe_device_get_root_tile(xe),
5858 size,
59− ttm_bo_type_kernel, XE_BO_FLAG_SCANOUT |
59+ ttm_bo_type_kernel,
60+ XE_BO_FLAG_FORCE_WC |
6061 XE_BO_FLAG_STOLEN |
61− XE_BO_FLAG_GGTT, false);
62+ XE_BO_FLAG_GGTT,
63+ false);
6264 if (!IS_ERR(obj))
6365 drm_info(&xe->drm, "Allocated fbdev into stolen\n");
6466 else
@@ -69,9 +71,11 @@ struct drm_gem_object *intel_fbdev_fb_bo_create(struct drm_device *drm, int size · 4 unmodified lines
6971
7072 if (IS_ERR(obj)) {
7173 obj = xe_bo_create_pin_map_novm(xe, xe_device_get_root_tile(xe), size,
72− ttm_bo_type_kernel, XE_BO_FLAG_SCANOUT |
74+ ttm_bo_type_kernel,
75+ XE_BO_FLAG_FORCE_WC |
7376 XE_BO_FLAG_VRAM_IF_DGFX(xe_device_get_root_tile(xe)) |
74− XE_BO_FLAG_GGTT, false);
77+ XE_BO_FLAG_GGTT,
78+ false);
7579 }
7680
7781 if (IS_ERR(obj)) {
drivers/gpu/drm/xe/display/xe_display.c+8−0
@@ -541,6 +541,13 @@ static const struct intel_display_irq_interface xe_display_irq_interface = { · 540 unmodified lines
541541 .synchronize = irq_synchronize,
542542 };
543543
544+static bool has_auxccs(struct drm_device *drm)
545+{
546+ struct xe_device *xe = to_xe_device(drm);
547+
548+ return xe->info.platform == XE_ALDERLAKE_P;
549+}
550+
544551 static const struct intel_display_parent_interface parent = {
545552 .bo = &xe_display_bo_interface,
546553 .dsb = &xe_display_dsb_interface,
@@ -552,6 +559,7 @@ static const struct intel_display_parent_interface parent = { · 5 unmodified lines
552559 .pcode = &xe_display_pcode_interface,
553560 .rpm = &xe_display_rpm_interface,
554561 .stolen = &xe_display_stolen_interface,
562+ .has_auxccs = has_auxccs,
555563 };
556564
557565 /**
drivers/gpu/drm/xe/display/xe_display_bo.c+3−3
@@ -42,9 +42,9 @@ static int xe_display_bo_framebuffer_init(struct drm_gem_object *obj, · 41 unmodified lines
4242 if (ret)
4343 goto err;
4444
45− if (!(bo->flags & XE_BO_FLAG_SCANOUT)) {
45+ if (!(bo->flags & XE_BO_FLAG_FORCE_WC)) {
4646 /*
47− * XE_BO_FLAG_SCANOUT should ideally be set at creation, or is
47+ * XE_BO_FLAG_FORCE_WC should ideally be set at creation, or is
4848 * automatically set when creating FB. We cannot change caching
4949 * mode when the bo is VM_BINDed, so we can only set
5050 * coherency with display when unbound.
@@ -54,7 +54,7 @@ static int xe_display_bo_framebuffer_init(struct drm_gem_object *obj, · 3 unmodified lines
5454 ret = -EINVAL;
5555 goto err;
5656 }
57− bo->flags |= XE_BO_FLAG_SCANOUT;
57+ bo->flags |= XE_BO_FLAG_FORCE_WC;
5858 }
5959 ttm_bo_unreserve(&bo->ttm);
6060 return 0;
drivers/gpu/drm/xe/display/xe_dsb_buffer.c+3−1
@@ -54,7 +54,9 @@ static struct intel_dsb_buffer *xe_dsb_buffer_create(struct drm_device *drm, siz · 53 unmodified lines
5454 PAGE_ALIGN(size),
5555 ttm_bo_type_kernel,
5656 XE_BO_FLAG_VRAM_IF_DGFX(xe_device_get_root_tile(xe)) |
57− XE_BO_FLAG_SCANOUT | XE_BO_FLAG_GGTT, false);
57+ XE_BO_FLAG_FORCE_WC |
58+ XE_BO_FLAG_GGTT,
59+ false);
5860 if (IS_ERR(obj)) {
5961 ret = PTR_ERR(obj);
6062 goto err_pin_map;
drivers/gpu/drm/xe/display/xe_fb_pin.c+82−30
@@ -49,33 +49,94 @@ write_dpt_rotated(struct xe_bo *bo, struct iosys_map *map, u32 *dpt_ofs, u32 bo_ · 48 unmodified lines
4949 *dpt_ofs = ALIGN(*dpt_ofs, 4096);
5050 }
5151
52−static void
53−write_dpt_remapped(struct xe_bo *bo, struct iosys_map *map, u32 *dpt_ofs,
54− u32 bo_ofs, u32 width, u32 height, u32 src_stride,
55− u32 dst_stride)
52+static unsigned int
53+write_dpt_padding(struct iosys_map *map, unsigned int dest, unsigned int pad)
54+{
55+ /* The DE ignores the PTEs for the padding tiles */
56+ return dest + pad * sizeof(u64);
57+}
58+
59+static unsigned int
60+write_dpt_remapped_linear(struct xe_bo *bo, struct iosys_map *map,
61+ unsigned int dest,
62+ const struct intel_remapped_plane_info *plane)
5663 {
5764 struct xe_device *xe = xe_bo_device(bo);
5865 struct xe_ggtt *ggtt = xe_device_get_root_tile(xe)->mem.ggtt;
59− u32 column, row;
60− u64 pte = xe_ggtt_encode_pte_flags(ggtt, bo, xe->pat.idx[XE_CACHE_NONE]);
66+ const u64 pte = xe_ggtt_encode_pte_flags(ggtt, bo,
67+ xe->pat.idx[XE_CACHE_NONE]);
68+ unsigned int offset = plane->offset * XE_PAGE_SIZE;
69+ unsigned int size = plane->size;
6170
62− for (row = 0; row < height; row++) {
63− u32 src_idx = src_stride * row + bo_ofs;
71+ while (size--) {
72+ u64 addr = xe_bo_addr(bo, offset, XE_PAGE_SIZE);
6473
65− for (column = 0; column < width; column++) {
66− u64 addr = xe_bo_addr(bo, src_idx * XE_PAGE_SIZE, XE_PAGE_SIZE);
67− iosys_map_wr(map, *dpt_ofs, u64, pte | addr);
74+ iosys_map_wr(map, dest, u64, addr | pte);
75+ dest += sizeof(u64);
76+ offset += XE_PAGE_SIZE;
77+ }
6878
69− *dpt_ofs += 8;
70− src_idx++;
79+ return dest;
80+}
81+
82+static unsigned int
83+write_dpt_remapped_tiled(struct xe_bo *bo, struct iosys_map *map,
84+ unsigned int dest,
85+ const struct intel_remapped_plane_info *plane)
86+{
87+ struct xe_device *xe = xe_bo_device(bo);
88+ struct xe_ggtt *ggtt = xe_device_get_root_tile(xe)->mem.ggtt;
89+ const u64 pte = xe_ggtt_encode_pte_flags(ggtt, bo,
90+ xe->pat.idx[XE_CACHE_NONE]);
91+ unsigned int offset, column, row;
92+
93+ for (row = 0; row < plane->height; row++) {
94+ offset = (plane->offset + plane->src_stride * row) *
95+ XE_PAGE_SIZE;
96+
97+ for (column = 0; column < plane->width; column++) {
98+ u64 addr = xe_bo_addr(bo, offset, XE_PAGE_SIZE);
99+
100+ iosys_map_wr(map, dest, u64, addr | pte);
101+ dest += sizeof(u64);
102+ offset += XE_PAGE_SIZE;
71103 }
72104
73− /* The DE ignores the PTEs for the padding tiles */
74− *dpt_ofs += (dst_stride - width) * 8;
105+ dest = write_dpt_padding(map, dest,
106+ plane->dst_stride - plane->width);
75107 }
76108
77− /* Align to next page */
78− *dpt_ofs = ALIGN(*dpt_ofs, 4096);
109+ return dest;
110+}
111+
112+static void
113+write_dpt_remapped(struct xe_bo *bo,
114+ const struct intel_remapped_info *remap_info,
115+ struct iosys_map *map)
116+{
117+ unsigned int i, dest = 0;
118+
119+ for (i = 0; i < ARRAY_SIZE(remap_info->plane); i++) {
120+ const struct intel_remapped_plane_info *plane =
121+ &remap_info->plane[i];
122+
123+ if (!plane->linear && !plane->width && !plane->height)
124+ continue;
125+
126+ if (dest && remap_info->plane_alignment) {
127+ const unsigned int index = dest / sizeof(u64);
128+ const unsigned int pad =
129+ ALIGN(index, remap_info->plane_alignment) -
130+ index;
131+
132+ dest = write_dpt_padding(map, dest, pad);
133+ }
134+
135+ if (plane->linear)
136+ dest = write_dpt_remapped_linear(bo, map, dest, plane);
137+ else
138+ dest = write_dpt_remapped_tiled(bo, map, dest, plane);
139+ }
79140 }
80141
81142 static int __xe_pin_fb_vma_dpt(const struct intel_framebuffer *fb,
@@ -122,7 +183,8 @@ static int __xe_pin_fb_vma_dpt(const struct intel_framebuffer *fb, · 40 unmodified lines
122183 ttm_bo_type_kernel,
123184 XE_BO_FLAG_SYSTEM |
124185 XE_BO_FLAG_GGTT |
125− XE_BO_FLAG_PAGETABLE,
186+ XE_BO_FLAG_PAGETABLE |
187+ XE_BO_FLAG_FORCE_WC,
126188 alignment, false);
127189 if (IS_ERR(dpt))
128190 return PTR_ERR(dpt);
@@ -137,17 +199,7 @@ static int __xe_pin_fb_vma_dpt(const struct intel_framebuffer *fb, · 8 unmodified lines
137199 iosys_map_wr(&dpt->vmap, x * 8, u64, pte | addr);
138200 }
139201 } else if (view->type == I915_GTT_VIEW_REMAPPED) {
140− const struct intel_remapped_info *remap_info = &view->remapped;
141− u32 i, dpt_ofs = 0;
142−
143− for (i = 0; i < ARRAY_SIZE(remap_info->plane); i++)
144− write_dpt_remapped(bo, &dpt->vmap, &dpt_ofs,
145− remap_info->plane[i].offset,
146− remap_info->plane[i].width,
147− remap_info->plane[i].height,
148− remap_info->plane[i].src_stride,
149− remap_info->plane[i].dst_stride);
150−
202+ write_dpt_remapped(bo, &view->remapped, &dpt->vmap);
151203 } else {
152204 const struct intel_rotation_info *rot_info = &view->rotated;
153205 u32 i, dpt_ofs = 0;
@@ -429,7 +481,7 @@ int intel_plane_pin_fb(struct intel_plane_state *new_plane_state, · 275 unmodified lines
429481 return 0;
430482
431483 /* We reject creating !SCANOUT fb's, so this is weird.. */
432− drm_WARN_ON(bo->ttm.base.dev, !(bo->flags & XE_BO_FLAG_SCANOUT));
484+ drm_WARN_ON(bo->ttm.base.dev, !(bo->flags & XE_BO_FLAG_FORCE_WC));
433485
434486 vma = __xe_pin_fb_vma(intel_fb, &new_plane_state->view.gtt, alignment);
435487
drivers/gpu/drm/xe/display/xe_initial_plane.c+1−1
@@ -48,7 +48,7 @@ initial_plane_bo(struct xe_device *xe, · 47 unmodified lines
4848 if (plane_config->size == 0)
4949 return NULL;
5050
51− flags = XE_BO_FLAG_SCANOUT | XE_BO_FLAG_GGTT;
51+ flags = XE_BO_FLAG_FORCE_WC | XE_BO_FLAG_GGTT;
5252
5353 base = round_down(plane_config->base, page_size);
5454 if (IS_DGFX(xe)) {
drivers/gpu/drm/xe/instructions/xe_mi_commands.h+19−0
@@ -34,6 +34,19 @@ · 33 unmodified lines
3434 #define MI_FORCE_WAKEUP __MI_INSTR(0x1D)
3535 #define MI_MATH(n) (__MI_INSTR(0x1A) | XE_INSTR_NUM_DW((n) + 1))
3636
37+#define MI_SEMAPHORE_WAIT (__MI_INSTR(0x1c) | XE_INSTR_NUM_DW(5))
38+#define MI_SEMW_GGTT REG_BIT(22)
39+#define MI_SEMW_POLL REG_BIT(15)
40+#define MI_SEMW_COMPARE_OP_MASK REG_GENMASK(14, 12)
41+#define COMPARE_OP_SAD_GT_SDD 0
42+#define COMPARE_OP_SAD_GTE_SDD 1
43+#define COMPARE_OP_SAD_LT_SDD 2
44+#define COMPARE_OP_SAD_LTE_SDD 3
45+#define COMPARE_OP_SAD_EQ_SDD 4
46+#define COMPARE_OP_SAD_NEQ_SDD 5
47+#define MI_SEMW_COMPARE(OP) REG_FIELD_PREP(MI_SEMW_COMPARE_OP_MASK, COMPARE_OP_##OP)
48+#define MI_SEMW_TOKEN(token) REG_FIELD_PREP(REG_GENMASK(9, 2), (token))
49+
3750 #define MI_STORE_DATA_IMM __MI_INSTR(0x20)
3851 #define MI_SDI_GGTT REG_BIT(22)
3952 #define MI_SDI_LEN_DW GENMASK(9, 0)
@@ -81,4 +94,10 @@ · 41 unmodified lines
8194 #define MI_SET_APPID_SESSION_ID_MASK REG_GENMASK(6, 0)
8295 #define MI_SET_APPID_SESSION_ID(x) REG_FIELD_PREP(MI_SET_APPID_SESSION_ID_MASK, x)
8396
97+#define MI_SEMAPHORE_WAIT_TOKEN (__MI_INSTR(0x1c) | XE_INSTR_NUM_DW(5)) /* XeLP+ */
98+#define MI_SEMAPHORE_REGISTER_POLL REG_BIT(16)
99+#define MI_SEMAPHORE_POLL REG_BIT(15)
100+#define MI_SEMAPHORE_CMP_OP_MASK REG_GENMASK(14, 12)
101+#define MI_SEMAPHORE_SAD_EQ_SDD REG_FIELD_PREP(MI_SEMAPHORE_CMP_OP_MASK, 4)
102+
84103 #endif
drivers/gpu/drm/xe/regs/xe_engine_regs.h+8−0
@@ -132,6 +132,14 @@ · 131 unmodified lines
132132 #define RING_BBADDR(base) XE_REG((base) + 0x140)
133133 #define RING_BBADDR_UDW(base) XE_REG((base) + 0x168)
134134
135+#define PR_CTR_CTRL(base) XE_REG((base) + 0x178)
136+#define CTR_COUNT_SELECT_FF REG_BIT(31)
137+#define CTR_LOGIC_OP_MASK REG_GENMASK(30, 0)
138+#define CTR_START 0
139+#define CTR_STOP 1
140+#define CTR_LOGIC_OP(OP) REG_FIELD_PREP(CTR_LOGIC_OP_MASK, CTR_##OP)
141+#define PR_CTR_THRSH(base) XE_REG((base) + 0x17c)
142+
135143 #define BCS_SWCTRL(base) XE_REG((base) + 0x200, XE_REG_OPTION_MASKED)
136144 #define BCS_SWCTRL_DISABLE_256B REG_BIT(2)
137145
drivers/gpu/drm/xe/regs/xe_gt_regs.h+1−0
@@ -578,6 +578,7 @@ · 577 unmodified lines
578578 #define ENABLE_SMP_LD_RENDER_SURFACE_CONTROL REG_BIT(44 - 32)
579579 #define FORCE_SLM_FENCE_SCOPE_TO_TILE REG_BIT(42 - 32)
580580 #define FORCE_UGM_FENCE_SCOPE_TO_TILE REG_BIT(41 - 32)
581+#define L3_128B_256B_WRT_DIS REG_BIT(40 - 32)
581582 #define MAXREQS_PER_BANK REG_GENMASK(39 - 32, 37 - 32)
582583 #define DISABLE_128B_EVICTION_COMMAND_UDW REG_BIT(36 - 32)
583584 #define LSCFE_SAME_ADDRESS_ATOMICS_COALESCING_DISABLE REG_BIT(35 - 32)
drivers/gpu/drm/xe/xe_bo.c+15−9
@@ -510,13 +510,11 @@ static struct ttm_tt *xe_ttm_tt_create(struct ttm_buffer_object *ttm_bo, · 509 unmodified lines
510510 WARN_ON((bo->flags & XE_BO_FLAG_USER) && !bo->cpu_caching);
511511
512512 /*
513− * Display scanout is always non-coherent with the CPU cache.
514− *
515513 * For Xe_LPG and beyond up to NVL-P (excluding), PPGTT PTE
516514 * lookups are also non-coherent and require a CPU:WC mapping.
517515 */
518− if ((!bo->cpu_caching && bo->flags & XE_BO_FLAG_SCANOUT) ||
519− (!xe->info.has_cached_pt && bo->flags & XE_BO_FLAG_PAGETABLE))
516+ if ((!bo->cpu_caching && bo->flags & XE_BO_FLAG_FORCE_WC) ||
517+ (!xe->info.has_cached_pt && bo->flags & XE_BO_FLAG_PAGETABLE))
520518 caching = ttm_write_combined;
521519 }
522520
@@ -689,7 +687,12 @@ static int xe_bo_trigger_rebind(struct xe_device *xe, struct xe_bo *bo, · 166 unmodified lines
689687
690688 if (!xe_vm_in_fault_mode(vm)) {
691689 drm_gpuvm_bo_evict(vm_bo, true);
692− continue;
690+ /*
691+ * L2 cache may not be flushed, so ensure that is done in
692+ * xe_vm_invalidate_vma() below
693+ */
694+ if (!xe_device_is_l2_flush_optimized(xe))
695+ continue;
693696 }
694697
695698 if (!idle) {
@@ -3196,8 +3199,11 @@ int xe_gem_create_ioctl(struct drm_device *dev, void *data, · 2500 unmodified lines
31963199 if (args->flags & DRM_XE_GEM_CREATE_FLAG_DEFER_BACKING)
31973200 bo_flags |= XE_BO_FLAG_DEFER_BACKING;
31983201
3202+ /*
3203+ * Display scanout is always non-coherent with the CPU cache.
3204+ */
31993205 if (args->flags & DRM_XE_GEM_CREATE_FLAG_SCANOUT)
3200− bo_flags |= XE_BO_FLAG_SCANOUT;
3206+ bo_flags |= XE_BO_FLAG_FORCE_WC;
32013207
32023208 if (args->flags & DRM_XE_GEM_CREATE_FLAG_NO_COMPRESSION) {
32033209 if (XE_IOCTL_DBG(xe, GRAPHICS_VER(xe) < 20))
@@ -3209,7 +3215,7 @@ int xe_gem_create_ioctl(struct drm_device *dev, void *data, · 5 unmodified lines
32093215
32103216 /* CCS formats need physical placement at a 64K alignment in VRAM. */
32113217 if ((bo_flags & XE_BO_FLAG_VRAM_MASK) &&
3212− (bo_flags & XE_BO_FLAG_SCANOUT) &&
3218+ (args->flags & DRM_XE_GEM_CREATE_FLAG_SCANOUT) &&
32133219 !(xe->info.vram_flags & XE_VRAM_FLAGS_NEED64K) &&
32143220 IS_ALIGNED(args->size, SZ_64K))
32153221 bo_flags |= XE_BO_FLAG_NEEDS_64K;
@@ -3229,7 +3235,7 @@ int xe_gem_create_ioctl(struct drm_device *dev, void *data, · 13 unmodified lines
32293235 args->cpu_caching != DRM_XE_GEM_CPU_CACHING_WC))
32303236 return -EINVAL;
32313237
3232− if (XE_IOCTL_DBG(xe, bo_flags & XE_BO_FLAG_SCANOUT &&
3238+ if (XE_IOCTL_DBG(xe, bo_flags & XE_BO_FLAG_FORCE_WC &&
32333239 args->cpu_caching == DRM_XE_GEM_CPU_CACHING_WB))
32343240 return -EINVAL;
32353241
@@ -3697,7 +3703,7 @@ int xe_bo_dumb_create(struct drm_file *file_priv, · 461 unmodified lines
36973703 bo = xe_bo_create_user(xe, NULL, args->size,
36983704 DRM_XE_GEM_CPU_CACHING_WC,
36993705 XE_BO_FLAG_VRAM_IF_DGFX(xe_device_get_root_tile(xe)) |
3700− XE_BO_FLAG_SCANOUT |
3706+ XE_BO_FLAG_FORCE_WC |
37013707 XE_BO_FLAG_NEEDS_CPU_ACCESS, NULL);
37023708 if (IS_ERR(bo))
37033709 return PTR_ERR(bo);
drivers/gpu/drm/xe/xe_bo.h+1−1
@@ -35,7 +35,7 @@ · 34 unmodified lines
3535 #define XE_BO_FLAG_PINNED BIT(7)
3636 #define XE_BO_FLAG_NO_RESV_EVICT BIT(8)
3737 #define XE_BO_FLAG_DEFER_BACKING BIT(9)
38−#define XE_BO_FLAG_SCANOUT BIT(10)
38+#define XE_BO_FLAG_FORCE_WC BIT(10)
3939 #define XE_BO_FLAG_FIXED_PLACEMENT BIT(11)
4040 #define XE_BO_FLAG_PAGETABLE BIT(12)
4141 #define XE_BO_FLAG_NEEDS_CPU_ACCESS BIT(13)
drivers/gpu/drm/xe/xe_device.c+33−0
@@ -211,6 +211,8 @@ static const struct drm_ioctl_desc xe_ioctls[] = { · 210 unmodified lines
211211 DRM_RENDER_ALLOW),
212212 DRM_IOCTL_DEF_DRV(XE_EXEC_QUEUE_SET_PROPERTY, xe_exec_queue_set_property_ioctl,
213213 DRM_RENDER_ALLOW),
214+ DRM_IOCTL_DEF_DRV(XE_VM_GET_PROPERTY, xe_vm_get_property_ioctl,
215+ DRM_RENDER_ALLOW),
214216 };
215217
216218 static long xe_drm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
@@ -1094,6 +1096,29 @@ static void tdf_request_sync(struct xe_device *xe) · 877 unmodified lines
10941096 }
10951097 }
10961098
1099+/**
1100+ * xe_device_is_l2_flush_optimized - if L2 flush is optimized by HW
1101+ * @xe: The device to check.
1102+ *
1103+ * Return: true if the HW device optimizing L2 flush, false otherwise.
1104+ */
1105+bool xe_device_is_l2_flush_optimized(struct xe_device *xe)
1106+{
1107+ /* XA is *always* flushed, like at the end-of-submssion (and maybe other
1108+ * places), just that internally as an optimisation hw doesn't need to make
1109+ * that a full flush (which will also include XA) when Media is
1110+ * off/powergated, since it doesn't need to worry about GT caches vs Media
1111+ * coherency, and only CPU vs GPU coherency, so can make that flush a
1112+ * targeted XA flush, since stuff tagged with XA now means it's shared with
1113+ * the CPU. The main implication is that we now need to somehow flush non-XA before
1114+ * freeing system memory pages, otherwise dirty cachelines could be flushed after the free
1115+ * (like if Media suddenly turns on and does a full flush)
1116+ */
1117+ if (GRAPHICS_VER(xe) >= 35 && !IS_DGFX(xe))
1118+ return true;
1119+ return false;
1120+}
1121+
10971122 void xe_device_l2_flush(struct xe_device *xe)
10981123 {
10991124 struct xe_gt *gt;
@@ -1140,6 +1165,14 @@ void xe_device_td_flush(struct xe_device *xe) · 40 unmodified lines
11401165 {
11411166 struct xe_gt *root_gt;
11421167
1168+ /*
1169+ * From Xe3p onward the HW takes care of flush of TD entries also along
1170+ * with flushing XA entries, which will be at the usual sync points,
1171+ * like at the end of submission, so no manual flush is needed here.
1172+ */
1173+ if (GRAPHICS_VER(xe) >= 35)
1174+ return;
1175+
11431176 if (!IS_DGFX(xe) || GRAPHICS_VER(xe) < 20)
11441177 return;
11451178
drivers/gpu/drm/xe/xe_device.h+1−0
@@ -188,6 +188,7 @@ void xe_device_snapshot_print(struct xe_device *xe, struct drm_printer *p); · 187 unmodified lines
188188 u64 xe_device_canonicalize_addr(struct xe_device *xe, u64 address);
189189 u64 xe_device_uncanonicalize_addr(struct xe_device *xe, u64 address);
190190
191+bool xe_device_is_l2_flush_optimized(struct xe_device *xe);
191192 void xe_device_td_flush(struct xe_device *xe);
192193 void xe_device_l2_flush(struct xe_device *xe);
193194
drivers/gpu/drm/xe/xe_ggtt.c+9−6
@@ -66,6 +66,9 @@ · 65 unmodified lines
6666 * give us the correct placement for free.
6767 */
6868
69+#define XE_GGTT_FLAGS_64K BIT(0)
70+#define XE_GGTT_FLAGS_ONLINE BIT(1)
71+
6972 /**
7073 * struct xe_ggtt_node - A node in GGTT.
7174 *
@@ -117,6 +120,8 @@ struct xe_ggtt { · 45 unmodified lines
117120 * @flags: Flags for this GGTT
118121 * Acceptable flags:
119122 * - %XE_GGTT_FLAGS_64K - if PTE size is 64K. Otherwise, regular is 4K.
123+ * - %XE_GGTT_FLAGS_ONLINE - is GGTT online, protected by ggtt->lock
124+ * after init
120125 */
121126 unsigned int flags;
122127 /** @scratch: Internal object allocation used as a scratch page */
@@ -367,6 +372,8 @@ static void dev_fini_ggtt(void *arg) · 244 unmodified lines
367372 {
368373 struct xe_ggtt *ggtt = arg;
369374
375+ scoped_guard(mutex, &ggtt->lock)
376+ ggtt->flags &= ~XE_GGTT_FLAGS_ONLINE;
370377 drain_workqueue(ggtt->wq);
371378 }
372379
@@ -437,6 +444,7 @@ int xe_ggtt_init_early(struct xe_ggtt *ggtt) · 64 unmodified lines
437444 if (err)
438445 return err;
439446
447+ ggtt->flags |= XE_GGTT_FLAGS_ONLINE;
440448 return devm_add_action_or_reset(xe->drm.dev, dev_fini_ggtt, ggtt);
441449 }
442450 ALLOW_ERROR_INJECTION(xe_ggtt_init_early, ERRNO); /* See xe_pci_probe() */
@@ -465,13 +473,10 @@ static void ggtt_node_fini(struct xe_ggtt_node *node) · 22 unmodified lines
465473 static void ggtt_node_remove(struct xe_ggtt_node *node)
466474 {
467475 struct xe_ggtt *ggtt = node->ggtt;
468− struct xe_device *xe = tile_to_xe(ggtt->tile);
469476 bool bound;
470− int idx;
471−
472− bound = drm_dev_enter(&xe->drm, &idx);
473477
474478 mutex_lock(&ggtt->lock);
479+ bound = ggtt->flags & XE_GGTT_FLAGS_ONLINE;
475480 if (bound)
476481 xe_ggtt_clear(ggtt, xe_ggtt_node_addr(node), xe_ggtt_node_size(node));
477482 drm_mm_remove_node(&node->base);
@@ -484,8 +489,6 @@ static void ggtt_node_remove(struct xe_ggtt_node *node) · 6 unmodified lines
484489 if (node->invalidate_on_remove)
485490 xe_ggtt_invalidate(ggtt);
486491
487− drm_dev_exit(idx);
488−
489492 free_node:
490493 ggtt_node_fini(node);
491494 }
drivers/gpu/drm/xe/xe_gt.c+6−3
@@ -171,7 +171,7 @@ static void xe_gt_enable_comp_1wcoh(struct xe_gt *gt) · 170 unmodified lines
171171 static void gt_reset_worker(struct work_struct *w);
172172
173173 static int emit_job_sync(struct xe_exec_queue *q, struct xe_bb *bb,
174− long timeout_jiffies)
174+ long timeout_jiffies, bool force_reset)
175175 {
176176 struct xe_sched_job *job;
177177 struct dma_fence *fence;
@@ -181,6 +181,8 @@ static int emit_job_sync(struct xe_exec_queue *q, struct xe_bb *bb, · 3 unmodified lines
181181 if (IS_ERR(job))
182182 return PTR_ERR(job);
183183
184+ job->ring_ops_force_reset = force_reset;
185+
184186 xe_sched_job_arm(job);
185187 fence = dma_fence_get(&job->drm.s_fence->finished);
186188 xe_sched_job_push(job);
@@ -204,7 +206,7 @@ static int emit_nop_job(struct xe_gt *gt, struct xe_exec_queue *q) · 17 unmodified lines
204206 if (IS_ERR(bb))
205207 return PTR_ERR(bb);
206208
207− ret = emit_job_sync(q, bb, HZ);
209+ ret = emit_job_sync(q, bb, HZ, false);
208210 xe_bb_free(bb, NULL);
209211
210212 return ret;
@@ -369,7 +371,8 @@ static int emit_wa_job(struct xe_gt *gt, struct xe_exec_queue *q) · 158 unmodified lines
369371
370372 bb->len = cs - bb->cs;
371373
372− ret = emit_job_sync(q, bb, HZ);
374+ /* only VFs need to trigger reset to get a clean NULL context */
375+ ret = emit_job_sync(q, bb, HZ, IS_SRIOV_VF(gt_to_xe(gt)));
373376
374377 xe_bb_free(bb, NULL);
375378
drivers/gpu/drm/xe/xe_gt_ccs_mode.c+2−0
@@ -12,6 +12,7 @@ · 11 unmodified lines
1212 #include "xe_gt_printk.h"
1313 #include "xe_gt_sysfs.h"
1414 #include "xe_mmio.h"
15+#include "xe_pm.h"
1516 #include "xe_sriov.h"
1617 #include "xe_sriov_pf.h"
1718
@@ -163,6 +164,7 @@ ccs_mode_store(struct device *kdev, struct device_attribute *attr, · 145 unmodified lines
163164 xe_gt_info(gt, "Setting compute mode to %d\n", num_engines);
164165 gt->ccs_mode = num_engines;
165166 xe_gt_record_user_engines(gt);
167+ guard(xe_pm_runtime)(xe);
166168 xe_gt_reset(gt);
167169
168170 /* We may end PF lockdown once CCS mode is default again */
drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c+62−16
@@ -171,6 +171,7 @@ static const char *control_bit_to_string(enum xe_gt_sriov_control_bits bit) · 170 unmodified lines
171171 case XE_GT_SRIOV_STATE_##_X: return #_X
172172 CASE2STR(WIP);
173173 CASE2STR(FLR_WIP);
174+ CASE2STR(FLR_PREPARE);
174175 CASE2STR(FLR_SEND_START);
175176 CASE2STR(FLR_WAIT_GUC);
176177 CASE2STR(FLR_GUC_DONE);
@@ -1486,11 +1487,15 @@ int xe_gt_sriov_pf_control_stop_vf(struct xe_gt *gt, unsigned int vfid) · 1309 unmodified lines
14861487 * The VF FLR state machine looks like::
14871488 *
14881489 * (READY,PAUSED,STOPPED)<------------<--------------o
1489− * | \
1490− * flr \
1491− * | \
1492− * ....V..........................FLR_WIP........... \
1493− * : \ : \
1490+ * | | \
1491+ * flr prepare \
1492+ * | | \
1493+ * ....V.............V............FLR_WIP........... \
1494+ * : | | : \
1495+ * : | FLR_PREPARE : |
1496+ * : | / : |
1497+ * : \ flr : |
1498+ * : \ / : |
14941499 * : \ o----<----busy : |
14951500 * : \ / / : |
14961501 * : FLR_SEND_START---failed----->-----------o--->(FLR_FAILED)<---o
@@ -1539,20 +1544,28 @@ static void pf_enter_vf_flr_send_start(struct xe_gt *gt, unsigned int vfid) · 42 unmodified lines
15391544 pf_queue_vf(gt, vfid);
15401545 }
15411546
1542−static void pf_enter_vf_flr_wip(struct xe_gt *gt, unsigned int vfid)
1547+static bool pf_exit_vf_flr_prepare(struct xe_gt *gt, unsigned int vfid)
15431548 {
1544− if (!pf_enter_vf_state(gt, vfid, XE_GT_SRIOV_STATE_FLR_WIP)) {
1545− xe_gt_sriov_dbg(gt, "VF%u FLR is already in progress\n", vfid);
1546− return;
1547− }
1549+ if (!pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_FLR_PREPARE))
1550+ return false;
15481551
1549− pf_enter_vf_wip(gt, vfid);
15501552 pf_enter_vf_flr_send_start(gt, vfid);
1553+ return true;
1554+}
1555+
1556+static bool pf_enter_vf_flr_wip(struct xe_gt *gt, unsigned int vfid)
1557+{
1558+ if (!pf_enter_vf_state(gt, vfid, XE_GT_SRIOV_STATE_FLR_WIP))
1559+ return false;
1560+
1561+ pf_enter_vf_wip(gt, vfid);
1562+ return true;
15511563 }
15521564
15531565 static void pf_exit_vf_flr_wip(struct xe_gt *gt, unsigned int vfid)
15541566 {
15551567 if (pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_FLR_WIP)) {
1568+ pf_escape_vf_state(gt, vfid, XE_GT_SRIOV_STATE_FLR_PREPARE);
15561569 pf_escape_vf_state(gt, vfid, XE_GT_SRIOV_STATE_FLR_SEND_FINISH);
15571570 pf_escape_vf_state(gt, vfid, XE_GT_SRIOV_STATE_FLR_RESET_MMIO);
15581571 pf_escape_vf_state(gt, vfid, XE_GT_SRIOV_STATE_FLR_RESET_DATA);
@@ -1760,21 +1773,54 @@ static void pf_enter_vf_flr_guc_done(struct xe_gt *gt, unsigned int vfid) · 201 unmodified lines
17601773 }
17611774
17621775 /**
1763− * xe_gt_sriov_pf_control_trigger_flr - Start a VF FLR sequence.
1776+ * xe_gt_sriov_pf_control_prepare_flr() - Notify PF that VF FLR request was issued.
17641777 * @gt: the &xe_gt
17651778 * @vfid: the VF identifier
17661779 *
1780+ * This is an optional early notification path used to mark pending FLR before
1781+ * the GuC notifies the PF with a FLR event.
1782+ *
17671783 * This function is for PF only.
17681784 *
17691785 * Return: 0 on success or a negative error code on failure.
17701786 */
1771−int xe_gt_sriov_pf_control_trigger_flr(struct xe_gt *gt, unsigned int vfid)
1787+int xe_gt_sriov_pf_control_prepare_flr(struct xe_gt *gt, unsigned int vfid)
17721788 {
1773− pf_enter_vf_flr_wip(gt, vfid);
1789+ if (!pf_enter_vf_flr_wip(gt, vfid))
1790+ return -EALREADY;
17741791
1792+ pf_enter_vf_state(gt, vfid, XE_GT_SRIOV_STATE_FLR_PREPARE);
17751793 return 0;
17761794 }
17771795
1796+static int pf_begin_vf_flr(struct xe_gt *gt, unsigned int vfid)
1797+{
1798+ if (pf_enter_vf_flr_wip(gt, vfid)) {
1799+ pf_enter_vf_flr_send_start(gt, vfid);
1800+ return 0;
1801+ }
1802+
1803+ if (pf_exit_vf_flr_prepare(gt, vfid))
1804+ return 0;
1805+
1806+ xe_gt_sriov_dbg(gt, "VF%u FLR is already in progress\n", vfid);
1807+ return -EALREADY;
1808+}
1809+
1810+/**
1811+ * xe_gt_sriov_pf_control_trigger_flr - Start a VF FLR sequence.
1812+ * @gt: the &xe_gt
1813+ * @vfid: the VF identifier
1814+ *
1815+ * This function is for PF only.
1816+ *
1817+ * Return: 0 on success or a negative error code on failure.
1818+ */
1819+int xe_gt_sriov_pf_control_trigger_flr(struct xe_gt *gt, unsigned int vfid)
1820+{
1821+ return pf_begin_vf_flr(gt, vfid);
1822+}
1823+
17781824 /**
17791825 * xe_gt_sriov_pf_control_sync_flr() - Synchronize on the VF FLR checkpoint.
17801826 * @gt: the &xe_gt
@@ -1879,9 +1925,9 @@ static void pf_handle_vf_flr(struct xe_gt *gt, u32 vfid) · 98 unmodified lines
18791925
18801926 if (needs_dispatch_flr(xe)) {
18811927 for_each_gt(gtit, xe, gtid)
1882− pf_enter_vf_flr_wip(gtit, vfid);
1928+ pf_begin_vf_flr(gtit, vfid);
18831929 } else {
1884− pf_enter_vf_flr_wip(gt, vfid);
1930+ pf_begin_vf_flr(gt, vfid);
18851931 }
18861932 }
18871933
drivers/gpu/drm/xe/xe_gt_sriov_pf_control.h+1−0
@@ -27,6 +27,7 @@ int xe_gt_sriov_pf_control_process_restore_data(struct xe_gt *gt, unsigned int v · 26 unmodified lines
2727 int xe_gt_sriov_pf_control_trigger_restore_vf(struct xe_gt *gt, unsigned int vfid);
2828 int xe_gt_sriov_pf_control_finish_restore_vf(struct xe_gt *gt, unsigned int vfid);
2929 int xe_gt_sriov_pf_control_stop_vf(struct xe_gt *gt, unsigned int vfid);
30+int xe_gt_sriov_pf_control_prepare_flr(struct xe_gt *gt, unsigned int vfid);
3031 int xe_gt_sriov_pf_control_trigger_flr(struct xe_gt *gt, unsigned int vfid);
3132 int xe_gt_sriov_pf_control_sync_flr(struct xe_gt *gt, unsigned int vfid, bool sync);
3233 int xe_gt_sriov_pf_control_wait_flr(struct xe_gt *gt, unsigned int vfid);
drivers/gpu/drm/xe/xe_gt_sriov_pf_control_types.h+2−0
@@ -15,6 +15,7 @@ · 14 unmodified lines
1515 *
1616 * @XE_GT_SRIOV_STATE_WIP: indicates that some operations are in progress.
1717 * @XE_GT_SRIOV_STATE_FLR_WIP: indicates that a VF FLR is in progress.
18+ * @XE_GT_SRIOV_STATE_FLR_PREPARE: indicates that the PF received early VF FLR prepare notification.
1819 * @XE_GT_SRIOV_STATE_FLR_SEND_START: indicates that the PF wants to send a FLR START command.
1920 * @XE_GT_SRIOV_STATE_FLR_WAIT_GUC: indicates that the PF awaits for a response from the GuC.
2021 * @XE_GT_SRIOV_STATE_FLR_GUC_DONE: indicates that the PF has received a response from the GuC.
@@ -56,6 +57,7 @@ enum xe_gt_sriov_control_bits { · 35 unmodified lines
5657 XE_GT_SRIOV_STATE_WIP = 1,
5758
5859 XE_GT_SRIOV_STATE_FLR_WIP,
60+ XE_GT_SRIOV_STATE_FLR_PREPARE,
5961 XE_GT_SRIOV_STATE_FLR_SEND_START,
6062 XE_GT_SRIOV_STATE_FLR_WAIT_GUC,
6163 XE_GT_SRIOV_STATE_FLR_GUC_DONE,
drivers/gpu/drm/xe/xe_gt_stats.c+6−0
@@ -85,7 +85,13 @@ static const char *const stat_description[__XE_GT_STATS_NUM_IDS] = { · 84 unmodified lines
8585 DEF_STAT_STR(SVM_64K_CPU_COPY_US, "svm_64K_cpu_copy_us"),
8686 DEF_STAT_STR(SVM_2M_CPU_COPY_US, "svm_2M_cpu_copy_us"),
8787 DEF_STAT_STR(SVM_DEVICE_COPY_KB, "svm_device_copy_kb"),
88+ DEF_STAT_STR(SVM_4K_DEVICE_COPY_KB, "svm_4K_device_copy_kb"),
89+ DEF_STAT_STR(SVM_64K_DEVICE_COPY_KB, "svm_64K_device_copy_kb"),
90+ DEF_STAT_STR(SVM_2M_DEVICE_COPY_KB, "svm_2M_device_copy_kb"),
8891 DEF_STAT_STR(SVM_CPU_COPY_KB, "svm_cpu_copy_kb"),
92+ DEF_STAT_STR(SVM_4K_CPU_COPY_KB, "svm_4K_cpu_copy_kb"),
93+ DEF_STAT_STR(SVM_64K_CPU_COPY_KB, "svm_64K_cpu_copy_kb"),
94+ DEF_STAT_STR(SVM_2M_CPU_COPY_KB, "svm_2M_cpu_copy_kb"),
8995 DEF_STAT_STR(SVM_4K_GET_PAGES_US, "svm_4K_get_pages_us"),
9096 DEF_STAT_STR(SVM_64K_GET_PAGES_US, "svm_64K_get_pages_us"),
9197 DEF_STAT_STR(SVM_2M_GET_PAGES_US, "svm_2M_get_pages_us"),
drivers/gpu/drm/xe/xe_gt_stats_types.h+6−0
@@ -40,7 +40,13 @@ enum xe_gt_stats_id { · 39 unmodified lines
4040 XE_GT_STATS_ID_SVM_64K_CPU_COPY_US,
4141 XE_GT_STATS_ID_SVM_2M_CPU_COPY_US,
4242 XE_GT_STATS_ID_SVM_DEVICE_COPY_KB,
43+ XE_GT_STATS_ID_SVM_4K_DEVICE_COPY_KB,
44+ XE_GT_STATS_ID_SVM_64K_DEVICE_COPY_KB,
45+ XE_GT_STATS_ID_SVM_2M_DEVICE_COPY_KB,
4346 XE_GT_STATS_ID_SVM_CPU_COPY_KB,
47+ XE_GT_STATS_ID_SVM_4K_CPU_COPY_KB,
48+ XE_GT_STATS_ID_SVM_64K_CPU_COPY_KB,
49+ XE_GT_STATS_ID_SVM_2M_CPU_COPY_KB,
4450 XE_GT_STATS_ID_SVM_4K_GET_PAGES_US,
4551 XE_GT_STATS_ID_SVM_64K_GET_PAGES_US,
4652 XE_GT_STATS_ID_SVM_2M_GET_PAGES_US,
drivers/gpu/drm/xe/xe_guc.c+30−5
@@ -98,6 +98,9 @@ static u32 guc_ctl_feature_flags(struct xe_guc *guc) · 97 unmodified lines
9898 if (xe_guc_using_main_gamctrl_queues(guc))
9999 flags |= GUC_CTL_MAIN_GAMCTRL_QUEUES;
100100
101+ if (GRAPHICS_VER(xe) >= 35 && !IS_DGFX(xe) && xe_gt_is_media_type(guc_to_gt(guc)))
102+ flags |= GUC_CTL_ENABLE_L2FLUSH_OPT;
103+
101104 return flags;
102105 }
103106
@@ -1176,14 +1179,14 @@ static int guc_wait_ucode(struct xe_guc *guc) · 1072 unmodified lines
11761179 struct xe_guc_pc *guc_pc = &gt->uc.guc.pc;
11771180 u32 before_freq, act_freq, cur_freq;
11781181 u32 status = 0, tries = 0;
1182+ int load_result, ret;
11791183 ktime_t before;
11801184 u64 delta_ms;
1181− int ret;
11821185
11831186 before_freq = xe_guc_pc_get_act_freq(guc_pc);
11841187 before = ktime_get();
11851188
1186− ret = poll_timeout_us(ret = guc_load_done(gt, &status, &tries), ret,
1189+ ret = poll_timeout_us(load_result = guc_load_done(gt, &status, &tries), load_result,
11871190 10 * USEC_PER_MSEC,
11881191 GUC_LOAD_TIMEOUT_SEC * USEC_PER_SEC, false);
11891192
@@ -1191,7 +1194,7 @@ static int guc_wait_ucode(struct xe_guc *guc) · 1 unmodified line
11911194 act_freq = xe_guc_pc_get_act_freq(guc_pc);
11921195 cur_freq = xe_guc_pc_get_cur_freq_fw(guc_pc);
11931196
1194− if (ret) {
1197+ if (ret || load_result <= 0) {
11951198 xe_gt_err(gt, "load failed: status = 0x%08X, time = %lldms, freq = %dMHz (req %dMHz)\n",
11961199 status, delta_ms, xe_guc_pc_get_act_freq(guc_pc),
11971200 xe_guc_pc_get_cur_freq_fw(guc_pc));
@@ -1399,15 +1402,37 @@ int xe_guc_enable_communication(struct xe_guc *guc) · 201 unmodified lines
13991402 return 0;
14001403 }
14011404
1402−int xe_guc_suspend(struct xe_guc *guc)
1405+/**
1406+ * xe_guc_softreset() - Soft reset GuC
1407+ * @guc: The GuC object
1408+ *
1409+ * Send soft reset command to GuC through mmio send.
1410+ *
1411+ * Return: 0 if success, otherwise error code
1412+ */
1413+int xe_guc_softreset(struct xe_guc *guc)
14031414 {
1404− struct xe_gt *gt = guc_to_gt(guc);
14051415 u32 action[] = {
14061416 XE_GUC_ACTION_CLIENT_SOFT_RESET,
14071417 };
14081418 int ret;
14091419
1420+ if (!xe_uc_fw_is_running(&guc->fw))
1421+ return 0;
1422+
14101423 ret = xe_guc_mmio_send(guc, action, ARRAY_SIZE(action));
1424+ if (ret)
1425+ return ret;
1426+
1427+ return 0;
1428+}
1429+
1430+int xe_guc_suspend(struct xe_guc *guc)
1431+{
1432+ struct xe_gt *gt = guc_to_gt(guc);
1433+ int ret;
1434+
1435+ ret = xe_guc_softreset(guc);
14111436 if (ret) {
14121437 xe_gt_err(gt, "GuC suspend failed: %pe\n", ERR_PTR(ret));
14131438 return ret;
drivers/gpu/drm/xe/xe_guc.h+1−0
@@ -44,6 +44,7 @@ int xe_guc_opt_in_features_enable(struct xe_guc *guc); · 43 unmodified lines
4444 void xe_guc_runtime_suspend(struct xe_guc *guc);
4545 void xe_guc_runtime_resume(struct xe_guc *guc);
4646 int xe_guc_suspend(struct xe_guc *guc);
47+int xe_guc_softreset(struct xe_guc *guc);
4748 void xe_guc_notify(struct xe_guc *guc);
4849 int xe_guc_auth_huc(struct xe_guc *guc, u32 rsa_addr);
4950 int xe_guc_mmio_send(struct xe_guc *guc, const u32 *request, u32 len);
drivers/gpu/drm/xe/xe_guc_ct.c+9−15
@@ -31,6 +31,7 @@ · 30 unmodified lines
3131 #include "xe_guc_submit.h"
3232 #include "xe_guc_tlb_inval.h"
3333 #include "xe_map.h"
34+#include "xe_page_reclaim.h"
3435 #include "xe_pm.h"
3536 #include "xe_sleep.h"
3637 #include "xe_sriov_vf.h"
@@ -352,6 +353,7 @@ static void guc_action_disable_ct(void *arg) · 315 unmodified lines
352353 {
353354 struct xe_guc_ct *ct = arg;
354355
356+ xe_guc_ct_stop(ct);
355357 guc_ct_change_state(ct, XE_GUC_CT_STATE_DISABLED);
356358 }
357359
@@ -1629,17 +1631,11 @@ static int process_g2h_msg(struct xe_guc_ct *ct, u32 *msg, u32 len) · 1271 unmodified lines
16291631 ret = xe_guc_pagefault_handler(guc, payload, adj_len);
16301632 break;
16311633 case XE_GUC_ACTION_TLB_INVALIDATION_DONE:
1632− case XE_GUC_ACTION_PAGE_RECLAMATION_DONE:
1633− /*
1634− * Page reclamation is an extension of TLB invalidation. Both
1635− * operations share the same seqno and fence. When either
1636− * action completes, we need to signal the corresponding
1637− * fence. Since the handling logic (lookup fence by seqno,
1638− * fence signalling) is identical, we use the same handler
1639− * for both G2H events.
1640− */
16411634 ret = xe_guc_tlb_inval_done_handler(guc, payload, adj_len);
16421635 break;
1636+ case XE_GUC_ACTION_PAGE_RECLAMATION_DONE:
1637+ ret = xe_guc_page_reclaim_done_handler(guc, payload, adj_len);
1638+ break;
16431639 case XE_GUC_ACTION_GUC2PF_RELAY_FROM_VF:
16441640 ret = xe_guc_relay_process_guc2pf(&guc->relay, hxg, hxg_len);
16451641 break;
@@ -1847,15 +1843,13 @@ static void g2h_fast_path(struct xe_guc_ct *ct, u32 *msg, u32 len) · 201 unmodified lines
18471843 ret = xe_guc_pagefault_handler(guc, payload, adj_len);
18481844 break;
18491845 case XE_GUC_ACTION_TLB_INVALIDATION_DONE:
1850− case XE_GUC_ACTION_PAGE_RECLAMATION_DONE:
1851− /*
1852− * Seqno and fence handling of page reclamation and TLB
1853− * invalidation is identical, so we can use the same handler
1854− * for both actions.
1855− */
18561846 __g2h_release_space(ct, len);
18571847 ret = xe_guc_tlb_inval_done_handler(guc, payload, adj_len);
18581848 break;
1849+ case XE_GUC_ACTION_PAGE_RECLAMATION_DONE:
1850+ __g2h_release_space(ct, len);
1851+ ret = xe_guc_page_reclaim_done_handler(guc, payload, adj_len);
1852+ break;
18591853 default:
18601854 xe_gt_warn(gt, "NOT_POSSIBLE\n");
18611855 }
drivers/gpu/drm/xe/xe_guc_fwif.h+1−0
@@ -67,6 +67,7 @@ struct guc_update_exec_queue_policy { · 66 unmodified lines
6767 #define GUC_CTL_ENABLE_PSMI_LOGGING BIT(7)
6868 #define GUC_CTL_MAIN_GAMCTRL_QUEUES BIT(9)
6969 #define GUC_CTL_DISABLE_SCHEDULER BIT(14)
70+#define GUC_CTL_ENABLE_L2FLUSH_OPT BIT(15)
7071
7172 #define GUC_CTL_DEBUG 3
7273 #define GUC_LOG_VERBOSITY REG_GENMASK(1, 0)
drivers/gpu/drm/xe/xe_guc_submit.c+62−25
@@ -47,6 +47,8 @@ · 46 unmodified lines
4747
4848 #define XE_GUC_EXEC_QUEUE_CGP_CONTEXT_ERROR_LEN 6
4949
50+static int guc_submit_reset_prepare(struct xe_guc *guc);
51+
5052 static struct xe_guc *
5153 exec_queue_to_guc(struct xe_exec_queue *q)
5254 {
@@ -238,7 +240,7 @@ static bool exec_queue_killed_or_banned_or_wedged(struct xe_exec_queue *q) · 185 unmodified lines
238240 EXEC_QUEUE_STATE_BANNED));
239241 }
240242
241−static void guc_submit_fini(struct drm_device *drm, void *arg)
243+static void guc_submit_sw_fini(struct drm_device *drm, void *arg)
242244 {
243245 struct xe_guc *guc = arg;
244246 struct xe_device *xe = guc_to_xe(guc);
@@ -256,6 +258,19 @@ static void guc_submit_fini(struct drm_device *drm, void *arg) · 11 unmodified lines
256258 xa_destroy(&guc->submission_state.exec_queue_lookup);
257259 }
258260
261+static void guc_submit_fini(void *arg)
262+{
263+ struct xe_guc *guc = arg;
264+
265+ /* Forcefully kill any remaining exec queues */
266+ xe_guc_ct_stop(&guc->ct);
267+ guc_submit_reset_prepare(guc);
268+ xe_guc_softreset(guc);
269+ xe_guc_submit_stop(guc);
270+ xe_uc_fw_sanitize(&guc->fw);
271+ xe_guc_submit_pause_abort(guc);
272+}
273+
259274 static void guc_submit_wedged_fini(void *arg)
260275 {
261276 struct xe_guc *guc = arg;
@@ -325,7 +340,11 @@ int xe_guc_submit_init(struct xe_guc *guc, unsigned int num_ids) · 63 unmodified lines
325340
326341 guc->submission_state.initialized = true;
327342
328− return drmm_add_action_or_reset(&xe->drm, guc_submit_fini, guc);
343+ err = drmm_add_action_or_reset(&xe->drm, guc_submit_sw_fini, guc);
344+ if (err)
345+ return err;
346+
347+ return devm_add_action_or_reset(xe->drm.dev, guc_submit_fini, guc);
329348 }
330349
331350 /*
@@ -1300,6 +1319,7 @@ static void disable_scheduling_deregister(struct xe_guc *guc, · 968 unmodified lines
13001319 */
13011320 void xe_guc_submit_wedge(struct xe_guc *guc)
13021321 {
1322+ struct xe_device *xe = guc_to_xe(guc);
13031323 struct xe_gt *gt = guc_to_gt(guc);
13041324 struct xe_exec_queue *q;
13051325 unsigned long index;
@@ -1314,20 +1334,29 @@ void xe_guc_submit_wedge(struct xe_guc *guc) · 8 unmodified lines
13141334 if (!guc->submission_state.initialized)
13151335 return;
13161336
1317− err = devm_add_action_or_reset(guc_to_xe(guc)->drm.dev,
1318− guc_submit_wedged_fini, guc);
1319− if (err) {
1320− xe_gt_err(gt, "Failed to register clean-up in wedged.mode=%s; "
1321− "Although device is wedged.\n",
1322− xe_wedged_mode_to_string(XE_WEDGED_MODE_UPON_ANY_HANG_NO_RESET));
1323− return;
1324− }
1337+ if (xe->wedged.mode == XE_WEDGED_MODE_UPON_ANY_HANG_NO_RESET) {
1338+ err = devm_add_action_or_reset(guc_to_xe(guc)->drm.dev,
1339+ guc_submit_wedged_fini, guc);
1340+ if (err) {
1341+ xe_gt_err(gt, "Failed to register clean-up on wedged.mode=%s; "
1342+ "Although device is wedged.\n",
1343+ xe_wedged_mode_to_string(XE_WEDGED_MODE_UPON_ANY_HANG_NO_RESET));
1344+ return;
1345+ }
13251346
1326− mutex_lock(&guc->submission_state.lock);
1327− xa_for_each(&guc->submission_state.exec_queue_lookup, index, q)
1328− if (xe_exec_queue_get_unless_zero(q))
1329− set_exec_queue_wedged(q);
1330− mutex_unlock(&guc->submission_state.lock);
1347+ mutex_lock(&guc->submission_state.lock);
1348+ xa_for_each(&guc->submission_state.exec_queue_lookup, index, q)
1349+ if (xe_exec_queue_get_unless_zero(q))
1350+ set_exec_queue_wedged(q);
1351+ mutex_unlock(&guc->submission_state.lock);
1352+ } else {
1353+ /* Forcefully kill any remaining exec queues, signal fences */
1354+ guc_submit_reset_prepare(guc);
1355+ xe_guc_submit_stop(guc);
1356+ xe_guc_softreset(guc);
1357+ xe_uc_fw_sanitize(&guc->fw);
1358+ xe_guc_submit_pause_abort(guc);
1359+ }
13311360 }
13321361
13331362 static bool guc_submit_hint_wedged(struct xe_guc *guc)
@@ -2298,6 +2327,7 @@ static const struct xe_exec_queue_ops guc_exec_queue_ops = { · 964 unmodified lines
22982327 static void guc_exec_queue_stop(struct xe_guc *guc, struct xe_exec_queue *q)
22992328 {
23002329 struct xe_gpu_scheduler *sched = &q->guc->sched;
2330+ bool do_destroy = false;
23012331
23022332 /* Stop scheduling + flush any DRM scheduler operations */
23032333 xe_sched_submission_stop(sched);
@@ -2305,7 +2335,7 @@ static void guc_exec_queue_stop(struct xe_guc *guc, struct xe_exec_queue *q) · 1 unmodified line
23052335 /* Clean up lost G2H + reset engine state */
23062336 if (exec_queue_registered(q)) {
23072337 if (exec_queue_destroyed(q))
2308− __guc_exec_queue_destroy(guc, q);
2338+ do_destroy = true;
23092339 }
23102340 if (q->guc->suspend_pending) {
23112341 set_exec_queue_suspended(q);
@@ -2341,18 +2371,15 @@ static void guc_exec_queue_stop(struct xe_guc *guc, struct xe_exec_queue *q) · 29 unmodified lines
23412371 xe_guc_exec_queue_trigger_cleanup(q);
23422372 }
23432373 }
2374+
2375+ if (do_destroy)
2376+ __guc_exec_queue_destroy(guc, q);
23442377 }
23452378
2346−int xe_guc_submit_reset_prepare(struct xe_guc *guc)
2379+static int guc_submit_reset_prepare(struct xe_guc *guc)
23472380 {
23482381 int ret;
23492382
2350− if (xe_gt_WARN_ON(guc_to_gt(guc), vf_recovery(guc)))
2351− return 0;
2352−
2353− if (!guc->submission_state.initialized)
2354− return 0;
2355−
23562383 /*
23572384 * Using an atomic here rather than submission_state.lock as this
23582385 * function can be called while holding the CT lock (engine reset
@@ -2367,6 +2394,17 @@ int xe_guc_submit_reset_prepare(struct xe_guc *guc) · 8 unmodified lines
23672394 return ret;
23682395 }
23692396
2397+int xe_guc_submit_reset_prepare(struct xe_guc *guc)
2398+{
2399+ if (xe_gt_WARN_ON(guc_to_gt(guc), vf_recovery(guc)))
2400+ return 0;
2401+
2402+ if (!guc->submission_state.initialized)
2403+ return 0;
2404+
2405+ return guc_submit_reset_prepare(guc);
2406+}
2407+
23702408 void xe_guc_submit_reset_wait(struct xe_guc *guc)
23712409 {
23722410 wait_event(guc->ct.wq, xe_device_wedged(guc_to_xe(guc)) ||
@@ -2763,8 +2801,7 @@ void xe_guc_submit_pause_abort(struct xe_guc *guc) · 390 unmodified lines
27632801 continue;
27642802
27652803 xe_sched_submission_start(sched);
2766− if (exec_queue_killed_or_banned_or_wedged(q))
2767− xe_guc_exec_queue_trigger_cleanup(q);
2804+ guc_exec_queue_kill(q);
27682805 }
27692806 mutex_unlock(&guc->submission_state.lock);
27702807 }
drivers/gpu/drm/xe/xe_i2c.c+12−3
@@ -176,11 +176,18 @@ static bool xe_i2c_irq_present(struct xe_device *xe) · 175 unmodified lines
176176 */
177177 void xe_i2c_irq_handler(struct xe_device *xe, u32 master_ctl)
178178 {
179− if (!xe_i2c_irq_present(xe))
179+ struct xe_mmio *mmio = xe_root_tile_mmio(xe);
180+
181+ if (!(master_ctl & I2C_IRQ) || !xe_i2c_irq_present(xe))
180182 return;
181183
182− if (master_ctl & I2C_IRQ)
183− generic_handle_irq_safe(xe->i2c->adapter_irq);
184+ /* Forward interrupt to I2C adapter */
185+ generic_handle_irq_safe(xe->i2c->adapter_irq);
186+
187+ /* Deassert after I2C adapter clears the interrupt */
188+ xe_mmio_rmw32(mmio, I2C_CONFIG_CMD, 0, PCI_COMMAND_INTX_DISABLE);
189+ /* Reassert to allow subsequent interrupt generation */
190+ xe_mmio_rmw32(mmio, I2C_CONFIG_CMD, PCI_COMMAND_INTX_DISABLE, 0);
184191 }
185192
186193 void xe_i2c_irq_reset(struct xe_device *xe)
@@ -190,6 +197,7 @@ void xe_i2c_irq_reset(struct xe_device *xe) · 3 unmodified lines
190197 if (!xe_i2c_irq_present(xe))
191198 return;
192199
200+ xe_mmio_rmw32(mmio, I2C_CONFIG_CMD, 0, PCI_COMMAND_INTX_DISABLE);
193201 xe_mmio_rmw32(mmio, I2C_BRIDGE_PCICFGCTL, ACPI_INTR_EN, 0);
194202 }
195203
@@ -201,6 +209,7 @@ void xe_i2c_irq_postinstall(struct xe_device *xe) · 5 unmodified lines
201209 return;
202210
203211 xe_mmio_rmw32(mmio, I2C_BRIDGE_PCICFGCTL, 0, ACPI_INTR_EN);
212+ xe_mmio_rmw32(mmio, I2C_CONFIG_CMD, PCI_COMMAND_INTX_DISABLE, 0);
204213 }
205214
206215 static int xe_i2c_irq_map(struct irq_domain *h, unsigned int virq,
drivers/gpu/drm/xe/xe_lrc.c+66−30
@@ -28,6 +28,7 @@ · 27 unmodified lines
2828 #include "xe_map.h"
2929 #include "xe_memirq.h"
3030 #include "xe_mmio.h"
31+#include "xe_ring_ops.h"
3132 #include "xe_sriov.h"
3233 #include "xe_trace_lrc.h"
3334 #include "xe_vm.h"
@@ -94,6 +95,9 @@ gt_engine_needs_indirect_ctx(struct xe_gt *gt, enum xe_engine_class class) · 60 unmodified lines
9495 class, NULL))
9596 return true;
9697
98+ if (gt->ring_ops[class]->emit_aux_table_inv)
99+ return true;
100+
97101 return false;
98102 }
99103
@@ -1217,6 +1221,23 @@ static ssize_t setup_invalidate_state_cache_wa(struct xe_lrc *lrc, · 1117 unmodified lines
12171221 return cmd - batch;
12181222 }
12191223
1224+static ssize_t setup_invalidate_auxccs_wa(struct xe_lrc *lrc,
1225+ struct xe_hw_engine *hwe,
1226+ u32 *batch, size_t max_len)
1227+{
1228+ struct xe_gt *gt = lrc->gt;
1229+ u32 *(*emit)(struct xe_gt *gt, u32 *cmd) =
1230+ gt->ring_ops[hwe->class]->emit_aux_table_inv;
1231+
1232+ if (!emit)
1233+ return 0;
1234+
1235+ if (xe_gt_WARN_ON(gt, max_len < 8))
1236+ return -ENOSPC;
1237+
1238+ return emit(gt, batch) - batch;
1239+}
1240+
12201241 struct bo_setup {
12211242 ssize_t (*setup)(struct xe_lrc *lrc, struct xe_hw_engine *hwe,
12221243 u32 *batch, size_t max_size);
@@ -1349,9 +1370,11 @@ setup_indirect_ctx(struct xe_lrc *lrc, struct xe_hw_engine *hwe) · 126 unmodified lines
13491370 {
13501371 static const struct bo_setup rcs_funcs[] = {
13511372 { .setup = setup_timestamp_wa },
1373+ { .setup = setup_invalidate_auxccs_wa },
13521374 { .setup = setup_configfs_mid_ctx_restore_bb },
13531375 };
13541376 static const struct bo_setup xcs_funcs[] = {
1377+ { .setup = setup_invalidate_auxccs_wa },
13551378 { .setup = setup_configfs_mid_ctx_restore_bb },
13561379 };
13571380 struct bo_setup_state state = {
@@ -1607,8 +1630,8 @@ static int xe_lrc_init(struct xe_lrc *lrc, struct xe_hw_engine *hwe, struct xe_v · 249 unmodified lines
16071630 bo = xe_bo_create_pin_map_novm(xe, tile, bo_size,
16081631 ttm_bo_type_kernel,
16091632 bo_flags, false);
1610− if (IS_ERR(lrc->bo))
1611− return PTR_ERR(lrc->bo);
1633+ if (IS_ERR(bo))
1634+ return PTR_ERR(bo);
16121635
16131636 lrc->bo = bo;
16141637
@@ -1902,6 +1925,7 @@ static int instr_dw(u32 cmd_header) · 287 unmodified lines
19021925
19031926 static int dump_mi_command(struct drm_printer *p,
19041927 struct xe_gt *gt,
1928+ u32 *start,
19051929 u32 *dw,
19061930 int remaining_dw)
19071931 {
@@ -1917,15 +1941,18 @@ static int dump_mi_command(struct drm_printer *p, · 9 unmodified lines
19171941 while (num_noop < remaining_dw &&
19181942 (*(++dw) & REG_GENMASK(31, 23)) == MI_NOOP)
19191943 num_noop++;
1920− drm_printf(p, "[%#010x] MI_NOOP (%d dwords)\n", inst_header, num_noop);
1944+ drm_printf(p, "LRC[%#5tx] = [%#010x] MI_NOOP (%d dwords)\n",
1945+ dw - num_noop - start, inst_header, num_noop);
19211946 return num_noop;
19221947
19231948 case MI_TOPOLOGY_FILTER:
1924− drm_printf(p, "[%#010x] MI_TOPOLOGY_FILTER\n", inst_header);
1949+ drm_printf(p, "LRC[%#5tx] = [%#010x] MI_TOPOLOGY_FILTER\n",
1950+ dw - start, inst_header);
19251951 return 1;
19261952
19271953 case MI_BATCH_BUFFER_END:
1928− drm_printf(p, "[%#010x] MI_BATCH_BUFFER_END\n", inst_header);
1954+ drm_printf(p, "LRC[%#5tx] = [%#010x] MI_BATCH_BUFFER_END\n",
1955+ dw - start, inst_header);
19291956 /* Return 'remaining_dw' to consume the rest of the LRC */
19301957 return remaining_dw;
19311958 }
@@ -1939,39 +1966,43 @@ static int dump_mi_command(struct drm_printer *p, · 7 unmodified lines
19391966
19401967 switch (inst_header & MI_OPCODE) {
19411968 case MI_LOAD_REGISTER_IMM:
1942− drm_printf(p, "[%#010x] MI_LOAD_REGISTER_IMM: %d regs\n",
1943− inst_header, (numdw - 1) / 2);
1969+ drm_printf(p, "LRC[%#5tx] = [%#010x] MI_LOAD_REGISTER_IMM: %d regs\n",
1970+ dw - start, inst_header, (numdw - 1) / 2);
19441971 for (int i = 1; i < numdw; i += 2)
1945− drm_printf(p, " - %#6x = %#010x\n", dw[i], dw[i + 1]);
1972+ drm_printf(p, "LRC[%#5tx] = - %#6x = %#010x\n",
1973+ &dw[i] - start, dw[i], dw[i + 1]);
19461974 return numdw;
19471975
19481976 case MI_LOAD_REGISTER_MEM & MI_OPCODE:
1949− drm_printf(p, "[%#010x] MI_LOAD_REGISTER_MEM: %s%s\n",
1950− inst_header,
1977+ drm_printf(p, "LRC[%#5tx] = [%#010x] MI_LOAD_REGISTER_MEM: %s%s\n",
1978+ dw - start, inst_header,
19511979 dw[0] & MI_LRI_LRM_CS_MMIO ? "CS_MMIO " : "",
19521980 dw[0] & MI_LRM_USE_GGTT ? "USE_GGTT " : "");
19531981 if (numdw == 4)
1954− drm_printf(p, " - %#6x = %#010llx\n",
1982+ drm_printf(p, "LRC[%#5tx] = - %#6x = %#010llx\n",
1983+ dw - start,
19551984 dw[1], ((u64)(dw[3]) << 32 | (u64)(dw[2])));
19561985 else
1957− drm_printf(p, " - %*ph (%s)\n",
1958− (int)sizeof(u32) * (numdw - 1), dw + 1,
1959− numdw < 4 ? "truncated" : "malformed");
1986+ drm_printf(p, "LRC[%#5tx] = - %*ph (%s)\n",
1987+ dw - start, (int)sizeof(u32) * (numdw - 1),
1988+ dw + 1, numdw < 4 ? "truncated" : "malformed");
19601989 return numdw;
19611990
19621991 case MI_FORCE_WAKEUP:
1963− drm_printf(p, "[%#010x] MI_FORCE_WAKEUP\n", inst_header);
1992+ drm_printf(p, "LRC[%#5tx] = [%#010x] MI_FORCE_WAKEUP\n",
1993+ dw - start, inst_header);
19641994 return numdw;
19651995
19661996 default:
1967− drm_printf(p, "[%#010x] unknown MI opcode %#x, likely %d dwords\n",
1968− inst_header, opcode, numdw);
1997+ drm_printf(p, "LRC[%#5tx] = [%#010x] unknown MI opcode %#x, likely %d dwords\n",
1998+ dw - start, inst_header, opcode, numdw);
19691999 return numdw;
19702000 }
19712001 }
19722002
19732003 static int dump_gfxpipe_command(struct drm_printer *p,
19742004 struct xe_gt *gt,
2005+ u32 *start,
19752006 u32 *dw,
19762007 int remaining_dw)
19772008 {
@@ -1990,11 +2021,13 @@ static int dump_gfxpipe_command(struct drm_printer *p, · 12 unmodified lines
19902021 switch (*dw & GFXPIPE_MATCH_MASK) {
19912022 #define MATCH(cmd) \
19922023 case cmd: \
1993− drm_printf(p, "[%#010x] " #cmd " (%d dwords)\n", *dw, numdw); \
2024+ drm_printf(p, "LRC[%#5tx] = [%#010x] " #cmd " (%d dwords)\n", \
2025+ dw - start, *dw, numdw); \
19942026 return numdw
19952027 #define MATCH3D(cmd) \
19962028 case CMD_##cmd: \
1997− drm_printf(p, "[%#010x] " #cmd " (%d dwords)\n", *dw, numdw); \
2029+ drm_printf(p, "LRC[%#5tx] = [%#010x] " #cmd " (%d dwords)\n", \
2030+ dw - start, *dw, numdw); \
19982031 return numdw
19992032
20002033 MATCH(STATE_BASE_ADDRESS);
@@ -2126,14 +2159,15 @@ static int dump_gfxpipe_command(struct drm_printer *p, · 125 unmodified lines
21262159 MATCH3D(3DSTATE_SLICE_TABLE_STATE_POINTER_2);
21272160
21282161 default:
2129− drm_printf(p, "[%#010x] unknown GFXPIPE command (pipeline=%#x, opcode=%#x, subopcode=%#x), likely %d dwords\n",
2130− *dw, pipeline, opcode, subopcode, numdw);
2162+ drm_printf(p, "LRC[%#5tx] = [%#010x] unknown GFXPIPE command (pipeline=%#x, opcode=%#x, subopcode=%#x), likely %d dwords\n",
2163+ dw - start, *dw, pipeline, opcode, subopcode, numdw);
21312164 return numdw;
21322165 }
21332166 }
21342167
21352168 static int dump_gfx_state_command(struct drm_printer *p,
21362169 struct xe_gt *gt,
2170+ u32 *start,
21372171 u32 *dw,
21382172 int remaining_dw)
21392173 {
@@ -2151,8 +2185,8 @@ static int dump_gfx_state_command(struct drm_printer *p, · 11 unmodified lines
21512185 MATCH(STATE_WRITE_INLINE);
21522186
21532187 default:
2154− drm_printf(p, "[%#010x] unknown GFX_STATE command (opcode=%#x), likely %d dwords\n",
2155− *dw, opcode, numdw);
2188+ drm_printf(p, "LRC[%#5tx] = [%#010x] unknown GFX_STATE command (opcode=%#x), likely %d dwords\n",
2189+ dw - start, *dw, opcode, numdw);
21562190 return numdw;
21572191 }
21582192 }
@@ -2161,7 +2195,7 @@ void xe_lrc_dump_default(struct drm_printer *p, · 2 unmodified lines
21612195 struct xe_gt *gt,
21622196 enum xe_engine_class hwe_class)
21632197 {
2164− u32 *dw;
2198+ u32 *dw, *start;
21652199 int remaining_dw, num_dw;
21662200
21672201 if (!gt->default_lrc[hwe_class]) {
@@ -2174,18 +2208,20 @@ void xe_lrc_dump_default(struct drm_printer *p, · 6 unmodified lines
21742208 * hardware status page.
21752209 */
21762210 dw = gt->default_lrc[hwe_class] + LRC_PPHWSP_SIZE;
2211+ start = dw;
21772212 remaining_dw = (xe_gt_lrc_size(gt, hwe_class) - LRC_PPHWSP_SIZE) / 4;
21782213
21792214 while (remaining_dw > 0) {
21802215 if ((*dw & XE_INSTR_CMD_TYPE) == XE_INSTR_MI) {
2181− num_dw = dump_mi_command(p, gt, dw, remaining_dw);
2216+ num_dw = dump_mi_command(p, gt, start, dw, remaining_dw);
21822217 } else if ((*dw & XE_INSTR_CMD_TYPE) == XE_INSTR_GFXPIPE) {
2183− num_dw = dump_gfxpipe_command(p, gt, dw, remaining_dw);
2218+ num_dw = dump_gfxpipe_command(p, gt, start, dw, remaining_dw);
21842219 } else if ((*dw & XE_INSTR_CMD_TYPE) == XE_INSTR_GFX_STATE) {
2185− num_dw = dump_gfx_state_command(p, gt, dw, remaining_dw);
2220+ num_dw = dump_gfx_state_command(p, gt, start, dw, remaining_dw);
21862221 } else {
21872222 num_dw = min(instr_dw(*dw), remaining_dw);
2188− drm_printf(p, "[%#10x] Unknown instruction of type %#x, likely %d dwords\n",
2223+ drm_printf(p, "LRC[%#5tx] = [%#10x] Unknown instruction of type %#x, likely %d dwords\n",
2224+ dw - start,
21892225 *dw, REG_FIELD_GET(XE_INSTR_CMD_TYPE, *dw),
21902226 num_dw);
21912227 }
@@ -2563,14 +2599,14 @@ static int get_ctx_timestamp(struct xe_lrc *lrc, u32 engine_id, u64 *reg_ctx_ts) · 371 unmodified lines
25632599 * @lrc: Pointer to the lrc.
25642600 *
25652601 * Return latest ctx timestamp. With support for active contexts, the
2566− * calculation may bb slightly racy, so follow a read-again logic to ensure that
2602+ * calculation may be slightly racy, so follow a read-again logic to ensure that
25672603 * the context is still active before returning the right timestamp.
25682604 *
25692605 * Returns: New ctx timestamp value
25702606 */
25712607 u64 xe_lrc_timestamp(struct xe_lrc *lrc)
25722608 {
2573− u64 lrc_ts, reg_ts, new_ts;
2609+ u64 lrc_ts, reg_ts, new_ts = lrc->ctx_timestamp;
25742610 u32 engine_id;
25752611
25762612 lrc_ts = xe_lrc_ctx_timestamp(lrc);
drivers/gpu/drm/xe/xe_oa.c+5−2
@@ -543,8 +543,7 @@ static ssize_t xe_oa_read(struct file *file, char __user *buf, · 542 unmodified lines
543543 size_t offset = 0;
544544 int ret;
545545
546− /* Can't read from disabled streams */
547− if (!stream->enabled || !stream->sample)
546+ if (!stream->sample)
548547 return -EINVAL;
549548
550549 if (!(file->f_flags & O_NONBLOCK)) {
@@ -1460,6 +1459,10 @@ static void xe_oa_stream_disable(struct xe_oa_stream *stream) · 909 unmodified lines
14601459
14611460 if (stream->sample)
14621461 hrtimer_cancel(&stream->poll_check_timer);
1462+
1463+ /* Update stream->oa_buffer.tail to allow any final reports to be read */
1464+ if (xe_oa_buffer_check_unlocked(stream))
1465+ wake_up(&stream->poll_wq);
14631466 }
14641467
14651468 static int xe_oa_enable_preempt_timeslice(struct xe_oa_stream *stream)
drivers/gpu/drm/xe/xe_page_reclaim.c+26−0
@@ -11,6 +11,7 @@ · 10 unmodified lines
1111 #include "xe_page_reclaim.h"
1212
1313 #include "xe_gt_stats.h"
14+#include "xe_guc_tlb_inval.h"
1415 #include "xe_macros.h"
1516 #include "xe_pat.h"
1617 #include "xe_sa.h"
@@ -26,12 +27,18 @@ · 9 unmodified lines
2627 * flushes.
2728 * - pat_index is transient display (1)
2829 *
30+ * For cases of NULL VMA, there should be no corresponding PRL entry
31+ * so skip over.
32+ *
2933 * Return: true when page reclamation is unnecessary, false otherwise.
3034 */
3135 bool xe_page_reclaim_skip(struct xe_tile *tile, struct xe_vma *vma)
3236 {
3337 u8 l3_policy;
3438
39+ if (xe_vma_is_null(vma))
40+ return true;
41+
3542 l3_policy = xe_pat_index_get_l3_policy(tile->xe, vma->attr.pat_index);
3643
3744 /*
@@ -130,3 +137,22 @@ int xe_page_reclaim_list_alloc_entries(struct xe_page_reclaim_list *prl) · 92 unmodified lines
130137
131138 return page ? 0 : -ENOMEM;
132139 }
140+
141+/**
142+ * xe_guc_page_reclaim_done_handler() - Page reclaim done handler
143+ * @guc: guc
144+ * @msg: message indicating page reclamation done
145+ * @len: length of message
146+ *
147+ * Page reclamation is an extension of TLB invalidation. Both
148+ * operations share the same seqno and fence. When either
149+ * action completes, we need to signal the corresponding
150+ * fence. Since the handling logic is currently identical, this
151+ * function delegates to the TLB invalidation handler.
152+ *
153+ * Return: 0 on success, -EPROTO for malformed messages.
154+ */
155+int xe_guc_page_reclaim_done_handler(struct xe_guc *guc, u32 *msg, u32 len)
156+{
157+ return xe_guc_tlb_inval_done_handler(guc, msg, len);
158+}
drivers/gpu/drm/xe/xe_page_reclaim.h+3−0
@@ -20,6 +20,7 @@ struct xe_tlb_inval; · 19 unmodified lines
2020 struct xe_tlb_inval_fence;
2121 struct xe_tile;
2222 struct xe_gt;
23+struct xe_guc;
2324 struct xe_vma;
2425
2526 struct xe_guc_page_reclaim_entry {
@@ -122,4 +123,6 @@ static inline void xe_page_reclaim_entries_put(struct xe_guc_page_reclaim_entry · 96 unmodified lines
122123 put_page(virt_to_page(entries));
123124 }
124125
126+int xe_guc_page_reclaim_done_handler(struct xe_guc *guc, u32 *msg, u32 len);
127+
125128 #endif /* _XE_PAGE_RECLAIM_H_ */
drivers/gpu/drm/xe/xe_pagefault.c+32−0
@@ -187,6 +187,12 @@ static int xe_pagefault_service(struct xe_pagefault *pf) · 186 unmodified lines
187187 goto unlock_vm;
188188 }
189189
190+ if (xe_vma_read_only(vma) &&
191+ pf->consumer.access_type != XE_PAGEFAULT_ACCESS_TYPE_READ) {
192+ err = -EPERM;
193+ goto unlock_vm;
194+ }
195+
190196 atomic = xe_pagefault_access_is_atomic(pf->consumer.access_type);
191197
192198 if (xe_vma_is_cpu_addr_mirror(vma))
@@ -244,6 +250,31 @@ static void xe_pagefault_print(struct xe_pagefault *pf) · 51 unmodified lines
244250 pf->consumer.engine_instance);
245251 }
246252
253+static void xe_pagefault_save_to_vm(struct xe_device *xe, struct xe_pagefault *pf)
254+{
255+ struct xe_vm *vm;
256+
257+ /*
258+ * Pagefault may be asociated to VM that is not in fault mode.
259+ * Perform asid_to_vm behavior, except if VM is not in fault
260+ * mode, return VM anyways.
261+ */
262+ down_read(&xe->usm.lock);
263+ vm = xa_load(&xe->usm.asid_to_vm, pf->consumer.asid);
264+ if (vm)
265+ xe_vm_get(vm);
266+ else
267+ vm = ERR_PTR(-EINVAL);
268+ up_read(&xe->usm.lock);
269+
270+ if (IS_ERR(vm))
271+ return;
272+
273+ xe_vm_add_fault_entry_pf(vm, pf);
274+
275+ xe_vm_put(vm);
276+}
277+
247278 static void xe_pagefault_queue_work(struct work_struct *w)
248279 {
249280 struct xe_pagefault_queue *pf_queue =
@@ -262,6 +293,7 @@ static void xe_pagefault_queue_work(struct work_struct *w) · 12 unmodified lines
262293
263294 err = xe_pagefault_service(&pf);
264295 if (err) {
296+ xe_pagefault_save_to_vm(gt_to_xe(pf.gt), &pf);
265297 if (!(pf.consumer.access_type & XE_PAGEFAULT_ACCESS_PREFETCH)) {
266298 xe_pagefault_print(&pf);
267299 xe_gt_info(pf.gt, "Fault response: Unsuccessful %pe\n",
drivers/gpu/drm/xe/xe_pat.c+7−7
@@ -92,7 +92,7 @@ struct xe_pat_ops { · 91 unmodified lines
9292 };
9393
9494 static const struct xe_pat_table_entry xelp_pat_table[] = {
95− [0] = { XELP_PAT_WB, XE_COH_AT_LEAST_1WAY },
95+ [0] = { XELP_PAT_WB, XE_COH_1WAY },
9696 [1] = { XELP_PAT_WC, XE_COH_NONE },
9797 [2] = { XELP_PAT_WT, XE_COH_NONE },
9898 [3] = { XELP_PAT_UC, XE_COH_NONE },
@@ -102,19 +102,19 @@ static const struct xe_pat_table_entry xehpc_pat_table[] = { · 3 unmodified lines
102102 [0] = { XELP_PAT_UC, XE_COH_NONE },
103103 [1] = { XELP_PAT_WC, XE_COH_NONE },
104104 [2] = { XELP_PAT_WT, XE_COH_NONE },
105− [3] = { XELP_PAT_WB, XE_COH_AT_LEAST_1WAY },
105+ [3] = { XELP_PAT_WB, XE_COH_1WAY },
106106 [4] = { XEHPC_PAT_CLOS(1) | XELP_PAT_WT, XE_COH_NONE },
107− [5] = { XEHPC_PAT_CLOS(1) | XELP_PAT_WB, XE_COH_AT_LEAST_1WAY },
107+ [5] = { XEHPC_PAT_CLOS(1) | XELP_PAT_WB, XE_COH_1WAY },
108108 [6] = { XEHPC_PAT_CLOS(2) | XELP_PAT_WT, XE_COH_NONE },
109− [7] = { XEHPC_PAT_CLOS(2) | XELP_PAT_WB, XE_COH_AT_LEAST_1WAY },
109+ [7] = { XEHPC_PAT_CLOS(2) | XELP_PAT_WB, XE_COH_1WAY },
110110 };
111111
112112 static const struct xe_pat_table_entry xelpg_pat_table[] = {
113113 [0] = { XELPG_PAT_0_WB, XE_COH_NONE },
114114 [1] = { XELPG_PAT_1_WT, XE_COH_NONE },
115115 [2] = { XELPG_PAT_3_UC, XE_COH_NONE },
116− [3] = { XELPG_PAT_0_WB | XELPG_2_COH_1W, XE_COH_AT_LEAST_1WAY },
117− [4] = { XELPG_PAT_0_WB | XELPG_3_COH_2W, XE_COH_AT_LEAST_1WAY },
116+ [3] = { XELPG_PAT_0_WB | XELPG_2_COH_1W, XE_COH_1WAY },
117+ [4] = { XELPG_PAT_0_WB | XELPG_3_COH_2W, XE_COH_2WAY },
118118 };
119119
120120 /*
@@ -147,7 +147,7 @@ static const struct xe_pat_table_entry xelpg_pat_table[] = { · 26 unmodified lines
147147 REG_FIELD_PREP(XE2_L3_POLICY, l3_policy) | \
148148 REG_FIELD_PREP(XE2_L4_POLICY, l4_policy) | \
149149 REG_FIELD_PREP(XE2_COH_MODE, __coh_mode), \
150− .coh_mode = __coh_mode ? XE_COH_AT_LEAST_1WAY : XE_COH_NONE, \
150+ .coh_mode = __coh_mode ? __coh_mode : XE_COH_NONE, \
151151 .valid = 1 \
152152 }
153153
drivers/gpu/drm/xe/xe_pat.h+3−2
@@ -28,8 +28,9 @@ struct xe_pat_table_entry { · 27 unmodified lines
2828 /**
2929 * @coh_mode: The GPU coherency mode that @value maps to.
3030 */
31−#define XE_COH_NONE 1
32−#define XE_COH_AT_LEAST_1WAY 2
31+#define XE_COH_NONE 1
32+#define XE_COH_1WAY 2
33+#define XE_COH_2WAY 3
3334 u16 coh_mode;
3435
3536 /**
drivers/gpu/drm/xe/xe_pt.c+35−15
@@ -1442,9 +1442,9 @@ static int op_check_svm_userptr(struct xe_vm *vm, struct xe_vma_op *op, · 1441 unmodified lines
14421442 err = vma_check_userptr(vm, op->map.vma, pt_update);
14431443 break;
14441444 case DRM_GPUVA_OP_REMAP:
1445− if (op->remap.prev)
1445+ if (op->remap.prev && !op->remap.skip_prev)
14461446 err = vma_check_userptr(vm, op->remap.prev, pt_update);
1447− if (!err && op->remap.next)
1447+ if (!err && op->remap.next && !op->remap.skip_next)
14481448 err = vma_check_userptr(vm, op->remap.next, pt_update);
14491449 break;
14501450 case DRM_GPUVA_OP_UNMAP:
@@ -1655,14 +1655,35 @@ static int xe_pt_stage_unbind_entry(struct xe_ptw *parent, pgoff_t offset, · 204 unmodified lines
16551655 XE_WARN_ON(!level);
16561656 /* Check for leaf node */
16571657 if (xe_walk->prl && xe_page_reclaim_list_valid(xe_walk->prl) &&
1658− (!xe_child->base.children || !xe_child->base.children[first])) {
1658+ xe_child->level <= MAX_HUGEPTE_LEVEL) {
16591659 struct iosys_map *leaf_map = &xe_child->bo->vmap;
16601660 pgoff_t count = xe_pt_num_entries(addr, next, xe_child->level, walk);
16611661
16621662 for (pgoff_t i = 0; i < count; i++) {
1663− u64 pte = xe_map_rd(xe, leaf_map, (first + i) * sizeof(u64), u64);
1663+ u64 pte;
16641664 int ret;
16651665
1666+ /*
1667+ * If not a leaf pt, skip unless non-leaf pt is interleaved between
1668+ * leaf ptes which causes the page walk to skip over the child leaves
1669+ */
1670+ if (xe_child->base.children && xe_child->base.children[first + i]) {
1671+ u64 pt_size = 1ULL << walk->shifts[xe_child->level];
1672+ bool edge_pt = (i == 0 && !IS_ALIGNED(addr, pt_size)) ||
1673+ (i == count - 1 && !IS_ALIGNED(next, pt_size));
1674+
1675+ if (!edge_pt) {
1676+ xe_page_reclaim_list_abort(xe_walk->tile->primary_gt,
1677+ xe_walk->prl,
1678+ "PT is skipped by walk at level=%u offset=%lu",
1679+ xe_child->level, first + i);
1680+ break;
1681+ }
1682+ continue;
1683+ }
1684+
1685+ pte = xe_map_rd(xe, leaf_map, (first + i) * sizeof(u64), u64);
1686+
16661687 /*
16671688 * In rare scenarios, pte may not be written yet due to racy conditions.
16681689 * In such cases, invalidate the PRL and fallback to full PPC invalidation.
@@ -1674,9 +1695,8 @@ static int xe_pt_stage_unbind_entry(struct xe_ptw *parent, pgoff_t offset, · 5 unmodified lines
16741695 }
16751696
16761697 /* Ensure it is a defined page */
1677− xe_tile_assert(xe_walk->tile,
1678− xe_child->level == 0 ||
1679− (pte & (XE_PTE_PS64 | XE_PDE_PS_2M | XE_PDPE_PS_1G)));
1698+ xe_tile_assert(xe_walk->tile, xe_child->level == 0 ||
1699+ (pte & (XE_PDE_PS_2M | XE_PDPE_PS_1G)));
16801700
16811701 /* An entry should be added for 64KB but contigious 4K have XE_PTE_PS64 */
16821702 if (pte & XE_PTE_PS64)
@@ -1701,11 +1721,11 @@ static int xe_pt_stage_unbind_entry(struct xe_ptw *parent, pgoff_t offset, · 18 unmodified lines
17011721 killed = xe_pt_check_kill(addr, next, level - 1, xe_child, action, walk);
17021722
17031723 /*
1704− * Verify PRL is active and if entry is not a leaf pte (base.children conditions),
1705− * there is a potential need to invalidate the PRL if any PTE (num_live) are dropped.
1724+ * Verify if any PTE are potentially dropped at non-leaf levels, either from being
1725+ * killed or the page walk covers the region.
17061726 */
1707− if (xe_walk->prl && level > 1 && xe_child->num_live &&
1708− xe_child->base.children && xe_child->base.children[first]) {
1727+ if (xe_walk->prl && xe_page_reclaim_list_valid(xe_walk->prl) &&
1728+ xe_child->level > MAX_HUGEPTE_LEVEL && xe_child->num_live) {
17091729 bool covered = xe_pt_covers(addr, next, xe_child->level, &xe_walk->base);
17101730
17111731 /*
@@ -2178,12 +2198,12 @@ static int op_prepare(struct xe_vm *vm, · 466 unmodified lines
21782198
21792199 err = unbind_op_prepare(tile, pt_update_ops, old);
21802200
2181− if (!err && op->remap.prev) {
2201+ if (!err && op->remap.prev && !op->remap.skip_prev) {
21822202 err = bind_op_prepare(vm, tile, pt_update_ops,
21832203 op->remap.prev, false);
21842204 pt_update_ops->wait_vm_bookkeep = true;
21852205 }
2186− if (!err && op->remap.next) {
2206+ if (!err && op->remap.next && !op->remap.skip_next) {
21872207 err = bind_op_prepare(vm, tile, pt_update_ops,
21882208 op->remap.next, false);
21892209 pt_update_ops->wait_vm_bookkeep = true;
@@ -2408,10 +2428,10 @@ static void op_commit(struct xe_vm *vm, · 218 unmodified lines
24082428
24092429 unbind_op_commit(vm, tile, pt_update_ops, old, fence, fence2);
24102430
2411− if (op->remap.prev)
2431+ if (op->remap.prev && !op->remap.skip_prev)
24122432 bind_op_commit(vm, tile, pt_update_ops, op->remap.prev,
24132433 fence, fence2, false);
2414− if (op->remap.next)
2434+ if (op->remap.next && !op->remap.skip_next)
24152435 bind_op_commit(vm, tile, pt_update_ops, op->remap.next,
24162436 fence, fence2, false);
24172437 break;
drivers/gpu/drm/xe/xe_ring_ops.c+122−21
@@ -48,15 +48,48 @@ static u32 preparser_disable(bool state) · 47 unmodified lines
4848 return MI_ARB_CHECK | BIT(8) | state;
4949 }
5050
51−static int emit_aux_table_inv(struct xe_gt *gt, struct xe_reg reg,
52− u32 *dw, int i)
51+static u32 *
52+__emit_aux_table_inv(u32 *cmd, const struct xe_reg reg, u32 adj_offset)
5353 {
54− dw[i++] = MI_LOAD_REGISTER_IMM | MI_LRI_NUM_REGS(1) | MI_LRI_MMIO_REMAP_EN;
55− dw[i++] = reg.addr + gt->mmio.adj_offset;
56− dw[i++] = AUX_INV;
57− dw[i++] = MI_NOOP;
54+ *cmd++ = MI_LOAD_REGISTER_IMM | MI_LRI_NUM_REGS(1) |
55+ MI_LRI_MMIO_REMAP_EN;
56+ *cmd++ = reg.addr + adj_offset;
57+ *cmd++ = AUX_INV;
58+ *cmd++ = MI_SEMAPHORE_WAIT_TOKEN | MI_SEMAPHORE_REGISTER_POLL |
59+ MI_SEMAPHORE_POLL | MI_SEMAPHORE_SAD_EQ_SDD;
60+ *cmd++ = 0;
61+ *cmd++ = reg.addr + adj_offset;
62+ *cmd++ = 0;
63+ *cmd++ = 0;
64+
65+ return cmd;
66+}
5867
59− return i;
68+static u32 *emit_aux_table_inv_render_compute(struct xe_gt *gt, u32 *cmd)
69+{
70+ return __emit_aux_table_inv(cmd, CCS_AUX_INV, gt->mmio.adj_offset);
71+}
72+
73+static u32 *emit_aux_table_inv_video_decode(struct xe_gt *gt, u32 *cmd)
74+{
75+ return __emit_aux_table_inv(cmd, VD0_AUX_INV, gt->mmio.adj_offset);
76+}
77+
78+static u32 *emit_aux_table_inv_video_enhance(struct xe_gt *gt, u32 *cmd)
79+{
80+ return __emit_aux_table_inv(cmd, VE0_AUX_INV, gt->mmio.adj_offset);
81+}
82+
83+static int emit_aux_table_inv(struct xe_hw_engine *hwe, u32 *dw, int i)
84+{
85+ struct xe_gt *gt = hwe->gt;
86+ u32 *(*emit)(struct xe_gt *gt, u32 *cmd) =
87+ gt->ring_ops[hwe->class]->emit_aux_table_inv;
88+
89+ if (emit)
90+ return emit(gt, dw + i) - dw;
91+ else
92+ return i;
6093 }
6194
6295 static int emit_user_interrupt(u32 *dw, int i)
@@ -256,6 +289,32 @@ static int emit_copy_timestamp(struct xe_device *xe, struct xe_lrc *lrc, · 193 unmodified lines
256289 return i;
257290 }
258291
292+static int emit_fake_watchdog(struct xe_lrc *lrc, u32 *dw, int i)
293+{
294+ /*
295+ * Setup a watchdog with impossible condition to always trigger an
296+ * hardware interrupt that would force the GuC to reset the engine.
297+ */
298+
299+ dw[i++] = MI_LOAD_REGISTER_IMM | MI_LRI_NUM_REGS(2) | MI_LRI_LRM_CS_MMIO;
300+ dw[i++] = PR_CTR_THRSH(0).addr;
301+ dw[i++] = 2; /* small threshold */
302+ dw[i++] = PR_CTR_CTRL(0).addr;
303+ dw[i++] = CTR_LOGIC_OP(START);
304+
305+ dw[i++] = MI_SEMAPHORE_WAIT | MI_SEMW_GGTT | MI_SEMW_POLL | MI_SEMW_COMPARE(SAD_EQ_SDD);
306+ dw[i++] = 0xdead; /* this should never be seen */
307+ dw[i++] = lower_32_bits(xe_lrc_ggtt_addr(lrc));
308+ dw[i++] = upper_32_bits(xe_lrc_ggtt_addr(lrc));
309+ dw[i++] = 0; /* unused token */
310+
311+ dw[i++] = MI_LOAD_REGISTER_IMM | MI_LRI_NUM_REGS(1) | MI_LRI_LRM_CS_MMIO;
312+ dw[i++] = PR_CTR_CTRL(0).addr;
313+ dw[i++] = CTR_LOGIC_OP(STOP);
314+
315+ return i;
316+}
317+
259318 /* for engines that don't require any special HW handling (no EUs, no aux inval, etc) */
260319 static void __emit_job_gen12_simple(struct xe_sched_job *job, struct xe_lrc *lrc,
261320 u64 batch_addr, u32 *head, u32 seqno)
@@ -266,6 +325,9 @@ static void __emit_job_gen12_simple(struct xe_sched_job *job, struct xe_lrc *lrc · 4 unmodified lines
266325
267326 *head = lrc->ring.tail;
268327
328+ if (job->ring_ops_force_reset)
329+ i = emit_fake_watchdog(lrc, dw, i);
330+
269331 i = emit_copy_timestamp(gt_to_xe(gt), lrc, dw, i);
270332
271333 if (job->ring_ops_flush_tlb) {
@@ -305,9 +367,9 @@ static bool has_aux_ccs(struct xe_device *xe) · 33 unmodified lines
305367 * PVC is a special case that has no compression of either type
306368 * (FlatCCS or AuxCCS). Also, AuxCCS is no longer used from Xe2
307369 * onward, so any future platforms with no FlatCCS will not have
308− * AuxCCS either.
370+ * AuxCCS, and we explicitly do not want to support it on MTL.
309371 */
310− if (GRAPHICS_VER(xe) >= 20 || xe->info.platform == XE_PVC)
372+ if (GRAPHICS_VERx100(xe) >= 1270 || xe->info.platform == XE_PVC)
311373 return false;
312374
313375 return !xe->info.has_flat_ccs;
@@ -320,21 +382,18 @@ static void __emit_job_gen12_video(struct xe_sched_job *job, struct xe_lrc *lrc, · 6 unmodified lines
320382 u32 ppgtt_flag = get_ppgtt_flag(job);
321383 struct xe_gt *gt = job->q->gt;
322384 struct xe_device *xe = gt_to_xe(gt);
323− bool decode = job->q->class == XE_ENGINE_CLASS_VIDEO_DECODE;
324385
325386 *head = lrc->ring.tail;
326387
388+ if (job->ring_ops_force_reset)
389+ i = emit_fake_watchdog(lrc, dw, i);
390+
327391 i = emit_copy_timestamp(xe, lrc, dw, i);
328392
329393 dw[i++] = preparser_disable(true);
330394
331395 /* hsdes: 1809175790 */
332− if (has_aux_ccs(xe)) {
333− if (decode)
334− i = emit_aux_table_inv(gt, VD0_AUX_INV, dw, i);
335− else
336− i = emit_aux_table_inv(gt, VE0_AUX_INV, dw, i);
337− }
396+ i = emit_aux_table_inv(job->q->hwe, dw, i);
338397
339398 if (job->ring_ops_flush_tlb)
340399 i = emit_flush_imm_ggtt(xe_lrc_start_seqno_ggtt_addr(lrc),
@@ -381,8 +440,18 @@ static void __emit_job_gen12_render_compute(struct xe_sched_job *job, · 40 unmodified lines
381440
382441 *head = lrc->ring.tail;
383442
443+ if (job->ring_ops_force_reset)
444+ i = emit_fake_watchdog(lrc, dw, i);
445+
384446 i = emit_copy_timestamp(xe, lrc, dw, i);
385447
448+ /*
449+ * On AuxCCS platforms the invalidation of the Aux table requires
450+ * quiescing the memory traffic beforehand.
451+ */
452+ if (has_aux_ccs(xe))
453+ i = emit_render_cache_flush(job, dw, i);
454+
386455 dw[i++] = preparser_disable(true);
387456 if (lacks_render)
388457 mask_flags = PIPE_CONTROL_3D_ARCH_FLAGS;
@@ -393,8 +462,7 @@ static void __emit_job_gen12_render_compute(struct xe_sched_job *job, · 4 unmodified lines
393462 i = emit_pipe_invalidate(job->q, mask_flags, job->ring_ops_flush_tlb, dw, i);
394463
395464 /* hsdes: 1809175790 */
396− if (has_aux_ccs(xe))
397− i = emit_aux_table_inv(gt, CCS_AUX_INV, dw, i);
465+ i = emit_aux_table_inv(job->q->hwe, dw, i);
398466
399467 dw[i++] = preparser_disable(false);
400468
@@ -433,6 +501,8 @@ static void emit_migration_job_gen12(struct xe_sched_job *job, · 32 unmodified lines
433501
434502 *head = lrc->ring.tail;
435503
504+ xe_gt_assert(gt, !job->ring_ops_force_reset);
505+
436506 i = emit_copy_timestamp(xe, lrc, dw, i);
437507
438508 i = emit_store_imm_ggtt(saddr, seqno, dw, i);
@@ -519,7 +589,11 @@ static const struct xe_ring_ops ring_ops_gen12_copy = { · 80 unmodified lines
519589 .emit_job = emit_job_gen12_copy,
520590 };
521591
522−static const struct xe_ring_ops ring_ops_gen12_video = {
592+static const struct xe_ring_ops ring_ops_gen12_video_decode = {
593+ .emit_job = emit_job_gen12_video,
594+};
595+
596+static const struct xe_ring_ops ring_ops_gen12_video_enhance = {
523597 .emit_job = emit_job_gen12_video,
524598 };
525599
@@ -527,20 +601,47 @@ static const struct xe_ring_ops ring_ops_gen12_render_compute = { · 1 unmodified line
527601 .emit_job = emit_job_gen12_render_compute,
528602 };
529603
604+static const struct xe_ring_ops auxccs_ring_ops_gen12_video_decode = {
605+ .emit_job = emit_job_gen12_video,
606+ .emit_aux_table_inv = emit_aux_table_inv_video_decode,
607+};
608+
609+static const struct xe_ring_ops auxccs_ring_ops_gen12_video_enhance = {
610+ .emit_job = emit_job_gen12_video,
611+ .emit_aux_table_inv = emit_aux_table_inv_video_enhance,
612+};
613+
614+static const struct xe_ring_ops auxccs_ring_ops_gen12_render_compute = {
615+ .emit_job = emit_job_gen12_render_compute,
616+ .emit_aux_table_inv = emit_aux_table_inv_render_compute,
617+};
618+
530619 const struct xe_ring_ops *
531620 xe_ring_ops_get(struct xe_gt *gt, enum xe_engine_class class)
532621 {
622+ struct xe_device *xe = gt_to_xe(gt);
623+
533624 switch (class) {
534625 case XE_ENGINE_CLASS_OTHER:
535626 return &ring_ops_gen12_gsc;
536627 case XE_ENGINE_CLASS_COPY:
537628 return &ring_ops_gen12_copy;
538629 case XE_ENGINE_CLASS_VIDEO_DECODE:
630+ if (has_aux_ccs(xe))
631+ return &auxccs_ring_ops_gen12_video_decode;
632+ else
633+ return &ring_ops_gen12_video_decode;
539634 case XE_ENGINE_CLASS_VIDEO_ENHANCE:
540− return &ring_ops_gen12_video;
635+ if (has_aux_ccs(xe))
636+ return &auxccs_ring_ops_gen12_video_enhance;
637+ else
638+ return &ring_ops_gen12_video_enhance;
541639 case XE_ENGINE_CLASS_RENDER:
542640 case XE_ENGINE_CLASS_COMPUTE:
543− return &ring_ops_gen12_render_compute;
641+ if (has_aux_ccs(xe))
642+ return &auxccs_ring_ops_gen12_render_compute;
643+ else
644+ return &ring_ops_gen12_render_compute;
544645 default:
545646 return NULL;
546647 }
drivers/gpu/drm/xe/xe_ring_ops_types.h+7−1
@@ -6,9 +6,12 @@ · 5 unmodified lines
66 #ifndef _XE_RING_OPS_TYPES_H_
77 #define _XE_RING_OPS_TYPES_H_
88
9+#include <linux/types.h>
10+
11+struct xe_gt;
912 struct xe_sched_job;
1013
11−#define MAX_JOB_SIZE_DW 58
14+#define MAX_JOB_SIZE_DW 74
1215 #define MAX_JOB_SIZE_BYTES (MAX_JOB_SIZE_DW * 4)
1316
1417 /**
@@ -17,6 +20,9 @@ struct xe_sched_job; · 2 unmodified lines
1720 struct xe_ring_ops {
1821 /** @emit_job: Write job to ring */
1922 void (*emit_job)(struct xe_sched_job *job);
23+
24+ /** @emit_aux_table_inv: Emit aux table invalidation to the ring */
25+ u32 *(*emit_aux_table_inv)(struct xe_gt *gt, u32 *cmd);
2026 };
2127
2228 #endif
drivers/gpu/drm/xe/xe_sched_job_types.h+2−0
@@ -63,6 +63,8 @@ struct xe_sched_job { · 62 unmodified lines
6363 u64 sample_timestamp;
6464 /** @ring_ops_flush_tlb: The ring ops need to flush TLB before payload. */
6565 bool ring_ops_flush_tlb;
66+ /** @ring_ops_force_reset: The ring ops need to trigger a reset before payload. */
67+ bool ring_ops_force_reset;
6668 /** @ggtt: mapped in ggtt. */
6769 bool ggtt;
6870 /** @restore_replay: job being replayed for restore */
drivers/gpu/drm/xe/xe_sriov_packet.c+2−0
@@ -341,6 +341,8 @@ ssize_t xe_sriov_packet_write_single(struct xe_device *xe, unsigned int vfid, · 340 unmodified lines
341341 ret = xe_sriov_pf_migration_restore_produce(xe, vfid, *data);
342342 if (ret) {
343343 xe_sriov_packet_free(*data);
344+ *data = NULL;
345+
344346 return ret;
345347 }
346348
drivers/gpu/drm/xe/xe_sriov_pf_control.c+24−0
@@ -123,6 +123,30 @@ int xe_sriov_pf_control_reset_vf(struct xe_device *xe, unsigned int vfid) · 122 unmodified lines
123123 return result;
124124 }
125125
126+/**
127+ * xe_sriov_pf_control_prepare_flr() - Notify PF that VF FLR prepare has started.
128+ * @xe: the &xe_device
129+ * @vfid: the VF identifier
130+ *
131+ * This function is for PF only.
132+ *
133+ * Return: 0 on success or a negative error code on failure.
134+ */
135+int xe_sriov_pf_control_prepare_flr(struct xe_device *xe, unsigned int vfid)
136+{
137+ struct xe_gt *gt;
138+ unsigned int id;
139+ int result = 0;
140+ int err;
141+
142+ for_each_gt(gt, xe, id) {
143+ err = xe_gt_sriov_pf_control_prepare_flr(gt, vfid);
144+ result = result ? -EUCLEAN : err;
145+ }
146+
147+ return result;
148+}
149+
126150 /**
127151 * xe_sriov_pf_control_wait_flr() - Wait for a VF reset (FLR) to complete.
128152 * @xe: the &xe_device
drivers/gpu/drm/xe/xe_sriov_pf_control.h+1−0
@@ -12,6 +12,7 @@ int xe_sriov_pf_control_pause_vf(struct xe_device *xe, unsigned int vfid); · 11 unmodified lines
1212 int xe_sriov_pf_control_resume_vf(struct xe_device *xe, unsigned int vfid);
1313 int xe_sriov_pf_control_stop_vf(struct xe_device *xe, unsigned int vfid);
1414 int xe_sriov_pf_control_reset_vf(struct xe_device *xe, unsigned int vfid);
15+int xe_sriov_pf_control_prepare_flr(struct xe_device *xe, unsigned int vfid);
1516 int xe_sriov_pf_control_wait_flr(struct xe_device *xe, unsigned int vfid);
1617 int xe_sriov_pf_control_sync_flr(struct xe_device *xe, unsigned int vfid);
1718 int xe_sriov_pf_control_trigger_save_vf(struct xe_device *xe, unsigned int vfid);
drivers/gpu/drm/xe/xe_sriov_vfio.c+1−0
@@ -42,6 +42,7 @@ _type xe_sriov_vfio_##_func(struct xe_device *xe, unsigned int vfid) \ · 41 unmodified lines
4242 EXPORT_SYMBOL_FOR_MODULES(xe_sriov_vfio_##_func, "xe-vfio-pci")
4343
4444 DEFINE_XE_SRIOV_VFIO_FUNCTION(int, wait_flr_done, control_wait_flr);
45+DEFINE_XE_SRIOV_VFIO_FUNCTION(int, flr_prepare, control_prepare_flr);
4546 DEFINE_XE_SRIOV_VFIO_FUNCTION(int, suspend_device, control_pause_vf);
4647 DEFINE_XE_SRIOV_VFIO_FUNCTION(int, resume_device, control_resume_vf);
4748 DEFINE_XE_SRIOV_VFIO_FUNCTION(int, stop_copy_enter, control_trigger_save_vf);
drivers/gpu/drm/xe/xe_svm.c+25−2
@@ -485,10 +485,33 @@ static void xe_svm_copy_kb_stats_incr(struct xe_gt *gt, · 484 unmodified lines
485485 const enum xe_svm_copy_dir dir,
486486 int kb)
487487 {
488− if (dir == XE_SVM_COPY_TO_VRAM)
488+ if (dir == XE_SVM_COPY_TO_VRAM) {
489+ switch (kb) {
490+ case 4:
491+ xe_gt_stats_incr(gt, XE_GT_STATS_ID_SVM_4K_DEVICE_COPY_KB, kb);
492+ break;
493+ case 64:
494+ xe_gt_stats_incr(gt, XE_GT_STATS_ID_SVM_64K_DEVICE_COPY_KB, kb);
495+ break;
496+ case 2048:
497+ xe_gt_stats_incr(gt, XE_GT_STATS_ID_SVM_2M_DEVICE_COPY_KB, kb);
498+ break;
499+ }
489500 xe_gt_stats_incr(gt, XE_GT_STATS_ID_SVM_DEVICE_COPY_KB, kb);
490− else
501+ } else {
502+ switch (kb) {
503+ case 4:
504+ xe_gt_stats_incr(gt, XE_GT_STATS_ID_SVM_4K_CPU_COPY_KB, kb);
505+ break;
506+ case 64:
507+ xe_gt_stats_incr(gt, XE_GT_STATS_ID_SVM_64K_CPU_COPY_KB, kb);
508+ break;
509+ case 2048:
510+ xe_gt_stats_incr(gt, XE_GT_STATS_ID_SVM_2M_CPU_COPY_KB, kb);
511+ break;
512+ }
491513 xe_gt_stats_incr(gt, XE_GT_STATS_ID_SVM_CPU_COPY_KB, kb);
514+ }
492515 }
493516
494517 static void xe_svm_copy_us_stats_incr(struct xe_gt *gt,
drivers/gpu/drm/xe/xe_uc.c+7−15
@@ -157,23 +157,19 @@ static int vf_uc_load_hw(struct xe_uc *uc) · 156 unmodified lines
157157
158158 err = xe_gt_sriov_vf_connect(uc_to_gt(uc));
159159 if (err)
160− goto err_out;
160+ return err;
161161
162162 uc->guc.submission_state.enabled = true;
163163
164164 err = xe_guc_opt_in_features_enable(&uc->guc);
165165 if (err)
166− goto err_out;
166+ return err;
167167
168168 err = xe_gt_record_default_lrcs(uc_to_gt(uc));
169169 if (err)
170− goto err_out;
170+ return err;
171171
172172 return 0;
173−
174−err_out:
175− xe_guc_sanitize(&uc->guc);
176− return err;
177173 }
178174
179175 /*
@@ -205,19 +201,19 @@ int xe_uc_load_hw(struct xe_uc *uc) · 25 unmodified lines
205201
206202 ret = xe_gt_record_default_lrcs(uc_to_gt(uc));
207203 if (ret)
208− goto err_out;
204+ return ret;
209205
210206 ret = xe_guc_post_load_init(&uc->guc);
211207 if (ret)
212− goto err_out;
208+ return ret;
213209
214210 ret = xe_guc_pc_start(&uc->guc.pc);
215211 if (ret)
216− goto err_out;
212+ return ret;
217213
218214 ret = xe_guc_rc_enable(&uc->guc);
219215 if (ret)
220− goto err_out;
216+ return ret;
221217
222218 xe_guc_engine_activity_enable_stats(&uc->guc);
223219
@@ -232,10 +228,6 @@ int xe_uc_load_hw(struct xe_uc *uc) · 8 unmodified lines
232228 xe_gsc_load_start(&uc->gsc);
233229
234230 return 0;
235−
236−err_out:
237− xe_guc_sanitize(&uc->guc);
238− return ret;
239231 }
240232
241233 int xe_uc_reset_prepare(struct xe_uc *uc)
drivers/gpu/drm/xe/xe_vm.c+218−5
@@ -27,6 +27,7 @@ · 26 unmodified lines
2727 #include "xe_device.h"
2828 #include "xe_drm_client.h"
2929 #include "xe_exec_queue.h"
30+#include "xe_gt.h"
3031 #include "xe_migrate.h"
3132 #include "xe_pat.h"
3233 #include "xe_pm.h"
@@ -577,6 +578,74 @@ out_unlock_outer: · 544 unmodified lines
577578 trace_xe_vm_rebind_worker_exit(vm);
578579 }
579580
581+/**
582+ * xe_vm_add_fault_entry_pf() - Add pagefault to vm fault list
583+ * @vm: The VM.
584+ * @pf: The pagefault.
585+ *
586+ * This function takes the data from the pagefault @pf and saves it to @vm->faults.list.
587+ *
588+ * The function exits silently if the list is full, and reports a warning if the pagefault
589+ * could not be saved to the list.
590+ */
591+void xe_vm_add_fault_entry_pf(struct xe_vm *vm, struct xe_pagefault *pf)
592+{
593+ struct xe_vm_fault_entry *e;
594+ struct xe_hw_engine *hwe;
595+
596+ /* Do not report faults on reserved engines */
597+ hwe = xe_gt_hw_engine(pf->gt, pf->consumer.engine_class,
598+ pf->consumer.engine_instance, false);
599+ if (!hwe || xe_hw_engine_is_reserved(hwe))
600+ return;
601+
602+ e = kzalloc_obj(*e);
603+ if (!e) {
604+ drm_warn(&vm->xe->drm,
605+ "Could not allocate memory for fault!\n");
606+ return;
607+ }
608+
609+ guard(spinlock)(&vm->faults.lock);
610+
611+ /*
612+ * Limit the number of faults in the fault list to prevent
613+ * memory overuse.
614+ */
615+ if (vm->faults.len >= MAX_FAULTS_SAVED_PER_VM) {
616+ kfree(e);
617+ return;
618+ }
619+
620+ e->address = pf->consumer.page_addr;
621+ /*
622+ * TODO:
623+ * Address precision is currently always SZ_4K, but this may change
624+ * in the future.
625+ */
626+ e->address_precision = SZ_4K;
627+ e->access_type = pf->consumer.access_type;
628+ e->fault_type = FIELD_GET(XE_PAGEFAULT_TYPE_MASK,
629+ pf->consumer.fault_type_level),
630+ e->fault_level = FIELD_GET(XE_PAGEFAULT_LEVEL_MASK,
631+ pf->consumer.fault_type_level),
632+
633+ list_add_tail(&e->list, &vm->faults.list);
634+ vm->faults.len++;
635+}
636+
637+static void xe_vm_clear_fault_entries(struct xe_vm *vm)
638+{
639+ struct xe_vm_fault_entry *e, *tmp;
640+
641+ guard(spinlock)(&vm->faults.lock);
642+ list_for_each_entry_safe(e, tmp, &vm->faults.list, list) {
643+ list_del(&e->list);
644+ kfree(e);
645+ }
646+ vm->faults.len = 0;
647+}
648+
580649 static int xe_vma_ops_alloc(struct xe_vma_ops *vops, bool array_of_binds)
581650 {
582651 int i;
@@ -1538,6 +1607,9 @@ struct xe_vm *xe_vm_create(struct xe_device *xe, u32 flags, struct xe_file *xef) · 955 unmodified lines
15381607 INIT_LIST_HEAD(&vm->userptr.invalidated);
15391608 spin_lock_init(&vm->userptr.invalidated_lock);
15401609
1610+ INIT_LIST_HEAD(&vm->faults.list);
1611+ spin_lock_init(&vm->faults.lock);
1612+
15411613 ttm_lru_bulk_move_init(&vm->lru_bulk_move);
15421614
15431615 INIT_WORK(&vm->destroy_work, vm_destroy_work_func);
@@ -1854,6 +1926,8 @@ void xe_vm_close_and_put(struct xe_vm *vm) · 310 unmodified lines
18541926 }
18551927 up_write(&xe->usm.lock);
18561928
1929+ xe_vm_clear_fault_entries(vm);
1930+
18571931 for_each_tile(tile, xe, id)
18581932 xe_range_fence_tree_fini(&vm->rftree[id]);
18591933
@@ -2584,7 +2658,6 @@ static int xe_vma_op_commit(struct xe_vm *vm, struct xe_vma_op *op) · 724 unmodified lines
25842658 if (!err && op->remap.skip_prev) {
25852659 op->remap.prev->tile_present =
25862660 tile_present;
2587− op->remap.prev = NULL;
25882661 }
25892662 }
25902663 if (op->remap.next) {
@@ -2594,11 +2667,13 @@ static int xe_vma_op_commit(struct xe_vm *vm, struct xe_vma_op *op) · 3 unmodified lines
25942667 if (!err && op->remap.skip_next) {
25952668 op->remap.next->tile_present =
25962669 tile_present;
2597− op->remap.next = NULL;
25982670 }
25992671 }
26002672
2601− /* Adjust for partial unbind after removing VMA from VM */
2673+ /*
2674+ * Adjust for partial unbind after removing VMA from VM. In case
2675+ * of unwind we might need to undo this later.
2676+ */
26022677 if (!err) {
26032678 op->base.remap.unmap->va->va.addr = op->remap.start;
26042679 op->base.remap.unmap->va->va.range = op->remap.range;
@@ -2717,6 +2792,8 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops, · 112 unmodified lines
27172792
27182793 op->remap.start = xe_vma_start(old);
27192794 op->remap.range = xe_vma_size(old);
2795+ op->remap.old_start = op->remap.start;
2796+ op->remap.old_range = op->remap.range;
27202797
27212798 flags |= op->base.remap.unmap->va->flags & XE_VMA_CREATE_MASK;
27222799 if (op->base.remap.prev) {
@@ -2865,8 +2942,19 @@ static void xe_vma_op_unwind(struct xe_vm *vm, struct xe_vma_op *op, · 142 unmodified lines
28652942 xe_svm_notifier_lock(vm);
28662943 vma->gpuva.flags &= ~XE_VMA_DESTROYED;
28672944 xe_svm_notifier_unlock(vm);
2868− if (post_commit)
2945+ if (post_commit) {
2946+ /*
2947+ * Restore the old va range, in case of the
2948+ * prev/next skip optimisation. Otherwise what
2949+ * we re-insert here could be smaller than the
2950+ * original range.
2951+ */
2952+ op->base.remap.unmap->va->va.addr =
2953+ op->remap.old_start;
2954+ op->base.remap.unmap->va->va.range =
2955+ op->remap.old_range;
28692956 xe_vm_insert_vma(vm, vma);
2957+ }
28702958 }
28712959 break;
28722960 }
@@ -3465,7 +3553,7 @@ static int vm_bind_ioctl_check_args(struct xe_device *xe, struct xe_vm *vm, · 592 unmodified lines
34653553 goto free_bind_ops;
34663554 }
34673555
3468− if (XE_WARN_ON(coh_mode > XE_COH_AT_LEAST_1WAY)) {
3556+ if (XE_WARN_ON(coh_mode > XE_COH_2WAY)) {
34693557 err = -EINVAL;
34703558 goto free_bind_ops;
34713559 }
@@ -3492,6 +3580,10 @@ static int vm_bind_ioctl_check_args(struct xe_device *xe, struct xe_vm *vm, · 20 unmodified lines
34923580 op == DRM_XE_VM_BIND_OP_MAP_USERPTR) ||
34933581 XE_IOCTL_DBG(xe, coh_mode == XE_COH_NONE &&
34943582 op == DRM_XE_VM_BIND_OP_MAP_USERPTR) ||
3583+ XE_IOCTL_DBG(xe, xe_device_is_l2_flush_optimized(xe) &&
3584+ (op == DRM_XE_VM_BIND_OP_MAP_USERPTR ||
3585+ is_cpu_addr_mirror) &&
3586+ (pat_index != 19 && coh_mode != XE_COH_2WAY)) ||
34953587 XE_IOCTL_DBG(xe, comp_en &&
34963588 op == DRM_XE_VM_BIND_OP_MAP_USERPTR) ||
34973589 XE_IOCTL_DBG(xe, op == DRM_XE_VM_BIND_OP_MAP_USERPTR &&
@@ -3633,6 +3725,10 @@ static int xe_vm_bind_ioctl_validate_bo(struct xe_device *xe, struct xe_bo *bo, · 135 unmodified lines
36333725 if (XE_IOCTL_DBG(xe, bo->ttm.base.import_attach && comp_en))
36343726 return -EINVAL;
36353727
3728+ if (XE_IOCTL_DBG(xe, bo->ttm.base.import_attach && xe_device_is_l2_flush_optimized(xe) &&
3729+ (pat_index != 19 && coh_mode != XE_COH_2WAY)))
3730+ return -EINVAL;
3731+
36363732 /* If a BO is protected it can only be mapped if the key is still valid */
36373733 if ((bind_flags & DRM_XE_VM_BIND_FLAG_CHECK_PXP) && xe_bo_is_protected(bo) &&
36383734 op != DRM_XE_VM_BIND_OP_UNMAP && op != DRM_XE_VM_BIND_OP_UNMAP_ALL)
@@ -3878,6 +3974,123 @@ put_vm: · 239 unmodified lines
38783974 return err;
38793975 }
38803976
3977+/*
3978+ * Map access type, fault type, and fault level from current bspec
3979+ * specification to user spec abstraction. The current mapping is
3980+ * approximately 1-to-1, with access type being the only notable
3981+ * exception as it carries additional data with respect to prefetch
3982+ * status that needs to be masked out.
3983+ */
3984+static u8 xe_to_user_access_type(u8 access_type)
3985+{
3986+ return access_type & XE_PAGEFAULT_ACCESS_TYPE_MASK;
3987+}
3988+
3989+static u8 xe_to_user_fault_type(u8 fault_type)
3990+{
3991+ return fault_type;
3992+}
3993+
3994+static u8 xe_to_user_fault_level(u8 fault_level)
3995+{
3996+ return fault_level;
3997+}
3998+
3999+static int fill_faults(struct xe_vm *vm,
4000+ struct drm_xe_vm_get_property *args)
4001+{
4002+ struct xe_vm_fault __user *usr_ptr = u64_to_user_ptr(args->data);
4003+ struct xe_vm_fault *fault_list, fault_entry = { 0 };
4004+ struct xe_vm_fault_entry *entry;
4005+ int ret = 0, i = 0, count, entry_size;
4006+
4007+ entry_size = sizeof(struct xe_vm_fault);
4008+ count = args->size / entry_size;
4009+
4010+ fault_list = kcalloc(count, sizeof(struct xe_vm_fault), GFP_KERNEL);
4011+ if (!fault_list)
4012+ return -ENOMEM;
4013+
4014+ spin_lock(&vm->faults.lock);
4015+ list_for_each_entry(entry, &vm->faults.list, list) {
4016+ if (i == count)
4017+ break;
4018+
4019+ fault_entry.address = xe_device_canonicalize_addr(vm->xe, entry->address);
4020+ fault_entry.address_precision = entry->address_precision;
4021+
4022+ fault_entry.access_type = xe_to_user_access_type(entry->access_type);
4023+ fault_entry.fault_type = xe_to_user_fault_type(entry->fault_type);
4024+ fault_entry.fault_level = xe_to_user_fault_level(entry->fault_level);
4025+
4026+ memcpy(&fault_list[i], &fault_entry, entry_size);
4027+
4028+ i++;
4029+ }
4030+ spin_unlock(&vm->faults.lock);
4031+
4032+ ret = copy_to_user(usr_ptr, fault_list, args->size);
4033+
4034+ kfree(fault_list);
4035+ return ret ? -EFAULT : 0;
4036+}
4037+
4038+static int xe_vm_get_property_helper(struct xe_vm *vm,
4039+ struct drm_xe_vm_get_property *args)
4040+{
4041+ size_t size;
4042+
4043+ switch (args->property) {
4044+ case DRM_XE_VM_GET_PROPERTY_FAULTS:
4045+ spin_lock(&vm->faults.lock);
4046+ size = size_mul(sizeof(struct xe_vm_fault), vm->faults.len);
4047+ spin_unlock(&vm->faults.lock);
4048+
4049+ if (!args->size) {
4050+ args->size = size;
4051+ return 0;
4052+ }
4053+
4054+ /*
4055+ * Number of faults may increase between calls to
4056+ * xe_vm_get_property_ioctl, so just report the number of
4057+ * faults the user requests if it's less than or equal to
4058+ * the number of faults in the VM fault array.
4059+ *
4060+ * We should also at least assert that the args->size value
4061+ * is a multiple of the xe_vm_fault struct size.
4062+ */
4063+ if (args->size > size || args->size % sizeof(struct xe_vm_fault))
4064+ return -EINVAL;
4065+
4066+ return fill_faults(vm, args);
4067+ }
4068+ return -EINVAL;
4069+}
4070+
4071+int xe_vm_get_property_ioctl(struct drm_device *drm, void *data,
4072+ struct drm_file *file)
4073+{
4074+ struct xe_device *xe = to_xe_device(drm);
4075+ struct xe_file *xef = to_xe_file(file);
4076+ struct drm_xe_vm_get_property *args = data;
4077+ struct xe_vm *vm;
4078+ int ret = 0;
4079+
4080+ if (XE_IOCTL_DBG(xe, (args->reserved[0] || args->reserved[1] ||
4081+ args->reserved[2])))
4082+ return -EINVAL;
4083+
4084+ vm = xe_vm_lookup(xef, args->vm_id);
4085+ if (XE_IOCTL_DBG(xe, !vm))
4086+ return -ENOENT;
4087+
4088+ ret = xe_vm_get_property_helper(vm, args);
4089+
4090+ xe_vm_put(vm);
4091+ return ret;
4092+}
4093+
38814094 /**
38824095 * xe_vm_bind_kernel_bo - bind a kernel BO to a VM
38834096 * @vm: VM to bind the BO to
drivers/gpu/drm/xe/xe_vm.h+12−0
@@ -12,6 +12,12 @@ · 11 unmodified lines
1212 #include "xe_map.h"
1313 #include "xe_vm_types.h"
1414
15+/**
16+ * MAX_FAULTS_SAVED_PER_VM - Maximum number of faults each vm can store before future
17+ * faults are discarded to prevent memory overuse
18+ */
19+#define MAX_FAULTS_SAVED_PER_VM 50
20+
1521 struct drm_device;
1622 struct drm_printer;
1723 struct drm_file;
@@ -22,6 +28,7 @@ struct dma_fence; · 4 unmodified lines
2228
2329 struct xe_exec_queue;
2430 struct xe_file;
31+struct xe_pagefault;
2532 struct xe_sync_entry;
2633 struct xe_svm_range;
2734 struct drm_exec;
@@ -203,6 +210,9 @@ int xe_vm_destroy_ioctl(struct drm_device *dev, void *data, · 175 unmodified lines
203210 int xe_vm_bind_ioctl(struct drm_device *dev, void *data,
204211 struct drm_file *file);
205212 int xe_vm_query_vmas_attrs_ioctl(struct drm_device *dev, void *data, struct drm_file *file);
213+int xe_vm_get_property_ioctl(struct drm_device *dev, void *data,
214+ struct drm_file *file);
215+
206216 void xe_vm_close_and_put(struct xe_vm *vm);
207217
208218 static inline bool xe_vm_in_fault_mode(struct xe_vm *vm)
@@ -318,6 +328,8 @@ void xe_vm_snapshot_capture_delayed(struct xe_vm_snapshot *snap); · 109 unmodified lines
318328 void xe_vm_snapshot_print(struct xe_vm_snapshot *snap, struct drm_printer *p);
319329 void xe_vm_snapshot_free(struct xe_vm_snapshot *snap);
320330
331+void xe_vm_add_fault_entry_pf(struct xe_vm *vm, struct xe_pagefault *pf);
332+
321333 /**
322334 * xe_vm_set_validating() - Register this task as currently making bos resident
323335 * @allow_res_evict: Allow eviction of buffer objects bound to @vm when
drivers/gpu/drm/xe/xe_vm_madvise.c+24−1
@@ -309,7 +309,7 @@ static bool madvise_args_are_sane(struct xe_device *xe, const struct drm_xe_madv · 308 unmodified lines
309309 if (XE_IOCTL_DBG(xe, !coh_mode))
310310 return false;
311311
312− if (XE_WARN_ON(coh_mode > XE_COH_AT_LEAST_1WAY))
312+ if (XE_WARN_ON(coh_mode > XE_COH_2WAY))
313313 return false;
314314
315315 if (XE_IOCTL_DBG(xe, args->pat_index.pad))
@@ -419,6 +419,7 @@ int xe_vm_madvise_ioctl(struct drm_device *dev, void *data, struct drm_file *fil · 103 unmodified lines
419419 struct xe_vmas_in_madvise_range madvise_range = {.addr = args->start,
420420 .range = args->range, };
421421 struct xe_madvise_details details;
422+ u16 pat_index, coh_mode;
422423 struct xe_vm *vm;
423424 struct drm_exec exec;
424425 int err, attr_type;
@@ -455,6 +456,17 @@ int xe_vm_madvise_ioctl(struct drm_device *dev, void *data, struct drm_file *fil · 30 unmodified lines
455456 if (err || !madvise_range.num_vmas)
456457 goto madv_fini;
457458
459+ if (args->type == DRM_XE_MEM_RANGE_ATTR_PAT) {
460+ pat_index = array_index_nospec(args->pat_index.val, xe->pat.n_entries);
461+ coh_mode = xe_pat_index_get_coh_mode(xe, pat_index);
462+ if (XE_IOCTL_DBG(xe, madvise_range.has_svm_userptr_vmas &&
463+ xe_device_is_l2_flush_optimized(xe) &&
464+ (pat_index != 19 && coh_mode != XE_COH_2WAY))) {
465+ err = -EINVAL;
466+ goto madv_fini;
467+ }
468+ }
469+
458470 if (madvise_range.has_bo_vmas) {
459471 if (args->type == DRM_XE_MEM_RANGE_ATTR_ATOMIC) {
460472 if (!check_bo_args_are_sane(vm, madvise_range.vmas,
@@ -472,6 +484,17 @@ int xe_vm_madvise_ioctl(struct drm_device *dev, void *data, struct drm_file *fil · 11 unmodified lines
472484
473485 if (!bo)
474486 continue;
487+
488+ if (args->type == DRM_XE_MEM_RANGE_ATTR_PAT) {
489+ if (XE_IOCTL_DBG(xe, bo->ttm.base.import_attach &&
490+ xe_device_is_l2_flush_optimized(xe) &&
491+ (pat_index != 19 &&
492+ coh_mode != XE_COH_2WAY))) {
493+ err = -EINVAL;
494+ goto err_fini;
495+ }
496+ }
497+
475498 err = drm_exec_lock_obj(&exec, &bo->ttm.base);
476499 drm_exec_retry_on_contention(&exec);
477500 if (err)
drivers/gpu/drm/xe/xe_vm_types.h+33−0
@@ -24,6 +24,7 @@ · 23 unmodified lines
2424 struct drm_pagemap;
2525
2626 struct xe_bo;
27+struct xe_pagefault;
2728 struct xe_svm_range;
2829 struct xe_sync_entry;
2930 struct xe_user_fence;
@@ -176,6 +177,24 @@ struct xe_userptr_vma { · 146 unmodified lines
176177
177178 struct xe_device;
178179
180+/**
181+ * struct xe_vm_fault_entry - Elements of vm->faults.list
182+ * @list: link into @xe_vm.faults.list
183+ * @address: address of the fault
184+ * @address_precision: precision of faulted address
185+ * @access_type: type of address access that resulted in fault
186+ * @fault_type: type of fault reported
187+ * @fault_level: fault level of the fault
188+ */
189+struct xe_vm_fault_entry {
190+ struct list_head list;
191+ u64 address;
192+ u32 address_precision;
193+ u8 access_type;
194+ u8 fault_type;
195+ u8 fault_level;
196+};
197+
179198 struct xe_vm {
180199 /** @gpuvm: base GPUVM used to track VMAs */
181200 struct drm_gpuvm gpuvm;
@@ -333,6 +352,16 @@ struct xe_vm { · 151 unmodified lines
333352 bool capture_once;
334353 } error_capture;
335354
355+ /** @faults: List of all faults associated with this VM */
356+ struct {
357+ /** @faults.lock: lock protecting @faults.list */
358+ spinlock_t lock;
359+ /** @faults.list: list of xe_vm_fault_entry entries */
360+ struct list_head list;
361+ /** @faults.len: length of @faults.list */
362+ unsigned int len;
363+ } faults;
364+
336365 /**
337366 * @validation: Validation data only valid with the vm resv held.
338367 * Note: This is really task state of the task holding the vm resv,
@@ -393,6 +422,10 @@ struct xe_vma_op_remap { · 54 unmodified lines
393422 u64 start;
394423 /** @range: range of the VMA unmap */
395424 u64 range;
425+ /** @old_start: Original start of the VMA we unmap */
426+ u64 old_start;
427+ /** @old_range: Original range of the VMA we unmap */
428+ u64 old_range;
396429 /** @skip_prev: skip prev rebind */
397430 bool skip_prev;
398431 /** @skip_next: skip next rebind */
drivers/gpu/drm/xe/xe_wa.c+7−20
@@ -260,21 +260,8 @@ static const struct xe_rtp_entry_sr gt_was[] = { · 259 unmodified lines
260260 LSN_DIM_Z_WGT_MASK,
261261 LSN_LNI_WGT(1) | LSN_LNE_WGT(1) |
262262 LSN_DIM_X_WGT(1) | LSN_DIM_Y_WGT(1) |
263− LSN_DIM_Z_WGT(1)))
264− },
265−
266− /* Xe2_HPM */
267−
268− { XE_RTP_NAME("16021867713"),
269− XE_RTP_RULES(MEDIA_VERSION(1301),
270− ENGINE_CLASS(VIDEO_DECODE)),
271− XE_RTP_ACTIONS(SET(VDBOX_CGCTL3F1C(0), MFXPIPE_CLKGATE_DIS)),
272− XE_RTP_ENTRY_FLAG(FOREACH_ENGINE),
273− },
274− { XE_RTP_NAME("14019449301"),
275− XE_RTP_RULES(MEDIA_VERSION(1301), ENGINE_CLASS(VIDEO_DECODE)),
276− XE_RTP_ACTIONS(SET(VDBOX_CGCTL3F08(0), CG3DDISHRS_CLKGATE_DIS)),
277− XE_RTP_ENTRY_FLAG(FOREACH_ENGINE),
263+ LSN_DIM_Z_WGT(1)),
264+ SET(LSC_CHICKEN_BIT_0_UDW, L3_128B_256B_WRT_DIS))
278265 },
279266
280267 /* Xe3_LPG */
@@ -306,7 +293,7 @@ static const struct xe_rtp_entry_sr gt_was[] = { · 25 unmodified lines
306293 XE_RTP_ACTIONS(SET(MMIOATSREQLIMIT_GAM_WALK_3D,
307294 DIS_ATS_WRONLY_PG))
308295 },
309− { XE_RTP_NAME("14026144927"),
296+ { XE_RTP_NAME("14026144927, 16029437861"),
310297 XE_RTP_RULES(GRAPHICS_VERSION(3510), GRAPHICS_STEP(A0, B0)),
311298 XE_RTP_ACTIONS(SET(L3SQCREG2, L3_SQ_DISABLE_COAMA_2WAY_COH |
312299 L3_SQ_DISABLE_COAMA))
@@ -670,6 +657,10 @@ static const struct xe_rtp_entry_sr lrc_was[] = { · 357 unmodified lines
670657 XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2004), ENGINE_CLASS(RENDER)),
671658 XE_RTP_ACTIONS(SET(CHICKEN_RASTER_1, DIS_CLIP_NEGATIVE_BOUNDING_BOX))
672659 },
660+ { XE_RTP_NAME("14026781792"),
661+ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(3000, 3510), ENGINE_CLASS(RENDER)),
662+ XE_RTP_ACTIONS(SET(FF_MODE, DIS_TE_PATCH_CTRL))
663+ },
673664
674665 /* DG1 */
675666
@@ -798,10 +789,6 @@ static const struct xe_rtp_entry_sr lrc_was[] = { · 122 unmodified lines
798789 ENGINE_CLASS(RENDER)),
799790 XE_RTP_ACTIONS(SET(CHICKEN_RASTER_1, DIS_CLIP_NEGATIVE_BOUNDING_BOX))
800791 },
801− { XE_RTP_NAME("14026781792"),
802− XE_RTP_RULES(GRAPHICS_VERSION(3510), ENGINE_CLASS(RENDER)),
803− XE_RTP_ACTIONS(SET(FF_MODE, DIS_TE_PATCH_CTRL))
804− },
805792 };
806793
807794 static __maybe_unused const struct xe_rtp_entry oob_was[] = {
drivers/vfio/pci/xe/main.c+14−0
@@ -85,6 +85,19 @@ again: · 84 unmodified lines
8585 spin_unlock(&xe_vdev->reset_lock);
8686 }
8787
88+static void xe_vfio_pci_reset_prepare(struct pci_dev *pdev)
89+{
90+ struct xe_vfio_pci_core_device *xe_vdev = pci_get_drvdata(pdev);
91+ int ret;
92+
93+ if (!pdev->is_virtfn)
94+ return;
95+
96+ ret = xe_sriov_vfio_flr_prepare(xe_vdev->xe, xe_vdev->vfid);
97+ if (ret)
98+ dev_err(&pdev->dev, "Failed to prepare FLR: %d\n", ret);
99+}
100+
88101 static void xe_vfio_pci_reset_done(struct pci_dev *pdev)
89102 {
90103 struct xe_vfio_pci_core_device *xe_vdev = pci_get_drvdata(pdev);
@@ -127,6 +140,7 @@ static void xe_vfio_pci_reset_done(struct pci_dev *pdev) · 36 unmodified lines
127140 }
128141
129142 static const struct pci_error_handlers xe_vfio_pci_err_handlers = {
143+ .reset_prepare = xe_vfio_pci_reset_prepare,
130144 .reset_done = xe_vfio_pci_reset_done,
131145 .error_detected = vfio_pci_core_aer_err_detected,
132146 };
include/drm/drm_pagemap.h+21−0
@@ -4,6 +4,7 @@ · 3 unmodified lines
44
55 #include <linux/dma-direction.h>
66 #include <linux/hmm.h>
7+#include <linux/memremap.h>
78 #include <linux/types.h>
89
910 #define NR_PAGES(order) (1U << (order))
@@ -367,6 +368,26 @@ void drm_pagemap_destroy(struct drm_pagemap *dpagemap, bool is_atomic_or_reclaim · 357 unmodified lines
367368
368369 int drm_pagemap_reinit(struct drm_pagemap *dpagemap);
369370
371+/**
372+ * drm_pagemap_page_zone_device_data() - Page to zone_device_data
373+ * @page: Pointer to the page
374+ *
375+ * Return: Page's zone_device_data
376+ */
377+static inline struct drm_pagemap_zdd *drm_pagemap_page_zone_device_data(struct page *page)
378+{
379+ struct folio *folio = page_folio(page);
380+
381+ return folio_zone_device_data(folio);
382+}
383+
384+#else
385+
386+static inline struct drm_pagemap_zdd *drm_pagemap_page_zone_device_data(struct page *page)
387+{
388+ return NULL;
389+}
390+
370391 #endif /* IS_ENABLED(CONFIG_ZONE_DEVICE) */
371392
372393 #endif
include/drm/intel/xe_sriov_vfio.h+11−0
@@ -27,6 +27,17 @@ struct xe_device *xe_sriov_vfio_get_pf(struct pci_dev *pdev); · 26 unmodified lines
2727 */
2828 bool xe_sriov_vfio_migration_supported(struct xe_device *xe);
2929
30+/**
31+ * xe_sriov_vfio_flr_prepare() - Notify PF that VF FLR prepare has started.
32+ * @xe: the PF &xe_device obtained by calling xe_sriov_vfio_get_pf()
33+ * @vfid: the VF identifier (can't be 0)
34+ *
35+ * This function marks VF FLR as pending before PF receives GuC FLR event.
36+ *
37+ * Return: 0 on success or a negative error code on failure.
38+ */
39+int xe_sriov_vfio_flr_prepare(struct xe_device *xe, unsigned int vfid);
40+
3041 /**
3142 * xe_sriov_vfio_wait_flr_done() - Wait for VF FLR completion.
3243 * @xe: the PF &xe_device obtained by calling xe_sriov_vfio_get_pf()
include/uapi/drm/xe_drm.h+90−2
@@ -83,6 +83,7 @@ extern "C" { · 82 unmodified lines
8383 * - &DRM_IOCTL_XE_OBSERVATION
8484 * - &DRM_IOCTL_XE_MADVISE
8585 * - &DRM_IOCTL_XE_VM_QUERY_MEM_RANGE_ATTRS
86+ * - &DRM_IOCTL_XE_VM_GET_PROPERTY
8687 */
8788
8889 /*
@@ -107,6 +108,7 @@ extern "C" { · 18 unmodified lines
107108 #define DRM_XE_MADVISE 0x0c
108109 #define DRM_XE_VM_QUERY_MEM_RANGE_ATTRS 0x0d
109110 #define DRM_XE_EXEC_QUEUE_SET_PROPERTY 0x0e
111+#define DRM_XE_VM_GET_PROPERTY 0x0f
110112
111113 /* Must be kept compact -- no holes */
112114
@@ -125,6 +127,7 @@ extern "C" { · 12 unmodified lines
125127 #define DRM_IOCTL_XE_MADVISE DRM_IOW(DRM_COMMAND_BASE + DRM_XE_MADVISE, struct drm_xe_madvise)
126128 #define DRM_IOCTL_XE_VM_QUERY_MEM_RANGE_ATTRS DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_VM_QUERY_MEM_RANGE_ATTRS, struct drm_xe_vm_query_mem_range_attr)
127129 #define DRM_IOCTL_XE_EXEC_QUEUE_SET_PROPERTY DRM_IOW(DRM_COMMAND_BASE + DRM_XE_EXEC_QUEUE_SET_PROPERTY, struct drm_xe_exec_queue_set_property)
130+#define DRM_IOCTL_XE_VM_GET_PROPERTY DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_VM_GET_PROPERTY, struct drm_xe_vm_get_property)
128131
129132 /**
130133 * DOC: Xe IOCTL Extensions
@@ -1057,7 +1060,7 @@ struct drm_xe_vm_destroy { · 926 unmodified lines
10571060 * not invoke autoreset. Neither will stack variables going out of scope.
10581061 * Therefore it's recommended to always explicitly reset the madvises when
10591062 * freeing the memory backing a region used in a &DRM_IOCTL_XE_MADVISE call.
1060− * - DRM_XE_VM_BIND_FLAG_DECOMPRESS - Request on-device decompression for a MAP.
1063+ * - %DRM_XE_VM_BIND_FLAG_DECOMPRESS - Request on-device decompression for a MAP.
10611064 * When set on a MAP bind operation, request the driver schedule an on-device
10621065 * in-place decompression (via the migrate/resolve path) for the GPU mapping
10631066 * created by this bind. Only valid for DRM_XE_VM_BIND_OP_MAP; usage on
@@ -1114,7 +1117,9 @@ struct drm_xe_vm_bind_op { · 50 unmodified lines
11141117 * incoherent GT access is possible.
11151118 *
11161119 * Note: For userptr and externally imported dma-buf the kernel expects
1117− * either 1WAY or 2WAY for the @pat_index.
1120+ * either 1WAY or 2WAY for the @pat_index. Starting from NVL-P, for
1121+ * userptr, svm, madvise and externally imported dma-buf the kernel expects
1122+ * either 2WAY or 1WAY and XA @pat_index.
11181123 *
11191124 * For DRM_XE_VM_BIND_FLAG_NULL bindings there are no KMD restrictions
11201125 * on the @pat_index. For such mappings there is no actual memory being
@@ -1261,6 +1266,89 @@ struct drm_xe_vm_bind { · 140 unmodified lines
12611266 __u64 reserved[2];
12621267 };
12631268
1269+/** struct xe_vm_fault - Describes faults for %DRM_XE_VM_GET_PROPERTY_FAULTS */
1270+struct xe_vm_fault {
1271+ /** @address: Canonical address of the fault */
1272+ __u64 address;
1273+ /** @address_precision: Precision of faulted address */
1274+ __u32 address_precision;
1275+ /** @access_type: Type of address access that resulted in fault */
1276+#define FAULT_ACCESS_TYPE_READ 0
1277+#define FAULT_ACCESS_TYPE_WRITE 1
1278+#define FAULT_ACCESS_TYPE_ATOMIC 2
1279+ __u8 access_type;
1280+ /** @fault_type: Type of fault reported */
1281+#define FAULT_TYPE_NOT_PRESENT 0
1282+#define FAULT_TYPE_WRITE_ACCESS 1
1283+#define FAULT_TYPE_ATOMIC_ACCESS 2
1284+ __u8 fault_type;
1285+ /** @fault_level: fault level of the fault */
1286+#define FAULT_LEVEL_PTE 0
1287+#define FAULT_LEVEL_PDE 1
1288+#define FAULT_LEVEL_PDP 2
1289+#define FAULT_LEVEL_PML4 3
1290+#define FAULT_LEVEL_PML5 4
1291+ __u8 fault_level;
1292+ /** @pad: MBZ */
1293+ __u8 pad;
1294+ /** @reserved: MBZ */
1295+ __u64 reserved[4];
1296+};
1297+
1298+/**
1299+ * struct drm_xe_vm_get_property - Input of &DRM_IOCTL_XE_VM_GET_PROPERTY
1300+ *
1301+ * The user provides a VM and a property to query among DRM_XE_VM_GET_PROPERTY_*,
1302+ * and sets the values in the vm_id and property members, respectively. This
1303+ * determines both the VM to get the property of, as well as the property to
1304+ * report.
1305+ *
1306+ * If size is set to 0, the driver fills it with the required size for the
1307+ * requested property. The user is expected here to allocate memory for the
1308+ * property structure and to provide a pointer to the allocated memory using the
1309+ * data member. For some properties, this may be zero, in which case, the
1310+ * value of the property will be saved to the value member and size will remain
1311+ * zero on return.
1312+ *
1313+ * If size is not zero, then the IOCTL will attempt to copy the requested
1314+ * property into the data member.
1315+ *
1316+ * The IOCTL will return -ENOENT if the VM could not be identified from the
1317+ * provided VM ID, or -EINVAL if the IOCTL fails for any other reason, such as
1318+ * providing an invalid size for the given property or if the property data
1319+ * could not be copied to the memory allocated to the data member.
1320+ *
1321+ * The property member can be:
1322+ * - %DRM_XE_VM_GET_PROPERTY_FAULTS
1323+ */
1324+struct drm_xe_vm_get_property {
1325+ /** @extensions: Pointer to the first extension struct, if any */
1326+ __u64 extensions;
1327+
1328+ /** @vm_id: The ID of the VM to query the properties of */
1329+ __u32 vm_id;
1330+
1331+#define DRM_XE_VM_GET_PROPERTY_FAULTS 0
1332+ /** @property: property to get */
1333+ __u32 property;
1334+
1335+ /** @size: Size to allocate for @data */
1336+ __u32 size;
1337+
1338+ /** @pad: MBZ */
1339+ __u32 pad;
1340+
1341+ union {
1342+ /** @data: Pointer to user-defined array of flexible size and type */
1343+ __u64 data;
1344+ /** @value: Return value for scalar queries */
1345+ __u64 value;
1346+ };
1347+
1348+ /** @reserved: MBZ */
1349+ __u64 reserved[3];
1350+};
1351+
12641352 /**
12651353 * struct drm_xe_exec_queue_create - Input of &DRM_IOCTL_XE_EXEC_QUEUE_CREATE
12661354 *