[S390] hibernate: make sure pfn_is_nosave handles lowcore pages
authorHeiko Carstens <heiko.carstens@de.ibm.com>
Tue, 22 Sep 2009 20:58:50 +0000 (22:58 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Tue, 22 Sep 2009 20:58:45 +0000 (22:58 +0200)
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>
arch/s390/include/asm/lowcore.h
arch/s390/kernel/suspend.c

index 8c5570366a0e8e1669eed2214ec7ac3cde608b48..a3ff9b01bf7d8636e64da98f9e80c6c777a416a8 100644 (file)
@@ -195,6 +195,8 @@ union save_area {
 #define LC_ORDER 1
 #endif
 
+#define LC_PAGES (1UL << LC_ORDER)
+
 struct _lowcore
 {
 #ifndef __s390x__
index 086bee970cae501fbe579e0dda107c2438c13623..cf9e5c6d55274ce2da221e5f258fab08c58ee21e 100644 (file)
@@ -6,36 +6,26 @@
  * Author(s): Hans-Joachim Picht <hans@linux.vnet.ibm.com>
  */
 
-#include <linux/suspend.h>
-#include <linux/reboot.h>
 #include <linux/pfn.h>
-#include <linux/mm.h>
-#include <asm/sections.h>
 #include <asm/system.h>
-#include <asm/ipl.h>
 
 /*
  * References to section boundaries
  */
 extern const void __nosave_begin, __nosave_end;
 
-/*
- *  check if given pfn is in the 'nosave' or in the read only NSS section
- */
 int pfn_is_nosave(unsigned long pfn)
 {
-       unsigned long nosave_begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT;
-       unsigned long nosave_end_pfn = PAGE_ALIGN(__pa(&__nosave_end))
-                                       >> PAGE_SHIFT;
-       unsigned long eshared_pfn = PFN_DOWN(__pa(&_eshared)) - 1;
-       unsigned long stext_pfn = PFN_DOWN(__pa(&_stext));
+       unsigned long nosave_begin_pfn = PFN_DOWN(__pa(&__nosave_begin));
+       unsigned long nosave_end_pfn = PFN_DOWN(__pa(&__nosave_end));
 
+       /* Always save lowcore pages (LC protection might be enabled). */
+       if (pfn <= LC_PAGES)
+               return 0;
        if (pfn >= nosave_begin_pfn && pfn < nosave_end_pfn)
                return 1;
-       if (pfn >= stext_pfn && pfn <= eshared_pfn) {
-               if (ipl_info.type == IPL_TYPE_NSS)
-                       return 1;
-       } else if ((tprot(pfn * PAGE_SIZE) && pfn > 0))
+       /* Skip memory holes and read-only pages (NSS, DCSS, ...). */
+       if (tprot(PFN_PHYS(pfn)))
                return 1;
        return 0;
 }