riscv: Add tests for riscv module loading
authorCharlie Jenkins <charlie@rivosinc.com>
Wed, 1 Nov 2023 18:33:01 +0000 (11:33 -0700)
committerPalmer Dabbelt <palmer@rivosinc.com>
Tue, 7 Nov 2023 22:59:32 +0000 (14:59 -0800)
Add test cases for the two main groups of relocations added: SUB and
SET, along with uleb128.

Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
Link: https://lore.kernel.org/r/20231101-module_relocations-v9-3-8dfa3483c400@rivosinc.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
16 files changed:
arch/riscv/Kconfig.debug
arch/riscv/kernel/Makefile
arch/riscv/kernel/tests/Kconfig.debug [new file with mode: 0644]
arch/riscv/kernel/tests/Makefile [new file with mode: 0644]
arch/riscv/kernel/tests/module_test/Makefile [new file with mode: 0644]
arch/riscv/kernel/tests/module_test/test_module_linking_main.c [new file with mode: 0644]
arch/riscv/kernel/tests/module_test/test_set16.S [new file with mode: 0644]
arch/riscv/kernel/tests/module_test/test_set32.S [new file with mode: 0644]
arch/riscv/kernel/tests/module_test/test_set6.S [new file with mode: 0644]
arch/riscv/kernel/tests/module_test/test_set8.S [new file with mode: 0644]
arch/riscv/kernel/tests/module_test/test_sub16.S [new file with mode: 0644]
arch/riscv/kernel/tests/module_test/test_sub32.S [new file with mode: 0644]
arch/riscv/kernel/tests/module_test/test_sub6.S [new file with mode: 0644]
arch/riscv/kernel/tests/module_test/test_sub64.S [new file with mode: 0644]
arch/riscv/kernel/tests/module_test/test_sub8.S [new file with mode: 0644]
arch/riscv/kernel/tests/module_test/test_uleb128.S [new file with mode: 0644]

index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..eafe17ebf7102c93925eea57be96fd6ee1e191a1 100644 (file)
@@ -0,0 +1 @@
+source "arch/riscv/kernel/tests/Kconfig.debug"
index 95cf25d484052e88b39ca3a49b74cc2bb1453992..bb99657252f41cdb5b59d4f15887de405b9bdaca 100644 (file)
@@ -57,6 +57,7 @@ obj-y += stacktrace.o
 obj-y  += cacheinfo.o
 obj-y  += patch.o
 obj-y  += probes/
+obj-y  += tests/
 obj-$(CONFIG_MMU) += vdso.o vdso/
 
 obj-$(CONFIG_RISCV_M_MODE)     += traps_misaligned.o
