From patchwork Wed Jun 21 21:00:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 13287956 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 C99D0EB64D8 for ; Wed, 21 Jun 2023 21:01:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229893AbjFUVBX (ORCPT ); Wed, 21 Jun 2023 17:01:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39474 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229590AbjFUVBW (ORCPT ); Wed, 21 Jun 2023 17:01:22 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9B29B10F2; Wed, 21 Jun 2023 14:01:21 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 2F78D616D5; Wed, 21 Jun 2023 21:01:21 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 03452C433CC; Wed, 21 Jun 2023 21:01:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1687381280; bh=w8fxWAGiQaBMUkDFhDb0uejIT4OUWJBakDRMQaptQUc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=JiOVv+OUQ+GiSChpM3EbH//sZ9SW/cdtlVUBmlB99xwHurGA0IB21aX7NtIRBVSZv 2jKP7BjYYD1wBUJZLHrHJTJ/b/RTQBMaWWaIDcW53eOdLIPOAdxBBJyHDvaZ8n6TuW dGN/toXoCWf7+mkPVWJ8oAiQFylGAiD6jzKC3OIwLsXYxw6t8o1Kt7kQlNcT1d+UKg wqnom1XH2Fi2tCZKhsw3uVDQLXhGLMXPER8bXSYdIpSANkUQJbaUrxVLn3dst3D4tt /e1/sHNVzBLhAIei9oR5TY9HVRiMiHdV3fOe70AMOQSBiVYa06ZhZ1YO5NCOGdog0c kZLPLDYFbYRfA== From: Mark Brown Date: Wed, 21 Jun 2023 22:00:50 +0100 Subject: [PATCH 1/2] arm64/signal: Restore TPIDR2 register rather than memory state MIME-Version: 1.0 Message-Id: <20230621-arm64-fix-tpidr2-signal-restore-v1-1-b6d9e584d2ee@kernel.org> References: <20230621-arm64-fix-tpidr2-signal-restore-v1-0-b6d9e584d2ee@kernel.org> In-Reply-To: <20230621-arm64-fix-tpidr2-signal-restore-v1-0-b6d9e584d2ee@kernel.org> To: Catalin Marinas , Will Deacon , Shuah Khan , Szabolcs Nagy Cc: linux-arm-kernel@lists.infradead.org, linux-kselftest@vger.kernel.org, Mark Brown , stable@vger.kernel.org X-Mailer: b4 0.13-dev-c6835 X-Developer-Signature: v=1; a=openpgp-sha256; l=1250; i=broonie@kernel.org; h=from:subject:message-id; bh=w8fxWAGiQaBMUkDFhDb0uejIT4OUWJBakDRMQaptQUc=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBkk2UbS0wOwkAWAp+qIYM0ZvfglKPKPUmMPK3OciMF ig54HByJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCZJNlGwAKCRAk1otyXVSH0DnFB/ 4/OhOmCaDtC6BJBtGVnMSAH2V/hCabEzZqI5wEeh/K/BHoRw1ks+XiL+wU7BQN/R7oPfqZ4ZQhhezM WDK7HxpI2KN0XyMv3+VL5chk/LRbh6Jy3HZ5X8Y0YD740T/dcxfIwgggIo7Fea0swkXBHoGv6M/U1R VFujmezrE/NAJqhbmW5pNHYI2N7FG8/fkMjP8XdQDgc7MT2izYSFqqbq9iV1v5ZVMeycuTTluQYD+B +5tR1HhYZ2HjNjPnXn74D8ZsHJmjFlQEL+MZkIVood5WkIk4nCXlQm9ocmQTm9JBpuKuXy4SX9iuEu Uhs/mS5LhHoy+mPTGWqdTUXMiDyJzz X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org Currently when restoring the TPIDR2 signal context we set the new value from the signal frame in the thread data structure but not the register, following the pattern for the rest of the data we are restoring. This does not work in the case of TPIDR2, the register always has the value for the current task. This means that either we return to userspace and ignore the new value or we context switch and save the register value on top of the newly restored value. Load the value from the signal context into the register instead. Fixes: 39e54499280f ("arm64/signal: Include TPIDR2 in the signal context") Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- arch/arm64/kernel/signal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c index 2cfc810d0a5b..10b407672c42 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -398,7 +398,7 @@ static int restore_tpidr2_context(struct user_ctxs *user) __get_user_error(tpidr2_el0, &user->tpidr2->tpidr2, err); if (!err) - current->thread.tpidr2_el0 = tpidr2_el0; + write_sysreg_s(tpidr2_el0, SYS_TPIDR2_EL0); return err; } From patchwork Wed Jun 21 21:00:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 13287957 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 A8CACEB64D7 for ; Wed, 21 Jun 2023 21:01:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229789AbjFUVBZ (ORCPT ); Wed, 21 Jun 2023 17:01:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39486 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229590AbjFUVBY (ORCPT ); Wed, 21 Jun 2023 17:01:24 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7F5EB19C for ; Wed, 21 Jun 2023 14:01:23 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 13D19616DB for ; Wed, 21 Jun 2023 21:01:23 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1002DC433C0; Wed, 21 Jun 2023 21:01:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1687381282; bh=0Otr1gGFLIbmZ8hW9P3ig3nqrlBtVGxAbSaBQQaDgYA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=skgLlztnDvomOw/rgIEU6ujzcipJIoKacTRUQfgKoYDksgqQCdGE37MjSTiT2hBoV +/BOD9xOH6T+S3WvfC5TrbsXdXl5und1qv7cgOGLTsGr+YJ5Jx9ERsfeXxwABAlOqd dd6JD/En3jRfnAl2ahnBZV0snh1n6rIA7Hc7uUUPTNQ9SQ3CKCKEBEpZuFNwo6sQwr 3mUx4npQpGcyOc7N5W7el6lYmrR0hxloqgIgIgwo6M/LmUVaeS5LQGMgVsinD3Jehc mUvMr1nKdvQvykj1OnJKlnhbaI0SNCYJhJ8auiOnJXc0bT0YjD9j3e48dPTjq/a4Cp QRqE3LvT6z08A== From: Mark Brown Date: Wed, 21 Jun 2023 22:00:51 +0100 Subject: [PATCH 2/2] kselftest/arm64: Add a test case for TPIDR2 restore MIME-Version: 1.0 Message-Id: <20230621-arm64-fix-tpidr2-signal-restore-v1-2-b6d9e584d2ee@kernel.org> References: <20230621-arm64-fix-tpidr2-signal-restore-v1-0-b6d9e584d2ee@kernel.org> In-Reply-To: <20230621-arm64-fix-tpidr2-signal-restore-v1-0-b6d9e584d2ee@kernel.org> To: Catalin Marinas , Will Deacon , Shuah Khan , Szabolcs Nagy Cc: linux-arm-kernel@lists.infradead.org, linux-kselftest@vger.kernel.org, Mark Brown X-Mailer: b4 0.13-dev-c6835 X-Developer-Signature: v=1; a=openpgp-sha256; l=3063; i=broonie@kernel.org; h=from:subject:message-id; bh=0Otr1gGFLIbmZ8hW9P3ig3nqrlBtVGxAbSaBQQaDgYA=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBkk2UbdLcf5wQjFOxU9upjX8rHFyxptm5JQjM5C+dw 5qod0TaJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCZJNlGwAKCRAk1otyXVSH0IwxB/ 91+aGd7wZPnKphcbFssxji/rPLXVi3hwFV8O6khOQbkftrx1kAP48+6YPH8+mE2V9gXLfW5Q/nqEda 9Rl3xbOikVV2mSuxU2VPU4Z+25Fo9LPW+fLzauNCrWSvVqfoyDlOmDE1QkcVCdzCbSaMNpV1Q5AkkM TP5oDELlIwSPmfju2S2NGcDUAaA2+rnGYiO81abDNe/E0QL4RUHP4M76ipdlkuOdTEl0qwkgsczFKT ThqNqSXXUy1oXYUUDITb3fhwCHL36tYdLcN+majux+qQkg489WqlXLt7ygWUMybEIpZtGUNt2XhaZU ZBxsmcMe8+EjpBPJMZWu5MbTkCLmGj X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org Due to the fact that TPIDR2 is intended to be managed by libc we don't currently test modifying it via the signal context since that might disrupt libc's usage of it and cause instability. We can however test the opposite case with less risk, modifying TPIDR2 in a signal handler and making sure that the original value is restored after returning from the signal handler. Add a test which does this. Signed-off-by: Mark Brown --- tools/testing/selftests/arm64/signal/.gitignore | 2 +- .../arm64/signal/testcases/tpidr2_restore.c | 85 ++++++++++++++++++++++ 2 files changed, 86 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/arm64/signal/.gitignore b/tools/testing/selftests/arm64/signal/.gitignore index 8ab4c86837fd..839e3a252629 100644 --- a/tools/testing/selftests/arm64/signal/.gitignore +++ b/tools/testing/selftests/arm64/signal/.gitignore @@ -4,7 +4,7 @@ fake_sigreturn_* sme_* ssve_* sve_* -tpidr2_siginfo +tpidr2_* za_* zt_* !*.[ch] diff --git a/tools/testing/selftests/arm64/signal/testcases/tpidr2_restore.c b/tools/testing/selftests/arm64/signal/testcases/tpidr2_restore.c new file mode 100644 index 000000000000..c01db4d56eb9 --- /dev/null +++ b/tools/testing/selftests/arm64/signal/testcases/tpidr2_restore.c @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2023 ARM Limited + * + * Verify that the TPIDR2 register context in signal frames is restored. + */ + +#include +#include +#include +#include +#include +#include + +#include "test_signals_utils.h" +#include "testcases.h" + +#define SYS_TPIDR2 "S3_3_C13_C0_5" + +static uint64_t get_tpidr2(void) +{ + uint64_t val; + + asm volatile ( + "mrs %0, " SYS_TPIDR2 "\n" + : "=r"(val) + : + : "cc"); + + return val; +} + +static void set_tpidr2(uint64_t val) +{ + asm volatile ( + "msr " SYS_TPIDR2 ", %0\n" + : + : "r"(val) + : "cc"); +} + + +static uint64_t initial_tpidr2; + +static bool save_tpidr2(struct tdescr *td) +{ + initial_tpidr2 = get_tpidr2(); + fprintf(stderr, "Initial TPIDR2: %lx\n", initial_tpidr2); + + return true; +} + +static int modify_tpidr2(struct tdescr *td, siginfo_t *si, ucontext_t *uc) +{ + uint64_t my_tpidr2 = get_tpidr2(); + + my_tpidr2++; + fprintf(stderr, "Setting TPIDR2 to %lx\n", my_tpidr2); + set_tpidr2(my_tpidr2); + + return 0; +} + +static void check_tpidr2(struct tdescr *td) +{ + uint64_t tpidr2 = get_tpidr2(); + + td->pass = tpidr2 == initial_tpidr2; + + if (td->pass) + fprintf(stderr, "TPIDR2 restored\n"); + else + fprintf(stderr, "TPIDR2 was %lx but is now %lx\n", + initial_tpidr2, tpidr2); +} + +struct tdescr tde = { + .name = "TPIDR2 restore", + .descr = "Validate that TPIDR2 is restored from the sigframe", + .timeout = 3, + .sig_trig = SIGUSR1, + .init = save_tpidr2, + .run = modify_tpidr2, + .check_result = check_tpidr2, +};