From patchwork Wed Jul 28 16:33:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 12406343 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.7 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1FFEEC4338F for ; Wed, 28 Jul 2021 16:34:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E8F3960F9B for ; Wed, 28 Jul 2021 16:34:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229716AbhG1QeM (ORCPT ); Wed, 28 Jul 2021 12:34:12 -0400 Received: from mail.kernel.org ([198.145.29.99]:37570 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229591AbhG1QeL (ORCPT ); Wed, 28 Jul 2021 12:34:11 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 1A58961019; Wed, 28 Jul 2021 16:34:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1627490049; bh=RCUI82H/4W6FmihK1AkpRMF/AXitVCXzKcuEuGl6Cws=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=AOQUiF1JWUO7NK2AQzN8gpwtfYmLeeMCV6WdOhKq7W7UZaJi2REKrbA/Inwrqv6ut AV9bQQEGnQuLt8fTUkcLrJl0nyg2XzxsFb19b/oidNbmQLWnCT0d9H16DW97oDuJ09 rb3wbC00pK/XbpLx+crSh2e8TVmKqwLmRlApu6ZKMRlkjLugsmiJ5Oq5/sAjfcWUZJ QxSPU75Ki2Rgf5yiPevoNhA6HcCkCgdek62ElHTnPB8NJhKMF+V2pTa7JQsSrQ6HPq vr8zITlM8mp2UafT77IiPEaqko4LqtH3W2HibdoD0bnp38fP5hMEa7diHN71lisdRv /vH6Uzcb4z22g== From: Mark Brown To: Catalin Marinas , Will Deacon , Shuah Khan Cc: Dave Martin , linux-arm-kernel@lists.infradead.org, linux-kselftest@vger.kernel.org, Mark Brown Subject: [PATCH v2 1/4] kselftest/arm64: Provide a helper binary and "library" for SVE RDVL Date: Wed, 28 Jul 2021 17:33:15 +0100 Message-Id: <20210728163318.51492-2-broonie@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210728163318.51492-1-broonie@kernel.org> References: <20210728163318.51492-1-broonie@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=3690; h=from:subject; bh=RCUI82H/4W6FmihK1AkpRMF/AXitVCXzKcuEuGl6Cws=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBhAYbJMq3zDnqSnFUJ1lvpDawfFS3yduzdzxjq60HD 0JBiBAOJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCYQGGyQAKCRAk1otyXVSH0GFMB/ 4kheASFmEw33ww3jo6pF7GQdVH6TLvOo+Ji9hhnfkHt0LS5GM6jXGTNtXj0jtbfqnGGCtU01omJnTo t0cGvNAL6lBAhgPv/iOUzW4w1EfmAsJHfnEHyjAfgxZhW2mKXHYlF1USx+Svo6of0OaM5nSAB2HhvG ruDd9jTaGkaNxSwyhKPRG/8q0w1D3npORzW0YWJMP2PDzMsPddF6yVN1xCs1Xnr78tSUhR8nlfQ4xm G9g8R+klEfivWN7aqZtgc5GhOh8P1fMla0ixppl0BDhqgeXNPwJTmJ3YS6daH3fcKFM2OXIAL6KgSd n/L9Hu8P1VExqkPJDJWyIPBlrQ09m+ X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org SVE provides an instruction RDVL which reports the currently configured vector length. In order to validate that our vector length configuration interfaces are working correctly without having to build the C code for our test programs with SVE enabled provide a trivial assembly library with a C callable function that executes RDVL. Since these interfaces also control behaviour on exec*() provide a trivial wrapper program which reports the currently configured vector length on stdout, tests can use this to verify that behaviour on exec*() is as expected. In preparation for providing similar helper functionality for SME, the Scalable Matrix Extension, which allows separately configured vector lengths to be read back both the assembler function and wrapper binary have SVE included in their name. Signed-off-by: Mark Brown Reviewed-by: Dave Martin --- tools/testing/selftests/arm64/fp/.gitignore | 1 + tools/testing/selftests/arm64/fp/Makefile | 6 +++++- tools/testing/selftests/arm64/fp/rdvl-sve.c | 14 ++++++++++++++ tools/testing/selftests/arm64/fp/rdvl.S | 9 +++++++++ tools/testing/selftests/arm64/fp/rdvl.h | 8 ++++++++ 5 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/arm64/fp/rdvl-sve.c create mode 100644 tools/testing/selftests/arm64/fp/rdvl.S create mode 100644 tools/testing/selftests/arm64/fp/rdvl.h diff --git a/tools/testing/selftests/arm64/fp/.gitignore b/tools/testing/selftests/arm64/fp/.gitignore index d66f76d2a650..6b53a7b60fee 100644 --- a/tools/testing/selftests/arm64/fp/.gitignore +++ b/tools/testing/selftests/arm64/fp/.gitignore @@ -1,4 +1,5 @@ fpsimd-test +rdvl-sve sve-probe-vls sve-ptrace sve-test diff --git a/tools/testing/selftests/arm64/fp/Makefile b/tools/testing/selftests/arm64/fp/Makefile index a57009d3a0dc..ed62e7003b96 100644 --- a/tools/testing/selftests/arm64/fp/Makefile +++ b/tools/testing/selftests/arm64/fp/Makefile @@ -2,12 +2,16 @@ CFLAGS += -I../../../../../usr/include/ TEST_GEN_PROGS := sve-ptrace sve-probe-vls -TEST_PROGS_EXTENDED := fpsimd-test fpsimd-stress sve-test sve-stress vlset +TEST_PROGS_EXTENDED := fpsimd-test fpsimd-stress \ + rdvl-sve \ + sve-test sve-stress \ + vlset all: $(TEST_GEN_PROGS) $(TEST_PROGS_EXTENDED) fpsimd-test: fpsimd-test.o $(CC) -nostdlib $^ -o $@ +rdvl-sve: rdvl-sve.o rdvl.o sve-ptrace: sve-ptrace.o sve-ptrace-asm.o sve-probe-vls: sve-probe-vls.o sve-test: sve-test.o diff --git a/tools/testing/selftests/arm64/fp/rdvl-sve.c b/tools/testing/selftests/arm64/fp/rdvl-sve.c new file mode 100644 index 000000000000..7f8a13a18f5d --- /dev/null +++ b/tools/testing/selftests/arm64/fp/rdvl-sve.c @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include + +#include "rdvl.h" + +int main(void) +{ + int vl = rdvl_sve(); + + printf("%d\n", vl); + + return 0; +} diff --git a/tools/testing/selftests/arm64/fp/rdvl.S b/tools/testing/selftests/arm64/fp/rdvl.S new file mode 100644 index 000000000000..6e76dd720b87 --- /dev/null +++ b/tools/testing/selftests/arm64/fp/rdvl.S @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (C) 2021 ARM Limited. + +.arch_extension sve + +.globl rdvl_sve +rdvl_sve: + rdvl x0, #1 + ret diff --git a/tools/testing/selftests/arm64/fp/rdvl.h b/tools/testing/selftests/arm64/fp/rdvl.h new file mode 100644 index 000000000000..7c9d953fc9e7 --- /dev/null +++ b/tools/testing/selftests/arm64/fp/rdvl.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef RDVL_H +#define RDVL_H + +int rdvl_sve(void); + +#endif From patchwork Wed Jul 28 16:33:16 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 12406345 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.7 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2F788C4338F for ; Wed, 28 Jul 2021 16:34:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 175F46101C for ; Wed, 28 Jul 2021 16:34:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229806AbhG1QeS (ORCPT ); Wed, 28 Jul 2021 12:34:18 -0400 Received: from mail.kernel.org ([198.145.29.99]:37600 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229797AbhG1QeO (ORCPT ); Wed, 28 Jul 2021 12:34:14 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id E5BFA60F9B; Wed, 28 Jul 2021 16:34:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1627490052; bh=R0X/PIkba67SuYhiFH1mZDCaVfSVQGrDfuGGj27KXBk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=I49G2+ItDNCkfyRqD9DYs5pZuruYq/Nc2HJq+U9Y2ZHE+zESWn2j8Ys14OWKb9mw6 wXCvBeYKZzS0hClvI5UuFCzNoKdlo6IxXxkTxf1RGQbvl4+EE79+Bhaha83Mk1eDMq kq9kJIOy8cEb7bcEtWyFP4kwPoVIFIxn84I+zZn0V7EjXNJCsh/ldS49mZGy+lc4T6 C9rNbgmVrvIaERMVglWklxAtRaDLLUQDlwuFwfe9d90NP1Tyfji/KQzKTkZVeoDKSS b2a0HQL56Xlcp75/oTp9CTmWJHDOpl7u+MzqFpLir5ofkixkstt2PA6mc1hTX1K58J f0nWWxTgyGjOQ== From: Mark Brown To: Catalin Marinas , Will Deacon , Shuah Khan Cc: Dave Martin , linux-arm-kernel@lists.infradead.org, linux-kselftest@vger.kernel.org, Mark Brown Subject: [PATCH v2 2/4] kselftest/arm64: Validate vector lengths are set in sve-probe-vls Date: Wed, 28 Jul 2021 17:33:16 +0100 Message-Id: <20210728163318.51492-3-broonie@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210728163318.51492-1-broonie@kernel.org> References: <20210728163318.51492-1-broonie@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=1685; h=from:subject; bh=R0X/PIkba67SuYhiFH1mZDCaVfSVQGrDfuGGj27KXBk=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBhAYbJ1000oTPFcE2/jiud0uwYD+HZwSrRozpN9ybC UULtZ56JATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCYQGGyQAKCRAk1otyXVSH0HABB/ 4wRecWQSAHkkRzw8y9ZX5HROcXHxWySc4zYjLUN9sZ3LlxLyZDOAiDvP/pUNd+zg+5PqYKv46q77nv 9nKir3jA0mvpmWs5bG0ZRc9TMkRcnsS/gvM8Zwhq0EgzAioC23dcxADGIWcAglanjp0wRIXz3V0r2f gYxjGeAlNbcDGzMWjaO1Xxg5einaZcjIy13HfanGKMwveDos0tE7eGwiEsUT9u8ULSsl5+FoDToncc Wb0iGnMs3TGGrTHKHOe9JbOW/3rk0fIXW3PK69f1dvzrZ6eFh6l8YtAtBFNA9MgukxCsNYhlOruHK4 Bova0U1lCgLvux6DiYRFGaFqnG8B/v X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org Currently sve-probe-vls does not verify that the vector lengths reported by the prctl() interface are actually what is reported by the architecture, use the rdvl_sve() helper to validate this. Signed-off-by: Mark Brown Reviewed-by: Dave Martin --- tools/testing/selftests/arm64/fp/Makefile | 2 +- tools/testing/selftests/arm64/fp/sve-probe-vls.c | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/arm64/fp/Makefile b/tools/testing/selftests/arm64/fp/Makefile index ed62e7003b96..fa3a0167db2d 100644 --- a/tools/testing/selftests/arm64/fp/Makefile +++ b/tools/testing/selftests/arm64/fp/Makefile @@ -13,7 +13,7 @@ fpsimd-test: fpsimd-test.o $(CC) -nostdlib $^ -o $@ rdvl-sve: rdvl-sve.o rdvl.o sve-ptrace: sve-ptrace.o sve-ptrace-asm.o -sve-probe-vls: sve-probe-vls.o +sve-probe-vls: sve-probe-vls.o rdvl.o sve-test: sve-test.o $(CC) -nostdlib $^ -o $@ vlset: vlset.o diff --git a/tools/testing/selftests/arm64/fp/sve-probe-vls.c b/tools/testing/selftests/arm64/fp/sve-probe-vls.c index 76e138525d55..a24eca7a4ecb 100644 --- a/tools/testing/selftests/arm64/fp/sve-probe-vls.c +++ b/tools/testing/selftests/arm64/fp/sve-probe-vls.c @@ -13,6 +13,7 @@ #include #include "../../kselftest.h" +#include "rdvl.h" int main(int argc, char **argv) { @@ -38,6 +39,10 @@ int main(int argc, char **argv) vl &= PR_SVE_VL_LEN_MASK; + if (rdvl_sve() != vl) + ksft_exit_fail_msg("PR_SVE_SET_VL reports %d, RDVL %d\n", + vl, rdvl_sve()); + if (!sve_vl_valid(vl)) ksft_exit_fail_msg("VL %d invalid\n", vl); vq = sve_vq_from_vl(vl); From patchwork Wed Jul 28 16:33:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 12406347 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.7 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 910BCC4320A for ; Wed, 28 Jul 2021 16:34:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6815060F9B for ; Wed, 28 Jul 2021 16:34:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229729AbhG1QeS (ORCPT ); Wed, 28 Jul 2021 12:34:18 -0400 Received: from mail.kernel.org ([198.145.29.99]:37628 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230001AbhG1QeR (ORCPT ); Wed, 28 Jul 2021 12:34:17 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id A4BB061019; Wed, 28 Jul 2021 16:34:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1627490055; bh=EN820oZ5k8blUq0DCy4U6RFJp5l8AIsEi0JmwQjoCLg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jLH6UDP+TE5CNjQnASoc9d86h3CzHyHf0c38HinYlK4isKJ0xY1X8ihzEVWxChN+F BD/11sl6JkQ6TdU6psfeQieRQbmWYEbUsIzl3y7DNPNyP9yiB1Bwr3gBATjUew3CaW MJ51P9PBBmVMLROK7PoMSCTKhzEcC4FAMOtvYJuGR7TkkLFl7zReD8jFxIkKFHA7Kl J9yNJ0Z7qRJRvEGkDtvqL5XlWi21FbF3vB6Dq4uKPhV0BlnkjLnLQksrhCU88fOSl8 1hGBLqeJalNupWXzHkLd0xgwMBcQRs9j2u/fG0kPooev8yW0KBGFhzQPZvK9kU6RSi 6+y8BI6QD9MLQ== From: Mark Brown To: Catalin Marinas , Will Deacon , Shuah Khan Cc: Dave Martin , linux-arm-kernel@lists.infradead.org, linux-kselftest@vger.kernel.org, Mark Brown Subject: [PATCH v2 3/4] kselftest/arm64: Add tests for SVE vector configuration Date: Wed, 28 Jul 2021 17:33:17 +0100 Message-Id: <20210728163318.51492-4-broonie@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210728163318.51492-1-broonie@kernel.org> References: <20210728163318.51492-1-broonie@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=17248; h=from:subject; bh=EN820oZ5k8blUq0DCy4U6RFJp5l8AIsEi0JmwQjoCLg=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBhAYbK5LOb1vE1WFnF9eAbbZOLfUcO9qu6RG+jdCcz UVsXc9eJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCYQGGygAKCRAk1otyXVSH0LGIB/ 4qTEvGo/Su/VYTT+Vb/3vQFLYE71F8m3GZqulFHbAC83eJwqnqEeuX0eNY/bd0By5kpvC+jSaP98bO I+cPUmgmpZbFY7VixWOjQ/0Xc8N2DrkoimeaHXxThHmgYGaG+ONF8VklHktQwMPZIj+Cd5Aq72D8r2 yM6hJVnlCWOe5fNVoifOZBW4ERa+GCv8WwC7jIM1henVZO1UmmVuNnYc0GQLAGapXjY4QczJrEahIx m9hZtSoOQgdfpmlvG3E0B5v4gSCYDZyEVXdQLnWq1LQ1IIkPlZqIA8zHnafBJIWOnXnfmRCR3ZBIXe zHqpRVl24kUGIVXHdskwYSNUapbQKu X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org We provide interfaces for configuring the SVE vector length seen by processes using prctl and also via /proc for configuring the default values. Provide tests that exercise all these interfaces and verify that they take effect as expected, though at present no test fully enumerates all the possible vector lengths. A subset of this is already tested via sve-probe-vls but the /proc interfaces are not currently covered at all. In preparation for the forthcoming support for SME, the Scalable Matrix Extension, which has separately but similarly configured vector lengths which we expect to offer similar userspace interfaces for, all the actual files and prctls used are parameterised and we don't validate that the architectural minimum vector length is the minimum we see. Signed-off-by: Mark Brown --- tools/testing/selftests/arm64/fp/.gitignore | 1 + tools/testing/selftests/arm64/fp/Makefile | 3 +- tools/testing/selftests/arm64/fp/vec-syscfg.c | 580 ++++++++++++++++++ 3 files changed, 583 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/arm64/fp/vec-syscfg.c diff --git a/tools/testing/selftests/arm64/fp/.gitignore b/tools/testing/selftests/arm64/fp/.gitignore index 6b53a7b60fee..b67395903b9b 100644 --- a/tools/testing/selftests/arm64/fp/.gitignore +++ b/tools/testing/selftests/arm64/fp/.gitignore @@ -3,4 +3,5 @@ rdvl-sve sve-probe-vls sve-ptrace sve-test +vec-syscfg vlset diff --git a/tools/testing/selftests/arm64/fp/Makefile b/tools/testing/selftests/arm64/fp/Makefile index fa3a0167db2d..f2abdd6ba12e 100644 --- a/tools/testing/selftests/arm64/fp/Makefile +++ b/tools/testing/selftests/arm64/fp/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 CFLAGS += -I../../../../../usr/include/ -TEST_GEN_PROGS := sve-ptrace sve-probe-vls +TEST_GEN_PROGS := sve-ptrace sve-probe-vls vec-syscfg TEST_PROGS_EXTENDED := fpsimd-test fpsimd-stress \ rdvl-sve \ sve-test sve-stress \ @@ -16,6 +16,7 @@ sve-ptrace: sve-ptrace.o sve-ptrace-asm.o sve-probe-vls: sve-probe-vls.o rdvl.o sve-test: sve-test.o $(CC) -nostdlib $^ -o $@ +vec-syscfg: vec-syscfg.o rdvl.o vlset: vlset.o include ../../lib.mk diff --git a/tools/testing/selftests/arm64/fp/vec-syscfg.c b/tools/testing/selftests/arm64/fp/vec-syscfg.c new file mode 100644 index 000000000000..63d080537d21 --- /dev/null +++ b/tools/testing/selftests/arm64/fp/vec-syscfg.c @@ -0,0 +1,580 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2021 ARM Limited. + * Original author: Mark Brown + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../kselftest.h" +#include "rdvl.h" + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) + +#define ARCH_MIN_VL SVE_VL_MIN + +struct vec_data { + const char *name; + unsigned long hwcap_type; + unsigned long hwcap; + const char *rdvl_binary; + int (*rdvl)(void); + + int prctl_get; + int prctl_set; + const char *default_vl_file; + + int default_vl; + int min_vl; + int max_vl; +}; + + +static struct vec_data vec_data[] = { + { + .name = "SVE", + .hwcap_type = AT_HWCAP, + .hwcap = HWCAP_SVE, + .rdvl = rdvl_sve, + .rdvl_binary = "./rdvl-sve", + .prctl_get = PR_SVE_GET_VL, + .prctl_set = PR_SVE_SET_VL, + .default_vl_file = "/proc/sys/abi/sve_default_vector_length", + }, +}; + +/* Start a new process and return the vector length it sees */ +int get_child_rdvl(struct vec_data *data) +{ + FILE *out; + int pipefd[2]; + pid_t pid, child; + int read_vl, ret; + + ret = pipe(pipefd); + if (ret == -1) { + ksft_print_msg("pipe() failed: %d (%s)\n", + errno, strerror(errno)); + return -1; + } + + fflush(stdout); + + child = fork(); + if (child == -1) { + ksft_print_msg("fork() failed: %d (%s)\n", + errno, strerror(errno)); + return -1; + } + + /* Child: put vector length on the pipe */ + if (child == 0) { + /* + * Replace stdout with the pipe, errors to stderr from + * here as kselftest prints to stdout. + */ + ret = dup2(pipefd[1], 1); + if (ret == -1) { + fprintf(stderr, "dup2() %d\n", errno); + exit(EXIT_FAILURE); + } + + /* exec() a new binary which puts the VL on stdout */ + ret = execl(data->rdvl_binary, data->rdvl_binary, NULL); + fprintf(stderr, "execl(%s) failed: %d\n", + data->rdvl_binary, errno, strerror(errno)); + + exit(EXIT_FAILURE); + } + + close(pipefd[1]); + + /* Parent; wait for the exit status from the child & verify it */ + while (1) { + pid = wait(&ret); + if (pid == -1) { + ksft_print_msg("wait() failed: %d (%s)\n", + errno, strerror(errno)); + return -1; + } + + if (pid != child) + continue; + + if (!WIFEXITED(ret)) { + ksft_print_msg("child exited abnormally\n"); + return -1; + } + + if (WEXITSTATUS(ret) != 0) { + ksft_print_msg("child returned error %d\n", + WEXITSTATUS(ret)); + return -1; + } + + out = fdopen(pipefd[0], "r"); + if (!out) { + ksft_print_msg("failed to open child stdout\n"); + return -1; + } + + ret = fscanf(out, "%d", &read_vl); + fclose(out); + if (ret != 1) { + ksft_print_msg("failed to parse VL from '%s'\n", + data->rdvl_binary); + return -1; + } + + return read_vl; + } +} + +int file_read_integer(const char *name, int *val) +{ + FILE *f; + int ret; + + f = fopen(name, "r"); + if (!f) { + ksft_test_result_fail("Unable to open %s: %d (%s)\n", + name, errno, + strerror(errno)); + return -1; + } + + ret = fscanf(f, "%d", val); + fclose(f); + if (ret != 1) { + ksft_test_result_fail("Failed to parse %s\n", name); + return -1; + } + + return 0; +} + +int file_write_integer(const char *name, int val) +{ + FILE *f; + int ret; + + f = fopen(name, "w"); + if (!f) { + ksft_test_result_fail("Unable to open %s: %d (%s)\n", + name, errno, + strerror(errno)); + return -1; + } + + fprintf(f, "%d", val); + fclose(f); + if (ret < 0) { + ksft_test_result_fail("Error writing %d to %s\n", + val, name); + return -1; + } + + return 0; +} + +/* + * Verify that we can read the default VL via proc, checking that it + * is set in a freshly spawned child. + */ +void proc_read_default(struct vec_data *data) +{ + int default_vl, child_vl, ret; + + ret = file_read_integer(data->default_vl_file, &default_vl); + if (ret != 0) + return; + + /* Is this the actual default seen by new processes? */ + child_vl = get_child_rdvl(data); + if (child_vl != default_vl) { + ksft_test_result_fail("%s is %d but child VL is %d\n", + data->default_vl_file, + default_vl, child_vl); + return; + } + + ksft_test_result_pass("%s default vector length %d\n", data->name, + default_vl); + data->default_vl = default_vl; +} + +/* Verify that we can write a minimum value and have it take effect */ +void proc_write_min(struct vec_data *data) +{ + int ret, new_default, child_vl; + + if (geteuid() != 0) { + ksft_test_result_skip("Need to be root to write to /proc\n"); + return; + } + + ret = file_write_integer(data->default_vl_file, ARCH_MIN_VL); + if (ret != 0) + return; + + /* What was the new value? */ + ret = file_read_integer(data->default_vl_file, &new_default); + if (ret != 0) + return; + + /* Did it take effect in a new process? */ + child_vl = get_child_rdvl(data); + if (child_vl != new_default) { + ksft_test_result_fail("%s is %d but child VL is %d\n", + data->default_vl_file, + new_default, child_vl); + return; + } + + ksft_test_result_pass("%s minimum vector length %d\n", data->name, + new_default); + data->min_vl = new_default; + + file_write_integer(data->default_vl_file, data->default_vl); +} + +/* Verify that we can write a maximum value and have it take effect */ +void proc_write_max(struct vec_data *data) +{ + int ret, new_default, child_vl; + + if (geteuid() != 0) { + ksft_test_result_skip("Need to be root to write to /proc\n"); + return; + } + + /* -1 is accepted by the /proc interface as the maximum VL */ + ret = file_write_integer(data->default_vl_file, -1); + if (ret != 0) + return; + + /* What was the new value? */ + ret = file_read_integer(data->default_vl_file, &new_default); + if (ret != 0) + return; + + /* Did it take effect in a new process? */ + child_vl = get_child_rdvl(data); + if (child_vl != new_default) { + ksft_test_result_fail("%s is %d but child VL is %d\n", + data->default_vl_file, + new_default, child_vl); + return; + } + + ksft_test_result_pass("%s maximum vector length %d\n", data->name, + new_default); + data->max_vl = new_default; + + file_write_integer(data->default_vl_file, data->default_vl); +} + +/* Can we read back a VL from prctl? */ +void prctl_get(struct vec_data *data) +{ + int ret; + + ret = prctl(data->prctl_get); + if (ret == -1) { + ksft_test_result_fail("%s prctl() read failed: %d (%s)\n", + data->name, errno, strerror(errno)); + return; + } + + /* Mask out any flags */ + ret &= PR_SVE_VL_LEN_MASK; + + /* Is that what we can read back directly? */ + if (ret == data->rdvl()) + ksft_test_result_pass("%s current VL is %d\n", + data->name, ret); + else + ksft_test_result_fail("%s prctl() VL %d but RDVL is %d\n", + data->name, ret, data->rdvl()); +} + +/* Does the prctl let us set the VL we already have? */ +void prctl_set_same(struct vec_data *data) +{ + int cur_vl = data->rdvl(); + int ret; + + ret = prctl(data->prctl_set, cur_vl); + if (ret < 0) { + ksft_test_result_fail("%s prctl set failed: %d (%s)\n", + data->name, errno, strerror(errno)); + return; + } + + if (cur_vl != data->rdvl()) + ksft_test_result_pass("%s current VL is %d\n", + data->name, ret); + else + ksft_test_result_fail("%s prctl() VL %d but RDVL is %d\n", + data->name, ret, data->rdvl()); +} + +/* Can we set a new VL for this process? */ +void prctl_set(struct vec_data *data) +{ + int ret; + + if (data->min_vl == data->max_vl) { + ksft_test_result_skip("%s only one VL supported\n", + data->name); + return; + } + + /* Try to set the minimum VL */ + ret = prctl(data->prctl_set, data->min_vl); + if (ret < 0) { + ksft_test_result_fail("%s prctl set failed for %d: %d (%s)\n", + data->name, data->min_vl, + errno, strerror(errno)); + return; + } + + if ((ret & PR_SVE_VL_LEN_MASK) != data->min_vl) { + ksft_test_result_fail("%s prctl set %d but return value is %d\n", + data->name, data->min_vl, data->rdvl()); + return; + } + + if (data->rdvl() != data->min_vl) { + ksft_test_result_fail("%s set %d but RDVL is %d\n", + data->name, data->min_vl, data->rdvl()); + return; + } + + /* Try to set the maximum VL */ + ret = prctl(data->prctl_set, data->max_vl); + if (ret < 0) { + ksft_test_result_fail("%s prctl set failed for %d: %d (%s)\n", + data->name, data->max_vl, + errno, strerror(errno)); + return; + } + + if ((ret & PR_SVE_VL_LEN_MASK) != data->max_vl) { + ksft_test_result_fail("%s prctl() set %d but return value is %d\n", + data->name, data->max_vl, data->rdvl()); + return; + } + + /* The _INHERIT flag should not be present when we read the VL */ + ret = prctl(data->prctl_get); + if (ret == -1) { + ksft_test_result_fail("%s prctl() read failed: %d (%s)\n", + data->name, errno, strerror(errno)); + return; + } + + if (ret & PR_SVE_VL_INHERIT) { + ksft_test_result_fail("%s prctl() reports _INHERIT\n", + data->name); + return; + } + + ksft_test_result_pass("%s prctl() set min/max\n", data->name); +} + +/* If we didn't request it a new VL shouldn't affect the child */ +void prctl_set_no_child(struct vec_data *data) +{ + int ret, child_vl; + + if (data->min_vl == data->max_vl) { + ksft_test_result_skip("%s only one VL supported\n", + data->name); + return; + } + + ret = prctl(data->prctl_set, data->min_vl); + if (ret < 0) { + ksft_test_result_fail("%s prctl set failed for %d: %d (%s)\n", + data->name, data->min_vl, + errno, strerror(errno)); + return; + } + + /* Ensure the default VL is different */ + ret = file_write_integer(data->default_vl_file, data->max_vl); + if (ret != 0) + return; + + /* Check that the child has the default we just set */ + child_vl = get_child_rdvl(data); + if (child_vl != data->max_vl) { + ksft_test_result_fail("%s is %d but child VL is %d\n", + data->default_vl_file, + data->max_vl, child_vl); + return; + } + + ksft_test_result_pass("%s vector length used default\n", data->name); + + file_write_integer(data->default_vl_file, data->default_vl); +} + +/* If we didn't request it a new VL shouldn't affect the child */ +void prctl_set_for_child(struct vec_data *data) +{ + int ret, child_vl; + + if (data->min_vl == data->max_vl) { + ksft_test_result_skip("%s only one VL supported\n", + data->name); + return; + } + + ret = prctl(data->prctl_set, data->min_vl | PR_SVE_VL_INHERIT); + if (ret < 0) { + ksft_test_result_fail("%s prctl set failed for %d: %d (%s)\n", + data->name, data->min_vl, + errno, strerror(errno)); + return; + } + + /* The _INHERIT flag should be present when we read the VL */ + ret = prctl(data->prctl_get); + if (ret == -1) { + ksft_test_result_fail("%s prctl() read failed: %d (%s)\n", + data->name, errno, strerror(errno)); + return; + } + if (!(ret & PR_SVE_VL_INHERIT)) { + ksft_test_result_fail("%s prctl() does not report _INHERIT\n", + data->name); + return; + } + + /* Ensure the default VL is different */ + ret = file_write_integer(data->default_vl_file, data->max_vl); + if (ret != 0) + return; + + /* Check that the child inherited our VL */ + child_vl = get_child_rdvl(data); + if (child_vl != data->min_vl) { + ksft_test_result_fail("%s is %d but child VL is %d\n", + data->default_vl_file, + data->min_vl, child_vl); + return; + } + + ksft_test_result_pass("%s vector length was inherited\n", data->name); + + file_write_integer(data->default_vl_file, data->default_vl); +} + +/* _ONEXEC takes effect only in the child process */ +void prctl_set_onexec(struct vec_data *data) +{ + int ret, child_vl; + + if (data->min_vl == data->max_vl) { + ksft_test_result_skip("%s only one VL supported\n", + data->name); + return; + } + + /* Set a known value for the default and our current VL */ + ret = file_write_integer(data->default_vl_file, data->max_vl); + if (ret != 0) + return; + + ret = prctl(data->prctl_set, data->max_vl); + if (ret < 0) { + ksft_test_result_fail("%s prctl set failed for %d: %d (%s)\n", + data->name, data->min_vl, + errno, strerror(errno)); + return; + } + + /* Set a different value for the child to have on exec */ + ret = prctl(data->prctl_set, data->min_vl | PR_SVE_SET_VL_ONEXEC); + if (ret < 0) { + ksft_test_result_fail("%s prctl set failed for %d: %d (%s)\n", + data->name, data->min_vl, + errno, strerror(errno)); + return; + } + + /* Our current VL should stay the same */ + if (data->rdvl() != data->max_vl) { + ksft_test_result_fail("%s VL changed by _ONEXEC prctl()\n", + data->name); + return; + } + + /* Check that the child inherited our VL */ + child_vl = get_child_rdvl(data); + if (child_vl != data->min_vl) { + ksft_test_result_fail("%s is %d but child VL is %d\n", + data->default_vl_file, + data->min_vl, child_vl); + return; + } + + ksft_test_result_pass("%s vector length set on exec\n", data->name); + + file_write_integer(data->default_vl_file, data->default_vl); +} + +typedef void (*test_type)(struct vec_data *); + +test_type tests[] = { + /* + * The default/min/max tests must be first and in this order + * to provide data for other tests. + */ + proc_read_default, + proc_write_min, + proc_write_max, + + prctl_get, + prctl_set, + prctl_set_no_child, + prctl_set_for_child, + prctl_set_onexec, +}; + +int main(void) +{ + int i, j; + + ksft_print_header(); + ksft_set_plan(ARRAY_SIZE(tests) * ARRAY_SIZE(vec_data)); + + for (i = 0; i < ARRAY_SIZE(vec_data); i++) { + struct vec_data *data = &vec_data[i]; + int supported = getauxval(data->hwcap_type) & data->hwcap; + + for (j = 0; j < ARRAY_SIZE(tests); j++) { + if (supported) + tests[j](data); + else + ksft_test_result_skip("%s not supported\n", + data->name); + } + } + + ksft_exit_pass(); +} From patchwork Wed Jul 28 16:33:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 12406349 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.7 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BF9EBC4338F for ; Wed, 28 Jul 2021 16:34:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A339A6101B for ; Wed, 28 Jul 2021 16:34:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229693AbhG1QeU (ORCPT ); Wed, 28 Jul 2021 12:34:20 -0400 Received: from mail.kernel.org ([198.145.29.99]:37668 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229591AbhG1QeT (ORCPT ); Wed, 28 Jul 2021 12:34:19 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 7416D60F23; Wed, 28 Jul 2021 16:34:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1627490058; bh=V33Ijhd+xG+OltrEOSfLIQyuHzAL4taRF9kOtS+AXUU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rNllgp2x6keKy5lkCWPCMBkFuGPNLW45u4DrEojxj5dJULeWZlBudYyxbqNieDhQN D8aIC4ilZHprkhDmdns3F5Lfvc75YTzKokTBZEZYijum6DZB6srZIl6oN/S6+OzH3Q CbSN9LjydMfL5xbme5wj44mG2ZolAf+hhfAheOwiXdAtg+X8ZyIN3XNWLhErb/5ef8 NOP19tYmdaCcZf5ibRp+ZlboAoJxpdtPGUOCFaE6tCCC5a5x+WvDV97itWgnc9wOjW fqDvYIwnLYyglzEWvaA8O2HYAFOEHyAX1X3dJi5X+FsjPDT42elz6b/9FBCdwZduF8 YgmYHzxxqXrUA== From: Mark Brown To: Catalin Marinas , Will Deacon , Shuah Khan Cc: Dave Martin , linux-arm-kernel@lists.infradead.org, linux-kselftest@vger.kernel.org, Mark Brown Subject: [PATCH v2 4/4] kselftest/arm64: Add a TODO list for floating point tests Date: Wed, 28 Jul 2021 17:33:18 +0100 Message-Id: <20210728163318.51492-5-broonie@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210728163318.51492-1-broonie@kernel.org> References: <20210728163318.51492-1-broonie@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=681; h=from:subject; bh=V33Ijhd+xG+OltrEOSfLIQyuHzAL4taRF9kOtS+AXUU=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBhAYbLsZx68yAmc02VZ8d6xESMUx5a4KdjiVxwqGGD VtKCJjCJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCYQGGywAKCRAk1otyXVSH0EfaB/ 9esyb3f9tcHVvoUjq4YtJcgY8QEfdIjiV+3cT94W3eRmkp7JCYKvASDQBXzGj3pGWVshEYzzqHPBAq JBN2RSGq0x7jf6bnK2qDtq73e8ZfaQhjYRhPMqo8UBcBu/v1oZGbyWWAT2YH6q8sOCYw8ys82PeWM8 c+8wOM1iqswInsNSSN6fPP8ktjjxUWbwSmdIvOyoOo3ZQxZiki3i/z7y0BvOAj6EnTuLTdkkkG912Y fvb1jbbp0Q9EfQUGvYBsxjhrWtdhkH5YDcg19keEcmfjp3OjyblfHfxrDMh0G/ebY6YLYzBowHxgdq +NwWDcjuCWtecCWNaG25dR7eWQHP8J X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org Write down some ideas for additional coverage for floating point in case someone feels inspired to look into them. Signed-off-by: Mark Brown Reviewed-by: Dave Martin --- tools/testing/selftests/arm64/fp/TODO | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 tools/testing/selftests/arm64/fp/TODO diff --git a/tools/testing/selftests/arm64/fp/TODO b/tools/testing/selftests/arm64/fp/TODO new file mode 100644 index 000000000000..eada915227cf --- /dev/null +++ b/tools/testing/selftests/arm64/fp/TODO @@ -0,0 +1,3 @@ +- Test unsupported values in the ABIs +- More coverage for ptrace (eg, vector length conversions). +- Coverage for signals.