/*
 * \file drm_ioc32.c
 *
 * 32-bit ioctl compatibility routines for the DRM.
 *
 * \author Paul Mackerras <paulus@samba.org>
 *
 * Copyright (C) Paul Mackerras 2005.
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */
#include <linux/compat.h>
#include <linux/ratelimit.h>
#include <linux/export.h>

#include <drm/drmP.h>
#include "drm_legacy.h"
#include "drm_internal.h"
#include "drm_crtc_internal.h"

#define DRM_IOCTL_VERSION32		DRM_IOWR(0x00, drm_version32_t)
#define DRM_IOCTL_GET_UNIQUE32		DRM_IOWR(0x01, drm_unique32_t)
#define DRM_IOCTL_GET_MAP32		DRM_IOWR(0x04, drm_map32_t)
#define DRM_IOCTL_GET_CLIENT32		DRM_IOWR(0x05, drm_client32_t)
#define DRM_IOCTL_GET_STATS32		DRM_IOR( 0x06, drm_stats32_t)

#define DRM_IOCTL_SET_UNIQUE32		DRM_IOW( 0x10, drm_unique32_t)
#define DRM_IOCTL_ADD_MAP32		DRM_IOWR(0x15, drm_map32_t)
#define DRM_IOCTL_ADD_BUFS32		DRM_IOWR(0x16, drm_buf_desc32_t)
#define DRM_IOCTL_MARK_BUFS32		DRM_IOW( 0x17, drm_buf_desc32_t)
#define DRM_IOCTL_INFO_BUFS32		DRM_IOWR(0x18, drm_buf_info32_t)
#define DRM_IOCTL_MAP_BUFS32		DRM_IOWR(0x19, drm_buf_map32_t)
#define DRM_IOCTL_FREE_BUFS32		DRM_IOW( 0x1a, drm_buf_free32_t)

#define DRM_IOCTL_RM_MAP32		DRM_IOW( 0x1b, drm_map32_t)

#define DRM_IOCTL_SET_SAREA_CTX32	DRM_IOW( 0x1c, drm_ctx_priv_map32_t)
#define DRM_IOCTL_GET_SAREA_CTX32	DRM_IOWR(0x1d, drm_ctx_priv_map32_t)

#define DRM_IOCTL_RES_CTX32		DRM_IOWR(0x26, drm_ctx_res32_t)
#define DRM_IOCTL_DMA32			DRM_IOWR(0x29, drm_dma32_t)

#define DRM_IOCTL_AGP_ENABLE32		DRM_IOW( 0x32, drm_agp_mode32_t)
#define DRM_IOCTL_AGP_INFO32		DRM_IOR( 0x33, drm_agp_info32_t)
#define DRM_IOCTL_AGP_ALLOC32		DRM_IOWR(0x34, drm_agp_buffer32_t)
#define DRM_IOCTL_AGP_FREE32		DRM_IOW( 0x35, drm_agp_buffer32_t)
#define DRM_IOCTL_AGP_BIND32		DRM_IOW( 0x36, drm_agp_binding32_t)
#define DRM_IOCTL_AGP_UNBIND32		DRM_IOW( 0x37, drm_agp_binding32_t)

#define DRM_IOCTL_SG_ALLOC32		DRM_IOW( 0x38, drm_scatter_gather32_t)
#define DRM_IOCTL_SG_FREE32		DRM_IOW( 0x39, drm_scatter_gather32_t)

#define DRM_IOCTL_UPDATE_DRAW32		DRM_IOW( 0x3f, drm_update_draw32_t)

#define DRM_IOCTL_WAIT_VBLANK32		DRM_IOWR(0x3a, drm_wait_vblank32_t)

#define DRM_IOCTL_MODE_ADDFB232		DRM_IOWR(0xb8, drm_mode_fb_cmd232_t)

typedef struct drm_version_32 {
	int version_major;	  /* Major version */
	int version_minor;	  /* Minor version */
	int version_patchlevel;	   /* Patch level */
	u32 name_len;		  /* Length of name buffer */
	u32 name;		  /* Name of driver */
	u32 date_len;		  /* Length of date buffer */
	u32 date;		  /* User-space buffer to hold date */
	u32 desc_len;		  /* Length of desc buffer */
	u32 desc;		  /* User-space buffer to hold desc */
} drm_version32_t;

