From: André Draszik Date: Fri, 7 Mar 2025 07:50:18 +0000 (+0000) Subject: power: reset: reboot-mode: better compatibility with DT (replace ' ,/') X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=ca3d2ea52314286dda597f03b07ed759c5798fba;p=linux.git power: reset: reboot-mode: better compatibility with DT (replace ' ,/') This driver's purpose is to parse boot modes described in DT, via key (node name) / value pairs, and to match them to a reboot mode requested by the kernel. Unfortunately, DT node names can not contain certain characters, like space ' ' or comma ',' or slash '/', while the requested reboot mode may. This is a problem because it makes it impossible to match reboot modes containing any of those characters. For example, this makes it impossible to communicate DM verity errors to the boot loader - DM verity errors trigger a reboot with mode "dm-verity device corrupted" in drivers/md/dm-verity-target.c and devices typically have to take action in that case [1]. Changing this string itself is not feasible, see e.g. discussion in [2], but would also just cover this one case. Another example is Android, which may use comma in the reboot mode string, e.g. as "shutdown,thermal" in [3]. The kernel also shouldn't prescribe what characters are allowed inside the boot mode string for a user to set. It hasn't done this so far, and introducing such a restriction would be an interface break and arbitrarily enforce a random new policy. Therefore, update this driver to do another round of string matching, after replacing the common characters mentioned above with dash '-', if a match hasn't been found without doing said replacement. This now allows us to have DT entries of e.g.: mode-dm-verity-device-corrupted = <...> and so on. Link: https://cs.android.com/android/kernel/superproject/+/android14-gs-pixel-6.1:private/google-modules/power/reset/exynos-gs101-reboot.c;l=144 [1] Link: https://lore.kernel.org/all/CAAFS_9FuSb7PZwQ2itUh_H7ZdhvAEiiX7fhxJ4kmmv9JCaHmkA@mail.gmail.com/ [2] Link: https://cs.android.com/android/platform/superproject/main/+/main:system/core/init/reboot_utils.cpp;drc=79ad1e2e9bf1628c141c8cd2fbb4f3df61a6ba75;l=122 [3] Signed-off-by: André Draszik Link: https://lore.kernel.org/r/20250307-reboot-mode-chars-v1-1-d83ff95da524@linaro.org Signed-off-by: Sebastian Reichel --- diff --git a/drivers/power/reset/reboot-mode.c b/drivers/power/reset/reboot-mode.c index b4076b10b893..fba53f638da0 100644 --- a/drivers/power/reset/reboot-mode.c +++ b/drivers/power/reset/reboot-mode.c @@ -23,20 +23,29 @@ static unsigned int get_reboot_mode_magic(struct reboot_mode_driver *reboot, const char *cmd) { const char *normal = "normal"; - int magic = 0; struct mode_info *info; + char cmd_[110]; if (!cmd) cmd = normal; - list_for_each_entry(info, &reboot->head, list) { - if (!strcmp(info->mode, cmd)) { - magic = info->magic; - break; - } - } + list_for_each_entry(info, &reboot->head, list) + if (!strcmp(info->mode, cmd)) + return info->magic; + + /* try to match again, replacing characters impossible in DT */ + if (strscpy(cmd_, cmd, sizeof(cmd_)) == -E2BIG) + return 0; - return magic; + strreplace(cmd_, ' ', '-'); + strreplace(cmd_, ',', '-'); + strreplace(cmd_, '/', '-'); + + list_for_each_entry(info, &reboot->head, list) + if (!strcmp(info->mode, cmd_)) + return info->magic; + + return 0; } static int reboot_mode_notify(struct notifier_block *this,