Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751508AbeAPAnx (ORCPT + 1 other); Mon, 15 Jan 2018 19:43:53 -0500 Received: from mx1.redhat.com ([209.132.183.28]:46756 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751178AbeAPAnu (ORCPT ); Mon, 15 Jan 2018 19:43:50 -0500 Date: Tue, 16 Jan 2018 08:43:20 +0800 From: Baoquan He To: Chao Fan Cc: linux-kernel@vger.kernel.org, x86@kernel.org, hpa@zytor.com, tglx@linutronix.de, mingo@redhat.com, keescook@chromium.org, yasu.isimatu@gmail.com, indou.takao@jp.fujitsu.com, lcapitulino@redhat.com Subject: Re: [PATCH v6 5/5] kaslr: add kaslr_mem=nn[KMG]!ss[KMG] to avoid memory regions Message-ID: <20180116004320.GA4122@localhost.localdomain> References: <20180115124016.17683-1-fanc.fnst@cn.fujitsu.com> <20180115124016.17683-6-fanc.fnst@cn.fujitsu.com> <20180115124930.GG13719@localhost.localdomain> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20180115124930.GG13719@localhost.localdomain> User-Agent: Mutt/1.9.1 (2017-09-22) X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Tue, 16 Jan 2018 00:43:50 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Return-Path: On 01/15/18 at 08:49pm, Chao Fan wrote: > Hi Luiz, > > I don't know if this patch is OK for you. > Of coure you can only use kaslr_mem=nn@ss to solve the 1G huge page > issue. Because we know the region [0,1G] is not suitable for 1G huge > page, so you can specify ksalr_mem=1G@0 of kaslr_mem=1G to solve > your problem. But the regions may be too slow and is not good > for the randomness. I guess you want to say: "Because we know the region [0,1G] is not suitable for 1G huge page, so you can specify ksalr_mem=1G@0 or kaslr_mem=1G to solve your problem. But the region may be too small and is not good for the randomness." Hi Luiz, For hugetlb issue, we can always suggest users adding "kaslr_mem=1G" to kernel cmdline on KVM. Surely if users are very familiar with system memory layout, they can specify "kaslr_mem=1G, kaslr_mem=1G@2G kaslr_mem=1G@4G" for better kernel text KASLR. The "kaslr_mem=1G" suggestion can be documented for redhat kvm usage. Any thought or suggestion? Thanks Baoquan > > So as Kess said, I put the regions suitable for 1G huge page to > mem_avoid, you can use kaslr_mem=1G!1G to solve the problem in your > email. > > Thanks, > Chao Fan > > On Mon, Jan 15, 2018 at 08:40:16PM +0800, Chao Fan wrote: > >In current code, kaslr choose the only suitable memory region for 1G > >huge page, so the no suitable region for 1G huge page. So add this > >feature to store these regions. > > > >Of coure, we can use memmap= to do this job. But memmap will be handled > >in the later code, but kaslr_mem= only works in this period. > > > >It can help users to avoid more memory regions, not only the 1G huge > >huge page issue. > > > >Signed-off-by: Chao Fan > >--- > > arch/x86/boot/compressed/kaslr.c | 56 +++++++++++++++++++++++++++++++++++----- > > 1 file changed, 50 insertions(+), 6 deletions(-) > > > >diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c > >index fc531fa1f10c..c71189cf8d56 100644 > >--- a/arch/x86/boot/compressed/kaslr.c > >+++ b/arch/x86/boot/compressed/kaslr.c > >@@ -95,6 +95,18 @@ static bool memmap_too_large; > > /* Store memory limit specified by "mem=nn[KMG]" or "memmap=nn[KMG]" */ > > unsigned long long mem_limit = ULLONG_MAX; > > > >+/* > >+ * Only supporting at most 4 unusable memory regions for > >+ * "kaslr_mem=nn[KMG]!ss[KMG]" > >+ */ > >+#define MAX_KASLR_MEM_AVOID 4 > >+ > >+static bool kaslr_mem_avoid_too_large; > >+ > >+enum kaslr_mem_type { > >+ CMD_MEM_USABLE = 1, > >+ CMD_MEM_AVOID, > >+}; > > > > enum mem_avoid_index { > > MEM_AVOID_ZO_RANGE = 0, > >@@ -103,6 +115,8 @@ enum mem_avoid_index { > > MEM_AVOID_BOOTPARAMS, > > MEM_AVOID_MEMMAP_BEGIN, > > MEM_AVOID_MEMMAP_END = MEM_AVOID_MEMMAP_BEGIN + MAX_MEMMAP_REGIONS - 1, > >+ MEM_AVOID_KASLR_MEM_BEGIN, > >+ MEM_AVOID_KASLR_MEM_END = MEM_AVOID_KASLR_MEM_BEGIN + MAX_KASLR_MEM_AVOID - 1, > > MEM_AVOID_MAX, > > }; > > > >@@ -217,7 +231,8 @@ static void mem_avoid_memmap(char *str) > > > > static int parse_kaslr_mem(char *p, > > unsigned long long *start, > >- unsigned long long *size) > >+ unsigned long long *size, > >+ int *cmd_type) > > { > > char *oldp; > > > >@@ -230,8 +245,13 @@ static int parse_kaslr_mem(char *p, > > return -EINVAL; > > > > switch (*p) { > >+ case '!' : > >+ *start = memparse(p + 1, &p); > >+ *cmd_type = CMD_MEM_AVOID; > >+ return 0; > > case '@': > > *start = memparse(p + 1, &p); > >+ *cmd_type = CMD_MEM_USABLE; > > return 0; > > default: > > /* > >@@ -240,6 +260,7 @@ static int parse_kaslr_mem(char *p, > > * the region starts from 0. > > */ > > *start = 0; > >+ *cmd_type = CMD_MEM_USABLE; > > return 0; > > } > > > >@@ -248,26 +269,44 @@ static int parse_kaslr_mem(char *p, > > > > static void parse_kaslr_mem_regions(char *str) > > { > >- static int i; > >+ static int i = 0, j = 0; > >+ int cmd_type = 0; > > > > while (str && (i < MAX_KASLR_MEM_USABLE)) { > > int rc; > > unsigned long long start, size; > > char *k = strchr(str, ','); > > > >+ if (i >= MAX_KASLR_MEM_USABLE && j >= MAX_KASLR_MEM_AVOID) > >+ break; > >+ > > if (k) > > *k++ = 0; > > > >- rc = parse_kaslr_mem(str, &start, &size); > >+ rc = parse_kaslr_mem(str, &start, &size, &cmd_type); > > if (rc < 0) > > break; > > str = k; > > > >- mem_usable[i].start = start; > >- mem_usable[i].size = size; > >- i++; > >+ if (cmd_type == CMD_MEM_USABLE) { > >+ if (i >= MAX_KASLR_MEM_USABLE) > >+ continue; > >+ mem_usable[i].start = start; > >+ mem_usable[i].size = size; > >+ i++; > >+ } else if (cmd_type == CMD_MEM_AVOID) { > >+ if (j >= MAX_KASLR_MEM_AVOID) > >+ continue; > >+ mem_avoid[MEM_AVOID_KASLR_MEM_BEGIN + j].start = start; > >+ mem_avoid[MEM_AVOID_KASLR_MEM_BEGIN + j].size = size; > >+ j++; > >+ } > > } > > num_usable_region = i; > >+ > >+ /* More than 4 kaslr_mem avoid, fail kaslr */ > >+ if ((j >= MAX_KASLR_MEM_AVOID) && str) > >+ kaslr_mem_avoid_too_large = true; > > } > > > > static int handle_mem_filter(void) > >@@ -799,6 +838,11 @@ static unsigned long find_random_phys_addr(unsigned long minimum, > > return 0; > > } > > > >+ /* Check if we had too many kaslr_mem avoid. */ > >+ if (kaslr_mem_avoid_too_large) { > >+ debug_putstr("Aborted memory entries scan (more than 4 kaslr_mem avoid args)!\n"); > >+ return 0; > >+ } > > /* Make sure minimum is aligned. */ > > minimum = ALIGN(minimum, CONFIG_PHYSICAL_ALIGN); > > > >-- > >2.14.3 > > > >