static int compat_drm_version(struct file *file, unsigned int cmd,
			      unsigned long arg)
{
	drm_version32_t v32;
	struct drm_version v;
	int err;

	if (copy_from_user(&v32, (void __user *)arg, sizeof(v32)))
		return -EFAULT;

	memset(&v, 0, sizeof(v));

	v = (struct drm_version) {
		.name_len = v32.name_len,
		.name = compat_ptr(v32.name),
		.date_len = v32.date_len,
		.date = compat_ptr(v32.date),
		.desc_len = v32.desc_len,
		.desc = compat_ptr(v32.desc),
	};
	err = drm_ioctl_kernel(file, drm_version, &v,
			       DRM_UNLOCKED|DRM_RENDER_ALLOW);
	if (err)
		return err;

	v32.version_major = v.version_major;
	v32.version_minor = v.version_minor;
	v32.version_patchlevel = v.version_patchlevel;
	v32.name_len = v.name_len;
	v32.date_len = v.date_len;
	v32.desc_len = v.desc_len;
	if (copy_to_user((void __user *)arg, &v32, sizeof(v32)))
		return -EFAULT;
	return 0;
}

typedef struct drm_unique32 {
	u32 unique_len;	/* Length of unique */
	u32 unique;	/* Unique name for driver instantiation */
} drm_unique32_t;

static int compat_drm_getunique(struct file *file, unsigned int cmd,
				unsigned long arg)
{
	drm_unique32_t uq32;
	struct drm_unique uq;
	int err;

	if (copy_from_user(&uq32, (void __user *)arg, sizeof(uq32)))
		return -EFAULT;

	memset(&uq, 0, sizeof(uq));

	uq = (struct drm_unique){
		.unique_len = uq32.unique_len,
		.unique = compat_ptr(uq32.unique),
	};

	err = drm_ioctl_kernel(file, drm_getunique, &uq, DRM_UNLOCKED);
	if (err)
		return err;

	uq32.unique_len = uq.unique_len;
	if (copy_to_user((void __user *)arg, &uq32, sizeof(uq32)))
		return -EFAULT;
	return 0;
}

static int compat_drm_setunique(struct file *file, unsigned int cmd,
				unsigned long arg)
{
	/* it's dead */
	return -EINVAL;
}

typedef struct drm_map32 {
	u32 offset;		/* Requested physical address (0 for SAREA) */
	u32 size;		/* Requested physical size (bytes) */
	enum drm_map_type type;	/* Type of memory to map */
	enum drm_map_flags flags;	/* Flags */
	u32 handle;		/* User-space: "Handle" to pass to mmap() */
	int mtrr;		/* MTRR slot used */
} drm_map32_t;

static int compat_drm_getmap(struct file *file, unsigned int cmd,
			     unsigned long arg)
{
	drm_map32_t __user *argp = (void __user *)arg;
	drm_map32_t m32;
	struct drm_map map;
	int err;

	if (copy_from_user(&m32, argp, sizeof(m32)))
		return -EFAULT;

	map.offset = m32.offset;
	err = drm_ioctl_kernel(file, drm_legacy_getmap_ioctl, &map, DRM_UNLOCKED);
	if (err)
		return err;

	m32.offset = map.offset;
	m32.size = map.size;
	m32.type = map.type;
	m32.flags = map.flags;
	m32.handle = ptr_to_compat((void __user *)map.handle);
	m32.mtrr = map.mtrr;
	if (copy_to_user(argp, &m32, sizeof(m32)))
		return -EFAULT;
	return 0;

}

static int compat_drm_addmap(struct file *file, unsigned int cmd,
			     unsigned long arg)
{
	drm_map32_t __user *argp = (void __user *)arg;
	drm_map32_t m32;
	struct drm_map map;
	int err;

	if (copy_from_user(&m32, argp, sizeof(m32)))
		return -EFAULT;

	map.offset = m32.offset;
	map.size = m32.size;
	map.type = m32.type;
	map.flags = m32.flags;

	err = drm_ioctl_kernel(file, drm_legacy_addmap_ioctl, &map,
				DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY);
	if (err)
		return err;

	m32.offset = map.offset;
	m32.mtrr = map.mtrr;
	m32.handle = ptr_to_compat((void __user *)map.handle);
	if (map.handle != compat_ptr(m32.handle))
		pr_err_ratelimited("compat_drm_addmap truncated handle %p for type %d offset %x\n",
				   map.handle, m32.type, m32.offset);

	if (copy_to_user(argp, &m32, sizeof(m32)))
		return -EFAULT;

	return 0;
}

