Lines Matching +full:segment +full:- +full:0
1 // SPDX-License-Identifier: GPL-2.0-only
3 * kexec.c - kexec system call core code.
4 * Copyright (C) 2002-2004 Eric Biederman <ebiederm@xmission.com>
43 #include <linux/dma-map-ops.h>
51 atomic_t __kexec_lock = ATOMIC_INIT(0);
59 * When kexec transitions to the new kernel there is a one-to-one
78 * 0 - TASK_SIZE, as only the user space mappings are arbitrarily
85 * be self-contained.
93 * - allocating a page table with the control code buffer identity
102 #define KIMAGE_NO_DEST (-1UL)
103 #define PAGE_COUNT(x) (((x) + PAGE_SIZE - 1) >> PAGE_SHIFT)
112 unsigned long nr_segments = image->nr_segments; in sanity_check_segment_list()
113 unsigned long total_pages = 0; in sanity_check_segment_list()
129 for (i = 0; i < nr_segments; i++) { in sanity_check_segment_list()
132 mstart = image->segment[i].mem; in sanity_check_segment_list()
133 mend = mstart + image->segment[i].memsz; in sanity_check_segment_list()
135 return -EADDRNOTAVAIL; in sanity_check_segment_list()
137 return -EADDRNOTAVAIL; in sanity_check_segment_list()
139 return -EADDRNOTAVAIL; in sanity_check_segment_list()
145 * easy explanation as one segment stops on another. in sanity_check_segment_list()
147 for (i = 0; i < nr_segments; i++) { in sanity_check_segment_list()
151 mstart = image->segment[i].mem; in sanity_check_segment_list()
152 mend = mstart + image->segment[i].memsz; in sanity_check_segment_list()
153 for (j = 0; j < i; j++) { in sanity_check_segment_list()
156 pstart = image->segment[j].mem; in sanity_check_segment_list()
157 pend = pstart + image->segment[j].memsz; in sanity_check_segment_list()
160 return -EINVAL; in sanity_check_segment_list()
169 for (i = 0; i < nr_segments; i++) { in sanity_check_segment_list()
170 if (image->segment[i].bufsz > image->segment[i].memsz) in sanity_check_segment_list()
171 return -EINVAL; in sanity_check_segment_list()
179 for (i = 0; i < nr_segments; i++) { in sanity_check_segment_list()
180 if (PAGE_COUNT(image->segment[i].memsz) > nr_pages / 2) in sanity_check_segment_list()
181 return -EINVAL; in sanity_check_segment_list()
183 total_pages += PAGE_COUNT(image->segment[i].memsz); in sanity_check_segment_list()
187 return -EINVAL; in sanity_check_segment_list()
200 if (image->type == KEXEC_TYPE_CRASH) { in sanity_check_segment_list()
201 for (i = 0; i < nr_segments; i++) { in sanity_check_segment_list()
204 mstart = image->segment[i].mem; in sanity_check_segment_list()
205 mend = mstart + image->segment[i].memsz - 1; in sanity_check_segment_list()
209 return -EADDRNOTAVAIL; in sanity_check_segment_list()
221 for (i = 0; i < nr_segments; i++) in sanity_check_segment_list()
222 accept_memory(image->segment[i].mem, image->segment[i].memsz); in sanity_check_segment_list()
224 return 0; in sanity_check_segment_list()
236 image->entry = &image->head; in do_kimage_alloc_init()
237 image->last_entry = &image->head; in do_kimage_alloc_init()
238 image->control_page = ~0; /* By default this does not apply */ in do_kimage_alloc_init()
239 image->type = KEXEC_TYPE_DEFAULT; in do_kimage_alloc_init()
242 INIT_LIST_HEAD(&image->control_pages); in do_kimage_alloc_init()
245 INIT_LIST_HEAD(&image->dest_pages); in do_kimage_alloc_init()
248 INIT_LIST_HEAD(&image->unusable_pages); in do_kimage_alloc_init()
251 image->hp_action = KEXEC_CRASH_HP_NONE; in do_kimage_alloc_init()
252 image->elfcorehdr_index = -1; in do_kimage_alloc_init()
253 image->elfcorehdr_updated = false; in do_kimage_alloc_init()
265 for (i = 0; i < image->nr_segments; i++) { in kimage_is_destination_range()
268 mstart = image->segment[i].mem; in kimage_is_destination_range()
269 mend = mstart + image->segment[i].memsz - 1; in kimage_is_destination_range()
274 return 0; in kimage_is_destination_range()
287 pages->mapping = NULL; in kimage_alloc_pages()
290 for (i = 0; i < count; i++) in kimage_alloc_pages()
297 for (i = 0; i < count; i++) in kimage_alloc_pages()
313 for (i = 0; i < count; i++) in kimage_free_pages()
323 list_del(&page->lru); in kimage_free_page_list()
363 eaddr = (epfn << PAGE_SHIFT) - 1; in kimage_alloc_normal_control_pages()
366 list_add(&pages->lru, &extra_pages); in kimage_alloc_normal_control_pages()
373 list_add(&pages->lru, &image->control_pages); in kimage_alloc_normal_control_pages()
379 * to give it an entry in image->segment[]. in kimage_alloc_normal_control_pages()
384 * Ideally I would convert multi-page allocations into single in kimage_alloc_normal_control_pages()
385 * page allocations, and add everything to image->dest_pages. in kimage_alloc_normal_control_pages()
424 hole_start = ALIGN(image->control_page, size); in kimage_alloc_crash_control_pages()
425 hole_end = hole_start + size - 1; in kimage_alloc_crash_control_pages()
434 for (i = 0; i < image->nr_segments; i++) { in kimage_alloc_crash_control_pages()
437 mstart = image->segment[i].mem; in kimage_alloc_crash_control_pages()
438 mend = mstart + image->segment[i].memsz - 1; in kimage_alloc_crash_control_pages()
440 /* Advance the hole to the end of the segment */ in kimage_alloc_crash_control_pages()
442 hole_end = hole_start + size - 1; in kimage_alloc_crash_control_pages()
447 if (i == image->nr_segments) { in kimage_alloc_crash_control_pages()
449 image->control_page = hole_end + 1; in kimage_alloc_crash_control_pages()
456 arch_kexec_post_alloc_pages(page_address(pages), 1 << order, 0); in kimage_alloc_crash_control_pages()
468 switch (image->type) { in kimage_alloc_control_pages()
484 if (*image->entry != 0) in kimage_add_entry()
485 image->entry++; in kimage_add_entry()
487 if (image->entry == image->last_entry) { in kimage_add_entry()
493 return -ENOMEM; in kimage_add_entry()
496 *image->entry = virt_to_boot_phys(ind_page) | IND_INDIRECTION; in kimage_add_entry()
497 image->entry = ind_page; in kimage_add_entry()
498 image->last_entry = ind_page + in kimage_add_entry()
499 ((PAGE_SIZE/sizeof(kimage_entry_t)) - 1); in kimage_add_entry()
501 *image->entry = entry; in kimage_add_entry()
502 image->entry++; in kimage_add_entry()
503 *image->entry = 0; in kimage_add_entry()
505 return 0; in kimage_add_entry()
528 kimage_free_page_list(&image->dest_pages); in kimage_free_extra_pages()
531 kimage_free_page_list(&image->unusable_pages); in kimage_free_extra_pages()
537 if (*image->entry != 0) in kimage_terminate()
538 image->entry++; in kimage_terminate()
540 *image->entry = IND_DONE; in kimage_terminate()
544 for (ptr = &image->head; (entry = *ptr) && !(entry & IND_DONE); \
560 for (i = 0; i < image->nr_segments; i++) { in kimage_free_cma()
561 struct page *cma = image->segment_cma[i]; in kimage_free_cma()
562 u32 nr_pages = image->segment[i].memsz >> PAGE_SHIFT; in kimage_free_cma()
569 image->segment_cma[i] = NULL; in kimage_free_cma()
577 kimage_entry_t ind = 0; in kimage_free()
583 if (image->vmcoreinfo_data_copy) { in kimage_free()
585 vunmap(image->vmcoreinfo_data_copy); in kimage_free()
610 kimage_free_page_list(&image->control_pages); in kimage_free()
619 if (image->file_mode) in kimage_free()
629 unsigned long destination = 0; in kimage_dst_used()
673 list_for_each_entry(page, &image->dest_pages, lru) { in kimage_alloc_page()
676 list_del(&page->lru); in kimage_alloc_page()
685 page = kimage_alloc_pages(gfp_mask, 0); in kimage_alloc_page()
691 list_add(&page->lru, &image->unusable_pages); in kimage_alloc_page()
702 addr + PAGE_SIZE - 1)) in kimage_alloc_page()
734 list_add(&page->lru, &image->dest_pages); in kimage_alloc_page()
742 struct kexec_segment *segment = &image->segment[idx]; in kimage_load_cma_segment() local
743 struct page *cma = image->segment_cma[idx]; in kimage_load_cma_segment()
747 int result = 0; in kimage_load_cma_segment()
751 if (image->file_mode) in kimage_load_cma_segment()
752 kbuf = segment->kbuf; in kimage_load_cma_segment()
754 buf = segment->buf; in kimage_load_cma_segment()
755 ubytes = segment->bufsz; in kimage_load_cma_segment()
756 mbytes = segment->memsz; in kimage_load_cma_segment()
757 maddr = segment->mem; in kimage_load_cma_segment()
765 PAGE_SIZE - (maddr & ~PAGE_MASK)); in kimage_load_cma_segment()
770 if (image->file_mode) in kimage_load_cma_segment()
774 ubytes -= uchunk; in kimage_load_cma_segment()
775 if (image->file_mode) in kimage_load_cma_segment()
782 result = -EFAULT; in kimage_load_cma_segment()
788 mbytes -= mchunk; in kimage_load_cma_segment()
794 memset(ptr, 0, mbytes); in kimage_load_cma_segment()
802 struct kexec_segment *segment = &image->segment[idx]; in kimage_load_normal_segment() local
809 if (image->file_mode) in kimage_load_normal_segment()
810 kbuf = segment->kbuf; in kimage_load_normal_segment()
812 buf = segment->buf; in kimage_load_normal_segment()
813 ubytes = segment->bufsz; in kimage_load_normal_segment()
814 mbytes = segment->memsz; in kimage_load_normal_segment()
815 maddr = segment->mem; in kimage_load_normal_segment()
817 if (image->segment_cma[idx]) in kimage_load_normal_segment()
821 if (result < 0) in kimage_load_normal_segment()
831 result = -ENOMEM; in kimage_load_normal_segment()
836 if (result < 0) in kimage_load_normal_segment()
844 PAGE_SIZE - (maddr & ~PAGE_MASK)); in kimage_load_normal_segment()
849 if (image->file_mode) in kimage_load_normal_segment()
853 ubytes -= uchunk; in kimage_load_normal_segment()
854 if (image->file_mode) in kimage_load_normal_segment()
861 result = -EFAULT; in kimage_load_normal_segment()
865 mbytes -= mchunk; in kimage_load_normal_segment()
880 struct kexec_segment *segment = &image->segment[idx]; in kimage_load_crash_segment() local
887 result = 0; in kimage_load_crash_segment()
888 if (image->file_mode) in kimage_load_crash_segment()
889 kbuf = segment->kbuf; in kimage_load_crash_segment()
891 buf = segment->buf; in kimage_load_crash_segment()
892 ubytes = segment->bufsz; in kimage_load_crash_segment()
893 mbytes = segment->memsz; in kimage_load_crash_segment()
894 maddr = segment->mem; in kimage_load_crash_segment()
902 result = -ENOMEM; in kimage_load_crash_segment()
905 arch_kexec_post_alloc_pages(page_address(page), 1, 0); in kimage_load_crash_segment()
909 PAGE_SIZE - (maddr & ~PAGE_MASK)); in kimage_load_crash_segment()
913 memset(ptr + uchunk, 0, mchunk - uchunk); in kimage_load_crash_segment()
918 if (image->file_mode) in kimage_load_crash_segment()
922 ubytes -= uchunk; in kimage_load_crash_segment()
923 if (image->file_mode) in kimage_load_crash_segment()
932 result = -EFAULT; in kimage_load_crash_segment()
936 mbytes -= mchunk; in kimage_load_crash_segment()
947 int result = -ENOMEM; in kimage_load_segment()
949 switch (image->type) { in kimage_load_segment()
966 unsigned long src_page_addr, dest_page_addr = 0; in kimage_map_segment()
977 npages = PFN_UP(eaddr) - PFN_DOWN(addr); in kimage_map_segment()
984 i = 0; in kimage_map_segment()
1025 .limit = -1,
1030 .limit = -1,
1041 struct kexec_load_limit *limit = table->data; in kexec_limit_handler()
1046 .mode = table->mode, in kexec_limit_handler()
1055 if (val < 0) in kexec_limit_handler()
1056 return -EINVAL; in kexec_limit_handler()
1058 mutex_lock(&limit->mutex); in kexec_limit_handler()
1059 if (limit->limit != -1 && val >= limit->limit) in kexec_limit_handler()
1060 ret = -EINVAL; in kexec_limit_handler()
1062 limit->limit = val; in kexec_limit_handler()
1063 mutex_unlock(&limit->mutex); in kexec_limit_handler()
1068 mutex_lock(&limit->mutex); in kexec_limit_handler()
1069 val = limit->limit; in kexec_limit_handler()
1070 mutex_unlock(&limit->mutex); in kexec_limit_handler()
1081 /* only handle a transition from default "0" to "1" */
1103 return 0; in kexec_core_sysctl_init()
1122 mutex_lock(&limit->mutex); in kexec_load_permitted()
1123 if (!limit->limit) { in kexec_load_permitted()
1124 mutex_unlock(&limit->mutex); in kexec_load_permitted()
1127 if (limit->limit != -1) in kexec_load_permitted()
1128 limit->limit--; in kexec_load_permitted()
1129 mutex_unlock(&limit->mutex); in kexec_load_permitted()
1140 int error = 0; in kernel_kexec()
1143 return -EBUSY; in kernel_kexec()
1145 error = -EINVAL; in kernel_kexec()
1150 if (kexec_image->preserve_context) { in kernel_kexec()
1160 error = -EBUSY; in kernel_kexec()
1194 * CPU hotplug again; so re-enable it here. in kernel_kexec()
1205 if (kexec_image->preserve_context) { in kernel_kexec()