Skip to content

Commit

Permalink
PM: Fix oops in suspend/hibernate code related to failing ioremap()
Browse files Browse the repository at this point in the history
When ioremap() fails (which might happen for some reason), we nicely
oops in suspend_nvs_save() due to NULL dereference by memcpy() in there.
Fail gracefully instead.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Len Brown <len.brown@intel.com>
  • Loading branch information
Jiri Slaby authored and Len Brown committed Jan 7, 2011
1 parent 3c0eee3 commit 26fcaf6
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 6 deletions.
5 changes: 2 additions & 3 deletions drivers/acpi/sleep.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,7 @@ static int acpi_pm_freeze(void)
static int acpi_pm_pre_suspend(void)
{
acpi_pm_freeze();
suspend_nvs_save();
return 0;
return suspend_nvs_save();
}

/**
Expand All @@ -151,7 +150,7 @@ static int acpi_pm_prepare(void)
{
int error = __acpi_pm_prepare();
if (!error)
acpi_pm_pre_suspend();
error = acpi_pm_pre_suspend();

return error;
}
Expand Down
4 changes: 2 additions & 2 deletions include/linux/suspend.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ static inline bool system_entering_hibernation(void) { return false; }
extern int suspend_nvs_register(unsigned long start, unsigned long size);
extern int suspend_nvs_alloc(void);
extern void suspend_nvs_free(void);
extern void suspend_nvs_save(void);
extern int suspend_nvs_save(void);
extern void suspend_nvs_restore(void);
#else /* CONFIG_SUSPEND_NVS */
static inline int suspend_nvs_register(unsigned long a, unsigned long b)
Expand All @@ -271,7 +271,7 @@ static inline int suspend_nvs_register(unsigned long a, unsigned long b)
}
static inline int suspend_nvs_alloc(void) { return 0; }
static inline void suspend_nvs_free(void) {}
static inline void suspend_nvs_save(void) {}
static inline int suspend_nvs_save(void) {}
static inline void suspend_nvs_restore(void) {}
#endif /* CONFIG_SUSPEND_NVS */

Expand Down
8 changes: 7 additions & 1 deletion kernel/power/nvs.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ int suspend_nvs_alloc(void)
/**
* suspend_nvs_save - save NVS memory regions
*/
void suspend_nvs_save(void)
int suspend_nvs_save(void)
{
struct nvs_page *entry;

Expand All @@ -114,8 +114,14 @@ void suspend_nvs_save(void)
list_for_each_entry(entry, &nvs_list, node)
if (entry->data) {
entry->kaddr = ioremap(entry->phys_start, entry->size);
if (!entry->kaddr) {
suspend_nvs_free();
return -ENOMEM;
}
memcpy(entry->data, entry->kaddr, entry->size);
}

return 0;
}

/**
Expand Down

0 comments on commit 26fcaf6

Please sign in to comment.