Skip to content

Commit fb596ec

Browse files
author
Alex Shi
committed
Merge branch 'v4.4/topic/kexec-kdump' into linux-linaro-lsk-v4.4
2 parents 3ad6822 + c83ee19 commit fb596ec

7 files changed

Lines changed: 180 additions & 119 deletions

File tree

Documentation/kdump/gdbmacros.txt

Lines changed: 44 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -15,37 +15,38 @@
1515

1616
define bttnobp
1717
set $tasks_off=((size_t)&((struct task_struct *)0)->tasks)
18-
set $pid_off=((size_t)&((struct task_struct *)0)->pids[1].pid_list.next)
18+
set $pid_off=((size_t)&((struct task_struct *)0)->thread_group.next)
1919
set $init_t=&init_task
2020
set $next_t=(((char *)($init_t->tasks).next) - $tasks_off)
21+
set var $stacksize = sizeof(union thread_union)
2122
while ($next_t != $init_t)
2223
set $next_t=(struct task_struct *)$next_t
2324
printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm
2425
printf "===================\n"
25-
set var $stackp = $next_t.thread.esp
26-
set var $stack_top = ($stackp & ~4095) + 4096
26+
set var $stackp = $next_t.thread.sp
27+
set var $stack_top = ($stackp & ~($stacksize - 1)) + $stacksize
2728

2829
while ($stackp < $stack_top)
2930
if (*($stackp) > _stext && *($stackp) < _sinittext)
3031
info symbol *($stackp)
3132
end
3233
set $stackp += 4
3334
end
34-
set $next_th=(((char *)$next_t->pids[1].pid_list.next) - $pid_off)
35+
set $next_th=(((char *)$next_t->thread_group.next) - $pid_off)
3536
while ($next_th != $next_t)
3637
set $next_th=(struct task_struct *)$next_th
3738
printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm
3839
printf "===================\n"
39-
set var $stackp = $next_t.thread.esp
40-
set var $stack_top = ($stackp & ~4095) + 4096
40+
set var $stackp = $next_t.thread.sp
41+
set var $stack_top = ($stackp & ~($stacksize - 1)) + stacksize
4142

4243
while ($stackp < $stack_top)
4344
if (*($stackp) > _stext && *($stackp) < _sinittext)
4445
info symbol *($stackp)
4546
end
4647
set $stackp += 4
4748
end
48-
set $next_th=(((char *)$next_th->pids[1].pid_list.next) - $pid_off)
49+
set $next_th=(((char *)$next_th->thread_group.next) - $pid_off)
4950
end
5051
set $next_t=(char *)($next_t->tasks.next) - $tasks_off
5152
end
@@ -54,42 +55,44 @@ document bttnobp
5455
dump all thread stack traces on a kernel compiled with !CONFIG_FRAME_POINTER
5556
end
5657

58+
define btthreadstack
59+
set var $pid_task = $arg0
60+
61+
printf "\npid %d; comm %s:\n", $pid_task.pid, $pid_task.comm
62+
printf "task struct: "
63+
print $pid_task
64+
printf "===================\n"
65+
set var $stackp = $pid_task.thread.sp
66+
set var $stacksize = sizeof(union thread_union)
67+
set var $stack_top = ($stackp & ~($stacksize - 1)) + $stacksize
68+
set var $stack_bot = ($stackp & ~($stacksize - 1))
69+
70+
set $stackp = *((unsigned long *) $stackp)
71+
while (($stackp < $stack_top) && ($stackp > $stack_bot))
72+
set var $addr = *(((unsigned long *) $stackp) + 1)
73+
info symbol $addr
74+
set $stackp = *((unsigned long *) $stackp)
75+
end
76+
end
77+
document btthreadstack
78+
dump a thread stack using the given task structure pointer
79+
end
80+
81+
5782
define btt
5883
set $tasks_off=((size_t)&((struct task_struct *)0)->tasks)
59-
set $pid_off=((size_t)&((struct task_struct *)0)->pids[1].pid_list.next)
84+
set $pid_off=((size_t)&((struct task_struct *)0)->thread_group.next)
6085
set $init_t=&init_task
6186
set $next_t=(((char *)($init_t->tasks).next) - $tasks_off)
6287
while ($next_t != $init_t)
6388
set $next_t=(struct task_struct *)$next_t
64-
printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm
65-
printf "===================\n"
66-
set var $stackp = $next_t.thread.esp
67-
set var $stack_top = ($stackp & ~4095) + 4096
68-
set var $stack_bot = ($stackp & ~4095)
69-
70-
set $stackp = *($stackp)
71-
while (($stackp < $stack_top) && ($stackp > $stack_bot))
72-
set var $addr = *($stackp + 4)
73-
info symbol $addr
74-
set $stackp = *($stackp)
75-
end
89+
btthreadstack $next_t
7690

77-
set $next_th=(((char *)$next_t->pids[1].pid_list.next) - $pid_off)
91+
set $next_th=(((char *)$next_t->thread_group.next) - $pid_off)
7892
while ($next_th != $next_t)
7993
set $next_th=(struct task_struct *)$next_th
80-
printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm
81-
printf "===================\n"
82-
set var $stackp = $next_t.thread.esp
83-
set var $stack_top = ($stackp & ~4095) + 4096
84-
set var $stack_bot = ($stackp & ~4095)
85-
86-
set $stackp = *($stackp)
87-
while (($stackp < $stack_top) && ($stackp > $stack_bot))
88-
set var $addr = *($stackp + 4)
89-
info symbol $addr
90-
set $stackp = *($stackp)
91-
end
92-
set $next_th=(((char *)$next_th->pids[1].pid_list.next) - $pid_off)
94+
btthreadstack $next_th
95+
set $next_th=(((char *)$next_th->thread_group.next) - $pid_off)
9396
end
9497
set $next_t=(char *)($next_t->tasks.next) - $tasks_off
9598
end
@@ -101,7 +104,7 @@ end
101104
define btpid
102105
set var $pid = $arg0
103106
set $tasks_off=((size_t)&((struct task_struct *)0)->tasks)
104-
set $pid_off=((size_t)&((struct task_struct *)0)->pids[1].pid_list.next)
107+
set $pid_off=((size_t)&((struct task_struct *)0)->thread_group.next)
105108
set $init_t=&init_task
106109
set $next_t=(((char *)($init_t->tasks).next) - $tasks_off)
107110
set var $pid_task = 0
@@ -113,29 +116,18 @@ define btpid
113116
set $pid_task = $next_t
114117
end
115118

116-
set $next_th=(((char *)$next_t->pids[1].pid_list.next) - $pid_off)
119+
set $next_th=(((char *)$next_t->thread_group.next) - $pid_off)
117120
while ($next_th != $next_t)
118121
set $next_th=(struct task_struct *)$next_th
119122
if ($next_th.pid == $pid)
120123
set $pid_task = $next_th
121124
end
122-
set $next_th=(((char *)$next_th->pids[1].pid_list.next) - $pid_off)
125+
set $next_th=(((char *)$next_th->thread_group.next) - $pid_off)
123126
end
124127
set $next_t=(char *)($next_t->tasks.next) - $tasks_off
125128
end
126129

127-
printf "\npid %d; comm %s:\n", $pid_task.pid, $pid_task.comm
128-
printf "===================\n"
129-
set var $stackp = $pid_task.thread.esp
130-
set var $stack_top = ($stackp & ~4095) + 4096
131-
set var $stack_bot = ($stackp & ~4095)
132-
133-
set $stackp = *($stackp)
134-
while (($stackp < $stack_top) && ($stackp > $stack_bot))
135-
set var $addr = *($stackp + 4)
136-
info symbol $addr
137-
set $stackp = *($stackp)
138-
end
130+
btthreadstack $pid_task
139131
end
140132
document btpid
141133
backtrace of pid
@@ -145,7 +137,7 @@ end
145137
define trapinfo
146138
set var $pid = $arg0
147139
set $tasks_off=((size_t)&((struct task_struct *)0)->tasks)
148-
set $pid_off=((size_t)&((struct task_struct *)0)->pids[1].pid_list.next)
140+
set $pid_off=((size_t)&((struct task_struct *)0)->thread_group.next)
149141
set $init_t=&init_task
150142
set $next_t=(((char *)($init_t->tasks).next) - $tasks_off)
151143
set var $pid_task = 0
@@ -157,13 +149,13 @@ define trapinfo
157149
set $pid_task = $next_t
158150
end
159151

160-
set $next_th=(((char *)$next_t->pids[1].pid_list.next) - $pid_off)
152+
set $next_th=(((char *)$next_t->thread_group.next) - $pid_off)
161153
while ($next_th != $next_t)
162154
set $next_th=(struct task_struct *)$next_th
163155
if ($next_th.pid == $pid)
164156
set $pid_task = $next_th
165157
end
166-
set $next_th=(((char *)$next_th->pids[1].pid_list.next) - $pid_off)
158+
set $next_th=(((char *)$next_th->thread_group.next) - $pid_off)
167159
end
168160
set $next_t=(char *)($next_t->tasks.next) - $tasks_off
169161
end

