Linux-RISC-V Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/2] riscv: hwprobe: Add Zicbop support
@ 2025-10-20 15:29 Yao Zihong
  2025-10-20 15:33 ` [PATCH v3 1/2] riscv: hwprobe: Expose Zicbop extension and its block size Yao Zihong
  2025-10-20 15:37 ` [PATCH v3 2/2] selftests/riscv: Add Zicbop prefetch test Yao Zihong
  0 siblings, 2 replies; 7+ messages in thread
From: Yao Zihong @ 2025-10-20 15:29 UTC (permalink / raw)
  To: linux-riscv, linux-kernel
  Cc: ajones, alexghiti, shuah, samuel.holland, evan, cleger,
	zihong.plct, zihongyao, zhangyin2018, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti

Changes since v2:
------------------
- Squash the previous UAPI/kernel/doc patches(originally 1/4, 2/4, 3/4)
  into a single hwprobe patch for simplicity.
- Selftests:
  * Drop the `memory` clobber from the prefetch inline asm since it is
    pure hint.
  * Fix style problems. (Andrew Jones)
  * Merge the standalone prefetch test into 
    `tools/testing/selftests/riscv/hwprobe/cbo.c` (Andrew Jones)
  * Switch to `getopt_long` for option parsing. (Andrew Jones)

Changes since v1:
------------------
- Bump RISCV_HWPROBE_MAX_KEY (modified 1/4).
- Add documentation for the Zicbop hwprobe bit/key (new 3/4).
- Add a selftest(prefetch.c) for Zicbop (new 4/4).

Add UAPI and kernel plumbing to expose the Zicbop extension presence
and its block size through hwprobe. The interface mirrors
Zicbom/Zicboz. This allows userspace to safely discover and optimize
for Zicbop when available.

Background: Zicbop is mandated by the RVA22U64 profile. Downstream may
combine the presence bit with ZICBOP_BLOCK_SIZE to make profile-level
policy decisions or enable Zicbop-specific optimizations.


Yao Zihong (2):
  riscv: hwprobe: Expose Zicbop extension and its block size
  selftests/riscv: Add Zicbop prefetch test

 Documentation/arch/riscv/hwprobe.rst        |   8 +-
 arch/riscv/include/asm/hwprobe.h            |   2 +-
 arch/riscv/include/uapi/asm/hwprobe.h       |   2 +
 arch/riscv/kernel/sys_hwprobe.c             |   6 +
 tools/testing/selftests/riscv/hwprobe/cbo.c | 188 +++++++++++++++++---
 5 files changed, 175 insertions(+), 31 deletions(-)

-- 
2.47.2


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v3 1/2] riscv: hwprobe: Expose Zicbop extension and its block size
  2025-10-20 15:29 [PATCH v3 0/2] riscv: hwprobe: Add Zicbop support Yao Zihong
@ 2025-10-20 15:33 ` Yao Zihong
  2025-10-21 23:21   ` Andrew Jones
  2025-10-20 15:37 ` [PATCH v3 2/2] selftests/riscv: Add Zicbop prefetch test Yao Zihong
  1 sibling, 1 reply; 7+ messages in thread
From: Yao Zihong @ 2025-10-20 15:33 UTC (permalink / raw)
  To: zihong.plct
  Cc: ajones, alex, alexghiti, aou, cleger, evan, linux-kernel,
	linux-riscv, palmer, pjw, samuel.holland, shuah, zhangyin2018,
	zihongyao

- Add `RISCV_HWPROBE_EXT_ZICBOP` to report the presence of the
  Zicbop extension.
- Add `RISCV_HWPROBE_KEY_ZICBOP_BLOCK_SIZE` to expose the block
  size (in bytes) when Zicbop is supported.
- Update hwprobe.rst to document the new extension bit and block
  size key, following the existing Zicbom/Zicboz style.

Signed-off-by: Yao Zihong <zihong.plct@isrc.iscas.ac.cn>
---
 Documentation/arch/riscv/hwprobe.rst  | 8 +++++++-
 arch/riscv/include/asm/hwprobe.h      | 2 +-
 arch/riscv/include/uapi/asm/hwprobe.h | 2 ++
 arch/riscv/kernel/sys_hwprobe.c       | 6 ++++++
 4 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/Documentation/arch/riscv/hwprobe.rst b/Documentation/arch/riscv/hwprobe.rst
index 2f449c9b15bd..52f12af43b9d 100644
--- a/Documentation/arch/riscv/hwprobe.rst
+++ b/Documentation/arch/riscv/hwprobe.rst
@@ -275,6 +275,9 @@ The following keys are defined:
        ratified in commit 49f49c842ff9 ("Update to Rafified state") of
        riscv-zabha.
 
+  * :c:macro:`RISCV_HWPROBE_EXT_ZICBOP`: The Zicbop extension is supported, as
+       ratified in commit 3dd606f ("Create cmobase-v1.0.pdf") of riscv-CMOs.
+
 * :c:macro:`RISCV_HWPROBE_KEY_CPUPERF_0`: Deprecated.  Returns similar values to
      :c:macro:`RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF`, but the key was
      mistakenly classified as a bitmask rather than a value.
@@ -369,4 +372,7 @@ The following keys are defined:
 
     * :c:macro:`RISCV_HWPROBE_VENDOR_EXT_XSFVFWMACCQQQ`: The Xsfvfwmaccqqq
         vendor extension is supported in version 1.0 of Matrix Multiply Accumulate
-	Instruction Extensions Specification.
\ No newline at end of file
+	Instruction Extensions Specification.
+
+* :c:macro:`RISCV_HWPROBE_KEY_ZICBOP_BLOCK_SIZE`: An unsigned int which
+  represents the size of the Zicbop block in bytes.
diff --git a/arch/riscv/include/asm/hwprobe.h b/arch/riscv/include/asm/hwprobe.h
index 948d2b34e94e..2f278c395af9 100644
--- a/arch/riscv/include/asm/hwprobe.h
+++ b/arch/riscv/include/asm/hwprobe.h
@@ -8,7 +8,7 @@
 
 #include <uapi/asm/hwprobe.h>
 
-#define RISCV_HWPROBE_MAX_KEY 14
+#define RISCV_HWPROBE_MAX_KEY 15
 
 static inline bool riscv_hwprobe_key_is_valid(__s64 key)
 {
diff --git a/arch/riscv/include/uapi/asm/hwprobe.h b/arch/riscv/include/uapi/asm/hwprobe.h
index 5d30a4fae37a..9cc508be54c5 100644
--- a/arch/riscv/include/uapi/asm/hwprobe.h
+++ b/arch/riscv/include/uapi/asm/hwprobe.h
@@ -82,6 +82,7 @@ struct riscv_hwprobe {
 #define		RISCV_HWPROBE_EXT_ZAAMO		(1ULL << 56)
 #define		RISCV_HWPROBE_EXT_ZALRSC	(1ULL << 57)
 #define		RISCV_HWPROBE_EXT_ZABHA		(1ULL << 58)
+#define		RISCV_HWPROBE_EXT_ZICBOP	(1ULL << 59)
 #define RISCV_HWPROBE_KEY_CPUPERF_0	5
 #define		RISCV_HWPROBE_MISALIGNED_UNKNOWN	(0 << 0)
 #define		RISCV_HWPROBE_MISALIGNED_EMULATED	(1 << 0)
@@ -107,6 +108,7 @@ struct riscv_hwprobe {
 #define RISCV_HWPROBE_KEY_ZICBOM_BLOCK_SIZE	12
 #define RISCV_HWPROBE_KEY_VENDOR_EXT_SIFIVE_0	13
 #define RISCV_HWPROBE_KEY_VENDOR_EXT_MIPS_0	14
+#define RISCV_HWPROBE_KEY_ZICBOP_BLOCK_SIZE	15
 /* Increase RISCV_HWPROBE_MAX_KEY when adding items. */
 
 /* Flags */
diff --git a/arch/riscv/kernel/sys_hwprobe.c b/arch/riscv/kernel/sys_hwprobe.c
index 000f4451a9d8..7a6ae1327504 100644
--- a/arch/riscv/kernel/sys_hwprobe.c
+++ b/arch/riscv/kernel/sys_hwprobe.c
@@ -113,6 +113,7 @@ static void hwprobe_isa_ext0(struct riscv_hwprobe *pair,
 		EXT_KEY(ZCB);
 		EXT_KEY(ZCMOP);
 		EXT_KEY(ZICBOM);
+		EXT_KEY(ZICBOP);
 		EXT_KEY(ZICBOZ);
 		EXT_KEY(ZICNTR);
 		EXT_KEY(ZICOND);
@@ -293,6 +294,11 @@ static void hwprobe_one_pair(struct riscv_hwprobe *pair,
 		if (hwprobe_ext0_has(cpus, RISCV_HWPROBE_EXT_ZICBOM))
 			pair->value = riscv_cbom_block_size;
 		break;
+	case RISCV_HWPROBE_KEY_ZICBOP_BLOCK_SIZE:
+		pair->value = 0;
+		if (hwprobe_ext0_has(cpus, RISCV_HWPROBE_EXT_ZICBOP))
+			pair->value = riscv_cbop_block_size;
+		break;
 	case RISCV_HWPROBE_KEY_HIGHEST_VIRT_ADDRESS:
 		pair->value = user_max_virt_addr();
 		break;
-- 
2.47.2


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v3 2/2] selftests/riscv: Add Zicbop prefetch test
  2025-10-20 15:29 [PATCH v3 0/2] riscv: hwprobe: Add Zicbop support Yao Zihong
  2025-10-20 15:33 ` [PATCH v3 1/2] riscv: hwprobe: Expose Zicbop extension and its block size Yao Zihong
@ 2025-10-20 15:37 ` Yao Zihong
  2025-10-21 23:32   ` Andrew Jones
  1 sibling, 1 reply; 7+ messages in thread
From: Yao Zihong @ 2025-10-20 15:37 UTC (permalink / raw)
  To: zihong.plct
  Cc: ajones, alex, alexghiti, aou, cleger, evan, linux-kernel,
	linux-riscv, palmer, pjw, samuel.holland, shuah, zhangyin2018,
	zihongyao

Add selftest to cbo.c to verify Zicbop extension behavior.

The test checks:
- That hwprobe correctly reports Zicbop presence and block size.
- That prefetch instructions execute without exception on valid and NULL
  addresses when Zicbop is present.
- That prefetch.{i,r,w} do not trigger SIGILL even when Zicbop is absent,
  since Zicbop instructions are defined as hints.

Signed-off-by: Yao Zihong <zihong.plct@isrc.iscas.ac.cn>
---
 tools/testing/selftests/riscv/hwprobe/cbo.c | 188 +++++++++++++++++---
 1 file changed, 159 insertions(+), 29 deletions(-)

diff --git a/tools/testing/selftests/riscv/hwprobe/cbo.c b/tools/testing/selftests/riscv/hwprobe/cbo.c
index 5e96ef785d0d..163228e3f2c7 100644
--- a/tools/testing/selftests/riscv/hwprobe/cbo.c
+++ b/tools/testing/selftests/riscv/hwprobe/cbo.c
@@ -15,24 +15,30 @@
 #include <linux/compiler.h>
 #include <linux/kernel.h>
 #include <asm/ucontext.h>
+#include <getopt.h>
 
 #include "hwprobe.h"
 #include "../../kselftest.h"
 
 #define MK_CBO(fn) le32_bswap((uint32_t)(fn) << 20 | 10 << 15 | 2 << 12 | 0 << 7 | 15)
+#define MK_PREFETCH(fn) \
+	le32_bswap(0 << 25 | (uint32_t)(fn) << 20 | 10 << 15 | 6 << 12 | 0 << 7 | 19)
 
 static char mem[4096] __aligned(4096) = { [0 ... 4095] = 0xa5 };
 
-static bool illegal_insn;
+static bool got_fault;
 
 static void sigill_handler(int sig, siginfo_t *info, void *context)
 {
 	unsigned long *regs = (unsigned long *)&((ucontext_t *)context)->uc_mcontext;
 	uint32_t insn = *(uint32_t *)regs[0];
 
-	assert(insn == MK_CBO(regs[11]));
+	if (regs[12] == 0)
+		assert(insn == MK_CBO(regs[11]));
+	else
+		assert(insn == MK_PREFETCH(regs[11]));
 
-	illegal_insn = true;
+	got_fault = true;
 	regs[0] += 4;
 }
 
