[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [BLKTAP]: Fix potential grant entry leaks on error
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Node ID 068aed15496dc0d1209ef2fbb19bba0f107b9cd6 # Parent bb76521fdcb34fb10247f335b9e3836d9779321f [BLKTAP]: Fix potential grant entry leaks on error As it stands grant entries for the actual data are mapped in bulk. If one of the earlier entries fail to be mapped, it can cause all subsequent entries to be leaked if they were successfully mapped. This patch changes it so that we will continue to reap grant entries even when an error is detected. There is still a potential leak if create_lookup_pte_addr fails in fast_flush_area. This leak is not affected by this patch. Signed-off-by: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx> --- linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c | 59 +++++++++++++---------- 1 files changed, 35 insertions(+), 24 deletions(-) diff -r bb76521fdcb3 -r 068aed15496d linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c --- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c Fri Oct 20 09:24:26 2006 +0100 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c Fri Oct 20 09:28:31 2006 +0100 @@ -845,28 +845,29 @@ static void fast_flush_area(pending_req_ uvaddr = MMAP_VADDR(info->user_vstart, u_idx, i); khandle = &pending_handle(mmap_idx, k_idx, i); - if (BLKTAP_INVALID_HANDLE(khandle)) { - WPRINTK("BLKTAP_INVALID_HANDLE\n"); - continue; - } - gnttab_set_unmap_op(&unmap[invcount], - idx_to_kaddr(mmap_idx, k_idx, i), - GNTMAP_host_map, khandle->kernel); - invcount++; - - if (create_lookup_pte_addr( - info->vma->vm_mm, - MMAP_VADDR(info->user_vstart, u_idx, i), - &ptep) !=0) { - WPRINTK("Couldn't get a pte addr!\n"); - return; - } - - gnttab_set_unmap_op(&unmap[invcount], - ptep, GNTMAP_host_map, - khandle->user); - invcount++; - + + if (khandle->kernel != 0xFFFF) { + gnttab_set_unmap_op(&unmap[invcount], + idx_to_kaddr(mmap_idx, k_idx, i), + GNTMAP_host_map, khandle->kernel); + invcount++; + } + + if (khandle->user != 0xFFFF) { + if (create_lookup_pte_addr( + info->vma->vm_mm, + MMAP_VADDR(info->user_vstart, u_idx, i), + &ptep) !=0) { + WPRINTK("Couldn't get a pte addr!\n"); + return; + } + + gnttab_set_unmap_op(&unmap[invcount], + ptep, GNTMAP_host_map, + khandle->user); + invcount++; + } + BLKTAP_INVALIDATE_HANDLE(khandle); } ret = HYPERVISOR_grant_table_op( @@ -1223,19 +1224,25 @@ static void dispatch_rw_block_io(blkif_t if (unlikely(map[i].status != 0)) { WPRINTK("invalid kernel buffer -- " "could not remap it\n"); - goto fail_flush; + ret |= 1; + map[i].handle = 0xFFFF; } if (unlikely(map[i+1].status != 0)) { WPRINTK("invalid user buffer -- " "could not remap it\n"); - goto fail_flush; + ret |= 1; + map[i+1].handle = 0xFFFF; } pending_handle(mmap_idx, pending_idx, i/2).kernel = map[i].handle; pending_handle(mmap_idx, pending_idx, i/2).user = map[i+1].handle; + + if (ret) + continue; + 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; @@ -1243,6 +1250,10 @@ static void dispatch_rw_block_io(blkif_t ((struct page **)info->vma->vm_private_data)[offset] = pg; } + + if (ret) + goto fail_flush; + /* Mark mapped pages as reserved: */ for (i = 0; i < req->nr_segments; i++) { unsigned long kvaddr; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |