aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2015-03-25 05:13:33 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2015-04-13 04:46:18 -0400
commitd74419495633493c9cd3f2bbeb7f3529d0edded6 (patch)
treedc4e833c05c7e4f8b66c30f8acf3f22d85300cff
parent77bb36e57bbe5586bea29b67ba7f87cfe03610a0 (diff)
s390/hibernate: fix save and restore of kernel text section
Sebastian reported a crash caused by a jump label mismatch after resume. This happens because we do not save the kernel text section during suspend and therefore also do not restore it during resume, but use the kernel image that restores the old system. This means that after a suspend/resume cycle we lost all modifications done to the kernel text section. The reason for this is the pfn_is_nosave() function, which incorrectly returns that read-only pages don't need to be saved. This is incorrect since we mark the kernel text section read-only. We still need to make sure to not save and restore pages contained within NSS and DCSS segment. To fix this add an extra case for the kernel text section and only save those pages if they are not contained within an NSS segment. Fixes the following crash (and the above bugs as well): Jump label code mismatch at netif_receive_skb_internal+0x28/0xd0 Found: c0 04 00 00 00 00 Expected: c0 f4 00 00 00 11 New: c0 04 00 00 00 00 Kernel panic - not syncing: Corrupted kernel text CPU: 0 PID: 9 Comm: migration/0 Not tainted 3.19.0-01975-gb1b096e70f23 #4 Call Trace: [<0000000000113972>] show_stack+0x72/0xf0 [<000000000081f15e>] dump_stack+0x6e/0x90 [<000000000081c4e8>] panic+0x108/0x2b0 [<000000000081be64>] jump_label_bug.isra.2+0x104/0x108 [<0000000000112176>] __jump_label_transform+0x9e/0xd0 [<00000000001121e6>] __sm_arch_jump_label_transform+0x3e/0x50 [<00000000001d1136>] multi_cpu_stop+0x12e/0x170 [<00000000001d1472>] cpu_stopper_thread+0xb2/0x168 [<000000000015d2ac>] smpboot_thread_fn+0x134/0x1b0 [<0000000000158baa>] kthread+0x10a/0x110 [<0000000000824a86>] kernel_thread_starter+0x6/0xc Reported-and-tested-by: Sebastian Ott <sebott@linux.vnet.ibm.com> Cc: stable@vger.kernel.org Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--arch/s390/kernel/suspend.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/arch/s390/kernel/suspend.c b/arch/s390/kernel/suspend.c
index 1c4c5accd220..d3236c9e226b 100644
--- a/arch/s390/kernel/suspend.c
+++ b/arch/s390/kernel/suspend.c
@@ -138,6 +138,8 @@ int pfn_is_nosave(unsigned long pfn)
138{ 138{
139 unsigned long nosave_begin_pfn = PFN_DOWN(__pa(&__nosave_begin)); 139 unsigned long nosave_begin_pfn = PFN_DOWN(__pa(&__nosave_begin));
140 unsigned long nosave_end_pfn = PFN_DOWN(__pa(&__nosave_end)); 140 unsigned long nosave_end_pfn = PFN_DOWN(__pa(&__nosave_end));
141 unsigned long eshared_pfn = PFN_DOWN(__pa(&_eshared)) - 1;
142 unsigned long stext_pfn = PFN_DOWN(__pa(&_stext));
141 143
142 /* Always save lowcore pages (LC protection might be enabled). */ 144 /* Always save lowcore pages (LC protection might be enabled). */
143 if (pfn <= LC_PAGES) 145 if (pfn <= LC_PAGES)
@@ -145,6 +147,8 @@ int pfn_is_nosave(unsigned long pfn)
145 if (pfn >= nosave_begin_pfn && pfn < nosave_end_pfn) 147 if (pfn >= nosave_begin_pfn && pfn < nosave_end_pfn)
146 return 1; 148 return 1;
147 /* Skip memory holes and read-only pages (NSS, DCSS, ...). */ 149 /* Skip memory holes and read-only pages (NSS, DCSS, ...). */
150 if (pfn >= stext_pfn && pfn <= eshared_pfn)
151 return ipl_info.type == IPL_TYPE_NSS ? 1 : 0;
148 if (tprot(PFN_PHYS(pfn))) 152 if (tprot(PFN_PHYS(pfn)))
149 return 1; 153 return 1;
150 return 0; 154 return 0;