Messages in this thread | | | Date | Mon, 15 Jan 2018 20:49:31 +0800 | From | Chao Fan <> | Subject | Re: [PATCH v6 5/5] kaslr: add kaslr_mem=nn[KMG]!ss[KMG] to avoid memory regions |
| |
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.
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 <fanc.fnst@cn.fujitsu.com> >--- > 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 >
| |