From patchwork Fri Feb 12 18:06:00 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: 8294931 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 34B2E9FC5D for ; Fri, 12 Feb 2016 18:09:25 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 0A5DF20435 for ; Fri, 12 Feb 2016 18:09:24 +0000 (UTC) Received: from lists.xen.org (lists.xenproject.org [50.57.142.19]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8497B2042C for ; Fri, 12 Feb 2016 18:09:22 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xen.org) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1aUI7M-00065M-1p; Fri, 12 Feb 2016 18:06:56 +0000 Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1aUI7J-00062t-0k for xen-devel@lists.xenproject.org; Fri, 12 Feb 2016 18:06:53 +0000 Received: from [85.158.139.211] by server-9.bemta-5.messagelabs.com id 19/B7-29478-C3F1EB65; Fri, 12 Feb 2016 18:06:52 +0000 X-Env-Sender: konrad@char.us.oracle.com X-Msg-Ref: server-16.tower-206.messagelabs.com!1455300410!21761011!1 X-Originating-IP: [141.146.126.69] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogMTQxLjE0Ni4xMjYuNjkgPT4gMjc3MjE4\n X-StarScan-Received: X-StarScan-Version: 7.35.1; banners=-,-,- X-VirusChecked: Checked Received: (qmail 34445 invoked from network); 12 Feb 2016 18:06:51 -0000 Received: from aserp1040.oracle.com (HELO aserp1040.oracle.com) (141.146.126.69) by server-16.tower-206.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 12 Feb 2016 18:06:51 -0000 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id u1CI6i0P025068 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 12 Feb 2016 18:06:44 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id u1CI6iXW023482 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Fri, 12 Feb 2016 18:06:44 GMT Received: from abhmp0010.oracle.com (abhmp0010.oracle.com [141.146.116.16]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id u1CI6huh024682; Fri, 12 Feb 2016 18:06:43 GMT Received: from char.us.oracle.com (/10.137.176.158) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 12 Feb 2016 10:06:43 -0800 Received: by char.us.oracle.com (Postfix, from userid 1000) id 6C3026A4C01; Fri, 12 Feb 2016 13:06:41 -0500 (EST) From: Konrad Rzeszutek Wilk To: xen-devel@lists.xenproject.org, andrew.cooper3@citrix.com, konrad@kernel.org, mpohlack@amazon.de, ross.lagerwall@citrix.com, sasha.levin@citrix.com, jinsong.liu@alibaba-inc.com, Ian Campbell , Ian Jackson , Jan Beulich , Keir Fraser , Tim Deegan , xen-devel@lists.xen.org Date: Fri, 12 Feb 2016 13:06:00 -0500 Message-Id: <1455300361-13092-23-git-send-email-konrad.wilk@oracle.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1455300361-13092-1-git-send-email-konrad.wilk@oracle.com> References: <1455300361-13092-1-git-send-email-konrad.wilk@oracle.com> X-Source-IP: aserv0022.oracle.com [141.146.126.234] Cc: Konrad Rzeszutek Wilk Subject: [Xen-devel] [PATCH v3 22/23] xsplice: Add hooks functions and other macros X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org 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 Add hook functions which run during patch apply and patch revert. Hook functions are used by xsplice modules to manipulate data structures during patching, etc. Also add macros to be used by modules for excluding functions or sections from being included in a patch. Signed-off-by: Ross Lagerwall --- docs/misc/xsplice.markdown | 21 +++++++++++++++++++ xen/common/xsplice.c | 38 ++++++++++++++++++++++++++++++++++ xen/include/xen/xsplice_patch.h | 46 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+) diff --git a/docs/misc/xsplice.markdown b/docs/misc/xsplice.markdown index 1a982f2..d74293a 100644 --- a/docs/misc/xsplice.markdown +++ b/docs/misc/xsplice.markdown @@ -290,6 +290,12 @@ The payload contains at least three sections: depends on. * `.note.gnu.build-id` - the build-id of this payload. +It optionally may contain the address of functions to be called right before +being applied and reverted: + + * `.xsplice.hooks.load` - an array of function pointers. + * `.xsplice.hooks.unload` - an array of function pointers. + ### .xsplice.funcs The `.xsplice.funcs` contains an array of xsplice_patch_func structures @@ -387,6 +393,21 @@ checksum, MD5 checksum or any unique value. The size of these structures varies with the --build-id linker option. +### .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/common/xsplice.c b/xen/common/xsplice.c index ae2882f..fc901ad 100644 --- a/xen/common/xsplice.c +++ b/xen/common/xsplice.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -46,10 +47,15 @@ struct payload { struct list_head applied_list; /* Linked to 'applied_list'. */ struct xsplice_patch_func *funcs; /* The array of functions to patch. */ unsigned int nfuncs; /* Nr of functions to patch. */ + 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. */ size_t core_size; /* Everything else - .data,.rodata, etc. */ size_t core_text_size; /* Only .text size. */ struct bug_frame *start_bug_frames[BUGFRAME_NR]; /* .bug.frame patching. */ struct bug_frame *stop_bug_frames[BUGFRAME_NR]; + #ifdef CONFIG_X86 struct exception_table_entry *start_ex_table; struct exception_table_entry *stop_ex_table; @@ -744,6 +750,28 @@ static int find_special_sections(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); + } + sec = xsplice_elf_sec_by_name(elf, ".note.gnu.build-id"); if ( sec ) { @@ -1029,6 +1057,11 @@ static int apply_payload(struct payload *data) for ( i = 0; i < data->nfuncs; i++ ) xsplice_apply_jmp(data->funcs + i); + 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); return 0; @@ -1059,6 +1092,11 @@ static int revert_payload(struct payload *data) for ( i = 0; i < data->nfuncs; i++ ) xsplice_revert_jmp(data->funcs + i); + spin_debug_disable(); + for (i = 0; i < data->n_unload_funcs; i++) + data->unload_funcs[i](); + spin_debug_enable(); + list_del(&data->applied_list); return 0; diff --git a/xen/include/xen/xsplice_patch.h b/xen/include/xen/xsplice_patch.h index e3f344b..1450406 100644 --- a/xen/include/xen/xsplice_patch.h +++ b/xen/include/xen/xsplice_patch.h @@ -5,6 +5,52 @@ * 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; /* * xsplice shadow variables