Messages in this thread | | | Date | Fri, 19 Jan 2018 10:34:05 +0800 | From | Baoquan He <> | Subject | Re: [PATCH v7 1/5] x86/KASLR: Add kaslr_mem=nn[KMG]@ss[KMG] |
| |
On 01/17/18 at 06:53pm, Chao Fan wrote: > Introduce a new kernel parameter kaslr_mem=nn[KMG]@ss[KMG] which is used > by KASLR only during kernel decompression stage. > > Users can use it to specify memory regions where kernel can be randomized > into. E.g if movable_node specified in kernel cmdline, kernel could be ~ remove 'into' > extracted into those movable regions, this will make memory hotplug fail. > With the help of 'kaslr_mem=', limit kernel in those immovable regions > specified. > > Signed-off-by: Chao Fan <fanc.fnst@cn.fujitsu.com> > --- > arch/x86/boot/compressed/kaslr.c | 73 ++++++++++++++++++++++++++++++++++++++-- > 1 file changed, 70 insertions(+), 3 deletions(-) > > diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c > index 8199a6187251..b21741135673 100644 > --- a/arch/x86/boot/compressed/kaslr.c > +++ b/arch/x86/boot/compressed/kaslr.c > @@ -108,6 +108,15 @@ enum mem_avoid_index { > > static struct mem_vector mem_avoid[MEM_AVOID_MAX]; > > +/* Only support at most 4 usable memory regions specified for kaslr */ > +#define MAX_KASLR_MEM_USABLE 4 > + > +/* Store the usable memory regions for kaslr */ > +static struct mem_vector mem_usable[MAX_KASLR_MEM_USABLE];
The name xx_usable sounds not so good, while I don't know what is better. Otherwise this patch looks good to me.
Ack it.
Acked-by: Baoquan He <bhe@redhat.com>
> + > +/* The amount of usable regions for kaslr user specify, not more than 4 */ > +static int num_usable_region; > + > static bool mem_overlaps(struct mem_vector *one, struct mem_vector *two) > { > /* Item one is entirely before item two. */ > @@ -206,7 +215,62 @@ static void mem_avoid_memmap(char *str) > memmap_too_large = true; > } > > -static int handle_mem_memmap(void) > +static int parse_kaslr_mem(char *p, > + unsigned long long *start, > + unsigned long long *size) > +{ > + char *oldp; > + > + if (!p) > + return -EINVAL; > + > + oldp = p; > + *size = memparse(p, &p); > + if (p == oldp) > + return -EINVAL; > + > + switch (*p) { > + case '@': > + *start = memparse(p + 1, &p); > + return 0; > + default: > + /* > + * If w/o offset, only size specified, kaslr_mem=nn[KMG] > + * has the same behaviour as kaslr_mem=nn[KMG]@0. It means > + * the region starts from 0. > + */ > + *start = 0; > + return 0; > + } > + > + return -EINVAL; > +} > + > +static void parse_kaslr_mem_regions(char *str) > +{ > + static int i; > + > + while (str && (i < MAX_KASLR_MEM_USABLE)) { > + int rc; > + unsigned long long start, size; > + char *k = strchr(str, ','); > + > + if (k) > + *k++ = 0; > + > + rc = parse_kaslr_mem(str, &start, &size); > + if (rc < 0) > + break; > + str = k; > + > + mem_usable[i].start = start; > + mem_usable[i].size = size; > + i++; > + } > + num_usable_region = i; > +} > + > +static int handle_mem_filter(void) > { > char *args = (char *)get_cmd_line_ptr(); > size_t len = strlen((char *)args); > @@ -214,7 +278,8 @@ static int handle_mem_memmap(void) > char *param, *val; > u64 mem_size; > > - if (!strstr(args, "memmap=") && !strstr(args, "mem=")) > + if (!strstr(args, "memmap=") && !strstr(args, "mem=") && > + !strstr(args, "kaslr_mem=")) > return 0; > > tmp_cmdline = malloc(len + 1); > @@ -239,6 +304,8 @@ static int handle_mem_memmap(void) > > if (!strcmp(param, "memmap")) { > mem_avoid_memmap(val); > + } else if (!strcmp(param, "kaslr_mem")) { > + parse_kaslr_mem_regions(val); > } else if (!strcmp(param, "mem")) { > char *p = val; > > @@ -378,7 +445,7 @@ static void mem_avoid_init(unsigned long input, unsigned long input_size, > /* We don't need to set a mapping for setup_data. */ > > /* Mark the memmap regions we need to avoid */ > - handle_mem_memmap(); > + handle_mem_filter(); > > #ifdef CONFIG_X86_VERBOSE_BOOTUP > /* Make sure video RAM can be used. */ > -- > 2.14.3 > > >
| |