Path: blob/master/drivers/gpu/drm/i915/i915_ioc32.c
15113 views
/**1* \file i915_ioc32.c2*3* 32-bit ioctl compatibility routines for the i915 DRM.4*5* \author Alan Hourihane <[email protected]>6*7*8* Copyright (C) Paul Mackerras 20059* Copyright (C) Alan Hourihane 200510* All Rights Reserved.11*12* Permission is hereby granted, free of charge, to any person obtaining a13* copy of this software and associated documentation files (the "Software"),14* to deal in the Software without restriction, including without limitation15* the rights to use, copy, modify, merge, publish, distribute, sublicense,16* and/or sell copies of the Software, and to permit persons to whom the17* Software is furnished to do so, subject to the following conditions:18*19* The above copyright notice and this permission notice (including the next20* paragraph) shall be included in all copies or substantial portions of the21* Software.22*23* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR24* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,25* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL26* THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,27* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,28* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS29* IN THE SOFTWARE.30*/31#include <linux/compat.h>3233#include "drmP.h"34#include "drm.h"35#include "i915_drm.h"3637typedef struct _drm_i915_batchbuffer32 {38int start; /* agp offset */39int used; /* nr bytes in use */40int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */41int DR4; /* window origin for GFX_OP_DRAWRECT_INFO */42int num_cliprects; /* mulitpass with multiple cliprects? */43u32 cliprects; /* pointer to userspace cliprects */44} drm_i915_batchbuffer32_t;4546static int compat_i915_batchbuffer(struct file *file, unsigned int cmd,47unsigned long arg)48{49drm_i915_batchbuffer32_t batchbuffer32;50drm_i915_batchbuffer_t __user *batchbuffer;5152if (copy_from_user53(&batchbuffer32, (void __user *)arg, sizeof(batchbuffer32)))54return -EFAULT;5556batchbuffer = compat_alloc_user_space(sizeof(*batchbuffer));57if (!access_ok(VERIFY_WRITE, batchbuffer, sizeof(*batchbuffer))58|| __put_user(batchbuffer32.start, &batchbuffer->start)59|| __put_user(batchbuffer32.used, &batchbuffer->used)60|| __put_user(batchbuffer32.DR1, &batchbuffer->DR1)61|| __put_user(batchbuffer32.DR4, &batchbuffer->DR4)62|| __put_user(batchbuffer32.num_cliprects,63&batchbuffer->num_cliprects)64|| __put_user((int __user *)(unsigned long)batchbuffer32.cliprects,65&batchbuffer->cliprects))66return -EFAULT;6768return drm_ioctl(file, DRM_IOCTL_I915_BATCHBUFFER,69(unsigned long)batchbuffer);70}7172typedef struct _drm_i915_cmdbuffer32 {73u32 buf; /* pointer to userspace command buffer */74int sz; /* nr bytes in buf */75int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */76int DR4; /* window origin for GFX_OP_DRAWRECT_INFO */77int num_cliprects; /* mulitpass with multiple cliprects? */78u32 cliprects; /* pointer to userspace cliprects */79} drm_i915_cmdbuffer32_t;8081static int compat_i915_cmdbuffer(struct file *file, unsigned int cmd,82unsigned long arg)83{84drm_i915_cmdbuffer32_t cmdbuffer32;85drm_i915_cmdbuffer_t __user *cmdbuffer;8687if (copy_from_user88(&cmdbuffer32, (void __user *)arg, sizeof(cmdbuffer32)))89return -EFAULT;9091cmdbuffer = compat_alloc_user_space(sizeof(*cmdbuffer));92if (!access_ok(VERIFY_WRITE, cmdbuffer, sizeof(*cmdbuffer))93|| __put_user((int __user *)(unsigned long)cmdbuffer32.buf,94&cmdbuffer->buf)95|| __put_user(cmdbuffer32.sz, &cmdbuffer->sz)96|| __put_user(cmdbuffer32.DR1, &cmdbuffer->DR1)97|| __put_user(cmdbuffer32.DR4, &cmdbuffer->DR4)98|| __put_user(cmdbuffer32.num_cliprects, &cmdbuffer->num_cliprects)99|| __put_user((int __user *)(unsigned long)cmdbuffer32.cliprects,100&cmdbuffer->cliprects))101return -EFAULT;102103return drm_ioctl(file, DRM_IOCTL_I915_CMDBUFFER,104(unsigned long)cmdbuffer);105}106107typedef struct drm_i915_irq_emit32 {108u32 irq_seq;109} drm_i915_irq_emit32_t;110111static int compat_i915_irq_emit(struct file *file, unsigned int cmd,112unsigned long arg)113{114drm_i915_irq_emit32_t req32;115drm_i915_irq_emit_t __user *request;116117if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))118return -EFAULT;119120request = compat_alloc_user_space(sizeof(*request));121if (!access_ok(VERIFY_WRITE, request, sizeof(*request))122|| __put_user((int __user *)(unsigned long)req32.irq_seq,123&request->irq_seq))124return -EFAULT;125126return drm_ioctl(file, DRM_IOCTL_I915_IRQ_EMIT,127(unsigned long)request);128}129typedef struct drm_i915_getparam32 {130int param;131u32 value;132} drm_i915_getparam32_t;133134static int compat_i915_getparam(struct file *file, unsigned int cmd,135unsigned long arg)136{137drm_i915_getparam32_t req32;138drm_i915_getparam_t __user *request;139140if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))141return -EFAULT;142143request = compat_alloc_user_space(sizeof(*request));144if (!access_ok(VERIFY_WRITE, request, sizeof(*request))145|| __put_user(req32.param, &request->param)146|| __put_user((void __user *)(unsigned long)req32.value,147&request->value))148return -EFAULT;149150return drm_ioctl(file, DRM_IOCTL_I915_GETPARAM,151(unsigned long)request);152}153154typedef struct drm_i915_mem_alloc32 {155int region;156int alignment;157int size;158u32 region_offset; /* offset from start of fb or agp */159} drm_i915_mem_alloc32_t;160161static int compat_i915_alloc(struct file *file, unsigned int cmd,162unsigned long arg)163{164drm_i915_mem_alloc32_t req32;165drm_i915_mem_alloc_t __user *request;166167if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))168return -EFAULT;169170request = compat_alloc_user_space(sizeof(*request));171if (!access_ok(VERIFY_WRITE, request, sizeof(*request))172|| __put_user(req32.region, &request->region)173|| __put_user(req32.alignment, &request->alignment)174|| __put_user(req32.size, &request->size)175|| __put_user((void __user *)(unsigned long)req32.region_offset,176&request->region_offset))177return -EFAULT;178179return drm_ioctl(file, DRM_IOCTL_I915_ALLOC,180(unsigned long)request);181}182183drm_ioctl_compat_t *i915_compat_ioctls[] = {184[DRM_I915_BATCHBUFFER] = compat_i915_batchbuffer,185[DRM_I915_CMDBUFFER] = compat_i915_cmdbuffer,186[DRM_I915_GETPARAM] = compat_i915_getparam,187[DRM_I915_IRQ_EMIT] = compat_i915_irq_emit,188[DRM_I915_ALLOC] = compat_i915_alloc189};190191/**192* Called whenever a 32-bit process running under a 64-bit kernel193* performs an ioctl on /dev/dri/card<n>.194*195* \param filp file pointer.196* \param cmd command.197* \param arg user argument.198* \return zero on success or negative number on failure.199*/200long i915_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)201{202unsigned int nr = DRM_IOCTL_NR(cmd);203drm_ioctl_compat_t *fn = NULL;204int ret;205206if (nr < DRM_COMMAND_BASE)207return drm_compat_ioctl(filp, cmd, arg);208209if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(i915_compat_ioctls))210fn = i915_compat_ioctls[nr - DRM_COMMAND_BASE];211212if (fn != NULL)213ret = (*fn) (filp, cmd, arg);214else215ret = drm_ioctl(filp, cmd, arg);216217return ret;218}219220221