static int compat_drm_rmmap(struct file *file, unsigned int cmd,
			    unsigned long arg)
{
	drm_map32_t __user *argp = (void __user *)arg;
	struct drm_map map;
	u32 handle;

	if (get_user(handle, &argp->handle))
		return -EFAULT;
	map.handle = compat_ptr(handle);
	return drm_ioctl_kernel(file, drm_legacy_rmmap_ioctl, &map, DRM_AUTH);
}

typedef struct drm_client32 {
	int idx;	/* Which client desired? */
	int auth;	/* Is client authenticated? */
	u32 pid;	/* Process ID */
	u32 uid;	/* User ID */
	u32 magic;	/* Magic */
	u32 iocs;	/* Ioctl count */
} drm_client32_t;

static int compat_drm_getclient(struct file *file, unsigned int cmd,
				unsigned long arg)
{
	drm_client32_t c32;
	drm_client32_t __user *argp = (void __user *)arg;
	struct drm_client client;
	int err;

	if (copy_from_user(&c32, argp, sizeof(c32)))
		return -EFAULT;

	memset(&client, 0, sizeof(client));

	client.idx = c32.idx;

	err = drm_ioctl_kernel(file, drm_getclient, &client, DRM_UNLOCKED);
	if (err)
		return err;

	c32.idx = client.idx;
	c32.auth = client.auth;
	c32.pid = client.pid;
	c32.uid = client.uid;
	c32.magic = client.magic;
	c32.iocs = client.iocs;

	if (copy_to_user(argp, &c32, sizeof(c32)))
		return -EFAULT;
	return 0;
}

typedef struct drm_stats32 {
	u32 count;
	struct {
		u32 value;
		enum drm_stat_type type;
	} data[15];
} drm_stats32_t;

static int compat_drm_getstats(struct file *file, unsigned int cmd,
			       unsigned long arg)
{
	drm_stats32_t __user *argp = (void __user *)arg;
	int err;

	err = drm_ioctl_kernel(file, drm_noop, NULL, DRM_UNLOCKED);
	if (err)
		return err;

	if (clear_user(argp, sizeof(drm_stats32_t)))
		return -EFAULT;
	return 0;
}

typedef struct drm_buf_desc32 {
	int count;		 /* Number of buffers of this size */
	int size;		 /* Size in bytes */
	int low_mark;		 /* Low water mark */
	int high_mark;		 /* High water mark */
	int flags;
	u32 agp_start;		 /* Start address in the AGP aperture */
} drm_buf_desc32_t;

static int compat_drm_addbufs(struct file *file, unsigned int cmd,
			      unsigned long arg)
{
	drm_buf_desc32_t __user *argp = (void __user *)arg;
	drm_buf_desc32_t desc32;
	struct drm_buf_desc desc;
	int err;

	if (copy_from_user(&desc32, argp, sizeof(drm_buf_desc32_t)))
		return -EFAULT;

	desc = (struct drm_buf_desc){
		desc32.count, desc32.size, desc32.low_mark, desc32.high_mark,
		desc32.flags, desc32.agp_start
	};

	err = drm_ioctl_kernel(file, drm_legacy_addbufs, &desc,
				   DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY);
	if (err)
		return err;

	desc32 = (drm_buf_desc32_t){
		desc.count, desc.size, desc.low_mark, desc.high_mark,
		desc.flags, desc.agp_start
	};
	if (copy_to_user(argp, &desc32, sizeof(drm_buf_desc32_t)))
		return -EFAULT;

	return 0;
}

static int compat_drm_markbufs(struct file *file, unsigned int cmd,
			       unsigned long arg)
{
	drm_buf_desc32_t b32;
	drm_buf_desc32_t __user *argp = (void __user *)arg;
	struct drm_buf_desc buf;

	if (copy_from_user(&b32, argp, sizeof(b32)))
		return -EFAULT;

	buf.size = b32.size;
	buf.low_mark = b32.low_mark;
	buf.high_mark = b32.high_mark;

	return drm_ioctl_kernel(file, drm_legacy_markbufs, &buf,
				DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY);
}

typedef struct drm_buf_info32 {
	int count;		/**< Entries in list */
	u32 list;
} drm_buf_info32_t;

static int copy_one_buf32(void *data, int count, struct drm_buf_entry *from)
{
	drm_buf_info32_t *request = data;
	drm_buf_desc32_t __user *to = compat_ptr(request->list);
	drm_buf_desc32_t v = {.count = from->buf_count,
			      .size = from->buf_size,
			      .low_mark = from->low_mark,
			      .high_mark = from->high_mark};

	if (copy_to_user(to + count, &v, offsetof(drm_buf_desc32_t, flags)))
		return -EFAULT;
	return 0;
}

