Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/gpu/drm/i915/i915_ioc32.c
15113 views
1
/**
2
* \file i915_ioc32.c
3
*
4
* 32-bit ioctl compatibility routines for the i915 DRM.
5
*
6
* \author Alan Hourihane <[email protected]>
7
*
8
*
9
* Copyright (C) Paul Mackerras 2005
10
* Copyright (C) Alan Hourihane 2005
11
* All Rights Reserved.
12
*
13
* Permission is hereby granted, free of charge, to any person obtaining a
14
* copy of this software and associated documentation files (the "Software"),
15
* to deal in the Software without restriction, including without limitation
16
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
17
* and/or sell copies of the Software, and to permit persons to whom the
18
* Software is furnished to do so, subject to the following conditions:
19
*
20
* The above copyright notice and this permission notice (including the next
21
* paragraph) shall be included in all copies or substantial portions of the
22
* Software.
23
*
24
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27
* THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
28
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
30
* IN THE SOFTWARE.
31
*/
32
#include <linux/compat.h>
33
34
#include "drmP.h"
35
#include "drm.h"
36
#include "i915_drm.h"
37
38
typedef struct _drm_i915_batchbuffer32 {
39
int start; /* agp offset */
40
int used; /* nr bytes in use */
41
int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */
42
int DR4; /* window origin for GFX_OP_DRAWRECT_INFO */
43
int num_cliprects; /* mulitpass with multiple cliprects? */
44
u32 cliprects; /* pointer to userspace cliprects */
45
} drm_i915_batchbuffer32_t;
46
47
static int compat_i915_batchbuffer(struct file *file, unsigned int cmd,
48
unsigned long arg)
49
{
50
drm_i915_batchbuffer32_t batchbuffer32;
51
drm_i915_batchbuffer_t __user *batchbuffer;
52
53
if (copy_from_user
54
(&batchbuffer32, (void __user *)arg, sizeof(batchbuffer32)))
55
return -EFAULT;
56
57
batchbuffer = compat_alloc_user_space(sizeof(*batchbuffer));
58
if (!access_ok(VERIFY_WRITE, batchbuffer, sizeof(*batchbuffer))
59
|| __put_user(batchbuffer32.start, &batchbuffer->start)
60
|| __put_user(batchbuffer32.used, &batchbuffer->used)
61
|| __put_user(batchbuffer32.DR1, &batchbuffer->DR1)
62
|| __put_user(batchbuffer32.DR4, &batchbuffer->DR4)
63
|| __put_user(batchbuffer32.num_cliprects,
64
&batchbuffer->num_cliprects)
65
|| __put_user((int __user *)(unsigned long)batchbuffer32.cliprects,
66
&batchbuffer->cliprects))
67
return -EFAULT;
68
69
return drm_ioctl(file, DRM_IOCTL_I915_BATCHBUFFER,
70
(unsigned long)batchbuffer);
71
}
72
73
typedef struct _drm_i915_cmdbuffer32 {
74
u32 buf; /* pointer to userspace command buffer */
75
int sz; /* nr bytes in buf */
76
int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */
77
int DR4; /* window origin for GFX_OP_DRAWRECT_INFO */
78
int num_cliprects; /* mulitpass with multiple cliprects? */
79
u32 cliprects; /* pointer to userspace cliprects */
80
} drm_i915_cmdbuffer32_t;
81
82
static int compat_i915_cmdbuffer(struct file *file, unsigned int cmd,
83
unsigned long arg)
84
{
85
drm_i915_cmdbuffer32_t cmdbuffer32;
86
drm_i915_cmdbuffer_t __user *cmdbuffer;
87
88
if (copy_from_user
89
(&cmdbuffer32, (void __user *)arg, sizeof(cmdbuffer32)))
90
return -EFAULT;
91
92
cmdbuffer = compat_alloc_user_space(sizeof(*cmdbuffer));
93
if (!access_ok(VERIFY_WRITE, cmdbuffer, sizeof(*cmdbuffer))
94
|| __put_user((int __user *)(unsigned long)cmdbuffer32.buf,
95
&cmdbuffer->buf)
96
|| __put_user(cmdbuffer32.sz, &cmdbuffer->sz)
97
|| __put_user(cmdbuffer32.DR1, &cmdbuffer->DR1)
98
|| __put_user(cmdbuffer32.DR4, &cmdbuffer->DR4)
99
|| __put_user(cmdbuffer32.num_cliprects, &cmdbuffer->num_cliprects)
100
|| __put_user((int __user *)(unsigned long)cmdbuffer32.cliprects,
101
&cmdbuffer->cliprects))
102
return -EFAULT;
103
104
return drm_ioctl(file, DRM_IOCTL_I915_CMDBUFFER,
105
(unsigned long)cmdbuffer);
106
}
107
108
typedef struct drm_i915_irq_emit32 {
109
u32 irq_seq;
110
} drm_i915_irq_emit32_t;
111
112
static int compat_i915_irq_emit(struct file *file, unsigned int cmd,
113
unsigned long arg)
114
{
115
drm_i915_irq_emit32_t req32;
116
drm_i915_irq_emit_t __user *request;
117
118
if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
119
return -EFAULT;
120
121
request = compat_alloc_user_space(sizeof(*request));
122
if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
123
|| __put_user((int __user *)(unsigned long)req32.irq_seq,
124
&request->irq_seq))
125
return -EFAULT;
126
127
return drm_ioctl(file, DRM_IOCTL_I915_IRQ_EMIT,
128
(unsigned long)request);
129
}
130
typedef struct drm_i915_getparam32 {
131
int param;
132
u32 value;
133
} drm_i915_getparam32_t;
134
135
static int compat_i915_getparam(struct file *file, unsigned int cmd,
136
unsigned long arg)
137
{
138
drm_i915_getparam32_t req32;
139
drm_i915_getparam_t __user *request;
140
141
if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
142
return -EFAULT;
143
144
request = compat_alloc_user_space(sizeof(*request));
145
if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
146
|| __put_user(req32.param, &request->param)
147
|| __put_user((void __user *)(unsigned long)req32.value,
148
&request->value))
149
return -EFAULT;
150
151
return drm_ioctl(file, DRM_IOCTL_I915_GETPARAM,
152
(unsigned long)request);
153
}
154
155
typedef struct drm_i915_mem_alloc32 {
156
int region;
157
int alignment;
158
int size;
159
u32 region_offset; /* offset from start of fb or agp */
160
} drm_i915_mem_alloc32_t;
161
162
static int compat_i915_alloc(struct file *file, unsigned int cmd,
163
unsigned long arg)
164
{
165
drm_i915_mem_alloc32_t req32;
166
drm_i915_mem_alloc_t __user *request;
167
168
if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
169
return -EFAULT;
170
171
request = compat_alloc_user_space(sizeof(*request));
172
if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
173
|| __put_user(req32.region, &request->region)
174
|| __put_user(req32.alignment, &request->alignment)
175
|| __put_user(req32.size, &request->size)
176
|| __put_user((void __user *)(unsigned long)req32.region_offset,
177
&request->region_offset))
178
return -EFAULT;
179
180
return drm_ioctl(file, DRM_IOCTL_I915_ALLOC,
181
(unsigned long)request);
182
}
183
184
drm_ioctl_compat_t *i915_compat_ioctls[] = {
185
[DRM_I915_BATCHBUFFER] = compat_i915_batchbuffer,
186
[DRM_I915_CMDBUFFER] = compat_i915_cmdbuffer,
187
[DRM_I915_GETPARAM] = compat_i915_getparam,
188
[DRM_I915_IRQ_EMIT] = compat_i915_irq_emit,
189
[DRM_I915_ALLOC] = compat_i915_alloc
190
};
191
192
/**
193
* Called whenever a 32-bit process running under a 64-bit kernel
194
* performs an ioctl on /dev/dri/card<n>.
195
*
196
* \param filp file pointer.
197
* \param cmd command.
198
* \param arg user argument.
199
* \return zero on success or negative number on failure.
200
*/
201
long i915_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
202
{
203
unsigned int nr = DRM_IOCTL_NR(cmd);
204
drm_ioctl_compat_t *fn = NULL;
205
int ret;
206
207
if (nr < DRM_COMMAND_BASE)
208
return drm_compat_ioctl(filp, cmd, arg);
209
210
if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(i915_compat_ioctls))
211
fn = i915_compat_ioctls[nr - DRM_COMMAND_BASE];
212
213
if (fn != NULL)
214
ret = (*fn) (filp, cmd, arg);
215
else
216
ret = drm_ioctl(filp, cmd, arg);
217
218
return ret;
219
}
220
221