diff --git a/docs/misc/xsplice.markdown b/docs/misc/xsplice.markdown
index e7c41da..d1f2a5b 100644
--- a/docs/misc/xsplice.markdown
+++ b/docs/misc/xsplice.markdown
@@ -285,6 +285,12 @@ 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:
+It optionally may contain the address of functions to be called right before
+being applied and after being reverted:
+
+ * `.xsplice.hooks.load` - an array of function pointers.
+ * `.xsplice.hooks.unload` - an array of function pointers.
+
 
 <pre>
 struct xsplice_patch_func {  
@@ -362,6 +368,21 @@ struct xsplice_patch_func xsplice_hello_world = {
 
 Code must be compiled with -fPIC.
 
+
+### .xsplice.hooks.load and .xsplice.hooks.unload
+
+This section contains an array of function pointers to be executed
+before payload is being applied (.xsplice.funcs) or after reverting
+the payload.
+
+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>
 ## Hypercalls
 
 We will employ the sub operations of the system management hypercall (sysctl).
diff --git a/xen/arch/x86/test/xen_hello_world.c b/xen/arch/x86/test/xen_hello_world.c
index 243eb3f..d2b3cc2 100644
--- a/xen/arch/x86/test/xen_hello_world.c
+++ b/xen/arch/x86/test/xen_hello_world.c
@@ -5,8 +5,10 @@
 
 #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_hello_world_name[] = "xen_hello_world";
 extern const char *xen_hello_world(void);
@@ -14,6 +16,19 @@ extern const char *xen_hello_world(void);
 /* External symbol. */
 extern const char *xen_extra_version(void);
 
+void apply_hook(void)
+{
+    printk(KERN_DEBUG "Hook executing.\n");
+}
+
+void revert_hook(void)
+{
+    printk(KERN_DEBUG "Hook unloaded.\n");
+}
+
+XSPLICE_LOAD_HOOK(apply_hook);
+XSPLICE_UNLOAD_HOOK(revert_hook);
+
 struct xsplice_patch_func __section(".xsplice.funcs") xsplice_xen_hello_world = {
     .name = xen_hello_world_name,
     .new_addr = (unsigned long)(xen_hello_world),
diff --git a/xen/common/xsplice.c b/xen/common/xsplice.c
index a3366ef..5fb1867 100644
--- a/xen/common/xsplice.c
+++ b/xen/common/xsplice.c
@@ -20,6 +20,7 @@
 #include <xen/wait.h>
 #include <xen/xsplice_elf.h>
 #include <xen/xsplice.h>
+#include <xen/xsplice_patch.h>
 
 #include <asm/event.h>
 #include <asm/nmi.h>
@@ -56,6 +57,10 @@ struct payload {
     struct xsplice_symbol *symtab;       /* All symbols. */
     char *strtab;                        /* Pointer to .strtab. */
     unsigned int nsyms;                  /* Nr of entries in .strtab and symbols. */
+    xsplice_loadcall_t *load_funcs;      /* The array of funcs to call after */
+    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. */
     char name[XEN_XSPLICE_NAME_SIZE + 1];/* Name of it. */
 };
 
@@ -433,6 +438,28 @@ static int prepare_payload(struct payload *payload,
         }
     }
 
+    sec = xsplice_elf_sec_by_name(elf, ".xsplice.hooks.load");
+    if ( sec )
+    {
+        if ( !sec->sec->sh_size ||
+             (sec->sec->sh_size % sizeof (*payload->load_funcs)) )
+            return -EINVAL;
+
+        payload->load_funcs = (xsplice_loadcall_t *)sec->load_addr;
+        payload->n_load_funcs = sec->sec->sh_size / (sizeof *payload->load_funcs);
+    }
+
+    sec = xsplice_elf_sec_by_name(elf, ".xsplice.hooks.unload");
+    if ( sec )
+    {
+        if ( !sec->sec->sh_size ||
+             (sec->sec->sh_size % sizeof (*payload->unload_funcs)) )
+            return -EINVAL;
+
+        payload->unload_funcs = (xsplice_unloadcall_t *)sec->load_addr;
+        payload->n_unload_funcs = sec->sec->sh_size / (sizeof *payload->unload_funcs);
+    }
+
     /* Setup the virtual region with proper data. */
     region = &payload->bug_ex_region;
     region->skip = ignore_region;
@@ -769,6 +796,11 @@ static int apply_payload(struct payload *data)
 
     arch_xsplice_patching_leave();
 
+    spin_debug_disable();
+    for ( i = 0; i < data->n_load_funcs; i++ )
+        data->load_funcs[i]();
+    spin_debug_enable();
+
     list_add_tail(&data->applied_list, &applied_list);
     register_virtual_region(&data->bug_ex_region);
 
@@ -792,6 +824,11 @@ static int revert_payload(struct payload *data)
 
     arch_xsplice_patching_leave();
 
+    spin_debug_disable();
+    for ( i = 0; i < data->n_unload_funcs; i++ )
+        data->unload_funcs[i]();
+    spin_debug_enable();
+
     list_del_init(&data->applied_list);
     unregister_virtual_region(&data->bug_ex_region);
 
diff --git a/xen/include/xen/xsplice_patch.h b/xen/include/xen/xsplice_patch.h
new file mode 100644
index 0000000..19d3f76
--- /dev/null
+++ b/xen/include/xen/xsplice_patch.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2016 Citrix Systems R&D Ltd.
+ */
+
+#ifndef __XEN_XSPLICE_PATCH_H__
+#define __XEN_XSPLICE_PATCH_H__
+
+/*
+ * The following definitions are to be used in patches. They are taken
+ * from kpatch.
+ */
+typedef void (*xsplice_loadcall_t)(void);
+typedef void (*xsplice_unloadcall_t)(void);
+
+/* This definition is taken from Linux. */
+#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
+/*
+ * XSPLICE_IGNORE_SECTION macro
+ *
+ * This macro is for ignoring sections that may change as a side effect of
+ * another change or might be a non-bundlable section; that is one that does
+ * not honor -ffunction-section and create a one-to-one relation from function
+ * symbol to section.
+ */
+#define XSPLICE_IGNORE_SECTION(_sec) \
+	char *__UNIQUE_ID(xsplice_ignore_section_) __section(".xsplice.ignore.sections") = _sec;
+
+/*
+ * XSPLICE_IGNORE_FUNCTION macro
+ *
+ * This macro is for ignoring functions that may change as a side effect of a
+ * change in another function.
+ */
+#define XSPLICE_IGNORE_FUNCTION(_fn) \
+	void *__xsplice_ignore_func_##_fn __section(".xsplice.ignore.functions") = _fn;
+
+/*
+ * XSPLICE_LOAD_HOOK macro
+ *
+ * Declares a function pointer to be allocated in a new
+ * .xsplice.hook.load section.  This xsplice_load_data symbol is later
+ * stripped by create-diff-object so that it can be declared in multiple
+ * objects that are later linked together, avoiding global symbol
+ * collision.  Since multiple hooks can be registered, the
+ * .xsplice.hook.load section is a table of functions that will be
+ * executed in series by the xsplice infrastructure at patch load time.
+ */
+#define XSPLICE_LOAD_HOOK(_fn) \
+	xsplice_loadcall_t __attribute__((weak)) xsplice_load_data __section(".xsplice.hooks.load") = _fn;
+
+/*
+ * XSPLICE_UNLOAD_HOOK macro
+ *
+ * Same as LOAD hook with s/load/unload/
+ */
+#define XSPLICE_UNLOAD_HOOK(_fn) \
+	xsplice_unloadcall_t __attribute__((weak)) xsplice_unload_data __section(".xsplice.hooks.unload") = _fn;
+
+#endif /* __XEN_XSPLICE_PATCH_H__ */