static int drm_legacy_infobufs32(struct drm_device *dev, void *data,
			struct drm_file *file_priv)
{
	drm_buf_info32_t *request = data;
	return __drm_legacy_infobufs(dev, data, &request->count, copy_one_buf32);
}

static int compat_drm_infobufs(struct file *file, unsigned int cmd,
			       unsigned long arg)
{
	drm_buf_info32_t req32;
	drm_buf_info32_t __user *argp = (void __user *)arg;
	int err;

	if (copy_from_user(&req32, argp, sizeof(req32)))
		return -EFAULT;

	if (req32.count < 0)
		req32.count = 0;

	err = drm_ioctl_kernel(file, drm_legacy_infobufs32, &req32, DRM_AUTH);
	if (err)
		return err;

	if (put_user(req32.count, &argp->count))
		return -EFAULT;

	return 0;
}

typedef struct drm_buf_pub32 {
	int idx;		/**< Index into the master buffer list */
	int total;		/**< Buffer size */
	int used;		/**< Amount of buffer in use (for DMA) */
	u32 address;		/**< Address of buffer */
} drm_buf_pub32_t;

typedef struct drm_buf_map32 {
	int count;		/**< Length of the buffer list */
	u32 virtual;		/**< Mmap'd area in user-virtual */
	u32 list;		/**< Buffer information */
} drm_buf_map32_t;

static int map_one_buf32(void *data, int idx, unsigned long virtual,
			struct drm_buf *buf)
{
	drm_buf_map32_t *request = data;
	drm_buf_pub32_t __user *to = compat_ptr(request->list) + idx;
	drm_buf_pub32_t v;

	v.idx = buf->idx;
	v.total = buf->total;
	v.used = 0;
	v.address = virtual + buf->offset;
	if (copy_to_user(to, &v, sizeof(v)))
		return -EFAULT;
	return 0;
}

static int drm_legacy_mapbufs32(struct drm_device *dev, void *data,
		       struct drm_file *file_priv)
{
	drm_buf_map32_t *request = data;
	void __user *v;
	int err = __drm_legacy_mapbufs(dev, data, &request->count,
				    &v, map_one_buf32,
				    file_priv);
	request->virtual = ptr_to_compat(v);
	return err;
}

static int compat_drm_mapbufs(struct file *file, unsigned int cmd,
			      unsigned long arg)
{
	drm_buf_map32_t __user *argp = (void __user *)arg;
	drm_buf_map32_t req32;
	int err;

	if (copy_from_user(&req32, argp, sizeof(req32)))
		return -EFAULT;
	if (req32.count < 0)
		return -EINVAL;

	err = drm_ioctl_kernel(file, drm_legacy_mapbufs32, &req32, DRM_AUTH);
	if (err)
		return err;

	if (put_user(req32.count, &argp->count)
	    || put_user(req32.virtual, &argp->virtual))
		return -EFAULT;

	return 0;
}

typedef struct drm_buf_free32 {
	int count;
	u32 list;
} drm_buf_free32_t;

static int compat_drm_freebufs(struct file *file, unsigned int cmd,
			       unsigned long arg)
{
	drm_buf_free32_t req32;
	struct drm_buf_free request;
	drm_buf_free32_t __user *argp = (void __user *)arg;

	if (copy_from_user(&req32, argp, sizeof(req32)))
		return -EFAULT;

	request.count = req32.count;
	request.list = compat_ptr(req32.list);
	return drm_ioctl_kernel(file, drm_legacy_freebufs, &request, DRM_AUTH);
}

typedef struct drm_ctx_priv_map32 {
	unsigned int ctx_id;	 /**< Context requesting private mapping */
	u32 handle;		/**< Handle of map */
} drm_ctx_priv_map32_t;

static int compat_drm_setsareactx(struct file *file, unsigned int cmd,
				  unsigned long arg)
{
	drm_ctx_priv_map32_t req32;
	struct drm_ctx_priv_map request;
	drm_ctx_priv_map32_t __user *argp = (void __user *)arg;

	if (copy_from_user(&req32, argp, sizeof(req32)))
		return -EFAULT;

	request.ctx_id = req32.ctx_id;
	request.handle = compat_ptr(req32.handle);
	return drm_ioctl_kernel(file, drm_legacy_setsareactx, &request,
				DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY);
}

