Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=d7d8aac79dc38cbdef83b774e49bafdae9918137
Commit:     d7d8aac79dc38cbdef83b774e49bafdae9918137
Parent:     040ac32048d5efabd557c1e0a6ab8aec2c710c56
Author:     Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
AuthorDate: Sat Mar 24 17:52:49 2007 +1100
Committer:  Dave Airlie <[EMAIL PROTECTED]>
CommitDate: Sat Mar 24 18:00:22 2007 +1100

    drm: fix up mmap locking in preparation for ttm changes
    
    This change is needed to protect againt disappearing maps which aren't 
common.
    The map lists are protected using sturct_mutex but drm_mmap never locked it.
    
    Signed-off-by: Dave Airlie <[EMAIL PROTECTED]>
---
 drivers/char/drm/drm_vm.c |   35 ++++++++++++++++++++++++++---------
 1 files changed, 26 insertions(+), 9 deletions(-)

diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c
index 239ac33..f7d4e29 100644
--- a/drivers/char/drm/drm_vm.c
+++ b/drivers/char/drm/drm_vm.c
@@ -413,7 +413,7 @@ static struct vm_operations_struct drm_vm_sg_ops = {
  * Create a new drm_vma_entry structure as the \p vma private data entry and
  * add it to drm_device::vmalist.
  */
-static void drm_vm_open(struct vm_area_struct *vma)
+static void drm_vm_open_locked(struct vm_area_struct *vma)
 {
        drm_file_t *priv = vma->vm_file->private_data;
        drm_device_t *dev = priv->head->dev;
@@ -425,15 +425,23 @@ static void drm_vm_open(struct vm_area_struct *vma)
 
        vma_entry = drm_alloc(sizeof(*vma_entry), DRM_MEM_VMAS);
        if (vma_entry) {
-               mutex_lock(&dev->struct_mutex);
                vma_entry->vma = vma;
                vma_entry->next = dev->vmalist;
                vma_entry->pid = current->pid;
                dev->vmalist = vma_entry;
-               mutex_unlock(&dev->struct_mutex);
        }
 }
 
+static void drm_vm_open(struct vm_area_struct *vma)
+{
+       drm_file_t *priv = vma->vm_file->private_data;
+       drm_device_t *dev = priv->head->dev;
+
+       mutex_lock(&dev->struct_mutex);
+       drm_vm_open_locked(vma);
+       mutex_unlock(&dev->struct_mutex);
+}
+
 /**
  * \c close method for all virtual memory types.
  *
@@ -484,7 +492,6 @@ static int drm_mmap_dma(struct file *filp, struct 
vm_area_struct *vma)
        drm_device_dma_t *dma;
        unsigned long length = vma->vm_end - vma->vm_start;
 
-       lock_kernel();
        dev = priv->head->dev;
        dma = dev->dma;
        DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n",
@@ -492,10 +499,8 @@ static int drm_mmap_dma(struct file *filp, struct 
vm_area_struct *vma)
 
        /* Length must match exact page count */
        if (!dma || (length >> PAGE_SHIFT) != dma->page_count) {
-               unlock_kernel();
                return -EINVAL;
        }
-       unlock_kernel();
 
        if (!capable(CAP_SYS_ADMIN) &&
            (dma->flags & _DRM_DMA_USE_PCI_RO)) {
@@ -518,7 +523,7 @@ static int drm_mmap_dma(struct file *filp, struct 
vm_area_struct *vma)
        vma->vm_flags |= VM_RESERVED;   /* Don't swap */
 
        vma->vm_file = filp;    /* Needed for drm_vm_open() */
-       drm_vm_open(vma);
+       drm_vm_open_locked(vma);
        return 0;
 }
 
@@ -553,7 +558,7 @@ EXPORT_SYMBOL(drm_core_get_reg_ofs);
  * according to the mapping type and remaps the pages. Finally sets the file
  * pointer and calls vm_open().
  */
-int drm_mmap(struct file *filp, struct vm_area_struct *vma)
+static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
 {
        drm_file_t *priv = filp->private_data;
        drm_device_t *dev = priv->head->dev;
@@ -667,8 +672,20 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
        vma->vm_flags |= VM_RESERVED;   /* Don't swap */
 
        vma->vm_file = filp;    /* Needed for drm_vm_open() */
-       drm_vm_open(vma);
+       drm_vm_open_locked(vma);
        return 0;
 }
 
+int drm_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+       drm_file_t *priv = filp->private_data;
+       drm_device_t *dev = priv->head->dev;
+       int ret;
+
+       mutex_lock(&dev->struct_mutex);
+       ret = drm_mmap_locked(filp, vma);
+       mutex_unlock(&dev->struct_mutex);
+
+       return ret;
+}
 EXPORT_SYMBOL(drm_mmap);
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to