This patch tests the dynamic memory consistency model prctl() behaviour on RISC-V. It does not depend on CONFIG_RISCV_ISA_SSDTSO or the availability of Ssdtso, but will test other aspects if these are not given. Signed-off-by: Christoph Müllner <christoph.muellner@xxxxxxxx> --- tools/testing/selftests/riscv/Makefile | 2 +- tools/testing/selftests/riscv/dtso/.gitignore | 1 + tools/testing/selftests/riscv/dtso/Makefile | 11 +++ tools/testing/selftests/riscv/dtso/dtso.c | 82 +++++++++++++++++++ 4 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/riscv/dtso/.gitignore create mode 100644 tools/testing/selftests/riscv/dtso/Makefile create mode 100644 tools/testing/selftests/riscv/dtso/dtso.c diff --git a/tools/testing/selftests/riscv/Makefile b/tools/testing/selftests/riscv/Makefile index 4a9ff515a3a0..1421c21841f9 100644 --- a/tools/testing/selftests/riscv/Makefile +++ b/tools/testing/selftests/riscv/Makefile @@ -5,7 +5,7 @@ ARCH ?= $(shell uname -m 2>/dev/null || echo not) ifneq (,$(filter $(ARCH),riscv)) -RISCV_SUBTARGETS ?= hwprobe vector mm +RISCV_SUBTARGETS ?= dtso hwprobe vector mm else RISCV_SUBTARGETS := endif diff --git a/tools/testing/selftests/riscv/dtso/.gitignore b/tools/testing/selftests/riscv/dtso/.gitignore new file mode 100644 index 000000000000..217d01679115 --- /dev/null +++ b/tools/testing/selftests/riscv/dtso/.gitignore @@ -0,0 +1 @@ +dtso diff --git a/tools/testing/selftests/riscv/dtso/Makefile b/tools/testing/selftests/riscv/dtso/Makefile new file mode 100644 index 000000000000..a1ffbdd3da85 --- /dev/null +++ b/tools/testing/selftests/riscv/dtso/Makefile @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 VRULL + +CFLAGS += -I$(top_srcdir)/tools/include + +TEST_GEN_PROGS := dtso + +include ../../lib.mk + +$(OUTPUT)/dtso: dtso.c ../hwprobe/sys_hwprobe.S + $(CC) -static -o$@ $(CFLAGS) $(LDFLAGS) $^ diff --git a/tools/testing/selftests/riscv/dtso/dtso.c b/tools/testing/selftests/riscv/dtso/dtso.c new file mode 100644 index 000000000000..c8a7b25adefd --- /dev/null +++ b/tools/testing/selftests/riscv/dtso/dtso.c @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* dtso - used for functional tests of memory consistency model switching + * at run-time. + * + * Copyright (c) 2023 Christoph Muellner <christoph.muellner@xxxxxxxx> + */ + +#include <sys/prctl.h> +#include <unistd.h> +#include <errno.h> + +#include "../hwprobe/hwprobe.h" +#include "../../kselftest_harness.h" + +/* + * We have the following cases: + * 1) DTSO support disabed in the kernel config: + * - Ssdtso is not detected + * - {G,S}ET_MEMORY_CONSISTENCY_MODEL fails with EINVAL + * 2) DTSO support enabled and Ssdtso not available: + * - Ssdtso is not detected + * - {G,S}ET_MEMORY_CONSISTENCY_MODEL works for WMO and fails for TSO with EINVAL: + * 3) DTSO support enabled and Ssdtso available + * - Ssdtso is detected + * - {G,S}ET_MEMORY_CONSISTENCY_MODEL works for WMO and TSO + */ + +TEST(dtso) +{ + struct riscv_hwprobe pair; + int ret; + bool ssdtso_configured; + bool ssdtso_available; + + ret = prctl(PR_GET_MEMORY_CONSISTENCY_MODEL); + if (ret < 0) { + ASSERT_EQ(errno, EINVAL); + ssdtso_configured = false; + } else { + ASSERT_TRUE(ret == PR_MEMORY_CONSISTENCY_MODEL_RISCV_WMO || + ret == PR_MEMORY_CONSISTENCY_MODEL_RISCV_TSO); + ssdtso_configured = true; + } + + pair.key = RISCV_HWPROBE_KEY_IMA_EXT_0; + ret = riscv_hwprobe(&pair, 1, 0, NULL, 0); + ASSERT_GE(ret, 0); + ASSERT_EQ(pair.key, RISCV_HWPROBE_KEY_IMA_EXT_0); + ssdtso_available = !!(pair.value & RISCV_HWPROBE_EXT_SSDTSO); + + if (ssdtso_configured) { + /* Read out current model. */ + ret = prctl(PR_GET_MEMORY_CONSISTENCY_MODEL); + ASSERT_TRUE(ret == PR_MEMORY_CONSISTENCY_MODEL_RISCV_WMO || + ret == PR_MEMORY_CONSISTENCY_MODEL_RISCV_TSO); + + if (ssdtso_available) { + /* Switch to TSO. */ + ret = prctl(PR_SET_MEMORY_CONSISTENCY_MODEL, + PR_MEMORY_CONSISTENCY_MODEL_RISCV_TSO); + ASSERT_EQ(ret, 0); + ret = prctl(PR_GET_MEMORY_CONSISTENCY_MODEL); + ASSERT_TRUE(ret == PR_MEMORY_CONSISTENCY_MODEL_RISCV_TSO); + + /* Try switching back to WMO (must fail). */ + ret = prctl(PR_SET_MEMORY_CONSISTENCY_MODEL, + PR_MEMORY_CONSISTENCY_MODEL_RISCV_WMO); + ASSERT_LT(ret, 0); + ret = prctl(PR_GET_MEMORY_CONSISTENCY_MODEL); + ASSERT_TRUE(ret == PR_MEMORY_CONSISTENCY_MODEL_RISCV_TSO); + } else { + /* Set the same model, that's currently active. */ + ret = prctl(PR_SET_MEMORY_CONSISTENCY_MODEL, ret); + ASSERT_EQ(ret, 0); + } + } else { + ASSERT_EQ(ssdtso_available, false); + ksft_test_result_skip("Ssdtso not configured\n"); + } +} + +TEST_HARNESS_MAIN -- 2.43.0