From: James Morse <james.morse@arm.com>
To: linux-arm-kernel@lists.infradead.org, linux-kselftest@vger.kernel.org
Cc: Catalin Marinas <catalin.marinas@arm.com>,
Will Deacon <will@kernel.org>, Marc Zyngier <maz@kernel.org>,
Shuah Khan <shuah@kernel.org>, Mark Brown <broonie@kernel.org>,
james.morse@arm.com
Subject: [PATCH 2/3] arm64: insn: Add tests for aarch64_insn_gen_logical_immediate()
Date: Thu, 27 Jan 2022 16:21:26 +0000 [thread overview]
Message-ID: <20220127162127.2391947-3-james.morse@arm.com> (raw)
In-Reply-To: <20220127162127.2391947-1-james.morse@arm.com>
Aarch64 has instructions to generate reasonably complicated 32 or 64
bit masks from only 13 bits of information.
aarch64_insn_gen_logical_immediate() has to created the immediate
encoding by spotting the patterns in the 32 or 64 bit immediate.
Despite attempts to validate or model this code, or use it as-is outside
the kernel tree, bugs still exist.
Add a self test module that tests this code in place against a golden
set of values.
Signed-off-by: James Morse <james.morse@arm.com>
---
arch/arm64/Kconfig.debug | 3 +
arch/arm64/Makefile | 2 +
arch/arm64/lib/Makefile | 2 +
arch/arm64/lib/insn.c | 3 +
arch/arm64/lib/test_insn.c | 90 ++++++++++++++++++++++
tools/testing/selftests/arm64/Makefile | 2 +-
tools/testing/selftests/arm64/lib/Makefile | 6 ++
tools/testing/selftests/arm64/lib/config | 1 +
tools/testing/selftests/arm64/lib/insn.sh | 5 ++
9 files changed, 113 insertions(+), 1 deletion(-)
create mode 100644 arch/arm64/lib/test_insn.c
create mode 100644 tools/testing/selftests/arm64/lib/Makefile
create mode 100644 tools/testing/selftests/arm64/lib/config
create mode 100755 tools/testing/selftests/arm64/lib/insn.sh
diff --git a/arch/arm64/Kconfig.debug b/arch/arm64/Kconfig.debug
index 265c4461031f..10df6056db3e 100644
--- a/arch/arm64/Kconfig.debug
+++ b/arch/arm64/Kconfig.debug
@@ -20,4 +20,7 @@ config ARM64_RELOC_TEST
depends on m
tristate "Relocation testing module"
+config TEST_INSN
+ tristate "Test functions located in the aarch64 instruction encoder at runtime"
+
source "drivers/hwtracing/coresight/Kconfig"
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 0bd590605416..4930a2b077b8 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -176,7 +176,9 @@ vdso_install:
archprepare:
$(Q)$(MAKE) $(build)=arch/arm64/tools kapi
+#ifdef CONFIG_TEST_INSN
$(Q)$(MAKE) $(build)=arch/arm64/tools tests
+#endif
ifeq ($(CONFIG_ARM64_ERRATUM_843419),y)
ifneq ($(CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419),y)
@echo "warning: ld does not support --fix-cortex-a53-843419; kernel may be susceptible to erratum" >&2
diff --git a/arch/arm64/lib/Makefile b/arch/arm64/lib/Makefile
index 29490be2546b..d180945ecc22 100644
--- a/arch/arm64/lib/Makefile
+++ b/arch/arm64/lib/Makefile
@@ -22,3 +22,5 @@ obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
obj-$(CONFIG_ARM64_MTE) += mte.o
obj-$(CONFIG_KASAN_SW_TAGS) += kasan_sw_tags.o
+
+obj-$(CONFIG_TEST_INSN) += test_insn.o
diff --git a/arch/arm64/lib/insn.c b/arch/arm64/lib/insn.c
index fccfe363e567..8888e407032f 100644
--- a/arch/arm64/lib/insn.c
+++ b/arch/arm64/lib/insn.c
@@ -193,6 +193,7 @@ u64 aarch64_insn_decode_immediate(enum aarch64_insn_imm_type type, u32 insn)
return (insn >> shift) & mask;
}
+EXPORT_SYMBOL_GPL(aarch64_insn_decode_immediate);
u32 __kprobes aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type,
u32 insn, u64 imm)
@@ -256,6 +257,7 @@ u32 aarch64_insn_decode_register(enum aarch64_insn_register_type type,
return (insn >> shift) & GENMASK(4, 0);
}
+EXPORT_SYMBOL_GPL(aarch64_insn_decode_register);
static u32 aarch64_insn_encode_register(enum aarch64_insn_register_type type,
u32 insn,
@@ -1424,6 +1426,7 @@ u32 aarch64_insn_gen_logical_immediate(enum aarch64_insn_logic_type type,
insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, Rn);
return aarch64_encode_immediate(imm, variant, insn);
}
+EXPORT_SYMBOL_GPL(aarch64_insn_gen_logical_immediate);
u32 aarch64_insn_gen_extr(enum aarch64_insn_variant variant,
enum aarch64_insn_register Rm,
diff --git a/arch/arm64/lib/test_insn.c b/arch/arm64/lib/test_insn.c
new file mode 100644
index 000000000000..41466f61c6c0
--- /dev/null
+++ b/arch/arm64/lib/test_insn.c
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Test cases for the aarch64 insn encoder.
+ *
+ * Copyright (C) 2021 ARM Limited.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/printk.h>
+
+#include <asm/debug-monitors.h>
+#include <asm/insn.h>
+
+#include "../../../tools/testing/selftests/kselftest_module.h"
+
+struct bitmask_test_case {
+ /* input */
+ u64 imm;
+
+ /* expected output */
+ u64 n, immr, imms;
+};
+struct bitmask_test_case aarch64_logic_imm_test[] = {
+#include <asm/test_logic_imm_generated.h>
+};
+
+KSTM_MODULE_GLOBALS();
+
+static void __init test_logic_imm(void)
+{
+ int i;
+ u8 rd, rn;
+ u32 insn;
+
+ for (i = 0; i < ARRAY_SIZE(aarch64_logic_imm_test); i++) {
+ total_tests++;
+
+ rd = i % 30;
+ rn = (i + 1) % 30;
+
+ insn = aarch64_insn_gen_logical_immediate(AARCH64_INSN_LOGIC_AND,
+ AARCH64_INSN_VARIANT_64BIT,
+ rn, rd, aarch64_logic_imm_test[i].imm);
+
+ if (!aarch64_insn_is_and_imm(insn) ||
+ rd != aarch64_insn_decode_register(AARCH64_INSN_REGTYPE_RD, insn) ||
+ rn != aarch64_insn_decode_register(AARCH64_INSN_REGTYPE_RN, insn) ||
+ aarch64_logic_imm_test[i].imms != aarch64_insn_decode_immediate(AARCH64_INSN_IMM_S, insn) ||
+ aarch64_logic_imm_test[i].immr != aarch64_insn_decode_immediate(AARCH64_INSN_IMM_R, insn) ||
+ aarch64_logic_imm_test[i].n != aarch64_insn_decode_immediate(AARCH64_INSN_IMM_N, insn)) {
+ failed_tests++;
+ pr_warn_once("[%s:%u] Failed to encode immediate 0x%llx (got insn 0x%x))\n",
+ __FILE__, __LINE__, aarch64_logic_imm_test[i].imm, insn);
+ continue;
+ }
+ }
+}
+
+static void __init do_test_bad_logic_imm(u64 imm, enum aarch64_insn_variant var)
+{
+ u32 insn;
+
+ total_tests++;
+ insn = aarch64_insn_gen_logical_immediate(AARCH64_INSN_LOGIC_AND,
+ var, 0, 0, imm);
+ if (insn != AARCH64_BREAK_FAULT)
+ failed_tests++;
+}
+
+static void __init test_bad_logic_imm(void)
+{
+ do_test_bad_logic_imm(0, AARCH64_INSN_VARIANT_64BIT);
+ do_test_bad_logic_imm(0x1234, AARCH64_INSN_VARIANT_64BIT);
+ do_test_bad_logic_imm(0xffffffffffffffff, AARCH64_INSN_VARIANT_64BIT);
+ do_test_bad_logic_imm((1ULL<<32), AARCH64_INSN_VARIANT_32BIT);
+}
+
+static void __init selftest(void)
+{
+ test_logic_imm();
+ test_bad_logic_imm();
+}
+
+KSTM_MODULE_LOADERS(test_insn);
+MODULE_AUTHOR("James Morse <james.morse@arm.com>");
+MODULE_LICENSE("GPL");
diff --git a/tools/testing/selftests/arm64/Makefile b/tools/testing/selftests/arm64/Makefile
index 1e8d9a8f59df..2c59e7d40524 100644
--- a/tools/testing/selftests/arm64/Makefile
+++ b/tools/testing/selftests/arm64/Makefile
@@ -4,7 +4,7 @@
ARCH ?= $(shell uname -m 2>/dev/null || echo not)
ifneq (,$(filter $(ARCH),aarch64 arm64))
-ARM64_SUBTARGETS ?= tags signal pauth fp mte bti abi
+ARM64_SUBTARGETS ?= tags signal pauth fp mte bti abi lib
else
ARM64_SUBTARGETS :=
endif
diff --git a/tools/testing/selftests/arm64/lib/Makefile b/tools/testing/selftests/arm64/lib/Makefile
new file mode 100644
index 000000000000..5ed92a5135ce
--- /dev/null
+++ b/tools/testing/selftests/arm64/lib/Makefile
@@ -0,0 +1,6 @@
+# Copyright (C) 2022 ARM Limited
+# Makefile for arm64/lib/ function selftests
+
+TEST_PROGS := insn.sh
+
+include ../../lib.mk
diff --git a/tools/testing/selftests/arm64/lib/config b/tools/testing/selftests/arm64/lib/config
new file mode 100644
index 000000000000..cb982478782b
--- /dev/null
+++ b/tools/testing/selftests/arm64/lib/config
@@ -0,0 +1 @@
+CONFIG_TEST_INSN=m
diff --git a/tools/testing/selftests/arm64/lib/insn.sh b/tools/testing/selftests/arm64/lib/insn.sh
new file mode 100755
index 000000000000..3d893b1a0069
--- /dev/null
+++ b/tools/testing/selftests/arm64/lib/insn.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+# Tests the aarch64 instruction generation infrastructure using test_insn
+# kernel module.
+$(dirname $0)/../../kselftest/module.sh "insn" test_insn
--
2.30.2
next prev parent reply other threads:[~2022-01-27 16:22 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-01-27 16:21 [PATCH 0/3] arm64: insn: Generate 64 bit mask immediates correctly James Morse
2022-01-27 16:21 ` [PATCH 1/3] arm64: selftests: Generate all the possible logical immediates as a header James Morse
2022-01-28 2:47 ` kernel test robot
2022-01-27 16:21 ` James Morse [this message]
2022-02-15 15:55 ` [PATCH 2/3] arm64: insn: Add tests for aarch64_insn_gen_logical_immediate() Will Deacon
2022-01-27 16:21 ` [PATCH 3/3] arm64: insn: Generate 64 bit mask immediates correctly James Morse
2022-01-27 18:34 ` Marc Zyngier
2022-02-15 23:18 ` [PATCH 0/3] " Will Deacon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220127162127.2391947-3-james.morse@arm.com \
--to=james.morse@arm.com \
--cc=broonie@kernel.org \
--cc=catalin.marinas@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=maz@kernel.org \
--cc=shuah@kernel.org \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox