Received: by 10.223.185.116 with SMTP id b49csp4546381wrg; Mon, 26 Feb 2018 21:10:02 -0800 (PST) X-Google-Smtp-Source: AH8x227nTtF3Os6hQPP6Lo5v++WPs5jWhK0B4Q///j5Opq806eT1bt8Sz0gZzKoNzVZciiE7wypt X-Received: by 10.98.171.24 with SMTP id p24mr12937351pff.71.1519708202458; Mon, 26 Feb 2018 21:10:02 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519708202; cv=none; d=google.com; s=arc-20160816; b=hsVIcgKLjuaOKfcHgfNTzbYXM+NWsGiQoZWXSMkc9nQf6FgzR8uaVQ3sDLWV49PRDT OUboTLc4pz39RK5X8hgZZ6VQ3EKjFnUOF5AX1DICWs1JOVXqEtZC4uG97g4sEj6AKOSa MOcf3kzvsvKlyoORuxxs5uZD8Bgr2PZzxMIFLTMugXyqYAtbRAtUus/0hpVxsTvIgSRO mREpoTbX9CPPkwt/vP4wJQ9JBmmp4aCFBQP4z8z00FNOY6Deo+wrnArFbcBYaPu91koL 9XWM5mb4rjsYdvfPiz7Dt8t/1bqfZxaq/17phrIwr6McXHvz7rFmks2z7fwCbBV87ejT Pjdw== 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=6J4PL6OwT926Kxkehg8cPsNnwK0orobwxAOR83ZTd0o=; b=Cyvm/1xz16DZoH52mLHYcuDJ02/tN7+1wRSZn/GDhc8/HTPue6Kf+IPy4GTSVqZ9fO XffkJ301vXU/1WgGfPpyMnJchdpAagkLAMnT5u3M5SDP6N02YTiu5BSXuB6zgR5MIaAI pHFy7boTOScclQTcogOqKElwniJCmRAwzl+w3lEhmQWbf0o/Ho7E53P5OOgRm/wqvOKH RZJZjdb50eEctlp9jzBDIB0Rzn3Ymt93mx516xHRyuY6e8WrsBFFmJRHU3CMvp4iyCWP 5Sk3LGW9f7zrlQWNIvvh7VTD0WFV9sQzyaXvnpVxO02RGIvrIEHpkWeg+DD6qrgbViE3 N7qQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=eeA3mZOR; 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 j8-v6si7741183plk.774.2018.02.26.21.09.45; Mon, 26 Feb 2018 21:10:02 -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=eeA3mZOR; 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 S1752113AbeB0EtH (ORCPT + 99 others); Mon, 26 Feb 2018 23:49:07 -0500 Received: from mail-pf0-f195.google.com ([209.85.192.195]:46455 "EHLO mail-pf0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752097AbeB0EtE (ORCPT ); Mon, 26 Feb 2018 23:49:04 -0500 Received: by mail-pf0-f195.google.com with SMTP id z10so3170742pfh.13 for ; Mon, 26 Feb 2018 20:49:04 -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=6J4PL6OwT926Kxkehg8cPsNnwK0orobwxAOR83ZTd0o=; b=eeA3mZORYL1kdcznaSkxNsl8SLcBTItGoeSmiPoPqxno6roaKv9f7uMg9NSmqSa13S 6ekRc+JC9sYzCKcVpW6T/e0NcMrULxR+1i7CqYUBF84xOkPP8nw1QdENjnNtKo/Z0fn0 LW9iBt8aF1C+s84yFMBez3MmaA2xhpeyx8qeM= 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=6J4PL6OwT926Kxkehg8cPsNnwK0orobwxAOR83ZTd0o=; b=Mu1i7CjQnuHx3Ab4O8ZD7HqpwdNifD7ReTOGKlGkhKBXrqhiOjtWzgY+WtLzskEAHL 6IZ/w1Eqt52vazKsZWvf+GHgIvrEJml+px0DnPvj26/onBrMKF2rPjNkNFPSi6rjQ5XZ wVf5IthIE+lYfHWnPo5DWShwVOpOkIV9MEE3qNxUqZ5LeNCSHv8/q/nBWZPg8F5yYors NAPQc4sdOJNFJuEU5z8dEKvJgkpYihI7SUH872tpkI6tSYNiEIpljRSGxSVASFvPkRmy VnXEN2pG+3ESAVB+FGSs5VKVuc2GHm/ABb+LTPB5L7YLEcFu3tIDMszKL06GF1wKqyqR 3TyA== X-Gm-Message-State: APf1xPB3KVrJYzbpZJoKs7CytMirqTg1f7frQhcg1Pdz6ujJqpCtoI24 xyHZsTEcO9WYxjr8pBjO/gtCWw== X-Received: by 10.99.96.137 with SMTP id u131mr10523483pgb.103.1519706944103; Mon, 26 Feb 2018 20:49:04 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id g80sm20981660pfj.101.2018.02.26.20.49.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 26 Feb 2018 20:49:03 -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 5/7] x86: kexec_file: lift CRASH_MAX_RANGES limit on crash_mem buffer Date: Tue, 27 Feb 2018 13:48:12 +0900 Message-Id: <20180227044814.24808-6-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 CRASH_MAX_RANGES (== 16) seems to be good enough, fixed-number array is not a good idea in general. In this patch, size of crash_mem buffer is calculated as before and the buffer is now dynamically allocated. This change also allows removing crash_elf_data structure. Signed-off-by: AKASHI Takahiro Cc: Dave Young Cc: Vivek Goyal Cc: Baoquan He --- arch/x86/kernel/crash.c | 80 ++++++++++++++++++------------------------------- 1 file changed, 29 insertions(+), 51 deletions(-) diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c index 913fd8021f8a..bfc37ad20d4a 100644 --- a/arch/x86/kernel/crash.c +++ b/arch/x86/kernel/crash.c @@ -41,32 +41,14 @@ /* Alignment required for elf header segment */ #define ELF_CORE_HEADER_ALIGN 4096 -/* This primarily represents number of split ranges due to exclusion */ -#define CRASH_MAX_RANGES 16 - struct crash_mem_range { u64 start, end; }; struct crash_mem { - unsigned int nr_ranges; - struct crash_mem_range ranges[CRASH_MAX_RANGES]; -}; - -/* Misc data about ram ranges needed to prepare elf headers */ -struct crash_elf_data { - struct kimage *image; - /* - * Total number of ram ranges we have after various adjustments for - * crash reserved region, etc. - */ unsigned int max_nr_ranges; - - /* Pointer to elf header */ - void *ehdr; - /* Pointer to next phdr */ - void *bufp; - struct crash_mem mem; + unsigned int nr_ranges; + struct crash_mem_range ranges[0]; }; /* Used while preparing memory map entries for second kernel */ @@ -217,26 +199,29 @@ static int get_nr_ram_ranges_callback(struct resource *res, void *arg) return 0; } - /* Gather all the required information to prepare elf headers for ram regions */ -static void fill_up_crash_elf_data(struct crash_elf_data *ced, - struct kimage *image) +static struct crash_mem *fill_up_crash_elf_data(void) { unsigned int nr_ranges = 0; - - ced->image = image; + struct crash_mem *cmem; walk_system_ram_res(0, -1, &nr_ranges, get_nr_ram_ranges_callback); - ced->max_nr_ranges = nr_ranges; + /* + * Exclusion of crash region and/or crashk_low_res may cause + * another range split. So add extra two slots here. + */ + nr_ranges += 2; + cmem = vmalloc(sizeof(struct crash_mem) + + sizeof(struct crash_mem_range) * nr_ranges); + if (!cmem) + return NULL; - /* Exclusion of crash region could split memory ranges */ - ced->max_nr_ranges++; + cmem->max_nr_ranges = nr_ranges; + cmem->nr_ranges = 0; - /* If crashk_low_res is not 0, another range split possible */ - if (crashk_low_res.end) - ced->max_nr_ranges++; + return cmem; } static int exclude_mem_range(struct crash_mem *mem, @@ -293,10 +278,8 @@ static int exclude_mem_range(struct crash_mem *mem, return 0; /* Split happened */ - if (i == CRASH_MAX_RANGES - 1) { - pr_err("Too many crash ranges after split\n"); + if (i == mem->max_nr_ranges - 1) return -ENOMEM; - } /* Location where new range should go */ j = i + 1; @@ -314,11 +297,10 @@ 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 + * might lead to split and split ranges are put in cmem->ranges[] array */ -static int elf_header_exclude_ranges(struct crash_elf_data *ced) +static int elf_header_exclude_ranges(struct crash_mem *cmem) { - struct crash_mem *cmem = &ced->mem; int ret = 0; /* Exclude crashkernel region */ @@ -337,8 +319,7 @@ 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; - struct crash_mem *cmem = &ced->mem; + struct crash_mem *cmem = arg; cmem->ranges[cmem->nr_ranges].start = res->start; cmem->ranges[cmem->nr_ranges].end = res->end; @@ -347,7 +328,7 @@ static int prepare_elf64_ram_headers_callback(struct resource *res, void *arg) return 0; } -static int prepare_elf64_headers(struct crash_elf_data *ced, int kernel_map, +static int prepare_elf64_headers(struct crash_mem *cmem, int kernel_map, void **addr, unsigned long *sz) { Elf64_Ehdr *ehdr; @@ -356,12 +337,11 @@ static int prepare_elf64_headers(struct crash_elf_data *ced, int kernel_map, unsigned char *buf, *bufp; unsigned int cpu, i; unsigned long long notes_addr; - struct crash_mem *cmem = &ced->mem; unsigned long mstart, mend; /* extra phdr for vmcoreinfo elf note */ nr_phdr = nr_cpus + 1; - nr_phdr += ced->max_nr_ranges; + nr_phdr += cmem->nr_ranges; /* * kexec-tools creates an extra PT_LOAD phdr for kernel text mapping @@ -455,29 +435,27 @@ static int prepare_elf64_headers(struct crash_elf_data *ced, int kernel_map, static int prepare_elf_headers(struct kimage *image, void **addr, unsigned long *sz) { - struct crash_elf_data *ced; + struct crash_mem *cmem; Elf64_Ehdr *ehdr; Elf64_Phdr *phdr; int ret, i; - ced = kzalloc(sizeof(*ced), GFP_KERNEL); - if (!ced) + cmem = fill_up_crash_elf_data(); + if (!cmem) return -ENOMEM; - fill_up_crash_elf_data(ced, image); - - ret = walk_system_ram_res(0, -1, ced, + ret = walk_system_ram_res(0, -1, cmem, prepare_elf64_ram_headers_callback); if (ret) goto out; /* Exclude unwanted mem ranges */ - ret = elf_header_exclude_ranges(ced); + ret = elf_header_exclude_ranges(cmem); if (ret) goto out; /* By default prepare 64bit headers */ - ret = prepare_elf64_headers(ced, + ret = prepare_elf64_headers(cmem, (int)IS_ENABLED(CONFIG_X86_64), addr, sz); if (ret) goto out; @@ -496,7 +474,7 @@ static int prepare_elf_headers(struct kimage *image, void **addr, break; } out: - kfree(ced); + vfree(cmem); return ret; } -- 2.16.2