From e5d1c8722083f0332dcd3c85fa1273d85fb6bed8 Mon Sep 17 00:00:00 2001 From: Nikita Zhandarovich Date: Tue, 18 Apr 2023 06:07:43 -0700 Subject: PM: domains: fix integer overflow issues in genpd_parse_state() Currently, while calculating residency and latency values, right operands may overflow if resulting values are big enough. To prevent this, albeit unlikely case, play it safe and convert right operands to left ones' type s64. Found by Linux Verification Center (linuxtesting.org) with static analysis tool SVACE. Fixes: 30f604283e05 ("PM / Domains: Allow domain power states to be read from DT") Signed-off-by: Nikita Zhandarovich Acked-by: Ulf Hansson Signed-off-by: Rafael J. Wysocki --- drivers/base/power/domain.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 32084e38b73d..51b9d4eaab5e 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -2939,10 +2939,10 @@ static int genpd_parse_state(struct genpd_power_state *genpd_state, err = of_property_read_u32(state_node, "min-residency-us", &residency); if (!err) - genpd_state->residency_ns = 1000 * residency; + genpd_state->residency_ns = 1000LL * residency; - genpd_state->power_on_latency_ns = 1000 * exit_latency; - genpd_state->power_off_latency_ns = 1000 * entry_latency; + genpd_state->power_on_latency_ns = 1000LL * exit_latency; + genpd_state->power_off_latency_ns = 1000LL * entry_latency; genpd_state->fwnode = &state_node->fwnode; return 0; -- cgit v1.2.3 From 2e41e3ca4729455e002bcb585f0d3749ee66d572 Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Tue, 2 May 2023 17:04:34 +0200 Subject: PM: suspend: Fix pm_suspend_target_state handling for !CONFIG_PM Move the pm_suspend_target_state definition for CONFIG_SUSPEND unset from the wakeup code into the headers so as to allow it to still be used elsewhere when CONFIG_SUSPEND is not set. Signed-off-by: Kai-Heng Feng [ rjw: Changelog and subject edits ] Signed-off-by: Rafael J. Wysocki --- drivers/base/power/wakeup.c | 5 ----- include/linux/suspend.h | 4 +++- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index 7cc0c0cf8eaa..a917219feea6 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -19,11 +19,6 @@ #include "power.h" -#ifndef CONFIG_SUSPEND -suspend_state_t pm_suspend_target_state; -#define pm_suspend_target_state (PM_SUSPEND_ON) -#endif - #define list_for_each_entry_rcu_locked(pos, head, member) \ list_for_each_entry_rcu(pos, head, member, \ srcu_read_lock_held(&wakeup_srcu)) diff --git a/include/linux/suspend.h b/include/linux/suspend.h index d0d4598a7b3f..474ecfbbaa62 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -202,6 +202,7 @@ struct platform_s2idle_ops { }; #ifdef CONFIG_SUSPEND +extern suspend_state_t pm_suspend_target_state; extern suspend_state_t mem_sleep_current; extern suspend_state_t mem_sleep_default; @@ -337,6 +338,8 @@ extern bool sync_on_suspend_enabled; #else /* !CONFIG_SUSPEND */ #define suspend_valid_only_mem NULL +#define pm_suspend_target_state (PM_SUSPEND_ON) + static inline void pm_suspend_clear_flags(void) {} static inline void pm_set_suspend_via_firmware(void) {} static inline void pm_set_resume_via_firmware(void) {} @@ -503,7 +506,6 @@ extern void pm_report_max_hw_sleep(u64 t); /* drivers/base/power/wakeup.c */ extern bool events_check_enabled; -extern suspend_state_t pm_suspend_target_state; extern bool pm_wakeup_pending(void); extern void pm_system_wakeup(void); -- cgit v1.2.3 From 847aea98e01cf084efcb84490b3060af343d1458 Mon Sep 17 00:00:00 2001 From: Wang Honghui Date: Thu, 4 May 2023 17:18:24 +0800 Subject: PM: hibernate: Correct spelling mistake in a comment Fix a typo in a comment in kernel/power/snapshot.c Signed-off-by: Wang Honghui [ rjw: Subject and changelog edits ] Signed-off-by: Rafael J. Wysocki --- kernel/power/snapshot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index cd8b7b35f1e8..b27affb7503f 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c @@ -398,7 +398,7 @@ struct mem_zone_bm_rtree { unsigned int blocks; /* Number of Bitmap Blocks */ }; -/* strcut bm_position is used for browsing memory bitmaps */ +/* struct bm_position is used for browsing memory bitmaps */ struct bm_position { struct mem_zone_bm_rtree *zone; -- cgit v1.2.3 From ab23ed6e73ecd198bf577077677beaded0a9e718 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 17 May 2023 15:10:58 +0200 Subject: PM: suspend: add a arch_resume_nosmt() prototype The arch_resume_nosmt() has a __weak definition, plus an x86 specific override, but no prototype that ensures the two have the same arguments. This causes a W=1 warning: arch/x86/power/hibernate.c:189:5: error: no previous prototype for 'arch_resume_nosmt' [-Werror=missing-prototypes] Add the prototype in linux/suspend.h, which is included in both places. Signed-off-by: Arnd Bergmann Signed-off-by: Rafael J. Wysocki --- include/linux/suspend.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 474ecfbbaa62..1a0426e6761c 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -471,6 +471,8 @@ static inline int hibernate_quiet_exec(int (*func)(void *data), void *data) { } #endif /* CONFIG_HIBERNATION */ +int arch_resume_nosmt(void); + #ifdef CONFIG_HIBERNATION_SNAPSHOT_DEV int is_hibernate_resume_dev(dev_t dev); #else -- cgit v1.2.3 From cdb8c100d8a4b4e31c829724e40b4fdf32977cce Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Fri, 2 Jun 2023 02:30:22 -0500 Subject: include/linux/suspend.h: Only show pm_pr_dbg messages at suspend/resume All uses in the kernel are currently already oriented around suspend/resume. As some other parts of the kernel may also use these messages in functions that could also be used outside of suspend/resume, only enable in suspend/resume path. Signed-off-by: Mario Limonciello Signed-off-by: Rafael J. Wysocki --- include/linux/suspend.h | 8 +++++--- kernel/power/main.c | 6 ++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 1a0426e6761c..74f406c53ac0 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -555,6 +555,7 @@ static inline void unlock_system_sleep(unsigned int flags) {} #ifdef CONFIG_PM_SLEEP_DEBUG extern bool pm_print_times_enabled; extern bool pm_debug_messages_on; +extern bool pm_debug_messages_should_print(void); static inline int pm_dyn_debug_messages_on(void) { #ifdef CONFIG_DYNAMIC_DEBUG @@ -568,14 +569,14 @@ static inline int pm_dyn_debug_messages_on(void) #endif #define __pm_pr_dbg(fmt, ...) \ do { \ - if (pm_debug_messages_on) \ + if (pm_debug_messages_should_print()) \ printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); \ else if (pm_dyn_debug_messages_on()) \ pr_debug(fmt, ##__VA_ARGS__); \ } while (0) #define __pm_deferred_pr_dbg(fmt, ...) \ do { \ - if (pm_debug_messages_on) \ + if (pm_debug_messages_should_print()) \ printk_deferred(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); \ } while (0) #else @@ -593,7 +594,8 @@ static inline int pm_dyn_debug_messages_on(void) /** * pm_pr_dbg - print pm sleep debug messages * - * If pm_debug_messages_on is enabled, print message. + * If pm_debug_messages_on is enabled and the system is entering/leaving + * suspend, print message. * If pm_debug_messages_on is disabled and CONFIG_DYNAMIC_DEBUG is enabled, * print message only from instances explicitly enabled on dynamic debug's * control. diff --git a/kernel/power/main.c b/kernel/power/main.c index 3113ec2f1db4..daa535012e51 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -556,6 +556,12 @@ power_attr_ro(pm_wakeup_irq); bool pm_debug_messages_on __read_mostly; +bool pm_debug_messages_should_print(void) +{ + return pm_debug_messages_on && pm_suspend_target_state != PM_SUSPEND_ON; +} +EXPORT_SYMBOL_GPL(pm_debug_messages_should_print); + static ssize_t pm_debug_messages_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { -- cgit v1.2.3 From f75400603f5fb7a031218c659852809378a77cb7 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Fri, 2 Jun 2023 02:30:23 -0500 Subject: ACPI: x86: Add pm_debug_messages for LPS0 _DSM state tracking Enabling debugging messages for the state requires turning on dynamic debugging for the file. To make it more accessible, use `pm_debug_messages` and clearer strings for what is happening. Signed-off-by: Mario Limonciello Signed-off-by: Rafael J. Wysocki --- drivers/acpi/x86/s2idle.c | 52 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c index e499c60c4579..7681f6ecab67 100644 --- a/drivers/acpi/x86/s2idle.c +++ b/drivers/acpi/x86/s2idle.c @@ -59,6 +59,7 @@ static int lps0_dsm_func_mask; static guid_t lps0_dsm_guid_microsoft; static int lps0_dsm_func_mask_microsoft; +static int lps0_dsm_state; /* Device constraint entry structure */ struct lpi_device_info { @@ -320,6 +321,44 @@ static void lpi_check_constraints(void) } } +static bool acpi_s2idle_vendor_amd(void) +{ + return boot_cpu_data.x86_vendor == X86_VENDOR_AMD; +} + +static const char *acpi_sleep_dsm_state_to_str(unsigned int state) +{ + if (lps0_dsm_func_mask_microsoft || !acpi_s2idle_vendor_amd()) { + switch (state) { + case ACPI_LPS0_SCREEN_OFF: + return "screen off"; + case ACPI_LPS0_SCREEN_ON: + return "screen on"; + case ACPI_LPS0_ENTRY: + return "lps0 entry"; + case ACPI_LPS0_EXIT: + return "lps0 exit"; + case ACPI_LPS0_MS_ENTRY: + return "lps0 ms entry"; + case ACPI_LPS0_MS_EXIT: + return "lps0 ms exit"; + } + } else { + switch (state) { + case ACPI_LPS0_SCREEN_ON_AMD: + return "screen on"; + case ACPI_LPS0_SCREEN_OFF_AMD: + return "screen off"; + case ACPI_LPS0_ENTRY_AMD: + return "lps0 entry"; + case ACPI_LPS0_EXIT_AMD: + return "lps0 exit"; + } + } + + return "unknown"; +} + static void acpi_sleep_run_lps0_dsm(unsigned int func, unsigned int func_mask, guid_t dsm_guid) { union acpi_object *out_obj; @@ -331,14 +370,15 @@ static void acpi_sleep_run_lps0_dsm(unsigned int func, unsigned int func_mask, g rev_id, func, NULL); ACPI_FREE(out_obj); - acpi_handle_debug(lps0_device_handle, "_DSM function %u evaluation %s\n", - func, out_obj ? "successful" : "failed"); + lps0_dsm_state = func; + if (pm_debug_messages_on) { + acpi_handle_info(lps0_device_handle, + "%s transitioned to state %s\n", + out_obj ? "Successfully" : "Failed to", + acpi_sleep_dsm_state_to_str(lps0_dsm_state)); + } } -static bool acpi_s2idle_vendor_amd(void) -{ - return boot_cpu_data.x86_vendor == X86_VENDOR_AMD; -} static int validate_dsm(acpi_handle handle, const char *uuid, int rev, guid_t *dsm_guid) { -- cgit v1.2.3 From c9a236419ff936755eb5db8a894c3047440e65a8 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Fri, 2 Jun 2023 02:30:24 -0500 Subject: pinctrl: amd: Use pm_pr_dbg to show debugging messages To make the GPIO tracking around suspend easier for end users to use, link it with pm_debug_messages. This will make discovering sources of spurious GPIOs around suspend easier. Signed-off-by: Mario Limonciello Acked-by: Linus Walleij Signed-off-by: Rafael J. Wysocki --- drivers/pinctrl/pinctrl-amd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c index f279b360c20d..43d3530bab48 100644 --- a/drivers/pinctrl/pinctrl-amd.c +++ b/drivers/pinctrl/pinctrl-amd.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "core.h" #include "pinctrl-utils.h" @@ -636,9 +637,8 @@ static bool do_amd_gpio_irq_handler(int irq, void *dev_id) regval = readl(regs + i); if (regval & PIN_IRQ_PENDING) - dev_dbg(&gpio_dev->pdev->dev, - "GPIO %d is active: 0x%x", - irqnr + i, regval); + pm_pr_dbg("GPIO %d is active: 0x%x", + irqnr + i, regval); /* caused wake on resume context for shared IRQ */ if (irq < 0 && (regval & BIT(WAKE_STS_OFF))) -- cgit v1.2.3 From b77505ed8a885c67a589c049c38824082a569068 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Fri, 2 Jun 2023 02:30:25 -0500 Subject: platform/x86/amd: pmc: Use pm_pr_dbg() for suspend related messages Using pm_pr_dbg() allows users to toggle `/sys/power/pm_debug_messages` as a single knob to turn on messages that amd-pmc can emit to aid in any s2idle debugging. Signed-off-by: Mario Limonciello Acked-by: Hans de Goede Signed-off-by: Rafael J. Wysocki --- drivers/platform/x86/amd/pmc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/amd/pmc.c b/drivers/platform/x86/amd/pmc.c index 427905714f79..1304cd6f13f6 100644 --- a/drivers/platform/x86/amd/pmc.c +++ b/drivers/platform/x86/amd/pmc.c @@ -543,7 +543,7 @@ static int amd_pmc_idlemask_read(struct amd_pmc_dev *pdev, struct device *dev, } if (dev) - dev_dbg(pdev->dev, "SMU idlemask s0i3: 0x%x\n", val); + pm_pr_dbg("SMU idlemask s0i3: 0x%x\n", val); if (s) seq_printf(s, "SMU idlemask : 0x%x\n", val); @@ -769,7 +769,7 @@ static int amd_pmc_verify_czn_rtc(struct amd_pmc_dev *pdev, u32 *arg) *arg |= (duration << 16); rc = rtc_alarm_irq_enable(rtc_device, 0); - dev_dbg(pdev->dev, "wakeup timer programmed for %lld seconds\n", duration); + pm_pr_dbg("wakeup timer programmed for %lld seconds\n", duration); return rc; } -- cgit v1.2.3 From 4384a70c8813e8573d1841fd94eee873f80a7e1a Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 30 May 2023 11:55:36 +0200 Subject: PM: domains: Move the verification of in-params from genpd_add_device() Commit f38d1a6d0025 ("PM: domains: Allocate governor data dynamically based on a genpd governor") started to use the in-parameters in genpd_add_device(), without first doing a verification of them. This isn't really a big problem, as most callers do a verification already. Therefore, let's drop the verification from genpd_add_device() and make sure all the callers take care of it instead. Reported-by: Dan Carpenter Fixes: f38d1a6d0025 ("PM: domains: Allocate governor data dynamically based on a genpd governor") Signed-off-by: Ulf Hansson Signed-off-by: Rafael J. Wysocki --- drivers/base/power/domain.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 51b9d4eaab5e..5cb2023581d4 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -1632,9 +1632,6 @@ static int genpd_add_device(struct generic_pm_domain *genpd, struct device *dev, dev_dbg(dev, "%s()\n", __func__); - if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev)) - return -EINVAL; - gpd_data = genpd_alloc_dev_data(dev, gd); if (IS_ERR(gpd_data)) return PTR_ERR(gpd_data); @@ -1676,6 +1673,9 @@ int pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev) { int ret; + if (!genpd || !dev) + return -EINVAL; + mutex_lock(&gpd_list_lock); ret = genpd_add_device(genpd, dev, dev); mutex_unlock(&gpd_list_lock); @@ -2523,6 +2523,9 @@ int of_genpd_add_device(struct of_phandle_args *genpdspec, struct device *dev) struct generic_pm_domain *genpd; int ret; + if (!dev) + return -EINVAL; + mutex_lock(&gpd_list_lock); genpd = genpd_get_from_provider(genpdspec); -- cgit v1.2.3