Blame view

kernel/kexec.c 42.8 KB
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
1
2
3
4
5
6
7
  /*
   * kexec.c - kexec system call
   * Copyright (C) 2002-2004 Eric Biederman  <ebiederm@xmission.com>
   *
   * This source code is licensed under the GNU General Public License,
   * Version 2.  See the file COPYING for more details.
   */
c59ede7b7   Randy.Dunlap   [PATCH] move capa...
8
  #include <linux/capability.h>
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
9
10
11
12
13
  #include <linux/mm.h>
  #include <linux/file.h>
  #include <linux/slab.h>
  #include <linux/fs.h>
  #include <linux/kexec.h>
8c5a1cf0a   Andrew Morton   kexec: use a mute...
14
  #include <linux/mutex.h>
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
15
16
17
18
  #include <linux/list.h>
  #include <linux/highmem.h>
  #include <linux/syscalls.h>
  #include <linux/reboot.h>
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
19
  #include <linux/ioport.h>
6e274d144   Alexander Nyberg   [PATCH] kdump: Us...
20
  #include <linux/hardirq.h>
85916f816   Magnus Damm   [PATCH] Kexec / K...
21
22
  #include <linux/elf.h>
  #include <linux/elfcore.h>
fd59d231f   Ken'ichi Ohmichi   Add vmcoreinfo
23
24
  #include <linux/utsname.h>
  #include <linux/numa.h>
3ab835213   Huang Ying   kexec jump
25
26
  #include <linux/suspend.h>
  #include <linux/device.h>
89081d17f   Huang Ying   kexec jump: save/...
27
28
29
30
  #include <linux/freezer.h>
  #include <linux/pm.h>
  #include <linux/cpu.h>
  #include <linux/console.h>
5f41b8cdc   Tony Luck   kexec: fix crash_...
31
  #include <linux/vmalloc.h>
06a7f7112   Amerigo Wang   kexec: premit red...
32
  #include <linux/swap.h>
19234c081   Rafael J. Wysocki   PM: Add missing s...
33
  #include <linux/syscore_ops.h>
52f5684c8   Gideon Israel Dsouza   kernel: use macro...
34
  #include <linux/compiler.h>
8f1d26d0e   Atsushi Kumagai   kexec: export fre...
35
  #include <linux/hugetlb.h>
6e274d144   Alexander Nyberg   [PATCH] kdump: Us...
36

dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
37
38
39
  #include <asm/page.h>
  #include <asm/uaccess.h>
  #include <asm/io.h>
fd59d231f   Ken'ichi Ohmichi   Add vmcoreinfo
40
  #include <asm/sections.h>
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
41

cc5716587   Vivek Goyal   [PATCH] kdump: dy...
42
  /* Per cpu memory for storing cpu states in case of system crash. */
43cf38eb5   Tejun Heo   percpu: add __per...
43
  note_buf_t __percpu *crash_notes;
cc5716587   Vivek Goyal   [PATCH] kdump: dy...
44

fd59d231f   Ken'ichi Ohmichi   Add vmcoreinfo
45
  /* vmcoreinfo stuff */
edb79a213   Dmitri Vorobiev   kexec: vmcoreinfo...
46
  static unsigned char vmcoreinfo_data[VMCOREINFO_BYTES];
fd59d231f   Ken'ichi Ohmichi   Add vmcoreinfo
47
  u32 vmcoreinfo_note[VMCOREINFO_NOTE_SIZE/4];
d768281e9   Ken'ichi Ohmichi   add-vmcore: clean...
48
49
  size_t vmcoreinfo_size;
  size_t vmcoreinfo_max_size = sizeof(vmcoreinfo_data);
fd59d231f   Ken'ichi Ohmichi   Add vmcoreinfo
50

4fc9bbf98   Khalid Aziz   PCI: Disable Bus ...
51
52
  /* Flag to indicate we are going to kexec a new kernel */
  bool kexec_in_progress = false;
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
53
54
55
56
57
58
59
  /* Location of the reserved area for the crash kernel */
  struct resource crashk_res = {
  	.name  = "Crash kernel",
  	.start = 0,
  	.end   = 0,
  	.flags = IORESOURCE_BUSY | IORESOURCE_MEM
  };
0212f9159   Yinghai Lu   x86: Add Crash ke...
60
  struct resource crashk_low_res = {
157752d84   Yinghai Lu   kexec: use Crash ...
61
  	.name  = "Crash kernel",
0212f9159   Yinghai Lu   x86: Add Crash ke...
62
63
64
65
  	.start = 0,
  	.end   = 0,
  	.flags = IORESOURCE_BUSY | IORESOURCE_MEM
  };
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
66

6e274d144   Alexander Nyberg   [PATCH] kdump: Us...
67
68
  int kexec_should_crash(struct task_struct *p)
  {
b460cbc58   Serge E. Hallyn   pid namespaces: d...
69
  	if (in_interrupt() || !p->pid || is_global_init(p) || panic_on_oops)
6e274d144   Alexander Nyberg   [PATCH] kdump: Us...
70
71
72
  		return 1;
  	return 0;
  }
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
  /*
   * When kexec transitions to the new kernel there is a one-to-one
   * mapping between physical and virtual addresses.  On processors
   * where you can disable the MMU this is trivial, and easy.  For
   * others it is still a simple predictable page table to setup.
   *
   * In that environment kexec copies the new kernel to its final
   * resting place.  This means I can only support memory whose
   * physical address can fit in an unsigned long.  In particular
   * addresses where (pfn << PAGE_SHIFT) > ULONG_MAX cannot be handled.
   * If the assembly stub has more restrictive requirements
   * KEXEC_SOURCE_MEMORY_LIMIT and KEXEC_DEST_MEMORY_LIMIT can be
   * defined more restrictively in <asm/kexec.h>.
   *
   * The code for the transition from the current kernel to the
   * the new kernel is placed in the control_code_buffer, whose size
163f6876f   Huang Ying   kexec jump: renam...
89
   * is given by KEXEC_CONTROL_PAGE_SIZE.  In the best case only a single
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
   * page of memory is necessary, but some architectures require more.
   * Because this memory must be identity mapped in the transition from
   * virtual to physical addresses it must live in the range
   * 0 - TASK_SIZE, as only the user space mappings are arbitrarily
   * modifiable.
   *
   * The assembly stub in the control code buffer is passed a linked list
   * of descriptor pages detailing the source pages of the new kernel,
   * and the destination addresses of those source pages.  As this data
   * structure is not used in the context of the current OS, it must
   * be self-contained.
   *
   * The code has been made to work with highmem pages and will use a
   * destination page in its final resting place (if it happens
   * to allocate it).  The end product of this is that most of the
   * physical address space, and most of RAM can be used.
   *
   * Future directions include:
   *  - allocating a page table with the control code buffer identity
   *    mapped, to simplify machine_kexec and make kexec_on_panic more
   *    reliable.
   */
  
  /*
   * KIMAGE_NO_DEST is an impossible destination address..., for
   * allocating pages whose destination address we do not care about.
   */
  #define KIMAGE_NO_DEST (-1UL)
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
118
119
120
  static int kimage_is_destination_range(struct kimage *image,
  				       unsigned long start, unsigned long end);
  static struct page *kimage_alloc_page(struct kimage *image,
9796fdd82   Al Viro   [PATCH] gfp_t: ke...
121
  				       gfp_t gfp_mask,
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
122
  				       unsigned long dest);
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
123
124
  
  static int do_kimage_alloc(struct kimage **rimage, unsigned long entry,
e1bebcf41   Fabian Frederick   kernel/kexec.c: c...
125
126
  			   unsigned long nr_segments,
  			   struct kexec_segment __user *segments)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
127
128
129
130
131
132
133
134
  {
  	size_t segment_bytes;
  	struct kimage *image;
  	unsigned long i;
  	int result;
  
  	/* Allocate a controlling structure */
  	result = -ENOMEM;
4668edc33   Burman Yan   [PATCH] kernel co...
135
  	image = kzalloc(sizeof(*image), GFP_KERNEL);
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
136
  	if (!image)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
137
  		goto out;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
138

dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
139
140
141
142
143
144
145
146
147
148
149
150
  	image->head = 0;
  	image->entry = &image->head;
  	image->last_entry = &image->head;
  	image->control_page = ~0; /* By default this does not apply */
  	image->start = entry;
  	image->type = KEXEC_TYPE_DEFAULT;
  
  	/* Initialize the list of control pages */
  	INIT_LIST_HEAD(&image->control_pages);
  
  	/* Initialize the list of destination pages */
  	INIT_LIST_HEAD(&image->dest_pages);
25985edce   Lucas De Marchi   Fix common misspe...
151
  	/* Initialize the list of unusable pages */
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
152
153
154
155
156
157
  	INIT_LIST_HEAD(&image->unuseable_pages);
  
  	/* Read in the segments */
  	image->nr_segments = nr_segments;
  	segment_bytes = nr_segments * sizeof(*segments);
  	result = copy_from_user(image->segment, segments, segment_bytes);
f65a03f6a   Dan Carpenter   kexec: return -EF...
158
159
  	if (result) {
  		result = -EFAULT;
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
160
  		goto out;
f65a03f6a   Dan Carpenter   kexec: return -EF...
161
  	}
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
162
163
164
165
166
167
168
169
  
  	/*
  	 * Verify we have good destination addresses.  The caller is
  	 * responsible for making certain we don't attempt to load
  	 * the new image into invalid or reserved areas of RAM.  This
  	 * just verifies it is an address we can use.
  	 *
  	 * Since the kernel does everything in page size chunks ensure
b595076a1   Uwe Kleine-König   tree-wide: fix co...
170
  	 * the destination addresses are page aligned.  Too many
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
171
172
173
174
175
176
177
178
  	 * special cases crop of when we don't do this.  The most
  	 * insidious is getting overlapping destination addresses
  	 * simply because addresses are changed to page size
  	 * granularity.
  	 */
  	result = -EADDRNOTAVAIL;
  	for (i = 0; i < nr_segments; i++) {
  		unsigned long mstart, mend;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
179

dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
180
181
182
183
184
185
186
187
188
189
190
191
192
193
  		mstart = image->segment[i].mem;
  		mend   = mstart + image->segment[i].memsz;
  		if ((mstart & ~PAGE_MASK) || (mend & ~PAGE_MASK))
  			goto out;
  		if (mend >= KEXEC_DESTINATION_MEMORY_LIMIT)
  			goto out;
  	}
  
  	/* Verify our destination addresses do not overlap.
  	 * If we alloed overlapping destination addresses
  	 * through very weird things can happen with no
  	 * easy explanation as one segment stops on another.
  	 */
  	result = -EINVAL;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
194
  	for (i = 0; i < nr_segments; i++) {
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
195
196
  		unsigned long mstart, mend;
  		unsigned long j;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
197

dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
198
199
  		mstart = image->segment[i].mem;
  		mend   = mstart + image->segment[i].memsz;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
200
  		for (j = 0; j < i; j++) {
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
  			unsigned long pstart, pend;
  			pstart = image->segment[j].mem;
  			pend   = pstart + image->segment[j].memsz;
  			/* Do the segments overlap ? */
  			if ((mend > pstart) && (mstart < pend))
  				goto out;
  		}
  	}
  
  	/* Ensure our buffer sizes are strictly less than
  	 * our memory sizes.  This should always be the case,
  	 * and it is easier to check up front than to be surprised
  	 * later on.
  	 */
  	result = -EINVAL;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
216
  	for (i = 0; i < nr_segments; i++) {
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
217
218
219
  		if (image->segment[i].bufsz > image->segment[i].memsz)
  			goto out;
  	}
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
220
  	result = 0;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
221
222
  out:
  	if (result == 0)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
223
  		*rimage = image;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
224
  	else
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
225
  		kfree(image);
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
226

dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
227
228
229
  	return result;
  
  }
