Prepare for 64bit relocation addresses
[platform/upstream/intel-gpu-tools.git] / tests / gem_unfence_active_buffers.c
1 /*
2  * Copyright © 2012 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  * Authors:
24  *    Daniel Vetter <daniel.vetter@ffwll.ch>
25  *
26  */
27
28 /** @file gem_unfence_active_buffers.c
29  *
30  * Testcase: Check for use-after free in the fence stealing code
31  *
32  * If we're stealing the fence of a active object where the active list is the
33  * only thing holding a reference, we need to be careful not to access the old
34  * object we're stealing the fence from after that reference has been dropped by
35  * retire_requests.
36  *
37  * Note that this needs slab poisoning enabled in the kernel to reliably hit the
38  * problem - the race window is too small.
39  */
40
41 #include <stdlib.h>
42 #include <stdio.h>
43 #include <string.h>
44 #include <fcntl.h>
45 #include <inttypes.h>
46 #include <errno.h>
47 #include <sys/stat.h>
48 #include <sys/time.h>
49 #include <stdbool.h>
50 #include "drm.h"
51 #include "ioctl_wrappers.h"
52 #include "drmtest.h"
53 #include "intel_bufmgr.h"
54 #include "intel_batchbuffer.h"
55 #include "intel_io.h"
56 #include "intel_chipset.h"
57
58 static drm_intel_bufmgr *bufmgr;
59 struct intel_batchbuffer *batch;
60 uint32_t devid;
61
62 #define TEST_SIZE (1024*1024)
63 #define TEST_STRIDE (4*1024)
64
65 uint32_t data[TEST_SIZE/4];
66
67 igt_simple_main
68 {
69         int i, ret, fd, num_fences;
70         drm_intel_bo *busy_bo, *test_bo;
71         uint32_t tiling = I915_TILING_X;
72
73         igt_skip_on_simulation();
74
75         for (i = 0; i < 1024*256; i++)
76                 data[i] = i;
77
78         fd = drm_open_any();
79
80         bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
81         drm_intel_bufmgr_gem_enable_reuse(bufmgr);
82         devid = intel_get_drm_devid(fd);
83         batch = intel_batchbuffer_alloc(bufmgr, devid);
84
85         igt_info("filling ring\n");
86         busy_bo = drm_intel_bo_alloc(bufmgr, "busy bo bo", 16*1024*1024, 4096);
87
88         for (i = 0; i < 250; i++) {
89                 BLIT_COPY_BATCH_START(devid, 0);
90                 OUT_BATCH((3 << 24) | /* 32 bits */
91                           (0xcc << 16) | /* copy ROP */
92                           2*1024*4);
93                 OUT_BATCH(0 << 16 | 1024);
94                 OUT_BATCH((2048) << 16 | (2048));
95                 OUT_RELOC_FENCED(busy_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);
96                 OUT_BATCH(0 << 16 | 0);
97                 OUT_BATCH(2*1024*4);
98                 OUT_RELOC_FENCED(busy_bo, I915_GEM_DOMAIN_RENDER, 0, 0);
99                 ADVANCE_BATCH();
100
101                 if (IS_GEN6(devid) || IS_GEN7(devid)) {
102                         BEGIN_BATCH(3);
103                         OUT_BATCH(XY_SETUP_CLIP_BLT_CMD);
104                         OUT_BATCH(0);
105                         OUT_BATCH(0);
106                         ADVANCE_BATCH();
107                 }
108         }
109         intel_batchbuffer_flush(batch);
110
111         num_fences = gem_available_fences(fd);
112         igt_info("creating havoc on %i fences\n", num_fences);
113
114         for (i = 0; i < num_fences*2; i++) {
115                 test_bo = drm_intel_bo_alloc(bufmgr, "test_bo",
116                                              TEST_SIZE, 4096);
117                 ret = drm_intel_bo_set_tiling(test_bo, &tiling, TEST_STRIDE);
118                 igt_assert(ret == 0);
119
120                 drm_intel_bo_disable_reuse(test_bo);
121
122                 BLIT_COPY_BATCH_START(devid, 0);
123                 OUT_BATCH((3 << 24) | /* 32 bits */
124                           (0xcc << 16) | /* copy ROP */
125                           TEST_STRIDE);
126                 OUT_BATCH(0 << 16 | 0);
127                 OUT_BATCH((1) << 16 | (1));
128                 OUT_RELOC_FENCED(test_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);
129                 OUT_BATCH(0 << 16 | 0);
130                 OUT_BATCH(TEST_STRIDE);
131                 OUT_RELOC_FENCED(test_bo, I915_GEM_DOMAIN_RENDER, 0, 0);
132                 ADVANCE_BATCH();
133                 intel_batchbuffer_flush(batch);
134                 igt_info("test bo offset: %#lx\n", test_bo->offset);
135
136                 drm_intel_bo_unreference(test_bo);
137         }
138
139         /* launch a few batchs to ensure the damaged slab objects get reused. */
140         for (i = 0; i < 10; i++) {
141                 BLIT_COPY_BATCH_START(devid, 0);
142                 OUT_BATCH((3 << 24) | /* 32 bits */
143                           (0xcc << 16) | /* copy ROP */
144                           2*1024*4);
145                 OUT_BATCH(0 << 16 | 1024);
146                 OUT_BATCH((1) << 16 | (1));
147                 OUT_RELOC_FENCED(busy_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);
148                 OUT_BATCH(0 << 16 | 0);
149                 OUT_BATCH(2*1024*4);
150                 OUT_RELOC_FENCED(busy_bo, I915_GEM_DOMAIN_RENDER, 0, 0);
151                 ADVANCE_BATCH();
152
153                 if (IS_GEN6(devid) || IS_GEN7(devid)) {
154                         BEGIN_BATCH(3);
155                         OUT_BATCH(XY_SETUP_CLIP_BLT_CMD);
156                         OUT_BATCH(0);
157                         OUT_BATCH(0);
158                         ADVANCE_BATCH();
159                 }
160         }
161         intel_batchbuffer_flush(batch);
162 }