Re: [PATCH 2/4] kaslr: select the memory region in immovable node to process

From: Dou Liyang
Date: Fri Oct 20 2017 - 02:05:36 EST


Hi Chao,

At 10/20/2017 11:41 AM, Chao Fan wrote:
On Fri, Oct 20, 2017 at 11:17:26AM +0800, Dou Liyang wrote:
Hi Chao

Hi Dou-san,

At 10/19/2017 06:02 PM, Chao Fan wrote:
Since the interrelationship between e820 or efi entries and memory
region in immovable_mem is different:
One memory region in one node may contain several entries of e820 or
efi sometimes, and one entry of e820 or efi may contain the memory in
different nodes sometimes. So select the intersection as a region to
process_mem_region. It may split one node or one entry to several regions.

Signed-off-by: Chao Fan <fanc.fnst@xxxxxxxxxxxxxx>
---
arch/x86/boot/compressed/kaslr.c | 72 ++++++++++++++++++++++++++++++++--------
1 file changed, 58 insertions(+), 14 deletions(-)

diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c
index 3c1f5204693b..22330cbe8515 100644
--- a/arch/x86/boot/compressed/kaslr.c
+++ b/arch/x86/boot/compressed/kaslr.c
@@ -563,6 +563,7 @@ static void process_mem_region(struct mem_vector *entry,
end = min(entry->size + entry->start, mem_limit);
if (entry->start >= end)
return;
+
cur_entry.start = entry->start;
cur_entry.size = end - entry->start;

Above code has nothing to do with this patch. remove it.


@@ -621,6 +622,52 @@ static void process_mem_region(struct mem_vector *entry,
}
}

+static bool select_immovable_node(unsigned long long start,
+ unsigned long long size,
+ unsigned long long minimum,
+ unsigned long long image_size)
+{
+ struct mem_vector region;
+ int i;
+
+ if (num_immovable_region == 0) {

Seems it more better:

#ifdef CONFIG_MEMORY_HOTPLUG
for (i = 0; i < num_immovable_region; i++) {
...
}
#else
...
process_mem_region(&region, minimum, image_size);
...
#endif

No, if we set CONFIG_MEMORY_HOTPLUG=y(the default is y in fedora), but we do not
use movable_node, we should go to process_mem_region straight, right?

Yes, Indeed, you are right! ;-).

But in your change, we still go to the for(...), even if
num_immovable_region == 0.
So if num_immovable_region is 0, it includes the situation of
CONFIG_MEMORY_HOTPLUG=n


+ region.start = start;
+ region.size = size;
+ process_mem_region(&region, minimum, image_size);
+
+ if (slot_area_index == MAX_SLOT_AREA) {
+ debug_putstr("Aborted memmap scan (slot_areas full)!\n");
+ return 1;
+ }
+ } else {
+ for (i = 0; i < num_immovable_region; i++) {
+ unsigned long long end, select_end;
+ unsigned long long region_start, region_end;
+
+ end = start + size - 1;
+ region_start = immovable_mem[i].start;
+ region_end = region_start + immovable_mem[i].size - 1;
+
+ if (end < region_start || start > region_end)
+ continue;
+
+ region.start = start > region_start ?
+ start : region_start;
+ select_end = end > region_end ? region_end : end;
+
+ region.size = select_end - region.start + 1;
+
+ process_mem_region(&region, minimum, image_size);
+
+ if (slot_area_index == MAX_SLOT_AREA) {
+ debug_putstr("Aborted memmap scan (slot_areas full)!\n");
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
#ifdef CONFIG_EFI
/*
* Returns true if mirror region found (and must have been processed
@@ -631,7 +678,6 @@ process_efi_entries(unsigned long minimum, unsigned long image_size)
{
struct efi_info *e = &boot_params->efi_info;
bool efi_mirror_found = false;
- struct mem_vector region;
efi_memory_desc_t *md;
unsigned long pmap;
char *signature;
@@ -664,6 +710,8 @@ process_efi_entries(unsigned long minimum, unsigned long image_size)
}

for (i = 0; i < nr_desc; i++) {
+ unsigned long long start, size;
+
md = efi_early_memdesc_ptr(pmap, e->efi_memdesc_size, i);

/*
@@ -684,13 +732,11 @@ process_efi_entries(unsigned long minimum, unsigned long image_size)
!(md->attribute & EFI_MEMORY_MORE_RELIABLE))
continue;

- region.start = md->phys_addr;
- region.size = md->num_pages << EFI_PAGE_SHIFT;
- process_mem_region(&region, minimum, image_size);
- if (slot_area_index == MAX_SLOT_AREA) {
- debug_putstr("Aborted EFI scan (slot_areas full)!\n");
+ start = md->phys_addr;
+ size = md->num_pages << EFI_PAGE_SHIFT;
+
+ if (select_immovable_node(start, size, minimum, image_size))

Why you replace the region with two parameters? Just use region.


You can see the commit message, we may splite one entry to more regions,
so there will be region.start compared with memory region in
immovable_mem and then fill more new regions if we use region here.
The code will look strange.

Start and size will be more clear.

OK, Understood!

Thanks,
dou.