From patchwork Thu Mar 24 20:00:27 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Konrad Rzeszutek Wilk X-Patchwork-Id: 8664191 Return-Path: X-Original-To: patchwork-xen-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 4A9D09F326 for ; Thu, 24 Mar 2016 20:03:31 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 25AFA203A1 for ; Thu, 24 Mar 2016 20:03:30 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id BD2FA20390 for ; Thu, 24 Mar 2016 20:03:24 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ajBRU-0007L1-7b; Thu, 24 Mar 2016 20:01:16 +0000 Received: from mail6.bemta6.messagelabs.com ([85.158.143.247]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ajBRT-0007Ki-3s for xen-devel@lists.xenproject.org; Thu, 24 Mar 2016 20:01:15 +0000 Received: from [85.158.143.35] by server-3.bemta-6.messagelabs.com id CA/9F-07120-A8744F65; Thu, 24 Mar 2016 20:01:14 +0000 X-Env-Sender: konrad@char.us.oracle.com X-Msg-Ref: server-7.tower-21.messagelabs.com!1458849672!5902723!1 X-Originating-IP: [156.151.31.81] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogMTU2LjE1MS4zMS44MSA9PiAyODgzMzk=\n X-StarScan-Received: X-StarScan-Version: 8.11; banners=-,-,- X-VirusChecked: Checked Received: (qmail 49816 invoked from network); 24 Mar 2016 20:01:13 -0000 Received: from userp1040.oracle.com (HELO userp1040.oracle.com) (156.151.31.81) by server-7.tower-21.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 24 Mar 2016 20:01:13 -0000 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id u2OK17nQ011534 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 24 Mar 2016 20:01:07 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id u2OK16qn013300 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 24 Mar 2016 20:01:06 GMT Received: from abhmp0007.oracle.com (abhmp0007.oracle.com [141.146.116.13]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id u2OK15VL025689; Thu, 24 Mar 2016 20:01:06 GMT Received: from char.us.oracle.com (/10.137.176.158) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Thu, 24 Mar 2016 13:01:05 -0700 Received: by char.us.oracle.com (Postfix, from userid 1000) id A119A6A00E2; Thu, 24 Mar 2016 16:01:03 -0400 (EDT) From: Konrad Rzeszutek Wilk To: xen-devel@lists.xenproject.org, ross.lagerwall@citrix.com, konrad@kernel.org, andrew.cooper3@citrix.com, mpohlack@amazon.de, sasha.levin@oracle.com Date: Thu, 24 Mar 2016 16:00:27 -0400 Message-Id: <1458849640-22588-16-git-send-email-konrad.wilk@oracle.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1458849640-22588-1-git-send-email-konrad.wilk@oracle.com> References: <1458849640-22588-1-git-send-email-konrad.wilk@oracle.com> X-Source-IP: aserv0022.oracle.com [141.146.126.234] Cc: Keir Fraser , Jan Beulich , Konrad Rzeszutek Wilk Subject: [Xen-devel] [PATCH v5 15/28] xsplice: Add .xsplice.hooks functions and test-case X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Ross Lagerwall Add hook functions which run during patch apply and patch revert. Hook functions are used by xsplice payloads to manipulate data structures during patching, etc. Also add macros to be used by payloads for excluding functions or sections from being included in a patch. Furthermore include a test-case for it. Signed-off-by: Ross Lagerwall Signed-off-by: Konrad Rzeszutek Wilk --- Cc: Keir Fraser Cc: Jan Beulich Cc: Andrew Cooper v2: Style guide changes v3: Include the test-case - and also re-order this patch --- docs/misc/xsplice.markdown | 21 +++++++++++++ xen/arch/x86/test/xen_hello_world.c | 15 ++++++++++ xen/common/xsplice.c | 37 +++++++++++++++++++++++ xen/include/xen/xsplice_patch.h | 59 +++++++++++++++++++++++++++++++++++++ 4 files changed, 132 insertions(+) create mode 100644 xen/include/xen/xsplice_patch.h diff --git a/docs/misc/xsplice.markdown b/docs/misc/xsplice.markdown index a498a61..be9cd71 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. +
 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:
+
+
+typedef void (*xsplice_loadcall_t)(void);  
+typedef void (*xsplice_unloadcall_t)(void);   
+
## 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 #include +#include #include #include "config.h" +#include 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 5e77360..03b32e4 100644 --- a/xen/common/xsplice.c +++ b/xen/common/xsplice.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -62,6 +63,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]; /* Name of it. */ }; @@ -499,6 +504,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->region; @@ -851,6 +878,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->region); @@ -874,6 +906,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->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__ */