From patchwork Fri Dec 15 11:18:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Roger_Pau_Monn=C3=A9?= X-Patchwork-Id: 13494328 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E3945C41535 for ; Fri, 15 Dec 2023 11:19:08 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.655030.1022680 (Exim 4.92) (envelope-from ) id 1rE6DW-0002Jf-2f; Fri, 15 Dec 2023 11:18:54 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 655030.1022680; Fri, 15 Dec 2023 11:18:54 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1rE6DV-0002JY-Vj; Fri, 15 Dec 2023 11:18:53 +0000 Received: by outflank-mailman (input) for mailman id 655030; Fri, 15 Dec 2023 11:18:52 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1rE6DU-00024C-Dj for xen-devel@lists.xenproject.org; Fri, 15 Dec 2023 11:18:52 +0000 Received: from mail-wr1-x435.google.com (mail-wr1-x435.google.com [2a00:1450:4864:20::435]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id b9b3ba33-9b3b-11ee-98ea-6d05b1d4d9a1; Fri, 15 Dec 2023 12:18:51 +0100 (CET) Received: by mail-wr1-x435.google.com with SMTP id ffacd0b85a97d-33638e7f71aso269965f8f.1 for ; Fri, 15 Dec 2023 03:18:51 -0800 (PST) Received: from localhost ([213.195.127.70]) by smtp.gmail.com with ESMTPSA id t6-20020a5d6906000000b003364c7a8f2csm2414842wru.60.2023.12.15.03.18.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Dec 2023 03:18:49 -0800 (PST) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: b9b3ba33-9b3b-11ee-98ea-6d05b1d4d9a1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1702639130; x=1703243930; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ZC9Vxss+k2nEc+pnvf7NZ+INbsOVxJbzC5jLly5PWRM=; b=cIG0B2tXACsBh1SIt0wsXQQ5Ecw5r11Zn7lo6gZp6JF/jAVpo7zddcG0u+SZrIs5mF ykAKZJy1g7bb+8rv1K8ipAT/by7xy2vUfR/FTeni4RHcFRJroRB024LaibOHWa7xz2yx Xf50vQDIJrEB90CwgSgj0QRoL/mHqd48qciKg= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702639130; x=1703243930; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ZC9Vxss+k2nEc+pnvf7NZ+INbsOVxJbzC5jLly5PWRM=; b=YbkEs2pNgDcPvrO8wO02ZVkwpuCwYnfrRuZ430q3PYFtGyydWDW6xdqBviqeu7FHf3 +AuOz9rQ7xs0RK065R3kcmArnhZyTOx6pRFCXcDSF7zIBm/nIh2CrBsmjbw+iVs46lyL gmCCCJiYKs2F+YoUrLVkE436t1i6/gorsxdgQWCKeKxknF3CR3FaL8xJKmwhtYSX9DX3 hvXGipnqxNdavdzXGcOx9RtKFbbYr/DVYTl0nt1u4IG35nT91LrudeDVgB5O5C/iMYTc 5fqOiz1McfPt0JjVJLHCusUSTNlLM3z02uOu+6GdX2KvPAzdwh1vWE231bxd8Ki7qm0U gJkw== X-Gm-Message-State: AOJu0Yzk4MZ2WDDiLjonSlu73CZVDdfRvsb0Erwk2qV2CiKKz1Wi2rcG LFuBWCu8JUQ0EJP9q9LlvGI3xx0D9YSELWr6TyQ= X-Google-Smtp-Source: AGHT+IH0M+5D/QAwXYgxAkDN+ZljJ81WuOOU4uJQ0nLNU+3BWqfooFuQ8OidqkMHCnkLGDT3PC0FAA== X-Received: by 2002:a5d:458c:0:b0:336:44f0:6427 with SMTP id p12-20020a5d458c000000b0033644f06427mr1507783wrq.28.1702639130458; Fri, 15 Dec 2023 03:18:50 -0800 (PST) From: Roger Pau Monne To: xen-devel@lists.xenproject.org Cc: Roger Pau Monne , Andrew Cooper , George Dunlap , Jan Beulich , Julien Grall , Stefano Stabellini , Wei Liu , Konrad Rzeszutek Wilk , Ross Lagerwall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk Subject: [PATCH v4 1/4] x86/livepatch: align functions to ensure minimal distance between entry points Date: Fri, 15 Dec 2023 12:18:39 +0100 Message-ID: <20231215111842.8009-2-roger.pau@citrix.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231215111842.8009-1-roger.pau@citrix.com> References: <20231215111842.8009-1-roger.pau@citrix.com> MIME-Version: 1.0 The minimal function size requirements for livepatch are either 5 bytes (for jmp) or 9 bytes (for endbr + jmp) on x86, and always 4 bytes on Arm. Ensure that distance between functions entry points is always at least of the minimal required size for livepatch instruction replacement to be successful. Add an additional align directive to the linker script, in order to ensure that the next section placed after the .text.* (per-function sections) is also aligned to the required boundary, so that the distance of the last function entry point with the next symbol is also of minimal size. Note that it's possible for the compiler to end up using a higher function alignment regardless of the passed value, so this change just make sure that the minimum required for livepatch to work is present. Different compilers handle the option differently, as clang will ignore -falign-functions value if it's smaller than the one that would be set by the optimization level, while gcc seems to always honor the function alignment passed in -falign-functions. In order to cope with this behavior and avoid that setting -falign-functions results in an alignment inferior to what the optimization level would have selected force x86 release builds to use a function alignment of 16 bytes. The compiler option -falign-functions is not available on at least clang 3.8, so introduce a Kconfig check for it and make the livepatch option depend on the compiler supporting the option. The naming of the option(s) CONFIG_FUNCTION_ALIGNMENT is explicitly not mentioning CC in preparation for the option also being used by assembly code. Signed-off-by: Roger Pau Monné Reviewed-by: Jan Beulich --- Changes since v3: - Test for compiler option with -falign-functions. - Make FUNCTION_ALIGNMENT depend on CC_HAS_FUNCTION_ALIGNMENT. - Set 16byte function alignment for x86 release builds. Changes since v2: - Add Arm side. - Align end of section in the linker script to ensure enough padding for the last function. - Expand commit message and subject. - Rework Kconfig options. - Check that the compiler supports the option. Changes since v1: - New in this version. --- xen/Kconfig | 19 +++++++++++++++++++ xen/Makefile | 3 +++ xen/arch/arm/livepatch.c | 2 ++ xen/arch/arm/xen.lds.S | 4 ++++ xen/arch/x86/Kconfig | 1 + xen/arch/x86/livepatch.c | 4 ++++ xen/arch/x86/xen.lds.S | 4 ++++ xen/common/Kconfig | 5 ++++- 8 files changed, 41 insertions(+), 1 deletion(-) diff --git a/xen/Kconfig b/xen/Kconfig index 134e6e68ad84..c2cc3fe165eb 100644 --- a/xen/Kconfig +++ b/xen/Kconfig @@ -37,6 +37,25 @@ config CC_HAS_VISIBILITY_ATTRIBUTE config CC_SPLIT_SECTIONS bool +# Set function alignment. +# +# Allow setting on a boolean basis, and then convert such selection to an +# integer for the build system and code to consume more easily. +config CC_HAS_FUNCTION_ALIGNMENT + def_bool $(cc-option,-falign-functions) +config FUNCTION_ALIGNMENT_4B + bool +config FUNCTION_ALIGNMENT_8B + bool +config FUNCTION_ALIGNMENT_16B + bool +config FUNCTION_ALIGNMENT + int + depends on CC_HAS_FUNCTION_ALIGNMENT + default 16 if FUNCTION_ALIGNMENT_16B + default 8 if FUNCTION_ALIGNMENT_8B + default 4 if FUNCTION_ALIGNMENT_4B + source "arch/$(SRCARCH)/Kconfig" config DEFCONFIG_LIST diff --git a/xen/Makefile b/xen/Makefile index 21832d640225..162cb2bda1c5 100644 --- a/xen/Makefile +++ b/xen/Makefile @@ -390,6 +390,9 @@ CFLAGS += -fomit-frame-pointer endif CFLAGS-$(CONFIG_CC_SPLIT_SECTIONS) += -ffunction-sections -fdata-sections +ifdef CONFIG_FUNCTION_ALIGNMENT +CFLAGS += -falign-functions=$(CONFIG_FUNCTION_ALIGNMENT) +endif CFLAGS += -nostdinc -fno-builtin -fno-common CFLAGS += -Werror -Wredundant-decls -Wwrite-strings -Wno-pointer-arith diff --git a/xen/arch/arm/livepatch.c b/xen/arch/arm/livepatch.c index bbca1e5a5ed3..aa8ae8c38d28 100644 --- a/xen/arch/arm/livepatch.c +++ b/xen/arch/arm/livepatch.c @@ -68,6 +68,8 @@ void arch_livepatch_revive(void) int arch_livepatch_verify_func(const struct livepatch_func *func) { + BUILD_BUG_ON(ARCH_PATCH_INSN_SIZE > CONFIG_FUNCTION_ALIGNMENT); + /* If NOPing only do up to maximum amount we can put in the ->opaque. */ if ( !func->new_addr && (func->new_size > LIVEPATCH_OPAQUE_SIZE || func->new_size % ARCH_PATCH_INSN_SIZE) ) diff --git a/xen/arch/arm/xen.lds.S b/xen/arch/arm/xen.lds.S index 59b80d122fd0..afaf1e996b0e 100644 --- a/xen/arch/arm/xen.lds.S +++ b/xen/arch/arm/xen.lds.S @@ -44,6 +44,10 @@ SECTIONS #ifdef CONFIG_CC_SPLIT_SECTIONS *(.text.*) #endif +#ifdef CONFIG_FUNCTION_ALIGNMENT + /* Ensure enough distance with the next placed section. */ + . = ALIGN(CONFIG_FUNCTION_ALIGNMENT); +#endif *(.fixup) *(.gnu.warning) diff --git a/xen/arch/x86/Kconfig b/xen/arch/x86/Kconfig index 1acdffc51c22..0cd741be5b6f 100644 --- a/xen/arch/x86/Kconfig +++ b/xen/arch/x86/Kconfig @@ -29,6 +29,7 @@ config X86 select HAS_UBSAN select HAS_VPCI if HVM select NEEDS_LIBELF + select FUNCTION_ALIGNMENT_16B if !DEBUG config ARCH_DEFCONFIG string diff --git a/xen/arch/x86/livepatch.c b/xen/arch/x86/livepatch.c index ee539f001b73..b00ad7120da9 100644 --- a/xen/arch/x86/livepatch.c +++ b/xen/arch/x86/livepatch.c @@ -109,6 +109,10 @@ int arch_livepatch_verify_func(const struct livepatch_func *func) */ uint8_t needed = ARCH_PATCH_INSN_SIZE; + BUILD_BUG_ON(ARCH_PATCH_INSN_SIZE + + (IS_ENABLED(CONIFG_XEN_IBT) ? ENDBR64_LEN : 0) > + CONFIG_FUNCTION_ALIGNMENT); + if ( is_endbr64(func->old_addr) || is_endbr64_poison(func->old_addr) ) needed += ENDBR64_LEN; diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S index 8930e14fc40e..5b3332300d44 100644 --- a/xen/arch/x86/xen.lds.S +++ b/xen/arch/x86/xen.lds.S @@ -99,6 +99,10 @@ SECTIONS *(.text) #ifdef CONFIG_CC_SPLIT_SECTIONS *(.text.*) +#endif +#ifdef CONFIG_FUNCTION_ALIGNMENT + /* Ensure enough distance with the next placed section. */ + . = ALIGN(CONFIG_FUNCTION_ALIGNMENT); #endif *(.text.__x86_indirect_thunk_*) diff --git a/xen/common/Kconfig b/xen/common/Kconfig index 310ad4229cdf..c9a21c3c8a07 100644 --- a/xen/common/Kconfig +++ b/xen/common/Kconfig @@ -395,8 +395,11 @@ config CRYPTO config LIVEPATCH bool "Live patching support" default X86 - depends on "$(XEN_HAS_BUILD_ID)" = "y" + depends on "$(XEN_HAS_BUILD_ID)" = "y" && CC_HAS_FUNCTION_ALIGNMENT select CC_SPLIT_SECTIONS + select FUNCTION_ALIGNMENT_16B if XEN_IBT + select FUNCTION_ALIGNMENT_8B if X86 + select FUNCTION_ALIGNMENT_4B ---help--- Allows a running Xen hypervisor to be dynamically patched using binary patches without rebooting. This is primarily used to binarily From patchwork Fri Dec 15 11:18:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Roger_Pau_Monn=C3=A9?= X-Patchwork-Id: 13494326 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 8C6D2C46CA2 for ; Fri, 15 Dec 2023 11:19:08 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.655031.1022691 (Exim 4.92) (envelope-from ) id 1rE6DZ-0002a1-Bn; Fri, 15 Dec 2023 11:18:57 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 655031.1022691; Fri, 15 Dec 2023 11:18:57 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1rE6DZ-0002Zr-6O; Fri, 15 Dec 2023 11:18:57 +0000 Received: by outflank-mailman (input) for mailman id 655031; Fri, 15 Dec 2023 11:18:55 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1rE6DX-0002YQ-KJ for xen-devel@lists.xenproject.org; Fri, 15 Dec 2023 11:18:55 +0000 Received: from mail-wr1-x435.google.com (mail-wr1-x435.google.com [2a00:1450:4864:20::435]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id bacae79c-9b3b-11ee-9b0f-b553b5be7939; Fri, 15 Dec 2023 12:18:53 +0100 (CET) Received: by mail-wr1-x435.google.com with SMTP id ffacd0b85a97d-3333074512bso935334f8f.1 for ; Fri, 15 Dec 2023 03:18:53 -0800 (PST) Received: from localhost ([213.195.127.70]) by smtp.gmail.com with ESMTPSA id i1-20020a05600c354100b0040c411da99csm23156935wmq.48.2023.12.15.03.18.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Dec 2023 03:18:51 -0800 (PST) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: bacae79c-9b3b-11ee-9b0f-b553b5be7939 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1702639132; x=1703243932; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=EJ4YPQXNY4qR0RRVt6L4swFAHn2UjNCHVeT7LC23VgE=; b=AXr7RXjid2TlJ9EA5EBdQp8ZworaGzRbkNAtGM6B89EUcTsx4ApvOINBczd+Yuh5+x RWE7YRzU8cu3SqVF9sxHdDHm/p/D5sbBTvD7DDUnDEa5eBBtqSc0h5Y0/tUGqT1/PGiA XXzgib7qi/w4UuKCkuiS2C1MNvvHv5Qy5mwBU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702639132; x=1703243932; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=EJ4YPQXNY4qR0RRVt6L4swFAHn2UjNCHVeT7LC23VgE=; b=szvZFN9zn8mTaS5cI21CNJrQRdiCZn1l1ncZJqGdJlXXkgAi0GVM3P28rUvHxXC+iP lGpXx0rgW0p+WoNdSi0p3guFGaZavGLZsDmO2pxAyEfhn/jxIa1zfq4dBreWMr8gibhV G5B9/x+f+bS040m+Na+t6wZYgFGS/BHuwTHCOQGHTjOyUIO+1bPd6MhVDBu7ngWatd2v RB7Rt52uHIOR9Qoqkcu2HZ4FVCajhEmy3peA5urERXzxdkI19Y0XDgukor81JOToAV9b Un4v/shdzKiaD/EsfLXngaBLz9pisBhYT9TwA/6XRZHh1Svdh9MS2OPV9FKTj6WAC61M Ud8g== X-Gm-Message-State: AOJu0Yx7MdbyDn7kbPbOXi/UTLhyLsE/psa7eiPkGswxrgNRMfPemdgi AvfFPsHzh5PW+twO4SkUPIy7Y0ysnLkT6ZyRPZQ= X-Google-Smtp-Source: AGHT+IH5PNz/24/bP8VTc+j65gdAELWDZpYAGHFgO/QA947980Z1wu/Y9/3QUmVawihD/uomRJLkug== X-Received: by 2002:a05:600c:54c4:b0:40c:3984:4983 with SMTP id iw4-20020a05600c54c400b0040c39844983mr6213574wmb.76.1702639132200; Fri, 15 Dec 2023 03:18:52 -0800 (PST) From: Roger Pau Monne To: xen-devel@lists.xenproject.org Cc: Roger Pau Monne , Wei Liu , Anthony PERARD , Juergen Gross , Andrew Cooper , George Dunlap , Jan Beulich , Julien Grall , Stefano Stabellini Subject: [PATCH v4 2/4] xen/x86: introduce self modifying code test Date: Fri, 15 Dec 2023 12:18:40 +0100 Message-ID: <20231215111842.8009-3-roger.pau@citrix.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231215111842.8009-1-roger.pau@citrix.com> References: <20231215111842.8009-1-roger.pau@citrix.com> MIME-Version: 1.0 Introduce a helper to perform checks related to self modifying code, and start by creating a simple test to check that alternatives have been applied. Such test is hooked into the boot process and called just after alternatives have been applied. In case of failure a message is printed, and the hypervisor is tainted as not having passed the tests, this does require introducing a new taint bit (printed as 'T'). A new sysctl is also introduced to run the tests on demand. While there are no current users introduced here, further changes will introduce those, and it's helpful to have the interface defined in the sysctl header from the start. Note the sysctl visibility is not limited to x86, albeit the only implementation is for x86. It's expected that other architectures can reuse the same sysctl and structure, with possibly different tests. Leave adjusting those to when support for a different architecture is introduced, as the sysctl interface is not stable anyway. Signed-off-by: Roger Pau Monné Acked-by: Jan Beulich --- Changes since v3: - Rename taint variable. - Introduce a wrapper to run all selftests. - Only print messages and taint the hypervisor when tests are executed on boot. Changes since v2: - Rename to smoc and place in test/smoc* - fix inline assembly. Changes since v1: - Rework test and interface. --- tools/include/xenctrl.h | 2 + tools/libs/ctrl/xc_misc.c | 14 +++++++ xen/arch/x86/Makefile | 1 + xen/arch/x86/include/asm/test.h | 30 +++++++++++++++ xen/arch/x86/setup.c | 3 ++ xen/arch/x86/sysctl.c | 9 +++++ xen/arch/x86/test/Makefile | 1 + xen/arch/x86/test/smoc.c | 66 +++++++++++++++++++++++++++++++++ xen/common/kernel.c | 5 ++- xen/include/public/sysctl.h | 9 +++++ xen/include/xen/lib.h | 1 + 11 files changed, 139 insertions(+), 2 deletions(-) create mode 100644 xen/arch/x86/include/asm/test.h create mode 100644 xen/arch/x86/test/Makefile create mode 100644 xen/arch/x86/test/smoc.c diff --git a/tools/include/xenctrl.h b/tools/include/xenctrl.h index 2ef8b4e05422..0af796ae84e8 100644 --- a/tools/include/xenctrl.h +++ b/tools/include/xenctrl.h @@ -2658,6 +2658,8 @@ int xc_dt_overlay(xc_interface *xch, void *overlay_fdt, uint32_t overlay_fdt_size, uint8_t overlay_op); #endif +int xc_test_smoc(xc_interface *xch, uint32_t tests, uint32_t *result); + /* Compat shims */ #include "xenctrl_compat.h" diff --git a/tools/libs/ctrl/xc_misc.c b/tools/libs/ctrl/xc_misc.c index 5ecdfa2c7934..1d3d5929cf96 100644 --- a/tools/libs/ctrl/xc_misc.c +++ b/tools/libs/ctrl/xc_misc.c @@ -1021,6 +1021,20 @@ int xc_livepatch_replace(xc_interface *xch, char *name, uint32_t timeout, uint32 return _xc_livepatch_action(xch, name, LIVEPATCH_ACTION_REPLACE, timeout, flags); } +int xc_test_smoc(xc_interface *xch, uint32_t tests, uint32_t *result) +{ + struct xen_sysctl sysctl = { + .cmd = XEN_SYSCTL_test_smoc, + .u.test_smoc.tests = tests, + }; + int rc = do_sysctl(xch, &sysctl); + + if ( !rc ) + *result = sysctl.u.test_smoc.results; + + return rc; +} + /* * Local variables: * mode: C diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile index f3abdf9cd111..ad5112b03c64 100644 --- a/xen/arch/x86/Makefile +++ b/xen/arch/x86/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_HVM) += hvm/ obj-y += mm/ obj-$(CONFIG_XENOPROF) += oprofile/ obj-$(CONFIG_PV) += pv/ +obj-y += test/ obj-y += x86_64/ obj-y += x86_emulate/ diff --git a/xen/arch/x86/include/asm/test.h b/xen/arch/x86/include/asm/test.h new file mode 100644 index 000000000000..e96e709c6a52 --- /dev/null +++ b/xen/arch/x86/include/asm/test.h @@ -0,0 +1,30 @@ +#ifndef _ASM_X86_TEST_H_ +#define _ASM_X86_TEST_H_ + +#include + +int test_smoc(uint32_t selection, uint32_t *results); + +static inline void execute_selftests(void) +{ + const uint32_t exec_mask = XEN_SYSCTL_TEST_SMOC_ALL; + uint32_t result; + int rc; + + printk(XENLOG_INFO "Checking Self Modify Code\n"); + rc = test_smoc(exec_mask, &result); + if ( rc || (result & exec_mask) != exec_mask ) + add_taint(TAINT_ERROR_SELFTEST); +} + +#endif /* _ASM_X86_TEST_H_ */ + +/* + * 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/setup.c b/xen/arch/x86/setup.c index 3cba2be0af6c..e974a8f8d725 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -58,6 +58,7 @@ #include #include #include +#include /* opt_nosmp: If true, secondary processors are ignored. */ static bool __initdata opt_nosmp; @@ -1951,6 +1952,8 @@ void asmlinkage __init noreturn __start_xen(unsigned long mbi_p) alternative_branches(); + execute_selftests(); + /* * NB: when running as a PV shim VCPUOP_up/down is wired to the shim * physical cpu_add/remove functions, so launch the guest with only diff --git a/xen/arch/x86/sysctl.c b/xen/arch/x86/sysctl.c index 1d40d82c5ad2..a61a99f8696a 100644 --- a/xen/arch/x86/sysctl.c +++ b/xen/arch/x86/sysctl.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -423,6 +424,14 @@ long arch_do_sysctl( break; } + case XEN_SYSCTL_test_smoc: + ret = test_smoc(sysctl->u.test_smoc.tests, + &sysctl->u.test_smoc.results); + if ( !ret && __copy_field_to_guest(u_sysctl, sysctl, + u.test_smoc.results) ) + ret = -EFAULT; + break; + default: ret = -ENOSYS; break; diff --git a/xen/arch/x86/test/Makefile b/xen/arch/x86/test/Makefile new file mode 100644 index 000000000000..b504b8196659 --- /dev/null +++ b/xen/arch/x86/test/Makefile @@ -0,0 +1 @@ +obj-y += smoc.o diff --git a/xen/arch/x86/test/smoc.c b/xen/arch/x86/test/smoc.c new file mode 100644 index 000000000000..09db5cee9ae2 --- /dev/null +++ b/xen/arch/x86/test/smoc.c @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#include + +#include +#include +#include + +static bool cf_check test_insn_replacement(void) +{ +#define EXPECTED_VALUE 2 + unsigned int r = ~EXPECTED_VALUE; + + alternative_io("", "mov %1, %0", X86_FEATURE_ALWAYS, + "+r" (r), "i" (EXPECTED_VALUE)); + + return r == EXPECTED_VALUE; +#undef EXPECTED_VALUE +} + +int test_smoc(uint32_t selection, uint32_t *results) +{ + struct { + unsigned int mask; + bool (*test)(void); + const char *name; + } static const tests[] = { + { XEN_SYSCTL_TEST_SMOC_INSN_REPL, &test_insn_replacement, + "alternative instruction replacement" }, + }; + unsigned int i; + + if ( selection & ~XEN_SYSCTL_TEST_SMOC_ALL ) + return -EINVAL; + + if ( results ) + *results = 0; + + for ( i = 0; i < ARRAY_SIZE(tests); i++ ) + { + if ( !(selection & tests[i].mask) ) + continue; + + if ( tests[i].test() ) + { + if ( results ) + *results |= tests[i].mask; + continue; + } + + if ( system_state < SYS_STATE_active ) + printk(XENLOG_ERR "%s test failed\n", tests[i].name); + } + + return 0; +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/common/kernel.c b/xen/common/kernel.c index 08dbaa2a054c..77f93f137cac 100644 --- a/xen/common/kernel.c +++ b/xen/common/kernel.c @@ -386,13 +386,14 @@ char *print_tainted(char *str) { if ( tainted ) { - snprintf(str, TAINT_STRING_MAX_LEN, "Tainted: %c%c%c%c%c%c", + snprintf(str, TAINT_STRING_MAX_LEN, "Tainted: %c%c%c%c%c%c%c", tainted & TAINT_MACHINE_INSECURE ? 'I' : ' ', tainted & TAINT_MACHINE_CHECK ? 'M' : ' ', tainted & TAINT_SYNC_CONSOLE ? 'C' : ' ', tainted & TAINT_ERROR_INJECT ? 'E' : ' ', tainted & TAINT_HVM_FEP ? 'H' : ' ', - tainted & TAINT_CPU_OUT_OF_SPEC ? 'S' : ' '); + tainted & TAINT_CPU_OUT_OF_SPEC ? 'S' : ' ', + tainted & TAINT_ERROR_SELFTEST ? 'T' : ' '); } else { diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h index 9b19679caeb1..d015a490da38 100644 --- a/xen/include/public/sysctl.h +++ b/xen/include/public/sysctl.h @@ -1201,6 +1201,13 @@ struct xen_sysctl_dt_overlay { }; #endif +struct xen_sysctl_test_smoc { + uint32_t tests; /* IN: bitmap with selected tests to execute. */ +#define XEN_SYSCTL_TEST_SMOC_INSN_REPL (1U << 0) +#define XEN_SYSCTL_TEST_SMOC_ALL (XEN_SYSCTL_TEST_SMOC_INSN_REPL) + uint32_t results; /* OUT: test result: 1 -> success, 0 -> failure. */ +}; + struct xen_sysctl { uint32_t cmd; #define XEN_SYSCTL_readconsole 1 @@ -1232,6 +1239,7 @@ struct xen_sysctl { /* #define XEN_SYSCTL_set_parameter 28 */ #define XEN_SYSCTL_get_cpu_policy 29 #define XEN_SYSCTL_dt_overlay 30 +#define XEN_SYSCTL_test_smoc 31 uint32_t interface_version; /* XEN_SYSCTL_INTERFACE_VERSION */ union { struct xen_sysctl_readconsole readconsole; @@ -1259,6 +1267,7 @@ struct xen_sysctl { struct xen_sysctl_cpu_levelling_caps cpu_levelling_caps; struct xen_sysctl_cpu_featureset cpu_featureset; struct xen_sysctl_livepatch_op livepatch; + struct xen_sysctl_test_smoc test_smoc; #if defined(__i386__) || defined(__x86_64__) struct xen_sysctl_cpu_policy cpu_policy; #endif diff --git a/xen/include/xen/lib.h b/xen/include/xen/lib.h index 1793be5b6b89..dcb42a5b64c9 100644 --- a/xen/include/xen/lib.h +++ b/xen/include/xen/lib.h @@ -167,6 +167,7 @@ uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c); #define TAINT_HVM_FEP (1u << 3) #define TAINT_MACHINE_INSECURE (1u << 4) #define TAINT_CPU_OUT_OF_SPEC (1u << 5) +#define TAINT_ERROR_SELFTEST (1U << 6) extern unsigned int tainted; #define TAINT_STRING_MAX_LEN 20 extern char *print_tainted(char *str); From patchwork Fri Dec 15 11:18:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Roger_Pau_Monn=C3=A9?= X-Patchwork-Id: 13494325 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id CF02EC4167B for ; Fri, 15 Dec 2023 11:19:06 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.655032.1022695 (Exim 4.92) (envelope-from ) id 1rE6DZ-0002hG-Ph; Fri, 15 Dec 2023 11:18:57 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 655032.1022695; Fri, 15 Dec 2023 11:18:57 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1rE6DZ-0002ez-LW; Fri, 15 Dec 2023 11:18:57 +0000 Received: by outflank-mailman (input) for mailman id 655032; Fri, 15 Dec 2023 11:18:56 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1rE6DY-0002YQ-AE for xen-devel@lists.xenproject.org; Fri, 15 Dec 2023 11:18:56 +0000 Received: from mail-wm1-x332.google.com (mail-wm1-x332.google.com [2a00:1450:4864:20::332]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id bb6777a3-9b3b-11ee-9b0f-b553b5be7939; Fri, 15 Dec 2023 12:18:54 +0100 (CET) Received: by mail-wm1-x332.google.com with SMTP id 5b1f17b1804b1-40c38e292c8so2717425e9.0 for ; Fri, 15 Dec 2023 03:18:54 -0800 (PST) Received: from localhost ([213.195.127.70]) by smtp.gmail.com with ESMTPSA id v14-20020a5d4a4e000000b003333541a5bdsm18546891wrs.80.2023.12.15.03.18.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Dec 2023 03:18:53 -0800 (PST) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: bb6777a3-9b3b-11ee-9b0f-b553b5be7939 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1702639134; x=1703243934; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=8pZ/40IFyhVPhsZHwd4jJR9UQEqZhbtR8GJbwcsXPwM=; b=dGKmgbvQHjwTTfbLTDcDoDAbHpTYx07UkR8jWXaFjhdoHa8dHfB3dkde8ovY1BGjr7 1U7Nab3QlvPllhWk2xEcHnEFt/b+N3dIQr9KmKC26C6snPeLEQT5/GZpR7va93THCJRw 3FTqWw4i4AamkI2fBEnvTTdWtzR/AIJ36pCE4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702639134; x=1703243934; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=8pZ/40IFyhVPhsZHwd4jJR9UQEqZhbtR8GJbwcsXPwM=; b=m233xB0XFqtai9MaBSM1Olngb0+O53jLBT01tibj7wwbsF/+HX8eEuxOR8BB0VWELd GYGiMJ/DEJhzvtY37NvCYSDIJ5vwSCoj7pW9pqnCxxwPpAs4bhdmVfszwHNcf9Ixshcj XWtTMirIZ61LW2IN8MTTDD/w8L3gp713KEkFg6len4wPOlJk2+C4LnCLOXcTbYFOsRHm yWlHYeWfACoHskLRT3ZhI3c1QBdaqwTyWdiETftzRtEnrDtgSfDKyQHbrYF/XK13Rz3e Ln4GT2/mmEX/tO+l9d/Fn9lZNsALlU1pxS5aeALEMPvp3RmZFokRXWmjRqepyjn/8c+y /9mg== X-Gm-Message-State: AOJu0YxCISA9WZBJGMTMlxMribSI+p3eLYrCXAZLiH1DH6WruXMlSalp SSBCaSsKDHvnLiH0Qs1Q27a3IyerzOg0X3/b/wc= X-Google-Smtp-Source: AGHT+IHM6LyEQJjS5r5wgOMqxTjLBuiwG9g8fGA70gVVpa+M0/gMISIxwNnAsj0O1luVjyHYHVl7jA== X-Received: by 2002:a05:600c:1503:b0:40c:2c5f:5887 with SMTP id b3-20020a05600c150300b0040c2c5f5887mr5740434wmg.22.1702639133809; Fri, 15 Dec 2023 03:18:53 -0800 (PST) From: Roger Pau Monne To: xen-devel@lists.xenproject.org Cc: Roger Pau Monne , Konrad Rzeszutek Wilk , Ross Lagerwall , Wei Liu , Anthony PERARD , Andrew Cooper , George Dunlap , Jan Beulich , Julien Grall , Stefano Stabellini Subject: [PATCH v4 3/4] x86/livepatch: introduce a basic live patch test to gitlab CI Date: Fri, 15 Dec 2023 12:18:41 +0100 Message-ID: <20231215111842.8009-4-roger.pau@citrix.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231215111842.8009-1-roger.pau@citrix.com> References: <20231215111842.8009-1-roger.pau@citrix.com> MIME-Version: 1.0 Introduce a basic livepatch test using the interface to run self modifying tests. The introduced test relies on changing a function from returning false to returning true. To simplify the burden of keeping a patch that can be provided to livepatch-build-tools, introduce two new files: one containing the unpatched test functions, and another one that contains the patched forms of such functions. Note that only the former is linked into the Xen image, the latter is built but the object file is not consumed afterwards. Do this to assert that the file containing the patched functions continues to build. Since livepatch testing will ensure that the functions are not patched previous the applying the livepatch, allow the livepatch related tests to fail without tainting the hypervisor. Note the livepatch tests are not run as part of the self modifying checks executed during boot, as they would obviously fail. Signed-off-by: Roger Pau Monné Acked-by: Jan Beulich --- Changes since v3: - Rebase over previous changes. Changes since v2: - Clarify comment about xor vs mov instructions for return false/true encodings. Changes since v1: - New interface & test. --- tools/misc/xen-livepatch.c | 29 +++++++++++++++++++++++++++++ xen/arch/x86/include/asm/test.h | 9 ++++++++- xen/arch/x86/test/Makefile | 2 ++ xen/arch/x86/test/smoc-lp-alt.c | 24 ++++++++++++++++++++++++ xen/arch/x86/test/smoc-lp.c | 24 ++++++++++++++++++++++++ xen/arch/x86/test/smoc.c | 4 ++++ xen/include/public/sysctl.h | 6 +++++- 7 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 xen/arch/x86/test/smoc-lp-alt.c create mode 100644 xen/arch/x86/test/smoc-lp.c diff --git a/tools/misc/xen-livepatch.c b/tools/misc/xen-livepatch.c index 5bf9d9a32b65..4ebd1b4e936d 100644 --- a/tools/misc/xen-livepatch.c +++ b/tools/misc/xen-livepatch.c @@ -37,6 +37,7 @@ void show_help(void) " replace apply patch and revert all others.\n" " unload unload name patch.\n" " load [flags] upload and apply with name as the name\n" + " test execute self modifying code livepatch hypervisor tests\n" " Supported flags:\n" " --nodeps Disable inter-module buildid dependency check.\n" " Check only against hypervisor buildid.\n", @@ -542,6 +543,33 @@ error: return rc; } +static int test_func(int argc, char *argv[]) +{ + uint32_t results = 0; + int rc; + + if ( argc != 0 ) + { + show_help(); + return -1; + } + + rc = xc_test_smoc(xch, XEN_SYSCTL_TEST_SMOC_LP, &results); + if ( rc ) + { + fprintf(stderr, "test operation failed: %s\n", strerror(errno)); + return -1; + } + if ( (results & XEN_SYSCTL_TEST_SMOC_LP) != XEN_SYSCTL_TEST_SMOC_LP ) + { + fprintf(stderr, "some tests failed: %#x (expected %#x)\n", + results, XEN_SYSCTL_TEST_SMOC_LP); + return -1; + } + + return 0; +} + /* * These are also functions in action_options that are called in case * none of the ones in main_options match. @@ -554,6 +582,7 @@ struct { { "list", list_func }, { "upload", upload_func }, { "load", load_func }, + { "test", test_func }, }; int main(int argc, char *argv[]) diff --git a/xen/arch/x86/include/asm/test.h b/xen/arch/x86/include/asm/test.h index e96e709c6a52..951aaaa1f55e 100644 --- a/xen/arch/x86/include/asm/test.h +++ b/xen/arch/x86/include/asm/test.h @@ -3,11 +3,18 @@ #include +#include + int test_smoc(uint32_t selection, uint32_t *results); +#ifdef CONFIG_LIVEPATCH +bool cf_check test_lp_insn_replacement(void); +#endif + static inline void execute_selftests(void) { - const uint32_t exec_mask = XEN_SYSCTL_TEST_SMOC_ALL; + const uint32_t exec_mask = XEN_SYSCTL_TEST_SMOC_ALL & + ~XEN_SYSCTL_TEST_SMOC_LP; uint32_t result; int rc; diff --git a/xen/arch/x86/test/Makefile b/xen/arch/x86/test/Makefile index b504b8196659..3a5a0a98e4db 100644 --- a/xen/arch/x86/test/Makefile +++ b/xen/arch/x86/test/Makefile @@ -1 +1,3 @@ obj-y += smoc.o +obj-$(CONFIG_LIVEPATCH) += smoc-lp.o # for livepatch testing +extra-$(CONFIG_LIVEPATCH) += smoc-lp-alt.o diff --git a/xen/arch/x86/test/smoc-lp-alt.c b/xen/arch/x86/test/smoc-lp-alt.c new file mode 100644 index 000000000000..16cf65dafdc1 --- /dev/null +++ b/xen/arch/x86/test/smoc-lp-alt.c @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#include + +/* + * Interesting case because `return false` can be encoded as `xor %eax, %eax`, + * which is shorter than `return true` which is encoded as a `mov $1, %eax` + * instruction (based on code generated by GCC 13.2 at -O2), and also shorter + * than the replacement `jmp` instruction. + */ +bool cf_check test_lp_insn_replacement(void) +{ + return true; +} + +/* + * 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/smoc-lp.c b/xen/arch/x86/test/smoc-lp.c new file mode 100644 index 000000000000..ac32bce4d464 --- /dev/null +++ b/xen/arch/x86/test/smoc-lp.c @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#include + +/* + * Interesting case because `return false` can be encoded as `xor %eax, %eax`, + * which is shorter than `return true` which is encoded as a `mov $1, %eax` + * instruction (based on code generated by GCC 13.2 at -O2), and also shorter + * than the replacement `jmp` instruction. + */ +bool cf_check test_lp_insn_replacement(void) +{ + return false; +} + +/* + * 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/smoc.c b/xen/arch/x86/test/smoc.c index 09db5cee9ae2..3a6091141fdf 100644 --- a/xen/arch/x86/test/smoc.c +++ b/xen/arch/x86/test/smoc.c @@ -27,6 +27,10 @@ int test_smoc(uint32_t selection, uint32_t *results) } static const tests[] = { { XEN_SYSCTL_TEST_SMOC_INSN_REPL, &test_insn_replacement, "alternative instruction replacement" }, +#ifdef CONFIG_LIVEPATCH + { XEN_SYSCTL_TEST_SMOC_LP_INSN, &test_lp_insn_replacement, + "livepatch instruction replacement" }, +#endif }; unsigned int i; diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h index d015a490da38..f12fc1e2f110 100644 --- a/xen/include/public/sysctl.h +++ b/xen/include/public/sysctl.h @@ -1204,7 +1204,11 @@ struct xen_sysctl_dt_overlay { struct xen_sysctl_test_smoc { uint32_t tests; /* IN: bitmap with selected tests to execute. */ #define XEN_SYSCTL_TEST_SMOC_INSN_REPL (1U << 0) -#define XEN_SYSCTL_TEST_SMOC_ALL (XEN_SYSCTL_TEST_SMOC_INSN_REPL) +#define XEN_SYSCTL_TEST_SMOC_LP_INSN (1U << 1) +#define XEN_SYSCTL_TEST_SMOC_ALL (XEN_SYSCTL_TEST_SMOC_INSN_REPL | \ + XEN_SYSCTL_TEST_SMOC_LP_INSN) +#define XEN_SYSCTL_TEST_SMOC_LP (XEN_SYSCTL_TEST_SMOC_LP_INSN) + uint32_t results; /* OUT: test result: 1 -> success, 0 -> failure. */ }; From patchwork Fri Dec 15 11:18:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Roger_Pau_Monn=C3=A9?= X-Patchwork-Id: 13494327 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 2FC08C46CC5 for ; Fri, 15 Dec 2023 11:19:09 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.655033.1022701 (Exim 4.92) (envelope-from ) id 1rE6Da-0002o1-61; Fri, 15 Dec 2023 11:18:58 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 655033.1022701; Fri, 15 Dec 2023 11:18:58 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1rE6Da-0002lu-26; Fri, 15 Dec 2023 11:18:58 +0000 Received: by outflank-mailman (input) for mailman id 655033; Fri, 15 Dec 2023 11:18:57 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1rE6DZ-00024C-0m for xen-devel@lists.xenproject.org; Fri, 15 Dec 2023 11:18:57 +0000 Received: from mail-wm1-x335.google.com (mail-wm1-x335.google.com [2a00:1450:4864:20::335]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id bc62f88d-9b3b-11ee-98ea-6d05b1d4d9a1; Fri, 15 Dec 2023 12:18:56 +0100 (CET) Received: by mail-wm1-x335.google.com with SMTP id 5b1f17b1804b1-40c38e292c8so2717515e9.0 for ; Fri, 15 Dec 2023 03:18:56 -0800 (PST) Received: from localhost ([213.195.127.70]) by smtp.gmail.com with ESMTPSA id y12-20020a5d614c000000b0033643505580sm5386737wrt.92.2023.12.15.03.18.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Dec 2023 03:18:54 -0800 (PST) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: bc62f88d-9b3b-11ee-98ea-6d05b1d4d9a1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1702639135; x=1703243935; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ZZlPTOk9/t1OmWoVhIbxLZaJgIzAgwV+V3DWNDNFJhM=; b=f3BLzzv5ZsU/UZqlYbkCDjgpO7r3L5wQQtBjDqhDuJs8Y6ujcceFYbAQSvhTYFGR2l 55VuGviFlAYAesWWedS/rWzi9Zt1ceNfj/GQVQkh0aBLj8ZsUpGSMGi5uyT/K1tQPd05 uNn8h+vcot3p9cQtwV/l8M9QIcLZnSjucIugc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702639135; x=1703243935; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ZZlPTOk9/t1OmWoVhIbxLZaJgIzAgwV+V3DWNDNFJhM=; b=Z5MMlEJX8HUlQyQbwdNXUtf7W41sw1+TP9+GpuIfPCtUC687+H34p/iHvh6vufjUo7 hUEujAKOxnKpAD1Kwtc7miYlEMKOlIsYGJ6dQEMLQ01wkBNVHauvFFQI0jSTrEdQZhLp Vyysb6NfNuo2d/0Q7b1gQt6qfSbbMV4STcHfbX4yI7wo8XucwDSqdoti8i3iARKpwlej tGzqsEUWl9/eSf6Lpz5NVYRu8b7xuZr9CRn6t7vUQ/ad3KF86CGvCa4MEeTR87wrgFiw pzB56KfE3PWJYM73dtV3xy3QcsWI826hj+14tIKDPgCUbOGNdLzswhwzWZ3VgVeQGV4c Ee3w== X-Gm-Message-State: AOJu0Yzg8pLAxGWmDRqOsnZDWZsjdbLnIZsfeHqlf7PwSgyM5MC1AmvX l+upMLZ7ncsVCcBO6BCa+gNxWKTYscZeDKE85XM= X-Google-Smtp-Source: AGHT+IHQcoXi5iRHcJl9BtkyYNoOiiLzn01aWEKXAHCv8Vq7W5AiqIeHGveqt0nuPd3l7VKX8C1RcA== X-Received: by 2002:a05:600c:54e4:b0:40b:5e56:7b48 with SMTP id jb4-20020a05600c54e400b0040b5e567b48mr5458792wmb.145.1702639135024; Fri, 15 Dec 2023 03:18:55 -0800 (PST) From: Roger Pau Monne To: xen-devel@lists.xenproject.org Cc: Roger Pau Monne , Doug Goldstein , Stefano Stabellini Subject: [PATCH v4 4/4] automation: add x86-64 livepatching test Date: Fri, 15 Dec 2023 12:18:42 +0100 Message-ID: <20231215111842.8009-5-roger.pau@citrix.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231215111842.8009-1-roger.pau@citrix.com> References: <20231215111842.8009-1-roger.pau@citrix.com> MIME-Version: 1.0 Introduce a new gitlab tests for livepatching, using livepatch-build-tools, which better reflects how downstreams build live patches rather than the in-tree tests. The tests applies the dummy in-tree patch example, checks that the patch is applied correctly and then reverts and unloads it. Signed-off-by: Roger Pau Monné Reviewed-by: Stefano Stabellini --- Changes since v2: - Split livepatch build into a separate script. --- automation/gitlab-ci/build.yaml | 9 +++ automation/gitlab-ci/test.yaml | 8 +++ automation/scripts/build-livepatch | 27 ++++++++ .../scripts/qemu-alpine-x86_64-livepatch.sh | 68 +++++++++++++++++++ 4 files changed, 112 insertions(+) create mode 100755 automation/scripts/build-livepatch create mode 100755 automation/scripts/qemu-alpine-x86_64-livepatch.sh diff --git a/automation/gitlab-ci/build.yaml b/automation/gitlab-ci/build.yaml index 32af30ccedc9..d770bffb845e 100644 --- a/automation/gitlab-ci/build.yaml +++ b/automation/gitlab-ci/build.yaml @@ -358,6 +358,15 @@ alpine-3.18-gcc-debug: variables: CONTAINER: alpine:3.18 +alpine-3.18-gcc-livepatch: + extends: .gcc-x86-64-build + script: + - ./automation/scripts/build-livepatch 2>&1 | tee build.log + variables: + CONTAINER: alpine:3.18 + EXTRA_XEN_CONFIG: | + CONFIG_LIVEPATCH=y + debian-stretch-gcc-debug: extends: .gcc-x86-64-build-debug variables: diff --git a/automation/gitlab-ci/test.yaml b/automation/gitlab-ci/test.yaml index 6aabdb9d156f..58a90be5ed0e 100644 --- a/automation/gitlab-ci/test.yaml +++ b/automation/gitlab-ci/test.yaml @@ -459,3 +459,11 @@ qemu-smoke-ppc64le-powernv9-gcc: needs: - qemu-system-ppc64-8.1.0-ppc64-export - debian-bullseye-gcc-ppc64le-debug + +qemu-alpine-x86_64-gcc-livepatch: + extends: .qemu-x86-64 + script: + - ./automation/scripts/qemu-alpine-x86_64-livepatch.sh 2>&1 | tee ${LOGFILE} + needs: + - *x86-64-test-needs + - alpine-3.18-gcc-livepatch diff --git a/automation/scripts/build-livepatch b/automation/scripts/build-livepatch new file mode 100755 index 000000000000..ac86b17ae5e4 --- /dev/null +++ b/automation/scripts/build-livepatch @@ -0,0 +1,27 @@ +#!/bin/bash -ex + +# Do a regular build first +./automation/scripts/build + +# Build a test livepatch using livepatch-build-tools. + +if [[ "$XEN_TARGET_ARCH" != "x86_64" ]]; then + exit 1 +fi + +BASE=xen/arch/x86/test/smoc-lp.c +ALT=xen/arch/x86/test/smoc-lp-alt.c + +[[ -f $BASE && -f $ALT ]] + +# git diff --no-index returns 0 if no differences, otherwise 1. +git diff --no-index --output=test.patch $BASE $ALT && exit 1 + +BUILDID=$(readelf -Wn xen/xen-syms | sed -n -e 's/^.*Build ID: //p') + +git clone https://xenbits.xen.org/git-http/livepatch-build-tools.git +cd livepatch-build-tools +make +./livepatch-build -s ../ -p ../test.patch -o out -c ../xen/.config \ + --depends $BUILDID --xen-depends $BUILDID +cp out/test.livepatch ../binaries/test.livepatch diff --git a/automation/scripts/qemu-alpine-x86_64-livepatch.sh b/automation/scripts/qemu-alpine-x86_64-livepatch.sh new file mode 100755 index 000000000000..da478cac4376 --- /dev/null +++ b/automation/scripts/qemu-alpine-x86_64-livepatch.sh @@ -0,0 +1,68 @@ +#!/bin/bash + +set -ex + +cd binaries +# initrd.tar.gz is Dom0 rootfs +mkdir -p rootfs +cd rootfs +tar xvzf ../initrd.tar.gz +mkdir proc +mkdir run +mkdir srv +mkdir sys +rm var/run +cp -ar ../dist/install/* . +cp ../test.livepatch ./root/ +cat << "EOF" >> etc/local.d/xen-lp.start +#!/bin/bash + +set -ex + +trap poweroff EXIT + +export LD_LIBRARY_PATH=/usr/local/lib + +xen-livepatch test && exit 1 || true + +xen-livepatch load /root/test.livepatch + +# Cannot fail now +xen-livepatch test + +xen-livepatch revert test +xen-livepatch unload test + +xen-livepatch test && exit 1 || true + +echo "SUCCESS" +EOF +chmod +x etc/local.d/xen-lp.start +echo "rc_verbose=yes" >> etc/rc.conf +# rebuild Dom0 rootfs +find . |cpio -H newc -o|gzip > ../xen-rootfs.cpio.gz +cd ../.. + +cat >> binaries/pxelinux.0 << EOF +#!ipxe + +kernel xen console=com1 console_timestamps=boot +module bzImage console=hvc0 +module xen-rootfs.cpio.gz +boot +EOF + +# Run the test +rm -f smoke.serial +timeout -k 1 360 \ +qemu-system-x86_64 \ + -cpu qemu64,+svm \ + -m 2G -smp 2 \ + -monitor none -serial stdio \ + -nographic \ + -device virtio-net-pci,netdev=n0 \ + -netdev user,id=n0,tftp=binaries,bootfile=/pxelinux.0 |& \ + tee smoke.serial | sed 's/\r//' + +grep -q "SUCCESS" smoke.serial +exit 0