All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH v2 0/4] x86/boot/KASLR: Parse ACPI table and limit kaslr in immovable memory.
@ 2018-07-16  8:55 Chao Fan
  2018-07-16  8:55 ` [RFC PATCH v2 1/4] x86/boot: Add acpitb.h to help parse acpi tables Chao Fan
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Chao Fan @ 2018-07-16  8:55 UTC (permalink / raw)
  To: linux-kernel, x86, hpa, tglx, mingo, bhe, keescook, yasu.isimatu
  Cc: indou.takao, lcapitulino, caoj.fnst, douly.fnst, Chao Fan

***Background:
People reported that kaslr may randomly chooses some positions
which are located in movable memory regions. This will break memory
hotplug feature and make the memory can't be removed.

***Solutions:
There should be a method to limit kaslr to choosing immovable memory
regions, so there are 2 solutions:
1) Add a kernel parameter to specify the memory regions.
2) Get the information of memory hotremove, then kaslr will know the
   right regions.
In method 2, information about memory hot remove is in ACPI
tables, which will be parsed after 'start_kernel', kaslr can't get
the information.
In method 1, users should know the regions address and specify in
kernel parameter.

In the earliest time, I tried to dig ACPI tabls to solve this problem.
But I didn't splite the code in 'compressed/' and ACPI code, so the patch
is hard to follow so refused by community.
Somebody suggest to add a kernel parameter to specify the
immovable memory so that limit kaslr in these regions. Then I make
a patchset. After several versions, Ingo gave a suggestion:
https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1634024.html
Follow Ingo's suggestion, imitate the ACPI code to parse the acpi
tables, so that the kaslr can get necessary memory information in
ACPI tables.
Since I think ACPI code is independent part, so copy the codes
and functions to 'compressed/' directory, so that kaslr won't
influence the initialization of ACPI.

PATCH 1/4 Reuse the head file of linux/acpi.h, and copy a fcuntion from
          ACPI code.
PATCH 2/4 Functions to parse ACPI code.
PATCH 3/4 If 'CONFIG_MEMORY_HOTREMOVE' specified, walk all nodes and
          store the information of immovable memory regions.
PATCH 4/4 According to the immovable memory regions, filter the
          immovable regions which KASLR can choose.

***Test results:
 - I did a very simple test, and it can get the memory information in
   bios and efi KVM guest machine, and put it by early printk. But no
   more tests, so it's with RFC tag.

v1->v2:
 -  Simplify some code.
Follow Baoquan He's suggestion:
 - Reuse the head file of acpi code.

Any comments will be welcome.


Chao Fan (4):
  x86/boot: Add acpitb.h to help parse acpi tables
  x86/boot: Add acpitb.c to parse acpi tables
  x86/boot/KASLR: Walk srat tables to filter immovable memory
  x86/boot/KASLR: Limit kaslr to choosing the immovable memory

 arch/x86/boot/compressed/Makefile |   4 +
 arch/x86/boot/compressed/acpitb.c | 242 ++++++++++++++++++++++++++++++
 arch/x86/boot/compressed/acpitb.h |  49 ++++++
 arch/x86/boot/compressed/kaslr.c  | 120 +++++++++++++--
 4 files changed, 404 insertions(+), 11 deletions(-)
 create mode 100644 arch/x86/boot/compressed/acpitb.c
 create mode 100644 arch/x86/boot/compressed/acpitb.h

-- 
2.17.1




^ permalink raw reply	[flat|nested] 7+ messages in thread

* [RFC PATCH v2 1/4] x86/boot: Add acpitb.h to help parse acpi tables
  2018-07-16  8:55 [RFC PATCH v2 0/4] x86/boot/KASLR: Parse ACPI table and limit kaslr in immovable memory Chao Fan
@ 2018-07-16  8:55 ` Chao Fan
  2018-07-16  8:55 ` [RFC PATCH v2 2/4] x86/boot: Add acpitb.c to " Chao Fan
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 7+ messages in thread
From: Chao Fan @ 2018-07-16  8:55 UTC (permalink / raw)
  To: linux-kernel, x86, hpa, tglx, mingo, bhe, keescook, yasu.isimatu
  Cc: indou.takao, lcapitulino, caoj.fnst, douly.fnst, Chao Fan

In order to parse ACPI tables, reuse the head file linux/acpi.h,
so that the files in 'compressed' directory can read ACPI table
by including this head file.

Signed-off-by: Chao Fan <fanc.fnst@cn.fujitsu.com>
---
 arch/x86/boot/compressed/acpitb.h | 49 +++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)
 create mode 100644 arch/x86/boot/compressed/acpitb.h

diff --git a/arch/x86/boot/compressed/acpitb.h b/arch/x86/boot/compressed/acpitb.h
new file mode 100644
index 000000000000..b51dedb7c46f
--- /dev/null
+++ b/arch/x86/boot/compressed/acpitb.h
@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <linux/acpi.h>
+
+#define ACPI_MAX_TABLES                128
+
+struct acpi_table_header *get_acpi_srat_table(void);
+
+#ifdef ACPI_BIG_ENDIAN
+
+#define ACPI_MOVE_64_TO_64(d, s) \
+{((u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[7]; \
+((u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[6]; \
+((u8 *)(void *)(d))[2] = ((u8 *)(void *)(s))[5]; \
+((u8 *)(void *)(d))[3] = ((u8 *)(void *)(s))[4]; \
+((u8 *)(void *)(d))[4] = ((u8 *)(void *)(s))[3]; \
+((u8 *)(void *)(d))[5] = ((u8 *)(void *)(s))[2]; \
+((u8 *)(void *)(d))[6] = ((u8 *)(void *)(s))[1]; \
+((u8 *)(void *)(d))[7] = ((u8 *)(void *)(s))[0]; }
+
+#define ACPI_MOVE_16_TO_32(d, s) \
+{(*(u32 *)(void *)(d)) = 0; \
+((u8 *)(void *)(d))[2] = ((u8 *)(void *)(s))[1]; \
+((u8 *)(void *)(d))[3] = ((u8 *)(void *)(s))[0]; }
+
+#else
+#ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED
+
+#define ACPI_MOVE_64_TO_64(d, s) \
+{*(u64 *)(void *)(d) = *(u64 *)(void *)(s); }
+
+#define ACPI_MOVE_16_TO_32(d, s) \
+{*(u32 *)(void *)(d) = *(u16 *)(void *)(s); }
+
+#else
+#define ACPI_MOVE_64_TO_64(d, s) \
+{((u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[0]; \
+((u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[1]; \
+((u8 *)(void *)(d))[2] = ((u8 *)(void *)(s))[2]; \
+((u8 *)(void *)(d))[3] = ((u8 *)(void *)(s))[3]; \
+((u8 *)(void *)(d))[4] = ((u8 *)(void *)(s))[4]; \
+((u8 *)(void *)(d))[5] = ((u8 *)(void *)(s))[5]; \
+((u8 *)(void *)(d))[6] = ((u8 *)(void *)(s))[6]; \
+((u8 *)(void *)(d))[7] = ((u8 *)(void *)(s))[7]; }
+
+#define ACPI_MOVE_16_TO_32(d, s) \
+{(*(u32 *)(void *)(d)) = 0; ACPI_MOVE_16_TO_16(d, s); }
+
+#endif
+#endif
-- 
2.17.1




^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [RFC PATCH v2 2/4] x86/boot: Add acpitb.c to parse acpi tables
  2018-07-16  8:55 [RFC PATCH v2 0/4] x86/boot/KASLR: Parse ACPI table and limit kaslr in immovable memory Chao Fan
  2018-07-16  8:55 ` [RFC PATCH v2 1/4] x86/boot: Add acpitb.h to help parse acpi tables Chao Fan
