summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/vkms/vkms_gem.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-10-29 03:49:53 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2018-10-29 03:49:53 +0300
commit53b3b6bbfde6aae8d1ededc86ad4e0e1e00eb5f8 (patch)
treeb29473f21270aefd113b298c9402be8b4b3c91b4 /drivers/gpu/drm/vkms/vkms_gem.c
parent746bb4ed6d626f3f9e431a7f9b20504538e62ded (diff)
parentf2bfc71aee75feff33ca659322b72ffeed5a243d (diff)
downloadlinux-53b3b6bbfde6aae8d1ededc86ad4e0e1e00eb5f8.tar.xz
Merge tag 'drm-next-2018-10-24' of git://anongit.freedesktop.org/drm/drm
Pull drm updates from Dave Airlie: "This is going to rebuild more than drm as it adds a new helper to list.h for doing bulk updates. Seemed like a reasonable addition to me. Otherwise the usual merge window stuff lots of i915 and amdgpu, not so much nouveau, and piles of everything else. Core: - Adds a new list.h helper for doing bulk list updates for TTM. - Don't leak fb address in smem_start to userspace (comes with EXPORT workaround for people using mali out of tree hacks) - udmabuf device to turn memfd regions into dma-buf - Per-plane blend mode property - ref/unref replacements with get/put - fbdev conflicting framebuffers code cleaned up - host-endian format variants - panel orientation quirk for Acer One 10 bridge: - TI SN65DSI86 chip support vkms: - GEM support. - Cursor support amdgpu: - Merge amdkfd and amdgpu into one module - CEC over DP AUX support - Picasso APU support + VCN dynamic powergating - Raven2 APU support - Vega20 enablement + kfd support - ACP powergating improvements - ABGR/XBGR display support - VCN jpeg support - xGMI support - DC i2c/aux cleanup - Ycbcr 4:2:0 support - GPUVM improvements - Powerplay and powerplay endian fixes - Display underflow fixes vmwgfx: - Move vmwgfx specific TTM code to vmwgfx - Split out vmwgfx buffer/resource validation code - Atomic operation rework bochs: - use more helpers - format/byteorder improvements qxl: - use more helpers i915: - GGTT coherency getparam - Turn off resource streamer API - More Icelake enablement + DMC firmware - Full PPGTT for Ivybridge, Haswell and Valleyview - DDB distribution based on resolution - Limited range DP display support nouveau: - CEC over DP AUX support - Initial HDMI 2.0 support virtio-gpu: - vmap support for PRIME objects tegra: - Initial Tegra194 support - DMA/IOMMU integration fixes msm: - a6xx perf improvements + clock prefix - GPU preemption optimisations - a6xx devfreq support - cursor support rockchip: - PX30 support - rgb output interface support mediatek: - HDMI output support on mt2701 and mt7623 rcar-du: - Interlaced modes on Gen3 - LVDS on R8A77980 - D3 and E3 SoC support hisilicon: - misc fixes mxsfb: - runtime pm support sun4i: - R40 TCON support - Allwinner A64 support - R40 HDMI support omapdrm: - Driver rework changing display pipeline ordering to use common code - DMM memory barrier and irq fixes - Errata workarounds exynos: - out-bridge support for LVDS bridge driver - Samsung 16x16 tiled format support - Plane alpha and pixel blend mode support tilcdc: - suspend/resume update mali-dp: - misc updates" * tag 'drm-next-2018-10-24' of git://anongit.freedesktop.org/drm/drm: (1382 commits) firmware/dmc/icl: Add missing MODULE_FIRMWARE() for Icelake. drm/i915/icl: Fix signal_levels drm/i915/icl: Fix DDI/TC port clk_off bits drm/i915/icl: create function to identify combophy port drm/i915/gen9+: Fix initial readout for Y tiled framebuffers drm/i915: Large page offsets for pread/pwrite drm/i915/selftests: Disable shrinker across mmap-exhaustion drm/i915/dp: Link train Fallback on eDP only if fallback link BW can fit panel's native mode drm/i915: Fix intel_dp_mst_best_encoder() drm/i915: Skip vcpi allocation for MSTB ports that are gone drm/i915: Don't unset intel_connector->mst_port drm/i915: Only reset seqno if actually idle drm/i915: Use the correct crtc when sanitizing plane mapping drm/i915: Restore vblank interrupts earlier drm/i915: Check fb stride against plane max stride drm/amdgpu/vcn:Fix uninitialized symbol error drm: panel-orientation-quirks: Add quirk for Acer One 10 (S1003) drm/amd/amdgpu: Fix debugfs error handling drm/amdgpu: Update gc_9_0 golden settings. drm/amd/powerplay: update PPtable with DC BTC and Tvr SocLimit fields ...
Diffstat (limited to 'drivers/gpu/drm/vkms/vkms_gem.c')
-rw-r--r--drivers/gpu/drm/vkms/vkms_gem.c83
1 files changed, 79 insertions, 4 deletions
diff --git a/drivers/gpu/drm/vkms/vkms_gem.c b/drivers/gpu/drm/vkms/vkms_gem.c
index c7e38368602b..d04e988b4cbe 100644
--- a/drivers/gpu/drm/vkms/vkms_gem.c
+++ b/drivers/gpu/drm/vkms/vkms_gem.c
@@ -37,20 +37,22 @@ void vkms_gem_free_object(struct drm_gem_object *obj)
struct vkms_gem_object *gem = container_of(obj, struct vkms_gem_object,
gem);
- kvfree(gem->pages);
+ WARN_ON(gem->pages);
+ WARN_ON(gem->vaddr);
+
mutex_destroy(&gem->pages_lock);
drm_gem_object_release(obj);
kfree(gem);
}
-int vkms_gem_fault(struct vm_fault *vmf)
+vm_fault_t vkms_gem_fault(struct vm_fault *vmf)
{
struct vm_area_struct *vma = vmf->vma;
struct vkms_gem_object *obj = vma->vm_private_data;
unsigned long vaddr = vmf->address;
pgoff_t page_offset;
loff_t num_pages;
- int ret;
+ vm_fault_t ret = VM_FAULT_SIGBUS;
page_offset = (vaddr - vma->vm_start) >> PAGE_SHIFT;
num_pages = DIV_ROUND_UP(obj->gem.size, PAGE_SIZE);
@@ -58,7 +60,6 @@ int vkms_gem_fault(struct vm_fault *vmf)
if (page_offset > num_pages)
return VM_FAULT_SIGBUS;
- ret = -ENOENT;
mutex_lock(&obj->pages_lock);
if (obj->pages) {
get_page(obj->pages[page_offset]);
@@ -177,3 +178,77 @@ unref:
return ret;
}
+
+static struct page **_get_pages(struct vkms_gem_object *vkms_obj)
+{
+ struct drm_gem_object *gem_obj = &vkms_obj->gem;
+
+ if (!vkms_obj->pages) {
+ struct page **pages = drm_gem_get_pages(gem_obj);
+
+ if (IS_ERR(pages))
+ return pages;
+
+ if (cmpxchg(&vkms_obj->pages, NULL, pages))
+ drm_gem_put_pages(gem_obj, pages, false, true);
+ }
+
+ return vkms_obj->pages;
+}
+
+void vkms_gem_vunmap(struct drm_gem_object *obj)
+{
+ struct vkms_gem_object *vkms_obj = drm_gem_to_vkms_gem(obj);
+
+ mutex_lock(&vkms_obj->pages_lock);
+ if (vkms_obj->vmap_count < 1) {
+ WARN_ON(vkms_obj->vaddr);
+ WARN_ON(vkms_obj->pages);
+ mutex_unlock(&vkms_obj->pages_lock);
+ return;
+ }
+
+ vkms_obj->vmap_count--;
+
+ if (vkms_obj->vmap_count == 0) {
+ vunmap(vkms_obj->vaddr);
+ vkms_obj->vaddr = NULL;
+ drm_gem_put_pages(obj, vkms_obj->pages, false, true);
+ vkms_obj->pages = NULL;
+ }
+
+ mutex_unlock(&vkms_obj->pages_lock);
+}
+
+int vkms_gem_vmap(struct drm_gem_object *obj)
+{
+ struct vkms_gem_object *vkms_obj = drm_gem_to_vkms_gem(obj);
+ int ret = 0;
+
+ mutex_lock(&vkms_obj->pages_lock);
+
+ if (!vkms_obj->vaddr) {
+ unsigned int n_pages = obj->size >> PAGE_SHIFT;
+ struct page **pages = _get_pages(vkms_obj);
+
+ if (IS_ERR(pages)) {
+ ret = PTR_ERR(pages);
+ goto out;
+ }
+
+ vkms_obj->vaddr = vmap(pages, n_pages, VM_MAP, PAGE_KERNEL);
+ if (!vkms_obj->vaddr)
+ goto err_vmap;
+ }
+
+ vkms_obj->vmap_count++;
+ goto out;
+
+err_vmap:
+ ret = -ENOMEM;
+ drm_gem_put_pages(obj, vkms_obj->pages, false, true);
+ vkms_obj->pages = NULL;
+out:
+ mutex_unlock(&vkms_obj->pages_lock);
+ return ret;
+}