~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/kernel/crash_reserve.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /kernel/crash_reserve.c (Version linux-6.12-rc7) and /kernel/crash_reserve.c (Version linux-3.10.108)


  1 // SPDX-License-Identifier: GPL-2.0-only            1 
  2 /*                                                
  3  * crash.c - kernel crash support code.           
  4  * Copyright (C) 2002-2004 Eric Biederman  <eb    
  5  */                                               
  6                                                   
  7 #include <linux/buildid.h>                        
  8 #include <linux/init.h>                           
  9 #include <linux/utsname.h>                        
 10 #include <linux/vmalloc.h>                        
 11 #include <linux/sizes.h>                          
 12 #include <linux/kexec.h>                          
 13 #include <linux/memory.h>                         
 14 #include <linux/cpuhotplug.h>                     
 15 #include <linux/memblock.h>                       
 16 #include <linux/kmemleak.h>                       
 17                                                   
 18 #include <asm/page.h>                             
 19 #include <asm/sections.h>                         
 20                                                   
 21 #include <crypto/sha1.h>                          
 22                                                   
 23 #include "kallsyms_internal.h"                    
 24 #include "kexec_internal.h"                       
 25                                                   
 26 /* Location of the reserved area for the crash    
 27 struct resource crashk_res = {                    
 28         .name  = "Crash kernel",                  
 29         .start = 0,                               
 30         .end   = 0,                               
 31         .flags = IORESOURCE_BUSY | IORESOURCE_    
 32         .desc  = IORES_DESC_CRASH_KERNEL          
 33 };                                                
 34 struct resource crashk_low_res = {                
 35         .name  = "Crash kernel",                  
 36         .start = 0,                               
 37         .end   = 0,                               
 38         .flags = IORESOURCE_BUSY | IORESOURCE_    
 39         .desc  = IORES_DESC_CRASH_KERNEL          
 40 };                                                
 41                                                   
 42 /*                                                
 43  * parsing the "crashkernel" commandline          
 44  *                                                
 45  * this code is intended to be called from arc    
 46  */                                               
 47                                                   
 48                                                   
 49 /*                                                
 50  * This function parses command lines in the f    
 51  *                                                
 52  *   crashkernel=ramsize-range:size[,...][@off    
 53  *                                                
 54  * The function returns 0 on success and -EINV    
 55  */                                               
 56 static int __init parse_crashkernel_mem(char *    
 57                                         unsign    
 58                                         unsign    
 59                                         unsign    
 60 {                                                 
 61         char *cur = cmdline, *tmp;                
 62         unsigned long long total_mem = system_    
 63                                                   
 64         /*                                        
 65          * Firmware sometimes reserves some me    
 66          * so the system memory size is less t    
 67          * size. Work around this by rounding     
 68          * which is enough for most test cases    
 69          */                                       
 70         total_mem = roundup(total_mem, SZ_128M    
 71                                                   
 72         /* for each entry of the comma-separat    
 73         do {                                      
 74                 unsigned long long start, end     
 75                                                   
 76                 /* get the start of the range     
 77                 start = memparse(cur, &tmp);      
 78                 if (cur == tmp) {                 
 79                         pr_warn("crashkernel:     
 80                         return -EINVAL;           
 81                 }                                 
 82                 cur = tmp;                        
 83                 if (*cur != '-') {                
 84                         pr_warn("crashkernel:     
 85                         return -EINVAL;           
 86                 }                                 
 87                 cur++;                            
 88                                                   
 89                 /* if no ':' is here, than we     
 90                 if (*cur != ':') {                
 91                         end = memparse(cur, &t    
 92                         if (cur == tmp) {         
 93                                 pr_warn("crash    
 94                                 return -EINVAL    
 95                         }                         
 96                         cur = tmp;                
 97                         if (end <= start) {       
 98                                 pr_warn("crash    
 99                                 return -EINVAL    
100                         }                         
101                 }                                 
102                                                   
103                 if (*cur != ':') {                
104                         pr_warn("crashkernel:     
105                         return -EINVAL;           
106                 }                                 
107                 cur++;                            
108                                                   
109                 size = memparse(cur, &tmp);       
110                 if (cur == tmp) {                 
111                         pr_warn("crashkernel:     
112                         return -EINVAL;           
113                 }                                 
114                 cur = tmp;                        
115                 if (size >= total_mem) {          
116                         pr_warn("crashkernel:     
117                         return -EINVAL;           
118                 }                                 
119                                                   
120                 /* match ? */                     
121                 if (total_mem >= start && tota    
122                         *crash_size = size;       
123                         break;                    
124                 }                                 
125         } while (*cur++ == ',');                  
126                                                   
127         if (*crash_size > 0) {                    
128                 while (*cur && *cur != ' ' &&     
129                         cur++;                    
130                 if (*cur == '@') {                
131                         cur++;                    
132                         *crash_base = memparse    
133                         if (cur == tmp) {         
134                                 pr_warn("crahs    
135                                 return -EINVAL    
136                         }                         
137                 }                                 
138         } else                                    
139                 pr_info("crashkernel size resu    
140                                                   
141         return 0;                                 
142 }                                                 
143                                                   
144 /*                                                
145  * That function parses "simple" (old) crashke    
146  *                                                
147  *      crashkernel=size[@offset]                 
148  *                                                
149  * It returns 0 on success and -EINVAL on fail    
150  */                                               
151 static int __init parse_crashkernel_simple(cha    
152                                            uns    
153                                            uns    
154 {                                                 
155         char *cur = cmdline;                      
156                                                   
157         *crash_size = memparse(cmdline, &cur);    
158         if (cmdline == cur) {                     
159                 pr_warn("crashkernel: memory v    
160                 return -EINVAL;                   
161         }                                         
162                                                   
163         if (*cur == '@')                          
164                 *crash_base = memparse(cur+1,     
165         else if (*cur != ' ' && *cur != '\0')     
166                 pr_warn("crashkernel: unrecogn    
167                 return -EINVAL;                   
168         }                                         
169                                                   
170         return 0;                                 
171 }                                                 
172                                                   
173 #define SUFFIX_HIGH 0                             
174 #define SUFFIX_LOW  1                             
175 #define SUFFIX_NULL 2                             
176 static __initdata char *suffix_tbl[] = {          
177         [SUFFIX_HIGH] = ",high",                  
178         [SUFFIX_LOW]  = ",low",                   
179         [SUFFIX_NULL] = NULL,                     
180 };                                                
181                                                   
182 /*                                                
183  * That function parses "suffix"  crashkernel     
184  *                                                
185  *      crashkernel=size,[high|low]               
186  *                                                
187  * It returns 0 on success and -EINVAL on fail    
188  */                                               
189 static int __init parse_crashkernel_suffix(cha    
190                                            uns    
191                                            con    
192 {                                                 
193         char *cur = cmdline;                      
194                                                   
195         *crash_size = memparse(cmdline, &cur);    
196         if (cmdline == cur) {                     
197                 pr_warn("crashkernel: memory v    
198                 return -EINVAL;                   
199         }                                         
200                                                   
201         /* check with suffix */                   
202         if (strncmp(cur, suffix, strlen(suffix    
203                 pr_warn("crashkernel: unrecogn    
204                 return -EINVAL;                   
205         }                                         
206         cur += strlen(suffix);                    
207         if (*cur != ' ' && *cur != '\0') {        
208                 pr_warn("crashkernel: unrecogn    
209                 return -EINVAL;                   
210         }                                         
211                                                   
212         return 0;                                 
213 }                                                 
214                                                   
215 static __init char *get_last_crashkernel(char     
216                              const char *name,    
217                              const char *suffi    
218 {                                                 
219         char *p = cmdline, *ck_cmdline = NULL;    
220                                                   
221         /* find crashkernel and use the last o    
222         p = strstr(p, name);                      
223         while (p) {                               
224                 char *end_p = strchr(p, ' ');     
225                 char *q;                          
226                                                   
227                 if (!end_p)                       
228                         end_p = p + strlen(p);    
229                                                   
230                 if (!suffix) {                    
231                         int i;                    
232                                                   
233                         /* skip the one with a    
234                         for (i = 0; suffix_tbl    
235                                 q = end_p - st    
236                                 if (!strncmp(q    
237                                              s    
238                                         goto n    
239                         }                         
240                         ck_cmdline = p;           
241                 } else {                          
242                         q = end_p - strlen(suf    
243                         if (!strncmp(q, suffix    
244                                 ck_cmdline = p    
245                 }                                 
246 next:                                             
247                 p = strstr(p+1, name);            
248         }                                         
249                                                   
250         return ck_cmdline;                        
251 }                                                 
252                                                   
253 static int __init __parse_crashkernel(char *cm    
254                              unsigned long lon    
255                              unsigned long lon    
256                              unsigned long lon    
257                              const char *suffi    
258 {                                                 
259         char *first_colon, *first_space;          
260         char *ck_cmdline;                         
261         char *name = "crashkernel=";              
262                                                   
263         BUG_ON(!crash_size || !crash_base);       
264         *crash_size = 0;                          
265         *crash_base = 0;                          
266                                                   
267         ck_cmdline = get_last_crashkernel(cmdl    
268         if (!ck_cmdline)                          
269                 return -ENOENT;                   
270                                                   
271         ck_cmdline += strlen(name);               
272                                                   
273         if (suffix)                               
274                 return parse_crashkernel_suffi    
275                                 suffix);          
276         /*                                        
277          * if the commandline contains a ':',     
278          * syntax -- if not, it must be the cl    
279          */                                       
280         first_colon = strchr(ck_cmdline, ':');    
281         first_space = strchr(ck_cmdline, ' ');    
282         if (first_colon && (!first_space || fi    
283                 return parse_crashkernel_mem(c    
284                                 crash_size, cr    
285                                                   
286         return parse_crashkernel_simple(ck_cmd    
287 }                                                 
288                                                   
289 /*                                                
290  * That function is the entry point for comman    
291  * called from the arch-specific code.            
292  *                                                
293  * If crashkernel=,high|low is supported on ar    
294  * should be passed to parameters 'low_size' a    
295  */                                               
296 int __init parse_crashkernel(char *cmdline,       
297                              unsigned long lon    
298                              unsigned long lon    
299                              unsigned long lon    
300                              unsigned long lon    
301                              bool *high)          
302 {                                                 
303         int ret;                                  
304                                                   
305         /* crashkernel=X[@offset] */              
306         ret = __parse_crashkernel(cmdline, sys    
307                                 crash_base, NU    
308 #ifdef CONFIG_ARCH_HAS_GENERIC_CRASHKERNEL_RES    
309         /*                                        
310          * If non-NULL 'high' passed in and no    
311          * setting detected, try parsing crash    
312          */                                       
313         if (high && ret == -ENOENT) {             
314                 ret = __parse_crashkernel(cmdl    
315                                 crash_base, su    
316                 if (ret || !*crash_size)          
317                         return -EINVAL;           
318                                                   
319                 /*                                
320                  * crashkernel=Y,low can be sp    
321                  * is not allowed.                
322                  */                               
323                 ret = __parse_crashkernel(cmdl    
324                                 crash_base, su    
325                 if (ret == -ENOENT) {             
326                         *low_size = DEFAULT_CR    
327                         ret = 0;                  
328                 } else if (ret) {                 
329                         return ret;               
330                 }                                 
331                                                   
332                 *high = true;                     
333         }                                         
334 #endif                                            
335         if (!*crash_size)                         
336                 ret = -EINVAL;                    
337                                                   
338         if (*crash_size >= system_ram)            
339                 ret = -EINVAL;                    
340                                                   
341         return ret;                               
342 }                                                 
343                                                   
344 /*                                                
345  * Add a dummy early_param handler to mark cra    
346  * parameter and suppress incorrect warnings i    
347  */                                               
348 static int __init parse_crashkernel_dummy(char    
349 {                                                 
350         return 0;                                 
351 }                                                 
352 early_param("crashkernel", parse_crashkernel_d    
353                                                   
354 #ifdef CONFIG_ARCH_HAS_GENERIC_CRASHKERNEL_RES    
355 static int __init reserve_crashkernel_low(unsi    
356 {                                                 
357 #ifdef CONFIG_64BIT                               
358         unsigned long long low_base;              
359                                                   
360         low_base = memblock_phys_alloc_range(l    
361         if (!low_base) {                          
362                 pr_err("cannot allocate crashk    
363                 return -ENOMEM;                   
364         }                                         
365                                                   
366         pr_info("crashkernel low memory reserv    
367                 low_base, low_base + low_size,    
368                                                   
369         crashk_low_res.start = low_base;          
370         crashk_low_res.end   = low_base + low_    
371 #ifdef HAVE_ARCH_ADD_CRASH_RES_TO_IOMEM_EARLY     
372         insert_resource(&iomem_resource, &cras    
373 #endif                                            
374 #endif                                            
375         return 0;                                 
376 }                                                 
377                                                   
378 void __init reserve_crashkernel_generic(char *    
379                              unsigned long lon    
380                              unsigned long lon    
381                              unsigned long lon    
382                              bool high)           
383 {                                                 
384         unsigned long long search_end = CRASH_    
385         bool fixed_base = false;                  
386                                                   
387         /* User specifies base address explici    
388         if (crash_base) {                         
389                 fixed_base = true;                
390                 search_base = crash_base;         
391                 search_end = crash_base + cras    
392         } else if (high) {                        
393                 search_base = CRASH_ADDR_LOW_M    
394                 search_end = CRASH_ADDR_HIGH_M    
395         }                                         
396                                                   
397 retry:                                            
398         crash_base = memblock_phys_alloc_range    
399                                                   
400         if (!crash_base) {                        
401                 /*                                
402                  * For crashkernel=size[KMG]@o    
403                  * message if can't reserve th    
404                  */                               
405                 if (fixed_base) {                 
406                         pr_warn("crashkernel r    
407                         return;                   
408                 }                                 
409                                                   
410                 /*                                
411                  * For crashkernel=size[KMG],     
412                  * low memory, fall back to hi    
413                  * low memory will be reserved    
414                  */                               
415                 if (!high && search_end == CRA    
416                         search_end = CRASH_ADD    
417                         search_base = CRASH_AD    
418                         crash_low_size = DEFAU    
419                         goto retry;               
420                 }                                 
421                                                   
422                 /*                                
423                  * For crashkernel=size[KMG],h    
424                  * for high memory, fall back     
425                  */                               
426                 if (high && search_end == CRAS    
427                         search_end = CRASH_ADD    
428                         search_base = 0;          
429                         if (search_end != CRAS    
430                                 goto retry;       
431                 }                                 
432                 pr_warn("cannot allocate crash    
433                         crash_size);              
434                 return;                           
435         }                                         
436                                                   
437         if ((crash_base >= CRASH_ADDR_LOW_MAX)    
438              crash_low_size && reserve_crashke    
439                 memblock_phys_free(crash_base,    
440                 return;                           
441         }                                         
442                                                   
443         pr_info("crashkernel reserved: 0x%016l    
444                 crash_base, crash_base + crash    
445                                                   
446         /*                                        
447          * The crashkernel memory will be remo    
448          * map. Inform kmemleak so that it won    
449          */                                       
450         kmemleak_ignore_phys(crash_base);         
451         if (crashk_low_res.end)                   
452                 kmemleak_ignore_phys(crashk_lo    
453                                                   
454         crashk_res.start = crash_base;            
455         crashk_res.end = crash_base + crash_si    
456 #ifdef HAVE_ARCH_ADD_CRASH_RES_TO_IOMEM_EARLY     
457         insert_resource(&iomem_resource, &cras    
458 #endif                                            
459 }                                                 
460                                                   
461 #ifndef HAVE_ARCH_ADD_CRASH_RES_TO_IOMEM_EARLY    
462 static __init int insert_crashkernel_resources    
463 {                                                 
464         if (crashk_res.start < crashk_res.end)    
465                 insert_resource(&iomem_resourc    
466                                                   
467         if (crashk_low_res.start < crashk_low_    
468                 insert_resource(&iomem_resourc    
469                                                   
470         return 0;                                 
471 }                                                 
472 early_initcall(insert_crashkernel_resources);     
473 #endif                                            
474 #endif                                            
475                                                   

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php