|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v3 1/9] libxc: reorganize domain builder guest memory allocator
On Tue, Oct 13, 2015 at 03:11:10PM +0200, Juergen Gross wrote:
> Guest memory allocation in the domain builder of libxc is done via
> virtual addresses only. In order to be able to support preallocated
> areas not virtually mapped reorganize the memory allocator to keep
> track of allocated pages globally and in allocated segments.
>
> This requires an interface change of the allocate callback of the
> domain builder which currently is using the last mapped virtual
> address as a parameter. This is no problem as the only user of this
> callback is stubdom/grub/kexec.c using this virtual address to
> calculate the last used pfn.
>
> Signed-off-by: Juergen Gross <jgross@xxxxxxxx>
> ---
> stubdom/grub/kexec.c | 6 +--
> tools/libxc/include/xc_dom.h | 11 +++--
> tools/libxc/xc_dom_core.c | 101
> +++++++++++++++++++++++++++++--------------
> 3 files changed, 75 insertions(+), 43 deletions(-)
>
> diff --git a/stubdom/grub/kexec.c b/stubdom/grub/kexec.c
> index 0b2f4f3..2300318 100644
> --- a/stubdom/grub/kexec.c
> +++ b/stubdom/grub/kexec.c
> @@ -100,9 +100,9 @@ static void do_exchange(struct xc_dom_image *dom,
> xen_pfn_t target_pfn, xen_pfn_
> dom->p2m_host[target_pfn] = source_mfn;
> }
>
> -int kexec_allocate(struct xc_dom_image *dom, xen_vaddr_t up_to)
> +int kexec_allocate(struct xc_dom_image *dom)
> {
> - unsigned long new_allocated = (up_to - dom->parms.virt_base) / PAGE_SIZE;
> + unsigned long new_allocated = dom->pfn_alloc_end - dom->rambase_pfn;
> unsigned long i;
>
> pages = realloc(pages, new_allocated * sizeof(*pages));
> @@ -319,8 +319,6 @@ void kexec(void *kernel, long kernel_size, void *module,
> long module_size, char
>
> /* Make sure the bootstrap page table does not RW-map any of our current
> * page table frames */
> - kexec_allocate(dom, dom->virt_pgtab_end);
> -
Does this mean pvgrub is now able to use this shiny new feature?
> if ( (rc = xc_dom_update_guest_p2m(dom))) {
> grub_printf("xc_dom_update_guest_p2m returned %d\n", rc);
> errnum = ERR_BOOT_FAILURE;
> diff --git a/tools/libxc/include/xc_dom.h b/tools/libxc/include/xc_dom.h
> index e52b023..878dc52 100644
> --- a/tools/libxc/include/xc_dom.h
> +++ b/tools/libxc/include/xc_dom.h
> @@ -29,6 +29,7 @@ struct xc_dom_seg {
> xen_vaddr_t vstart;
> xen_vaddr_t vend;
> xen_pfn_t pfn;
> + xen_pfn_t pages;
> };
>
> struct xc_dom_mem {
> @@ -90,6 +91,7 @@ struct xc_dom_image {
> xen_pfn_t xenstore_pfn;
> xen_pfn_t shared_info_pfn;
> xen_pfn_t bootstack_pfn;
> + xen_pfn_t pfn_alloc_end;
> xen_vaddr_t virt_alloc_end;
> xen_vaddr_t bsd_symtab_start;
>
> @@ -177,7 +179,7 @@ struct xc_dom_image {
> /* kernel loader */
> struct xc_dom_arch *arch_hooks;
> /* allocate up to virt_alloc_end */
I think you need to update this comment, too.
> - int (*allocate) (struct xc_dom_image * dom, xen_vaddr_t up_to);
> + int (*allocate) (struct xc_dom_image * dom);
>
> /* Container type (HVM or PV). */
> enum {
> @@ -361,14 +363,11 @@ static inline void *xc_dom_seg_to_ptr_pages(struct
> xc_dom_image *dom,
> struct xc_dom_seg *seg,
> xen_pfn_t *pages_out)
> {
> - xen_vaddr_t segsize = seg->vend - seg->vstart;
> - unsigned int page_size = XC_DOM_PAGE_SIZE(dom);
> - xen_pfn_t pages = (segsize + page_size - 1) / page_size;
> void *retval;
>
> - retval = xc_dom_pfn_to_ptr(dom, seg->pfn, pages);
> + retval = xc_dom_pfn_to_ptr(dom, seg->pfn, seg->pages);
>
> - *pages_out = retval ? pages : 0;
> + *pages_out = retval ? seg->pages : 0;
> return retval;
> }
>
> diff --git a/tools/libxc/xc_dom_core.c b/tools/libxc/xc_dom_core.c
> index fbe4464..b1d7890 100644
> --- a/tools/libxc/xc_dom_core.c
> +++ b/tools/libxc/xc_dom_core.c
> @@ -535,56 +535,75 @@ void *xc_dom_pfn_to_ptr_retcount(struct xc_dom_image
> *dom, xen_pfn_t pfn,
> return phys->ptr;
> }
>
> -int xc_dom_alloc_segment(struct xc_dom_image *dom,
> - struct xc_dom_seg *seg, char *name,
> - xen_vaddr_t start, xen_vaddr_t size)
> +static int xc_dom_chk_alloc_pages(struct xc_dom_image *dom, char *name,
> + xen_pfn_t pages)
> {
> unsigned int page_size = XC_DOM_PAGE_SIZE(dom);
> - xen_pfn_t pages = (size + page_size - 1) / page_size;
> - xen_pfn_t pfn;
> - void *ptr;
>
> - if ( start == 0 )
> - start = dom->virt_alloc_end;
> + if ( pages > dom->total_pages || /* multiple test avoids overflow probs
> */
> + dom->pfn_alloc_end - dom->rambase_pfn > dom->total_pages ||
> + pages > dom->total_pages - dom->pfn_alloc_end + dom->rambase_pfn )
> + {
> + xc_dom_panic(dom->xch, XC_OUT_OF_MEMORY,
> + "%s: segment %s too large (0x%"PRIpfn" > "
> + "0x%"PRIpfn" - 0x%"PRIpfn" pages)", __FUNCTION__, name,
> + pages, dom->total_pages,
> + dom->pfn_alloc_end - dom->rambase_pfn);
> + return -1;
> + }
> +
> + dom->pfn_alloc_end += pages;
> + dom->virt_alloc_end += pages * page_size;
>
> - if ( start & (page_size - 1) )
> + return 0;
> +}
> +
> +static int xc_dom_alloc_pad(struct xc_dom_image *dom, xen_vaddr_t end)
> +{
> + unsigned int page_size = XC_DOM_PAGE_SIZE(dom);
> + xen_pfn_t pages;
> +
> + if ( end & (page_size - 1) )
> {
> xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
> "%s: segment start isn't page aligned (0x%" PRIx64 ")",
"segment end"?
> - __FUNCTION__, start);
> + __FUNCTION__, end);
> return -1;
> }
> - if ( start < dom->virt_alloc_end )
> + if ( end < dom->virt_alloc_end )
> {
> xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
> "%s: segment start too low (0x%" PRIx64 " < 0x%" PRIx64
Ditto.
A major part of this patch looks like refactoring to me. And to the
best of my knowledge it seems to be doing the right thing.
Wei.
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |