diff --git a/Config.mk b/Config.mk
index c8e89fe..80629e3 100644
--- a/Config.mk
+++ b/Config.mk
@@ -134,6 +134,7 @@ ifeq ($(call ld-ver-build-id,$(LD)),n)
 build_id_linker :=
 else
 CFLAGS += -DBUILD_ID
+export XEN_HAS_BUILD_ID=y
 build_id_linker := --build-id=sha1
 endif
 
diff --git a/docs/misc/xsplice.markdown b/docs/misc/xsplice.markdown
index d1f2a5b..c453b67 100644
--- a/docs/misc/xsplice.markdown
+++ b/docs/misc/xsplice.markdown
@@ -283,8 +283,7 @@ The xSplice core code loads the payload as a standard ELF binary, relocates it
 and handles the architecture-specifc sections as needed. This process is much
 like what the Linux kernel module loader does.
 
-The payload contains a section (xsplice_patch_func) with an array of structures
-describing the functions to be patched:
+The payload contains at least three sections:
 It optionally may contain the address of functions to be called right before
 being applied and after being reverted:
 
@@ -292,6 +291,15 @@ being applied and after being reverted:
  * `.xsplice.hooks.unload` - an array of function pointers.
 
 
+ * `.xsplice.funcs` - which is an array of xsplice_patch_func structures.
+ * `.xsplice.depends` - which is an ELF Note that describes what the payload
+    depends on.
+ *  `.note.gnu.build-id` - the build-id of this payload.
+
+### .xsplice.funcs
+
+The `.xsplice.funcs` contains an array of xsplice_patch_func structures
+which describe the functions to be patched:
 <pre>
 struct xsplice_patch_func {  
     const char *name;  
@@ -333,7 +341,7 @@ 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
+### Example of .xsplice.funcs
 
 A simple example of what a payload file can be:
 
@@ -379,10 +387,29 @@ Each entry in this array is eight bytes.
 
 The type definition of the function are as follow:
 
+
 <pre>
 typedef void (*xsplice_loadcall_t)(void);  
 typedef void (*xsplice_unloadcall_t)(void);   
 </pre>
+
+### .xsplice.depends and .note.gnu.build-id
+
+To support dependencies checking and safe loading (to load the
+appropiate payload against the right hypervisor) there is a need
+to embbed an build-id dependency.
+
+This is done by the payload containing an section `.xsplice.depends`
+which follows the format of an ELF Note. The contents of this
+(name, and description) are specific to the linker utilized to
+build the hypevisor and payload.
+
+If GNU linker is used then the name is `GNU` and the description
+is an NT_GNU_BUILD_ID type ID. The description can be an SHA1
+checksum, MD5 checksum or any unique value.
+
+The size of these structures varies with the --build-id linker option.
+
 ## Hypercalls
 
 We will employ the sub operations of the system management hypercall (sysctl).
@@ -867,30 +894,6 @@ This is implemented in the Xen Project hypervisor.
 
 Only the privileged domain should be allowed to do this operation.
 
-
-# Not Yet Done
-
-This is for further development of xSplice.
-
-## Goals
-
-The implementation must also have a mechanism for:
-
- *  An dependency mechanism for the payloads. To use that information to load:
-    - The appropiate payload. To verify that payload is built against the
-      hypervisor. This can be done via the `build-id`
-      or via providing an copy of the old code - so that the hypervisor can
-       verify it against the code in memory.
-    - To construct an appropiate order of payloads to load in case they
-      depend on each other.
- * Be able to lookup in the Xen hypervisor the symbol names of functions from the ELF payload.
- * Be able to patch .rodata, .bss, and .data sections.
- * Further safety checks (blacklist of which functions cannot be patched, check
-   the stack, make sure the payload is built with same compiler as hypervisor,
-   and NMI/MCE handlers and do_nmi for right now - until an safe solution is found).
- * NOP out the code sequence if `new_size` is zero.
- * Deal with other relocation types:  R_X86_64_[8,16,32,32S], R_X86_64_PC[8,16,64] in payload file.
-
 ### xSplice interdependencies
 
 xSplice patches interdependencies are tricky.
@@ -917,6 +920,33 @@ being loaded and requires an hypervisor build-id to match against.
 The old code allows much more flexibility and an additional guard,
 but is more complex to implement.
 
+The second option which requires an build-id of the hypervisor
+is implemented in the Xen Project hypervisor.
+
+Specifically each payload has two build-id ELF notes:
+ * The build-id of the payload itself (generated via --build-id).
+ * The build-id of the payload it depends on (extracted from the
+   the previous payload or hypervisor during build time).
+
+This means that the very first payload depends on the hypervisor
+build-id.
+
+# Not Yet Done
+
+This is for further development of xSplice.
+
+## Goals
+
+The implementation must also have a mechanism for:
+
+ * Be able to lookup in the Xen hypervisor the symbol names of functions from the ELF payload.
+ * Be able to patch .rodata, .bss, and .data sections.
+ * Further safety checks (blacklist of which functions cannot be patched, check
+   the stack, make sure the payload is built with same compiler as hypervisor,
+   and NMI/MCE handlers and do_nmi for right now - until an safe solution is found).
+ * NOP out the code sequence if `new_size` is zero.
+ * Deal with other relocation types:  R_X86_64_[8,16,32,32S], R_X86_64_PC[8,16,64] in payload file.
+
 ### Handle inlined __LINE__
 
 This problem is related to hotpatch construction
diff --git a/xen/arch/x86/test/Makefile b/xen/arch/x86/test/Makefile
index 45df301..a84c609 100644
--- a/xen/arch/x86/test/Makefile
+++ b/xen/arch/x86/test/Makefile
@@ -7,13 +7,16 @@ CODE_SZ=$(shell nm --defined -S $(1) | grep $(2) | awk '{ print "0x"$$2}')
 ifdef CONFIG_XSPLICE
 
 XSPLICE := xen_hello_world.xsplice
+XSPLICE_BYE := xen_bye_world.xsplice
 
 default: xsplice
 
 install: xsplice
 	$(INSTALL_DATA) $(XSPLICE) $(DESTDIR)$(DEBUG_DIR)/$(XSPLICE)
+	$(INSTALL_DATA) $(XSPLICE_BYE) $(DESTDIR)$(DEBUG_DIR)/$(XSPLICE_BYE)
 uninstall:
 	rm -f $(DESTDIR)$(DEBUG_DIR)/$(XSPLICE)
+	rm -f $(DESTDIR)$(DEBUG_DIR)/$(XSPLICE_BYE)
 else
 default:
 install:
@@ -22,7 +25,7 @@ endif
 
 .PHONY: clean
 clean::
-	rm -f *.o .*.o.d $(XSPLICE) config.h
+	rm -f *.o .*.o.d $(XSPLICE) config.h build_id.o
 
 #
 # To compute these values we need the binary files: xen-syms
@@ -34,15 +37,45 @@ clean::
 .PHONY: config.h
 config.h: OLD_CODE_SZ=$(call CODE_SZ,$(BASEDIR)/xen-syms,xen_extra_version)
 config.h: NEW_CODE_SZ=$(call CODE_SZ,$<,xen_hello_world)
-config.h: xen_hello_world_func.o
+config.h: xen_hello_world_func.o xen_bye_world_func.o
 	(set -e; \
 	 echo "#define NEW_CODE_SZ $(NEW_CODE_SZ)"; \
 	 echo "#define OLD_CODE_SZ $(OLD_CODE_SZ)") > $@
 
+#
+# This target is only accessible if CONFIG_XSPLICE is defined, which
+# depends on $(build_id_linker) being available. Hence we do not
+# need any checks.
+#
+.PHONY: build_id.o
+build_id.o:
+	$(OBJCOPY) -O binary --only-section=.note $(BASEDIR)/xen-syms $@.bin
+	$(OBJCOPY) -I binary -O elf64-x86-64 -B i386:x86-64 \
+		   --rename-section=.data=.xsplice.depends -S $@.bin $@
+	rm -f $@.bin
+
+
+#
+# Extract the build-id of the xen_hello_world.xsplice
+# (which xen_bye_world will depend on).
+#
+.PHONY: hello_world_build_id.o
+hello_world_build_id.o:
+	$(OBJCOPY) -O binary --only-section=.note.gnu.build-id $(XSPLICE) $@.bin
+	$(OBJCOPY)  -I binary -O elf64-x86-64 -B i386:x86-64 \
+		   --rename-section=.data=.xsplice.depends -S $@.bin $@
+	rm -f $@.bin
+
 .PHONY: xsplice
-xsplice: config.h
+xsplice: config.h build_id.o
 	# Need to have these done in sequential order
 	$(MAKE) -f $(BASEDIR)/Rules.mk xen_hello_world_func.o
 	$(MAKE) -f $(BASEDIR)/Rules.mk xen_hello_world.o
-	$(LD) $(LDFLAGS) -r -o $(XSPLICE) xen_hello_world_func.o xen_hello_world.o
+	$(LD) $(LDFLAGS) $(build_id_linker) -r -o $(XSPLICE) \
+		xen_hello_world_func.o xen_hello_world.o build_id.o
+	$(MAKE) -f $(BASEDIR)/Rules.mk xen_bye_world_func.o
+	$(MAKE) -f $(BASEDIR)/Rules.mk xen_bye_world.o
+	$(MAKE) -f $(BASEDIR)/Rules.mk hello_world_build_id.o
+	$(LD) $(LDFLAGS) $(build_id_linker) -r -o $(XSPLICE_BYE) \
+		xen_bye_world_func.o xen_bye_world.o hello_world_build_id.o
 
diff --git a/xen/arch/x86/test/xen_bye_world.c b/xen/arch/x86/test/xen_bye_world.c
new file mode 100644
index 0000000..d26641c
--- /dev/null
+++ b/xen/arch/x86/test/xen_bye_world.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved.
+ *
+ */
+
+#include <xen/config.h>
+#include <xen/types.h>
+#include <xen/xsplice_patch.h>
+#include <xen/xsplice.h>
+#include "config.h"
+#include <xen/lib.h>
+
+static char xen_bye_world_name[] = "xen_bye_world";
+extern const char *xen_bye_world(void);
+
+/* External symbol. */
+extern const char *xen_extra_version(void);
+
+struct xsplice_patch_func __section(".xsplice.funcs") xsplice_xen_bye_world = {
+    .name = xen_bye_world_name,
+    .new_addr = (unsigned long)(xen_bye_world),
+    .old_addr = (unsigned long)(xen_extra_version),
+    .new_size = NEW_CODE_SZ,
+    .old_size = OLD_CODE_SZ,
+};
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/arch/x86/test/xen_bye_world_func.c b/xen/arch/x86/test/xen_bye_world_func.c
new file mode 100644
index 0000000..574268c
--- /dev/null
+++ b/xen/arch/x86/test/xen_bye_world_func.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved.
+ *
+ */
+
+#include <xen/config.h>
+#include <xen/types.h>
+#include <asm/nops.h>
+#include <asm/alternative.h>
+
+/* Our replacement function for xen_hello_world. */
+const char *xen_bye_world(void)
+{
+    return "Bye World!";
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/common/Kconfig b/xen/common/Kconfig
index dbe9ccc..d153c4a 100644
--- a/xen/common/Kconfig
+++ b/xen/common/Kconfig
@@ -54,6 +54,10 @@ config HAS_GDBSX
 config HAS_IOPORTS
 	bool
 
+config HAS_BUILD_ID
+	string
+	option env="XEN_HAS_BUILD_ID"
+
 # Enable/Disable kexec support
 config KEXEC
 	bool "kexec support"
@@ -172,6 +176,7 @@ endmenu
 config XSPLICE
 	bool "xSplice live patching support"
 	default y
+	depends on HAS_BUILD_ID = "y"
 	---help---
 	  Allows a running Xen hypervisor to be dynamically patched using
 	  binary patches without rebooting. This is primarily used to binarily
diff --git a/xen/common/version.c b/xen/common/version.c
index af87371..50906b1 100644
--- a/xen/common/version.c
+++ b/xen/common/version.c
@@ -70,10 +70,29 @@ const char *xen_deny(void)
 /* Defined in linker script. */
 extern const Elf_Note __note_gnu_build_id_start[], __note_gnu_build_id_end[];
 
+int xen_build_id_check(const Elf_Note *n, const void **p, ssize_t *len)
+{
+    /* 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;
+
+    if ( len )
+        *len = n->descsz;
+    if ( p )
+        *p = ELFNOTE_DESC(n);
+
+    return 0;
+}
+
 int xen_build_id(const void **p, ssize_t *len)
 {
     const Elf_Note *n = __note_gnu_build_id_start;
     static bool_t checked = 0;
+    int rc;
 
     if ( checked )
     {
@@ -89,23 +108,20 @@ int xen_build_id(const void **p, ssize_t *len)
     if ( &n[1] > __note_gnu_build_id_end )
         return -ENODATA;
 
-    /* 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);
+    rc = xen_build_id_check(n, p, len);
+    if ( !rc )
+        checked = 1;
 
-    checked = 1;
-    return 0;
+    return rc;
 }
 
 #else
 
+int xen_build_id_check(const Elf_Note *n, const void **p, ssize_t *len)
+{
+    return -ENODATA;
+}
+
 int xen_build_id(const void **p, ssize_t *len)
 {
     return -ENODATA;
diff --git a/xen/common/xsplice.c b/xen/common/xsplice.c
index effae86..e963ccd 100644
--- a/xen/common/xsplice.c
+++ b/xen/common/xsplice.c
@@ -5,6 +5,7 @@
 
 #include <xen/bug_ex_symbols.h>
 #include <xen/cpu.h>
+#include <xen/elf.h>
 #include <xen/guest_access.h>
 #include <xen/keyhandler.h>
 #include <xen/lib.h>
@@ -62,6 +63,8 @@ struct payload {
     xsplice_unloadcall_t *unload_funcs;  /* load and unload of the payload. */
     unsigned int n_load_funcs;           /* Nr of the funcs to load and execute. */
     unsigned int n_unload_funcs;         /* Nr of funcs to call durung unload. */
+    struct xsplice_build_id id;          /* ELFNOTE_DESC(.note.gnu.build-id) of the payload. */
+    struct xsplice_build_id dep;         /* ELFNOTE_DESC(.xsplice.depends). */
     char name[XEN_XSPLICE_NAME_SIZE + 1];/* Name of it. */
 };
 
@@ -379,7 +382,9 @@ static int check_special_sections(struct payload *payload,
                                   struct xsplice_elf *elf)
 {
     unsigned int i;
-    static const char *const names[] = { ".xsplice.funcs" };
+    static const char *const names[] = { ".xsplice.funcs" ,
+                                         ".xsplice.depends",
+                                         ".note.gnu.build-id"};
 
     for ( i = 0; i < ARRAY_SIZE(names); i++ )
     {
@@ -398,6 +403,8 @@ static int check_special_sections(struct payload *payload,
     return 0;
 }
 
+#define NT_GNU_BUILD_ID 3
+
 static int prepare_payload(struct payload *payload,
                            struct xsplice_elf *elf)
 {
@@ -405,6 +412,7 @@ static int prepare_payload(struct payload *payload,
     unsigned int i;
     struct xsplice_patch_func *f;
     struct virtual_region *region;
+    Elf_Note *n;
 
     sec = xsplice_elf_sec_by_name(elf, ".xsplice.funcs");
     if ( sec )
@@ -480,6 +488,33 @@ static int prepare_payload(struct payload *payload,
         payload->n_unload_funcs = sec->sec->sh_size / (sizeof *payload->unload_funcs);
     }
 
+    sec = xsplice_elf_sec_by_name(elf, ".note.gnu.build-id");
+    if ( sec )
+    {
+        n = (Elf_Note *)sec->load_addr;
+        if ( sec->sec->sh_size <= sizeof *n )
+            return -EINVAL;
+
+        if ( xen_build_id_check(n, &payload->id.p, &payload->id.len) )
+            return -EINVAL;
+
+        if ( !payload->id.len || !payload->id.p )
+            return -EINVAL;
+    }
+
+    sec = xsplice_elf_sec_by_name(elf, ".xsplice.depends");
+    {
+        n = (Elf_Note *)sec->load_addr;
+        if ( sec->sec->sh_size <= sizeof *n )
+            return -EINVAL;
+
+        if ( xen_build_id_check(n, &payload->dep.p, &payload->dep.len) )
+            return -EINVAL;
+
+        if ( !payload->dep.len || !payload->dep.p )
+            return -EINVAL;
+    }
+
     /* Setup the virtual region with proper data. */
     region = &payload->bug_ex_region;
     region->skip = ignore_region;
@@ -1175,6 +1210,53 @@ void check_for_xsplice_work(void)
     }
 }
 
+/*
+ * Only allow dependent payload is applied on top of the correct
+ * build-id.
+ *
+ * This enforces an stacking order - the first payload MUST be against the
+ * hypervisor. The second against the first payload, and so on.
+ *
+ * Unless the 'ignore' parameter is used - in which case we only
+ * check against the hypervisor.
+ */
+static int build_id_dep(struct payload *payload, bool_t ignore)
+{
+    const void *id = NULL;
+    ssize_t len = 0;
+    int rc;
+    const char *name = "hypervisor";
+
+    ASSERT(payload->dep.len && payload->dep.p);
+
+    /* First time user is against hypervisor. */
+    if ( ignore || list_empty(&applied_list) )
+    {
+        rc = xen_build_id(&id, &len);
+        if ( rc )
+            return rc;
+    }
+    else
+    {
+        /* We should be against the last applied one. */
+        struct payload *data = list_last_entry(&applied_list, struct payload,
+                                               applied_list);
+
+        id = data->id.p;
+        len = data->id.len;
+        name = data->name;
+    }
+
+    if ( payload->dep.len != len ||
+         memcmp(id, payload->dep.p, len) )
+    {
+        dprintk(XENLOG_DEBUG, "%s%s: check against %s build-id failed!\n",
+                XSPLICE, payload->name, name);
+        return -EINVAL;
+    }
+    return 0;
+}
+
 static int xsplice_action(xen_sysctl_xsplice_action_t *action)
 {
     struct payload *data;
@@ -1213,6 +1295,18 @@ static int xsplice_action(xen_sysctl_xsplice_action_t *action)
     case XSPLICE_ACTION_REVERT:
         if ( data->state == XSPLICE_STATE_APPLIED )
         {
+            struct payload *p = list_last_entry(&applied_list, struct payload,
+                                                   applied_list);
+
+            ASSERT(p);
+            /* We should be the last applied one. */
+            if ( p != data )
+            {
+                dprintk(XENLOG_DEBUG, "%s%s: can't unload. Top is %s!\n",
+                        XSPLICE, data->name, p->name);
+                rc = -EBUSY;
+                break;
+            }
             data->rc = -EAGAIN;
             rc = schedule_work(data, action->cmd, action->timeout);
         }
@@ -1221,6 +1315,9 @@ static int xsplice_action(xen_sysctl_xsplice_action_t *action)
     case XSPLICE_ACTION_APPLY:
         if ( (data->state == XSPLICE_STATE_CHECKED) )
         {
+            rc = build_id_dep(data, 0 /* against top one. */);
+            if ( rc )
+                break;
             data->rc = -EAGAIN;
             rc = schedule_work(data, action->cmd, action->timeout);
         }
@@ -1229,6 +1326,9 @@ static int xsplice_action(xen_sysctl_xsplice_action_t *action)
     case XSPLICE_ACTION_REPLACE:
         if ( data->state == XSPLICE_STATE_CHECKED )
         {
+            rc = build_id_dep(data, 1 /* against hypervisor. */);
+            if ( rc )
+                break;
             data->rc = -EAGAIN;
             rc = schedule_work(data, action->cmd, action->timeout);
         }
diff --git a/xen/include/xen/version.h b/xen/include/xen/version.h
index a461c85..bc92370 100644
--- a/xen/include/xen/version.h
+++ b/xen/include/xen/version.h
@@ -16,4 +16,7 @@ const char *xen_deny(void);
 #include <xen/types.h>
 int xen_build_id(const void **p, ssize_t *len);
 
+#include <xen/elfstructs.h>
+int xen_build_id_check(const Elf_Note *n, const void **p, ssize_t *len);
+
 #endif /* __XEN_VERSION_H__ */
diff --git a/xen/include/xen/xsplice.h b/xen/include/xen/xsplice.h
index 16d35b8..82b20ca 100644
--- a/xen/include/xen/xsplice.h
+++ b/xen/include/xen/xsplice.h
@@ -40,6 +40,11 @@ struct xsplice_symbol {
     bool_t new_symbol;
 };
 
+struct xsplice_build_id {
+   const void *p;
+   ssize_t len;
+};
+
 int xsplice_op(struct xen_sysctl_xsplice_op *);
 void check_for_xsplice_work(void);
 bool_t is_patch(const void *addr);