@ 2018-07-16  8:55 ` Chao Fan
  2018-07-16  8:55 ` [RFC PATCH v2 3/4] x86/boot/KASLR: Walk srat tables to filter immovable memory Chao Fan
  2018-07-16  8:55 ` [RFC PATCH v2 4/4] x86/boot/KASLR: Limit kaslr to choosing the " Chao Fan
  3 siblings, 0 replies; 7+ messages in thread
From: Chao Fan @ 2018-07-16  8:55 UTC (permalink / raw)
  To: linux-kernel, x86, hpa, tglx, mingo, bhe, keescook, yasu.isimatu
  Cc: indou.takao, lcapitulino, caoj.fnst, douly.fnst, Chao Fan

Imitate the ACPI code to parse ACPI tables. Functions are simplified
cause some operations are not needed here.
And also, this method won't influence the initialization of ACPI.

Signed-off-by: Chao Fan <fanc.fnst@cn.fujitsu.com>
---
 arch/x86/boot/compressed/Makefile |   4 +
 arch/x86/boot/compressed/acpitb.c | 242 ++++++++++++++++++++++++++++++
 2 files changed, 246 insertions(+)
 create mode 100644 arch/x86/boot/compressed/acpitb.c

diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
index fa42f895fdde..41017dc98b61 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -83,6 +83,10 @@ ifdef CONFIG_X86_64
 	vmlinux-objs-y += $(obj)/pgtable_64.o
 endif
 
+ifdef CONFIG_MEMORY_HOTREMOVE
+vmlinux-objs-$(CONFIG_RANDOMIZE_BASE) += $(obj)/acpitb.o
+endif
+
 $(obj)/eboot.o: KBUILD_CFLAGS += -fshort-wchar -mno-red-zone
 
 vmlinux-objs-$(CONFIG_EFI_STUB) += $(obj)/eboot.o $(obj)/efi_stub_$(BITS).o \
diff --git a/arch/x86/boot/compressed/acpitb.c b/arch/x86/boot/compressed/acpitb.c
new file mode 100644
index 000000000000..e6eaaa6b0b22
--- /dev/null
+++ b/arch/x86/boot/compressed/acpitb.c
@@ -0,0 +1,242 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#define BOOT_CTYPE_H
+#include "misc.h"
+#include "acpitb.h"
+
+#include <linux/efi.h>
+#include <asm/efi.h>
+#include <linux/numa.h>
+
+extern unsigned long get_cmd_line_ptr(void);
+
+/* Search from efi table for rsdp table. */
+static bool efi_get_rsdp_addr(acpi_physical_address *rsdp_addr)
+{
+	efi_system_table_t *systab;
+	bool find_rsdp = false;
+	bool acpi_20 = false;
+	bool efi_64 = false;
+	void *config_tables;
+	struct efi_info *e;
+	char *sig;
+	int size;
+	int i;
+
+#ifndef CONFIG_EFI
+	return false;
+#endif
+
+	e = &boot_params->efi_info;
+	sig = (char *)&e->efi_loader_signature;
+
+	if (!strncmp(sig, EFI64_LOADER_SIGNATURE, 4))
+		efi_64 = true;
+	else if (!strncmp(sig, EFI32_LOADER_SIGNATURE, 4))
+		efi_64 = false;
+	else {
+		debug_putstr("Wrong efi loader signature.\n");
+		return false;
+	}
+
+	/* Get systab from boot params. */
+#ifdef CONFIG_X86_32
+	if (e->efi_systab_hi || e->efi_memmap_hi) {
+		debug_putstr("Table located above 4GB, disabling EFI.\n");
+		return false;
+	}
+	systab = (efi_system_table_t *)e->efi_systab;
+#else
+	systab = (efi_system_table_t *)(
+			e->efi_systab | ((__u64)e->efi_systab_hi<<32));
+#endif
+
+	if (systab == NULL)
+		return false;
+
+	/* Get efi tables from systab. */
+	size = efi_64 ? sizeof(efi_config_table_64_t) :
+			sizeof(efi_config_table_32_t);
+
+	for (i = 0; i < systab->nr_tables; i++) {
+		efi_guid_t guid;
+		unsigned long table;
+
+		config_tables = (void *)(systab->tables + size * i);
+		if (efi_64) {
+			efi_config_table_64_t *tmp_table;
+
+			tmp_table = (efi_config_table_64_t *)config_tables;
+			guid = tmp_table->guid;
+			table = tmp_table->table;
+#ifndef CONFIG_64BIT
+			if (table >> 32) {
+				debug_putstr("Table located above 4G, disabling EFI.\n");
+				return false;
+			}
+#endif
+		} else {
+			efi_config_table_32_t *tmp_table;
+
+			tmp_table = (efi_config_table_32_t *)config_tables;
+			guid = tmp_table->guid;
+			table = tmp_table->table;
+		}
+
+		/* Get rsdp from efi tables. */
+		if (!(efi_guidcmp(guid, ACPI_TABLE_GUID)) && !acpi_20) {
+			*rsdp_addr = (acpi_physical_address)table;
+			acpi_20 = false;
+			find_rsdp = true;
+		} else if (!(efi_guidcmp(guid, ACPI_20_TABLE_GUID))) {
+			*rsdp_addr = (acpi_physical_address)table;
+			acpi_20 = true;
+			return true;
+		}
+	}
+	return find_rsdp;
+}
+
+static u8 checksum(u8 *buffer, u32 length)
+{
+	u8 sum = 0;
+	u8 *end = buffer + length;
+
+	while (buffer < end)
+		sum = (u8)(sum + *(buffer++));
+
+	return sum;
+}
+
+static u8 *scan_memory_for_rsdp(u8 *start_address, u32 length)
+{
+	struct acpi_table_rsdp *rsdp;
+	u8 *end_address;
+	u8 *mem_rover;
+
+	end_address = start_address + length;
+
+	for (mem_rover = start_address; mem_rover < end_address;
+	     mem_rover += ACPI_RSDP_SCAN_STEP) {
+		rsdp = (struct acpi_table_rsdp *)mem_rover;
+		if (!ACPI_VALIDATE_RSDP_SIG(rsdp->signature))
+			continue;
+		if (checksum((u8 *) rsdp,
+		    ACPI_RSDP_CHECKSUM_LENGTH) != 0)
+			continue;
+		if ((rsdp->revision >= 2) && (checksum((u8 *)
+		    rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0))
+			continue;
+		return mem_rover;
+	}
+	return NULL;
+}
+
+static void bios_get_rsdp_addr(acpi_physical_address *rsdp_addr)
+{
+	struct acpi_table_rsdp *rsdp;
+	u32 physical_address;
+	u8 *table_ptr;
+	u8 *mem_rover;
+
+	table_ptr = (u8 *)ACPI_EBDA_PTR_LOCATION;
+	ACPI_MOVE_16_TO_32(&physical_address, table_ptr);
+	physical_address <<= 4;
+	table_ptr = (u8 *)(acpi_physical_address)physical_address;
+
+	if (physical_address > 0x400) {
+		mem_rover = scan_memory_for_rsdp(table_ptr,
+						 ACPI_EBDA_WINDOW_SIZE);
+
+		if (mem_rover) {
+			physical_address += (u32)ACPI_PTR_DIFF(mem_rover,
+							       table_ptr);
+			*rsdp_addr = (acpi_physical_address)physical_address;
+			return;
+		}
+	}
+
+	table_ptr = (u8 *)ACPI_HI_RSDP_WINDOW_BASE;
+	mem_rover = scan_memory_for_rsdp(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE);
+
+	if (mem_rover) {
+		physical_address = (u32)(ACPI_HI_RSDP_WINDOW_BASE +
+					 ACPI_PTR_DIFF(mem_rover, table_ptr));
+		*rsdp_addr = (acpi_physical_address)physical_address;
+		return;
+	}
+}
+
+/*
+ * Used to dig rsdp table from efi table or bios.
+ * If rsdp table found in efi table, use it. Or search bios.
+ */
+static acpi_physical_address get_rsdp_addr(void)
+{
+	acpi_physical_address pa = 0;
+	bool status = false;
+
+	status = efi_get_rsdp_addr(&pa);
+
+	if (!status || pa == 0)
+		bios_get_rsdp_addr(&pa);
+
+	return pa;
+}
+
+struct acpi_table_header *get_acpi_srat_table(void)
+{
+	char *args = (char *)get_cmd_line_ptr();
+	acpi_physical_address acpi_table;
+	acpi_physical_address root_table;
+	struct acpi_table_header *header;
+	struct acpi_table_rsdp *rsdp;
+	char *signature;
+	u32 size;
+	u8 *entry;
+	u32 count;
+	int i, j;
+	u32 len;
+
+	rsdp = (struct acpi_table_rsdp *)get_rsdp_addr();
+	if (!rsdp)
+		return NULL;
+
+	/* Get rsdt or xsdt from rsdp. */
+	if (!strstr(args, "acpi=rsdt") &&
+	    rsdp->xsdt_physical_address &&
+	    rsdp->revision > 1) {
+		root_table = rsdp->xsdt_physical_address;
+		size = ACPI_XSDT_ENTRY_SIZE;
+	} else {
+		root_table = rsdp->rsdt_physical_address;
+		size = ACPI_RSDT_ENTRY_SIZE;
+	}
+
+	/* Get acpi root table from rsdt or xsdt.*/
+	header = (struct acpi_table_header *)root_table;
+	len = header->length;
+	count = (u32)((len - sizeof(struct acpi_table_header)) / size);
+	entry = ACPI_ADD_PTR(u8, header, sizeof(struct acpi_table_header));
+
+	for (i = 0; i < count; i++) {
+		u64 address64;
+
+		if (size == ACPI_RSDT_ENTRY_SIZE)
+			acpi_table = ((acpi_physical_address)
+				      (*ACPI_CAST_PTR(u32, entry)));
+		else {
+			ACPI_MOVE_64_TO_64(&address64, entry);
+			acpi_table = (acpi_physical_address) address64;
+		}
+
+		if (acpi_table) {
+			header = (struct acpi_table_header *)acpi_table;
+			signature = header->signature;
+
+			if (!strncmp(signature, "SRAT", 4))
+				return header;
+		}
+		entry += size;
+	}
+	return NULL;
+}
-- 
2.17.1




^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [RFC PATCH v2 3/4] x86/boot/KASLR: Walk srat tables to filter immovable memory
  2018-07-16  8:55 [RFC PATCH v2 0/4] x86/boot/KASLR: Parse ACPI table and limit kaslr in immovable memory Chao Fan
  2018-07-16  8:55 ` [RFC PATCH v2 1/4] x86/boot: Add acpitb.h to help parse acpi tables Chao Fan
  2018-07-16  8:55 ` [RFC PATCH v2 2/4] x86/boot: Add acpitb.c to " Chao Fan
@ 2018-07-16  8:55 ` Chao Fan
  2018-07-16 11:44   ` Ingo Molnar
  2018-07-16  8:55 ` [RFC PATCH v2 4/4] x86/boot/KASLR: Limit kaslr to choosing the " Chao Fan
  3 siblings, 1 reply; 7+ messages in thread
