Merge tag 'asm-generic-6.8' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd...
[linux-block.git] / kernel / kexec_core.c
index be5642a4ec4906ee262b2e892c89045411b49218..a08031b57a61f64526b09a4ea7d28c7d6092e104 100644 (file)
@@ -52,6 +52,8 @@ atomic_t __kexec_lock = ATOMIC_INIT(0);
 /* Flag to indicate we are going to kexec a new kernel */
 bool kexec_in_progress = false;
 
+bool kexec_file_dbg_print;
+
 int kexec_should_crash(struct task_struct *p)
 {
        /*
@@ -276,8 +278,8 @@ int kimage_is_destination_range(struct kimage *image,
                unsigned long mstart, mend;
 
                mstart = image->segment[i].mem;
-               mend = mstart + image->segment[i].memsz;
-               if ((end > mstart) && (start < mend))
+               mend = mstart + image->segment[i].memsz - 1;
+               if ((end >= mstart) && (start <= mend))
                        return 1;
        }
 
@@ -370,7 +372,7 @@ static struct page *kimage_alloc_normal_control_pages(struct kimage *image,
                pfn   = page_to_boot_pfn(pages);
                epfn  = pfn + count;
                addr  = pfn << PAGE_SHIFT;
-               eaddr = epfn << PAGE_SHIFT;
+               eaddr = (epfn << PAGE_SHIFT) - 1;
                if ((epfn >= (KEXEC_CONTROL_MEMORY_LIMIT >> PAGE_SHIFT)) ||
                              kimage_is_destination_range(image, addr, eaddr)) {
                        list_add(&pages->lru, &extra_pages);
@@ -430,7 +432,7 @@ static struct page *kimage_alloc_crash_control_pages(struct kimage *image,
 
        pages = NULL;
        size = (1 << order) << PAGE_SHIFT;
-       hole_start = (image->control_page + (size - 1)) & ~(size - 1);
+       hole_start = ALIGN(image->control_page, size);
        hole_end   = hole_start + size - 1;
        while (hole_end <= crashk_res.end) {
                unsigned long i;
@@ -447,7 +449,7 @@ static struct page *kimage_alloc_crash_control_pages(struct kimage *image,
                        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_start = ALIGN(mend, size);
                                hole_end   = hole_start + size - 1;
                                break;
                        }
@@ -455,7 +457,7 @@ static struct page *kimage_alloc_crash_control_pages(struct kimage *image,
                /* 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);
-                       image->control_page = hole_end;
+                       image->control_page = hole_end + 1;
                        break;
                }
        }
@@ -716,7 +718,7 @@ static struct page *kimage_alloc_page(struct kimage *image,
 
                /* If the page is not a destination page use it */
                if (!kimage_is_destination_range(image, addr,
-                                                 addr + PAGE_SIZE))
+                                                 addr + PAGE_SIZE - 1))
                        break;
 
                /*
@@ -1063,9 +1065,10 @@ __bpf_kfunc void crash_kexec(struct pt_regs *regs)
         * panic().  Otherwise parallel calls of panic() and crash_kexec()
         * may stop each other.  To exclude them, we use panic_cpu here too.
         */
+       old_cpu = PANIC_CPU_INVALID;
        this_cpu = raw_smp_processor_id();
-       old_cpu = atomic_cmpxchg(&panic_cpu, PANIC_CPU_INVALID, this_cpu);
-       if (old_cpu == PANIC_CPU_INVALID) {
+
+       if (atomic_try_cmpxchg(&panic_cpu, &old_cpu, this_cpu)) {
                /* This is the 1st CPU which comes here, so go ahead. */
                __crash_kexec(regs);