|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v1 5/5] xsplice: Use ld-embedded build-ids
From: Martin Pohlack <mpohlack@xxxxxxxxx>
The mechanism to get this is via the XSPLICE_OP and
we add a new subsequent hypercall to retrieve the
binary build-id. The hypercall allows an arbirarty
size (the buffer is provided to the hypervisor) - however
by default the toolstack will allocate it up to 128
bytes.
We also add two places for the build-id to be printed:
- xsplice keyhandler. We cannot use 'hh' in the hypervisor
snprintf handler (as it is not implemented) so instead
we use an simpler way to print it.
- In the 'xen-xsplice' tool add an extra parameter - build-id
to print this as an human readable value.
Note that one can also retrieve the value by 'readelf -h xen-syms'.
Signed-off-by: Martin Pohlack <mpohlack@xxxxxxxxx>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>
---
tools/libxc/include/xenctrl.h | 1 +
tools/libxc/xc_misc.c | 26 +++++++++++++
tools/misc/xen-xsplice.c | 39 ++++++++++++++++++++
xen/arch/x86/Makefile | 4 +-
xen/arch/x86/xen.lds.S | 5 +++
xen/common/xsplice.c | 86 +++++++++++++++++++++++++++++++++++++++++++
xen/include/public/sysctl.h | 18 +++++++++
xen/include/xen/version.h | 1 +
8 files changed, 178 insertions(+), 2 deletions(-)
diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index 2cd982d..946ddc0 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -2860,6 +2860,7 @@ int xc_xsplice_apply(xc_interface *xch, char *id);
int xc_xsplice_revert(xc_interface *xch, char *id);
int xc_xsplice_unload(xc_interface *xch, char *id);
int xc_xsplice_check(xc_interface *xch, char *id);
+int xc_xsplice_build_id(xc_interface *xch, char *build_id, unsigned int max);
#endif /* XENCTRL_H */
diff --git a/tools/libxc/xc_misc.c b/tools/libxc/xc_misc.c
index e59f0a1..f67ff16 100644
--- a/tools/libxc/xc_misc.c
+++ b/tools/libxc/xc_misc.c
@@ -992,6 +992,32 @@ int xc_xsplice_check(xc_interface *xch, char *id)
return _xc_xsplice_action(xch, id, XSPLICE_ACTION_CHECK);
}
+int xc_xsplice_build_id(xc_interface *xch, char *build_id, unsigned int max)
+{
+ int rc;
+ DECLARE_SYSCTL;
+ DECLARE_HYPERCALL_BOUNCE(build_id, max, XC_HYPERCALL_BUFFER_BOUNCE_OUT);
+
+ if ( !build_id || !max )
+ return -1;
+
+ if ( xc_hypercall_bounce_pre(xch, build_id) )
+ return -1;
+
+ sysctl.cmd = XEN_SYSCTL_xsplice_op;
+ sysctl.u.xsplice.cmd = XEN_SYSCTL_XSPLICE_INFO;
+
+ sysctl.u.xsplice.u.info.cmd = XEN_SYSCTL_XSPLICE_INFO_BUILD_ID;
+ sysctl.u.xsplice.u.info.size = max;
+
+ set_xen_guest_handle(sysctl.u.xsplice.u.info.u.info, build_id);
+
+ rc = do_sysctl(xch, &sysctl);
+
+ xc_hypercall_bounce_post(xch, build_id);
+
+ return rc;
+}
/*
* Local variables:
* mode: C
diff --git a/tools/misc/xen-xsplice.c b/tools/misc/xen-xsplice.c
index d8bd222..609d799 100644
--- a/tools/misc/xen-xsplice.c
+++ b/tools/misc/xen-xsplice.c
@@ -17,6 +17,7 @@ void show_help(void)
" <id> An unique name of payload. Up to %d characters.\n"
"Commands:\n"
" help display this help\n"
+ " build-id display build-id of hypervisor.\n"
" upload <id> <file> upload file <cpuid> with <id> name\n"
" list list payloads uploaded.\n"
" apply <id> apply <id> patch.\n"
@@ -361,12 +362,50 @@ unload:
return rc;
}
+
+#define MAX_LEN 1024
+static int build_id_func(int argc, char *argv[])
+{
+ char binary_id[MAX_LEN];
+ char ascii_id[MAX_LEN];
+ int rc;
+ unsigned int i;
+
+ if ( argc )
+ {
+ show_help();
+ return -1;
+ }
+
+ memset(binary_id, 0, sizeof(binary_id));
+
+ rc = xc_xsplice_build_id(xch, binary_id, MAX_LEN);
+ if ( rc < 0 )
+ {
+ printf("Failed to get build_id: %d(%s)\n", errno, strerror(errno));
+ return -1;
+ }
+ /* Convert to printable format. */
+ if ( rc > MAX_LEN )
+ rc = MAX_LEN;
+
+ for ( i = 0; i < rc && (i + 1) * 2 < sizeof(binary_id); i++ )
+ snprintf(&ascii_id[i * 2], 3, "%02hhx", binary_id[i]);
+
+ ascii_id[i*2]='\0';
+ printf("%s", ascii_id);
+
+ return 0;
+}
+#undef MAX
+
struct {
const char *name;
int (*function)(int argc, char *argv[]);
} main_options[] = {
{ "help", help_func },
{ "list", list_func },
+ { "build-id", build_id_func },
{ "upload", upload_func },
{ "all", all_func },
};
diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
index 39a8059..de11910 100644
--- a/xen/arch/x86/Makefile
+++ b/xen/arch/x86/Makefile
@@ -108,11 +108,11 @@ $(TARGET)-syms: prelink.o xen.lds
$(BASEDIR)/common/symbols-dummy.o
$(BASEDIR)/common/symbols-dummy.o -o $(@D)/.$(@F).0
$(NM) -n $(@D)/.$(@F).0 | $(BASEDIR)/tools/symbols >$(@D)/.$(@F).0.S
$(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).0.o
- $(LD) $(LDFLAGS) -T xen.lds -N prelink.o \
+ $(LD) $(LDFLAGS) -T xen.lds -N prelink.o --build-id=sha1 \
$(@D)/.$(@F).0.o -o $(@D)/.$(@F).1
$(NM) -n $(@D)/.$(@F).1 | $(BASEDIR)/tools/symbols >$(@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=sha1 \
$(@D)/.$(@F).1.o -o $@
rm -f $(@D)/.$(@F).[0-9]*
diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S
index 6553cff..2176782 100644
--- a/xen/arch/x86/xen.lds.S
+++ b/xen/arch/x86/xen.lds.S
@@ -67,6 +67,11 @@ SECTIONS
*(.rodata.*)
} :text
+ .note.gnu.build-id : {
+ __note_gnu_build_id_start = .;
+ *(.note.gnu.build-id)
+ } :text
+
. = ALIGN(SMP_CACHE_BYTES);
.data.read_mostly : {
/* Exception table */
diff --git a/xen/common/xsplice.c b/xen/common/xsplice.c
index d330efe..5728c4b 100644
--- a/xen/common/xsplice.c
+++ b/xen/common/xsplice.c
@@ -14,6 +14,8 @@
#include <xen/sched.h>
#include <xen/lib.h>
#include <xen/xsplice.h>
+#include <xen/elf.h>
+#include <xen/types.h>
#include <public/sysctl.h>
#include <asm/event.h>
@@ -44,6 +46,36 @@ struct payload {
struct tasklet tasklet;
};
+#ifdef CONFIG_ARM
+static int build_id(char **p, unsigned int *len)
+{
+ return 0;
+}
+#else
+#define NT_GNU_BUILD_ID 3
+
+extern char * __note_gnu_build_id_start; /* defined in linker script */
+static int build_id(char **p, unsigned int *len)
+{
+ Elf_Note *n;
+
+ n = (Elf_Note *)&__note_gnu_build_id_start;
+
+ /* Check if we really have a build-id. */
+ if ( NT_GNU_BUILD_ID != n->type )
+ return -ENODATA;
+
+ /* Sanity check, name should be "GNU" for ld-generated build-id. */
+ if ( strncmp(ELFNOTE_NAME(n), "GNU", n->namesz) != 0 )
+ return -ENODATA;
+
+ *len = n->descsz;
+ *p = ELFNOTE_DESC(n);
+
+ return 0;
+}
+#endif
+
static const char *status2str(int64_t status)
{
#define STATUS(x) [XSPLICE_STATUS_##x] = #x
@@ -68,9 +100,31 @@ static const char *status2str(int64_t status)
return names[status];
}
+#define LEN 128
void xsplice_printall(unsigned char key)
{
struct payload *data;
+ char *binary_id = NULL;
+ unsigned int len = 0;
+ int rc;
+
+ rc = build_id(&binary_id, &len);
+ printk("build-id: ");
+ if ( !rc )
+ {
+ unsigned int i;
+
+ if ( len > LEN )
+ len = LEN;
+
+ for ( i = 0; i < len; i++ )
+ {
+ uint8_t c = binary_id[i];
+ printk("%02x", c);
+ }
+ printk("\n");
+ } else if ( rc < 0 )
+ printk("rc = %d\n", rc);
spin_lock(&payload_list_lock);
@@ -81,6 +135,7 @@ void xsplice_printall(unsigned char key)
}
spin_unlock(&payload_list_lock);
}
+#undef LEN
static int verify_id(xen_xsplice_id_t *id)
{
@@ -415,6 +470,34 @@ static int xsplice_action(xen_sysctl_xsplice_action_t
*action)
return rc;
}
+static int xsplice_info(xen_sysctl_xsplice_info_t *info)
+{
+ int rc;
+ unsigned int len = 0;
+ char *p = NULL;
+
+ if ( info->cmd != XEN_SYSCTL_XSPLICE_INFO_BUILD_ID )
+ return -EINVAL;
+
+ if ( info->size == 0 )
+ return -EINVAL;
+
+ if ( !guest_handle_okay(info->u.info, info->size) )
+ return -EFAULT;
+
+ rc = build_id(&p, &len);
+ if ( rc )
+ return rc;
+
+ if ( len > info->size )
+ return -ENOMEM;
+
+ if ( copy_to_guest(info->u.info, p, len) )
+ return -EFAULT;
+
+ return len;
+}
+
int xsplice_control(xen_sysctl_xsplice_op_t *xsplice)
{
int rc;
@@ -433,6 +516,9 @@ int xsplice_control(xen_sysctl_xsplice_op_t *xsplice)
case XEN_SYSCTL_XSPLICE_ACTION:
rc = xsplice_action(&xsplice->u.action);
break;
+ case XEN_SYSCTL_XSPLICE_INFO:
+ rc = xsplice_info(&xsplice->u.info);
+ break;
default:
rc = -ENOSYS;
break;
diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h
index 08952de..583dce8 100644
--- a/xen/include/public/sysctl.h
+++ b/xen/include/public/sysctl.h
@@ -905,6 +905,23 @@ struct xen_sysctl_xsplice_action {
typedef struct xen_sysctl_xsplice_action xen_sysctl_xsplice_action_t;
DEFINE_XEN_GUEST_HANDLE(xen_sysctl_xsplice_action_t);
+/*
+ * Retrieve information useful for patching tools.
+ */
+#define XEN_SYSCTL_XSPLICE_INFO 4
+/* The build-id of the hypervisor. */
+#define XEN_SYSCTL_XSPLICE_INFO_BUILD_ID 0
+struct xen_sysctl_xsplice_info {
+ uint32_t cmd; /* IN: XEN_SYSCTL_XSPLICE_INFO_* */
+ uint32_t size; /* IN: Size of info: OUT: Amount of
+ bytes filed out in info. */
+ union {
+ XEN_GUEST_HANDLE_64(char) info; /* OUT: Requested information. */
+ } u;
+};
+typedef struct xen_sysctl_xsplice_info xen_sysctl_xsplice_info_t;
+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_xsplice_info_t);
+
struct xen_sysctl_xsplice_op {
uint32_t cmd; /* IN: XEN_SYSCTL_XSPLICE_* */
uint32_t _pad; /* IN: Always zero. */
@@ -913,6 +930,7 @@ struct xen_sysctl_xsplice_op {
xen_sysctl_xsplice_list_t list;
xen_sysctl_xsplice_summary_t get;
xen_sysctl_xsplice_action_t action;
+ xen_sysctl_xsplice_info_t info;
} u;
};
typedef struct xen_sysctl_xsplice_op xen_sysctl_xsplice_op_t;
diff --git a/xen/include/xen/version.h b/xen/include/xen/version.h
index 81a3c7d..02f9585 100644
--- a/xen/include/xen/version.h
+++ b/xen/include/xen/version.h
@@ -12,5 +12,6 @@ unsigned int xen_minor_version(void);
const char *xen_extra_version(void);
const char *xen_changeset(void);
const char *xen_banner(void);
+const char *xen_build_id(void);
#endif /* __XEN_VERSION_H__ */
--
2.1.0
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |