From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ross Lagerwall Subject: Re: [PATCH v2 08/13] xsplice: Implement payload loading (v2) Date: Tue, 19 Jan 2016 14:34:56 +0000 Message-ID: <569E4990.1010603@citrix.com> References: <1452808031-706-1-git-send-email-konrad.wilk@oracle.com> <1452808031-706-9-git-send-email-konrad.wilk@oracle.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii"; Format="flowed" Content-Transfer-Encoding: 7bit Return-path: Received: from mail6.bemta14.messagelabs.com ([193.109.254.103]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1aLXN7-0001Yl-55 for xen-devel@lists.xenproject.org; Tue, 19 Jan 2016 14:35:01 +0000 In-Reply-To: <1452808031-706-9-git-send-email-konrad.wilk@oracle.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: Konrad Rzeszutek Wilk , xen-devel@lists.xenproject.org, mpohlack@amazon.com, andrew.cooper3@citrix.com, stefano.stabellini@citrix.com, jbeulich@suse.com, ian.jackson@eu.citrix.com, ian.campbell@citrix.com, wei.liu2@citrix.com, sasha.levin@oracle.com List-Id: xen-devel@lists.xenproject.org On 01/14/2016 09:47 PM, Konrad Rzeszutek Wilk wrote: > From: Ross Lagerwall > > Add support for loading xsplice payloads. This is somewhat similar to > the Linux kernel module loader, implementing the following steps: > - Verify the elf file. > - Parse the elf file. > - Allocate a region of memory mapped within a free area of > [xen_virt_end, XEN_VIRT_END]. > - Copy allocated sections into the new region. > - Resolve section symbols. All other symbols must be absolute addresses. > - Perform relocations. > > Note that the structure 'xsplice_patch_func' differs a bit from the design > by usurping 8 bytes from the padding. We use that for our own uses. > > Signed-off-by: Ross Lagerwall > Signed-off-by: Konrad Rzeszutek Wilk > --- > v2: - Change the 'xsplice_patch_func' structure layout/size. > - Add more error checking. Fix memory leak. > - Move elf_resolve and elf_perform relocs in elf file. > - Print the payload address and pages in keyhandler. > v3: > - Make it build under ARM snip > > +static void find_hole(ssize_t pages, unsigned long *hole_start, > + unsigned long *hole_end) > +{ > + struct payload *data, *data2; > + > + spin_lock(&payload_list_lock); > + list_for_each_entry ( data, &payload_list, list ) > + { > + list_for_each_entry ( data2, &payload_list, list ) > + { > + unsigned long start, end; > + > + start = (unsigned long)data2->payload_address; > + end = start + data2->payload_pages * PAGE_SIZE; > + if ( *hole_end > start && *hole_start < end ) > + { > + *hole_start = end; > + *hole_end = *hole_start + pages * PAGE_SIZE; > + break; > + } > + } > + if ( &data2->list == &payload_list ) > + break; > + } > + spin_unlock(&payload_list_lock); > +} This function above should go down into the CONFIG_X86 section below. > + > +/* > + * The following functions prepare an xSplice payload to be executed by > + * allocating space, loading the allocated sections, resolving symbols, > + * performing relocations, etc. > + */ > +#ifdef CONFIG_X86 > +static void *alloc_payload(size_t size) > +{ > + mfn_t *mfn, *mfn_ptr; > + size_t pages, i; > + struct page_info *pg; > + unsigned long hole_start, hole_end, cur; > + > + ASSERT(size); > + > + /* > + * Copied from vmalloc which allocates pages and then maps them to an > + * arbitrary virtual address with PAGE_HYPERVISOR. We need specific > + * virtual address with PAGE_HYPERVISOR_RWX. > + */ > + pages = PFN_UP(size); > + mfn = xmalloc_array(mfn_t, pages); > + if ( mfn == NULL ) > + return NULL; > + > + for ( i = 0; i < pages; i++ ) > + { > + pg = alloc_domheap_page(NULL, 0); > + if ( pg == NULL ) > + goto error; > + mfn[i] = _mfn(page_to_mfn(pg)); snip > diff --git a/xen/common/xsplice_elf.c b/xen/common/xsplice_elf.c > index a5e9d63..ea7eb73 100644 > --- a/xen/common/xsplice_elf.c > +++ b/xen/common/xsplice_elf.c > @@ -199,3 +199,87 @@ void xsplice_elf_free(struct xsplice_elf *elf) > elf->name = NULL; > elf->len = 0; > } > + > +int xsplice_elf_resolve_symbols(struct xsplice_elf *elf) > +{ > + unsigned int i; > + > + /* > + * The first entry of an ELF symbol table is the "undefined symbol index". > + * aka reserved so we skip it. > + */ > + ASSERT( elf->sym ); > + for ( i = 1; i < elf->nsym; i++ ) > + { > + switch ( elf->sym[i].sym->st_shndx ) > + { > + case SHN_COMMON: > + printk(XENLOG_ERR "%s: Unexpected common symbol: %s\n", > + elf->name, elf->sym[i].name); > + return_(-EINVAL); > + break; > + case SHN_UNDEF: > + printk(XENLOG_ERR "%s: Unknown symbol: %s\n", elf->name, > + elf->sym[i].name); > + return_(-ENOENT); > + break; > + case SHN_ABS: > + printk(XENLOG_DEBUG "%s: Absolute symbol: %s => 0x%p\n", > + elf->name, elf->sym[i].name, > + (void *)elf->sym[i].sym->st_value); > + break; > + default: > + if ( elf->sec[elf->sym[i].sym->st_shndx].sec->sh_flags & SHF_ALLOC ) > + { > + elf->sym[i].sym->st_value += > + (unsigned long)elf->sec[elf->sym[i].sym->st_shndx].load_addr; > + printk(XENLOG_DEBUG "%s: Symbol resolved: %s => 0x%p\n", > + elf->name, elf->sym[i].name, > + (void *)elf->sym[i].sym->st_value); > + } > + } > + } > + > + return 0; > +} > + > +int xsplice_elf_perform_relocs(struct xsplice_elf *elf) > +{ > + struct xsplice_elf_sec *rela, *base; > + unsigned int i; > + int rc; > + > + /* > + * The first entry of an ELF symbol table is the "undefined symbol index". > + * aka reserved so we skip it. > + */ > + ASSERT( elf->sym ); > + for ( i = 1; i < elf->hdr->e_shnum; i++ ) > + { > + rela = &elf->sec[i]; > + > + if ( (rela->sec->sh_type != SHT_RELA ) && > + (rela->sec->sh_type != SHT_REL ) ) > + continue; > + > + /* Is it a valid relocation section? */ > + if ( rela->sec->sh_info >= elf->hdr->e_shnum ) > + continue; > + > + base = &elf->sec[rela->sec->sh_info]; > + > + /* Don't relocate non-allocated sections. */ > + if ( !(base->sec->sh_flags & SHF_ALLOC) ) > + continue; > + > + if ( elf->sec[i].sec->sh_type == SHT_RELA ) > + rc = xsplice_perform_rela(elf, base, rela); > + else /* SHT_REL */ > + rc = xsplice_perform_rel(elf, base, rela); > + > + if ( rc ) > + return rc; > + } > + > + return 0; > +} Is there a reason the above two functions weren't put in the previous patch? > diff --git a/xen/include/asm-arm/config.h b/xen/include/asm-arm/config.h > index bd832df..4ea66bf 100644 > --- a/xen/include/asm-arm/config.h > +++ b/xen/include/asm-arm/config.h > @@ -15,8 +15,10 @@ > > #if defined(CONFIG_ARM_64) > # define LONG_BYTEORDER 3 > +# define ELFSIZE 64 > #else > # define LONG_BYTEORDER 2 > +# define ELFSIZE 32 > #endif What does this do? (And perhaps it should also be in the previous patch since it's mentioned in the previous patch's changelog?) -- Ross Lagerwall