diff options
Diffstat (limited to 'tests/gem_reloc_overflow.c')
-rw-r--r-- | tests/gem_reloc_overflow.c | 155 |
1 files changed, 74 insertions, 81 deletions
diff --git a/tests/gem_reloc_overflow.c b/tests/gem_reloc_overflow.c index ff2e2f58..6fcf4b8e 100644 --- a/tests/gem_reloc_overflow.c +++ b/tests/gem_reloc_overflow.c @@ -48,105 +48,98 @@ * Testcase: Kernel relocation overflows are caught. */ +int fd, entries, num; +size_t reloc_size; +uint32_t *handles; +struct drm_i915_gem_exec_object2 *execobjs; +struct drm_i915_gem_execbuffer2 execbuf = { 0 }; +struct drm_i915_gem_relocation_entry *reloc; + int main(int argc, char *argv[]) { - int fd, i, entries, num; - size_t reloc_size; + int i; size_t total_actual = 0; unsigned int total_unsigned = 0; int total_signed = 0; - uint32_t *handles; - struct drm_i915_gem_relocation_entry *reloc; - struct drm_i915_gem_exec_object2 *execobjs; - struct drm_i915_gem_execbuffer2 execbuf = { 0 }; - - fd = drm_open_any(); - - /* Create giant reloc buffer area. */ - num = 257; - entries = ((1ULL << 32) / (num - 1)); - reloc_size = entries * sizeof(struct drm_i915_gem_relocation_entry); - reloc = mmap(NULL, reloc_size, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON, -1, 0); - if (reloc == MAP_FAILED) { - perror("mmap"); - return errno; - } + igt_subtest_init(argc, argv); + + igt_fixture { + fd = drm_open_any(); + + /* Create giant reloc buffer area. */ + num = 257; + entries = ((1ULL << 32) / (num - 1)); + reloc_size = entries * sizeof(struct drm_i915_gem_relocation_entry); + reloc = mmap(NULL, reloc_size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, -1, 0); + igt_assert(reloc != MAP_FAILED); + + /* Allocate the handles we'll need to wrap. */ + handles = calloc(num, sizeof(*handles)); + for (i = 0; i < num; i++) { + struct drm_i915_gem_create create_args = { 0 }; - /* Allocate the handles we'll need to wrap. */ - handles = calloc(num, sizeof(*handles)); - for (i = 0; i < num; i++) { - struct drm_i915_gem_create create_args = { 0 }; - create_args.size = 0x1000; - if (ioctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create_args)) { - perror("DRM_IOCTL_I915_GEM_CREATE"); - return errno; + create_args.size = 0x1000; + igt_assert(ioctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create_args) == 0); + + handles[i] = create_args.handle; } - handles[i] = create_args.handle; - } - /* Create relocation objects. */ - execobjs = calloc(num, sizeof(*execobjs)); - execbuf.buffers_ptr = (uintptr_t)execobjs; + /* Create relocation objects. */ + execobjs = calloc(num, sizeof(*execobjs)); + execbuf.buffers_ptr = (uintptr_t)execobjs; + } - /* Attempt unmapped single entry. */ - execobjs[0].relocation_count = 1; - execobjs[0].relocs_ptr = 0; - execbuf.buffer_count = 1; + igt_subtest("invalid-address") { + /* Attempt unmapped single entry. */ + execobjs[0].relocation_count = 1; + execobjs[0].relocs_ptr = 0; + execbuf.buffer_count = 1; - errno = 0; - ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf); - if (errno != EFAULT) { - perror("DRM_IOCTL_I915_GEM_EXECBUFFER2, invalid address"); - abort(); + errno = 0; + ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf); + igt_assert(errno == EFAULT); } - /* Attempt single overflowed entry. */ - execobjs[0].relocation_count = (1 << 31); - execobjs[0].relocs_ptr = (uintptr_t)reloc; - execbuf.buffer_count = 1; + igt_subtest("single-overflow") { + /* Attempt single overflowed entry. */ + execobjs[0].relocation_count = (1 << 31); + execobjs[0].relocs_ptr = (uintptr_t)reloc; + execbuf.buffer_count = 1; - errno = 0; - ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf); - if (errno != EINVAL) { - perror("DRM_IOCTL_I915_GEM_EXECBUFFER2, single overflow"); - abort(); + errno = 0; + ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf); + igt_assert(errno == EINVAL); } - /* Attempt wrapped overflow entries. */ - for (i = 0; i < num; i++) { - struct drm_i915_gem_exec_object2 *obj = &execobjs[i]; - obj->handle = handles[i]; - - if (i == num - 1) { - /* Wraps to 1 on last count. */ - obj->relocation_count = 1 - total_unsigned; - obj->relocs_ptr = (uintptr_t)reloc; - } else { - obj->relocation_count = entries; - obj->relocs_ptr = (uintptr_t)reloc; + igt_subtest("wrapped-overflow") { + /* Attempt wrapped overflow entries. */ + for (i = 0; i < num; i++) { + struct drm_i915_gem_exec_object2 *obj = &execobjs[i]; + obj->handle = handles[i]; + + if (i == num - 1) { + /* Wraps to 1 on last count. */ + obj->relocation_count = 1 - total_unsigned; + obj->relocs_ptr = (uintptr_t)reloc; + } else { + obj->relocation_count = entries; + obj->relocs_ptr = (uintptr_t)reloc; + } + + total_unsigned += obj->relocation_count; + total_signed += obj->relocation_count; + total_actual += obj->relocation_count; } + execbuf.buffer_count = num; - total_unsigned += obj->relocation_count; - total_signed += obj->relocation_count; - total_actual += obj->relocation_count; - } - execbuf.buffer_count = num; - - errno = 0; - ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf); - if (errno != EINVAL) { - /* ENOENT means we're subject to wrapping overflow since - * processing has continued into validating buffer contents. - */ - perror("DRM_IOCTL_I915_GEM_EXECBUFFER2, wrap overflow"); - abort(); + errno = 0; + ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf); + igt_assert(errno == EINVAL); } - if (close(fd)) { - perror("close"); - return errno; - } + igt_fixture + close(fd); - return 0; + igt_exit(); } |