xref: /aosp_15_r20/external/igt-gpu-tools/lib/i915/gem_mman.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker  * Copyright © 2007, 2011, 2013, 2014, 2019 Intel Corporation
3*d83cc019SAndroid Build Coastguard Worker  *
4*d83cc019SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*d83cc019SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*d83cc019SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*d83cc019SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*d83cc019SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*d83cc019SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*d83cc019SAndroid Build Coastguard Worker  *
11*d83cc019SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*d83cc019SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*d83cc019SAndroid Build Coastguard Worker  * Software.
14*d83cc019SAndroid Build Coastguard Worker  *
15*d83cc019SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*d83cc019SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*d83cc019SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*d83cc019SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*d83cc019SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*d83cc019SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*d83cc019SAndroid Build Coastguard Worker  * IN THE SOFTWARE.
22*d83cc019SAndroid Build Coastguard Worker  *
23*d83cc019SAndroid Build Coastguard Worker  */
24*d83cc019SAndroid Build Coastguard Worker 
25*d83cc019SAndroid Build Coastguard Worker #include <stdbool.h>
26*d83cc019SAndroid Build Coastguard Worker #include <sys/ioctl.h>
27*d83cc019SAndroid Build Coastguard Worker #include <errno.h>
28*d83cc019SAndroid Build Coastguard Worker 
29*d83cc019SAndroid Build Coastguard Worker #include "igt_core.h"
30*d83cc019SAndroid Build Coastguard Worker #include "ioctl_wrappers.h"
31*d83cc019SAndroid Build Coastguard Worker 
32*d83cc019SAndroid Build Coastguard Worker #include "gem_mman.h"
33*d83cc019SAndroid Build Coastguard Worker 
34*d83cc019SAndroid Build Coastguard Worker #ifdef HAVE_VALGRIND
35*d83cc019SAndroid Build Coastguard Worker #include <valgrind/valgrind.h>
36*d83cc019SAndroid Build Coastguard Worker #include <valgrind/memcheck.h>
37*d83cc019SAndroid Build Coastguard Worker 
38*d83cc019SAndroid Build Coastguard Worker #define VG(x) x
39*d83cc019SAndroid Build Coastguard Worker #else
40*d83cc019SAndroid Build Coastguard Worker #define VG(x) do {} while (0)
41*d83cc019SAndroid Build Coastguard Worker #endif
42*d83cc019SAndroid Build Coastguard Worker 
43*d83cc019SAndroid Build Coastguard Worker /**
44*d83cc019SAndroid Build Coastguard Worker  * __gem_mmap__gtt:
45*d83cc019SAndroid Build Coastguard Worker  * @fd: open i915 drm file descriptor
46*d83cc019SAndroid Build Coastguard Worker  * @handle: gem buffer object handle
47*d83cc019SAndroid Build Coastguard Worker  * @size: size of the gem buffer
48*d83cc019SAndroid Build Coastguard Worker  * @prot: memory protection bits as used by mmap()
49*d83cc019SAndroid Build Coastguard Worker  *
50*d83cc019SAndroid Build Coastguard Worker  * This functions wraps up procedure to establish a memory mapping through the
51*d83cc019SAndroid Build Coastguard Worker  * GTT.
52*d83cc019SAndroid Build Coastguard Worker  *
53*d83cc019SAndroid Build Coastguard Worker  * Returns: A pointer to the created memory mapping, NULL on failure.
54*d83cc019SAndroid Build Coastguard Worker  */
__gem_mmap__gtt(int fd,uint32_t handle,uint64_t size,unsigned prot)55*d83cc019SAndroid Build Coastguard Worker void *__gem_mmap__gtt(int fd, uint32_t handle, uint64_t size, unsigned prot)
56*d83cc019SAndroid Build Coastguard Worker {
57*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_mmap_gtt mmap_arg;
58*d83cc019SAndroid Build Coastguard Worker 	void *ptr;
59*d83cc019SAndroid Build Coastguard Worker 
60*d83cc019SAndroid Build Coastguard Worker 	memset(&mmap_arg, 0, sizeof(mmap_arg));
61*d83cc019SAndroid Build Coastguard Worker 	mmap_arg.handle = handle;
62*d83cc019SAndroid Build Coastguard Worker 	if (igt_ioctl(fd, DRM_IOCTL_I915_GEM_MMAP_GTT, &mmap_arg))
63*d83cc019SAndroid Build Coastguard Worker 		return NULL;
64*d83cc019SAndroid Build Coastguard Worker 
65*d83cc019SAndroid Build Coastguard Worker 	ptr = mmap64(0, size, prot, MAP_SHARED, fd, mmap_arg.offset);
66*d83cc019SAndroid Build Coastguard Worker 	if (ptr == MAP_FAILED)
67*d83cc019SAndroid Build Coastguard Worker 		ptr = NULL;
68*d83cc019SAndroid Build Coastguard Worker 	else
69*d83cc019SAndroid Build Coastguard Worker 		errno = 0;
70*d83cc019SAndroid Build Coastguard Worker 
71*d83cc019SAndroid Build Coastguard Worker 	VG(VALGRIND_MAKE_MEM_DEFINED(ptr, size));
72*d83cc019SAndroid Build Coastguard Worker 
73*d83cc019SAndroid Build Coastguard Worker 	return ptr;
74*d83cc019SAndroid Build Coastguard Worker }
75*d83cc019SAndroid Build Coastguard Worker 
76*d83cc019SAndroid Build Coastguard Worker /**
77*d83cc019SAndroid Build Coastguard Worker  * gem_mmap__gtt:
78*d83cc019SAndroid Build Coastguard Worker  * @fd: open i915 drm file descriptor
79*d83cc019SAndroid Build Coastguard Worker  * @handle: gem buffer object handle
80*d83cc019SAndroid Build Coastguard Worker  * @size: size of the gem buffer
81*d83cc019SAndroid Build Coastguard Worker  * @prot: memory protection bits as used by mmap()
82*d83cc019SAndroid Build Coastguard Worker  *
83*d83cc019SAndroid Build Coastguard Worker  * Like __gem_mmap__gtt() except we assert on failure.
84*d83cc019SAndroid Build Coastguard Worker  *
85*d83cc019SAndroid Build Coastguard Worker  * Returns: A pointer to the created memory mapping
86*d83cc019SAndroid Build Coastguard Worker  */
gem_mmap__gtt(int fd,uint32_t handle,uint64_t size,unsigned prot)87*d83cc019SAndroid Build Coastguard Worker void *gem_mmap__gtt(int fd, uint32_t handle, uint64_t size, unsigned prot)
88*d83cc019SAndroid Build Coastguard Worker {
89*d83cc019SAndroid Build Coastguard Worker 	void *ptr = __gem_mmap__gtt(fd, handle, size, prot);
90*d83cc019SAndroid Build Coastguard Worker 	igt_assert(ptr);
91*d83cc019SAndroid Build Coastguard Worker 	return ptr;
92*d83cc019SAndroid Build Coastguard Worker }
93*d83cc019SAndroid Build Coastguard Worker 
gem_munmap(void * ptr,uint64_t size)94*d83cc019SAndroid Build Coastguard Worker int gem_munmap(void *ptr, uint64_t size)
95*d83cc019SAndroid Build Coastguard Worker {
96*d83cc019SAndroid Build Coastguard Worker 	int ret = munmap(ptr, size);
97*d83cc019SAndroid Build Coastguard Worker 
98*d83cc019SAndroid Build Coastguard Worker 	if (ret == 0)
99*d83cc019SAndroid Build Coastguard Worker 		VG(VALGRIND_MAKE_MEM_NOACCESS(ptr, size));
100*d83cc019SAndroid Build Coastguard Worker 
101*d83cc019SAndroid Build Coastguard Worker 	return ret;
102*d83cc019SAndroid Build Coastguard Worker }
103*d83cc019SAndroid Build Coastguard Worker 
gem_mmap__has_wc(int fd)104*d83cc019SAndroid Build Coastguard Worker bool gem_mmap__has_wc(int fd)
105*d83cc019SAndroid Build Coastguard Worker {
106*d83cc019SAndroid Build Coastguard Worker 	static int has_wc = -1;
107*d83cc019SAndroid Build Coastguard Worker 
108*d83cc019SAndroid Build Coastguard Worker 	if (has_wc == -1) {
109*d83cc019SAndroid Build Coastguard Worker 		struct drm_i915_getparam gp;
110*d83cc019SAndroid Build Coastguard Worker 		int mmap_version = -1;
111*d83cc019SAndroid Build Coastguard Worker 		int gtt_version = -1;
112*d83cc019SAndroid Build Coastguard Worker 
113*d83cc019SAndroid Build Coastguard Worker 		has_wc = 0;
114*d83cc019SAndroid Build Coastguard Worker 
115*d83cc019SAndroid Build Coastguard Worker 		memset(&gp, 0, sizeof(gp));
116*d83cc019SAndroid Build Coastguard Worker 		gp.param = I915_PARAM_MMAP_GTT_VERSION;
117*d83cc019SAndroid Build Coastguard Worker 		gp.value = &gtt_version;
118*d83cc019SAndroid Build Coastguard Worker 		ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp);
119*d83cc019SAndroid Build Coastguard Worker 
120*d83cc019SAndroid Build Coastguard Worker 		memset(&gp, 0, sizeof(gp));
121*d83cc019SAndroid Build Coastguard Worker 		gp.param = I915_PARAM_MMAP_VERSION;
122*d83cc019SAndroid Build Coastguard Worker 		gp.value = &mmap_version;
123*d83cc019SAndroid Build Coastguard Worker 		ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp);
124*d83cc019SAndroid Build Coastguard Worker 
125*d83cc019SAndroid Build Coastguard Worker 		/* Do we have the new mmap_ioctl with DOMAIN_WC? */
126*d83cc019SAndroid Build Coastguard Worker 		if (mmap_version >= 1 && gtt_version >= 2) {
127*d83cc019SAndroid Build Coastguard Worker 			struct drm_i915_gem_mmap arg;
128*d83cc019SAndroid Build Coastguard Worker 
129*d83cc019SAndroid Build Coastguard Worker 			/* Does this device support wc-mmaps ? */
130*d83cc019SAndroid Build Coastguard Worker 			memset(&arg, 0, sizeof(arg));
131*d83cc019SAndroid Build Coastguard Worker 			arg.handle = gem_create(fd, 4096);
132*d83cc019SAndroid Build Coastguard Worker 			arg.offset = 0;
133*d83cc019SAndroid Build Coastguard Worker 			arg.size = 4096;
134*d83cc019SAndroid Build Coastguard Worker 			arg.flags = I915_MMAP_WC;
135*d83cc019SAndroid Build Coastguard Worker 			has_wc = igt_ioctl(fd, DRM_IOCTL_I915_GEM_MMAP, &arg) == 0;
136*d83cc019SAndroid Build Coastguard Worker 			gem_close(fd, arg.handle);
137*d83cc019SAndroid Build Coastguard Worker 		}
138*d83cc019SAndroid Build Coastguard Worker 		errno = 0;
139*d83cc019SAndroid Build Coastguard Worker 	}
140*d83cc019SAndroid Build Coastguard Worker 
141*d83cc019SAndroid Build Coastguard Worker 	return has_wc > 0;
142*d83cc019SAndroid Build Coastguard Worker }
143*d83cc019SAndroid Build Coastguard Worker 
144*d83cc019SAndroid Build Coastguard Worker /**
145*d83cc019SAndroid Build Coastguard Worker  * __gem_mmap:
146*d83cc019SAndroid Build Coastguard Worker  * @fd: open i915 drm file descriptor
147*d83cc019SAndroid Build Coastguard Worker  * @handle: gem buffer object handle
148*d83cc019SAndroid Build Coastguard Worker  * @offset: offset in the gem buffer of the mmap arena
149*d83cc019SAndroid Build Coastguard Worker  * @size: size of the mmap arena
150*d83cc019SAndroid Build Coastguard Worker  * @prot: memory protection bits as used by mmap()
151*d83cc019SAndroid Build Coastguard Worker  * @flags: flags used to determine caching
152*d83cc019SAndroid Build Coastguard Worker  *
153*d83cc019SAndroid Build Coastguard Worker  * This functions wraps up procedure to establish a memory mapping through
154*d83cc019SAndroid Build Coastguard Worker  * direct cpu access, bypassing the gpu (valid for wc == false). For wc == true
155*d83cc019SAndroid Build Coastguard Worker  * it also bypass cpu caches completely and GTT system agent (i.e. there is no
156*d83cc019SAndroid Build Coastguard Worker  * automatic tiling of the mmapping through the fence registers).
157*d83cc019SAndroid Build Coastguard Worker  *
158*d83cc019SAndroid Build Coastguard Worker  * Returns: A pointer to the created memory mapping, NULL on failure.
159*d83cc019SAndroid Build Coastguard Worker  */
160*d83cc019SAndroid Build Coastguard Worker static void
__gem_mmap(int fd,uint32_t handle,uint64_t offset,uint64_t size,unsigned int prot,uint64_t flags)161*d83cc019SAndroid Build Coastguard Worker *__gem_mmap(int fd, uint32_t handle, uint64_t offset, uint64_t size, unsigned int prot, uint64_t flags)
162*d83cc019SAndroid Build Coastguard Worker {
163*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_mmap arg;
164*d83cc019SAndroid Build Coastguard Worker 
165*d83cc019SAndroid Build Coastguard Worker 	memset(&arg, 0, sizeof(arg));
166*d83cc019SAndroid Build Coastguard Worker 	arg.handle = handle;
167*d83cc019SAndroid Build Coastguard Worker 	arg.offset = offset;
168*d83cc019SAndroid Build Coastguard Worker 	arg.size = size;
169*d83cc019SAndroid Build Coastguard Worker 	arg.flags = flags;
170*d83cc019SAndroid Build Coastguard Worker 
171*d83cc019SAndroid Build Coastguard Worker 	if (igt_ioctl(fd, DRM_IOCTL_I915_GEM_MMAP, &arg))
172*d83cc019SAndroid Build Coastguard Worker 		return NULL;
173*d83cc019SAndroid Build Coastguard Worker 
174*d83cc019SAndroid Build Coastguard Worker 	VG(VALGRIND_MAKE_MEM_DEFINED(from_user_pointer(arg.addr_ptr), arg.size));
175*d83cc019SAndroid Build Coastguard Worker 
176*d83cc019SAndroid Build Coastguard Worker 	errno = 0;
177*d83cc019SAndroid Build Coastguard Worker 	return from_user_pointer(arg.addr_ptr);
178*d83cc019SAndroid Build Coastguard Worker }
179*d83cc019SAndroid Build Coastguard Worker 
180*d83cc019SAndroid Build Coastguard Worker /**
181*d83cc019SAndroid Build Coastguard Worker  * __gem_mmap__wc:
182*d83cc019SAndroid Build Coastguard Worker  * @fd: open i915 drm file descriptor
183*d83cc019SAndroid Build Coastguard Worker  * @handle: gem buffer object handle
184*d83cc019SAndroid Build Coastguard Worker  * @offset: offset in the gem buffer of the mmap arena
185*d83cc019SAndroid Build Coastguard Worker  * @size: size of the mmap arena
186*d83cc019SAndroid Build Coastguard Worker  * @prot: memory protection bits as used by mmap()
187*d83cc019SAndroid Build Coastguard Worker  *
188*d83cc019SAndroid Build Coastguard Worker  * This functions wraps up procedure to establish a memory mapping through
189*d83cc019SAndroid Build Coastguard Worker  * direct cpu access, bypassing the gpu and cpu caches completely and also
190*d83cc019SAndroid Build Coastguard Worker  * bypassing the GTT system agent (i.e. there is no automatic tiling of
191*d83cc019SAndroid Build Coastguard Worker  * the mmapping through the fence registers).
192*d83cc019SAndroid Build Coastguard Worker  *
193*d83cc019SAndroid Build Coastguard Worker  * Returns: A pointer to the created memory mapping, NULL on failure.
194*d83cc019SAndroid Build Coastguard Worker  */
__gem_mmap__wc(int fd,uint32_t handle,uint64_t offset,uint64_t size,unsigned prot)195*d83cc019SAndroid Build Coastguard Worker void *__gem_mmap__wc(int fd, uint32_t handle, uint64_t offset, uint64_t size, unsigned prot)
196*d83cc019SAndroid Build Coastguard Worker {
197*d83cc019SAndroid Build Coastguard Worker 	return __gem_mmap(fd, handle, offset, size, prot, I915_MMAP_WC);
198*d83cc019SAndroid Build Coastguard Worker }
199*d83cc019SAndroid Build Coastguard Worker 
200*d83cc019SAndroid Build Coastguard Worker /**
201*d83cc019SAndroid Build Coastguard Worker  * gem_mmap__wc:
202*d83cc019SAndroid Build Coastguard Worker  * @fd: open i915 drm file descriptor
203*d83cc019SAndroid Build Coastguard Worker  * @handle: gem buffer object handle
204*d83cc019SAndroid Build Coastguard Worker  * @offset: offset in the gem buffer of the mmap arena
205*d83cc019SAndroid Build Coastguard Worker  * @size: size of the mmap arena
206*d83cc019SAndroid Build Coastguard Worker  * @prot: memory protection bits as used by mmap()
207*d83cc019SAndroid Build Coastguard Worker  *
208*d83cc019SAndroid Build Coastguard Worker  * Like __gem_mmap__wc() except we assert on failure.
209*d83cc019SAndroid Build Coastguard Worker  *
210*d83cc019SAndroid Build Coastguard Worker  * Returns: A pointer to the created memory mapping
211*d83cc019SAndroid Build Coastguard Worker  */
gem_mmap__wc(int fd,uint32_t handle,uint64_t offset,uint64_t size,unsigned prot)212*d83cc019SAndroid Build Coastguard Worker void *gem_mmap__wc(int fd, uint32_t handle, uint64_t offset, uint64_t size, unsigned prot)
213*d83cc019SAndroid Build Coastguard Worker {
214*d83cc019SAndroid Build Coastguard Worker 	void *ptr = __gem_mmap__wc(fd, handle, offset, size, prot);
215*d83cc019SAndroid Build Coastguard Worker 	igt_assert(ptr);
216*d83cc019SAndroid Build Coastguard Worker 	return ptr;
217*d83cc019SAndroid Build Coastguard Worker }
218*d83cc019SAndroid Build Coastguard Worker 
219*d83cc019SAndroid Build Coastguard Worker /**
220*d83cc019SAndroid Build Coastguard Worker  * __gem_mmap__cpu:
221*d83cc019SAndroid Build Coastguard Worker  * @fd: open i915 drm file descriptor
222*d83cc019SAndroid Build Coastguard Worker  * @handle: gem buffer object handle
223*d83cc019SAndroid Build Coastguard Worker  * @offset: offset in the gem buffer of the mmap arena
224*d83cc019SAndroid Build Coastguard Worker  * @size: size of the mmap arena
225*d83cc019SAndroid Build Coastguard Worker  * @prot: memory protection bits as used by mmap()
226*d83cc019SAndroid Build Coastguard Worker  *
227*d83cc019SAndroid Build Coastguard Worker  * This functions wraps up procedure to establish a memory mapping through
228*d83cc019SAndroid Build Coastguard Worker  * direct cpu access, bypassing the gpu completely.
229*d83cc019SAndroid Build Coastguard Worker  *
230*d83cc019SAndroid Build Coastguard Worker  * Returns: A pointer to the created memory mapping, NULL on failure.
231*d83cc019SAndroid Build Coastguard Worker  */
__gem_mmap__cpu(int fd,uint32_t handle,uint64_t offset,uint64_t size,unsigned prot)232*d83cc019SAndroid Build Coastguard Worker void *__gem_mmap__cpu(int fd, uint32_t handle, uint64_t offset, uint64_t size, unsigned prot)
233*d83cc019SAndroid Build Coastguard Worker {
234*d83cc019SAndroid Build Coastguard Worker 	return __gem_mmap(fd, handle, offset, size, prot, 0);
235*d83cc019SAndroid Build Coastguard Worker }
236*d83cc019SAndroid Build Coastguard Worker 
237*d83cc019SAndroid Build Coastguard Worker /**
238*d83cc019SAndroid Build Coastguard Worker  * gem_mmap__cpu:
239*d83cc019SAndroid Build Coastguard Worker  * @fd: open i915 drm file descriptor
240*d83cc019SAndroid Build Coastguard Worker  * @handle: gem buffer object handle
241*d83cc019SAndroid Build Coastguard Worker  * @offset: offset in the gem buffer of the mmap arena
242*d83cc019SAndroid Build Coastguard Worker  * @size: size of the mmap arena
243*d83cc019SAndroid Build Coastguard Worker  * @prot: memory protection bits as used by mmap()
244*d83cc019SAndroid Build Coastguard Worker  *
245*d83cc019SAndroid Build Coastguard Worker  * Like __gem_mmap__cpu() except we assert on failure.
246*d83cc019SAndroid Build Coastguard Worker  *
247*d83cc019SAndroid Build Coastguard Worker  * Returns: A pointer to the created memory mapping
248*d83cc019SAndroid Build Coastguard Worker  */
gem_mmap__cpu(int fd,uint32_t handle,uint64_t offset,uint64_t size,unsigned prot)249*d83cc019SAndroid Build Coastguard Worker void *gem_mmap__cpu(int fd, uint32_t handle, uint64_t offset, uint64_t size, unsigned prot)
250*d83cc019SAndroid Build Coastguard Worker {
251*d83cc019SAndroid Build Coastguard Worker 	void *ptr = __gem_mmap__cpu(fd, handle, offset, size, prot);
252*d83cc019SAndroid Build Coastguard Worker 	igt_assert(ptr);
253*d83cc019SAndroid Build Coastguard Worker 	return ptr;
254*d83cc019SAndroid Build Coastguard Worker }
255