Commit e0da9686 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-misc-fixes-2021-03-11' of git://anongit.freedesktop.org/drm/drm-misc into drm-fixes



drm-misc-fixes for rc3, rebased on rc2:
- Fix oops in drm_fbdev_cleanup()
- unpin qxl bos created as pinned when freeing them,
  and make ttm only warn once on this behavior.
- Use LCD management for atyfb on PPC_MAC.
- Use gitlab for drm bugzilla now.
- Fix ttm page pool accounting.
- Zero head.surface_id correctly in qxl.
- Assorted fixes for shmem helpers.
- Shutdown kms poll helper in meson correctly.
- Clear holes when converting compat ioctl's between 32-bits and 64-bits.

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/4606f08e-d0e8-c543-5e96-cee2fd728a41@linux.intel.com
parents a38fd874 de066e11
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -613,6 +613,27 @@ Some of these date from the very introduction of KMS in 2008 ...

Level: Intermediate

Remove automatic page mapping from dma-buf importing
----------------------------------------------------

When importing dma-bufs, the dma-buf and PRIME frameworks automatically map
imported pages into the importer's DMA area. drm_gem_prime_fd_to_handle() and
drm_gem_prime_handle_to_fd() require that importers call dma_buf_attach()
even if they never do actual device DMA, but only CPU access through
dma_buf_vmap(). This is a problem for USB devices, which do not support DMA
operations.

To fix the issue, automatic page mappings should be removed from the
buffer-sharing code. Fixing this is a bit more involved, since the import/export
cache is also tied to &drm_gem_object.import_attach. Meanwhile we paper over
this problem for USB devices by fishing out the USB host controller device, as
long as that supports DMA. Otherwise importing can still needlessly fail.

Contact: Thomas Zimmermann <tzimmermann@suse.de>, Daniel Vetter

Level: Advanced


Better Testing
==============

+1 −1
Original line number Diff line number Diff line
@@ -5835,7 +5835,7 @@ M: David Airlie <airlied@linux.ie>
M:	Daniel Vetter <daniel@ffwll.ch>
L:	dri-devel@lists.freedesktop.org
S:	Maintained
B:	https://bugs.freedesktop.org/
B:	https://gitlab.freedesktop.org/drm
C:	irc://chat.freenode.net/dri-devel
T:	git git://anongit.freedesktop.org/drm/drm
F:	Documentation/devicetree/bindings/display/
+1 −1
Original line number Diff line number Diff line
@@ -2048,7 +2048,7 @@ static void drm_fbdev_cleanup(struct drm_fb_helper *fb_helper)

	if (shadow)
		vfree(shadow);
	else
	else if (fb_helper->buffer)
		drm_client_buffer_vunmap(fb_helper->buffer);

	drm_client_framebuffer_delete(fb_helper->buffer);
+22 −10
Original line number Diff line number Diff line
@@ -357,13 +357,14 @@ static void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem,
	if (--shmem->vmap_use_count > 0)
		return;

	if (obj->import_attach)
	if (obj->import_attach) {
		dma_buf_vunmap(obj->import_attach->dmabuf, map);
	else
	} else {
		vunmap(shmem->vaddr);
		drm_gem_shmem_put_pages(shmem);
	}

	shmem->vaddr = NULL;
	drm_gem_shmem_put_pages(shmem);
}

/*
@@ -525,14 +526,28 @@ static vm_fault_t drm_gem_shmem_fault(struct vm_fault *vmf)
	struct drm_gem_object *obj = vma->vm_private_data;
	struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
	loff_t num_pages = obj->size >> PAGE_SHIFT;
	vm_fault_t ret;
	struct page *page;
	pgoff_t page_offset;

	if (vmf->pgoff >= num_pages || WARN_ON_ONCE(!shmem->pages))
		return VM_FAULT_SIGBUS;
	/* We don't use vmf->pgoff since that has the fake offset */
	page_offset = (vmf->address - vma->vm_start) >> PAGE_SHIFT;

	page = shmem->pages[vmf->pgoff];
	mutex_lock(&shmem->pages_lock);

	return vmf_insert_page(vma, vmf->address, page);
	if (page_offset >= num_pages ||
	    WARN_ON_ONCE(!shmem->pages) ||
	    shmem->madv < 0) {
		ret = VM_FAULT_SIGBUS;
	} else {
		page = shmem->pages[page_offset];

		ret = vmf_insert_page(vma, vmf->address, page);
	}

	mutex_unlock(&shmem->pages_lock);

	return ret;
}

static void drm_gem_shmem_vm_open(struct vm_area_struct *vma)
@@ -581,9 +596,6 @@ int drm_gem_shmem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
	struct drm_gem_shmem_object *shmem;
	int ret;

	/* Remove the fake offset */
	vma->vm_pgoff -= drm_vma_node_start(&obj->vma_node);

	if (obj->import_attach) {
		/* Drop the reference drm_gem_mmap_obj() acquired.*/
		drm_gem_object_put(obj);
+11 −0
Original line number Diff line number Diff line
@@ -99,6 +99,8 @@ static int compat_drm_version(struct file *file, unsigned int cmd,
	if (copy_from_user(&v32, (void __user *)arg, sizeof(v32)))
		return -EFAULT;

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

	v = (struct drm_version) {
		.name_len = v32.name_len,
		.name = compat_ptr(v32.name),
@@ -137,6 +139,9 @@ static int compat_drm_getunique(struct file *file, unsigned int cmd,

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

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

	uq = (struct drm_unique){
		.unique_len = uq32.unique_len,
		.unique = compat_ptr(uq32.unique),
@@ -265,6 +270,8 @@ static int compat_drm_getclient(struct file *file, unsigned int cmd,
	if (copy_from_user(&c32, argp, sizeof(c32)))
		return -EFAULT;

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

	client.idx = c32.idx;

	err = drm_ioctl_kernel(file, drm_getclient, &client, 0);
@@ -852,6 +859,8 @@ static int compat_drm_wait_vblank(struct file *file, unsigned int cmd,
	if (copy_from_user(&req32, argp, sizeof(req32)))
		return -EFAULT;

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

	req.request.type = req32.request.type;
	req.request.sequence = req32.request.sequence;
	req.request.signal = req32.request.signal;
@@ -889,6 +898,8 @@ static int compat_drm_mode_addfb2(struct file *file, unsigned int cmd,
	struct drm_mode_fb_cmd2 req64;
	int err;

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

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