PM: hibernate: Use __get_safe_page() rather than touching the list
[platform/kernel/linux-starfive.git] / kernel / kexec_file.c
index 1d546dc..6d787ae 100644 (file)
@@ -339,7 +339,7 @@ SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
 
        image = NULL;
 
-       if (!mutex_trylock(&kexec_mutex))
+       if (!kexec_trylock())
                return -EBUSY;
 
        dest_image = &kexec_image;
@@ -411,7 +411,7 @@ out:
        if ((flags & KEXEC_FILE_ON_CRASH) && kexec_crash_image)
                arch_kexec_protect_crashkres();
 
-       mutex_unlock(&kexec_mutex);
+       kexec_unlock();
        kimage_free(image);
        return ret;
 }
@@ -898,10 +898,22 @@ static int kexec_purgatory_setup_sechdrs(struct purgatory_info *pi,
                }
 
                offset = ALIGN(offset, align);
+
+               /*
+                * Check if the segment contains the entry point, if so,
+                * calculate the value of image->start based on it.
+                * If the compiler has produced more than one .text section
+                * (Eg: .text.hot), they are generally after the main .text
+                * section, and they shall not be used to calculate
+                * image->start. So do not re-calculate image->start if it
+                * is not set to the initial value, and warn the user so they
+                * have a chance to fix their purgatory's linker script.
+                */
                if (sechdrs[i].sh_flags & SHF_EXECINSTR &&
                    pi->ehdr->e_entry >= sechdrs[i].sh_addr &&
                    pi->ehdr->e_entry < (sechdrs[i].sh_addr
-                                        + sechdrs[i].sh_size)) {
+                                        + sechdrs[i].sh_size) &&
+                   !WARN_ON(kbuf->image->start != pi->ehdr->e_entry)) {
                        kbuf->image->start -= sechdrs[i].sh_addr;
                        kbuf->image->start += kbuf->mem + offset;
                }