Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 362782
b: refs/heads/master
c: 91c15a9
h: refs/heads/master
v: v3
  • Loading branch information
Michael Holzheu authored and Martin Schwidefsky committed Apr 17, 2013
1 parent 5f4fc13 commit ad9985f
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 4 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5294ee00a16567355c85b849742e5219aad880d0
refs/heads/master: 91c15a951091a64a5f048ff93292057e3b590b6f
1 change: 1 addition & 0 deletions trunk/arch/s390/kernel/entry.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <asm/cputime.h>

extern void *restart_stack;
extern unsigned long suspend_zero_pages;

void system_call(void);
void pgm_check_handler(void);
Expand Down
31 changes: 31 additions & 0 deletions trunk/arch/s390/kernel/suspend.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ struct page_key_data {
static struct page_key_data *page_key_data;
static struct page_key_data *page_key_rp, *page_key_wp;
static unsigned long page_key_rx, page_key_wx;
unsigned long suspend_zero_pages;

/*
* For each page in the hibernation image one additional byte is
Expand Down Expand Up @@ -149,6 +150,36 @@ int pfn_is_nosave(unsigned long pfn)
return 0;
}

/*
* PM notifier callback for suspend
*/
static int suspend_pm_cb(struct notifier_block *nb, unsigned long action,
void *ptr)
{
switch (action) {
case PM_SUSPEND_PREPARE:
case PM_HIBERNATION_PREPARE:
suspend_zero_pages = __get_free_pages(GFP_KERNEL, LC_ORDER);
if (!suspend_zero_pages)
return NOTIFY_BAD;
break;
case PM_POST_SUSPEND:
case PM_POST_HIBERNATION:
free_pages(suspend_zero_pages, LC_ORDER);
break;
default:
return NOTIFY_DONE;
}
return NOTIFY_OK;
}

static int __init suspend_pm_init(void)
{
pm_notifier(suspend_pm_cb, 0);
return 0;
}
arch_initcall(suspend_pm_init);

void save_processor_state(void)
{
/* swsusp_arch_suspend() actually saves all cpu register contents.
Expand Down
29 changes: 26 additions & 3 deletions trunk/arch/s390/kernel/swsusp_asm64.S
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ ENTRY(swsusp_arch_suspend)
/* Store prefix register on stack */
stpx __SF_EMPTY(%r15)

/* Save prefix register contents for lowcore */
llgf %r4,__SF_EMPTY(%r15)
/* Save prefix register contents for lowcore copy */
llgf %r10,__SF_EMPTY(%r15)

/* Get pointer to save area */
lghi %r1,0x1000
Expand Down Expand Up @@ -91,7 +91,18 @@ ENTRY(swsusp_arch_suspend)
xc __SF_EMPTY(4,%r15),__SF_EMPTY(%r15)
spx __SF_EMPTY(%r15)

/* Save absolute zero pages */
larl %r2,suspend_zero_pages
lg %r2,0(%r2)
lghi %r4,0
lghi %r3,2*PAGE_SIZE
lghi %r5,2*PAGE_SIZE
1: mvcle %r2,%r4,0
jo 1b

/* Copy lowcore to absolute zero lowcore */
lghi %r2,0
lgr %r4,%r10
lghi %r3,2*PAGE_SIZE
lghi %r5,2*PAGE_SIZE
1: mvcle %r2,%r4,0
Expand Down Expand Up @@ -248,8 +259,20 @@ restore_registers:
/* Load old stack */
lg %r15,0x2f8(%r13)

/* Save prefix register */
mvc __SF_EMPTY(4,%r15),0x318(%r13)

/* Restore absolute zero pages */
lghi %r2,0
larl %r4,suspend_zero_pages
lg %r4,0(%r4)
lghi %r3,2*PAGE_SIZE
lghi %r5,2*PAGE_SIZE
1: mvcle %r2,%r4,0
jo 1b

/* Restore prefix register */
spx 0x318(%r13)
spx __SF_EMPTY(%r15)

/* Activate DAT */
stosm __SF_EMPTY(%r15),0x04
Expand Down

0 comments on commit ad9985f

Please sign in to comment.