@@ -41,43 +47,75 @@ static void sigill_handler(int sig, siginfo_t *info, void *context)
 	asm volatile(								\
 	"mv	a0, %0\n"							\
 	"li	a1, %1\n"							\
+	"li	a2, 0\n"							\
 	".4byte	%2\n"								\
-	: : "r" (base), "i" (fn), "i" (MK_CBO(fn)) : "a0", "a1", "memory");	\
+	: : "r" (base), "i" (fn), "i" (MK_CBO(fn)) : "a0", "a1", "a2", "memory");	\
+})
+
+#define prefetch_insn(base, fn)							\
+({										\
+	asm volatile(								\
+	"mv	a0, %0\n"							\
+	"li	a1, %1\n"							\
+	"li	a2, 1\n"							\
+	".4byte	%2\n"								\
+	: : "r" (base), "i" (fn), "i" (MK_PREFETCH(fn)) : "a0", "a1", "a2");\
 })
 
 static void cbo_inval(char *base) { cbo_insn(base, 0); }
 static void cbo_clean(char *base) { cbo_insn(base, 1); }
 static void cbo_flush(char *base) { cbo_insn(base, 2); }
 static void cbo_zero(char *base)  { cbo_insn(base, 4); }
+static void prefetch_i(char *base) { prefetch_insn(base, 0); }
+static void prefetch_r(char *base) { prefetch_insn(base, 1); }
+static void prefetch_w(char *base) { prefetch_insn(base, 3); }
+
+static void test_no_zicbop(void *arg)
+{
+	/* Zicbop prefetch.* are HINT instructions. */
+	ksft_print_msg("Testing Zicbop instructions\n");
+
+	got_fault = false;
+	prefetch_i(&mem[0]);
+	ksft_test_result(!got_fault, "No prefetch.i\n");
+
+	got_fault = false;
+	prefetch_r(&mem[0]);
+	ksft_test_result(!got_fault, "No prefetch.r\n");
+
+	got_fault = false;
+	prefetch_w(&mem[0]);
+	ksft_test_result(!got_fault, "No prefetch.w\n");
+}
 
 static void test_no_cbo_inval(void *arg)
 {
 	ksft_print_msg("Testing cbo.inval instruction remain privileged\n");
-	illegal_insn = false;
+	got_fault = false;
 	cbo_inval(&mem[0]);
-	ksft_test_result(illegal_insn, "No cbo.inval\n");
+	ksft_test_result(got_fault, "No cbo.inval\n");
 }
 
 static void test_no_zicbom(void *arg)
 {
 	ksft_print_msg("Testing Zicbom instructions remain privileged\n");
 
-	illegal_insn = false;
+	got_fault = false;
 	cbo_clean(&mem[0]);
-	ksft_test_result(illegal_insn, "No cbo.clean\n");
+	ksft_test_result(got_fault, "No cbo.clean\n");
 
-	illegal_insn = false;
+	got_fault = false;
 	cbo_flush(&mem[0]);
-	ksft_test_result(illegal_insn, "No cbo.flush\n");
+	ksft_test_result(got_fault, "No cbo.flush\n");
 }
 
 static void test_no_zicboz(void *arg)
 {
 	ksft_print_msg("No Zicboz, testing cbo.zero remains privileged\n");
 
-	illegal_insn = false;
+	got_fault = false;
 	cbo_zero(&mem[0]);
-	ksft_test_result(illegal_insn, "No cbo.zero\n");
+	ksft_test_result(got_fault, "No cbo.zero\n");
 }
 
 static bool is_power_of_2(__u64 n)
@@ -85,6 +123,34 @@ static bool is_power_of_2(__u64 n)
 	return n != 0 && (n & (n - 1)) == 0;
 }
 
+static void test_zicbop(void *arg)
+{
+	struct riscv_hwprobe pair = {
+		.key = RISCV_HWPROBE_KEY_ZICBOP_BLOCK_SIZE,
+	};
+	cpu_set_t *cpus = (cpu_set_t *)arg;
+	__u64 block_size;
+	long rc;
+
+	rc = riscv_hwprobe(&pair, 1, sizeof(cpu_set_t), (unsigned long *)cpus, 0);
+	block_size = pair.value;
+	ksft_test_result(rc == 0 && pair.key == RISCV_HWPROBE_KEY_ZICBOP_BLOCK_SIZE &&
+			 is_power_of_2(block_size), "Zicbop block size\n");
+	ksft_print_msg("Zicbop block size: %llu\n", block_size);
+
+	got_fault = false;
+	prefetch_i(&mem[0]);
+	prefetch_r(&mem[0]);
+	prefetch_w(&mem[0]);
+	ksft_test_result(!got_fault, "Zicbop prefetch.* on valid address\n");
+
+	got_fault = false;
+	prefetch_i(NULL);
+	prefetch_r(NULL);
+	prefetch_w(NULL);
+	ksft_test_result(!got_fault, "Zicbop prefetch.* on NULL\n");
+}
+
 static void test_zicbom(void *arg)
 {
 	struct riscv_hwprobe pair = {
@@ -100,13 +166,13 @@ static void test_zicbom(void *arg)
 			 is_power_of_2(block_size), "Zicbom block size\n");
 	ksft_print_msg("Zicbom block size: %llu\n", block_size);
 
-	illegal_insn = false;
+	got_fault = false;
 	cbo_clean(&mem[block_size]);
-	ksft_test_result(!illegal_insn, "cbo.clean\n");
+	ksft_test_result(!got_fault, "cbo.clean\n");
 
-	illegal_insn = false;
+	got_fault = false;
 	cbo_flush(&mem[block_size]);
-	ksft_test_result(!illegal_insn, "cbo.flush\n");
+	ksft_test_result(!got_fault, "cbo.flush\n");
 }
 
 static void test_zicboz(void *arg)
@@ -125,11 +191,11 @@ static void test_zicboz(void *arg)
 			 is_power_of_2(block_size), "Zicboz block size\n");
 	ksft_print_msg("Zicboz block size: %llu\n", block_size);
 
-	illegal_insn = false;
+	got_fault = false;
 	cbo_zero(&mem[block_size]);
-	ksft_test_result(!illegal_insn, "cbo.zero\n");
+	ksft_test_result(!got_fault, "cbo.zero\n");
 
-	if (illegal_insn || !is_power_of_2(block_size)) {
+	if (got_fault || !is_power_of_2(block_size)) {
 		ksft_test_result_skip("cbo.zero check\n");
 		return;
 	}
@@ -148,7 +214,7 @@ static void test_zicboz(void *arg)
 			if (mem[i * block_size + j] != expected) {
 				ksft_test_result_fail("cbo.zero check\n");
 				ksft_print_msg("cbo.zero check: mem[%llu] != 0x%x\n",
-					       i * block_size + j, expected);
+						   i * block_size + j, expected);
 				return;
 			}
 		}
@@ -177,7 +243,19 @@ static void check_no_zicbo_cpus(cpu_set_t *cpus, __u64 cbo)
 		rc = riscv_hwprobe(&pair, 1, sizeof(cpu_set_t), (unsigned long *)&one_cpu, 0);
 		assert(rc == 0 && pair.key == RISCV_HWPROBE_KEY_IMA_EXT_0);
 
-		cbostr = cbo == RISCV_HWPROBE_EXT_ZICBOZ ? "Zicboz" : "Zicbom";
+		switch (cbo) {
+		case RISCV_HWPROBE_EXT_ZICBOZ:
+			cbostr = "Zicboz";
+			break;
+		case RISCV_HWPROBE_EXT_ZICBOM:
+			cbostr = "Zicbom";
+			break;
+		case RISCV_HWPROBE_EXT_ZICBOP:
+			cbostr = "Zicbop";
+			break;
+		default:
+			ksft_exit_fail_msg("Internal error: invalid cbo %llu\n", cbo);
+		}
 
 		if (pair.value & cbo)
 			ksft_exit_fail_msg("%s is only present on a subset of harts.\n"
@@ -194,6 +272,8 @@ enum {
 	TEST_ZICBOM,
 	TEST_NO_ZICBOM,
 	TEST_NO_CBO_INVAL,
+	TEST_ZICBOP,
+	TEST_NO_ZICBOP
 };
 
 static struct test_info {
@@ -206,27 +286,70 @@ static struct test_info {
 	[TEST_ZICBOM]		= { .nr_tests = 3, test_zicbom },
 	[TEST_NO_ZICBOM]	= { .nr_tests = 2, test_no_zicbom },
 	[TEST_NO_CBO_INVAL]	= { .nr_tests = 1, test_no_cbo_inval },
+	[TEST_ZICBOP]		= { .nr_tests = 3, test_zicbop },
+	[TEST_NO_ZICBOP]	= { .nr_tests = 3, test_no_zicbop },
 };
 
-int main(int argc, char **argv)
+static const struct option long_opts[] = {
+	{"sigill", no_argument, 0, 'i'},
+	{"sigsegv", no_argument, 0, 's'},
+	{"sigbus", no_argument, 0, 'b'},
+	{0, 0, 0, 0}
+};
+
+static void install_sigaction(int argc, char **argv)
 {
+	int rc, opt, long_index;
+	bool sigill;
+
 	struct sigaction act = {
 		.sa_sigaction = &sigill_handler,
 		.sa_flags = SA_SIGINFO,
 	};
+
+	long_index = 0;
+	sigill = false;
+
+	while ((opt = getopt_long(argc, argv, "isb", long_opts, &long_index)) != -1) {
+		switch (opt) {
+		case 'i':
+			rc = sigaction(SIGILL, &act, NULL);
+			assert(rc == 0);
+			sigill = true;
+			break;
+		case 's':
+			rc = sigaction(SIGSEGV, &act, NULL);
+			assert(rc == 0);
+			break;
+		case 'b':
+			rc = sigaction(SIGBUS, &act, NULL);
+			assert(rc == 0);
+			break;
+		case '?':
+			fprintf(stderr, "Unknown option or missing arg\n");
+			exit(1);
+		default:
+			break;
+		}
+	}
+
+	if (sigill) {
+		tests[TEST_NO_ZICBOZ].enabled = true;
+		tests[TEST_NO_ZICBOM].enabled = true;
+		tests[TEST_NO_CBO_INVAL].enabled = true;
+		tests[TEST_NO_ZICBOP].enabled = true;
+	}
+}
+
+int main(int argc, char **argv)
+{
 	struct riscv_hwprobe pair;
 	unsigned int plan = 0;
 	cpu_set_t cpus;
 	long rc;
 	int i;
 
-	if (argc > 1 && !strcmp(argv[1], "--sigill")) {
-		rc = sigaction(SIGILL, &act, NULL);
-		assert(rc == 0);
-		tests[TEST_NO_ZICBOZ].enabled = true;
-		tests[TEST_NO_ZICBOM].enabled = true;
-		tests[TEST_NO_CBO_INVAL].enabled = true;
-	}
+	install_sigaction(argc, argv);
 
 	rc = sched_getaffinity(0, sizeof(cpu_set_t), &cpus);
 	assert(rc == 0);
@@ -253,6 +376,13 @@ int main(int argc, char **argv)
 		check_no_zicbo_cpus(&cpus, RISCV_HWPROBE_EXT_ZICBOM);
 	}
 
+	if (pair.value & RISCV_HWPROBE_EXT_ZICBOP) {
+		tests[TEST_ZICBOP].enabled = true;
+		tests[TEST_NO_ZICBOP].enabled = false;
+	} else {
+		check_no_zicbo_cpus(&cpus, RISCV_HWPROBE_EXT_ZICBOP);
+	}
+
 	for (i = 0; i < ARRAY_SIZE(tests); ++i)
 		plan += tests[i].enabled ? tests[i].nr_tests : 0;
 
-- 
2.47.2


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 1/2] riscv: hwprobe: Expose Zicbop extension and its block size
  2025-10-20 15:33 ` [PATCH v3 1/2] riscv: hwprobe: Expose Zicbop extension and its block size Yao Zihong
@ 2025-10-21 23:21   ` Andrew Jones
  0 siblings, 0 replies; 7+ messages in thread
From: Andrew Jones @ 2025-10-21 23:21 UTC (permalink / raw)
  To: Yao Zihong
  Cc: alex, alexghiti, aou, cleger, evan, linux-kernel, linux-riscv,
	palmer, pjw, samuel.holland, shuah, zhangyin2018, zihongyao

On Mon, Oct 20, 2025 at 11:33:08PM +0800, Yao Zihong wrote:
> - Add `RISCV_HWPROBE_EXT_ZICBOP` to report the presence of the
>   Zicbop extension.
> - Add `RISCV_HWPROBE_KEY_ZICBOP_BLOCK_SIZE` to expose the block
>   size (in bytes) when Zicbop is supported.
> - Update hwprobe.rst to document the new extension bit and block
>   size key, following the existing Zicbom/Zicboz style.
> 
> Signed-off-by: Yao Zihong <zihong.plct@isrc.iscas.ac.cn>
> ---
>  Documentation/arch/riscv/hwprobe.rst  | 8 +++++++-
>  arch/riscv/include/asm/hwprobe.h      | 2 +-
>  arch/riscv/include/uapi/asm/hwprobe.h | 2 ++
>  arch/riscv/kernel/sys_hwprobe.c       | 6 ++++++
>  4 files changed, 16 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/arch/riscv/hwprobe.rst b/Documentation/arch/riscv/hwprobe.rst
> index 2f449c9b15bd..52f12af43b9d 100644
> --- a/Documentation/arch/riscv/hwprobe.rst
> +++ b/Documentation/arch/riscv/hwprobe.rst
> @@ -275,6 +275,9 @@ The following keys are defined:
>         ratified in commit 49f49c842ff9 ("Update to Rafified state") of
>         riscv-zabha.
>  
> +  * :c:macro:`RISCV_HWPROBE_EXT_ZICBOP`: The Zicbop extension is supported, as
> +       ratified in commit 3dd606f ("Create cmobase-v1.0.pdf") of riscv-CMOs.
> +
>  * :c:macro:`RISCV_HWPROBE_KEY_CPUPERF_0`: Deprecated.  Returns similar values to
>       :c:macro:`RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF`, but the key was
>       mistakenly classified as a bitmask rather than a value.
> @@ -369,4 +372,7 @@ The following keys are defined:
>  
>      * :c:macro:`RISCV_HWPROBE_VENDOR_EXT_XSFVFWMACCQQQ`: The Xsfvfwmaccqqq
>          vendor extension is supported in version 1.0 of Matrix Multiply Accumulate
> -	Instruction Extensions Specification.
> \ No newline at end of file
> +	Instruction Extensions Specification.
> +
> +* :c:macro:`RISCV_HWPROBE_KEY_ZICBOP_BLOCK_SIZE`: An unsigned int which
> +  represents the size of the Zicbop block in bytes.
> diff --git a/arch/riscv/include/asm/hwprobe.h b/arch/riscv/include/asm/hwprobe.h
> index 948d2b34e94e..2f278c395af9 100644
> --- a/arch/riscv/include/asm/hwprobe.h
> +++ b/arch/riscv/include/asm/hwprobe.h
> @@ -8,7 +8,7 @@
>  
>  #include <uapi/asm/hwprobe.h>
>  
> -#define RISCV_HWPROBE_MAX_KEY 14
> +#define RISCV_HWPROBE_MAX_KEY 15
>  
>  static inline bool riscv_hwprobe_key_is_valid(__s64 key)
>  {
> diff --git a/arch/riscv/include/uapi/asm/hwprobe.h b/arch/riscv/include/uapi/asm/hwprobe.h
> index 5d30a4fae37a..9cc508be54c5 100644
> --- a/arch/riscv/include/uapi/asm/hwprobe.h
> +++ b/arch/riscv/include/uapi/asm/hwprobe.h
> @@ -82,6 +82,7 @@ struct riscv_hwprobe {
>  #define		RISCV_HWPROBE_EXT_ZAAMO		(1ULL << 56)
>  #define		RISCV_HWPROBE_EXT_ZALRSC	(1ULL << 57)
>  #define		RISCV_HWPROBE_EXT_ZABHA		(1ULL << 58)
> +#define		RISCV_HWPROBE_EXT_ZICBOP	(1ULL << 59)
>  #define RISCV_HWPROBE_KEY_CPUPERF_0	5
>  #define		RISCV_HWPROBE_MISALIGNED_UNKNOWN	(0 << 0)
>  #define		RISCV_HWPROBE_MISALIGNED_EMULATED	(1 << 0)
> @@ -107,6 +108,7 @@ struct riscv_hwprobe {
>  #define RISCV_HWPROBE_KEY_ZICBOM_BLOCK_SIZE	12
>  #define RISCV_HWPROBE_KEY_VENDOR_EXT_SIFIVE_0	13
>  #define RISCV_HWPROBE_KEY_VENDOR_EXT_MIPS_0	14
> +#define RISCV_HWPROBE_KEY_ZICBOP_BLOCK_SIZE	15
>  /* Increase RISCV_HWPROBE_MAX_KEY when adding items. */
>  
>  /* Flags */
> diff --git a/arch/riscv/kernel/sys_hwprobe.c b/arch/riscv/kernel/sys_hwprobe.c
> index 000f4451a9d8..7a6ae1327504 100644
> --- a/arch/riscv/kernel/sys_hwprobe.c
> +++ b/arch/riscv/kernel/sys_hwprobe.c
> @@ -113,6 +113,7 @@ static void hwprobe_isa_ext0(struct riscv_hwprobe *pair,
>  		EXT_KEY(ZCB);
>  		EXT_KEY(ZCMOP);
>  		EXT_KEY(ZICBOM);
> +		EXT_KEY(ZICBOP);
>  		EXT_KEY(ZICBOZ);
>  		EXT_KEY(ZICNTR);
>  		EXT_KEY(ZICOND);
> @@ -293,6 +294,11 @@ static void hwprobe_one_pair(struct riscv_hwprobe *pair,
>  		if (hwprobe_ext0_has(cpus, RISCV_HWPROBE_EXT_ZICBOM))
>  			pair->value = riscv_cbom_block_size;
>  		break;
> +	case RISCV_HWPROBE_KEY_ZICBOP_BLOCK_SIZE:
> +		pair->value = 0;
> +		if (hwprobe_ext0_has(cpus, RISCV_HWPROBE_EXT_ZICBOP))
> +			pair->value = riscv_cbop_block_size;
> +		break;
>  	case RISCV_HWPROBE_KEY_HIGHEST_VIRT_ADDRESS:
>  		pair->value = user_max_virt_addr();
>  		break;
> -- 
> 2.47.2
>

Reviewed-by: Andrew Jones <ajones@ventanamicro.com>

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 2/2] selftests/riscv: Add Zicbop prefetch test
  2025-10-20 15:37 ` [PATCH v3 2/2] selftests/riscv: Add Zicbop prefetch test Yao Zihong
@ 2025-10-21 23:32   ` Andrew Jones
  2025-10-23 15:48     ` Yao Zihong
  0 siblings, 1 reply; 7+ messages in thread
From: Andrew Jones @ 2025-10-21 23:32 UTC (permalink / raw)
  To: Yao Zihong
  Cc: alex, alexghiti, aou, cleger, evan, linux-kernel, linux-riscv,
	palmer, pjw, samuel.holland, shuah, zhangyin2018, zihongyao

On Mon, Oct 20, 2025 at 11:37:20PM +0800, Yao Zihong wrote:
> Add selftest to cbo.c to verify Zicbop extension behavior.
> 
> The test checks:
> - That hwprobe correctly reports Zicbop presence and block size.
> - That prefetch instructions execute without exception on valid and NULL
>   addresses when Zicbop is present.
> - That prefetch.{i,r,w} do not trigger SIGILL even when Zicbop is absent,
>   since Zicbop instructions are defined as hints.
> 
> Signed-off-by: Yao Zihong <zihong.plct@isrc.iscas.ac.cn>
> ---
>  tools/testing/selftests/riscv/hwprobe/cbo.c | 188 +++++++++++++++++---
>  1 file changed, 159 insertions(+), 29 deletions(-)
> 
> diff --git a/tools/testing/selftests/riscv/hwprobe/cbo.c b/tools/testing/selftests/riscv/hwprobe/cbo.c
> index 5e96ef785d0d..163228e3f2c7 100644
> --- a/tools/testing/selftests/riscv/hwprobe/cbo.c
> +++ b/tools/testing/selftests/riscv/hwprobe/cbo.c
> @@ -15,24 +15,30 @@
>  #include <linux/compiler.h>
>  #include <linux/kernel.h>
>  #include <asm/ucontext.h>
> +#include <getopt.h>
>  
>  #include "hwprobe.h"
>  #include "../../kselftest.h"
>  
>  #define MK_CBO(fn) le32_bswap((uint32_t)(fn) << 20 | 10 << 15 | 2 << 12 | 0 << 7 | 15)
> +#define MK_PREFETCH(fn) \
> +	le32_bswap(0 << 25 | (uint32_t)(fn) << 20 | 10 << 15 | 6 << 12 | 0 << 7 | 19)
>  
>  static char mem[4096] __aligned(4096) = { [0 ... 4095] = 0xa5 };
>  
> -static bool illegal_insn;
> +static bool got_fault;
>  
>  static void sigill_handler(int sig, siginfo_t *info, void *context)
>  {
>  	unsigned long *regs = (unsigned long *)&((ucontext_t *)context)->uc_mcontext;
>  	uint32_t insn = *(uint32_t *)regs[0];
>  
> -	assert(insn == MK_CBO(regs[11]));
> +	if (regs[12] == 0)
> +		assert(insn == MK_CBO(regs[11]));
> +	else
> +		assert(insn == MK_PREFETCH(regs[11]));
>  
> -	illegal_insn = true;
> +	got_fault = true;
>  	regs[0] += 4;
>  }
>  
> @@ -41,43 +47,75 @@ static void sigill_handler(int sig, siginfo_t *info, void *context)
>  	asm volatile(								\
>  	"mv	a0, %0\n"							\
>  	"li	a1, %1\n"							\
> +	"li	a2, 0\n"							\
>  	".4byte	%2\n"								\
> -	: : "r" (base), "i" (fn), "i" (MK_CBO(fn)) : "a0", "a1", "memory");	\
> +	: : "r" (base), "i" (fn), "i" (MK_CBO(fn)) : "a0", "a1", "a2", "memory");	\
> +})
> +
> +#define prefetch_insn(base, fn)							\
> +({										\
> +	asm volatile(								\
> +	"mv	a0, %0\n"							\
> +	"li	a1, %1\n"							\
> +	"li	a2, 1\n"							\
> +	".4byte	%2\n"								\
> +	: : "r" (base), "i" (fn), "i" (MK_PREFETCH(fn)) : "a0", "a1", "a2");\
>  })
>  
>  static void cbo_inval(char *base) { cbo_insn(base, 0); }
>  static void cbo_clean(char *base) { cbo_insn(base, 1); }
>  static void cbo_flush(char *base) { cbo_insn(base, 2); }
>  static void cbo_zero(char *base)  { cbo_insn(base, 4); }
> +static void prefetch_i(char *base) { prefetch_insn(base, 0); }
> +static void prefetch_r(char *base) { prefetch_insn(base, 1); }
> +static void prefetch_w(char *base) { prefetch_insn(base, 3); }
> +
> +static void test_no_zicbop(void *arg)
> +{
> +	/* Zicbop prefetch.* are HINT instructions. */
> +	ksft_print_msg("Testing Zicbop instructions\n");
> +
> +	got_fault = false;
> +	prefetch_i(&mem[0]);
> +	ksft_test_result(!got_fault, "No prefetch.i\n");
> +
> +	got_fault = false;
> +	prefetch_r(&mem[0]);
> +	ksft_test_result(!got_fault, "No prefetch.r\n");
> +
> +	got_fault = false;
> +	prefetch_w(&mem[0]);
> +	ksft_test_result(!got_fault, "No prefetch.w\n");
> +}
>  
>  static void test_no_cbo_inval(void *arg)
>  {
>  	ksft_print_msg("Testing cbo.inval instruction remain privileged\n");
> -	illegal_insn = false;
> +	got_fault = false;
>  	cbo_inval(&mem[0]);
> -	ksft_test_result(illegal_insn, "No cbo.inval\n");
> +	ksft_test_result(got_fault, "No cbo.inval\n");
>  }
>  
>  static void test_no_zicbom(void *arg)
>  {
>  	ksft_print_msg("Testing Zicbom instructions remain privileged\n");
>  
> -	illegal_insn = false;
> +	got_fault = false;
>  	cbo_clean(&mem[0]);
> -	ksft_test_result(illegal_insn, "No cbo.clean\n");
> +	ksft_test_result(got_fault, "No cbo.clean\n");
>  
> -	illegal_insn = false;
> +	got_fault = false;
>  	cbo_flush(&mem[0]);
> -	ksft_test_result(illegal_insn, "No cbo.flush\n");
> +	ksft_test_result(got_fault, "No cbo.flush\n");
>  }
>  
>  static void test_no_zicboz(void *arg)
>  {
>  	ksft_print_msg("No Zicboz, testing cbo.zero remains privileged\n");
>  
> -	illegal_insn = false;
> +	got_fault = false;
>  	cbo_zero(&mem[0]);
> -	ksft_test_result(illegal_insn, "No cbo.zero\n");
> +	ksft_test_result(got_fault, "No cbo.zero\n");
>  }
>  
>  static bool is_power_of_2(__u64 n)
> @@ -85,6 +123,34 @@ static bool is_power_of_2(__u64 n)
>  	return n != 0 && (n & (n - 1)) == 0;
>  }
>  
> +static void test_zicbop(void *arg)
> +{
> +	struct riscv_hwprobe pair = {
> +		.key = RISCV_HWPROBE_KEY_ZICBOP_BLOCK_SIZE,
> +	};
> +	cpu_set_t *cpus = (cpu_set_t *)arg;
> +	__u64 block_size;
> +	long rc;
> +
> +	rc = riscv_hwprobe(&pair, 1, sizeof(cpu_set_t), (unsigned long *)cpus, 0);
> +	block_size = pair.value;
> +	ksft_test_result(rc == 0 && pair.key == RISCV_HWPROBE_KEY_ZICBOP_BLOCK_SIZE &&
> +			 is_power_of_2(block_size), "Zicbop block size\n");
> +	ksft_print_msg("Zicbop block size: %llu\n", block_size);
> +
> +	got_fault = false;
> +	prefetch_i(&mem[0]);
> +	prefetch_r(&mem[0]);
> +	prefetch_w(&mem[0]);
> +	ksft_test_result(!got_fault, "Zicbop prefetch.* on valid address\n");
> +
> +	got_fault = false;
> +	prefetch_i(NULL);
> +	prefetch_r(NULL);
> +	prefetch_w(NULL);
> +	ksft_test_result(!got_fault, "Zicbop prefetch.* on NULL\n");
> +}
> +
>  static void test_zicbom(void *arg)
>  {
>  	struct riscv_hwprobe pair = {
> @@ -100,13 +166,13 @@ static void test_zicbom(void *arg)
>  			 is_power_of_2(block_size), "Zicbom block size\n");
>  	ksft_print_msg("Zicbom block size: %llu\n", block_size);
>  
> -	illegal_insn = false;
> +	got_fault = false;
>  	cbo_clean(&mem[block_size]);
> -	ksft_test_result(!illegal_insn, "cbo.clean\n");
> +	ksft_test_result(!got_fault, "cbo.clean\n");
>  
> -	illegal_insn = false;
> +	got_fault = false;
>  	cbo_flush(&mem[block_size]);
> -	ksft_test_result(!illegal_insn, "cbo.flush\n");
> +	ksft_test_result(!got_fault, "cbo.flush\n");
>  }
>  
>  static void test_zicboz(void *arg)
> @@ -125,11 +191,11 @@ static void test_zicboz(void *arg)
>  			 is_power_of_2(block_size), "Zicboz block size\n");
>  	ksft_print_msg("Zicboz block size: %llu\n", block_size);
>  
> -	illegal_insn = false;
> +	got_fault = false;
>  	cbo_zero(&mem[block_size]);
> -	ksft_test_result(!illegal_insn, "cbo.zero\n");
> +	ksft_test_result(!got_fault, "cbo.zero\n");
>  
> -	if (illegal_insn || !is_power_of_2(block_size)) {
> +	if (got_fault || !is_power_of_2(block_size)) {
>  		ksft_test_result_skip("cbo.zero check\n");
>  		return;
>  	}
> @@ -148,7 +214,7 @@ static void test_zicboz(void *arg)
>  			if (mem[i * block_size + j] != expected) {
>  				ksft_test_result_fail("cbo.zero check\n");
>  				ksft_print_msg("cbo.zero check: mem[%llu] != 0x%x\n",
> -					       i * block_size + j, expected);
> +						   i * block_size + j, expected);

Undesired reformatting

>  				return;
>  			}
>  		}
> @@ -177,7 +243,19 @@ static void check_no_zicbo_cpus(cpu_set_t *cpus, __u64 cbo)
>  		rc = riscv_hwprobe(&pair, 1, sizeof(cpu_set_t), (unsigned long *)&one_cpu, 0);
>  		assert(rc == 0 && pair.key == RISCV_HWPROBE_KEY_IMA_EXT_0);
>  
> -		cbostr = cbo == RISCV_HWPROBE_EXT_ZICBOZ ? "Zicboz" : "Zicbom";
> +		switch (cbo) {
> +		case RISCV_HWPROBE_EXT_ZICBOZ:
> +			cbostr = "Zicboz";
> +			break;
> +		case RISCV_HWPROBE_EXT_ZICBOM:
> +			cbostr = "Zicbom";
> +			break;
> +		case RISCV_HWPROBE_EXT_ZICBOP:
> +			cbostr = "Zicbop";
> +			break;
> +		default:
> +			ksft_exit_fail_msg("Internal error: invalid cbo %llu\n", cbo);
> +		}
>  
>  		if (pair.value & cbo)
>  			ksft_exit_fail_msg("%s is only present on a subset of harts.\n"
> @@ -194,6 +272,8 @@ enum {
>  	TEST_ZICBOM,
>  	TEST_NO_ZICBOM,
>  	TEST_NO_CBO_INVAL,
> +	TEST_ZICBOP,
> +	TEST_NO_ZICBOP
>  };
>  
>  static struct test_info {
> @@ -206,27 +286,70 @@ static struct test_info {
>  	[TEST_ZICBOM]		= { .nr_tests = 3, test_zicbom },
>  	[TEST_NO_ZICBOM]	= { .nr_tests = 2, test_no_zicbom },
>  	[TEST_NO_CBO_INVAL]	= { .nr_tests = 1, test_no_cbo_inval },
> +	[TEST_ZICBOP]		= { .nr_tests = 3, test_zicbop },
> +	[TEST_NO_ZICBOP]	= { .nr_tests = 3, test_no_zicbop },
>  };
>  
> -int main(int argc, char **argv)
> +static const struct option long_opts[] = {
> +	{"sigill", no_argument, 0, 'i'},
> +	{"sigsegv", no_argument, 0, 's'},
> +	{"sigbus", no_argument, 0, 'b'},
> +	{0, 0, 0, 0}
> +};
> +
> +static void install_sigaction(int argc, char **argv)
>  {
> +	int rc, opt, long_index;
> +	bool sigill;
> +
>  	struct sigaction act = {
>  		.sa_sigaction = &sigill_handler,
>  		.sa_flags = SA_SIGINFO,
>  	};
> +
> +	long_index = 0;
> +	sigill = false;
> +
> +	while ((opt = getopt_long(argc, argv, "isb", long_opts, &long_index)) != -1) {
> +		switch (opt) {
> +		case 'i':
> +			rc = sigaction(SIGILL, &act, NULL);
> +			assert(rc == 0);
> +			sigill = true;
> +			break;
> +		case 's':
> +			rc = sigaction(SIGSEGV, &act, NULL);
> +			assert(rc == 0);
> +			break;
> +		case 'b':
> +			rc = sigaction(SIGBUS, &act, NULL);
> +			assert(rc == 0);
> +			break;

Should we just unconditionally register handlers for SIGSEGV and SIGBUS?

> +		case '?':
> +			fprintf(stderr, "Unknown option or missing arg\n");
> +			exit(1);
> +		default:
> +			break;
> +		}
> +	}
> +
> +	if (sigill) {
> +		tests[TEST_NO_ZICBOZ].enabled = true;
> +		tests[TEST_NO_ZICBOM].enabled = true;
> +		tests[TEST_NO_CBO_INVAL].enabled = true;
> +		tests[TEST_NO_ZICBOP].enabled = true;
> +	}
> +}
> +
> +int main(int argc, char **argv)
> +{
>  	struct riscv_hwprobe pair;
>  	unsigned int plan = 0;
>  	cpu_set_t cpus;
>  	long rc;
>  	int i;
>  
> -	if (argc > 1 && !strcmp(argv[1], "--sigill")) {
> -		rc = sigaction(SIGILL, &act, NULL);
> -		assert(rc == 0);
> -		tests[TEST_NO_ZICBOZ].enabled = true;
> -		tests[TEST_NO_ZICBOM].enabled = true;
> -		tests[TEST_NO_CBO_INVAL].enabled = true;
> -	}
> +	install_sigaction(argc, argv);
>  
>  	rc = sched_getaffinity(0, sizeof(cpu_set_t), &cpus);
>  	assert(rc == 0);
> @@ -253,6 +376,13 @@ int main(int argc, char **argv)
>  		check_no_zicbo_cpus(&cpus, RISCV_HWPROBE_EXT_ZICBOM);
>  	}
>  
> +	if (pair.value & RISCV_HWPROBE_EXT_ZICBOP) {
> +		tests[TEST_ZICBOP].enabled = true;
> +		tests[TEST_NO_ZICBOP].enabled = false;
> +	} else {
> +		check_no_zicbo_cpus(&cpus, RISCV_HWPROBE_EXT_ZICBOP);
> +	}
> +
>  	for (i = 0; i < ARRAY_SIZE(tests); ++i)
>  		plan += tests[i].enabled ? tests[i].nr_tests : 0;
>  
> -- 
> 2.47.2
>

Otherwise

Reviewed-by: Andrew Jones <ajones@ventanamicro.com>

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 2/2] selftests/riscv: Add Zicbop prefetch test
  2025-10-21 23:32   ` Andrew Jones
@ 2025-10-23 15:48     ` Yao Zihong
  2025-10-30 21:16       ` Andrew Jones
  0 siblings, 1 reply; 7+ messages in thread
From: Yao Zihong @ 2025-10-23 15:48 UTC (permalink / raw)
  To: ajones
  Cc: alex, alexghiti, aou, cleger, evan, linux-kernel, linux-riscv,
	palmer, pjw, samuel.holland, shuah, zhangyin2018, zihong.plct,
	zihongyao

> Undesired reformatting
My bad. It will be fixed in the next version.

> Should we just unconditionally register handlers for SIGSEGV and SIGBUS?
I think it depends on what the flags --sig{segv,ill,bus} are intended to mean:

  a) We intend to handle these faults that might be raised inside the test
     (i.e., catch and convert them into pass/fail results without crashing the
     test binary, rather than letting something else handle them externally).
  b) We expect these signals to be raised as part of the test scenario and
     handle them within the test program accordingly.

I'm not sure if (a) is appropriate, since it might mess up someone’s CI
or other automation setups.

If we’re going with (b), then registering handlers for SIGSEGV and SIGBUS
based on flags would be inconsistent with that semantics, since prefetch.*
should never legitimately raise them. In that case, this design probably
doesn’t make sense. Would it also make sense to rename the '--sigill' flag
to make this clearer?

Thanks,
Zihong


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 2/2] selftests/riscv: Add Zicbop prefetch test
  2025-10-23 15:48     ` Yao Zihong
@ 2025-10-30 21:16       ` Andrew Jones
  0 siblings, 0 replies; 7+ messages in thread
From: Andrew Jones @ 2025-10-30 21:16 UTC (permalink / raw)
  To: Yao Zihong
  Cc: alex, alexghiti, aou, cleger, evan, linux-kernel, linux-riscv,
	palmer, pjw, samuel.holland, shuah, zhangyin2018, zihongyao

On Thu, Oct 23, 2025 at 11:48:18PM +0800, Yao Zihong wrote:
> > Undesired reformatting
> My bad. It will be fixed in the next version.
> 
> > Should we just unconditionally register handlers for SIGSEGV and SIGBUS?
> I think it depends on what the flags --sig{segv,ill,bus} are intended to mean:
> 
>   a) We intend to handle these faults that might be raised inside the test
>      (i.e., catch and convert them into pass/fail results without crashing the
>      test binary, rather than letting something else handle them externally).
>   b) We expect these signals to be raised as part of the test scenario and
>      handle them within the test program accordingly.
> 
> I'm not sure if (a) is appropriate, since it might mess up someone’s CI
> or other automation setups.

The intention of --sigill is to tell the test that a SIGILL is expected
and tests should be run to ensure they are raised. We should probably
allow that expectation to be extension specific though, i.e. have both a
--zicbom-raises-sigill and a --zicboz-raises-sigill

> 
> If we’re going with (b), then registering handlers for SIGSEGV and SIGBUS
> based on flags would be inconsistent with that semantics, since prefetch.*
> should never legitimately raise them. In that case, this design probably
> doesn’t make sense. Would it also make sense to rename the '--sigill' flag
> to make this clearer?

Since SIGSEGV and SIGBUS are never expected, then we could always handle
those in order to report failures, but we should narrow the time the
handlers are registered to be just around the use of instructions under
test.

Thanks,
drew

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2025-10-30 21:17 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-20 15:29 [PATCH v3 0/2] riscv: hwprobe: Add Zicbop support Yao Zihong
2025-10-20 15:33 ` [PATCH v3 1/2] riscv: hwprobe: Expose Zicbop extension and its block size Yao Zihong
2025-10-21 23:21   ` Andrew Jones
2025-10-20 15:37 ` [PATCH v3 2/2] selftests/riscv: Add Zicbop prefetch test Yao Zihong
2025-10-21 23:32   ` Andrew Jones
2025-10-23 15:48     ` Yao Zihong
2025-10-30 21:16       ` Andrew Jones

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox