i915_ioc32.c revision 1.2
1/* $NetBSD: i915_ioc32.c,v 1.2 2018/08/27 04:58:23 riastradh Exp $ */ 2 3/** 4 * \file i915_ioc32.c 5 * 6 * 32-bit ioctl compatibility routines for the i915 DRM. 7 * 8 * \author Alan Hourihane <alanh@fairlite.demon.co.uk> 9 * 10 * 11 * Copyright (C) Paul Mackerras 2005 12 * Copyright (C) Alan Hourihane 2005 13 * All Rights Reserved. 14 * 15 * Permission is hereby granted, free of charge, to any person obtaining a 16 * copy of this software and associated documentation files (the "Software"), 17 * to deal in the Software without restriction, including without limitation 18 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 19 * and/or sell copies of the Software, and to permit persons to whom the 20 * Software is furnished to do so, subject to the following conditions: 21 * 22 * The above copyright notice and this permission notice (including the next 23 * paragraph) shall be included in all copies or substantial portions of the 24 * Software. 25 * 26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 29 * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 30 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 31 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 32 * IN THE SOFTWARE. 33 */ 34#include <sys/cdefs.h> 35__KERNEL_RCSID(0, "$NetBSD: i915_ioc32.c,v 1.2 2018/08/27 04:58:23 riastradh Exp $"); 36 37#include <linux/compat.h> 38 39#include <drm/drmP.h> 40#include <drm/i915_drm.h> 41#include "i915_drv.h" 42 43struct drm_i915_getparam32 { 44 s32 param; 45 /* 46 * We screwed up the generic ioctl struct here and used a variable-sized 47 * pointer. Use u32 in the compat struct to match the 32bit pointer 48 * userspace expects. 49 */ 50 u32 value; 51}; 52 53static int compat_i915_getparam(struct file *file, unsigned int cmd, 54 unsigned long arg) 55{ 56 struct drm_i915_getparam32 req32; 57 drm_i915_getparam_t __user *request; 58 59 if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) 60 return -EFAULT; 61 62 request = compat_alloc_user_space(sizeof(*request)); 63 if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) 64 || __put_user(req32.param, &request->param) 65 || __put_user((void __user *)(unsigned long)req32.value, 66 &request->value)) 67 return -EFAULT; 68 69 return drm_ioctl(file, DRM_IOCTL_I915_GETPARAM, 70 (unsigned long)request); 71} 72 73static drm_ioctl_compat_t *i915_compat_ioctls[] = { 74 [DRM_I915_GETPARAM] = compat_i915_getparam, 75}; 76 77/** 78 * Called whenever a 32-bit process running under a 64-bit kernel 79 * performs an ioctl on /dev/dri/card<n>. 80 * 81 * \param filp file pointer. 82 * \param cmd command. 83 * \param arg user argument. 84 * \return zero on success or negative number on failure. 85 */ 86long i915_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 87{ 88 unsigned int nr = DRM_IOCTL_NR(cmd); 89 drm_ioctl_compat_t *fn = NULL; 90 int ret; 91 92 if (nr < DRM_COMMAND_BASE || nr >= DRM_COMMAND_END) 93 return drm_compat_ioctl(filp, cmd, arg); 94 95 if (nr < DRM_COMMAND_BASE + ARRAY_SIZE(i915_compat_ioctls)) 96 fn = i915_compat_ioctls[nr - DRM_COMMAND_BASE]; 97 98 if (fn != NULL) 99 ret = (*fn) (filp, cmd, arg); 100 else 101 ret = drm_ioctl(filp, cmd, arg); 102 103 return ret; 104} 105