static int compat_drm_getsareactx(struct file *file, unsigned int cmd,
				  unsigned long arg)
{
	struct drm_ctx_priv_map req;
	drm_ctx_priv_map32_t req32;
	drm_ctx_priv_map32_t __user *argp = (void __user *)arg;
	int err;

	if (copy_from_user(&req32, argp, sizeof(req32)))
		return -EFAULT;

	req.ctx_id = req32.ctx_id;
	err = drm_ioctl_kernel(file, drm_legacy_getsareactx, &req, DRM_AUTH);
	if (err)
		return err;

	req32.handle = ptr_to_compat((void __user *)req.handle);
	if (copy_to_user(argp, &req32, sizeof(req32)))
		return -EFAULT;

	return 0;
}

typedef struct drm_ctx_res32 {
	int count;
	u32 contexts;
} drm_ctx_res32_t;

static int compat_drm_resctx(struct file *file, unsigned int cmd,
			     unsigned long arg)
{
	drm_ctx_res32_t __user *argp = (void __user *)arg;
	drm_ctx_res32_t res32;
	struct drm_ctx_res res;
	int err;

	if (copy_from_user(&res32, argp, sizeof(res32)))
		return -EFAULT;

	res.count = res32.count;
	res.contexts = compat_ptr(res32.contexts);
	err = drm_ioctl_kernel(file, drm_legacy_resctx, &res, DRM_AUTH);
	if (err)
		return err;

	res32.count = res.count;
	if (copy_to_user(argp, &res32, sizeof(res32)))
		return -EFAULT;

	return 0;
}

typedef struct drm_dma32 {
	int context;		  /**< Context handle */
	int send_count;		  /**< Number of buffers to send */
	u32 send_indices;	  /**< List of handles to buffers */
	u32 send_sizes;		  /**< Lengths of data to send */
	enum drm_dma_flags flags;		  /**< Flags */
	int request_count;	  /**< Number of buffers requested */
	int request_size;	  /**< Desired size for buffers */
	u32 request_indices;	  /**< Buffer information */
	u32 request_sizes;
	int granted_count;	  /**< Number of buffers granted */
} drm_dma32_t;

static int compat_drm_dma(struct file *file, unsigned int cmd,
			  unsigned long arg)
{
	drm_dma32_t d32;
	drm_dma32_t __user *argp = (void __user *)arg;
	struct drm_dma d;
	int err;

	if (copy_from_user(&d32, argp, sizeof(d32)))
		return -EFAULT;

	d.context = d32.context;
	d.send_count = d32.send_count;
	d.send_indices = compat_ptr(d32.send_indices);
	d.send_sizes = compat_ptr(d32.send_sizes);
	d.flags = d32.flags;
	d.request_count = d32.request_count;
	d.request_indices = compat_ptr(d32.request_indices);
	d.request_sizes = compat_ptr(d32.request_sizes);
	err = drm_ioctl_kernel(file, drm_legacy_dma_ioctl, &d, DRM_AUTH);
	if (err)
		return err;

	if (put_user(d.request_size, &argp->request_size)
	    || put_user(d.granted_count, &argp->granted_count))
		return -EFAULT;

	return 0;
}

#if IS_ENABLED(CONFIG_AGP)
typedef struct drm_agp_mode32 {
	u32 mode;	/**< AGP mode */
} drm_agp_mode32_t;

static int compat_drm_agp_enable(struct file *file, unsigned int cmd,
				 unsigned long arg)
{
	drm_agp_mode32_t __user *argp = (void __user *)arg;
	struct drm_agp_mode mode;

	if (get_user(mode.mode, &argp->mode))
		return -EFAULT;

	return drm_ioctl_kernel(file,  drm_agp_enable_ioctl, &mode,
				DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY);
}

typedef struct drm_agp_info32 {
	int agp_version_major;
	int agp_version_minor;
	u32 mode;
	u32 aperture_base;	/* physical address */
	u32 aperture_size;	/* bytes */
	u32 memory_allowed;	/* bytes */
	u32 memory_used;

	/* PCI information */
	unsigned short id_vendor;
	unsigned short id_device;
} drm_agp_info32_t;