From: Chao Fan @ 2018-07-16  8:55 UTC (permalink / raw)
  To: linux-kernel, x86, hpa, tglx, mingo, bhe, keescook, yasu.isimatu
  Cc: indou.takao, lcapitulino, caoj.fnst, douly.fnst, Chao Fan

If 'CONFIG_MEMORY_HOTREMOVE' specified, walk the acpi srat memory
tables, store the immovable memory regions, so that kaslr can get
the information abouth where can be selected or not.
If 'CONFIG_MEMORY_HOTREMOVE' not specified, go on the old code.

Signed-off-by: Chao Fan <fanc.fnst@cn.fujitsu.com>
---
 arch/x86/boot/compressed/kaslr.c | 55 ++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c
index 531c9876f573..0ec5aab915db 100644
--- a/arch/x86/boot/compressed/kaslr.c
+++ b/arch/x86/boot/compressed/kaslr.c
@@ -31,6 +31,7 @@
 
 #include "misc.h"
 #include "error.h"
+#include "acpitb.h"
 #include "../string.h"
 
 #include <generated/compile.h>
@@ -104,6 +105,14 @@ static bool memmap_too_large;
 /* Store memory limit specified by "mem=nn[KMG]" or "memmap=nn[KMG]" */
 unsigned long long mem_limit = ULLONG_MAX;
 
