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.
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"); + } + + 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]>