static int compat_drm_agp_info(struct file *file, unsigned int cmd,
			       unsigned long arg)
{
	drm_agp_info32_t __user *argp = (void __user *)arg;
	drm_agp_info32_t i32;
	struct drm_agp_info info;
	int err;

	err = drm_ioctl_kernel(file, drm_agp_info_ioctl, &info, DRM_AUTH);
	if (err)
		return err;

	i32.agp_version_major = info.agp_version_major;
	i32.agp_version_minor = info.agp_version_minor;
	i32.mode = info.mode;
	i32.aperture_base = info.aperture_base;
	i32.aperture_size = info.aperture_size;
	i32.memory_allowed = info.memory_allowed;
	i32.memory_used = info.memory_used;
	i32.id_vendor = info.id_vendor;
	i32.id_device = info.id_device;
	if (copy_to_user(argp, &i32, sizeof(i32)))
		return -EFAULT;

	return 0;
}

typedef struct drm_agp_buffer32 {
	u32 size;	/**< In bytes -- will round to page boundary */
	u32 handle;	/**< Used for binding / unbinding */
	u32 type;	/**< Type of memory to allocate */
	u32 physical;	/**< Physical used by i810 */
} drm_agp_buffer32_t;

static int compat_drm_agp_alloc(struct file *file, unsigned int cmd,
				unsigned long arg)
{
	drm_agp_buffer32_t __user *argp = (void __user *)arg;
	drm_agp_buffer32_t req32;
	struct drm_agp_buffer request;
	int err;

	if (copy_from_user(&req32, argp, sizeof(req32)))
		return -EFAULT;

	request.size = req32.size;
	request.type = req32.type;
	err = drm_ioctl_kernel(file, drm_agp_alloc_ioctl, &request,
				DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY);
	if (err)
		return err;

	req32.handle = request.handle;
	req32.physical = request.physical;
	if (copy_to_user(argp, &req32, sizeof(req32))) {
		drm_ioctl_kernel(file, drm_agp_free_ioctl, &request,
				DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY);
		return -EFAULT;
	}

	return 0;
}

static int compat_drm_agp_free(struct file *file, unsigned int cmd,
			       unsigned long arg)
{
	drm_agp_buffer32_t __user *argp = (void __user *)arg;
	struct drm_agp_buffer request;

	if (get_user(request.handle, &argp->handle))
		return -EFAULT;

	return drm_ioctl_kernel(file, drm_agp_free_ioctl, &request,
				DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY);
}

typedef struct drm_agp_binding32 {
	u32 handle;	/**< From drm_agp_buffer */
	u32 offset;	/**< In bytes -- will round to page boundary */
} drm_agp_binding32_t;

static int compat_drm_agp_bind(struct file *file, unsigned int cmd,
			       unsigned long arg)
{
	drm_agp_binding32_t __user *argp = (void __user *)arg;
	drm_agp_binding32_t req32;
	struct drm_agp_binding request;

	if (copy_from_user(&req32, argp, sizeof(req32)))
		return -EFAULT;

	request.handle = req32.handle;
	request.offset = req32.offset;
	return drm_ioctl_kernel(file, drm_agp_bind_ioctl, &request,
				DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY);
}

static int compat_drm_agp_unbind(struct file *file, unsigned int cmd,
				 unsigned long arg)
{
	drm_agp_binding32_t __user *argp = (void __user *)arg;
	struct drm_agp_binding request;

	if (get_user(request.handle, &argp->handle))
		return -EFAULT;

	return drm_ioctl_kernel(file, drm_agp_unbind_ioctl, &request,
				DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY);
}
#endif /* CONFIG_AGP */

typedef struct drm_scatter_gather32 {
	u32 size;	/**< In bytes -- will round to page boundary */
	u32 handle;	/**< Used for mapping / unmapping */
} drm_scatter_gather32_t;

static int compat_drm_sg_alloc(struct file *file, unsigned int cmd,
			       unsigned long arg)
{
	drm_scatter_gather32_t __user *argp = (void __user *)arg;
	struct drm_scatter_gather request;
	int err;

	if (get_user(request.size, &argp->size))
		return -EFAULT;

	err = drm_ioctl_kernel(file, drm_legacy_sg_alloc, &request,
				DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY);
	if (err)
		return err;

	/* XXX not sure about the handle conversion here... */
	if (put_user(request.handle >> PAGE_SHIFT, &argp->handle))
		return -EFAULT;

	return 0;
}

static int compat_drm_sg_free(struct file *file, unsigned int cmd,
			      unsigned long arg)
{
	drm_scatter_gather32_t __user *argp = (void __user *)arg;
	struct drm_scatter_gather request;
	unsigned long x;

	if (get_user(x, &argp->handle))
		return -EFAULT;
	request.handle = x << PAGE_SHIFT;
	return drm_ioctl_kernel(file, drm_legacy_sg_free, &request,
				DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY);
}

