xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
To: xen-devel@lists.xenproject.org, msw@amazon.com,
	aliguori@amazon.com, amesserl@rackspace.com,
	rick.harris@rackspace.com, paul.voccio@rackspace.com,
	steven.wilson@rackspace.com, major.hayden@rackspace.com,
	josh.kearney@rackspace.com, jinsong.liu@alibaba-inc.com,
	xiantao.zxt@alibaba-inc.com, boris.ostrovsky@oracle.com,
	daniel.kiper@oracle.com, elena.ufimtseva@oracle.com,
	bob.liu@oracle.com, lars.kurth@citrix.com, hanweidong@huawei.com,
	peter.huangpeng@huawei.com, fanhenglong@huawei.com,
	liuyingdong@huawei.com, john.liuqiming@huawei.com,
	jbeulich@suse.com, andrew.cooper3@citrix.com,
	mpohlack@amazon.com, ian.campbell@citrix.com
Cc: Martin Pohlack <mpohlack@amazon.de>,
	Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Subject: [PATCH v1 5/5] xsplice: Use ld-embedded build-ids
Date: Wed, 16 Sep 2015 17:01:16 -0400	[thread overview]
Message-ID: <1442437276-2620-6-git-send-email-konrad.wilk@oracle.com> (raw)
In-Reply-To: <1442437276-2620-1-git-send-email-konrad.wilk@oracle.com>

From: Martin Pohlack <mpohlack@amazon.de>

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@amazon.de>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
---
 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

  parent reply	other threads:[~2015-09-16 21:02 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-09-16 21:01 [PATCH v1] xSplice initial foundation patches Konrad Rzeszutek Wilk
2015-09-16 21:01 ` [PATCH v1 1/5] xsplice: Design document Konrad Rzeszutek Wilk
2015-10-05 10:02   ` Jan Beulich
2015-10-05 10:28   ` Ross Lagerwall
2015-10-12 11:44     ` xsplice-build prototype (was [PATCH v1 1/5] xsplice: Design document.) Ross Lagerwall
2015-10-12 13:06       ` Konrad Rzeszutek Wilk
2015-10-12 14:20       ` Konrad Rzeszutek Wilk
2015-10-06 12:57   ` [PATCH v1 1/5] xsplice: Design document Ross Lagerwall
2015-10-27  8:08     ` Martin Pohlack
2015-10-27  8:45       ` Ross Lagerwall
2015-10-06 15:26   ` Jan Beulich
2015-10-26 12:01   ` Martin Pohlack
2015-10-26 12:10     ` Jan Beulich
2015-10-26 13:21     ` Ross Lagerwall
2015-10-26 13:55       ` Konrad Rzeszutek Wilk
2015-09-16 21:01 ` [PATCH v1 2/5] xen/xsplice: Hypervisor implementation of XEN_XSPLICE_op Konrad Rzeszutek Wilk
2015-10-02 15:06   ` Jan Beulich
2015-09-16 21:01 ` [PATCH v1 3/5] libxc: Implementation of XEN_XSPLICE_op in libxc Konrad Rzeszutek Wilk
2015-09-16 21:01 ` [PATCH v1 4/5] xen-xsplice: Tool to manipulate xsplice payloads Konrad Rzeszutek Wilk
2015-09-16 21:01 ` Konrad Rzeszutek Wilk [this message]
2015-09-16 21:41   ` [PATCH v1 5/5] xsplice: Use ld-embedded build-ids Andrew Cooper
2015-09-16 21:59     ` Konrad Rzeszutek Wilk
2015-09-16 22:31       ` Andrew Cooper
2015-09-17  6:41         ` Martin Pohlack
2015-09-17  9:35           ` Andrew Cooper
2015-09-17 18:45             ` Is: Make XENVER_* use XSM, seperate the different ops in smaller security domains. Was:Re: " Konrad Rzeszutek Wilk
2015-09-18 11:40               ` Andrew Cooper
2015-09-22 13:22                 ` Konrad Rzeszutek Wilk
2015-09-22 13:33                   ` Andrew Cooper
2015-09-22 13:45                     ` Konrad Rzeszutek Wilk
2015-09-22 16:28                       ` Daniel De Graaf
2015-09-22 16:28               ` Daniel De Graaf
2015-09-25 20:18                 ` Konrad Rzeszutek Wilk
2015-10-02 15:13   ` Jan Beulich
2015-10-02 14:48 ` [PATCH v1] xSplice initial foundation patches Konrad Rzeszutek Wilk
2015-10-09 12:46   ` Konrad Rzeszutek Wilk

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1442437276-2620-6-git-send-email-konrad.wilk@oracle.com \
    --to=konrad.wilk@oracle.com \
    --cc=aliguori@amazon.com \
    --cc=amesserl@rackspace.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=bob.liu@oracle.com \
    --cc=boris.ostrovsky@oracle.com \
    --cc=daniel.kiper@oracle.com \
    --cc=elena.ufimtseva@oracle.com \
    --cc=fanhenglong@huawei.com \
    --cc=hanweidong@huawei.com \
    --cc=ian.campbell@citrix.com \
    --cc=jbeulich@suse.com \
    --cc=jinsong.liu@alibaba-inc.com \
    --cc=john.liuqiming@huawei.com \
    --cc=josh.kearney@rackspace.com \
    --cc=lars.kurth@citrix.com \
    --cc=liuyingdong@huawei.com \
    --cc=major.hayden@rackspace.com \
    --cc=mpohlack@amazon.com \
    --cc=mpohlack@amazon.de \
    --cc=msw@amazon.com \
    --cc=paul.voccio@rackspace.com \
    --cc=peter.huangpeng@huawei.com \
    --cc=rick.harris@rackspace.com \
    --cc=steven.wilson@rackspace.com \
    --cc=xen-devel@lists.xenproject.org \
    --cc=xiantao.zxt@alibaba-inc.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).