Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

of: fdt: Honor CONFIG_CMDLINE* even without /chosen node, take 2

I do not read a strict requirement on /chosen node in either ePAPR or in
Documentation/devicetree. Help text for CONFIG_CMDLINE and
CONFIG_CMDLINE_EXTEND doesn't make their behavior explicitly dependent on
the presence of /chosen or the presense of /chosen/bootargs.

However the early check for /chosen and bailing out in
early_init_dt_scan_chosen() skips CONFIG_CMDLINE handling which is not
really related to /chosen node or the particular method of passing cmdline
from bootloader.

This leads to counterintuitive combinations (assuming
CONFIG_CMDLINE_EXTEND=y):

a) bootargs="foo", CONFIG_CMDLINE="bar" => cmdline=="foo bar"
b) /chosen missing, CONFIG_CMDLINE="bar" => cmdline==""
c) bootargs="", CONFIG_CMDLINE="bar" => cmdline==" bar"

Rework early_init_dt_scan_chosen() so that the cmdline config options are
always handled.

[commit msg written by Alexander Sverdlin]

Cc: Alexander Sverdlin <alexander.sverdlin@gmail.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Tested-by: Geoff Levand <geoff@infradead.org>
Reviewed-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
Link: https://lore.kernel.org/r/20230103-dt-cmdline-fix-v1-2-7038e88b18b6@kernel.org
Signed-off-by: Rob Herring <robh@kernel.org>

+15 -13
+15 -13
drivers/of/fdt.c
··· 1163 1163 if (node < 0) 1164 1164 node = fdt_path_offset(fdt, "/chosen@0"); 1165 1165 if (node < 0) 1166 - return -ENOENT; 1166 + /* Handle the cmdline config options even if no /chosen node */ 1167 + goto handle_cmdline; 1167 1168 1168 1169 chosen_node_offset = node; 1169 1170 1170 1171 early_init_dt_check_for_initrd(node); 1171 1172 early_init_dt_check_for_elfcorehdr(node); 1172 1173 1174 + rng_seed = of_get_flat_dt_prop(node, "rng-seed", &l); 1175 + if (rng_seed && l > 0) { 1176 + add_bootloader_randomness(rng_seed, l); 1177 + 1178 + /* try to clear seed so it won't be found. */ 1179 + fdt_nop_property(initial_boot_params, node, "rng-seed"); 1180 + 1181 + /* update CRC check value */ 1182 + of_fdt_crc32 = crc32_be(~0, initial_boot_params, 1183 + fdt_totalsize(initial_boot_params)); 1184 + } 1185 + 1173 1186 /* Retrieve command line */ 1174 1187 p = of_get_flat_dt_prop(node, "bootargs", &l); 1175 1188 if (p != NULL && l > 0) 1176 1189 strscpy(cmdline, p, min(l, COMMAND_LINE_SIZE)); 1177 1190 1191 + handle_cmdline: 1178 1192 /* 1179 1193 * CONFIG_CMDLINE is meant to be a default in case nothing else 1180 1194 * managed to set the command line, unless CONFIG_CMDLINE_FORCE ··· 1208 1194 #endif /* CONFIG_CMDLINE */ 1209 1195 1210 1196 pr_debug("Command line is: %s\n", (char *)cmdline); 1211 - 1212 - rng_seed = of_get_flat_dt_prop(node, "rng-seed", &l); 1213 - if (rng_seed && l > 0) { 1214 - add_bootloader_randomness(rng_seed, l); 1215 - 1216 - /* try to clear seed so it won't be found. */ 1217 - fdt_nop_property(initial_boot_params, node, "rng-seed"); 1218 - 1219 - /* update CRC check value */ 1220 - of_fdt_crc32 = crc32_be(~0, initial_boot_params, 1221 - fdt_totalsize(initial_boot_params)); 1222 - } 1223 1197 1224 1198 return 0; 1225 1199 }