#if defined(CONFIG_X86)
typedef struct drm_update_draw32 {
	drm_drawable_t handle;
	unsigned int type;
	unsigned int num;
	/* 64-bit version has a 32-bit pad here */
	u64 data;	/**< Pointer */
} __attribute__((packed)) drm_update_draw32_t;

static int compat_drm_update_draw(struct file *file, unsigned int cmd,
				  unsigned long arg)
{
	drm_update_draw32_t update32;
	if (copy_from_user(&update32, (void __user *)arg, sizeof(update32)))
		return -EFAULT;

	return drm_ioctl_kernel(file, drm_noop, NULL,
				DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY);
}
#endif

struct drm_wait_vblank_request32 {
	enum drm_vblank_seq_type type;
	unsigned int sequence;
	u32 signal;
};

struct drm_wait_vblank_reply32 {
	enum drm_vblank_seq_type type;
	unsigned int sequence;
	s32 tval_sec;
	s32 tval_usec;
};

typedef union drm_wait_vblank32 {
	struct drm_wait_vblank_request32 request;
	struct drm_wait_vblank_reply32 reply;
} drm_wait_vblank32_t;

static int compat_drm_wait_vblank(struct file *file, unsigned int cmd,
				  unsigned long arg)
{
	drm_wait_vblank32_t __user *argp = (void __user *)arg;
	drm_wait_vblank32_t req32;
	union drm_wait_vblank req;
	int err;

	if (copy_from_user(&req32, argp, sizeof(req32)))
		return -EFAULT;

	memset(&req, 0, sizeof(req));

	req.request.type = req32.request.type;
	req.request.sequence = req32.request.sequence;
	req.request.signal = req32.request.signal;
	err = drm_ioctl_kernel(file, drm_wait_vblank_ioctl, &req, DRM_UNLOCKED);

	req32.reply.type = req.reply.type;
	req32.reply.sequence = req.reply.sequence;
	req32.reply.tval_sec = req.reply.tval_sec;
	req32.reply.tval_usec = req.reply.tval_usec;
	if (copy_to_user(argp, &req32, sizeof(req32)))
		return -EFAULT;

	return err;
}

#if defined(CONFIG_X86)
typedef struct drm_mode_fb_cmd232 {
	u32 fb_id;
	u32 width;
	u32 height;
	u32 pixel_format;
	u32 flags;
	u32 handles[4];
	u32 pitches[4];
	u32 offsets[4];
	u64 modifier[4];
} __attribute__((packed)) drm_mode_fb_cmd232_t;

static int compat_drm_mode_addfb2(struct file *file, unsigned int cmd,
				  unsigned long arg)
{
	struct drm_mode_fb_cmd232 __user *argp = (void __user *)arg;
	struct drm_mode_fb_cmd2 req64;
	int err;

	memset(&req64, 0, sizeof(req64));

	if (copy_from_user(&req64, argp,
			   offsetof(drm_mode_fb_cmd232_t, modifier)))
		return -EFAULT;

	if (copy_from_user(&req64.modifier, &argp->modifier,
			   sizeof(req64.modifier)))
		return -EFAULT;

	err = drm_ioctl_kernel(file, drm_mode_addfb2, &req64,
			       DRM_UNLOCKED);
	if (err)
		return err;

	if (put_user(req64.fb_id, &argp->fb_id))
		return -EFAULT;

	return 0;
}
#endif

