[PATCH 7/7] platform: virt: add WorldGuard HWISO failure-mode SBIUNIT test
Raymond Mao
raymondmaoca at gmail.com
Tue May 19 13:33:31 PDT 2026
From: Raymond Mao <raymond.mao at riscstar.com>
Extend the generic HWISO SBIUNIT test hook interface with a
failure-test callback and invoke it from a new hwiso_failure_mode_test
case.
Implement the QEMU virt WorldGuard failure-mode test by switching into
domain at 0's WorldGuard state, issuing an intentional denied store to a
protected DRAM address, and verifying that the access raises the
expected store access fault with the faulting address recorded in
tval.
Also print the captured trap cause and trap value so the negative-path
result is visible in the runtime log.
Signed-off-by: Raymond Mao <raymond.mao at riscstar.com>
---
include/sbi/sbi_hwiso_test.h | 2 ++
lib/sbi/sbi_hwiso_test.c | 6 ++++
lib/sbi/sbi_hwiso_testlib.c | 11 ++++++
.../generic/virt/qemu_virt_wgchecker_test.c | 35 +++++++++++++++++++
4 files changed, 54 insertions(+)
diff --git a/include/sbi/sbi_hwiso_test.h b/include/sbi/sbi_hwiso_test.h
index 3970df5a..354e8d17 100644
--- a/include/sbi/sbi_hwiso_test.h
+++ b/include/sbi/sbi_hwiso_test.h
@@ -15,6 +15,7 @@
#ifdef CONFIG_SBIUNIT
struct sbi_hwiso_test_ops {
void (*boot_test)(struct sbiunit_test_case *test);
+ void (*failure_test)(struct sbiunit_test_case *test);
void (*domain_state_test)(struct sbiunit_test_case *test,
const struct sbi_domain *dom, void *ctx);
void (*domain_quiesce_test)(struct sbiunit_test_case *test,
@@ -24,6 +25,7 @@ struct sbi_hwiso_test_ops {
int sbi_hwiso_test_register(const struct sbi_hwiso_ops *ops,
const struct sbi_hwiso_test_ops *test_ops);
void sbi_hwiso_test_boot(struct sbiunit_test_case *test);
+void sbi_hwiso_test_failure(struct sbiunit_test_case *test);
void sbi_hwiso_test_domain_state(struct sbiunit_test_case *test,
const struct sbi_domain *dom);
void sbi_hwiso_test_domain_quiesced(struct sbiunit_test_case *test,
diff --git a/lib/sbi/sbi_hwiso_test.c b/lib/sbi/sbi_hwiso_test.c
index 716596e2..6b8384d4 100644
--- a/lib/sbi/sbi_hwiso_test.c
+++ b/lib/sbi/sbi_hwiso_test.c
@@ -96,6 +96,11 @@ static void hwiso_boot_test(struct sbiunit_test_case *test)
sbi_hwiso_test_boot(test);
}
+static void hwiso_failure_mode_test(struct sbiunit_test_case *test)
+{
+ sbi_hwiso_test_failure(test);
+}
+
static void hwiso_domain_switch_test(struct sbiunit_test_case *test)
{
struct sbi_domain *cur_dom = sbi_domain_thishart_ptr();
@@ -160,6 +165,7 @@ out:
static struct sbiunit_test_case hwiso_test_cases[] = {
SBIUNIT_TEST_CASE(hwiso_boot_test),
+ SBIUNIT_TEST_CASE(hwiso_failure_mode_test),
SBIUNIT_TEST_CASE(hwiso_domain_switch_test),
SBIUNIT_END_CASE,
};
diff --git a/lib/sbi/sbi_hwiso_testlib.c b/lib/sbi/sbi_hwiso_testlib.c
index 2a988088..2dfb8646 100644
--- a/lib/sbi/sbi_hwiso_testlib.c
+++ b/lib/sbi/sbi_hwiso_testlib.c
@@ -64,6 +64,17 @@ void sbi_hwiso_test_boot(struct sbiunit_test_case *test)
}
}
+void sbi_hwiso_test_failure(struct sbiunit_test_case *test)
+{
+ struct sbi_hwiso_test_node *entry;
+
+ sbi_list_for_each_entry(entry, &hwiso_test_ops_list, node) {
+ if (!entry->test_ops->failure_test)
+ continue;
+ entry->test_ops->failure_test(test);
+ }
+}
+
void sbi_hwiso_test_domain_state(struct sbiunit_test_case *test,
const struct sbi_domain *dom)
{
diff --git a/platform/generic/virt/qemu_virt_wgchecker_test.c b/platform/generic/virt/qemu_virt_wgchecker_test.c
index 0eeaa3a0..eaaa39f7 100644
--- a/platform/generic/virt/qemu_virt_wgchecker_test.c
+++ b/platform/generic/virt/qemu_virt_wgchecker_test.c
@@ -7,14 +7,17 @@
#include <libfdt.h>
#include <sbi/riscv_encoding.h>
#include <sbi/riscv_io.h>
+#include <sbi/sbi_console.h>
#include <sbi/sbi_domain.h>
#include <sbi/sbi_error.h>
#include <sbi/sbi_hart.h>
#include <sbi/sbi_hwiso.h>
#include <sbi/sbi_hwiso_test.h>
#include <sbi/sbi_scratch.h>
+#include <sbi/sbi_trap.h>
#include <sbi/sbi_string.h>
#include <sbi/sbi_unit_test.h>
+#include <sbi/sbi_unpriv.h>
#include <sbi_utils/fdt/fdt_helper.h>
#include <wgchecker2.h>
#include <worldguard.h>
@@ -40,6 +43,8 @@ struct qemu_virt_wg_expect {
u32 slwid;
};
+#define QEMU_VIRT_WG_DENIED_STORE_ADDR 0xc0001000UL
+
static u64 qemu_virt_wg_mmio_read64(unsigned long addr)
{
#if __riscv_xlen != 32
@@ -314,8 +319,38 @@ static void qemu_virt_wg_boot_test(struct sbiunit_test_case *test)
0);
}
+static void qemu_virt_wg_failure_test(struct sbiunit_test_case *test)
+{
+ struct sbi_domain *cur_dom = sbi_domain_thishart_ptr();
+ struct sbi_domain *dom0 = qemu_virt_wg_find_domain("domain at 0");
+ struct sbi_trap_info trap = { 0 };
+
+ SBIUNIT_ASSERT_NE(test, cur_dom, NULL);
+ SBIUNIT_ASSERT_NE(test, dom0, NULL);
+
+ if (cur_dom != dom0) {
+ sbi_hwiso_domain_exit(cur_dom, dom0);
+ sbi_hwiso_domain_enter(dom0, cur_dom);
+ }
+
+ sbi_store_u32((u32 *)QEMU_VIRT_WG_DENIED_STORE_ADDR, 0x5a5aa5a5U,
+ &trap);
+
+ if (cur_dom != dom0) {
+ sbi_hwiso_domain_exit(dom0, cur_dom);
+ sbi_hwiso_domain_enter(cur_dom, dom0);
+ }
+
+ sbi_printf("[WG TEST] failure trap cause=0x%lx tval=0x%lx\n",
+ trap.cause, trap.tval);
+
+ SBIUNIT_ASSERT_EQ(test, trap.cause, CAUSE_STORE_ACCESS);
+ SBIUNIT_ASSERT_EQ(test, trap.tval, QEMU_VIRT_WG_DENIED_STORE_ADDR);
+}
+
const struct sbi_hwiso_test_ops qemu_virt_worldguard_test_ops = {
.boot_test = qemu_virt_wg_boot_test,
+ .failure_test = qemu_virt_wg_failure_test,
.domain_state_test = qemu_virt_wg_assert_state,
.domain_quiesce_test = qemu_virt_wg_assert_quiesced,
};
--
2.25.1
More information about the opensbi
mailing list