[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v3 17/25] xen/arm: introduce allocate_memory
Introduce an allocate_memory function able to allocate memory for DomUs and map it at the right guest addresses, according to the guest memory map: GUEST_RAM0_BASE and GUEST_RAM1_BASE. Signed-off-by: Stefano Stabellini <stefanos@xxxxxxxxxx> --- Changes in v3: - new patch --- xen/arch/arm/domain_build.c | 125 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 124 insertions(+), 1 deletion(-) diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c index ab72c36..dfa74e4 100644 --- a/xen/arch/arm/domain_build.c +++ b/xen/arch/arm/domain_build.c @@ -369,6 +369,129 @@ static void __init allocate_memory_11(struct domain *d, } } +static bool __init insert_bank(struct domain *d, + struct kernel_info *kinfo, + struct page_info *pg, + unsigned int order) +{ + int res, i; + mfn_t smfn; + paddr_t gaddr, size; + struct membank *bank; + + smfn = page_to_mfn(pg); + size = pfn_to_paddr(1UL << order); + + /* + * DomU memory is provided in two banks: + * GUEST_RAM0_BASE - GUEST_RAM0_BASE + GUEST_RAM0_SIZE + * GUEST_RAM1_BASE - GUEST_RAM1_BASE + GUEST_RAM1_SIZE + * + * Find the right gaddr address for DomUs accordingly. + */ + gaddr = GUEST_RAM0_BASE; + if ( kinfo->mem.nr_banks > 0 ) + { + for( i = 0; i < kinfo->mem.nr_banks; i++ ) + { + bank = &kinfo->mem.bank[i]; + gaddr = bank->start + bank->size; + } + if ( bank->start == GUEST_RAM0_BASE && + gaddr + size > (GUEST_RAM0_BASE + GUEST_RAM0_SIZE) ) + gaddr = GUEST_RAM1_BASE; + if ( bank->start == GUEST_RAM1_BASE && + gaddr + size > (GUEST_RAM1_BASE + GUEST_RAM1_SIZE) ) + goto fail; + } + + dprintk(XENLOG_INFO, + "Allocated %#"PRIpaddr"-%#"PRIpaddr":%#"PRIpaddr"-%#"PRIpaddr" (%ldMB/%ldMB, order %d)\n", + mfn_to_maddr(smfn), mfn_to_maddr(smfn) + size, + gaddr, gaddr + size, + 1UL << (order + PAGE_SHIFT - 20), + /* Don't want format this as PRIpaddr (16 digit hex) */ + (unsigned long)(kinfo->unassigned_mem >> 20), + order); + + res = guest_physmap_add_page(d, gaddr_to_gfn(gaddr), smfn, order); + if ( res ) + { + dprintk(XENLOG_ERR, "Failed map pages to DOMU: %d", res); + goto fail; + } + + kinfo->unassigned_mem -= size; + bank = &kinfo->mem.bank[kinfo->mem.nr_banks]; + + bank->start = gaddr; + bank->size = size; + kinfo->mem.nr_banks++; + return true; + +fail: + free_domheap_pages(pg, order); + return false; +} + +static void __init allocate_memory(struct domain *d, struct kernel_info *kinfo) +{ + const unsigned int min_order = get_order_from_bytes(MB(4)); + struct page_info *pg; + unsigned int order = get_allocation_size(kinfo->unassigned_mem); + int i; + + dprintk(XENLOG_INFO, "Allocating mappings totalling %ldMB for dom%d:\n", + /* Don't want format this as PRIpaddr (16 digit hex) */ + (unsigned long)(kinfo->unassigned_mem >> 20), d->domain_id); + + kinfo->mem.nr_banks = 0; + + order = get_allocation_size(kinfo->unassigned_mem); + if ( order > GUEST_RAM0_SIZE ) + order = GUEST_RAM0_SIZE; + while ( kinfo->unassigned_mem ) + { + pg = alloc_domheap_pages(d, order, 0); + if ( !pg ) + { + order --; + + if ( order >= min_order ) + continue; + + /* No more we can do */ + break; + } + + if ( !insert_bank(d, kinfo, pg, order) ) + break; + + /* + * Success, next time around try again to get the largest order + * allocation possible. + */ + order = get_allocation_size(kinfo->unassigned_mem); + } + + if ( kinfo->unassigned_mem ) + dprintk(XENLOG_WARNING, "Failed to allocate requested domain memory." + /* Don't want format this as PRIpaddr (16 digit hex) */ + " %ldMB unallocated\n", + (unsigned long)kinfo->unassigned_mem >> 20); + + for( i = 0; i < kinfo->mem.nr_banks; i++ ) + { + dprintk(XENLOG_INFO, "Dom%d BANK[%d] %#"PRIpaddr"-%#"PRIpaddr" (%ldMB)\n", + d->domain_id, + i, + kinfo->mem.bank[i].start, + kinfo->mem.bank[i].start + kinfo->mem.bank[i].size, + /* Don't want format this as PRIpaddr (16 digit hex) */ + (unsigned long)(kinfo->mem.bank[i].size >> 20)); + } +} + static int __init write_properties(struct domain *d, struct kernel_info *kinfo, const struct dt_device_node *node) { @@ -2241,7 +2364,7 @@ static int __init construct_domU(struct domain *d, struct dt_device_node *node) /* type must be set before allocate memory */ d->arch.type = kinfo.type; #endif - allocate_memory_11(d, &kinfo); + allocate_memory(d, &kinfo); return __construct_domain(d, &kinfo); } -- 1.9.1 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |