aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2009-09-22 16:58:50 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2009-09-22 16:58:45 -0400
commit2573a575304c5ce4765fc88f9d09ed4dbf8d04bf (patch)
treea639741e80e2424254767b332c53bddd0ebc42cb /arch/s390
parent3fd26a7793fb21b88ccf1e238670b2a508fcf835 (diff)
[S390] hibernate: make sure pfn_is_nosave handles lowcore pages
pfn_is_nosave doesn't return the correct value for the second lowcore page if lowcore protection is enabled. Make sure it always returns the correct value. While at it simplify the whole thing. NSS special handling is done by the tprot check like it already works for DCSS as well. So remove the extra code for NSS. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/include/asm/lowcore.h2
-rw-r--r--arch/s390/kernel/suspend.c24
2 files changed, 9 insertions, 17 deletions
diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h
index 8c5570366a0e..a3ff9b01bf7d 100644
--- a/arch/s390/include/asm/lowcore.h
+++ b/arch/s390/include/asm/lowcore.h
@@ -195,6 +195,8 @@ union save_area {
195#define LC_ORDER 1 195#define LC_ORDER 1
196#endif 196#endif
197 197
198#define LC_PAGES (1UL << LC_ORDER)
199
198struct _lowcore 200struct _lowcore
199{ 201{
200#ifndef __s390x__ 202#ifndef __s390x__
diff --git a/arch/s390/kernel/suspend.c b/arch/s390/kernel/suspend.c
index 086bee970cae..cf9e5c6d5527 100644
--- a/arch/s390/kernel/suspend.c
+++ b/arch/s390/kernel/suspend.c
@@ -6,36 +6,26 @@
6 * Author(s): Hans-Joachim Picht <hans@linux.vnet.ibm.com> 6 * Author(s): Hans-Joachim Picht <hans@linux.vnet.ibm.com>
7 */ 7 */
8 8
9#include <linux/suspend.h>
10#include <linux/reboot.h>
11#include <linux/pfn.h> 9#include <linux/pfn.h>
12#include <linux/mm.h>
13#include <asm/sections.h>
14#include <asm/system.h> 10#include <asm/system.h>
15#include <asm/ipl.h>
16 11
17/* 12/*
18 * References to section boundaries 13 * References to section boundaries
19 */ 14 */
20extern const void __nosave_begin, __nosave_end; 15extern const void __nosave_begin, __nosave_end;
21 16
22/*
23 * check if given pfn is in the 'nosave' or in the read only NSS section
24 */
25int pfn_is_nosave(unsigned long pfn) 17int pfn_is_nosave(unsigned long pfn)
26{ 18{
27 unsigned long nosave_begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT; 19 unsigned long nosave_begin_pfn = PFN_DOWN(__pa(&__nosave_begin));
28 unsigned long nosave_end_pfn = PAGE_ALIGN(__pa(&__nosave_end)) 20 unsigned long nosave_end_pfn = PFN_DOWN(__pa(&__nosave_end));
29 >> PAGE_SHIFT;
30 unsigned long eshared_pfn = PFN_DOWN(__pa(&_eshared)) - 1;
31 unsigned long stext_pfn = PFN_DOWN(__pa(&_stext));
32 21
22 /* Always save lowcore pages (LC protection might be enabled). */
23 if (pfn <= LC_PAGES)
24 return 0;
33 if (pfn >= nosave_begin_pfn && pfn < nosave_end_pfn) 25 if (pfn >= nosave_begin_pfn && pfn < nosave_end_pfn)
34 return 1; 26 return 1;
35 if (pfn >= stext_pfn && pfn <= eshared_pfn) { 27 /* Skip memory holes and read-only pages (NSS, DCSS, ...). */
36 if (ipl_info.type == IPL_TYPE_NSS) 28 if (tprot(PFN_PHYS(pfn)))
37 return 1;
38 } else if ((tprot(pfn * PAGE_SIZE) && pfn > 0))
39 return 1; 29 return 1;
40 return 0; 30 return 0;
41} 31}