From patchwork Tue Aug 3 14:04:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 12416435 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 2E4DFC432BE for ; Tue, 3 Aug 2021 14:07:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0A60E60FC2 for ; Tue, 3 Aug 2021 14:07:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236412AbhHCOHP (ORCPT ); Tue, 3 Aug 2021 10:07:15 -0400 Received: from mail.kernel.org ([198.145.29.99]:45934 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236045AbhHCOHP (ORCPT ); Tue, 3 Aug 2021 10:07:15 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id A033560F58; Tue, 3 Aug 2021 14:07:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1627999624; bh=CdGB4OG/NflCYBfXLsaKyb4ZgSAIM7cHqA6soZ5TczM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DZAhL0lhMdOqPuhfqFJHm3YdHK4fZBPYMZkj4rmwIKJ+izfLJMzu3AqRLy18x/UEQ /HA0wO4QkSIfqpYpHEQ6fa1kzDKCg/1s094CpHBX09ahOZjKBPvKGsLdvnsdYXAuEO ckxv+AHzXUdTjYBz/AOpWirtfR7xdqaJ/DJn06oBHWWNfvcNaxajt4Sd55P6N1baAv r4PptcjzYGswwXnxX/GqB45Z5e0q8bCICw2C9TM8AUhrvR143agcGSdBbFUQxsUeqw qZUo9jTQ+YWuOPvvMMAvUFf9IjbkBLkQKY7VFJzUlsP+A4wJCIu0ph4MzVBC/rIpYb mzyPhQkilS0jg== 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 v5 1/4] kselftest/arm64: Provide a helper binary and "library" for SVE RDVL Date: Tue, 3 Aug 2021 15:04:47 +0100 Message-Id: <20210803140450.46624-2-broonie@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210803140450.46624-1-broonie@kernel.org> References: <20210803140450.46624-1-broonie@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=3762; h=from:subject; bh=CdGB4OG/NflCYBfXLsaKyb4ZgSAIM7cHqA6soZ5TczM=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBhCUz+oc07YHrsOh1K2NDPohsDGoEt9Zt9fNhL16wI 3/ocqPOJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCYQlM/gAKCRAk1otyXVSH0HsPB/ 9Rs0XhQPDNJzZfvm1QLSriYUIJODU/HJz4lREPzuB2LvrBJzf++WiUAzQA6BcKvdV7WZ1CygkCxLLD Gw+hejl1/TClEZQ7VOMg93o65dS1ftAJEwdUFvHBIC8ugMoYNGeF/dFFbDDP3Y2NzzVPWfy3WrgCN+ Ho9Y0RnjqvU8fnC6HpLL9spP3yvAHNCUghM+2kFWfaJy8u4bfGlVwq1BGF951HsCEiu8UOUbP85toV U5kD+0BcIE91nPAPt8KO524zn79bS0MO3K+NqKOweFnVv4yUuqJ2EnSXVo8sp2vfs1Ca+0uCpOIgan So5Xo3dmTIfVKZl2ccKvMv9UAmwHwm 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 | 10 ++++++++++ tools/testing/selftests/arm64/fp/rdvl.h | 8 ++++++++ 5 files changed, 38 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..c916c1c9defd --- /dev/null +++ b/tools/testing/selftests/arm64/fp/rdvl.S @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (C) 2021 ARM Limited. + +.arch_extension sve + +.globl rdvl_sve +rdvl_sve: + hint 34 // BTI C + 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 Tue Aug 3 14:04:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 12416437 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 CC27EC4338F for ; Tue, 3 Aug 2021 14:07:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AE26560FA0 for ; Tue, 3 Aug 2021 14:07:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236421AbhHCOHS (ORCPT ); Tue, 3 Aug 2021 10:07:18 -0400 Received: from mail.kernel.org ([198.145.29.99]:45982 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236045AbhHCOHR (ORCPT ); Tue, 3 Aug 2021 10:07:17 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 5938660EE7; Tue, 3 Aug 2021 14:07:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1627999626; bh=EKvkyVbCFIkHGIl1Aft6XfS6vxY/FRzv+NjTpqSFwTM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Ooq1d1wq9OpuQC5QvktC8CdDA8/IqoX2jf25b4/phsUanbnSW4cgv115hVzMqlnOG 4T167GiFTkYtgJwn6OWIEGnSnO4RfRIm1NDiuUQ7if9SqwNUyJw0XLRJo3tXr2kuyv NiA5bY/zi8ZVMRuo1vewlp+4Yz6xZLbmUBXmnQcuCbKSpRJJstdAzKr407xx7wfRAN EMntfHkAFII2dvssLPImOCmaWCaWithAu2bJiClxwpCzi1sKvbk1StiG9YleNouL4J dLr32Eglhbhjb4B9No6/ySU8BqoBQ1XkMZTKqFWRcVySFcmO/AG/Y5Da1ShqsT1Lsg LlNnSqiA2dgYA== 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 v5 2/4] kselftest/arm64: Validate vector lengths are set in sve-probe-vls Date: Tue, 3 Aug 2021 15:04:48 +0100 Message-Id: <20210803140450.46624-3-broonie@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210803140450.46624-1-broonie@kernel.org> References: <20210803140450.46624-1-broonie@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=1733; h=from:subject; bh=EKvkyVbCFIkHGIl1Aft6XfS6vxY/FRzv+NjTpqSFwTM=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBhCUz+yb4Ch9ouisizN+OUT44lVwHjZYwPWcERArhr KSPtigSJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCYQlM/gAKCRAk1otyXVSH0LJZB/ 9Z5f4wgiwSMPzOIt5LyYqJU+yMz7rCb0HOEABAfK/dBg8ouHLEBXTg4pWpsHqCZCxQwYYI0IQe6o16 BpA5VpOiGKsHC0/Bbu+pEFbf5W7aTCGHr2aHtuWFBRrPvgx/5gNSHIUkLwNwvNWky9avYVXeeYRqwy UcUcOsQUK7l4vIQ/e+rVPYqfG2cgnb041Y5GWo38+hSa7wY4K+EdghNze5598ZH7FS2kL+GFxo3yTn neRAT7Bn2GAgAyxSfi3s/3DNea6VnFPrX2Fj0ieePKfUFS3livhrSPQe+i/4W0n4Www/0Fnt8tLn6I prTA+iao5xdsPtO5wO7MUEWYhSlTKF 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 Tue Aug 3 14:04:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 12416439 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 C9895C4320A for ; Tue, 3 Aug 2021 14:07:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id ADF9160EE7 for ; Tue, 3 Aug 2021 14:07:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236501AbhHCOHV (ORCPT ); Tue, 3 Aug 2021 10:07:21 -0400 Received: from mail.kernel.org ([198.145.29.99]:46040 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236506AbhHCOHU (ORCPT ); Tue, 3 Aug 2021 10:07:20 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id DB7CA60F58; Tue, 3 Aug 2021 14:07:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1627999629; bh=vUki7JpvO0satyYvlCRxQEkFKABdY2bN8GBJV5TGxas=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tGCn+iP4izoTqSYy0zNcKOrLIL1qH+gRtHtYvusChEu723M1A9J4AC24daDZrF3wW 7uesJID8X+60NhhA61YERFrQ0LxKll6B7WENGYU7BmyrwGGKHDOBY1G5U7239K3aGK PEBsiMKJ74NyidBhGIhLWbwGSUmn5Jkpuw8nStq390TxsW0/aIkeR9UJVBy9VJggOh 9Tk6nbRxrKJRE9sBb7p1k20qdyH4Yz5bwRfxJNgojARpZdlJmMdJcMtydqYtV/0v3P 07f8MSn9xjgwWS88nXeoVktdaFLX2sKboVg8dfbPCZUMKl/svM5KZO/Kt8mvfiVTRs Y8BPP0JETDkrg== 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 v5 3/4] kselftest/arm64: Add tests for SVE vector configuration Date: Tue, 3 Aug 2021 15:04:49 +0100 Message-Id: <20210803140450.46624-4-broonie@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210803140450.46624-1-broonie@kernel.org> References: <20210803140450.46624-1-broonie@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=17623; h=from:subject; bh=vUki7JpvO0satyYvlCRxQEkFKABdY2bN8GBJV5TGxas=; b=owGbwMvMwMWocq27KDak/QLjabUkhkROn/+MIftirv6bpxNayRRxz7R+PheL5bq/Xz+lat6N9ZVW Ew/tZDRmYWDkYpAVU2RZ+yxjVXq4xNb5j+a/ghnEygQyhYGLUwAmsluC/X9C2K7e+qVG7XIVW0X2Kz xZNjHXW6V9Zknkz1y18JYNgqpx+pLsf8JiE/pyply05XnJevPJ77jS5TdWMBwRnZiZWrPW1fvx9sPK 3FW5jX8CXm+Yu+vOU3WhWOekayxOmnuUF3PE/wpmfbr38uVC3iOXHAqLazeEzE96VVEjqWZZ7lkamd d45Ndpr37vB1LfDbQ9pBZcVheYeyph5v6E6+kHuvsfi9foRqqnmt7/c/xyv2h6FaPXbBumpZsZZ+/f YHM76Midi0bFsjG+b7cr3PwWH/B4a6/OLKH4bYEBL1JbbadLq9SW3J86jUPCep71nkO968uYgpfx7p 33mc96XZV0Y2X6DgVn3VvbDD3jAA== 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 Reviewed-by: Dave Martin --- tools/testing/selftests/arm64/fp/.gitignore | 1 + tools/testing/selftests/arm64/fp/Makefile | 3 +- tools/testing/selftests/arm64/fp/vec-syscfg.c | 593 ++++++++++++++++++ 3 files changed, 596 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..c02071dcb563 --- /dev/null +++ b/tools/testing/selftests/arm64/fp/vec-syscfg.c @@ -0,0 +1,593 @@ +// 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", + }, +}; + +static int stdio_read_integer(FILE *f, const char *what, int *val) +{ + int n = 0; + int ret; + + ret = fscanf(f, "%d%*1[\n]%n", val, &n); + if (ret < 1 || n < 1) { + ksft_print_msg("failed to parse integer from %s\n", what); + return -1; + } + + return 0; +} + +/* Start a new process and return the vector length it sees */ +static 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)); + close(pipefd[0]); + close(pipefd[1]); + 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 */ + do { + pid = wait(&ret); + if (pid == -1) { + ksft_print_msg("wait() failed: %d (%s)\n", + errno, strerror(errno)); + close(pipefd[0]); + return -1; + } + } while (pid != child); + + assert(pid == child); + + if (!WIFEXITED(ret)) { + ksft_print_msg("child exited abnormally\n"); + close(pipefd[0]); + return -1; + } + + if (WEXITSTATUS(ret) != 0) { + ksft_print_msg("child returned error %d\n", + WEXITSTATUS(ret)); + close(pipefd[0]); + return -1; + } + + out = fdopen(pipefd[0], "r"); + if (!out) { + ksft_print_msg("failed to open child stdout\n"); + close(pipefd[0]); + return -1; + } + + ret = stdio_read_integer(out, "child", &read_vl); + fclose(out); + if (ret != 0) + return ret; + + return read_vl; +} + +static 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 = stdio_read_integer(f, name, val); + fclose(f); + + return ret; +} + +static 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. + */ +static 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 */ +static 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 */ +static 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? */ +static 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? */ +static 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? */ +static 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 */ +static 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 */ +static 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 */ +static 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("Set %d _ONEXEC but child VL is %d\n", + 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 *); + +static const 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]; + unsigned long supported; + + 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 Tue Aug 3 14:04:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 12416441 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 22313C432BE for ; Tue, 3 Aug 2021 14:07:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 088D860F58 for ; Tue, 3 Aug 2021 14:07:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236523AbhHCOHX (ORCPT ); Tue, 3 Aug 2021 10:07:23 -0400 Received: from mail.kernel.org ([198.145.29.99]:46122 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236514AbhHCOHX (ORCPT ); Tue, 3 Aug 2021 10:07:23 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 9C5096109F; Tue, 3 Aug 2021 14:07:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1627999632; bh=ckFb0XkUcQ+z5yIZsL4be9ZuCeRo+R3uqsj85+boQZI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=l34lfKH9fpS7PxH+XsgEEiZSM69TnHlXHEmQels620+55P7crJSJSBmKJt0fxPvv6 x5HNHdP4z0EU90kyml0QC19ta+Qjr96z/52kjE6O4dMD4WEvj+mEmwst+fMVoYmvSS gn2RcqC2H09NoW2HnGWrCf751sfB3clyXkwMaYMVfGZ0954WFFIg4fZMex4qId9Rxj L7By35MKljKwrMdJBqbauQm8BEsJAPRh+SZtgxz7fLbXbYp71BmjDJ47pci3NqLgzc kIKCbAFYthSDoTzJp/gZVseF/1jzt1c/bXMyOOCFVRSNR25otZ7LyN8dvm7+MHxQlk mc6XclNU/7J3Q== 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 v5 4/4] kselftest/arm64: Add a TODO list for floating point tests Date: Tue, 3 Aug 2021 15:04:50 +0100 Message-Id: <20210803140450.46624-5-broonie@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210803140450.46624-1-broonie@kernel.org> References: <20210803140450.46624-1-broonie@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=780; h=from:subject; bh=ckFb0XkUcQ+z5yIZsL4be9ZuCeRo+R3uqsj85+boQZI=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBhCU0A/AIZFwsJX5MFEL+yg9uGqFdyidL53LVC2BC0 pdprvxSJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCYQlNAAAKCRAk1otyXVSH0EUyB/ 9pxh8auFgRWSXooaQdP2MvpGhj+bj8THiDhmHxjEqAgMzegtJ9OoWQH3hgpH7IkXD15/uuRP8lutLn jICOYLzODPsC6HEyJMzOqCrsefLd/tsvKTLkukiJVfRWVin4fJVtfwvb/q5hb8UVl1o176rzSk3v9B tC9EIS3dFKXggIA6R1tM+CTzICjqWYq/uUKIsmHtqn0d7y4Ap0+O0BxHZCo2R4oNDAxQuCvk2CS7J+ C+muLcov3zYsjItV1sIV6EG7rxMrD+U7q3Kqzisn4O2SbV1fdosOUAN23C34xoqUzzpNPSTNPgmtCj ZVZoxNlQtLwap0fJ1IyJA5iAyNpuMl 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 | 4 ++++ 1 file changed, 4 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..b6b7ebfcf362 --- /dev/null +++ b/tools/testing/selftests/arm64/fp/TODO @@ -0,0 +1,4 @@ +- Test unsupported values in the ABIs. +- More coverage for ptrace (eg, vector length conversions). +- Coverage for signals. +- Test PR_SVE_VL_INHERITY after a double fork.