On Tue, Jan 16, 2018 at 08:43:20AM +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?
>
>Thanks
>Baoquan
>

Thanks for your explaination.

Thanks,
Chao Fan

>> 
>> 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 <[email protected]>
>> >---
>> > 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