linux/drivers/of/of_kunit_helpers.c
Stephen Boyd 6e0391e48c of: Skip kunit tests when arm64+ACPI doesn't populate root node
A root node is required to apply DT overlays. A root node is usually
present after commit 7b937cc243 ("of: Create of_root if no dtb
provided by firmware"), except for on arm64 systems booted with ACPI
tables. In that case, the root node is intentionally not populated
because it would "allow DT devices to be instantiated atop an ACPI base
system"[1].

Introduce an OF function that skips the kunit test if the root node
isn't populated. Limit the test to when both CONFIG_ARM64 and
CONFIG_ACPI are set, because otherwise the lack of a root node is a bug.
Make the function private and take a kunit test parameter so that it
can't be abused to test for the presence of the root node in non-test
code.

Use this function to skip tests that require the root node. Currently
that's the DT tests and any tests that apply overlays.

Reported-by: Guenter Roeck <linux@roeck-us.net>
Closes: https://lore.kernel.org/r/6cd337fb-38f0-41cb-b942-5844b84433db@roeck-us.net
Link: https://lore.kernel.org/r/Zd4dQpHO7em1ji67@FVFF77S0Q05N.cambridge.arm.com [1]
Fixes: 893ecc6d2d ("of: Add KUnit test to confirm DTB is loaded")
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Tested-by: Guenter Roeck <linux@roeck-us.net>
Acked-by: Mark Rutland <mark.rutland@arm.com>
Link: https://lore.kernel.org/r/20241009204133.1169931-1-sboyd@kernel.org
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
2024-10-10 12:43:01 -05:00

93 lines
2.4 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* Test managed DeviceTree APIs
*/
#include <linux/of.h>
#include <linux/of_fdt.h>
#include <kunit/of.h>
#include <kunit/test.h>
#include <kunit/resource.h>
#include "of_private.h"
/**
* of_root_kunit_skip() - Skip test if the root node isn't populated
* @test: test to skip if the root node isn't populated
*/
void of_root_kunit_skip(struct kunit *test)
{
if (IS_ENABLED(CONFIG_ARM64) && IS_ENABLED(CONFIG_ACPI) && !of_root)
kunit_skip(test, "arm64+acpi doesn't populate a root node");
}
EXPORT_SYMBOL_GPL(of_root_kunit_skip);
#if defined(CONFIG_OF_OVERLAY) && defined(CONFIG_OF_EARLY_FLATTREE)
static void of_overlay_fdt_apply_kunit_exit(void *ovcs_id)
{
of_overlay_remove(ovcs_id);
}
/**
* of_overlay_fdt_apply_kunit() - Test managed of_overlay_fdt_apply()
* @test: test context
* @overlay_fdt: device tree overlay to apply
* @overlay_fdt_size: size in bytes of @overlay_fdt
* @ovcs_id: identifier of overlay, used to remove the overlay
*
* Just like of_overlay_fdt_apply(), except the overlay is managed by the test
* case and is automatically removed with of_overlay_remove() after the test
* case concludes.
*
* Return: 0 on success, negative errno on failure
*/
int of_overlay_fdt_apply_kunit(struct kunit *test, void *overlay_fdt,
u32 overlay_fdt_size, int *ovcs_id)
{
int ret;
int *copy_id;
of_root_kunit_skip(test);
copy_id = kunit_kmalloc(test, sizeof(*copy_id), GFP_KERNEL);
if (!copy_id)
return -ENOMEM;
ret = of_overlay_fdt_apply(overlay_fdt, overlay_fdt_size,
ovcs_id, NULL);
if (ret)
return ret;
*copy_id = *ovcs_id;
return kunit_add_action_or_reset(test, of_overlay_fdt_apply_kunit_exit,
copy_id);
}
EXPORT_SYMBOL_GPL(of_overlay_fdt_apply_kunit);
#endif
KUNIT_DEFINE_ACTION_WRAPPER(of_node_put_wrapper, of_node_put, struct device_node *);
/**
* of_node_put_kunit() - Test managed of_node_put()
* @test: test context
* @node: node to pass to `of_node_put()`
*
* Just like of_node_put(), except the node is managed by the test case and is
* automatically put with of_node_put() after the test case concludes.
*/
void of_node_put_kunit(struct kunit *test, struct device_node *node)
{
if (kunit_add_action(test, of_node_put_wrapper, node)) {
KUNIT_FAIL(test,
"Can't allocate a kunit resource to put of_node\n");
}
}
EXPORT_SYMBOL_GPL(of_node_put_kunit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Test managed DeviceTree APIs");