[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v3 13/23] XENVER_build_id: Provide ld-embedded build-ids (v10)
On 12/02/16 18:05, Konrad Rzeszutek Wilk wrote: Building the hypervisor with buildid and making it available via hypercall really should be split into two different patches, especially given the complexity in each. > The mechanism to get this is via the XENVER hypercall and > we add a new sub-command to retrieve the binary build-id > called XENVER_build_id. The sub-hypercall parameter > allows an arbitrary size (the buffer and len is provided > to the hypervisor). A NULL parameter will probe the hypervisor > for the length of the build-id. > > One can also retrieve the value of the build-id by doing > 'readelf -n xen-syms'. > > For EFI builds we re-use the same build-id that the xen-syms > was built with. > > The version of ld that first implemented --build-id is v2.18. > Hence we check for that or later version - if older version > found we do not build the hypervisor with the build-id > (and the return code is -ENODATA for that case). > > For x86 we have two binaries - the xen-syms and the xen - an > smaller version with lots of sections removed. To make it possible > for readelf -n xen we also modify mkelf32 and xen.lds.S to include > the PT_NOTE ELF section. > > The EFI binary is more complicated. Having any non-recognizable > sections (.note, .data.note, etc) causes the boot to hang. > Moving the .note in the .data section makes it work. It is also > worth noting that the PE/COFF does not have any "comment" > sections to the author. > > Suggested-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> > Signed-off-by: Martin Pohlack <mpohlack@xxxxxxxxx> > Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx> > --- > v1: Rebase it on Martin's initial patch > v2: Move it to XENVER hypercall > v3: Fix EFI building (Ross's fix) > v4: Don't use the third argument for length. > v5: Use new structure for XENVER_build_id with variable buf. > v6: Include Ross's fix. > v7: Include detection of bin-utils for build-id support, add > probing for size, and return -EPERM for XSM denied calls. > v8: Build xen_build_id under ARM, required adding ELFSIZE in proper file. > v9: Rebase on top XSM version class. > v10: Include the build-id .note in the xen ELF binary. > s/build_id/build_id_linker/ > For EFI build, moved the --build-id values in .data section > --- > Config.mk | 11 +++ > tools/flask/policy/policy/modules/xen/xen.te | 4 +- > tools/libxc/xc_private.c | 7 ++ > tools/libxc/xc_private.h | 10 ++ > xen/arch/arm/Makefile | 2 +- > xen/arch/arm/xen.lds.S | 13 +++ > xen/arch/x86/Makefile | 31 +++++- > xen/arch/x86/boot/mkelf32.c | 137 > +++++++++++++++++++++++---- > xen/arch/x86/xen.lds.S | 23 +++++ > xen/common/kernel.c | 36 +++++++ > xen/common/version.c | 48 ++++++++++ > xen/include/public/version.h | 16 +++- > xen/include/xen/version.h | 1 + > xen/xsm/flask/hooks.c | 3 + > xen/xsm/flask/policy/access_vectors | 2 + > 15 files changed, 319 insertions(+), 25 deletions(-) > > diff --git a/Config.mk b/Config.mk > index 429e460..61186e2 100644 > --- a/Config.mk > +++ b/Config.mk > @@ -126,6 +126,17 @@ endef > check-$(gcc) = $(call cc-ver-check,CC,0x040100,"Xen requires at least > gcc-4.1") > $(eval $(check-y)) > > +ld-ver-build-id = $(shell $(1) --build-id 2>&1 | \ > + grep -q unrecognized && echo n || echo > y) > + > +# binutils 2.18 implement build-id. > +ifeq ($(call ld-ver-build-id,$(LD)),n) > +build_id_linker := > +else > +CFLAGS += -DBUILD_ID > +build_id_linker := --build-id=sha1 > +endif > + > # as-insn: Check whether assembler supports an instruction. > # Usage: cflags-y += $(call as-insn "insn",option-yes,option-no) > as-insn = $(if $(shell echo 'void _(void) { asm volatile ( $(2) ); }' \ > diff --git a/tools/flask/policy/policy/modules/xen/xen.te > b/tools/flask/policy/policy/modules/xen/xen.te > index 9ad648a..2988954 100644 > --- a/tools/flask/policy/policy/modules/xen/xen.te > +++ b/tools/flask/policy/policy/modules/xen/xen.te > @@ -79,7 +79,7 @@ allow dom0_t xen_t:xen2 { > # Note that dom0 is part of domain_type so this has duplicates. > allow dom0_t xen_t:version { > version extraversion compile_info capabilities changeset > - platform_parameters get_features pagesize guest_handle commandline > + platform_parameters get_features pagesize guest_handle commandline > build_id > }; > > allow dom0_t xen_t:mmu memorymap; > @@ -146,7 +146,7 @@ if (guest_writeconsole) { > # pmu_ctrl is for) > allow domain_type xen_t:xen2 pmu_use; > > -# For normal guests all except XENVER_commandline > +# For normal guests all except XENVER_commandline|build_id > allow domain_type xen_t:version { > version extraversion compile_info capabilities changeset > platform_parameters get_features pagesize guest_handle > diff --git a/tools/libxc/xc_private.c b/tools/libxc/xc_private.c > index c41e433..d57c39a 100644 > --- a/tools/libxc/xc_private.c > +++ b/tools/libxc/xc_private.c > @@ -495,6 +495,13 @@ int xc_version(xc_interface *xch, int cmd, void *arg) > case XENVER_commandline: > sz = sizeof(xen_commandline_t); > break; > + case XENVER_build_id: > + { > + xen_build_id_t *build_id = (xen_build_id_t *)arg; > + sz = sizeof(*build_id) + build_id->len; > + HYPERCALL_BOUNCE_SET_DIR(arg, XC_HYPERCALL_BUFFER_BOUNCE_BOTH); > + break; > + } > default: > ERROR("xc_version: unknown command %d\n", cmd); > return -EINVAL; > diff --git a/tools/libxc/xc_private.h b/tools/libxc/xc_private.h > index aa8daf1..6b592d3 100644 > --- a/tools/libxc/xc_private.h > +++ b/tools/libxc/xc_private.h > @@ -191,6 +191,16 @@ enum { > #define DECLARE_HYPERCALL_BOUNCE(_ubuf, _sz, _dir) > DECLARE_NAMED_HYPERCALL_BOUNCE(_ubuf, _ubuf, _sz, _dir) > > /* > + * Change the direction. > + * > + * Can only be used if the bounce_pre/bounce_post commands have > + * not been used. > + */ > +#define HYPERCALL_BOUNCE_SET_DIR(_buf, _dir) do { if > ((HYPERCALL_BUFFER(_buf))->hbuf) \ > + assert(1); > \ > + > (HYPERCALL_BUFFER(_buf))->dir = _dir; \ > + } while (0) > +/* > * Set the size of data to bounce. Useful when the size is not known > * when the bounce buffer is declared. > */ > diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile > index 35ba293..8491267 100644 > --- a/xen/arch/arm/Makefile > +++ b/xen/arch/arm/Makefile > @@ -93,7 +93,7 @@ $(TARGET)-syms: prelink.o xen.lds > $(BASEDIR)/common/symbols-dummy.o > $(NM) -pa --format=sysv $(@D)/.$(@F).1 \ > | $(BASEDIR)/tools/symbols --sysv --sort >$(@D)/.$(@F).1.S > $(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).1.o > - $(LD) $(LDFLAGS) -T xen.lds -N prelink.o \ > + $(LD) $(LDFLAGS) -T xen.lds -N prelink.o $(build_id_linker) \ > $(@D)/.$(@F).1.o -o $@ > rm -f $(@D)/.$(@F).[0-9]* > > diff --git a/xen/arch/arm/xen.lds.S b/xen/arch/arm/xen.lds.S > index f501a2f..5cf180f 100644 > --- a/xen/arch/arm/xen.lds.S > +++ b/xen/arch/arm/xen.lds.S > @@ -22,6 +22,9 @@ OUTPUT_ARCH(FORMAT) > PHDRS > { > text PT_LOAD /* XXX should be AT ( XEN_PHYS_START ) */ ; > +#if defined(BUILD_ID) > + note PT_NOTE ; > +#endif > } > SECTIONS > { > @@ -53,6 +56,16 @@ SECTIONS > _erodata = .; /* End of read-only data */ > } :text > > +#if defined(BUILD_ID) > + .note : { > + __note_gnu_build_id_start = .; > + *(.note.gnu.build-id) > + __note_gnu_build_id_end = .; > + *(.note) > + *(.note.*) > + } :text > +#endif This data really should be contained inside rodata. > diff --git a/xen/include/public/version.h b/xen/include/public/version.h > index 44f26b0..adca602 100644 > --- a/xen/include/public/version.h > +++ b/xen/include/public/version.h > @@ -30,7 +30,8 @@ > > #include "xen.h" > > -/* NB. All ops return zero on success, except XENVER_{version,pagesize} */ > +/* NB. All ops return zero on success, except > + * XENVER_{version,pagesize,build_id} */ > > /* arg == NULL; returns major:minor (16:16). */ > #define XENVER_version 0 > @@ -83,6 +84,19 @@ typedef struct xen_feature_info xen_feature_info_t; > #define XENVER_commandline 9 > typedef char xen_commandline_t[1024]; > > +/* Return value is the number of bytes written, or XEN_Exx on error. > + * Calling with empty parameter returns the size of build_id. */ > +#define XENVER_build_id 10 > +struct xen_build_id { > + uint32_t len; /* IN: size of buf[]. */ > +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L > + unsigned char buf[]; > +#elif defined(__GNUC__) > + unsigned char buf[1]; /* OUT: Variable length buffer with > build_id. */ > +#endif > +}; > +typedef struct xen_build_id xen_build_id_t; I am still against trying to perpetuate this broken interface. Variable length structures are a pain for everyone to use. How about introducing a brand new hypercall with a separate length and data parameters? ~Andrew _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |