mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/2] firmware/psci: Switch to the sys-off handler API
@ 2022-11-05 21:48 Samuel Holland
  2022-11-05 21:48 ` [PATCH 1/2] kernel/reboot: Use the static sys-off handler for any priority Samuel Holland
  2022-11-05 21:48 ` [PATCH 2/2] firmware/psci: Switch to the sys-off handler API Samuel Holland
  0 siblings, 2 replies; 5+ messages in thread
From: Samuel Holland @ 2022-11-05 21:48 UTC (permalink / raw)
  To: Dmitry Osipenko, Rafael J . Wysocki, Mark Rutland, Lorenzo Pieralisi
  Cc: linux-kernel, linux-arm-kernel, Samuel Holland

I am interested in converting the axp20x PMIC driver to use the sys-off
API for its poweroff handler, so it can be used as a fallback for the
SBI poweroff handler on RISC-V. But the PSCI poweroff handler still uses
pm_power_off, so done alone, this would cause the axp20x callback to be
called first, before the PSCI poweroff handler.

In order to prevent this change in behavior, the PSCI poweroff handler
needs to be converted to the sys-off API first, at a higher priority.

This series performs the conversion, after accounting for the fact that
the PSCI poweroff handler is registered quite early during boot.


Samuel Holland (2):
  kernel/reboot: Use the static sys-off handler for any priority
  firmware/psci: Switch to the sys-off handler API

 drivers/firmware/psci/psci.c |  9 ++++++---
 kernel/reboot.c              | 10 ++++------
 2 files changed, 10 insertions(+), 9 deletions(-)

-- 
2.37.3


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/2] kernel/reboot: Use the static sys-off handler for any priority
  2022-11-05 21:48 [PATCH 0/2] firmware/psci: Switch to the sys-off handler API Samuel Holland
@ 2022-11-05 21:48 ` Samuel Holland
  2022-11-06 22:28   ` Dmitry Osipenko
  2022-11-05 21:48 ` [PATCH 2/2] firmware/psci: Switch to the sys-off handler API Samuel Holland
  1 sibling, 1 reply; 5+ messages in thread
From: Samuel Holland @ 2022-11-05 21:48 UTC (permalink / raw)
  To: Dmitry Osipenko, Rafael J . Wysocki, Mark Rutland, Lorenzo Pieralisi
  Cc: linux-kernel, linux-arm-kernel, Samuel Holland

commit 587b9bfe0668 ("kernel/reboot: Use static handler for
register_platform_power_off()") addded a statically-allocated handler
so register_sys_off_handler() could be called before the slab allocator
is available.

That behavior was limited to the SYS_OFF_PRIO_PLATFORM priority.
However, it is also required for handlers such as PSCI on ARM, which
needs to be registered at SYS_OFF_PRIO_FIRMWARE. Currently, this call
stack crashes:

  start_kernel()
    setup_arch()
      psci_dt_init()
        psci_0_2_init()
          register_sys_off_handler()
            kmem_cache_alloc()

Generalize the code to use the statically-allocated handler for the
first registration, regardless of priority. Check .sys_off_cb for
conflicts instead of .cb_data; some callbacks (e.g. firmware) do not
need any per-instance data, so .cb_data could be NULL.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---

 kernel/reboot.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/kernel/reboot.c b/kernel/reboot.c
index 3bba88c7ffc6..38c18d4f0a36 100644
--- a/kernel/reboot.c
+++ b/kernel/reboot.c
@@ -327,7 +327,7 @@ static int sys_off_notify(struct notifier_block *nb,
 	return handler->sys_off_cb(&data);
 }
 
-static struct sys_off_handler platform_sys_off_handler;
+static struct sys_off_handler early_sys_off_handler;
 
 static struct sys_off_handler *alloc_sys_off_handler(int priority)
 {
@@ -338,10 +338,8 @@ static struct sys_off_handler *alloc_sys_off_handler(int priority)
 	 * Platforms like m68k can't allocate sys_off handler dynamically
 	 * at the early boot time because memory allocator isn't available yet.
 	 */
-	if (priority == SYS_OFF_PRIO_PLATFORM) {
-		handler = &platform_sys_off_handler;
-		if (handler->cb_data)
-			return ERR_PTR(-EBUSY);
+	if (!early_sys_off_handler.sys_off_cb) {
+		handler = &early_sys_off_handler;
 	} else {
 		if (system_state > SYSTEM_RUNNING)
 			flags = GFP_ATOMIC;
@@ -358,7 +356,7 @@ static struct sys_off_handler *alloc_sys_off_handler(int priority)
 
 static void free_sys_off_handler(struct sys_off_handler *handler)
 {
-	if (handler == &platform_sys_off_handler)
+	if (handler == &early_sys_off_handler)
 		memset(handler, 0, sizeof(*handler));
 	else
 		kfree(handler);
-- 
2.37.3


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 2/2] firmware/psci: Switch to the sys-off handler API
  2022-11-05 21:48 [PATCH 0/2] firmware/psci: Switch to the sys-off handler API Samuel Holland
  2022-11-05 21:48 ` [PATCH 1/2] kernel/reboot: Use the static sys-off handler for any priority Samuel Holland
@ 2022-11-05 21:48 ` Samuel Holland
  2022-11-07 10:55   ` Sudeep Holla
  1 sibling, 1 reply; 5+ messages in thread
From: Samuel Holland @ 2022-11-05 21:48 UTC (permalink / raw)
  To: Dmitry Osipenko, Rafael J . Wysocki, Mark Rutland, Lorenzo Pieralisi
  Cc: linux-kernel, linux-arm-kernel, Samuel Holland

Any other poweroff handlers registered at the default priority will
run before the legacy pm_power_off() function. Register the PSCI
poweroff handler with the correct priority to ensure it runs first.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---

 drivers/firmware/psci/psci.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c
index e7bcfca4159f..6d528021925d 100644
--- a/drivers/firmware/psci/psci.c
+++ b/drivers/firmware/psci/psci.c
@@ -13,7 +13,6 @@
 #include <linux/errno.h>
 #include <linux/linkage.h>
 #include <linux/of.h>
-#include <linux/pm.h>
 #include <linux/printk.h>
 #include <linux/psci.h>
 #include <linux/reboot.h>
@@ -322,9 +321,11 @@ static struct notifier_block psci_sys_reset_nb = {
 	.priority = 129,
 };
 
-static void psci_sys_poweroff(void)
+static int psci_sys_poweroff(struct sys_off_data *data)
 {
 	invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);
+
+	return NOTIFY_DONE;
 }
 
 static int psci_features(u32 psci_func_id)
@@ -603,7 +604,9 @@ static void __init psci_0_2_set_functions(void)
 
 	register_restart_handler(&psci_sys_reset_nb);
 