diff --git a/arch/riscv/kernel/tests/Kconfig.debug b/arch/riscv/kernel/tests/Kconfig.debug
new file mode 100644 (file)
index 0000000..5dba64e
--- /dev/null
@@ -0,0 +1,35 @@
+# SPDX-License-Identifier: GPL-2.0-only
+menu "arch/riscv/kernel Testing and Coverage"
+
+config AS_HAS_ULEB128
+       def_bool $(as-instr,.reloc label$(comma) R_RISCV_SET_ULEB128$(comma) 127\n.reloc label$(comma) R_RISCV_SUB_ULEB128$(comma) 127\nlabel:\n.word 0)
+
+menuconfig RUNTIME_KERNEL_TESTING_MENU
+       bool "arch/riscv/kernel runtime Testing"
+       def_bool y
+       help
+         Enable riscv kernel runtime testing.
+
+if RUNTIME_KERNEL_TESTING_MENU
+
+config RISCV_MODULE_LINKING_KUNIT
+       bool "KUnit test riscv module linking at runtime" if !KUNIT_ALL_TESTS
+       depends on KUNIT
+       default KUNIT_ALL_TESTS
+       help
+         Enable this option to test riscv module linking at boot. This will
+        enable a module called "test_module_linking".
+
+         KUnit tests run during boot and output the results to the debug log
+         in TAP format (http://testanything.org/). Only useful for kernel devs
+         running the KUnit test harness, and not intended for inclusion into a
+         production build.
+
+         For more information on KUnit and unit tests in general please refer
+         to the KUnit documentation in Documentation/dev-tools/kunit/.
+
+         If unsure, say N.
+
+endif # RUNTIME_TESTING_MENU
+
+endmenu # "arch/riscv/kernel runtime Testing"
diff --git a/arch/riscv/kernel/tests/Makefile b/arch/riscv/kernel/tests/Makefile
new file mode 100644 (file)
index 0000000..7d6c76c
--- /dev/null
@@ -0,0 +1 @@
+obj-$(CONFIG_RISCV_MODULE_LINKING_KUNIT)       += module_test/
diff --git a/arch/riscv/kernel/tests/module_test/Makefile b/arch/riscv/kernel/tests/module_test/Makefile
new file mode 100644 (file)
index 0000000..d7a6fd8
--- /dev/null
@@ -0,0 +1,15 @@
+obj-m += test_module_linking.o
+
+test_sub := test_sub6.o test_sub8.o test_sub16.o test_sub32.o test_sub64.o
+
+test_set := test_set6.o test_set8.o test_set16.o test_set32.o
+
+test_module_linking-objs += $(test_sub)
+
+test_module_linking-objs += $(test_set)
+
+ifeq ($(CONFIG_AS_HAS_ULEB128),y)
+test_module_linking-objs += test_uleb128.o
+endif
+
+test_module_linking-objs += test_module_linking_main.o
diff --git a/arch/riscv/kernel/tests/module_test/test_module_linking_main.c b/arch/riscv/kernel/tests/module_test/test_module_linking_main.c
new file mode 100644 (file)
index 0000000..8df5fa5
--- /dev/null
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2023 Rivos Inc.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <kunit/test.h>
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Test module linking");
+
+extern int test_set32(void);
+extern int test_set16(void);
+extern int test_set8(void);
+extern int test_set6(void);
+extern long test_sub64(void);
+extern int test_sub32(void);
+extern int test_sub16(void);
+extern int test_sub8(void);
+extern int test_sub6(void);
+
+#ifdef CONFIG_AS_HAS_ULEB128
+extern int test_uleb_basic(void);
+extern int test_uleb_large(void);
+#endif
+
+#define CHECK_EQ(lhs, rhs) KUNIT_ASSERT_EQ(test, lhs, rhs)
+
+void run_test_set(struct kunit *test);
+void run_test_sub(struct kunit *test);
+void run_test_uleb(struct kunit *test);
+
+void run_test_set(struct kunit *test)
+{
+       int val32 = test_set32();
+       int val16 = test_set16();
+       int val8 = test_set8();
+       int val6 = test_set6();
+
+       CHECK_EQ(val32, 0);
+       CHECK_EQ(val16, 0);
+       CHECK_EQ(val8, 0);
+       CHECK_EQ(val6, 0);
+}
+
+void run_test_sub(struct kunit *test)
+{
+       int val64 = test_sub64();
+       int val32 = test_sub32();
+       int val16 = test_sub16();
+       int val8 = test_sub8();
+       int val6 = test_sub6();
+
+       CHECK_EQ(val64, 0);
+       CHECK_EQ(val32, 0);
+       CHECK_EQ(val16, 0);
+       CHECK_EQ(val8, 0);
+       CHECK_EQ(val6, 0);
+}
+
+#ifdef CONFIG_AS_HAS_ULEB128
+void run_test_uleb(struct kunit *test)
+{
+       int val_uleb = test_uleb_basic();
+       int val_uleb2 = test_uleb_large();
+
+       CHECK_EQ(val_uleb, 0);
+       CHECK_EQ(val_uleb2, 0);
+}
+#endif
+
+static struct kunit_case __refdata riscv_module_linking_test_cases[] = {
+       KUNIT_CASE(run_test_set),
+       KUNIT_CASE(run_test_sub),
+#ifdef CONFIG_AS_HAS_ULEB128
+       KUNIT_CASE(run_test_uleb),
+#endif
+       {}
+};
+
+static struct kunit_suite riscv_module_linking_test_suite = {
+       .name = "riscv_checksum",
+       .test_cases = riscv_module_linking_test_cases,
+};
+
+kunit_test_suites(&riscv_module_linking_test_suite);
diff --git a/arch/riscv/kernel/tests/module_test/test_set16.S b/arch/riscv/kernel/tests/module_test/test_set16.S
new file mode 100644 (file)
index 0000000..2be0e44
--- /dev/null
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2023 Rivos Inc.
+ */
+
+.text
+.global test_set16
+test_set16:
+       lw      a0, set16
+       la      t0, set16
+#ifdef CONFIG_32BIT
+       slli    t0, t0, 16
+       srli    t0, t0, 16
+#else
+       slli    t0, t0, 48
+       srli    t0, t0, 48
+#endif
+       sub     a0, a0, t0
+       ret
+.data
+set16:
+       .reloc set16, R_RISCV_SET16, set16
+       .word 0
diff --git a/arch/riscv/kernel/tests/module_test/test_set32.S b/arch/riscv/kernel/tests/module_test/test_set32.S
new file mode 100644 (file)
index 0000000..de04445
--- /dev/null
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2023 Rivos Inc.
+ */
+
+.text
+.global test_set32
+test_set32:
+       lw      a0, set32
+       la      t0, set32
+#ifndef CONFIG_32BIT
+       slli    t0, t0, 32
+       srli    t0, t0, 32
+#endif
+       sub     a0, a0, t0
+       ret
+.data
+set32:
+       .reloc set32, R_RISCV_SET32, set32
+       .word 0
diff --git a/arch/riscv/kernel/tests/module_test/test_set6.S b/arch/riscv/kernel/tests/module_test/test_set6.S
new file mode 100644 (file)
index 0000000..c39ce4c
--- /dev/null
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2023 Rivos Inc.
+ */
+
+.text
+.global test_set6
+test_set6:
+       lw      a0, set6
+       la      t0, set6
+#ifdef CONFIG_32BIT
+       slli    t0, t0, 26
+       srli    t0, t0, 26
+#else
+       slli    t0, t0, 58
+       srli    t0, t0, 58
+#endif
+       sub     a0, a0, t0
+       ret
+.data
+set6:
+       .reloc set6, R_RISCV_SET6, set6
+       .word 0
diff --git a/arch/riscv/kernel/tests/module_test/test_set8.S b/arch/riscv/kernel/tests/module_test/test_set8.S
new file mode 100644 (file)
index 0000000..a656173
--- /dev/null
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2023 Rivos Inc.
+ */
+
+.text
+.global test_set8
+test_set8:
+       lw      a0, set8
+       la      t0, set8
+#ifdef CONFIG_32BIT
+       slli    t0, t0, 24
+       srli    t0, t0, 24
+#else
+       slli    t0, t0, 56
+       srli    t0, t0, 56
+#endif
+       sub     a0, a0, t0
+       ret
+.data
+set8:
+       .reloc set8, R_RISCV_SET8, set8
+       .word 0
diff --git a/arch/riscv/kernel/tests/module_test/test_sub16.S b/arch/riscv/kernel/tests/module_test/test_sub16.S
new file mode 100644 (file)
index 0000000..80f731d
--- /dev/null
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2023 Rivos Inc.
+ */
+
+.text
+.global test_sub16
+test_sub16:
+       lh      a0, sub16
+       addi    a0, a0, -32
+       ret
+first:
+       .space 32
+second:
+
+.data
+sub16:
+       .reloc          sub16, R_RISCV_ADD16, second
+       .reloc          sub16, R_RISCV_SUB16, first
+       .half           0
diff --git a/arch/riscv/kernel/tests/module_test/test_sub32.S b/arch/riscv/kernel/tests/module_test/test_sub32.S
new file mode 100644 (file)
index 0000000..a341686
--- /dev/null
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2023 Rivos Inc.
+ */
+
+.text
+.global test_sub32
+test_sub32:
+       lw      a0, sub32
+       addi    a0, a0, -32
+       ret
+first:
+       .space 32
+second:
+
+.data
+sub32:
+       .reloc          sub32, R_RISCV_ADD32, second
+       .reloc          sub32, R_RISCV_SUB32, first
+       .word           0
diff --git a/arch/riscv/kernel/tests/module_test/test_sub6.S b/arch/riscv/kernel/tests/module_test/test_sub6.S
new file mode 100644 (file)
index 0000000..e8b61c1
--- /dev/null
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2023 Rivos Inc.
+ */
+
+.text
+.global test_sub6
+test_sub6:
+       lb      a0, sub6
+       addi    a0, a0, -32
+       ret
+first:
+       .space 32
+second:
+
+.data
+sub6:
+       .reloc          sub6, R_RISCV_SET6, second
+       .reloc          sub6, R_RISCV_SUB6, first
+       .byte           0
diff --git a/arch/riscv/kernel/tests/module_test/test_sub64.S b/arch/riscv/kernel/tests/module_test/test_sub64.S
new file mode 100644 (file)
index 0000000..a59e8af
--- /dev/null
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2023 Rivos Inc.
+ */
+
+.text
+.global test_sub64
+test_sub64:
+#ifdef CONFIG_32BIT
+       lw      a0, sub64
+#else
+       ld      a0, sub64
+#endif
+       addi    a0, a0, -32
+       ret
+first:
+       .space 32
+second:
+
+.data
+sub64:
+       .reloc          sub64, R_RISCV_ADD64, second
+       .reloc          sub64, R_RISCV_SUB64, first
+       .word           0
+       .word           0
diff --git a/arch/riscv/kernel/tests/module_test/test_sub8.S b/arch/riscv/kernel/tests/module_test/test_sub8.S
new file mode 100644 (file)
index 0000000..ac5d0ec
--- /dev/null
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2023 Rivos Inc.
+ */
+
+.text
+.global test_sub8
+test_sub8:
+       lb      a0, sub8
+       addi    a0, a0, -32
+       ret
+first:
+       .space 32
+second:
+
+.data
+sub8:
+       .reloc          sub8, R_RISCV_ADD8, second
+       .reloc          sub8, R_RISCV_SUB8, first
+       .byte           0
diff --git a/arch/riscv/kernel/tests/module_test/test_uleb128.S b/arch/riscv/kernel/tests/module_test/test_uleb128.S
new file mode 100644 (file)
index 0000000..90f2204
--- /dev/null
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2023 Rivos Inc.
+ */
+
+.text
+.global test_uleb_basic
+test_uleb_basic:
+       ld      a0, second
+       addi    a0, a0, -127
+       ret
+
+.global test_uleb_large
+test_uleb_large:
+       ld      a0, fourth
+       addi    a0, a0, -0x07e8
+       ret
+
+.data
+first:
+       .space 127
+second:
+       .reloc second, R_RISCV_SET_ULEB128, second
+       .reloc second, R_RISCV_SUB_ULEB128, first
+       .dword 0
+third:
+       .space 1000
+fourth:
+       .reloc fourth, R_RISCV_SET_ULEB128, fourth
+       .reloc fourth, R_RISCV_SUB_ULEB128, third
+       .dword 0