Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/external/bsd/drm2 Tweak some DRM GEM page indexing crap.
details: https://anonhg.NetBSD.org/src/rev/83a893a99910
branches: trunk
changeset: 329051:83a893a99910
user: riastradh <riastradh%NetBSD.org@localhost>
date: Thu May 01 15:19:16 2014 +0000
description:
Tweak some DRM GEM page indexing crap.
- Fix order of subtraction in drm_mmap_paddr_locked.
- Address GEM objects' pages from 0, not from the mmap cookie.
- Check page alignment earlier in mmap code paths.
- Sprinkle kasserts throughout.
Still doesn't fix the garbage that is sometimes being scribbled all
over kernel memory!
diffstat:
sys/external/bsd/drm2/dist/drm/i915/i915_gem.c | 6 ++-
sys/external/bsd/drm2/dist/include/drm/drmP.h | 4 +-
sys/external/bsd/drm2/drm/drm_drv.c | 15 ++++++----
sys/external/bsd/drm2/drm/drm_gem_vm.c | 19 +++++++------
sys/external/bsd/drm2/drm/drm_vm.c | 37 ++++++++++++++++---------
5 files changed, 49 insertions(+), 32 deletions(-)
diffs (287 lines):
diff -r b486f412200d -r 83a893a99910 sys/external/bsd/drm2/dist/drm/i915/i915_gem.c
--- a/sys/external/bsd/drm2/dist/drm/i915/i915_gem.c Thu May 01 14:37:36 2014 +0000
+++ b/sys/external/bsd/drm2/dist/drm/i915/i915_gem.c Thu May 01 15:19:16 2014 +0000
@@ -1521,12 +1521,14 @@
struct drm_i915_gem_object *obj = to_intel_bo(gem_obj);
struct drm_device *dev = obj->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
+ voff_t byte_offset;
pgoff_t page_offset;
int ret = 0;
bool write = ISSET(access_type, VM_PROT_WRITE)? 1 : 0;
- page_offset = (ufi->entry->offset + (vaddr - ufi->entry->start)) >>
- PAGE_SHIFT;
+ byte_offset = (ufi->entry->offset + (vaddr - ufi->entry->start));
+ KASSERT(byte_offset <= obj->base.size);
+ page_offset = (byte_offset >> PAGE_SHIFT);
ret = i915_mutex_lock_interruptible(dev);
if (ret)
diff -r b486f412200d -r 83a893a99910 sys/external/bsd/drm2/dist/include/drm/drmP.h
--- a/sys/external/bsd/drm2/dist/include/drm/drmP.h Thu May 01 14:37:36 2014 +0000
+++ b/sys/external/bsd/drm2/dist/include/drm/drmP.h Thu May 01 15:19:16 2014 +0000
@@ -1495,7 +1495,7 @@
/* Mapping support (drm_vm.h) */
#ifdef __NetBSD__
extern int drm_mmap_object(struct drm_device *, off_t, size_t, int,
- struct uvm_object **);
+ struct uvm_object **, voff_t *);
extern paddr_t drm_mmap_paddr(struct drm_device *, off_t, int);
#else
extern int drm_mmap(struct file *filp, struct vm_area_struct *vma);
@@ -1868,7 +1868,7 @@
void drm_gem_pager_reference(struct uvm_object *);
void drm_gem_pager_detach(struct uvm_object *);
int drm_gem_mmap_object(struct drm_device *, off_t, size_t, int,
- struct uvm_object **);
+ struct uvm_object **, voff_t *);
#else
void drm_gem_vm_open(struct vm_area_struct *vma);
void drm_gem_vm_close(struct vm_area_struct *vma);
diff -r b486f412200d -r 83a893a99910 sys/external/bsd/drm2/drm/drm_drv.c
--- a/sys/external/bsd/drm2/drm/drm_drv.c Thu May 01 14:37:36 2014 +0000
+++ b/sys/external/bsd/drm2/drm/drm_drv.c Thu May 01 15:19:16 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: drm_drv.c,v 1.3 2014/04/04 15:16:59 riastradh Exp $ */
+/* $NetBSD: drm_drv.c,v 1.4 2014/05/01 15:19:16 riastradh Exp $ */
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: drm_drv.c,v 1.3 2014/04/04 15:16:59 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: drm_drv.c,v 1.4 2014/05/01 15:19:16 riastradh Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -977,6 +977,7 @@
const int flags = args->dnm_flags;
const off_t offset = args->dnm_offset;
struct uvm_object *uobj;
+ voff_t uoffset;
const vm_prot_t vm_maxprot = (VM_PROT_READ | VM_PROT_WRITE);
vm_prot_t vm_prot;
int uvmflag;
@@ -991,17 +992,19 @@
return -EACCES;
if (flags != MAP_SHARED)
return -EINVAL;
+ if (offset != (offset & ~(PAGE_SIZE-1)))
+ return -EINVAL;
(void)addr; /* XXX ignore -- no MAP_FIXED for now */
/* Try a GEM object mapping first. */
- ret = drm_gem_mmap_object(dev, offset, size, prot, &uobj);
+ ret = drm_gem_mmap_object(dev, offset, size, prot, &uobj, &uoffset);
if (ret)
return ret;
if (uobj != NULL)
goto map;
/* Try a traditional DRM mapping second. */
- ret = drm_mmap_object(dev, offset, size, prot, &uobj);
+ ret = drm_mmap_object(dev, offset, size, prot, &uobj, &uoffset);
if (ret)
return ret;
if (uobj != NULL)
@@ -1020,8 +1023,8 @@
vaddr = (*curproc->p_emul->e_vm_default_addr)(curproc,
(vaddr_t)curproc->p_vmspace->vm_daddr, size);
/* XXX errno NetBSD->Linux */
- ret = -uvm_map(&curproc->p_vmspace->vm_map, &vaddr, size, uobj, offset,
- align, uvmflag);
+ ret = -uvm_map(&curproc->p_vmspace->vm_map, &vaddr, size, uobj,
+ uoffset, align, uvmflag);
if (ret) {
(*uobj->pgops->pgo_detach)(uobj);
return ret;
diff -r b486f412200d -r 83a893a99910 sys/external/bsd/drm2/drm/drm_gem_vm.c
--- a/sys/external/bsd/drm2/drm/drm_gem_vm.c Thu May 01 14:37:36 2014 +0000
+++ b/sys/external/bsd/drm2/drm/drm_gem_vm.c Thu May 01 15:19:16 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: drm_gem_vm.c,v 1.2 2014/03/18 18:20:42 riastradh Exp $ */
+/* $NetBSD: drm_gem_vm.c,v 1.3 2014/05/01 15:19:16 riastradh Exp $ */
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: drm_gem_vm.c,v 1.2 2014/03/18 18:20:42 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: drm_gem_vm.c,v 1.3 2014/05/01 15:19:16 riastradh Exp $");
#include <sys/types.h>
@@ -39,7 +39,7 @@
#include <drm/drmP.h>
static int drm_gem_mmap_object_locked(struct drm_device *, off_t, size_t,
- int, struct uvm_object **);
+ int, struct uvm_object **, voff_t *);
void
drm_gem_pager_reference(struct uvm_object *uobj)
@@ -61,13 +61,13 @@
int
drm_gem_mmap_object(struct drm_device *dev, off_t byte_offset, size_t nbytes,
- int prot, struct uvm_object **uobjp)
+ int prot, struct uvm_object **uobjp, voff_t *uoffsetp)
{
int ret;
mutex_lock(&dev->struct_mutex);
ret = drm_gem_mmap_object_locked(dev, byte_offset, nbytes, prot,
- uobjp);
+ uobjp, uoffsetp);
mutex_unlock(&dev->struct_mutex);
return ret;
@@ -75,7 +75,8 @@
static int
drm_gem_mmap_object_locked(struct drm_device *dev, off_t byte_offset,
- size_t nbytes, int prot __unused, struct uvm_object **uobjp)
+ size_t nbytes, int prot __unused, struct uvm_object **uobjp,
+ voff_t *uoffsetp)
{
struct drm_gem_mm *const mm = dev->mm_private;
const off_t page_offset = (byte_offset >> PAGE_SHIFT);
@@ -85,13 +86,12 @@
KASSERT(drm_core_check_feature(dev, DRIVER_GEM));
KASSERT(dev->driver->gem_uvm_ops != NULL);
KASSERT(prot == (prot & (PROT_READ | PROT_WRITE)));
-
- if (byte_offset != (byte_offset & ~(PAGE_SIZE-1))) /* XXX kassert? */
- return -EINVAL;
+ KASSERT(byte_offset == (byte_offset & ~(PAGE_SIZE-1)));
if (drm_ht_find_item(&mm->offset_hash, page_offset, &hash) != 0) {
/* Fall back to vanilla device mappings. */
*uobjp = NULL;
+ *uoffsetp = (voff_t)-1;
return 0;
}
@@ -109,5 +109,6 @@
/* Success! */
drm_gem_object_reference(obj);
*uobjp = &obj->gemo_uvmobj;
+ *uoffsetp = 0;
return 0;
}
diff -r b486f412200d -r 83a893a99910 sys/external/bsd/drm2/drm/drm_vm.c
--- a/sys/external/bsd/drm2/drm/drm_vm.c Thu May 01 14:37:36 2014 +0000
+++ b/sys/external/bsd/drm2/drm/drm_vm.c Thu May 01 15:19:16 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: drm_vm.c,v 1.2 2014/03/18 18:20:42 riastradh Exp $ */
+/* $NetBSD: drm_vm.c,v 1.3 2014/05/01 15:19:16 riastradh Exp $ */
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: drm_vm.c,v 1.2 2014/03/18 18:20:42 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: drm_vm.c,v 1.3 2014/05/01 15:19:16 riastradh Exp $");
#include <sys/types.h>
#include <sys/conf.h>
@@ -47,16 +47,24 @@
int
drm_mmap_object(struct drm_device *dev, off_t offset, size_t size, int prot,
- struct uvm_object **uobjp)
+ struct uvm_object **uobjp, voff_t *uoffsetp)
{
dev_t devno = cdevsw_lookup_major(&drm_cdevsw);
struct uvm_object *uobj;
+ KASSERT(offset == (offset & ~(PAGE_SIZE-1)));
+
+ /*
+ * Attach the device. The size and offset are used only for
+ * access checks; offset does not become a base address for the
+ * subsequent uvm_map, hence we set *uoffsetp to offset, not 0.
+ */
uobj = udv_attach(&devno, prot, offset, size);
if (uobj == NULL)
return -EINVAL;
*uobjp = uobj;
+ *uoffsetp = offset;
return 0;
}
@@ -65,6 +73,9 @@
{
paddr_t paddr;
+ if (byte_offset != (byte_offset & ~(PAGE_SIZE-1)))
+ return -1;
+
mutex_lock(&dev->struct_mutex);
paddr = drm_mmap_paddr_locked(dev, byte_offset, prot);
mutex_unlock(&dev->struct_mutex);
@@ -79,13 +90,11 @@
struct drm_hash_item *hash;
KASSERT(mutex_is_locked(&dev->struct_mutex));
-
- if (byte_offset != (byte_offset & ~(PAGE_SIZE-1)))
- return -1;
+ KASSERT(byte_offset == (byte_offset & ~(PAGE_SIZE-1)));
if ((dev->dma != NULL) &&
(0 <= byte_offset) &&
- (byte_offset <= (dev->dma->page_count << PAGE_SHIFT)))
+ (page_offset <= dev->dma->page_count))
return drm_mmap_dma_paddr(dev, byte_offset, prot);
if (drm_ht_find_item(&dev->map_hash, page_offset, &hash))
@@ -105,11 +114,12 @@
if (ISSET(map->flags, _DRM_RESTRICTED) && !DRM_SUSER())
return -1;
- if (byte_offset < map->offset)
+ if (!(map->offset <= byte_offset))
+ return -1;
+ if (map->size < (map->offset - byte_offset))
return -1;
- return drm_mmap_map_paddr(dev, map, (map->offset - byte_offset),
- prot);
+ return drm_mmap_map_paddr(dev, map, (byte_offset - map->offset), prot);
}
static paddr_t
@@ -118,13 +128,12 @@
const off_t page_offset = (byte_offset >> PAGE_SHIFT);
KASSERT(mutex_is_locked(&dev->struct_mutex));
+ KASSERT(byte_offset == (byte_offset & ~(PAGE_SIZE-1)));
+ KASSERT(page_offset <= dev->dma->page_count);
if (dev->dma->pagelist == NULL)
return (paddr_t)-1;
- if (page_offset >= dev->dma->page_count)
- return (paddr_t)-1;
-
return dev->dma->pagelist[page_offset];
}
@@ -134,6 +143,8 @@
{
int flags = 0;
+ KASSERT(byte_offset <= map->size);
+
switch (map->type) {
case _DRM_FRAME_BUFFER:
case _DRM_AGP:
Home |
Main Index |
Thread Index |
Old Index