Download raw body.
[PATCH 0/4] i915 dg2 patches
On Fri, Sep 11, 2026 at 09:54:43PM +0300, kisekinopureya wrote:
> I tested your patches as is on latest codebase, it throws uvm_fault and
> system
> hard locks:
>
> i915_tt_get_st: stub
> i915_tt_get_st: stub
> uvm_fault(0xffffffff82b3a700, 0xffffffffffffffda, 0, 1) -> e
I set up my dg2 again:
inteldrm0 at pci12 dev 0 function 0 "Intel Arc Pro A40/A50" rev 0x05
drm0 at inteldrm0
inteldrm0: msi, DG2, gen 12
...
intel_slicemask_from_xehp_dssmask: stub
intel_slicemask_from_xehp_dssmask: stub
i915_resize_lmem_bar: stub
intel_slicemask_from_xehp_dssmask: stub
drm:pid0:wa_verify *ERROR* [drm] *ERROR* GT0: GT workaround lost on init! (reg[b188]=0x0, relevant bits were 0x0 vs expected 0x8)
gsc_init_one: stub
gsc_init_one: stub
inteldrm0: 1280x1024, 32bpp
The problem was with dma_map_sgtable() and another in i915_ttm_purge().
With the below diff X starts and glxinfo/glxgears work.
Disabling HuC not required.
diff --git sys/dev/pci/drm/drm_linux.c sys/dev/pci/drm/drm_linux.c
index 53a6efd90e2..faca11e360d 100644
--- sys/dev/pci/drm/drm_linux.c
+++ sys/dev/pci/drm/drm_linux.c
@@ -1251,6 +1251,38 @@ sg_free_table(struct sg_table *table)
table->sgl = NULL;
}
+int
+sg_alloc_table_from_pages_segment(struct sg_table *table, struct vm_page **pages,
+ unsigned int npages, unsigned int off, unsigned long size,
+ unsigned int max_segs, gfp_t gfp_mask)
+{
+ struct scatterlist *sg;
+ int r, i;
+ unsigned int len;
+
+ r = sg_alloc_table(table, npages, gfp_mask);
+ if (r != 0)
+ return r;
+
+ sg = table->sgl;
+ table->nents = 0;
+ len = PAGE_SIZE - off;
+ for (i = 0; i < npages; i++) {
+ if (i)
+ sg = sg_next(sg);
+ sg_set_page(sg, pages[i], len, off);
+ off = 0;
+ table->nents++;
+ size -= len;
+ if (size > PAGE_SIZE)
+ len = PAGE_SIZE;
+ else
+ len = size;
+ }
+
+ return 0;
+}
+
int
i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
{
@@ -3487,6 +3519,19 @@ dma_unmap_resource(struct device *dev, dma_addr_t addr, size_t size,
STUB();
}
+int
+dma_map_sgtable(struct device *dev, struct sg_table *sgt,
+ enum dma_data_direction dir, unsigned long attrs)
+{
+ return 0;
+}
+
+void
+dma_unmap_sgtable(struct device *dev, struct sg_table *sgt,
+ enum dma_data_direction dir, unsigned long attrs)
+{
+}
+
#ifdef BUS_DMA_FIXED
#include <linux/iommu.h>
diff --git sys/dev/pci/drm/i915/gem/i915_gem_object.h sys/dev/pci/drm/i915/gem/i915_gem_object.h
index b266814d3fb..0fb18d0aa43 100644
--- sys/dev/pci/drm/i915/gem/i915_gem_object.h
+++ sys/dev/pci/drm/i915/gem/i915_gem_object.h
@@ -855,10 +855,10 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st,
size_t size, struct intel_memory_region *mr,
struct address_space *mapping,
unsigned int max_segment,
- struct drm_i915_gem_object *obj);
+ struct uvm_object *);
void shmem_sg_free_table(struct sg_table *st, struct address_space *mapping,
bool dirty, bool backup,
- struct drm_i915_gem_object *obj);
+ struct uvm_object *, size_t);
#endif
void __shmem_writeback(size_t size, struct address_space *mapping);
diff --git sys/dev/pci/drm/i915/gem/i915_gem_shmem.c sys/dev/pci/drm/i915/gem/i915_gem_shmem.c
index ee8034c9c63..970b47f8fd6 100644
--- sys/dev/pci/drm/i915/gem/i915_gem_shmem.c
+++ sys/dev/pci/drm/i915/gem/i915_gem_shmem.c
@@ -34,7 +34,7 @@ static void check_release_folio_batch(struct folio_batch *fbatch)
void shmem_sg_free_table(struct sg_table *st, struct address_space *mapping,
bool dirty, bool backup,
- struct drm_i915_gem_object *obj)
+ struct uvm_object *uao, size_t uao_size)
{
struct sgt_iter sgt_iter;
struct folio_batch fbatch;
@@ -69,7 +69,7 @@ void shmem_sg_free_table(struct sg_table *st, struct address_space *mapping,
if (fbatch.nr)
check_release_folio_batch(&fbatch);
#else
- uvm_obj_unwire(obj->base.uao, 0, obj->base.size);
+ uvm_obj_unwire(uao, 0, uao_size);
#endif
sg_free_table(st);
@@ -79,7 +79,7 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st,
size_t size, struct intel_memory_region *mr,
struct address_space *mapping,
unsigned int max_segment,
- struct drm_i915_gem_object *obj)
+ struct uvm_object *uao)
{
unsigned int page_count; /* restricted by sg_alloc_table */
unsigned long i;
@@ -201,7 +201,7 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st,
st->nents = 0;
TAILQ_INIT(&plist);
- if (uvm_obj_wire(obj->base.uao, 0, obj->base.size, &plist)) {
+ if (uvm_obj_wire(uao, 0, size, &plist)) {
ret = -ENOMEM;
goto err_sg;
}
@@ -225,7 +225,7 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st,
err_sg:
sg_mark_end(sg);
if (sg != st->sgl) {
- shmem_sg_free_table(st, mapping, false, false, obj);
+ shmem_sg_free_table(st, mapping, false, false, uao, size);
} else {
mapping_clear_unevictable(mapping);
sg_free_table(st);
@@ -275,7 +275,7 @@ rebuild_st:
max_segment);
#else
ret = shmem_sg_alloc_table(i915, st, obj->base.size, mem, NULL,
- max_segment, obj);
+ max_segment, obj->base.uao);
#endif
if (ret)
goto err_st;
@@ -291,7 +291,7 @@ rebuild_st:
#ifdef __linux__
shmem_sg_free_table(st, mapping, false, false);
#else
- shmem_sg_free_table(st, NULL, false, false, obj);
+ shmem_sg_free_table(st, NULL, false, false, obj->base.uao, obj->base.size);
#endif
sg_free_table(st);
kfree(st);
@@ -320,7 +320,7 @@ err_pages:
#ifdef __linux__
shmem_sg_free_table(st, mapping, false, false);
#else
- shmem_sg_free_table(st, NULL, false, false, obj);
+ shmem_sg_free_table(st, NULL, false, false, obj->base.uao, obj->base.size);
#endif
/*
* shmemfs first checks if there is enough memory to allocate the page
@@ -459,7 +459,8 @@ void i915_gem_object_put_pages_shmem(struct drm_i915_gem_object *obj, struct sg_
obj->mm.dirty, obj->mm.madv == I915_MADV_WILLNEED);
#else
shmem_sg_free_table(pages, NULL,
- obj->mm.dirty, obj->mm.madv == I915_MADV_WILLNEED, obj);
+ obj->mm.dirty, obj->mm.madv == I915_MADV_WILLNEED,
+ obj->base.uao, obj->base.size);
#endif
kfree(pages);
obj->mm.dirty = false;
diff --git sys/dev/pci/drm/i915/gem/i915_gem_ttm.c sys/dev/pci/drm/i915/gem/i915_gem_ttm.c
index 570d0971fd4..d6676d6d3c3 100644
--- sys/dev/pci/drm/i915/gem/i915_gem_ttm.c
+++ sys/dev/pci/drm/i915/gem/i915_gem_ttm.c
@@ -53,7 +53,11 @@ struct i915_ttm_tt {
struct i915_refct_sgt cached_rsgt;
bool is_shmem;
+#ifdef __linux__
struct file *filp;
+#else
+ struct uvm_object *filp;
+#endif
};
static const struct ttm_place sys_placement_flags = {
@@ -179,13 +183,11 @@ i915_ttm_placement_from_obj(const struct drm_i915_gem_object *obj,
placement->placement = places;
}
+#ifdef __linux__
static int i915_ttm_tt_shmem_populate(struct ttm_device *bdev,
struct ttm_tt *ttm,
struct ttm_operation_ctx *ctx)
{
- STUB();
- return -ENOSYS;
-#ifdef notyet
struct drm_i915_private *i915 = container_of(bdev, typeof(*i915), bdev);
struct intel_memory_region *mr = i915->mm.regions[INTEL_MEMORY_SYSTEM];
struct i915_ttm_tt *i915_tt = container_of(ttm, typeof(*i915_tt), ttm);
@@ -239,19 +241,71 @@ err_free_st:
shmem_sg_free_table(st, filp->f_mapping, false, false);
return err;
-#endif
}
+#else /* !__linux__ */
+static int i915_ttm_tt_shmem_populate(struct ttm_device *bdev,
+ struct ttm_tt *ttm,
+ struct ttm_operation_ctx *ctx)
+{
+ struct drm_i915_private *i915 = container_of(bdev, typeof(*i915), bdev);
+ struct intel_memory_region *mr = i915->mm.regions[INTEL_MEMORY_SYSTEM];
+ struct i915_ttm_tt *i915_tt = container_of(ttm, typeof(*i915_tt), ttm);
+ const unsigned int max_segment = i915_sg_segment_size(i915->drm.dev);
+ const size_t size = (size_t)ttm->num_pages << PAGE_SHIFT;
+ struct uvm_object *uao = i915_tt->filp;
+ struct sgt_iter sgt_iter;
+ struct sg_table *st;
+ struct vm_page *page;
+ unsigned long i;
+ int err;
+
+ if (!uao) {
+ uao = uao_create(size, 0);
+ if (uao == NULL)
+ return -ENOMEM;
+
+ i915_tt->filp = uao;
+ }
+
+ st = &i915_tt->cached_rsgt.table;
+ err = shmem_sg_alloc_table(i915, st, size, mr, /*filp->f_mapping*/NULL,
+ max_segment, uao);
+ if (err)
+ return err;
+
+ err = dma_map_sgtable(i915_tt->dev, st, DMA_BIDIRECTIONAL,
+ DMA_ATTR_SKIP_CPU_SYNC);
+ if (err)
+ goto err_free_st;
+
+ i = 0;
+ for_each_sgt_page(page, sgt_iter, st)
+ ttm->pages[i++] = page;
+
+ if (ttm->page_flags & TTM_TT_FLAG_SWAPPED)
+ ttm->page_flags &= ~TTM_TT_FLAG_SWAPPED;
+
+ return 0;
+
+err_free_st:
+ shmem_sg_free_table(st, NULL, false, false, uao, size);
+
+ return err;
+}
+#endif /* !__linux__ */
static void i915_ttm_tt_shmem_unpopulate(struct ttm_tt *ttm)
{
- STUB();
-#ifdef notyet
struct i915_ttm_tt *i915_tt = container_of(ttm, typeof(*i915_tt), ttm);
bool backup = ttm->page_flags & TTM_TT_FLAG_SWAPPED;
struct sg_table *st = &i915_tt->cached_rsgt.table;
+#ifdef __linux__
shmem_sg_free_table(st, file_inode(i915_tt->filp)->i_mapping,
backup, backup);
+#else
+ const size_t size = (size_t)ttm->num_pages << PAGE_SHIFT;
+ shmem_sg_free_table(st, NULL, backup, backup, i915_tt->filp, size);
#endif
}
@@ -334,8 +388,6 @@ static int i915_ttm_tt_populate(struct ttm_device *bdev,
static void i915_ttm_tt_unpopulate(struct ttm_device *bdev, struct ttm_tt *ttm)
{
- STUB();
-#ifdef notyet
struct i915_ttm_tt *i915_tt = container_of(ttm, typeof(*i915_tt), ttm);
struct sg_table *st = &i915_tt->cached_rsgt.table;
@@ -348,7 +400,6 @@ static void i915_ttm_tt_unpopulate(struct ttm_device *bdev, struct ttm_tt *ttm)
sg_free_table(st);
ttm_pool_free(&bdev->pool, ttm);
}
-#endif
}
static void i915_ttm_tt_destroy(struct ttm_device *bdev, struct ttm_tt *ttm)
@@ -356,7 +407,11 @@ static void i915_ttm_tt_destroy(struct ttm_device *bdev, struct ttm_tt *ttm)
struct i915_ttm_tt *i915_tt = container_of(ttm, typeof(*i915_tt), ttm);
if (i915_tt->filp)
+#ifdef __linux__
fput(i915_tt->filp);
+#else
+ uao_detach(i915_tt->filp);
+#endif
ttm_tt_fini(ttm);
i915_refct_sgt_put(&i915_tt->cached_rsgt);
@@ -456,13 +511,14 @@ int i915_ttm_purge(struct drm_i915_gem_object *obj)
#ifdef __linux__
shmem_truncate_range(file_inode(i915_tt->filp),
0, (loff_t)-1);
+ fput(fetch_and_zero(&i915_tt->filp));
#else
- rw_enter(obj->base.uao->vmobjlock, RW_WRITE);
- obj->base.uao->pgops->pgo_flush(obj->base.uao, 0,
+ rw_enter(i915_tt->filp->vmobjlock, RW_WRITE);
+ i915_tt->filp->pgops->pgo_flush(i915_tt->filp, 0,
obj->base.size, PGO_ALLPAGES | PGO_FREE);
- rw_exit(obj->base.uao->vmobjlock);
+ rw_exit(i915_tt->filp->vmobjlock);
+ uao_detach(fetch_and_zero(&i915_tt->filp));
#endif
- fput(fetch_and_zero(&i915_tt->filp));
}
}
@@ -544,9 +600,6 @@ static void i915_ttm_delete_mem_notify(struct ttm_buffer_object *bo)
static struct i915_refct_sgt *i915_ttm_tt_get_st(struct ttm_tt *ttm)
{
- STUB();
- return ERR_PTR(-ENOSYS);
-#ifdef notyet
struct i915_ttm_tt *i915_tt = container_of(ttm, typeof(*i915_tt), ttm);
struct sg_table *st;
int ret;
@@ -571,7 +624,6 @@ static struct i915_refct_sgt *i915_ttm_tt_get_st(struct ttm_tt *ttm)
}
return i915_refct_sgt_get(&i915_tt->cached_rsgt);
-#endif
}
/**
diff --git sys/dev/pci/drm/i915/i915_pci.c sys/dev/pci/drm/i915/i915_pci.c
index 37fe0367e7b..3aea0d1c4b2 100644
--- sys/dev/pci/drm/i915/i915_pci.c
+++ sys/dev/pci/drm/i915/i915_pci.c
@@ -738,7 +738,6 @@ static const struct intel_device_info adl_p_info = {
static const struct intel_device_info dg2_info = {
DG2_FEATURES,
- .require_force_probe = 1,
};
static const struct intel_device_info ats_m_info = {
diff --git sys/dev/pci/drm/include/linux/scatterlist.h sys/dev/pci/drm/include/linux/scatterlist.h
index fed5b3a399a..d1e02c69791 100644
--- sys/dev/pci/drm/include/linux/scatterlist.h
+++ sys/dev/pci/drm/include/linux/scatterlist.h
@@ -59,6 +59,9 @@ sg_next(struct scatterlist *sgl)
int sg_alloc_table(struct sg_table *, unsigned int, gfp_t);
void sg_free_table(struct sg_table *);
+int sg_alloc_table_from_pages_segment(struct sg_table *, struct vm_page **,
+ unsigned int, unsigned int, unsigned long, unsigned int, gfp_t);
+
static inline void
sg_mark_end(struct scatterlist *sgl)
{
[PATCH 0/4] i915 dg2 patches