static struct page_info * __init alloc_chunk( struct domain *d, unsigned long max_pages) { static unsigned int __initdata last_order = MAX_ORDER; static unsigned int __initdata memflags = MEMF_no_dma | MEMF_node(1); struct page_info *page; unsigned int order = get_order_from_pages(max_pages), free_order; if ( order > last_order ) order = last_order; else if ( max_pages & (max_pages - 1) ) --order; while ( (page = alloc_domheap_pages(d, order, memflags)) == NULL ) if ( order-- == 0 ) break; if ( page ) last_order = order; else if ( memflags ) { /* * Allocate up to 2MB at a time: It prevents allocating very large * chunks from DMA pools before the >4GB pool is fully depleted. */ last_order = 21 - PAGE_SHIFT; memflags = 0; return alloc_chunk(d, max_pages); } /* * Make a reasonable attempt at finding a smaller chunk at a higher * address, to avoid allocating from low memory as much as possible. */ for ( free_order = order; !memflags && page && order--; ) { struct page_info *pg2; if ( d->tot_pages + (1 << order) > d->max_pages ) continue; pg2 = alloc_domheap_pages(d, order, 0); if ( pg2 > page ) { free_domheap_pages(page, free_order); page = pg2; free_order = order; } else if ( pg2 ) free_domheap_pages(pg2, order); } return page; }
int vcpu_initialise(struct vcpu *v) { int rc = 0; BUILD_BUG_ON( sizeof(struct cpu_info) > STACK_SIZE ); v->arch.stack = alloc_xenheap_pages(STACK_ORDER, MEMF_node(vcpu_to_node(v))); if ( v->arch.stack == NULL ) return -ENOMEM; v->arch.cpu_info = (struct cpu_info *)(v->arch.stack + STACK_SIZE - sizeof(struct cpu_info)); memset(&v->arch.saved_context, 0, sizeof(v->arch.saved_context)); v->arch.saved_context.sp = (register_t)v->arch.cpu_info; v->arch.saved_context.pc = (register_t)continue_new_vcpu; /* Idle VCPUs don't need the rest of this setup */ if ( is_idle_vcpu(v) ) return rc; v->arch.sctlr = SCTLR_GUEST_INIT; /* * By default exposes an SMP system with AFF0 set to the VCPU ID * TODO: Handle multi-threading processor and cluster */ v->arch.vmpidr = MPIDR_SMP | (v->vcpu_id << MPIDR_AFF0_SHIFT); v->arch.actlr = READ_SYSREG32(ACTLR_EL1); processor_vcpu_initialise(v); if ( (rc = vcpu_vgic_init(v)) != 0 ) goto fail; if ( (rc = vcpu_vtimer_init(v)) != 0 ) goto fail; return rc; fail: vcpu_destroy(v); return rc; }
int vcpu_initialise(struct vcpu *v) { int rc = 0; BUILD_BUG_ON( sizeof(struct cpu_info) > STACK_SIZE ); v->arch.stack = alloc_xenheap_pages(STACK_ORDER, MEMF_node(vcpu_to_node(v))); if ( v->arch.stack == NULL ) return -ENOMEM; v->arch.cpu_info = (struct cpu_info *)(v->arch.stack + STACK_SIZE - sizeof(struct cpu_info)); memset(&v->arch.saved_context, 0, sizeof(v->arch.saved_context)); v->arch.saved_context.sp = (register_t)v->arch.cpu_info; v->arch.saved_context.pc = (register_t)continue_new_vcpu; /* Idle VCPUs don't need the rest of this setup */ if ( is_idle_vcpu(v) ) return rc; v->arch.sctlr = SCTLR_GUEST_INIT; v->arch.vmpidr = MPIDR_SMP | vcpuid_to_vaffinity(v->vcpu_id); v->arch.actlr = READ_SYSREG32(ACTLR_EL1); processor_vcpu_initialise(v); if ( (rc = vcpu_vgic_init(v)) != 0 ) goto fail; if ( (rc = vcpu_vtimer_init(v)) != 0 ) goto fail; return rc; fail: vcpu_destroy(v); return rc; }