Skip to content

Commit 30a0fd8

Browse files
author
Fox Snowpatch
committed
1 parent 4f37907 commit 30a0fd8

14 files changed

Lines changed: 195 additions & 277 deletions

File tree

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,14 +1122,14 @@ Kernel parameters
11221122
It will be ignored when crashkernel=X,high is not used
11231123
or memory reserved is below 4G.
11241124
crashkernel=size[KMG],cma
1125-
[KNL, X86, ppc] Reserve additional crash kernel memory from
1126-
CMA. This reservation is usable by the first system's
1127-
userspace memory and kernel movable allocations (memory
1128-
balloon, zswap). Pages allocated from this memory range
1129-
will not be included in the vmcore so this should not
1130-
be used if dumping of userspace memory is intended and
1131-
it has to be expected that some movable kernel pages
1132-
may be missing from the dump.
1125+
[KNL, X86, ARM64, RISCV, PPC] Reserve additional crash
1126+
kernel memory from CMA. This reservation is usable by
1127+
the first system's userspace memory and kernel movable
1128+
allocations (memory balloon, zswap). Pages allocated
1129+
from this memory range will not be included in the vmcore
1130+
so this should not be used if dumping of userspace memory
1131+
is intended and it has to be expected that some movable
1132+
kernel pages may be missing from the dump.
11331133

11341134
A standard crashkernel reservation, as described above,
11351135
is still needed to hold the crash kernel and initrd.

arch/arm64/kernel/machine_kexec_file.c

Lines changed: 12 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -40,46 +40,31 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image)
4040
}
4141

4242
#ifdef CONFIG_CRASH_DUMP
43-
static int prepare_elf_headers(void **addr, unsigned long *sz)
43+
unsigned int arch_get_system_nr_ranges(void)
4444
{
45-
struct crash_mem *cmem;
46-
unsigned int nr_ranges;
47-
int ret;
48-
u64 i;
45+
unsigned int nr_ranges = 2 + crashk_cma_cnt; /* for exclusion of crashkernel region */
4946
phys_addr_t start, end;
47+
u64 i;
5048

51-
nr_ranges = 2; /* for exclusion of crashkernel region */
5249
for_each_mem_range(i, &start, &end)
5350
nr_ranges++;
5451

55-
cmem = kmalloc_flex(*cmem, ranges, nr_ranges);
56-
if (!cmem)
57-
return -ENOMEM;
52+
return nr_ranges;
53+
}
54+
55+
int arch_crash_populate_cmem(struct crash_mem *cmem)
56+
{
57+
phys_addr_t start, end;
58+
u64 i;
5859

59-
cmem->max_nr_ranges = nr_ranges;
6060
cmem->nr_ranges = 0;
6161
for_each_mem_range(i, &start, &end) {
6262
cmem->ranges[cmem->nr_ranges].start = start;
6363
cmem->ranges[cmem->nr_ranges].end = end - 1;
6464
cmem->nr_ranges++;
6565
}
6666

67-
/* Exclude crashkernel region */
68-
ret = crash_exclude_mem_range(cmem, crashk_res.start, crashk_res.end);
69-
if (ret)
70-
goto out;
71-
72-
if (crashk_low_res.end) {
73-
ret = crash_exclude_mem_range(cmem, crashk_low_res.start, crashk_low_res.end);
74-
if (ret)
75-
goto out;
76-
}
77-
78-
ret = crash_prepare_elf64_headers(cmem, true, addr, sz);
79-
80-
out:
81-
kfree(cmem);
82-
return ret;
67+
return 0;
8368
}
8469
#endif
8570

