All of lore.kernel.org
 help / color / mirror / Atom feed
From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
To: xen-devel@lists.xenproject.org, ross.lagerwall@citrix.com,
	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
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Subject: [PATCH v2 10/13] xen_hello_world.xsplice: Test payload for patching 'xen_extra_version'.
Date: Thu, 14 Jan 2016 16:47:08 -0500	[thread overview]
Message-ID: <1452808031-706-11-git-send-email-konrad.wilk@oracle.com> (raw)
In-Reply-To: <1452808031-706-1-git-send-email-konrad.wilk@oracle.com>

This change demonstrates how to generate an xSplice ELF payload.

The idea here is that we want to patch in the hypervisor
the 'xen_version_extra' function with an function that will
return 'Hello World'. The 'xl info | grep extraversion'
will reflect the new value after the patching.

To generate this ELF payload file we need:
 - C code of the new code.
 - C code generating the .xsplice.func structure.
 - The address of the old code (xen_extra_version). We
   do it by using 'nm' but that is a bit of hack.

The linker script file:
 - Discards .debug* and .comments* sections.
 - Changes the name of .data.local.xsplice_hello_world to
   .xsplice.func
 - Figures out the size of the new code.

Also if you are curious on the input/output sections
magic the linker does, add these to the GCC line:
  -Wl,-M  -Wl,-t -Wl,-verbose
which are: print linking map, provide trace and be verbose.

The use-case is simple:

$xen-xsplice load /usr/lib/xen/bin/xen_hello_world.xsplice
$xen-xsplice list
 ID                                     | status
----------------------------------------+------------
xen_hello_world                           APPLIED
$xl info | grep extra
xen_extra              : Hello World
$xen-xsplice revert xen_hello_world
Performing revert: completed
$xen-xsplice unload xen_hello_world
Performing unload: completed
$xl info | grep extra
xen_extra              : -unstable

Note that it does not build under a 32-bit toolstack as
there is no access to the hypervisor (xen-syms).

We also force it to be built every time - as the hypervisor
may have been rebuilt.

Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
---
 docs/misc/xsplice.markdown   | 50 ++++++++++++++++++++++++++++++++++++++++++++
 tools/misc/Makefile          | 25 +++++++++++++++++++++-
 tools/misc/xen_hello_world.c | 15 +++++++++++++
 tools/misc/xsplice.h         | 12 +++++++++++
 tools/misc/xsplice.lds       | 11 ++++++++++
 5 files changed, 112 insertions(+), 1 deletion(-)
 create mode 100644 tools/misc/xen_hello_world.c
 create mode 100644 tools/misc/xsplice.h
 create mode 100644 tools/misc/xsplice.lds

diff --git a/docs/misc/xsplice.markdown b/docs/misc/xsplice.markdown
index beb452e..e2cdcff 100644
--- a/docs/misc/xsplice.markdown
+++ b/docs/misc/xsplice.markdown
@@ -312,11 +312,61 @@ size.
 
 When applying the patch the hypervisor iterates over each `xsplice_patch_func`
 structure and the core code inserts a trampoline at `old_addr` to `new_addr`.
+The `new_addr` is altered when the ELF payload is loaded.
 
 When reverting a patch, the hypervisor iterates over each `xsplice_patch_func`
 and the core code copies the data from the undo buffer (private internal copy)
 to `old_addr`.
 
+### Example
+
+A simple example of what a payload file can be:
+
+<pre>
+/* MUST be in sync with hypervisor. */  
+struct xsplice_patch_func {  
+    const char *name;  
+    unsigned long new_addr;  
+    const unsigned long old_addr;  
+    uint32_t new_size;  
+    const uint32_t old_size;  
+    uint8_t pad[32];  
+};  
+
+/* Our replacement function for xen_extra_version. */  
+const char *xen_hello_world(void)  
+{  
+    return "Hello World";  
+}  
+
+struct xsplice_patch_func xsplice_hello_world = {  
+    .name = "xen_extra_version",  
+    .new_addr = &xen_hello_world,  
+    .old_addr = 0xffff82d08013963c, /* Extracted from xen-syms. */  
+    .new_size = 13, /* To be be computed by scripts. */  
+    .old_size = 13, /* -----------""---------------  */  
+};  
+</pre>
+
+With the linker script as follow to change the `xsplice_hello_world`
+do be `.xsplice.funcs` :
+
+<pre>
+OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")  
+OUTPUT_ARCH(i386:x86-64)  
+ENTRY(xsplice_hello_world)  
+SECTIONS  
+{  
+    /* The hypervisor expects ".xsplice.func", so change  
+     * the ".data.xsplice_hello_world" to it. */  
+
+    .xsplice.funcs : { *(*.xsplice_hello_world) }  
+    }  
+}  
+</pre>
+
+Code must be compiled with -fPIC.
+
 ## Hypercalls
 
 We will employ the sub operations of the system management hypercall (sysctl).
