From patchwork Mon Apr 3 04:43:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Chang S. Bae" X-Patchwork-Id: 13197664 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E9700C761AF for ; Mon, 3 Apr 2023 04:55:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230390AbjDCEzl (ORCPT ); Mon, 3 Apr 2023 00:55:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47264 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229863AbjDCEzk (ORCPT ); Mon, 3 Apr 2023 00:55:40 -0400 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 357D6902A; Sun, 2 Apr 2023 21:55:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1680497739; x=1712033739; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=QiABlPcf4IEH+I5tudzpH19X+ip8aQsWuAxBcqSPwt4=; b=Mk6p1a3e84DrH9CP0N34MPbUFckvZbm513/pBuKwTOBQs9485nLFWt01 thn5lUAeA6kAT8N9DPDzjldvtc9Nidq8xukN1Dc3DUOIWMVcVIqD6aw9T cMrGoxLlf4RNsXtYWdfyPprmuzkLo2RkgS8mAlCFACaJdxuctgTxgPoBl 7vrYE/0YLsFwGherh7Hgg1fU9keRwfo1H7onFetY2smXpN9SIH9g2miOv 9YCnk0bIjwVGqYmZ5+kHHz1UQn+uGJO4sPNuvo581MxEF7EsC4wICmc7Y syBss+0YtEAgVo6e/pZCQU3Z0fJAupW8DJLZMX24QRnQDuKgK5bCq9BTu g==; X-IronPort-AV: E=McAfee;i="6600,9927,10668"; a="344362544" X-IronPort-AV: E=Sophos;i="5.98,314,1673942400"; d="scan'208";a="344362544" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Apr 2023 21:55:37 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10668"; a="829421517" X-IronPort-AV: E=Sophos;i="5.98,314,1673942400"; d="scan'208";a="829421517" Received: from chang-linux-3.sc.intel.com ([172.25.66.173]) by fmsmga001.fm.intel.com with ESMTP; 02 Apr 2023 21:55:37 -0700 From: "Chang S. Bae" To: linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org Cc: shuah@kernel.org, luto@kernel.org, dave.hansen@intel.com, tglx@linutronix.de, bp@suse.de, jun.miao@windriver.com, chang.seok.bae@intel.com Subject: [PATCH v1 1/4] selftests/x86: Fix the altstack free Date: Sun, 2 Apr 2023 21:43:37 -0700 Message-Id: <20230403044340.1312-2-chang.seok.bae@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230403044340.1312-1-chang.seok.bae@intel.com> References: <20230403044340.1312-1-chang.seok.bae@intel.com> Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org Some altstacks are freed up too early even before the test signal delivery. Move the memory cleanup after a signal return. Fixes: a051b2e56f2a ("selftests/x86: Fix error: variably modified 'altstack_data' at file scope") Signed-off-by: Chang S. Bae Cc: Shuah Khan Cc: Jun Miao Cc: linux-kselftest@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- The issue was discovered by the altstack refactoring in this series that replaces malloc()/free() with mmap()/munmap(). --- tools/testing/selftests/x86/mov_ss_trap.c | 17 ++++++++++------- .../testing/selftests/x86/single_step_syscall.c | 17 ++++++++++------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/tools/testing/selftests/x86/mov_ss_trap.c b/tools/testing/selftests/x86/mov_ss_trap.c index cc3de6ff9fba..6b9bf8dc3b60 100644 --- a/tools/testing/selftests/x86/mov_ss_trap.c +++ b/tools/testing/selftests/x86/mov_ss_trap.c @@ -142,8 +142,17 @@ static void handle_and_longjmp(int sig, siginfo_t *si, void *ctx_void) int main() { + stack_t stack = { }; unsigned long nr; + stack.ss_size = SIGSTKSZ; + stack.ss_sp = malloc(sizeof(char) * SIGSTKSZ); + if (!stack.ss_sp) + err(1, "malloc()"); + + if (sigaltstack(&stack, NULL) != 0) + err(1, "sigaltstack()"); + asm volatile ("mov %%ss, %[ss]" : [ss] "=m" (ss)); printf("\tSS = 0x%hx, &SS = 0x%p\n", ss, &ss); @@ -248,15 +257,8 @@ int main() */ if (sigsetjmp(jmpbuf, 1) == 0) { printf("[RUN]\tMOV SS; SYSENTER\n"); - stack_t stack = { - .ss_sp = malloc(sizeof(char) * SIGSTKSZ), - .ss_size = SIGSTKSZ, - }; - if (sigaltstack(&stack, NULL) != 0) - err(1, "sigaltstack"); sethandler(SIGSEGV, handle_and_longjmp, SA_RESETHAND | SA_ONSTACK); nr = SYS_getpid; - free(stack.ss_sp); /* Clear EBP first to make sure we segfault cleanly. */ asm volatile ("xorl %%ebp, %%ebp; mov %[ss], %%ss; SYSENTER" : "+a" (nr) : [ss] "m" (ss) : "flags", "rcx" @@ -281,6 +283,7 @@ int main() ); } + free(stack.ss_sp); printf("[OK]\tI aten't dead\n"); return 0; } diff --git a/tools/testing/selftests/x86/single_step_syscall.c b/tools/testing/selftests/x86/single_step_syscall.c index 9a30f443e928..2d8e0edca23f 100644 --- a/tools/testing/selftests/x86/single_step_syscall.c +++ b/tools/testing/selftests/x86/single_step_syscall.c @@ -144,10 +144,19 @@ static void fast_syscall_no_tf(void) int main() { + stack_t stack = { }; #ifdef CAN_BUILD_32 int tmp; #endif + stack.ss_size = SIGSTKSZ; + stack.ss_sp = malloc(sizeof(char) * SIGSTKSZ); + if (!stack.ss_sp) + err(1, "malloc()"); + + if (sigaltstack(&stack, NULL) != 0) + err(1, "sigaltstack()"); + sethandler(SIGTRAP, sigtrap, 0); printf("[RUN]\tSet TF and check nop\n"); @@ -208,17 +217,10 @@ int main() if (sigsetjmp(jmpbuf, 1) == 0) { unsigned long nr = SYS_getpid; printf("[RUN]\tSet TF and check SYSENTER\n"); - stack_t stack = { - .ss_sp = malloc(sizeof(char) * SIGSTKSZ), - .ss_size = SIGSTKSZ, - }; - if (sigaltstack(&stack, NULL) != 0) - err(1, "sigaltstack"); sethandler(SIGSEGV, print_and_longjmp, SA_RESETHAND | SA_ONSTACK); sethandler(SIGILL, print_and_longjmp, SA_RESETHAND); set_eflags(get_eflags() | X86_EFLAGS_TF); - free(stack.ss_sp); /* Clear EBP first to make sure we segfault cleanly. */ asm volatile ("xorl %%ebp, %%ebp; SYSENTER" : "+a" (nr) :: "flags", "rcx" #ifdef __x86_64__ @@ -238,5 +240,6 @@ int main() /* Now make sure that another fast syscall doesn't set TF again. */ fast_syscall_no_tf(); + free(stack.ss_sp); return 0; } From patchwork Mon Apr 3 04:43:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Chang S. Bae" X-Patchwork-Id: 13197665 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 03F38C77B6D for ; Mon, 3 Apr 2023 04:55:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230484AbjDCEzl (ORCPT ); Mon, 3 Apr 2023 00:55:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47266 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230052AbjDCEzk (ORCPT ); Mon, 3 Apr 2023 00:55:40 -0400 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6BE359030; Sun, 2 Apr 2023 21:55:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1680497739; x=1712033739; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=Is8fj3zJKTZDSXv8iw0EPER+gTr6qXPPdy6BaVHjocs=; b=BsMf/gZ1TYalkF+c10zgoAOUcmBHT4wcTAPFKh3N1NCw93C1C4Ha2dud yeqYq10VCgFr2QuUBuoKBobOu8NEYlGf7tCUKYCve92gqCmSPLEY3X3AN 7kOSjI2sUAAJ+U+tm9FsiYd52MYi0zd7i3aBcYIlx8cxx8zetkpiK+LDm x9gQ6/Z462McjpVYnWOFmycOERGUwYYjNJva74Y4Y2xYG5HvC8LkTTWdG HKBG2kiZGFLkR+UWW39Y9uMz7WCCCyyJ3RTS+G87uU7nHr6UQ34VCfrUw F58N46fuOPNO3yODBof1c53Iy7oSZqnzdpeNk1accwATtB5NSH9ow8l0H w==; X-IronPort-AV: E=McAfee;i="6600,9927,10668"; a="344362547" X-IronPort-AV: E=Sophos;i="5.98,314,1673942400"; d="scan'208";a="344362547" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Apr 2023 21:55:37 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10668"; a="829421520" X-IronPort-AV: E=Sophos;i="5.98,314,1673942400"; d="scan'208";a="829421520" Received: from chang-linux-3.sc.intel.com ([172.25.66.173]) by fmsmga001.fm.intel.com with ESMTP; 02 Apr 2023 21:55:37 -0700 From: "Chang S. Bae" To: linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org Cc: shuah@kernel.org, luto@kernel.org, dave.hansen@intel.com, tglx@linutronix.de, bp@suse.de, jun.miao@windriver.com, chang.seok.bae@intel.com Subject: [PATCH v1 2/4] selftests/x86/mov_ss_trap: Include processor-flags.h Date: Sun, 2 Apr 2023 21:43:38 -0700 Message-Id: <20230403044340.1312-3-chang.seok.bae@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230403044340.1312-1-chang.seok.bae@intel.com> References: <20230403044340.1312-1-chang.seok.bae@intel.com> Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org Instead of defining X86_EFLAGS_RF, include the header file. Signed-off-by: Chang S. Bae Cc: Shuah Khan Cc: linux-kselftest@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- Resolve here before including helper.h in the next patch which, otherwise, has to remove the define there along with other changes. --- tools/testing/selftests/x86/mov_ss_trap.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/testing/selftests/x86/mov_ss_trap.c b/tools/testing/selftests/x86/mov_ss_trap.c index 6b9bf8dc3b60..f8633aafc90c 100644 --- a/tools/testing/selftests/x86/mov_ss_trap.c +++ b/tools/testing/selftests/x86/mov_ss_trap.c @@ -35,8 +35,7 @@ #include #include #include - -#define X86_EFLAGS_RF (1UL << 16) +#include #if __x86_64__ # define REG_IP REG_RIP From patchwork Mon Apr 3 04:43:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Chang S. Bae" X-Patchwork-Id: 13197667 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 36FF4C761A6 for ; Mon, 3 Apr 2023 04:55:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231310AbjDCEzu (ORCPT ); Mon, 3 Apr 2023 00:55:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47310 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230493AbjDCEzn (ORCPT ); Mon, 3 Apr 2023 00:55:43 -0400 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6764C8A5E; Sun, 2 Apr 2023 21:55:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1680497740; x=1712033740; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=vfgDViWJ7zk/qoC5nEzW6DFni6a5M80nOTSbnNq7Un8=; b=SuNWSuOUu8oonDRg2vNQgq3yopLLfmeQYCPFUj/TCqtkuI1ubpse7IMD fww7Tgt5T6nhz5A7QkuHTDHvQJUNjLXL79UX6Id0XL1lDcRB1LQ5x5KjS R8d8RQ+R3+6N2qLGP9FGj3fiWrz0YZ60/VsC91eCngWZt+iRE+ICzByGP nPyoEIUN3vI8RMiavKlb52ObzAG0fL6Z2O3Z88Oiv14adeo0H1h2xY1XC ENnLeQ+TzuOqPoE5wB2PXIs3t0vmBFYuvSb9KzXCKXmwd4D6ttR92f9zM mBEIY2KtKDxCCOImx6Hu4fZR8pv+ofbkvBb/r8py7t2WLWvznRCeyVdyN g==; X-IronPort-AV: E=McAfee;i="6600,9927,10668"; a="344362552" X-IronPort-AV: E=Sophos;i="5.98,314,1673942400"; d="scan'208";a="344362552" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Apr 2023 21:55:37 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10668"; a="829421523" X-IronPort-AV: E=Sophos;i="5.98,314,1673942400"; d="scan'208";a="829421523" Received: from chang-linux-3.sc.intel.com ([172.25.66.173]) by fmsmga001.fm.intel.com with ESMTP; 02 Apr 2023 21:55:37 -0700 From: "Chang S. Bae" To: linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org Cc: shuah@kernel.org, luto@kernel.org, dave.hansen@intel.com, tglx@linutronix.de, bp@suse.de, jun.miao@windriver.com, chang.seok.bae@intel.com, Borislav Petkov Subject: [PATCH v1 3/4] selftests/x86: Consolidate signal handler helpers Date: Sun, 2 Apr 2023 21:43:39 -0700 Message-Id: <20230403044340.1312-4-chang.seok.bae@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230403044340.1312-1-chang.seok.bae@intel.com> References: <20230403044340.1312-1-chang.seok.bae@intel.com> Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org Many test cases have the same signal handler (un)register helpers which have been copied exactly over there. Clean up this by moving this helper into a common place. Also, update the Makefile to support this shared code. Signed-off-by: Chang S. Bae Cc: Shuah Khan Cc: Andy Lutomirski Cc: Thomas Gleixner Cc: Borislav Petkov Cc: linux-kernel@vger.kernel.org Cc: linux-kselftest@vger.kernel.org --- tools/testing/selftests/x86/Makefile | 16 ++++++++-- tools/testing/selftests/x86/amx.c | 25 +--------------- .../selftests/x86/corrupt_xstate_header.c | 15 +--------- tools/testing/selftests/x86/entry_from_vm86.c | 25 ++-------------- tools/testing/selftests/x86/fsgsbase.c | 25 ++-------------- tools/testing/selftests/x86/helpers.c | 30 +++++++++++++++++++ tools/testing/selftests/x86/helpers.h | 6 ++++ tools/testing/selftests/x86/ioperm.c | 26 ++-------------- tools/testing/selftests/x86/iopl.c | 26 ++-------------- tools/testing/selftests/x86/ldt_gdt.c | 19 +++--------- tools/testing/selftests/x86/mov_ss_trap.c | 15 ++-------- tools/testing/selftests/x86/ptrace_syscall.c | 24 ++------------- tools/testing/selftests/x86/sigaltstack.c | 27 ++--------------- tools/testing/selftests/x86/sigreturn.c | 25 ++-------------- .../selftests/x86/single_step_syscall.c | 23 -------------- .../testing/selftests/x86/syscall_arg_fault.c | 13 -------- tools/testing/selftests/x86/syscall_nt.c | 13 -------- tools/testing/selftests/x86/sysret_rip.c | 24 +-------------- tools/testing/selftests/x86/test_vsyscall.c | 13 -------- tools/testing/selftests/x86/unwind_vdso.c | 13 -------- 20 files changed, 72 insertions(+), 331 deletions(-) create mode 100644 tools/testing/selftests/x86/helpers.c diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile index ca9374b56ead..382585a314c0 100644 --- a/tools/testing/selftests/x86/Makefile +++ b/tools/testing/selftests/x86/Makefile @@ -36,6 +36,10 @@ BINARIES_64 := $(patsubst %,$(OUTPUT)/%,$(BINARIES_64)) CFLAGS := -O2 -g -std=gnu99 -pthread -Wall $(KHDR_INCLUDES) +LIB := helpers +LIB_OBJ_32 := $(patsubst %,$(OUTPUT)/%.o,$(LIB:%=%_32)) +LIB_OBJ_64 := $(patsubst %,$(OUTPUT)/%.o,$(LIB:%=%_64)) + # call32_from_64 in thunks.S uses absolute addresses. ifeq ($(CAN_BUILD_WITH_NOPIE),1) CFLAGS += -no-pie @@ -69,12 +73,18 @@ all_32: $(BINARIES_32) all_64: $(BINARIES_64) -EXTRA_CLEAN := $(BINARIES_32) $(BINARIES_64) +EXTRA_CLEAN := $(BINARIES_32) $(BINARIES_64) $(LIB_OBJ_32) $(LIB_OBJ_64) + +$(LIB_OBJ_32): $(OUTPUT)/%_32.o: %.c + $(CC) -O -m32 -o $@ -c $^ $(CFLAGS) $(EXTRA_CFLAGS) + +$(LIB_OBJ_64): $(OUTPUT)/%_64.o: %.c + $(CC) -O -m64 -o $@ -c $^ $(CFLAGS) $(EXTRA_CFLAGS) -$(BINARIES_32): $(OUTPUT)/%_32: %.c helpers.h +$(BINARIES_32): $(OUTPUT)/%_32: %.c helpers.h $(LIB_OBJ_32) $(CC) -m32 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $^ -lrt -ldl -lm -$(BINARIES_64): $(OUTPUT)/%_64: %.c helpers.h +$(BINARIES_64): $(OUTPUT)/%_64: %.c helpers.h $(LIB_OBJ_64) $(CC) -m64 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $^ -lrt -ldl # x86_64 users should be encouraged to install 32-bit libraries diff --git a/tools/testing/selftests/x86/amx.c b/tools/testing/selftests/x86/amx.c index 854f7d61be89..1e8e60b1f7b9 100644 --- a/tools/testing/selftests/x86/amx.c +++ b/tools/testing/selftests/x86/amx.c @@ -20,6 +20,7 @@ #include #include "../kselftest.h" /* For __cpuid_count() */ +#include "helpers.h" #ifndef __x86_64__ # error This test is 64-bit only @@ -61,30 +62,6 @@ static inline void xrstor(struct xsave_buffer *xbuf, uint64_t rfbm) /* err() exits and will not return */ #define fatal_error(msg, ...) err(1, "[FAIL]\t" msg, ##__VA_ARGS__) -static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), - int flags) -{ - struct sigaction sa; - - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO | flags; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - fatal_error("sigaction"); -} - -static void clearhandler(int sig) -{ - struct sigaction sa; - - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_DFL; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - fatal_error("sigaction"); -} - #define XFEATURE_XTILECFG 17 #define XFEATURE_XTILEDATA 18 #define XFEATURE_MASK_XTILECFG (1 << XFEATURE_XTILECFG) diff --git a/tools/testing/selftests/x86/corrupt_xstate_header.c b/tools/testing/selftests/x86/corrupt_xstate_header.c index cf9ce8fbb656..111ec58cd1d0 100644 --- a/tools/testing/selftests/x86/corrupt_xstate_header.c +++ b/tools/testing/selftests/x86/corrupt_xstate_header.c @@ -11,13 +11,13 @@ #include #include #include -#include #include #include #include #include #include "../kselftest.h" /* For __cpuid_count() */ +#include "helpers.h" static inline int xsave_enabled(void) { @@ -29,19 +29,6 @@ static inline int xsave_enabled(void) return ecx & (1U << 27); } -static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), - int flags) -{ - struct sigaction sa; - - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO | flags; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - static void sigusr1(int sig, siginfo_t *info, void *uc_void) { ucontext_t *uc = uc_void; diff --git a/tools/testing/selftests/x86/entry_from_vm86.c b/tools/testing/selftests/x86/entry_from_vm86.c index d1e919b0c1dc..535596f9ce24 100644 --- a/tools/testing/selftests/x86/entry_from_vm86.c +++ b/tools/testing/selftests/x86/entry_from_vm86.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -24,31 +23,11 @@ #include #include +#include "helpers.h" + static unsigned long load_addr = 0x10000; static int nerrs = 0; -static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), - int flags) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO | flags; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - -static void clearhandler(int sig) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_DFL; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - static sig_atomic_t got_signal; static void sighandler(int sig, siginfo_t *info, void *ctx_void) diff --git a/tools/testing/selftests/x86/fsgsbase.c b/tools/testing/selftests/x86/fsgsbase.c index 8c780cce941d..94642c57e483 100644 --- a/tools/testing/selftests/x86/fsgsbase.c +++ b/tools/testing/selftests/x86/fsgsbase.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -28,6 +27,8 @@ #include #include +#include "helpers.h" + #ifndef __x86_64__ # error This test is 64-bit only #endif @@ -39,28 +40,6 @@ static unsigned short *shared_scratch; static int nerrs; -static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), - int flags) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO | flags; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - -static void clearhandler(int sig) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_DFL; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - static void sigsegv(int sig, siginfo_t *si, void *ctx_void) { ucontext_t *ctx = (ucontext_t*)ctx_void; diff --git a/tools/testing/selftests/x86/helpers.c b/tools/testing/selftests/x86/helpers.c new file mode 100644 index 000000000000..a6ecc42d359f --- /dev/null +++ b/tools/testing/selftests/x86/helpers.c @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0-only +#define _GNU_SOURCE +#include +#include + +#include "helpers.h" + +void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), + int flags) +{ + struct sigaction sa; + + memset(&sa, 0, sizeof(sa)); + sa.sa_sigaction = handler; + sa.sa_flags = SA_SIGINFO | flags; + sigemptyset(&sa.sa_mask); + if (sigaction(sig, &sa, 0)) + err(1, "sigaction"); +} + +void clearhandler(int sig) +{ + struct sigaction sa; + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = SIG_DFL; + sigemptyset(&sa.sa_mask); + if (sigaction(sig, &sa, 0)) + err(1, "sigaction"); +} diff --git a/tools/testing/selftests/x86/helpers.h b/tools/testing/selftests/x86/helpers.h index 4ef42c4559a9..35ff4df35397 100644 --- a/tools/testing/selftests/x86/helpers.h +++ b/tools/testing/selftests/x86/helpers.h @@ -2,8 +2,14 @@ #ifndef __SELFTESTS_X86_HELPERS_H #define __SELFTESTS_X86_HELPERS_H +#include #include +void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), + int flags); + +void clearhandler(int sig); + static inline unsigned long get_eflags(void) { #ifdef __x86_64__ diff --git a/tools/testing/selftests/x86/ioperm.c b/tools/testing/selftests/x86/ioperm.c index 57ec5e99edb9..103573c3d855 100644 --- a/tools/testing/selftests/x86/ioperm.c +++ b/tools/testing/selftests/x86/ioperm.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -20,30 +19,9 @@ #include #include -static int nerrs = 0; - -static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), - int flags) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO | flags; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); - -} +#include "helpers.h" -static void clearhandler(int sig) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_DFL; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} +static int nerrs = 0; static jmp_buf jmpbuf; diff --git a/tools/testing/selftests/x86/iopl.c b/tools/testing/selftests/x86/iopl.c index 7e3e09c1abac..09544e598def 100644 --- a/tools/testing/selftests/x86/iopl.c +++ b/tools/testing/selftests/x86/iopl.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -20,30 +19,9 @@ #include #include -static int nerrs = 0; - -static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), - int flags) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO | flags; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); - -} +#include "helpers.h" -static void clearhandler(int sig) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_DFL; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} +static int nerrs = 0; static jmp_buf jmpbuf; diff --git a/tools/testing/selftests/x86/ldt_gdt.c b/tools/testing/selftests/x86/ldt_gdt.c index 3a29346e1452..80acade5d7df 100644 --- a/tools/testing/selftests/x86/ldt_gdt.c +++ b/tools/testing/selftests/x86/ldt_gdt.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -26,6 +25,8 @@ #include #include +#include "helpers.h" + #define AR_ACCESSED (1<<8) #define AR_TYPE_RODATA (0 * (1<<9)) @@ -506,20 +507,6 @@ static void fix_sa_restorer(int sig) } #endif -static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), - int flags) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO | flags; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); - - fix_sa_restorer(sig); -} - static jmp_buf jmpbuf; static void sigsegv(int sig, siginfo_t *info, void *ctx_void) @@ -549,9 +536,11 @@ static void do_multicpu_tests(void) } sethandler(SIGSEGV, sigsegv, 0); + fix_sa_restorer(SIGSEGV); #ifdef __i386__ /* True 32-bit kernels send SIGILL instead of SIGSEGV on IRET faults. */ sethandler(SIGILL, sigsegv, 0); + fix_sa_restorer(SIGILL); #endif printf("[RUN]\tCross-CPU LDT invalidation\n"); diff --git a/tools/testing/selftests/x86/mov_ss_trap.c b/tools/testing/selftests/x86/mov_ss_trap.c index f8633aafc90c..cfec7a3e30b7 100644 --- a/tools/testing/selftests/x86/mov_ss_trap.c +++ b/tools/testing/selftests/x86/mov_ss_trap.c @@ -35,7 +35,8 @@ #include #include #include -#include + +#include "helpers.h" #if __x86_64__ # define REG_IP REG_RIP @@ -93,18 +94,6 @@ static void enable_watchpoint(void) } } -static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), - int flags) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO | flags; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - static char const * const signames[] = { [SIGSEGV] = "SIGSEGV", [SIGBUS] = "SIBGUS", diff --git a/tools/testing/selftests/x86/ptrace_syscall.c b/tools/testing/selftests/x86/ptrace_syscall.c index 12aaa063196e..360ec88d5432 100644 --- a/tools/testing/selftests/x86/ptrace_syscall.c +++ b/tools/testing/selftests/x86/ptrace_syscall.c @@ -15,6 +15,8 @@ #include #include +#include "helpers.h" + /* Bitness-agnostic defines for user_regs_struct fields. */ #ifdef __x86_64__ # define user_syscall_nr orig_rax @@ -93,18 +95,6 @@ static siginfo_t wait_trap(pid_t chld) return si; } -static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), - int flags) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO | flags; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - static void setsigign(int sig, int flags) { struct sigaction sa; @@ -116,16 +106,6 @@ static void setsigign(int sig, int flags) err(1, "sigaction"); } -static void clearhandler(int sig) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_DFL; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - #ifdef __x86_64__ # define REG_BP REG_RBP #else diff --git a/tools/testing/selftests/x86/sigaltstack.c b/tools/testing/selftests/x86/sigaltstack.c index 22a88b764a8e..7c2bd27908d5 100644 --- a/tools/testing/selftests/x86/sigaltstack.c +++ b/tools/testing/selftests/x86/sigaltstack.c @@ -1,7 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only #define _GNU_SOURCE -#include #include #include #include @@ -14,6 +13,8 @@ #include #include +#include "helpers.h" + /* sigaltstack()-enforced minimum stack */ #define ENFORCED_MINSIGSTKSZ 2048 @@ -27,30 +28,6 @@ static bool sigalrm_expected; static unsigned long at_minstack_size; -static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), - int flags) -{ - struct sigaction sa; - - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO | flags; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - -static void clearhandler(int sig) -{ - struct sigaction sa; - - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_DFL; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - static int setup_altstack(void *start, unsigned long size) { stack_t ss; diff --git a/tools/testing/selftests/x86/sigreturn.c b/tools/testing/selftests/x86/sigreturn.c index 5d7961a5f7f6..b2282ca57e23 100644 --- a/tools/testing/selftests/x86/sigreturn.c +++ b/tools/testing/selftests/x86/sigreturn.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include @@ -46,6 +45,8 @@ #include #include +#include "helpers.h" + /* Pull in AR_xyz defines. */ typedef unsigned int u32; typedef unsigned short u16; @@ -138,28 +139,6 @@ static unsigned short LDT3(int idx) return (idx << 3) | 7; } -static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), - int flags) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO | flags; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - -static void clearhandler(int sig) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_DFL; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - static void add_ldt(const struct user_desc *desc, unsigned short *var, const char *name) { diff --git a/tools/testing/selftests/x86/single_step_syscall.c b/tools/testing/selftests/x86/single_step_syscall.c index 2d8e0edca23f..4c9b8fd7a41a 100644 --- a/tools/testing/selftests/x86/single_step_syscall.c +++ b/tools/testing/selftests/x86/single_step_syscall.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -33,28 +32,6 @@ #include "helpers.h" -static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), - int flags) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO | flags; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - -static void clearhandler(int sig) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_DFL; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - static volatile sig_atomic_t sig_traps, sig_eflags; sigjmp_buf jmpbuf; diff --git a/tools/testing/selftests/x86/syscall_arg_fault.c b/tools/testing/selftests/x86/syscall_arg_fault.c index 461fa41a4d02..1149ac24921a 100644 --- a/tools/testing/selftests/x86/syscall_arg_fault.c +++ b/tools/testing/selftests/x86/syscall_arg_fault.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -17,18 +16,6 @@ #include "helpers.h" -static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), - int flags) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO | flags; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - static volatile sig_atomic_t sig_traps; static sigjmp_buf jmpbuf; diff --git a/tools/testing/selftests/x86/syscall_nt.c b/tools/testing/selftests/x86/syscall_nt.c index a108b80dd082..1a019bc43b9d 100644 --- a/tools/testing/selftests/x86/syscall_nt.c +++ b/tools/testing/selftests/x86/syscall_nt.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include @@ -18,18 +17,6 @@ static unsigned int nerrs; -static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), - int flags) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO | flags; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - static void sigtrap(int sig, siginfo_t *si, void *ctx_void) { } diff --git a/tools/testing/selftests/x86/sysret_rip.c b/tools/testing/selftests/x86/sysret_rip.c index 84d74be1d902..da5164fde79a 100644 --- a/tools/testing/selftests/x86/sysret_rip.c +++ b/tools/testing/selftests/x86/sysret_rip.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -22,6 +21,7 @@ #include #include +#include "helpers.h" asm ( ".pushsection \".text\", \"ax\"\n\t" @@ -39,28 +39,6 @@ asm ( extern const char test_page[]; static void const *current_test_page_addr = test_page; -static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), - int flags) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO | flags; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - -static void clearhandler(int sig) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_DFL; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - /* State used by our signal handlers. */ static gregset_t initial_regs; diff --git a/tools/testing/selftests/x86/test_vsyscall.c b/tools/testing/selftests/x86/test_vsyscall.c index 47cab972807c..d54f5e767abe 100644 --- a/tools/testing/selftests/x86/test_vsyscall.c +++ b/tools/testing/selftests/x86/test_vsyscall.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -39,18 +38,6 @@ /* max length of lines in /proc/self/maps - anything longer is skipped here */ #define MAPS_LINE_LEN 128 -static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), - int flags) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO | flags; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - /* vsyscalls and vDSO */ bool vsyscall_map_r = false, vsyscall_map_x = false; diff --git a/tools/testing/selftests/x86/unwind_vdso.c b/tools/testing/selftests/x86/unwind_vdso.c index 4c311e1af4c7..51ba53904130 100644 --- a/tools/testing/selftests/x86/unwind_vdso.c +++ b/tools/testing/selftests/x86/unwind_vdso.c @@ -31,7 +31,6 @@ int main() #include #include #include -#include #include #include #include @@ -43,18 +42,6 @@ int main() #include #include -static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), - int flags) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO | flags; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - static volatile sig_atomic_t nerrs; static unsigned long sysinfo; static bool got_sysinfo = false; From patchwork Mon Apr 3 04:43:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Chang S. Bae" X-Patchwork-Id: 13197666 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 30E53C761A6 for ; Mon, 3 Apr 2023 04:55:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230499AbjDCEzn (ORCPT ); Mon, 3 Apr 2023 00:55:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47286 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229751AbjDCEzm (ORCPT ); Mon, 3 Apr 2023 00:55:42 -0400 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6861F903C; Sun, 2 Apr 2023 21:55:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1680497740; x=1712033740; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=euXEsNEkSUOAUq8daq1ZcEClIpm9HdmCSEM+8SwkCu8=; b=H1HMnAxFJ+cl1hGQu4oJmig6Lwh+ypyI+D1/9yuU6P2GSLT3UhKutJt2 U+Gsfj3kee/62sf/Y0w1cqzU6l82UY2DtckAOBnZYE0xcdLwlo92X+/uS ltgIEuxWJA5TwDHfTARGqLOXKKM1xlt28DrRQUmoNTmN4dg4VPVnZPnIS HO4LNDGHYW5fNIuFYUBcR3pJ8JrSzdMcCthfE6F4K02PO1Yo+EcF3TofL 2MOA8Tko9D4MZlbby8K2QR3E3iDk/FLIm9/ZGf2aPLnOqfYmw9KkOuzkw W8rlIlj8thx/LgsMkfmOoL6sS/Z15GE3dxvadF0Tk5lKtgZTuUsewGtT2 Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10668"; a="344362558" X-IronPort-AV: E=Sophos;i="5.98,314,1673942400"; d="scan'208";a="344362558" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Apr 2023 21:55:37 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10668"; a="829421527" X-IronPort-AV: E=Sophos;i="5.98,314,1673942400"; d="scan'208";a="829421527" Received: from chang-linux-3.sc.intel.com ([172.25.66.173]) by fmsmga001.fm.intel.com with ESMTP; 02 Apr 2023 21:55:37 -0700 From: "Chang S. Bae" To: linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org Cc: shuah@kernel.org, luto@kernel.org, dave.hansen@intel.com, tglx@linutronix.de, bp@suse.de, jun.miao@windriver.com, chang.seok.bae@intel.com, Borislav Petkov Subject: [PATCH v1 4/4] selftests/x86: Refactor altstack setup code Date: Sun, 2 Apr 2023 21:43:40 -0700 Message-Id: <20230403044340.1312-5-chang.seok.bae@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230403044340.1312-1-chang.seok.bae@intel.com> References: <20230403044340.1312-1-chang.seok.bae@intel.com> Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org The sigaltstack setup code is almost the same across x86 tests. Most of the test probably just needs a ready-to-use altstack instead of all the setup code. Refactor them to these helpers to simplify the test code: - setup_sigaltstack() Allocate an altstack memory with a size more than the kernel-provided minimum. Then register the altstack via sigaltstack(2). - cleanup_sigaltstack() Unregister the altstack and free up the memory. Then, these two function calls are supposed to be enough for most sigaltstack-needed test cases. But, when explicit sigaltstack() is needed, another helper is available: - init_sigaltstack() Do the same as setup_sigaltstack(), except for not invoking the sigaltstack syscall. Finally, while here, ensure an altstack cleanup everywhere an altstack is used. Signed-off-by: Chang S. Bae Cc: Shuah Khan Cc: Borislav Petkov Cc: Thomas Gleixner Cc: Andy Lutomirski Cc: linux-kselftest@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- The patch is based on another series that fixes the sigaltstack test: https://lore.kernel.org/all/20230330233520.21937-2-chang.seok.bae@intel.com/ Considerably that fix should go first before this cleanup rework. --- tools/testing/selftests/x86/amx.c | 42 ++++------ tools/testing/selftests/x86/helpers.c | 80 +++++++++++++++++++ tools/testing/selftests/x86/helpers.h | 4 + tools/testing/selftests/x86/mov_ss_trap.c | 11 +-- tools/testing/selftests/x86/sigaltstack.c | 40 ++++------ tools/testing/selftests/x86/sigreturn.c | 10 +-- .../selftests/x86/single_step_syscall.c | 12 +-- .../testing/selftests/x86/syscall_arg_fault.c | 11 +-- 8 files changed, 130 insertions(+), 80 deletions(-) diff --git a/tools/testing/selftests/x86/amx.c b/tools/testing/selftests/x86/amx.c index 1e8e60b1f7b9..70e1d64e9c57 100644 --- a/tools/testing/selftests/x86/amx.c +++ b/tools/testing/selftests/x86/amx.c @@ -362,29 +362,11 @@ static void validate_xcomp_perm(enum expected_result exp) # define AT_MINSIGSTKSZ 51 #endif -static void *alloc_altstack(unsigned int size) +static void setup_altstack(stack_t *stack, enum expected_result exp) { - void *altstack; - - altstack = mmap(NULL, size, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); - - if (altstack == MAP_FAILED) - fatal_error("mmap() for altstack"); - - return altstack; -} - -static void setup_altstack(void *addr, unsigned long size, enum expected_result exp) -{ - stack_t ss; int rc; - memset(&ss, 0, sizeof(ss)); - ss.ss_size = size; - ss.ss_sp = addr; - - rc = sigaltstack(&ss, NULL); + rc = sigaltstack(stack, NULL); if (exp == FAIL_EXPECTED) { if (rc) { @@ -401,7 +383,7 @@ static void test_dynamic_sigaltstack(void) { unsigned int small_size, enough_size; unsigned long minsigstksz; - void *altstack; + stack_t stack = { }; minsigstksz = getauxval(AT_MINSIGSTKSZ); printf("\tAT_MINSIGSTKSZ = %lu\n", minsigstksz); @@ -416,9 +398,9 @@ static void test_dynamic_sigaltstack(void) return; } - enough_size = minsigstksz * 2; - - altstack = alloc_altstack(enough_size); + if (init_sigaltstack(&stack) != 0) + fatal_error("sigaltstack allocation failed."); + enough_size = stack.ss_size; printf("\tAllocate memory for altstack (%u bytes).\n", enough_size); /* @@ -427,7 +409,8 @@ static void test_dynamic_sigaltstack(void) */ small_size = minsigstksz - xtiledata.size; printf("\tAfter sigaltstack() with small size (%u bytes).\n", small_size); - setup_altstack(altstack, small_size, SUCCESS_EXPECTED); + stack.ss_size = small_size; + setup_altstack(&stack, SUCCESS_EXPECTED); validate_req_xcomp_perm(FAIL_EXPECTED); /* @@ -436,7 +419,8 @@ static void test_dynamic_sigaltstack(void) * and thus ARCH_REQ_XCOMP_PERM should succeed. */ printf("\tAfter sigaltstack() with enough size (%u bytes).\n", enough_size); - setup_altstack(altstack, enough_size, SUCCESS_EXPECTED); + stack.ss_size = enough_size; + setup_altstack(&stack, SUCCESS_EXPECTED); validate_req_xcomp_perm(SUCCESS_EXPECTED); /* @@ -446,7 +430,11 @@ static void test_dynamic_sigaltstack(void) * once XTILEDATA permission is established. */ printf("\tThen, sigaltstack() with small size (%u bytes).\n", small_size); - setup_altstack(altstack, small_size, FAIL_EXPECTED); + stack.ss_size = small_size; + setup_altstack(&stack, FAIL_EXPECTED); + + stack.ss_size = enough_size; + cleanup_sigaltstack(&stack); } static void test_dynamic_state(void) diff --git a/tools/testing/selftests/x86/helpers.c b/tools/testing/selftests/x86/helpers.c index a6ecc42d359f..1f5b1e5a3d66 100644 --- a/tools/testing/selftests/x86/helpers.c +++ b/tools/testing/selftests/x86/helpers.c @@ -3,6 +3,15 @@ #include #include +#include +#include + +#include "helpers.h" + +#ifndef AT_MINSIGSTKSZ +# define AT_MINSIGSTKSZ 51 +#endif + #include "helpers.h" void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), @@ -28,3 +37,74 @@ void clearhandler(int sig) if (sigaction(sig, &sa, 0)) err(1, "sigaction"); } + +#define ALTSTKSZ 8096 + +static unsigned long get_sigaltstacksz(void) +{ + return getauxval(AT_MINSIGSTKSZ) + ALTSTKSZ; +} + +/** + * init_sigalstack -- allocate an altstack without registration + * @stack: stack_t pointer + * Returns: 0 if successful; otherwise, nonzero + * + * Unless testing with different sizes, setup_sigaltstack() should be + * enough to provide a ready-to-use stack + */ +int init_sigaltstack(stack_t *stack) +{ + if (!stack) + return -1; + + if (stack->ss_size > 0 && stack->ss_sp > 0) + return 0; + + stack->ss_size = get_sigaltstacksz(); + + stack->ss_sp = mmap(NULL, stack->ss_size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); + if (stack->ss_sp == MAP_FAILED) + return -1; + + return 0; +} + +/** + * setup_sigaltstack -- allocate and register an altstack + * @stack: stack_t pointer + * Returns: 0 if successful; otherwise, nonzero + */ +int setup_sigaltstack(stack_t *stack) +{ + int rc; + + rc = init_sigaltstack(stack); + if (rc) + return -1; + + return sigaltstack(stack, NULL); +} + +/** + * cleanup_sigaltstack -- unregister and free an altstack + * @stack: stack_t pointer + * Returns: None + */ +void cleanup_sigaltstack(stack_t *stack) +{ + size_t size; + void *sp; + + if (!stack) + return; + + size = stack->ss_size; + sp = stack->ss_sp; + + stack->ss_flags = SS_DISABLE; + sigaltstack(stack, NULL); + + munmap(sp, size); +} diff --git a/tools/testing/selftests/x86/helpers.h b/tools/testing/selftests/x86/helpers.h index 35ff4df35397..a47ba1a2d929 100644 --- a/tools/testing/selftests/x86/helpers.h +++ b/tools/testing/selftests/x86/helpers.h @@ -5,6 +5,10 @@ #include #include +int init_sigaltstack(stack_t *stack); +int setup_sigaltstack(stack_t *stack); +void cleanup_sigaltstack(stack_t *stack); + void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), int flags); diff --git a/tools/testing/selftests/x86/mov_ss_trap.c b/tools/testing/selftests/x86/mov_ss_trap.c index cfec7a3e30b7..c9ffc8b3a214 100644 --- a/tools/testing/selftests/x86/mov_ss_trap.c +++ b/tools/testing/selftests/x86/mov_ss_trap.c @@ -133,13 +133,8 @@ int main() stack_t stack = { }; unsigned long nr; - stack.ss_size = SIGSTKSZ; - stack.ss_sp = malloc(sizeof(char) * SIGSTKSZ); - if (!stack.ss_sp) - err(1, "malloc()"); - - if (sigaltstack(&stack, NULL) != 0) - err(1, "sigaltstack()"); + if (setup_sigaltstack(&stack) != 0) + err(1, "sigaltstack"); asm volatile ("mov %%ss, %[ss]" : [ss] "=m" (ss)); printf("\tSS = 0x%hx, &SS = 0x%p\n", ss, &ss); @@ -271,7 +266,7 @@ int main() ); } - free(stack.ss_sp); + cleanup_sigaltstack(&stack); printf("[OK]\tI aten't dead\n"); return 0; } diff --git a/tools/testing/selftests/x86/sigaltstack.c b/tools/testing/selftests/x86/sigaltstack.c index 7c2bd27908d5..6f753406ca91 100644 --- a/tools/testing/selftests/x86/sigaltstack.c +++ b/tools/testing/selftests/x86/sigaltstack.c @@ -28,17 +28,6 @@ static bool sigalrm_expected; static unsigned long at_minstack_size; -static int setup_altstack(void *start, unsigned long size) -{ - stack_t ss; - - memset(&ss, 0, sizeof(ss)); - ss.ss_size = size; - ss.ss_sp = start; - - return sigaltstack(&ss, NULL); -} - static jmp_buf jmpbuf; static void sigsegv(int sig, siginfo_t *info, void *ctx_void) @@ -63,14 +52,14 @@ static void sigalrm(int sig, siginfo_t *info, void *ctx_void) } } -static void test_sigaltstack(void *altstack, unsigned long size) +static void test_sigaltstack(stack_t *stack) { - if (setup_altstack(altstack, size)) { + if (sigaltstack(stack, NULL)) { /* * The kernel may return ENOMEM when the altstack size * is insufficient. Skip the test in this case. */ - if (errno == ENOMEM && size < at_minstack_size) { + if (errno == ENOMEM && stack->ss_size < at_minstack_size) { printf("[SKIP]\tThe running kernel disallows an insufficient size.\n"); return; } @@ -78,7 +67,7 @@ static void test_sigaltstack(void *altstack, unsigned long size) err(1, "sigaltstack()"); } - sigalrm_expected = (size > at_minstack_size) ? true : false; + sigalrm_expected = (stack->ss_size > at_minstack_size) ? true : false; sethandler(SIGSEGV, sigsegv, 0); sethandler(SIGALRM, sigalrm, SA_ONSTACK); @@ -97,19 +86,24 @@ static void test_sigaltstack(void *altstack, unsigned long size) int main(void) { - void *altstack; + unsigned long enough_size; + stack_t stack = { }; at_minstack_size = getauxval(AT_MINSIGSTKSZ); - altstack = mmap(NULL, at_minstack_size + SIGSTKSZ, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); - if (altstack == MAP_FAILED) - err(1, "mmap()"); + if (init_sigaltstack(&stack) != 0) + err(1, "sigaltstack allocation failed."); + enough_size = stack.ss_size; + + if ((ENFORCED_MINSIGSTKSZ + 1) < at_minstack_size) { + stack.ss_size = ENFORCED_MINSIGSTKSZ + 1; + test_sigaltstack(&stack); + } - if ((ENFORCED_MINSIGSTKSZ + 1) < at_minstack_size) - test_sigaltstack(altstack, ENFORCED_MINSIGSTKSZ + 1); + stack.ss_size = enough_size; + test_sigaltstack(&stack); - test_sigaltstack(altstack, at_minstack_size + SIGSTKSZ); + cleanup_sigaltstack(&stack); return nerrs == 0 ? 0 : 1; } diff --git a/tools/testing/selftests/x86/sigreturn.c b/tools/testing/selftests/x86/sigreturn.c index b2282ca57e23..f9e06a13ad82 100644 --- a/tools/testing/selftests/x86/sigreturn.c +++ b/tools/testing/selftests/x86/sigreturn.c @@ -741,17 +741,13 @@ int main() { int total_nerrs = 0; unsigned short my_cs, my_ss; + stack_t stack = { }; asm volatile ("mov %%cs,%0" : "=r" (my_cs)); asm volatile ("mov %%ss,%0" : "=r" (my_ss)); setup_ldt(); - stack_t stack = { - /* Our sigaltstack scratch space. */ - .ss_sp = malloc(sizeof(char) * SIGSTKSZ), - .ss_size = SIGSTKSZ, - }; - if (sigaltstack(&stack, NULL) != 0) + if (setup_sigaltstack(&stack) != 0) err(1, "sigaltstack"); sethandler(SIGUSR1, sigusr1, 0); @@ -849,6 +845,6 @@ int main() total_nerrs += test_nonstrict_ss(); #endif - free(stack.ss_sp); + cleanup_sigaltstack(&stack); return total_nerrs ? 1 : 0; } diff --git a/tools/testing/selftests/x86/single_step_syscall.c b/tools/testing/selftests/x86/single_step_syscall.c index 4c9b8fd7a41a..4e3224e52e30 100644 --- a/tools/testing/selftests/x86/single_step_syscall.c +++ b/tools/testing/selftests/x86/single_step_syscall.c @@ -126,13 +126,8 @@ int main() int tmp; #endif - stack.ss_size = SIGSTKSZ; - stack.ss_sp = malloc(sizeof(char) * SIGSTKSZ); - if (!stack.ss_sp) - err(1, "malloc()"); - - if (sigaltstack(&stack, NULL) != 0) - err(1, "sigaltstack()"); + if (setup_sigaltstack(&stack) != 0) + err(1, "sigaltstack"); sethandler(SIGTRAP, sigtrap, 0); @@ -193,6 +188,7 @@ int main() */ if (sigsetjmp(jmpbuf, 1) == 0) { unsigned long nr = SYS_getpid; + printf("[RUN]\tSet TF and check SYSENTER\n"); sethandler(SIGSEGV, print_and_longjmp, SA_RESETHAND | SA_ONSTACK); @@ -217,6 +213,6 @@ int main() /* Now make sure that another fast syscall doesn't set TF again. */ fast_syscall_no_tf(); - free(stack.ss_sp); + cleanup_sigaltstack(&stack); return 0; } diff --git a/tools/testing/selftests/x86/syscall_arg_fault.c b/tools/testing/selftests/x86/syscall_arg_fault.c index 1149ac24921a..1b22ef548582 100644 --- a/tools/testing/selftests/x86/syscall_arg_fault.c +++ b/tools/testing/selftests/x86/syscall_arg_fault.c @@ -87,12 +87,9 @@ static void sigill(int sig, siginfo_t *info, void *ctx_void) int main() { - stack_t stack = { - /* Our sigaltstack scratch space. */ - .ss_sp = malloc(sizeof(char) * SIGSTKSZ), - .ss_size = SIGSTKSZ, - }; - if (sigaltstack(&stack, NULL) != 0) + stack_t stack = { }; + + if (setup_sigaltstack(&stack) != 0) err(1, "sigaltstack"); sethandler(SIGSEGV, sigsegv_or_sigbus, SA_ONSTACK); @@ -218,6 +215,6 @@ int main() set_eflags(get_eflags() & ~X86_EFLAGS_TF); #endif - free(stack.ss_sp); + cleanup_sigaltstack(&stack); return 0; }