diff --git a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_64 b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_64 index 21eabb7c38..6b9a05feb0 100644 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_64 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_64 @@ -2202,7 +2202,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="ascii" CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set +CONFIG_DEVFS_FS=y CONFIG_DEVPTS_FS_XATTR=y CONFIG_DEVPTS_FS_SECURITY=y CONFIG_TMPFS=y diff --git a/linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c b/linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c index 8e14408d54..8016210ece 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c @@ -22,13 +22,14 @@ #define ISA_START_ADDRESS 0x0 #define ISA_END_ADDRESS 0x100000 +#if 0 /* not PAE safe */ /* These hacky macros avoid phys->machine translations. */ #define __direct_pte(x) ((pte_t) { (x) } ) #define __direct_mk_pte(page_nr,pgprot) \ __direct_pte(((page_nr) << PAGE_SHIFT) | pgprot_val(pgprot)) #define direct_mk_pte_phys(physpage, pgprot) \ __direct_mk_pte((physpage) >> PAGE_SHIFT, pgprot) - +#endif static int direct_remap_area_pte_fn(pte_t *pte, struct page *pte_page, @@ -37,16 +38,16 @@ static int direct_remap_area_pte_fn(pte_t *pte, { mmu_update_t **v = (mmu_update_t **)data; - (*v)->ptr = ((maddr_t)pfn_to_mfn(page_to_pfn(pte_page)) << + (*v)->ptr = ((u64)pfn_to_mfn(page_to_pfn(pte_page)) << PAGE_SHIFT) | ((unsigned long)pte & ~PAGE_MASK); (*v)++; return 0; } -int direct_remap_area_pages(struct mm_struct *mm, +int direct_remap_pfn_range(struct mm_struct *mm, unsigned long address, - unsigned long machine_addr, + unsigned long mfn, unsigned long size, pgprot_t prot, domid_t domid) @@ -77,9 +78,9 @@ int direct_remap_area_pages(struct mm_struct *mm, * Fill in the machine address: PTE ptr is done later by * __direct_remap_area_pages(). */ - v->val = pte_val_ma(pfn_pte_ma(machine_addr >> PAGE_SHIFT, prot)); + v->val = pte_val_ma(pfn_pte_ma(mfn, prot)); - machine_addr += PAGE_SIZE; + mfn++; address += PAGE_SIZE; v++; } @@ -97,8 +98,10 @@ int direct_remap_area_pages(struct mm_struct *mm, return 0; } -EXPORT_SYMBOL(direct_remap_area_pages); +EXPORT_SYMBOL(direct_remap_pfn_range); + +/* FIXME: This is horribly broken on PAE */ static int lookup_pte_fn( pte_t *pte, struct page *pte_page, unsigned long addr, void *data) { @@ -218,7 +221,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l #ifdef __x86_64__ flags |= _PAGE_USER; #endif - if (direct_remap_area_pages(&init_mm, (unsigned long) addr, phys_addr, + if (direct_remap_pfn_range(&init_mm, (unsigned long) addr, phys_addr>>PAGE_SHIFT, size, __pgprot(flags), domid)) { vunmap((void __force *) addr); return NULL; diff --git a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c index a507f66d93..8226222db4 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c @@ -182,7 +182,7 @@ int blkif_ioctl(struct inode *inode, struct file *filep, static int blkif_queue_request(struct request *req) { struct blkfront_info *info = req->rq_disk->private_data; - unsigned long buffer_ma; + unsigned long buffer_mfn; blkif_request_t *ring_req; struct bio *bio; struct bio_vec *bvec; @@ -221,7 +221,7 @@ static int blkif_queue_request(struct request *req) bio_for_each_segment (bvec, bio, idx) { BUG_ON(ring_req->nr_segments == BLKIF_MAX_SEGMENTS_PER_REQUEST); - buffer_ma = page_to_phys(bvec->bv_page); + buffer_mfn = page_to_phys(bvec->bv_page) >> PAGE_SHIFT; fsect = bvec->bv_offset >> 9; lsect = fsect + (bvec->bv_len >> 9) - 1; /* install a grant reference. */ @@ -231,11 +231,11 @@ static int blkif_queue_request(struct request *req) gnttab_grant_foreign_access_ref( ref, info->backend_id, - buffer_ma >> PAGE_SHIFT, + buffer_mfn, rq_data_dir(req) ); info->shadow[id].frame[ring_req->nr_segments] = - buffer_ma >> PAGE_SHIFT; + buffer_mfn; ring_req->frame_and_sects[ring_req->nr_segments] = blkif_fas_from_gref(ref, fsect, lsect); diff --git a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c index c1694fe7bb..8b42041e62 100644 --- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c +++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c @@ -154,12 +154,12 @@ static int map_frontend_pages(netif_t *netif, unsigned long localaddr, pgprot_t prot = __pgprot(_KERNPG_TABLE); int err; - err = direct_remap_area_pages(&init_mm, localaddr, - tx_ring_ref<domid); - err |= direct_remap_area_pages(&init_mm, localaddr + PAGE_SIZE, - rx_ring_ref<domid); if (err) diff --git a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c index 32ceb5f0b9..40eac7b491 100644 --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c @@ -297,7 +297,7 @@ static void net_rx_action(unsigned long unused) mmuext->mfn = old_mfn; mmuext++; #endif - mmu->ptr = (new_mfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE; + mmu->ptr = ((unsigned long long)new_mfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE; mmu->val = __pa(vdata) >> PAGE_SHIFT; mmu++; diff --git a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c index 45755083de..e31434ac12 100644 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c @@ -618,7 +618,7 @@ static int netif_poll(struct net_device *dev, int *pbudget) /* Remap the page. */ #ifdef CONFIG_XEN_NETDEV_GRANT - mmu->ptr = mfn << PAGE_SHIFT | MMU_MACHPHYS_UPDATE; + mmu->ptr = ((unsigned long long)mfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE; #else mmu->ptr = (rx->addr & PAGE_MASK) | MMU_MACHPHYS_UPDATE; #endif diff --git a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c index ed068a06c6..a2965a0e70 100644 --- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c +++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c @@ -116,9 +116,9 @@ static int privcmd_ioctl(struct inode *inode, struct file *file, if ( (msg[j].va + (msg[j].npages< vma->vm_end ) return -EINVAL; - if ( (rc = direct_remap_area_pages(vma->vm_mm, + if ( (rc = direct_remap_pfn_range(vma->vm_mm, msg[j].va&PAGE_MASK, - msg[j].mfn<vm_page_prot, mmapcmd.dom)) < 0 ) diff --git a/linux-2.6-xen-sparse/drivers/xen/usbback/interface.c b/linux-2.6-xen-sparse/drivers/xen/usbback/interface.c index 27365b3fa6..ab44ed3040 100644 --- a/linux-2.6-xen-sparse/drivers/xen/usbback/interface.c +++ b/linux-2.6-xen-sparse/drivers/xen/usbback/interface.c @@ -161,8 +161,8 @@ void usbif_connect(usbif_be_connect_t *connect) } prot = __pgprot(_KERNPG_TABLE); - error = direct_remap_area_pages(&init_mm, VMALLOC_VMADDR(vma->addr), - shmem_frame<addr), + shmem_frame, PAGE_SIZE, prot, domid); if ( error != 0 ) { diff --git a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable.h b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable.h index 6e33a59886..4779997177 100644 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable.h +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable.h @@ -460,9 +460,9 @@ void make_pages_writable(void *va, unsigned int nr); #define kern_addr_valid(addr) (1) #endif /* !CONFIG_DISCONTIGMEM */ -int direct_remap_area_pages(struct mm_struct *mm, +int direct_remap_pfn_range(struct mm_struct *mm, unsigned long address, - unsigned long machine_addr, + unsigned long mfn, unsigned long size, pgprot_t prot, domid_t domid); @@ -474,10 +474,10 @@ int touch_pte_range(struct mm_struct *mm, unsigned long size); #define io_remap_page_range(vma,from,phys,size,prot) \ -direct_remap_area_pages(vma->vm_mm,from,phys,size,prot,DOMID_IO) +direct_remap_pfn_range(vma->vm_mm,from,phys>>PAGE_SHIFT,size,prot,DOMID_IO) #define io_remap_pfn_range(vma,from,pfn,size,prot) \ -direct_remap_area_pages(vma->vm_mm,from,pfn<vm_mm,from,pfn,size,prot,DOMID_IO) #define MK_IOSPACE_PFN(space, pfn) (pfn) #define GET_IOSPACE(pfn) 0 diff --git a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h index e8f986c452..86f1b4f7fa 100644 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h @@ -526,28 +526,26 @@ extern int kern_addr_valid(unsigned long addr); #define DOMID_LOCAL (0xFFFFU) -int direct_remap_area_pages(struct mm_struct *mm, +int direct_remap_pfn_range(struct mm_struct *mm, unsigned long address, - unsigned long machine_addr, + unsigned long mfn, unsigned long size, pgprot_t prot, domid_t domid); -int __direct_remap_area_pages(struct mm_struct *mm, - unsigned long address, - unsigned long size, - mmu_update_t *v); + int create_lookup_pte_addr(struct mm_struct *mm, unsigned long address, unsigned long *ptep); + int touch_pte_range(struct mm_struct *mm, unsigned long address, unsigned long size); #define io_remap_page_range(vma, vaddr, paddr, size, prot) \ - direct_remap_area_pages((vma)->vm_mm,vaddr,paddr,size,prot,DOMID_IO) + direct_remap_pfn_range((vma)->vm_mm,vaddr,paddr>>PAGE_SHIFT,size,prot,DOMID_IO) #define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ - direct_remap_area_pages((vma)->vm_mm,vaddr,(pfn)<vm_mm,vaddr,pfn,size,prot,DOMID_IO) #define MK_IOSPACE_PFN(space, pfn) (pfn) #define GET_IOSPACE(pfn) 0 diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c index 4b6771fd04..7181518380 100644 --- a/tools/libxc/xc_domain.c +++ b/tools/libxc/xc_domain.c @@ -262,23 +262,66 @@ int xc_domain_setmaxmem(int xc_handle, int xc_domain_memory_increase_reservation(int xc_handle, u32 domid, - unsigned int mem_kb) + unsigned long nr_extents, + unsigned int extent_order, + unsigned int address_bits, + unsigned long *extent_start) { int err; - unsigned int npages = mem_kb / (PAGE_SIZE/1024); struct xen_memory_reservation reservation = { - .nr_extents = npages, - .extent_order = 0, + .extent_start = extent_start, /* may be NULL */ + .nr_extents = nr_extents, + .extent_order = extent_order, + .address_bits = address_bits, .domid = domid }; err = xc_memory_op(xc_handle, XENMEM_increase_reservation, &reservation); - if (err == npages) + if (err == nr_extents) return 0; if (err > 0) { + fprintf(stderr,"Failed alocation for dom %d : %ld pages order %d addr_bits %d\n", + domid, nr_extents, extent_order, address_bits); errno = ENOMEM; err = -1; } return err; } + +int xc_domain_memory_decrease_reservation(int xc_handle, + u32 domid, + unsigned long nr_extents, + unsigned int extent_order, + unsigned long *extent_start) +{ + int err; + struct xen_memory_reservation reservation = { + .extent_start = extent_start, + .nr_extents = nr_extents, + .extent_order = extent_order, + .address_bits = 0, + .domid = domid + }; + + if (extent_start == NULL) + { + fprintf(stderr,"decrease_reservation extent_start is NULL!\n"); + errno = EINVAL; + err = -1; + goto out; + } + + err = xc_memory_op(xc_handle, XENMEM_increase_reservation, &reservation); + if (err == nr_extents) + return 0; + + if (err > 0) { + fprintf(stderr,"Failed de-alocation for dom %d : %ld pages order %d\n", + domid, nr_extents, extent_order); + errno = EBUSY; + err = -1; + } +out: + return err; +} diff --git a/tools/libxc/xc_linux_build.c b/tools/libxc/xc_linux_build.c index 498cb75542..1d0f6d7388 100644 --- a/tools/libxc/xc_linux_build.c +++ b/tools/libxc/xc_linux_build.c @@ -57,7 +57,7 @@ static int probeimageformat(char *image, } #define alloc_pt(ltab, vltab) \ - ltab = page_array[ppt_alloc++] << PAGE_SHIFT; \ + ltab = (unsigned long long)(page_array[ppt_alloc++]) << PAGE_SHIFT; \ if (vltab != NULL) { \ munmap(vltab, PAGE_SIZE); \ } \ @@ -128,18 +128,37 @@ static int setup_pg_tables_pae(int xc_handle, u32 dom, l1_pgentry_64_t *vl1tab=NULL, *vl1e=NULL; l2_pgentry_64_t *vl2tab=NULL, *vl2e=NULL; l3_pgentry_64_t *vl3tab=NULL, *vl3e=NULL; - unsigned long l1tab = 0; - unsigned long l2tab = 0; - unsigned long l3tab = 0; + unsigned long long l1tab = 0; + unsigned long long l2tab = 0; + unsigned long long l3tab = 0; unsigned long ppt_alloc; unsigned long count; /* First allocate page for page dir. */ ppt_alloc = (vpt_start - dsi_v_start) >> PAGE_SHIFT; + + if ( page_array[ppt_alloc] > 0xfffff ) + { + unsigned long nmfn; + nmfn = xc_make_page_below_4G( xc_handle, dom, page_array[ppt_alloc] ); + if ( nmfn == 0 ) + { + fprintf(stderr, "Couldn't get a page below 4GB :-(\n"); + goto error_out; + } + page_array[ppt_alloc] = nmfn; + } + alloc_pt(l3tab, vl3tab); vl3e = &vl3tab[l3_table_offset_pae(dsi_v_start)]; ctxt->ctrlreg[3] = l3tab; - + + if(l3tab>0xfffff000ULL) + { + fprintf(stderr,"L3TAB = %llx above 4GB!\n",l3tab); + goto error_out; + } + for ( count = 0; count < ((v_end-dsi_v_start)>>PAGE_SHIFT); count++) { if ( !((unsigned long)vl1e & (PAGE_SIZE-1)) ) @@ -525,12 +544,14 @@ static int setup_guest(int xc_handle, physmap = physmap_e = xc_map_foreign_range( xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, page_array[physmap_pfn++]); + for ( count = 0; count < nr_pages; count++ ) { if ( xc_add_mmu_update(xc_handle, mmu, - (page_array[count] << PAGE_SHIFT) | + ((unsigned long long)page_array[count] << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE, count) ) { + fprintf(stderr,"m2p update failure p=%lx m=%lx\n",count,page_array[count] ); munmap(physmap, PAGE_SIZE); goto error_out; } diff --git a/tools/libxc/xc_linux_restore.c b/tools/libxc/xc_linux_restore.c index b60c629e91..f1fb60db8d 100644 --- a/tools/libxc/xc_linux_restore.c +++ b/tools/libxc/xc_linux_restore.c @@ -149,9 +149,9 @@ int xc_linux_restore(int xc_handle, int io_fd, u32 dom, unsigned long nr_pfns, } err = xc_domain_memory_increase_reservation(xc_handle, dom, - nr_pfns * PAGE_SIZE / 1024); + nr_pfns, 0, 0, NULL); if (err != 0) { - ERR("Failed to increate reservation by %lx\n", + ERR("Failed to increase reservation by %lx\n", nr_pfns * PAGE_SIZE / 1024); errno = ENOMEM; goto out; diff --git a/tools/libxc/xc_private.c b/tools/libxc/xc_private.c index 4cbfa2f1f2..5a1d78f9d5 100644 --- a/tools/libxc/xc_private.c +++ b/tools/libxc/xc_private.c @@ -116,7 +116,7 @@ int xc_mmuext_op( if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 ) { - fprintf(stderr, "Dom_mem operation failed (rc=%ld errno=%d)-- need to" + fprintf(stderr, "Dom_mmuext operation failed (rc=%ld errno=%d)-- need to" " rebuild the user-space tool set?\n",ret,errno); } @@ -172,7 +172,7 @@ xc_mmu_t *xc_init_mmu_updates(int xc_handle, domid_t dom) } int xc_add_mmu_update(int xc_handle, xc_mmu_t *mmu, - unsigned long ptr, unsigned long val) + unsigned long long ptr, unsigned long long val) { mmu->updates[mmu->idx].ptr = ptr; mmu->updates[mmu->idx].val = val; @@ -229,7 +229,7 @@ int xc_memory_op(int xc_handle, if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 ) { - fprintf(stderr, "Dom_mem operation failed (rc=%ld errno=%d)-- need to" + fprintf(stderr, "hypercall failed (rc=%ld errno=%d)-- need to" " rebuild the user-space tool set?\n",ret,errno); } @@ -427,3 +427,21 @@ int xc_version(int xc_handle, int cmd, void *arg) { return do_xen_version(xc_handle, cmd, arg); } + +unsigned long xc_make_page_below_4G(int xc_handle, u32 domid, + unsigned long mfn) +{ + unsigned long new_mfn; + if ( xc_domain_memory_decrease_reservation( + xc_handle, domid, 1, 0, &mfn ) != 1 ) + { + fprintf(stderr,"xc_make_page_below_4G decrease failed. mfn=%lx\n",mfn); + return 0; + } + if ( xc_domain_memory_increase_reservation( xc_handle, domid, 1, 0, 32, &new_mfn ) != 1 ) + { + fprintf(stderr,"xc_make_page_below_4G increase failed. mfn=%lx\n",mfn); + return 0; + } + return new_mfn; +} diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h index 16a6339a5e..41174c1feb 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -387,7 +387,19 @@ int xc_domain_setmaxmem(int xc_handle, int xc_domain_memory_increase_reservation(int xc_handle, u32 domid, - unsigned int mem_kb); + unsigned long nr_extents, + unsigned int extent_order, + unsigned int address_bits, + unsigned long *extent_start); + +int xc_domain_memory_decrease_reservation(int xc_handle, + u32 domid, + unsigned long nr_extents, + unsigned int extent_order, + unsigned long *extent_start); + +unsigned long xc_make_page_below_4G(int xc_handle, u32 domid, + unsigned long mfn); typedef dom0_perfc_desc_t xc_perfc_desc_t; /* IMPORTANT: The caller is responsible for mlock()'ing the @desc array. */ @@ -521,7 +533,7 @@ struct xc_mmu { typedef struct xc_mmu xc_mmu_t; xc_mmu_t *xc_init_mmu_updates(int xc_handle, domid_t dom); int xc_add_mmu_update(int xc_handle, xc_mmu_t *mmu, - unsigned long ptr, unsigned long val); + unsigned long long ptr, unsigned long long val); int xc_finish_mmu_updates(int xc_handle, xc_mmu_t *mmu); #endif diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index e173f943cc..531b7a7b1c 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -841,14 +841,21 @@ static PyObject *pyxc_domain_memory_increase_reservation(PyObject *self, u32 dom; unsigned long mem_kb; + unsigned int extent_order = 0 , address_bits = 0; + unsigned long nr_extents; - static char *kwd_list[] = { "dom", "mem_kb", NULL }; + static char *kwd_list[] = { "dom", "mem_kb", "extent_order", "address_bits", NULL }; - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list, - &dom, &mem_kb) ) + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "il|ii", kwd_list, + &dom, &mem_kb, &extent_order, &address_bits) ) return NULL; - if ( xc_domain_memory_increase_reservation(xc->xc_handle, dom, mem_kb) ) + /* round down to nearest power of 2. Assume callers using extent_order>0 + know what they are doing */ + nr_extents = (mem_kb / (XC_PAGE_SIZE/1024)) >> extent_order; + if ( xc_domain_memory_increase_reservation(xc->xc_handle, dom, + nr_extents, extent_order, + address_bits, NULL) ) return PyErr_SetFromErrno(xc_error); Py_INCREF(zero); diff --git a/tools/python/xen/xend/image.py b/tools/python/xen/xend/image.py index 721dd3dab3..8b3b646afa 100644 --- a/tools/python/xen/xend/image.py +++ b/tools/python/xen/xend/image.py @@ -159,7 +159,12 @@ class ImageHandler: xc.domain_setmaxmem(dom, mem_kb) try: - xc.domain_memory_increase_reservation(dom, mem_kb) + # Give the domain some memory below 4GB + lmem_kb = 0 + if lmem_kb > 0: + xc.domain_memory_increase_reservation(dom, min(lmem_kb,mem_kb), 0, 32) + if mem_kb > lmem_kb: + xc.domain_memory_increase_reservation(dom, mem_kb-lmem_kb, 0, 0) except: xc.domain_destroy(dom) raise diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 7a15059416..0ae19d1ea3 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -381,11 +381,13 @@ static int vmx_final_setup_guest( out: free_vmcs(vmcs); if(v->arch.arch_vmx.io_bitmap_a != 0) { - free_xenheap_pages(v->arch.arch_vmx.io_bitmap_a, get_order(0x1000)); + free_xenheap_pages( + v->arch.arch_vmx.io_bitmap_a, get_order_from_bytes(0x1000)); v->arch.arch_vmx.io_bitmap_a = 0; } if(v->arch.arch_vmx.io_bitmap_b != 0) { - free_xenheap_pages(v->arch.arch_vmx.io_bitmap_b, get_order(0x1000)); + free_xenheap_pages( + v->arch.arch_vmx.io_bitmap_b, get_order_from_bytes(0x1000)); v->arch.arch_vmx.io_bitmap_b = 0; } v->arch.arch_vmx.vmcs = 0; @@ -972,11 +974,13 @@ static void vmx_relinquish_resources(struct vcpu *v) BUG_ON(v->arch.arch_vmx.vmcs == NULL); free_vmcs(v->arch.arch_vmx.vmcs); if(v->arch.arch_vmx.io_bitmap_a != 0) { - free_xenheap_pages(v->arch.arch_vmx.io_bitmap_a, get_order(0x1000)); + free_xenheap_pages( + v->arch.arch_vmx.io_bitmap_a, get_order_from_bytes(0x1000)); v->arch.arch_vmx.io_bitmap_a = 0; } if(v->arch.arch_vmx.io_bitmap_b != 0) { - free_xenheap_pages(v->arch.arch_vmx.io_bitmap_b, get_order(0x1000)); + free_xenheap_pages( + v->arch.arch_vmx.io_bitmap_b, get_order_from_bytes(0x1000)); v->arch.arch_vmx.io_bitmap_b = 0; } v->arch.arch_vmx.vmcs = 0; diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c index 98a7ec0902..0d1795150b 100644 --- a/xen/arch/x86/domain_build.c +++ b/xen/arch/x86/domain_build.c @@ -75,15 +75,12 @@ static struct pfn_info *alloc_chunk(struct domain *d, unsigned long max_pages) struct pfn_info *page; unsigned int order; /* - * Allocate up to 2MB at a time: - * 1. This prevents overflow of get_order() when allocating more than - * 4GB to domain 0 on a PAE machine. - * 2. It prevents allocating very large chunks from DMA pools before - * the >4GB pool is fully depleted. + * Allocate up to 2MB at a time: It prevents allocating very large chunks + * from DMA pools before the >4GB pool is fully depleted. */ if ( max_pages > (2UL << (20 - PAGE_SHIFT)) ) max_pages = 2UL << (20 - PAGE_SHIFT); - order = get_order(max_pages << PAGE_SHIFT); + order = get_order_from_pages(max_pages); if ( (max_pages & (max_pages-1)) != 0 ) order--; while ( (page = alloc_domheap_pages(d, order, 0)) == NULL ) @@ -252,7 +249,7 @@ int construct_dom0(struct domain *d, #endif } - order = get_order(v_end - dsi.v_start); + order = get_order_from_bytes(v_end - dsi.v_start); if ( (1UL << order) > nr_pages ) panic("Domain 0 allocation is too small for kernel image.\n"); diff --git a/xen/arch/x86/vmx_vmcs.c b/xen/arch/x86/vmx_vmcs.c index 8a2402fd9a..a870044b15 100644 --- a/xen/arch/x86/vmx_vmcs.c +++ b/xen/arch/x86/vmx_vmcs.c @@ -44,7 +44,7 @@ struct vmcs_struct *alloc_vmcs(void) rdmsr(MSR_IA32_VMX_BASIC_MSR, vmx_msr_low, vmx_msr_high); vmcs_size = vmx_msr_high & 0x1fff; - vmcs = alloc_xenheap_pages(get_order(vmcs_size)); + vmcs = alloc_xenheap_pages(get_order_from_bytes(vmcs_size)); memset((char *)vmcs, 0, vmcs_size); /* don't remove this */ vmcs->vmcs_revision_id = vmx_msr_low; @@ -55,7 +55,7 @@ void free_vmcs(struct vmcs_struct *vmcs) { int order; - order = get_order(vmcs_size); + order = get_order_from_bytes(vmcs_size); free_xenheap_pages(vmcs, order); } @@ -76,8 +76,8 @@ static inline int construct_vmcs_controls(struct arch_vmx_struct *arch_vmx) error |= __vmwrite(VM_ENTRY_CONTROLS, MONITOR_VM_ENTRY_CONTROLS); /* need to use 0x1000 instead of PAGE_SIZE */ - io_bitmap_a = (void*) alloc_xenheap_pages(get_order(0x1000)); - io_bitmap_b = (void*) alloc_xenheap_pages(get_order(0x1000)); + io_bitmap_a = (void*) alloc_xenheap_pages(get_order_from_bytes(0x1000)); + io_bitmap_b = (void*) alloc_xenheap_pages(get_order_from_bytes(0x1000)); memset(io_bitmap_a, 0xff, 0x1000); /* don't bother debug port access */ clear_bit(PC_DEBUG_PORT, io_bitmap_a); diff --git a/xen/arch/x86/x86_32/mm.c b/xen/arch/x86/x86_32/mm.c index 002b9f8bc6..25c2ea7a7d 100644 --- a/xen/arch/x86/x86_32/mm.c +++ b/xen/arch/x86/x86_32/mm.c @@ -118,7 +118,8 @@ void __init paging_init(void) } /* Set up mapping cache for domain pages. */ - mapcache_order = get_order(MAPCACHE_MBYTES << (20 - PAGETABLE_ORDER)); + mapcache_order = get_order_from_bytes( + MAPCACHE_MBYTES << (20 - PAGETABLE_ORDER)); mapcache = alloc_xenheap_pages(mapcache_order); memset(mapcache, 0, PAGE_SIZE << mapcache_order); for ( i = 0; i < (MAPCACHE_MBYTES >> (L2_PAGETABLE_SHIFT - 20)); i++ ) diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index 69ab0580b5..d444fb4136 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -399,7 +399,7 @@ __gnttab_map_grant_ref( { int i; grant_mapping_t *new_mt; - grant_table_t *lgt = ld->grant_table; + grant_table_t *lgt = ld->grant_table; if ( (lgt->maptrack_limit << 1) > MAPTRACK_MAX_ENTRIES ) { @@ -437,9 +437,8 @@ __gnttab_map_grant_ref( ref, dom, dev_hst_ro_flags); #endif - if ( 0 <= ( rc = __gnttab_activate_grant_ref( ld, led, rd, ref, - dev_hst_ro_flags, - addr, &frame))) + if ( (rc = __gnttab_activate_grant_ref(ld, led, rd, ref, dev_hst_ro_flags, + addr, &frame)) >= 0 ) { /* * Only make the maptrack live _after_ writing the pte, in case we @@ -807,7 +806,8 @@ gnttab_donate(gnttab_donate_t *uop, unsigned int count) int i; int result = GNTST_okay; - for (i = 0; i < count; i++) { + for ( i = 0; i < count; i++ ) + { gnttab_donate_t *gop = &uop[i]; #if GRANT_DEBUG printk("gnttab_donate: i=%d mfn=%lx domid=%d gref=%08x\n", @@ -815,19 +815,24 @@ gnttab_donate(gnttab_donate_t *uop, unsigned int count) #endif page = &frame_table[gop->mfn]; - if (unlikely(IS_XEN_HEAP_FRAME(page))) { + if ( unlikely(IS_XEN_HEAP_FRAME(page))) + { printk("gnttab_donate: xen heap frame mfn=%lx\n", (unsigned long) gop->mfn); gop->status = GNTST_bad_virt_addr; continue; } - if (unlikely(!pfn_valid(page_to_pfn(page)))) { + + if ( unlikely(!pfn_valid(page_to_pfn(page))) ) + { printk("gnttab_donate: invalid pfn for mfn=%lx\n", (unsigned long) gop->mfn); gop->status = GNTST_bad_virt_addr; continue; } - if (unlikely((e = find_domain_by_id(gop->domid)) == NULL)) { + + if ( unlikely((e = find_domain_by_id(gop->domid)) == NULL) ) + { printk("gnttab_donate: can't find domain %d\n", gop->domid); gop->status = GNTST_bad_domain; continue; @@ -881,48 +886,23 @@ gnttab_donate(gnttab_donate_t *uop, unsigned int count) * headroom. Also, a domain mustn't have PGC_allocated * pages when it is dying. */ -#ifdef GRANT_DEBUG - if (unlikely(e->tot_pages >= e->max_pages)) { - printk("gnttab_dontate: no headroom tot_pages=%d max_pages=%d\n", - e->tot_pages, e->max_pages); + if ( unlikely(test_bit(DOMFLAGS_DYING, &e->domain_flags)) || + unlikely(e->tot_pages >= e->max_pages) || + unlikely(!gnttab_prepare_for_transfer(e, d, gop->handle)) ) + { + DPRINTK("gnttab_donate: Transferee has no reservation headroom " + "(%d,%d) or provided a bad grant ref (%08x) or " + "is dying (%lx)\n", + e->tot_pages, e->max_pages, gop->handle, e->domain_flags); spin_unlock(&e->page_alloc_lock); put_domain(e); gop->status = result = GNTST_general_error; break; } - if (unlikely(test_bit(DOMFLAGS_DYING, &e->domain_flags))) { - printk("gnttab_donate: target domain is dying\n"); - spin_unlock(&e->page_alloc_lock); - put_domain(e); - gop->status = result = GNTST_general_error; - break; - } - if (unlikely(!gnttab_prepare_for_transfer(e, d, gop->handle))) { - printk("gnttab_donate: gnttab_prepare_for_transfer fails.\n"); - spin_unlock(&e->page_alloc_lock); - put_domain(e); - gop->status = result = GNTST_general_error; - break; - } -#else - ASSERT(e->tot_pages <= e->max_pages); - if (unlikely(test_bit(DOMFLAGS_DYING, &e->domain_flags)) || - unlikely(e->tot_pages == e->max_pages) || - unlikely(!gnttab_prepare_for_transfer(e, d, gop->handle))) { - printk("gnttab_donate: Transferee has no reservation headroom (%d," - "%d) or provided a bad grant ref (%08x) or is dying (%p)\n", - e->tot_pages, e->max_pages, gop->handle, e->d_flags); - spin_unlock(&e->page_alloc_lock); - put_domain(e); - /* XXX SMH: better error return here would be useful */ - gop->status = result = GNTST_general_error; - break; - } -#endif + /* Okay, add the page to 'e'. */ - if (unlikely(e->tot_pages++ == 0)) { + if ( unlikely(e->tot_pages++ == 0) ) get_knownalive_domain(e); - } list_add_tail(&page->list, &e->page_list); page_set_owner(page, e); @@ -938,6 +918,7 @@ gnttab_donate(gnttab_donate_t *uop, unsigned int count) gop->status = GNTST_okay; } + return result; } @@ -957,38 +938,38 @@ do_grant_table_op( rc = -EFAULT; switch ( cmd ) - { - case GNTTABOP_map_grant_ref: - if ( unlikely(!array_access_ok( - uop, count, sizeof(gnttab_map_grant_ref_t))) ) - goto out; - rc = gnttab_map_grant_ref((gnttab_map_grant_ref_t *)uop, count); - break; - case GNTTABOP_unmap_grant_ref: - if ( unlikely(!array_access_ok( - uop, count, sizeof(gnttab_unmap_grant_ref_t))) ) - goto out; - rc = gnttab_unmap_grant_ref((gnttab_unmap_grant_ref_t *)uop, - count); - break; - case GNTTABOP_setup_table: - rc = gnttab_setup_table((gnttab_setup_table_t *)uop, count); - break; + { + case GNTTABOP_map_grant_ref: + if ( unlikely(!array_access_ok( + uop, count, sizeof(gnttab_map_grant_ref_t))) ) + goto out; + rc = gnttab_map_grant_ref((gnttab_map_grant_ref_t *)uop, count); + break; + case GNTTABOP_unmap_grant_ref: + if ( unlikely(!array_access_ok( + uop, count, sizeof(gnttab_unmap_grant_ref_t))) ) + goto out; + rc = gnttab_unmap_grant_ref( + (gnttab_unmap_grant_ref_t *)uop, count); + break; + case GNTTABOP_setup_table: + rc = gnttab_setup_table((gnttab_setup_table_t *)uop, count); + break; #if GRANT_DEBUG - case GNTTABOP_dump_table: - rc = gnttab_dump_table((gnttab_dump_table_t *)uop); - break; + case GNTTABOP_dump_table: + rc = gnttab_dump_table((gnttab_dump_table_t *)uop); + break; #endif - case GNTTABOP_donate: - if (unlikely(!array_access_ok(uop, count, - sizeof(gnttab_donate_t)))) - goto out; - rc = gnttab_donate(uop, count); - break; - default: - rc = -ENOSYS; - break; - } + case GNTTABOP_donate: + if (unlikely(!array_access_ok( + uop, count, sizeof(gnttab_donate_t)))) + goto out; + rc = gnttab_donate(uop, count); + break; + default: + rc = -ENOSYS; + break; + } out: UNLOCK_BIGLOCK(d); @@ -1021,17 +1002,17 @@ gnttab_check_unmap( lgt = ld->grant_table; #if GRANT_DEBUG_VERBOSE - if ( ld->domain_id != 0 ) { - DPRINTK("Foreign unref rd(%d) ld(%d) frm(%lx) flgs(%x).\n", - rd->domain_id, ld->domain_id, frame, readonly); - } + if ( ld->domain_id != 0 ) + DPRINTK("Foreign unref rd(%d) ld(%d) frm(%lx) flgs(%x).\n", + rd->domain_id, ld->domain_id, frame, readonly); #endif /* Fast exit if we're not mapping anything using grant tables */ if ( lgt->map_count == 0 ) return 0; - if ( get_domain(rd) == 0 ) { + if ( get_domain(rd) == 0 ) + { DPRINTK("gnttab_check_unmap: couldn't get_domain rd(%d)\n", rd->domain_id); return 0; @@ -1268,8 +1249,11 @@ grant_table_create( for ( i = 0; i < NR_GRANT_FRAMES; i++ ) { SHARE_PFN_WITH_DOMAIN( - virt_to_page((char *)(t->shared)+(i*PAGE_SIZE)), d); - set_pfn_from_mfn((virt_to_phys(t->shared) >> PAGE_SHIFT) + i, INVALID_M2P_ENTRY); + virt_to_page((char *)t->shared + (i * PAGE_SIZE)), + d); + set_pfn_from_mfn( + (virt_to_phys(t->shared) >> PAGE_SHIFT) + i, + INVALID_M2P_ENTRY); } /* Okay, install the structure. */ @@ -1306,57 +1290,53 @@ gnttab_release_dev_mappings(grant_table_t *gt) { map = >->maptrack[handle]; - if ( map->ref_and_flags & GNTMAP_device_map ) + if ( !(map->ref_and_flags & GNTMAP_device_map) ) + continue; + + dom = map->domid; + ref = map->ref_and_flags >> MAPTRACK_REF_SHIFT; + + DPRINTK("Grant release (%hu) ref:(%hu) flags:(%x) dom:(%hu)\n", + handle, ref, map->ref_and_flags & MAPTRACK_GNTMAP_MASK, dom); + + if ( unlikely((rd = find_domain_by_id(dom)) == NULL) || + unlikely(ld == rd) ) { - dom = map->domid; - ref = map->ref_and_flags >> MAPTRACK_REF_SHIFT; - - DPRINTK("Grant release (%hu) ref:(%hu) flags:(%x) dom:(%hu)\n", - handle, ref, - map->ref_and_flags & MAPTRACK_GNTMAP_MASK, dom); - - if ( unlikely((rd = find_domain_by_id(dom)) == NULL) || - unlikely(ld == rd) ) - { - if ( rd != NULL ) - put_domain(rd); - - printk(KERN_WARNING "Grant release: No dom%d\n", dom); - continue; - } - - act = &rd->grant_table->active[ref]; - sha = &rd->grant_table->shared[ref]; - - spin_lock(&rd->grant_table->lock); - - if ( act->pin & (GNTPIN_devw_mask | GNTPIN_devr_mask) ) - { - frame = act->frame; - - if ( ( (act->pin & GNTPIN_hstw_mask) == 0 ) && - ( (act->pin & GNTPIN_devw_mask) > 0 ) ) - { - clear_bit(_GTF_writing, &sha->flags); - put_page_type(&frame_table[frame]); - } - - act->pin &= ~(GNTPIN_devw_mask | GNTPIN_devr_mask); - - if ( act->pin == 0 ) - { - clear_bit(_GTF_reading, &sha->flags); - map->ref_and_flags = 0; - put_page(&frame_table[frame]); - } - else - map->ref_and_flags &= ~GNTMAP_device_map; - } - - spin_unlock(&rd->grant_table->lock); - - put_domain(rd); + if ( rd != NULL ) + put_domain(rd); + printk(KERN_WARNING "Grant release: No dom%d\n", dom); + continue; } + + act = &rd->grant_table->active[ref]; + sha = &rd->grant_table->shared[ref]; + + spin_lock(&rd->grant_table->lock); + + if ( act->pin & (GNTPIN_devw_mask | GNTPIN_devr_mask) ) + { + frame = act->frame; + + if ( ( (act->pin & GNTPIN_hstw_mask) == 0 ) && + ( (act->pin & GNTPIN_devw_mask) > 0 ) ) + { + clear_bit(_GTF_writing, &sha->flags); + put_page_type(&frame_table[frame]); + } + + map->ref_and_flags &= ~GNTMAP_device_map; + act->pin &= ~(GNTPIN_devw_mask | GNTPIN_devr_mask); + if ( act->pin == 0 ) + { + clear_bit(_GTF_reading, &sha->flags); + map->ref_and_flags = 0; + put_page(&frame_table[frame]); + } + } + + spin_unlock(&rd->grant_table->lock); + + put_domain(rd); } } diff --git a/xen/common/memory.c b/xen/common/memory.c index ca394edb81..45e9cc6852 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -31,8 +31,8 @@ increase_reservation( struct pfn_info *page; unsigned long i; - if ( (extent_list != NULL) - && !array_access_ok(extent_list, nr_extents, sizeof(*extent_list)) ) + if ( (extent_list != NULL) && + !array_access_ok(extent_list, nr_extents, sizeof(*extent_list)) ) return 0; if ( (extent_order != 0) && !IS_CAPABLE_PHYSDEV(current->domain) ) @@ -52,13 +52,14 @@ increase_reservation( if ( unlikely((page = alloc_domheap_pages( d, extent_order, flags)) == NULL) ) { - DPRINTK("Could not allocate a frame\n"); + DPRINTK("Could not allocate order=%d extent: id=%d flags=%x\n", + extent_order, d->domain_id, flags); return i; } /* Inform the domain of the new page's machine address. */ - if ( (extent_list != NULL) - && (__put_user(page_to_pfn(page), &extent_list[i]) != 0) ) + if ( (extent_list != NULL) && + (__put_user(page_to_pfn(page), &extent_list[i]) != 0) ) return i; } @@ -152,8 +153,9 @@ long do_memory_op(int cmd, void *arg) reservation.extent_start += start_extent; reservation.nr_extents -= start_extent; - if ( unlikely(reservation.address_bits != 0) - && (reservation.address_bits > (get_order(max_page)+PAGE_SHIFT)) ) + if ( (reservation.address_bits != 0) && + (reservation.address_bits < + (get_order_from_pages(max_page) + PAGE_SHIFT)) ) { if ( reservation.address_bits < 31 ) return -ENOMEM; diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c index 9e1059aadd..d4ae62ee2e 100644 --- a/xen/common/page_alloc.c +++ b/xen/common/page_alloc.c @@ -216,7 +216,7 @@ unsigned long alloc_boot_pages(unsigned long nr_pfns, unsigned long pfn_align) #define NR_ZONES 3 -#define MAX_DMADOM_PFN 0x7FFFF /* 31 addressable bits */ +#define MAX_DMADOM_PFN 0x7FFFFUL /* 31 addressable bits */ #define pfn_dom_zone_type(_pfn) \ (((_pfn) <= MAX_DMADOM_PFN) ? MEMZONE_DMADOM : MEMZONE_DOM) @@ -485,43 +485,40 @@ void free_xenheap_pages(void *v, unsigned int order) void init_domheap_pages(physaddr_t ps, physaddr_t pe) { + unsigned long s_tot, e_tot, s_dma, e_dma, s_nrm, e_nrm; + ASSERT(!in_irq()); - ps = round_pgup(ps) >> PAGE_SHIFT; - pe = round_pgdown(pe) >> PAGE_SHIFT; - if ( pe <= ps ) - return; + s_tot = round_pgup(ps) >> PAGE_SHIFT; + e_tot = round_pgdown(pe) >> PAGE_SHIFT; - if ( (ps < MAX_DMADOM_PFN) && (pe > MAX_DMADOM_PFN) ) - { - init_heap_pages( - MEMZONE_DMADOM, pfn_to_page(ps), MAX_DMADOM_PFN - ps); - init_heap_pages( - MEMZONE_DOM, pfn_to_page(MAX_DMADOM_PFN), pe - MAX_DMADOM_PFN); - } - else - { - init_heap_pages(pfn_dom_zone_type(ps), pfn_to_page(ps), pe - ps); - } + s_dma = min(s_tot, MAX_DMADOM_PFN + 1); + e_dma = min(e_tot, MAX_DMADOM_PFN + 1); + if ( s_dma < e_dma ) + init_heap_pages(MEMZONE_DMADOM, pfn_to_page(s_dma), e_dma - s_dma); + + s_nrm = max(s_tot, MAX_DMADOM_PFN + 1); + e_nrm = max(e_tot, MAX_DMADOM_PFN + 1); + if ( s_nrm < e_nrm ) + init_heap_pages(MEMZONE_DOM, pfn_to_page(s_nrm), e_nrm - s_nrm); } struct pfn_info *alloc_domheap_pages( struct domain *d, unsigned int order, unsigned int flags) { - struct pfn_info *pg; + struct pfn_info *pg = NULL; cpumask_t mask; int i; ASSERT(!in_irq()); - pg = NULL; - if (! (flags & ALLOC_DOM_DMA)) + if ( !(flags & ALLOC_DOM_DMA) ) pg = alloc_heap_pages(MEMZONE_DOM, order); - if (pg == NULL) { - if ( unlikely((pg = alloc_heap_pages(MEMZONE_DMADOM, order)) == NULL) ) + + if ( pg == NULL ) + if ( (pg = alloc_heap_pages(MEMZONE_DMADOM, order)) == NULL ) return NULL; - } mask = pg->u.free.cpumask; tlbflush_filter(mask, pg->tlbflush_timestamp); diff --git a/xen/common/trace.c b/xen/common/trace.c index c5af36c4a0..7ba71a8009 100644 --- a/xen/common/trace.c +++ b/xen/common/trace.c @@ -66,7 +66,7 @@ void init_trace_bufs(void) } nr_pages = num_online_cpus() * opt_tbuf_size; - order = get_order(nr_pages * PAGE_SIZE); + order = get_order_from_pages(nr_pages); if ( (rawbuf = alloc_xenheap_pages(order)) == NULL ) { diff --git a/xen/common/xmalloc.c b/xen/common/xmalloc.c index 70c9c7fb29..5c0c02c754 100644 --- a/xen/common/xmalloc.c +++ b/xen/common/xmalloc.c @@ -86,7 +86,7 @@ static void *xmalloc_new_page(size_t size) static void *xmalloc_whole_pages(size_t size) { struct xmalloc_hdr *hdr; - unsigned int pageorder = get_order(size); + unsigned int pageorder = get_order_from_bytes(size); hdr = alloc_xenheap_pages(pageorder); if ( hdr == NULL ) @@ -159,7 +159,7 @@ void xfree(const void *p) /* Big allocs free directly. */ if ( hdr->size >= PAGE_SIZE ) { - free_xenheap_pages(hdr, get_order(hdr->size)); + free_xenheap_pages(hdr, get_order_from_bytes(hdr->size)); return; } diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c index 22524db86e..782ec814bf 100644 --- a/xen/drivers/char/console.c +++ b/xen/drivers/char/console.c @@ -627,7 +627,7 @@ static int __init debugtrace_init(void) if ( bytes == 0 ) return 0; - order = get_order(bytes); + order = get_order_from_bytes(bytes); debugtrace_buf = alloc_xenheap_pages(order); ASSERT(debugtrace_buf != NULL); diff --git a/xen/drivers/char/serial.c b/xen/drivers/char/serial.c index ad5ad5cde0..5eb0589443 100644 --- a/xen/drivers/char/serial.c +++ b/xen/drivers/char/serial.c @@ -366,8 +366,9 @@ void serial_register_uart(int idx, struct uart_driver *driver, void *uart) void serial_async_transmit(struct serial_port *port) { BUG_ON(!port->driver->tx_empty); - if ( !port->txbuf ) - port->txbuf = alloc_xenheap_pages(get_order(SERIAL_TXBUFSZ)); + if ( port->txbuf == NULL ) + port->txbuf = alloc_xenheap_pages( + get_order_from_bytes(SERIAL_TXBUFSZ)); } /* diff --git a/xen/include/asm-x86/page.h b/xen/include/asm-x86/page.h index 71edad1530..d84a73a4f1 100644 --- a/xen/include/asm-x86/page.h +++ b/xen/include/asm-x86/page.h @@ -280,7 +280,7 @@ extern void paging_init(void); #ifndef __ASSEMBLY__ -static __inline__ int get_order(unsigned long size) +static inline int get_order_from_bytes(physaddr_t size) { int order; size = (size-1) >> PAGE_SHIFT; @@ -289,6 +289,15 @@ static __inline__ int get_order(unsigned long size) return order; } +static inline int get_order_from_pages(unsigned long nr_pages) +{ + int order; + nr_pages--; + for ( order = 0; nr_pages; order++ ) + nr_pages >>= 1; + return order; +} + /* Allocator functions for Xen pagetables. */ struct pfn_info *alloc_xen_pagetable(void); void free_xen_pagetable(struct pfn_info *pg);