From patchwork Tue Mar 15 17:56:55 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: 8591291 Return-Path: X-Original-To: patchwork-xen-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 0D20EC0553 for ; Tue, 15 Mar 2016 18:03:11 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 0E20820155 for ; Tue, 15 Mar 2016 18:03:10 +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 0C290202F0 for ; Tue, 15 Mar 2016 18:03:08 +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 1aftHa-000347-Km; Tue, 15 Mar 2016 18:01:26 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1aftHZ-00031D-Dy for xen-devel@lists.xenproject.org; Tue, 15 Mar 2016 18:01:25 +0000 Received: from [85.158.137.68] by server-16.bemta-3.messagelabs.com id 9B/F4-02994-4FD48E65; Tue, 15 Mar 2016 18:01:24 +0000 X-Env-Sender: konrad@char.us.oracle.com X-Msg-Ref: server-12.tower-31.messagelabs.com!1458064882!12569053!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 8140 invoked from network); 15 Mar 2016 18:01:24 -0000 Received: from userp1040.oracle.com (HELO userp1040.oracle.com) (156.151.31.81) by server-12.tower-31.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 15 Mar 2016 18:01:24 -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 u2FI0Hhu011483 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 15 Mar 2016 18:00:18 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 u2FI0Hdm013312 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Tue, 15 Mar 2016 18:00:17 GMT Received: from abhmp0004.oracle.com (abhmp0004.oracle.com [141.146.116.10]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id u2FI0GxJ001308; Tue, 15 Mar 2016 18:00:16 GMT Received: from char.us.oracle.com (/10.137.176.158) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 15 Mar 2016 11:00:16 -0700 Received: by char.us.oracle.com (Postfix, from userid 1000) id F0E7D6A0101; Tue, 15 Mar 2016 14:00:04 -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: Tue, 15 Mar 2016 13:56:55 -0400 Message-Id: <1458064616-23101-34-git-send-email-konrad.wilk@oracle.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1458064616-23101-1-git-send-email-konrad.wilk@oracle.com> References: <1458064616-23101-1-git-send-email-konrad.wilk@oracle.com> X-Source-IP: aserv0022.oracle.com [141.146.126.234] Cc: Keir Fraser , Ian Jackson , Jan Beulich , Tim Deegan Subject: [Xen-devel] [PATCH v4 33/34] xsplice: Add support for shadow variables. 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=-1.9 required=5.0 tests=BAYES_00, 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 Shadow variables are a piece of infrastructure to be used by xsplice modules. They are used to attach a new piece of data to an existing structure in memory. Signed-off-by: Ross Lagerwall --- Cc: Ian Jackson Cc: Jan Beulich Cc: Keir Fraser Cc: Tim Deegan v2: Add Copyright --- --- xen/common/Makefile | 1 + xen/common/xsplice_shadow.c | 109 ++++++++++++++++++++++++++++++++++++++++ xen/include/xen/xsplice_patch.h | 36 +++++++++++++ 3 files changed, 146 insertions(+) create mode 100644 xen/common/xsplice_shadow.c diff --git a/xen/common/Makefile b/xen/common/Makefile index 9b7fac7..200a544 100644 --- a/xen/common/Makefile +++ b/xen/common/Makefile @@ -62,6 +62,7 @@ obj-$(CONFIG_XENOPROF) += xenoprof.o obj-y += xmalloc_tlsf.o obj-$(CONFIG_XSPLICE) += xsplice.o obj-$(CONFIG_XSPLICE) += xsplice_elf.o +obj-$(CONFIG_XSPLICE) += xsplice_shadow.o obj-bin-$(CONFIG_X86) += $(foreach n,decompress bunzip2 unxz unlzma unlzo unlz4 earlycpio,$(n).init.o) diff --git a/xen/common/xsplice_shadow.c b/xen/common/xsplice_shadow.c new file mode 100644 index 0000000..4196a0a --- /dev/null +++ b/xen/common/xsplice_shadow.c @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2016 Citrix Systems R&D Ltd. + */ + +#include +#include +#include +#include +#include +#include + +#define SHADOW_SLOTS 256 +struct hlist_head shadow_tbl[SHADOW_SLOTS]; +static DEFINE_SPINLOCK(shadow_lock); + +struct shadow_var { + struct hlist_node list; /* Linked to 'shadow_tbl' */ + void *data; + const void *obj; + char var[16]; +}; + +void *xsplice_shadow_alloc(const void *obj, const char *var, size_t size) +{ + struct shadow_var *shadow; + unsigned int slot; + + shadow = xmalloc(struct shadow_var); + if ( !shadow ) + return NULL; + + shadow->obj = obj; + strlcpy(shadow->var, var, sizeof shadow->var); + shadow->data = xmalloc_bytes(size); + if ( !shadow->data ) + { + xfree(shadow); + return NULL; + } + + slot = (unsigned long)obj % SHADOW_SLOTS; + spin_lock(&shadow_lock); + hlist_add_head(&shadow->list, &shadow_tbl[slot]); + spin_unlock(&shadow_lock); + + return shadow->data; +} + +void xsplice_shadow_free(const void *obj, const char *var) +{ + struct shadow_var *entry, *shadow = NULL; + unsigned int slot; + struct hlist_node *next; + + slot = (unsigned long)obj % SHADOW_SLOTS; + + spin_lock(&shadow_lock); + hlist_for_each_entry(entry, next, &shadow_tbl[slot], list) + { + if ( entry->obj == obj && + !strcmp(entry->var, var) ) + { + shadow = entry; + break; + } + } + if (shadow) + { + hlist_del(&shadow->list); + xfree(shadow->data); + xfree(shadow); + } + spin_unlock(&shadow_lock); +} + +void *xsplice_shadow_get(const void *obj, const char *var) +{ + struct shadow_var *entry; + unsigned int slot; + struct hlist_node *next; + void *ret = NULL; + + slot = (unsigned long)obj % SHADOW_SLOTS; + + spin_lock(&shadow_lock); + hlist_for_each_entry(entry, next, &shadow_tbl[slot], list) + { + if ( entry->obj == obj && + !strcmp(entry->var, var) ) + { + ret = entry->data; + break; + } + } + + spin_unlock(&shadow_lock); + return ret; +} + +static int __init xsplice_shadow_init(void) +{ + int i; + + for ( i = 0; i < SHADOW_SLOTS; i++ ) + INIT_HLIST_HEAD(&shadow_tbl[i]); + + return 0; +} +__initcall(xsplice_shadow_init); diff --git a/xen/include/xen/xsplice_patch.h b/xen/include/xen/xsplice_patch.h index 19d3f76..e297fe1 100644 --- a/xen/include/xen/xsplice_patch.h +++ b/xen/include/xen/xsplice_patch.h @@ -56,4 +56,40 @@ typedef void (*xsplice_unloadcall_t)(void); #define XSPLICE_UNLOAD_HOOK(_fn) \ xsplice_unloadcall_t __attribute__((weak)) xsplice_unload_data __section(".xsplice.hooks.unload") = _fn; + +/* + * The following definitions are to be used in patches. They are taken + * from kpatch. + */ + +/* + * xsplice shadow variables + * + * These functions can be used to add new "shadow" fields to existing data + * structures. For example, to allocate a "newpid" variable associated with an + * instance of task_struct, and assign it a value of 1000: + * + * struct task_struct *tsk = current; + * int *newpid; + * newpid = xsplice_shadow_alloc(tsk, "newpid", sizeof(int)); + * if (newpid) + * *newpid = 1000; + * + * To retrieve a pointer to the variable: + * + * struct task_struct *tsk = current; + * int *newpid; + * newpid = xsplice_shadow_get(tsk, "newpid"); + * if (newpid) + * printk("task newpid = %d\n", *newpid); // prints "task newpid = 1000" + * + * To free it: + * + * xsplice_shadow_free(tsk, "newpid"); + */ + +void *xsplice_shadow_alloc(const void *obj, const char *var, size_t size); +void xsplice_shadow_free(const void *obj, const char *var); +void *xsplice_shadow_get(const void *obj, const char *var); + #endif /* __XEN_XSPLICE_PATCH_H__ */