+#ifdef CONFIG_MEMORY_HOTREMOVE
+/* Store the movable memory */
+struct mem_vector immovable_mem[MAX_NUMNODES*2];
+
+/* Store the num of movable mem regions */
+static int num_immovable_mem;
+#endif
+
 
 enum mem_avoid_index {
 	MEM_AVOID_ZO_RANGE = 0,
@@ -298,6 +307,47 @@ static int handle_mem_options(void)
 	return 0;
 }
 
+#ifdef CONFIG_MEMORY_HOTREMOVE
+/*
+ * According to ACPI table, filter the immvoable memory regions
+ * and store them in immovable_mem[].
+ */
+static void handle_movable_mem(void)
+{
+	struct acpi_table_header *table_header;
+	struct acpi_subtable_header *table;
+	struct acpi_srat_mem_affinity *ma;
+	unsigned long table_size;
+	unsigned long table_end;
+	int i = 0;
+
+	table_header = get_acpi_srat_table();
+
+	if (!table_header)
+		return;
+
+	table_end = (unsigned long)table_header + table_header->length;
+
+	table = (struct acpi_subtable_header *)
+		((unsigned long)table_header + sizeof(struct acpi_table_srat));
+
+	table_size = sizeof(struct acpi_subtable_header);
+	while (((unsigned long)table) + table->length < table_end) {
+		if (table->type == 1) {
+			ma = (struct acpi_srat_mem_affinity *)table;
+			if (!(ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)) {
+				immovable_mem[i].start = ma->base_address;
+				immovable_mem[i].size = ma->length;
+				i++;
+			}
+		}
+		table = (struct acpi_subtable_header *)
+			((unsigned long)table + table->length);
+	}
+	num_immovable_mem = i;
+}
+#endif
+
 /*
  * In theory, KASLR can put the kernel anywhere in the range of [16M, 64T).
  * The mem_avoid array is used to store the ranges that need to be avoided
@@ -421,6 +471,11 @@ static void mem_avoid_init(unsigned long input, unsigned long input_size,
 	/* Mark the memmap regions we need to avoid */
 	handle_mem_options();
 
