diff options
Diffstat (limited to 'drivers/gpu/drm')
32 files changed, 578 insertions, 1116 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 2fe1e0a20c17..4a8fc15467cf 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -1162,16 +1162,12 @@ static void amdgpu_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero return; if (state == VGA_SWITCHEROO_ON) { - unsigned d3_delay = dev->pdev->d3_delay; - pr_info("amdgpu: switched on\n"); /* don't suspend or resume card normally */ dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; amdgpu_device_resume(dev, true, true); - dev->pdev->d3_delay = d3_delay; - dev->switch_power_state = DRM_SWITCH_POWER_ON; drm_kms_helper_poll_enable(dev); } else { diff --git a/drivers/gpu/drm/armada/armada_fb.c b/drivers/gpu/drm/armada/armada_fb.c index 2a7eb6817c36..92e6b08ea64a 100644 --- a/drivers/gpu/drm/armada/armada_fb.c +++ b/drivers/gpu/drm/armada/armada_fb.c @@ -133,7 +133,7 @@ static struct drm_framebuffer *armada_fb_create(struct drm_device *dev, } /* Framebuffer objects must have a valid device address for scanout */ - if (obj->dev_addr == DMA_ERROR_CODE) { + if (!obj->mapped) { ret = -EINVAL; goto err_unref; } diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c index d6c2a5d190eb..a76ca21d063b 100644 --- a/drivers/gpu/drm/armada/armada_gem.c +++ b/drivers/gpu/drm/armada/armada_gem.c @@ -175,6 +175,7 @@ armada_gem_linear_back(struct drm_device *dev, struct armada_gem_object *obj) obj->phys_addr = obj->linear->start; obj->dev_addr = obj->linear->start; + obj->mapped = true; } DRM_DEBUG_DRIVER("obj %p phys %#llx dev %#llx\n", obj, @@ -205,7 +206,6 @@ armada_gem_alloc_private_object(struct drm_device *dev, size_t size) return NULL; drm_gem_private_object_init(dev, &obj->obj, size); - obj->dev_addr = DMA_ERROR_CODE; DRM_DEBUG_DRIVER("alloc private obj %p size %zu\n", obj, size); @@ -229,8 +229,6 @@ static struct armada_gem_object *armada_gem_alloc_object(struct drm_device *dev, return NULL; } - obj->dev_addr = DMA_ERROR_CODE; - mapping = obj->obj.filp->f_mapping; mapping_set_gfp_mask(mapping, GFP_HIGHUSER | __GFP_RECLAIMABLE); @@ -610,5 +608,6 @@ int armada_gem_map_import(struct armada_gem_object *dobj) return -EINVAL; } dobj->dev_addr = sg_dma_address(dobj->sgt->sgl); + dobj->mapped = true; return 0; } diff --git a/drivers/gpu/drm/armada/armada_gem.h b/drivers/gpu/drm/armada/armada_gem.h index b88d2b9853c7..6e524e0676bb 100644 --- a/drivers/gpu/drm/armada/armada_gem.h +++ b/drivers/gpu/drm/armada/armada_gem.h @@ -16,6 +16,7 @@ struct armada_gem_object { void *addr; phys_addr_t phys_addr; resource_size_t dev_addr; + bool mapped; struct drm_mm_node *linear; /* for linear backed */ struct page *page; /* for page backed */ struct sg_table *sgt; /* for imported */ diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c index cf92ebfe6ab7..67469c26bae8 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c @@ -11,6 +11,7 @@ #include <sound/hdmi-codec.h> #include <sound/pcm.h> #include <sound/soc.h> +#include <linux/of_graph.h> #include "adv7511.h" @@ -182,10 +183,31 @@ static void audio_shutdown(struct device *dev, void *data) { } +static int adv7511_hdmi_i2s_get_dai_id(struct snd_soc_component *component, + struct device_node *endpoint) +{ + struct of_endpoint of_ep; + int ret; + + ret = of_graph_parse_endpoint(endpoint, &of_ep); + if (ret < 0) + return ret; + + /* + * HDMI sound should be located as reg = <2> + * Then, it is sound port 0 + */ + if (of_ep.port == 2) + return 0; + + return -EINVAL; +} + static const struct hdmi_codec_ops adv7511_codec_ops = { .hw_params = adv7511_hdmi_hw_params, .audio_shutdown = audio_shutdown, .audio_startup = audio_startup, + .get_dai_id = adv7511_hdmi_i2s_get_dai_id, }; static struct hdmi_codec_pdata codec_data = { diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c index aaf287d2e91d..b2cf59f54c88 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c @@ -82,9 +82,30 @@ static void dw_hdmi_i2s_audio_shutdown(struct device *dev, void *data) hdmi_write(audio, HDMI_AUD_CONF0_SW_RESET, HDMI_AUD_CONF0); } +static int dw_hdmi_i2s_get_dai_id(struct snd_soc_component *component, + struct device_node *endpoint) +{ + struct of_endpoint of_ep; + int ret; + + ret = of_graph_parse_endpoint(endpoint, &of_ep); + if (ret < 0) + return ret; + + /* + * HDMI sound should be located as reg = <2> + * Then, it is sound port 0 + */ + if (of_ep.port == 2) + return 0; + + return -EINVAL; +} + static struct hdmi_codec_ops dw_hdmi_i2s_ops = { .hw_params = dw_hdmi_i2s_hw_params, .audio_shutdown = dw_hdmi_i2s_audio_shutdown, + .get_dai_id = dw_hdmi_i2s_get_dai_id, }; static int snd_dw_hdmi_probe(struct platform_device *pdev) diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c index adb1dd7fde5f..1ee84dd802d4 100644 --- a/drivers/gpu/drm/drm_bufs.c +++ b/drivers/gpu/drm/drm_bufs.c @@ -1258,11 +1258,11 @@ int drm_legacy_addbufs(struct drm_device *dev, void *data, * lock, preventing of allocating more buffers after this call. Information * about each requested buffer is then copied into user space. */ -int drm_legacy_infobufs(struct drm_device *dev, void *data, - struct drm_file *file_priv) +int __drm_legacy_infobufs(struct drm_device *dev, + void *data, int *p, + int (*f)(void *, int, struct drm_buf_entry *)) { struct drm_device_dma *dma = dev->dma; - struct drm_buf_info *request = data; int i; int count; @@ -1290,26 +1290,12 @@ int drm_legacy_infobufs(struct drm_device *dev, void *data, DRM_DEBUG("count = %d\n", count); - if (request->count >= count) { + if (*p >= count) { for (i = 0, count = 0; i < DRM_MAX_ORDER + 1; i++) { - if (dma->bufs[i].buf_count) { - struct drm_buf_desc __user *to = - &request->list[count]; - struct drm_buf_entry *from = &dma->bufs[i]; - if (copy_to_user(&to->count, - &from->buf_count, - sizeof(from->buf_count)) || - copy_to_user(&to->size, - &from->buf_size, - sizeof(from->buf_size)) || - copy_to_user(&to->low_mark, - &from->low_mark, - sizeof(from->low_mark)) || - copy_to_user(&to->high_mark, - &from->high_mark, - sizeof(from->high_mark))) + struct drm_buf_entry *from = &dma->bufs[i]; + if (from->buf_count) { + if (f(data, count, from) < 0) return -EFAULT; - DRM_DEBUG("%d %d %d %d %d\n", i, dma->bufs[i].buf_count, @@ -1320,11 +1306,29 @@ int drm_legacy_infobufs(struct drm_device *dev, void *data, } } } - request->count = count; + *p = count; return 0; } +static int copy_one_buf(void *data, int count, struct drm_buf_entry *from) +{ + struct drm_buf_info *request = data; + struct drm_buf_desc __user *to = &request->list[count]; + struct drm_buf_desc v = {.count = from->buf_count, + .size = from->buf_size, + .low_mark = from->low_mark, + .high_mark = from->high_mark}; + return copy_to_user(to, &v, offsetof(struct drm_buf_desc, flags)); +} + +int drm_legacy_infobufs(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_buf_info *request = data; + return __drm_legacy_infobufs(dev, data, &request->count, copy_one_buf); +} + /** * Specifies a low and high water mark for buffer allocation * @@ -1439,15 +1443,15 @@ int drm_legacy_freebufs(struct drm_device *dev, void *data, * offset equal to 0, which drm_mmap() interpretes as PCI buffers and calls * drm_mmap_dma(). */ -int drm_legacy_mapbufs(struct drm_device *dev, void *data, - struct drm_file *file_priv) +int __drm_legacy_mapbufs(struct drm_device *dev, void *data, int *p, + void __user **v, + int (*f)(void *, int, unsigned long, + struct drm_buf *), + struct drm_file *file_priv) { struct drm_device_dma *dma = dev->dma; int retcode = 0; - const int zero = 0; unsigned long virtual; - unsigned long address; - struct drm_buf_map *request = data; int i; if (!drm_core_check_feature(dev, DRIVER_LEGACY)) @@ -1467,7 +1471,7 @@ int drm_legacy_mapbufs(struct drm_device *dev, void *data, dev->buf_use++; /* Can't allocate more after this call */ spin_unlock(&dev->buf_lock); - if (request->count >= dma->buf_count) { + if (*p >= dma->buf_count) { if ((dev->agp && (dma->flags & _DRM_DMA_USE_AGP)) || (drm_core_check_feature(dev, DRIVER_SG) && (dma->flags & _DRM_DMA_USE_SG))) { @@ -1492,41 +1496,51 @@ int drm_legacy_mapbufs(struct drm_device *dev, void *data, retcode = (signed long)virtual; goto done; } - request->virtual = (void __user *)virtual; + *v = (void __user *)virtual; for (i = 0; i < dma->buf_count; i++) { - if (copy_to_user(&request->list[i].idx, - &dma->buflist[i]->idx, - sizeof(request->list[0].idx))) { - retcode = -EFAULT; - goto done; - } - if (copy_to_user(&request->list[i].total, - &dma->buflist[i]->total, - sizeof(request->list[0].total))) { - retcode = -EFAULT; - goto done; - } - if (copy_to_user(&request->list[i].used, - &zero, sizeof(zero))) { - retcode = -EFAULT; - goto done; - } - address = virtual + dma->buflist[i]->offset; /* *** */ - if (copy_to_user(&request->list[i].address, - &address, sizeof(address))) { + if (f(data, i, virtual, dma->buflist[i]) < 0) { retcode = -EFAULT; goto done; } } } done: - request->count = dma->buf_count; - DRM_DEBUG("%d buffers, retcode = %d\n", request->count, retcode); + *p = dma->buf_count; + DRM_DEBUG("%d buffers, retcode = %d\n", *p, retcode); return retcode; } +static int map_one_buf(void *data, int idx, unsigned long virtual, + struct drm_buf *buf) +{ + struct drm_buf_map *request = data; + unsigned long address = virtual + buf->offset; /* *** */ + + if (copy_to_user(&request->list[idx].idx, &buf->idx, + sizeof(request->list[0].idx))) + return -EFAULT; + if (copy_to_user(&request->list[idx].total, &buf->total, + sizeof(request->list[0].total))) + return -EFAULT; + if (clear_user(&request->list[idx].used, sizeof(int))) + return -EFAULT; + if (copy_to_user(&request->list[idx].address, &address, + sizeof(address))) + return -EFAULT; + return 0; +} + +int drm_legacy_mapbufs(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_buf_map *request = data; + return __drm_legacy_mapbufs(dev, data, &request->count, + &request->virtual, map_one_buf, + file_priv); +} + int drm_legacy_dma_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h index 5cecc974d2f9..5edc24bd10fa 100644 --- a/drivers/gpu/drm/drm_internal.h +++ b/drivers/gpu/drm/drm_internal.h @@ -146,6 +146,10 @@ static inline int drm_debugfs_crtc_crc_add(struct drm_crtc *crtc) #endif +drm_ioctl_t drm_version; +drm_ioctl_t drm_getunique; +drm_ioctl_t drm_getclient; + /* drm_syncobj.c */ void drm_syncobj_open(struct drm_file *file_private); void drm_syncobj_release(struct drm_file *file_private); diff --git a/drivers/gpu/drm/drm_ioc32.c b/drivers/gpu/drm/drm_ioc32.c index ae386783e3ea..0b2d8c4a2fa5 100644 --- a/drivers/gpu/drm/drm_ioc32.c +++ b/drivers/gpu/drm/drm_ioc32.c @@ -32,6 +32,9 @@ #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) @@ -87,39 +90,28 @@ static int compat_drm_version(struct file *file, unsigned int cmd, unsigned long arg) { drm_version32_t v32; - struct drm_version __user *version; + struct drm_version v; int err; if (copy_from_user(&v32, (void __user *)arg, sizeof(v32))) return -EFAULT; - version = compat_alloc_user_space(sizeof(*version)); - if (!version) - return -EFAULT; - if (__put_user(v32.name_len, &version->name_len) - || __put_user((void __user *)(unsigned long)v32.name, - &version->name) - || __put_user(v32.date_len, &version->date_len) - || __put_user((void __user *)(unsigned long)v32.date, - &version->date) - || __put_user(v32.desc_len, &version->desc_len) - || __put_user((void __user *)(unsigned long)v32.desc, - &version->desc)) - return -EFAULT; - - err = drm_ioctl(file, - DRM_IOCTL_VERSION, (unsigned long)version); + 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|DRM_CONTROL_ALLOW); if (err) return err; - if (__get_user(v32.version_major, &version->version_major) - || __get_user(v32.version_minor, &version->version_minor) - || __get_user(v32.version_patchlevel, &version->version_patchlevel) - || __get_user(v32.name_len, &version->name_len) - || __get_user(v32.date_len, &version->date_len) - || __get_user(v32.desc_len, &version->desc_len)) - return -EFAULT; - + v32.version_major = v.version_major; + v32.version_minor = v.version_minor; + v32.version_patchlevel = v.version_patchlevel; if (copy_to_user((void __user *)arg, &v32, sizeof(v32))) return -EFAULT; return 0; @@ -134,26 +126,21 @@ static int compat_drm_getunique(struct file *file, unsigned int cmd, unsigned long arg) { drm_unique32_t uq32; - struct drm_unique __user *u; + struct drm_unique uq; int err; if (copy_from_user(&uq32, (void __user *)arg, sizeof(uq32))) return -EFAULT; + uq = (struct drm_unique){ + .unique_len = uq32.unique_len, + .unique = compat_ptr(uq32.unique), + }; - u = compat_alloc_user_space(sizeof(*u)); - if (!u) - return -EFAULT; - if (__put_user(uq32.unique_len, &u->unique_len) - || __put_user((void __user *)(unsigned long)uq32.unique, - &u->unique)) - return -EFAULT; - - err = drm_ioctl(file, DRM_IOCTL_GET_UNIQUE, (unsigned long)u); + err = drm_ioctl_kernel(file, drm_getunique, &uq, DRM_UNLOCKED); if (err) return err; - if (__get_user(uq32.unique_len, &u->unique_len)) - return -EFAULT; + uq32.unique_len = uq.unique_len; if (copy_to_user((void __user *)arg, &uq32, sizeof(uq32))) return -EFAULT; return 0; @@ -162,21 +149,8 @@ static int compat_drm_getunique(struct file *file, unsigned int cmd, static int compat_drm_setunique(struct file *file, unsigned int cmd, unsigned long arg) { - drm_unique32_t uq32; - struct drm_unique __user *u; - - if (copy_from_user(&uq32, (void __user *)arg, sizeof(uq32))) - return -EFAULT; - - u = compat_alloc_user_space(sizeof(*u)); - if (!u) - return -EFAULT; - if (__put_user(uq32.unique_len, &u->unique_len) - || __put_user((void __user *)(unsigned long)uq32.unique, - &u->unique)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_SET_UNIQUE, (unsigned long)u); + /* it's dead */ + return -EINVAL; } typedef struct drm_map32 { @@ -193,32 +167,23 @@ static int compat_drm_getmap(struct file *file, unsigned int cmd, { drm_map32_t __user *argp = (void __user *)arg; drm_map32_t m32; - struct drm_map __user *map; - int idx, err; - void *handle; - - if (get_user(idx, &argp->offset)) - return -EFAULT; + struct drm_map map; + int err; - map = compat_alloc_user_space(sizeof(*map)); - if (!map) - return -EFAULT; - if (__put_user(idx, &map->offset)) + if (copy_from_user(&m32, argp, sizeof(m32))) return -EFAULT; - err = drm_ioctl(file, DRM_IOCTL_GET_MAP, (unsigned long)map); + map.offset = m32.offset; + err = drm_ioctl_kernel(file, drm_legacy_getmap_ioctl, &map, DRM_UNLOCKED); if (err) return err; - if (__get_user(m32.offset, &map->offset) - || __get_user(m32.size, &map->size) - || __get_user(m32.type, &map->type) - || __get_user(m32.flags, &map->flags) - || __get_user(handle, &map->handle) - || __get_user(m32.mtrr, &map->mtrr)) - return -EFAULT; - - m32.handle = (unsigned long)handle; + m32.offset = map.offset; + m32.size = map.size; + m32.type = map.type; + m32.flags = map.flags; + m32.handle = ptr_to_compat(map.handle); + m32.mtrr = map.mtrr; if (copy_to_user(argp, &m32, sizeof(m32))) return -EFAULT; return 0; @@ -230,35 +195,28 @@ static int compat_drm_addmap(struct file *file, unsigned int cmd, { drm_map32_t __user *argp = (void __user *)arg; drm_map32_t m32; - struct drm_map __user *map; + struct drm_map map; int err; - void *handle; if (copy_from_user(&m32, argp, sizeof(m32))) return -EFAULT; - map = compat_alloc_user_space(sizeof(*map)); - if (!map) - return -EFAULT; - if (__put_user(m32.offset, &map->offset) - || __put_user(m32.size, &map->size) - || __put_user(m32.type, &map->type) - || __put_user(m32.flags, &map->flags)) - return -EFAULT; + map.offset = m32.offset; + map.size = m32.size; + map.type = m32.type; + map.flags = m32.flags; - err = drm_ioctl(file, DRM_IOCTL_ADD_MAP, (unsigned long)map); + err = drm_ioctl_kernel(file, drm_legacy_addmap_ioctl, &map, + DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY); if (err) return err; - if (__get_user(m32.offset, &map->offset) - || __get_user(m32.mtrr, &map->mtrr) - || __get_user(handle, &map->handle)) - return -EFAULT; - - m32.handle = (unsigned long)handle; - if (m32.handle != (unsigned long)handle) + m32.offset = map.offset; + m32.mtrr = map.mtrr; + m32.handle = ptr_to_compat(map.handle); + if (map.handle != compat_ptr(m32.handle)) pr_err_ratelimited("compat_drm_addmap truncated handle %p for type %d offset %x\n", - handle, m32.type, m32.offset); + map.handle, m32.type, m32.offset); if (copy_to_user(argp, &m32, sizeof(m32))) return -EFAULT; @@ -270,19 +228,13 @@ 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 __user *map; + struct drm_map map; u32 handle; if (get_user(handle, &argp->handle)) return -EFAULT; - - map = compat_alloc_user_space(sizeof(*map)); - if (!map) - return -EFAULT; - if (__put_user((void *)(unsigned long)handle, &map->handle)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_RM_MAP, (unsigned long)map); + map.handle = compat_ptr(handle); + return drm_ioctl_kernel(file, drm_legacy_rmmap_ioctl, &map, DRM_AUTH); } typedef struct drm_client32 { @@ -299,29 +251,24 @@ static int compat_drm_getclient(struct file *file, unsigned int cmd, { drm_client32_t c32; drm_client32_t __user *argp = (void __user *)arg; - struct drm_client __user *client; - int idx, err; + struct drm_client client; + int err; - if (get_user(idx, &argp->idx)) + if (copy_from_user(&c32, argp, sizeof(c32))) return -EFAULT; - client = compat_alloc_user_space(sizeof(*client)); - if (!client) - return -EFAULT; - if (__put_user(idx, &client->idx)) - return -EFAULT; + client.idx = c32.idx; - err = drm_ioctl(file, DRM_IOCTL_GET_CLIENT, (unsigned long)client); + err = drm_ioctl_kernel(file, drm_getclient, &client, DRM_UNLOCKED); if (err) return err; - if (__get_user(c32.idx, &client->idx) - || __get_user(c32.auth, &client->auth) - || __get_user(c32.pid, &client->pid) - || __get_user(c32.uid, &client->uid) - || __get_user(c32.magic, &client->magic) - || __get_user(c32.iocs, &client->iocs)) - return -EFAULT; + 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; @@ -339,28 +286,14 @@ typedef struct drm_stats32 { static int compat_drm_getstats(struct file *file, unsigned int cmd, unsigned long arg) { - drm_stats32_t s32; drm_stats32_t __user *argp = (void __user *)arg; - struct drm_stats __user *stats; - int i, err; - - memset(&s32, 0, sizeof(drm_stats32_t)); - stats = compat_alloc_user_space(sizeof(*stats)); - if (!stats) - return -EFAULT; + int err; - err = drm_ioctl(file, DRM_IOCTL_GET_STATS, (unsigned long)stats); + err = drm_ioctl_kernel(file, drm_noop, NULL, DRM_UNLOCKED); if (err) return err; - if (__get_user(s32.count, &stats->count)) - return -EFAULT; - for (i = 0; i < 15; ++i) - if (__get_user(s32.data[i].value, &stats->data[i].value) - || __get_user(s32.data[i].type, &stats->data[i].type)) - return -EFAULT; - - if (copy_to_user(argp, &s32, sizeof(s32))) + if (clear_user(argp, sizeof(drm_stats32_t))) return -EFAULT; return 0; } @@ -378,26 +311,28 @@ static int compat_drm_addbufs(struct file *file, unsigned int cmd, unsigned long arg) { drm_buf_desc32_t __user *argp = (void __user *)arg; - struct drm_buf_desc __user *buf; + drm_buf_desc32_t desc32; + struct drm_buf_desc desc; int err; - unsigned long agp_start; - buf = compat_alloc_user_space(sizeof(*buf)); - if (!buf || !access_ok(VERIFY_WRITE, argp, sizeof(*argp))) + if (copy_from_user(&desc32, argp, sizeof(drm_buf_desc32_t))) return -EFAULT; - if (__copy_in_user(buf, argp, offsetof(drm_buf_desc32_t, agp_start)) - || __get_user(agp_start, &argp->agp_start) - || __put_user(agp_start, &buf->agp_start)) - 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(file, DRM_IOCTL_ADD_BUFS, (unsigned long)buf); + err = drm_ioctl_kernel(file, drm_legacy_addbufs, &desc, + DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY); if (err) return err; - if (__copy_in_user(argp, buf, offsetof(drm_buf_desc32_t, agp_start)) - || __get_user(agp_start, &buf->agp_start) - || __put_user(agp_start, &argp->agp_start)) + 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; @@ -408,21 +343,17 @@ static int compat_drm_markbufs(struct file *file, unsigned int cmd, { drm_buf_desc32_t b32; drm_buf_desc32_t __user *argp = (void __user *)arg; - struct drm_buf_desc __user *buf; + struct drm_buf_desc buf; if (copy_from_user(&b32, argp, sizeof(b32))) return -EFAULT; - buf = compat_alloc_user_space(sizeof(*buf)); - if (!buf) - return -EFAULT; - - if (__put_user(b32.size, &buf->size) - || __put_user(b32.low_mark, &buf->low_mark) - || __put_user(b32.high_mark, &buf->high_mark)) - return -EFAULT; + buf.size = b32.size; + buf.low_mark = b32.low_mark; + buf.high_mark = b32.high_mark; - return drm_ioctl(file, DRM_IOCTL_MARK_BUFS, (unsigned long)buf); + return drm_ioctl_kernel(file, drm_legacy_markbufs, &buf, + DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY); } typedef struct drm_buf_info32 { @@ -430,52 +361,42 @@ typedef struct drm_buf_info32 { 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}; + return copy_to_user(to + count, &v, offsetof(drm_buf_desc32_t, flags)); +} + +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; - drm_buf_desc32_t __user *to; - struct drm_buf_info __user *request; - struct drm_buf_desc __user *list; - size_t nbytes; - int i, err; - int count, actual; + int err; if (copy_from_user(&req32, argp, sizeof(req32))) return -EFAULT; - count = req32.count; - to = (drm_buf_desc32_t __user *) (unsigned long)req32.list; - if (count < 0) - count = 0; - if (count > 0 - && !access_ok(VERIFY_WRITE, to, count * sizeof(drm_buf_desc32_t))) - return -EFAULT; - - nbytes = sizeof(*request) + count * sizeof(struct drm_buf_desc); - request = compat_alloc_user_space(nbytes); - if (!request) - return -EFAULT; - list = (struct drm_buf_desc *) (request + 1); - - if (__put_user(count, &request->count) - || __put_user(list, &request->list)) - return -EFAULT; + if (req32.count < 0) + req32.count = 0; - err = drm_ioctl(file, DRM_IOCTL_INFO_BUFS, (unsigned long)request); + err = drm_ioctl_kernel(file, drm_legacy_infobufs32, &req32, DRM_AUTH); if (err) return err; - if (__get_user(actual, &request->count)) - return -EFAULT; - if (count >= actual) - for (i = 0; i < actual; ++i) - if (__copy_in_user(&to[i], &list[i], - offsetof(struct drm_buf_desc, flags))) - return -EFAULT; - - if (__put_user(actual, &argp->count)) + if (put_user(req32.count, &argp->count)) return -EFAULT; return 0; @@ -494,54 +415,52 @@ typedef struct drm_buf_map32 { 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; - drm_buf_pub32_t __user *list32; - struct drm_buf_map __user *request; - struct drm_buf_pub __user *list; - int i, err; - int count, actual; - size_t nbytes; - void __user *addr; + int err; if (copy_from_user(&req32, argp, sizeof(req32))) return -EFAULT; - count = req32.count; - list32 = (void __user *)(unsigned long)req32.list; - - if (count < 0) + if (req32.count < 0) return -EINVAL; - nbytes = sizeof(*request) + count * sizeof(struct drm_buf_pub); - request = compat_alloc_user_space(nbytes); - if (!request) - return -EFAULT; - list = (struct drm_buf_pub *) (request + 1); - - if (__put_user(count, &request->count) - || __put_user(list, &request->list)) - return -EFAULT; - err = drm_ioctl(file, DRM_IOCTL_MAP_BUFS, (unsigned long)request); + err = drm_ioctl_kernel(file, drm_legacy_mapbufs32, &req32, DRM_AUTH); if (err) return err; - if (__get_user(actual, &request->count)) - return -EFAULT; - if (count >= actual) - for (i = 0; i < actual; ++i) - if (__copy_in_user(&list32[i], &list[i], - offsetof(struct drm_buf_pub, address)) - || __get_user(addr, &list[i].address) - || __put_user((unsigned long)addr, - &list32[i].address)) - return -EFAULT; - - if (__put_user(actual, &argp->count) - || __get_user(addr, &request->virtual) - || __put_user((unsigned long)addr, &argp->virtual)) + if (put_user(req32.count, &argp->count) + || put_user(req32.virtual, &argp->virtual)) return -EFAULT; return 0; @@ -556,21 +475,15 @@ static int compat_drm_freebufs(struct file *file, unsigned int cmd, unsigned long arg) { drm_buf_free32_t req32; - struct drm_buf_free __user *request; + 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 = compat_alloc_user_space(sizeof(*request)); - if (!request) - return -EFAULT; - if (__put_user(req32.count, &request->count) - || __put_user((int __user *)(unsigned long)req32.list, - &request->list)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_FREE_BUFS, (unsigned long)request); + 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 { @@ -582,48 +495,36 @@ 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 __user *request; + 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 = compat_alloc_user_space(sizeof(*request)); - if (!request) - return -EFAULT; - if (__put_user(req32.ctx_id, &request->ctx_id) - || __put_user((void *)(unsigned long)req32.handle, - &request->handle)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_SET_SAREA_CTX, (unsigned long)request); + 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 __user *request; + struct drm_ctx_priv_map req; + drm_ctx_priv_map32_t req32; drm_ctx_priv_map32_t __user *argp = (void __user *)arg; int err; - unsigned int ctx_id; - void *handle; - - if (!access_ok(VERIFY_WRITE, argp, sizeof(*argp)) - || __get_user(ctx_id, &argp->ctx_id)) - return -EFAULT; - request = compat_alloc_user_space(sizeof(*request)); - if (!request) - return -EFAULT; - if (__put_user(ctx_id, &request->ctx_id)) + if (copy_from_user(&req32, argp, sizeof(req32))) return -EFAULT; - err = drm_ioctl(file, DRM_IOCTL_GET_SAREA_CTX, (unsigned long)request); + req.ctx_id = req32.ctx_id; + err = drm_ioctl_kernel(file, drm_legacy_getsareactx, &req, DRM_AUTH); if (err) return err; - if (__get_user(handle, &request->handle) - || __put_user((unsigned long)handle, &argp->handle)) + req32.handle = ptr_to_compat(req.handle); + if (copy_to_user(argp, &req32, sizeof(req32))) return -EFAULT; return 0; @@ -639,26 +540,20 @@ static int compat_drm_resctx(struct file *file, unsigned int cmd, { drm_ctx_res32_t __user *argp = (void __user *)arg; drm_ctx_res32_t res32; - struct drm_ctx_res __user *res; + struct drm_ctx_res res; int err; if (copy_from_user(&res32, argp, sizeof(res32))) return -EFAULT; - res = compat_alloc_user_space(sizeof(*res)); - if (!res) - return -EFAULT; - if (__put_user(res32.count, &res->count) - || __put_user((struct drm_ctx __user *) (unsigned long)res32.contexts, - &res->contexts)) - return -EFAULT; - - err = drm_ioctl(file, DRM_IOCTL_RES_CTX, (unsigned long)res); + 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; - if (__get_user(res32.count, &res->count) - || __put_user(res32.count, &argp->count)) + res32.count = res.count; + if (copy_to_user(argp, &res32, sizeof(res32))) return -EFAULT; return 0; @@ -682,38 +577,26 @@ static int compat_drm_dma(struct file *file, unsigned int cmd, { drm_dma32_t d32; drm_dma32_t __user *argp = (void __user *)arg; - struct drm_dma __user *d; + struct drm_dma d; int err; if (copy_from_user(&d32, argp, sizeof(d32))) return -EFAULT; - d = compat_alloc_user_space(sizeof(*d)); - if (!d) - return -EFAULT; - - if (__put_user(d32.context, &d->context) - || __put_user(d32.send_count, &d->send_count) - || __put_user((int __user *)(unsigned long)d32.send_indices, - &d->send_indices) - || __put_user((int __user *)(unsigned long)d32.send_sizes, - &d->send_sizes) - || __put_user(d32.flags, &d->flags) - || __put_user(d32.request_count, &d->request_count) - || __put_user((int __user *)(unsigned long)d32.request_indices, - &d->request_indices) - || __put_user((int __user *)(unsigned long)d32.request_sizes, - &d->request_sizes)) - return -EFAULT; - - err = drm_ioctl(file, DRM_IOCTL_DMA, (unsigned long)d); + 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 (__get_user(d32.request_size, &d->request_size) - || __get_user(d32.granted_count, &d->granted_count) - || __put_user(d32.request_size, &argp->request_size) - || __put_user(d32.granted_count, &argp->granted_count)) + if (put_user(d.request_size, &argp->request_size) + || put_user(d.granted_count, &argp->granted_count)) return -EFAULT; return 0; @@ -728,17 +611,13 @@ static int compat_drm_agp_enable(struct file *file, unsigned int cmd, unsigned long arg) { drm_agp_mode32_t __user *argp = (void __user *)arg; - drm_agp_mode32_t m32; - struct drm_agp_mode __user *mode; - - if (get_user(m32.mode, &argp->mode)) - return -EFAULT; + struct drm_agp_mode mode; - mode = compat_alloc_user_space(sizeof(*mode)); - if (put_user(m32.mode, &mode->mode)) + if (get_user(mode.mode, &argp->mode)) return -EFAULT; - return drm_ioctl(file, DRM_IOCTL_AGP_ENABLE, (unsigned long)mode); + return drm_ioctl_kernel(file, drm_agp_enable_ioctl, &mode, + DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY); } typedef struct drm_agp_info32 { @@ -760,28 +639,22 @@ static int compat_drm_agp_info(struct file *file, unsigned int cmd, { drm_agp_info32_t __user *argp = (void __user *)arg; drm_agp_info32_t i32; - struct drm_agp_info __user *info; + struct drm_agp_info info; int err; - info = compat_alloc_user_space(sizeof(*info)); - if (!info) - return -EFAULT; - - err = drm_ioctl(file, DRM_IOCTL_AGP_INFO, (unsigned long)info); + err = drm_ioctl_kernel(file, drm_agp_info_ioctl, &info, DRM_AUTH); if (err) return err; - if (__get_user(i32.agp_version_major, &info->agp_version_major) - || __get_user(i32.agp_version_minor, &info->agp_version_minor) - || __get_user(i32.mode, &info->mode) - || __get_user(i32.aperture_base, &info->aperture_base) - || __get_user(i32.aperture_size, &info->aperture_size) - || __get_user(i32.memory_allowed, &info->memory_allowed) - || __get_user(i32.memory_used, &info->memory_used) - || __get_user(i32.id_vendor, &info->id_vendor) - || __get_user(i32.id_device, &info->id_device)) - return -EFAULT; - + 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; @@ -800,26 +673,24 @@ static int compat_drm_agp_alloc(struct file *file, unsigned int cmd, { drm_agp_buffer32_t __user *argp = (void __user *)arg; drm_agp_buffer32_t req32; - struct drm_agp_buffer __user *request; + struct drm_agp_buffer request; int err; if (copy_from_user(&req32, argp, sizeof(req32))) return -EFAULT; - request = compat_alloc_user_space(sizeof(*request)); - if (!request - || __put_user(req32.size, &request->size) - || __put_user(req32.type, &request->type)) - return -EFAULT; - - err = drm_ioctl(file, DRM_IOCTL_AGP_ALLOC, (unsigned long)request); + 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; - if (__get_user(req32.handle, &request->handle) - || __get_user(req32.physical, &request->physical) - || copy_to_user(argp, &req32, sizeof(req32))) { - drm_ioctl(file, DRM_IOCTL_AGP_FREE, (unsigned long)request); + 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; } @@ -830,16 +701,13 @@ 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 __user *request; - u32 handle; + struct drm_agp_buffer request; - request = compat_alloc_user_space(sizeof(*request)); - if (!request - || get_user(handle, &argp->handle) - || __put_user(handle, &request->handle)) + if (get_user(request.handle, &argp->handle)) return -EFAULT; - return drm_ioctl(file, DRM_IOCTL_AGP_FREE, (unsigned long)request); + return drm_ioctl_kernel(file, drm_agp_free_ioctl, &request, + DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY); } typedef struct drm_agp_binding32 { @@ -852,34 +720,28 @@ static int compat_drm_agp_bind(struct file *file, unsigned int cmd, { drm_agp_binding32_t __user *argp = (void __user *)arg; drm_agp_binding32_t req32; - struct drm_agp_binding __user *request; + struct drm_agp_binding request; if (copy_from_user(&req32, argp, sizeof(req32))) return -EFAULT; - request = compat_alloc_user_space(sizeof(*request)); - if (!request - || __put_user(req32.handle, &request->handle) - || __put_user(req32.offset, &request->offset)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_AGP_BIND, (unsigned long)request); + 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 __user *request; - u32 handle; + struct drm_agp_binding request; - request = compat_alloc_user_space(sizeof(*request)); - if (!request - || get_user(handle, &argp->handle) - || __put_user(handle, &request->handle)) + if (get_user(request.handle, &argp->handle)) return -EFAULT; - return drm_ioctl(file, DRM_IOCTL_AGP_UNBIND, (unsigned long)request); + return drm_ioctl_kernel(file, drm_agp_unbind_ioctl, &request, + DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY); } #endif /* CONFIG_AGP */ @@ -892,23 +754,19 @@ 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 __user *request; + struct drm_scatter_gather request; int err; - unsigned long x; - request = compat_alloc_user_space(sizeof(*request)); - if (!request || !access_ok(VERIFY_WRITE, argp, sizeof(*argp)) - || __get_user(x, &argp->size) - || __put_user(x, &request->size)) + if (get_user(request.size, &argp->size)) return -EFAULT; - err = drm_ioctl(file, DRM_IOCTL_SG_ALLOC, (unsigned long)request); + 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 (__get_user(x, &request->handle) - || __put_user(x >> PAGE_SHIFT, &argp->handle)) + if (put_user(request.handle >> PAGE_SHIFT, &argp->handle)) return -EFAULT; return 0; @@ -918,19 +776,17 @@ 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 __user *request; + struct drm_scatter_gather request; unsigned long x; - request = compat_alloc_user_space(sizeof(*request)); - if (!request || !access_ok(VERIFY_WRITE, argp, sizeof(*argp)) - || __get_user(x, &argp->handle) - || __put_user(x << PAGE_SHIFT, &request->handle)) + if (get_user(x, &argp->handle)) return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_SG_FREE, (unsigned long)request); + 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) || defined(CONFIG_IA64) +#if defined(CONFIG_X86) typedef struct drm_update_draw32 { drm_drawable_t handle; unsigned int type; @@ -943,22 +799,11 @@ static int compat_drm_update_draw(struct file *file, unsigned int cmd, unsigned long arg) { drm_update_draw32_t update32; - struct drm_update_draw __user *request; - int err; - if (copy_from_user(&update32, (void __user *)arg, sizeof(update32))) return -EFAULT; - request = compat_alloc_user_space(sizeof(*request)); - if (!request || - __put_user(update32.handle, &request->handle) || - __put_user(update32.type, &request->type) || - __put_user(update32.num, &request->num) || - __put_user(update32.data, &request->data)) - return -EFAULT; - - err = drm_ioctl(file, DRM_IOCTL_UPDATE_DRAW, (unsigned long)request); - return err; + return drm_ioctl_kernel(file, drm_noop, NULL, + DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY); } #endif @@ -985,36 +830,30 @@ static int compat_drm_wait_vblank(struct file *file, unsigned int cmd, { drm_wait_vblank32_t __user *argp = (void __user *)arg; drm_wait_vblank32_t req32; - union drm_wait_vblank __user *request; + union drm_wait_vblank req; int err; if (copy_from_user(&req32, argp, sizeof(req32))) return -EFAULT; - request = compat_alloc_user_space(sizeof(*request)); - if (!request - || __put_user(req32.request.type, &request->request.type) - || __put_user(req32.request.sequence, &request->request.sequence) - || __put_user(req32.request.signal, &request->request.signal)) - return -EFAULT; - - err = drm_ioctl(file, DRM_IOCTL_WAIT_VBLANK, (unsigned long)request); + 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, &req, DRM_UNLOCKED); if (err) return err; - if (__get_user(req32.reply.type, &request->reply.type) - || __get_user(req32.reply.sequence, &request->reply.sequence) - || __get_user(req32.reply.tval_sec, &request->reply.tval_sec) - || __get_user(req32.reply.tval_usec, &request->reply.tval_usec)) - return -EFAULT; - + 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 0; } -#if defined(CONFIG_X86) || defined(CONFIG_IA64) +#if defined(CONFIG_X86) typedef struct drm_mode_fb_cmd232 { u32 fb_id; u32 width; @@ -1031,82 +870,67 @@ 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_cmd232 req32; - struct drm_mode_fb_cmd2 __user *req64; - int i; + struct drm_mode_fb_cmd2 req64; int err; - if (copy_from_user(&req32, argp, sizeof(req32))) + if (copy_from_user(&req64, argp, + offsetof(drm_mode_fb_cmd232_t, modifier))) return -EFAULT; - req64 = compat_alloc_user_space(sizeof(*req64)); - - if (!access_ok(VERIFY_WRITE, req64, sizeof(*req64)) - || __put_user(req32.width, &req64->width) - || __put_user(req32.height, &req64->height) - || __put_user(req32.pixel_format, &req64->pixel_format) - || __put_user(req32.flags, &req64->flags)) + if (copy_from_user(&req64.modifier, &argp->modifier, + sizeof(req64.modifier))) return -EFAULT; - for (i = 0; i < 4; i++) { - if (__put_user(req32.handles[i], &req64->handles[i])) - return -EFAULT; - if (__put_user(req32.pitches[i], &req64->pitches[i])) - return -EFAULT; - if (__put_user(req32.offsets[i], &req64->offsets[i])) - return -EFAULT; - if (__put_user(req32.modifier[i], &req64->modifier[i])) - return -EFAULT; - } - - err = drm_ioctl(file, DRM_IOCTL_MODE_ADDFB2, (unsigned long)req64); + err = drm_ioctl_kernel(file, drm_mode_addfb2, &req64, + DRM_CONTROL_ALLOW|DRM_UNLOCKED); if (err) return err; - if (__get_user(req32.fb_id, &req64->fb_id)) - return -EFAULT; - - if (copy_to_user(argp, &req32, sizeof(req32))) + if (put_user(req64.fb_id, &argp->fb_id)) return -EFAULT; return 0; } #endif -static drm_ioctl_compat_t *drm_compat_ioctls[] = { - [DRM_IOCTL_NR(DRM_IOCTL_VERSION32)] = compat_drm_version, - [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE32)] = compat_drm_getunique, - [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP32)] = compat_drm_getmap, - [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT32)] = compat_drm_getclient, - [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS32)] = compat_drm_getstats, - [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE32)] = compat_drm_setunique, - [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP32)] = compat_drm_addmap, - [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS32)] = compat_drm_addbufs, - [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS32)] = compat_drm_markbufs, - [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS32)] = compat_drm_infobufs, - [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS32)] = compat_drm_mapbufs, - [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS32)] = compat_drm_freebufs, - [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP32)] = compat_drm_rmmap, - [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX32)] = compat_drm_setsareactx, - [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX32)] = compat_drm_getsareactx, - [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX32)] = compat_drm_resctx, - [DRM_IOCTL_NR(DRM_IOCTL_DMA32)] = compat_drm_dma, +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_IOCTL_NR(DRM_IOCTL_AGP_ENABLE32)] = compat_drm_agp_enable, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO32)] = compat_drm_agp_info, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC32)] = compat_drm_agp_alloc, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE32)] = compat_drm_agp_free, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND32)] = compat_drm_agp_bind, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND32)] = compat_drm_agp_unbind, + 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_IOCTL_NR(DRM_IOCTL_SG_ALLOC32)] = compat_drm_sg_alloc, - [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE32)] = compat_drm_sg_free, + 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_IOCTL_NR(DRM_IOCTL_UPDATE_DRAW32)] = compat_drm_update_draw, + DRM_IOCTL32_DEF(DRM_IOCTL_UPDATE_DRAW, compat_drm_update_draw), #endif - [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK32)] = compat_drm_wait_vblank, + DRM_IOCTL32_DEF(DRM_IOCTL_WAIT_VBLANK, compat_drm_wait_vblank), #if defined(CONFIG_X86) || defined(CONFIG_IA64) - [DRM_IOCTL_NR(DRM_IOCTL_MODE_ADDFB232)] = compat_drm_mode_addfb2, + DRM_IOCTL32_DEF(DRM_IOCTL_MODE_ADDFB2, compat_drm_mode_addfb2), #endif }; @@ -1127,6 +951,7 @@ static drm_ioctl_compat_t *drm_compat_ioctls[] = { 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; @@ -1137,13 +962,18 @@ long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (nr >= ARRAY_SIZE(drm_compat_ioctls)) return drm_ioctl(filp, cmd, arg); - fn = drm_compat_ioctls[nr]; - - if (fn != NULL) - ret = (*fn) (filp, cmd, arg); - else - ret = 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); diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index f1e568176da9..f1eb326524cf 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -107,7 +107,7 @@ * * Copies the bus id from drm_device::unique into user space. */ -static int drm_getunique(struct drm_device *dev, void *data, +int drm_getunique(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_unique *u = data; @@ -172,7 +172,7 @@ static int drm_set_busid(struct drm_device *dev, struct drm_file *file_priv) * Searches for the client with the specified index and copies its information * into userspace */ -static int drm_getclient(struct drm_device *dev, void *data, +int drm_getclient(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_client *client = data; @@ -464,7 +464,7 @@ static int drm_copy_field(char __user *buf, size_t *buf_len, const char *value) * * Fills in the version information in \p arg. */ -static int drm_version(struct drm_device *dev, void *data, +int drm_version(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_version *version = data; @@ -706,6 +706,33 @@ static const struct drm_ioctl_desc drm_ioctls[] = { * structure. */ +long drm_ioctl_kernel(struct file *file, drm_ioctl_t *func, void *kdata, + u32 flags) +{ + struct drm_file *file_priv = file->private_data; + struct drm_device *dev = file_priv->minor->dev; + int retcode; + + if (drm_device_is_unplugged(dev)) + return -ENODEV; + + retcode = drm_ioctl_permit(flags, file_priv); + if (unlikely(retcode)) + return retcode; + + /* Enforce sane locking for modern driver ioctls. */ + if (!drm_core_check_feature(dev, DRIVER_LEGACY) || + (flags & DRM_UNLOCKED)) + retcode = func(dev, kdata, file_priv); + else { + mutex_lock(&drm_global_mutex); + retcode = func(dev, kdata, file_priv); + mutex_unlock(&drm_global_mutex); + } + return retcode; +} +EXPORT_SYMBOL(drm_ioctl_kernel); + /** * drm_ioctl - ioctl callback implementation for DRM drivers * @filp: file this ioctl is called on @@ -774,10 +801,6 @@ long drm_ioctl(struct file *filp, goto err_i1; } - retcode = drm_ioctl_permit(ioctl->flags, file_priv); - if (unlikely(retcode)) - goto err_i1; - if (ksize <= sizeof(stack_kdata)) { kdata = stack_kdata; } else { @@ -796,16 +819,7 @@ long drm_ioctl(struct file *filp, if (ksize > in_size) memset(kdata + in_size, 0, ksize - in_size); - /* Enforce sane locking for modern driver ioctls. */ - if (!drm_core_check_feature(dev, DRIVER_LEGACY) || - (ioctl->flags & DRM_UNLOCKED)) - retcode = func(dev, kdata, file_priv); - else { - mutex_lock(&drm_global_mutex); - retcode = func(dev, kdata, file_priv); - mutex_unlock(&drm_global_mutex); - } - + retcode = drm_ioctl_kernel(filp, func, kdata, ioctl->flags); if (copy_to_user((void __user *)arg, kdata, out_size) != 0) retcode = -EFAULT; diff --git a/drivers/gpu/drm/drm_legacy.h b/drivers/gpu/drm/drm_legacy.h index e4bb5ad747c8..280fbeb846ff 100644 --- a/drivers/gpu/drm/drm_legacy.h +++ b/drivers/gpu/drm/drm_legacy.h @@ -74,6 +74,13 @@ int drm_legacy_freebufs(struct drm_device *d, void *v, struct drm_file *f); int drm_legacy_mapbufs(struct drm_device *d, void *v, struct drm_file *f); int drm_legacy_dma_ioctl(struct drm_device *d, void *v, struct drm_file *f); +int __drm_legacy_infobufs(struct drm_device *, void *, int *, + int (*)(void *, int, struct drm_buf_entry *)); +int __drm_legacy_mapbufs(struct drm_device *, void *, int *, + void __user **, + int (*)(void *, int, unsigned long, struct drm_buf *), + struct drm_file *); + #ifdef CONFIG_DRM_VM void drm_legacy_vma_flush(struct drm_device *d); #else diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.h b/drivers/gpu/drm/etnaviv/etnaviv_gem.h index c4a091e87426..e437fba1209d 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.h @@ -106,9 +106,10 @@ struct etnaviv_gem_submit { struct etnaviv_gpu *gpu; struct ww_acquire_ctx ticket; struct dma_fence *fence; + u32 flags; unsigned int nr_bos; struct etnaviv_gem_submit_bo bos[0]; - u32 flags; + /* No new members here, the previous one is variable-length! */ }; int etnaviv_gem_wait_bo(struct etnaviv_gpu *gpu, struct drm_gem_object *obj, diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c index ee7069e93eda..5bd93169dac2 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c @@ -172,7 +172,7 @@ static int submit_fence_sync(const struct etnaviv_gem_submit *submit) for (i = 0; i < submit->nr_bos; i++) { struct etnaviv_gem_object *etnaviv_obj = submit->bos[i].obj; bool write = submit->bos[i].flags & ETNA_SUBMIT_BO_WRITE; - bool explicit = !(submit->flags & ETNA_SUBMIT_NO_IMPLICIT); + bool explicit = !!(submit->flags & ETNA_SUBMIT_NO_IMPLICIT); ret = etnaviv_gpu_fence_sync_obj(etnaviv_obj, context, write, explicit); diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c index c77a5aced81a..d48fd7c918f8 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fb.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c @@ -181,8 +181,8 @@ dma_addr_t exynos_drm_fb_dma_addr(struct drm_framebuffer *fb, int index) { struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb); - if (index >= MAX_FB_BUFFER) - return DMA_ERROR_CODE; + if (WARN_ON_ONCE(index >= MAX_FB_BUFFER)) + return 0; return exynos_fb->dma_addr[index]; } diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 4577b0af6886..3f44076ec8a0 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -292,6 +292,8 @@ static int per_file_stats(int id, void *ptr, void *data) struct file_stats *stats = data; struct i915_vma *vma; + lockdep_assert_held(&obj->base.dev->struct_mutex); + stats->count++; stats->total += obj->base.size; if (!obj->bind_count) @@ -476,6 +478,8 @@ static int i915_gem_object_info(struct seq_file *m, void *data) struct drm_i915_gem_request *request; struct task_struct *task; + mutex_lock(&dev->struct_mutex); + memset(&stats, 0, sizeof(stats)); stats.file_priv = file->driver_priv; spin_lock(&file->table_lock); @@ -487,7 +491,6 @@ static int i915_gem_object_info(struct seq_file *m, void *data) * still alive (e.g. get_pid(current) => fork() => exit()). * Therefore, we need to protect this ->comm access using RCU. */ - mutex_lock(&dev->struct_mutex); request = list_first_entry_or_null(&file_priv->mm.request_list, struct drm_i915_gem_request, client_link); @@ -497,6 +500,7 @@ static int i915_gem_object_info(struct seq_file *m, void *data) PIDTYPE_PID); print_file_stats(m, task ? task->comm : "<unknown>", stats); rcu_read_unlock(); + mutex_unlock(&dev->struct_mutex); } mutex_unlock(&dev->filelist_mutex); diff --git a/drivers/gpu/drm/i915/i915_gem_request.h b/drivers/gpu/drm/i915/i915_gem_request.h index 7b7c84369d78..7579b9702c22 100644 --- a/drivers/gpu/drm/i915/i915_gem_request.h +++ b/drivers/gpu/drm/i915/i915_gem_request.h @@ -129,7 +129,7 @@ struct drm_i915_gem_request { * It is used by the driver to then queue the request for execution. */ struct i915_sw_fence submit; - wait_queue_t submitq; + wait_queue_entry_t submitq; wait_queue_head_t execute; /* A list of everyone we wait upon, and everyone who waits upon us. diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c b/drivers/gpu/drm/i915/i915_sw_fence.c index 474d23c0c0ce..f29540f922af 100644 --- a/drivers/gpu/drm/i915/i915_sw_fence.c +++ b/drivers/gpu/drm/i915/i915_sw_fence.c @@ -125,7 +125,7 @@ static void __i915_sw_fence_wake_up_all(struct i915_sw_fence *fence, struct list_head *continuation) { wait_queue_head_t *x = &fence->wait; - wait_queue_t *pos, *next; + wait_queue_entry_t *pos, *next; unsigned long flags; debug_fence_deactivate(fence); @@ -133,31 +133,30 @@ static void __i915_sw_fence_wake_up_all(struct i915_sw_fence *fence, /* * To prevent unbounded recursion as we traverse the graph of - * i915_sw_fences, we move the task_list from this, the next ready - * fence, to the tail of the original fence's task_list + * i915_sw_fences, we move the entry list from this, the next ready + * fence, to the tail of the original fence's entry list * (and so added to the list to be woken). */ spin_lock_irqsave_nested(&x->lock, flags, 1 + !!continuation); if (continuation) { - list_for_each_entry_safe(pos, next, &x->task_list, task_list) { + list_for_each_entry_safe(pos, next, &x->head, entry) { if (pos->func == autoremove_wake_function) pos->func(pos, TASK_NORMAL, 0, continuation); else - list_move_tail(&pos->task_list, continuation); + list_move_tail(&pos->entry, continuation); } } else { LIST_HEAD(extra); do { - list_for_each_entry_safe(pos, next, - &x->task_list, task_list) + list_for_each_entry_safe(pos, next, &x->head, entry) pos->func(pos, TASK_NORMAL, 0, &extra); if (list_empty(&extra)) break; - list_splice_tail_init(&extra, &x->task_list); + list_splice_tail_init(&extra, &x->head); } while (1); } spin_unlock_irqrestore(&x->lock, flags); @@ -222,9 +221,9 @@ void i915_sw_fence_commit(struct i915_sw_fence *fence) i915_sw_fence_complete(fence); } -static int i915_sw_fence_wake(wait_queue_t *wq, unsigned mode, int flags, void *key) +static int i915_sw_fence_wake(wait_queue_entry_t *wq, unsigned mode, int flags, void *key) { - list_del(&wq->task_list); + list_del(&wq->entry); __i915_sw_fence_complete(wq->private, key); if (wq->flags & I915_SW_FENCE_FLAG_ALLOC) @@ -235,7 +234,7 @@ static int i915_sw_fence_wake(wait_queue_t *wq, unsigned mode, int flags, void * static bool __i915_sw_fence_check_if_after(struct i915_sw_fence *fence, const struct i915_sw_fence * const signaler) { - wait_queue_t *wq; + wait_queue_entry_t *wq; if (__test_and_set_bit(I915_SW_FENCE_CHECKED_BIT, &fence->flags)) return false; @@ -243,7 +242,7 @@ static bool __i915_sw_fence_check_if_after(struct i915_sw_fence *fence, if (fence == signaler) return true; - list_for_each_entry(wq, &fence->wait.task_list, task_list) { + list_for_each_entry(wq, &fence->wait.head, entry) { if (wq->func != i915_sw_fence_wake) continue; @@ -256,12 +255,12 @@ static bool __i915_sw_fence_check_if_after(struct i915_sw_fence *fence, static void __i915_sw_fence_clear_checked_bit(struct i915_sw_fence *fence) { - wait_queue_t *wq; + wait_queue_entry_t *wq; if (!__test_and_clear_bit(I915_SW_FENCE_CHECKED_BIT, &fence->flags)) return; - list_for_each_entry(wq, &fence->wait.task_list, task_list) { + list_for_each_entry(wq, &fence->wait.head, entry) { if (wq->func != i915_sw_fence_wake) continue; @@ -288,7 +287,7 @@ static bool i915_sw_fence_check_if_after(struct i915_sw_fence *fence, static int __i915_sw_fence_await_sw_fence(struct i915_sw_fence *fence, struct i915_sw_fence *signaler, - wait_queue_t *wq, gfp_t gfp) + wait_queue_entry_t *wq, gfp_t gfp) { unsigned long flags; int pending; @@ -318,7 +317,7 @@ static int __i915_sw_fence_await_sw_fence(struct i915_sw_fence *fence, pending |= I915_SW_FENCE_FLAG_ALLOC; } - INIT_LIST_HEAD(&wq->task_list); + INIT_LIST_HEAD(&wq->entry); wq->flags = pending; wq->func = i915_sw_fence_wake; wq->private = fence; @@ -327,7 +326,7 @@ static int __i915_sw_fence_await_sw_fence(struct i915_sw_fence *fence, spin_lock_irqsave(&signaler->wait.lock, flags); if (likely(!i915_sw_fence_done(signaler))) { - __add_wait_queue_tail(&signaler->wait, wq); + __add_wait_queue_entry_tail(&signaler->wait, wq); pending = 1; } else { i915_sw_fence_wake(wq, 0, 0, NULL); @@ -340,7 +339,7 @@ static int __i915_sw_fence_await_sw_fence(struct i915_sw_fence *fence, int i915_sw_fence_await_sw_fence(struct i915_sw_fence *fence, struct i915_sw_fence *signaler, - wait_queue_t *wq) + wait_queue_entry_t *wq) { return __i915_sw_fence_await_sw_fence(fence, signaler, wq, 0); } diff --git a/drivers/gpu/drm/i915/i915_sw_fence.h b/drivers/gpu/drm/i915/i915_sw_fence.h index 1d3b6051daaf..fe2ef4dadfc6 100644 --- a/drivers/gpu/drm/i915/i915_sw_fence.h +++ b/drivers/gpu/drm/i915/i915_sw_fence.h @@ -65,7 +65,7 @@ void i915_sw_fence_commit(struct i915_sw_fence *fence); int i915_sw_fence_await_sw_fence(struct i915_sw_fence *fence, struct i915_sw_fence *after, - wait_queue_t *wq); + wait_queue_entry_t *wq); int i915_sw_fence_await_sw_fence_gfp(struct i915_sw_fence *fence, struct i915_sw_fence *after, gfp_t gfp); diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 532c709febbd..1cfe137cdc32 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -672,6 +672,11 @@ int i915_vma_unbind(struct i915_vma *vma) break; } + if (!ret) { + ret = i915_gem_active_retire(&vma->last_fence, + &vma->vm->i915->drm.struct_mutex); + } + __i915_vma_unpin(vma); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/intel_acpi.c b/drivers/gpu/drm/i915/intel_acpi.c index eb638a1e69d2..42fb436f6cdc 100644 --- a/drivers/gpu/drm/i915/intel_acpi.c +++ b/drivers/gpu/drm/i915/intel_acpi.c @@ -15,13 +15,9 @@ static struct intel_dsm_priv { acpi_handle dhandle; } intel_dsm_priv; -static const u8 intel_dsm_guid[] = { - 0xd3, 0x73, 0xd8, 0x7e, - 0xd0, 0xc2, - 0x4f, 0x4e, - 0xa8, 0x54, - 0x0f, 0x13, 0x17, 0xb0, 0x1c, 0x2c -}; +static const guid_t intel_dsm_guid = + GUID_INIT(0x7ed873d3, 0xc2d0, 0x4e4f, + 0xa8, 0x54, 0x0f, 0x13, 0x17, 0xb0, 0x1c, 0x2c); static char *intel_dsm_port_name(u8 id) { @@ -80,7 +76,7 @@ static void intel_dsm_platform_mux_info(void) int i; union acpi_object *pkg, *connector_count; - pkg = acpi_evaluate_dsm_typed(intel_dsm_priv.dhandle, intel_dsm_guid, + pkg = acpi_evaluate_dsm_typed(intel_dsm_priv.dhandle, &intel_dsm_guid, INTEL_DSM_REVISION_ID, INTEL_DSM_FN_PLATFORM_MUX_INFO, NULL, ACPI_TYPE_PACKAGE); if (!pkg) { @@ -118,7 +114,7 @@ static bool intel_dsm_pci_probe(struct pci_dev *pdev) if (!dhandle) return false; - if (!acpi_check_dsm(dhandle, intel_dsm_guid, INTEL_DSM_REVISION_ID, + if (!acpi_check_dsm(dhandle, &intel_dsm_guid, INTEL_DSM_REVISION_ID, 1 << INTEL_DSM_FN_PLATFORM_MUX_INFO)) { DRM_DEBUG_KMS("no _DSM method for intel device\n"); return false; diff --git a/drivers/gpu/drm/mga/mga_drv.h b/drivers/gpu/drm/mga/mga_drv.h index 45cf363d25ad..a45bb22275a7 100644 --- a/drivers/gpu/drm/mga/mga_drv.h +++ b/drivers/gpu/drm/mga/mga_drv.h @@ -159,6 +159,8 @@ extern int mga_dma_bootstrap(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int mga_dma_init(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int mga_getparam(struct drm_device *dev, void *data, + struct drm_file *file_priv); extern int mga_dma_flush(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int mga_dma_reset(struct drm_device *dev, void *data, diff --git a/drivers/gpu/drm/mga/mga_ioc32.c b/drivers/gpu/drm/mga/mga_ioc32.c index 729bfd56b55f..245fb2e359cf 100644 --- a/drivers/gpu/drm/mga/mga_ioc32.c +++ b/drivers/gpu/drm/mga/mga_ioc32.c @@ -61,46 +61,25 @@ static int compat_mga_init(struct file *file, unsigned int cmd, unsigned long arg) { drm_mga_init32_t init32; - drm_mga_init_t __user *init; - int err = 0, i; + drm_mga_init_t init; if (copy_from_user(&init32, (void __user *)arg, sizeof(init32))) return -EFAULT; - init = compat_alloc_user_space(sizeof(*init)); - if (!access_ok(VERIFY_WRITE, init, sizeof(*init)) - || __put_user(init32.func, &init->func) - || __put_user(init32.sarea_priv_offset, &init->sarea_priv_offset) - || __put_user(init32.chipset, &init->chipset) - || __put_user(init32.sgram, &init->sgram) - || __put_user(init32.maccess, &init->maccess) - || __put_user(init32.fb_cpp, &init->fb_cpp) - || __put_user(init32.front_offset, &init->front_offset) - || __put_user(init32.front_pitch, &init->front_pitch) - || __put_user(init32.back_offset, &init->back_offset) - || __put_user(init32.back_pitch, &init->back_pitch) - || __put_user(init32.depth_cpp, &init->depth_cpp) - || __put_user(init32.depth_offset, &init->depth_offset) - || __put_user(init32.depth_pitch, &init->depth_pitch) - || __put_user(init32.fb_offset, &init->fb_offset) - || __put_user(init32.mmio_offset, &init->mmio_offset) - || __put_user(init32.status_offset, &init->status_offset) - || __put_user(init32.warp_offset, &init->warp_offset) - || __put_user(init32.primary_offset, &init->primary_offset) - || __put_user(init32.buffers_offset, &init->buffers_offset)) - return -EFAULT; - - for (i = 0; i < MGA_NR_TEX_HEAPS; i++) { - err |= - __put_user(init32.texture_offset[i], - &init->texture_offset[i]); - err |= - __put_user(init32.texture_size[i], &init->texture_size[i]); - } - if (err) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_MGA_INIT, (unsigned long)init); + init.func = init32.func; + init.sarea_priv_offset = init32.sarea_priv_offset; + memcpy(&init.chipset, &init32.chipset, + offsetof(drm_mga_init_t, fb_offset) - + offsetof(drm_mga_init_t, chipset)); + init.fb_offset = init32.fb_offset; + init.mmio_offset = init32.mmio_offset; + init.status_offset = init32.status_offset; + init.warp_offset = init32.warp_offset; + init.primary_offset = init32.primary_offset; + init.buffers_offset = init32.buffers_offset; + + return drm_ioctl_kernel(file, mga_dma_init, &init, + DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY); } typedef struct drm_mga_getparam32 { @@ -112,19 +91,14 @@ static int compat_mga_getparam(struct file *file, unsigned int cmd, unsigned long arg) { drm_mga_getparam32_t getparam32; - drm_mga_getparam_t __user *getparam; + drm_mga_getparam_t getparam; if (copy_from_user(&getparam32, (void __user *)arg, sizeof(getparam32))) return -EFAULT; - getparam = compat_alloc_user_space(sizeof(*getparam)); - if (!access_ok(VERIFY_WRITE, getparam, sizeof(*getparam)) - || __put_user(getparam32.param, &getparam->param) - || __put_user((void __user *)(unsigned long)getparam32.value, - &getparam->value)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_MGA_GETPARAM, (unsigned long)getparam); + getparam.param = getparam32.param; + getparam.value = compat_ptr(getparam32.value); + return drm_ioctl_kernel(file, mga_getparam, &getparam, DRM_AUTH); } typedef struct drm_mga_drm_bootstrap32 { @@ -141,48 +115,33 @@ static int compat_mga_dma_bootstrap(struct file *file, unsigned int cmd, unsigned long arg) { drm_mga_dma_bootstrap32_t dma_bootstrap32; - drm_mga_dma_bootstrap_t __user *dma_bootstrap; + drm_mga_dma_bootstrap_t dma_bootstrap; int err; if (copy_from_user(&dma_bootstrap32, (void __user *)arg, sizeof(dma_bootstrap32))) return -EFAULT; - dma_bootstrap = compat_alloc_user_space(sizeof(*dma_bootstrap)); - if (!access_ok(VERIFY_WRITE, dma_bootstrap, sizeof(*dma_bootstrap)) - || __put_user(dma_bootstrap32.texture_handle, - &dma_bootstrap->texture_handle) - || __put_user(dma_bootstrap32.texture_size, - &dma_bootstrap->texture_size) - || __put_user(dma_bootstrap32.primary_size, - &dma_bootstrap->primary_size) - || __put_user(dma_bootstrap32.secondary_bin_count, - &dma_bootstrap->secondary_bin_count) - || __put_user(dma_bootstrap32.secondary_bin_size, - &dma_bootstrap->secondary_bin_size) - || __put_user(dma_bootstrap32.agp_mode, &dma_bootstrap->agp_mode) - || __put_user(dma_bootstrap32.agp_size, &dma_bootstrap->agp_size)) - return -EFAULT; + dma_bootstrap.texture_handle = dma_bootstrap32.texture_handle; + dma_bootstrap.texture_size = dma_bootstrap32.texture_size; + dma_bootstrap.primary_size = dma_bootstrap32.primary_size; + dma_bootstrap.secondary_bin_count = dma_bootstrap32.secondary_bin_count; + dma_bootstrap.secondary_bin_size = dma_bootstrap32.secondary_bin_size; + dma_bootstrap.agp_mode = dma_bootstrap32.agp_mode; + dma_bootstrap.agp_size = dma_bootstrap32.agp_size; - err = drm_ioctl(file, DRM_IOCTL_MGA_DMA_BOOTSTRAP, - (unsigned long)dma_bootstrap); + err = drm_ioctl_kernel(file, mga_dma_bootstrap, &dma_bootstrap, + DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY); if (err) return err; - if (__get_user(dma_bootstrap32.texture_handle, - &dma_bootstrap->texture_handle) - || __get_user(dma_bootstrap32.texture_size, - &dma_bootstrap->texture_size) - || __get_user(dma_bootstrap32.primary_size, - &dma_bootstrap->primary_size) - || __get_user(dma_bootstrap32.secondary_bin_count, - &dma_bootstrap->secondary_bin_count) - || __get_user(dma_bootstrap32.secondary_bin_size, - &dma_bootstrap->secondary_bin_size) - || __get_user(dma_bootstrap32.agp_mode, &dma_bootstrap->agp_mode) - || __get_user(dma_bootstrap32.agp_size, &dma_bootstrap->agp_size)) - return -EFAULT; - + dma_bootstrap32.texture_handle = dma_bootstrap.texture_handle; + dma_bootstrap32.texture_size = dma_bootstrap.texture_size; + dma_bootstrap32.primary_size = dma_bootstrap.primary_size; + dma_bootstrap32.secondary_bin_count = dma_bootstrap.secondary_bin_count; + dma_bootstrap32.secondary_bin_size = dma_bootstrap.secondary_bin_size; + dma_bootstrap32.agp_mode = dma_bootstrap.agp_mode; + dma_bootstrap32.agp_size = dma_bootstrap.agp_size; if (copy_to_user((void __user *)arg, &dma_bootstrap32, sizeof(dma_bootstrap32))) return -EFAULT; @@ -190,10 +149,14 @@ static int compat_mga_dma_bootstrap(struct file *file, unsigned int cmd, return 0; } -drm_ioctl_compat_t *mga_compat_ioctls[] = { - [DRM_MGA_INIT] = compat_mga_init, - [DRM_MGA_GETPARAM] = compat_mga_getparam, - [DRM_MGA_DMA_BOOTSTRAP] = compat_mga_dma_bootstrap, +static struct { + drm_ioctl_compat_t *fn; + char *name; +} mga_compat_ioctls[] = { +#define DRM_IOCTL32_DEF(n, f)[DRM_##n] = {.fn = f, .name = #n} + DRM_IOCTL32_DEF(MGA_INIT, compat_mga_init), + DRM_IOCTL32_DEF(MGA_GETPARAM, compat_mga_getparam), + DRM_IOCTL32_DEF(MGA_DMA_BOOTSTRAP, compat_mga_dma_bootstrap), }; /** @@ -208,19 +171,27 @@ drm_ioctl_compat_t *mga_compat_ioctls[] = { long mga_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 = NULL; int ret; if (nr < DRM_COMMAND_BASE) return drm_compat_ioctl(filp, cmd, arg); - if (nr < DRM_COMMAND_BASE + ARRAY_SIZE(mga_compat_ioctls)) - fn = mga_compat_ioctls[nr - DRM_COMMAND_BASE]; - - if (fn != NULL) - ret = (*fn) (filp, cmd, arg); - else - ret = drm_ioctl(filp, cmd, arg); - + if (nr >= DRM_COMMAND_BASE + ARRAY_SIZE(mga_compat_ioctls)) + return drm_ioctl(filp, cmd, arg); + + fn = mga_compat_ioctls[nr - DRM_COMMAND_BASE].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, + mga_compat_ioctls[nr - DRM_COMMAND_BASE].name); + ret = (*fn) (filp, cmd, arg); + if (ret) + DRM_DEBUG("ret = %d\n", ret); return ret; } diff --git a/drivers/gpu/drm/mga/mga_state.c b/drivers/gpu/drm/mga/mga_state.c index 792f924496fc..e5f6b735f575 100644 --- a/drivers/gpu/drm/mga/mga_state.c +++ b/drivers/gpu/drm/mga/mga_state.c @@ -1005,7 +1005,7 @@ static int mga_dma_blit(struct drm_device *dev, void *data, struct drm_file *fil return 0; } -static int mga_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv) +int mga_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_getparam_t *param = data; diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index 39468c218027..7459ef9943ec 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c @@ -60,15 +60,13 @@ bool nouveau_is_v1_dsm(void) { } #ifdef CONFIG_VGA_SWITCHEROO -static const char nouveau_dsm_muid[] = { - 0xA0, 0xA0, 0x95, 0x9D, 0x60, 0x00, 0x48, 0x4D, - 0xB3, 0x4D, 0x7E, 0x5F, 0xEA, 0x12, 0x9F, 0xD4, -}; +static const guid_t nouveau_dsm_muid = + GUID_INIT(0x9D95A0A0, 0x0060, 0x4D48, + 0xB3, 0x4D, 0x7E, 0x5F, 0xEA, 0x12, 0x9F, 0xD4); -static const char nouveau_op_dsm_muid[] = { - 0xF8, 0xD8, 0x86, 0xA4, 0xDA, 0x0B, 0x1B, 0x47, - 0xA7, 0x2B, 0x60, 0x42, 0xA6, 0xB5, 0xBE, 0xE0, -}; +static const guid_t nouveau_op_dsm_muid = + GUID_INIT(0xA486D8F8, 0x0BDA, 0x471B, + 0xA7, 0x2B, 0x60, 0x42, 0xA6, 0xB5, 0xBE, 0xE0); static int nouveau_optimus_dsm(acpi_handle handle, int func, int arg, uint32_t *result) { @@ -86,7 +84,7 @@ static int nouveau_optimus_dsm(acpi_handle handle, int func, int arg, uint32_t * args_buff[i] = (arg >> i * 8) & 0xFF; *result = 0; - obj = acpi_evaluate_dsm_typed(handle, nouveau_op_dsm_muid, 0x00000100, + obj = acpi_evaluate_dsm_typed(handle, &nouveau_op_dsm_muid, 0x00000100, func, &argv4, ACPI_TYPE_BUFFER); if (!obj) { acpi_handle_info(handle, "failed to evaluate _DSM\n"); @@ -138,7 +136,7 @@ static int nouveau_dsm(acpi_handle handle, int func, int arg) .integer.value = arg, }; - obj = acpi_evaluate_dsm_typed(handle, nouveau_dsm_muid, 0x00000102, + obj = acpi_evaluate_dsm_typed(handle, &nouveau_dsm_muid, 0x00000102, func, &argv4, ACPI_TYPE_INTEGER); if (!obj) { acpi_handle_info(handle, "failed to evaluate _DSM\n"); @@ -259,7 +257,7 @@ static void nouveau_dsm_pci_probe(struct pci_dev *pdev, acpi_handle *dhandle_out if (!acpi_has_method(dhandle, "_DSM")) return; - supports_mux = acpi_check_dsm(dhandle, nouveau_dsm_muid, 0x00000102, + supports_mux = acpi_check_dsm(dhandle, &nouveau_dsm_muid, 0x00000102, 1 << NOUVEAU_DSM_POWER); optimus_funcs = nouveau_dsm_get_optimus_functions(dhandle); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mxm/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mxm/base.c index e3e2f5e83815..f44682d62f75 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mxm/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mxm/base.c @@ -81,10 +81,9 @@ mxm_shadow_dsm(struct nvkm_mxm *mxm, u8 version) { struct nvkm_subdev *subdev = &mxm->subdev; struct nvkm_device *device = subdev->device; - static char muid[] = { - 0x00, 0xA4, 0x04, 0x40, 0x7D, 0x91, 0xF2, 0x4C, - 0xB8, 0x9C, 0x79, 0xB6, 0x2F, 0xD5, 0x56, 0x65 - }; + static guid_t muid = + GUID_INIT(0x4004A400, 0x917D, 0x4CF2, + 0xB8, 0x9C, 0x79, 0xB6, 0x2F, 0xD5, 0x56, 0x65); u32 mxms_args[] = { 0x00000000 }; union acpi_object argv4 = { .buffer.type = ACPI_TYPE_BUFFER, @@ -105,7 +104,7 @@ mxm_shadow_dsm(struct nvkm_mxm *mxm, u8 version) * unless you pass in exactly the version it supports.. */ rev = (version & 0xf0) << 4 | (version & 0x0f); - obj = acpi_evaluate_dsm(handle, muid, rev, 0x00000010, &argv4); + obj = acpi_evaluate_dsm(handle, &muid, rev, 0x00000010, &argv4); if (!obj) { nvkm_debug(subdev, "DSM MXMS failed\n"); return false; diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index a5d3cd3ecb5f..4acbb944bcd2 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile @@ -105,7 +105,6 @@ radeon-y += \ vce_v2_0.o \ radeon_kfd.o -radeon-$(CONFIG_COMPAT) += radeon_ioc32.o radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o radeon-$(CONFIG_ACPI) += radeon_acpi.o diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 68be1bfa22b9..5008f3d4cccc 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -377,7 +377,7 @@ struct radeon_fence { unsigned ring; bool is_vm_update; - wait_queue_t fence_wake; + wait_queue_entry_t fence_wake; }; int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring); diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 0a6444d72000..997131d58c7f 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -113,7 +113,6 @@ static inline bool radeon_is_atpx_hybrid(void) { return false; } #endif #define RADEON_PX_QUIRK_DISABLE_PX (1 << 0) -#define RADEON_PX_QUIRK_LONG_WAKEUP (1 << 1) struct radeon_px_quirk { u32 chip_vendor; @@ -140,8 +139,6 @@ static struct radeon_px_quirk radeon_px_quirk_list[] = { * https://bugs.freedesktop.org/show_bug.cgi?id=101491 */ { PCI_VENDOR_ID_ATI, 0x6741, 0x1043, 0x2122, RADEON_PX_QUIRK_DISABLE_PX }, - /* macbook pro 8.2 */ - { PCI_VENDOR_ID_ATI, 0x6741, PCI_VENDOR_ID_APPLE, 0x00e2, RADEON_PX_QUIRK_LONG_WAKEUP }, { 0, 0, 0, 0, 0 }, }; @@ -1245,25 +1242,17 @@ static void radeon_check_arguments(struct radeon_device *rdev) static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_state state) { struct drm_device *dev = pci_get_drvdata(pdev); - struct radeon_device *rdev = dev->dev_private; if (radeon_is_px(dev) && state == VGA_SWITCHEROO_OFF) return; if (state == VGA_SWITCHEROO_ON) { - unsigned d3_delay = dev->pdev->d3_delay; - pr_info("radeon: switched on\n"); /* don't suspend or resume card normally */ dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; - if (d3_delay < 20 && (rdev->px_quirk_flags & RADEON_PX_QUIRK_LONG_WAKEUP)) - dev->pdev->d3_delay = 20; - radeon_resume_kms(dev, true, true); - dev->pdev->d3_delay = d3_delay; - dev->switch_power_state = DRM_SWITCH_POWER_ON; drm_kms_helper_poll_enable(dev); } else { diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index b23c771f4216..74abd161237b 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -38,6 +38,7 @@ #include <linux/module.h> #include <linux/pm_runtime.h> #include <linux/vga_switcheroo.h> +#include <linux/compat.h> #include <drm/drm_gem.h> #include <drm/drm_fb_helper.h> @@ -150,8 +151,6 @@ void radeon_gem_prime_unpin(struct drm_gem_object *obj); struct reservation_object *radeon_gem_prime_res_obj(struct drm_gem_object *); void *radeon_gem_prime_vmap(struct drm_gem_object *obj); void radeon_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr); -extern long radeon_kms_compat_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg); /* atpx handler */ #if defined(CONFIG_VGA_SWITCHEROO) @@ -509,6 +508,21 @@ long radeon_drm_ioctl(struct file *filp, return ret; } +#ifdef CONFIG_COMPAT +static long radeon_kms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + unsigned int nr = DRM_IOCTL_NR(cmd); + int ret; + + if (nr < DRM_COMMAND_BASE) + return drm_compat_ioctl(filp, cmd, arg); + + ret = radeon_drm_ioctl(filp, cmd, arg); + + return ret; +} +#endif + static const struct dev_pm_ops radeon_pm_ops = { .suspend = radeon_pmops_suspend, .resume = radeon_pmops_resume, diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index ef09f0a63754..e86f2bd38410 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c @@ -158,7 +158,7 @@ int radeon_fence_emit(struct radeon_device *rdev, * for the fence locking itself, so unlocked variants are used for * fence_signal, and remove_wait_queue. */ -static int radeon_fence_check_signaled(wait_queue_t *wait, unsigned mode, int flags, void *key) +static int radeon_fence_check_signaled(wait_queue_entry_t *wait, unsigned mode, int flags, void *key) { struct radeon_fence *fence; u64 seq; diff --git a/drivers/gpu/drm/radeon/radeon_ioc32.c b/drivers/gpu/drm/radeon/radeon_ioc32.c deleted file mode 100644 index 0b98ea134579..000000000000 --- a/drivers/gpu/drm/radeon/radeon_ioc32.c +++ /dev/null @@ -1,424 +0,0 @@ -/** - * \file radeon_ioc32.c - * - * 32-bit ioctl compatibility routines for the Radeon 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 <drm/drmP.h> -#include <drm/radeon_drm.h> -#include "radeon_drv.h" - -typedef struct drm_radeon_init32 { - int func; - u32 sarea_priv_offset; - int is_pci; - int cp_mode; - int gart_size; - int ring_size; - int usec_timeout; - - unsigned int fb_bpp; - unsigned int front_offset, front_pitch; - unsigned int back_offset, back_pitch; - unsigned int depth_bpp; - unsigned int depth_offset, depth_pitch; - - u32 fb_offset; - u32 mmio_offset; - u32 ring_offset; - u32 ring_rptr_offset; - u32 buffers_offset; - u32 gart_textures_offset; -} drm_radeon_init32_t; - -static int compat_radeon_cp_init(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_radeon_init32_t init32; - drm_radeon_init_t __user *init; - - if (copy_from_user(&init32, (void __user *)arg, sizeof(init32))) - return -EFAULT; - - init = compat_alloc_user_space(sizeof(*init)); - if (!access_ok(VERIFY_WRITE, init, sizeof(*init)) - || __put_user(init32.func, &init->func) - || __put_user(init32.sarea_priv_offset, &init->sarea_priv_offset) - || __put_user(init32.is_pci, &init->is_pci) - || __put_user(init32.cp_mode, &init->cp_mode) - || __put_user(init32.gart_size, &init->gart_size) - || __put_user(init32.ring_size, &init->ring_size) - || __put_user(init32.usec_timeout, &init->usec_timeout) - || __put_user(init32.fb_bpp, &init->fb_bpp) - || __put_user(init32.front_offset, &init->front_offset) - || __put_user(init32.front_pitch, &init->front_pitch) - || __put_user(init32.back_offset, &init->back_offset) - || __put_user(init32.back_pitch, &init->back_pitch) - || __put_user(init32.depth_bpp, &init->depth_bpp) - || __put_user(init32.depth_offset, &init->depth_offset) - || __put_user(init32.depth_pitch, &init->depth_pitch) - || __put_user(init32.fb_offset, &init->fb_offset) - || __put_user(init32.mmio_offset, &init->mmio_offset) - || __put_user(init32.ring_offset, &init->ring_offset) - || __put_user(init32.ring_rptr_offset, &init->ring_rptr_offset) - || __put_user(init32.buffers_offset, &init->buffers_offset) - || __put_user(init32.gart_textures_offset, - &init->gart_textures_offset)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_RADEON_CP_INIT, (unsigned long)init); -} - -typedef struct drm_radeon_clear32 { - unsigned int flags; - unsigned int clear_color; - unsigned int clear_depth; - unsigned int color_mask; - unsigned int depth_mask; /* misnamed field: should be stencil */ - u32 depth_boxes; -} drm_radeon_clear32_t; - -static int compat_radeon_cp_clear(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_radeon_clear32_t clr32; - drm_radeon_clear_t __user *clr; - - if (copy_from_user(&clr32, (void __user *)arg, sizeof(clr32))) - return -EFAULT; - - clr = compat_alloc_user_space(sizeof(*clr)); - if (!access_ok(VERIFY_WRITE, clr, sizeof(*clr)) - || __put_user(clr32.flags, &clr->flags) - || __put_user(clr32.clear_color, &clr->clear_color) - || __put_user(clr32.clear_depth, &clr->clear_depth) - || __put_user(clr32.color_mask, &clr->color_mask) - || __put_user(clr32.depth_mask, &clr->depth_mask) - || __put_user((void __user *)(unsigned long)clr32.depth_boxes, - &clr->depth_boxes)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_RADEON_CLEAR, (unsigned long)clr); -} - -typedef struct drm_radeon_stipple32 { - u32 mask; -} drm_radeon_stipple32_t; - -static int compat_radeon_cp_stipple(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_radeon_stipple32_t __user *argp = (void __user *)arg; - drm_radeon_stipple_t __user *request; - u32 mask; - - if (get_user(mask, &argp->mask)) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user((unsigned int __user *)(unsigned long)mask, - &request->mask)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_RADEON_STIPPLE, (unsigned long)request); -} - -typedef struct drm_radeon_tex_image32 { - unsigned int x, y; /* Blit coordinates */ - unsigned int width, height; - u32 data; -} drm_radeon_tex_image32_t; - -typedef struct drm_radeon_texture32 { - unsigned int offset; - int pitch; - int format; - int width; /* Texture image coordinates */ - int height; - u32 image; -} drm_radeon_texture32_t; - -static int compat_radeon_cp_texture(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_radeon_texture32_t req32; - drm_radeon_texture_t __user *request; - drm_radeon_tex_image32_t img32; - drm_radeon_tex_image_t __user *image; - - if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) - return -EFAULT; - if (req32.image == 0) - return -EINVAL; - if (copy_from_user(&img32, (void __user *)(unsigned long)req32.image, - sizeof(img32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request) + sizeof(*image)); - if (!access_ok(VERIFY_WRITE, request, - sizeof(*request) + sizeof(*image))) - return -EFAULT; - image = (drm_radeon_tex_image_t __user *) (request + 1); - - if (__put_user(req32.offset, &request->offset) - || __put_user(req32.pitch, &request->pitch) - || __put_user(req32.format, &request->format) - || __put_user(req32.width, &request->width) - || __put_user(req32.height, &request->height) - || __put_user(image, &request->image) - || __put_user(img32.x, &image->x) - || __put_user(img32.y, &image->y) - || __put_user(img32.width, &image->width) - || __put_user(img32.height, &image->height) - || __put_user((const void __user *)(unsigned long)img32.data, - &image->data)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_RADEON_TEXTURE, (unsigned long)request); -} - -typedef struct drm_radeon_vertex2_32 { - int idx; /* Index of vertex buffer */ - int discard; /* Client finished with buffer? */ - int nr_states; - u32 state; - int nr_prims; - u32 prim; -} drm_radeon_vertex2_32_t; - -static int compat_radeon_cp_vertex2(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_radeon_vertex2_32_t req32; - drm_radeon_vertex2_t __user *request; - - if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user(req32.idx, &request->idx) - || __put_user(req32.discard, &request->discard) - || __put_user(req32.nr_states, &request->nr_states) - || __put_user((void __user *)(unsigned long)req32.state, - &request->state) - || __put_user(req32.nr_prims, &request->nr_prims) - || __put_user((void __user *)(unsigned long)req32.prim, - &request->prim)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_RADEON_VERTEX2, (unsigned long)request); -} - -typedef struct drm_radeon_cmd_buffer32 { - int bufsz; - u32 buf; - int nbox; - u32 boxes; -} drm_radeon_cmd_buffer32_t; - -static int compat_radeon_cp_cmdbuf(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_radeon_cmd_buffer32_t req32; - drm_radeon_cmd_buffer_t __user *request; - - if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user(req32.bufsz, &request->bufsz) - || __put_user((void __user *)(unsigned long)req32.buf, - &request->buf) - || __put_user(req32.nbox, &request->nbox) - || __put_user((void __user *)(unsigned long)req32.boxes, - &request->boxes)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_RADEON_CMDBUF, (unsigned long)request); -} - -typedef struct drm_radeon_getparam32 { - int param; - u32 value; -} drm_radeon_getparam32_t; - -static int compat_radeon_cp_getparam(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_radeon_getparam32_t req32; - drm_radeon_getparam_t __user *request; - - if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user(req32.param, &request->param) - || __put_user((void __user *)(unsigned long)req32.value, - &request->value)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_RADEON_GETPARAM, (unsigned long)request); -} - -typedef struct drm_radeon_mem_alloc32 { - int region; - int alignment; - int size; - u32 region_offset; /* offset from start of fb or GART */ -} drm_radeon_mem_alloc32_t; - -static int compat_radeon_mem_alloc(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_radeon_mem_alloc32_t req32; - drm_radeon_mem_alloc_t __user *request; - - if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user(req32.region, &request->region) - || __put_user(req32.alignment, &request->alignment) - || __put_user(req32.size, &request->size) - || __put_user((int __user *)(unsigned long)req32.region_offset, - &request->region_offset)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_RADEON_ALLOC, (unsigned long)request); -} - -typedef struct drm_radeon_irq_emit32 { - u32 irq_seq; -} drm_radeon_irq_emit32_t; - -static int compat_radeon_irq_emit(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_radeon_irq_emit32_t req32; - drm_radeon_irq_emit_t __user *request; - - if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user((int __user *)(unsigned long)req32.irq_seq, - &request->irq_seq)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_RADEON_IRQ_EMIT, (unsigned long)request); -} - -/* The two 64-bit arches where alignof(u64)==4 in 32-bit code */ -#if defined (CONFIG_X86_64) || defined(CONFIG_IA64) -typedef struct drm_radeon_setparam32 { - int param; - u64 value; -} __attribute__((packed)) drm_radeon_setparam32_t; - -static int compat_radeon_cp_setparam(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_radeon_setparam32_t req32; - drm_radeon_setparam_t __user *request; - - if (copy_from_user(&req32, (void __user *) arg, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user(req32.param, &request->param) - || __put_user((void __user *)(unsigned long)req32.value, - &request->value)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_RADEON_SETPARAM, (unsigned long) request); -} -#else -#define compat_radeon_cp_setparam NULL -#endif /* X86_64 || IA64 */ - -static drm_ioctl_compat_t *radeon_compat_ioctls[] = { - [DRM_RADEON_CP_INIT] = compat_radeon_cp_init, - [DRM_RADEON_CLEAR] = compat_radeon_cp_clear, - [DRM_RADEON_STIPPLE] = compat_radeon_cp_stipple, - [DRM_RADEON_TEXTURE] = compat_radeon_cp_texture, - [DRM_RADEON_VERTEX2] = compat_radeon_cp_vertex2, - [DRM_RADEON_CMDBUF] = compat_radeon_cp_cmdbuf, - [DRM_RADEON_GETPARAM] = compat_radeon_cp_getparam, - [DRM_RADEON_SETPARAM] = compat_radeon_cp_setparam, - [DRM_RADEON_ALLOC] = compat_radeon_mem_alloc, - [DRM_RADEON_IRQ_EMIT] = compat_radeon_irq_emit, -}; - -/** - * Called whenever a 32-bit process running under a 64-bit kernel - * performs an ioctl on /dev/dri/card<n>. - * - * \param filp file pointer. - * \param cmd command. - * \param arg user argument. - * \return zero on success or negative number on failure. - */ -long radeon_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - unsigned int nr = DRM_IOCTL_NR(cmd); - drm_ioctl_compat_t *fn = NULL; - int ret; - - if (nr < DRM_COMMAND_BASE) - return drm_compat_ioctl(filp, cmd, arg); - - if (nr < DRM_COMMAND_BASE + ARRAY_SIZE(radeon_compat_ioctls)) - fn = radeon_compat_ioctls[nr - DRM_COMMAND_BASE]; - - if (fn != NULL) - ret = (*fn) (filp, cmd, arg); - else - ret = drm_ioctl(filp, cmd, arg); - - return ret; -} - -long radeon_kms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - unsigned int nr = DRM_IOCTL_NR(cmd); - int ret; - - if (nr < DRM_COMMAND_BASE) - return drm_compat_ioctl(filp, cmd, arg); - - ret = radeon_drm_ioctl(filp, cmd, arg); - - return ret; -} diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c index 13db8a2851ed..1f013d45c9e9 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c @@ -321,6 +321,7 @@ void vmw_cmdbuf_res_man_destroy(struct vmw_cmdbuf_res_manager *man) list_for_each_entry_safe(entry, next, &man->list, head) vmw_cmdbuf_res_free(man, entry); + drm_ht_remove(&man->resources); kfree(man); } |