aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Rudo <prudo@linux.vnet.ibm.com>2018-04-13 18:36:32 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-04-13 20:10:28 -0400
commitf1b1cca39650c9c1dbe26140946a518953f66771 (patch)
treeec9b5b836fa82cd7956f01ec4f40ad66d51dc165
parent930457057abe4e6d57433dea75e97e0e39fd0ab6 (diff)
kernel/kexec_file.c: remove unneeded for-loop in kexec_purgatory_setup_sechdrs
To update the entry point there is an extra loop over all section headers although this can be done in the main loop. So move it there and eliminate the extra loop and variable to store the 'entry section index'. Also, in the main loop, move the usual case, i.e. non-bss section, out of the extra if-block. Link: http://lkml.kernel.org/r/20180321112751.22196-8-prudo@linux.vnet.ibm.com Signed-off-by: Philipp Rudo <prudo@linux.vnet.ibm.com> Reviewed-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Acked-by: Dave Young <dyoung@redhat.com> Cc: AKASHI Takahiro <takahiro.akashi@linaro.org> Cc: Eric Biederman <ebiederm@xmission.com> Cc: Heiko Carstens <heiko.carstens@de.ibm.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Thiago Jung Bauermann <bauerman@linux.vnet.ibm.com> Cc: Vivek Goyal <vgoyal@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--kernel/kexec_file.c76
1 files changed, 30 insertions, 46 deletions
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index 878b97bd3067..6f0ec9f2e5c1 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -792,7 +792,6 @@ static int kexec_purgatory_setup_sechdrs(struct purgatory_info *pi,
792 unsigned char *buf_addr; 792 unsigned char *buf_addr;
793 unsigned char *src; 793 unsigned char *src;
794 Elf_Shdr *sechdrs; 794 Elf_Shdr *sechdrs;
795 int entry_sidx = -1;
796 int i; 795 int i;
797 796
798 sechdrs = vzalloc(pi->ehdr->e_shnum * sizeof(Elf_Shdr)); 797 sechdrs = vzalloc(pi->ehdr->e_shnum * sizeof(Elf_Shdr));
@@ -824,32 +823,11 @@ static int kexec_purgatory_setup_sechdrs(struct purgatory_info *pi,
824 sechdrs[i].sh_offset; 823 sechdrs[i].sh_offset;
825 } 824 }
826 825
827 /*
828 * Identify entry point section and make entry relative to section
829 * start.
830 */
831 kbuf->image->start = pi->ehdr->e_entry;
832 for (i = 0; i < pi->ehdr->e_shnum; i++) {
833 if (!(sechdrs[i].sh_flags & SHF_ALLOC))
834 continue;
835
836 if (!(sechdrs[i].sh_flags & SHF_EXECINSTR))
837 continue;
838
839 /* Make entry section relative */
840 if (sechdrs[i].sh_addr <= pi->ehdr->e_entry &&
841 ((sechdrs[i].sh_addr + sechdrs[i].sh_size) >
842 pi->ehdr->e_entry)) {
843 entry_sidx = i;
844 kbuf->image->start -= sechdrs[i].sh_addr;
845 break;
846 }
847 }
848
849 /* Load SHF_ALLOC sections */ 826 /* Load SHF_ALLOC sections */
850 buf_addr = kbuf->buffer; 827 buf_addr = kbuf->buffer;
851 load_addr = curr_load_addr = kbuf->mem; 828 load_addr = curr_load_addr = kbuf->mem;
852 bss_addr = load_addr + kbuf->bufsz; 829 bss_addr = load_addr + kbuf->bufsz;
830 kbuf->image->start = pi->ehdr->e_entry;
853 831
854 for (i = 0; i < pi->ehdr->e_shnum; i++) { 832 for (i = 0; i < pi->ehdr->e_shnum; i++) {
855 unsigned long align; 833 unsigned long align;
@@ -858,34 +836,40 @@ static int kexec_purgatory_setup_sechdrs(struct purgatory_info *pi,
858 continue; 836 continue;
859 837
860 align = sechdrs[i].sh_addralign; 838 align = sechdrs[i].sh_addralign;
861 if (sechdrs[i].sh_type != SHT_NOBITS) { 839
862 curr_load_addr = ALIGN(curr_load_addr, align); 840 if (sechdrs[i].sh_type == SHT_NOBITS) {
863 offset = curr_load_addr - load_addr;
864 /* We already modifed ->sh_offset to keep src addr */
865 src = (char *) sechdrs[i].sh_offset;
866 memcpy(buf_addr + offset, src, sechdrs[i].sh_size);
867
868 /* Store load address and source address of section */
869 sechdrs[i].sh_addr = curr_load_addr;
870
871 /*
872 * This section got copied to temporary buffer. Update
873 * ->sh_offset accordingly.
874 */
875 sechdrs[i].sh_offset = (unsigned long)(buf_addr + offset);
876
877 /* Advance to the next address */
878 curr_load_addr += sechdrs[i].sh_size;
879 } else {
880 bss_addr = ALIGN(bss_addr, align); 841 bss_addr = ALIGN(bss_addr, align);
881 sechdrs[i].sh_addr = bss_addr; 842 sechdrs[i].sh_addr = bss_addr;
882 bss_addr += sechdrs[i].sh_size; 843 bss_addr += sechdrs[i].sh_size;
844 continue;
845 }
846
847 curr_load_addr = ALIGN(curr_load_addr, align);
848 offset = curr_load_addr - load_addr;
849 /* We already modifed ->sh_offset to keep src addr */
850 src = (char *)sechdrs[i].sh_offset;
851 memcpy(buf_addr + offset, src, sechdrs[i].sh_size);
852
853 if (sechdrs[i].sh_flags & SHF_EXECINSTR &&
854 pi->ehdr->e_entry >= sechdrs[i].sh_addr &&
855 pi->ehdr->e_entry < (sechdrs[i].sh_addr
856 + sechdrs[i].sh_size)) {
857 kbuf->image->start -= sechdrs[i].sh_addr;
858 kbuf->image->start += curr_load_addr;
883 } 859 }
884 }
885 860
886 /* Update entry point based on load address of text section */ 861 /* Store load address and source address of section */
887 if (entry_sidx >= 0) 862 sechdrs[i].sh_addr = curr_load_addr;
888 kbuf->image->start += sechdrs[entry_sidx].sh_addr; 863
864 /*
865 * This section got copied to temporary buffer. Update
866 * ->sh_offset accordingly.
867 */
868 sechdrs[i].sh_offset = (unsigned long)(buf_addr + offset);
869
870 /* Advance to the next address */
871 curr_load_addr += sechdrs[i].sh_size;
872 }
889 873
890 return 0; 874 return 0;
891} 875}