Isaku Yamahata
2007-Aug-28 06:17 UTC
[Xen-devel] [PATCH 2/3] xencomm take 4: xen side multiple page support
# HG changeset patch # User yamahata@valinux.co.jp # Date 1188280422 -32400 # Node ID ec6538af0ce5c0cee25d7a063c1d33df0f80a8d9 # Parent fa5615e8bf84df1d5b4f9d87e95359692a65dbcb [xen, xencomm] xencomm multiple page support Current implementation doesn''t allow struct xencomm_desc::address array to be more than single page. On IA64 it causes 64GB+ domain creation failure. This patch generalizes xencomm to allow multipage xencomm_desc::address array. PATCHNAME: xencomm_multiple_page Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp> diff -r fa5615e8bf84 -r ec6538af0ce5 xen/common/xencomm.c --- a/xen/common/xencomm.c Tue Aug 28 14:43:33 2007 +0900 +++ b/xen/common/xencomm.c Tue Aug 28 14:53:42 2007 +0900 @@ -17,6 +17,7 @@ * * Authors: Hollis Blanchard <hollisb@us.ibm.com> * Tristan Gingold <tristan.gingold@bull.net> + * Isaku Yamahata <yamahata@valinux.co.jp> multiple page support */ #include <xen/config.h> @@ -82,10 +83,11 @@ xencomm_desc_cross_page_boundary(unsigne } struct xencomm_ctxt { - struct xencomm_desc *desc; - + struct xencomm_desc __user *desc_in_paddr; uint32_t nr_addrs; + struct page_info *page; + unsigned long *address; }; static uint32_t @@ -95,21 +97,9 @@ xencomm_ctxt_nr_addrs(const struct xenco } static unsigned long* -xencomm_ctxt_address(struct xencomm_ctxt *ctxt, int i) -{ - return &ctxt->desc->address[i]; -} - -/* check if struct xencomm_desc and address array cross page boundary */ -static int -xencomm_ctxt_cross_page_boundary(struct xencomm_ctxt *ctxt) -{ - unsigned long saddr = (unsigned long)ctxt->desc; - unsigned long eaddr - (unsigned long)&ctxt->desc->address[ctxt->nr_addrs] - 1; - if ( (saddr >> PAGE_SHIFT) != (eaddr >> PAGE_SHIFT) ) - return 1; - return 0; +xencomm_ctxt_address(struct xencomm_ctxt *ctxt) +{ + return ctxt->address; } static int @@ -138,16 +128,40 @@ xencomm_ctxt_init(const void* handle, st return -EINVAL; } - ctxt->desc = desc; ctxt->nr_addrs = desc->nr_addrs; /* copy before use. * It is possible for a guest domain to * modify concurrently. */ + ctxt->desc_in_paddr = (struct xencomm_desc*)handle; ctxt->page = page; - if ( xencomm_ctxt_cross_page_boundary(ctxt) ) - { - put_page(page); - return -EINVAL; + ctxt->address = &desc->address[0]; + return 0; +} + +static int +xencomm_ctxt_next(struct xencomm_ctxt *ctxt, int i) +{ + BUG_ON(i >= ctxt->nr_addrs); + /* in i == 0 case, we already calculated in xecomm_addr_init() */ + if ( i != 0 ) + ctxt->address++; + + /* When crossing page boundary, machine address must be calculated. */ + if ( ((unsigned long)ctxt->address & ~PAGE_MASK) == 0 ) + { + unsigned long paddr + (unsigned long)&(ctxt->desc_in_paddr->address[i]); + struct page_info *page; + int ret; + + ret = xencomm_get_page(paddr, &page); + if ( ret == 0 ) + { + put_page(ctxt->page); + ctxt->page = page; + ctxt->address = xencomm_vaddr(paddr, page); + } + return ret; } return 0; } @@ -238,9 +252,12 @@ xencomm_copy_from_guest( /* Iterate through the descriptor, copying up to a page at a time */ while ( (to_pos < n) && (i < xencomm_ctxt_nr_addrs(&ctxt)) ) { - unsigned long src_paddr = *xencomm_ctxt_address(&ctxt, i); + unsigned long src_paddr; unsigned int pgoffset, chunksz, chunk_skip; + if ( xencomm_ctxt_next(&ctxt, i) ) + goto out; + src_paddr = *xencomm_ctxt_address(&ctxt); if ( src_paddr == XENCOMM_INVALID ) { i++; @@ -354,9 +371,12 @@ xencomm_copy_to_guest( /* Iterate through the descriptor, copying up to a page at a time */ while ( (from_pos < n) && (i < xencomm_ctxt_nr_addrs(&ctxt)) ) { - unsigned long dest_paddr = *xencomm_ctxt_address(&ctxt, i); + unsigned long dest_paddr; unsigned int pgoffset, chunksz, chunk_skip; + if ( xencomm_ctxt_next(&ctxt, i) ) + goto out; + dest_paddr = *xencomm_ctxt_address(&ctxt); if ( dest_paddr == XENCOMM_INVALID ) { i++; @@ -402,22 +422,27 @@ int xencomm_add_offset(void **handle, un { struct xencomm_ctxt ctxt; int i = 0; + int res = 0; if ( xencomm_is_inline(*handle) ) return xencomm_inline_add_offset(handle, bytes); - if ( xencomm_ctxt_init(handle, &ctxt) ) - return -1; + res = xencomm_ctxt_init(handle, &ctxt); + if ( res != 0 ) + return res; /* Iterate through the descriptor incrementing addresses */ while ( (bytes > 0) && (i < xencomm_ctxt_nr_addrs(&ctxt)) ) { - unsigned long *address = xencomm_ctxt_address(&ctxt, i); - unsigned long dest_paddr = *address; - unsigned int pgoffset; - unsigned int chunksz; - unsigned int chunk_skip; - + unsigned long *address; + unsigned long dest_paddr; + unsigned int pgoffset, chunksz, chunk_skip; + + res = xencomm_ctxt_next(&ctxt, i); + if ( res ) + goto out; + address = xencomm_ctxt_address(&ctxt); + dest_paddr = *address; if ( dest_paddr == XENCOMM_INVALID ) { i++; @@ -436,8 +461,10 @@ int xencomm_add_offset(void **handle, un i++; } + +out: xencomm_ctxt_done(&ctxt); - return 0; + return res; } int xencomm_handle_is_null(void *handle) @@ -454,7 +481,9 @@ int xencomm_handle_is_null(void *handle) for ( i = 0; i < xencomm_ctxt_nr_addrs(&ctxt); i++ ) { - if ( *xencomm_ctxt_address(&ctxt, i) != XENCOMM_INVALID ) + if ( xencomm_ctxt_next(&ctxt, i) ) + goto out; + if ( *xencomm_ctxt_address(&ctxt) != XENCOMM_INVALID ) { res = 0; goto out; _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2007-Aug-28 14:45 UTC
Re: [Xen-devel] [PATCH 2/3] xencomm take 4: xen side multiple page support
On 28/8/07 07:17, "Isaku Yamahata" <yamahata@valinux.co.jp> wrote:> +static int > +xencomm_ctxt_next(struct xencomm_ctxt *ctxt, int i) > +{ > + BUG_ON(i >= ctxt->nr_addrs); > + /* in i == 0 case, we already calculated in xecomm_addr_init() */ > + if ( i != 0 ) > + ctxt->address++;This function may deserve a comment -- what is it for? The ''i == 0'' comment is confusing, and appears to refer to a function that doesn''t exist (I couldn''t find any function with suffix _addr_init()). These patches are all in the staging tree now, so provide delta patches to apply on top. -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Isaku Yamahata
2007-Aug-29 02:43 UTC
Re: [Xen-devel] [PATCH 2/3] xencomm take 4: xen side multiple page support
On Tue, Aug 28, 2007 at 03:45:56PM +0100, Keir Fraser wrote:> On 28/8/07 07:17, "Isaku Yamahata" <yamahata@valinux.co.jp> wrote: > > > +static int > > +xencomm_ctxt_next(struct xencomm_ctxt *ctxt, int i) > > +{ > > + BUG_ON(i >= ctxt->nr_addrs); > > + /* in i == 0 case, we already calculated in xecomm_addr_init() */ > > + if ( i != 0 ) > > + ctxt->address++; > > This function may deserve a comment -- what is it for? The ''i == 0'' comment > is confusing, and appears to refer to a function that doesn''t exist (I > couldn''t find any function with suffix _addr_init()). > > These patches are all in the staging tree now, so provide delta patches to > apply on top.I attached the patch to add the comment. I hope that the comment clarify. -- yamahata _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel