WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH] blktap: ensure vma->vm_mm's mmap_sem is being held w

To: <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH] blktap: ensure vma->vm_mm's mmap_sem is being held whenever it is being modified
From: "Jan Beulich" <jbeulich@xxxxxxxxxx>
Date: Wed, 05 Nov 2008 13:58:56 +0000
Delivery-date: Wed, 05 Nov 2008 05:58:51 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
As usual, written and (build-)tested on 2.6.27.4 and made apply to the 2.6.18
tree without further testing.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>

Index: head-2008-11-04/drivers/xen/blktap/blktap.c
===================================================================
--- head-2008-11-04.orig/drivers/xen/blktap/blktap.c    2008-10-01 
16:35:04.000000000 +0200
+++ head-2008-11-04/drivers/xen/blktap/blktap.c 2008-11-05 14:27:58.000000000 
+0100
@@ -611,9 +611,13 @@ static int blktap_release(struct inode *
 
        /* Clear any active mappings and free foreign map table */
        if (info->vma) {
+               struct mm_struct *mm = info->vma->vm_mm;
+
+               down_write(&mm->mmap_sem);
                zap_page_range(
                        info->vma, info->vma->vm_start, 
                        info->vma->vm_end - info->vma->vm_start, NULL);
+               up_write(&mm->mmap_sem);
 
                kfree(info->vma->vm_private_data);
 
@@ -993,12 +997,13 @@ static void fast_flush_area(pending_req_
                            int tapidx)
 {
        struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST*2];
-       unsigned int i, invcount = 0;
+       unsigned int i, invcount = 0, locked = 0;
        struct grant_handle_pair *khandle;
        uint64_t ptep;
        int ret, mmap_idx;
        unsigned long kvaddr, uvaddr;
        tap_blkif_t *info;
+       struct mm_struct *mm;
        
 
        info = tapfds[tapidx];
@@ -1008,13 +1013,15 @@ static void fast_flush_area(pending_req_
                return;
        }
 
+       mm = info->vma ? info->vma->vm_mm : NULL;
+
        if (info->vma != NULL &&
            xen_feature(XENFEAT_auto_translated_physmap)) {
-               down_write(&info->vma->vm_mm->mmap_sem);
+               down_write(&mm->mmap_sem);
                zap_page_range(info->vma, 
                               MMAP_VADDR(info->user_vstart, u_idx, 0), 
                               req->nr_pages << PAGE_SHIFT, NULL);
-               up_write(&info->vma->vm_mm->mmap_sem);
+               up_write(&mm->mmap_sem);
                return;
        }
 
@@ -1039,10 +1046,13 @@ static void fast_flush_area(pending_req_
 
                if (khandle->user != INVALID_GRANT_HANDLE) {
                        BUG_ON(xen_feature(XENFEAT_auto_translated_physmap));
+                       if (!locked++)
+                               down_write(&mm->mmap_sem);
                        if (create_lookup_pte_addr(
-                               info->vma->vm_mm,
+                               mm,
                                MMAP_VADDR(info->user_vstart, u_idx, i),
                                &ptep) !=0) {
+                               up_write(&mm->mmap_sem);
                                WPRINTK("Couldn't get a pte addr!\n");
                                return;
                        }
@@ -1061,10 +1071,17 @@ static void fast_flush_area(pending_req_
                GNTTABOP_unmap_grant_ref, unmap, invcount);
        BUG_ON(ret);
        
-       if (info->vma != NULL && !xen_feature(XENFEAT_auto_translated_physmap))
+       if (info->vma != NULL &&
+           !xen_feature(XENFEAT_auto_translated_physmap)) {
+               if (!locked++)
+                       down_write(&mm->mmap_sem);
                zap_page_range(info->vma, 
                               MMAP_VADDR(info->user_vstart, u_idx, 0), 
                               req->nr_pages << PAGE_SHIFT, NULL);
+       }
+
+       if (locked)
+               up_write(&mm->mmap_sem);
 }
 
 /******************************************************************
@@ -1356,6 +1373,7 @@ static void dispatch_rw_block_io(blkif_t
        int pending_idx = RTN_PEND_IDX(pending_req,pending_req->mem_idx);
        int usr_idx;
        uint16_t mmap_idx = pending_req->mem_idx;
+       struct mm_struct *mm;
 
        if (blkif->dev_num < 0 || blkif->dev_num > MAX_TAP_DEV)
                goto fail_response;
@@ -1416,6 +1434,9 @@ static void dispatch_rw_block_io(blkif_t
        pending_req->status    = BLKIF_RSP_OKAY;
        pending_req->nr_pages  = nseg;
        op = 0;
+       mm = info->vma->vm_mm;
+       if (!xen_feature(XENFEAT_auto_translated_physmap))
+               down_write(&mm->mmap_sem);
        for (i = 0; i < nseg; i++) {
                unsigned long uvaddr;
                unsigned long kvaddr;
@@ -1434,9 +1455,9 @@ static void dispatch_rw_block_io(blkif_t
 
                if (!xen_feature(XENFEAT_auto_translated_physmap)) {
                        /* Now map it to user. */
-                       ret = create_lookup_pte_addr(info->vma->vm_mm, 
-                                                    uvaddr, &ptep);
+                       ret = create_lookup_pte_addr(mm, uvaddr, &ptep);
                        if (ret) {
+                               up_write(&mm->mmap_sem);
                                WPRINTK("Couldn't get a pte addr!\n");
                                goto fail_flush;
                        }
@@ -1458,6 +1479,8 @@ static void dispatch_rw_block_io(blkif_t
        BUG_ON(ret);
 
        if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+               up_write(&mm->mmap_sem);
+
                for (i = 0; i < (nseg*2); i+=2) {
                        unsigned long uvaddr;
                        unsigned long kvaddr;
@@ -1531,7 +1554,7 @@ static void dispatch_rw_block_io(blkif_t
                goto fail_flush;
 
        if (xen_feature(XENFEAT_auto_translated_physmap))
-               down_write(&info->vma->vm_mm->mmap_sem);
+               down_write(&mm->mmap_sem);
        /* Mark mapped pages as reserved: */
        for (i = 0; i < req->nr_segments; i++) {
                unsigned long kvaddr;
@@ -1545,13 +1568,13 @@ static void dispatch_rw_block_io(blkif_t
                                             MMAP_VADDR(info->user_vstart,
                                                        usr_idx, i), pg);
                        if (ret) {
-                               up_write(&info->vma->vm_mm->mmap_sem);
+                               up_write(&mm->mmap_sem);
                                goto fail_flush;
                        }
                }
        }
        if (xen_feature(XENFEAT_auto_translated_physmap))
-               up_write(&info->vma->vm_mm->mmap_sem);
+               up_write(&mm->mmap_sem);
        
        /*record [mmap_idx,pending_idx] to [usr_idx] mapping*/
        info->idx_map[usr_idx] = MAKE_ID(mmap_idx, pending_idx);



_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH] blktap: ensure vma->vm_mm's mmap_sem is being held whenever it is being modified, Jan Beulich <=