static unsigned long __init compute_dom0_nr_pages( struct domain *d, struct elf_dom_parms *parms, unsigned long initrd_len) { unsigned long avail = avail_domheap_pages() + initial_images_nrpages(); unsigned long nr_pages = dom0_nrpages; unsigned long min_pages = dom0_min_nrpages; unsigned long max_pages = dom0_max_nrpages; /* Reserve memory for further dom0 vcpu-struct allocations... */ avail -= (opt_dom0_max_vcpus - 1UL) << get_order_from_bytes(sizeof(struct vcpu)); /* ...and compat_l4's, if needed. */ if ( is_pv_32on64_domain(d) ) avail -= opt_dom0_max_vcpus - 1; /* Reserve memory for iommu_dom0_init() (rough estimate). */ if ( iommu_enabled ) { unsigned int s; for ( s = 9; s < BITS_PER_LONG; s += 9 ) avail -= max_pdx >> s; } /* * If domain 0 allocation isn't specified, reserve 1/16th of available * memory for things like DMA buffers. This reservation is clamped to * a maximum of 128MB. */ if ( nr_pages == 0 ) nr_pages = -min(avail / 16, 128UL << (20 - PAGE_SHIFT)); /* Negative memory specification means "all memory - specified amount". */ if ( (long)nr_pages < 0 ) nr_pages += avail; if ( (long)min_pages < 0 ) min_pages += avail; if ( (long)max_pages < 0 ) max_pages += avail; /* Clamp dom0 memory according to min/max limits and available memory. */ nr_pages = max(nr_pages, min_pages); nr_pages = min(nr_pages, max_pages); nr_pages = min(nr_pages, avail); #ifdef __x86_64__ if ( (parms->p2m_base == UNSET_ADDR) && (dom0_nrpages <= 0) && ((dom0_min_nrpages <= 0) || (nr_pages > min_pages)) ) { /* * Legacy Linux kernels (i.e. such without a XEN_ELFNOTE_INIT_P2M * note) require that there is enough virtual space beyond the initial * allocation to set up their initial page tables. This space is * roughly the same size as the p2m table, so make sure the initial * allocation doesn't consume more than about half the space that's * available between params.virt_base and the address space end. */ unsigned long vstart, vend, end; size_t sizeof_long = is_pv_32bit_domain(d) ? sizeof(int) : sizeof(long); vstart = parms->virt_base; vend = round_pgup(parms->virt_kend); if ( !parms->elf_notes[XEN_ELFNOTE_MOD_START_PFN].data.num ) vend += round_pgup(initrd_len); end = vend + nr_pages * sizeof_long; if ( end > vstart ) end += end - vstart; if ( end <= vstart || (sizeof_long < sizeof(end) && end > (1UL << (8 * sizeof_long))) ) { end = sizeof_long >= sizeof(end) ? 0 : 1UL << (8 * sizeof_long); nr_pages = (end - vend) / (2 * sizeof_long); if ( dom0_min_nrpages > 0 && nr_pages < min_pages ) nr_pages = min_pages; printk("Dom0 memory clipped to %lu pages\n", nr_pages); } } #endif d->max_pages = min_t(unsigned long, max_pages, UINT_MAX); return nr_pages; }
domain_set_alloc_bitsize(d); /* * Why do we need this? The number of page-table frames depends on the * size of the bootstrap address space. But the size of the address space * depends on the number of page-table frames (since each one is mapped * read-only). We have a pair of simultaneous equations in two unknowns, * which we solve by exhaustive search. */ v_start = parms.virt_base; vkern_start = parms.virt_kstart; vkern_end = parms.virt_kend; vinitrd_start = round_pgup(vkern_end); vinitrd_end = vinitrd_start + initrd_len; vphysmap_start = round_pgup(vinitrd_end); vphysmap_end = vphysmap_start + (nr_pages * (!is_pv_32on64_domain(d) ? sizeof(unsigned long) : sizeof(unsigned int))); vstartinfo_start = round_pgup(vphysmap_end); vstartinfo_end = (vstartinfo_start + sizeof(struct start_info) + sizeof(struct dom0_vga_console_info)); vpt_start = round_pgup(vstartinfo_end); for ( nr_pt_pages = 2; ; nr_pt_pages++ ) { vpt_end = vpt_start + (nr_pt_pages * PAGE_SIZE); vstack_start = vpt_end; vstack_end = vstack_start + PAGE_SIZE; v_end = (vstack_end + (1UL<<22)-1) & ~((1UL<<22)-1); if ( (v_end - vstack_end) < (512UL << 10) ) v_end += 1UL << 22; /* Add extra 4MB to get >= 512kB padding. */
static int alloc_xenoprof_struct( struct domain *d, int max_samples, int is_passive) { struct vcpu *v; int nvcpu, npages, bufsize, max_bufsize; unsigned max_max_samples; int i; d->xenoprof = xmalloc(struct xenoprof); if ( d->xenoprof == NULL ) { printk("alloc_xenoprof_struct(): memory allocation failed\n"); return -ENOMEM; } memset(d->xenoprof, 0, sizeof(*d->xenoprof)); d->xenoprof->vcpu = xmalloc_array(struct xenoprof_vcpu, d->max_vcpus); if ( d->xenoprof->vcpu == NULL ) { xfree(d->xenoprof); d->xenoprof = NULL; printk("alloc_xenoprof_struct(): vcpu array allocation failed\n"); return -ENOMEM; } memset(d->xenoprof->vcpu, 0, d->max_vcpus * sizeof(*d->xenoprof->vcpu)); nvcpu = 0; for_each_vcpu ( d, v ) nvcpu++; bufsize = sizeof(struct xenoprof_buf); i = sizeof(struct event_log); #ifdef CONFIG_COMPAT d->xenoprof->is_compat = is_pv_32on64_domain(is_passive ? dom0 : d); if ( XENOPROF_COMPAT(d->xenoprof) ) { bufsize = sizeof(struct compat_oprof_buf); i = sizeof(struct compat_event_log); } #endif /* reduce max_samples if necessary to limit pages allocated */ max_bufsize = (MAX_OPROF_SHARED_PAGES * PAGE_SIZE) / nvcpu; max_max_samples = ( (max_bufsize - bufsize) / i ) + 1; if ( (unsigned)max_samples > max_max_samples ) max_samples = max_max_samples; bufsize += (max_samples - 1) * i; npages = (nvcpu * bufsize - 1) / PAGE_SIZE + 1; d->xenoprof->rawbuf = alloc_xenheap_pages(get_order_from_pages(npages), 0); if ( d->xenoprof->rawbuf == NULL ) { xfree(d->xenoprof); d->xenoprof = NULL; return -ENOMEM; } d->xenoprof->npages = npages; d->xenoprof->nbuf = nvcpu; d->xenoprof->bufsize = bufsize; d->xenoprof->domain_ready = 0; d->xenoprof->domain_type = XENOPROF_DOMAIN_IGNORED; /* Update buffer pointers for active vcpus */ i = 0; for_each_vcpu ( d, v ) { xenoprof_buf_t *buf = (xenoprof_buf_t *) &d->xenoprof->rawbuf[i * bufsize]; d->xenoprof->vcpu[v->vcpu_id].event_size = max_samples; d->xenoprof->vcpu[v->vcpu_id].buffer = buf; xenoprof_buf(d, buf, event_size) = max_samples; xenoprof_buf(d, buf, vcpu_id) = v->vcpu_id; i++; /* in the unlikely case that the number of active vcpus changes */ if ( i >= nvcpu ) break; }