From nobody Fri Dec 19 12:14:49 2025 Received: from mail-pf1-f176.google.com (mail-pf1-f176.google.com [209.85.210.176]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 98F0D13D2B5 for ; Wed, 3 Jul 2024 05:57:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.176 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719986242; cv=none; b=J71FCR7pI90WBFwF1znl4KtE1EM3a3ctO/2/3aQ21ZzAg3JzrBXHzxOjOWWbjbh/GAj4oO11Rk9IK8a/kcvfm9hQodLROCq1JU8I7bF9xDZ5oRY6kznoWqUDdNa6s2eLE7xyECGczVd/EDSkB+Drt5uxo63H4HOFhICNQIp0bRE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719986242; c=relaxed/simple; bh=jzH/9y8d7HpBSeuVnCS+9H12uNYWluVUbxgd6rp+TH4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=WgsrJXoAdlYBr8RduxEVVuJmgg9PtzAD/R7jnxTRWdYvMBGpDWbNiXY6Y2LcGHzo5/Xz3o2mY9cFUFyGjp1fZZB0g/ULaCMCfJt0bGN21faFtWOzcS4DzwQWBJxrD2g0I4/4VU7MQXaq2iciWRuTT1N0CVTakI0teQha6GifwFM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rivosinc.com; spf=pass smtp.mailfrom=rivosinc.com; dkim=pass (2048-bit key) header.d=rivosinc-com.20230601.gappssmtp.com header.i=@rivosinc-com.20230601.gappssmtp.com header.b=yZ6946o5; arc=none smtp.client-ip=209.85.210.176 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rivosinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rivosinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=rivosinc-com.20230601.gappssmtp.com header.i=@rivosinc-com.20230601.gappssmtp.com header.b="yZ6946o5" Received: by mail-pf1-f176.google.com with SMTP id d2e1a72fcca58-7066f68e22cso3460186b3a.2 for ; Tue, 02 Jul 2024 22:57:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1719986240; x=1720591040; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=whnKjWwZlEAm2Tk1WNNpUsvcMFmVvQvxiY5eIxqDPb4=; b=yZ6946o5Kkq20QPHTPN0LwWdhUFtHNafx2W75MBtBUZY0H/D2cbvzVPJ50of12a9a4 3A0J8rA7HksJpZ+yY8n3z0SaT+PIr8ltOvO3Zkb/f82qUW6emli6GKdMk48HeSS7F7pu NJcIbwW4I5VJrtNEFuk9EHoWCFGIiQulCzDK/+K8KVmcxzreQmL/mz9GTNjyT88q6r6R TY5wkDFPokFwqqA11bzyY2w7pzFOu5m0Owxz2IgBeT96mgCaYqMRPqfoxE3g74vv8uQj bqMDDIcMAeJRpGkTdcT5seTlhVelaLx554bumJRdFLiJHzetfnNA6vVAAnUF1lbo1hrb yAvg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719986240; x=1720591040; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=whnKjWwZlEAm2Tk1WNNpUsvcMFmVvQvxiY5eIxqDPb4=; b=jxfKOIWHfDTXsaSMc8Bw1UrD9811kmM9Z16PXJmnrS3UWZa7Nwc4nmgBHNojoPmrJF Usd983DXYZnfjvCKNWJ1ou3oUdP1sAqkzpHMI9UqLdKJ7gohy8lUhJPiRAYG1cpiek9R uQSzgjdT2vqe8wOxL4nLP4YPQu6PWhuZHqT9UhbIq7kK4ZvyldUksZKJexFgjw8S6hV3 ncElI41t0JNKyYLMARD013ONyfmbD5Sz1WPfwNtdsXWuTF92RQSE92Mf/VljI0TlBOEm LJA+MTsod82g+Ys3ougbaDjyozoYP65uIyHKSdyzyGe9mZpxPN+kEioikLNJ6EfAEy+8 CBAA== X-Forwarded-Encrypted: i=1; AJvYcCVQVnBUe7DFw7PdDy5PajIA3qA6Z/jYXiJAR3Nxi/gg573vRPSyG5Bj466ktjrmqeatHEvCzBPYkqyHyPp3+krh6VkwuXQA6EYHWqjx X-Gm-Message-State: AOJu0YwMKyGzFDBNxkkawMba2zDedwFlv/s+ywR9prr6UsokZJ/lm+KV bTT0KUd9GBOeqyjRJdPzdiz8bvOcqrixgttRpOOpCti3VsmlOWvhFcLqOW+03L8= X-Google-Smtp-Source: AGHT+IH9WpiTU8Y0rAlB/18A+njEfv/sus3pIGwuKKdj/itIdusf2Vz5ppeEPEgECieEomWb6fabvw== X-Received: by 2002:a05:6a00:1881:b0:706:6ad6:1866 with SMTP id d2e1a72fcca58-70aaaf518e6mr10370810b3a.30.1719986239687; Tue, 02 Jul 2024 22:57:19 -0700 (PDT) Received: from charlie.ba.rivosinc.com ([64.71.180.162]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-70804a89fc9sm9514103b3a.212.2024.07.02.22.57.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 02 Jul 2024 22:57:18 -0700 (PDT) From: Charlie Jenkins Date: Tue, 02 Jul 2024 22:56:32 -0700 Subject: [PATCH v4 12/13] selftests: riscv: Fix vector tests Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240702-xtheadvector-v4-12-2bad6820db11@rivosinc.com> References: <20240702-xtheadvector-v4-0-2bad6820db11@rivosinc.com> In-Reply-To: <20240702-xtheadvector-v4-0-2bad6820db11@rivosinc.com> To: Conor Dooley , Rob Herring , Krzysztof Kozlowski , Paul Walmsley , Palmer Dabbelt , Albert Ou , Jisheng Zhang , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Samuel Holland , Jonathan Corbet , Shuah Khan , Guo Ren , Evan Green , Andy Chiu , Jessica Clarke Cc: linux-riscv@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-sunxi@lists.linux.dev, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Charlie Jenkins X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1719986213; l=19626; i=charlie@rivosinc.com; s=20231120; h=from:subject:message-id; bh=jzH/9y8d7HpBSeuVnCS+9H12uNYWluVUbxgd6rp+TH4=; b=5iE3AmKmM+LwUODVnRcYgarkQzVYVpxdqCgB2XDeQjt6/8NWcFLKLBVZnqmcg6Wq/wW+5x7Fu VHhmV4YH0bOAQGeiwjwx4BOPCEZbLrWcloD5H5VvgVk9xR8SCM8P3+e X-Developer-Key: i=charlie@rivosinc.com; a=ed25519; pk=t4RSWpMV1q5lf/NWIeR9z58bcje60/dbtxxmoSfBEcs= Overhaul the riscv vector tests to use kselftest_harness to help the test cases correctly report the results and decouple the individual test cases from each other. With this refactoring, only run the test cases is vector is reported and properly report the test case as skipped otherwise. The v_initval_nolibc test was previously not checking if vector was supported and used a function (malloc) which invalidates the state of the vector registers. Signed-off-by: Charlie Jenkins --- tools/testing/selftests/riscv/vector/.gitignore | 3 +- tools/testing/selftests/riscv/vector/Makefile | 17 +- .../selftests/riscv/vector/v_exec_initval_nolibc.c | 84 +++++++ tools/testing/selftests/riscv/vector/v_helpers.c | 56 +++++ tools/testing/selftests/riscv/vector/v_helpers.h | 5 + tools/testing/selftests/riscv/vector/v_initval.c | 16 ++ .../selftests/riscv/vector/v_initval_nolibc.c | 68 ------ .../testing/selftests/riscv/vector/vstate_prctl.c | 266 ++++++++++++-----= ---- 8 files changed, 324 insertions(+), 191 deletions(-) diff --git a/tools/testing/selftests/riscv/vector/.gitignore b/tools/testin= g/selftests/riscv/vector/.gitignore index 9ae7964491d5..7d9c87cd0649 100644 --- a/tools/testing/selftests/riscv/vector/.gitignore +++ b/tools/testing/selftests/riscv/vector/.gitignore @@ -1,3 +1,4 @@ vstate_exec_nolibc vstate_prctl -v_initval_nolibc +v_initval +v_exec_initval_nolibc diff --git a/tools/testing/selftests/riscv/vector/Makefile b/tools/testing/= selftests/riscv/vector/Makefile index bfff0ff4f3be..995746359477 100644 --- a/tools/testing/selftests/riscv/vector/Makefile +++ b/tools/testing/selftests/riscv/vector/Makefile @@ -2,18 +2,27 @@ # Copyright (C) 2021 ARM Limited # Originally tools/testing/arm64/abi/Makefile =20 -TEST_GEN_PROGS :=3D vstate_prctl v_initval_nolibc -TEST_GEN_PROGS_EXTENDED :=3D vstate_exec_nolibc +TEST_GEN_PROGS :=3D v_initval vstate_prctl +TEST_GEN_PROGS_EXTENDED :=3D vstate_exec_nolibc v_exec_initval_nolibc sys_= hwprobe.o v_helpers.o =20 include ../../lib.mk =20 -$(OUTPUT)/vstate_prctl: vstate_prctl.c ../hwprobe/sys_hwprobe.S +$(OUTPUT)/sys_hwprobe.o: ../hwprobe/sys_hwprobe.S + $(CC) -static -c -o$@ $(CFLAGS) $^ + +$(OUTPUT)/v_helpers.o: v_helpers.c + $(CC) -static -c -o$@ $(CFLAGS) $^ + +$(OUTPUT)/vstate_prctl: vstate_prctl.c $(OUTPUT)/sys_hwprobe.o $(OUTPUT)/v= _helpers.o $(CC) -static -o$@ $(CFLAGS) $(LDFLAGS) $^ =20 $(OUTPUT)/vstate_exec_nolibc: vstate_exec_nolibc.c $(CC) -nostdlib -static -include ../../../../include/nolibc/nolibc.h \ -Wall $(CFLAGS) $(LDFLAGS) $^ -o $@ -lgcc =20 -$(OUTPUT)/v_initval_nolibc: v_initval_nolibc.c +$(OUTPUT)/v_initval: v_initval.c $(OUTPUT)/sys_hwprobe.o $(OUTPUT)/v_helpe= rs.o + $(CC) -static -o$@ $(CFLAGS) $(LDFLAGS) $^ + +$(OUTPUT)/v_exec_initval_nolibc: v_exec_initval_nolibc.c $(CC) -nostdlib -static -include ../../../../include/nolibc/nolibc.h \ -Wall $(CFLAGS) $(LDFLAGS) $^ -o $@ -lgcc diff --git a/tools/testing/selftests/riscv/vector/v_exec_initval_nolibc.c b= /tools/testing/selftests/riscv/vector/v_exec_initval_nolibc.c new file mode 100644 index 000000000000..74b13806baf0 --- /dev/null +++ b/tools/testing/selftests/riscv/vector/v_exec_initval_nolibc.c @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Get values of vector registers as soon as the program starts to test if + * is properly cleaning the values before starting a new program. Vector + * registers are caller saved, so no function calls may happen before read= ing + * the values. To further ensure consistency, this file is compiled without + * libc and without auto-vectorization. + * + * To be "clean" all values must be either all ones or all zeroes. + */ + +#define __stringify_1(x...) #x +#define __stringify(x...) __stringify_1(x) + +int main(int argc, char **argv) +{ + char prev_value =3D 0, value; + unsigned long vl; + int first =3D 1; + + asm volatile ( + ".option push\n\t" + ".option arch, +v\n\t" + "vsetvli %[vl], x0, e8, m1, ta, ma\n\t" + ".option pop\n\t" + : [vl] "=3Dr" (vl) + ); + +#define CHECK_VECTOR_REGISTER(register) ({ \ + for (int i =3D 0; i < vl; i++) { \ + asm volatile ( \ + ".option push\n\t" \ + ".option arch, +v\n\t" \ + "vmv.x.s %0, " __stringify(register) "\n\t" \ + "vsrl.vi " __stringify(register) ", " __stringify(register) ", 8\n\t" \ + ".option pop\n\t" \ + : "=3Dr" (value)); \ + if (first) { \ + first =3D 0; \ + } else if (value !=3D prev_value || !(value =3D=3D 0x00 || value =3D=3D = 0xff)) { \ + printf("Register " __stringify(register) " values not clean! value: %u\= n", value); \ + exit(-1); \ + } \ + prev_value =3D value; \ + } \ +}) + + CHECK_VECTOR_REGISTER(v0); + CHECK_VECTOR_REGISTER(v1); + CHECK_VECTOR_REGISTER(v2); + CHECK_VECTOR_REGISTER(v3); + CHECK_VECTOR_REGISTER(v4); + CHECK_VECTOR_REGISTER(v5); + CHECK_VECTOR_REGISTER(v6); + CHECK_VECTOR_REGISTER(v7); + CHECK_VECTOR_REGISTER(v8); + CHECK_VECTOR_REGISTER(v9); + CHECK_VECTOR_REGISTER(v10); + CHECK_VECTOR_REGISTER(v11); + CHECK_VECTOR_REGISTER(v12); + CHECK_VECTOR_REGISTER(v13); + CHECK_VECTOR_REGISTER(v14); + CHECK_VECTOR_REGISTER(v15); + CHECK_VECTOR_REGISTER(v16); + CHECK_VECTOR_REGISTER(v17); + CHECK_VECTOR_REGISTER(v18); + CHECK_VECTOR_REGISTER(v19); + CHECK_VECTOR_REGISTER(v20); + CHECK_VECTOR_REGISTER(v21); + CHECK_VECTOR_REGISTER(v22); + CHECK_VECTOR_REGISTER(v23); + CHECK_VECTOR_REGISTER(v24); + CHECK_VECTOR_REGISTER(v25); + CHECK_VECTOR_REGISTER(v26); + CHECK_VECTOR_REGISTER(v27); + CHECK_VECTOR_REGISTER(v28); + CHECK_VECTOR_REGISTER(v29); + CHECK_VECTOR_REGISTER(v30); + CHECK_VECTOR_REGISTER(v31); + +#undef CHECK_VECTOR_REGISTER + + return 0; +} diff --git a/tools/testing/selftests/riscv/vector/v_helpers.c b/tools/testi= ng/selftests/riscv/vector/v_helpers.c new file mode 100644 index 000000000000..15c22318db72 --- /dev/null +++ b/tools/testing/selftests/riscv/vector/v_helpers.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include "../hwprobe/hwprobe.h" +#include +#include +#include +#include + +int is_vector_supported(void) +{ + struct riscv_hwprobe pair; + + pair.key =3D RISCV_HWPROBE_KEY_IMA_EXT_0; + riscv_hwprobe(&pair, 1, 0, NULL, 0); + return pair.value & RISCV_HWPROBE_IMA_V; +} + +int launch_test(char *next_program, int test_inherit) +{ + char *exec_argv[3], *exec_envp[1]; + int rc, pid, status; + + pid =3D fork(); + if (pid < 0) { + printf("fork failed %d", pid); + return -1; + } + + if (!pid) { + exec_argv[0] =3D next_program; + exec_argv[1] =3D test_inherit !=3D 0 ? "x" : NULL; + exec_argv[2] =3D NULL; + exec_envp[0] =3D NULL; + /* launch the program again to check inherit */ + rc =3D execve(next_program, exec_argv, exec_envp); + if (rc) { + perror("execve"); + printf("child execve failed %d\n", rc); + exit(-1); + } + } + + rc =3D waitpid(-1, &status, 0); + if (rc < 0) { + printf("waitpid failed\n"); + return -3; + } + + if ((WIFEXITED(status) && WEXITSTATUS(status) =3D=3D -1) || + WIFSIGNALED(status)) { + printf("child exited abnormally\n"); + return -4; + } + + return WEXITSTATUS(status); +} diff --git a/tools/testing/selftests/riscv/vector/v_helpers.h b/tools/testi= ng/selftests/riscv/vector/v_helpers.h new file mode 100644 index 000000000000..88719c4be496 --- /dev/null +++ b/tools/testing/selftests/riscv/vector/v_helpers.h @@ -0,0 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +int is_vector_supported(void); + +int launch_test(char *next_program, int test_inherit); diff --git a/tools/testing/selftests/riscv/vector/v_initval.c b/tools/testi= ng/selftests/riscv/vector/v_initval.c new file mode 100644 index 000000000000..f38b5797fa31 --- /dev/null +++ b/tools/testing/selftests/riscv/vector/v_initval.c @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include "../../kselftest_harness.h" +#include "v_helpers.h" + +#define NEXT_PROGRAM "./v_exec_initval_nolibc" + +TEST(v_initval) +{ + if (!is_vector_supported()) + SKIP(return, "Vector not supported"); + + ASSERT_EQ(0, launch_test(NEXT_PROGRAM, 0)); +} + +TEST_HARNESS_MAIN diff --git a/tools/testing/selftests/riscv/vector/v_initval_nolibc.c b/tool= s/testing/selftests/riscv/vector/v_initval_nolibc.c deleted file mode 100644 index 1dd94197da30..000000000000 --- a/tools/testing/selftests/riscv/vector/v_initval_nolibc.c +++ /dev/null @@ -1,68 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only - -#include "../../kselftest.h" -#define MAX_VSIZE (8192 * 32) - -void dump(char *ptr, int size) -{ - int i =3D 0; - - for (i =3D 0; i < size; i++) { - if (i !=3D 0) { - if (i % 16 =3D=3D 0) - printf("\n"); - else if (i % 8 =3D=3D 0) - printf(" "); - } - printf("%02x ", ptr[i]); - } - printf("\n"); -} - -int main(void) -{ - int i; - unsigned long vl; - char *datap, *tmp; - - datap =3D malloc(MAX_VSIZE); - if (!datap) { - ksft_test_result_fail("fail to allocate memory for size =3D %d\n", MAX_V= SIZE); - exit(-1); - } - - tmp =3D datap; - asm volatile ( - ".option push\n\t" - ".option arch, +v\n\t" - "vsetvli %0, x0, e8, m8, ta, ma\n\t" - "vse8.v v0, (%2)\n\t" - "add %1, %2, %0\n\t" - "vse8.v v8, (%1)\n\t" - "add %1, %1, %0\n\t" - "vse8.v v16, (%1)\n\t" - "add %1, %1, %0\n\t" - "vse8.v v24, (%1)\n\t" - ".option pop\n\t" - : "=3D&r" (vl), "=3Dr" (tmp) : "r" (datap) : "memory"); - - ksft_print_msg("vl =3D %lu\n", vl); - - if (datap[0] !=3D 0x00 && datap[0] !=3D 0xff) { - ksft_test_result_fail("v-regesters are not properly initialized\n"); - dump(datap, vl * 4); - exit(-1); - } - - for (i =3D 1; i < vl * 4; i++) { - if (datap[i] !=3D datap[0]) { - ksft_test_result_fail("detect stale values on v-regesters\n"); - dump(datap, vl * 4); - exit(-2); - } - } - - free(datap); - ksft_exit_pass(); - return 0; -} diff --git a/tools/testing/selftests/riscv/vector/vstate_prctl.c b/tools/te= sting/selftests/riscv/vector/vstate_prctl.c index 27668fb3b6d0..528e8c544db0 100644 --- a/tools/testing/selftests/riscv/vector/vstate_prctl.c +++ b/tools/testing/selftests/riscv/vector/vstate_prctl.c @@ -3,50 +3,13 @@ #include #include #include +#include +#include =20 -#include "../hwprobe/hwprobe.h" -#include "../../kselftest.h" +#include "../../kselftest_harness.h" +#include "v_helpers.h" =20 #define NEXT_PROGRAM "./vstate_exec_nolibc" -static int launch_test(int test_inherit) -{ - char *exec_argv[3], *exec_envp[1]; - int rc, pid, status; - - pid =3D fork(); - if (pid < 0) { - ksft_test_result_fail("fork failed %d", pid); - return -1; - } - - if (!pid) { - exec_argv[0] =3D NEXT_PROGRAM; - exec_argv[1] =3D test_inherit !=3D 0 ? "x" : NULL; - exec_argv[2] =3D NULL; - exec_envp[0] =3D NULL; - /* launch the program again to check inherit */ - rc =3D execve(NEXT_PROGRAM, exec_argv, exec_envp); - if (rc) { - perror("execve"); - ksft_test_result_fail("child execve failed %d\n", rc); - exit(-1); - } - } - - rc =3D waitpid(-1, &status, 0); - if (rc < 0) { - ksft_test_result_fail("waitpid failed\n"); - return -3; - } - - if ((WIFEXITED(status) && WEXITSTATUS(status) =3D=3D -1) || - WIFSIGNALED(status)) { - ksft_test_result_fail("child exited abnormally\n"); - return -4; - } - - return WEXITSTATUS(status); -} =20 int test_and_compare_child(long provided, long expected, int inherit) { @@ -54,14 +17,13 @@ int test_and_compare_child(long provided, long expected= , int inherit) =20 rc =3D prctl(PR_RISCV_V_SET_CONTROL, provided); if (rc !=3D 0) { - ksft_test_result_fail("prctl with provided arg %lx failed with code %d\n= ", - provided, rc); + printf("prctl with provided arg %lx failed with code %d\n", + provided, rc); return -1; } - rc =3D launch_test(inherit); + rc =3D launch_test(NEXT_PROGRAM, inherit); if (rc !=3D expected) { - ksft_test_result_fail("Test failed, check %d !=3D %ld\n", rc, - expected); + printf("Test failed, check %d !=3D %ld\n", rc, expected); return -2; } return 0; @@ -70,112 +32,180 @@ int test_and_compare_child(long provided, long expect= ed, int inherit) #define PR_RISCV_V_VSTATE_CTRL_CUR_SHIFT 0 #define PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT 2 =20 -int main(void) +TEST(get_control_no_v) { - struct riscv_hwprobe pair; - long flag, expected; long rc; =20 - pair.key =3D RISCV_HWPROBE_KEY_IMA_EXT_0; - rc =3D riscv_hwprobe(&pair, 1, 0, NULL, 0); - if (rc < 0) { - ksft_test_result_fail("hwprobe() failed with %ld\n", rc); - return -1; - } + if (is_vector_supported()) + SKIP(return, "Test expects vector to be not supported"); =20 - if (pair.key !=3D RISCV_HWPROBE_KEY_IMA_EXT_0) { - ksft_test_result_fail("hwprobe cannot probe RISCV_HWPROBE_KEY_IMA_EXT_0\= n"); - return -2; - } + rc =3D prctl(PR_RISCV_V_GET_CONTROL); + EXPECT_EQ(-1, rc) TH_LOG("GET_CONTROL should fail on kernel/hw without V"= ); + EXPECT_EQ(EINVAL, errno) TH_LOG("GET_CONTROL should fail on kernel/hw wit= hout V"); +} =20 - if (!(pair.value & RISCV_HWPROBE_IMA_V)) { - rc =3D prctl(PR_RISCV_V_GET_CONTROL); - if (rc !=3D -1 || errno !=3D EINVAL) { - ksft_test_result_fail("GET_CONTROL should fail on kernel/hw without V\n= "); - return -3; - } - - rc =3D prctl(PR_RISCV_V_SET_CONTROL, PR_RISCV_V_VSTATE_CTRL_ON); - if (rc !=3D -1 || errno !=3D EINVAL) { - ksft_test_result_fail("GET_CONTROL should fail on kernel/hw without V\n= "); - return -4; - } - - ksft_test_result_skip("Vector not supported\n"); - return 0; - } +TEST(set_control_no_v) +{ + long rc; + + if (is_vector_supported()) + SKIP(return, "Test expects vector to be not supported"); + + rc =3D prctl(PR_RISCV_V_SET_CONTROL, PR_RISCV_V_VSTATE_CTRL_ON); + EXPECT_EQ(-1, rc) TH_LOG("SET_CONTROL should fail on kernel/hw without V"= ); + EXPECT_EQ(EINVAL, errno) TH_LOG("SET_CONTROL should fail on kernel/hw wit= hout V"); +} + +TEST(vstate_on_current) +{ + long flag; + long rc; + + if (!is_vector_supported()) + SKIP(return, "Vector not supported"); =20 flag =3D PR_RISCV_V_VSTATE_CTRL_ON; rc =3D prctl(PR_RISCV_V_SET_CONTROL, flag); - if (rc !=3D 0) { - ksft_test_result_fail("Enabling V for current should always success\n"); - return -5; - } + EXPECT_EQ(0, rc) TH_LOG("Enabling V for current should always success"); +} + +TEST(vstate_off_eperm) +{ + long flag; + long rc; + + if (!is_vector_supported()) + SKIP(return, "Vector not supported"); =20 flag =3D PR_RISCV_V_VSTATE_CTRL_OFF; rc =3D prctl(PR_RISCV_V_SET_CONTROL, flag); - if (rc !=3D -1 || errno !=3D EPERM) { - ksft_test_result_fail("Disabling current's V alive must fail with EPERM(= %d)\n", - errno); - return -5; - } + EXPECT_EQ(EPERM, errno) TH_LOG("Disabling current's V alive must fail wit= h EPERM(%d)", errno); + EXPECT_EQ(-1, rc) TH_LOG("Disabling current's V alive must fail with EPER= M(%d)", errno); +} + +TEST(vstate_on_no_nesting) +{ + long flag; + + if (!is_vector_supported()) + SKIP(return, "Vector not supported"); =20 /* Turn on next's vector explicitly and test */ flag =3D PR_RISCV_V_VSTATE_CTRL_ON << PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT; - if (test_and_compare_child(flag, PR_RISCV_V_VSTATE_CTRL_ON, 0)) - return -6; + + EXPECT_EQ(0, test_and_compare_child(flag, PR_RISCV_V_VSTATE_CTRL_ON, 0)); +} + +TEST(vstate_off_nesting) +{ + long flag; + + if (!is_vector_supported()) + SKIP(return, "Vector not supported"); =20 /* Turn off next's vector explicitly and test */ flag =3D PR_RISCV_V_VSTATE_CTRL_OFF << PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT; - if (test_and_compare_child(flag, PR_RISCV_V_VSTATE_CTRL_OFF, 0)) - return -7; + + EXPECT_EQ(0, test_and_compare_child(flag, PR_RISCV_V_VSTATE_CTRL_OFF, 1)); +} + +TEST(vstate_on_inherit_no_nesting) +{ + long flag, expected; + + if (!is_vector_supported()) + SKIP(return, "Vector not supported"); + + /* Turn on next's vector explicitly and test no inherit */ + flag =3D PR_RISCV_V_VSTATE_CTRL_ON << PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT; + flag |=3D PR_RISCV_V_VSTATE_CTRL_INHERIT; + expected =3D flag | PR_RISCV_V_VSTATE_CTRL_ON; + + EXPECT_EQ(0, test_and_compare_child(flag, expected, 0)); +} + +TEST(vstate_on_inherit) +{ + long flag, expected; + + if (!is_vector_supported()) + SKIP(return, "Vector not supported"); =20 /* Turn on next's vector explicitly and test inherit */ flag =3D PR_RISCV_V_VSTATE_CTRL_ON << PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT; flag |=3D PR_RISCV_V_VSTATE_CTRL_INHERIT; expected =3D flag | PR_RISCV_V_VSTATE_CTRL_ON; - if (test_and_compare_child(flag, expected, 0)) - return -8; =20 - if (test_and_compare_child(flag, expected, 1)) - return -9; + EXPECT_EQ(0, test_and_compare_child(flag, expected, 1)); +} + +TEST(vstate_off_inherit_no_nesting) +{ + long flag, expected; + + if (!is_vector_supported()) + SKIP(return, "Vector not supported"); + + /* Turn off next's vector explicitly and test no inherit */ + flag =3D PR_RISCV_V_VSTATE_CTRL_OFF << PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT; + flag |=3D PR_RISCV_V_VSTATE_CTRL_INHERIT; + expected =3D flag | PR_RISCV_V_VSTATE_CTRL_OFF; + + EXPECT_EQ(0, test_and_compare_child(flag, expected, 0)); +} + +TEST(vstate_off_inherit) +{ + long flag, expected; + + if (!is_vector_supported()) + SKIP(return, "Vector not supported"); =20 /* Turn off next's vector explicitly and test inherit */ flag =3D PR_RISCV_V_VSTATE_CTRL_OFF << PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT; flag |=3D PR_RISCV_V_VSTATE_CTRL_INHERIT; expected =3D flag | PR_RISCV_V_VSTATE_CTRL_OFF; - if (test_and_compare_child(flag, expected, 0)) - return -10; =20 - if (test_and_compare_child(flag, expected, 1)) - return -11; + EXPECT_EQ(0, test_and_compare_child(flag, expected, 1)); +} + +/* arguments should fail with EINVAL */ +TEST(inval_set_control_1) +{ + int rc; + + if (!is_vector_supported()) + SKIP(return, "Vector not supported"); =20 - /* arguments should fail with EINVAL */ rc =3D prctl(PR_RISCV_V_SET_CONTROL, 0xff0); - if (rc !=3D -1 || errno !=3D EINVAL) { - ksft_test_result_fail("Undefined control argument should return EINVAL\n= "); - return -12; - } + EXPECT_EQ(-1, rc); + EXPECT_EQ(EINVAL, errno); +} + +/* arguments should fail with EINVAL */ +TEST(inval_set_control_2) +{ + int rc; + + if (!is_vector_supported()) + SKIP(return, "Vector not supported"); =20 rc =3D prctl(PR_RISCV_V_SET_CONTROL, 0x3); - if (rc !=3D -1 || errno !=3D EINVAL) { - ksft_test_result_fail("Undefined control argument should return EINVAL\n= "); - return -12; - } + EXPECT_EQ(-1, rc); + EXPECT_EQ(EINVAL, errno); +} =20 - rc =3D prctl(PR_RISCV_V_SET_CONTROL, 0xc); - if (rc !=3D -1 || errno !=3D EINVAL) { - ksft_test_result_fail("Undefined control argument should return EINVAL\n= "); - return -12; - } +/* arguments should fail with EINVAL */ +TEST(inval_set_control_3) +{ + int rc; =20 - rc =3D prctl(PR_RISCV_V_SET_CONTROL, 0xc); - if (rc !=3D -1 || errno !=3D EINVAL) { - ksft_test_result_fail("Undefined control argument should return EINVAL\n= "); - return -12; - } + if (!is_vector_supported()) + SKIP(return, "Vector not supported"); =20 - ksft_test_result_pass("tests for riscv_v_vstate_ctrl pass\n"); - ksft_exit_pass(); - return 0; + rc =3D prctl(PR_RISCV_V_SET_CONTROL, 0xc); + EXPECT_EQ(-1, rc); + EXPECT_EQ(EINVAL, errno); } + +TEST_HARNESS_MAIN --=20 2.44.0