Let the drm driver decide what part of what object gets mmapped.
Pass the file around too so radeon/ttm can get at it to verify access. Add drm_gem_or_legacy_mmap_object for drivers to choose the previous behaviour, like i915.
This commit is contained in:
parent
609cad5551
commit
ae23e861e3
|
@ -1049,6 +1049,8 @@ static struct drm_driver driver = {
|
|||
#endif
|
||||
.gem_free_object = i915_gem_free_object,
|
||||
#ifdef __NetBSD__
|
||||
/* XXX Not clear the `or legacy' part is important here. */
|
||||
.mmap_object = &drm_gem_or_legacy_mmap_object,
|
||||
.gem_uvm_ops = &i915_gem_uvm_ops,
|
||||
#else
|
||||
.gem_vm_ops = &i915_gem_vm_ops,
|
||||
|
|
|
@ -119,7 +119,10 @@ extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc,
|
|||
extern bool radeon_is_px(struct drm_device *dev);
|
||||
extern const struct drm_ioctl_desc radeon_ioctls_kms[];
|
||||
extern int radeon_max_kms_ioctl;
|
||||
#ifndef __NetBSD__
|
||||
#ifdef __NetBSD__
|
||||
int radeon_mmap_object(struct drm_device *, off_t, size_t, vm_prot_t,
|
||||
struct uvm_object **, voff_t *, struct file *);
|
||||
#else
|
||||
int radeon_mmap(struct file *filp, struct vm_area_struct *vma);
|
||||
#endif
|
||||
int radeon_mode_dumb_mmap(struct drm_file *filp,
|
||||
|
@ -563,6 +566,7 @@ static struct drm_driver kms_driver = {
|
|||
.dumb_destroy = drm_gem_dumb_destroy,
|
||||
#ifdef __NetBSD__
|
||||
.fops = NULL,
|
||||
.mmap_object = &radeon_mmap_object,
|
||||
.gem_uvm_ops = &radeon_gem_uvm_ops,
|
||||
#else
|
||||
.fops = &radeon_driver_kms_fops,
|
||||
|
|
|
@ -879,7 +879,7 @@ radeon_mmap_object(struct drm_device *dev, off_t offset, size_t size,
|
|||
|
||||
if (__predict_false((offset >> PAGE_SHIFT) < DRM_FILE_PAGE_OFFSET))
|
||||
return drm_mmap_object(dev, offset, size, prot, uobjp,
|
||||
uoffsetp /* , file */);
|
||||
uoffsetp, file);
|
||||
else
|
||||
return ttm_bo_mmap_object(&rdev->mman.bdev, offset, size, prot,
|
||||
uobjp, uoffsetp, file);
|
||||
|
|
|
@ -1097,6 +1097,8 @@ struct drm_driver {
|
|||
|
||||
/* Driver private ops for this object */
|
||||
#ifdef __NetBSD__
|
||||
int (*mmap_object)(struct drm_device *, off_t, size_t, int,
|
||||
struct uvm_object **, voff_t *, struct file *);
|
||||
const struct uvm_pagerops *gem_uvm_ops;
|
||||
#else
|
||||
const struct vm_operations_struct *gem_vm_ops;
|
||||
|
@ -1422,7 +1424,7 @@ extern int drm_release(struct inode *inode, struct file *filp);
|
|||
/* Mapping support (drm_vm.h) */
|
||||
#ifdef __NetBSD__
|
||||
extern int drm_mmap_object(struct drm_device *, off_t, size_t, int,
|
||||
struct uvm_object **, voff_t *);
|
||||
struct uvm_object **, voff_t *, struct file *);
|
||||
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);
|
||||
|
@ -1775,7 +1777,9 @@ void drm_gem_private_object_init(struct drm_device *dev,
|
|||
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 **, voff_t *);
|
||||
struct uvm_object **, voff_t *, struct file *);
|
||||
int drm_gem_or_legacy_mmap_object(struct drm_device *, off_t, size_t, int,
|
||||
struct uvm_object **, voff_t *, struct file *);
|
||||
#else
|
||||
void drm_gem_vm_open(struct vm_area_struct *vma);
|
||||
void drm_gem_vm_close(struct vm_area_struct *vma);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: drm_drv.c,v 1.8 2014/07/25 08:10:39 dholland Exp $ */
|
||||
/* $NetBSD: drm_drv.c,v 1.9 2014/07/26 21:15:45 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.8 2014/07/25 08:10:39 dholland Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: drm_drv.c,v 1.9 2014/07/26 21:15:45 riastradh Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
|
@ -754,24 +754,14 @@ drm_mmap_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
|
|||
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, &uoffset);
|
||||
ret = (*dev->driver->mmap_object)(dev, offset, size, prot, &uobj,
|
||||
&uoffset, file->filp);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (uobj != NULL)
|
||||
goto map;
|
||||
if (uobj == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
/* Try a traditional DRM mapping second. */
|
||||
ret = drm_mmap_object(dev, offset, size, prot, &uobj, &uoffset);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (uobj != NULL)
|
||||
goto map;
|
||||
|
||||
/* Fail. */
|
||||
return ret;
|
||||
|
||||
map: vm_prot = ((ISSET(prot, PROT_READ)? VM_PROT_READ : 0) |
|
||||
vm_prot = ((ISSET(prot, PROT_READ)? VM_PROT_READ : 0) |
|
||||
(ISSET(prot, PROT_WRITE)? VM_PROT_WRITE : 0));
|
||||
KASSERT(vm_prot == (vm_prot & vm_maxprot));
|
||||
uvmflag = UVM_MAPFLAG(vm_prot, vm_maxprot, UVM_INH_COPY,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: drm_gem_vm.c,v 1.4 2014/07/16 20:56:25 riastradh Exp $ */
|
||||
/* $NetBSD: drm_gem_vm.c,v 1.5 2014/07/26 21:15:45 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.4 2014/07/16 20:56:25 riastradh Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: drm_gem_vm.c,v 1.5 2014/07/26 21:15:45 riastradh Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
|
@ -40,7 +40,7 @@ __KERNEL_RCSID(0, "$NetBSD: drm_gem_vm.c,v 1.4 2014/07/16 20:56:25 riastradh Exp
|
|||
#include <drm/drm_vma_manager.h>
|
||||
|
||||
static int drm_gem_mmap_object_locked(struct drm_device *, off_t, size_t,
|
||||
int, struct uvm_object **, voff_t *);
|
||||
int, struct uvm_object **, voff_t *, struct file *);
|
||||
|
||||
void
|
||||
drm_gem_pager_reference(struct uvm_object *uobj)
|
||||
|
@ -60,15 +60,33 @@ drm_gem_pager_detach(struct uvm_object *uobj)
|
|||
drm_gem_object_unreference_unlocked(obj);
|
||||
}
|
||||
|
||||
int
|
||||
drm_gem_or_legacy_mmap_object(struct drm_device *dev, off_t byte_offset,
|
||||
size_t nbytes, int prot, struct uvm_object **uobjp, voff_t *uoffsetp,
|
||||
struct file *file)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = drm_gem_mmap_object(dev, byte_offset, nbytes, prot, uobjp,
|
||||
uoffsetp, file);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (*uobjp != NULL)
|
||||
return 0;
|
||||
|
||||
return drm_mmap_object(dev, byte_offset, nbytes, prot, uobjp,
|
||||
uoffsetp, file);
|
||||
}
|
||||
|
||||
int
|
||||
drm_gem_mmap_object(struct drm_device *dev, off_t byte_offset, size_t nbytes,
|
||||
int prot, struct uvm_object **uobjp, voff_t *uoffsetp)
|
||||
int prot, struct uvm_object **uobjp, voff_t *uoffsetp, struct file *file)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
ret = drm_gem_mmap_object_locked(dev, byte_offset, nbytes, prot,
|
||||
uobjp, uoffsetp);
|
||||
uobjp, uoffsetp, file);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
|
||||
return ret;
|
||||
|
@ -77,7 +95,7 @@ drm_gem_mmap_object(struct drm_device *dev, off_t byte_offset, size_t nbytes,
|
|||
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,
|
||||
voff_t *uoffsetp)
|
||||
voff_t *uoffsetp, struct file *file __unused)
|
||||
{
|
||||
const unsigned long startpage = (byte_offset >> PAGE_SHIFT);
|
||||
const unsigned long npages = (nbytes >> PAGE_SHIFT);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: drm_vm.c,v 1.4 2014/07/16 20:56:25 riastradh Exp $ */
|
||||
/* $NetBSD: drm_vm.c,v 1.5 2014/07/26 21:15:45 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.4 2014/07/16 20:56:25 riastradh Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: drm_vm.c,v 1.5 2014/07/26 21:15:45 riastradh Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/conf.h>
|
||||
|
@ -47,7 +47,7 @@ static paddr_t drm_mmap_map_paddr(struct drm_device *, struct drm_local_map *,
|
|||
|
||||
int
|
||||
drm_mmap_object(struct drm_device *dev, off_t offset, size_t size, int prot,
|
||||
struct uvm_object **uobjp, voff_t *uoffsetp)
|
||||
struct uvm_object **uobjp, voff_t *uoffsetp, struct file *file __unused)
|
||||
{
|
||||
dev_t devno = cdevsw_lookup_major(&drm_cdevsw);
|
||||
struct uvm_object *uobj;
|
||||
|
|
Loading…
Reference in New Issue