On Tue, Jan 16, 2018 at 11:34:23AM -0500, Luiz Capitulino wrote:
>On Tue, 16 Jan 2018 08:43:20 +0800
>Baoquan He <b...@redhat.com> 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 <fanc.f...@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
>> > >  
>> > 
>> >   
>> 
>
>
>


Reply via email to