[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [linux-2.6.18-xen] privcmd: Handle paged-out areas of foreign guest memory in mmap().
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1261031869 0 # Node ID c4572f01675ed0a3fe5284e437383d925265a247 # Parent 0d9c11acc93900270caa0a9fdf50cde73157da9c privcmd: Handle paged-out areas of foreign guest memory in mmap(). Signed-off-by: Grzegorz Milos <Grzegorz.Milos@xxxxxxxxxx> --- drivers/xen/privcmd/privcmd.c | 33 ++++++++++++++++++++++++++------- 1 files changed, 26 insertions(+), 7 deletions(-) diff -r 0d9c11acc939 -r c4572f01675e drivers/xen/privcmd/privcmd.c --- a/drivers/xen/privcmd/privcmd.c Wed Dec 16 16:44:12 2009 +0000 +++ b/drivers/xen/privcmd/privcmd.c Thu Dec 17 06:37:49 2009 +0000 @@ -197,6 +197,7 @@ static long privcmd_ioctl(struct file *f int i; LIST_HEAD(pagelist); struct list_head *l, *l2; + int paged_out = 0; if (!is_initial_xendomain()) return -EPERM; @@ -236,8 +237,14 @@ static long privcmd_ioctl(struct file *f (m.addr != vma->vm_start) || ((m.addr + (nr_pages << PAGE_SHIFT)) != vma->vm_end) || !privcmd_enforce_singleshot_mapping(vma)) { - up_write(&mm->mmap_sem); - goto mmapbatch_out; + if (!(vma && + (m.addr >= vma->vm_start) && + ((m.addr + (nr_pages << PAGE_SHIFT)) <= vma->vm_end) && + (nr_pages == 1) && + !privcmd_enforce_singleshot_mapping(vma))) { + up_write(&mm->mmap_sem); + goto mmapbatch_out; + } } p = m.arr; @@ -246,13 +253,22 @@ static long privcmd_ioctl(struct file *f ret = 0; list_for_each(l, &pagelist) { int nr = i + min(nr_pages - i, MMAPBATCH_NR_PER_PAGE); + int rc; + mfn = (unsigned long *)(l + 1); while (i<nr) { - if(direct_remap_pfn_range(vma, addr & PAGE_MASK, - *mfn, PAGE_SIZE, - vma->vm_page_prot, m.dom) < 0) { - *mfn |= 0xf0000000U; + rc = direct_remap_pfn_range(vma, addr & PAGE_MASK, + *mfn, PAGE_SIZE, + vma->vm_page_prot, m.dom); + if(rc < 0) { + if (rc == -ENOENT) + { + *mfn |= 0x80000000U; + paged_out = 1; + } + else + *mfn |= 0xf0000000U; ret++; } mfn++; i++; addr += PAGE_SIZE; @@ -263,7 +279,10 @@ static long privcmd_ioctl(struct file *f if (ret > 0) { p = m.arr; i = 0; - ret = 0; + if (paged_out) + ret = -ENOENT; + else + ret = 0; list_for_each(l, &pagelist) { int nr = min(nr_pages - i, MMAPBATCH_NR_PER_PAGE); mfn = (unsigned long *)(l + 1); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |