From: Sailesh Nandanavanam <saileshnandanavanam@gmail.com>
To: andersson@kernel.org, mathieu.poirier@linaro.org
Cc: linux-remoteproc@vger.kernel.org, linux-kernel@vger.kernel.org,
Sailesh Nandanavanam <saileshnandanavanam@gmail.com>
Subject: [RFC PATCH] remoteproc: core: add KUnit tests for rproc_check_carveout_da()
Date: Sun, 27 Sep 2026 22:54:28 +0530 [thread overview]
Message-ID: <20260927172428.110718-1-saileshnandanavanam@gmail.com> (raw)
Add a KUnit test suite covering rproc_check_carveout_da(), the
internal helper that validates a resource-table-requested (da, len)
pair against an already-allocated carveout's bounds.
The test is #include'd directly into remoteproc_core.c (a pattern
already used by mm/damon/) rather than built as a separate module,
since rproc_check_carveout_da() is static and this avoids adding an
exported symbol purely for test visibility.
Six cases are included, exercising every branch of the function:
requested length exceeding the carveout, a specific da requested
against a carveout with none set, a da before the carveout's start,
a (da + len) past the carveout's end, an exact boundary fit, and the
FW_RSC_ADDR_ANY skip-check path.
Verified via:
- QEMU (x86_64), booting a kernel with CONFIG_REMOTEPROC_KUNIT_TEST=y
- tools/testing/kunit/kunit.py under UML
All 6 cases pass in both environments:
# remoteproc_core: pass:6 fail:0 skip:0 total:6
This is posted as an RFC to check whether this structure (test
headers embedded per-file, DAMON-style) is the preferred approach for
remoteproc before expanding coverage to other files in the driver
(remoteproc_virtio.c, remoteproc_sysfs.c, etc.).
Signed-off-by: Sailesh Nandanavanam <saileshnandanavanam@gmail.com>
---
drivers/remoteproc/Kconfig | 10 ++
drivers/remoteproc/remoteproc_core.c | 4 +
.../remoteproc/tests/remoteproc_core-kunit.h | 130 ++++++++++++++++++
3 files changed, 144 insertions(+)
create mode 100644 drivers/remoteproc/tests/remoteproc_core-kunit.h
diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 5b56b2dcc725..dc5a8f483693 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -390,6 +390,16 @@ config XLNX_R5_REMOTEPROC
It's safe to say N if not interested in using RPU r5f cores.
+config REMOTEPROC_KUNIT_TEST
+ bool "KUnit tests for remoteproc core" if !KUNIT_ALL_TESTS
+ depends on REMOTEPROC && KUNIT=y
+ default KUNIT_ALL_TESTS
+ help
+ Enable KUnit tests for the remoteproc core, covering internal
+ helpers such as carveout/address-translation logic.
+
+ If unsure, say N.
+
endif # REMOTEPROC
endmenu
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index 1ed406714849..4f0ad28305d2 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -2839,3 +2839,7 @@ static void __exit remoteproc_exit(void)
module_exit(remoteproc_exit);
MODULE_DESCRIPTION("Generic Remote Processor Framework");
+
+#if IS_ENABLED(CONFIG_REMOTEPROC_KUNIT_TEST)
+#include "tests/remoteproc_core-kunit.h"
+#endif
diff --git a/drivers/remoteproc/tests/remoteproc_core-kunit.h b/drivers/remoteproc/tests/remoteproc_core-kunit.h
new file mode 100644
index 000000000000..615a854fffbf
--- /dev/null
+++ b/drivers/remoteproc/tests/remoteproc_core-kunit.h
@@ -0,0 +1,130 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _REMOTEPROC_CORE_KUNIT_H
+#define _REMOTEPROC_CORE_KUNIT_H
+
+#include <kunit/test.h>
+
+/*
+ * Tests for rproc_check_carveout_da().
+ *
+ * The function is static, so this header is #include'd directly at the
+ * bottom of remoteproc_core.c (see CONFIG_REMOTEPROC_KUNIT_TEST), giving
+ * it access to the symbol despite the lack of external linkage.
+ *
+ * rproc_check_carveout_da() only touches &rproc->dev for dev_err() on
+ * its failure paths, so a zeroed struct rproc is sufficient here -- no
+ * device registration needed. dev_err()'s formatting chain
+ * (dev_driver_string() -> "" on NULL driver/bus/class, dev_name() ->
+ * NULL on an unregistered device, and the kernel's own %s NULL guard
+ * in lib/vsprintf.c) is safe end-to-end against a bare zeroed device.
+ */
+
+static void rproc_test_check_carveout_len_exceeds(struct kunit *test)
+{
+ struct rproc rproc = { 0 };
+ struct rproc_mem_entry mem = { 0 };
+ int ret;
+
+ /* mem->len = 0x100; request len 0x200 with no da constraint */
+ mem.da = FW_RSC_ADDR_ANY;
+ mem.len = 0x100;
+
+ ret = rproc_check_carveout_da(&rproc, &mem, FW_RSC_ADDR_ANY, 0x200);
+ KUNIT_EXPECT_EQ(test, ret, -EINVAL);
+}
+
+static void rproc_test_check_carveout_da_any_mismatch(struct kunit *test)
+{
+ struct rproc rproc = { 0 };
+ struct rproc_mem_entry mem = { 0 };
+ int ret;
+
+ /* caller wants a specific da, but the carveout itself has none set */
+ mem.da = FW_RSC_ADDR_ANY;
+ mem.len = 0x100;
+
+ ret = rproc_check_carveout_da(&rproc, &mem, 0x1000, 0x50);
+ KUNIT_EXPECT_EQ(test, ret, -EINVAL);
+}
+
+static void rproc_test_check_carveout_da_negative_delta(struct kunit *test)
+{
+ struct rproc rproc = { 0 };
+ struct rproc_mem_entry mem = { 0 };
+ int ret;
+
+ /* requested da (0x1000) lies before the carveout's da (0x2000) */
+ mem.da = 0x2000;
+ mem.len = 0x100;
+
+ ret = rproc_check_carveout_da(&rproc, &mem, 0x1000, 0x10);
+ KUNIT_EXPECT_EQ(test, ret, -EINVAL);
+}
+
+static void rproc_test_check_carveout_da_exceeds_end(struct kunit *test)
+{
+ struct rproc rproc = { 0 };
+ struct rproc_mem_entry mem = { 0 };
+ int ret;
+
+ /* delta (0x80) + len (0x100) = 0x180, one byte over mem->len (0x100) -> 0x180 > 0x100 */
+ mem.da = 0x1000;
+ mem.len = 0x100;
+
+ ret = rproc_check_carveout_da(&rproc, &mem, 0x1080, 0x100);
+ KUNIT_EXPECT_EQ(test, ret, -EINVAL);
+}
+
+static void rproc_test_check_carveout_da_exact_fit(struct kunit *test)
+{
+ struct rproc rproc = { 0 };
+ struct rproc_mem_entry mem = { 0 };
+ int ret;
+
+ /*
+ * Boundary case: delta (0xf0) + len (0x10) == mem->len (0x100)
+ * exactly. The check is "> mem->len", so this must pass -- this
+ * is exactly the kind of edge an off-by-one would break.
+ */
+ mem.da = 0x1000;
+ mem.len = 0x100;
+
+ ret = rproc_check_carveout_da(&rproc, &mem, 0x10f0, 0x10);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+}
+
+static void rproc_test_check_carveout_da_any_skip_check(struct kunit *test)
+{
+ struct rproc rproc = { 0 };
+ struct rproc_mem_entry mem = { 0 };
+ int ret;
+
+ /*
+ * da == FW_RSC_ADDR_ANY -> address check is skipped entirely,
+ * only len is validated against mem->len.
+ */
+ mem.da = 0x1000;
+ mem.len = 0x100;
+
+ ret = rproc_check_carveout_da(&rproc, &mem, FW_RSC_ADDR_ANY, 0x50);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+}
+
+static struct kunit_case rproc_core_test_cases[] = {
+ KUNIT_CASE(rproc_test_check_carveout_len_exceeds),
+ KUNIT_CASE(rproc_test_check_carveout_da_any_mismatch),
+ KUNIT_CASE(rproc_test_check_carveout_da_negative_delta),
+ KUNIT_CASE(rproc_test_check_carveout_da_exceeds_end),
+ KUNIT_CASE(rproc_test_check_carveout_da_exact_fit),
+ KUNIT_CASE(rproc_test_check_carveout_da_any_skip_check),
+ {}
+};
+
+static struct kunit_suite rproc_core_test_suite = {
+ .name = "remoteproc_core",
+ .test_cases = rproc_core_test_cases,
+};
+
+kunit_test_suite(rproc_core_test_suite);
+
+#endif /* _REMOTEPROC_CORE_KUNIT_H */
--
2.34.1
reply other threads:[~2026-09-27 17:24 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=20260927172428.110718-1-saileshnandanavanam@gmail.com \
--to=saileshnandanavanam@gmail.com \
--cc=andersson@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-remoteproc@vger.kernel.org \
--cc=mathieu.poirier@linaro.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
all inboxes | Powered by JetHome®