+#ifdef CONFIG_MEMORY_HOTREMOVE
+	/* Mark the hotplug SB regions we need choose */
+	handle_movable_mem();
+#endif
+
 #ifdef CONFIG_X86_VERBOSE_BOOTUP
 	/* Make sure video RAM can be used. */
 	add_identity_map(0, PMD_SIZE);
-- 
2.17.1




^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [RFC PATCH v2 4/4] x86/boot/KASLR: Limit kaslr to choosing the immovable memory
  2018-07-16  8:55 [RFC PATCH v2 0/4] x86/boot/KASLR: Parse ACPI table and limit kaslr in immovable memory Chao Fan
                   ` (2 preceding siblings ...)
  2018-07-16  8:55 ` [RFC PATCH v2 3/4] x86/boot/KASLR: Walk srat tables to filter immovable memory Chao Fan
@ 2018-07-16  8:55 ` Chao Fan
  3 siblings, 0 replies; 7+ messages in thread
From: Chao Fan @ 2018-07-16  8:55 UTC (permalink / raw)
  To: linux-kernel, x86, hpa, tglx, mingo, bhe, keescook, yasu.isimatu
  Cc: indou.takao, lcapitulino, caoj.fnst, douly.fnst, Chao Fan

If 'CONFIG_MEMORY_HOTREMOVE' specified and the account of immovable
memory regions is not zero. Calculate the intersection between memory
regions from e820/efi memory table and immovable memory regions.
Or go on the old code.

Rename process_mem_region to slots_count to match slots_fetch_random,
and name new function as process_mem_region.

Signed-off-by: Chao Fan <fanc.fnst@cn.fujitsu.com>
---
 arch/x86/boot/compressed/kaslr.c | 65 ++++++++++++++++++++++++++------
 1 file changed, 54 insertions(+), 11 deletions(-)

diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c
index 0ec5aab915db..f9e316e30936 100644
--- a/arch/x86/boot/compressed/kaslr.c
+++ b/arch/x86/boot/compressed/kaslr.c
@@ -631,9 +631,9 @@ static unsigned long slots_fetch_random(void)
 	return 0;
 }
 
-static void process_mem_region(struct mem_vector *entry,
-			       unsigned long minimum,
-			       unsigned long image_size)
+static void slots_count(struct mem_vector *entry,
+			unsigned long minimum,
+			unsigned long image_size)
 {
 	struct mem_vector region, overlap;
 	struct slot_area slot_area;
@@ -710,6 +710,55 @@ static void process_mem_region(struct mem_vector *entry,
 	}
 }
 
+static bool process_mem_region(struct mem_vector *region,
+			       unsigned long long minimum,
+			       unsigned long long image_size)
+{
+#ifdef CONFIG_MEMORY_HOTREMOVE
+	/*
+	 * If hotplug memory found, filter the intersection between
+	 * immovable memory and region to slots_count.
+	 */
+	if (num_immovable_mem > 0) {
+		int i;
+
+		for (i = 0; i < num_immovable_mem; i++) {
+			struct mem_vector entry;
+			unsigned long long start, end, entry_end, region_end;
+
+			start = immovable_mem[i].start;
+			end = start + immovable_mem[i].size;
+			region_end = region->start + region->size;
+
+			entry.start = clamp(region->start, start, end);
+			entry_end = clamp(region_end, start, end);
+
+			if (entry.start + image_size < entry_end) {
+				entry.size = entry_end - entry.start;
+				slots_count(&entry, minimum, image_size);
+
+				if (slot_area_index == MAX_SLOT_AREA) {
+					debug_putstr("Aborted e820/efi memmap scan (slot_areas full)!\n");
+					return 1;
+				}
+			}
+		}
+		return 0;
+	}
+#endif
+	/*
+	 * If no hotplug memory found, walk all the regions,
+	 * so use region directely.
+	 */
+	slots_count(region, minimum, image_size);
+
+	if (slot_area_index == MAX_SLOT_AREA) {
+		debug_putstr("Aborted e820/efi memmap scan (slot_areas full)!\n");
+		return 1;
+	}
+	return 0;
+}
+
 #ifdef CONFIG_EFI
 /*
  * Returns true if mirror region found (and must have been processed
@@ -775,11 +824,8 @@ process_efi_entries(unsigned long minimum, unsigned long image_size)
 
 		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");
+		if (process_mem_region(&region, minimum, image_size))
 			break;
-		}
 	}
 	return true;
 }
@@ -806,11 +852,8 @@ static void process_e820_entries(unsigned long minimum,
 			continue;
 		region.start = entry->addr;
 		region.size = entry->size;
-		process_mem_region(&region, minimum, image_size);
-		if (slot_area_index == MAX_SLOT_AREA) {
-			debug_putstr("Aborted e820 scan (slot_areas full)!\n");
+		if (process_mem_region(&region, minimum, image_size))
 			break;
-		}
 	}
 }
 
-- 
2.17.1




^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [RFC PATCH v2 3/4] x86/boot/KASLR: Walk srat tables to filter immovable memory
  2018-07-16  8:55 ` [RFC PATCH v2 3/4] x86/boot/KASLR: Walk srat tables to filter immovable memory Chao Fan
