Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753795AbdHXRcH (ORCPT ); Thu, 24 Aug 2017 13:32:07 -0400 Received: from usa-sjc-mx-foss1.foss.arm.com ([217.140.101.70]:45142 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753609AbdHXRcG (ORCPT ); Thu, 24 Aug 2017 13:32:06 -0400 Date: Thu, 24 Aug 2017 18:30:50 +0100 From: Mark Rutland To: AKASHI Takahiro Cc: catalin.marinas@arm.com, will.deacon@arm.com, bauerman@linux.vnet.ibm.com, dhowells@redhat.com, vgoyal@redhat.com, herbert@gondor.apana.org.au, davem@davemloft.net, akpm@linux-foundation.org, mpe@ellerman.id.au, dyoung@redhat.com, bhe@redhat.com, arnd@arndb.de, ard.biesheuvel@linaro.org, kexec@lists.infradead.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: Re: [PATCH 14/14] arm64: kexec_file: add vmlinux format support Message-ID: <20170824173049.GG29665@leverpostej> References: <20170824081811.19299-1-takahiro.akashi@linaro.org> <20170824081811.19299-15-takahiro.akashi@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20170824081811.19299-15-takahiro.akashi@linaro.org> User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4059 Lines: 129 On Thu, Aug 24, 2017 at 05:18:11PM +0900, AKASHI Takahiro wrote: > The first PT_LOAD segment, which is assumed to be "text" code, in vmlinux > will be loaded at the offset of TEXT_OFFSET from the begining of system > memory. The other PT_LOAD segments are placed relative to the first one. I really don't like assuming things about the vmlinux ELF file. > Regarding kernel verification, since there is no standard way to contain > a signature within elf binary, we follow PowerPC's (not yet upstreamed) > approach, that is, appending a signature right after the kernel binary > itself like module signing. I also *really* don't like this. It's a bizarre in-band mechanism, without explcit information. It's not a nice ABI. If we can load an Image, why do we need to be able to load a vmlinux? [...] > diff --git a/arch/arm64/kernel/kexec_elf.c b/arch/arm64/kernel/kexec_elf.c > new file mode 100644 > index 000000000000..7bd3c1e1f65a > --- /dev/null > +++ b/arch/arm64/kernel/kexec_elf.c > @@ -0,0 +1,216 @@ > +/* > + * Kexec vmlinux loader > + > + * Copyright (C) 2017 Linaro Limited > + * Authors: AKASHI Takahiro > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 as > + * published by the Free Software Foundation. > + */ > + > +#define pr_fmt(fmt) "kexec_file(elf): " fmt > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +static int elf64_probe(const char *buf, unsigned long len) > +{ > + struct elfhdr ehdr; > + > + /* Check for magic and architecture */ > + memcpy(&ehdr, buf, sizeof(ehdr)); > + if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) || > + (elf16_to_cpu(&ehdr, ehdr.e_machine) != EM_AARCH64)) > + return -ENOEXEC; > + > + return 0; > +} > + > +static int elf_exec_load(struct kimage *image, struct elfhdr *ehdr, > + struct elf_info *elf_info, > + unsigned long *kernel_load_addr) > +{ > + struct kexec_buf kbuf; > + const struct elf_phdr *phdr; > + const struct arm64_image_header *h; > + unsigned long text_offset, rand_offset; > + unsigned long page_offset, phys_offset; > + int first_segment, i, ret = -ENOEXEC; > + > + kbuf.image = image; > + if (image->type == KEXEC_TYPE_CRASH) { > + kbuf.buf_min = crashk_res.start; > + kbuf.buf_max = crashk_res.end + 1; > + } else { > + kbuf.buf_min = 0; > + kbuf.buf_max = ULONG_MAX; > + } > + kbuf.top_down = 0; > + > + /* Load PT_LOAD segments. */ > + for (i = 0, first_segment = 1; i < ehdr->e_phnum; i++) { > + phdr = &elf_info->proghdrs[i]; > + if (phdr->p_type != PT_LOAD) > + continue; > + > + kbuf.buffer = (void *) elf_info->buffer + phdr->p_offset; > + kbuf.bufsz = min(phdr->p_filesz, phdr->p_memsz); > + kbuf.memsz = phdr->p_memsz; > + kbuf.buf_align = phdr->p_align; > + > + if (first_segment) { > + /* > + * Identify TEXT_OFFSET: > + * When CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET=y the image > + * header could be offset in the elf segment. The linker > + * script sets ehdr->e_entry to the start of text. Please, let's not have to go delving into the vmlinux, knowing intimate details about how it's put together. > + * > + * NOTE: In v3.16 or older, h->text_offset is 0, > + * so use the default, 0x80000 > + */ > + rand_offset = ehdr->e_entry - phdr->p_vaddr; > + h = (struct arm64_image_header *) > + (elf_info->buffer + phdr->p_offset + > + rand_offset); > + > + if (!arm64_header_check_magic(h)) > + goto out; > + > + if (h->image_size) > + text_offset = le64_to_cpu(h->text_offset); > + else > + text_offset = 0x80000; Surely we can share the Image header parsing with the Image parser? The Image code had practically the exact same logic operating on the header struct. Thanks, Mark.