From patchwork Sun Sep 11 20:35:17 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: 9325583 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 6C2B16048B for ; Sun, 11 Sep 2016 20:38:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 59BB6284EF for ; Sun, 11 Sep 2016 20:38:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4E5A528AB5; Sun, 11 Sep 2016 20:38:27 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 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.wl.linuxfoundation.org (Postfix) with ESMTPS id 011A2284EF for ; Sun, 11 Sep 2016 20:38:25 +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 1bjBTv-00023N-N5; Sun, 11 Sep 2016 20:36:03 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bjBTu-00021u-6T for xen-devel@lists.xenproject.org; Sun, 11 Sep 2016 20:36:02 +0000 Received: from [85.158.137.68] by server-5.bemta-3.messagelabs.com id 29/D4-03281-130C5D75; Sun, 11 Sep 2016 20:36:01 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrDLMWRWlGSWpSXmKPExsXSO6nOVdfgwNV wg5/rdSy+b5nM5MDocfjDFZYAxijWzLyk/IoE1ozOnwfZClYdZqy4MfEUewPjoeWMXYxcHEIC E5kktp5ZyAzhfGOUOH5gApDDCeRsZJRYcUsOIjGBUeLzxaNALRwcbAImEm9WOYLERQTaGCW+n djKDtLALFAm8XDxE1YQW1ggQuLjpE4wm0VAVeLwlh1sIDavgLvErJ3LWUHmSAjISzy7XQ8S5g QKb5zzngUkLCTgJnGixxgkLCFgKPF541LmCYx8CxgZVjFqFKcWlaUW6Rpa6iUVZaZnlOQmZub oGhoY6+WmFhcnpqfmJCYV6yXn525iBIZKPQMD4w7G38f9DjFKcjApifL6L7gaLsSXlJ9SmZFY nBFfVJqTWnyIUYaDQ0mC9/Q+oJxgUWp6akVaZg4waGHSEhw8SiK8f0HSvMUFibnFmekQqVOMi lLivF9AEgIgiYzSPLg2WKRcYpSVEuZlZGBgEOIpSC3KzSxBlX/FKM7BqCTMy7EfaApPZl4J3P RXQIuZgBY/3XoZZHFJIkJKqoFxz9IEEa49DZ0P9vGd2cZgGm0mq3Ld3Sm/zTVyawGjqvO63av vtuedl2D4Jl/0N+cX94ndLvXCLx8oyK441fqiM+zGyyLDY5+Y0qeczAvfwxWW0ZeZfX+RgCfr oU9uhpnX9tRvs3MVkUzfHW3lecN2qfXM1ydT+jIV5VXThY/a72LlM/h67aoSS3FGoqEWc1FxI gCitViijwIAAA== X-Env-Sender: konrad.wilk@oracle.com X-Msg-Ref: server-6.tower-31.messagelabs.com!1473626158!33746616!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: 8.84; banners=-,-,- X-VirusChecked: Checked Received: (qmail 34365 invoked from network); 11 Sep 2016 20:36:00 -0000 Received: from aserp1040.oracle.com (HELO aserp1040.oracle.com) (141.146.126.69) by server-6.tower-31.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 11 Sep 2016 20:36:00 -0000 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id u8BKZjNR004835 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 11 Sep 2016 20:35:46 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userv0022.oracle.com (8.14.4/8.13.8) with ESMTP id u8BKZjBa005292 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Sun, 11 Sep 2016 20:35:45 GMT Received: from abhmp0016.oracle.com (abhmp0016.oracle.com [141.146.116.22]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id u8BKZixs030388; Sun, 11 Sep 2016 20:35:44 GMT Received: from localhost.localdomain.com (/209.6.196.81) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Sun, 11 Sep 2016 13:35:43 -0700 From: Konrad Rzeszutek Wilk To: xen-devel@lists.xenproject.org, konrad@kernel.org, julien.grall@arm.com, sstabellini@kernel.org, ross.lagerwall@citrix.com Date: Sun, 11 Sep 2016 16:35:17 -0400 Message-Id: <1473626125-13683-11-git-send-email-konrad.wilk@oracle.com> X-Mailer: git-send-email 2.4.11 In-Reply-To: <1473626125-13683-1-git-send-email-konrad.wilk@oracle.com> References: <1473626125-13683-1-git-send-email-konrad.wilk@oracle.com> X-Source-IP: userv0022.oracle.com [156.151.31.74] Cc: andrew.cooper3@citrix.com, Jan Beulich , Konrad Rzeszutek Wilk Subject: [Xen-devel] [PATCH v3 10/18] livepatch: Move test-cases to their own sub-directory in test. 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-Virus-Scanned: ClamAV using ClamSMTP So they can be shared with ARM64 (but not yet, so they are only built on x86). No functional change. We also need to tweak the MAINTAINERS and .gitignore file. Also we need to update SUBDIRS to include the new 'test' directory so 'cscope' can show the example livepatches. Acked-by: Jan Beulich [for directory] Signed-off-by: Konrad Rzeszutek Wilk --- Cc: Stefano Stabellini Cc: Julien Grall Cc: Jan Beulich Cc: Andrew Cooper v1: First submission v2: Move to test/livepatch per Jan's recommendation v3: Sort MAINTAINERS for livepatch. Add Jan's Acked-by. Added on the SUBDIRS the 'test' directory Change title of patch (common-> own sub-directory) --- .gitignore | 8 +-- MAINTAINERS | 1 + xen/Makefile | 5 +- xen/arch/arm/Makefile | 3 - xen/arch/x86/Makefile | 5 -- xen/arch/x86/test/Makefile | 85 ----------------------------- xen/arch/x86/test/xen_bye_world.c | 34 ------------ xen/arch/x86/test/xen_bye_world_func.c | 22 -------- xen/arch/x86/test/xen_hello_world.c | 63 --------------------- xen/arch/x86/test/xen_hello_world_func.c | 39 ------------- xen/arch/x86/test/xen_replace_world.c | 33 ----------- xen/arch/x86/test/xen_replace_world_func.c | 22 -------- xen/test/Makefile | 9 +++ xen/test/livepatch/Makefile | 85 +++++++++++++++++++++++++++++ xen/test/livepatch/xen_bye_world.c | 34 ++++++++++++ xen/test/livepatch/xen_bye_world_func.c | 22 ++++++++ xen/test/livepatch/xen_hello_world.c | 63 +++++++++++++++++++++ xen/test/livepatch/xen_hello_world_func.c | 39 +++++++++++++ xen/test/livepatch/xen_replace_world.c | 33 +++++++++++ xen/test/livepatch/xen_replace_world_func.c | 22 ++++++++ 20 files changed, 315 insertions(+), 312 deletions(-) delete mode 100644 xen/arch/x86/test/Makefile delete mode 100644 xen/arch/x86/test/xen_bye_world.c delete mode 100644 xen/arch/x86/test/xen_bye_world_func.c delete mode 100644 xen/arch/x86/test/xen_hello_world.c delete mode 100644 xen/arch/x86/test/xen_hello_world_func.c delete mode 100644 xen/arch/x86/test/xen_replace_world.c delete mode 100644 xen/arch/x86/test/xen_replace_world_func.c create mode 100644 xen/test/Makefile create mode 100644 xen/test/livepatch/Makefile create mode 100644 xen/test/livepatch/xen_bye_world.c create mode 100644 xen/test/livepatch/xen_bye_world_func.c create mode 100644 xen/test/livepatch/xen_hello_world.c create mode 100644 xen/test/livepatch/xen_hello_world_func.c create mode 100644 xen/test/livepatch/xen_replace_world.c create mode 100644 xen/test/livepatch/xen_replace_world_func.c diff --git a/.gitignore b/.gitignore index cc64fc9..eeabe0b 100644 --- a/.gitignore +++ b/.gitignore @@ -254,10 +254,6 @@ xen/arch/x86/efi.lds xen/arch/x86/efi/check.efi xen/arch/x86/efi/disabled xen/arch/x86/efi/mkreloc -xen/arch/x86/test/config.h -xen/arch/x86/test/xen_hello_world.livepatch -xen/arch/x86/test/xen_bye_world.livepatch -xen/arch/x86/test/xen_replace_world.livepatch xen/arch/*/efi/boot.c xen/arch/*/efi/compat.c xen/arch/*/efi/efi.h @@ -274,6 +270,10 @@ xen/include/public/public xen/include/xen/*.new xen/include/xen/acm_policy.h xen/include/xen/compile.h +xen/test/livepatch/config.h +xen/test/livepatch/xen_bye_world.livepatch +xen/test/livepatch/xen_hello_world.livepatch +xen/test/livepatch/xen_replace_world.livepatch xen/tools/kconfig/.tmp_gtkcheck xen/tools/kconfig/.tmp_qtcheck xen/tools/symbols diff --git a/MAINTAINERS b/MAINTAINERS index ae0b6bc..edc8603 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -272,6 +272,7 @@ F: xen/arch/*/livepatch* F: xen/arch/*/*/livepatch* F: xen/common/livepatch* F: xen/include/xen/livepatch* +F: xen/test/livepatch/* MACHINE CHECK (MCA) & RAS M: Christoph Egger diff --git a/xen/Makefile b/xen/Makefile index 012509b..e989a20 100644 --- a/xen/Makefile +++ b/xen/Makefile @@ -80,7 +80,7 @@ _install: $(TARGET)$(CONFIG_XEN_INSTALL_SUFFIX) .PHONY: _tests _tests: - $(MAKE) -f $(BASEDIR)/Rules.mk -C arch/$(TARGET_ARCH) tests + $(MAKE) -f $(BASEDIR)/Rules.mk -C test tests .PHONY: _uninstall _uninstall: D=$(DESTDIR) @@ -114,6 +114,7 @@ _clean: delete-unfresh-files $(MAKE) -f $(BASEDIR)/Rules.mk -C xsm clean $(MAKE) -f $(BASEDIR)/Rules.mk -C crypto clean $(MAKE) -f $(BASEDIR)/Rules.mk -C arch/$(TARGET_ARCH) clean + $(MAKE) -f $(BASEDIR)/Rules.mk -C test clean $(MAKE) -f $(BASEDIR)/tools/kconfig/Makefile.kconfig ARCH=$(ARCH) SRCARCH=$(SRCARCH) clean find . \( -name "*.o" -o -name ".*.d" \) -exec rm -f {} \; rm -f include/asm $(TARGET) $(TARGET).gz $(TARGET).efi $(TARGET).efi.map $(TARGET)-syms $(TARGET)-syms.map *~ core @@ -189,7 +190,7 @@ include/asm-$(TARGET_ARCH)/asm-offsets.h: arch/$(TARGET_ARCH)/asm-offsets.s echo ""; \ echo "#endif") <$< >$@ -SUBDIRS = xsm arch/$(TARGET_ARCH) common drivers +SUBDIRS = xsm arch/$(TARGET_ARCH) common drivers test define all_sources ( find include/asm-$(TARGET_ARCH) -name '*.h' -print; \ find include -name 'asm-*' -prune -o -name '*.h' -print; \ diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile index c3ce5a3..516e0af 100644 --- a/xen/arch/arm/Makefile +++ b/xen/arch/arm/Makefile @@ -74,9 +74,6 @@ ifeq ($(CONFIG_ARM_64),y) ln -sf $(notdir $@) ../../$(notdir $@).efi endif -.PHONY: tests -tests: - $(TARGET).axf: $(TARGET)-syms # XXX: VE model loads by VMA so instead of # making a proper ELF we link with LMA == VMA and adjust crudely diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile index d3875c5..931917d 100644 --- a/xen/arch/x86/Makefile +++ b/xen/arch/x86/Makefile @@ -93,10 +93,6 @@ $(TARGET): $(TARGET)-syms $(efi-y) boot/mkelf32 ./boot/mkelf32 $(notes_phdrs) $(TARGET)-syms $(TARGET) 0x100000 \ `$(NM) -nr $(TARGET)-syms | head -n 1 | sed -e 's/^\([^ ]*\).*/0x\1/'` -.PHONY: tests -tests: - $(MAKE) -f $(BASEDIR)/Rules.mk -C test livepatch - ALL_OBJS := $(BASEDIR)/arch/x86/boot/built_in.o $(BASEDIR)/arch/x86/efi/built_in.o $(ALL_OBJS) ifeq ($(lto),y) @@ -226,4 +222,3 @@ clean:: rm -f $(BASEDIR)/.xen.efi.[0-9]* efi/*.o efi/.*.d efi/*.efi efi/disabled efi/mkreloc rm -f boot/reloc.S boot/reloc.lnk boot/reloc.bin rm -f note.o - $(MAKE) -f $(BASEDIR)/Rules.mk -C test clean diff --git a/xen/arch/x86/test/Makefile b/xen/arch/x86/test/Makefile deleted file mode 100644 index 23dff1d..0000000 --- a/xen/arch/x86/test/Makefile +++ /dev/null @@ -1,85 +0,0 @@ -include $(XEN_ROOT)/Config.mk - -CODE_ADDR=$(shell nm --defined $(1) | grep $(2) | awk '{print "0x"$$1}') -CODE_SZ=$(shell nm --defined -S $(1) | grep $(2) | awk '{ print "0x"$$2}') - -.PHONY: default - -LIVEPATCH := xen_hello_world.livepatch -LIVEPATCH_BYE := xen_bye_world.livepatch -LIVEPATCH_REPLACE := xen_replace_world.livepatch - -default: livepatch - -install: livepatch - $(INSTALL_DATA) $(LIVEPATCH) $(DESTDIR)$(DEBUG_DIR)/$(LIVEPATCH) - $(INSTALL_DATA) $(LIVEPATCH_BYE) $(DESTDIR)$(DEBUG_DIR)/$(LIVEPATCH_BYE) - $(INSTALL_DATA) $(LIVEPATCH_REPLACE) $(DESTDIR)$(DEBUG_DIR)/$(LIVEPATCH_REPLACE) -uninstall: - rm -f $(DESTDIR)$(DEBUG_DIR)/$(LIVEPATCH) - rm -f $(DESTDIR)$(DEBUG_DIR)/$(LIVEPATCH_BYE) - rm -f $(DESTDIR)$(DEBUG_DIR)/$(LIVEPATCH_REPLACE) - -.PHONY: clean -clean:: - rm -f *.o .*.o.d *.livepatch config.h - -# -# To compute these values we need the binary files: xen-syms -# and xen_hello_world_func.o to be already compiled. -# -.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 - (set -e; \ - echo "#define NEW_CODE_SZ $(NEW_CODE_SZ)"; \ - echo "#define OLD_CODE_SZ $(OLD_CODE_SZ)") > $@ - -xen_hello_world.o: config.h - -.PHONY: $(LIVEPATCH) -$(LIVEPATCH): xen_hello_world_func.o xen_hello_world.o note.o - $(LD) $(LDFLAGS) $(build_id_linker) -r -o $(LIVEPATCH) $^ - -# -# This target is only accessible if CONFIG_LIVEPATCH is defined, which -# depends on $(build_id_linker) being available. Hence we do not -# need any checks. -# -# N.B. The reason we don't use arch/x86/note.o is that it may -# not be built (it is for EFI builds), and that we do not have -# the note.o.bin to muck with (as it gets deleted) -# -.PHONY: note.o -note.o: - $(OBJCOPY) -O binary --only-section=.note.gnu.build-id $(BASEDIR)/xen-syms $@.bin - $(OBJCOPY) -I binary -O elf64-x86-64 -B i386:x86-64 \ - --rename-section=.data=.livepatch.depends -S $@.bin $@ - rm -f $@.bin - -# -# Extract the build-id of the xen_hello_world.livepatch -# (which xen_bye_world will depend on). -# -.PHONY: hello_world_note.o -hello_world_note.o: $(LIVEPATCH) - $(OBJCOPY) -O binary --only-section=.note.gnu.build-id $(LIVEPATCH) $@.bin - $(OBJCOPY) -I binary -O elf64-x86-64 -B i386:x86-64 \ - --rename-section=.data=.livepatch.depends -S $@.bin $@ - rm -f $@.bin - -xen_bye_world.o: config.h - -.PHONY: $(LIVEPATCH_BYE) -$(LIVEPATCH_BYE): xen_bye_world_func.o xen_bye_world.o hello_world_note.o - $(LD) $(LDFLAGS) $(build_id_linker) -r -o $(LIVEPATCH_BYE) $^ - -xen_replace_world.o: config.h - -.PHONY: $(LIVEPATCH_REPLACE) -$(LIVEPATCH_REPLACE): xen_replace_world_func.o xen_replace_world.o note.o - $(LD) $(LDFLAGS) $(build_id_linker) -r -o $(LIVEPATCH_REPLACE) $^ - -.PHONY: livepatch -livepatch: $(LIVEPATCH) $(LIVEPATCH_BYE) $(LIVEPATCH_REPLACE) diff --git a/xen/arch/x86/test/xen_bye_world.c b/xen/arch/x86/test/xen_bye_world.c deleted file mode 100644 index b75e0b1..0000000 --- a/xen/arch/x86/test/xen_bye_world.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. - * - */ - -#include "config.h" -#include -#include -#include -#include - -#include - -static char bye_world_patch_this_fnc[] = "xen_extra_version"; -extern const char *xen_bye_world(void); - -struct livepatch_func __section(".livepatch.funcs") livepatch_xen_bye_world = { - .version = LIVEPATCH_PAYLOAD_VERSION, - .name = bye_world_patch_this_fnc, - .new_addr = xen_bye_world, - .old_addr = 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 deleted file mode 100644 index 32ef341..0000000 --- a/xen/arch/x86/test/xen_bye_world_func.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. - * - */ - -#include - -/* 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/arch/x86/test/xen_hello_world.c b/xen/arch/x86/test/xen_hello_world.c deleted file mode 100644 index 472fe2e..0000000 --- a/xen/arch/x86/test/xen_hello_world.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. - * - */ - -#include "config.h" -#include -#include -#include -#include -#include - -#include - -static char hello_world_patch_this_fnc[] = "xen_extra_version"; -extern const char *xen_hello_world(void); -/* - * .bss is only cleared once - during upload. Apply/revert/apply will result - * in cnt to have a non-zero value (see the hooks below). - */ -static unsigned int cnt; - -static void apply_hook(void) -{ - printk(KERN_DEBUG "Hook executing.\n"); -} - -static void revert_hook(void) -{ - printk(KERN_DEBUG "Hook unloaded.\n"); -} - -static void hi_func(void) -{ - printk(KERN_DEBUG "%s: Hi! (called %u times)\n", __func__, ++cnt); -}; - -LIVEPATCH_LOAD_HOOK(apply_hook); -LIVEPATCH_UNLOAD_HOOK(revert_hook); - -/* Imbalance here. Two load and three unload. */ - -LIVEPATCH_LOAD_HOOK(hi_func); -LIVEPATCH_UNLOAD_HOOK(hi_func); - -struct livepatch_func __section(".livepatch.funcs") livepatch_xen_hello_world = { - .version = LIVEPATCH_PAYLOAD_VERSION, - .name = hello_world_patch_this_fnc, - .new_addr = xen_hello_world, - .old_addr = 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_hello_world_func.c b/xen/arch/x86/test/xen_hello_world_func.c deleted file mode 100644 index 03d6b84..0000000 --- a/xen/arch/x86/test/xen_hello_world_func.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. - * - */ - -#include - -#include -#include -#include - -static unsigned long *non_canonical_addr = (unsigned long *)0xdead000000000000ULL; - -/* Our replacement function for xen_extra_version. */ -const char *xen_hello_world(void) -{ - unsigned long tmp; - int rc; - - alternative(ASM_NOP8, ASM_NOP1, X86_FEATURE_LM); - /* - * Any BUG, or WARN_ON will contain symbol and payload name. Furthermore - * exceptions will be caught and processed properly. - */ - rc = __get_user(tmp, non_canonical_addr); - BUG_ON(rc != -EFAULT); - - return "Hello 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/arch/x86/test/xen_replace_world.c b/xen/arch/x86/test/xen_replace_world.c deleted file mode 100644 index a2a221a..0000000 --- a/xen/arch/x86/test/xen_replace_world.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. - * - */ - -#include "config.h" -#include -#include -#include - -#include - -static char xen_replace_world_name[] = "xen_extra_version"; -extern const char *xen_replace_world(void); - -struct livepatch_func __section(".livepatch.funcs") livepatch_xen_replace_world = { - .version = LIVEPATCH_PAYLOAD_VERSION, - .name = xen_replace_world_name, - .old_addr = 0, /* Forces the hypervisor to lookup .name */ - .new_addr = xen_replace_world, - .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_replace_world_func.c b/xen/arch/x86/test/xen_replace_world_func.c deleted file mode 100644 index afb5cda..0000000 --- a/xen/arch/x86/test/xen_replace_world_func.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. - * - */ - -#include - -/* Our replacement function for xen_hello_world. */ -const char *xen_replace_world(void) -{ - return "Hello Again 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/test/Makefile b/xen/test/Makefile new file mode 100644 index 0000000..8c53040 --- /dev/null +++ b/xen/test/Makefile @@ -0,0 +1,9 @@ +.PHONY: tests +tests: +ifeq ($(XEN_TARGET_ARCH),x86_64) + $(MAKE) -f $(BASEDIR)/Rules.mk -C livepatch livepatch +endif + +.PHONY: clean +clean:: + $(MAKE) -f $(BASEDIR)/Rules.mk -C livepatch clean diff --git a/xen/test/livepatch/Makefile b/xen/test/livepatch/Makefile new file mode 100644 index 0000000..23dff1d --- /dev/null +++ b/xen/test/livepatch/Makefile @@ -0,0 +1,85 @@ +include $(XEN_ROOT)/Config.mk + +CODE_ADDR=$(shell nm --defined $(1) | grep $(2) | awk '{print "0x"$$1}') +CODE_SZ=$(shell nm --defined -S $(1) | grep $(2) | awk '{ print "0x"$$2}') + +.PHONY: default + +LIVEPATCH := xen_hello_world.livepatch +LIVEPATCH_BYE := xen_bye_world.livepatch +LIVEPATCH_REPLACE := xen_replace_world.livepatch + +default: livepatch + +install: livepatch + $(INSTALL_DATA) $(LIVEPATCH) $(DESTDIR)$(DEBUG_DIR)/$(LIVEPATCH) + $(INSTALL_DATA) $(LIVEPATCH_BYE) $(DESTDIR)$(DEBUG_DIR)/$(LIVEPATCH_BYE) + $(INSTALL_DATA) $(LIVEPATCH_REPLACE) $(DESTDIR)$(DEBUG_DIR)/$(LIVEPATCH_REPLACE) +uninstall: + rm -f $(DESTDIR)$(DEBUG_DIR)/$(LIVEPATCH) + rm -f $(DESTDIR)$(DEBUG_DIR)/$(LIVEPATCH_BYE) + rm -f $(DESTDIR)$(DEBUG_DIR)/$(LIVEPATCH_REPLACE) + +.PHONY: clean +clean:: + rm -f *.o .*.o.d *.livepatch config.h + +# +# To compute these values we need the binary files: xen-syms +# and xen_hello_world_func.o to be already compiled. +# +.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 + (set -e; \ + echo "#define NEW_CODE_SZ $(NEW_CODE_SZ)"; \ + echo "#define OLD_CODE_SZ $(OLD_CODE_SZ)") > $@ + +xen_hello_world.o: config.h + +.PHONY: $(LIVEPATCH) +$(LIVEPATCH): xen_hello_world_func.o xen_hello_world.o note.o + $(LD) $(LDFLAGS) $(build_id_linker) -r -o $(LIVEPATCH) $^ + +# +# This target is only accessible if CONFIG_LIVEPATCH is defined, which +# depends on $(build_id_linker) being available. Hence we do not +# need any checks. +# +# N.B. The reason we don't use arch/x86/note.o is that it may +# not be built (it is for EFI builds), and that we do not have +# the note.o.bin to muck with (as it gets deleted) +# +.PHONY: note.o +note.o: + $(OBJCOPY) -O binary --only-section=.note.gnu.build-id $(BASEDIR)/xen-syms $@.bin + $(OBJCOPY) -I binary -O elf64-x86-64 -B i386:x86-64 \ + --rename-section=.data=.livepatch.depends -S $@.bin $@ + rm -f $@.bin + +# +# Extract the build-id of the xen_hello_world.livepatch +# (which xen_bye_world will depend on). +# +.PHONY: hello_world_note.o +hello_world_note.o: $(LIVEPATCH) + $(OBJCOPY) -O binary --only-section=.note.gnu.build-id $(LIVEPATCH) $@.bin + $(OBJCOPY) -I binary -O elf64-x86-64 -B i386:x86-64 \ + --rename-section=.data=.livepatch.depends -S $@.bin $@ + rm -f $@.bin + +xen_bye_world.o: config.h + +.PHONY: $(LIVEPATCH_BYE) +$(LIVEPATCH_BYE): xen_bye_world_func.o xen_bye_world.o hello_world_note.o + $(LD) $(LDFLAGS) $(build_id_linker) -r -o $(LIVEPATCH_BYE) $^ + +xen_replace_world.o: config.h + +.PHONY: $(LIVEPATCH_REPLACE) +$(LIVEPATCH_REPLACE): xen_replace_world_func.o xen_replace_world.o note.o + $(LD) $(LDFLAGS) $(build_id_linker) -r -o $(LIVEPATCH_REPLACE) $^ + +.PHONY: livepatch +livepatch: $(LIVEPATCH) $(LIVEPATCH_BYE) $(LIVEPATCH_REPLACE) diff --git a/xen/test/livepatch/xen_bye_world.c b/xen/test/livepatch/xen_bye_world.c new file mode 100644 index 0000000..b75e0b1 --- /dev/null +++ b/xen/test/livepatch/xen_bye_world.c @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. + * + */ + +#include "config.h" +#include +#include +#include +#include + +#include + +static char bye_world_patch_this_fnc[] = "xen_extra_version"; +extern const char *xen_bye_world(void); + +struct livepatch_func __section(".livepatch.funcs") livepatch_xen_bye_world = { + .version = LIVEPATCH_PAYLOAD_VERSION, + .name = bye_world_patch_this_fnc, + .new_addr = xen_bye_world, + .old_addr = 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/test/livepatch/xen_bye_world_func.c b/xen/test/livepatch/xen_bye_world_func.c new file mode 100644 index 0000000..32ef341 --- /dev/null +++ b/xen/test/livepatch/xen_bye_world_func.c @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. + * + */ + +#include + +/* 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/test/livepatch/xen_hello_world.c b/xen/test/livepatch/xen_hello_world.c new file mode 100644 index 0000000..472fe2e --- /dev/null +++ b/xen/test/livepatch/xen_hello_world.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. + * + */ + +#include "config.h" +#include +#include +#include +#include +#include + +#include + +static char hello_world_patch_this_fnc[] = "xen_extra_version"; +extern const char *xen_hello_world(void); +/* + * .bss is only cleared once - during upload. Apply/revert/apply will result + * in cnt to have a non-zero value (see the hooks below). + */ +static unsigned int cnt; + +static void apply_hook(void) +{ + printk(KERN_DEBUG "Hook executing.\n"); +} + +static void revert_hook(void) +{ + printk(KERN_DEBUG "Hook unloaded.\n"); +} + +static void hi_func(void) +{ + printk(KERN_DEBUG "%s: Hi! (called %u times)\n", __func__, ++cnt); +}; + +LIVEPATCH_LOAD_HOOK(apply_hook); +LIVEPATCH_UNLOAD_HOOK(revert_hook); + +/* Imbalance here. Two load and three unload. */ + +LIVEPATCH_LOAD_HOOK(hi_func); +LIVEPATCH_UNLOAD_HOOK(hi_func); + +struct livepatch_func __section(".livepatch.funcs") livepatch_xen_hello_world = { + .version = LIVEPATCH_PAYLOAD_VERSION, + .name = hello_world_patch_this_fnc, + .new_addr = xen_hello_world, + .old_addr = 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/test/livepatch/xen_hello_world_func.c b/xen/test/livepatch/xen_hello_world_func.c new file mode 100644 index 0000000..03d6b84 --- /dev/null +++ b/xen/test/livepatch/xen_hello_world_func.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. + * + */ + +#include + +#include +#include +#include + +static unsigned long *non_canonical_addr = (unsigned long *)0xdead000000000000ULL; + +/* Our replacement function for xen_extra_version. */ +const char *xen_hello_world(void) +{ + unsigned long tmp; + int rc; + + alternative(ASM_NOP8, ASM_NOP1, X86_FEATURE_LM); + /* + * Any BUG, or WARN_ON will contain symbol and payload name. Furthermore + * exceptions will be caught and processed properly. + */ + rc = __get_user(tmp, non_canonical_addr); + BUG_ON(rc != -EFAULT); + + return "Hello 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/test/livepatch/xen_replace_world.c b/xen/test/livepatch/xen_replace_world.c new file mode 100644 index 0000000..a2a221a --- /dev/null +++ b/xen/test/livepatch/xen_replace_world.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. + * + */ + +#include "config.h" +#include +#include +#include + +#include + +static char xen_replace_world_name[] = "xen_extra_version"; +extern const char *xen_replace_world(void); + +struct livepatch_func __section(".livepatch.funcs") livepatch_xen_replace_world = { + .version = LIVEPATCH_PAYLOAD_VERSION, + .name = xen_replace_world_name, + .old_addr = 0, /* Forces the hypervisor to lookup .name */ + .new_addr = xen_replace_world, + .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/test/livepatch/xen_replace_world_func.c b/xen/test/livepatch/xen_replace_world_func.c new file mode 100644 index 0000000..afb5cda --- /dev/null +++ b/xen/test/livepatch/xen_replace_world_func.c @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. + * + */ + +#include + +/* Our replacement function for xen_hello_world. */ +const char *xen_replace_world(void) +{ + return "Hello Again World!"; +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */