Hi Deborah, On 2026-09-15 at 17:13:26 -0700, Deborah Brouwer wrote: > Sparse VM_BIND support was introduced with Panthor DRM driver version > 1.9. If a driver isn't advertising support for v1.9, then tests that > call DRM_PANTHOR_VM_BIND_OP_MAP_SPARSE should not be run.
Can you just call that ioctl and if EINVALID skip? Checking version of a driver seems strange. > > So skip the sparse VM_BIND subtests when running against a driver older > than version 1.9. > > Also add indentation to group the sparse tests together. > > Signed-off-by: Deborah Brouwer <[email protected]> > --- > tests/panthor/panthor_vm.c | 660 > +++++++++++++++++++++++---------------------- > 1 file changed, 342 insertions(+), 318 deletions(-) > > diff --git a/tests/panthor/panthor_vm.c b/tests/panthor/panthor_vm.c > index 9011df25e..0140b9e40 100644 > --- a/tests/panthor/panthor_vm.c > +++ b/tests/panthor/panthor_vm.c > @@ -7,6 +7,20 @@ > #include "igt_sizes.h" > #include "panthor_drm.h" > > +static bool panthor_driver_version_at_least(int fd, int major, int minor) > +{ > + drmVersionPtr version = drmGetVersion(fd); > + bool supported; > + > + igt_assert(version); > + supported = version->version_major > major || > + (version->version_major == major && > + version->version_minor >= minor); > + drmFreeVersion(version); > + > + return supported; > +} > + > int igt_main() { > int fd = -1; > > @@ -288,324 +302,334 @@ int igt_main() { > igt_panthor_vm_destroy(fd, vm_id, 0); > } > > - igt_describe("Perform a simple sparse vm_bind operation"); > - igt_subtest("vm_bind_sparse") { > - uint32_t vm_id; > - uint64_t map_size = SZ_4K * 4; > - > - igt_panthor_vm_create(fd, &vm_id, 0); > - igt_assert(vm_id != 0); > - > - igt_panthor_vm_bind_sparse(fd, vm_id, SZ_2M, map_size, 0); > - igt_panthor_vm_destroy(fd, vm_id, 0); > - } > - > - igt_describe("Perform a partial hugepage-unaligned unmap of a sparsely > bound region"); > - igt_subtest("vm_bind_sparse_partial_unmap_start_size_unaligned") { > - uint32_t vm_id; > - uint64_t map_size = SZ_2M * 3; > - const int INITIAL_VA = SZ_4M; > - > - igt_panthor_vm_create(fd, &vm_id, 0); > - igt_assert(vm_id != 0); > - > - igt_panthor_vm_bind_sparse(fd, vm_id, INITIAL_VA, map_size, 0); > - igt_panthor_vm_bind(fd, vm_id, 0, INITIAL_VA, SZ_4K * 2, > - DRM_PANTHOR_VM_BIND_OP_TYPE_UNMAP, 0); > - igt_panthor_vm_destroy(fd, vm_id, 0); > - } > - > - igt_describe("Do a partial hugeapge-aligned unmap from start of > sparsely-bound region"); > - igt_subtest("vm_bind_sparse_partial_unmap_start_size_aligned") { > - uint32_t vm_id; > - uint64_t map_size = SZ_2M * 3; > - const int INITIAL_VA = SZ_4M; > - > - igt_panthor_vm_create(fd, &vm_id, 0); > - igt_assert(vm_id != 0); > - > - igt_panthor_vm_bind_sparse(fd, vm_id, INITIAL_VA, map_size, 0); > - igt_panthor_vm_bind(fd, vm_id, 0, INITIAL_VA, SZ_2M, > - DRM_PANTHOR_VM_BIND_OP_TYPE_UNMAP, 0); > - igt_panthor_vm_destroy(fd, vm_id, 0); > - } > - > - igt_describe("Do a partial hugeapge-unaligned unmap from start of > sparsely-bound region"); > - > igt_subtest("vm_bind_sparse_partial_unmap_start_aligned_no_hugepage_multiple") > { > - uint32_t vm_id; > - uint64_t map_size = SZ_2M * 3; > - const int INITIAL_VA = SZ_4M; > - > - igt_panthor_vm_create(fd, &vm_id, 0); > - igt_assert(vm_id != 0); > - > - igt_panthor_vm_bind_sparse(fd, vm_id, INITIAL_VA, map_size, 0); > - igt_panthor_vm_bind(fd, vm_id, 0, INITIAL_VA, 4 * SZ_64K, > - DRM_PANTHOR_VM_BIND_OP_TYPE_UNMAP, 0); > - igt_panthor_vm_destroy(fd, vm_id, 0); > - } > - > - igt_describe("Do partial hugeapge-aligned unmap that left-intersects > with sparse region"); > - igt_subtest("vm_bind_sparse_partial_unmap_below_start") { > - uint32_t vm_id; > - uint64_t map_size = SZ_2M * 3; > - const int INITIAL_VA = SZ_4M; > - > - igt_panthor_vm_create(fd, &vm_id, 0); > - igt_assert(vm_id != 0); > - > - igt_panthor_vm_bind_sparse(fd, vm_id, INITIAL_VA, map_size, 0); > - igt_panthor_vm_bind(fd, vm_id, 0, INITIAL_VA - SZ_2M, SZ_2M * 3, > - DRM_PANTHOR_VM_BIND_OP_TYPE_UNMAP, 0); > - igt_panthor_vm_destroy(fd, vm_id, 0); > - } > - > - igt_describe("Do partial hugepage-aligned unmap that is proper subset > of sparse region"); > - igt_subtest("vm_bind_sparse_partial_unmap_above_start") { > - uint32_t vm_id; > - uint64_t map_size = SZ_2M * 3; > - const int INITIAL_VA = SZ_4M; > - > - igt_panthor_vm_create(fd, &vm_id, 0); > - igt_assert(vm_id != 0); > - > - igt_panthor_vm_bind_sparse(fd, vm_id, INITIAL_VA, map_size, 0); > - igt_panthor_vm_bind(fd, vm_id, 0, INITIAL_VA + SZ_2M, SZ_2M, > - DRM_PANTHOR_VM_BIND_OP_TYPE_UNMAP, 0); > - igt_panthor_vm_destroy(fd, vm_id, 0); > - } > - > - igt_describe("Do normal hugepage-aligned bind that intersects with > sparsely-mapped region"); > - igt_subtest("vm_bind_sparse_remap") { > - uint32_t vm_id; > - struct panthor_bo bo; > - uint64_t map_size = SZ_2M * 3; > - const int INITIAL_VA = SZ_4M; > - > - igt_panthor_vm_create(fd, &vm_id, 0); > - igt_assert(vm_id != 0); > - > - igt_panthor_vm_bind_sparse(fd, vm_id, INITIAL_VA, map_size, 0); > - > - /* Now attempt normal VM_BIND's that intersect with the > previous chunk */ > - igt_panthor_bo_create(fd, &bo, SZ_8M, 0, 0); > - igt_panthor_vm_bind(fd, vm_id, bo.handle, INITIAL_VA + SZ_2M, > SZ_2M * 2, > - DRM_PANTHOR_VM_BIND_OP_TYPE_MAP, 0); > - > - igt_panthor_vm_destroy(fd, vm_id, 0); > - } > - > - igt_describe("Do normal hugepage-unaligned bind that intersects with > sparsely-mapped region"); > - igt_subtest("vm_bind_sparse_remap_start_unaligned") { > - uint32_t vm_id; > - struct panthor_bo bo; > - uint64_t map_size = SZ_2M * 3; > - const int INITIAL_VA = SZ_4M; > - > - igt_panthor_vm_create(fd, &vm_id, 0); > - igt_assert(vm_id != 0); > - > - igt_panthor_vm_bind_sparse(fd, vm_id, INITIAL_VA, map_size, 0); > - > - /* Now attempt normal VM_BIND's that intersect with the > previous chunk */ > - igt_panthor_bo_create(fd, &bo, SZ_8M, 0, 0); > - igt_panthor_vm_bind(fd, vm_id, bo.handle, INITIAL_VA + map_size > - SZ_1M, > - SZ_4M, DRM_PANTHOR_VM_BIND_OP_TYPE_MAP, 0); > - > - igt_panthor_vm_destroy(fd, vm_id, 0); > - } > - > - igt_describe("Do normal hugepage-unaligned bind that intersects with > sparsely-mapped region"); > - igt_subtest("vm_bind_sparse_remap_start_size_unaligned") { > - uint32_t vm_id; > - struct panthor_bo bo; > - uint64_t map_size = SZ_2M * 3; > - const int INITIAL_VA = SZ_4M; > - > - igt_panthor_vm_create(fd, &vm_id, 0); > - igt_assert(vm_id != 0); > - > - igt_panthor_vm_bind_sparse(fd, vm_id, INITIAL_VA, map_size, 0); > - > - /* Now attempt normal VM_BIND's that intersect with the > previous chunk */ > - igt_panthor_bo_create(fd, &bo, SZ_8M, 0, 0); > - igt_panthor_vm_bind(fd, vm_id, bo.handle, INITIAL_VA + map_size > - SZ_1M, > - SZ_1M, DRM_PANTHOR_VM_BIND_OP_TYPE_MAP, 0); > - > - igt_panthor_vm_destroy(fd, vm_id, 0); > - } > - > - igt_describe("Do normal hugepage-aligned bind that intersects with > sparsely-mapped region"); > - igt_subtest("vm_bind_sparse_remap_start_size_aligned") { > - uint32_t vm_id; > - struct panthor_bo bo; > - uint64_t map_size = SZ_2M * 3; > - const int INITIAL_VA = SZ_4M; > - > - igt_panthor_vm_create(fd, &vm_id, 0); > - igt_assert(vm_id != 0); > - > - igt_panthor_vm_bind_sparse(fd, vm_id, INITIAL_VA, map_size, 0); > - > - /* Now attempt normal VM_BIND's that intersect with the > previous chunk */ > - igt_panthor_bo_create(fd, &bo, SZ_8M, 0, 0); > - igt_panthor_vm_bind(fd, vm_id, bo.handle, > - INITIAL_VA + map_size - SZ_2M, SZ_4M, > - DRM_PANTHOR_VM_BIND_OP_TYPE_MAP, 0); > - > - igt_panthor_vm_destroy(fd, vm_id, 0); > - } > - > - igt_describe("Do normal hugepage-aligned bind that splits original > region in two"); > - igt_subtest("vm_bind_sparse_remap_aligned_split_original_va") { > - uint32_t vm_id; > - struct panthor_bo bo; > - uint64_t map_size = SZ_2M * 3; > - const int INITIAL_VA = SZ_4M; > - > - igt_panthor_vm_create(fd, &vm_id, 0); > - igt_assert(vm_id != 0); > - > - igt_panthor_vm_bind_sparse(fd, vm_id, INITIAL_VA, map_size, 0); > - > - /* Now attempt normal VM_BIND's that intersect with the > previous chunk */ > - igt_panthor_bo_create(fd, &bo, SZ_8M, 0, 0); > - igt_panthor_vm_bind(fd, vm_id, bo.handle, INITIAL_VA + SZ_2M, > - SZ_2M, DRM_PANTHOR_VM_BIND_OP_TYPE_MAP, 0); > - > - igt_panthor_vm_destroy(fd, vm_id, 0); > - } > - > - igt_describe("Do normal 2MiB aligned hugepage-size-unaligned bind over > sparse region"); > - igt_subtest("vm_bind_sparse_remap_start_aligned_size_unaligned") { > - uint32_t vm_id; > - struct panthor_bo bo; > - uint64_t map_size = SZ_2M * 3; > - const int INITIAL_VA = SZ_4M; > - > - igt_panthor_vm_create(fd, &vm_id, 0); > - igt_assert(vm_id != 0); > - > - igt_panthor_vm_bind_sparse(fd, vm_id, INITIAL_VA, map_size, 0); > - > - /* Now attempt normal VM_BIND's that intersect with the > previous chunk */ > - igt_panthor_bo_create(fd, &bo, SZ_8M, 0, 0); > - igt_panthor_vm_bind(fd, vm_id, bo.handle, INITIAL_VA + SZ_2M, > - SZ_1M, DRM_PANTHOR_VM_BIND_OP_TYPE_MAP, 0); > - > - igt_panthor_vm_destroy(fd, vm_id, 0); > - } > - > - igt_describe("Do normal hugepage-aligned bind over left end of sparse > region"); > - igt_subtest("vm_bind_sparse_remap_aligned_intersect_left") { > - uint32_t vm_id; > - struct panthor_bo bo; > - uint64_t map_size = SZ_2M * 3; > - const int INITIAL_VA = SZ_4M; > - > - igt_panthor_vm_create(fd, &vm_id, 0); > - igt_assert(vm_id != 0); > - > - igt_panthor_vm_bind_sparse(fd, vm_id, INITIAL_VA, map_size, 0); > - > - /* Now attempt normal VM_BIND's that intersect with the > previous chunk */ > - igt_panthor_bo_create(fd, &bo, SZ_8M, 0, 0); > - igt_panthor_vm_bind(fd, vm_id, bo.handle, > - INITIAL_VA - SZ_2M, SZ_2M * 2, > - DRM_PANTHOR_VM_BIND_OP_TYPE_MAP, 0); > - > - igt_panthor_vm_destroy(fd, vm_id, 0); > - } > - > - igt_describe("Do normal hugepage-unaligned bind over left end of sparse > region"); > - igt_subtest("vm_bind_sparse_remap_size_unaligned_intersect_left") { > - uint32_t vm_id; > - struct panthor_bo bo; > - uint64_t map_size = SZ_2M * 3; > - const int INITIAL_VA = SZ_4M; > - > - igt_panthor_vm_create(fd, &vm_id, 0); > - igt_assert(vm_id != 0); > - > - igt_panthor_vm_bind_sparse(fd, vm_id, INITIAL_VA, map_size, 0); > - > - /* Now attempt normal VM_BIND's that intersect with the > previous chunk */ > - igt_panthor_bo_create(fd, &bo, SZ_8M, 0, 0); > - igt_panthor_vm_bind(fd, vm_id, bo.handle, > - INITIAL_VA - SZ_2M, SZ_1M * 3, > - DRM_PANTHOR_VM_BIND_OP_TYPE_MAP, 0); > - > - igt_panthor_vm_destroy(fd, vm_id, 0); > - } > - > - igt_describe("Do normal hugepage-unaligned bind over right end of > sparse region"); > - igt_subtest("vm_bind_sparse_remap_start_aligned_intersect_right") { > - uint32_t vm_id; > - struct panthor_bo bo; > - uint64_t map_size = SZ_2M * 3; > - const int INITIAL_VA = SZ_4M; > - > - igt_panthor_vm_create(fd, &vm_id, 0); > - igt_assert(vm_id != 0); > - > - igt_panthor_vm_bind_sparse(fd, vm_id, INITIAL_VA, map_size, 0); > - > - /* Now attempt normal VM_BIND's that intersect with the > previous chunk */ > - igt_panthor_bo_create(fd, &bo, SZ_8M, 0, 0); > - igt_panthor_vm_bind(fd, vm_id, bo.handle, > - INITIAL_VA + map_size - SZ_2M, SZ_2M + > SZ_4K * 6, > - DRM_PANTHOR_VM_BIND_OP_TYPE_MAP, 0); > - > - igt_panthor_vm_destroy(fd, vm_id, 0); > - } > - > - igt_describe("Do normal hugepage-aligned bind that envelopes whole > sparse region"); > - igt_subtest("vm_bind_sparse_remap_wrap_around_va") { > - uint32_t vm_id; > - struct panthor_bo bo; > - uint64_t map_size = SZ_2M * 3; > - const int INITIAL_VA = SZ_4M; > - > - igt_panthor_vm_create(fd, &vm_id, 0); > - igt_assert(vm_id != 0); > - > - igt_panthor_vm_bind_sparse(fd, vm_id, INITIAL_VA, map_size, 0); > - > - /* Now attempt normal VM_BIND's that intersect with the > previous chunk */ > - igt_panthor_bo_create(fd, &bo, SZ_8M, 0, 0); > - igt_panthor_vm_bind(fd, vm_id, bo.handle, INITIAL_VA - SZ_2M, > - SZ_8M, DRM_PANTHOR_VM_BIND_OP_TYPE_MAP, 0); > - > - igt_panthor_vm_destroy(fd, vm_id, 0); > - } > - > - igt_describe("Perform sparse binding operation whose range causes an > overflow"); > - igt_subtest("vm_bind_sparse_overflow") { > - uint32_t vm_id; > - uint64_t map_size = ALIGN_DOWN(UINT64_MAX, SZ_2M) - (SZ_2M * 3); > - const int INITIAL_VA = SZ_512M; > - > - igt_panthor_vm_create(fd, &vm_id, 0); > - igt_assert(vm_id != 0); > - > - igt_panthor_vm_bind_sparse(fd, vm_id, INITIAL_VA, map_size, > EINVAL); > - igt_panthor_vm_destroy(fd, vm_id, 0); > - } > - > - igt_describe("Perform sparse unbind operation whose range causes an > overflow"); > - igt_subtest("vm_unbind_sparse_overflow") { > - uint32_t vm_id; > - uint64_t map_size = SZ_2M * 3; > - uint64_t unmap_size = ALIGN_DOWN(UINT64_MAX, SZ_2M) - map_size; > - const int INITIAL_VA = SZ_512M; > - > - igt_panthor_vm_create(fd, &vm_id, 0); > - igt_assert(vm_id != 0); > - > - igt_panthor_vm_bind_sparse(fd, vm_id, INITIAL_VA, map_size, 0); > - igt_panthor_vm_bind(fd, vm_id, 0, INITIAL_VA, unmap_size, > - DRM_PANTHOR_VM_BIND_OP_TYPE_UNMAP, EINVAL); > - igt_panthor_vm_destroy(fd, vm_id, 0); > + igt_subtest_group() { > + igt_fixture() { > + bool sparse_supported = > panthor_driver_version_at_least(fd, 1, 9); > + > + errno = 0; > + igt_require_f(sparse_supported, > + "Sparse VM_BIND requires Panthor DRM > driver version 1.9 or newer\n"); Skips in group fixture confuse users, it is better to add it to every subtests which needs it, it can also be calling a function which will check condition and then make a skip. Change then will be minimal in a few subtests. With this, when you will run some other tests after/before this, you can see: sudo ./panthor_vm --r some-later-subtest SKIP: igt_require not satisfied... SUCCESS: some-later-subtest Regards, Kamil > + } > + > + igt_describe("Perform a simple sparse vm_bind operation"); > + igt_subtest("vm_bind_sparse") { > + uint32_t vm_id; > + uint64_t map_size = SZ_4K * 4; > + > + igt_panthor_vm_create(fd, &vm_id, 0); > + igt_assert(vm_id != 0); > + > + igt_panthor_vm_bind_sparse(fd, vm_id, SZ_2M, map_size, > 0); > + igt_panthor_vm_destroy(fd, vm_id, 0); > + } > + > + igt_describe("Perform a partial hugepage-unaligned unmap of a > sparsely bound region"); > + > igt_subtest("vm_bind_sparse_partial_unmap_start_size_unaligned") { > + uint32_t vm_id; > + uint64_t map_size = SZ_2M * 3; > + const int INITIAL_VA = SZ_4M; > + > + igt_panthor_vm_create(fd, &vm_id, 0); > + igt_assert(vm_id != 0); > + > + igt_panthor_vm_bind_sparse(fd, vm_id, INITIAL_VA, > map_size, 0); > + igt_panthor_vm_bind(fd, vm_id, 0, INITIAL_VA, SZ_4K * 2, > + DRM_PANTHOR_VM_BIND_OP_TYPE_UNMAP, > 0); > + igt_panthor_vm_destroy(fd, vm_id, 0); > + } > + > + igt_describe("Do a partial hugeapge-aligned unmap from start of > sparsely-bound region"); > + igt_subtest("vm_bind_sparse_partial_unmap_start_size_aligned") { > + uint32_t vm_id; > + uint64_t map_size = SZ_2M * 3; > + const int INITIAL_VA = SZ_4M; > + > + igt_panthor_vm_create(fd, &vm_id, 0); > + igt_assert(vm_id != 0); > + > + igt_panthor_vm_bind_sparse(fd, vm_id, INITIAL_VA, > map_size, 0); > + igt_panthor_vm_bind(fd, vm_id, 0, INITIAL_VA, SZ_2M, > + DRM_PANTHOR_VM_BIND_OP_TYPE_UNMAP, > 0); > + igt_panthor_vm_destroy(fd, vm_id, 0); > + } > + > + igt_describe("Do a partial hugeapge-unaligned unmap from start > of sparsely-bound region"); > + > igt_subtest("vm_bind_sparse_partial_unmap_start_aligned_no_hugepage_multiple") > { > + uint32_t vm_id; > + uint64_t map_size = SZ_2M * 3; > + const int INITIAL_VA = SZ_4M; > + > + igt_panthor_vm_create(fd, &vm_id, 0); > + igt_assert(vm_id != 0); > + > + igt_panthor_vm_bind_sparse(fd, vm_id, INITIAL_VA, > map_size, 0); > + igt_panthor_vm_bind(fd, vm_id, 0, INITIAL_VA, 4 * > SZ_64K, > + DRM_PANTHOR_VM_BIND_OP_TYPE_UNMAP, > 0); > + igt_panthor_vm_destroy(fd, vm_id, 0); > + } > + > + igt_describe("Do partial hugeapge-aligned unmap that > left-intersects with sparse region"); > + igt_subtest("vm_bind_sparse_partial_unmap_below_start") { > + uint32_t vm_id; > + uint64_t map_size = SZ_2M * 3; > + const int INITIAL_VA = SZ_4M; > + > + igt_panthor_vm_create(fd, &vm_id, 0); > + igt_assert(vm_id != 0); > + > + igt_panthor_vm_bind_sparse(fd, vm_id, INITIAL_VA, > map_size, 0); > + igt_panthor_vm_bind(fd, vm_id, 0, INITIAL_VA - SZ_2M, > SZ_2M * 3, > + DRM_PANTHOR_VM_BIND_OP_TYPE_UNMAP, > 0); > + igt_panthor_vm_destroy(fd, vm_id, 0); > + } > + > + igt_describe("Do partial hugepage-aligned unmap that is proper > subset of sparse region"); > + igt_subtest("vm_bind_sparse_partial_unmap_above_start") { > + uint32_t vm_id; > + uint64_t map_size = SZ_2M * 3; > + const int INITIAL_VA = SZ_4M; > + > + igt_panthor_vm_create(fd, &vm_id, 0); > + igt_assert(vm_id != 0); > + > + igt_panthor_vm_bind_sparse(fd, vm_id, INITIAL_VA, > map_size, 0); > + igt_panthor_vm_bind(fd, vm_id, 0, INITIAL_VA + SZ_2M, > SZ_2M, > + DRM_PANTHOR_VM_BIND_OP_TYPE_UNMAP, > 0); > + igt_panthor_vm_destroy(fd, vm_id, 0); > + } > + > + igt_describe("Do normal hugepage-aligned bind that intersects > with sparsely-mapped region"); > + igt_subtest("vm_bind_sparse_remap") { > + uint32_t vm_id; > + struct panthor_bo bo; > + uint64_t map_size = SZ_2M * 3; > + const int INITIAL_VA = SZ_4M; > + > + igt_panthor_vm_create(fd, &vm_id, 0); > + igt_assert(vm_id != 0); > + > + igt_panthor_vm_bind_sparse(fd, vm_id, INITIAL_VA, > map_size, 0); > + > + /* Now attempt normal VM_BIND's that intersect with the > previous chunk */ > + igt_panthor_bo_create(fd, &bo, SZ_8M, 0, 0); > + igt_panthor_vm_bind(fd, vm_id, bo.handle, INITIAL_VA + > SZ_2M, SZ_2M * 2, > + DRM_PANTHOR_VM_BIND_OP_TYPE_MAP, 0); > + > + igt_panthor_vm_destroy(fd, vm_id, 0); > + } > + > + igt_describe("Do normal hugepage-unaligned bind that intersects > with sparsely-mapped region"); > + igt_subtest("vm_bind_sparse_remap_start_unaligned") { > + uint32_t vm_id; > + struct panthor_bo bo; > + uint64_t map_size = SZ_2M * 3; > + const int INITIAL_VA = SZ_4M; > + > + igt_panthor_vm_create(fd, &vm_id, 0); > + igt_assert(vm_id != 0); > + > + igt_panthor_vm_bind_sparse(fd, vm_id, INITIAL_VA, > map_size, 0); > + > + /* Now attempt normal VM_BIND's that intersect with the > previous chunk */ > + igt_panthor_bo_create(fd, &bo, SZ_8M, 0, 0); > + igt_panthor_vm_bind(fd, vm_id, bo.handle, INITIAL_VA + > map_size - SZ_1M, > + SZ_4M, > DRM_PANTHOR_VM_BIND_OP_TYPE_MAP, 0); > + > + igt_panthor_vm_destroy(fd, vm_id, 0); > + } > + > + igt_describe("Do normal hugepage-unaligned bind that intersects > with sparsely-mapped region"); > + igt_subtest("vm_bind_sparse_remap_start_size_unaligned") { > + uint32_t vm_id; > + struct panthor_bo bo; > + uint64_t map_size = SZ_2M * 3; > + const int INITIAL_VA = SZ_4M; > + > + igt_panthor_vm_create(fd, &vm_id, 0); > + igt_assert(vm_id != 0); > + > + igt_panthor_vm_bind_sparse(fd, vm_id, INITIAL_VA, > map_size, 0); > + > + /* Now attempt normal VM_BIND's that intersect with the > previous chunk */ > + igt_panthor_bo_create(fd, &bo, SZ_8M, 0, 0); > + igt_panthor_vm_bind(fd, vm_id, bo.handle, INITIAL_VA + > map_size - SZ_1M, > + SZ_1M, > DRM_PANTHOR_VM_BIND_OP_TYPE_MAP, 0); > + > + igt_panthor_vm_destroy(fd, vm_id, 0); > + } > + > + igt_describe("Do normal hugepage-aligned bind that intersects > with sparsely-mapped region"); > + igt_subtest("vm_bind_sparse_remap_start_size_aligned") { > + uint32_t vm_id; > + struct panthor_bo bo; > + uint64_t map_size = SZ_2M * 3; > + const int INITIAL_VA = SZ_4M; > + > + igt_panthor_vm_create(fd, &vm_id, 0); > + igt_assert(vm_id != 0); > + > + igt_panthor_vm_bind_sparse(fd, vm_id, INITIAL_VA, > map_size, 0); > + > + /* Now attempt normal VM_BIND's that intersect with the > previous chunk */ > + igt_panthor_bo_create(fd, &bo, SZ_8M, 0, 0); > + igt_panthor_vm_bind(fd, vm_id, bo.handle, > + INITIAL_VA + map_size - SZ_2M, > SZ_4M, > + DRM_PANTHOR_VM_BIND_OP_TYPE_MAP, 0); > + > + igt_panthor_vm_destroy(fd, vm_id, 0); > + } > + > + igt_describe("Do normal hugepage-aligned bind that splits > original region in two"); > + igt_subtest("vm_bind_sparse_remap_aligned_split_original_va") { > + uint32_t vm_id; > + struct panthor_bo bo; > + uint64_t map_size = SZ_2M * 3; > + const int INITIAL_VA = SZ_4M; > + > + igt_panthor_vm_create(fd, &vm_id, 0); > + igt_assert(vm_id != 0); > + > + igt_panthor_vm_bind_sparse(fd, vm_id, INITIAL_VA, > map_size, 0); > + > + /* Now attempt normal VM_BIND's that intersect with the > previous chunk */ > + igt_panthor_bo_create(fd, &bo, SZ_8M, 0, 0); > + igt_panthor_vm_bind(fd, vm_id, bo.handle, INITIAL_VA + > SZ_2M, > + SZ_2M, > DRM_PANTHOR_VM_BIND_OP_TYPE_MAP, 0); > + > + igt_panthor_vm_destroy(fd, vm_id, 0); > + } > + > + igt_describe("Do normal 2MiB aligned hugepage-size-unaligned > bind over sparse region"); > + > igt_subtest("vm_bind_sparse_remap_start_aligned_size_unaligned") { > + uint32_t vm_id; > + struct panthor_bo bo; > + uint64_t map_size = SZ_2M * 3; > + const int INITIAL_VA = SZ_4M; > + > + igt_panthor_vm_create(fd, &vm_id, 0); > + igt_assert(vm_id != 0); > + > + igt_panthor_vm_bind_sparse(fd, vm_id, INITIAL_VA, > map_size, 0); > + > + /* Now attempt normal VM_BIND's that intersect with the > previous chunk */ > + igt_panthor_bo_create(fd, &bo, SZ_8M, 0, 0); > + igt_panthor_vm_bind(fd, vm_id, bo.handle, INITIAL_VA + > SZ_2M, > + SZ_1M, > DRM_PANTHOR_VM_BIND_OP_TYPE_MAP, 0); > + > + igt_panthor_vm_destroy(fd, vm_id, 0); > + } > + > + igt_describe("Do normal hugepage-aligned bind over left end of > sparse region"); > + igt_subtest("vm_bind_sparse_remap_aligned_intersect_left") { > + uint32_t vm_id; > + struct panthor_bo bo; > + uint64_t map_size = SZ_2M * 3; > + const int INITIAL_VA = SZ_4M; > + > + igt_panthor_vm_create(fd, &vm_id, 0); > + igt_assert(vm_id != 0); > + > + igt_panthor_vm_bind_sparse(fd, vm_id, INITIAL_VA, > map_size, 0); > + > + /* Now attempt normal VM_BIND's that intersect with the > previous chunk */ > + igt_panthor_bo_create(fd, &bo, SZ_8M, 0, 0); > + igt_panthor_vm_bind(fd, vm_id, bo.handle, > + INITIAL_VA - SZ_2M, SZ_2M * 2, > + DRM_PANTHOR_VM_BIND_OP_TYPE_MAP, 0); > + > + igt_panthor_vm_destroy(fd, vm_id, 0); > + } > + > + igt_describe("Do normal hugepage-unaligned bind over left end > of sparse region"); > + > igt_subtest("vm_bind_sparse_remap_size_unaligned_intersect_left") { > + uint32_t vm_id; > + struct panthor_bo bo; > + uint64_t map_size = SZ_2M * 3; > + const int INITIAL_VA = SZ_4M; > + > + igt_panthor_vm_create(fd, &vm_id, 0); > + igt_assert(vm_id != 0); > + > + igt_panthor_vm_bind_sparse(fd, vm_id, INITIAL_VA, > map_size, 0); > + > + /* Now attempt normal VM_BIND's that intersect with the > previous chunk */ > + igt_panthor_bo_create(fd, &bo, SZ_8M, 0, 0); > + igt_panthor_vm_bind(fd, vm_id, bo.handle, > + INITIAL_VA - SZ_2M, SZ_1M * 3, > + DRM_PANTHOR_VM_BIND_OP_TYPE_MAP, 0); > + > + igt_panthor_vm_destroy(fd, vm_id, 0); > + } > + > + igt_describe("Do normal hugepage-unaligned bind over right end > of sparse region"); > + > igt_subtest("vm_bind_sparse_remap_start_aligned_intersect_right") { > + uint32_t vm_id; > + struct panthor_bo bo; > + uint64_t map_size = SZ_2M * 3; > + const int INITIAL_VA = SZ_4M; > + > + igt_panthor_vm_create(fd, &vm_id, 0); > + igt_assert(vm_id != 0); > + > + igt_panthor_vm_bind_sparse(fd, vm_id, INITIAL_VA, > map_size, 0); > + > + /* Now attempt normal VM_BIND's that intersect with the > previous chunk */ > + igt_panthor_bo_create(fd, &bo, SZ_8M, 0, 0); > + igt_panthor_vm_bind(fd, vm_id, bo.handle, > + INITIAL_VA + map_size - SZ_2M, > SZ_2M + SZ_4K * 6, > + DRM_PANTHOR_VM_BIND_OP_TYPE_MAP, 0); > + > + igt_panthor_vm_destroy(fd, vm_id, 0); > + } > + > + igt_describe("Do normal hugepage-aligned bind that envelopes > whole sparse region"); > + igt_subtest("vm_bind_sparse_remap_wrap_around_va") { > + uint32_t vm_id; > + struct panthor_bo bo; > + uint64_t map_size = SZ_2M * 3; > + const int INITIAL_VA = SZ_4M; > + > + igt_panthor_vm_create(fd, &vm_id, 0); > + igt_assert(vm_id != 0); > + > + igt_panthor_vm_bind_sparse(fd, vm_id, INITIAL_VA, > map_size, 0); > + > + /* Now attempt normal VM_BIND's that intersect with the > previous chunk */ > + igt_panthor_bo_create(fd, &bo, SZ_8M, 0, 0); > + igt_panthor_vm_bind(fd, vm_id, bo.handle, INITIAL_VA - > SZ_2M, > + SZ_8M, > DRM_PANTHOR_VM_BIND_OP_TYPE_MAP, 0); > + > + igt_panthor_vm_destroy(fd, vm_id, 0); > + } > + > + igt_describe("Perform sparse binding operation whose range > causes an overflow"); > + igt_subtest("vm_bind_sparse_overflow") { > + uint32_t vm_id; > + uint64_t map_size = ALIGN_DOWN(UINT64_MAX, SZ_2M) - > (SZ_2M * 3); > + const int INITIAL_VA = SZ_512M; > + > + igt_panthor_vm_create(fd, &vm_id, 0); > + igt_assert(vm_id != 0); > + > + igt_panthor_vm_bind_sparse(fd, vm_id, INITIAL_VA, > map_size, EINVAL); > + igt_panthor_vm_destroy(fd, vm_id, 0); > + } > + > + igt_describe("Perform sparse unbind operation whose range > causes an overflow"); > + igt_subtest("vm_unbind_sparse_overflow") { > + uint32_t vm_id; > + uint64_t map_size = SZ_2M * 3; > + uint64_t unmap_size = ALIGN_DOWN(UINT64_MAX, SZ_2M) - > map_size; > + const int INITIAL_VA = SZ_512M; > + > + igt_panthor_vm_create(fd, &vm_id, 0); > + igt_assert(vm_id != 0); > + > + igt_panthor_vm_bind_sparse(fd, vm_id, INITIAL_VA, > map_size, 0); > + igt_panthor_vm_bind(fd, vm_id, 0, INITIAL_VA, > unmap_size, > + DRM_PANTHOR_VM_BIND_OP_TYPE_UNMAP, > EINVAL); > + igt_panthor_vm_destroy(fd, vm_id, 0); > + } > } > > igt_fixture() { > > --- > base-commit: 970700a95acd74bb987287d10147b5f23380519b > change-id: 20260915-b4-panthor_version_sparse-5fbd31cc0d5d > > Best regards, > -- > Deborah Brouwer <[email protected]> >