@ 2018-07-16 11:44   ` Ingo Molnar
  2018-07-17  1:01     ` Chao Fan
  0 siblings, 1 reply; 7+ messages in thread
From: Ingo Molnar @ 2018-07-16 11:44 UTC (permalink / raw)
  To: Chao Fan
  Cc: linux-kernel, x86, hpa, tglx, mingo, bhe, keescook, yasu.isimatu,
	indou.takao, lcapitulino, caoj.fnst, douly.fnst


* Chao Fan <fanc.fnst@cn.fujitsu.com> wrote:

> If 'CONFIG_MEMORY_HOTREMOVE' specified, walk the acpi srat memory
> tables, store the immovable memory regions, so that kaslr can get
> the information abouth where can be selected or not.
> If 'CONFIG_MEMORY_HOTREMOVE' not specified, go on the old code.
> 
> Signed-off-by: Chao Fan <fanc.fnst@cn.fujitsu.com>
> ---
>  arch/x86/boot/compressed/kaslr.c | 55 ++++++++++++++++++++++++++++++++
>  1 file changed, 55 insertions(+)
> 
> diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c
> index 531c9876f573..0ec5aab915db 100644
> --- a/arch/x86/boot/compressed/kaslr.c
> +++ b/arch/x86/boot/compressed/kaslr.c
> @@ -31,6 +31,7 @@
>  
>  #include "misc.h"
>  #include "error.h"
> +#include "acpitb.h"
>  #include "../string.h"
>  
>  #include <generated/compile.h>
> @@ -104,6 +105,14 @@ static bool memmap_too_large;
>  /* Store memory limit specified by "mem=nn[KMG]" or "memmap=nn[KMG]" */
>  unsigned long long mem_limit = ULLONG_MAX;
>  
> +#ifdef CONFIG_MEMORY_HOTREMOVE
> +/* Store the movable memory */
> +struct mem_vector immovable_mem[MAX_NUMNODES*2];
> +
> +/* Store the num of movable mem regions */
> +static int num_immovable_mem;
> +#endif