static struct {
	drm_ioctl_compat_t *fn;
	char *name;
} drm_compat_ioctls[] = {
#define DRM_IOCTL32_DEF(n, f) [DRM_IOCTL_NR(n##32)] = {.fn = f, .name = #n}
	DRM_IOCTL32_DEF(DRM_IOCTL_VERSION, compat_drm_version),
	DRM_IOCTL32_DEF(DRM_IOCTL_GET_UNIQUE, compat_drm_getunique),
	DRM_IOCTL32_DEF(DRM_IOCTL_GET_MAP, compat_drm_getmap),
	DRM_IOCTL32_DEF(DRM_IOCTL_GET_CLIENT, compat_drm_getclient),
	DRM_IOCTL32_DEF(DRM_IOCTL_GET_STATS, compat_drm_getstats),
	DRM_IOCTL32_DEF(DRM_IOCTL_SET_UNIQUE, compat_drm_setunique),
	DRM_IOCTL32_DEF(DRM_IOCTL_ADD_MAP, compat_drm_addmap),
	DRM_IOCTL32_DEF(DRM_IOCTL_ADD_BUFS, compat_drm_addbufs),
	DRM_IOCTL32_DEF(DRM_IOCTL_MARK_BUFS, compat_drm_markbufs),
	DRM_IOCTL32_DEF(DRM_IOCTL_INFO_BUFS, compat_drm_infobufs),
	DRM_IOCTL32_DEF(DRM_IOCTL_MAP_BUFS, compat_drm_mapbufs),
	DRM_IOCTL32_DEF(DRM_IOCTL_FREE_BUFS, compat_drm_freebufs),
	DRM_IOCTL32_DEF(DRM_IOCTL_RM_MAP, compat_drm_rmmap),
	DRM_IOCTL32_DEF(DRM_IOCTL_SET_SAREA_CTX, compat_drm_setsareactx),
	DRM_IOCTL32_DEF(DRM_IOCTL_GET_SAREA_CTX, compat_drm_getsareactx),
	DRM_IOCTL32_DEF(DRM_IOCTL_RES_CTX, compat_drm_resctx),
	DRM_IOCTL32_DEF(DRM_IOCTL_DMA, compat_drm_dma),
#if IS_ENABLED(CONFIG_AGP)
	DRM_IOCTL32_DEF(DRM_IOCTL_AGP_ENABLE, compat_drm_agp_enable),
	DRM_IOCTL32_DEF(DRM_IOCTL_AGP_INFO, compat_drm_agp_info),
	DRM_IOCTL32_DEF(DRM_IOCTL_AGP_ALLOC, compat_drm_agp_alloc),
	DRM_IOCTL32_DEF(DRM_IOCTL_AGP_FREE, compat_drm_agp_free),
	DRM_IOCTL32_DEF(DRM_IOCTL_AGP_BIND, compat_drm_agp_bind),
	DRM_IOCTL32_DEF(DRM_IOCTL_AGP_UNBIND, compat_drm_agp_unbind),
#endif
	DRM_IOCTL32_DEF(DRM_IOCTL_SG_ALLOC, compat_drm_sg_alloc),
	DRM_IOCTL32_DEF(DRM_IOCTL_SG_FREE, compat_drm_sg_free),
#if defined(CONFIG_X86) || defined(CONFIG_IA64)
	DRM_IOCTL32_DEF(DRM_IOCTL_UPDATE_DRAW, compat_drm_update_draw),
#endif
	DRM_IOCTL32_DEF(DRM_IOCTL_WAIT_VBLANK, compat_drm_wait_vblank),
#if defined(CONFIG_X86) || defined(CONFIG_IA64)
	DRM_IOCTL32_DEF(DRM_IOCTL_MODE_ADDFB2, compat_drm_mode_addfb2),
#endif
};

/**
 * drm_compat_ioctl - 32bit IOCTL compatibility handler for DRM drivers
 * @filp: file this ioctl is called on
 * @cmd: ioctl cmd number
 * @arg: user argument
 *
 * Compatibility handler for 32 bit userspace running on 64 kernels. All actual
 * IOCTL handling is forwarded to drm_ioctl(), while marshalling structures as
 * appropriate. Note that this only handles DRM core IOCTLs, if the driver has
 * botched IOCTL itself, it must handle those by wrapping this function.
 *
 * Returns:
 * Zero on success, negative error code on failure.
 */
long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	unsigned int nr = DRM_IOCTL_NR(cmd);
	struct drm_file *file_priv = filp->private_data;
	drm_ioctl_compat_t *fn;
	int ret;

	/* Assume that ioctls without an explicit compat routine will just
	 * work.  This may not always be a good assumption, but it's better
	 * than always failing.
	 */
	if (nr >= ARRAY_SIZE(drm_compat_ioctls))
		return drm_ioctl(filp, cmd, arg);

	fn = drm_compat_ioctls[nr].fn;
	if (!fn)
		return drm_ioctl(filp, cmd, arg);

	DRM_DEBUG("pid=%d, dev=0x%lx, auth=%d, %s\n",
		  task_pid_nr(current),
		  (long)old_encode_dev(file_priv->minor->kdev->devt),
		  file_priv->authenticated,
		  drm_compat_ioctls[nr].name);
	ret = (*fn)(filp, cmd, arg);
	if (ret)
		DRM_DEBUG("ret = %d\n", ret);
	return ret;
}
EXPORT_SYMBOL(drm_compat_ioctl);
