of: populate of_root node if bootloader doesn't
Subsystems (5)
v4 cover of: populate of_root node if bootloader doesn't
Arch maintainers, please ack/review patches.
This is a resend of a series from Frank last year[1]. I worked in Rob's review comments to unconditionally call unflatten_device_tree() and fixup/audit calls to of_have_populated_dt() so that behavior doesn't change.
I need this series so I can add DT based tests in the clk framework. Either I can merge it through the clk tree once everyone is happy, or Rob can merge it through the DT tree and provide some branch so I can base clk patches on it.
Changes from v3 (https://lore.kernel.org/r/[email protected]):
* Made OF_UNITTEST depend on OF_EARLY_FLATREE
* Made OF_EARLY_FLATREE depend on absence of arches that don't call unflatten_device_tree()
* Added of_ prefix to dtb_ prefixed KUnit tests
* Picked up tags
Changes from v2 (https://lore.kernel.org/r/[email protected]):
* Reorder patches to have OF changes largely first
* No longer modify initial_boot_params if ACPI=y
* Put arm64 patch back to v1
Changes from v1 (https://lore.kernel.org/r/[email protected]):
* x86 patch included
* arm64 knocks out initial dtb if acpi is in use
* keep Kconfig hidden but def_bool enabled otherwise
Changes from Frank's series[1]:
* Add a DTB loaded kunit test
* Make of_have_populated_dt() return false if the DTB isn't from the bootloader
* Architecture calls made unconditional so that a root node is always made
Frank Rowand (2):
of: Create of_root if no dtb provided by firmware
of: unittest: treat missing of_root as error instead of fixing up
Stephen Boyd (5):
of: Always unflatten in unflatten_and_copy_device_tree()
um: Unconditionally call unflatten_device_tree() x86/of: Unconditionally call unflatten_and_copy_device_tree()
arm64: Unconditionally call unflatten_device_tree()
of: Add KUnit test to confirm DTB is loaded
arch/arm64/kernel/setup.c | 3 +- arch/um/kernel/dtb.c | 14 ++++---- arch/x86/kernel/devicetree.c | 24 +++++++------- drivers/of/.kunitconfig | 3 ++ drivers/of/Kconfig | 14 ++++++-- drivers/of/Makefile | 4 ++- drivers/of/empty_root.dts | 6 ++++ drivers/of/fdt.c | 64 +++++++++++++++++++++++++++--------- drivers/of/of_test.c | 57 ++++++++++++++++++++++++++++++++ drivers/of/platform.c | 3 -- drivers/of/unittest.c | 16 +++------ include/linux/of.h | 25 ++++++++------ 12 files changed, 168 insertions(+), 65 deletions(-) create mode 100644 drivers/of/.kunitconfig create mode 100644 drivers/of/empty_root.dts create mode 100644 drivers/of/of_test.c
[1] https://lore.kernel.org/r/[email protected]
base-commit: 6613476e225e090cc9aad49be7fa504e290dd33d
Signature · 2 lines
https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/ https://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git
PATCH v4 1/7 of: Always unflatten in unflatten_and_copy_device_tree()
We want to populate an empty DT whenever CONFIG_OF is enabled so that overlays can be applied and the DT unit tests can be run. Make unflatten_and_copy_device_tree() stop printing a warning if the 'initial_boot_params' pointer is NULL. Instead, simply copy the dtb if there is one and then unflatten it. If there isn't a DT to copy, then the call to unflatten_device_tree() is largely a no-op, so nothing really changes here.
--- drivers/of/fdt.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-)
drivers/of/fdt.c +17 -15
@@ -1318,6 +1318,21 @@ bool __init early_init_dt_scan(void *params)return true; } +static void *__init copy_device_tree (void *fdt) +{ +int size; +void *dt; + + size =fdt_totalsize (fdt); + dt =early_init_dt_alloc_memory_arch (size, +roundup_pow_of_two (FDT_V17_SIZE )); + +if (dt) +memcpy (dt, fdt, size); + +return dt; +} +/** * unflatten_device_tree - create tree of device_nodes from flat blob *
@@ -1350,22 +1365,9 @@ void __init unflatten_device_tree(void)*/ void __init unflatten_and_copy_device_tree (void ) { -int size; -void *dt; +if (initial_boot_params) + initial_boot_params =copy_device_tree (initial_boot_params); -if (!initial_boot_params) { -pr_warn ("No valid device tree found, continuing without\n" ); -return ; - } - - size =fdt_totalsize (initial_boot_params); - dt =early_init_dt_alloc_memory_arch (size, -roundup_pow_of_two (FDT_V17_SIZE )); - -if (dt) { -memcpy (dt, initial_boot_params, size); - initial_boot_params = dt; - }unflatten_device_tree (); }
Signature · 2 lines
https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/ https://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git
PATCH v4 2/7 of: Create of_root if no dtb provided by firmware
In reply to Stephen BoydFrom: Frank Rowand <[email protected]>
When enabling CONFIG_OF on a platform where 'of_root' is not populated by firmware, we end up without a root node. In order to apply overlays and create subnodes of the root node, we need one. Create this root node by unflattening an empty builtin dtb.
If firmware provides a flattened device tree (FDT) then the FDT is unflattened via setup_arch(). Otherwise, the call to unflatten(_and_copy)?_device_tree() will create an empty root node.
We make of_have_populated_dt() return true only if the DTB was loaded by firmware so that existing callers don't change behavior after this patch. The call in the of platform code is removed because it prevents overlays from creating platform devices when the empty root node is used.
[[email protected]: Update of_have_populated_dt() to treat this empty dtb as not populated. Drop setup_of() initcall]
--- drivers/of/Kconfig | 5 ++--- drivers/of/Makefile | 2 +- drivers/of/empty_root.dts | 6 ++++++ drivers/of/fdt.c | 32 +++++++++++++++++++++++++++++++- drivers/of/platform.c | 3 --- include/linux/of.h | 25 +++++++++++++++---------- 6 files changed, 55 insertions(+), 18 deletions(-) create mode 100644 drivers/of/empty_root.dts
drivers/of/Kconfig +2 -3
@@ -14,9 +14,8 @@ if OF config OF_UNITTEST bool "Device Tree runtime unit tests" - depends on !SPARC + depends on OF_EARLY_FLATTREE select IRQ_DOMAIN - select OF_EARLY_FLATTREE select OF_RESOLVE help This option builds in test cases for the device tree infrastructure
@@ -54,7 +53,7 @@ config OF_FLATTREE select CRC32 config OF_EARLY_FLATTREE - bool + def_bool OF && !(SPARC || ALPHA || HEXAGON || M68K || PARISC || S390) select DMA_DECLARE_COHERENT if HAS_DMA && HAS_IOMEM select OF_FLATTREE
drivers/of/Makefile +1 -1
@@ -2,7 +2,7 @@ obj-y = base.o cpu.o device.o module.o platform.o property.o obj-$(CONFIG_OF_KOBJ) += kobj.o obj-$(CONFIG_OF_DYNAMIC) += dynamic.o -obj-$(CONFIG_OF_FLATTREE) += fdt.o +obj-$(CONFIG_OF_FLATTREE) += fdt.o empty_root.dtb.o obj-$(CONFIG_OF_EARLY_FLATTREE) += fdt_address.o obj-$(CONFIG_OF_PROMTREE) += pdt.o obj-$(CONFIG_OF_ADDRESS) += address.o
drivers/of/empty_root.dts new file +6 -0
@@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-only +/dts-v1/; + +/ { + +};
drivers/of/fdt.c +31 -1
@@ -8,6 +8,7 @@#define pr_fmt (fmt) "OF: fdt: " fmt +#include <linux/acpi.h> #include <linux/crash_dump.h> #include <linux/crc32.h> #include <linux/kernel.h>
@@ -32,6 +33,13 @@#include "of_private.h" +/* +* __dtb_empty_root_begin[] and __dtb_empty_root_end[] magically created by +* cmd_dt_S_dtb in scripts/Makefile.lib +*/ +extern uint8_t __dtb_empty_root_begin[]; +extern uint8_t __dtb_empty_root_end[]; +/* * of_fdt_limit_memory - limit the number of regions in the /memory node * @limit: maximum entries
@@ -1343,7 +1351,29 @@ static void *__init copy_device_tree(void *fdt)*/ void __init unflatten_device_tree (void ) { -__unflatten_device_tree (initial_boot_params,NULL , &of_root, +void *fdt = initial_boot_params; + +/* Don't use the bootloader provided DTB if ACPI is enabled */ +if (!acpi_disabled) + fdt =NULL ; + +/* +* Populate an empty root node when ACPI is enabled or bootloader +* doesn't provide one. +*/ +if (!fdt) { + fdt = (void *) __dtb_empty_root_begin; +/* fdt_totalsize() will be used for copy size */ +if (fdt_totalsize (fdt) > + __dtb_empty_root_end - __dtb_empty_root_begin) { +pr_err ("invalid size in dtb_empty_root\n" ); +return ; + } + of_fdt_crc32 =crc32_be (~0 , fdt,fdt_totalsize (fdt)); + fdt =copy_device_tree (fdt); + } + +__unflatten_device_tree (fdt,NULL , &of_root, early_init_dt_alloc_memory_arch, false);/* Get pointer to "/chosen" and "/aliases" nodes for use everywhere */
drivers/of/platform.c +0 -3
@@ -510,9 +510,6 @@ static int __init of_platform_default_populate_init(void)device_links_supplier_sync_state_pause (); -if (!of_have_populated_dt ()) -return -ENODEV ; -if (IS_ENABLED (CONFIG_PPC )) {struct device_node *boot_display =NULL ;struct platform_device *dev;
include/linux/of.h +15 -10
@@ -180,11 +180,6 @@ static inline bool is_of_node(const struct fwnode_handle *fwnode) &__of_fwnode_handle_node->fwnode : NULL; \ }) -static inline bool of_have_populated_dt (void ) -{ -return of_root !=NULL ; -} -static inline bool of_node_is_root (const struct device_node *node) {return node && (node->parent ==NULL );
@@ -549,11 +544,6 @@ static inline struct device_node *of_find_node_with_property(#define of_fwnode_handle (node) NULL -static inline bool of_have_populated_dt (void ) -{ -return false; -} -static inline struct device_node *of_get_compatible_child (const struct device_node *parent,const char *compatible) {
@@ -1634,6 +1624,21 @@ static inline bool of_device_is_system_power_controller(const struct device_nodereturn of_property_read_bool (np,"system-power-controller" ); } +/** +* of_have_populated_dt() - Has DT been populated by bootloader +* +* Return: True if a DTB has been populated by the bootloader and it isn't the +* empty builtin one. False otherwise. +*/ +static inline bool of_have_populated_dt (void ) +{ +#ifdef CONFIG_OF +return of_property_present (of_root,"compatible" ); +#else +return false; +#endif +} +/* * Overlay support */
Signature · 2 lines
https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/ https://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git
PATCH v4 3/7 um: Unconditionally call unflatten_device_tree()
In reply to Stephen BoydCall this function unconditionally so that we can populate an empty DTB on platforms that don't boot with a command line provided DTB. There's no harm in calling unflatten_device_tree() unconditionally. If there isn't a valid initial_boot_params dtb then unflatten_device_tree() returns early.
--- arch/um/kernel/dtb.c | 14 +++++++------- drivers/of/unittest.c | 4 ---- 2 files changed, 7 insertions(+), 11 deletions(-)
arch/um/kernel/dtb.c +7 -7
@@ -16,16 +16,16 @@ void uml_dtb_init(void)void *area; area =uml_load_file (dtb, &size); -if (!area) -return ; +if (area) { +if (!early_init_dt_scan (area)) { +pr_err ("invalid DTB %s\n" , dtb); +memblock_free (area, size); +return ; + } -if (!early_init_dt_scan (area)) { -pr_err ("invalid DTB %s\n" , dtb); -memblock_free (area, size); -return ; +early_init_fdt_scan_reserved_mem (); } -early_init_fdt_scan_reserved_mem ();unflatten_device_tree (); }
drivers/of/unittest.c +0 -4
@@ -4087,10 +4087,6 @@ static int __init of_unittest(void)add_taint (TAINT_TEST ,LOCKDEP_STILL_OK );/* adding data for unittest */ - -if (IS_ENABLED (CONFIG_UML )) -unittest_unflatten_overlay_base (); - res =unittest_data_add ();if (res)return res;
Signature · 2 lines
https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/ https://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git
PATCH v4 4/7 x86/of: Unconditionally call unflatten_and_copy_device_tree()
In reply to Stephen BoydCall this function unconditionally so that we can populate an empty DTB on platforms that don't boot with a firmware provided or builtin DTB. There's no harm in calling unflatten_device_tree() unconditionally here. If there isn't a non-NULL 'initial_boot_params' pointer then unflatten_device_tree() returns early.
--- arch/x86/kernel/devicetree.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-)
arch/x86/kernel/devicetree.c +13 -11
@@ -283,22 +283,24 @@ void __init x86_flattree_get_config(void)u32 size, map_len;void *dt; -if (!initial_dtb) -return ; +if (initial_dtb) { + map_len =max (PAGE_SIZE - (initial_dtb & ~PAGE_MASK ), (u64 )128 ); - map_len =max (PAGE_SIZE - (initial_dtb & ~PAGE_MASK ), (u64 )128 ); + dt =early_memremap (initial_dtb, map_len); + size =fdt_totalsize (dt); +if (map_len < size) { +early_memunmap (dt, map_len); + dt =early_memremap (initial_dtb, size); + map_len = size; + } - dt =early_memremap (initial_dtb, map_len); - size =fdt_totalsize (dt); -if (map_len < size) { -early_memunmap (dt, map_len); - dt =early_memremap (initial_dtb, size); - map_len = size; +early_init_dt_verify (dt); } -early_init_dt_verify (dt);unflatten_and_copy_device_tree (); - early_memunmap(dt, map_len); + +if (initial_dtb) + early_memunmap(dt, map_len); }#endif
Signature · 2 lines
https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/ https://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git
PATCH v4 5/7 arm64: Unconditionally call unflatten_device_tree()
In reply to Stephen BoydCall this function unconditionally so that we can populate an empty DTB on platforms that don't boot with a firmware provided or builtin DTB. When ACPI is in use, unflatten_device_tree() ignores the 'initial_boot_params' pointer so the live DT on those systems won't be whatever that's pointing to. Similarly, when kexec copies the DT data the previous kernel to the new one on ACPI systems, of_kexec_alloc_and_setup_fdt() will ignore the live DT (the empty root one) and copy the 'initial_boot_params' data.
--- arch/arm64/kernel/setup.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
arch/arm64/kernel/setup.c +1 -2
@@ -351,8 +351,7 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p)/* Parse the ACPI tables for possible boot-time configuration */ acpi_boot_table_init (); -if (acpi_disabled) -unflatten_device_tree (); +unflatten_device_tree ();bootmem_init ();
Signature · 2 lines
https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/ https://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git
Rob Herring
maintainerRe: [PATCH v4 5/7] arm64: Unconditionally call unflatten_device_tree()
Quoted 16 lines · Stephen Boyd
Call this function unconditionally so that we can populate an empty DTB on platforms that don't boot with a firmware provided or builtin DTB. When ACPI is in use,
unflatten_device_tree()ignores the 'initial_boot_params' pointer so the live DT on those systems won't be whatever that's pointing to. Similarly, when kexec copies the DT data the previous kernel to the new one on ACPI systems,of_kexec_alloc_and_setup_fdt()will ignore the live DT (the empty root one) and copy the 'initial_boot_params' data.Cc Rob Herring <[email protected]>Cc Frank Rowand <[email protected]>Cc Catalin Marinas <[email protected]>Cc Will Deacon <[email protected]>Cc Mark Rutland <[email protected]>Cc <[email protected]>Signed-off-by Stephen Boyd <[email protected]>
Quoted 3 lines
--- arch/arm64/kernel/setup.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
Catalin, Will, Can I get an ack on this so I can take the series via the DT tree.
Rob
Will Deacon
maintainerRe: [PATCH v4 5/7] arm64: Unconditionally call unflatten_device_tree()
Quoted 21 lines · Rob Herring
Quoted 16 lines · Stephen Boyd
Call this function unconditionally so that we can populate an empty DTB on platforms that don't boot with a firmware provided or builtin DTB. When ACPI is in use,
unflatten_device_tree()ignores the 'initial_boot_params' pointer so the live DT on those systems won't be whatever that's pointing to. Similarly, when kexec copies the DT data the previous kernel to the new one on ACPI systems,of_kexec_alloc_and_setup_fdt()will ignore the live DT (the empty root one) and copy the 'initial_boot_params' data.Cc Rob Herring <[email protected]>Cc Frank Rowand <[email protected]>Cc Catalin Marinas <[email protected]>Cc Will Deacon <[email protected]>Cc Mark Rutland <[email protected]>Cc <[email protected]>Signed-off-by Stephen Boyd <[email protected]>Quoted 3 lines
--- arch/arm64/kernel/setup.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
Quoted 2 lines
Catalin, Will, Can I get an ack on this so I can take the series via the DT tree.
Mark had strong pretty strong objections to this in version one:
https://lore.kernel.org/all/ZaZtbU9hre3YhZam@FVFF77S0Q05N/
and this patch looks the same now as it did then. Did something else change?
Will
Rob Herring
maintainerRe: [PATCH v4 5/7] arm64: Unconditionally call unflatten_device_tree()
Quoted 23 lines · Will Deacon
Quoted 21 lines · Rob Herring
Quoted 19 lines · Stephen Boyd
Call this function unconditionally so that we can populate an empty DTB on platforms that don't boot with a firmware provided or builtin DTB. When ACPI is in use,
unflatten_device_tree()ignores the 'initial_boot_params' pointer so the live DT on those systems won't be whatever that's pointing to. Similarly, when kexec copies the DT data the previous kernel to the new one on ACPI systems,of_kexec_alloc_and_setup_fdt()will ignore the live DT (the empty root one) and copy the 'initial_boot_params' data.Cc Rob Herring <[email protected]>Cc Frank Rowand <[email protected]>Cc Catalin Marinas <[email protected]>Cc Will Deacon <[email protected]>Cc Mark Rutland <[email protected]>Cc <[email protected]>Signed-off-by Stephen Boyd <[email protected]>--- arch/arm64/kernel/setup.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
Quoted 4 lines
Quoted 2 lines
Catalin, Will, Can I get an ack on this so I can take the series via the DT tree.
Mark had strong pretty strong objections to this in version one:
Yes, I had concerns with it as well.
Quoted 4 lines
https://lore.kernel.org/all/ZaZtbU9hre3YhZam@FVFF77S0Q05N/
and this patch looks the same now as it did then. Did something else change?
Yes, that version unflattened the bootloader passed DT. Now within unflatten_devicetree(), the bootloader DT is ignored if ACPI is enabled and we unflatten an empty tree. That will prevent the kernel getting 2 h/w descriptions if/when a platform does such a thing. Also, kexec still uses the bootloader provided DT as before.
Rob
Mark Rutland
reviewerRe: [PATCH v4 5/7] arm64: Unconditionally call unflatten_device_tree()
Quoted 33 lines · Rob Herring
Quoted 23 lines · Will Deacon
Quoted 21 lines · Rob Herring
Quoted 19 lines · Stephen Boyd
Call this function unconditionally so that we can populate an empty DTB on platforms that don't boot with a firmware provided or builtin DTB. When ACPI is in use,
unflatten_device_tree()ignores the 'initial_boot_params' pointer so the live DT on those systems won't be whatever that's pointing to. Similarly, when kexec copies the DT data the previous kernel to the new one on ACPI systems,of_kexec_alloc_and_setup_fdt()will ignore the live DT (the empty root one) and copy the 'initial_boot_params' data.Cc Rob Herring <[email protected]>Cc Frank Rowand <[email protected]>Cc Catalin Marinas <[email protected]>Cc Will Deacon <[email protected]>Cc Mark Rutland <[email protected]>Cc <[email protected]>Signed-off-by Stephen Boyd <[email protected]>--- arch/arm64/kernel/setup.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)Quoted 4 lines
Quoted 2 lines
Catalin, Will, Can I get an ack on this so I can take the series via the DT tree.
Mark had strong pretty strong objections to this in version one:
Yes, I had concerns with it as well.
Quoted 8 lines
Quoted 2 lines
and this patch looks the same now as it did then. Did something else change?
Yes, that version unflattened the bootloader passed DT. Now within
unflatten_devicetree(), the bootloader DT is ignored if ACPI is enabled and we unflatten an empty tree. That will prevent the kernel getting 2 h/w descriptions if/when a platform does such a thing. Also, kexec still uses the bootloader provided DT as before.
That avoids the main instance of my concern, and means that this'll boot without issue, but IIUC this opens the door to dynamically instantiating DT devices atop an ACPI base system, which I think in general is something that's liable to cause more problems than it solves.
I understand that's desireable for the selftests, though I still don't believe it's strictly necessary -- there are plenty of other things that only work if the kernel is booted in a specific configuration.
Putting the selftests aside, why do we need to do this? Is there any other reason to enable this?
Mark.
Rob Herring
maintainerRe: [PATCH v4 5/7] arm64: Unconditionally call unflatten_device_tree()
Quoted 43 lines · Mark Rutland
Quoted 33 lines · Rob Herring
Quoted 23 lines · Will Deacon
Quoted 21 lines · Rob Herring
Quoted 19 lines · Stephen Boyd
Call this function unconditionally so that we can populate an empty DTB on platforms that don't boot with a firmware provided or builtin DTB. When ACPI is in use,
unflatten_device_tree()ignores the 'initial_boot_params' pointer so the live DT on those systems won't be whatever that's pointing to. Similarly, when kexec copies the DT data the previous kernel to the new one on ACPI systems,of_kexec_alloc_and_setup_fdt()will ignore the live DT (the empty root one) and copy the 'initial_boot_params' data.Cc Rob Herring <[email protected]>Cc Frank Rowand <[email protected]>Cc Catalin Marinas <[email protected]>Cc Will Deacon <[email protected]>Cc Mark Rutland <[email protected]>Cc <[email protected]>Signed-off-by Stephen Boyd <[email protected]>--- arch/arm64/kernel/setup.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)Quoted 4 lines
Quoted 2 lines
Catalin, Will, Can I get an ack on this so I can take the series via the DT tree.
Mark had strong pretty strong objections to this in version one:
Yes, I had concerns with it as well.
Quoted 8 lines
Quoted 2 lines
and this patch looks the same now as it did then. Did something else change?
Yes, that version unflattened the bootloader passed DT. Now within
unflatten_devicetree(), the bootloader DT is ignored if ACPI is enabled and we unflatten an empty tree. That will prevent the kernel getting 2 h/w descriptions if/when a platform does such a thing. Also, kexec still uses the bootloader provided DT as before.
Quoted 8 lines
That avoids the main instance of my concern, and means that this'll boot without issue, but IIUC this opens the door to dynamically instantiating DT devices atop an ACPI base system, which I think in general is something that's liable to cause more problems than it solves.
I understand that's desireable for the selftests, though I still don't believe it's strictly necessary -- there are plenty of other things that only work if the kernel is booted in a specific configuration.
Why add to the test matrix if we don't have to?
Quoted 2 lines
Putting the selftests aside, why do we need to do this? Is there any other reason to enable this?
See my Plumbers talk...
Or in short, there's 3 main usecases:
- PCI FPGA card with devices instantiated in it
- SoCs which expose their peripherals via a PCI endpoint.
- Injecting test devices with QEMU (testing, but not what this series does. Jonathan Cameron's usecase)
In all cases, drivers already exist for the devices, and they often only support DT. DT overlays is the natural solution for this, and there's now kernel support for it (dynamically generating PCI DT nodes when they don't exist). The intent is to do the same thing on ACPI systems.
I don't see another solution other than 'go away, you're crazy'. There's ACPI overlays, but that's only a debug feature. Also, that would encourage more of the DT bindings in ACPI which I find worse than this mixture. There's swnodes, but that's just board files and platform_data 2.0.
I share the concerns with mixing, but I don't see a better solution. The scope of what's possible is contained enough to avoid issues.
Rob
Herve Codina
Tested-byRe: [PATCH v4 5/7] arm64: Unconditionally call unflatten_device_tree()
Hi,
On Wed, 28 Feb 2024 10:26:47 -0600
Rob Herring <[email protected]> wrote:
...
Quoted 35 lines
Quoted 7 lines
Quoted 6 lines
Yes, that version unflattened the bootloader passed DT. Now within
unflatten_devicetree(), the bootloader DT is ignored if ACPI is enabled and we unflatten an empty tree. That will prevent the kernel getting 2 h/w descriptions if/when a platform does such a thing. Also, kexec still uses the bootloader provided DT as before.Quoted 8 lines
That avoids the main instance of my concern, and means that this'll boot without issue, but IIUC this opens the door to dynamically instantiating DT devices atop an ACPI base system, which I think in general is something that's liable to cause more problems than it solves.
I understand that's desireable for the selftests, though I still don't believe it's strictly necessary -- there are plenty of other things that only work if the kernel is booted in a specific configuration.
Why add to the test matrix if we don't have to?
Quoted 2 lines
Putting the selftests aside, why do we need to do this? Is there any other reason to enable this?
See my Plumbers talk...
Or in short, there's 3 main usecases:
- PCI FPGA card with devices instantiated in it
- SoCs which expose their peripherals via a PCI endpoint.
- Injecting test devices with QEMU (testing, but not what this series does. Jonathan Cameron's usecase)In all cases, drivers already exist for the devices, and they often only support DT. DT overlays is the natural solution for this, and there's now kernel support for it (dynamically generating PCI DT nodes when they don't exist). The intent is to do the same thing on ACPI systems.
Quoted 9 lines
I don't see another solution other than 'go away, you're crazy'. There's ACPI overlays, but that's only a debug feature. Also, that would encourage more of the DT bindings in ACPI which I find worse than this mixture. There's swnodes, but that's just board files and
platform_data2.0.I share the concerns with mixing, but I don't see a better solution. The scope of what's possible is contained enough to avoid issues.
I tested on a x86 system.
My use case is 'SoCs which expose their peripherals via a PCI endpoint' described by Rob.
Indeed, I have a Microchip Lan9662 board (the one mentioned by Rob in his Plumbers talk) and the root DT node creation is obviously needed.
I have previously used Frank Rowan's patches [1] that did this DT root node creation. This series perfectly replace them and the root DT node is successfully created.
[1]: https://lore.kernel.org/all/[email protected]/
Best regards,
Hervé Codina
Signature · 3 lines
Hervé Codina, Bootlin Embedded Linux and Kernel engineering https://bootlin.com
Re: [PATCH v4 5/7] arm64: Unconditionally call unflatten_device_tree()
In reply to Stephen BoydQuoted 9 lines · Stephen Boyd
Call this function unconditionally so that we can populate an empty DTB on platforms that don't boot with a firmware provided or builtin DTB. When ACPI is in use,
unflatten_device_tree()ignores the 'initial_boot_params' pointer so the live DT on those systems won't be whatever that's pointing to. Similarly, when kexec copies the DT data the previous kernel to the new one on ACPI systems,of_kexec_alloc_and_setup_fdt()will ignore the live DT (the empty root one) and copy the 'initial_boot_params' data.
Quoted 7 lines
Cc Rob Herring <[email protected]>Cc Frank Rowand <[email protected]>Cc Catalin Marinas <[email protected]>Cc Will Deacon <[email protected]>Cc Mark Rutland <[email protected]>Cc <[email protected]>Signed-off-by Stephen Boyd <[email protected]>
This change looks good to me. I am working on a patch set that will benefit from this.
Regards,
Oreoluwa
Quoted 17 lines
--- arch/arm64/kernel/setup.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)arch/arm64/kernel/setup.c +1
-2@@ -351,8 +351,7 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p)/* Parse the ACPI tables for possible boot-time configuration */ acpi_boot_table_init (); -if (acpi_disabled) -unflatten_device_tree (); +unflatten_device_tree ();bootmem_init ();
PATCH v4 6/7 of: unittest: treat missing of_root as error instead of fixing up
In reply to Stephen BoydFrom: Frank Rowand <[email protected]>
unflatten_device_tree() now ensures that the 'of_root' node is populated with the root of a default empty devicetree. Remove the unittest code that created 'of_root' if it was missing. Verify that 'of_root' is valid before attempting to attach the testcase-data subtree. Remove the unittest code that unflattens the unittest overlay base if architecture is UML because that is always done now.
--- drivers/of/unittest.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-)
drivers/of/unittest.c +4 -8
@@ -1744,20 +1744,16 @@ static int __init unittest_data_add(void)return -EINVAL ; } +/* attach the sub-tree to live tree */ if (!of_root) { - of_root = unittest_data_node; -for_each_of_allnodes (np) -__of_attach_node_sysfs (np); - of_aliases =of_find_node_by_path ("/aliases" ); - of_chosen =of_find_node_by_path ("/chosen" ); -of_overlay_mutex_unlock (); -return 0 ; +pr_warn ("%s: no live tree to attach sub-tree\n" , __func__); +kfree (unittest_data); +return -ENODEV ; }EXPECT_BEGIN (KERN_INFO ,"Duplicate name in testcase-data, renamed to \"duplicate-name#1\"" ); -/* attach the sub-tree to live tree */ np = unittest_data_node->child;while (np) {struct device_node *next = np->sibling;
Signature · 2 lines
https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/ https://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git
PATCH v4 7/7 of: Add KUnit test to confirm DTB is loaded
In reply to Stephen BoydAdd a KUnit test that confirms a DTB has been loaded, i.e. there is a root node, and that the of_have_populated_dt() API works properly. We skip the test when CONFIG_OF_EARLY_FLATREE=n because in that case we know architecture code hasn't called unflatten_(and_copy_)?device_tree() which would populate some sort of root node.
--- drivers/of/.kunitconfig | 3 +++ drivers/of/Kconfig | 9 +++++++ drivers/of/Makefile | 2 ++ drivers/of/of_test.c | 57 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 71 insertions(+) create mode 100644 drivers/of/.kunitconfig create mode 100644 drivers/of/of_test.c
drivers/of/.kunitconfig new file +3 -0
@@ -0,0 +1,3 @@ +CONFIG_KUNIT=y +CONFIG_OF=y +CONFIG_OF_KUNIT_TEST=y
drivers/of/Kconfig +9 -0
@@ -36,6 +36,15 @@ config OF_UNITTEST If unsure, say N here. This option is not safe to enable. +config OF_KUNIT_TEST + tristate "Devicetree KUnit Test" if !KUNIT_ALL_TESTS + depends on KUNIT + default KUNIT_ALL_TESTS + help + This option builds KUnit unit tests for device tree infrastructure. + + If unsure, say N here, but this option is safe to enable. + config OF_ALL_DTBS bool "Build all Device Tree Blobs" depends on COMPILE_TEST
drivers/of/Makefile +2 -0
@@ -19,4 +19,6 @@ obj-y += kexec.o endif endif +obj-$(CONFIG_OF_KUNIT_TEST) += of_test.o + obj-$(CONFIG_OF_UNITTEST) += unittest-data/
drivers/of/of_test.c new file +57 -0
57 lines not on this page · raw message
Signature · 2 lines
https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/ https://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git
Rob Herring
maintainerQuoted 40 lines · Stephen Boyd
Arch maintainers, please ack/review patches.
This is a resend of a series from Frank last year[1]. I worked in Rob's review comments to unconditionally call
unflatten_device_tree()and fixup/audit calls toof_have_populated_dt()so that behavior doesn't change.I need this series so I can add DT based tests in the clk framework. Either I can merge it through the clk tree once everyone is happy, or Rob can merge it through the DT tree and provide some branch so I can base clk patches on it.
Changes from v3 (https://lore.kernel.org/r/[email protected]):
* MadeOF_UNITTESTdepend onOF_EARLY_FLATREE
* MadeOF_EARLY_FLATREEdepend on absence of arches that don't callunflatten_device_tree()
* Addedof_prefix todtb_prefixed KUnit tests
* Picked up tagsChanges from v2 (https://lore.kernel.org/r/[email protected]):
* Reorder patches to have OF changes largely first
* No longer modifyinitial_boot_paramsif ACPI=y
* Put arm64 patch back to v1Changes from v1 (https://lore.kernel.org/r/[email protected]):
* x86 patch included
* arm64 knocks out initial dtb if acpi is in use
* keepKconfighidden butdef_boolenabled otherwiseChanges from Frank's series[1]:
* Add a DTB loaded kunit test
* Makeof_have_populated_dt()return false if the DTB isn't from the bootloader
* Architecture calls made unconditional so that a root node is always madeFrank Rowand (2):
of: Createof_rootif no dtb provided by firmware
of: unittest: treat missingof_rootas error instead of fixing up
Quoted 6 lines
Stephen Boyd (5):
of: Always unflatten inunflatten_and_copy_device_tree()
um: Unconditionally callunflatten_device_tree()x86/of: Unconditionally callunflatten_and_copy_device_tree()
arm64: Unconditionally callunflatten_device_tree()
of: Add KUnit test to confirm DTB is loaded
I've applied the series minus the arm64 patch. It's only needed if anyone cares about this working on arm64 ACPI systems. That can be delt with separately.
Rob