b92e7e0da   Zhang Yanfei   kexec: fix memory...
230
  static void kimage_free_page_list(struct list_head *list);
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
231
  static int kimage_normal_alloc(struct kimage **rimage, unsigned long entry,
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
232
233
  				unsigned long nr_segments,
  				struct kexec_segment __user *segments)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
234
235
236
237
238
239
240
  {
  	int result;
  	struct kimage *image;
  
  	/* Allocate and initialize a controlling structure */
  	image = NULL;
  	result = do_kimage_alloc(&image, entry, nr_segments, segments);
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
241
  	if (result)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
242
  		goto out;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
243

dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
244
245
246
247
248
249
250
  	/*
  	 * Find a location for the control code buffer, and add it
  	 * the vector of segments so that it's pages will also be
  	 * counted as destination pages.
  	 */
  	result = -ENOMEM;
  	image->control_code_page = kimage_alloc_control_pages(image,
163f6876f   Huang Ying   kexec jump: renam...
251
  					   get_order(KEXEC_CONTROL_PAGE_SIZE));
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
252
  	if (!image->control_code_page) {
e1bebcf41   Fabian Frederick   kernel/kexec.c: c...
253
254
  		pr_err("Could not allocate control_code_buffer
  ");
b92e7e0da   Zhang Yanfei   kexec: fix memory...
255
  		goto out_free;
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
256
  	}
3ab835213   Huang Ying   kexec jump
257
258
  	image->swap_page = kimage_alloc_control_pages(image, 0);
  	if (!image->swap_page) {
e1bebcf41   Fabian Frederick   kernel/kexec.c: c...
259
260
  		pr_err("Could not allocate swap buffer
  ");
b92e7e0da   Zhang Yanfei   kexec: fix memory...
261
  		goto out_free;
3ab835213   Huang Ying   kexec jump
262
  	}
b92e7e0da   Zhang Yanfei   kexec: fix memory...
263
264
  	*rimage = image;
  	return 0;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
265

b92e7e0da   Zhang Yanfei   kexec: fix memory...
266
267
268
269
  out_free:
  	kimage_free_page_list(&image->control_pages);
  	kfree(image);
  out:
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
270
271
272
273
  	return result;
  }
  
  static int kimage_crash_alloc(struct kimage **rimage, unsigned long entry,
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
274
  				unsigned long nr_segments,
314b6a4d8   Alexey Dobriyan   [PATCH] kexec: fi...
275
  				struct kexec_segment __user *segments)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
276
277
278
279
280
281
282
283
284
285
286
287
288
289
  {
  	int result;
  	struct kimage *image;
  	unsigned long i;
  
  	image = NULL;
  	/* Verify we have a valid entry point */
  	if ((entry < crashk_res.start) || (entry > crashk_res.end)) {
  		result = -EADDRNOTAVAIL;
  		goto out;
  	}
  
  	/* Allocate and initialize a controlling structure */
  	result = do_kimage_alloc(&image, entry, nr_segments, segments);
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
290
  	if (result)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
291
  		goto out;
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
  
  	/* Enable the special crash kernel control page
  	 * allocation policy.
  	 */
  	image->control_page = crashk_res.start;
  	image->type = KEXEC_TYPE_CRASH;
  
  	/*
  	 * Verify we have good destination addresses.  Normally
  	 * the caller is responsible for making certain we don't
  	 * attempt to load the new image into invalid or reserved
  	 * areas of RAM.  But crash kernels are preloaded into a
  	 * reserved area of ram.  We must ensure the addresses
  	 * are in the reserved area otherwise preloading the
  	 * kernel could corrupt things.
  	 */
  	result = -EADDRNOTAVAIL;
  	for (i = 0; i < nr_segments; i++) {
  		unsigned long mstart, mend;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
311

dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
312
  		mstart = image->segment[i].mem;
50cccc699   Vivek Goyal   [PATCH] Kexec on ...
313
  		mend = mstart + image->segment[i].memsz - 1;
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
314
315
  		/* Ensure we are within the crash kernel limits */
  		if ((mstart < crashk_res.start) || (mend > crashk_res.end))
8c333ac2e   Zhang Yanfei   kexec: avoid free...
316
  			goto out_free;
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
317
  	}
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
318
319
320
321
322
323
324
  	/*
  	 * Find a location for the control code buffer, and add
  	 * the vector of segments so that it's pages will also be
  	 * counted as destination pages.
  	 */
  	result = -ENOMEM;
  	image->control_code_page = kimage_alloc_control_pages(image,
163f6876f   Huang Ying   kexec jump: renam...
325
  					   get_order(KEXEC_CONTROL_PAGE_SIZE));
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
326
  	if (!image->control_code_page) {
e1bebcf41   Fabian Frederick   kernel/kexec.c: c...
327
328
  		pr_err("Could not allocate control_code_buffer
  ");
8c333ac2e   Zhang Yanfei   kexec: avoid free...
329
  		goto out_free;
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
330
  	}
8c333ac2e   Zhang Yanfei   kexec: avoid free...
331
332
  	*rimage = image;
  	return 0;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
333

8c333ac2e   Zhang Yanfei   kexec: avoid free...
334
335
336
  out_free:
  	kfree(image);
  out:
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
337
338
  	return result;
  }
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
339
340
341
  static int kimage_is_destination_range(struct kimage *image,
  					unsigned long start,
  					unsigned long end)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
342
343
344
345
346
  {
  	unsigned long i;
  
  	for (i = 0; i < image->nr_segments; i++) {
  		unsigned long mstart, mend;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
347

dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
348
  		mstart = image->segment[i].mem;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
349
350
  		mend = mstart + image->segment[i].memsz;
  		if ((end > mstart) && (start < mend))
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
351
  			return 1;
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
352
  	}
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
353

dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
354
355
  	return 0;
  }
9796fdd82   Al Viro   [PATCH] gfp_t: ke...
356
  static struct page *kimage_alloc_pages(gfp_t gfp_mask, unsigned int order)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
357
358
  {
  	struct page *pages;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
359

dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
360
361
362
363
  	pages = alloc_pages(gfp_mask, order);
  	if (pages) {
  		unsigned int count, i;
  		pages->mapping = NULL;
4c21e2f24   Hugh Dickins   [PATCH] mm: split...
364
  		set_page_private(pages, order);
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
365
  		count = 1 << order;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
366
  		for (i = 0; i < count; i++)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
367
  			SetPageReserved(pages + i);
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
368
  	}
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
369

dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
370
371
372
373
374
375
  	return pages;
  }
  
  static void kimage_free_pages(struct page *page)
  {
  	unsigned int order, count, i;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
376

4c21e2f24   Hugh Dickins   [PATCH] mm: split...
377
  	order = page_private(page);
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
378
  	count = 1 << order;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
379
  	for (i = 0; i < count; i++)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
380
  		ClearPageReserved(page + i);
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
381
382
383
384
385
386
  	__free_pages(page, order);
  }
  
  static void kimage_free_page_list(struct list_head *list)
  {
  	struct list_head *pos, *next;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
387

dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
388
389
390
391
392
  	list_for_each_safe(pos, next, list) {
  		struct page *page;
  
  		page = list_entry(pos, struct page, lru);
  		list_del(&page->lru);
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
393
394
395
  		kimage_free_pages(page);
  	}
  }
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
396
397
  static struct page *kimage_alloc_normal_control_pages(struct kimage *image,
  							unsigned int order)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
  {
  	/* Control pages are special, they are the intermediaries
  	 * that are needed while we copy the rest of the pages
  	 * to their final resting place.  As such they must
  	 * not conflict with either the destination addresses
  	 * or memory the kernel is already using.
  	 *
  	 * The only case where we really need more than one of
  	 * these are for architectures where we cannot disable
  	 * the MMU and must instead generate an identity mapped
  	 * page table for all of the memory.
  	 *
  	 * At worst this runs in O(N) of the image size.
  	 */
  	struct list_head extra_pages;
  	struct page *pages;
  	unsigned int count;
  
  	count = 1 << order;
  	INIT_LIST_HEAD(&extra_pages);
  
  	/* Loop while I can allocate a page and the page allocated
  	 * is a destination page.
  	 */
  	do {
  		unsigned long pfn, epfn, addr, eaddr;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
424

dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
425
426
427
428
429
430
431
432
  		pages = kimage_alloc_pages(GFP_KERNEL, order);
  		if (!pages)
  			break;
  		pfn   = page_to_pfn(pages);
  		epfn  = pfn + count;
  		addr  = pfn << PAGE_SHIFT;
  		eaddr = epfn << PAGE_SHIFT;
  		if ((epfn >= (KEXEC_CONTROL_MEMORY_LIMIT >> PAGE_SHIFT)) ||
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
433
  			      kimage_is_destination_range(image, addr, eaddr)) {
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
434
435
436
  			list_add(&pages->lru, &extra_pages);
  			pages = NULL;
  		}
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
437
  	} while (!pages);
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
438
439
440
441
442
443
444
445
446
447
448
449
450
451
  	if (pages) {
  		/* Remember the allocated page... */
  		list_add(&pages->lru, &image->control_pages);
  
  		/* Because the page is already in it's destination
  		 * location we will never allocate another page at
  		 * that address.  Therefore kimage_alloc_pages
  		 * will not return it (again) and we don't need
  		 * to give it an entry in image->segment[].
  		 */
  	}
  	/* Deal with the destination pages I have inadvertently allocated.
  	 *
  	 * Ideally I would convert multi-page allocations into single
25985edce   Lucas De Marchi   Fix common misspe...
452
  	 * page allocations, and add everything to image->dest_pages.
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
453
454
455
456
  	 *
  	 * For now it is simpler to just free the pages.
  	 */
  	kimage_free_page_list(&extra_pages);
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
457

72414d3f1   Maneesh Soni   [PATCH] kexec cod...
458
  	return pages;
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
459
  }
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
460
461
  static struct page *kimage_alloc_crash_control_pages(struct kimage *image,
  						      unsigned int order)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
  {
  	/* Control pages are special, they are the intermediaries
  	 * that are needed while we copy the rest of the pages
  	 * to their final resting place.  As such they must
  	 * not conflict with either the destination addresses
  	 * or memory the kernel is already using.
  	 *
  	 * Control pages are also the only pags we must allocate
  	 * when loading a crash kernel.  All of the other pages
  	 * are specified by the segments and we just memcpy
  	 * into them directly.
  	 *
  	 * The only case where we really need more than one of
  	 * these are for architectures where we cannot disable
  	 * the MMU and must instead generate an identity mapped
  	 * page table for all of the memory.
  	 *
  	 * Given the low demand this implements a very simple
  	 * allocator that finds the first hole of the appropriate
  	 * size in the reserved memory region, and allocates all
  	 * of the memory up to and including the hole.
  	 */
  	unsigned long hole_start, hole_end, size;
  	struct page *pages;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
486

dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
487
488
489
490
  	pages = NULL;
  	size = (1 << order) << PAGE_SHIFT;
  	hole_start = (image->control_page + (size - 1)) & ~(size - 1);
  	hole_end   = hole_start + size - 1;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
491
  	while (hole_end <= crashk_res.end) {
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
492
  		unsigned long i;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
493

3d214faea   Michael Holzheu   [S390] kdump: Add...
494
  		if (hole_end > KEXEC_CRASH_CONTROL_MEMORY_LIMIT)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
495
  			break;
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
496
  		/* See if I overlap any of the segments */
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
497
  		for (i = 0; i < image->nr_segments; i++) {
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
498
  			unsigned long mstart, mend;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
499

dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
  			mstart = image->segment[i].mem;
  			mend   = mstart + image->segment[i].memsz - 1;
  			if ((hole_end >= mstart) && (hole_start <= mend)) {
  				/* Advance the hole to the end of the segment */
  				hole_start = (mend + (size - 1)) & ~(size - 1);
  				hole_end   = hole_start + size - 1;
  				break;
  			}
  		}
  		/* If I don't overlap any segments I have found my hole! */
  		if (i == image->nr_segments) {
  			pages = pfn_to_page(hole_start >> PAGE_SHIFT);
  			break;
  		}
  	}
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
515
  	if (pages)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
516
  		image->control_page = hole_end;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
517

dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
518
519
  	return pages;
  }
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
520
521
  struct page *kimage_alloc_control_pages(struct kimage *image,
  					 unsigned int order)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
522
523
  {
  	struct page *pages = NULL;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
524
525
  
  	switch (image->type) {
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
526
527
528
529
530
531
532
  	case KEXEC_TYPE_DEFAULT:
  		pages = kimage_alloc_normal_control_pages(image, order);
  		break;
  	case KEXEC_TYPE_CRASH:
  		pages = kimage_alloc_crash_control_pages(image, order);
  		break;
  	}
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
533

dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
534
535
536
537
538
  	return pages;
  }
  
  static int kimage_add_entry(struct kimage *image, kimage_entry_t entry)
  {
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
539
  	if (*image->entry != 0)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
540
  		image->entry++;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
541

dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
542
543
544
  	if (image->entry == image->last_entry) {
  		kimage_entry_t *ind_page;
  		struct page *page;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
545

dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
546
  		page = kimage_alloc_page(image, GFP_KERNEL, KIMAGE_NO_DEST);
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
547
  		if (!page)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
548
  			return -ENOMEM;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
549

dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
550
551
552
  		ind_page = page_address(page);
  		*image->entry = virt_to_phys(ind_page) | IND_INDIRECTION;
  		image->entry = ind_page;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
553
554
  		image->last_entry = ind_page +
  				      ((PAGE_SIZE/sizeof(kimage_entry_t)) - 1);
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
555
556
557
558
  	}
  	*image->entry = entry;
  	image->entry++;
  	*image->entry = 0;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
559

dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
560
561
  	return 0;
  }
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
562
563
  static int kimage_set_destination(struct kimage *image,
  				   unsigned long destination)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
564
565
566
567
568
  {
  	int result;
  
  	destination &= PAGE_MASK;
  	result = kimage_add_entry(image, destination | IND_DESTINATION);
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
569
  	if (result == 0)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
570
  		image->destination = destination;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
571

dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
572
573
574
575
576
577
578
579
580
581
  	return result;
  }
  
  
  static int kimage_add_page(struct kimage *image, unsigned long page)
  {
  	int result;
  
  	page &= PAGE_MASK;
  	result = kimage_add_entry(image, page | IND_SOURCE);
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
582
  	if (result == 0)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
583
  		image->destination += PAGE_SIZE;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
584

dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
585
586
587
588
589
590
591
592
  	return result;
  }
  
  
  static void kimage_free_extra_pages(struct kimage *image)
  {
  	/* Walk through and free any extra destination pages I may have */
  	kimage_free_page_list(&image->dest_pages);
25985edce   Lucas De Marchi   Fix common misspe...
593
  	/* Walk through and free any unusable pages I have cached */
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
594
595
596
  	kimage_free_page_list(&image->unuseable_pages);
  
  }
7fccf0326   WANG Cong   kernel/kexec.c: m...
597
  static void kimage_terminate(struct kimage *image)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
598
  {
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
599
  	if (*image->entry != 0)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
600
  		image->entry++;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
601

dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
602
  	*image->entry = IND_DONE;
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
603
604
605
606
  }
  
  #define for_each_kimage_entry(image, ptr, entry) \
  	for (ptr = &image->head; (entry = *ptr) && !(entry & IND_DONE); \
e1bebcf41   Fabian Frederick   kernel/kexec.c: c...
607
608
  		ptr = (entry & IND_INDIRECTION) ? \
  			phys_to_virt((entry & PAGE_MASK)) : ptr + 1)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
  
  static void kimage_free_entry(kimage_entry_t entry)
  {
  	struct page *page;
  
  	page = pfn_to_page(entry >> PAGE_SHIFT);
  	kimage_free_pages(page);
  }
  
  static void kimage_free(struct kimage *image)
  {
  	kimage_entry_t *ptr, entry;
  	kimage_entry_t ind = 0;
  
  	if (!image)
  		return;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
625

dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
626
627
628
629
  	kimage_free_extra_pages(image);
  	for_each_kimage_entry(image, ptr, entry) {
  		if (entry & IND_INDIRECTION) {
  			/* Free the previous indirection page */
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
630
  			if (ind & IND_INDIRECTION)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
631
  				kimage_free_entry(ind);
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
632
633
634
635
  			/* Save this indirection page until we are
  			 * done with it.
  			 */
  			ind = entry;
e1bebcf41   Fabian Frederick   kernel/kexec.c: c...
636
  		} else if (entry & IND_SOURCE)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
637
  			kimage_free_entry(entry);
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
638
639
  	}
  	/* Free the final indirection page */
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
640
  	if (ind & IND_INDIRECTION)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
641
  		kimage_free_entry(ind);
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
642
643
644
645
646
647
648
649
  
  	/* Handle any machine specific cleanup */
  	machine_kexec_cleanup(image);
  
  	/* Free the kexec control pages... */
  	kimage_free_page_list(&image->control_pages);
  	kfree(image);
  }
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
650
651
  static kimage_entry_t *kimage_dst_used(struct kimage *image,
  					unsigned long page)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
652
653
654
655
656
  {
  	kimage_entry_t *ptr, entry;
  	unsigned long destination = 0;
  
  	for_each_kimage_entry(image, ptr, entry) {
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
657
  		if (entry & IND_DESTINATION)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
658
  			destination = entry & PAGE_MASK;
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
659
  		else if (entry & IND_SOURCE) {
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
660
  			if (page == destination)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
661
  				return ptr;
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
662
663
664
  			destination += PAGE_SIZE;
  		}
  	}
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
665

314b6a4d8   Alexey Dobriyan   [PATCH] kexec: fi...
666
  	return NULL;
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
667
  }
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
668
  static struct page *kimage_alloc_page(struct kimage *image,
9796fdd82   Al Viro   [PATCH] gfp_t: ke...
669
  					gfp_t gfp_mask,
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
670
  					unsigned long destination)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
  {
  	/*
  	 * Here we implement safeguards to ensure that a source page
  	 * is not copied to its destination page before the data on
  	 * the destination page is no longer useful.
  	 *
  	 * To do this we maintain the invariant that a source page is
  	 * either its own destination page, or it is not a
  	 * destination page at all.
  	 *
  	 * That is slightly stronger than required, but the proof
  	 * that no problems will not occur is trivial, and the
  	 * implementation is simply to verify.
  	 *
  	 * When allocating all pages normally this algorithm will run
  	 * in O(N) time, but in the worst case it will run in O(N^2)
  	 * time.   If the runtime is a problem the data structures can
  	 * be fixed.
  	 */
  	struct page *page;
  	unsigned long addr;
  
  	/*
  	 * Walk through the list of destination pages, and see if I
  	 * have a match.
  	 */
  	list_for_each_entry(page, &image->dest_pages, lru) {
  		addr = page_to_pfn(page) << PAGE_SHIFT;
  		if (addr == destination) {
  			list_del(&page->lru);
  			return page;
  		}
  	}
  	page = NULL;
  	while (1) {
  		kimage_entry_t *old;
  
  		/* Allocate a page, if we run out of memory give up */
  		page = kimage_alloc_pages(gfp_mask, 0);
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
710
  		if (!page)
314b6a4d8   Alexey Dobriyan   [PATCH] kexec: fi...
711
  			return NULL;
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
712
  		/* If the page cannot be used file it away */
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
713
714
  		if (page_to_pfn(page) >
  				(KEXEC_SOURCE_MEMORY_LIMIT >> PAGE_SHIFT)) {
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
715
716
717
718
719
720
721
722
723
724
  			list_add(&page->lru, &image->unuseable_pages);
  			continue;
  		}
  		addr = page_to_pfn(page) << PAGE_SHIFT;
  
  		/* If it is the destination page we want use it */
  		if (addr == destination)
  			break;
  
  		/* If the page is not a destination page use it */
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
725
726
  		if (!kimage_is_destination_range(image, addr,
  						  addr + PAGE_SIZE))
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
  			break;
  
  		/*
  		 * I know that the page is someones destination page.
  		 * See if there is already a source page for this
  		 * destination page.  And if so swap the source pages.
  		 */
  		old = kimage_dst_used(image, addr);
  		if (old) {
  			/* If so move it */
  			unsigned long old_addr;
  			struct page *old_page;
  
  			old_addr = *old & PAGE_MASK;
  			old_page = pfn_to_page(old_addr >> PAGE_SHIFT);
  			copy_highpage(page, old_page);
  			*old = addr | (*old & ~PAGE_MASK);
  
  			/* The old page I have found cannot be a
f9092f358   Jonathan Steel   kexec: fix segmen...
746
747
  			 * destination page, so return it if it's
  			 * gfp_flags honor the ones passed in.
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
748
  			 */
f9092f358   Jonathan Steel   kexec: fix segmen...
749
750
751
752
753
  			if (!(gfp_mask & __GFP_HIGHMEM) &&
  			    PageHighMem(old_page)) {
  				kimage_free_pages(old_page);
  				continue;
  			}
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
754
755
756
  			addr = old_addr;
  			page = old_page;
  			break;
e1bebcf41   Fabian Frederick   kernel/kexec.c: c...
757
  		} else {
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
758
759
760
761
762
763
  			/* Place the page on the destination list I
  			 * will use it later.
  			 */
  			list_add(&page->lru, &image->dest_pages);
  		}
  	}
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
764

dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
765
766
767
768
  	return page;
  }
  
  static int kimage_load_normal_segment(struct kimage *image,
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
769
  					 struct kexec_segment *segment)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
770
771
  {
  	unsigned long maddr;
310faaa9b   Zhang Yanfei   kexec: fix wrong ...
772
  	size_t ubytes, mbytes;
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
773
  	int result;
314b6a4d8   Alexey Dobriyan   [PATCH] kexec: fi...
774
  	unsigned char __user *buf;
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
775
776
777
778
779
780
781
782
  
  	result = 0;
  	buf = segment->buf;
  	ubytes = segment->bufsz;
  	mbytes = segment->memsz;
  	maddr = segment->mem;
  
  	result = kimage_set_destination(image, maddr);
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
783
  	if (result < 0)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
784
  		goto out;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
785
786
  
  	while (mbytes) {
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
787
788
789
  		struct page *page;
  		char *ptr;
  		size_t uchunk, mchunk;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
790

dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
791
  		page = kimage_alloc_page(image, GFP_HIGHUSER, maddr);
c80544dc0   Stephen Hemminger   sparse pointer us...
792
  		if (!page) {
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
793
794
795
  			result  = -ENOMEM;
  			goto out;
  		}
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
796
797
798
  		result = kimage_add_page(image, page_to_pfn(page)
  								<< PAGE_SHIFT);
  		if (result < 0)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
799
  			goto out;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
800

dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
801
802
  		ptr = kmap(page);
  		/* Start with a clear page */
3ecb01df3   Jan Beulich   use clear_page()/...
803
  		clear_page(ptr);
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
804
  		ptr += maddr & ~PAGE_MASK;
31c3a3fe0   Zhang Yanfei   kexec: Use min() ...
805
806
807
  		mchunk = min_t(size_t, mbytes,
  				PAGE_SIZE - (maddr & ~PAGE_MASK));
  		uchunk = min(ubytes, mchunk);
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
808

dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
809
810
811
  		result = copy_from_user(ptr, buf, uchunk);
  		kunmap(page);
  		if (result) {
f65a03f6a   Dan Carpenter   kexec: return -EF...
812
  			result = -EFAULT;
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
813
814
815
816
817
818
819
  			goto out;
  		}
  		ubytes -= uchunk;
  		maddr  += mchunk;
  		buf    += mchunk;
  		mbytes -= mchunk;
  	}
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
820
  out:
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
821
822
823
824
  	return result;
  }
  
  static int kimage_load_crash_segment(struct kimage *image,
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
825
  					struct kexec_segment *segment)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
826
827
828
829
830
831
  {
  	/* For crash dumps kernels we simply copy the data from
  	 * user space to it's destination.
  	 * We do things a page at a time for the sake of kmap.
  	 */
  	unsigned long maddr;
310faaa9b   Zhang Yanfei   kexec: fix wrong ...
832
  	size_t ubytes, mbytes;
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
833
  	int result;
314b6a4d8   Alexey Dobriyan   [PATCH] kexec: fi...
834
  	unsigned char __user *buf;
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
835
836
837
838
839
840
  
  	result = 0;
  	buf = segment->buf;
  	ubytes = segment->bufsz;
  	mbytes = segment->memsz;
  	maddr = segment->mem;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
841
  	while (mbytes) {
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
842
843
844
  		struct page *page;
  		char *ptr;
  		size_t uchunk, mchunk;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
845

dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
846
  		page = pfn_to_page(maddr >> PAGE_SHIFT);
c80544dc0   Stephen Hemminger   sparse pointer us...
847
  		if (!page) {
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
848
849
850
851
852
  			result  = -ENOMEM;
  			goto out;
  		}
  		ptr = kmap(page);
  		ptr += maddr & ~PAGE_MASK;
31c3a3fe0   Zhang Yanfei   kexec: Use min() ...
853
854
855
856
  		mchunk = min_t(size_t, mbytes,
  				PAGE_SIZE - (maddr & ~PAGE_MASK));
  		uchunk = min(ubytes, mchunk);
  		if (mchunk > uchunk) {
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
857
858
859
860
  			/* Zero the trailing part of the page */
  			memset(ptr + uchunk, 0, mchunk - uchunk);
  		}
  		result = copy_from_user(ptr, buf, uchunk);
a79561134   Zou Nan hai   [IA64] IA64 Kexec...
861
  		kexec_flush_icache_page(page);
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
862
863
  		kunmap(page);
  		if (result) {
f65a03f6a   Dan Carpenter   kexec: return -EF...
864
  			result = -EFAULT;
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
865
866
867
868
869
870
871
  			goto out;
  		}
  		ubytes -= uchunk;
  		maddr  += mchunk;
  		buf    += mchunk;
  		mbytes -= mchunk;
  	}
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
872
  out:
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
873
874
875
876
  	return result;
  }
  
  static int kimage_load_segment(struct kimage *image,
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
877
  				struct kexec_segment *segment)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
878
879
  {
  	int result = -ENOMEM;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
880
881
  
  	switch (image->type) {
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
882
883
884
885
886
887
888
  	case KEXEC_TYPE_DEFAULT:
  		result = kimage_load_normal_segment(image, segment);
  		break;
  	case KEXEC_TYPE_CRASH:
  		result = kimage_load_crash_segment(image, segment);
  		break;
  	}
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
889

dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
  	return result;
  }
  
  /*
   * Exec Kernel system call: for obvious reasons only root may call it.
   *
   * This call breaks up into three pieces.
   * - A generic part which loads the new kernel from the current
   *   address space, and very carefully places the data in the
   *   allocated pages.
   *
   * - A generic part that interacts with the kernel and tells all of
   *   the devices to shut down.  Preventing on-going dmas, and placing
   *   the devices in a consistent state so a later kernel can
   *   reinitialize them.
   *
   * - A machine specific part that includes the syscall number
002ace782   Geert Uytterhoeven   kexec: Typo s/the...
907
   *   and then copies the image to it's final destination.  And
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
908
909
910
911
912
   *   jumps into the image at entry.
   *
   * kexec does not sync, or unmount filesystems so if you need
   * that to happen you need to do that yourself.
   */
c330dda90   Jeff Moyer   [PATCH] Add a sys...
913
914
  struct kimage *kexec_image;
  struct kimage *kexec_crash_image;
7984754b9   Kees Cook   kexec: add sysctl...
915
  int kexec_load_disabled;
8c5a1cf0a   Andrew Morton   kexec: use a mute...
916
917
  
  static DEFINE_MUTEX(kexec_mutex);
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
918

754fe8d29   Heiko Carstens   [CVE-2009-0029] S...
919
920
  SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
  		struct kexec_segment __user *, segments, unsigned long, flags)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
921
922
  {
  	struct kimage **dest_image, *image;
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
923
924
925
  	int result;
  
  	/* We only trust the superuser with rebooting the system. */
7984754b9   Kees Cook   kexec: add sysctl...
926
  	if (!capable(CAP_SYS_BOOT) || kexec_load_disabled)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
927
928
929
930
931
932
933
934
935
936
937
938
  		return -EPERM;
  
  	/*
  	 * Verify we have a legal set of flags
  	 * This leaves us room for future extensions.
  	 */
  	if ((flags & KEXEC_FLAGS) != (flags & ~KEXEC_ARCH_MASK))
  		return -EINVAL;
  
  	/* Verify we are on the appropriate architecture */
  	if (((flags & KEXEC_ARCH_MASK) != KEXEC_ARCH) &&
  		((flags & KEXEC_ARCH_MASK) != KEXEC_ARCH_DEFAULT))
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
939
  		return -EINVAL;
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
  
  	/* Put an artificial cap on the number
  	 * of segments passed to kexec_load.
  	 */
  	if (nr_segments > KEXEC_SEGMENT_MAX)
  		return -EINVAL;
  
  	image = NULL;
  	result = 0;
  
  	/* Because we write directly to the reserved memory
  	 * region when loading crash kernels we need a mutex here to
  	 * prevent multiple crash  kernels from attempting to load
  	 * simultaneously, and to prevent a crash kernel from loading
  	 * over the top of a in use crash kernel.
  	 *
  	 * KISS: always take the mutex.
  	 */
8c5a1cf0a   Andrew Morton   kexec: use a mute...
958
  	if (!mutex_trylock(&kexec_mutex))
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
959
  		return -EBUSY;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
960

dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
961
  	dest_image = &kexec_image;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
962
  	if (flags & KEXEC_ON_CRASH)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
963
  		dest_image = &kexec_crash_image;
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
964
965
  	if (nr_segments > 0) {
  		unsigned long i;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
966

dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
967
  		/* Loading another kernel to reboot into */
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
968
969
970
  		if ((flags & KEXEC_ON_CRASH) == 0)
  			result = kimage_normal_alloc(&image, entry,
  							nr_segments, segments);
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
971
972
973
974
975
976
  		/* Loading another kernel to switch to if this one crashes */
  		else if (flags & KEXEC_ON_CRASH) {
  			/* Free any current crash dump kernel before
  			 * we corrupt it.
  			 */
  			kimage_free(xchg(&kexec_crash_image, NULL));
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
977
978
  			result = kimage_crash_alloc(&image, entry,
  						     nr_segments, segments);
558df7209   Michael Holzheu   [S390] kdump: Add...
979
  			crash_map_reserved_pages();
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
980
  		}
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
981
  		if (result)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
982
  			goto out;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
983

3ab835213   Huang Ying   kexec jump
984
985
  		if (flags & KEXEC_PRESERVE_CONTEXT)
  			image->preserve_context = 1;
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
986
  		result = machine_kexec_prepare(image);
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
987
  		if (result)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
988
  			goto out;
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
989
990
  
  		for (i = 0; i < nr_segments; i++) {
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
991
  			result = kimage_load_segment(image, &image->segment[i]);
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
992
  			if (result)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
993
  				goto out;
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
994
  		}
7fccf0326   WANG Cong   kernel/kexec.c: m...
995
  		kimage_terminate(image);
558df7209   Michael Holzheu   [S390] kdump: Add...
996
997
  		if (flags & KEXEC_ON_CRASH)
  			crash_unmap_reserved_pages();
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
998
999
1000
  	}
  	/* Install the new kernel, and  Uninstall the old */
  	image = xchg(dest_image, image);
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
1001
  out:
8c5a1cf0a   Andrew Morton   kexec: use a mute...
1002
  	mutex_unlock(&kexec_mutex);
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
1003
  	kimage_free(image);
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
1004

dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
1005
1006
  	return result;
  }
558df7209   Michael Holzheu   [S390] kdump: Add...
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
  /*
   * Add and remove page tables for crashkernel memory
   *
   * Provide an empty default implementation here -- architecture
   * code may override this
   */
  void __weak crash_map_reserved_pages(void)
  {}
  
  void __weak crash_unmap_reserved_pages(void)
  {}
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
1018
  #ifdef CONFIG_COMPAT
ca2c405ab   Heiko Carstens   kexec/compat: con...
1019
1020
1021
1022
  COMPAT_SYSCALL_DEFINE4(kexec_load, compat_ulong_t, entry,
  		       compat_ulong_t, nr_segments,
  		       struct compat_kexec_segment __user *, segments,
  		       compat_ulong_t, flags)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
1023
1024
1025
1026
1027
1028
1029
1030
  {
  	struct compat_kexec_segment in;
  	struct kexec_segment out, __user *ksegments;
  	unsigned long i, result;
  
  	/* Don't allow clients that don't understand the native
  	 * architecture to do anything.
  	 */
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
1031
  	if ((flags & KEXEC_ARCH_MASK) == KEXEC_ARCH_DEFAULT)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
1032
  		return -EINVAL;
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
1033

72414d3f1   Maneesh Soni   [PATCH] kexec cod...
1034
  	if (nr_segments > KEXEC_SEGMENT_MAX)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
1035
  		return -EINVAL;
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
1036
1037
  
  	ksegments = compat_alloc_user_space(nr_segments * sizeof(out));
e1bebcf41   Fabian Frederick   kernel/kexec.c: c...
1038
  	for (i = 0; i < nr_segments; i++) {
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
1039
  		result = copy_from_user(&in, &segments[i], sizeof(in));
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
1040
  		if (result)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
1041
  			return -EFAULT;
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
1042
1043
1044
1045
1046
1047
1048
  
  		out.buf   = compat_ptr(in.buf);
  		out.bufsz = in.bufsz;
  		out.mem   = in.mem;
  		out.memsz = in.memsz;
  
  		result = copy_to_user(&ksegments[i], &out, sizeof(out));
72414d3f1   Maneesh Soni   [PATCH] kexec cod...
1049
  		if (result)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
1050
  			return -EFAULT;
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
1051
1052
1053
1054
1055
  	}
  
  	return sys_kexec_load(entry, nr_segments, ksegments, flags);
  }
  #endif
6e274d144   Alexander Nyberg   [PATCH] kdump: Us...
1056
  void crash_kexec(struct pt_regs *regs)
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
1057
  {
8c5a1cf0a   Andrew Morton   kexec: use a mute...
1058
  	/* Take the kexec_mutex here to prevent sys_kexec_load
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
1059
1060
1061
1062
1063
1064
1065
  	 * running on one cpu from replacing the crash kernel
  	 * we are using after a panic on a different cpu.
  	 *
  	 * If the crash kernel was not located in a fixed area
  	 * of memory the xchg(&kexec_crash_image) would be
  	 * sufficient.  But since I reuse the memory...
  	 */
8c5a1cf0a   Andrew Morton   kexec: use a mute...
1066
  	if (mutex_trylock(&kexec_mutex)) {
c0ce7d088   David Wilder   [POWERPC] Add the...
1067
  		if (kexec_crash_image) {
e996e5813   Vivek Goyal   [PATCH] kdump: sa...
1068
  			struct pt_regs fixed_regs;
0f4bd46ec   KOSAKI Motohiro   kmsg_dump: Dump o...
1069

e996e5813   Vivek Goyal   [PATCH] kdump: sa...
1070
  			crash_setup_regs(&fixed_regs, regs);
fd59d231f   Ken'ichi Ohmichi   Add vmcoreinfo
1071
  			crash_save_vmcoreinfo();
e996e5813   Vivek Goyal   [PATCH] kdump: sa...
1072
  			machine_crash_shutdown(&fixed_regs);
c0ce7d088   David Wilder   [POWERPC] Add the...
1073
  			machine_kexec(kexec_crash_image);
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
1074
  		}
8c5a1cf0a   Andrew Morton   kexec: use a mute...
1075
  		mutex_unlock(&kexec_mutex);
dc009d924   Eric W. Biederman   [PATCH] kexec: ad...
1076
1077
  	}
  }
cc5716587   Vivek Goyal   [PATCH] kdump: dy...
1078

06a7f7112   Amerigo Wang   kexec: premit red...
1079
1080
  size_t crash_get_memory_size(void)
  {
e05bd3367   Pavan Naregundi   kexec: fix Oops i...
1081
  	size_t size = 0;
06a7f7112   Amerigo Wang   kexec: premit red...
1082
  	mutex_lock(&kexec_mutex);
e05bd3367   Pavan Naregundi   kexec: fix Oops i...
1083
  	if (crashk_res.end != crashk_res.start)
28f65c11f   Joe Perches   treewide: Convert...
1084
  		size = resource_size(&crashk_res);
06a7f7112   Amerigo Wang   kexec: premit red...
1085
1086
1087
  	mutex_unlock(&kexec_mutex);
  	return size;
  }
c0bb9e45f   Anton Blanchard   kdump: Allow shri...
1088
1089
  void __weak crash_free_reserved_phys_range(unsigned long begin,
  					   unsigned long end)
06a7f7112   Amerigo Wang   kexec: premit red...
1090
1091
  {
  	unsigned long addr;
e07cee23e   Jiang Liu   mm,kexec: use com...
1092
1093
  	for (addr = begin; addr < end; addr += PAGE_SIZE)
  		free_reserved_page(pfn_to_page(addr >> PAGE_SHIFT));
06a7f7112   Amerigo Wang   kexec: premit red...
1094
1095
1096
1097
1098
1099
  }
  
  int crash_shrink_memory(unsigned long new_size)
  {
  	int ret = 0;
  	unsigned long start, end;
bec013c40   Michael Holzheu   kdump: crashk_res...
1100
  	unsigned long old_size;
6480e5a09   Michael Holzheu   kdump: add missin...
1101
  	struct resource *ram_res;
06a7f7112   Amerigo Wang   kexec: premit red...
1102
1103
1104
1105
1106
1107
1108
1109
1110
  
  	mutex_lock(&kexec_mutex);
  
  	if (kexec_crash_image) {
  		ret = -ENOENT;
  		goto unlock;
  	}
  	start = crashk_res.start;
  	end = crashk_res.end;
bec013c40   Michael Holzheu   kdump: crashk_res...
1111
1112
1113
  	old_size = (end == 0) ? 0 : end - start + 1;
  	if (new_size >= old_size) {
  		ret = (new_size == old_size) ? 0 : -EINVAL;
06a7f7112   Amerigo Wang   kexec: premit red...
1114
1115
  		goto unlock;
  	}
6480e5a09   Michael Holzheu   kdump: add missin...
1116
1117
1118
1119
1120
  	ram_res = kzalloc(sizeof(*ram_res), GFP_KERNEL);
  	if (!ram_res) {
  		ret = -ENOMEM;
  		goto unlock;
  	}
558df7209   Michael Holzheu   [S390] kdump: Add...
1121
1122
  	start = roundup(start, KEXEC_CRASH_MEM_ALIGN);
  	end = roundup(start + new_size, KEXEC_CRASH_MEM_ALIGN);
06a7f7112   Amerigo Wang   kexec: premit red...
1123

558df7209   Michael Holzheu   [S390] kdump: Add...
1124
  	crash_map_reserved_pages();
c0bb9e45f   Anton Blanchard   kdump: Allow shri...
1125
  	crash_free_reserved_phys_range(end, crashk_res.end);
06a7f7112   Amerigo Wang   kexec: premit red...
1126

e05bd3367   Pavan Naregundi   kexec: fix Oops i...
1127
  	if ((start == end) && (crashk_res.parent != NULL))
06a7f7112   Amerigo Wang   kexec: premit red...
1128
  		release_resource(&crashk_res);
6480e5a09   Michael Holzheu   kdump: add missin...
1129
1130
1131
1132
1133
  
  	ram_res->start = end;
  	ram_res->end = crashk_res.end;
  	ram_res->flags = IORESOURCE_BUSY | IORESOURCE_MEM;
  	ram_res->name = "System RAM";
475f9aa6a   Vitaly Mayatskikh   kexec: fix OOPS i...
1134
  	crashk_res.end = end - 1;
6480e5a09   Michael Holzheu   kdump: add missin...
1135
1136
  
  	insert_resource(&iomem_resource, ram_res);
558df7209   Michael Holzheu   [S390] kdump: Add...
1137
  	crash_unmap_reserved_pages();
06a7f7112   Amerigo Wang   kexec: premit red...
1138
1139
1140
1141
1142
  
  unlock:
  	mutex_unlock(&kexec_mutex);
  	return ret;
  }
85916f816   Magnus Damm   [PATCH] Kexec / K...
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
  static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data,
  			    size_t data_len)
  {
  	struct elf_note note;
  
  	note.n_namesz = strlen(name) + 1;
  	note.n_descsz = data_len;
  	note.n_type   = type;
  	memcpy(buf, &note, sizeof(note));
  	buf += (sizeof(note) + 3)/4;
  	memcpy(buf, name, note.n_namesz);
  	buf += (note.n_namesz + 3)/4;
  	memcpy(buf, data, note.n_descsz);
  	buf += (note.n_descsz + 3)/4;
  
  	return buf;
  }
  
  static void final_note(u32 *buf)
  {
  	struct elf_note note;
  
  	note.n_namesz = 0;
  	note.n_descsz = 0;
  	note.n_type   = 0;
  	memcpy(buf, &note, sizeof(note));
  }
  
  void crash_save_cpu(struct pt_regs *regs, int cpu)
  {
  	struct elf_prstatus prstatus;
  	u32 *buf;
4f4b6c1a9   Rusty Russell   cpumask: prepare ...
1175
  	if ((cpu < 0) || (cpu >= nr_cpu_ids))
85916f816   Magnus Damm   [PATCH] Kexec / K...
1176
1177
1178
1179
1180
1181
1182
1183
1184
  		return;
  
  	/* Using ELF notes here is opportunistic.
  	 * I need a well defined structure format
  	 * for the data I pass, and I need tags
  	 * on the data to indicate what information I have
  	 * squirrelled away.  ELF notes happen to provide
  	 * all of that, so there is no need to invent something new.
  	 */
e1bebcf41   Fabian Frederick   kernel/kexec.c: c...
1185
  	buf = (u32 *)per_cpu_ptr(crash_notes, cpu);
85916f816   Magnus Damm   [PATCH] Kexec / K...
1186
1187
1188
1189
  	if (!buf)
  		return;
  	memset(&prstatus, 0, sizeof(prstatus));
  	prstatus.pr_pid = current->pid;
6cd61c0ba   Tejun Heo   elf: add ELF_CORE...
1190
  	elf_core_copy_kernel_regs(&prstatus.pr_reg, regs);
6672f76a5   Simon Horman   kdump/kexec: calc...
1191
  	buf = append_elf_note(buf, KEXEC_CORE_NOTE_NAME, NT_PRSTATUS,
e1bebcf41   Fabian Frederick   kernel/kexec.c: c...
1192
  			      &prstatus, sizeof(prstatus));
85916f816   Magnus Damm   [PATCH] Kexec / K...
1193
1194
  	final_note(buf);
  }
cc5716587   Vivek Goyal   [PATCH] kdump: dy...
1195
1196
1197
1198
1199
  static int __init crash_notes_memory_init(void)
  {
  	/* Allocate memory for saving cpu registers. */
  	crash_notes = alloc_percpu(note_buf_t);
  	if (!crash_notes) {
e1bebcf41   Fabian Frederick   kernel/kexec.c: c...
1200
1201
  		pr_warn("Kexec: Memory allocation for saving cpu register states failed
  ");
cc5716587   Vivek Goyal   [PATCH] kdump: dy...
1202
1203
1204
1205
  		return -ENOMEM;
  	}
  	return 0;
  }
c96d6660d   Paul Gortmaker   kernel: audit/fix...
1206
  subsys_initcall(crash_notes_memory_init);
fd59d231f   Ken'ichi Ohmichi   Add vmcoreinfo
1207

cba63c308   Bernhard Walle   Extended crashker...
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
  
  /*
   * parsing the "crashkernel" commandline
   *
   * this code is intended to be called from architecture specific code
   */
  
  
  /*
   * This function parses command lines in the format
   *
   *   crashkernel=ramsize-range:size[,...][@offset]
   *
   * The function returns 0 on success and -EINVAL on failure.
   */
e1bebcf41   Fabian Frederick   kernel/kexec.c: c...
1223
1224
1225
1226
  static int __init parse_crashkernel_mem(char *cmdline,
  					unsigned long long system_ram,
  					unsigned long long *crash_size,
  					unsigned long long *crash_base)
cba63c308   Bernhard Walle   Extended crashker...
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
  {
  	char *cur = cmdline, *tmp;
  
  	/* for each entry of the comma-separated list */
  	do {
  		unsigned long long start, end = ULLONG_MAX, size;
  
  		/* get the start of the range */
  		start = memparse(cur, &tmp);
  		if (cur == tmp) {
e1bebcf41   Fabian Frederick   kernel/kexec.c: c...
1237
1238
  			pr_warn("crashkernel: Memory value expected
  ");
cba63c308   Bernhard Walle   Extended crashker...
1239
1240
1241
1242
  			return -EINVAL;
  		}
  		cur = tmp;
  		if (*cur != '-') {
e1bebcf41   Fabian Frederick   kernel/kexec.c: c...
1243
1244
  			pr_warn("crashkernel: '-' expected
  ");
cba63c308   Bernhard Walle   Extended crashker...
1245
1246
1247
1248
1249
1250
1251
1252
  			return -EINVAL;
  		}
  		cur++;
  
  		/* if no ':' is here, than we read the end */
  		if (*cur != ':') {
  			end = memparse(cur, &tmp);
  			if (cur == tmp) {
e1bebcf41   Fabian Frederick   kernel/kexec.c: c...
1253
1254
  				pr_warn("crashkernel: Memory value expected
  ");
cba63c308   Bernhard Walle   Extended crashker...
1255
1256
1257
1258
  				return -EINVAL;
  			}
  			cur = tmp;
  			if (end <= start) {
e1bebcf41   Fabian Frederick   kernel/kexec.c: c...
1259
1260
  				pr_warn("crashkernel: end <= start
  ");
cba63c308   Bernhard Walle   Extended crashker...
1261
1262
1263
1264
1265
  				return -EINVAL;
  			}
  		}
  
  		if (*cur != ':') {
e1bebcf41   Fabian Frederick   kernel/kexec.c: c...
1266
1267
  			pr_warn("crashkernel: ':' expected
  ");
cba63c308   Bernhard Walle   Extended crashker...
1268
1269
1270
1271
1272
1273
  			return -EINVAL;
  		}
  		cur++;
  
  		size = memparse(cur, &tmp);
  		if (cur == tmp) {
e1bebcf41   Fabian Frederick   kernel/kexec.c: c...
1274
1275
  			pr_warn("Memory value expected
  ");
cba63c308   Bernhard Walle   Extended crashker...
1276
1277
1278
1279
  			return -EINVAL;
  		}
  		cur = tmp;
  		if (size >= system_ram) {
e1bebcf41   Fabian Frederick   kernel/kexec.c: c...
1280
1281
  			pr_warn("crashkernel: invalid size
  ");
cba63c308   Bernhard Walle   Extended crashker...
1282
1283
1284
1285
  			return -EINVAL;
  		}
  
  		/* match ? */
be089d79c   Michael Ellerman   kexec: make exten...
1286
  		if (system_ram >= start && system_ram < end) {
cba63c308   Bernhard Walle   Extended crashker...
1287
1288
1289
1290
1291
1292
  			*crash_size = size;
  			break;
  		}
  	} while (*cur++ == ',');
  
  	if (*crash_size > 0) {
11c7da4b0   Hidetoshi Seto   kexec: fix omitti...
1293
  		while (*cur && *cur != ' ' && *cur != '@')
cba63c308   Bernhard Walle   Extended crashker...
1294
1295
1296
1297
1298
  			cur++;
  		if (*cur == '@') {
  			cur++;
  			*crash_base = memparse(cur, &tmp);
  			if (cur == tmp) {
e1bebcf41   Fabian Frederick   kernel/kexec.c: c...
1299
1300
  				pr_warn("Memory value expected after '@'
  ");
cba63c308   Bernhard Walle   Extended crashker...
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
  				return -EINVAL;
  			}
  		}
  	}
  
  	return 0;
  }
  
  /*
   * That function parses "simple" (old) crashkernel command lines like
   *
e1bebcf41   Fabian Frederick   kernel/kexec.c: c...
1312
   *	crashkernel=size[@offset]
cba63c308   Bernhard Walle   Extended crashker...
1313
1314
1315
   *
   * It returns 0 on success and -EINVAL on failure.
   */
e1bebcf41   Fabian Frederick   kernel/kexec.c: c...
1316
1317
1318
  static int __init parse_crashkernel_simple(char *cmdline,
  					   unsigned long long *crash_size,
  					   unsigned long long *crash_base)
cba63c308   Bernhard Walle   Extended crashker...
1319
1320
1321
1322
1323
  {
  	char *cur = cmdline;
  
  	*crash_size = memparse(cmdline, &cur);
  	if (cmdline == cur) {
e1bebcf41   Fabian Frederick   kernel/kexec.c: c...
1324
1325
  		pr_warn("crashkernel: memory value expected
  ");
cba63c308   Bernhard Walle   Extended crashker...
1326
1327
1328
1329
1330
  		return -EINVAL;
  	}
  
  	if (*cur == '@')
  		*crash_base = memparse(cur+1, &cur);
eaa3be6ad   Zhenzhong Duan   kexec: add furthe...
1331
  	else if (*cur != ' ' && *cur != '\0') {
e1bebcf41   Fabian Frederick   kernel/kexec.c: c...
1332
1333
  		pr_warn("crashkernel: unrecognized char
  ");
eaa3be6ad   Zhenzhong Duan   kexec: add furthe...
1334
1335
  		return -EINVAL;
  	}
cba63c308   Bernhard Walle   Extended crashker...
1336
1337
1338
  
  	return 0;
  }
adbc742bf   Yinghai Lu   x86, kdump: Chang...
1339
1340
1341
1342
1343
1344
1345
1346
  #define SUFFIX_HIGH 0
  #define SUFFIX_LOW  1
  #define SUFFIX_NULL 2
  static __initdata char *suffix_tbl[] = {
  	[SUFFIX_HIGH] = ",high",
  	[SUFFIX_LOW]  = ",low",
  	[SUFFIX_NULL] = NULL,
  };
cba63c308   Bernhard Walle   Extended crashker...
1347
  /*
adbc742bf   Yinghai Lu   x86, kdump: Chang...
1348
1349
1350
1351
1352
   * That function parses "suffix"  crashkernel command lines like
   *
   *	crashkernel=size,[high|low]
   *
   * It returns 0 on success and -EINVAL on failure.
cba63c308   Bernhard Walle   Extended crashker...
1353
   */
adbc742bf   Yinghai Lu   x86, kdump: Chang...
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
  static int __init parse_crashkernel_suffix(char *cmdline,
  					   unsigned long long	*crash_size,
  					   unsigned long long	*crash_base,
  					   const char *suffix)
  {
  	char *cur = cmdline;
  
  	*crash_size = memparse(cmdline, &cur);
  	if (cmdline == cur) {
  		pr_warn("crashkernel: memory value expected
  ");
  		return -EINVAL;
  	}
  
  	/* check with suffix */
  	if (strncmp(cur, suffix, strlen(suffix))) {
  		pr_warn("crashkernel: unrecognized char
  ");
  		return -EINVAL;
  	}
  	cur += strlen(suffix);
  	if (*cur != ' ' && *cur != '\0') {
  		pr_warn("crashkernel: unrecognized char
  ");
  		return -EINVAL;
  	}
  
  	return 0;
  }
  
  static __init char *get_last_crashkernel(char *cmdline,
  			     const char *name,
  			     const char *suffix)
  {
  	char *p = cmdline, *ck_cmdline = NULL;
  
  	/* find crashkernel and use the last one if there are more */
  	p = strstr(p, name);
  	while (p) {
  		char *end_p = strchr(p, ' ');
  		char *q;
  
  		if (!end_p)
  			end_p = p + strlen(p);
  
  		if (!suffix) {
  			int i;
  
  			/* skip the one with any known suffix */
  			for (i = 0; suffix_tbl[i]; i++) {
  				q = end_p - strlen(suffix_tbl[i]);
  				if (!strncmp(q, suffix_tbl[i],
  					     strlen(suffix_tbl[i])))
  					goto next;
  			}
  			ck_cmdline = p;
  		} else {
  			q = end_p - strlen(suffix);
  			if (!strncmp(q, suffix, strlen(suffix)))
  				ck_cmdline = p;
  		}
  next:
  		p = strstr(p+1, name);
  	}
  
  	if (!ck_cmdline)
  		return NULL;
  
  	return ck_cmdline;
  }
0212f9159   Yinghai Lu   x86: Add Crash ke...
1424
  static int __init __parse_crashkernel(char *cmdline,
cba63c308   Bernhard Walle   Extended crashker...
1425
1426
  			     unsigned long long system_ram,
  			     unsigned long long *crash_size,
0212f9159   Yinghai Lu   x86: Add Crash ke...
1427
  			     unsigned long long *crash_base,
adbc742bf   Yinghai Lu   x86, kdump: Chang...
1428
1429
  			     const char *name,
  			     const char *suffix)
cba63c308   Bernhard Walle   Extended crashker...
1430
  {
cba63c308   Bernhard Walle   Extended crashker...
1431
  	char	*first_colon, *first_space;
adbc742bf   Yinghai Lu   x86, kdump: Chang...
1432
  	char	*ck_cmdline;
cba63c308   Bernhard Walle   Extended crashker...
1433
1434
1435
1436
  
  	BUG_ON(!crash_size || !crash_base);
  	*crash_size = 0;
  	*crash_base = 0;
adbc742bf   Yinghai Lu   x86, kdump: Chang...
1437
  	ck_cmdline = get_last_crashkernel(cmdline, name, suffix);
cba63c308   Bernhard Walle   Extended crashker...
1438
1439
1440
  
  	if (!ck_cmdline)
  		return -EINVAL;
0212f9159   Yinghai Lu   x86: Add Crash ke...
1441
  	ck_cmdline += strlen(name);
cba63c308   Bernhard Walle   Extended crashker...
1442

adbc742bf   Yinghai Lu   x86, kdump: Chang...
1443
1444
1445
  	if (suffix)
  		return parse_crashkernel_suffix(ck_cmdline, crash_size,
  				crash_base, suffix);
cba63c308   Bernhard Walle   Extended crashker...
1446
1447
1448
1449
1450
1451
1452
1453
1454
  	/*
  	 * if the commandline contains a ':', then that's the extended
  	 * syntax -- if not, it must be the classic syntax
  	 */
  	first_colon = strchr(ck_cmdline, ':');
  	first_space = strchr(ck_cmdline, ' ');
  	if (first_colon && (!first_space || first_colon < first_space))
  		return parse_crashkernel_mem(ck_cmdline, system_ram,
  				crash_size, crash_base);
cba63c308   Bernhard Walle   Extended crashker...
1455

80c74f6a4   Xishi Qiu   kexec: remove unn...
1456
  	return parse_crashkernel_simple(ck_cmdline, crash_size, crash_base);
cba63c308   Bernhard Walle   Extended crashker...
1457
  }
adbc742bf   Yinghai Lu   x86, kdump: Chang...
1458
1459
1460
1461
  /*
   * That function is the entry point for command line parsing and should be
   * called from the arch-specific code.
   */
0212f9159   Yinghai Lu   x86: Add Crash ke...
1462
1463
1464
1465
1466
1467
  int __init parse_crashkernel(char *cmdline,
  			     unsigned long long system_ram,
  			     unsigned long long *crash_size,
  			     unsigned long long *crash_base)
  {
  	return __parse_crashkernel(cmdline, system_ram, crash_size, crash_base,
adbc742bf   Yinghai Lu   x86, kdump: Chang...
1468
  					"crashkernel=", NULL);
0212f9159   Yinghai Lu   x86: Add Crash ke...
1469
  }
55a20ee78   Yinghai Lu   x86, kdump: Retor...
1470
1471
1472
1473
1474
1475
1476
  
  int __init parse_crashkernel_high(char *cmdline,
  			     unsigned long long system_ram,
  			     unsigned long long *crash_size,
  			     unsigned long long *crash_base)
  {
  	return __parse_crashkernel(cmdline, system_ram, crash_size, crash_base,
adbc742bf   Yinghai Lu   x86, kdump: Chang...
1477
  				"crashkernel=", suffix_tbl[SUFFIX_HIGH]);
55a20ee78   Yinghai Lu   x86, kdump: Retor...
1478
  }
0212f9159   Yinghai Lu   x86: Add Crash ke...
1479
1480
1481
1482
1483
1484
1485
  
  int __init parse_crashkernel_low(char *cmdline,
  			     unsigned long long system_ram,
  			     unsigned long long *crash_size,
  			     unsigned long long *crash_base)
  {
  	return __parse_crashkernel(cmdline, system_ram, crash_size, crash_base,
adbc742bf   Yinghai Lu   x86, kdump: Chang...
1486
  				"crashkernel=", suffix_tbl[SUFFIX_LOW]);
0212f9159   Yinghai Lu   x86: Add Crash ke...
1487
  }
cba63c308   Bernhard Walle   Extended crashker...
1488

fa8ff292b   Michael Holzheu   [S390] kdump: Ini...
1489
  static void update_vmcoreinfo_note(void)
fd59d231f   Ken'ichi Ohmichi   Add vmcoreinfo
1490
  {
fa8ff292b   Michael Holzheu   [S390] kdump: Ini...
1491
  	u32 *buf = vmcoreinfo_note;
fd59d231f   Ken'ichi Ohmichi   Add vmcoreinfo
1492
1493
1494
  
  	if (!vmcoreinfo_size)
  		return;
fd59d231f   Ken'ichi Ohmichi   Add vmcoreinfo
1495
1496
  	buf = append_elf_note(buf, VMCOREINFO_NOTE_NAME, 0, vmcoreinfo_data,
  			      vmcoreinfo_size);
fd59d231f   Ken'ichi Ohmichi   Add vmcoreinfo
1497
1498
  	final_note(buf);
  }
fa8ff292b   Michael Holzheu   [S390] kdump: Ini...
1499
1500
  void crash_save_vmcoreinfo(void)
  {
63dca8d5b   Vivek Goyal   kdump: append new...
1501
1502
  	vmcoreinfo_append_str("CRASHTIME=%ld
  ", get_seconds());
fa8ff292b   Michael Holzheu   [S390] kdump: Ini...
1503
1504
  	update_vmcoreinfo_note();
  }
fd59d231f   Ken'ichi Ohmichi   Add vmcoreinfo
1505
1506
1507
1508
  void vmcoreinfo_append_str(const char *fmt, ...)
  {
  	va_list args;
  	char buf[0x50];
310faaa9b   Zhang Yanfei   kexec: fix wrong ...
1509
  	size_t r;
fd59d231f   Ken'ichi Ohmichi   Add vmcoreinfo
1510
1511
  
  	va_start(args, fmt);
a19428e5c   Chen Gang   kernel/kexec.c: u...
1512
  	r = vscnprintf(buf, sizeof(buf), fmt, args);
fd59d231f   Ken'ichi Ohmichi   Add vmcoreinfo
1513
  	va_end(args);
31c3a3fe0   Zhang Yanfei   kexec: Use min() ...
1514
  	r = min(r, vmcoreinfo_max_size - vmcoreinfo_size);
fd59d231f   Ken'ichi Ohmichi   Add vmcoreinfo
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
  
  	memcpy(&vmcoreinfo_data[vmcoreinfo_size], buf, r);
  
  	vmcoreinfo_size += r;
  }
  
  /*
   * provide an empty default implementation here -- architecture
   * code may override this
   */
52f5684c8   Gideon Israel Dsouza   kernel: use macro...
1525
  void __weak arch_crash_save_vmcoreinfo(void)
fd59d231f   Ken'ichi Ohmichi   Add vmcoreinfo
1526
  {}
52f5684c8   Gideon Israel Dsouza   kernel: use macro...
1527
  unsigned long __weak paddr_vmcoreinfo_note(void)
fd59d231f   Ken'ichi Ohmichi   Add vmcoreinfo
1528
1529
1530
1531
1532
1533
  {
  	return __pa((unsigned long)(char *)&vmcoreinfo_note);
  }
  
  static int __init crash_save_vmcoreinfo_init(void)
  {
bba1f603b   Ken'ichi Ohmichi   vmcoreinfo: add "...
1534
1535
  	VMCOREINFO_OSRELEASE(init_uts_ns.name.release);
  	VMCOREINFO_PAGESIZE(PAGE_SIZE);
fd59d231f   Ken'ichi Ohmichi   Add vmcoreinfo
1536

bcbba6c10   Ken'ichi Ohmichi   add-vmcore: add a...
1537
1538
  	VMCOREINFO_SYMBOL(init_uts_ns);
  	VMCOREINFO_SYMBOL(node_online_map);
d034cfab4   Will Deacon   kexec: crash: don...
1539
  #ifdef CONFIG_MMU
bcbba6c10   Ken'ichi Ohmichi   add-vmcore: add a...
1540
  	VMCOREINFO_SYMBOL(swapper_pg_dir);
d034cfab4   Will Deacon   kexec: crash: don...
1541
  #endif
bcbba6c10   Ken'ichi Ohmichi   add-vmcore: add a...
1542
  	VMCOREINFO_SYMBOL(_stext);
f1c4069e1   Joonsoo Kim   mm, vmalloc: expo...
1543
  	VMCOREINFO_SYMBOL(vmap_area_list);
fd59d231f   Ken'ichi Ohmichi   Add vmcoreinfo
1544
1545
  
  #ifndef CONFIG_NEED_MULTIPLE_NODES
bcbba6c10   Ken'ichi Ohmichi   add-vmcore: add a...
1546
1547
  	VMCOREINFO_SYMBOL(mem_map);
  	VMCOREINFO_SYMBOL(contig_page_data);
fd59d231f   Ken'ichi Ohmichi   Add vmcoreinfo
1548
1549
  #endif
  #ifdef CONFIG_SPARSEMEM
bcbba6c10   Ken'ichi Ohmichi   add-vmcore: add a...
1550
1551
  	VMCOREINFO_SYMBOL(mem_section);
  	VMCOREINFO_LENGTH(mem_section, NR_SECTION_ROOTS);
c76f860c4   Ken'ichi Ohmichi   vmcoreinfo: renam...
1552
  	VMCOREINFO_STRUCT_SIZE(mem_section);
bcbba6c10   Ken'ichi Ohmichi   add-vmcore: add a...
1553
  	VMCOREINFO_OFFSET(mem_section, section_mem_map);
fd59d231f   Ken'ichi Ohmichi   Add vmcoreinfo
1554
  #endif
c76f860c4   Ken'ichi Ohmichi   vmcoreinfo: renam...
1555
1556
1557
1558
1559
1560
  	VMCOREINFO_STRUCT_SIZE(page);
  	VMCOREINFO_STRUCT_SIZE(pglist_data);
  	VMCOREINFO_STRUCT_SIZE(zone);
  	VMCOREINFO_STRUCT_SIZE(free_area);
  	VMCOREINFO_STRUCT_SIZE(list_head);
  	VMCOREINFO_SIZE(nodemask_t);
bcbba6c10   Ken'ichi Ohmichi   add-vmcore: add a...
1561
1562
1563
1564
  	VMCOREINFO_OFFSET(page, flags);
  	VMCOREINFO_OFFSET(page, _count);
  	VMCOREINFO_OFFSET(page, mapping);
  	VMCOREINFO_OFFSET(page, lru);
8d67091ec   Atsushi Kumagai   kexec: add the va...
1565
1566
  	VMCOREINFO_OFFSET(page, _mapcount);
  	VMCOREINFO_OFFSET(page, private);
bcbba6c10   Ken'ichi Ohmichi   add-vmcore: add a...
1567
1568
  	VMCOREINFO_OFFSET(pglist_data, node_zones);
  	VMCOREINFO_OFFSET(pglist_data, nr_zones);
fd59d231f   Ken'ichi Ohmichi   Add vmcoreinfo
1569
  #ifdef CONFIG_FLAT_NODE_MEM_MAP
bcbba6c10   Ken'ichi Ohmichi   add-vmcore: add a...
1570
  	VMCOREINFO_OFFSET(pglist_data, node_mem_map);
fd59d231f   Ken'ichi Ohmichi   Add vmcoreinfo
1571
  #endif
bcbba6c10   Ken'ichi Ohmichi   add-vmcore: add a...
1572
1573
1574
1575
1576
1577
1578
1579
1580
  	VMCOREINFO_OFFSET(pglist_data, node_start_pfn);
  	VMCOREINFO_OFFSET(pglist_data, node_spanned_pages);
  	VMCOREINFO_OFFSET(pglist_data, node_id);
  	VMCOREINFO_OFFSET(zone, free_area);
  	VMCOREINFO_OFFSET(zone, vm_stat);
  	VMCOREINFO_OFFSET(zone, spanned_pages);
  	VMCOREINFO_OFFSET(free_area, free_list);
  	VMCOREINFO_OFFSET(list_head, next);
  	VMCOREINFO_OFFSET(list_head, prev);
13ba3fcbb   Atsushi Kumagai   kexec, vmalloc: e...
1581
1582
  	VMCOREINFO_OFFSET(vmap_area, va_start);
  	VMCOREINFO_OFFSET(vmap_area, list);
bcbba6c10   Ken'ichi Ohmichi   add-vmcore: add a...
1583
  	VMCOREINFO_LENGTH(zone.free_area, MAX_ORDER);
04d491ab2   Neil Horman   kexec: add dmesg ...
1584
  	log_buf_kexec_setup();
83a08e7c6   Ken'ichi Ohmichi   vmcoreinfo: add t...
1585
  	VMCOREINFO_LENGTH(free_area.free_list, MIGRATE_TYPES);
bcbba6c10   Ken'ichi Ohmichi   add-vmcore: add a...
1586
  	VMCOREINFO_NUMBER(NR_FREE_PAGES);
122c7a590   Ken'ichi Ohmichi   vmcoreinfo: add p...
1587
1588
1589
  	VMCOREINFO_NUMBER(PG_lru);
  	VMCOREINFO_NUMBER(PG_private);
  	VMCOREINFO_NUMBER(PG_swapcache);
8d67091ec   Atsushi Kumagai   kexec: add the va...
1590
  	VMCOREINFO_NUMBER(PG_slab);
0d0bf6674   Mitsuhiro Tanino   kexec: export PG_...
1591
1592
1593
  #ifdef CONFIG_MEMORY_FAILURE
  	VMCOREINFO_NUMBER(PG_hwpoison);
  #endif
b3acc56bf   Petr Tesarik   kexec: save PG_he...
1594
  	VMCOREINFO_NUMBER(PG_head_mask);
8d67091ec   Atsushi Kumagai   kexec: add the va...
1595
  	VMCOREINFO_NUMBER(PAGE_BUDDY_MAPCOUNT_VALUE);
3a1122d26   David Rientjes   kexec: fix build ...
1596
  #ifdef CONFIG_HUGETLBFS
8f1d26d0e   Atsushi Kumagai   kexec: export fre...
1597
  	VMCOREINFO_SYMBOL(free_huge_page);
3a1122d26   David Rientjes   kexec: fix build ...
1598
  #endif
fd59d231f   Ken'ichi Ohmichi   Add vmcoreinfo
1599
1600
  
  	arch_crash_save_vmcoreinfo();
fa8ff292b   Michael Holzheu   [S390] kdump: Ini...
1601
  	update_vmcoreinfo_note();
fd59d231f   Ken'ichi Ohmichi   Add vmcoreinfo
1602
1603
1604
  
  	return 0;
  }
c96d6660d   Paul Gortmaker   kernel: audit/fix...
1605
  subsys_initcall(crash_save_vmcoreinfo_init);
3ab835213   Huang Ying   kexec jump
1606

7ade3fcc1   Huang Ying   kexec jump: clean...
1607
1608
1609
  /*
   * Move into place and start executing a preloaded standalone
   * executable.  If nothing was preloaded return an error.
3ab835213   Huang Ying   kexec jump
1610
1611
1612
1613
   */
  int kernel_kexec(void)
  {
  	int error = 0;
8c5a1cf0a   Andrew Morton   kexec: use a mute...
1614
  	if (!mutex_trylock(&kexec_mutex))
3ab835213   Huang Ying   kexec jump
1615
1616
1617
1618
1619
  		return -EBUSY;
  	if (!kexec_image) {
  		error = -EINVAL;
  		goto Unlock;
  	}
3ab835213   Huang Ying   kexec jump
1620
  #ifdef CONFIG_KEXEC_JUMP
7ade3fcc1   Huang Ying   kexec jump: clean...
1621
  	if (kexec_image->preserve_context) {
bcda53faf   Srivatsa S. Bhat   PM / Sleep: Repla...
1622
  		lock_system_sleep();
89081d17f   Huang Ying   kexec jump: save/...
1623
1624
1625
1626
1627
1628
1629
  		pm_prepare_console();
  		error = freeze_processes();
  		if (error) {
  			error = -EBUSY;
  			goto Restore_console;
  		}
  		suspend_console();
d16163029   Alan Stern   PM core: rename s...
1630
  		error = dpm_suspend_start(PMSG_FREEZE);
89081d17f   Huang Ying   kexec jump: save/...
1631
1632
  		if (error)
  			goto Resume_console;
d16163029   Alan Stern   PM core: rename s...
1633
  		/* At this point, dpm_suspend_start() has been called,
cf579dfb8   Rafael J. Wysocki   PM / Sleep: Intro...
1634
1635
  		 * but *not* dpm_suspend_end(). We *must* call
  		 * dpm_suspend_end() now.  Otherwise, drivers for
89081d17f   Huang Ying   kexec jump: save/...
1636
1637
1638
1639
  		 * some devices (e.g. interrupt controllers) become
  		 * desynchronized with the actual state of the
  		 * hardware at resume time, and evil weirdness ensues.
  		 */
cf579dfb8   Rafael J. Wysocki   PM / Sleep: Intro...
1640
  		error = dpm_suspend_end(PMSG_FREEZE);
89081d17f   Huang Ying   kexec jump: save/...
1641
  		if (error)
749b0afc3   Rafael J. Wysocki   kexec: Change kex...
1642
1643
1644
1645
  			goto Resume_devices;
  		error = disable_nonboot_cpus();
  		if (error)
  			goto Enable_cpus;
2ed8d2b3a   Rafael J. Wysocki   PM: Rework handli...
1646
  		local_irq_disable();
2e711c04d   Rafael J. Wysocki   PM: Remove sysdev...
1647
  		error = syscore_suspend();
770824bdc   Rafael J. Wysocki   PM: Split up sysd...
1648
  		if (error)
749b0afc3   Rafael J. Wysocki   kexec: Change kex...
1649
  			goto Enable_irqs;
7ade3fcc1   Huang Ying   kexec jump: clean...
1650
  	} else
3ab835213   Huang Ying   kexec jump
1651
  #endif
7ade3fcc1   Huang Ying   kexec jump: clean...
1652
  	{
4fc9bbf98   Khalid Aziz   PCI: Disable Bus ...
1653
  		kexec_in_progress = true;
ca195b7f6   Huang Ying   kexec jump: remov...
1654
  		kernel_restart_prepare(NULL);
c97102ba9   Vivek Goyal   kexec: migrate to...
1655
  		migrate_to_reboot_cpu();
011e4b02f   Srivatsa S. Bhat   powerpc, kexec: F...
1656
1657
1658
1659
1660
1661
1662
1663
  
  		/*
  		 * migrate_to_reboot_cpu() disables CPU hotplug assuming that
  		 * no further code needs to use CPU hotplug (which is true in
  		 * the reboot case). However, the kexec path depends on using
  		 * CPU hotplug again; so re-enable it here.
  		 */
  		cpu_hotplug_enable();
e1bebcf41   Fabian Frederick   kernel/kexec.c: c...
1664
1665
  		pr_emerg("Starting new kernel
  ");
3ab835213   Huang Ying   kexec jump
1666
1667
1668
1669
  		machine_shutdown();
  	}
  
  	machine_kexec(kexec_image);
3ab835213   Huang Ying   kexec jump
1670
  #ifdef CONFIG_KEXEC_JUMP
7ade3fcc1   Huang Ying   kexec jump: clean...
1671
  	if (kexec_image->preserve_context) {
19234c081   Rafael J. Wysocki   PM: Add missing s...
1672
  		syscore_resume();
749b0afc3   Rafael J. Wysocki   kexec: Change kex...
1673
   Enable_irqs:
3ab835213   Huang Ying   kexec jump
1674
  		local_irq_enable();
749b0afc3   Rafael J. Wysocki   kexec: Change kex...
1675
   Enable_cpus:
89081d17f   Huang Ying   kexec jump: save/...
1676
  		enable_nonboot_cpus();
cf579dfb8   Rafael J. Wysocki   PM / Sleep: Intro...
1677
  		dpm_resume_start(PMSG_RESTORE);
89081d17f   Huang Ying   kexec jump: save/...
1678
   Resume_devices:
d16163029   Alan Stern   PM core: rename s...
1679
  		dpm_resume_end(PMSG_RESTORE);
89081d17f   Huang Ying   kexec jump: save/...
1680
1681
1682
1683
1684
   Resume_console:
  		resume_console();
  		thaw_processes();
   Restore_console:
  		pm_restore_console();
bcda53faf   Srivatsa S. Bhat   PM / Sleep: Repla...
1685
  		unlock_system_sleep();
3ab835213   Huang Ying   kexec jump
1686
  	}
7ade3fcc1   Huang Ying   kexec jump: clean...
1687
  #endif
3ab835213   Huang Ying   kexec jump
1688
1689
  
   Unlock:
8c5a1cf0a   Andrew Morton   kexec: use a mute...
1690
  	mutex_unlock(&kexec_mutex);
3ab835213   Huang Ying   kexec jump
1691
1692
  	return error;
  }