So comment says 'movable', but variables are named 'immovable'??

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC PATCH v2 3/4] x86/boot/KASLR: Walk srat tables to filter immovable memory
  2018-07-16 11:44   ` Ingo Molnar
@ 2018-07-17  1:01     ` Chao Fan
  0 siblings, 0 replies; 7+ messages in thread
From: Chao Fan @ 2018-07-17  1:01 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, x86, hpa, tglx, mingo, bhe, keescook, yasu.isimatu,
	indou.takao, lcapitulino, caoj.fnst, douly.fnst

On Mon, Jul 16, 2018 at 01:44:47PM +0200, Ingo Molnar wrote:
>
>* Chao Fan <fanc.fnst@cn.fujitsu.com> wrote:
>
>> If 'CONFIG_MEMORY_HOTREMOVE' specified, walk the acpi srat memory
>> tables, store the immovable memory regions, so that kaslr can get
>> the information abouth where can be selected or not.
>> If 'CONFIG_MEMORY_HOTREMOVE' not specified, go on the old code.
>> 
>> Signed-off-by: Chao Fan <fanc.fnst@cn.fujitsu.com>
>> ---
>>  arch/x86/boot/compressed/kaslr.c | 55 ++++++++++++++++++++++++++++++++
>>  1 file changed, 55 insertions(+)
>> 
>> diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c
>> index 531c9876f573..0ec5aab915db 100644
>> --- a/arch/x86/boot/compressed/kaslr.c
>> +++ b/arch/x86/boot/compressed/kaslr.c
>> @@ -31,6 +31,7 @@
>>  
>>  #include "misc.h"
>>  #include "error.h"
>> +#include "acpitb.h"
>>  #include "../string.h"
>>  
>>  #include <generated/compile.h>
>> @@ -104,6 +105,14 @@ static bool memmap_too_large;
>>  /* Store memory limit specified by "mem=nn[KMG]" or "memmap=nn[KMG]" */
>>  unsigned long long mem_limit = ULLONG_MAX;
>>  
>> +#ifdef CONFIG_MEMORY_HOTREMOVE
>> +/* Store the movable memory */
>> +struct mem_vector immovable_mem[MAX_NUMNODES*2];
>> +
>> +/* Store the num of movable mem regions */
>> +static int num_immovable_mem;
>> +#endif
>
>So comment says 'movable', but variables are named 'immovable'??

Sorry for the typo, will change it immidiately.

Thanks,
Chao Fan

>
>Thanks,
>
>	Ingo
>
>



^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2018-07-17  1:03 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-07-16  8:55 [RFC PATCH v2 0/4] x86/boot/KASLR: Parse ACPI table and limit kaslr in immovable memory Chao Fan
2018-07-16  8:55 ` [RFC PATCH v2 1/4] x86/boot: Add acpitb.h to help parse acpi tables Chao Fan
2018-07-16  8:55 ` [RFC PATCH v2 2/4] x86/boot: Add acpitb.c to " Chao Fan
2018-07-16  8:55 ` [RFC PATCH v2 3/4] x86/boot/KASLR: Walk srat tables to filter immovable memory Chao Fan
2018-07-16 11:44   ` Ingo Molnar
2018-07-17  1:01     ` Chao Fan
2018-07-16  8:55 ` [RFC PATCH v2 4/4] x86/boot/KASLR: Limit kaslr to choosing the " Chao Fan

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.