Skip to content

Commit 2378645

Browse files
heicarstsashalevin
authored andcommitted
s390/hibernate: fix save and restore of kernel text section
[ Upstream commit d744194 ] 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 <[email protected]> Cc: [email protected] Signed-off-by: Heiko Carstens <[email protected]> Signed-off-by: Martin Schwidefsky <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 00d8372 commit 2378645

File tree

1 file changed

+4
-0
lines changed

1 file changed

+4
-0
lines changed

arch/s390/kernel/suspend.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,13 +138,17 @@ int pfn_is_nosave(unsigned long pfn)
138138
{
139139
unsigned long nosave_begin_pfn = PFN_DOWN(__pa(&__nosave_begin));
140140
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));
141143

142144
/* Always save lowcore pages (LC protection might be enabled). */
143145
if (pfn <= LC_PAGES)
144146
return 0;
145147
if (pfn >= nosave_begin_pfn && pfn < nosave_end_pfn)
146148
return 1;
147149
/* 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;
148152
if (tprot(PFN_PHYS(pfn)))
149153
return 1;
150154
return 0;

0 commit comments

Comments
 (0)