blktap: don't use vma->vm_start to calculate offset.

struct vma can be split by partial munmap(), we can't depend on vm_start.
Instead, use tap_blkif_t::rings_vstart.

Signed-off-by: Isaku Yamahata <yamah...@valinux.co.jp>

diff --git a/drivers/xen/blktap/blktap.c b/drivers/xen/blktap/blktap.c
--- a/drivers/xen/blktap/blktap.c
+++ b/drivers/xen/blktap/blktap.c
@@ -317,7 +317,7 @@ static pte_t blktap_clear_pte(struct vm_
        pte_t copy;
        tap_blkif_t *info;
        int offset, seg, usr_idx, pending_idx, mmap_idx;
-       unsigned long uvstart = vma->vm_start + (RING_PAGES << PAGE_SHIFT);
+       unsigned long uvstart;
        unsigned long kvaddr;
        struct tap_vma_priv *priv;
        struct page *pg;
@@ -329,11 +329,15 @@ static pte_t blktap_clear_pte(struct vm_
         * If the address is before the start of the grant mapped region or
         * if vm_file is NULL (meaning mmap failed and we have nothing to do)
         */
-       if (uvaddr < uvstart || vma->vm_file == NULL)
+       if (vma->vm_file != NULL) {
+               info = vma->vm_file->private_data;
+               uvstart = info->rings_vstart + (RING_PAGES << PAGE_SHIFT);
+       } else
+               uvstart = uvaddr;       /* make the following if clause true */
+       if (uvaddr < uvstart)
                return ptep_get_and_clear_full(vma->vm_mm, uvaddr, 
                                               ptep, is_fullmm);
 
-       info = vma->vm_file->private_data;
        priv = vma->vm_private_data;
 
        /* TODO Should these be changed to if statements? */
@@ -1200,8 +1204,7 @@ static int blktap_read_ufe_ring(tap_blki
 
                        pg = pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT);
                        ClearPageReserved(pg);
-                       offset = (uvaddr - info->vma->vm_start) 
-                               >> PAGE_SHIFT;
+                       offset = (uvaddr - info->rings_vstart) >> PAGE_SHIFT;
                        priv->map[offset] = NULL;
                }
                fast_flush_area(pending_req, pending_idx, usr_idx, info->minor);
@@ -1492,7 +1495,7 @@ static void dispatch_rw_block_io(blkif_t
                        set_phys_to_machine(__pa(kvaddr) >> PAGE_SHIFT,
                                            FOREIGN_FRAME(map[i].dev_bus_addr
                                                          >> PAGE_SHIFT));
-                       offset = (uvaddr - info->vma->vm_start) >> PAGE_SHIFT;
+                       offset = (uvaddr - info->rings_vstart) >> PAGE_SHIFT;
                        pg = pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT);
                        priv->map[offset] = pg;
                }
@@ -1519,7 +1522,7 @@ static void dispatch_rw_block_io(blkif_t
                        if (ret)
                                continue;
 
-                       offset = (uvaddr - info->vma->vm_start) >> PAGE_SHIFT;
+                       offset = (uvaddr - info->rings_vstart) >> PAGE_SHIFT;
                        pg = pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT);
                        priv->map[offset] = pg;
                }
blktap: don't use vma->vm_start to calculate offset.

struct vma can be split by partial munmap(), we can't depend on vm_start.
Instead, use tap_blkif_t::rings_vstart.

Signed-off-by: Isaku Yamahata <yamah...@valinux.co.jp>

diff --git a/drivers/xen/blktap/blktap.c b/drivers/xen/blktap/blktap.c
--- a/drivers/xen/blktap/blktap.c
+++ b/drivers/xen/blktap/blktap.c
@@ -317,7 +317,7 @@ static pte_t blktap_clear_pte(struct vm_
 	pte_t copy;
 	tap_blkif_t *info;
 	int offset, seg, usr_idx, pending_idx, mmap_idx;
-	unsigned long uvstart = vma->vm_start + (RING_PAGES << PAGE_SHIFT);
+	unsigned long uvstart;
 	unsigned long kvaddr;
 	struct tap_vma_priv *priv;
 	struct page *pg;
@@ -329,11 +329,15 @@ static pte_t blktap_clear_pte(struct vm_
 	 * If the address is before the start of the grant mapped region or
 	 * if vm_file is NULL (meaning mmap failed and we have nothing to do)
 	 */
-	if (uvaddr < uvstart || vma->vm_file == NULL)
+	if (vma->vm_file != NULL) {
+		info = vma->vm_file->private_data;
+		uvstart = info->rings_vstart + (RING_PAGES << PAGE_SHIFT);
+	} else
+		uvstart = uvaddr;	/* make the following if clause true */
+	if (uvaddr < uvstart)
 		return ptep_get_and_clear_full(vma->vm_mm, uvaddr, 
 					       ptep, is_fullmm);
 
-	info = vma->vm_file->private_data;
 	priv = vma->vm_private_data;
 
 	/* TODO Should these be changed to if statements? */
@@ -1200,8 +1204,7 @@ static int blktap_read_ufe_ring(tap_blki
 
 			pg = pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT);
 			ClearPageReserved(pg);
-			offset = (uvaddr - info->vma->vm_start) 
-				>> PAGE_SHIFT;
+			offset = (uvaddr - info->rings_vstart) >> PAGE_SHIFT;
 			priv->map[offset] = NULL;
 		}
 		fast_flush_area(pending_req, pending_idx, usr_idx, info->minor);
@@ -1492,7 +1495,7 @@ static void dispatch_rw_block_io(blkif_t
 			set_phys_to_machine(__pa(kvaddr) >> PAGE_SHIFT,
 					    FOREIGN_FRAME(map[i].dev_bus_addr
 							  >> PAGE_SHIFT));
-			offset = (uvaddr - info->vma->vm_start) >> PAGE_SHIFT;
+			offset = (uvaddr - info->rings_vstart) >> PAGE_SHIFT;
 			pg = pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT);
 			priv->map[offset] = pg;
 		}
@@ -1519,7 +1522,7 @@ static void dispatch_rw_block_io(blkif_t
 			if (ret)
 				continue;
 
-			offset = (uvaddr - info->vma->vm_start) >> PAGE_SHIFT;
+			offset = (uvaddr - info->rings_vstart) >> PAGE_SHIFT;
 			pg = pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT);
 			priv->map[offset] = pg;
 		}
_______________________________________________
Xen-ia64-devel mailing list
Xen-ia64-devel@lists.xensource.com
http://lists.xensource.com/xen-ia64-devel

Reply via email to