-	pm_power_off = psci_sys_poweroff;
+	register_sys_off_handler(SYS_OFF_MODE_POWER_OFF,
+				 SYS_OFF_PRIO_FIRMWARE,
+				 psci_sys_poweroff, NULL);
 }
 
 /*
-- 
2.37.3


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] kernel/reboot: Use the static sys-off handler for any priority
  2022-11-05 21:48 ` [PATCH 1/2] kernel/reboot: Use the static sys-off handler for any priority Samuel Holland
@ 2022-11-06 22:28   ` Dmitry Osipenko
  0 siblings, 0 replies; 5+ messages in thread
From: Dmitry Osipenko @ 2022-11-06 22:28 UTC (permalink / raw)
  To: Samuel Holland, Rafael J . Wysocki, Mark Rutland, Lorenzo Pieralisi
  Cc: linux-kernel, linux-arm-kernel

On 11/6/22 00:48, Samuel Holland wrote:
> commit 587b9bfe0668 ("kernel/reboot: Use static handler for
> register_platform_power_off()") addded a statically-allocated handler
> so register_sys_off_handler() could be called before the slab allocator
> is available.
> 
> That behavior was limited to the SYS_OFF_PRIO_PLATFORM priority.
> However, it is also required for handlers such as PSCI on ARM, which
> needs to be registered at SYS_OFF_PRIO_FIRMWARE. Currently, this call
> stack crashes:
> 
>   start_kernel()
>     setup_arch()
>       psci_dt_init()
>         psci_0_2_init()
>           register_sys_off_handler()
>             kmem_cache_alloc()
> 
> Generalize the code to use the statically-allocated handler for the
> first registration, regardless of priority. Check .sys_off_cb for
> conflicts instead of .cb_data; some callbacks (e.g. firmware) do not
> need any per-instance data, so .cb_data could be NULL.
> 
> Signed-off-by: Samuel Holland <samuel@sholland.org>
> ---
> 
>  kernel/reboot.c | 10 ++++------
>  1 file changed, 4 insertions(+), 6 deletions(-)
> 
> diff --git a/kernel/reboot.c b/kernel/reboot.c
> index 3bba88c7ffc6..38c18d4f0a36 100644
> --- a/kernel/reboot.c
> +++ b/kernel/reboot.c
> @@ -327,7 +327,7 @@ static int sys_off_notify(struct notifier_block *nb,
>  	return handler->sys_off_cb(&data);
>  }
>  
> -static struct sys_off_handler platform_sys_off_handler;
> +static struct sys_off_handler early_sys_off_handler;
>  
>  static struct sys_off_handler *alloc_sys_off_handler(int priority)
>  {
> @@ -338,10 +338,8 @@ static struct sys_off_handler *alloc_sys_off_handler(int priority)
>  	 * Platforms like m68k can't allocate sys_off handler dynamically
>  	 * at the early boot time because memory allocator isn't available yet.
>  	 */
> -	if (priority == SYS_OFF_PRIO_PLATFORM) {
> -		handler = &platform_sys_off_handler;
> -		if (handler->cb_data)
> -			return ERR_PTR(-EBUSY);
> +	if (!early_sys_off_handler.sys_off_cb) {
> +		handler = &early_sys_off_handler;
>  	} else {
>  		if (system_state > SYSTEM_RUNNING)
>  			flags = GFP_ATOMIC;
> @@ -358,7 +356,7 @@ static struct sys_off_handler *alloc_sys_off_handler(int priority)
>  
>  static void free_sys_off_handler(struct sys_off_handler *handler)
>  {
> -	if (handler == &platform_sys_off_handler)
> +	if (handler == &early_sys_off_handler)
>  		memset(handler, 0, sizeof(*handler));
>  	else
>  		kfree(handler);

Reviewed-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>

-- 
Best regards,
Dmitry


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 2/2] firmware/psci: Switch to the sys-off handler API
  2022-11-05 21:48 ` [PATCH 2/2] firmware/psci: Switch to the sys-off handler API Samuel Holland
@ 2022-11-07 10:55   ` Sudeep Holla
  0 siblings, 0 replies; 5+ messages in thread
From: Sudeep Holla @ 2022-11-07 10:55 UTC (permalink / raw)
  To: Samuel Holland
  Cc: Dmitry Osipenko, Rafael J . Wysocki, Sudeep Holla, Mark Rutland,
	Lorenzo Pieralisi, linux-kernel, linux-arm-kernel

On Sat, Nov 05, 2022 at 04:48:40PM -0500, Samuel Holland wrote:
> Any other poweroff handlers registered at the default priority will
> run before the legacy pm_power_off() function. Register the PSCI
> poweroff handler with the correct priority to ensure it runs first.
> 
> Signed-off-by: Samuel Holland <samuel@sholland.org>
> ---
> 
>  drivers/firmware/psci/psci.c | 9 ++++++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c
> index e7bcfca4159f..6d528021925d 100644
> --- a/drivers/firmware/psci/psci.c
> +++ b/drivers/firmware/psci/psci.c
> @@ -13,7 +13,6 @@
>  #include <linux/errno.h>
>  #include <linux/linkage.h>
>  #include <linux/of.h>
> -#include <linux/pm.h>
>  #include <linux/printk.h>
>  #include <linux/psci.h>
>  #include <linux/reboot.h>
> @@ -322,9 +321,11 @@ static struct notifier_block psci_sys_reset_nb = {
>  	.priority = 129,
>  };
>  
> -static void psci_sys_poweroff(void)
> +static int psci_sys_poweroff(struct sys_off_data *data)
>  {
>  	invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);
> +
> +	return NOTIFY_DONE;

Just note that PSCI SYSTEM_OFF doesn't return and hence the above return
is useless. I understand the generic idea here and should be fine, just
thought of pointing that the firmware won't return from the call.

-- 
Regards,
Sudeep

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2022-11-07 10:55 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-05 21:48 [PATCH 0/2] firmware/psci: Switch to the sys-off handler API Samuel Holland
2022-11-05 21:48 ` [PATCH 1/2] kernel/reboot: Use the static sys-off handler for any priority Samuel Holland
2022-11-06 22:28   ` Dmitry Osipenko
2022-11-05 21:48 ` [PATCH 2/2] firmware/psci: Switch to the sys-off handler API Samuel Holland
2022-11-07 10:55   ` Sudeep Holla

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®