Home | History | Annotate | Line # | Download | only in drm
drm_ioctl.c revision 1.11
      1  1.11      maya /*	$NetBSD: drm_ioctl.c,v 1.11 2018/09/14 05:31:14 maya Exp $	*/
      2   1.1  riastrad 
      3   1.1  riastrad /*
      4   1.1  riastrad  * Created: Fri Jan  8 09:01:26 1999 by faith (at) valinux.com
      5   1.1  riastrad  *
      6   1.1  riastrad  * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
      7   1.1  riastrad  * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
      8   1.1  riastrad  * All Rights Reserved.
      9   1.1  riastrad  *
     10   1.5  riastrad  * Author Rickard E. (Rik) Faith <faith (at) valinux.com>
     11   1.5  riastrad  * Author Gareth Hughes <gareth (at) valinux.com>
     12   1.5  riastrad  *
     13   1.1  riastrad  * Permission is hereby granted, free of charge, to any person obtaining a
     14   1.1  riastrad  * copy of this software and associated documentation files (the "Software"),
     15   1.1  riastrad  * to deal in the Software without restriction, including without limitation
     16   1.1  riastrad  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     17   1.1  riastrad  * and/or sell copies of the Software, and to permit persons to whom the
     18   1.1  riastrad  * Software is furnished to do so, subject to the following conditions:
     19   1.1  riastrad  *
     20   1.1  riastrad  * The above copyright notice and this permission notice (including the next
     21   1.1  riastrad  * paragraph) shall be included in all copies or substantial portions of the
     22   1.1  riastrad  * Software.
     23   1.1  riastrad  *
     24   1.1  riastrad  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     25   1.1  riastrad  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     26   1.1  riastrad  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     27   1.1  riastrad  * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
     28   1.1  riastrad  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     29   1.1  riastrad  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     30   1.1  riastrad  * OTHER DEALINGS IN THE SOFTWARE.
     31   1.1  riastrad  */
     32   1.1  riastrad 
     33   1.5  riastrad #include <sys/cdefs.h>
     34  1.11      maya __KERNEL_RCSID(0, "$NetBSD: drm_ioctl.c,v 1.11 2018/09/14 05:31:14 maya Exp $");
     35   1.5  riastrad 
     36   1.1  riastrad #include <drm/drmP.h>
     37   1.1  riastrad #include <drm/drm_core.h>
     38   1.5  riastrad #include "drm_legacy.h"
     39   1.5  riastrad #include "drm_internal.h"
     40   1.5  riastrad #include "drm_crtc_internal.h"
     41   1.1  riastrad 
     42   1.1  riastrad #include <linux/pci.h>
     43   1.1  riastrad #include <linux/export.h>
     44   1.1  riastrad 
     45   1.5  riastrad static int drm_version(struct drm_device *dev, void *data,
     46   1.5  riastrad 		       struct drm_file *file_priv);
     47   1.5  riastrad 
     48   1.5  riastrad /*
     49   1.1  riastrad  * Get the bus id.
     50   1.1  riastrad  *
     51   1.1  riastrad  * \param inode device inode.
     52   1.1  riastrad  * \param file_priv DRM file private.
     53   1.1  riastrad  * \param cmd command.
     54   1.1  riastrad  * \param arg user argument, pointing to a drm_unique structure.
     55   1.1  riastrad  * \return zero on success or a negative number on failure.
     56   1.1  riastrad  *
     57   1.1  riastrad  * Copies the bus id from drm_device::unique into user space.
     58   1.1  riastrad  */
     59   1.5  riastrad static int drm_getunique(struct drm_device *dev, void *data,
     60   1.1  riastrad 		  struct drm_file *file_priv)
     61   1.1  riastrad {
     62   1.1  riastrad 	struct drm_unique *u = data;
     63   1.1  riastrad 	struct drm_master *master = file_priv->master;
     64   1.1  riastrad 
     65   1.1  riastrad 	if (u->unique_len >= master->unique_len) {
     66   1.1  riastrad 		if (copy_to_user(u->unique, master->unique, master->unique_len))
     67   1.1  riastrad 			return -EFAULT;
     68   1.1  riastrad 	}
     69   1.1  riastrad 	u->unique_len = master->unique_len;
     70   1.1  riastrad 
     71   1.1  riastrad 	return 0;
     72   1.1  riastrad }
     73   1.1  riastrad 
     74   1.1  riastrad static void
     75   1.1  riastrad drm_unset_busid(struct drm_device *dev,
     76   1.1  riastrad 		struct drm_master *master)
     77   1.1  riastrad {
     78   1.1  riastrad 	kfree(master->unique);
     79   1.1  riastrad 	master->unique = NULL;
     80   1.1  riastrad 	master->unique_len = 0;
     81   1.1  riastrad }
     82   1.1  riastrad 
     83   1.5  riastrad /*
     84   1.1  riastrad  * Set the bus id.
     85   1.1  riastrad  *
     86   1.1  riastrad  * \param inode device inode.
     87   1.1  riastrad  * \param file_priv DRM file private.
     88   1.1  riastrad  * \param cmd command.
     89   1.1  riastrad  * \param arg user argument, pointing to a drm_unique structure.
     90   1.1  riastrad  * \return zero on success or a negative number on failure.
     91   1.1  riastrad  *
     92   1.1  riastrad  * Copies the bus id from userspace into drm_device::unique, and verifies that
     93   1.1  riastrad  * it matches the device this DRM is attached to (EINVAL otherwise).  Deprecated
     94   1.1  riastrad  * in interface version 1.1 and will return EBUSY when setversion has requested
     95   1.5  riastrad  * version 1.1 or greater. Also note that KMS is all version 1.1 and later and
     96   1.5  riastrad  * UMS was only ever supported on pci devices.
     97   1.1  riastrad  */
     98   1.5  riastrad static int drm_setunique(struct drm_device *dev, void *data,
     99   1.1  riastrad 		  struct drm_file *file_priv)
    100   1.1  riastrad {
    101   1.1  riastrad 	struct drm_unique *u = data;
    102   1.1  riastrad 	struct drm_master *master = file_priv->master;
    103   1.1  riastrad 	int ret;
    104   1.1  riastrad 
    105   1.1  riastrad 	if (master->unique_len || master->unique)
    106   1.1  riastrad 		return -EBUSY;
    107   1.1  riastrad 
    108   1.1  riastrad 	if (!u->unique_len || u->unique_len > 1024)
    109   1.1  riastrad 		return -EINVAL;
    110   1.1  riastrad 
    111   1.5  riastrad 	if (drm_core_check_feature(dev, DRIVER_MODESET))
    112   1.5  riastrad 		return 0;
    113   1.5  riastrad 
    114   1.5  riastrad 	if (WARN_ON(!dev->pdev))
    115   1.1  riastrad 		return -EINVAL;
    116   1.1  riastrad 
    117  1.10  riastrad 	if (!dev->driver->set_unique)
    118  1.10  riastrad 		return -ENODEV;
    119  1.10  riastrad 
    120  1.10  riastrad 	ret = dev->driver->set_unique(dev, master, u);
    121   1.1  riastrad 	if (ret)
    122   1.1  riastrad 		goto err;
    123   1.1  riastrad 
    124   1.1  riastrad 	return 0;
    125   1.1  riastrad 
    126   1.1  riastrad err:
    127   1.1  riastrad 	drm_unset_busid(dev, master);
    128   1.1  riastrad 	return ret;
    129   1.1  riastrad }
    130   1.1  riastrad 
    131   1.1  riastrad static int drm_set_busid(struct drm_device *dev, struct drm_file *file_priv)
    132   1.1  riastrad {
    133   1.1  riastrad 	struct drm_master *master = file_priv->master;
    134   1.1  riastrad 	int ret;
    135   1.1  riastrad 
    136   1.1  riastrad 	if (master->unique != NULL)
    137   1.1  riastrad 		drm_unset_busid(dev, master);
    138   1.1  riastrad 
    139   1.5  riastrad 	if (dev->driver->set_busid) {
    140   1.5  riastrad 		ret = dev->driver->set_busid(dev, master);
    141   1.5  riastrad 		if (ret) {
    142   1.5  riastrad 			drm_unset_busid(dev, master);
    143   1.5  riastrad 			return ret;
    144   1.5  riastrad 		}
    145   1.5  riastrad 	} else {
    146   1.5  riastrad 		if (WARN(dev->unique == NULL,
    147   1.5  riastrad 			 "No drm_driver.set_busid() implementation provided by "
    148   1.5  riastrad 			 "%ps. Use drm_dev_set_unique() to set the unique "
    149   1.5  riastrad 			 "name explicitly.", dev->driver))
    150   1.5  riastrad 			return -EINVAL;
    151   1.5  riastrad 
    152   1.5  riastrad 		master->unique = kstrdup(dev->unique, GFP_KERNEL);
    153   1.5  riastrad 		if (master->unique)
    154   1.5  riastrad 			master->unique_len = strlen(dev->unique);
    155   1.5  riastrad 	}
    156   1.5  riastrad 
    157   1.1  riastrad 	return 0;
    158   1.1  riastrad }
    159   1.1  riastrad 
    160   1.5  riastrad /*
    161   1.1  riastrad  * Get a mapping information.
    162   1.1  riastrad  *
    163   1.1  riastrad  * \param inode device inode.
    164   1.1  riastrad  * \param file_priv DRM file private.
    165   1.1  riastrad  * \param cmd command.
    166   1.1  riastrad  * \param arg user argument, pointing to a drm_map structure.
    167   1.1  riastrad  *
    168   1.1  riastrad  * \return zero on success or a negative number on failure.
    169   1.1  riastrad  *
    170   1.1  riastrad  * Searches for the mapping with the specified offset and copies its information
    171   1.1  riastrad  * into userspace
    172   1.1  riastrad  */
    173   1.5  riastrad static int drm_getmap(struct drm_device *dev, void *data,
    174   1.1  riastrad 	       struct drm_file *file_priv)
    175   1.1  riastrad {
    176   1.1  riastrad 	struct drm_map *map = data;
    177   1.1  riastrad 	struct drm_map_list *r_list = NULL;
    178   1.1  riastrad 	struct list_head *list;
    179   1.1  riastrad 	int idx;
    180   1.1  riastrad 	int i;
    181   1.1  riastrad 
    182   1.1  riastrad 	idx = map->offset;
    183   1.1  riastrad 	if (idx < 0)
    184   1.1  riastrad 		return -EINVAL;
    185   1.1  riastrad 
    186   1.1  riastrad 	i = 0;
    187   1.1  riastrad 	mutex_lock(&dev->struct_mutex);
    188   1.1  riastrad 	list_for_each(list, &dev->maplist) {
    189   1.1  riastrad 		if (i == idx) {
    190   1.1  riastrad 			r_list = list_entry(list, struct drm_map_list, head);
    191   1.1  riastrad 			break;
    192   1.1  riastrad 		}
    193   1.1  riastrad 		i++;
    194   1.1  riastrad 	}
    195   1.1  riastrad 	if (!r_list || !r_list->map) {
    196   1.1  riastrad 		mutex_unlock(&dev->struct_mutex);
    197   1.1  riastrad 		return -EINVAL;
    198   1.1  riastrad 	}
    199   1.1  riastrad 
    200   1.1  riastrad 	map->offset = r_list->map->offset;
    201   1.1  riastrad 	map->size = r_list->map->size;
    202   1.1  riastrad 	map->type = r_list->map->type;
    203   1.1  riastrad 	map->flags = r_list->map->flags;
    204   1.1  riastrad 	map->handle = (void *)(unsigned long) r_list->user_token;
    205   1.5  riastrad 	map->mtrr = arch_phys_wc_index(r_list->map->mtrr);
    206   1.3  riastrad 
    207   1.1  riastrad 	mutex_unlock(&dev->struct_mutex);
    208   1.1  riastrad 
    209   1.1  riastrad 	return 0;
    210   1.1  riastrad }
    211   1.1  riastrad 
    212   1.5  riastrad /*
    213   1.1  riastrad  * Get client information.
    214   1.1  riastrad  *
    215   1.1  riastrad  * \param inode device inode.
    216   1.1  riastrad  * \param file_priv DRM file private.
    217   1.1  riastrad  * \param cmd command.
    218   1.1  riastrad  * \param arg user argument, pointing to a drm_client structure.
    219   1.1  riastrad  *
    220   1.1  riastrad  * \return zero on success or a negative number on failure.
    221   1.1  riastrad  *
    222   1.1  riastrad  * Searches for the client with the specified index and copies its information
    223   1.1  riastrad  * into userspace
    224   1.1  riastrad  */
    225   1.5  riastrad static int drm_getclient(struct drm_device *dev, void *data,
    226   1.1  riastrad 		  struct drm_file *file_priv)
    227   1.1  riastrad {
    228   1.1  riastrad 	struct drm_client *client = data;
    229   1.1  riastrad 
    230   1.3  riastrad 	/*
    231   1.3  riastrad 	 * Hollowed-out getclient ioctl to keep some dead old drm tests/tools
    232   1.3  riastrad 	 * not breaking completely. Userspace tools stop enumerating one they
    233   1.3  riastrad 	 * get -EINVAL, hence this is the return value we need to hand back for
    234   1.3  riastrad 	 * no clients tracked.
    235   1.3  riastrad 	 *
    236   1.3  riastrad 	 * Unfortunately some clients (*cough* libva *cough*) use this in a fun
    237   1.3  riastrad 	 * attempt to figure out whether they're authenticated or not. Since
    238   1.3  riastrad 	 * that's the only thing they care about, give it to the directly
    239   1.3  riastrad 	 * instead of walking one giant list.
    240   1.3  riastrad 	 */
    241   1.3  riastrad 	if (client->idx == 0) {
    242   1.3  riastrad 		client->auth = file_priv->authenticated;
    243   1.2  riastrad #ifdef __NetBSD__		/* XXX Too scary to contemplate.  */
    244   1.4  riastrad 		client->pid = curproc->p_pid;
    245   1.4  riastrad 		client->uid = kauth_cred_geteuid(curproc->p_cred);
    246   1.2  riastrad #else
    247   1.3  riastrad 		client->pid = pid_vnr(file_priv->pid);
    248   1.3  riastrad 		client->uid = from_kuid_munged(current_user_ns(),
    249   1.3  riastrad 					       file_priv->uid);
    250   1.2  riastrad #endif
    251   1.3  riastrad 		client->magic = 0;
    252   1.3  riastrad 		client->iocs = 0;
    253   1.1  riastrad 
    254   1.3  riastrad 		return 0;
    255   1.3  riastrad 	} else {
    256   1.3  riastrad 		return -EINVAL;
    257   1.1  riastrad 	}
    258   1.1  riastrad }
    259   1.1  riastrad 
    260   1.5  riastrad /*
    261   1.1  riastrad  * Get statistics information.
    262   1.1  riastrad  *
    263   1.1  riastrad  * \param inode device inode.
    264   1.1  riastrad  * \param file_priv DRM file private.
    265   1.1  riastrad  * \param cmd command.
    266   1.1  riastrad  * \param arg user argument, pointing to a drm_stats structure.
    267   1.1  riastrad  *
    268   1.1  riastrad  * \return zero on success or a negative number on failure.
    269   1.1  riastrad  */
    270   1.5  riastrad static int drm_getstats(struct drm_device *dev, void *data,
    271   1.1  riastrad 		 struct drm_file *file_priv)
    272   1.1  riastrad {
    273   1.1  riastrad 	struct drm_stats *stats = data;
    274   1.1  riastrad 
    275   1.3  riastrad 	/* Clear stats to prevent userspace from eating its stack garbage. */
    276   1.1  riastrad 	memset(stats, 0, sizeof(*stats));
    277   1.1  riastrad 
    278   1.1  riastrad 	return 0;
    279   1.1  riastrad }
    280   1.1  riastrad 
    281   1.5  riastrad /*
    282   1.1  riastrad  * Get device/driver capabilities
    283   1.1  riastrad  */
    284   1.5  riastrad static int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_priv)
    285   1.1  riastrad {
    286   1.1  riastrad 	struct drm_get_cap *req = data;
    287   1.1  riastrad 
    288   1.1  riastrad 	req->value = 0;
    289   1.1  riastrad 	switch (req->capability) {
    290   1.1  riastrad 	case DRM_CAP_DUMB_BUFFER:
    291   1.1  riastrad 		if (dev->driver->dumb_create)
    292   1.1  riastrad 			req->value = 1;
    293   1.1  riastrad 		break;
    294   1.1  riastrad 	case DRM_CAP_VBLANK_HIGH_CRTC:
    295   1.1  riastrad 		req->value = 1;
    296   1.1  riastrad 		break;
    297   1.1  riastrad 	case DRM_CAP_DUMB_PREFERRED_DEPTH:
    298   1.1  riastrad 		req->value = dev->mode_config.preferred_depth;
    299   1.1  riastrad 		break;
    300   1.1  riastrad 	case DRM_CAP_DUMB_PREFER_SHADOW:
    301   1.1  riastrad 		req->value = dev->mode_config.prefer_shadow;
    302   1.1  riastrad 		break;
    303   1.1  riastrad 	case DRM_CAP_PRIME:
    304   1.1  riastrad 		req->value |= dev->driver->prime_fd_to_handle ? DRM_PRIME_CAP_IMPORT : 0;
    305   1.1  riastrad 		req->value |= dev->driver->prime_handle_to_fd ? DRM_PRIME_CAP_EXPORT : 0;
    306   1.1  riastrad 		break;
    307   1.1  riastrad 	case DRM_CAP_TIMESTAMP_MONOTONIC:
    308   1.1  riastrad 		req->value = drm_timestamp_monotonic;
    309   1.1  riastrad 		break;
    310   1.3  riastrad 	case DRM_CAP_ASYNC_PAGE_FLIP:
    311   1.3  riastrad 		req->value = dev->mode_config.async_page_flip;
    312   1.3  riastrad 		break;
    313   1.3  riastrad 	case DRM_CAP_CURSOR_WIDTH:
    314   1.3  riastrad 		if (dev->mode_config.cursor_width)
    315   1.3  riastrad 			req->value = dev->mode_config.cursor_width;
    316   1.3  riastrad 		else
    317   1.3  riastrad 			req->value = 64;
    318   1.3  riastrad 		break;
    319   1.3  riastrad 	case DRM_CAP_CURSOR_HEIGHT:
    320   1.3  riastrad 		if (dev->mode_config.cursor_height)
    321   1.3  riastrad 			req->value = dev->mode_config.cursor_height;
    322   1.3  riastrad 		else
    323   1.3  riastrad 			req->value = 64;
    324   1.3  riastrad 		break;
    325   1.5  riastrad 	case DRM_CAP_ADDFB2_MODIFIERS:
    326   1.5  riastrad 		req->value = dev->mode_config.allow_fb_modifiers;
    327   1.5  riastrad 		break;
    328   1.3  riastrad 	default:
    329   1.3  riastrad 		return -EINVAL;
    330   1.3  riastrad 	}
    331   1.3  riastrad 	return 0;
    332   1.3  riastrad }
    333   1.3  riastrad 
    334   1.5  riastrad /*
    335   1.3  riastrad  * Set device/driver capabilities
    336   1.3  riastrad  */
    337   1.5  riastrad static int
    338   1.3  riastrad drm_setclientcap(struct drm_device *dev, void *data, struct drm_file *file_priv)
    339   1.3  riastrad {
    340   1.3  riastrad 	struct drm_set_client_cap *req = data;
    341   1.3  riastrad 
    342   1.3  riastrad 	switch (req->capability) {
    343   1.3  riastrad 	case DRM_CLIENT_CAP_STEREO_3D:
    344   1.3  riastrad 		if (req->value > 1)
    345   1.3  riastrad 			return -EINVAL;
    346   1.3  riastrad 		file_priv->stereo_allowed = req->value;
    347   1.3  riastrad 		break;
    348   1.3  riastrad 	case DRM_CLIENT_CAP_UNIVERSAL_PLANES:
    349   1.5  riastrad 		if (req->value > 1)
    350   1.5  riastrad 			return -EINVAL;
    351   1.5  riastrad 		file_priv->universal_planes = req->value;
    352   1.5  riastrad 		break;
    353   1.5  riastrad 	case DRM_CLIENT_CAP_ATOMIC:
    354   1.5  riastrad 		if (!drm_core_check_feature(dev, DRIVER_ATOMIC))
    355   1.3  riastrad 			return -EINVAL;
    356   1.3  riastrad 		if (req->value > 1)
    357   1.3  riastrad 			return -EINVAL;
    358   1.5  riastrad 		file_priv->atomic = req->value;
    359   1.3  riastrad 		file_priv->universal_planes = req->value;
    360   1.3  riastrad 		break;
    361   1.1  riastrad 	default:
    362   1.1  riastrad 		return -EINVAL;
    363   1.1  riastrad 	}
    364   1.3  riastrad 
    365   1.1  riastrad 	return 0;
    366   1.1  riastrad }
    367   1.1  riastrad 
    368   1.5  riastrad /*
    369   1.1  riastrad  * Setversion ioctl.
    370   1.1  riastrad  *
    371   1.1  riastrad  * \param inode device inode.
    372   1.1  riastrad  * \param file_priv DRM file private.
    373   1.1  riastrad  * \param cmd command.
    374   1.1  riastrad  * \param arg user argument, pointing to a drm_lock structure.
    375   1.1  riastrad  * \return zero on success or negative number on failure.
    376   1.1  riastrad  *
    377   1.1  riastrad  * Sets the requested interface version
    378   1.1  riastrad  */
    379   1.5  riastrad static int drm_setversion(struct drm_device *dev, void *data, struct drm_file *file_priv)
    380   1.1  riastrad {
    381   1.1  riastrad 	struct drm_set_version *sv = data;
    382   1.1  riastrad 	int if_version, retcode = 0;
    383   1.1  riastrad 
    384   1.1  riastrad 	if (sv->drm_di_major != -1) {
    385   1.1  riastrad 		if (sv->drm_di_major != DRM_IF_MAJOR ||
    386   1.1  riastrad 		    sv->drm_di_minor < 0 || sv->drm_di_minor > DRM_IF_MINOR) {
    387   1.1  riastrad 			retcode = -EINVAL;
    388   1.1  riastrad 			goto done;
    389   1.1  riastrad 		}
    390   1.1  riastrad 		if_version = DRM_IF_VERSION(sv->drm_di_major,
    391   1.1  riastrad 					    sv->drm_di_minor);
    392   1.1  riastrad 		dev->if_version = max(if_version, dev->if_version);
    393   1.1  riastrad 		if (sv->drm_di_minor >= 1) {
    394   1.1  riastrad 			/*
    395   1.1  riastrad 			 * Version 1.1 includes tying of DRM to specific device
    396   1.1  riastrad 			 * Version 1.4 has proper PCI domain support
    397   1.1  riastrad 			 */
    398   1.1  riastrad 			retcode = drm_set_busid(dev, file_priv);
    399   1.1  riastrad 			if (retcode)
    400   1.1  riastrad 				goto done;
    401   1.1  riastrad 		}
    402   1.1  riastrad 	}
    403   1.1  riastrad 
    404   1.1  riastrad 	if (sv->drm_dd_major != -1) {
    405   1.1  riastrad 		if (sv->drm_dd_major != dev->driver->major ||
    406   1.1  riastrad 		    sv->drm_dd_minor < 0 || sv->drm_dd_minor >
    407   1.1  riastrad 		    dev->driver->minor) {
    408   1.1  riastrad 			retcode = -EINVAL;
    409   1.1  riastrad 			goto done;
    410   1.1  riastrad 		}
    411   1.1  riastrad 	}
    412   1.1  riastrad 
    413   1.1  riastrad done:
    414   1.1  riastrad 	sv->drm_di_major = DRM_IF_MAJOR;
    415   1.1  riastrad 	sv->drm_di_minor = DRM_IF_MINOR;
    416   1.1  riastrad 	sv->drm_dd_major = dev->driver->major;
    417   1.1  riastrad 	sv->drm_dd_minor = dev->driver->minor;
    418   1.1  riastrad 
    419   1.1  riastrad 	return retcode;
    420   1.1  riastrad }
    421   1.1  riastrad 
    422   1.5  riastrad /**
    423   1.5  riastrad  * drm_noop - DRM no-op ioctl implemntation
    424   1.5  riastrad  * @dev: DRM device for the ioctl
    425   1.5  riastrad  * @data: data pointer for the ioctl
    426   1.5  riastrad  * @file_priv: DRM file for the ioctl call
    427   1.5  riastrad  *
    428   1.5  riastrad  * This no-op implementation for drm ioctls is useful for deprecated
    429   1.5  riastrad  * functionality where we can't return a failure code because existing userspace
    430   1.5  riastrad  * checks the result of the ioctl, but doesn't care about the action.
    431   1.5  riastrad  *
    432   1.5  riastrad  * Always returns successfully with 0.
    433   1.5  riastrad  */
    434   1.1  riastrad int drm_noop(struct drm_device *dev, void *data,
    435   1.1  riastrad 	     struct drm_file *file_priv)
    436   1.1  riastrad {
    437   1.1  riastrad 	DRM_DEBUG("\n");
    438   1.1  riastrad 	return 0;
    439   1.1  riastrad }
    440   1.1  riastrad EXPORT_SYMBOL(drm_noop);
    441   1.5  riastrad 
    442   1.5  riastrad /**
    443   1.5  riastrad  * drm_invalid_op - DRM invalid ioctl implemntation
    444   1.5  riastrad  * @dev: DRM device for the ioctl
    445   1.5  riastrad  * @data: data pointer for the ioctl
    446   1.5  riastrad  * @file_priv: DRM file for the ioctl call
    447   1.5  riastrad  *
    448   1.5  riastrad  * This no-op implementation for drm ioctls is useful for deprecated
    449   1.5  riastrad  * functionality where we really don't want to allow userspace to call the ioctl
    450   1.5  riastrad  * any more. This is the case for old ums interfaces for drivers that
    451   1.5  riastrad  * transitioned to kms gradually and so kept the old legacy tables around. This
    452   1.5  riastrad  * only applies to radeon and i915 kms drivers, other drivers shouldn't need to
    453   1.5  riastrad  * use this function.
    454   1.5  riastrad  *
    455   1.5  riastrad  * Always fails with a return value of -EINVAL.
    456   1.5  riastrad  */
    457   1.5  riastrad int drm_invalid_op(struct drm_device *dev, void *data,
    458   1.5  riastrad 		   struct drm_file *file_priv)
    459   1.5  riastrad {
    460   1.5  riastrad 	return -EINVAL;
    461   1.5  riastrad }
    462   1.5  riastrad EXPORT_SYMBOL(drm_invalid_op);
    463   1.5  riastrad 
    464   1.5  riastrad /*
    465   1.5  riastrad  * Copy and IOCTL return string to user space
    466   1.5  riastrad  */
    467   1.5  riastrad static int drm_copy_field(char __user *buf, size_t *buf_len, const char *value)
    468   1.5  riastrad {
    469   1.5  riastrad 	int len;
    470   1.5  riastrad 
    471   1.5  riastrad 	/* don't overflow userbuf */
    472   1.5  riastrad 	len = strlen(value);
    473   1.5  riastrad 	if (len > *buf_len)
    474   1.5  riastrad 		len = *buf_len;
    475   1.5  riastrad 
    476   1.5  riastrad 	/* let userspace know exact length of driver value (which could be
    477   1.5  riastrad 	 * larger than the userspace-supplied buffer) */
    478   1.5  riastrad 	*buf_len = strlen(value);
    479   1.5  riastrad 
    480   1.5  riastrad 	/* finally, try filling in the userbuf */
    481   1.5  riastrad 	if (len && buf)
    482   1.5  riastrad 		if (copy_to_user(buf, value, len))
    483   1.5  riastrad 			return -EFAULT;
    484   1.5  riastrad 	return 0;
    485   1.5  riastrad }
    486   1.5  riastrad 
    487   1.5  riastrad /*
    488   1.5  riastrad  * Get version information
    489   1.5  riastrad  *
    490   1.5  riastrad  * \param inode device inode.
    491   1.5  riastrad  * \param filp file pointer.
    492   1.5  riastrad  * \param cmd command.
    493   1.5  riastrad  * \param arg user argument, pointing to a drm_version structure.
    494   1.5  riastrad  * \return zero on success or negative number on failure.
    495   1.5  riastrad  *
    496   1.5  riastrad  * Fills in the version information in \p arg.
    497   1.5  riastrad  */
    498   1.5  riastrad static int drm_version(struct drm_device *dev, void *data,
    499   1.5  riastrad 		       struct drm_file *file_priv)
    500   1.5  riastrad {
    501   1.5  riastrad 	struct drm_version *version = data;
    502   1.5  riastrad 	int err;
    503   1.5  riastrad 
    504   1.5  riastrad 	version->version_major = dev->driver->major;
    505   1.5  riastrad 	version->version_minor = dev->driver->minor;
    506   1.5  riastrad 	version->version_patchlevel = dev->driver->patchlevel;
    507   1.5  riastrad 	err = drm_copy_field(version->name, &version->name_len,
    508   1.5  riastrad 			dev->driver->name);
    509   1.5  riastrad 	if (!err)
    510   1.5  riastrad 		err = drm_copy_field(version->date, &version->date_len,
    511   1.5  riastrad 				dev->driver->date);
    512   1.5  riastrad 	if (!err)
    513   1.5  riastrad 		err = drm_copy_field(version->desc, &version->desc_len,
    514   1.5  riastrad 				dev->driver->desc);
    515   1.5  riastrad 
    516   1.5  riastrad 	return err;
    517   1.5  riastrad }
    518   1.5  riastrad 
    519   1.5  riastrad /*
    520   1.5  riastrad  * drm_ioctl_permit - Check ioctl permissions against caller
    521   1.5  riastrad  *
    522   1.5  riastrad  * @flags: ioctl permission flags.
    523   1.5  riastrad  * @file_priv: Pointer to struct drm_file identifying the caller.
    524   1.5  riastrad  *
    525   1.5  riastrad  * Checks whether the caller is allowed to run an ioctl with the
    526   1.5  riastrad  * indicated permissions. If so, returns zero. Otherwise returns an
    527   1.5  riastrad  * error code suitable for ioctl return.
    528   1.5  riastrad  */
    529   1.5  riastrad int drm_ioctl_permit(u32 flags, struct drm_file *file_priv)
    530   1.5  riastrad {
    531   1.5  riastrad 	/* ROOT_ONLY is only for CAP_SYS_ADMIN */
    532   1.6  riastrad #ifdef __NetBSD__
    533   1.6  riastrad 	if (unlikely((flags & DRM_ROOT_ONLY) && !DRM_SUSER()))
    534   1.6  riastrad #else
    535   1.5  riastrad 	if (unlikely((flags & DRM_ROOT_ONLY) && !capable(CAP_SYS_ADMIN)))
    536   1.6  riastrad #endif
    537   1.5  riastrad 		return -EACCES;
    538   1.5  riastrad 
    539   1.5  riastrad 	/* AUTH is only for authenticated or render client */
    540   1.5  riastrad 	if (unlikely((flags & DRM_AUTH) && !drm_is_render_client(file_priv) &&
    541   1.5  riastrad 		     !file_priv->authenticated))
    542   1.5  riastrad 		return -EACCES;
    543   1.5  riastrad 
    544   1.5  riastrad 	/* MASTER is only for master or control clients */
    545   1.5  riastrad 	if (unlikely((flags & DRM_MASTER) && !file_priv->is_master &&
    546   1.5  riastrad 		     !drm_is_control_client(file_priv)))
    547   1.5  riastrad 		return -EACCES;
    548   1.5  riastrad 
    549   1.5  riastrad 	/* Control clients must be explicitly allowed */
    550   1.5  riastrad 	if (unlikely(!(flags & DRM_CONTROL_ALLOW) &&
    551   1.5  riastrad 		     drm_is_control_client(file_priv)))
    552   1.5  riastrad 		return -EACCES;
    553   1.5  riastrad 
    554   1.5  riastrad 	/* Render clients must be explicitly allowed */
    555   1.5  riastrad 	if (unlikely(!(flags & DRM_RENDER_ALLOW) &&
    556   1.5  riastrad 		     drm_is_render_client(file_priv)))
    557   1.5  riastrad 		return -EACCES;
    558   1.5  riastrad 
    559   1.5  riastrad 	return 0;
    560   1.5  riastrad }
    561   1.5  riastrad EXPORT_SYMBOL(drm_ioctl_permit);
    562   1.5  riastrad 
    563   1.5  riastrad #define DRM_IOCTL_DEF(ioctl, _func, _flags)	\
    564   1.5  riastrad 	[DRM_IOCTL_NR(ioctl)] = {		\
    565   1.5  riastrad 		.cmd = ioctl,			\
    566   1.5  riastrad 		.func = _func,			\
    567   1.5  riastrad 		.flags = _flags,		\
    568   1.5  riastrad 		.name = #ioctl			\
    569   1.5  riastrad 	}
    570   1.5  riastrad 
    571   1.5  riastrad /* Ioctl table */
    572   1.5  riastrad static const struct drm_ioctl_desc drm_ioctls[] = {
    573   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version,
    574   1.5  riastrad 		      DRM_UNLOCKED|DRM_RENDER_ALLOW|DRM_CONTROL_ALLOW),
    575   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0),
    576   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0),
    577   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY),
    578   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, DRM_UNLOCKED),
    579   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, DRM_UNLOCKED),
    580   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, DRM_UNLOCKED),
    581   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_GET_CAP, drm_getcap, DRM_UNLOCKED|DRM_RENDER_ALLOW),
    582   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_SET_CLIENT_CAP, drm_setclientcap, 0),
    583   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER),
    584   1.5  riastrad 
    585   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
    586   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
    587   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_UNBLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
    588   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_AUTH|DRM_MASTER),
    589   1.5  riastrad 
    590   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_legacy_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
    591   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_legacy_rmmap_ioctl, DRM_AUTH),
    592   1.5  riastrad 
    593   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX, drm_legacy_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
    594   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX, drm_legacy_getsareactx, DRM_AUTH),
    595   1.5  riastrad 
    596   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_SET_MASTER, drm_setmaster_ioctl, DRM_ROOT_ONLY),
    597   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_DROP_MASTER, drm_dropmaster_ioctl, DRM_ROOT_ONLY),
    598   1.5  riastrad 
    599   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_ADD_CTX, drm_legacy_addctx, DRM_AUTH|DRM_ROOT_ONLY),
    600   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_RM_CTX, drm_legacy_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
    601   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MOD_CTX, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
    602   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_GET_CTX, drm_legacy_getctx, DRM_AUTH),
    603   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_SWITCH_CTX, drm_legacy_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
    604   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_NEW_CTX, drm_legacy_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
    605   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_RES_CTX, drm_legacy_resctx, DRM_AUTH),
    606   1.5  riastrad 
    607   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_ADD_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
    608   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_RM_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
    609   1.5  riastrad 
    610   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_LOCK, drm_legacy_lock, DRM_AUTH),
    611   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_UNLOCK, drm_legacy_unlock, DRM_AUTH),
    612   1.5  riastrad 
    613   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_FINISH, drm_noop, DRM_AUTH),
    614   1.5  riastrad 
    615   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_ADD_BUFS, drm_legacy_addbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
    616   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MARK_BUFS, drm_legacy_markbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
    617   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_INFO_BUFS, drm_legacy_infobufs, DRM_AUTH),
    618   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MAP_BUFS, drm_legacy_mapbufs, DRM_AUTH),
    619   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_FREE_BUFS, drm_legacy_freebufs, DRM_AUTH),
    620   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_DMA, drm_legacy_dma_ioctl, DRM_AUTH),
    621   1.5  riastrad 
    622   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_CONTROL, drm_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
    623   1.5  riastrad 
    624   1.5  riastrad #if IS_ENABLED(CONFIG_AGP)
    625   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_AGP_ACQUIRE, drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
    626   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_AGP_RELEASE, drm_agp_release_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
    627   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_AGP_ENABLE, drm_agp_enable_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
    628   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_AGP_INFO, drm_agp_info_ioctl, DRM_AUTH),
    629   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_AGP_ALLOC, drm_agp_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
    630   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_AGP_FREE, drm_agp_free_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
    631   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_AGP_BIND, drm_agp_bind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
    632   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_AGP_UNBIND, drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
    633   1.5  riastrad #endif
    634   1.5  riastrad 
    635   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_legacy_sg_alloc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
    636   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_legacy_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
    637   1.5  riastrad 
    638   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, DRM_UNLOCKED),
    639   1.5  riastrad 
    640   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0),
    641   1.5  riastrad 
    642   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
    643   1.5  riastrad 
    644   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
    645   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED),
    646   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED),
    647   1.5  riastrad 
    648   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
    649   1.5  riastrad 
    650   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, drm_prime_handle_to_fd_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
    651   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, drm_prime_fd_to_handle_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
    652   1.5  riastrad 
    653   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
    654   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
    655   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
    656   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANE, drm_mode_getplane, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
    657   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPLANE, drm_mode_setplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
    658   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
    659   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_UNLOCKED),
    660   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER|DRM_UNLOCKED),
    661   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
    662   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
    663   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_noop, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
    664   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_noop, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
    665   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
    666   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
    667   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
    668   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
    669   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
    670   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
    671   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
    672   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
    673   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
    674   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
    675   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_MAP_DUMB, drm_mode_mmap_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
    676   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
    677   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_GETPROPERTIES, drm_mode_obj_get_properties_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
    678   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_SETPROPERTY, drm_mode_obj_set_property_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
    679   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR2, drm_mode_cursor2_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
    680   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATOMIC, drm_mode_atomic_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
    681   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATEPROPBLOB, drm_mode_createblob_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
    682   1.5  riastrad 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROYPROPBLOB, drm_mode_destroyblob_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
    683   1.5  riastrad };
    684   1.5  riastrad 
    685   1.5  riastrad #define DRM_CORE_IOCTL_COUNT	ARRAY_SIZE( drm_ioctls )
    686   1.5  riastrad 
    687   1.5  riastrad /**
    688   1.5  riastrad  * drm_ioctl - ioctl callback implementation for DRM drivers
    689   1.5  riastrad  * @filp: file this ioctl is called on
    690   1.5  riastrad  * @cmd: ioctl cmd number
    691   1.5  riastrad  * @arg: user argument
    692   1.5  riastrad  *
    693   1.5  riastrad  * Looks up the ioctl function in the ::ioctls table, checking for root
    694   1.5  riastrad  * previleges if so required, and dispatches to the respective function.
    695   1.5  riastrad  *
    696   1.5  riastrad  * Returns:
    697   1.5  riastrad  * Zero on success, negative error code on failure.
    698   1.5  riastrad  */
    699   1.6  riastrad #ifdef __NetBSD__
    700   1.6  riastrad #include <sys/file.h>
    701   1.6  riastrad int
    702   1.6  riastrad drm_ioctl(struct file *fp, unsigned long cmd, void *data)
    703   1.6  riastrad {
    704   1.8  riastrad 	char stackbuf[128];
    705   1.8  riastrad 	char *buf = stackbuf;
    706  1.11      maya 	void *data0 = data;
    707   1.6  riastrad 	struct drm_file *const file = fp->f_data;
    708   1.6  riastrad 	const unsigned int nr = DRM_IOCTL_NR(cmd);
    709   1.6  riastrad 	int error;
    710   1.6  riastrad 
    711   1.6  riastrad 	switch (cmd) {
    712   1.6  riastrad 	case FIONBIO:
    713   1.6  riastrad 	case FIOASYNC:
    714   1.6  riastrad 		return 0;
    715   1.6  riastrad 	default:
    716   1.6  riastrad 		break;
    717   1.6  riastrad 	}
    718   1.6  riastrad 
    719   1.6  riastrad 	if (IOCGROUP(cmd) != DRM_IOCTL_BASE)
    720   1.6  riastrad 		return EINVAL;
    721   1.6  riastrad 
    722   1.6  riastrad 	KASSERT(file != NULL);
    723   1.6  riastrad 	KASSERT(file->minor != NULL);
    724   1.6  riastrad 	KASSERT(file->minor->dev != NULL);
    725   1.6  riastrad 	struct drm_device *const dev = file->minor->dev;
    726   1.6  riastrad 	const struct drm_ioctl_desc *ioctl;
    727   1.6  riastrad 
    728   1.6  riastrad 	if (drm_device_is_unplugged(dev))
    729   1.6  riastrad 		return ENXIO;
    730   1.6  riastrad 
    731   1.6  riastrad 	const bool is_driver_ioctl =
    732   1.6  riastrad 	    (DRM_COMMAND_BASE <= nr) && (nr < DRM_COMMAND_END);
    733   1.6  riastrad 
    734   1.6  riastrad 	if (is_driver_ioctl) {
    735   1.6  riastrad 		const unsigned int driver_nr = nr - DRM_COMMAND_BASE;
    736   1.6  riastrad 		if (driver_nr >= dev->driver->num_ioctls)
    737   1.6  riastrad 			return EINVAL;
    738   1.6  riastrad 		ioctl = &dev->driver->ioctls[driver_nr];
    739   1.6  riastrad 	} else if (nr < __arraycount(drm_ioctls)) {
    740   1.6  riastrad 		ioctl = &drm_ioctls[nr];
    741   1.6  riastrad 	} else {
    742   1.6  riastrad 		ioctl = NULL;
    743   1.6  riastrad 	}
    744   1.6  riastrad 
    745   1.6  riastrad 	if ((ioctl == NULL) || (ioctl->func == NULL))
    746   1.6  riastrad 		return EINVAL;
    747   1.6  riastrad 
    748   1.6  riastrad 	/* XXX errno Linux->NetBSD */
    749   1.6  riastrad 	error = -drm_ioctl_permit(ioctl->flags, file);
    750   1.6  riastrad 	if (error)
    751   1.6  riastrad 		return error;
    752   1.6  riastrad 
    753   1.8  riastrad 	/* If userland passed in too few bytes, zero-pad them.  */
    754   1.8  riastrad 	if (IOCPARM_LEN(cmd) < IOCPARM_LEN(ioctl->cmd)) {
    755   1.8  riastrad 		/* 12-bit quantity, according to <sys/ioccom.h> */
    756   1.8  riastrad 		KASSERT(IOCPARM_LEN(ioctl->cmd) <= 4096);
    757   1.8  riastrad 		if (IOCPARM_LEN(ioctl->cmd) > sizeof stackbuf) {
    758   1.8  riastrad 			buf = kmem_alloc(IOCPARM_LEN(ioctl->cmd), KM_NOSLEEP);
    759   1.8  riastrad 			if (buf == NULL)
    760   1.8  riastrad 				return ENOMEM;
    761   1.8  riastrad 		}
    762   1.8  riastrad 		memcpy(buf, data, IOCPARM_LEN(cmd));
    763   1.8  riastrad 		memset(buf + IOCPARM_LEN(cmd), 0,
    764   1.8  riastrad 		    IOCPARM_LEN(ioctl->cmd) - IOCPARM_LEN(cmd));
    765  1.11      maya 		data0 = buf;
    766   1.8  riastrad 	}
    767   1.8  riastrad 
    768   1.6  riastrad 	if ((drm_core_check_feature(dev, DRIVER_MODESET) && is_driver_ioctl) ||
    769   1.6  riastrad 	    ISSET(ioctl->flags, DRM_UNLOCKED)) {
    770   1.6  riastrad 		/* XXX errno Linux->NetBSD */
    771  1.11      maya 		error = -(*ioctl->func)(dev, data0, file);
    772   1.6  riastrad 	} else {
    773   1.6  riastrad 		mutex_lock(&drm_global_mutex);
    774   1.6  riastrad 		/* XXX errno Linux->NetBSD */
    775  1.11      maya 		error = -(*ioctl->func)(dev, data0, file);
    776   1.6  riastrad 		mutex_unlock(&drm_global_mutex);
    777   1.6  riastrad 	}
    778   1.6  riastrad 
    779  1.11      maya 	/* If we used a temporary buffer, copy it back out.  */
    780  1.11      maya 	if (data != data0)
    781  1.11      maya 		memcpy(data, data0, IOCPARM_LEN(cmd));
    782  1.11      maya 
    783   1.8  riastrad 	/* If we had to allocate a heap buffer, free it.  */
    784   1.8  riastrad 	if (buf != stackbuf)
    785   1.8  riastrad 		kmem_free(buf, IOCPARM_LEN(ioctl->cmd));
    786   1.8  riastrad 
    787   1.6  riastrad 	return error;
    788   1.6  riastrad }
    789   1.6  riastrad #else
    790   1.5  riastrad long drm_ioctl(struct file *filp,
    791   1.5  riastrad 	      unsigned int cmd, unsigned long arg)
    792   1.5  riastrad {
    793   1.5  riastrad 	struct drm_file *file_priv = filp->private_data;
    794   1.5  riastrad 	struct drm_device *dev;
    795   1.5  riastrad 	const struct drm_ioctl_desc *ioctl = NULL;
    796   1.5  riastrad 	drm_ioctl_t *func;
    797   1.5  riastrad 	unsigned int nr = DRM_IOCTL_NR(cmd);
    798   1.5  riastrad 	int retcode = -EINVAL;
    799   1.5  riastrad 	char stack_kdata[128];
    800   1.5  riastrad 	char *kdata = NULL;
    801   1.5  riastrad 	unsigned int usize, asize, drv_size;
    802   1.5  riastrad 	bool is_driver_ioctl;
    803   1.5  riastrad 
    804   1.5  riastrad 	dev = file_priv->minor->dev;
    805   1.5  riastrad 
    806   1.5  riastrad 	if (drm_device_is_unplugged(dev))
    807   1.5  riastrad 		return -ENODEV;
    808   1.5  riastrad 
    809   1.5  riastrad 	is_driver_ioctl = nr >= DRM_COMMAND_BASE && nr < DRM_COMMAND_END;
    810   1.5  riastrad 
    811   1.5  riastrad 	if (is_driver_ioctl) {
    812   1.5  riastrad 		/* driver ioctl */
    813   1.5  riastrad 		if (nr - DRM_COMMAND_BASE >= dev->driver->num_ioctls)
    814   1.5  riastrad 			goto err_i1;
    815   1.5  riastrad 		ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE];
    816   1.5  riastrad 	} else {
    817   1.5  riastrad 		/* core ioctl */
    818   1.5  riastrad 		if (nr >= DRM_CORE_IOCTL_COUNT)
    819   1.5  riastrad 			goto err_i1;
    820   1.5  riastrad 		ioctl = &drm_ioctls[nr];
    821   1.5  riastrad 	}
    822   1.5  riastrad 
    823   1.5  riastrad 	drv_size = _IOC_SIZE(ioctl->cmd);
    824   1.5  riastrad 	usize = _IOC_SIZE(cmd);
    825   1.5  riastrad 	asize = max(usize, drv_size);
    826   1.5  riastrad 	cmd = ioctl->cmd;
    827   1.5  riastrad 
    828   1.5  riastrad 	DRM_DEBUG("pid=%d, dev=0x%lx, auth=%d, %s\n",
    829   1.5  riastrad 		  task_pid_nr(current),
    830   1.5  riastrad 		  (long)old_encode_dev(file_priv->minor->kdev->devt),
    831   1.5  riastrad 		  file_priv->authenticated, ioctl->name);
    832   1.5  riastrad 
    833   1.5  riastrad 	/* Do not trust userspace, use our own definition */
    834   1.5  riastrad 	func = ioctl->func;
    835   1.5  riastrad 
    836   1.5  riastrad 	if (unlikely(!func)) {
    837   1.5  riastrad 		DRM_DEBUG("no function\n");
    838   1.5  riastrad 		retcode = -EINVAL;
    839   1.5  riastrad 		goto err_i1;
    840   1.5  riastrad 	}
    841   1.5  riastrad 
    842   1.5  riastrad 	retcode = drm_ioctl_permit(ioctl->flags, file_priv);
    843   1.5  riastrad 	if (unlikely(retcode))
    844   1.5  riastrad 		goto err_i1;
    845   1.5  riastrad 
    846   1.5  riastrad 	if (cmd & (IOC_IN | IOC_OUT)) {
    847   1.5  riastrad 		if (asize <= sizeof(stack_kdata)) {
    848   1.5  riastrad 			kdata = stack_kdata;
    849   1.5  riastrad 		} else {
    850   1.5  riastrad 			kdata = kmalloc(asize, GFP_KERNEL);
    851   1.5  riastrad 			if (!kdata) {
    852   1.5  riastrad 				retcode = -ENOMEM;
    853   1.5  riastrad 				goto err_i1;
    854   1.5  riastrad 			}
    855   1.5  riastrad 		}
    856   1.5  riastrad 		if (asize > usize)
    857   1.5  riastrad 			memset(kdata + usize, 0, asize - usize);
    858   1.5  riastrad 	}
    859   1.5  riastrad 
    860   1.5  riastrad 	if (cmd & IOC_IN) {
    861   1.5  riastrad 		if (copy_from_user(kdata, (void __user *)arg,
    862   1.5  riastrad 				   usize) != 0) {
    863   1.5  riastrad 			retcode = -EFAULT;
    864   1.5  riastrad 			goto err_i1;
    865   1.5  riastrad 		}
    866   1.5  riastrad 	} else if (cmd & IOC_OUT) {
    867   1.5  riastrad 		memset(kdata, 0, usize);
    868   1.5  riastrad 	}
    869   1.5  riastrad 
    870   1.5  riastrad 	/* Enforce sane locking for kms driver ioctls. Core ioctls are
    871   1.5  riastrad 	 * too messy still. */
    872   1.5  riastrad 	if ((drm_core_check_feature(dev, DRIVER_MODESET) && is_driver_ioctl) ||
    873   1.5  riastrad 	    (ioctl->flags & DRM_UNLOCKED))
    874   1.5  riastrad 		retcode = func(dev, kdata, file_priv);
    875   1.5  riastrad 	else {
    876   1.5  riastrad 		mutex_lock(&drm_global_mutex);
    877   1.5  riastrad 		retcode = func(dev, kdata, file_priv);
    878   1.5  riastrad 		mutex_unlock(&drm_global_mutex);
    879   1.5  riastrad 	}
    880   1.5  riastrad 
    881   1.5  riastrad 	if (cmd & IOC_OUT) {
    882   1.5  riastrad 		if (copy_to_user((void __user *)arg, kdata,
    883   1.5  riastrad 				 usize) != 0)
    884   1.5  riastrad 			retcode = -EFAULT;
    885   1.5  riastrad 	}
    886   1.5  riastrad 
    887   1.5  riastrad       err_i1:
    888   1.5  riastrad 	if (!ioctl)
    889   1.5  riastrad 		DRM_DEBUG("invalid ioctl: pid=%d, dev=0x%lx, auth=%d, cmd=0x%02x, nr=0x%02x\n",
    890   1.5  riastrad 			  task_pid_nr(current),
    891   1.5  riastrad 			  (long)old_encode_dev(file_priv->minor->kdev->devt),
    892   1.5  riastrad 			  file_priv->authenticated, cmd, nr);
    893   1.5  riastrad 
    894   1.5  riastrad 	if (kdata != stack_kdata)
    895   1.5  riastrad 		kfree(kdata);
    896   1.5  riastrad 	if (retcode)
    897   1.5  riastrad 		DRM_DEBUG("ret = %d\n", retcode);
    898   1.5  riastrad 	return retcode;
    899   1.5  riastrad }
    900   1.6  riastrad #endif
    901   1.5  riastrad EXPORT_SYMBOL(drm_ioctl);
    902   1.5  riastrad 
    903   1.5  riastrad /**
    904   1.5  riastrad  * drm_ioctl_flags - Check for core ioctl and return ioctl permission flags
    905   1.5  riastrad  * @nr: ioctl number
    906   1.5  riastrad  * @flags: where to return the ioctl permission flags
    907   1.5  riastrad  *
    908   1.5  riastrad  * This ioctl is only used by the vmwgfx driver to augment the access checks
    909   1.5  riastrad  * done by the drm core and insofar a pretty decent layering violation. This
    910   1.5  riastrad  * shouldn't be used by any drivers.
    911   1.5  riastrad  *
    912   1.5  riastrad  * Returns:
    913   1.5  riastrad  * True if the @nr corresponds to a DRM core ioctl numer, false otherwise.
    914   1.5  riastrad  */
    915   1.5  riastrad bool drm_ioctl_flags(unsigned int nr, unsigned int *flags)
    916   1.5  riastrad {
    917   1.5  riastrad 	if (nr >= DRM_COMMAND_BASE && nr < DRM_COMMAND_END)
    918   1.5  riastrad 		return false;
    919   1.5  riastrad 
    920   1.5  riastrad 	if (nr >= DRM_CORE_IOCTL_COUNT)
    921   1.5  riastrad 		return false;
    922   1.5  riastrad 
    923   1.5  riastrad 	*flags = drm_ioctls[nr].flags;
    924   1.5  riastrad 	return true;
    925   1.5  riastrad }
    926   1.5  riastrad EXPORT_SYMBOL(drm_ioctl_flags);
    927