Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750948AbeAQFlN (ORCPT + 1 other); Wed, 17 Jan 2018 00:41:13 -0500 Received: from mail.cn.fujitsu.com ([183.91.158.132]:37825 "EHLO heian.cn.fujitsu.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1750836AbeAQFlL (ORCPT ); Wed, 17 Jan 2018 00:41:11 -0500 X-IronPort-AV: E=Sophos;i="5.43,368,1503331200"; d="scan'208";a="35397951" Date: Wed, 17 Jan 2018 13:39:50 +0800 From: Chao Fan To: Luiz Capitulino CC: Baoquan He , , , , , , , , Subject: Re: [PATCH v6 5/5] kaslr: add kaslr_mem=nn[KMG]!ss[KMG] to avoid memory regions Message-ID: <20180117053950.GA16609@localhost.localdomain> References: <20180115124016.17683-1-fanc.fnst@cn.fujitsu.com> <20180115124016.17683-6-fanc.fnst@cn.fujitsu.com> <20180115124930.GG13719@localhost.localdomain> <20180116004320.GA4122@localhost.localdomain> <20180116113423.37e350ed@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Disposition: inline In-Reply-To: <20180116113423.37e350ed@redhat.com> User-Agent: Mutt/1.9.1 (2017-09-22) X-Originating-IP: [10.167.225.56] X-yoursite-MailScanner-ID: DB66A49F19A3.AE573 X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: fanc.fnst@cn.fujitsu.com Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Return-Path: On Tue, Jan 16, 2018 at 11:34:23AM -0500, Luiz Capitulino wrote: >On Tue, 16 Jan 2018 08:43:20 +0800 >Baoquan He wrote: > >> 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? > >I have to test it, but I'll only have time in one or two days. > >Btw, I think this series is a very good improvement over the current >situation where the only option to solve the 1GB page problem is >to disable kaslr entirely. > >However, I've discussed this problem with a few people and they think >that it may be possible to change KASLR to extract the kernel to >an already fragmented 1GB region, so that it doesn't split an otherwise >good 1GB page. The advantage of this approach is that it's automatic >and doesn't require the user to know the memory layout. > Seems the kaslr_mem=nn@ss can solve your problem, so the new feature in PATCH 5/5 is not needed now, I will post the new version without this part. Thanks, Chao Fan >> >> 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 >> > > >> > >> > >> > > >