Hi Isaku,
Should we make the same changes to the common xencomm files?
(xen-ppc-devel CC'd) I don't see why we wouldn't, at least for this
first one. How much memory have you been able to assign to a domain
with theses patches? My only nit on this patch is that the
from/to_ulong variables are actually a little uglier than the handful of
casts they remove (imho). Thanks,
Alex
On Tue, 2007-07-31 at 15:10 +0900, Isaku Yamahata wrote:
> # HG changeset patch
> # User yamahata@xxxxxxxxxxxxx
> # Date 1185762640 -32400
> # Node ID fb5043d15cae94f0686f5ad009d67ff97d0a1c3c
> # Parent 4492a0285bae734ee18f6acbb6b3f9c80f153be7
> remove xencomm page size limit.
> Currently xencomm has page size limit so that a domain with many memory
> (e.g. 100GB+) can't be created.
> This patch allows that the address array of struct xencomm_desc to cross
> page boundary so that the size of struct xencomm_desc can exceed page size.
> Note that struct xencomm_desc itself can't page boundary.
> PATCHNAME: remove_xencomm_page_size_limit_xen_side
>
> Signed-off-by: Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
>
> diff -r 4492a0285bae -r fb5043d15cae xen/arch/ia64/xen/xencomm.c
> --- a/xen/arch/ia64/xen/xencomm.c Fri Jul 27 08:15:16 2007 -0600
> +++ b/xen/arch/ia64/xen/xencomm.c Mon Jul 30 11:30:40 2007 +0900
> @@ -34,6 +34,15 @@ static int xencomm_debug = 1; /* extreme
> #else
> #define xencomm_debug 0
> #endif
> +
> +static int
> +xencomm_desc_cross_page_boundary(unsigned long paddr)
> +{
> + unsigned long offset = paddr & ~PAGE_MASK;
> + if (offset > PAGE_SIZE - sizeof(struct xencomm_desc))
> + return 1;
> + return 0;
> +}
>
> static int
> xencomm_copy_chunk_from(
> @@ -85,15 +94,18 @@ xencomm_copy_from_guest(
> unsigned int n,
> unsigned int skip)
> {
> + unsigned long from_ulong = (unsigned long)from;
> struct xencomm_desc *desc;
> unsigned long desc_addr;
> + struct xencomm_desc *desc_paddr;
> + unsigned long *address;
> unsigned int from_pos = 0;
> unsigned int to_pos = 0;
> unsigned int i = 0;
>
> if (xencomm_debug)
> printk("xencomm_copy_from_guest: from=%lx+%u n=%u\n",
> - (unsigned long)from, skip, n);
> + from_ulong, skip, n);
>
> if (XENCOMM_IS_INLINE(from)) {
> unsigned long src_paddr = XENCOMM_INLINE_ADDR(from);
> @@ -121,8 +133,11 @@ xencomm_copy_from_guest(
> return 0;
> }
>
> + /* check if struct desc doesn't cross page boundry */
> + if (xencomm_desc_cross_page_boundary(from_ulong))
> + return -EINVAL;
> /* first we need to access the descriptor */
> - desc_addr = xencomm_paddr_to_maddr((unsigned long)from);
> + desc_addr = xencomm_paddr_to_maddr(from_ulong);
> if (desc_addr == 0)
> return -EFAULT;
>
> @@ -132,18 +147,26 @@ xencomm_copy_from_guest(
> __func__, desc, desc->magic);
> return -EFAULT;
> }
> + desc_paddr = (struct xencomm_desc *)from;
> + address = &desc->address[i];
>
> /* iterate through the descriptor, copying up to a page at a time */
> while ((to_pos < n) && (i < desc->nr_addrs)) {
> - unsigned long src_paddr = desc->address[i];
> + unsigned long src_paddr;
> unsigned int pgoffset;
> unsigned int chunksz;
> unsigned int chunk_skip;
>
> - if (src_paddr == XENCOMM_INVALID) {
> - i++;
> - continue;
> - }
> + /* When crossing page boundary, machine address must be calculated.
> */
> + if (((unsigned long)address & ~PAGE_MASK) == 0) {
> + address = (unsigned long*)xencomm_paddr_to_maddr(
> + (unsigned long)&desc_paddr->address[i]);
> + if (address == NULL)
> + return -EFAULT;
> + }
> + src_paddr = *address;
> + if (src_paddr == XENCOMM_INVALID)
> + goto skip_to_next;
>
> pgoffset = src_paddr % PAGE_SIZE;
> chunksz = PAGE_SIZE - pgoffset;
> @@ -170,7 +193,9 @@ xencomm_copy_from_guest(
> to_pos += bytes;
> }
>
> + skip_to_next:
> i++;
> + address++;
> }
>
> return n - to_pos;
> @@ -226,15 +251,18 @@ xencomm_copy_to_guest(
> unsigned int n,
> unsigned int skip)
> {
> + unsigned long to_ulong = (unsigned long)to;
> struct xencomm_desc *desc;
> unsigned long desc_addr;
> + struct xencomm_desc *desc_paddr;
> + unsigned long *address;
> unsigned int from_pos = 0;
> unsigned int to_pos = 0;
> unsigned int i = 0;
>
> if (xencomm_debug)
> printk ("xencomm_copy_to_guest: to=%lx+%u n=%u\n",
> - (unsigned long)to, skip, n);
> + to_ulong, skip, n);
>
> if (XENCOMM_IS_INLINE(to)) {
> unsigned long dest_paddr = XENCOMM_INLINE_ADDR(to);
> @@ -263,8 +291,11 @@ xencomm_copy_to_guest(
> return 0;
> }
>
> + /* check if struct desc doesn't cross page boundry */
> + if (xencomm_desc_cross_page_boundary(to_ulong))
> + return -EINVAL;
> /* first we need to access the descriptor */
> - desc_addr = xencomm_paddr_to_maddr((unsigned long)to);
> + desc_addr = xencomm_paddr_to_maddr(to_ulong);
> if (desc_addr == 0)
> return -EFAULT;
>
> @@ -273,18 +304,26 @@ xencomm_copy_to_guest(
> printk("%s error: %p magic was 0x%x\n", __func__, desc, desc->magic);
> return -EFAULT;
> }
> + desc_paddr = (struct xencomm_desc*)to;
> + address = &desc->address[i];
>
> /* iterate through the descriptor, copying up to a page at a time */
> while ((from_pos < n) && (i < desc->nr_addrs)) {
> - unsigned long dest_paddr = desc->address[i];
> + unsigned long dest_paddr;
> unsigned int pgoffset;
> unsigned int chunksz;
> unsigned int chunk_skip;
>
> - if (dest_paddr == XENCOMM_INVALID) {
> - i++;
> - continue;
> - }
> + /* When crossing page boundary, machine address must be calculated.
> */
> + if (((unsigned long)address & ~PAGE_MASK) == 0) {
> + address = (unsigned long*)xencomm_paddr_to_maddr(
> + (unsigned long)&desc_paddr->address[i]);
> + if (address == NULL)
> + return -EFAULT;
> + }
> + dest_paddr = *address;
> + if (dest_paddr == XENCOMM_INVALID)
> + goto skip_to_next;
>
> pgoffset = dest_paddr % PAGE_SIZE;
> chunksz = PAGE_SIZE - pgoffset;
> @@ -308,7 +347,9 @@ xencomm_copy_to_guest(
> to_pos += bytes;
> }
>
> + skip_to_next:
> i++;
> + address++;
> }
> return n - from_pos;
> }
> @@ -320,15 +361,21 @@ xencomm_add_offset(
> void *handle,
> unsigned int bytes)
> {
> + unsigned long handle_ulong = (unsigned long)handle;
> struct xencomm_desc *desc;
> unsigned long desc_addr;
> + struct xencomm_desc *desc_paddr;
> + unsigned long *address;
> int i = 0;
>
> if (XENCOMM_IS_INLINE(handle))
> return (void *)((unsigned long)handle + bytes);
>
> + /* check if struct desc doesn't cross page boundry */
> + if (xencomm_desc_cross_page_boundary(handle_ulong))
> + return NULL;
> /* first we need to access the descriptor */
> - desc_addr = xencomm_paddr_to_maddr((unsigned long)handle);
> + desc_addr = xencomm_paddr_to_maddr(handle_ulong);
> if (desc_addr == 0)
> return NULL;
>
> @@ -337,18 +384,26 @@ xencomm_add_offset(
> printk("%s error: %p magic was 0x%x\n", __func__, desc, desc->magic);
> return NULL;
> }
> + desc_paddr = (struct xencomm_desc*)handle;
> + address = &desc->address[i];
>
> /* iterate through the descriptor incrementing addresses */
> while ((bytes > 0) && (i < desc->nr_addrs)) {
> - unsigned long dest_paddr = desc->address[i];
> + unsigned long dest_paddr;
> unsigned int pgoffset;
> unsigned int chunksz;
> unsigned int chunk_skip;
>
> - if (dest_paddr == XENCOMM_INVALID) {
> - i++;
> - continue;
> - }
> + /* When crossing page boundary, machine address must be calculated.
> */
> + if (((unsigned long)address & ~PAGE_MASK) == 0) {
> + address = (unsigned long*)xencomm_paddr_to_maddr(
> + (unsigned long)&desc_paddr->address[i]);
> + if (address == NULL)
> + return NULL;
> + }
> + dest_paddr = *address;
> + if (dest_paddr == XENCOMM_INVALID)
> + goto skip_to_next;
>
> pgoffset = dest_paddr % PAGE_SIZE;
> chunksz = PAGE_SIZE - pgoffset;
> @@ -356,13 +411,15 @@ xencomm_add_offset(
> chunk_skip = min(chunksz, bytes);
> if (chunk_skip == chunksz) {
> /* exhausted this page */
> - desc->address[i] = XENCOMM_INVALID;
> + *address = XENCOMM_INVALID;
> } else {
> - desc->address[i] += chunk_skip;
> + *address += chunk_skip;
> }
> bytes -= chunk_skip;
> -
> - i++;
> +
> + skip_to_next:
> + i++;
> + address++;
> }
> return handle;
> }
>
>
> _______________________________________________
> Xen-ia64-devel mailing list
> Xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
> http://lists.xensource.com/xen-ia64-devel
--
Alex Williamson HP Open Source & Linux Org.
_______________________________________________
Xen-ia64-devel mailing list
Xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ia64-devel
|