arch/s390/kernel/machine_kexec.c

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,13 @@ static int machine_kdump_pm_cb(struct notifier_block *nb, unsigned long action,
8383
switch (action) {
8484
case PM_SUSPEND_PREPARE:
8585
case PM_HIBERNATION_PREPARE:
86-
if (crashk_res.start)
87-
crash_map_reserved_pages();
86+
if (kexec_crash_image)
87+
arch_kexec_unprotect_crashkres();
8888
break;
8989
case PM_POST_SUSPEND:
9090
case PM_POST_HIBERNATION:
91-
if (crashk_res.start)
92-
crash_unmap_reserved_pages();
91+
if (kexec_crash_image)
92+
arch_kexec_protect_crashkres();
9393
break;
9494
default:
9595
return NOTIFY_DONE;
@@ -100,6 +100,8 @@ static int machine_kdump_pm_cb(struct notifier_block *nb, unsigned long action,
100100
static int __init machine_kdump_pm_init(void)
101101
{
102102
pm_notifier(machine_kdump_pm_cb, 0);
103+
/* Create initial mapping for crashkernel memory */
104+
arch_kexec_unprotect_crashkres();
103105
return 0;
104106
}
105107
arch_initcall(machine_kdump_pm_init);
@@ -134,6 +136,8 @@ static int kdump_csum_valid(struct kimage *image)
134136
#endif
135137
}
136138

139+
#ifdef CONFIG_CRASH_DUMP
140+
137141
/*
138142
* Map or unmap crashkernel memory
139143
*/
@@ -155,21 +159,25 @@ static void crash_map_pages(int enable)
155159
}
156160

157161
/*
158-
* Map crashkernel memory
162+
* Unmap crashkernel memory
159163
*/
160-
void crash_map_reserved_pages(void)
164+
void arch_kexec_protect_crashkres(void)
161165
{
162-
crash_map_pages(1);
166+
if (crashk_res.end)
167+
crash_map_pages(0);
163168
}
164169

165170
/*
166-
* Unmap crashkernel memory
171+
* Map crashkernel memory
167172
*/
168-
void crash_unmap_reserved_pages(void)
173+
void arch_kexec_unprotect_crashkres(void)
169174
{
170-
crash_map_pages(0);
175+
if (crashk_res.end)
176+
crash_map_pages(1);
171177
}
172178

179+
#endif
180+
173181
/*
174182
* Give back memory to hypervisor before new kdump is loaded
175183
*/

arch/x86/kernel/machine_kexec_64.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,3 +536,48 @@ int arch_kexec_apply_relocations_add(const Elf64_Ehdr *ehdr,
536536
return -ENOEXEC;
537537
}
538538
#endif /* CONFIG_KEXEC_FILE */
539+
540+
static int
541+
kexec_mark_range(unsigned long start, unsigned long end, bool protect)
542+
{
543+
struct page *page;
544+
unsigned int nr_pages;
545+
546+
/*
547+
* For physical range: [start, end]. We must skip the unassigned
548+
* crashk resource with zero-valued "end" member.
549+
*/
550+
if (!end || start > end)
551+
return 0;
552+
553+
page = pfn_to_page(start >> PAGE_SHIFT);
554+
nr_pages = (end >> PAGE_SHIFT) - (start >> PAGE_SHIFT) + 1;
555+
if (protect)
556+
return set_pages_ro(page, nr_pages);
557+
else
558+
return set_pages_rw(page, nr_pages);
559+
}
560+
561+
static void kexec_mark_crashkres(bool protect)
562+
{
563+
unsigned long control;
564+
565+
kexec_mark_range(crashk_low_res.start, crashk_low_res.end, protect);
566+
567+
/* Don't touch the control code page used in crash_kexec().*/
568+
control = PFN_PHYS(page_to_pfn(kexec_crash_image->control_code_page));
569+
/* Control code page is located in the 2nd page. */
570+
kexec_mark_range(crashk_res.start, control + PAGE_SIZE - 1, protect);
571+
control += KEXEC_CONTROL_PAGE_SIZE;
572+
kexec_mark_range(control, crashk_res.end, protect);
573+
}
574+
575+
void arch_kexec_protect_crashkres(void)
576+
{
577+
kexec_mark_crashkres(true);
578+
}
579+
580+
void arch_kexec_unprotect_crashkres(void)
581+
{
582+
kexec_mark_crashkres(false);
583+
}

include/linux/kexec.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,6 @@ extern void crash_kexec(struct pt_regs *);
241241
int kexec_should_crash(struct task_struct *);
242242
void crash_save_cpu(struct pt_regs *regs, int cpu);
243243
void crash_save_vmcoreinfo(void);
244-
void crash_map_reserved_pages(void);
245-
void crash_unmap_reserved_pages(void);
246244
void arch_crash_save_vmcoreinfo(void);
247245
__printf(1, 2)
248246
void vmcoreinfo_append_str(const char *fmt, ...);
@@ -328,6 +326,8 @@ int __weak arch_kexec_apply_relocations_add(const Elf_Ehdr *ehdr,
328326
Elf_Shdr *sechdrs, unsigned int relsec);
329327
int __weak arch_kexec_apply_relocations(const Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
330328
unsigned int relsec);
329+
void arch_kexec_protect_crashkres(void);
330+
void arch_kexec_unprotect_crashkres(void);
331331

332332
#else /* !CONFIG_KEXEC_CORE */
333333
struct pt_regs;

0 commit comments

Comments
 (0)