[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 36/38] libxc: add ARM support to xc_dom (PV domain building)
On Fri, 1 Jun 2012, Ian Campbell wrote: > Includes ARM zImage support. > > Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx> > --- > tools/libxc/Makefile | 1 + > tools/libxc/xc_dom.h | 5 +- > tools/libxc/xc_dom_arm.c | 135 +++++++++++++++++++++++++++- > tools/libxc/xc_dom_armzimageloader.c | 167 > ++++++++++++++++++++++++++++++++++ > tools/libxc/xc_dom_core.c | 12 ++- > tools/libxc/xg_private.h | 4 + > 6 files changed, 315 insertions(+), 9 deletions(-) > create mode 100644 tools/libxc/xc_dom_armzimageloader.c > > diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile > index ca38cbd..a01d457 100644 > --- a/tools/libxc/Makefile > +++ b/tools/libxc/Makefile > @@ -59,6 +59,7 @@ GUEST_SRCS-y += libelf-dominfo.c libelf-relocate.c > GUEST_SRCS-y += xc_dom_core.c xc_dom_boot.c > GUEST_SRCS-y += xc_dom_elfloader.c > GUEST_SRCS-$(CONFIG_X86) += xc_dom_bzimageloader.c > +GUEST_SRCS-$(CONFIG_ARM) += xc_dom_armzimageloader.c > GUEST_SRCS-y += xc_dom_binloader.c > GUEST_SRCS-y += xc_dom_compat_linux.c > > diff --git a/tools/libxc/xc_dom.h b/tools/libxc/xc_dom.h > index 2aef64a..4db8fad 100644 > --- a/tools/libxc/xc_dom.h > +++ b/tools/libxc/xc_dom.h > @@ -93,6 +93,7 @@ struct xc_dom_image { > void *p2m_guest; > > /* physical memory */ > + xen_pfn_t rambase_pfn; > xen_pfn_t total_pages; > struct xc_dom_phys *phys_pages; > int realmodearea_log; > @@ -286,7 +287,7 @@ static inline xen_pfn_t xc_dom_p2m_host(struct > xc_dom_image *dom, xen_pfn_t pfn) > { > if (dom->shadow_enabled) > return pfn; > - return dom->p2m_host[pfn]; > + return dom->p2m_host[pfn - dom->rambase_pfn]; > } > > static inline xen_pfn_t xc_dom_p2m_guest(struct xc_dom_image *dom, > @@ -294,7 +295,7 @@ static inline xen_pfn_t xc_dom_p2m_guest(struct > xc_dom_image *dom, > { > if (xc_dom_feature_translated(dom)) > return pfn; > - return dom->p2m_host[pfn]; > + return dom->p2m_host[pfn - dom->rambase_pfn]; > } I take that rambase_pfn is the offset in the guest physical address space where the ram is located. It would be nice to write it down. > /* --- arch bits --------------------------------------------------- */ > diff --git a/tools/libxc/xc_dom_arm.c b/tools/libxc/xc_dom_arm.c > index 122d0e8..9099cad 100644 > --- a/tools/libxc/xc_dom_arm.c > +++ b/tools/libxc/xc_dom_arm.c > @@ -18,14 +18,138 @@ > * Copyright (c) 2011, Citrix Systems > */ > #include <inttypes.h> > + > #include <xen/xen.h> > +#include <xen/io/protocols.h> > + > #include "xg_private.h" > #include "xc_dom.h" > > +/* ------------------------------------------------------------------------ > */ > +/* > + * arm guests are hybrid and start off with paging disabled, therefore no > + * pagetables and nothing to do here. > + */ > +static int count_pgtables_arm(struct xc_dom_image *dom) > +{ > + DOMPRINTF_CALLED(dom->xch); > + return 0; > +} > + > +static int setup_pgtables_arm(struct xc_dom_image *dom) > +{ > + DOMPRINTF_CALLED(dom->xch); > + return 0; > +} > + > +/* ------------------------------------------------------------------------ > */ > + > +static int alloc_magic_pages(struct xc_dom_image *dom) > +{ > + DOMPRINTF_CALLED(dom->xch); > + /* XXX > + * dom->p2m_guest > + * dom->start_info_pfn > + * dom->xenstore_pfn > + * dom->console_pfn > + */ > + return 0; > +} > + > +/* ------------------------------------------------------------------------ > */ > + > +static int start_info_arm(struct xc_dom_image *dom) > +{ > + DOMPRINTF_CALLED(dom->xch); > + /* XXX */ > + return 0; > +} > + > +static int shared_info_arm(struct xc_dom_image *dom, void *ptr) > +{ > + DOMPRINTF_CALLED(dom->xch); > + /* XXX */ > + return 0; > +} > + > +/* ------------------------------------------------------------------------ > */ > + > +static int vcpu_arm(struct xc_dom_image *dom, void *ptr) > +{ > + vcpu_guest_context_t *ctxt = ptr; > + > + DOMPRINTF_CALLED(dom->xch); > + > + /* clear everything */ > + memset(ctxt, 0, sizeof(*ctxt)); > + > + ctxt->user_regs.pc = dom->parms.virt_entry; > + ctxt->user_regs.r0 = 0; /* SBZ */ > + ctxt->user_regs.r1 = 2272; /* Machine NR: Versatile Express */ > + > + ctxt->user_regs.r2 = 0xffffffff; //devicetree_seg //dtb_paddr; //atags > or dtb /* XXX using APPEND right now */ > + ctxt->user_regs.r3 = 0xdeadbeef; > + ctxt->sctlr = /* #define SCTLR_BASE */0x00c50078; > + ctxt->ttbr0 = 0; > + ctxt->ttbr1 = 0; > + ctxt->ttbcr = 0; /* Defined Reset Value */ > + > + ctxt->user_regs.cpsr = > PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_SVC; > + > + DOMPRINTF("Initial state CPSR %#"PRIx32" PC %#"PRIx32, > + ctxt->user_regs.cpsr, ctxt->user_regs.pc); > + > + return 0; > +} > + > +/* ------------------------------------------------------------------------ > */ > + > +static struct xc_dom_arch xc_dom_32 = { > + .guest_type = "xen-3.0-armv7l", > + .native_protocol = XEN_IO_PROTO_ABI_ARM, > + .page_shift = PAGE_SHIFT_ARM, > + .sizeof_pfn = 8, > + .alloc_magic_pages = alloc_magic_pages, > + .count_pgtables = count_pgtables_arm, > + .setup_pgtables = setup_pgtables_arm, > + .start_info = start_info_arm, > + .shared_info = shared_info_arm, > + .vcpu = vcpu_arm, > +}; > + > +static void __init register_arch_hooks(void) > +{ > + xc_dom_register_arch_hooks(&xc_dom_32); > +} > + > int arch_setup_meminit(struct xc_dom_image *dom) > { > - errno = ENOSYS; > - return -1; > + int rc; > + xen_pfn_t pfn, allocsz, i; > + > + dom->shadow_enabled = 1; > + > + dom->p2m_host = xc_dom_malloc(dom, sizeof(xen_pfn_t) * dom->total_pages); > + > + /* setup initial p2m */ > + for ( pfn = 0; pfn < dom->total_pages; pfn++ ) > + dom->p2m_host[pfn] = pfn + dom->rambase_pfn; uhm.. so maybe rambase_pfn is the offset in the machine address space where the guest ram has been allocated? > + /* allocate guest memory */ > + for ( i = rc = allocsz = 0; > + (i < dom->total_pages) && !rc; > + i += allocsz ) > + { > + allocsz = dom->total_pages - i; > + if ( allocsz > 1024*1024 ) > + allocsz = 1024*1024; > + > + rc = xc_domain_populate_physmap_exact( > + dom->xch, dom->guest_domid, allocsz, > + 0, 0, &dom->p2m_host[i]); > + } > + > + return 0; > } > > int arch_setup_bootearly(struct xc_dom_image *dom) > @@ -36,9 +160,14 @@ int arch_setup_bootearly(struct xc_dom_image *dom) > > int arch_setup_bootlate(struct xc_dom_image *dom) > { > - DOMPRINTF("%s: doing nothing", __FUNCTION__); > + /* XXX > + * map shared info > + * map grant tables > + * setup shared info > + */ > return 0; > } > + > /* > * Local variables: > * mode: C > diff --git a/tools/libxc/xc_dom_armzimageloader.c > b/tools/libxc/xc_dom_armzimageloader.c > new file mode 100644 > index 0000000..220176d > --- /dev/null > +++ b/tools/libxc/xc_dom_armzimageloader.c > @@ -0,0 +1,167 @@ > +/* > + * Xen domain builder -- ARM zImage bits > + * > + * Parse and load ARM zImage kernel images. > + * > + * Copyright (C) 2012, Citrix Systems. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 > USA > + * > + */ > + > +#include <stdio.h> > +#include <stdlib.h> > +#include <inttypes.h> > + > +#include "xg_private.h" > +#include "xc_dom.h" > + > +#include <arpa/inet.h> /* XXX ntohl is not the right function... */ Yes, you are right, we should write a be32_to_cpu (the ones in Xen, QEMU and Linux are GPLv2 rather than LGLPv2). > +#define ZIMAGE_MAGIC_OFFSET 0x24 > +#define ZIMAGE_START_OFFSET 0x28 > +#define ZIMAGE_END_OFFSET 0x2c > + > +#define ZIMAGE_MAGIC 0x016f2818 > + > +struct minimal_dtb_header { > + uint32_t magic; > + uint32_t total_size; > + /* There are other fields but we don't use them yet. */ > +}; > + > +#define DTB_MAGIC 0xd00dfeed > + > +static int xc_dom_probe_zimage_kernel(struct xc_dom_image *dom) > +{ > + uint32_t *zimage; > + uint32_t end; > + > + if ( dom->kernel_blob == NULL ) > + { > + xc_dom_panic(dom->xch, XC_INTERNAL_ERROR, > + "%s: no kernel image loaded", __FUNCTION__); > + return -EINVAL; > + } > + > + if ( dom->kernel_size < 0x30 /*sizeof(struct setup_header)*/ ) > + { > + xc_dom_printf(dom->xch, "%s: kernel image too small", __FUNCTION__); > + return -EINVAL; > + } > + > + zimage = (uint32_t *)dom->kernel_blob; > + if ( zimage[ZIMAGE_MAGIC_OFFSET/4] != ZIMAGE_MAGIC ) > + { > + xc_dom_printf(dom->xch, "%s: kernel is not a bzImage", __FUNCTION__); > + return -EINVAL; > + } > + > + end = zimage[ZIMAGE_END_OFFSET/4]; > + > + /* > + * Check for an appended DTB. > + */ > + if ( end + sizeof(struct minimal_dtb_header) < dom->kernel_size ) { > + struct minimal_dtb_header *dtb_hdr; > + dtb_hdr = (struct minimal_dtb_header *)(dom->kernel_blob + end); > + if (ntohl/*be32_to_cpu*/(dtb_hdr->magic) == DTB_MAGIC) { > + xc_dom_printf(dom->xch, "%s: found an appended DTB", > __FUNCTION__); > + end += ntohl/*be32_to_cpu*/(dtb_hdr->total_size); > + } > + } > + > + dom->kernel_size = end; > + > + return 0; > +} > + > +static int xc_dom_parse_zimage_kernel(struct xc_dom_image *dom) > +{ > + uint32_t *zimage; > + uint32_t start, entry_addr; > + uint64_t v_start, v_end; > + uint64_t rambase = 0x80000000; /* XXX */ > + > + DOMPRINTF_CALLED(dom->xch); > + > + zimage = (uint32_t *)dom->kernel_blob; > + > + dom->rambase_pfn = rambase >> XC_PAGE_SHIFT; > + > + v_start = rambase + 0x8000; /* XXX */ > + v_end = v_start + dom->kernel_size; > + > + start = zimage[ZIMAGE_START_OFFSET/4]; > + > + if (start == 0) > + entry_addr = v_start; > + else > + entry_addr = start; > + > + /* find kernel segment */ > + dom->kernel_seg.vstart = v_start; > + dom->kernel_seg.vend = v_end; > + > + dom->parms.virt_entry = entry_addr; > + > + dom->guest_type = "xen-3.0-armv7l"; > + DOMPRINTF("%s: %s: RAM starts at %"PRI_xen_pfn, > + __FUNCTION__, dom->guest_type, dom->rambase_pfn); > + DOMPRINTF("%s: %s: 0x%" PRIx64 " -> 0x%" PRIx64 "", > + __FUNCTION__, dom->guest_type, > + dom->kernel_seg.vstart, dom->kernel_seg.vend); > + return 0; > +} > + > +static int xc_dom_load_zimage_kernel(struct xc_dom_image *dom) > +{ > + void *dst; > + > + DOMPRINTF_CALLED(dom->xch); > + > + dst = xc_dom_seg_to_ptr(dom, &dom->kernel_seg); > + > + DOMPRINTF("%s: kernel sed %#"PRIx64"-%#"PRIx64, > + __func__, dom->kernel_seg.vstart, dom->kernel_seg.vend); > + DOMPRINTF("%s: copy %zd bytes from blob %p to dst %p", > + __func__, dom->kernel_size, dom->kernel_blob, dst); > + > + memcpy(dst, dom->kernel_blob, dom->kernel_size); > + > + return 0; > +} > + > +static struct xc_dom_loader zimage_loader = { > + .name = "Linux zImage (ARM)", > + .probe = xc_dom_probe_zimage_kernel, > + .parser = xc_dom_parse_zimage_kernel, > + .loader = xc_dom_load_zimage_kernel, > +}; > + > +static void __init register_loader(void) > +{ > + xc_dom_register_loader(&zimage_loader); > +} > + > +/* > + * Local variables: > + * mode: C > + * c-set-style: "BSD" > + * c-basic-offset: 4 > + * tab-width: 4 > + * indent-tabs-mode: nil > + * End: > + */ > diff --git a/tools/libxc/xc_dom_core.c b/tools/libxc/xc_dom_core.c > index fea9de5..b0d48d5 100644 > --- a/tools/libxc/xc_dom_core.c > +++ b/tools/libxc/xc_dom_core.c > @@ -307,15 +307,17 @@ void *xc_dom_pfn_to_ptr(struct xc_dom_image *dom, > xen_pfn_t pfn, > xen_pfn_t count) > { > struct xc_dom_phys *phys; > + xen_pfn_t offset; > unsigned int page_shift = XC_DOM_PAGE_SHIFT(dom); > char *mode = "unset"; > > - if ( pfn > dom->total_pages || /* multiple checks to avoid overflows > */ > + offset = pfn-dom->rambase_pfn; spaces around the '-' please > + if ( offset > dom->total_pages || /* multiple checks to avoid > overflows */ > count > dom->total_pages || > - pfn > dom->total_pages - count ) > + offset > dom->total_pages - count ) > { > - DOMPRINTF("%s: pfn out of range (0x%" PRIpfn " > 0x%" PRIpfn ")", > - __FUNCTION__, pfn, dom->total_pages); > + DOMPRINTF("%s: pfn %"PRI_xen_pfn" out of range (0x%" PRIpfn " > 0x%" > PRIpfn ")", > + __FUNCTION__, pfn, offset, dom->total_pages); > return NULL; > } > > @@ -599,6 +601,8 @@ struct xc_dom_image *xc_dom_allocate(xc_interface *xch, > dom->parms.virt_hv_start_low = UNSET_ADDR; > dom->parms.elf_paddr_offset = UNSET_ADDR; > > + dom->rambase_pfn = 0; > + > dom->alloc_malloc += sizeof(*dom); > return dom; There is no need to explicitly set rambase_pfn to 0, because the whole dom struct is memset to 0 few lines above. > diff --git a/tools/libxc/xg_private.h b/tools/libxc/xg_private.h > index a29fa26..a271942 100644 > --- a/tools/libxc/xg_private.h > +++ b/tools/libxc/xg_private.h > @@ -148,6 +148,10 @@ typedef l4_pgentry_64_t l4_pgentry_t; > #define l4_table_offset(_a) l4_table_offset_x86_64(_a) > #endif > > +#define PAGE_SHIFT_ARM 12 > +#define PAGE_SIZE_ARM (1UL << PAGE_SHIFT_ARM) > +#define PAGE_MASK_ARM (~(PAGE_SIZE_ARM-1)) > + > #define PAGE_SHIFT_X86 12 > #define PAGE_SIZE_X86 (1UL << PAGE_SHIFT_X86) > #define PAGE_MASK_X86 (~(PAGE_SIZE_X86-1)) > -- > 1.7.9.1 > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@xxxxxxxxxxxxx > http://lists.xen.org/xen-devel > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |