mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
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®