diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2019-06-14 11:31:13 +0200 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2019-06-14 11:44:24 +0200 |
commit | 2454fcea338ad821a39d471bc7db5a58ba41b742 (patch) | |
tree | 16ea14df12e3c653ab5a0ec0eea2af6dfefacb91 /drivers/gpu/drm/virtio | |
parent | Merge tag 'omapdrm-5.3' of git://git.kernel.org/pub/scm/linux/kernel/git/tomb... (diff) | |
parent | drm/amdgpu: Fix connector atomic_check compilation fail (diff) | |
download | linux-2454fcea338ad821a39d471bc7db5a58ba41b742.tar.xz linux-2454fcea338ad821a39d471bc7db5a58ba41b742.zip |
Merge tag 'drm-misc-next-2019-06-14' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for v5.3:
UAPI Changes:
Cross-subsystem Changes:
- Add code to signal all dma-fences when freed with pending signals.
- Annotate reservation object access in CONFIG_DEBUG_MUTEXES
Core Changes:
- Assorted documentation fixes.
- Use irqsave/restore spinlock to add crc entry.
- Move code around to drm_client, for internal modeset clients.
- Make drm_crtc.h and drm_debugfs.h self-contained.
- Remove drm_fb_helper_connector.
- Add bootsplash to todo.
- Fix lock ordering in pan_display_legacy.
- Support pinning buffers to current location in gem-vram.
- Remove the now unused locking functions from gem-vram.
- Remove the now unused kmap-object argument from vram helpers.
- Stop checking return value of debugfs_create.
- Add atomic encoder enable/disable helpers.
- pass drm_atomic_state to atomic connector check.
- Add atomic support for bridge enable/disable.
- Add self refresh helpers to core.
Driver Changes:
- Add extra delay to make MTP SDM845 work.
- Small fixes to virtio, vkms, sii902x, sii9234, ast, mcde, analogix, rockchip.
- Add zpos and ?BGR8888 support to meson.
- More removals of drm_os_linux and drmP headers for amd, radeon, sti, r128, r128, savage, sis.
- Allow synopsis to unwedge the i2c hdmi bus.
- Add orientation quirks for GPD panels.
- Edid cleanups and fixing handling for edid < 1.2.
- Add runtime pm to stm.
- Handle s/r in dw-hdmi.
- Add hooks for power on/off to dsi for stm.
- Remove virtio dirty tracking code, done in drm core.
- Rework BO handling in ast and mgag200.
Tiny conflict in drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c,
needed #include <linux/slab.h> to make it compile.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/0e01de30-9797-853c-732f-4a5bd6e61445@linux.intel.com
Diffstat (limited to 'drivers/gpu/drm/virtio')
-rw-r--r-- | drivers/gpu/drm/virtio/Makefile | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_display.c | 20 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_drv.h | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_fb.c | 150 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_ioctl.c | 18 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_vq.c | 26 |
6 files changed, 36 insertions, 187 deletions
diff --git a/drivers/gpu/drm/virtio/Makefile b/drivers/gpu/drm/virtio/Makefile index 42949a17ff70..458e606a936f 100644 --- a/drivers/gpu/drm/virtio/Makefile +++ b/drivers/gpu/drm/virtio/Makefile @@ -4,7 +4,7 @@ # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. virtio-gpu-y := virtgpu_drv.o virtgpu_kms.o virtgpu_gem.o \ - virtgpu_fb.o virtgpu_display.o virtgpu_vq.o virtgpu_ttm.o \ + virtgpu_display.o virtgpu_vq.o virtgpu_ttm.o \ virtgpu_fence.o virtgpu_object.o virtgpu_debugfs.o virtgpu_plane.o \ virtgpu_ioctl.o virtgpu_prime.o virtgpu_trace_points.o diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c index 86843a4d6102..ba16e8cb7124 100644 --- a/drivers/gpu/drm/virtio/virtgpu_display.c +++ b/drivers/gpu/drm/virtio/virtgpu_display.c @@ -29,6 +29,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_probe_helper.h> +#include <drm/drm_damage_helper.h> #define XRES_MIN 32 #define YRES_MIN 32 @@ -49,23 +50,10 @@ static const struct drm_crtc_funcs virtio_gpu_crtc_funcs = { .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, }; -static int -virtio_gpu_framebuffer_surface_dirty(struct drm_framebuffer *fb, - struct drm_file *file_priv, - unsigned int flags, unsigned int color, - struct drm_clip_rect *clips, - unsigned int num_clips) -{ - struct virtio_gpu_framebuffer *virtio_gpu_fb - = to_virtio_gpu_framebuffer(fb); - - return virtio_gpu_surface_dirty(virtio_gpu_fb, clips, num_clips); -} - static const struct drm_framebuffer_funcs virtio_gpu_fb_funcs = { .create_handle = drm_gem_fb_create_handle, .destroy = drm_gem_fb_destroy, - .dirty = virtio_gpu_framebuffer_surface_dirty, + .dirty = drm_atomic_helper_dirtyfb, }; int @@ -85,10 +73,6 @@ virtio_gpu_framebuffer_init(struct drm_device *dev, vgfb->base.obj[0] = NULL; return ret; } - - spin_lock_init(&vgfb->dirty_lock); - vgfb->x1 = vgfb->y1 = INT_MAX; - vgfb->x2 = vgfb->y2 = 0; return 0; } diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 5faccf92aa15..9e2d3062b01d 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -142,9 +142,6 @@ struct virtio_gpu_output { struct virtio_gpu_framebuffer { struct drm_framebuffer base; - int x1, y1, x2, y2; /* dirty rect */ - spinlock_t dirty_lock; - uint32_t hw_res_handle; struct virtio_gpu_fence *fence; }; #define to_virtio_gpu_framebuffer(x) \ @@ -254,10 +251,6 @@ int virtio_gpu_mode_dumb_mmap(struct drm_file *file_priv, struct drm_device *dev, uint32_t handle, uint64_t *offset_p); -/* virtio_fb */ -int virtio_gpu_surface_dirty(struct virtio_gpu_framebuffer *qfb, - struct drm_clip_rect *clips, - unsigned int num_clips); /* virtio vg */ int virtio_gpu_alloc_vbufs(struct virtio_gpu_device *vgdev); void virtio_gpu_free_vbufs(struct virtio_gpu_device *vgdev); diff --git a/drivers/gpu/drm/virtio/virtgpu_fb.c b/drivers/gpu/drm/virtio/virtgpu_fb.c deleted file mode 100644 index b07584b1c2bf..000000000000 --- a/drivers/gpu/drm/virtio/virtgpu_fb.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (C) 2015 Red Hat, Inc. - * 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 <drm/drmP.h> -#include <drm/drm_fb_helper.h> -#include "virtgpu_drv.h" - -static int virtio_gpu_dirty_update(struct virtio_gpu_framebuffer *fb, - bool store, int x, int y, - int width, int height) -{ - struct drm_device *dev = fb->base.dev; - struct virtio_gpu_device *vgdev = dev->dev_private; - bool store_for_later = false; - int bpp = fb->base.format->cpp[0]; - int x2, y2; - unsigned long flags; - struct virtio_gpu_object *obj = gem_to_virtio_gpu_obj(fb->base.obj[0]); - - if ((width <= 0) || - (x + width > fb->base.width) || - (y + height > fb->base.height)) { - DRM_DEBUG("values out of range %dx%d+%d+%d, fb %dx%d\n", - width, height, x, y, - fb->base.width, fb->base.height); - return -EINVAL; - } - - /* - * Can be called with pretty much any context (console output - * path). If we are in atomic just store the dirty rect info - * to send out the update later. - * - * Can't test inside spin lock. - */ - if (in_atomic() || store) - store_for_later = true; - - x2 = x + width - 1; - y2 = y + height - 1; - - spin_lock_irqsave(&fb->dirty_lock, flags); - - if (fb->y1 < y) - y = fb->y1; - if (fb->y2 > y2) - y2 = fb->y2; - if (fb->x1 < x) - x = fb->x1; - if (fb->x2 > x2) - x2 = fb->x2; - - if (store_for_later) { - fb->x1 = x; - fb->x2 = x2; - fb->y1 = y; - fb->y2 = y2; - spin_unlock_irqrestore(&fb->dirty_lock, flags); - return 0; - } - - fb->x1 = fb->y1 = INT_MAX; - fb->x2 = fb->y2 = 0; - - spin_unlock_irqrestore(&fb->dirty_lock, flags); - - { - uint32_t offset; - uint32_t w = x2 - x + 1; - uint32_t h = y2 - y + 1; - - offset = (y * fb->base.pitches[0]) + x * bpp; - - virtio_gpu_cmd_transfer_to_host_2d(vgdev, obj, - offset, - cpu_to_le32(w), - cpu_to_le32(h), - cpu_to_le32(x), - cpu_to_le32(y), - NULL); - - } - virtio_gpu_cmd_resource_flush(vgdev, obj->hw_res_handle, - x, y, x2 - x + 1, y2 - y + 1); - return 0; -} - -int virtio_gpu_surface_dirty(struct virtio_gpu_framebuffer *vgfb, - struct drm_clip_rect *clips, - unsigned int num_clips) -{ - struct virtio_gpu_device *vgdev = vgfb->base.dev->dev_private; - struct virtio_gpu_object *obj = gem_to_virtio_gpu_obj(vgfb->base.obj[0]); - struct drm_clip_rect norect; - struct drm_clip_rect *clips_ptr; - int left, right, top, bottom; - int i; - int inc = 1; - - if (!num_clips) { - num_clips = 1; - clips = &norect; - norect.x1 = norect.y1 = 0; - norect.x2 = vgfb->base.width; - norect.y2 = vgfb->base.height; - } - left = clips->x1; - right = clips->x2; - top = clips->y1; - bottom = clips->y2; - - /* skip the first clip rect */ - for (i = 1, clips_ptr = clips + inc; - i < num_clips; i++, clips_ptr += inc) { - left = min_t(int, left, (int)clips_ptr->x1); - right = max_t(int, right, (int)clips_ptr->x2); - top = min_t(int, top, (int)clips_ptr->y1); - bottom = max_t(int, bottom, (int)clips_ptr->y2); - } - - if (obj->dumb) - return virtio_gpu_dirty_update(vgfb, false, left, top, - right - left, bottom - top); - - virtio_gpu_cmd_resource_flush(vgdev, obj->hw_res_handle, - left, top, right - left, bottom - top); - return 0; -} diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c index fe0bd6274db6..ac60be9b5c19 100644 --- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c +++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c @@ -168,7 +168,7 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data, goto out_unused_fd; } - user_bo_handles = (void __user *)(uintptr_t)exbuf->bo_handles; + user_bo_handles = u64_to_user_ptr(exbuf->bo_handles); if (copy_from_user(bo_handles, user_bo_handles, exbuf->num_bo_handles * sizeof(uint32_t))) { ret = -EFAULT; @@ -195,8 +195,7 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data, if (ret) goto out_free; - buf = memdup_user((void __user *)(uintptr_t)exbuf->command, - exbuf->size); + buf = memdup_user(u64_to_user_ptr(exbuf->command), exbuf->size); if (IS_ERR(buf)) { ret = PTR_ERR(buf); goto out_unresv; @@ -263,10 +262,9 @@ static int virtio_gpu_getparam_ioctl(struct drm_device *dev, void *data, default: return -EINVAL; } - if (copy_to_user((void __user *)(unsigned long)param->value, - &value, sizeof(int))) { + if (copy_to_user(u64_to_user_ptr(param->value), &value, sizeof(int))) return -EFAULT; - } + return 0; } @@ -526,7 +524,6 @@ static int virtio_gpu_get_caps_ioctl(struct drm_device *dev, list_for_each_entry(cache_ent, &vgdev->cap_cache, head) { if (cache_ent->id == args->cap_set_id && cache_ent->version == args->cap_set_ver) { - ptr = cache_ent->caps_cache; spin_unlock(&vgdev->display_info_lock); goto copy_exit; } @@ -537,15 +534,18 @@ static int virtio_gpu_get_caps_ioctl(struct drm_device *dev, virtio_gpu_cmd_get_capset(vgdev, found_valid, args->cap_set_ver, &cache_ent); +copy_exit: ret = wait_event_timeout(vgdev->resp_wq, atomic_read(&cache_ent->is_valid), 5 * HZ); if (!ret) return -EBUSY; + /* is_valid check must proceed before copy of the cache entry. */ + smp_rmb(); + ptr = cache_ent->caps_cache; -copy_exit: - if (copy_to_user((void __user *)(unsigned long)args->addr, ptr, size)) + if (copy_to_user(u64_to_user_ptr(args->addr), ptr, size)) return -EFAULT; return 0; diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index 2c5eeccb88c0..6c1a90717535 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -593,12 +593,14 @@ static void virtio_gpu_cmd_capset_cb(struct virtio_gpu_device *vgdev, cache_ent->id == le32_to_cpu(cmd->capset_id)) { memcpy(cache_ent->caps_cache, resp->capset_data, cache_ent->size); + /* Copy must occur before is_valid is signalled. */ + smp_wmb(); atomic_set(&cache_ent->is_valid, 1); break; } } spin_unlock(&vgdev->display_info_lock); - wake_up(&vgdev->resp_wq); + wake_up_all(&vgdev->resp_wq); } static int virtio_get_edid_block(void *data, u8 *buf, @@ -694,8 +696,11 @@ int virtio_gpu_cmd_get_capset(struct virtio_gpu_device *vgdev, struct virtio_gpu_vbuffer *vbuf; int max_size; struct virtio_gpu_drv_cap_cache *cache_ent; + struct virtio_gpu_drv_cap_cache *search_ent; void *resp_buf; + *cache_p = NULL; + if (idx >= vgdev->num_capsets) return -EINVAL; @@ -726,9 +731,26 @@ int virtio_gpu_cmd_get_capset(struct virtio_gpu_device *vgdev, atomic_set(&cache_ent->is_valid, 0); cache_ent->size = max_size; spin_lock(&vgdev->display_info_lock); - list_add_tail(&cache_ent->head, &vgdev->cap_cache); + /* Search while under lock in case it was added by another task. */ + list_for_each_entry(search_ent, &vgdev->cap_cache, head) { + if (search_ent->id == vgdev->capsets[idx].id && + search_ent->version == version) { + *cache_p = search_ent; + break; + } + } + if (!*cache_p) + list_add_tail(&cache_ent->head, &vgdev->cap_cache); spin_unlock(&vgdev->display_info_lock); + if (*cache_p) { + /* Entry was found, so free everything that was just created. */ + kfree(resp_buf); + kfree(cache_ent->caps_cache); + kfree(cache_ent); + return 0; + } + cmd_p = virtio_gpu_alloc_cmd_resp (vgdev, &virtio_gpu_cmd_capset_cb, &vbuf, sizeof(*cmd_p), sizeof(struct virtio_gpu_resp_capset) + max_size, |