From patchwork Tue Feb 27 04:48:10 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 10244285 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id C5373602DC for ; Tue, 27 Feb 2018 04:50:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id ADF0E2A52D for ; Tue, 27 Feb 2018 04:50:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AC8242A539; Tue, 27 Feb 2018 04:50:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 349CE2A54C for ; Tue, 27 Feb 2018 04:50:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=/TFaP2+frxPnjiwSWHHdGsBvjNBcioKTjS/kqelkDv4=; b=jMl7BTjc/qXuhpVeExwAw7hSgT E0jfznEebKrfRhNvB7kynSjDBEYZXG7bYAyXNWRGE8rnixBNdI+NY7i9j9yur8e0fHSX6+8n+ELTy TLlRHIjqeB8idp88HY7ifRm3H6zGX9KuAx1D/Yt/FJEC4EDVP2nO8ITt9WG2VlI1Q+YDnAWcZiCJN smt5U909P0qRmolBTqlQ/OIQRA+SYGHfHMsBdY1mHLa7skXRNuAbO42yYpH4+eoHc2BB85fljEpqP 1eqE3NR+hnv/MrUiE2Y5liJ+fcO/bN7es2TTLkTt2C9qyVclfp5x4MByRbJ02QvpBWz7f/RnXkqEm wlt/vjCw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.89 #1 (Red Hat Linux)) id 1eqXDA-0005vq-IF; Tue, 27 Feb 2018 04:49:56 +0000 Received: from mail-pf0-x244.google.com ([2607:f8b0:400e:c00::244]) by bombadil.infradead.org with esmtps (Exim 4.89 #1 (Red Hat Linux)) id 1eqXCD-0005O9-HD for linux-arm-kernel@lists.infradead.org; Tue, 27 Feb 2018 04:49:21 +0000 Received: by mail-pf0-x244.google.com with SMTP id u5so759441pfh.6 for ; Mon, 26 Feb 2018 20:48:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=+vdHx8igNuwtKYBwEka16s0oES3aT+sWWLO70kkZrSg=; b=FoISrgfb5W1fxFzdgdME7XeS+Y52e+qOFlx918CRCeM6aKxHEXxq/YQwH6TMj/2e6S ZC9otZaQtAP7/KdZ/ftYfhO/u4UOury1JJJF63E6XNU+rycmgbfTnRM4wXO5av3LRmqG Jz+um81QWPqw5sZLiLVtGrjsGz/5GDCTPP+Tk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=+vdHx8igNuwtKYBwEka16s0oES3aT+sWWLO70kkZrSg=; b=Rm17utR+zVANaGob8TCkhfmrXM5ksLpFkfLOgBGLZFZrqacPt3qMnMQbkjaIYfI1Ex o3sEJ8wSDATlMCuyNwmr7OyNbrVuXdqefhV+5TuCIZE3Su+OVfoKCrIIv7AeQWa/e40h II8bdxDKm4TdjNirfdNGOb/Mm2whelB65H20/5v4OttDGa2etLvo6zQYpBYNKAXFKT9T 9ZqSDS5xbvON7934l8b3f82ccFc+Pm+Jvz5+OmvDdyCbQtKSKH23gaL+3hmiroodrntd Afb7s29at4rX1W4aQRCJdBSGbKAwFxKEW/NJbZOWOAoT+Hetym7ej+jE54O4cNchXIO8 o4wA== X-Gm-Message-State: APf1xPC+n3oS+c5dVTQ+c7PRBnMmV8ox7dgCzh/dweQWFlyjSRxSzwUb J8VJgFLnwIYl2cmH9XGKpp8BgQ== X-Google-Smtp-Source: AH8x227ibXokdscoDi2am2ijoF8nnbW8FehNjQEy1JZXolcbmOaS8QDTbA+buls8vYV+507varz8vQ== X-Received: by 10.99.120.193 with SMTP id t184mr10547429pgc.348.1519706936039; Mon, 26 Feb 2018 20:48:56 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id u27sm16178570pfk.172.2018.02.26.20.48.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 26 Feb 2018 20:48:55 -0800 (PST) From: AKASHI Takahiro To: dyoung@redhat.com, vgoyal@redhat.com, bhe@redhat.com, mpe@ellerman.id.au, bauerman@linux.vnet.ibm.com, prudo@linux.vnet.ibm.com Subject: [PATCH 3/7] x86: kexec_file: purge system-ram walking from prepare_elf64_headers() Date: Tue, 27 Feb 2018 13:48:10 +0900 Message-Id: <20180227044814.24808-4-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180227044814.24808-1-takahiro.akashi@linaro.org> References: <20180227044814.24808-1-takahiro.akashi@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180226_204858_065017_CF100611 X-CRM114-Status: GOOD ( 19.20 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-s390@vger.kernel.org, kexec@lists.infradead.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, AKASHI Takahiro MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP While prepare_elf64_headers() in x86 looks pretty generic for other architectures' use, it contains some code which tries to list crash memory regions by walking through system resources, which is not always architecture agnostic. To make this function more generic, the related code should be purged. In this patch, prepare_elf64_headers() simply scans crash_mem buffer passed and add all the listed regions to elf header as a PT_LOAD segment. So walk_system_ram_res(prepare_elf64_headers_callback) have been moved forward before prepare_elf64_headers() where the callback, prepare_elf64_headers_callback(), is now responsible for filling up crash_mem buffer. Meanwhile exclude_elf_header_ranges() used to be called every time in this callback it is rather redundant and now called only once in prepare_elf_headers() as well. Signed-off-by: AKASHI Takahiro Cc: Dave Young Cc: Vivek Goyal Cc: Baoquan He --- arch/x86/kernel/crash.c | 121 +++++++++++++++++++++++------------------------- 1 file changed, 58 insertions(+), 63 deletions(-) diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c index 10e74d4778a1..2123fa0efc17 100644 --- a/arch/x86/kernel/crash.c +++ b/arch/x86/kernel/crash.c @@ -316,18 +316,11 @@ static int exclude_mem_range(struct crash_mem *mem, * Look for any unwanted ranges between mstart, mend and remove them. This * might lead to split and split ranges are put in ced->mem.ranges[] array */ -static int elf_header_exclude_ranges(struct crash_elf_data *ced, - unsigned long long mstart, unsigned long long mend) +static int elf_header_exclude_ranges(struct crash_elf_data *ced) { struct crash_mem *cmem = &ced->mem; int ret = 0; - memset(cmem->ranges, 0, sizeof(cmem->ranges)); - - cmem->ranges[0].start = mstart; - cmem->ranges[0].end = mend; - cmem->nr_ranges = 1; - /* Exclude crashkernel region */ ret = exclude_mem_range(cmem, crashk_res.start, crashk_res.end); if (ret) @@ -345,53 +338,13 @@ static int elf_header_exclude_ranges(struct crash_elf_data *ced, static int prepare_elf64_ram_headers_callback(struct resource *res, void *arg) { struct crash_elf_data *ced = arg; - Elf64_Ehdr *ehdr; - Elf64_Phdr *phdr; - unsigned long mstart, mend; - struct kimage *image = ced->image; - struct crash_mem *cmem; - int ret, i; - - ehdr = ced->ehdr; - - /* Exclude unwanted mem ranges */ - ret = elf_header_exclude_ranges(ced, res->start, res->end); - if (ret) - return ret; - - /* Go through all the ranges in ced->mem.ranges[] and prepare phdr */ - cmem = &ced->mem; - - for (i = 0; i < cmem->nr_ranges; i++) { - mstart = cmem->ranges[i].start; - mend = cmem->ranges[i].end; - - phdr = ced->bufp; - ced->bufp += sizeof(Elf64_Phdr); + struct crash_mem *cmem = &ced->mem; - phdr->p_type = PT_LOAD; - phdr->p_flags = PF_R|PF_W|PF_X; - phdr->p_offset = mstart; + cmem->ranges[cmem->nr_ranges].start = res->start; + cmem->ranges[cmem->nr_ranges].end = res->end; + cmem->nr_ranges++; - /* - * If a range matches backup region, adjust offset to backup - * segment. - */ - if (mstart == image->arch.backup_src_start && - (mend - mstart + 1) == image->arch.backup_src_sz) - phdr->p_offset = image->arch.backup_load_addr; - - phdr->p_paddr = mstart; - phdr->p_vaddr = (unsigned long long) __va(mstart); - phdr->p_filesz = phdr->p_memsz = mend - mstart + 1; - phdr->p_align = 0; - ehdr->e_phnum++; - pr_debug("Crash PT_LOAD elf header. phdr=%p vaddr=0x%llx, paddr=0x%llx, sz=0x%llx e_phnum=%d p_offset=0x%llx\n", - phdr, phdr->p_vaddr, phdr->p_paddr, phdr->p_filesz, - ehdr->e_phnum, phdr->p_offset); - } - - return ret; + return 0; } static int prepare_elf64_headers(struct crash_elf_data *ced, @@ -401,9 +354,10 @@ static int prepare_elf64_headers(struct crash_elf_data *ced, Elf64_Phdr *phdr; unsigned long nr_cpus = num_possible_cpus(), nr_phdr, elf_sz; unsigned char *buf, *bufp; - unsigned int cpu; + unsigned int cpu, i; unsigned long long notes_addr; - int ret; + struct crash_mem *cmem = &ced->mem; + unsigned long mstart, mend; /* extra phdr for vmcoreinfo elf note */ nr_phdr = nr_cpus + 1; @@ -472,13 +426,25 @@ static int prepare_elf64_headers(struct crash_elf_data *ced, (ehdr->e_phnum)++; #endif - /* Prepare PT_LOAD headers for system ram chunks. */ - ced->ehdr = ehdr; - ced->bufp = bufp; - ret = walk_system_ram_res(0, -1, ced, - prepare_elf64_ram_headers_callback); - if (ret < 0) - return ret; + /* Go through all the ranges in cmem->ranges[] and prepare phdr */ + for (i = 0; i < cmem->nr_ranges; i++) { + mstart = cmem->ranges[i].start; + mend = cmem->ranges[i].end; + + phdr->p_type = PT_LOAD; + phdr->p_flags = PF_R|PF_W|PF_X; + phdr->p_offset = mstart; + + phdr->p_paddr = mstart; + phdr->p_vaddr = (unsigned long long) __va(mstart); + phdr->p_filesz = phdr->p_memsz = mend - mstart + 1; + phdr->p_align = 0; + ehdr->e_phnum++; + phdr++; + pr_debug("Crash PT_LOAD elf header. phdr=%p vaddr=0x%llx, paddr=0x%llx, sz=0x%llx e_phnum=%d p_offset=0x%llx\n", + phdr, phdr->p_vaddr, phdr->p_paddr, phdr->p_filesz, + ehdr->e_phnum, phdr->p_offset); + } *addr = buf; *sz = elf_sz; @@ -490,7 +456,9 @@ static int prepare_elf_headers(struct kimage *image, void **addr, unsigned long *sz) { struct crash_elf_data *ced; - int ret; + Elf64_Ehdr *ehdr; + Elf64_Phdr *phdr; + int ret, i; ced = kzalloc(sizeof(*ced), GFP_KERNEL); if (!ced) @@ -498,8 +466,35 @@ static int prepare_elf_headers(struct kimage *image, void **addr, fill_up_crash_elf_data(ced, image); + ret = walk_system_ram_res(0, -1, ced, + prepare_elf64_ram_headers_callback); + if (ret) + goto out; + + /* Exclude unwanted mem ranges */ + ret = elf_header_exclude_ranges(ced); + if (ret) + goto out; + /* By default prepare 64bit headers */ ret = prepare_elf64_headers(ced, addr, sz); + if (ret) + goto out; + + /* + * If a range matches backup region, adjust offset to backup + * segment. + */ + ehdr = (Elf64_Ehdr *)*addr; + phdr = (Elf64_Phdr *)(ehdr + 1); + for (i = 0; i < ehdr->e_phnum; phdr++, i++) + if (phdr->p_type == PT_LOAD && + phdr->p_paddr == image->arch.backup_src_start && + phdr->p_memsz == image->arch.backup_src_sz) { + phdr->p_offset = image->arch.backup_load_addr; + break; + } +out: kfree(ced); return ret; }