@@ -109,7 +94,7 @@ int load_other_segments(struct kimage *image,
10994
void *headers;
11095
unsigned long headers_sz;
11196
if (image->type == KEXEC_TYPE_CRASH) {
112-
ret = prepare_elf_headers(&headers, &headers_sz);
97+
ret = crash_prepare_headers(true, &headers, &headers_sz, NULL);
11398
if (ret) {
11499
pr_err("Preparing elf core header failed\n");
115100
goto out_err;

arch/arm64/mm/init.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,8 @@ phys_addr_t __ro_after_init arm64_dma_phys_limit;
9696

9797
static void __init arch_reserve_crashkernel(void)
9898
{
99+
unsigned long long crash_base, crash_size, cma_size = 0;
99100
unsigned long long low_size = 0;
100-
unsigned long long crash_base, crash_size;
101101
bool high = false;
102102
int ret;
103103

@@ -106,11 +106,12 @@ static void __init arch_reserve_crashkernel(void)
106106

107107
ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
108108
&crash_size, &crash_base,
109-
&low_size, NULL, &high);
109+
&low_size, &cma_size, &high);
110110
if (ret)
111111
return;
112112

113113
reserve_crashkernel_generic(crash_size, crash_base, low_size, high);
114+
reserve_crashkernel_cma(cma_size);
114115
}
115116

116117
static phys_addr_t __init max_zone_phys(phys_addr_t zone_limit)

arch/loongarch/kernel/machine_kexec_file.c

Lines changed: 12 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -56,46 +56,31 @@ static void cmdline_add_initrd(struct kimage *image, unsigned long *cmdline_tmpl
5656
}
5757

5858
#ifdef CONFIG_CRASH_DUMP
59-
60-
static int prepare_elf_headers(void **addr, unsigned long *sz)
59+
unsigned int arch_get_system_nr_ranges(void)
6160
{
62-
int ret, nr_ranges;
63-
uint64_t i;
61+
int nr_ranges = 2; /* for exclusion of crashkernel region */
6462
phys_addr_t start, end;
65-
struct crash_mem *cmem;
63+
uint64_t i;
6664

67-
nr_ranges = 2; /* for exclusion of crashkernel region */
6865
for_each_mem_range(i, &start, &end)
6966
nr_ranges++;
7067

71-
cmem = kmalloc_flex(*cmem, ranges, nr_ranges);
72-
if (!cmem)
73-
return -ENOMEM;
68+
return nr_ranges;
69+
}
70+
71+
int arch_crash_populate_cmem(struct crash_mem *cmem)
72+
{
73+
phys_addr_t start, end;
74+
uint64_t i;
7475

75-
cmem->max_nr_ranges = nr_ranges;
7676
cmem->nr_ranges = 0;
7777
for_each_mem_range(i, &start, &end) {
7878
cmem->ranges[cmem->nr_ranges].start = start;
7979
cmem->ranges[cmem->nr_ranges].end = end - 1;
8080
cmem->nr_ranges++;
8181
}
8282

83-
/* Exclude crashkernel region */
84-
ret = crash_exclude_mem_range(cmem, crashk_res.start, crashk_res.end);
85-
if (ret < 0)
86-
goto out;
87-
88-
if (crashk_low_res.end) {
89-
ret = crash_exclude_mem_range(cmem, crashk_low_res.start, crashk_low_res.end);
90-
if (ret < 0)
91-
goto out;
92-
}
93-
94-
ret = crash_prepare_elf64_headers(cmem, true, addr, sz);
95-
96-
out:
97-
kfree(cmem);
98-
return ret;
83+
return 0;
9984
}
10085

10186
/*
@@ -163,7 +148,7 @@ int load_other_segments(struct kimage *image,
163148
void *headers;
164149
unsigned long headers_sz;
165150

166-
ret = prepare_elf_headers(&headers, &headers_sz);
151+
ret = crash_prepare_headers(true, &headers, &headers_sz, NULL);
167152
if (ret < 0) {
168153
pr_err("Preparing elf core header failed\n");
169154
goto out_err;

arch/powerpc/include/asm/kexec_ranges.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
void sort_memory_ranges(struct crash_mem *mrngs, bool merge);
88
struct crash_mem *realloc_mem_ranges(struct crash_mem **mem_ranges);
99
int add_mem_range(struct crash_mem **mem_ranges, u64 base, u64 size);
10-
int remove_mem_range(struct crash_mem **mem_ranges, u64 base, u64 size);
1110
int get_exclude_memory_ranges(struct crash_mem **mem_ranges);
1211
int get_reserved_memory_ranges(struct crash_mem **mem_ranges);
1312
int get_crash_memory_ranges(struct crash_mem **mem_ranges);

arch/powerpc/kexec/crash.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ static void update_crash_elfcorehdr(struct kimage *image, struct memory_notify *
431431
struct crash_mem *cmem = NULL;
432432
struct kexec_segment *ksegment;
433433
void *ptr, *mem, *elfbuf = NULL;
434-
unsigned long elfsz, memsz, base_addr, size;
434+
unsigned long elfsz, memsz, base_addr, size, end;
435435

436436
ksegment = &image->segment[image->elfcorehdr_index];
437437
mem = (void *) ksegment->mem;
@@ -440,7 +440,7 @@ static void update_crash_elfcorehdr(struct kimage *image, struct memory_notify *
440440
ret = get_crash_memory_ranges(&cmem);
441441
if (ret) {
442442
pr_err("Failed to get crash mem range\n");
443-
return;
443+
goto out;
444444
}
445445

446446
/*
@@ -450,7 +450,8 @@ static void update_crash_elfcorehdr(struct kimage *image, struct memory_notify *
450450
if (image->hp_action == KEXEC_CRASH_HP_REMOVE_MEMORY) {
451451
base_addr = PFN_PHYS(mn->start_pfn);
452452
size = mn->nr_pages * PAGE_SIZE;
453-
ret = remove_mem_range(&cmem, base_addr, size);
453+
end = base_addr + size - 1;
454+
ret = arch_crash_exclude_mem_range(&cmem, base_addr, end);
454455
if (ret) {
455456
pr_err("Failed to remove hot-unplugged memory from crash memory ranges\n");
456457
goto out;

arch/powerpc/kexec/ranges.c

Lines changed: 4 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -553,9 +553,9 @@ int get_usable_memory_ranges(struct crash_mem **mem_ranges)
553553
#endif /* CONFIG_KEXEC_FILE */
554554

555555
#ifdef CONFIG_CRASH_DUMP
556-
static int crash_exclude_mem_range_guarded(struct crash_mem **mem_ranges,
557-
unsigned long long mstart,
558-
unsigned long long mend)
556+
int arch_crash_exclude_mem_range(struct crash_mem **mem_ranges,
557+
unsigned long long mstart,
558+
unsigned long long mend)
559559
{
560560
struct crash_mem *tmem = *mem_ranges;
561561

@@ -604,18 +604,10 @@ int get_crash_memory_ranges(struct crash_mem **mem_ranges)
604604
sort_memory_ranges(*mem_ranges, true);
605605
}
606606

607-
/* Exclude crashkernel region */
608-
ret = crash_exclude_mem_range_guarded(mem_ranges, crashk_res.start, crashk_res.end);
607+
ret = crash_exclude_core_ranges(mem_ranges);
609608
if (ret)
610609
goto out;
611610

612-
for (i = 0; i < crashk_cma_cnt; ++i) {
613-
ret = crash_exclude_mem_range_guarded(mem_ranges, crashk_cma_ranges[i].start,
614-
crashk_cma_ranges[i].end);
615-
if (ret)
616-
goto out;
617-
}
618-
619611
/*
620612
* FIXME: For now, stay in parity with kexec-tools but if RTAS/OPAL
621613
* regions are exported to save their context at the time of
@@ -641,89 +633,4 @@ int get_crash_memory_ranges(struct crash_mem **mem_ranges)
641633
pr_err("Failed to setup crash memory ranges\n");
642634
return ret;
643635
}
644-
645-
/**
646-
* remove_mem_range - Removes the given memory range from the range list.
647-
* @mem_ranges: Range list to remove the memory range to.
648-
* @base: Base address of the range to remove.
649-
* @size: Size of the memory range to remove.
650-
*
651-
* (Re)allocates memory, if needed.
652-
*
653-
* Returns 0 on success, negative errno on error.
654-
*/
655-
int remove_mem_range(struct crash_mem **mem_ranges, u64 base, u64 size)
656-
{
657-
u64 end;
658-
int ret = 0;
659-
unsigned int i;
660-
u64 mstart, mend;
661-
struct crash_mem *mem_rngs = *mem_ranges;
662-
663-
if (!size)
664-
return 0;
665-
666-
/*
667-
* Memory range are stored as start and end address, use
668-
* the same format to do remove operation.
669-
*/
670-
end = base + size - 1;
671-
672-
for (i = 0; i < mem_rngs->nr_ranges; i++) {
673-
mstart = mem_rngs->ranges[i].start;
674-
mend = mem_rngs->ranges[i].end;
675-
676-
/*
677-
* Memory range to remove is not part of this range entry
678-
* in the memory range list
679-
*/
680-
if (!(base >= mstart && end <= mend))
681-
continue;
682-
683-
/*
684-
* Memory range to remove is equivalent to this entry in the
685-
* memory range list. Remove the range entry from the list.
686-
*/
687-
if (base == mstart && end == mend) {
688-
for (; i < mem_rngs->nr_ranges - 1; i++) {
689-
mem_rngs->ranges[i].start = mem_rngs->ranges[i+1].start;
690-
mem_rngs->ranges[i].end = mem_rngs->ranges[i+1].end;
691-
}
692-
mem_rngs->nr_ranges--;
693-
goto out;
694-
}
695-
/*
696-
* Start address of the memory range to remove and the
697-
* current memory range entry in the list is same. Just
698-
* move the start address of the current memory range
699-
* entry in the list to end + 1.
700-
*/
701-
else if (base == mstart) {
702-
mem_rngs->ranges[i].start = end + 1;
703-
goto out;
704-
}
705-
/*
706-
* End address of the memory range to remove and the
707-
* current memory range entry in the list is same.
708-
* Just move the end address of the current memory
709-
* range entry in the list to base - 1.
710-
*/
711-
else if (end == mend) {
712-
mem_rngs->ranges[i].end = base - 1;
713-
goto out;
714-
}
715-
/*
716-
* Memory range to remove is not at the edge of current
717-
* memory range entry. Split the current memory entry into
718-
* two half.
719-
*/
720-
else {
721-
size = mem_rngs->ranges[i].end - end + 1;
722-
mem_rngs->ranges[i].end = base - 1;
723-
ret = add_mem_range(mem_ranges, end + 1, size);
724-
}
725-
}
726-
out:
727-
return ret;
728-
}
729636
#endif /* CONFIG_CRASH_DUMP */

0 commit comments

Comments
 (0)