1 /*
2  * Copyright © 2019 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #include <errno.h>
25 #include <string.h>
26 
27 #include "ioctl_wrappers.h"
28 #include "drmtest.h"
29 
30 #include "i915/gem_vm.h"
31 
32 /**
33  * SECTION:gem_vm
34  * @short_description: Helpers for dealing with address spaces (vm/GTT)
35  * @title: GEM Virtual Memory
36  *
37  * This helper library contains functions used for handling gem address
38  * spaces.
39  */
40 
41 /**
42  * gem_has_vm:
43  * @i915: open i915 drm file descriptor
44  *
45  * Returns: whether VM creation is supported or not.
46  */
gem_has_vm(int i915)47 bool gem_has_vm(int i915)
48 {
49 	uint32_t vm_id = 0;
50 
51 	__gem_vm_create(i915, &vm_id);
52 	if (vm_id)
53 		gem_vm_destroy(i915, vm_id);
54 
55 	return vm_id;
56 }
57 
58 /**
59  * gem_require_vm:
60  * @i915: open i915 drm file descriptor
61  *
62  * This helper will automatically skip the test on platforms where address
63  * space creation is not available.
64  */
gem_require_vm(int i915)65 void gem_require_vm(int i915)
66 {
67 	igt_require(gem_has_vm(i915));
68 }
69 
__gem_vm_create(int i915,uint32_t * vm_id)70 int __gem_vm_create(int i915, uint32_t *vm_id)
71 {
72        struct drm_i915_gem_vm_control ctl = {};
73        int err = 0;
74 
75        if (igt_ioctl(i915, DRM_IOCTL_I915_GEM_VM_CREATE, &ctl) == 0) {
76                *vm_id = ctl.vm_id;
77        } else {
78 	       err = -errno;
79 	       igt_assume(err != 0);
80        }
81 
82        errno = 0;
83        return err;
84 }
85 
86 /**
87  * gem_vm_create:
88  * @i915: open i915 drm file descriptor
89  *
90  * This wraps the VM_CREATE ioctl, which is used to allocate a new
91  * address space for use with GEM contexts.
92  *
93  * Returns: The id of the allocated address space.
94  */
gem_vm_create(int i915)95 uint32_t gem_vm_create(int i915)
96 {
97 	uint32_t vm_id;
98 
99 	igt_assert_eq(__gem_vm_create(i915, &vm_id), 0);
100 	igt_assert(vm_id != 0);
101 
102 	return vm_id;
103 }
104 
__gem_vm_destroy(int i915,uint32_t vm_id)105 int __gem_vm_destroy(int i915, uint32_t vm_id)
106 {
107 	struct drm_i915_gem_vm_control ctl = { .vm_id = vm_id };
108 	int err = 0;
109 
110 	if (igt_ioctl(i915, DRM_IOCTL_I915_GEM_VM_DESTROY, &ctl)) {
111 		err = -errno;
112 		igt_assume(err);
113 	}
114 
115 	errno = 0;
116 	return err;
117 }
118 
119 /**
120  * gem_vm_destroy:
121  * @i915: open i915 drm file descriptor
122  * @vm_id: i915 VM id
123  *
124  * This wraps the VM_DESTROY ioctl, which is used to free an address space
125  * handle.
126  */
gem_vm_destroy(int i915,uint32_t vm_id)127 void gem_vm_destroy(int i915, uint32_t vm_id)
128 {
129 	igt_assert_eq(__gem_vm_destroy(i915, vm_id), 0);
130 }
131