diff --git a/tools/misc/Makefile b/tools/misc/Makefile
index c46873e..8385830 100644
--- a/tools/misc/Makefile
+++ b/tools/misc/Makefile
@@ -36,6 +36,10 @@ INSTALL_SBIN += $(INSTALL_SBIN-y)
 # Everything to be installed in a private bin/
 INSTALL_PRIVBIN                += xenpvnetboot
 
+# We need the hypervisor - and only 64-bit builds have it.
+ifeq ($(XEN_COMPILE_ARCH),x86_64)
+INSTALL_PRIVBIN                += xen_hello_world.xsplice
+endif
 # Everything to be installed
 TARGETS_ALL := $(INSTALL_BIN) $(INSTALL_SBIN) $(INSTALL_PRIVBIN)
 
@@ -49,7 +53,7 @@ TARGETS_COPY += xenpvnetboot
 # Everything which needs to be built
 TARGETS_BUILD := $(filter-out $(TARGETS_COPY),$(TARGETS_ALL))
 
-.PHONY: all build
+.PHONY: all build xsplice
 all build: $(TARGETS_BUILD)
 
 .PHONY: install
@@ -111,4 +115,23 @@ gtraceview: gtraceview.o
 xencov: xencov.o
 	$(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(APPEND_LDFLAGS)
 
+.PHONY: xsplice
+xsplice:
+ifeq ($(XEN_COMPILE_ARCH),x86_64)
+	# We MUST regenerate the file everytime we build - in case the hypervisor
+	# is rebuilt too.
+	$(RM) *.xplice
+	$(MAKE) xen_hello_world.xsplice
+endif
+
+XEN_EXTRA_VERSION_ADDR=$(shell nm --defined $(XEN_ROOT)/xen/xen-syms | grep xen_extra_version | awk '{print "0x"$$1}')
+
+xen_hello_world.xsplice: xen_hello_world.c
+	$(CC) -DOLD_CODE=$(XEN_EXTRA_VERSION_ADDR) -I$(XEN_ROOT)/tools/include \
+		-fPIC -Wl,--emit-relocs \
+		-Wl,-r -Wl,--entry=xsplice_hello_world \
+		-fdata-sections -ffunction-sections \
+		-nostdlib -Txsplice.lds \
+		-o $@ $<
+	@objdump -x --section=.xsplice.funcs $@
 -include $(DEPS)
diff --git a/tools/misc/xen_hello_world.c b/tools/misc/xen_hello_world.c
new file mode 100644
index 0000000..8c24d8f
--- /dev/null
+++ b/tools/misc/xen_hello_world.c
@@ -0,0 +1,15 @@
+#include "xsplice.h"
+
+/* Our replacement function for xen_extra_version. */
+const char *xen_hello_world(void)
+{
+    return "Hello World";
+}
+
+struct xsplice_patch_func xsplice_hello_world = {
+    .name = "xen_extra_version",
+    .new_addr = &xen_hello_world,
+    .old_addr = OLD_CODE,
+    .new_size = 13, /* TODO: Compute. */
+    .old_size = 13, /* TODO: Compute. */
+};
diff --git a/tools/misc/xsplice.h b/tools/misc/xsplice.h
new file mode 100644
index 0000000..6ce8bae
--- /dev/null
+++ b/tools/misc/xsplice.h
@@ -0,0 +1,12 @@
+#include <stdint.h>
+#include <sys/types.h>
+
+/* MUST be in sync with hypervisor. */
+struct xsplice_patch_func {
+    const char *name;
+    unsigned long new_addr;
+    const unsigned long old_addr;
+    uint32_t new_size;
+    const uint32_t old_size;
+    uint8_t pad[32];
+};
diff --git a/tools/misc/xsplice.lds b/tools/misc/xsplice.lds
new file mode 100644
index 0000000..f52eb8c
--- /dev/null
+++ b/tools/misc/xsplice.lds
@@ -0,0 +1,11 @@
+OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
+OUTPUT_ARCH(i386:x86-64)
+ENTRY(xsplice_hello_world)
+SECTIONS
+{
+    /* The hypervisor expects ".xsplice.func", so change
+     * the ".data.xsplice_hello_world" to it. */
+
+    .xsplice.funcs : { *(*.xsplice_hello_world) }
+
+}
-- 
2.1.0

  parent reply	other threads:[~2016-01-14 21:47 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-14 21:46 [PATCH v2] xSplice v1 implementation Konrad Rzeszutek Wilk
2016-01-14 21:46 ` [PATCH v2 01/13] xsplice: Design document (v5) Konrad Rzeszutek Wilk
2016-01-19 11:14   ` Wei Liu
2016-01-19 14:31   ` Ross Lagerwall
2016-02-05 18:27     ` Konrad Rzeszutek Wilk
2016-02-05 18:34     ` Konrad Rzeszutek Wilk
2016-02-05 15:25   ` Jan Beulich
2016-02-05 21:47     ` Konrad Rzeszutek Wilk
2016-02-09  8:25       ` Jan Beulich
2016-01-14 21:47 ` [PATCH v2 02/13] hypervisor/arm/keyhandler: Declare struct cpu_user_regs; Konrad Rzeszutek Wilk
2016-01-14 21:47 ` [PATCH v2 03/13] xen/xsplice: Hypervisor implementation of XEN_XSPLICE_op (v7) Konrad Rzeszutek Wilk
2016-01-19 14:30   ` Ross Lagerwall
2016-02-06 22:35   ` Doug Goldstein
2016-02-09  8:28     ` Jan Beulich
2016-02-09 14:39     ` Konrad Rzeszutek Wilk
2016-01-14 21:47 ` [PATCH v2 04/13] libxc: Implementation of XEN_XSPLICE_op in libxc (v4) Konrad Rzeszutek Wilk
2016-01-19 11:14   ` Wei Liu
2016-01-14 21:47 ` [PATCH v2 05/13] xen-xsplice: Tool to manipulate xsplice payloads (v3) Konrad Rzeszutek Wilk
2016-01-19 11:14   ` Wei Liu
2016-01-19 14:30   ` Ross Lagerwall
2016-01-14 21:47 ` [PATCH v2 06/13] elf: Add relocation types to elfstructs.h Konrad Rzeszutek Wilk
2016-01-14 21:47 ` [PATCH v2 07/13] xsplice: Add helper elf routines (v2) Konrad Rzeszutek Wilk
2016-01-19 14:33   ` Ross Lagerwall
2016-02-05 18:38     ` Konrad Rzeszutek Wilk
2016-02-05 20:34       ` Konrad Rzeszutek Wilk
2016-01-14 21:47 ` [PATCH v2 08/13] xsplice: Implement payload loading (v2) Konrad Rzeszutek Wilk
2016-01-19 14:34   ` Ross Lagerwall
2016-01-19 16:59     ` Konrad Rzeszutek Wilk
2016-01-25 11:21       ` Ross Lagerwall
2016-01-19 16:45   ` Ross Lagerwall
2016-01-14 21:47 ` [PATCH v2 09/13] xsplice: Implement support for applying/reverting/replacing patches. (v2) Konrad Rzeszutek Wilk
2016-01-19 14:39   ` Ross Lagerwall
2016-01-19 16:55     ` Konrad Rzeszutek Wilk
2016-01-25 11:43       ` Ross Lagerwall
2016-02-05 19:30         ` Konrad Rzeszutek Wilk
2016-01-14 21:47 ` Konrad Rzeszutek Wilk [this message]
2016-01-19 11:14   ` [PATCH v2 10/13] xen_hello_world.xsplice: Test payload for patching 'xen_extra_version' Wei Liu
2016-01-19 14:57   ` Ross Lagerwall
2016-01-19 16:47   ` Ross Lagerwall
2016-01-14 21:47 ` [PATCH v2 11/13] xsplice: Add support for bug frames. (v2) Konrad Rzeszutek Wilk
2016-01-19 14:42   ` Ross Lagerwall
2016-01-14 21:47 ` [PATCH v2 12/13] xsplice: Add support for exception tables. (v2) Konrad Rzeszutek Wilk
2016-01-14 21:47 ` [PATCH v2 13/13] xsplice: Add support for alternatives Konrad Rzeszutek Wilk
2016-01-15 16:58 ` [PATCH v2] xSplice v1 implementation Konrad Rzeszutek Wilk
2016-01-25 11:57   ` Ross Lagerwall

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=1452808031-706-11-git-send-email-konrad.wilk@oracle.com \
    --to=konrad.wilk@oracle.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=ian.campbell@citrix.com \
    --cc=ian.jackson@eu.citrix.com \
    --cc=jbeulich@suse.com \
    --cc=mpohlack@amazon.com \
    --cc=ross.lagerwall@citrix.com \
    --cc=sasha.levin@oracle.com \
    --cc=stefano.stabellini@citrix.com \
    --cc=wei.liu2@citrix.com \
    --cc=xen-devel@lists.xenproject.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.