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: 129735 Delivered-To: patch@linaro.org Received: by 10.46.66.2 with SMTP id p2csp972779lja; Mon, 26 Feb 2018 20:49:10 -0800 (PST) X-Google-Smtp-Source: AH8x226FxTzDH0FadIBQEng/LxNMY9KFaHzCDlaO5yPsJTj2XpIwRQlp1a1WVGthL6ISME/1AKAc X-Received: by 10.99.140.85 with SMTP id q21mr10087268pgn.51.1519706949873; Mon, 26 Feb 2018 20:49:09 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519706949; cv=none; d=google.com; s=arc-20160816; b=CPyyNQ6uhWF6YT8XBmh4d1wWINwjVpHQ+Xfl4VQIDV4+X/CbJRVfEvhbfI92cof2TH sAZFIJK+MSXj7ErXJLpW7ICBDjBWzV9EWxDk0qpK82DzdTfVJuo4s/53iHb/zh651ZLP 7+fASLRuIid2XpW+73Xt/RcJOr/khxWKGrd0axNohRlDNs8KfO2hSSlCfBfOw1cHAawf cwDvdP1X8vxYiFwKe0+mM/jp7Alqa+9b17II84dgCkcnb6RS+wWyEkFq7iCHuwI9l5/U wmHOiPAWDdIFgSNw9Tdl1dRmnJA0dsJ8lMlKd3m5OBy90ZDJoA65HVD4kOUXog5YbWia ryyA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=+vdHx8igNuwtKYBwEka16s0oES3aT+sWWLO70kkZrSg=; b=c1K0dIcZ0fwOuhAjy77oGzeKlVWJDPCo1SKgcII7qh+t5h9DkmjYFX+Tj8va3pvvm3 LIA+g+YR3+1H5TZdGmjcWFD8873wAl6gfB4MqwhFhBF0PM49YQjlJWBvmkbcGvwre+NV RC+HPlFBobW07hVsMgJ1HGK//HVmkULqrlv78/PRd9h4gXKIRWuUgvL8HjwR9zTfzXvL oR0Em6cVCIrm+88qUqM+P9OoYFMagdJSicYtcXIZht0V8eJ0SzJiwN6bNVjRu9ciydXg 21w7eHw0vKRWhnJbhxzZH0NQ9ztWkiK8gSmGZmFbi8dP257L7IQ7lfRSzkSPvUDYQCMi +B/w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=FoISrgfb; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id t15si2069346pgu.62.2018.02.26.20.49.09; Mon, 26 Feb 2018 20:49:09 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=FoISrgfb; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752093AbeB0EtD (ORCPT + 28 others); Mon, 26 Feb 2018 23:49:03 -0500 Received: from mail-pf0-f193.google.com ([209.85.192.193]:35774 "EHLO mail-pf0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752030AbeB0Es4 (ORCPT ); Mon, 26 Feb 2018 23:48:56 -0500 Received: by mail-pf0-f193.google.com with SMTP id y186so6824872pfb.2 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=Wop7kVDAyBi+oI911R4gmefZiw2RO1ia57b8/v2pMhJEXTA6EzTrcUUJxHEEfEqPdt 15VtfEXe5zd2gcCA4WKaka5IIUErnyfX9MeKWfgzI/l5lNLnAUpm1ccK3TZukxjMQsZD knwG874CRMxkptJDdWeTTYt1XSGZv2Cd9+NWm3+PEQVFo4i22X4BCFdMTjGPSQ6NzQ0c n32tj/A+UXRUqbpUsDGYa1pyzkVMoPG9w1jxepHF2yWb00JogDl/36vb4tOCLvnPhy6q ne5kXYXQlnbfbStO4DG4dOVLc59ZJmWYnUHUXJwG8nu5yn+T/Q0wzg7L9MwHGloYEdSj nxqg== X-Gm-Message-State: APf1xPBCgVqs+qETSpEt74zwVQeu9nQ+UbuRa9ib4sjT6h30T96ryPhy HV4YXPXLVlnQkRa+AaRg/Tn5Aw== 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 Cc: kexec@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org, AKASHI Takahiro 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> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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(-) -- 2.16.2 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; }