From nobody Wed Feb 11 02:26:55 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 24CB4482D7; Mon, 22 Apr 2024 07:08:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713769732; cv=none; b=MT0hyJSgdaI4+Ljn6AP35sZ3AmwKDDzyHQVapX7pocNeohilxFwcYy/K5MAGRUsuWZUeIQsnKTq5uGjAYtqJdg7cWPJdMTZIw5j/NNIS9nIktEjvfKb12dBrR+IBCBkeH7GQVewSWPedqJQkjq2ag2Q3/jmCYNEkFF47YbU3DCs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713769732; c=relaxed/simple; bh=ypJhMt8Uo2wr/UL7YmAzqCdpKHS3vYTHgdA1ZbWhI9g=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=oKTgHlcbP+gkU5b1B2/Ww3VF+aPQ73EwMJNrojIG7MAkcd9iaC9crbplQ3G4Ag+AjrpII9ftsSBUrMYkQseq0GoCutdjrKm2DCrTX1EezsZTFAQyGuADAsy5tQRJkDsjrR3p6k9g5NZ5pbRFmPqi4wgv8FUaCkbimt3MeEHJU+w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 966B31063; Mon, 22 Apr 2024 00:09:18 -0700 (PDT) Received: from e116581.blr.arm.com (e116581.arm.com [10.162.41.8]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id CC65C3F7BD; Mon, 22 Apr 2024 00:08:45 -0700 (PDT) From: Dev Jain To: shuah@kernel.org, linux-arm-kernel@lists.infradead.org Cc: linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Anshuman.Khandual@arm.com, suzuki.poulose@arm.com, ryan.roberts@arm.com, rob.herring@arm.com, Catalin.Marinas@arm.com, broonie@kernel.org, will@kernel.org, mark.rutland@arm.com, linux@armlinux.org.uk, Dev Jain Subject: [PATCH v2 1/4] selftests/arm: Add mm test Date: Mon, 22 Apr 2024 12:37:14 +0530 Message-Id: <20240422070717.2194201-2-dev.jain@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240422070717.2194201-1-dev.jain@arm.com> References: <20240422070717.2194201-1-dev.jain@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This patch tests the 4GB VA restriction for 32-bit processes; it is required to test the compat layer, whether the kernel knows that it is running a 32-= bit process or not. Chunks are allocated until the VA gets exhausted; mmap must fail beyond 4GB. This is asserted against the VA mappings found in /proc/self/maps. Signed-off-by: Dev Jain --- tools/testing/selftests/arm/mm/compat_va.c | 92 ++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 tools/testing/selftests/arm/mm/compat_va.c diff --git a/tools/testing/selftests/arm/mm/compat_va.c b/tools/testing/sel= ftests/arm/mm/compat_va.c new file mode 100644 index 000000000000..03f662fad79f --- /dev/null +++ b/tools/testing/selftests/arm/mm/compat_va.c @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2024 ARM Limited + * + * Author : Dev Jain + * + * Tests 4GB VA restriction for 32 bit process + */ + +#define _GNU_SOURCE +#include +#include +#include +#include + +#include +#include + +#define MAP_CHUNK_SIZE SZ_1M +#define NR_CHUNKS_4G (SZ_1G / MAP_CHUNK_SIZE) * 4 /* prevent overflow */ + +static int validate_address_hint(void) +{ + char *ptr; + + ptr =3D mmap((void *) (1UL << 29), MAP_CHUNK_SIZE, PROT_READ | + PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + + if (ptr =3D=3D MAP_FAILED) + return 0; + + return -1; +} + +int main(int argc, char *argv[]) +{ + char *ptr[NR_CHUNKS_4G + 3]; + char line[1000]; + int chunks; + FILE *file; + int i; + + ksft_print_header(); + ksft_set_plan(1); + + /* try allocation beyond 4 GB */ + for (i =3D 0; i < NR_CHUNKS_4G + 3; ++i) { + ptr[i] =3D mmap(NULL, MAP_CHUNK_SIZE, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + + if (ptr[i] =3D=3D MAP_FAILED) { + if (validate_address_hint()) + ksft_exit_fail_msg("VA exhaustion failed\n"); + break; + } + } + + chunks =3D i; + if (chunks >=3D NR_CHUNKS_4G) { + ksft_test_result_fail("mmapped chunks beyond 4GB\n"); + ksft_finished(); + } + + /* parse /proc/self/maps, confirm 32 bit VA mappings */ + file =3D fopen("/proc/self/maps", "r"); + if (file =3D=3D NULL) + ksft_exit_fail_msg("/proc/self/maps cannot be opened\n"); + + while (fgets(line, sizeof(line), file)) { + const char *whitespace_loc, *hyphen_loc; + + hyphen_loc =3D strchr(line, '-'); + whitespace_loc =3D strchr(line, ' '); + + if (!(hyphen_loc && whitespace_loc)) { + ksft_test_result_skip("Unexpected format"); + ksft_finished(); + } + + if ((hyphen_loc - line > 8) || + (whitespace_loc - hyphen_loc) > 9) { + ksft_test_result_fail("Memory map more than 32 bits\n"); + ksft_finished(); + } + } + + for (int i =3D 0; i < chunks; ++i) + munmap(ptr[i], MAP_CHUNK_SIZE); + + ksft_test_result_pass("Test\n"); + ksft_finished(); +} --=20 2.39.2 From nobody Wed Feb 11 02:26:55 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id A6C304D108; Mon, 22 Apr 2024 07:08:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713769737; cv=none; b=iX6uTBWstlw0eLY+j1x1rAGELjnh+5eLKfqZl7Rg7m3u6ENfdutjDFVFpQcoRCxw/Q0d93IIvfNlQCjLHjgk2gUcBt8bc4YMJC38vBQvoEaA+W4t0KHvbL9LUwr+6sfDvpkgsp2Ny5dQZffxSg+hqq+iLQq2/yjin9e5/+V6a3o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713769737; c=relaxed/simple; bh=tX6E2H8buOjrri9YyhAc10zMB6t29GgqGgvvPgqaBdo=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ROQp8zNvOkk3UYT6v4/+ypb/ybIvoaknbOEwZYbjN0aV7rLxHzHSNzwCr32/9tAJbD4VdQM1+KOfggpnERXv/DIKvY5GnCO6baPDQciFfmUGd6q1D4Bep0zH+ZyOoEm6aN5f4Br6/YxBgr9GgPAvzl4uj2gzDQ+xomDZZArSVes= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 6F782339; Mon, 22 Apr 2024 00:09:23 -0700 (PDT) Received: from e116581.blr.arm.com (e116581.arm.com [10.162.41.8]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id B9AA63F7BD; Mon, 22 Apr 2024 00:08:50 -0700 (PDT) From: Dev Jain To: shuah@kernel.org, linux-arm-kernel@lists.infradead.org Cc: linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Anshuman.Khandual@arm.com, suzuki.poulose@arm.com, ryan.roberts@arm.com, rob.herring@arm.com, Catalin.Marinas@arm.com, broonie@kernel.org, will@kernel.org, mark.rutland@arm.com, linux@armlinux.org.uk, Dev Jain Subject: [PATCH v2 2/4] selftests/arm: Add signal tests Date: Mon, 22 Apr 2024 12:37:15 +0530 Message-Id: <20240422070717.2194201-3-dev.jain@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240422070717.2194201-1-dev.jain@arm.com> References: <20240422070717.2194201-1-dev.jain@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This patch introduces two signal tests, and generic test wrappers similar to selftests/arm64/signal directory, along with the mangling testcases found therein. arm_cpsr, dumped by the kernel to user space in the ucontext struc= ture to the signal handler, is mangled with. The kernel must spot this illegal attempt and the testcases are expected to terminate via SEGV. Signed-off-by: Dev Jain --- .../selftests/arm/signal/test_signals.c | 27 ++ .../selftests/arm/signal/test_signals.h | 74 +++++ .../selftests/arm/signal/test_signals_utils.c | 257 ++++++++++++++++++ .../selftests/arm/signal/test_signals_utils.h | 128 +++++++++ .../signal/testcases/mangle_cpsr_aif_bits.c | 33 +++ .../mangle_cpsr_invalid_compat_toggle.c | 29 ++ 6 files changed, 548 insertions(+) create mode 100644 tools/testing/selftests/arm/signal/test_signals.c create mode 100644 tools/testing/selftests/arm/signal/test_signals.h create mode 100644 tools/testing/selftests/arm/signal/test_signals_utils.c create mode 100644 tools/testing/selftests/arm/signal/test_signals_utils.h create mode 100644 tools/testing/selftests/arm/signal/testcases/mangle_cps= r_aif_bits.c create mode 100644 tools/testing/selftests/arm/signal/testcases/mangle_cps= r_invalid_compat_toggle.c diff --git a/tools/testing/selftests/arm/signal/test_signals.c b/tools/test= ing/selftests/arm/signal/test_signals.c new file mode 100644 index 000000000000..1ecf1e9f041c --- /dev/null +++ b/tools/testing/selftests/arm/signal/test_signals.c @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2024 ARM Limited + * + * Generic test wrapper for arm signal tests. + * + * Each test provides its own tde struct tdescr descriptor to link with + * this wrapper. Framework provides common helpers. + */ +#include + +#include "test_signals.h" +#include "test_signals_utils.h" + +struct tdescr *current =3D &tde; + +int main(int argc, char *argv[]) +{ + ksft_print_msg("%s :: %s\n", current->name, current->descr); + if (test_setup(current) && test_init(current)) { + test_run(current); + test_cleanup(current); + } + test_result(current); + + return current->result; +} diff --git a/tools/testing/selftests/arm/signal/test_signals.h b/tools/test= ing/selftests/arm/signal/test_signals.h new file mode 100644 index 000000000000..bbd147127d66 --- /dev/null +++ b/tools/testing/selftests/arm/signal/test_signals.h @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2024 ARM Limited */ + +#ifndef __TEST_SIGNALS_H__ +#define __TEST_SIGNALS_H__ + +#include +#include +#include + +/* + * Using ARCH specific and sanitized Kernel headers from the tree. + */ +#include +#include + +/* + * A descriptor used to describe and configure a test case. + * Fields with a non-trivial meaning are described inline in the following. + */ +struct tdescr { + /* KEEP THIS FIELD FIRST for easier lookup from assembly */ + void *token; + /* when disabled token based sanity checking is skipped in handler */ + bool sanity_disabled; + /* just a name for the test-case; manadatory field */ + char *name; + char *descr; + + bool initialized; + unsigned int minsigstksz; + /* signum used as a test trigger. Zero if no trigger-signal is used */ + int sig_trig; + /* + * signum considered as a successful test completion. + * Zero when no signal is expected on success + */ + int sig_ok; + /* signum expected on unsupported CPU features. */ + int sig_unsupp; + /* a timeout in second for test completion */ + unsigned int timeout; + bool triggered; + bool pass; + unsigned int result; + /* optional sa_flags for the installed handler */ + int sa_flags; + ucontext_t saved_uc; + /* used by get_current_ctx() */ + size_t live_sz; + ucontext_t *live_uc; + volatile sig_atomic_t live_uc_valid; + /* optional test private data */ + void *priv; + + /* a custom setup: called alternatively to default_setup */ + int (*setup)(struct tdescr *td); + /* a custom init: called by default test init after test_setup */ + bool (*init)(struct tdescr *td); + /* a custom cleanup function called before test exits */ + void (*cleanup)(struct tdescr *td); + /* an optional function to be used as a trigger for starting test */ + int (*trigger)(struct tdescr *td); + /* + * the actual test-core: invoked differently depending on the + * presence of the trigger function above; this is mandatory + */ + int (*run)(struct tdescr *td, siginfo_t *si, ucontext_t *uc); + /* an optional function for custom results' processing */ + void (*check_result)(struct tdescr *td); +}; + +extern struct tdescr tde; +#endif diff --git a/tools/testing/selftests/arm/signal/test_signals_utils.c b/tool= s/testing/selftests/arm/signal/test_signals_utils.c new file mode 100644 index 000000000000..96aeb11de151 --- /dev/null +++ b/tools/testing/selftests/arm/signal/test_signals_utils.c @@ -0,0 +1,257 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2024 ARM Limited */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "test_signals.h" +#include "test_signals_utils.h" + + +extern struct tdescr *current; + +static int sig_copyctx =3D SIGTRAP; + +static void unblock_signal(int signum) +{ + sigset_t sset; + + sigemptyset(&sset); + sigaddset(&sset, signum); + sigprocmask(SIG_UNBLOCK, &sset, NULL); +} + +static void default_result(struct tdescr *td, bool force_exit) +{ + if (td->result =3D=3D KSFT_SKIP) { + fprintf(stderr, "=3D=3D>> completed. SKIP.\n"); + } else if (td->pass) { + fprintf(stderr, "=3D=3D>> completed. PASS(1)\n"); + td->result =3D KSFT_PASS; + } else { + fprintf(stdout, "=3D=3D>> completed. FAIL(0)\n"); + td->result =3D KSFT_FAIL; + } + + if (force_exit) + exit(td->result); +} + +/* + * The following handle_signal_* helpers are used by main default_handler + * and are meant to return true when signal is handled successfully: + * when false is returned instead, it means that the signal was somehow + * unexpected in that context and it was NOT handled; default_handler will + * take care of such unexpected situations. + */ + +static bool handle_signal_unsupported(struct tdescr *td, + siginfo_t *si, void *uc) +{ + + /* Mangling PC to avoid loops on original SIGILL */ + ((ucontext_t *)uc)->uc_mcontext.arm_pc +=3D 4; + + if (!td->initialized) { + fprintf(stderr, + "Got SIG_UNSUPP @test_init. Ignore.\n"); + } else { + fprintf(stderr, + "-- RX SIG_UNSUPP on unsupported feat...OK\n"); + td->pass =3D 1; + default_result(current, 1); + } + + return true; +} + +static bool handle_signal_trigger(struct tdescr *td, + siginfo_t *si, void *uc) +{ + td->triggered =3D 1; + + /* ->run was asserted NON-NULL in test_setup() already */ + td->run(td, si, uc); + + return true; +} + +static bool handle_signal_ok(struct tdescr *td, + siginfo_t *si, void *uc) +{ + + /* + * it's a bug in the test code when this assert fail: + * if sig_trig was defined, it must have been used before getting here. + */ + assert(!td->sig_trig || td->triggered); + fprintf(stderr, + "SIG_OK -- SP:0x%lX si_addr@:%p si_code:%d token@:%p offset:%d\n", + ((ucontext_t *)uc)->uc_mcontext.arm_sp, + si->si_addr, si->si_code, td->token, td->token - si->si_addr); + + /* + * Trying to narrow down the SEGV to the ones generated by Kernel itself + * via arm64_notify_segfault(). This is a best-effort check anyway, and + * the si_code check may need to change if this aspect of the kernel + * ABI changes. + */ + if (td->sig_ok =3D=3D SIGSEGV && si->si_code !=3D SEGV_ACCERR) { + fprintf(stdout, + "si_code !=3D SEGV_ACCERR...test is probably broken!\n"); + abort(); + } + td->pass =3D 1; + /* + * Some tests can lead to SEGV loops: in such a case we want to + * terminate immediately exiting straight away; some others are not + * supposed to outlive the signal handler code, due to the content of + * the fake sigframe which caused the signal itself. + */ + default_result(current, 1); + + return true; +} + +static void default_handler(int signum, siginfo_t *si, void *uc) +{ + if (current->sig_unsupp && signum =3D=3D current->sig_unsupp && + handle_signal_unsupported(current, si, uc)) { + fprintf(stderr, "Handled SIG_UNSUPP\n"); + } else if (current->sig_trig && signum =3D=3D current->sig_trig && + handle_signal_trigger(current, si, uc)) { + fprintf(stderr, "Handled SIG_TRIG\n"); + } else if (current->sig_ok && signum =3D=3D current->sig_ok && + handle_signal_ok(current, si, uc)) { + fprintf(stderr, "Handled SIG_OK\n"); + } else if (signum =3D=3D sig_copyctx && current->live_uc) { + fprintf(stderr, "Handled SIG_COPYCTX\n"); + } else { + if (signum =3D=3D SIGALRM && current->timeout) { + fprintf(stderr, "-- Timeout !\n"); + } else { + fprintf(stderr, + "-- RX UNEXPECTED SIGNAL: %d code %d address %p\n", + signum, si->si_code, si->si_addr); + } + default_result(current, 1); + } +} + +static int default_setup(struct tdescr *td) +{ + struct sigaction sa; + + sa.sa_sigaction =3D default_handler; + sa.sa_flags =3D SA_SIGINFO | SA_RESTART; + sa.sa_flags |=3D td->sa_flags; + sigemptyset(&sa.sa_mask); + /* uncatchable signals naturally skipped ... */ + for (int sig =3D 1; sig < 32; sig++) + sigaction(sig, &sa, NULL); + /* + * RT Signals default disposition is Term but they cannot be + * generated by the Kernel in response to our tests; so just catch + * them all and report them as UNEXPECTED signals. + */ + for (int sig =3D SIGRTMIN; sig <=3D SIGRTMAX; sig++) + sigaction(sig, &sa, NULL); + + /* just in case...unblock explicitly all we need */ + if (td->sig_trig) + unblock_signal(td->sig_trig); + if (td->sig_ok) + unblock_signal(td->sig_ok); + if (td->sig_unsupp) + unblock_signal(td->sig_unsupp); + + if (td->timeout) { + unblock_signal(SIGALRM); + alarm(td->timeout); + } + fprintf(stderr, "Registered handlers for all signals.\n"); + + return 1; +} + +static inline int default_trigger(struct tdescr *td) +{ + return !raise(td->sig_trig); +} + +int test_init(struct tdescr *td) +{ + if (td->sig_trig =3D=3D sig_copyctx) { + fprintf(stdout, + "Signal %d is RESERVED, cannot be used as a trigger. Aborting\n", + sig_copyctx); + return 0; + } + /* just in case */ + unblock_signal(sig_copyctx); + + td->minsigstksz =3D getauxval(AT_MINSIGSTKSZ); + if (!td->minsigstksz) + td->minsigstksz =3D MINSIGSTKSZ; + fprintf(stderr, "Detected MINSTKSIGSZ:%d\n", td->minsigstksz); + + /* Perform test specific additional initialization */ + if (td->init && !td->init(td)) { + fprintf(stderr, "FAILED Testcase initialization.\n"); + return 0; + } + td->initialized =3D 1; + fprintf(stderr, "Testcase initialized.\n"); + + return 1; +} + +int test_setup(struct tdescr *td) +{ + /* assert core invariants symptom of a rotten testcase */ + assert(current); + assert(td); + assert(td->name); + assert(td->run); + + /* Default result is FAIL if test setup fails */ + td->result =3D KSFT_FAIL; + if (td->setup) + return td->setup(td); + else + return default_setup(td); +} + +int test_run(struct tdescr *td) +{ + if (td->trigger) + return td->trigger(td); + else if (td->sig_trig) + return default_trigger(td); + else + return td->run(td, NULL, NULL); +} + +void test_result(struct tdescr *td) +{ + if (td->initialized && td->result !=3D KSFT_SKIP && td->check_result) + td->check_result(td); + default_result(td, 0); +} + +void test_cleanup(struct tdescr *td) +{ + if (td->cleanup) + td->cleanup(td); +} diff --git a/tools/testing/selftests/arm/signal/test_signals_utils.h b/tool= s/testing/selftests/arm/signal/test_signals_utils.h new file mode 100644 index 000000000000..386dcc6c268d --- /dev/null +++ b/tools/testing/selftests/arm/signal/test_signals_utils.h @@ -0,0 +1,128 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2024 ARM Limited */ + +#ifndef __TEST_SIGNALS_UTILS_H__ +#define __TEST_SIGNALS_UTILS_H__ + +#include +#include +#include + +#include +#include "test_signals.h" + +int test_init(struct tdescr *td); +int test_setup(struct tdescr *td); +void test_cleanup(struct tdescr *td); +int test_run(struct tdescr *td); +void test_result(struct tdescr *td); + +/* + * Obtaining a valid and full-blown ucontext_t from userspace is tricky: + * libc getcontext does() not save all the regs and messes with some of + * them (pstate value in particular is not reliable). + * + * Here we use a service signal to grab the ucontext_t from inside a + * dedicated signal handler, since there, it is populated by Kernel + * itself in setup_sigframe(). The grabbed context is then stored and + * made available in td->live_uc. + * + * As service-signal is used a SIGTRAP induced by a 'brk' instruction, + * because here we have to avoid syscalls to trigger the signal since + * they would cause any SVE sigframe content (if any) to be removed. + * + * Anyway this function really serves a dual purpose: + * + * 1. grab a valid sigcontext into td->live_uc for result analysis: in + * such case it returns 1. + * + * 2. detect if, somehow, a previously grabbed live_uc context has been + * used actively with a sigreturn: in such a case the execution would have + * magically resumed in the middle of this function itself (seen_already= =3D=3D1): + * in such a case return 0, since in fact we have not just simply grabbed + * the context. + * + * This latter case is useful to detect when a fake_sigreturn test-case has + * unexpectedly survived without hitting a SEGV. + * + * Note that the case of runtime dynamically sized sigframes (like in SVE + * context) is still NOT addressed: sigframe size is supposed to be fixed + * at sizeof(ucontext_t). + */ +static __always_inline bool get_current_context(struct tdescr *td, + ucontext_t *dest_uc, + size_t dest_sz) +{ + static volatile bool seen_already; + int i; + char *uc =3D (char *)dest_uc; + + assert(td && dest_uc); + /* it's a genuine invocation..reinit */ + seen_already =3D 0; + td->live_uc_valid =3D 0; + td->live_sz =3D dest_sz; + + /* + * This is a memset() but we don't want the compiler to + * optimise it into either instructions or a library call + * which might be incompatible with streaming mode. + */ + for (i =3D 0; i < td->live_sz; i++) { + uc[i] =3D 0; + OPTIMIZER_HIDE_VAR(uc[0]); + } + + td->live_uc =3D dest_uc; + /* + * Grab ucontext_t triggering a SIGTRAP. + * + * Note that: + * - live_uc_valid is declared volatile sig_atomic_t in + * struct tdescr since it will be changed inside the + * sig_copyctx handler + * - the additional 'memory' clobber is there to avoid possible + * compiler's assumption on live_uc_valid and the content + * pointed by dest_uc, which are all changed inside the signal + * handler + * - BRK causes a debug exception which is handled by the Kernel + * and finally causes the SIGTRAP signal to be delivered to this + * test thread. Since such delivery happens on the ret_to_user() + * /do_notify_resume() debug exception return-path, we are sure + * that the registered SIGTRAP handler has been run to completion + * before the execution path is restored here: as a consequence + * we can be sure that the volatile sig_atomic_t live_uc_valid + * carries a meaningful result. Being in a single thread context + * we'll also be sure that any access to memory modified by the + * handler (namely ucontext_t) will be visible once returned. + * - note that since we are using a breakpoint instruction here + * to cause a SIGTRAP, the ucontext_t grabbed from the signal + * handler would naturally contain a PC pointing exactly to this + * BRK line, which means that, on return from the signal handler, + * or if we place the ucontext_t on the stack to fake a sigreturn, + * we'll end up in an infinite loop of BRK-SIGTRAP-handler. + * For this reason we take care to artificially move forward the + * PC to the next instruction while inside the signal handler. + */ + asm volatile ("brk #666" + : "+m" (*dest_uc) + : + : "memory"); + + /* + * If we get here with seen_already=3D=3D1 it implies the td->live_uc + * context has been used to get back here....this probably means + * a test has failed to cause a SEGV...anyway live_uc does not + * point to a just acquired copy of ucontext_t...so return 0 + */ + if (seen_already) { + fprintf(stdout, + "Unexpected successful sigreturn detected: live_uc is stale !\n"); + return 0; + } + seen_already =3D 1; + + return td->live_uc_valid; +} + +#endif diff --git a/tools/testing/selftests/arm/signal/testcases/mangle_cpsr_aif_b= its.c b/tools/testing/selftests/arm/signal/testcases/mangle_cpsr_aif_bits.c new file mode 100644 index 000000000000..f422cd11ccf2 --- /dev/null +++ b/tools/testing/selftests/arm/signal/testcases/mangle_cpsr_aif_bits.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2024 ARM Limited + * + * Try to mangle the ucontext from inside a signal handler, mangling the + * AIF bits in an illegal manner: this attempt must be spotted by Kernel + * and the test case is expected to be terminated via SEGV. + * + */ + +#include "test_signals_utils.h" + +static int mangle_invalid_cpsr_run(struct tdescr *td, siginfo_t *si, + ucontext_t *uc) +{ + + /* + * This config should trigger a SIGSEGV by Kernel when it checks + * the sigframe consistency in valid_user_regs() routine. + */ + uc->uc_mcontext.arm_cpsr |=3D PSR_A_BIT | PSR_I_BIT | PSR_F_BIT; + + return 1; +} + +struct tdescr tde =3D { + .sanity_disabled =3D true, + .name =3D "MANGLE_CPSR_INVALID_AIF_BITS", + .descr =3D "Mangling uc_mcontext with INVALID AIF_BITS", + .sig_trig =3D SIGUSR1, + .sig_ok =3D SIGSEGV, + .run =3D mangle_invalid_cpsr_run, +}; diff --git a/tools/testing/selftests/arm/signal/testcases/mangle_cpsr_inval= id_compat_toggle.c b/tools/testing/selftests/arm/signal/testcases/mangle_cp= sr_invalid_compat_toggle.c new file mode 100644 index 000000000000..cb7eb8aec7f2 --- /dev/null +++ b/tools/testing/selftests/arm/signal/testcases/mangle_cpsr_invalid_comp= at_toggle.c @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2024 ARM Limited + * + * Try to mangle the ucontext from inside a signal handler, toggling + * the execution state bit: this attempt must be spotted by Kernel and + * the test case is expected to be terminated via SEGV. + */ + +#include "test_signals_utils.h" + +static int mangle_invalid_cpsr_run(struct tdescr *td, siginfo_t *si, + ucontext_t *uc) +{ + + /* This config should trigger a SIGSEGV by Kernel */ + uc->uc_mcontext.arm_cpsr ^=3D MODE32_BIT; + + return 1; +} + +struct tdescr tde =3D { + .sanity_disabled =3D true, + .name =3D "MANGLE_CPSR_INVALID_STATE_TOGGLE", + .descr =3D "Mangling uc_mcontext with INVALID STATE_TOGGLE", + .sig_trig =3D SIGUSR1, + .sig_ok =3D SIGSEGV, + .run =3D mangle_invalid_cpsr_run, +}; --=20 2.39.2 From nobody Wed Feb 11 02:26:55 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 0E8344D112; Mon, 22 Apr 2024 07:09:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713769742; cv=none; b=pfDJ+Jq59Vrey9e/7rZiNvvqKrWXJ/tzlh18YbJ5KkzXrIEYsrhMd6Bz0hpdIkPJzKtIdWK4qp4eMruSzGAChBL8mWgyvdRWE4JdLGS6HD7RT6LxCRJOjRDeImk+tUjQNtne+F+KxgTf922z4RQNkrg2ZUbVMV68SNmCQ38GOaA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713769742; c=relaxed/simple; bh=PhnsmAqWu+HmDRPdj49qRtxwYFJ41YZWd0ArXVRH1fg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=SIa1sumxa+5mjh35JrcmsqdsWHYnKfenHs0Neij2a4yrDdjxfzyGB5GdCfkkOOUK4kzw+JUih0zQ6uIH1wrL57Gj0GyQRdcMZzzKvcUJLxrU4bd4LF6mF22GSGmAekmQs7U0C1TzBBgA6QF2sxjkWFQjSS/S0dEFbjFmTPTBEy0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id D79121063; Mon, 22 Apr 2024 00:09:28 -0700 (PDT) Received: from e116581.blr.arm.com (e116581.arm.com [10.162.41.8]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id AE87F3F7BD; Mon, 22 Apr 2024 00:08:55 -0700 (PDT) From: Dev Jain To: shuah@kernel.org, linux-arm-kernel@lists.infradead.org Cc: linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Anshuman.Khandual@arm.com, suzuki.poulose@arm.com, ryan.roberts@arm.com, rob.herring@arm.com, Catalin.Marinas@arm.com, broonie@kernel.org, will@kernel.org, mark.rutland@arm.com, linux@armlinux.org.uk, Dev Jain Subject: [PATCH v2 3/4] selftests/arm: Add elf test Date: Mon, 22 Apr 2024 12:37:16 +0530 Message-Id: <20240422070717.2194201-4-dev.jain@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240422070717.2194201-1-dev.jain@arm.com> References: <20240422070717.2194201-1-dev.jain@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This patch introduces an ELF parsing test; the 5th byte of the ELF header must be 0x01 for a 32-bit process. A basic sanity check is required to ensu= re that we are actually testing a 32-bit build. Signed-off-by: Dev Jain --- tools/testing/selftests/arm/elf/parse_elf.c | 74 +++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 tools/testing/selftests/arm/elf/parse_elf.c diff --git a/tools/testing/selftests/arm/elf/parse_elf.c b/tools/testing/se= lftests/arm/elf/parse_elf.c new file mode 100644 index 000000000000..86a2ec88b47d --- /dev/null +++ b/tools/testing/selftests/arm/elf/parse_elf.c @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2024 ARM Limited + * + * Author : Dev Jain + * + * Parse elf header to confirm 32-bit process + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include + +#include + +/* The ELF file header. This appears at the start of every ELF file. */ + +struct elf_header { + unsigned char e_ident[16]; /* Magic number and other info */ + uint16_t e_type; /* Object file type */ + uint16_t e_machine; /* Architecture */ + uint32_t e_version; /* Object file version */ + uint64_t e_entry; /* Entry point virtual address */ + uint64_t e_phoff; /* Program header table file offset */ + uint64_t e_shoff; /* Section header table file offset */ + uint32_t e_flags; /* Processor-specific flags */ + uint16_t e_ehsize; /* ELF header size in bytes */ + uint16_t e_phentsize; /* Program header table entry size */ + uint16_t e_phnum; /* Program header table entry count */ + uint16_t e_shentsize; /* Section header table entry size */ + uint16_t e_shnum; /* Section header table entry count */ + uint16_t e_shstrndx; /* Section header string table index */ +}; + +static int read_elf_header(const char *elfFile) +{ + struct elf_header header; + FILE *file; + int ret =3D -1; + + file =3D fopen(elfFile, "r"); + if (file) { + + /* store header in struct */ + fread(&header, 1, sizeof(header), file); + fclose(file); + + /* sanity check: does it really follow ELF format */ + if (header.e_ident[0] =3D=3D 0x7f && + header.e_ident[1] =3D=3D 'E' && + header.e_ident[2] =3D=3D 'L' && + header.e_ident[3] =3D=3D 'F') { + if (header.e_ident[4] =3D=3D 0x01) + ret =3D 0; + } else { + ksft_print_msg("Cannot parse /proc/self/exe\n"); + } + } else { + ksft_print_msg("Cannot open /proc/self/exe\n"); + } + return ret; +} + +int main(int argc, char *argv[]) +{ + ksft_print_header(); + ksft_set_plan(1); + + ksft_test_result(read_elf_header("/proc/self/exe") =3D=3D 0, "ELF is 32 b= it\n"); + ksft_finished(); +} --=20 2.39.2 From nobody Wed Feb 11 02:26:55 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 753F34AEE0; Mon, 22 Apr 2024 07:09:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713769748; cv=none; b=Zcr3Fo3etY1vYCUwDWpZFpCgMqDwFb+Iq0oPkTM0upHJ9yCNG+IW1RBtzULwJK9TATh32oNswAaf2NsSHDvFFCTZF7X7EvyGz7hh7/bVqE3zUas+4HX0hP98T2Lrg21r4nN9PwmEaRan8tsI3DfHGpcMgJ0yxmXGmivqv50bb6E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713769748; c=relaxed/simple; bh=28b+Uc5vS3cu/g0Cy9Nux8bRU5W6BmMuyGIHQvZIBjc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Xhclm5pHm5dKyrwmyfuj2qOTztn9zdFwKTLLZi7SM+z/ebvMh28fehaZ8+b6aO6hP2fwsCyrL+rx8/+k52I7aWZvfbaq4PG8PX7qRFFvnBAvwl2u7mPDi2eFH7xxmSAkOOECtvHLJEFc7V+L1yZYtqOsNQT8zp5LzjYeQsHF1TU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 33D641476; Mon, 22 Apr 2024 00:09:34 -0700 (PDT) Received: from e116581.blr.arm.com (e116581.arm.com [10.162.41.8]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 24BCB3F7BD; Mon, 22 Apr 2024 00:09:00 -0700 (PDT) From: Dev Jain To: shuah@kernel.org, linux-arm-kernel@lists.infradead.org Cc: linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Anshuman.Khandual@arm.com, suzuki.poulose@arm.com, ryan.roberts@arm.com, rob.herring@arm.com, Catalin.Marinas@arm.com, broonie@kernel.org, will@kernel.org, mark.rutland@arm.com, linux@armlinux.org.uk, Dev Jain Subject: [PATCH v2 4/4] selftests: Add build infrastructure along with README Date: Mon, 22 Apr 2024 12:37:17 +0530 Message-Id: <20240422070717.2194201-5-dev.jain@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240422070717.2194201-1-dev.jain@arm.com> References: <20240422070717.2194201-1-dev.jain@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add arm target, individual Makefile targets, and instructions to build the tests, along with .gitignore files and a config file. Signed-off-by: Dev Jain --- tools/testing/selftests/Makefile | 1 + tools/testing/selftests/arm/Makefile | 57 +++++++++++++++++++ tools/testing/selftests/arm/README | 31 ++++++++++ tools/testing/selftests/arm/config | 1 + tools/testing/selftests/arm/elf/.gitignore | 2 + tools/testing/selftests/arm/elf/Makefile | 6 ++ tools/testing/selftests/arm/mm/.gitignore | 2 + tools/testing/selftests/arm/mm/Makefile | 6 ++ tools/testing/selftests/arm/signal/.gitignore | 3 + tools/testing/selftests/arm/signal/Makefile | 30 ++++++++++ 10 files changed, 139 insertions(+) create mode 100644 tools/testing/selftests/arm/Makefile create mode 100644 tools/testing/selftests/arm/README create mode 100644 tools/testing/selftests/arm/config create mode 100644 tools/testing/selftests/arm/elf/.gitignore create mode 100644 tools/testing/selftests/arm/elf/Makefile create mode 100644 tools/testing/selftests/arm/mm/.gitignore create mode 100644 tools/testing/selftests/arm/mm/Makefile create mode 100644 tools/testing/selftests/arm/signal/.gitignore create mode 100644 tools/testing/selftests/arm/signal/Makefile diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Mak= efile index e1504833654d..3966d2541ef7 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 TARGETS +=3D alsa TARGETS +=3D amd-pstate +TARGETS +=3D arm TARGETS +=3D arm64 TARGETS +=3D bpf TARGETS +=3D breakpoints diff --git a/tools/testing/selftests/arm/Makefile b/tools/testing/selftests= /arm/Makefile new file mode 100644 index 000000000000..039224bc006e --- /dev/null +++ b/tools/testing/selftests/arm/Makefile @@ -0,0 +1,57 @@ +# SPDX-License-Identifier: GPL-2.0 + +# When ARCH not overridden for crosscompiling, lookup machine +ARCH ?=3D $(shell uname -m 2>/dev/null || echo not) + +ifneq (,$(filter $(ARCH),aarch64 arm64 arm armv7l armv8l)) +ARM_SUBTARGETS ?=3D mm signal elf +else +ARM_SUBTARGETS :=3D +endif + +CFLAGS :=3D -Wall -O2 -g -static + +# A proper top_srcdir is needed by KSFT(lib.mk) +top_srcdir =3D $(realpath ../../../../) + +# Additional include paths needed by kselftest.h and local headers +CFLAGS +=3D -I$(top_srcdir)/tools/testing/selftests/ + +CFLAGS +=3D -I$(top_srcdir)/tools/include + +export CFLAGS +export top_srcdir + +all: + @for DIR in $(ARM_SUBTARGETS); do \ + BUILD_TARGET=3D$(OUTPUT)/$$DIR; \ + mkdir -p $$BUILD_TARGET; \ + make OUTPUT=3D$$BUILD_TARGET -C $$DIR $@; \ + done + +install: all + @for DIR in $(ARM_SUBTARGETS); do \ + BUILD_TARGET=3D$(OUTPUT)/$$DIR; \ + make OUTPUT=3D$$BUILD_TARGET -C $$DIR $@; \ + done + +run_tests: all + @for DIR in $(ARM_SUBTARGETS); do \ + BUILD_TARGET=3D$(OUTPUT)/$$DIR; \ + make OUTPUT=3D$$BUILD_TARGET -C $$DIR $@; \ + done + +# Avoid any output on non arm on emit_tests +emit_tests: + @for DIR in $(ARM_SUBTARGETS); do \ + BUILD_TARGET=3D$(OUTPUT)/$$DIR; \ + make OUTPUT=3D$$BUILD_TARGET -C $$DIR $@; \ + done + +clean: + @for DIR in $(ARM_SUBTARGETS); do \ + BUILD_TARGET=3D$(OUTPUT)/$$DIR; \ + make OUTPUT=3D$$BUILD_TARGET -C $$DIR $@; \ + done + +.PHONY: all clean install run_tests emit_tests diff --git a/tools/testing/selftests/arm/README b/tools/testing/selftests/a= rm/README new file mode 100644 index 000000000000..1a05c043d7ee --- /dev/null +++ b/tools/testing/selftests/arm/README @@ -0,0 +1,31 @@ +KSelfTest ARM +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +- This is a series of compatibility tests, wherein the source files are + built statically into a 32 bit ELF; they should pass on both 32 and 64 + bit kernels. They are not built or run but just skipped completely when + env-variable ARCH is found to be different than 'arm64' or 'arm' and + `uname -m` reports other than 'aarch64', 'armv7l' or 'armv8l'. + +- Please ensure that the test kernel is built with CONFIG_COMPAT enabled. + +- Holding true the above, ARM KSFT tests can be run within the KSelfTest + framework using standard Linux top-level-makefile targets. Please set + $(CROSS_COMPILE) to 'arm-linux-gnueabi-' or 'arm-linux-gnueabihf-'. + + $ make TARGETS=3Darm kselftest-clean + $ make $(CROSS_COMPILE) TARGETS=3Darm kselftest + + or + + $ make $(CROSS_COMPILE) -C tools/testing/selftests TARGETS=3Darm \ + INSTALL_PATH=3D install + + or, alternatively, only specific arm/ subtargets can be picked: + + $ make $(CROSS_COMPILE) -C tools/testing/selftests TARGETS=3Darm \ + ARM_SUBTARGETS=3D"signal" INSTALL_PATH=3D \ + install + + Further details on building and running KFST can be found in: + Documentation/dev-tools/kselftest.rst diff --git a/tools/testing/selftests/arm/config b/tools/testing/selftests/a= rm/config new file mode 100644 index 000000000000..9b072bae787e --- /dev/null +++ b/tools/testing/selftests/arm/config @@ -0,0 +1 @@ +CONFIG_COMPAT=3Dy diff --git a/tools/testing/selftests/arm/elf/.gitignore b/tools/testing/sel= ftests/arm/elf/.gitignore new file mode 100644 index 000000000000..41458ecbcd72 --- /dev/null +++ b/tools/testing/selftests/arm/elf/.gitignore @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +parse_elf diff --git a/tools/testing/selftests/arm/elf/Makefile b/tools/testing/selft= ests/arm/elf/Makefile new file mode 100644 index 000000000000..86636fe02994 --- /dev/null +++ b/tools/testing/selftests/arm/elf/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ARM Limited + +TEST_GEN_PROGS :=3D parse_elf + +include ../../lib.mk diff --git a/tools/testing/selftests/arm/mm/.gitignore b/tools/testing/self= tests/arm/mm/.gitignore new file mode 100644 index 000000000000..eb28169bb1b5 --- /dev/null +++ b/tools/testing/selftests/arm/mm/.gitignore @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +compat_va diff --git a/tools/testing/selftests/arm/mm/Makefile b/tools/testing/selfte= sts/arm/mm/Makefile new file mode 100644 index 000000000000..d8bfa45df98c --- /dev/null +++ b/tools/testing/selftests/arm/mm/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ARM Limited + +TEST_GEN_PROGS :=3D compat_va + +include ../../lib.mk diff --git a/tools/testing/selftests/arm/signal/.gitignore b/tools/testing/= selftests/arm/signal/.gitignore new file mode 100644 index 000000000000..26929e3c20ea --- /dev/null +++ b/tools/testing/selftests/arm/signal/.gitignore @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only +mangle_cpsr_aif_bits +mangle_cpsr_invalid_compat_toggle diff --git a/tools/testing/selftests/arm/signal/Makefile b/tools/testing/se= lftests/arm/signal/Makefile new file mode 100644 index 000000000000..3540a25de75a --- /dev/null +++ b/tools/testing/selftests/arm/signal/Makefile @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ARM Limited + +# Additional include paths needed by kselftest.h and local headers +CFLAGS +=3D -D_GNU_SOURCE -std=3Dgnu99 -I. + +SRCS :=3D $(filter-out testcases/testcases.c,$(wildcard testcases/*.c)) +PROGS :=3D $(patsubst %.c,%,$(SRCS)) + +# Generated binaries to be installed by top KSFT script +TEST_GEN_PROGS :=3D $(notdir $(PROGS)) + +# Get Kernel headers installed and use them. + +# Including KSFT lib.mk here will also mangle the TEST_GEN_PROGS list +# to account for any OUTPUT target-dirs optionally provided by +# the toplevel makefile +include ../../lib.mk + +$(TEST_GEN_PROGS): $(PROGS) + cp $(PROGS) $(OUTPUT)/ + +# Common test-unit targets to build common-layout test-cases executables +# Needs secondary expansion to properly include the testcase c-file in pre= -reqs +COMMON_SOURCES :=3D test_signals.c test_signals_utils.c +COMMON_HEADERS :=3D test_signals.h test_signals_utils.h + +.SECONDEXPANSION: +$(PROGS): $$@.c ${COMMON_SOURCES} ${COMMON_HEADERS} + $(CC) $(CFLAGS) ${@}.c ${COMMON_SOURCES} -o $@ --=20 2.39.2