All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v16 0/7] Parse ACPI table and limit KASLR to choosing immovable memory
@ 2019-01-23 11:08 Chao Fan
  2019-01-23 11:08 ` [PATCH v16 1/7] x86/boot: Copy kstrtoull() to boot/string.c instead of simple_strtoull() Chao Fan
                   ` (7 more replies)
  0 siblings, 8 replies; 54+ messages in thread
From: Chao Fan @ 2019-01-23 11:08 UTC (permalink / raw)
  To: linux-kernel, x86, bp, tglx, mingo, hpa, keescook, bhe, msys.mizuma
  Cc: indou.takao, caoj.fnst, fanc.fnst, kasong

***Background:
People reported that KASLR may randomly choose some positions
which are located in movable memory regions. This will make the
movable memory chosen by KASLR can't be removed.

***Solutions:
Get the information of memory hot-remove, then KASLR knows the
right regions. Information about memory-hotremove is in ACPI
SRAT, which will be parsed after start_kernel(), so KASLR
can't get the information.

Someone suggested to add a kernel parameter to specify the
immovable memory then 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.
ACPI code is an independent part, so imitate the codes and functions
to 'compressed/' directory, so that KASLR won't influence the
initialization of ACPI.

PATCH 1/7 Copy kstrtoull() to boot/string.c to instead of using
          old simple_strtoull()
PATCH 2/7 Introduce get_acpi_rsdp() to parse RSDP in cmdline from KEXEC
PATCH 3/6 Introduce efi_get_rsdp_addr() to find RSDP from EFI table when
          booting from EFI.
PATCH 4/7 Introduce bios_get_rsdp_addr() to search RSDP in memory when
          booting from BIOS
PATCH 5/7 Parse RSDP and fill in boot_params->acpi_rsdp_addr before
          KASLR.
PATCH 6/7 Compute SRAT from RSDP and walk SRAT to store the immovable
          memory regions and store the immovable memory regions.
PATCH 7/7 Calculate the intersection between memory regions from e820/efi
          memory table and immovable memory regions. Limit KASLR to
          choosing these regions for randomization.

***Tests:
Test it in QEMU guest with 10 NUMA nodes, every node has 512M memory.
Use earlyprintk with debug_putaddr() to display the immovable
memory regions when KASLR walks all memory. Compare the result with
dmesg. If they are same, the parsing job works well.
Here are test cases:
 - x86_64 machine booting from EFI
 - x86_64 machine booting from BIOS
 - i386 machine booting from BIOS
 - According to '/sys/firmware/efi/systab', add 'acpi_rsdp=' to cmdline to
   imitate case for get_acpi_rsdp()
 - Add 'acpi=off' to cmdline to test the detecting for cmdline.
 - Add debug_putaddr to test the value of boot_params->acpi_rsdp_addr

v15->v16:
 - Splite the parsing of RSDP.
 - Clean ACPI_* functions as local type cast
Follow Kairui Song's suggestion:
 - Add code to parse boot_params->acpi_rsdp_addr
Follow Boris' suggetsion:
 - Drop CONFIG_EARLY_SRAT_PARSE and build acpi.o
 - Change get_acpi_srat_table() type and clean type cast.
 - Change num_immovable_mem as static variable
 - Change count_immovable_mem_regions() type to int.

v14->v15:
Follow Boris' suggestion:
 - Fix the usage of kstrtoull()
 - Add more test case
Follow Ingo's suggestion:
 - Clear the typecast
 - Change some variable name
 - If no efi systab found, use error() to halt
Follow Baoquan's suggestion:
 - Rebase from tip/master to tip/x86/boot

v13->v14:
Follow Baoquan's suggestion:
 - Use simple_strtoull() for now.
Follow Boris' suggestion:
 - Put 'return 0' out of 'ifdef' to make sure function return.
Follow Masa's suggestion:
 - Change the end of string as '\0'

v12->v13:
Follow Boris' suggestion:
 - Copy kstrtoull() to boot/string.c
Follow Masa's suggestion:
 - Change some code logical
Follow Baoquan's suggestion:
 - Add tag to disable export symbol

v11->v12:
Follow Boris' suggestion:
 - Change patch log and code comments.
 - Add 'CONFIG_EARLY_PARSE_RSDP' to make code easy to read
 - Put strtoull() to misc.c
Follow Masa's suggestion:
 - Remove the detection for 'movable_node'
 - Change the code logical about cmdline_find_option()

v10->v11:
Follow Boris' suggestion:
 - Link kstrtoull() instead of copying it.
 - Drop the useless wrapped function.

v9->v10:
Follow Baoquan's suggestion:
 - Change some log
 - Merge last two patch together.

v8-v9:
Follow Boris' suggestion:
 - Change code style.
 - Splite PATCH 1/3 to more path.
 - Introduce some new function
 - Use existing function to rework some code
Follow Masayoshi's suggetion:
 - Make code more readable

v7-v8:
Follow Kees Cook's suggestion:
 - Use mem_overlaps() to check memory region.
 - Use #ifdef in the definition of function.

v6->v7:
Follow Rafael's suggestion:
 - Add more comments and patch log.
Follow test robot's suggestion:
 - Add "static" tag for function

v5->v6:
Follow Baoquan He's suggestion:
 - Change some log.
 - Add the check for acpi_rsdp
 - Change some code logical to make code clear

v4->v5:
Follow Dou Liyang's suggestion:
 - Add more comments about some functions based on kernel code.
 - Change some typo in comments.
 - Clean useless variable.
 - Add check for the boundary of array.
 - Add check for 'movable_node' parameter

v3->v4:
Follow Thomas Gleixner's suggestion:
 - Put the whole efi related function into #define CONFIG_EFI and return
   false in the other stub.

v2->v3:
 - Test in more conditions, so remove the 'RFC' tag.
 - Change some comments.

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

Any comments will be welcome.


Chao Fan (7):
  x86/boot: Copy kstrtoull() to boot/string.c instead of
    simple_strtoull()
  x86/boot: Introduce get_acpi_rsdp() to parse RSDP in cmdline from
    KEXEC
  x86/boot: Introduce efi_get_rsdp_addr() to find RSDP from EFI table
  x86/boot: Introduce bios_get_rsdp_addr() to search RSDP in memory
  x86/boot: Early parse RSDP and fill in boot_params
  x86/boot: Parse SRAT address from RSDP and store immovable memory
  x86/boot/KASLR: Limit KASLR to extracting kernel in immovable memory

 arch/x86/boot/compressed/Makefile |   2 +
 arch/x86/boot/compressed/acpi.c   | 341 ++++++++++++++++++++++++++++++
 arch/x86/boot/compressed/kaslr.c  |  76 +++++--
 arch/x86/boot/compressed/misc.c   |   7 +
 arch/x86/boot/compressed/misc.h   |  22 ++
 arch/x86/boot/string.c            | 141 ++++++++++++
 arch/x86/boot/string.h            |   1 +
 7 files changed, 575 insertions(+), 15 deletions(-)
 create mode 100644 arch/x86/boot/compressed/acpi.c

-- 
2.20.1




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

* [PATCH v16 1/7] x86/boot: Copy kstrtoull() to boot/string.c instead of simple_strtoull()
  2019-01-23 11:08 [PATCH v16 0/7] Parse ACPI table and limit KASLR to choosing immovable memory Chao Fan
@ 2019-01-23 11:08 ` Chao Fan
  2019-02-01 10:58   ` [tip:x86/boot] x86/boot: Copy kstrtoull() to boot/string.c tip-bot for Chao Fan
  2019-01-23 11:08 ` [PATCH v16 2/7] x86/boot: Introduce get_acpi_rsdp() to parse RSDP in cmdline from KEXEC Chao Fan
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 54+ messages in thread
From: Chao Fan @ 2019-01-23 11:08 UTC (permalink / raw)
  To: linux-kernel, x86, bp, tglx, mingo, hpa, keescook, bhe, msys.mizuma
  Cc: indou.takao, caoj.fnst, fanc.fnst, kasong

Copy kstrtoull() and necessary functions from lib/kstrtox.c to
boot/string.c so that code in boot/ can use kstrtoull() and the old
simple_strtoull() can be replaced.

In boot/string.c, using div_u64() from math64.h directly will cause the
dividend handled as 64-bit value and bring ld error. The solution is to
separate the dividend to upper and lower in boot/string.o. So copy the
useful div_u64() and div_u64_rem() to boot/string.c also. To avoid
redefinition in i386, rename them as __div_u64() and __div_u64_rem().

Signed-off-by: Chao Fan <fanc.fnst@cn.fujitsu.com>
---
 arch/x86/boot/string.c | 141 +++++++++++++++++++++++++++++++++++++++++
 arch/x86/boot/string.h |   1 +
 2 files changed, 142 insertions(+)

diff --git a/arch/x86/boot/string.c b/arch/x86/boot/string.c
index c4428a176973..315a67b8896b 100644
--- a/arch/x86/boot/string.c
+++ b/arch/x86/boot/string.c
@@ -13,10 +13,14 @@
  */
 
 #include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
 #include <asm/asm.h>
 #include "ctype.h"
 #include "string.h"
 
+#define KSTRTOX_OVERFLOW       (1U << 31)
+
 /*
  * Undef these macros so that the functions that we provide
  * here will have the correct names regardless of how string.h
@@ -187,3 +191,140 @@ char *strchr(const char *s, int c)
 			return NULL;
 	return (char *)s;
 }
+
+static inline u64 __div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
+{
+	union {
+		u64 v64;
+		u32 v32[2];
+	} d = { dividend };
+	u32 upper;
+
+	upper = d.v32[1];
+	d.v32[1] = 0;
+	if (upper >= divisor) {
+		d.v32[1] = upper / divisor;
+		upper %= divisor;
+	}
+	asm ("divl %2" : "=a" (d.v32[0]), "=d" (*remainder) :
+		"rm" (divisor), "0" (d.v32[0]), "1" (upper));
+	return d.v64;
+}
+
+static inline u64 __div_u64(u64 dividend, u32 divisor)
+{
+	u32 remainder;
+
+	return __div_u64_rem(dividend, divisor, &remainder);
+}
+
+static inline char _tolower(const char c)
+{
+	return c | 0x20;
+}
+
+static const char *_parse_integer_fixup_radix(const char *s, unsigned int *base)
+{
+	if (*base == 0) {
+		if (s[0] == '0') {
+			if (_tolower(s[1]) == 'x' && isxdigit(s[2]))
+				*base = 16;
+			else
+				*base = 8;
+		} else
+			*base = 10;
+	}
+	if (*base == 16 && s[0] == '0' && _tolower(s[1]) == 'x')
+		s += 2;
+	return s;
+}
+
+/*
+ * Convert non-negative integer string representation in explicitly given radix
+ * to an integer.
+ * Return number of characters consumed maybe or-ed with overflow bit.
+ * If overflow occurs, result integer (incorrect) is still returned.
+ *
+ * Don't you dare use this function.
+ */
+static unsigned int _parse_integer(const char *s,
+				   unsigned int base,
+				   unsigned long long *p)
+{
+	unsigned long long res;
+	unsigned int rv;
+
+	res = 0;
+	rv = 0;
+	while (1) {
+		unsigned int c = *s;
+		unsigned int lc = c | 0x20; /* don't tolower() this line */
+		unsigned int val;
+
+		if ('0' <= c && c <= '9')
+			val = c - '0';
+		else if ('a' <= lc && lc <= 'f')
+			val = lc - 'a' + 10;
+		else
+			break;
+
+		if (val >= base)
+			break;
+		/*
+		 * Check for overflow only if we are within range of
+		 * it in the max base we support (16)
+		 */
+		if (unlikely(res & (~0ull << 60))) {
+			if (res > __div_u64(ULLONG_MAX - val, base))
+				rv |= KSTRTOX_OVERFLOW;
+		}
+		res = res * base + val;
+		rv++;
+		s++;
+	}
+	*p = res;
+	return rv;
+}
+
+static int _kstrtoull(const char *s, unsigned int base, unsigned long long *res)
+{
+	unsigned long long _res;
+	unsigned int rv;
+
+	s = _parse_integer_fixup_radix(s, &base);
+	rv = _parse_integer(s, base, &_res);
+	if (rv & KSTRTOX_OVERFLOW)
+		return -ERANGE;
+	if (rv == 0)
+		return -EINVAL;
+	s += rv;
+	if (*s == '\n')
+		s++;
+	if (*s)
+		return -EINVAL;
+	*res = _res;
+	return 0;
+}
+
+/**
+ * kstrtoull - convert a string to an unsigned long long
+ * @s: The start of the string. The string must be null-terminated, and may also
+ *  include a single newline before its terminating null. The first character
+ *  may also be a plus sign, but not a minus sign.
+ * @base: The number base to use. The maximum supported base is 16. If base is
+ *  given as 0, then the base of the string is automatically detected with the
+ *  conventional semantics - If it begins with 0x the number will be parsed as a
+ *  hexadecimal (case insensitive), if it otherwise begins with 0, it will be
+ *  parsed as an octal number. Otherwise it will be parsed as a decimal.
+ * @res: Where to write the result of the conversion on success.
+ *
+ * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
+ * Used as a replacement for the obsolete simple_strtoull. Return code must
+ * be checked.
+ */
+int kstrtoull(const char *s, unsigned int base, unsigned long long *res)
+{
+	if (s[0] == '+')
+		s++;
+	return _kstrtoull(s, base, res);
+}
diff --git a/arch/x86/boot/string.h b/arch/x86/boot/string.h
index 3d78e27077f4..38d8f2f5e47e 100644
--- a/arch/x86/boot/string.h
+++ b/arch/x86/boot/string.h
@@ -29,4 +29,5 @@ extern unsigned int atou(const char *s);
 extern unsigned long long simple_strtoull(const char *cp, char **endp,
 					  unsigned int base);
 
+int kstrtoull(const char *s, unsigned int base, unsigned long long *res);
 #endif /* BOOT_STRING_H */
-- 
2.20.1




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

* [PATCH v16 2/7] x86/boot: Introduce get_acpi_rsdp() to parse RSDP in cmdline from KEXEC
  2019-01-23 11:08 [PATCH v16 0/7] Parse ACPI table and limit KASLR to choosing immovable memory Chao Fan
  2019-01-23 11:08 ` [PATCH v16 1/7] x86/boot: Copy kstrtoull() to boot/string.c instead of simple_strtoull() Chao Fan
@ 2019-01-23 11:08 ` Chao Fan
  2019-02-01 10:59   ` [tip:x86/boot] x86/boot: Add "acpi_rsdp=" early parsing tip-bot for Chao Fan
  2019-01-23 11:08 ` [PATCH v16 3/7] x86/boot: Introduce efi_get_rsdp_addr() to find RSDP from EFI table Chao Fan
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 54+ messages in thread
From: Chao Fan @ 2019-01-23 11:08 UTC (permalink / raw)
  To: linux-kernel, x86, bp, tglx, mingo, hpa, keescook, bhe, msys.mizuma
  Cc: indou.takao, caoj.fnst, fanc.fnst, kasong

KASLR may randomly choose some positions which are located in movable
memory regions. This will make the movable memory chosen by KASLR
can't be removed.

Memory information in SRAT is necessary to fix the conflict between
KASLR and memory-hotremove.

ACPI SRAT (System/Static Resource Affinity Table) shows the details
about memory ranges, including ranges of memory provided by hot-added
memory devices. SRAT is introduced by Root System Description
Pointer(RSDP). So RSDP should be found firstly.

When booting form KEXEC/EFI/BIOS, the methods to find RSDP
are different. When booting from KEXEC, 'acpi_rsdp=' may have been
added to cmdline, so parse cmdline to find RSDP.

Signed-off-by: Chao Fan <fanc.fnst@cn.fujitsu.com>
---
 arch/x86/boot/compressed/acpi.c | 32 ++++++++++++++++++++++++++++++++
 arch/x86/boot/compressed/misc.h |  3 +++
 2 files changed, 35 insertions(+)
 create mode 100644 arch/x86/boot/compressed/acpi.c

diff --git a/arch/x86/boot/compressed/acpi.c b/arch/x86/boot/compressed/acpi.c
new file mode 100644
index 000000000000..bacfc4ea35ac
--- /dev/null
+++ b/arch/x86/boot/compressed/acpi.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0
+#define BOOT_CTYPE_H
+#include "misc.h"
+#include "error.h"
+#include "../string.h"
+
+#ifdef CONFIG_ACPI
+
+/*
+ * Max length of 64-bit hex address string is 19, prefix "0x" + 16 hex
+ * digits, and '\0' for termination.
+ */
+#define MAX_ADDR_LEN 19
+
+static acpi_physical_address get_acpi_rsdp(void)
+{
+	acpi_physical_address addr = 0;
+
+#ifdef CONFIG_KEXEC
+	char val[MAX_ADDR_LEN] = { };
+	int ret;
+
+	ret = cmdline_find_option("acpi_rsdp", val, MAX_ADDR_LEN);
+	if (ret < 0)
+		return 0;
+
+	if (kstrtoull(val, 16, &addr))
+		return 0;
+#endif
+	return addr;
+}
+#endif /* CONFIG_ACPI */
diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h
index a1d5918765f3..764ad50c0119 100644
--- a/arch/x86/boot/compressed/misc.h
+++ b/arch/x86/boot/compressed/misc.h
@@ -25,6 +25,9 @@
 #include <asm/bootparam.h>
 #include <asm/bootparam_utils.h>
 
+#define BOOT_CTYPE_H
+#include <linux/acpi.h>
+
 #define BOOT_BOOT_H
 #include "../ctype.h"
 
-- 
2.20.1




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

* [PATCH v16 3/7] x86/boot: Introduce efi_get_rsdp_addr() to find RSDP from EFI table
  2019-01-23 11:08 [PATCH v16 0/7] Parse ACPI table and limit KASLR to choosing immovable memory Chao Fan
  2019-01-23 11:08 ` [PATCH v16 1/7] x86/boot: Copy kstrtoull() to boot/string.c instead of simple_strtoull() Chao Fan
  2019-01-23 11:08 ` [PATCH v16 2/7] x86/boot: Introduce get_acpi_rsdp() to parse RSDP in cmdline from KEXEC Chao Fan
@ 2019-01-23 11:08 ` Chao Fan
  2019-02-01 10:59   ` [tip:x86/boot] x86/boot: Search for RSDP in the EFI tables tip-bot for Chao Fan
  2019-01-23 11:08 ` [PATCH v16 4/7] x86/boot: Introduce bios_get_rsdp_addr() to search RSDP in memory Chao Fan
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 54+ messages in thread
From: Chao Fan @ 2019-01-23 11:08 UTC (permalink / raw)
  To: linux-kernel, x86, bp, tglx, mingo, hpa, keescook, bhe, msys.mizuma
  Cc: indou.takao, caoj.fnst, fanc.fnst, kasong

Memory information in SRAT is necessary to fix the conflict between
KASLR and memory-hotremove. So RSDP and SRAT should be parsed.

When booting form KEXEC/EFI/BIOS, the methods to compute RSDP
are different. When booting from EFI, EFI table points to RSDP.
So parse the EFI table and find the RSDP.

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

diff --git a/arch/x86/boot/compressed/acpi.c b/arch/x86/boot/compressed/acpi.c
index bacfc4ea35ac..75b3ce4356f4 100644
--- a/arch/x86/boot/compressed/acpi.c
+++ b/arch/x86/boot/compressed/acpi.c
@@ -4,6 +4,9 @@
 #include "error.h"
 #include "../string.h"
 
+#include <linux/efi.h>
+#include <asm/efi.h>
+
 #ifdef CONFIG_ACPI
 
 /*
@@ -29,4 +32,83 @@ static acpi_physical_address get_acpi_rsdp(void)
 #endif
 	return addr;
 }
+
+/* Search EFI table for RSDP. */
+static acpi_physical_address efi_get_rsdp_addr(void)
+{
+	acpi_physical_address rsdp_addr = 0;
+
+#ifdef CONFIG_EFI
+	efi_system_table_t *systab;
+	struct efi_info *ei;
+	bool efi_64;
+	int size, i;
+	char *sig;
+
+	ei = &boot_params->efi_info;
+	sig = (char *)&ei->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 0;
+	}
+
+	/* Get systab from boot params. Based on efi_init(). */
+#ifdef CONFIG_X86_64
+	systab = (efi_system_table_t *)(ei->efi_systab | ((__u64)ei->efi_systab_hi<<32));
+#else
+	if (ei->efi_systab_hi || ei->efi_memmap_hi) {
+		debug_putstr("Error getting RSDP address: EFI system table located above 4GB.\n");
+		return 0;
+	}
+	systab = (efi_system_table_t *)ei->efi_systab;
+#endif
+
+	if (!systab)
+		error("EFI system table not found.");
+
+	/*
+	 * Get EFI tables from systab. Based on efi_config_init() and
+	 * efi_config_parse_tables().
+	 */
+	size = efi_64 ? sizeof(efi_config_table_64_t) :
+			sizeof(efi_config_table_32_t);
+
+	for (i = 0; i < systab->nr_tables; i++) {
+		acpi_physical_address table;
+		void *config_tables;
+		efi_guid_t guid;
+
+		config_tables = (void *)(systab->tables + size * i);
+		if (efi_64) {
+			efi_config_table_64_t *tmp_table;
+
+			tmp_table = config_tables;
+			guid = tmp_table->guid;
+			table = tmp_table->table;
+
+			if (!IS_ENABLED(CONFIG_X86_64) && table >> 32) {
+				debug_putstr("Error getting RSDP address: EFI config table located above 4GB.\n");
+				return 0;
+			}
+		} else {
+			efi_config_table_32_t *tmp_table;
+
+			tmp_table = config_tables;
+			guid = tmp_table->guid;
+			table = tmp_table->table;
+		}
+
+		if (!(efi_guidcmp(guid, ACPI_TABLE_GUID)))
+			rsdp_addr = table;
+		else if (!(efi_guidcmp(guid, ACPI_20_TABLE_GUID)))
+			return table;
+	}
+#endif
+	return rsdp_addr;
+}
 #endif /* CONFIG_ACPI */
-- 
2.20.1




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

* [PATCH v16 4/7] x86/boot: Introduce bios_get_rsdp_addr() to search RSDP in memory
  2019-01-23 11:08 [PATCH v16 0/7] Parse ACPI table and limit KASLR to choosing immovable memory Chao Fan
                   ` (2 preceding siblings ...)
  2019-01-23 11:08 ` [PATCH v16 3/7] x86/boot: Introduce efi_get_rsdp_addr() to find RSDP from EFI table Chao Fan
@ 2019-01-23 11:08 ` Chao Fan
  2019-02-01 11:00   ` [tip:x86/boot] x86/boot: Search for " tip-bot for Chao Fan
  2019-01-23 11:08 ` [PATCH v16 5/7] x86/boot: Early parse RSDP and fill in boot_params Chao Fan
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 54+ messages in thread
From: Chao Fan @ 2019-01-23 11:08 UTC (permalink / raw)
  To: linux-kernel, x86, bp, tglx, mingo, hpa, keescook, bhe, msys.mizuma
  Cc: indou.takao, caoj.fnst, fanc.fnst, kasong

Memory information in SRAT table is necessary to fix the conflict
between KASLR and memory-hotremove. So RSDP and SRAT should be parsed.

When booting form KEXEC/EFI/BIOS, the methods to compute RSDP
are different. When booting from BIOS, there is no variable who can
point to RSDP directly, so scan memory for the RSDP and verify RSDP
by signature and checksum.

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

diff --git a/arch/x86/boot/compressed/acpi.c b/arch/x86/boot/compressed/acpi.c
index 75b3ce4356f4..0c389a22bb86 100644
--- a/arch/x86/boot/compressed/acpi.c
+++ b/arch/x86/boot/compressed/acpi.c
@@ -111,4 +111,87 @@ static acpi_physical_address efi_get_rsdp_addr(void)
 #endif
 	return rsdp_addr;
 }
+
+static u8 compute_checksum(u8 *buffer, u32 length)
+{
+	u8 *end = buffer + length;
+	u8 sum = 0;
+
+	while (buffer < end)
+		sum += *(buffer++);
+
+	return sum;
+}
+
+/* Search a block of memory for the RSDP signature. */
+static u8 *scan_mem_for_rsdp(u8 *start, u32 length)
+{
+	struct acpi_table_rsdp *rsdp;
+	u8 *address, *end;
+
+	end = start + length;
+
+	/* Search from given start address for the requested length */
+	for (address = start; address < end; address += ACPI_RSDP_SCAN_STEP) {
+		/*
+		 * Both RSDP signature and checksum must be correct.
+		 * Note: Sometimes there exists more than one RSDP in memory;
+		 * the valid RSDP has a valid checksum, all others have an
+		 * invalid checksum.
+		 */
+		rsdp = (struct acpi_table_rsdp *)address;
+
+		/* BAD Signature */
+		if (!ACPI_VALIDATE_RSDP_SIG(rsdp->signature))
+			continue;
+
+		/* Check the standard checksum */
+		if (compute_checksum((u8 *)rsdp, ACPI_RSDP_CHECKSUM_LENGTH))
+			continue;
+
+		/* Check extended checksum if table version >= 2 */
+		if ((rsdp->revision >= 2) &&
+		    (compute_checksum((u8 *)rsdp, ACPI_RSDP_XCHECKSUM_LENGTH)))
+			continue;
+
+		/* Signature and checksum valid, we have found a real RSDP */
+		return address;
+	}
+	return NULL;
+}
+
+/* Search RSDP address, based on acpi_find_root_pointer(). */
+static acpi_physical_address bios_get_rsdp_addr(void)
+{
+	unsigned long address;
+	u8 *table_ptr, *rsdp;
+
+	/* Get the location of the Extended BIOS Data Area (EBDA) */
+	table_ptr = (u8 *)ACPI_EBDA_PTR_LOCATION;
+	address = *(u16 *)table_ptr;
+	address <<= 4;
+	table_ptr = (u8 *)address;
+
+	/*
+	 * Search EBDA paragraphs (EBDA is required to be a minimum of
+	 * 1K length)
+	 */
+	if (address > 0x400) {
+		rsdp = scan_mem_for_rsdp(table_ptr, ACPI_EBDA_WINDOW_SIZE);
+		if (rsdp) {
+			address = (unsigned long)rsdp;
+			return address;
+		}
+	}
+
+	/* Search upper memory: 16-byte boundaries in E0000h-FFFFFh */
+	table_ptr = (u8 *)ACPI_HI_RSDP_WINDOW_BASE;
+	rsdp = scan_mem_for_rsdp(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE);
+	if (rsdp) {
+		address = (unsigned long)rsdp;
+		return address;
+	}
+
+	return 0;
+}
 #endif /* CONFIG_ACPI */
-- 
2.20.1




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

* [PATCH v16 5/7] x86/boot: Early parse RSDP and fill in boot_params
  2019-01-23 11:08 [PATCH v16 0/7] Parse ACPI table and limit KASLR to choosing immovable memory Chao Fan
                   ` (3 preceding siblings ...)
  2019-01-23 11:08 ` [PATCH v16 4/7] x86/boot: Introduce bios_get_rsdp_addr() to search RSDP in memory Chao Fan
@ 2019-01-23 11:08 ` Chao Fan
  2019-01-23 11:17   ` Chao Fan
  2019-02-01 11:01   ` [tip:x86/boot] x86/boot: Early parse RSDP and save it " tip-bot for Chao Fan
  2019-01-23 11:08 ` [PATCH v16 6/7] x86/boot: Parse SRAT address from RSDP and store immovable memory Chao Fan
                   ` (2 subsequent siblings)
  7 siblings, 2 replies; 54+ messages in thread
From: Chao Fan @ 2019-01-23 11:08 UTC (permalink / raw)
  To: linux-kernel, x86, bp, tglx, mingo, hpa, keescook, bhe, msys.mizuma
  Cc: indou.takao, caoj.fnst, fanc.fnst, kasong

RSDP is needed by both KASLR, so parse it early and fill it in
boot_params before KASLR code.

RSDP is needed by lots of other code, it would be easier to have it
always built-in instead of a long "depends on" line in Kconfig.

Signed-off-by: Chao Fan <fanc.fnst@cn.fujitsu.com>
---
 arch/x86/boot/compressed/Makefile |  2 ++
 arch/x86/boot/compressed/acpi.c   | 22 ++++++++++++++++++++++
 arch/x86/boot/compressed/misc.c   |  7 +++++++
 arch/x86/boot/compressed/misc.h   |  7 +++++++
 4 files changed, 38 insertions(+)

diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
index f0515ac895a4..96b71e52a2e8 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -84,6 +84,8 @@ ifdef CONFIG_X86_64
 	vmlinux-objs-y += $(obj)/pgtable_64.o
 endif
 
+vmlinux-objs-y += $(obj)/acpi.o
+
 $(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/acpi.c b/arch/x86/boot/compressed/acpi.c
index 0c389a22bb86..c207791332c7 100644
--- a/arch/x86/boot/compressed/acpi.c
+++ b/arch/x86/boot/compressed/acpi.c
@@ -194,4 +194,26 @@ static acpi_physical_address bios_get_rsdp_addr(void)
 
 	return 0;
 }
+
+/*
+ * Very early parse RSDP, based on acpi_os_get_root_pointer().
+ * Return address of RSDP on success, 0 on failed to parse RSDP.
+ */
+acpi_physical_address get_rsdp_addr(void)
+{
+	acpi_physical_address pa;
+
+	pa = get_acpi_rsdp();
+
+	if (!pa)
+		pa = boot_params->acpi_rsdp_addr;
+
+	if (!pa)
+		pa = efi_get_rsdp_addr();
+
+	if (!pa)
+		pa = bios_get_rsdp_addr();
+
+	return pa;
+}
 #endif /* CONFIG_ACPI */
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c
index 8dd1d5ccae58..86fa8bf56d68 100644
--- a/arch/x86/boot/compressed/misc.c
+++ b/arch/x86/boot/compressed/misc.c
@@ -382,6 +382,13 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap,
 	debug_putaddr(trampoline_32bit);
 #endif
 
+	/*
+	 * Very early parse RSDP and fill in boot_params.
+	 * Early parsing is only executed once, and later anyone who
+	 * needs RSDP can gain RSDP address by boot_params but not parse again.
+	 */
+	boot_params->acpi_rsdp_addr = get_rsdp_addr();
+
 	/*
 	 * The memory hole needed for the kernel is the larger of either
 	 * the entire decompressed kernel plus relocation table, or the
diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h
index 764ad50c0119..e1dd15769cf3 100644
--- a/arch/x86/boot/compressed/misc.h
+++ b/arch/x86/boot/compressed/misc.h
@@ -119,3 +119,10 @@ static inline void console_init(void)
 void set_sev_encryption_mask(void);
 
 #endif
+
+/* acpi.c */
+#ifdef CONFIG_ACPI
+acpi_physical_address get_rsdp_addr(void);
+#else
+static inline acpi_physical_address get_rsdp_addr(void) { return 0; }
+#endif
-- 
2.20.1




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

* [PATCH v16 6/7] x86/boot: Parse SRAT address from RSDP and store immovable memory
  2019-01-23 11:08 [PATCH v16 0/7] Parse ACPI table and limit KASLR to choosing immovable memory Chao Fan
                   ` (4 preceding siblings ...)
  2019-01-23 11:08 ` [PATCH v16 5/7] x86/boot: Early parse RSDP and fill in boot_params Chao Fan
@ 2019-01-23 11:08 ` Chao Fan
  2019-02-01 11:01   ` [tip:x86/boot] x86/boot: Parse SRAT table and count immovable memory regions tip-bot for Chao Fan
  2019-01-23 11:08 ` [PATCH v16 7/7] x86/boot/KASLR: Limit KASLR to extracting kernel in immovable memory Chao Fan
  2019-01-28 17:51 ` [PATCH v16 0/7] Parse ACPI table and limit KASLR to choosing immovable memory Borislav Petkov
  7 siblings, 1 reply; 54+ messages in thread
From: Chao Fan @ 2019-01-23 11:08 UTC (permalink / raw)
  To: linux-kernel, x86, bp, tglx, mingo, hpa, keescook, bhe, msys.mizuma
  Cc: indou.takao, caoj.fnst, fanc.fnst, kasong

SRAT should be parsed by RSDP to fix the conflict between KASLR and
memory-hotremove, then filter the immovable memory regions and
accoring to the memory information, KASLR can avoid to extract kernel
to movable memory regions.

Signed-off-by: Chao Fan <fanc.fnst@cn.fujitsu.com>
---
 arch/x86/boot/compressed/acpi.c  | 122 +++++++++++++++++++++++++++++++
 arch/x86/boot/compressed/kaslr.c |   4 -
 arch/x86/boot/compressed/misc.h  |  11 +++
 3 files changed, 133 insertions(+), 4 deletions(-)

diff --git a/arch/x86/boot/compressed/acpi.c b/arch/x86/boot/compressed/acpi.c
index c207791332c7..11dec68501c5 100644
--- a/arch/x86/boot/compressed/acpi.c
+++ b/arch/x86/boot/compressed/acpi.c
@@ -4,9 +4,23 @@
 #include "error.h"
 #include "../string.h"
 
+#include <linux/numa.h>
 #include <linux/efi.h>
 #include <asm/efi.h>
 
+/*
+ * Longest parameter of 'acpi=' is 'copy_dsdt', plus an extra '\0'
+ * for termination.
+ */
+#define MAX_ACPI_ARG_LENGTH 10
+
+/*
+ * Information of immovable memory regions.
+ * Max amount of memory regions is MAX_NUMNODES*2, so need such array
+ * to place immovable memory regions if all of the memory is immovable.
+ */
+struct mem_vector immovable_mem[MAX_NUMNODES*2];
+
 #ifdef CONFIG_ACPI
 
 /*
@@ -217,3 +231,111 @@ acpi_physical_address get_rsdp_addr(void)
 	return pa;
 }
 #endif /* CONFIG_ACPI */
+
+#if defined(CONFIG_RANDOMIZE_BASE) && defined(CONFIG_MEMORY_HOTREMOVE)
+/* Compute SRAT address from RSDP. */
+static unsigned long get_acpi_srat_table(void)
+{
+	unsigned long root_table, acpi_table;
+	struct acpi_table_header *header;
+	struct acpi_table_rsdp *rsdp;
+	u32 num_entries, size, len;
+	char arg[10];
+	u8 *entry;
+
+	rsdp = (struct acpi_table_rsdp *)(long)boot_params->acpi_rsdp_addr;
+	if (!rsdp)
+		return 0;
+
+	/* Get ACPI root table from RSDP.*/
+	if (!(cmdline_find_option("acpi", arg, sizeof(arg)) == 4 &&
+	    !strncmp(arg, "rsdt", 4)) &&
+	    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;
+	}
+
+	if (!root_table)
+		return 0;
+
+	header = (struct acpi_table_header *)root_table;
+	len = header->length;
+	if (len < sizeof(struct acpi_table_header) + size)
+		return 0;
+
+	num_entries = (len - sizeof(struct acpi_table_header)) / size;
+	entry = (u8 *)(root_table + sizeof(struct acpi_table_header));
+
+	while (num_entries--) {
+		if (size == ACPI_RSDT_ENTRY_SIZE)
+			acpi_table = *(u32 *)entry;
+		else
+			acpi_table = *(u64 *)entry;
+
+		if (acpi_table) {
+			header = (struct acpi_table_header *)acpi_table;
+
+			if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_SRAT))
+				return acpi_table;
+		}
+		entry += size;
+	}
+	return 0;
+}
+
+/**
+ * count_immovable_mem_regions - early parse SRAT, filter immovable
+ * memory regions
+ *
+ * Return amount of immovable memory regions on success, 0 on
+ * - Too many immovable memory regions
+ * - ACPI off or no SRAT found
+ * - No immovable memory region found
+ */
+int count_immovable_mem_regions(void)
+{
+	unsigned long table_addr, table_end, table;
+	struct acpi_subtable_header *sub_table;
+	struct acpi_table_header *table_header;
+	char arg[MAX_ACPI_ARG_LENGTH];
+	int num = 0;
+
+	if (cmdline_find_option("acpi", arg, sizeof(arg)) == 3 &&
+	    !strncmp(arg, "off", 3))
+		return 0;
+
+	table_addr = get_acpi_srat_table();
+	if (!table_addr)
+		return 0;
+
+	table_header = (struct acpi_table_header *)table_addr;
+	table_end = table_addr + table_header->length;
+	table = table_addr + sizeof(struct acpi_table_srat);
+
+	while (table + sizeof(struct acpi_subtable_header) < table_end) {
+		sub_table = (struct acpi_subtable_header *)table;
+		if (sub_table->type == ACPI_SRAT_TYPE_MEMORY_AFFINITY) {
+			struct acpi_srat_mem_affinity *ma;
+
+			ma = (struct acpi_srat_mem_affinity *)sub_table;
+			if (!(ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) &&
+			    ma->length) {
+				immovable_mem[num].start = ma->base_address;
+				immovable_mem[num].size = ma->length;
+				num++;
+			}
+
+			if (num >= MAX_NUMNODES*2) {
+				debug_putstr("Too many immovable memory regions, aborting.\n");
+				return 0;
+			}
+		}
+		table += sub_table->length;
+	}
+	return num;
+}
+#endif /* CONFIG_RANDOMIZE_BASE && CONFIG_MEMORY_HOTREMOVE */
diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c
index 9ed9709d9947..b251572e77af 100644
--- a/arch/x86/boot/compressed/kaslr.c
+++ b/arch/x86/boot/compressed/kaslr.c
@@ -87,10 +87,6 @@ static unsigned long get_boot_seed(void)
 #define KASLR_COMPRESSED_BOOT
 #include "../../lib/kaslr.c"
 
-struct mem_vector {
-	unsigned long long start;
-	unsigned long long size;
-};
 
 /* Only supporting at most 4 unusable memmap regions with kaslr */
 #define MAX_MEMMAP_REGIONS	4
diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h
index e1dd15769cf3..6fc51cebec7e 100644
--- a/arch/x86/boot/compressed/misc.h
+++ b/arch/x86/boot/compressed/misc.h
@@ -80,6 +80,11 @@ void choose_random_location(unsigned long input,
 			    unsigned long *output,
 			    unsigned long output_size,
 			    unsigned long *virt_addr);
+struct mem_vector {
+	unsigned long long start;
+	unsigned long long size;
+};
+
 /* cpuflags.c */
 bool has_cpuflag(int flag);
 #else
@@ -126,3 +131,9 @@ acpi_physical_address get_rsdp_addr(void);
 #else
 static inline acpi_physical_address get_rsdp_addr(void) { return 0; }
 #endif
+
+#if defined(CONFIG_RANDOMIZE_BASE) && defined(CONFIG_MEMORY_HOTREMOVE)
+int count_immovable_mem_regions(void);
+#else
+static inline int count_immovable_mem_regions(void) { return 0; }
+#endif
-- 
2.20.1




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

* [PATCH v16 7/7] x86/boot/KASLR: Limit KASLR to extracting kernel in immovable memory
  2019-01-23 11:08 [PATCH v16 0/7] Parse ACPI table and limit KASLR to choosing immovable memory Chao Fan
                   ` (5 preceding siblings ...)
  2019-01-23 11:08 ` [PATCH v16 6/7] x86/boot: Parse SRAT address from RSDP and store immovable memory Chao Fan
@ 2019-01-23 11:08 ` Chao Fan
  2019-02-01 11:02   ` [tip:x86/boot] x86/boot/KASLR: Limit KASLR to extract the kernel in immovable memory only tip-bot for Chao Fan
  2019-01-28 17:51 ` [PATCH v16 0/7] Parse ACPI table and limit KASLR to choosing immovable memory Borislav Petkov
  7 siblings, 1 reply; 54+ messages in thread
From: Chao Fan @ 2019-01-23 11:08 UTC (permalink / raw)
  To: linux-kernel, x86, bp, tglx, mingo, hpa, keescook, bhe, msys.mizuma
  Cc: indou.takao, caoj.fnst, fanc.fnst, kasong

KASLR may randomly choose some positions which are located in movable
memory regions. It will break memory hotplug feature and make the
movable memory chosen by KASLR can't be removed.

The solution is to limit KASLR to choose memory regions in immovable
node according to SRAT tables.
When CONFIG_EARLY_SRAT_PARSE is enabled, walk through SRAT to get the
information of immovable memory so that KASLR knows where should be
chosen for randomization.

Signed-off-by: Chao Fan <fanc.fnst@cn.fujitsu.com>
---
 arch/x86/boot/compressed/kaslr.c | 72 +++++++++++++++++++++++++++-----
 arch/x86/boot/compressed/misc.h  |  1 +
 2 files changed, 62 insertions(+), 11 deletions(-)

diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c
index b251572e77af..c6721c6d4b46 100644
--- a/arch/x86/boot/compressed/kaslr.c
+++ b/arch/x86/boot/compressed/kaslr.c
@@ -97,6 +97,8 @@ static bool memmap_too_large;
 /* Store memory limit specified by "mem=nn[KMG]" or "memmap=nn[KMG]" */
 static unsigned long long mem_limit = ULLONG_MAX;
 
+/* Amount of immovable memory regions */
+static int num_immovable_mem;
 
 enum mem_avoid_index {
 	MEM_AVOID_ZO_RANGE = 0,
@@ -413,6 +415,9 @@ static void mem_avoid_init(unsigned long input, unsigned long input_size,
 	/* Mark the memmap regions we need to avoid */
 	handle_mem_options();
 
+	/* Mark the immovable regions we need to choose */
+	num_immovable_mem = count_immovable_mem_regions();
+
 #ifdef CONFIG_X86_VERBOSE_BOOTUP
 	/* Make sure video RAM can be used. */
 	add_identity_map(0, PMD_SIZE);
@@ -568,9 +573,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 __process_mem_region(struct mem_vector *entry,
+				 unsigned long minimum,
+				 unsigned long image_size)
 {
 	struct mem_vector region, overlap;
 	unsigned long start_orig, end;
@@ -646,6 +651,57 @@ 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)
+{
+	int i;
+	/*
+	 * If no immovable memory found, or MEMORY_HOTREMOVE disabled,
+	 * walk all the regions, so use region directly.
+	 */
+	if (!num_immovable_mem) {
+		__process_mem_region(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_MEMORY_HOTREMOVE
+	/*
+	 * If immovable memory found, filter the intersection between
+	 * immovable memory and region to __process_mem_region().
+	 * Otherwise, go on old code.
+	 */
+	for (i = 0; i < num_immovable_mem; i++) {
+		unsigned long long start, end, entry_end, region_end;
+		struct mem_vector entry;
+
+		if (!mem_overlaps(region, &immovable_mem[i]))
+			continue;
+
+		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);
+		entry.size = entry_end - entry.start;
+
+		__process_mem_region(&entry, minimum, image_size);
+
+		if (slot_area_index == MAX_SLOT_AREA) {
+			debug_putstr("Aborted e820/efi memmap scan when walking immovable regions(slot_areas full)!\n");
+			return 1;
+		}
+	}
+	return 0;
+#endif
+}
+
 #ifdef CONFIG_EFI
 /*
  * Returns true if mirror region found (and must have been processed
@@ -711,11 +767,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;
 }
@@ -742,11 +795,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;
-		}
 	}
 }
 
diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h
index 6fc51cebec7e..dd941d622760 100644
--- a/arch/x86/boot/compressed/misc.h
+++ b/arch/x86/boot/compressed/misc.h
@@ -133,6 +133,7 @@ static inline acpi_physical_address get_rsdp_addr(void) { return 0; }
 #endif
 
 #if defined(CONFIG_RANDOMIZE_BASE) && defined(CONFIG_MEMORY_HOTREMOVE)
+extern struct mem_vector immovable_mem[MAX_NUMNODES*2];
 int count_immovable_mem_regions(void);
 #else
 static inline int count_immovable_mem_regions(void) { return 0; }
-- 
2.20.1




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

* Re: [PATCH v16 5/7] x86/boot: Early parse RSDP and fill in boot_params
  2019-01-23 11:08 ` [PATCH v16 5/7] x86/boot: Early parse RSDP and fill in boot_params Chao Fan
@ 2019-01-23 11:17   ` Chao Fan
  2019-02-01 11:01   ` [tip:x86/boot] x86/boot: Early parse RSDP and save it " tip-bot for Chao Fan
  1 sibling, 0 replies; 54+ messages in thread
From: Chao Fan @ 2019-01-23 11:17 UTC (permalink / raw)
  To: linux-kernel, x86, bp, tglx, mingo, hpa, keescook, bhe, msys.mizuma
  Cc: indou.takao, caoj.fnst, kasong

On Wed, Jan 23, 2019 at 07:08:48PM +0800, Chao Fan wrote:
[...]
> #endif /* CONFIG_ACPI */
>diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c
>index 8dd1d5ccae58..86fa8bf56d68 100644
>--- a/arch/x86/boot/compressed/misc.c
>+++ b/arch/x86/boot/compressed/misc.c
>@@ -382,6 +382,13 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap,
> 	debug_putaddr(trampoline_32bit);
> #endif
> 
>+	/*
>+	 * Very early parse RSDP and fill in boot_params.
>+	 * Early parsing is only executed once, and later anyone who
>+	 * needs RSDP can gain RSDP address by boot_params but not parse again.
>+	 */
>+	boot_params->acpi_rsdp_addr = get_rsdp_addr();
>+

Hi Boris and Kairui,

I splite my v15 PATCH 5/6 to two patches, this v16 5/7 is new added.
Since as Boris said much code such as Kairui's need RSDP where is not
related to KASLR, but in my v15 version, the function entry is only
in kaslr.c. So I expose get_rsdp_addr() as not static, and fill in
boot_params without #ifdef KASLR issue ot MEMORY_HOTREMOVE and so on.
More code can gain the RSDP by boot_params.

Since in KALSR, we need RSDP to parse SRAT and gain memroy information,
so I put  boot_params->acpi_rsdp_addr = get_rsdp_addr(); just before
choose_random_location(), in which KASLR works. Then in this version
v16 PATCH 6/7, only try to gain RSDP by boot_params and not parse again.

So I think this method can cover other people's usage, such as Kairui
Song, how do you think this change.

Thanks,
Chao Fan

> 	/*
> 	 * The memory hole needed for the kernel is the larger of either
> 	 * the entire decompressed kernel plus relocation table, or the
>diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h
>index 764ad50c0119..e1dd15769cf3 100644
>--- a/arch/x86/boot/compressed/misc.h
>+++ b/arch/x86/boot/compressed/misc.h
>@@ -119,3 +119,10 @@ static inline void console_init(void)
> void set_sev_encryption_mask(void);
> 
> #endif
>+
>+/* acpi.c */
>+#ifdef CONFIG_ACPI
>+acpi_physical_address get_rsdp_addr(void);
>+#else
>+static inline acpi_physical_address get_rsdp_addr(void) { return 0; }
>+#endif
>-- 
>2.20.1
>



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

* Re: [PATCH v16 0/7] Parse ACPI table and limit KASLR to choosing immovable memory
  2019-01-23 11:08 [PATCH v16 0/7] Parse ACPI table and limit KASLR to choosing immovable memory Chao Fan
                   ` (6 preceding siblings ...)
  2019-01-23 11:08 ` [PATCH v16 7/7] x86/boot/KASLR: Limit KASLR to extracting kernel in immovable memory Chao Fan
@ 2019-01-28 17:51 ` Borislav Petkov
  2019-01-30  5:58   ` Chao Fan
  7 siblings, 1 reply; 54+ messages in thread
From: Borislav Petkov @ 2019-01-28 17:51 UTC (permalink / raw)
  To: Chao Fan
  Cc: linux-kernel, x86, tglx, mingo, hpa, keescook, bhe, msys.mizuma,
	indou.takao, caoj.fnst, kasong

On Wed, Jan 23, 2019 at 07:08:43PM +0800, Chao Fan wrote:
> PATCH 1/7 Copy kstrtoull() to boot/string.c to instead of using
>           old simple_strtoull()
> PATCH 2/7 Introduce get_acpi_rsdp() to parse RSDP in cmdline from KEXEC
> PATCH 3/6 Introduce efi_get_rsdp_addr() to find RSDP from EFI table when
>           booting from EFI.
> PATCH 4/7 Introduce bios_get_rsdp_addr() to search RSDP in memory when
>           booting from BIOS
> PATCH 5/7 Parse RSDP and fill in boot_params->acpi_rsdp_addr before
>           KASLR.
> PATCH 6/7 Compute SRAT from RSDP and walk SRAT to store the immovable
>           memory regions and store the immovable memory regions.
> PATCH 7/7 Calculate the intersection between memory regions from e820/efi
>           memory table and immovable memory regions. Limit KASLR to
>           choosing these regions for randomization.

Ok, I've massaged the whole pile and fixed a couple of things that
sprang at me, see each commit message for details.

Please run it and check whether I haven't broken anything:

https://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.git/log/?h=tip-x86-boot

Thx.

-- 
Regards/Gruss,
    Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

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

* Re: [PATCH v16 0/7] Parse ACPI table and limit KASLR to choosing immovable memory
  2019-01-28 17:51 ` [PATCH v16 0/7] Parse ACPI table and limit KASLR to choosing immovable memory Borislav Petkov
@ 2019-01-30  5:58   ` Chao Fan
  2019-01-30 11:22     ` [PATCH] x86/boot: Build the command line parsing code unconditionally (was: Re: [PATCH v16 0/7] Parse ACPI table and limit KASLR to choosing immovable memory) Borislav Petkov
  0 siblings, 1 reply; 54+ messages in thread
From: Chao Fan @ 2019-01-30  5:58 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: linux-kernel, x86, tglx, mingo, hpa, keescook, bhe, msys.mizuma,
	indou.takao, caoj.fnst, kasong

On Mon, Jan 28, 2019 at 06:51:32PM +0100, Borislav Petkov wrote:
>On Wed, Jan 23, 2019 at 07:08:43PM +0800, Chao Fan wrote:
>> PATCH 1/7 Copy kstrtoull() to boot/string.c to instead of using
>>           old simple_strtoull()
>> PATCH 2/7 Introduce get_acpi_rsdp() to parse RSDP in cmdline from KEXEC
>> PATCH 3/6 Introduce efi_get_rsdp_addr() to find RSDP from EFI table when
>>           booting from EFI.
>> PATCH 4/7 Introduce bios_get_rsdp_addr() to search RSDP in memory when
>>           booting from BIOS
>> PATCH 5/7 Parse RSDP and fill in boot_params->acpi_rsdp_addr before
>>           KASLR.
>> PATCH 6/7 Compute SRAT from RSDP and walk SRAT to store the immovable
>>           memory regions and store the immovable memory regions.
>> PATCH 7/7 Calculate the intersection between memory regions from e820/efi
>>           memory table and immovable memory regions. Limit KASLR to
>>           choosing these regions for randomization.

Hi Boris,

Sorry for delay.
>
>Ok, I've massaged the whole pile and fixed a couple of things that
>sprang at me, see each commit message for details.

Thanks for your fix, your change looks good.
>
>Please run it and check whether I haven't broken anything:
>
>https://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.git/log/?h=tip-x86-boot

I clone your branch and test some cases. Except the build issue of
cmdline_find_option(), PATCHSET works well.
Build in x86_64 and i386.
Tested EFI/BIOS environment in x86_64 and BIOS environment in i386.
Tested the 'acpi_rsdp=' and 'boot_params->acpi_rsdp_addr' issue, all
work well.

Thanks,
Chao Fan

>
>Thx.
>
>-- 
>Regards/Gruss,
>    Boris.
>
>Good mailing practices for 400: avoid top-posting and trim the reply.
>
>



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

* [PATCH] x86/boot: Build the command line parsing code unconditionally (was: Re: [PATCH v16 0/7] Parse ACPI table and limit KASLR to choosing immovable memory)
  2019-01-30  5:58   ` Chao Fan
@ 2019-01-30 11:22     ` Borislav Petkov
  2019-02-01 10:57       ` [tip:x86/boot] x86/boot: Build the command line parsing code unconditionally tip-bot for Borislav Petkov
  0 siblings, 1 reply; 54+ messages in thread
From: Borislav Petkov @ 2019-01-30 11:22 UTC (permalink / raw)
  To: Chao Fan
  Cc: linux-kernel, x86, tglx, mingo, hpa, keescook, bhe, msys.mizuma,
	indou.takao, caoj.fnst, kasong

On Wed, Jan 30, 2019 at 01:58:47PM +0800, Chao Fan wrote:
> I clone your branch and test some cases. Except the build issue of
> cmdline_find_option(), PATCHSET works well.
> Build in x86_64 and i386.
> Tested EFI/BIOS environment in x86_64 and BIOS environment in i386.
> Tested the 'acpi_rsdp=' and 'boot_params->acpi_rsdp_addr' issue, all
> work well.

Thanks.

Here's a fix for the build issue below, pushing a new branch.

---
From: Borislav Petkov <bp@suse.de>
Subject: [PATCH] x86/boot: Build the command line parsing code unconditionally

Just drop the three-item ifdeffery and build it in unconditionally.
Early cmdline parsing is needed more often than not.

Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: x86@kernel.org
---
 arch/x86/boot/compressed/cmdline.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/arch/x86/boot/compressed/cmdline.c b/arch/x86/boot/compressed/cmdline.c
index af6cda0b7900..f1add5d85da9 100644
--- a/arch/x86/boot/compressed/cmdline.c
+++ b/arch/x86/boot/compressed/cmdline.c
@@ -1,8 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 #include "misc.h"
 
-#if CONFIG_EARLY_PRINTK || CONFIG_RANDOMIZE_BASE || CONFIG_X86_5LEVEL
-
 static unsigned long fs;
 static inline void set_fs(unsigned long seg)
 {
@@ -30,5 +28,3 @@ int cmdline_find_option_bool(const char *option)
 {
 	return __cmdline_find_option_bool(get_cmd_line_ptr(), option);
 }
-
-#endif
-- 
2.19.1

-- 
Regards/Gruss,
    Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

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

* [tip:x86/boot] x86/boot: Build the command line parsing code unconditionally
  2019-01-30 11:22     ` [PATCH] x86/boot: Build the command line parsing code unconditionally (was: Re: [PATCH v16 0/7] Parse ACPI table and limit KASLR to choosing immovable memory) Borislav Petkov
@ 2019-02-01 10:57       ` tip-bot for Borislav Petkov
  0 siblings, 0 replies; 54+ messages in thread
From: tip-bot for Borislav Petkov @ 2019-02-01 10:57 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: tglx, linux-kernel, bp, hpa, mingo

Commit-ID:  ac09c5f43cf613939850cc38d7a34ae6556016ba
Gitweb:     https://git.kernel.org/tip/ac09c5f43cf613939850cc38d7a34ae6556016ba
Author:     Borislav Petkov <bp@suse.de>
AuthorDate: Wed, 30 Jan 2019 11:19:37 +0100
Committer:  Borislav Petkov <bp@suse.de>
CommitDate: Fri, 1 Feb 2019 11:51:01 +0100

x86/boot: Build the command line parsing code unconditionally

Just drop the three-item ifdeffery and build it in unconditionally.
Early cmdline parsing is needed more often than not.

Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: bhe@redhat.com
Cc: hpa@zytor.com
Cc: indou.takao@jp.fujitsu.com
Cc: kasong@redhat.com
Cc: keescook@chromium.org
Cc: mingo@redhat.com
Cc: msys.mizuma@gmail.com
Cc: tglx@linutronix.de
Cc: x86@kernel.org
Link: https://lkml.kernel.org/r/20190130112238.GB18383@zn.tnic
---
 arch/x86/boot/compressed/cmdline.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/arch/x86/boot/compressed/cmdline.c b/arch/x86/boot/compressed/cmdline.c
index af6cda0b7900..f1add5d85da9 100644
--- a/arch/x86/boot/compressed/cmdline.c
+++ b/arch/x86/boot/compressed/cmdline.c
@@ -1,8 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 #include "misc.h"
 
-#if CONFIG_EARLY_PRINTK || CONFIG_RANDOMIZE_BASE || CONFIG_X86_5LEVEL
-
 static unsigned long fs;
 static inline void set_fs(unsigned long seg)
 {
@@ -30,5 +28,3 @@ int cmdline_find_option_bool(const char *option)
 {
 	return __cmdline_find_option_bool(get_cmd_line_ptr(), option);
 }
-
-#endif

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

* [tip:x86/boot] x86/boot: Copy kstrtoull() to boot/string.c
  2019-01-23 11:08 ` [PATCH v16 1/7] x86/boot: Copy kstrtoull() to boot/string.c instead of simple_strtoull() Chao Fan
@ 2019-02-01 10:58   ` tip-bot for Chao Fan
  0 siblings, 0 replies; 54+ messages in thread
From: tip-bot for Chao Fan @ 2019-02-01 10:58 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: tglx, hpa, mingo, mingo, x86, keescook, bp, linux-kernel, fanc.fnst

Commit-ID:  de50ce20cd05da4d1a7e5709a12fc23bc0b66be9
Gitweb:     https://git.kernel.org/tip/de50ce20cd05da4d1a7e5709a12fc23bc0b66be9
Author:     Chao Fan <fanc.fnst@cn.fujitsu.com>
AuthorDate: Wed, 23 Jan 2019 19:08:44 +0800
Committer:  Borislav Petkov <bp@suse.de>
CommitDate: Fri, 1 Feb 2019 11:52:54 +0100

x86/boot: Copy kstrtoull() to boot/string.c

Copy kstrtoull() and the other necessary functions from lib/kstrtox.c
to boot/string.c so that code in boot/ can use kstrtoull() and the old
simple_strtoull() can gradually be phased out.

Using div_u64() from math64.h directly will cause the dividend to be
handled as a 64-bit value and cause the infamous __divdi3 linker error
due to gcc trying to use its library function for the 64-bit division.

Therefore, separate the dividend into an upper and lower part.

 [ bp: Rewrite commit message. ]

Signed-off-by: Chao Fan <fanc.fnst@cn.fujitsu.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: bhe@redhat.com
Cc: caoj.fnst@cn.fujitsu.com
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: indou.takao@jp.fujitsu.com
Cc: Ingo Molnar <mingo@redhat.com>
Cc: kasong@redhat.com
Cc: Kees Cook <keescook@chromium.org>
Cc: msys.mizuma@gmail.com
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: x86-ml <x86@kernel.org>
Link: https://lkml.kernel.org/r/20190123110850.12433-2-fanc.fnst@cn.fujitsu.com
---
 arch/x86/boot/string.c | 141 +++++++++++++++++++++++++++++++++++++++++++++++++
 arch/x86/boot/string.h |   1 +
 2 files changed, 142 insertions(+)

diff --git a/arch/x86/boot/string.c b/arch/x86/boot/string.c
index c4428a176973..315a67b8896b 100644
--- a/arch/x86/boot/string.c
+++ b/arch/x86/boot/string.c
@@ -13,10 +13,14 @@
  */
 
 #include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
 #include <asm/asm.h>
 #include "ctype.h"
 #include "string.h"
 
+#define KSTRTOX_OVERFLOW       (1U << 31)
+
 /*
  * Undef these macros so that the functions that we provide
  * here will have the correct names regardless of how string.h
@@ -187,3 +191,140 @@ char *strchr(const char *s, int c)
 			return NULL;
 	return (char *)s;
 }
+
+static inline u64 __div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
+{
+	union {
+		u64 v64;
+		u32 v32[2];
+	} d = { dividend };
+	u32 upper;
+
+	upper = d.v32[1];
+	d.v32[1] = 0;
+	if (upper >= divisor) {
+		d.v32[1] = upper / divisor;
+		upper %= divisor;
+	}
+	asm ("divl %2" : "=a" (d.v32[0]), "=d" (*remainder) :
+		"rm" (divisor), "0" (d.v32[0]), "1" (upper));
+	return d.v64;
+}
+
+static inline u64 __div_u64(u64 dividend, u32 divisor)
+{
+	u32 remainder;
+
+	return __div_u64_rem(dividend, divisor, &remainder);
+}
+
+static inline char _tolower(const char c)
+{
+	return c | 0x20;
+}
+
+static const char *_parse_integer_fixup_radix(const char *s, unsigned int *base)
+{
+	if (*base == 0) {
+		if (s[0] == '0') {
+			if (_tolower(s[1]) == 'x' && isxdigit(s[2]))
+				*base = 16;
+			else
+				*base = 8;
+		} else
+			*base = 10;
+	}
+	if (*base == 16 && s[0] == '0' && _tolower(s[1]) == 'x')
+		s += 2;
+	return s;
+}
+
+/*
+ * Convert non-negative integer string representation in explicitly given radix
+ * to an integer.
+ * Return number of characters consumed maybe or-ed with overflow bit.
+ * If overflow occurs, result integer (incorrect) is still returned.
+ *
+ * Don't you dare use this function.
+ */
+static unsigned int _parse_integer(const char *s,
+				   unsigned int base,
+				   unsigned long long *p)
+{
+	unsigned long long res;
+	unsigned int rv;
+
+	res = 0;
+	rv = 0;
+	while (1) {
+		unsigned int c = *s;
+		unsigned int lc = c | 0x20; /* don't tolower() this line */
+		unsigned int val;
+
+		if ('0' <= c && c <= '9')
+			val = c - '0';
+		else if ('a' <= lc && lc <= 'f')
+			val = lc - 'a' + 10;
+		else
+			break;
+
+		if (val >= base)
+			break;
+		/*
+		 * Check for overflow only if we are within range of
+		 * it in the max base we support (16)
+		 */
+		if (unlikely(res & (~0ull << 60))) {
+			if (res > __div_u64(ULLONG_MAX - val, base))
+				rv |= KSTRTOX_OVERFLOW;
+		}
+		res = res * base + val;
+		rv++;
+		s++;
+	}
+	*p = res;
+	return rv;
+}
+
+static int _kstrtoull(const char *s, unsigned int base, unsigned long long *res)
+{
+	unsigned long long _res;
+	unsigned int rv;
+
+	s = _parse_integer_fixup_radix(s, &base);
+	rv = _parse_integer(s, base, &_res);
+	if (rv & KSTRTOX_OVERFLOW)
+		return -ERANGE;
+	if (rv == 0)
+		return -EINVAL;
+	s += rv;
+	if (*s == '\n')
+		s++;
+	if (*s)
+		return -EINVAL;
+	*res = _res;
+	return 0;
+}
+
+/**
+ * kstrtoull - convert a string to an unsigned long long
+ * @s: The start of the string. The string must be null-terminated, and may also
+ *  include a single newline before its terminating null. The first character
+ *  may also be a plus sign, but not a minus sign.
+ * @base: The number base to use. The maximum supported base is 16. If base is
+ *  given as 0, then the base of the string is automatically detected with the
+ *  conventional semantics - If it begins with 0x the number will be parsed as a
+ *  hexadecimal (case insensitive), if it otherwise begins with 0, it will be
+ *  parsed as an octal number. Otherwise it will be parsed as a decimal.
+ * @res: Where to write the result of the conversion on success.
+ *
+ * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
+ * Used as a replacement for the obsolete simple_strtoull. Return code must
+ * be checked.
+ */
+int kstrtoull(const char *s, unsigned int base, unsigned long long *res)
+{
+	if (s[0] == '+')
+		s++;
+	return _kstrtoull(s, base, res);
+}
diff --git a/arch/x86/boot/string.h b/arch/x86/boot/string.h
index 3d78e27077f4..38d8f2f5e47e 100644
--- a/arch/x86/boot/string.h
+++ b/arch/x86/boot/string.h
@@ -29,4 +29,5 @@ extern unsigned int atou(const char *s);
 extern unsigned long long simple_strtoull(const char *cp, char **endp,
 					  unsigned int base);
 
+int kstrtoull(const char *s, unsigned int base, unsigned long long *res);
 #endif /* BOOT_STRING_H */

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

* [tip:x86/boot] x86/boot: Add "acpi_rsdp=" early parsing
  2019-01-23 11:08 ` [PATCH v16 2/7] x86/boot: Introduce get_acpi_rsdp() to parse RSDP in cmdline from KEXEC Chao Fan
@ 2019-02-01 10:59   ` tip-bot for Chao Fan
  0 siblings, 0 replies; 54+ messages in thread
From: tip-bot for Chao Fan @ 2019-02-01 10:59 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: mingo, mingo, jgross, thomas.lendacky, tglx, hpa, fanc.fnst,
	linux-kernel, bp, x86, kirill.shutemov, keescook

Commit-ID:  3c98e71b42a7d0c14639ccb565ea315f3c887f92
Gitweb:     https://git.kernel.org/tip/3c98e71b42a7d0c14639ccb565ea315f3c887f92
Author:     Chao Fan <fanc.fnst@cn.fujitsu.com>
AuthorDate: Wed, 23 Jan 2019 19:08:45 +0800
Committer:  Borislav Petkov <bp@suse.de>
CommitDate: Fri, 1 Feb 2019 11:52:54 +0100

x86/boot: Add "acpi_rsdp=" early parsing

KASLR may randomly choose offsets which are located in movable memory
regions resulting in the movable memory becoming immovable.

The ACPI SRAT (System/Static Resource Affinity Table) describes memory
ranges including ranges of memory provided by hot-added memory devices.
In order to access SRAT, one needs the Root System Description Pointer
(RSDP) with which to find the Root/Extended System Description Table
(R/XSDT) which then contains the system description tables of which SRAT
is one of.

In case the RSDP address has been passed on the command line (kexec-ing
a second kernel) parse it from there.

 [ bp: Rewrite the commit message and cleanup the code. ]

Signed-off-by: Chao Fan <fanc.fnst@cn.fujitsu.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: bhe@redhat.com
Cc: caoj.fnst@cn.fujitsu.com
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: indou.takao@jp.fujitsu.com
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: kasong@redhat.com
Cc: Kees Cook <keescook@chromium.org>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Cc: msys.mizuma@gmail.com
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: x86-ml <x86@kernel.org>
Link: https://lkml.kernel.org/r/20190123110850.12433-3-fanc.fnst@cn.fujitsu.com
---
 arch/x86/boot/compressed/acpi.c | 32 ++++++++++++++++++++++++++++++++
 arch/x86/boot/compressed/misc.h |  3 +++
 2 files changed, 35 insertions(+)

diff --git a/arch/x86/boot/compressed/acpi.c b/arch/x86/boot/compressed/acpi.c
new file mode 100644
index 000000000000..bacfc4ea35ac
--- /dev/null
+++ b/arch/x86/boot/compressed/acpi.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0
+#define BOOT_CTYPE_H
+#include "misc.h"
+#include "error.h"
+#include "../string.h"
+
+#ifdef CONFIG_ACPI
+
+/*
+ * Max length of 64-bit hex address string is 19, prefix "0x" + 16 hex
+ * digits, and '\0' for termination.
+ */
+#define MAX_ADDR_LEN 19
+
+static acpi_physical_address get_acpi_rsdp(void)
+{
+	acpi_physical_address addr = 0;
+
+#ifdef CONFIG_KEXEC
+	char val[MAX_ADDR_LEN] = { };
+	int ret;
+
+	ret = cmdline_find_option("acpi_rsdp", val, MAX_ADDR_LEN);
+	if (ret < 0)
+		return 0;
+
+	if (kstrtoull(val, 16, &addr))
+		return 0;
+#endif
+	return addr;
+}
+#endif /* CONFIG_ACPI */
diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h
index a1d5918765f3..764ad50c0119 100644
--- a/arch/x86/boot/compressed/misc.h
+++ b/arch/x86/boot/compressed/misc.h
@@ -25,6 +25,9 @@
 #include <asm/bootparam.h>
 #include <asm/bootparam_utils.h>
 
+#define BOOT_CTYPE_H
+#include <linux/acpi.h>
+
 #define BOOT_BOOT_H
 #include "../ctype.h"
 

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

* [tip:x86/boot] x86/boot: Search for RSDP in the EFI tables
  2019-01-23 11:08 ` [PATCH v16 3/7] x86/boot: Introduce efi_get_rsdp_addr() to find RSDP from EFI table Chao Fan
@ 2019-02-01 10:59   ` tip-bot for Chao Fan
  0 siblings, 0 replies; 54+ messages in thread
From: tip-bot for Chao Fan @ 2019-02-01 10:59 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: hpa, mingo, bp, tglx, linux-kernel, mingo, keescook, fanc.fnst, x86

Commit-ID:  33f0df8d843deb9ec24116dcd79a40ca0ea8e8a9
Gitweb:     https://git.kernel.org/tip/33f0df8d843deb9ec24116dcd79a40ca0ea8e8a9
Author:     Chao Fan <fanc.fnst@cn.fujitsu.com>
AuthorDate: Wed, 23 Jan 2019 19:08:46 +0800
Committer:  Borislav Petkov <bp@suse.de>
CommitDate: Fri, 1 Feb 2019 11:52:54 +0100

x86/boot: Search for RSDP in the EFI tables

The immovable memory ranges information in the SRAT table is necessary
to fix the issue of KASLR not paying attention to movable memory regions
when selecting the offset. Therefore, SRAT needs to be parsed.

Depending on the boot: KEXEC/EFI/BIOS, the methods to compute RSDP are
different. When booting from EFI, the EFI table points to the RSDP. So
iterate over the EFI system tables in order to find the RSDP.

 [ bp:
   - Heavily massage commit message
   - Trim comments
   - Move the CONFIG_ACPI ifdeffery into the Makefile.
 ]

Signed-off-by: Chao Fan <fanc.fnst@cn.fujitsu.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: bhe@redhat.com
Cc: caoj.fnst@cn.fujitsu.com
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: indou.takao@jp.fujitsu.com
Cc: Ingo Molnar <mingo@redhat.com>
Cc: kasong@redhat.com
Cc: Kees Cook <keescook@chromium.org>
Cc: msys.mizuma@gmail.com
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: x86-ml <x86@kernel.org>
Link: https://lkml.kernel.org/r/20190123110850.12433-4-fanc.fnst@cn.fujitsu.com
---
 arch/x86/boot/compressed/acpi.c | 81 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 79 insertions(+), 2 deletions(-)

diff --git a/arch/x86/boot/compressed/acpi.c b/arch/x86/boot/compressed/acpi.c
index bacfc4ea35ac..5559fde1c0fe 100644
--- a/arch/x86/boot/compressed/acpi.c
+++ b/arch/x86/boot/compressed/acpi.c
@@ -4,7 +4,8 @@
 #include "error.h"
 #include "../string.h"
 
-#ifdef CONFIG_ACPI
+#include <linux/efi.h>
+#include <asm/efi.h>
 
 /*
  * Max length of 64-bit hex address string is 19, prefix "0x" + 16 hex
@@ -29,4 +30,80 @@ static acpi_physical_address get_acpi_rsdp(void)
 #endif
 	return addr;
 }
-#endif /* CONFIG_ACPI */
+
+/* Search EFI system tables for RSDP. */
+static acpi_physical_address efi_get_rsdp_addr(void)
+{
+	acpi_physical_address rsdp_addr = 0;
+
+#ifdef CONFIG_EFI
+	efi_system_table_t *systab;
+	struct efi_info *ei;
+	bool efi_64;
+	int size, i;
+	char *sig;
+
+	ei = &boot_params->efi_info;
+	sig = (char *)&ei->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 0;
+	}
+
+	/* Get systab from boot params. */
+#ifdef CONFIG_X86_64
+	systab = (efi_system_table_t *)(ei->efi_systab | ((__u64)ei->efi_systab_hi<<32));
+#else
+	if (ei->efi_systab_hi || ei->efi_memmap_hi) {
+		debug_putstr("Error getting RSDP address: EFI system table located above 4GB.\n");
+		return 0;
+	}
+	systab = (efi_system_table_t *)ei->efi_systab;
+#endif
+	if (!systab)
+		error("EFI system table not found.");
+
+	/*
+	 * 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++) {
+		acpi_physical_address table;
+		void *config_tables;
+		efi_guid_t guid;
+
+		config_tables = (void *)(systab->tables + size * i);
+		if (efi_64) {
+			efi_config_table_64_t *tmp_table;
+
+			tmp_table = config_tables;
+			guid = tmp_table->guid;
+			table = tmp_table->table;
+
+			if (!IS_ENABLED(CONFIG_X86_64) && table >> 32) {
+				debug_putstr("Error getting RSDP address: EFI config table located above 4GB.\n");
+				return 0;
+			}
+		} else {
+			efi_config_table_32_t *tmp_table;
+
+			tmp_table = config_tables;
+			guid = tmp_table->guid;
+			table = tmp_table->table;
+		}
+
+		if (!(efi_guidcmp(guid, ACPI_TABLE_GUID)))
+			rsdp_addr = table;
+		else if (!(efi_guidcmp(guid, ACPI_20_TABLE_GUID)))
+			return table;
+	}
+#endif
+	return rsdp_addr;
+}

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

* [tip:x86/boot] x86/boot: Search for RSDP in memory
  2019-01-23 11:08 ` [PATCH v16 4/7] x86/boot: Introduce bios_get_rsdp_addr() to search RSDP in memory Chao Fan
@ 2019-02-01 11:00   ` tip-bot for Chao Fan
  0 siblings, 0 replies; 54+ messages in thread
From: tip-bot for Chao Fan @ 2019-02-01 11:00 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: mingo, fanc.fnst, mingo, tglx, x86, keescook, hpa, linux-kernel, bp

Commit-ID:  93a209aaaad495d7d0bc9b6186a4495934f70402
Gitweb:     https://git.kernel.org/tip/93a209aaaad495d7d0bc9b6186a4495934f70402
Author:     Chao Fan <fanc.fnst@cn.fujitsu.com>
AuthorDate: Wed, 23 Jan 2019 19:08:47 +0800
Committer:  Borislav Petkov <bp@suse.de>
CommitDate: Fri, 1 Feb 2019 11:52:55 +0100

x86/boot: Search for RSDP in memory

Scan memory (EBDA) for the RSDP and verify RSDP by signature and
checksum.

 [ bp:
   - Trim commit message.
   - Simplify bios_get_rsdp_addr() and cleanup mad casting.
 ]

Signed-off-by: Chao Fan <fanc.fnst@cn.fujitsu.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: bhe@redhat.com
Cc: caoj.fnst@cn.fujitsu.com
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: indou.takao@jp.fujitsu.com
Cc: Ingo Molnar <mingo@redhat.com>
Cc: kasong@redhat.com
Cc: Kees Cook <keescook@chromium.org>
Cc: msys.mizuma@gmail.com
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: x86-ml <x86@kernel.org>
Link: https://lkml.kernel.org/r/20190123110850.12433-5-fanc.fnst@cn.fujitsu.com
---
 arch/x86/boot/compressed/acpi.c | 77 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 77 insertions(+)

diff --git a/arch/x86/boot/compressed/acpi.c b/arch/x86/boot/compressed/acpi.c
index 5559fde1c0fe..66bda1b5cf94 100644
--- a/arch/x86/boot/compressed/acpi.c
+++ b/arch/x86/boot/compressed/acpi.c
@@ -107,3 +107,80 @@ static acpi_physical_address efi_get_rsdp_addr(void)
 #endif
 	return rsdp_addr;
 }
+
+static u8 compute_checksum(u8 *buffer, u32 length)
+{
+	u8 *end = buffer + length;
+	u8 sum = 0;
+
+	while (buffer < end)
+		sum += *(buffer++);
+
+	return sum;
+}
+
+/* Search a block of memory for the RSDP signature. */
+static u8 *scan_mem_for_rsdp(u8 *start, u32 length)
+{
+	struct acpi_table_rsdp *rsdp;
+	u8 *address, *end;
+
+	end = start + length;
+
+	/* Search from given start address for the requested length */
+	for (address = start; address < end; address += ACPI_RSDP_SCAN_STEP) {
+		/*
+		 * Both RSDP signature and checksum must be correct.
+		 * Note: Sometimes there exists more than one RSDP in memory;
+		 * the valid RSDP has a valid checksum, all others have an
+		 * invalid checksum.
+		 */
+		rsdp = (struct acpi_table_rsdp *)address;
+
+		/* BAD Signature */
+		if (!ACPI_VALIDATE_RSDP_SIG(rsdp->signature))
+			continue;
+
+		/* Check the standard checksum */
+		if (compute_checksum((u8 *)rsdp, ACPI_RSDP_CHECKSUM_LENGTH))
+			continue;
+
+		/* Check extended checksum if table version >= 2 */
+		if ((rsdp->revision >= 2) &&
+		    (compute_checksum((u8 *)rsdp, ACPI_RSDP_XCHECKSUM_LENGTH)))
+			continue;
+
+		/* Signature and checksum valid, we have found a real RSDP */
+		return address;
+	}
+	return NULL;
+}
+
+/* Search RSDP address in EBDA. */
+static acpi_physical_address bios_get_rsdp_addr(void)
+{
+	unsigned long address;
+	u8 *rsdp;
+
+	/* Get the location of the Extended BIOS Data Area (EBDA) */
+	address = *(u16 *)ACPI_EBDA_PTR_LOCATION;
+	address <<= 4;
+
+	/*
+	 * Search EBDA paragraphs (EBDA is required to be a minimum of
+	 * 1K length)
+	 */
+	if (address > 0x400) {
+		rsdp = scan_mem_for_rsdp((u8 *)address, ACPI_EBDA_WINDOW_SIZE);
+		if (rsdp)
+			return (acpi_physical_address)(unsigned long)rsdp;
+	}
+
+	/* Search upper memory: 16-byte boundaries in E0000h-FFFFFh */
+	rsdp = scan_mem_for_rsdp((u8 *) ACPI_HI_RSDP_WINDOW_BASE,
+					ACPI_HI_RSDP_WINDOW_SIZE);
+	if (rsdp)
+		return (acpi_physical_address)(unsigned long)rsdp;
+
+	return 0;
+}

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

* [tip:x86/boot] x86/boot: Early parse RSDP and save it in boot_params
  2019-01-23 11:08 ` [PATCH v16 5/7] x86/boot: Early parse RSDP and fill in boot_params Chao Fan
  2019-01-23 11:17   ` Chao Fan
@ 2019-02-01 11:01   ` tip-bot for Chao Fan
  2019-02-08 19:02     ` Guenter Roeck
  1 sibling, 1 reply; 54+ messages in thread
From: tip-bot for Chao Fan @ 2019-02-01 11:01 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: mingo, jgross, yamada.masahiro, hpa, keescook, mingo, fanc.fnst,
	caoj.fnst, x86, thomas.lendacky, kirill.shutemov, bp, tglx,
	linux-kernel

Commit-ID:  3a63f70bf4c3a17f5d9c9bf3bc3288a23bdfefce
Gitweb:     https://git.kernel.org/tip/3a63f70bf4c3a17f5d9c9bf3bc3288a23bdfefce
Author:     Chao Fan <fanc.fnst@cn.fujitsu.com>
AuthorDate: Wed, 23 Jan 2019 19:08:48 +0800
Committer:  Borislav Petkov <bp@suse.de>
CommitDate: Fri, 1 Feb 2019 11:52:55 +0100

x86/boot: Early parse RSDP and save it in boot_params

The RSDP is needed by KASLR so parse it early and save it in
boot_params.acpi_rsdp_addr, before KASLR setup runs.

RSDP is needed by other kernel facilities so have the parsing code
built-in instead of a long "depends on" line in Kconfig.

 [ bp:
    - Trim commit message and comments
    - Add CONFIG_ACPI dependency in the Makefile
    - Move ->acpi_rsdp_addr assignment with the rest of boot_params massaging in extract_kernel().
 ]

Signed-off-by: Chao Fan <fanc.fnst@cn.fujitsu.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: bhe@redhat.com
Cc: Cao jin <caoj.fnst@cn.fujitsu.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: indou.takao@jp.fujitsu.com
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: kasong@redhat.com
Cc: Kees Cook <keescook@chromium.org>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
Cc: msys.mizuma@gmail.com
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: x86-ml <x86@kernel.org>
Link: https://lkml.kernel.org/r/20190123110850.12433-6-fanc.fnst@cn.fujitsu.com
---
 arch/x86/boot/compressed/Makefile |  2 ++
 arch/x86/boot/compressed/acpi.c   | 19 +++++++++++++++++++
 arch/x86/boot/compressed/misc.c   |  3 +++
 arch/x86/boot/compressed/misc.h   |  7 +++++++
 4 files changed, 31 insertions(+)

diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
index f0515ac895a4..6b84afdd7538 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -84,6 +84,8 @@ ifdef CONFIG_X86_64
 	vmlinux-objs-y += $(obj)/pgtable_64.o
 endif
 
+vmlinux-objs-$(CONFIG_ACPI) += $(obj)/acpi.o
+
 $(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/acpi.c b/arch/x86/boot/compressed/acpi.c
index 66bda1b5cf94..b2b50ad5299a 100644
--- a/arch/x86/boot/compressed/acpi.c
+++ b/arch/x86/boot/compressed/acpi.c
@@ -184,3 +184,22 @@ static acpi_physical_address bios_get_rsdp_addr(void)
 
 	return 0;
 }
+
+/* Return RSDP address on success, otherwise 0. */
+acpi_physical_address get_rsdp_addr(void)
+{
+	acpi_physical_address pa;
+
+	pa = get_acpi_rsdp();
+
+	if (!pa)
+		pa = boot_params->acpi_rsdp_addr;
+
+	if (!pa)
+		pa = efi_get_rsdp_addr();
+
+	if (!pa)
+		pa = bios_get_rsdp_addr();
+
+	return pa;
+}
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c
index 8dd1d5ccae58..c0d6c560df69 100644
--- a/arch/x86/boot/compressed/misc.c
+++ b/arch/x86/boot/compressed/misc.c
@@ -351,6 +351,9 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap,
 	/* Clear flags intended for solely in-kernel use. */
 	boot_params->hdr.loadflags &= ~KASLR_FLAG;
 
+	/* Save RSDP address for later use. */
+	boot_params->acpi_rsdp_addr = get_rsdp_addr();
+
 	sanitize_boot_params(boot_params);
 
 	if (boot_params->screen_info.orig_video_mode == 7) {
diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h
index 764ad50c0119..e1dd15769cf3 100644
--- a/arch/x86/boot/compressed/misc.h
+++ b/arch/x86/boot/compressed/misc.h
@@ -119,3 +119,10 @@ static inline void console_init(void)
 void set_sev_encryption_mask(void);
 
 #endif
+
+/* acpi.c */
+#ifdef CONFIG_ACPI
+acpi_physical_address get_rsdp_addr(void);
+#else
+static inline acpi_physical_address get_rsdp_addr(void) { return 0; }
+#endif

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

* [tip:x86/boot] x86/boot: Parse SRAT table and count immovable memory regions
  2019-01-23 11:08 ` [PATCH v16 6/7] x86/boot: Parse SRAT address from RSDP and store immovable memory Chao Fan
@ 2019-02-01 11:01   ` tip-bot for Chao Fan
  0 siblings, 0 replies; 54+ messages in thread
From: tip-bot for Chao Fan @ 2019-02-01 11:01 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: bhe, indou.takao, kirill.shutemov, jgross, x86, caoj.fnst,
	linux-kernel, dave.hansen, ard.biesheuvel, fanc.fnst, tglx,
	thomas.lendacky, keescook, msys.mizuma, hpa, mingo, bp, mingo,
	kasong

Commit-ID:  02a3e3cdb7f12fb8589e4a2e85d23c9e6544b54a
Gitweb:     https://git.kernel.org/tip/02a3e3cdb7f12fb8589e4a2e85d23c9e6544b54a
Author:     Chao Fan <fanc.fnst@cn.fujitsu.com>
AuthorDate: Wed, 23 Jan 2019 19:08:49 +0800
Committer:  Borislav Petkov <bp@suse.de>
CommitDate: Fri, 1 Feb 2019 11:52:55 +0100

x86/boot: Parse SRAT table and count immovable memory regions

Parse SRAT for the immovable memory regions and use that information to
control which offset KASLR selects so that it doesn't overlap with any
movable region.

 [ bp:
   - Move struct mem_vector where it is visible so that it builds.
   - Correct comments.
   - Rewrite commit message.
   ]

Signed-off-by: Chao Fan <fanc.fnst@cn.fujitsu.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Baoquan He <bhe@redhat.com>
Cc: <caoj.fnst@cn.fujitsu.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <indou.takao@jp.fujitsu.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: <kasong@redhat.com>
Cc: <keescook@chromium.org>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Cc: <msys.mizuma@gmail.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: x86-ml <x86@kernel.org>
Link: https://lkml.kernel.org/r/20190123110850.12433-7-fanc.fnst@cn.fujitsu.com
---
 arch/x86/boot/compressed/acpi.c  | 121 +++++++++++++++++++++++++++++++++++++++
 arch/x86/boot/compressed/kaslr.c |   4 --
 arch/x86/boot/compressed/misc.h  |  10 ++++
 3 files changed, 131 insertions(+), 4 deletions(-)

diff --git a/arch/x86/boot/compressed/acpi.c b/arch/x86/boot/compressed/acpi.c
index b2b50ad5299a..c5a949335d8b 100644
--- a/arch/x86/boot/compressed/acpi.c
+++ b/arch/x86/boot/compressed/acpi.c
@@ -4,9 +4,22 @@
 #include "error.h"
 #include "../string.h"
 
+#include <linux/numa.h>
 #include <linux/efi.h>
 #include <asm/efi.h>
 
+/*
+ * Longest parameter of 'acpi=' is 'copy_dsdt', plus an extra '\0'
+ * for termination.
+ */
+#define MAX_ACPI_ARG_LENGTH 10
+
+/*
+ * Immovable memory regions representation. Max amount of memory regions is
+ * MAX_NUMNODES*2.
+ */
+struct mem_vector immovable_mem[MAX_NUMNODES*2];
+
 /*
  * Max length of 64-bit hex address string is 19, prefix "0x" + 16 hex
  * digits, and '\0' for termination.
@@ -203,3 +216,111 @@ acpi_physical_address get_rsdp_addr(void)
 
 	return pa;
 }
+
+#if defined(CONFIG_RANDOMIZE_BASE) && defined(CONFIG_MEMORY_HOTREMOVE)
+/* Compute SRAT address from RSDP. */
+static unsigned long get_acpi_srat_table(void)
+{
+	unsigned long root_table, acpi_table;
+	struct acpi_table_header *header;
+	struct acpi_table_rsdp *rsdp;
+	u32 num_entries, size, len;
+	char arg[10];
+	u8 *entry;
+
+	rsdp = (struct acpi_table_rsdp *)(long)boot_params->acpi_rsdp_addr;
+	if (!rsdp)
+		return 0;
+
+	/* Get ACPI root table from RSDP.*/
+	if (!(cmdline_find_option("acpi", arg, sizeof(arg)) == 4 &&
+	    !strncmp(arg, "rsdt", 4)) &&
+	    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;
+	}
+
+	if (!root_table)
+		return 0;
+
+	header = (struct acpi_table_header *)root_table;
+	len = header->length;
+	if (len < sizeof(struct acpi_table_header) + size)
+		return 0;
+
+	num_entries = (len - sizeof(struct acpi_table_header)) / size;
+	entry = (u8 *)(root_table + sizeof(struct acpi_table_header));
+
+	while (num_entries--) {
+		if (size == ACPI_RSDT_ENTRY_SIZE)
+			acpi_table = *(u32 *)entry;
+		else
+			acpi_table = *(u64 *)entry;
+
+		if (acpi_table) {
+			header = (struct acpi_table_header *)acpi_table;
+
+			if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_SRAT))
+				return acpi_table;
+		}
+		entry += size;
+	}
+	return 0;
+}
+
+/**
+ * count_immovable_mem_regions - Parse SRAT and cache the immovable
+ * memory regions into the immovable_mem array.
+ *
+ * Return the number of immovable memory regions on success, 0 on failure:
+ *
+ * - Too many immovable memory regions
+ * - ACPI off or no SRAT found
+ * - No immovable memory region found.
+ */
+int count_immovable_mem_regions(void)
+{
+	unsigned long table_addr, table_end, table;
+	struct acpi_subtable_header *sub_table;
+	struct acpi_table_header *table_header;
+	char arg[MAX_ACPI_ARG_LENGTH];
+	int num = 0;
+
+	if (cmdline_find_option("acpi", arg, sizeof(arg)) == 3 &&
+	    !strncmp(arg, "off", 3))
+		return 0;
+
+	table_addr = get_acpi_srat_table();
+	if (!table_addr)
+		return 0;
+
+	table_header = (struct acpi_table_header *)table_addr;
+	table_end = table_addr + table_header->length;
+	table = table_addr + sizeof(struct acpi_table_srat);
+
+	while (table + sizeof(struct acpi_subtable_header) < table_end) {
+		sub_table = (struct acpi_subtable_header *)table;
+		if (sub_table->type == ACPI_SRAT_TYPE_MEMORY_AFFINITY) {
+			struct acpi_srat_mem_affinity *ma;
+
+			ma = (struct acpi_srat_mem_affinity *)sub_table;
+			if (!(ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) && ma->length) {
+				immovable_mem[num].start = ma->base_address;
+				immovable_mem[num].size = ma->length;
+				num++;
+			}
+
+			if (num >= MAX_NUMNODES*2) {
+				debug_putstr("Too many immovable memory regions, aborting.\n");
+				return 0;
+			}
+		}
+		table += sub_table->length;
+	}
+	return num;
+}
+#endif /* CONFIG_RANDOMIZE_BASE && CONFIG_MEMORY_HOTREMOVE */
diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c
index 9ed9709d9947..b251572e77af 100644
--- a/arch/x86/boot/compressed/kaslr.c
+++ b/arch/x86/boot/compressed/kaslr.c
@@ -87,10 +87,6 @@ static unsigned long get_boot_seed(void)
 #define KASLR_COMPRESSED_BOOT
 #include "../../lib/kaslr.c"
 
-struct mem_vector {
-	unsigned long long start;
-	unsigned long long size;
-};
 
 /* Only supporting at most 4 unusable memmap regions with kaslr */
 #define MAX_MEMMAP_REGIONS	4
diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h
index e1dd15769cf3..9911d11c5d09 100644
--- a/arch/x86/boot/compressed/misc.h
+++ b/arch/x86/boot/compressed/misc.h
@@ -72,6 +72,10 @@ int cmdline_find_option(const char *option, char *buffer, int bufsize);
 int cmdline_find_option_bool(const char *option);
 #endif
 
+struct mem_vector {
+	unsigned long long start;
+	unsigned long long size;
+};
 
 #if CONFIG_RANDOMIZE_BASE
 /* kaslr.c */
@@ -126,3 +130,9 @@ acpi_physical_address get_rsdp_addr(void);
 #else
 static inline acpi_physical_address get_rsdp_addr(void) { return 0; }
 #endif
+
+#if defined(CONFIG_RANDOMIZE_BASE) && defined(CONFIG_MEMORY_HOTREMOVE)
+int count_immovable_mem_regions(void);
+#else
+static inline int count_immovable_mem_regions(void) { return 0; }
+#endif

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

* [tip:x86/boot] x86/boot/KASLR: Limit KASLR to extract the kernel in immovable memory only
  2019-01-23 11:08 ` [PATCH v16 7/7] x86/boot/KASLR: Limit KASLR to extracting kernel in immovable memory Chao Fan
@ 2019-02-01 11:02   ` tip-bot for Chao Fan
  0 siblings, 0 replies; 54+ messages in thread
From: tip-bot for Chao Fan @ 2019-02-01 11:02 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: tglx, x86, ard.biesheuvel, hpa, linux-kernel, jgross, mingo,
	kirill.shutemov, bp, dave.hansen, thomas.lendacky, keescook,
	mingo, bhe, fanc.fnst

Commit-ID:  690eaa53205769fd5c0c36e3aa737a615135f969
Gitweb:     https://git.kernel.org/tip/690eaa53205769fd5c0c36e3aa737a615135f969
Author:     Chao Fan <fanc.fnst@cn.fujitsu.com>
AuthorDate: Wed, 23 Jan 2019 19:08:50 +0800
Committer:  Borislav Petkov <bp@suse.de>
CommitDate: Fri, 1 Feb 2019 11:52:55 +0100

x86/boot/KASLR: Limit KASLR to extract the kernel in immovable memory only

KASLR may randomly choose a range which is located in movable memory
regions. As a result, this will break memory hotplug and make the
movable memory chosen by KASLR immovable.

Therefore, limit KASLR to choose memory regions in the immovable range
after consulting the SRAT table.

 [ bp:
    - Rewrite commit message.
    - Trim comments.
 ]

Signed-off-by: Chao Fan <fanc.fnst@cn.fujitsu.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Baoquan He <bhe@redhat.com>
Cc: caoj.fnst@cn.fujitsu.com
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: indou.takao@jp.fujitsu.com
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: kasong@redhat.com
Cc: Kees Cook <keescook@chromium.org>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Cc: msys.mizuma@gmail.com
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: x86-ml <x86@kernel.org>
Link: https://lkml.kernel.org/r/20190123110850.12433-8-fanc.fnst@cn.fujitsu.com
---
 arch/x86/boot/compressed/kaslr.c | 71 +++++++++++++++++++++++++++++++++-------
 arch/x86/boot/compressed/misc.h  |  1 +
 2 files changed, 61 insertions(+), 11 deletions(-)

diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c
index b251572e77af..a2039afe14a7 100644
--- a/arch/x86/boot/compressed/kaslr.c
+++ b/arch/x86/boot/compressed/kaslr.c
@@ -97,6 +97,8 @@ static bool memmap_too_large;
 /* Store memory limit specified by "mem=nn[KMG]" or "memmap=nn[KMG]" */
 static unsigned long long mem_limit = ULLONG_MAX;
 
+/* Number of immovable memory regions */
+static int num_immovable_mem;
 
 enum mem_avoid_index {
 	MEM_AVOID_ZO_RANGE = 0,
@@ -413,6 +415,9 @@ static void mem_avoid_init(unsigned long input, unsigned long input_size,
 	/* Mark the memmap regions we need to avoid */
 	handle_mem_options();
 
+	/* Enumerate the immovable memory regions */
+	num_immovable_mem = count_immovable_mem_regions();
+
 #ifdef CONFIG_X86_VERBOSE_BOOTUP
 	/* Make sure video RAM can be used. */
 	add_identity_map(0, PMD_SIZE);
@@ -568,9 +573,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 __process_mem_region(struct mem_vector *entry,
+				 unsigned long minimum,
+				 unsigned long image_size)
 {
 	struct mem_vector region, overlap;
 	unsigned long start_orig, end;
@@ -646,6 +651,56 @@ 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)
+{
+	int i;
+	/*
+	 * If no immovable memory found, or MEMORY_HOTREMOVE disabled,
+	 * use @region directly.
+	 */
+	if (!num_immovable_mem) {
+		__process_mem_region(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_MEMORY_HOTREMOVE
+	/*
+	 * If immovable memory found, filter the intersection between
+	 * immovable memory and @region.
+	 */
+	for (i = 0; i < num_immovable_mem; i++) {
+		unsigned long long start, end, entry_end, region_end;
+		struct mem_vector entry;
+
+		if (!mem_overlaps(region, &immovable_mem[i]))
+			continue;
+
+		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);
+		entry.size = entry_end - entry.start;
+
+		__process_mem_region(&entry, minimum, image_size);
+
+		if (slot_area_index == MAX_SLOT_AREA) {
+			debug_putstr("Aborted e820/efi memmap scan when walking immovable regions(slot_areas full)!\n");
+			return 1;
+		}
+	}
+	return 0;
+#endif
+}
+
 #ifdef CONFIG_EFI
 /*
  * Returns true if mirror region found (and must have been processed
@@ -711,11 +766,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;
 }
@@ -742,11 +794,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;
-		}
 	}
 }
 
diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h
index 9911d11c5d09..19e8231a6fd6 100644
--- a/arch/x86/boot/compressed/misc.h
+++ b/arch/x86/boot/compressed/misc.h
@@ -132,6 +132,7 @@ static inline acpi_physical_address get_rsdp_addr(void) { return 0; }
 #endif
 
 #if defined(CONFIG_RANDOMIZE_BASE) && defined(CONFIG_MEMORY_HOTREMOVE)
+extern struct mem_vector immovable_mem[MAX_NUMNODES*2];
 int count_immovable_mem_regions(void);
 #else
 static inline int count_immovable_mem_regions(void) { return 0; }

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

* Re: [tip:x86/boot] x86/boot: Early parse RSDP and save it in boot_params
  2019-02-01 11:01   ` [tip:x86/boot] x86/boot: Early parse RSDP and save it " tip-bot for Chao Fan
@ 2019-02-08 19:02     ` Guenter Roeck
  2019-02-08 19:10       ` Borislav Petkov
                         ` (3 more replies)
  0 siblings, 4 replies; 54+ messages in thread
From: Guenter Roeck @ 2019-02-08 19:02 UTC (permalink / raw)
  To: tglx, linux-kernel, kirill.shutemov, bp, fanc.fnst, mingo,
	thomas.lendacky, yamada.masahiro, caoj.fnst, jgross, mingo,
	keescook, x86, hpa
  Cc: linux-tip-commits

Hi,

On Fri, Feb 01, 2019 at 03:01:11AM -0800, tip-bot for Chao Fan wrote:
> Commit-ID:  3a63f70bf4c3a17f5d9c9bf3bc3288a23bdfefce
> Gitweb:     https://git.kernel.org/tip/3a63f70bf4c3a17f5d9c9bf3bc3288a23bdfefce
> Author:     Chao Fan <fanc.fnst@cn.fujitsu.com>
> AuthorDate: Wed, 23 Jan 2019 19:08:48 +0800
> Committer:  Borislav Petkov <bp@suse.de>
> CommitDate: Fri, 1 Feb 2019 11:52:55 +0100
> 
> x86/boot: Early parse RSDP and save it in boot_params
> 
> The RSDP is needed by KASLR so parse it early and save it in
> boot_params.acpi_rsdp_addr, before KASLR setup runs.
> 
> RSDP is needed by other kernel facilities so have the parsing code
> built-in instead of a long "depends on" line in Kconfig.
> 
>  [ bp:
>     - Trim commit message and comments
>     - Add CONFIG_ACPI dependency in the Makefile
>     - Move ->acpi_rsdp_addr assignment with the rest of boot_params massaging in extract_kernel().
>  ]
> 

This patch causes x86_64 boots with efi32 bios to crash early and hard
(before any console output is seen).

Sample qemu command line:

qemu-system-x86_64 -kernel arch/x86/boot/bzImage -M q35 -cpu SandyBridge \
	-no-reboot -snapshot -smp 4 \
	-bios OVMF-pure-efi-32.fd \
	-m 1G \
	-usb -device usb-storage,drive=d0 \
	-drive file=rootfs.squashfs,if=none,id=d0,format=raw \
	--append 'earlycon=uart8250,io,0x3f8,9600n8 root=/dev/sda rootwait panic=-1 console=ttyS0' \
	-nographic

This is with qemu 3.1, though details other than "-bios OVMF-pure-efi-32.fd"
don't really matter.

Files used above are available from https://github.com/groeck/linux-build-test/.

The patch can not be reverted alone, but

Revert "x86/boot/KASLR: Limit KASLR to extract the kernel in immovable memory only"
Revert "x86/boot: Parse SRAT table and count immovable memory regions"
Revert "x86/boot: Early parse RSDP and save it in boot_params"

fixes the problem.

Bisect log attached below.

Guenter

---
# bad: [a46228f6598a191e25ca160870f20c3cd1743d13] Add linux-next specific files for 20190208
# good: [8834f5600cf3c8db365e18a3d5cac2c2780c81e5] Linux 5.0-rc5
git bisect start 'HEAD' 'v5.0-rc5'
# good: [d5ee02f33ec5ade9c9afb9d45bfc4f5cb1375e58] Merge remote-tracking branch 'spi-nor/spi-nor/next'
git bisect good d5ee02f33ec5ade9c9afb9d45bfc4f5cb1375e58
# good: [f34bff29873986d260d7a491fb6f543d12fbe7cd] Merge remote-tracking branch 'devicetree/for-next'
git bisect good f34bff29873986d260d7a491fb6f543d12fbe7cd
# bad: [68182cb929ec6a676655887cbfb12b09662c1e5b] Merge remote-tracking branch 'icc/icc-next'
git bisect bad 68182cb929ec6a676655887cbfb12b09662c1e5b
# bad: [0a5c6189664123753c298d90dec3a5a6b907f06f] Merge remote-tracking branch 'driver-core/driver-core-next'
git bisect bad 0a5c6189664123753c298d90dec3a5a6b907f06f
# bad: [e2a43b09bfc24369719437b5f8f703c5d7003af2] Merge remote-tracking branch 'tip/auto-latest'
git bisect bad e2a43b09bfc24369719437b5f8f703c5d7003af2
# good: [ba1ef96ac73d2a9851dc64d0a991ac8699aa6a22] Merge branch 'timers/core'
git bisect good ba1ef96ac73d2a9851dc64d0a991ac8699aa6a22
# good: [473a78a7bbeb7c77b81b596095f59ce4fbbd49dc] spi-atmel: support inter-word delay
git bisect good 473a78a7bbeb7c77b81b596095f59ce4fbbd49dc
# bad: [132dc31173c99bd252f6a54e3a9fba90f7417a43] Merge branch 'x86/cleanups'
git bisect bad 132dc31173c99bd252f6a54e3a9fba90f7417a43
# bad: [6eb09d138a331121740a4cf7458ab317979d9a17] Merge branch 'x86/boot'
git bisect bad 6eb09d138a331121740a4cf7458ab317979d9a17
# good: [e2c403557ebbcd1f0052e1ae51cfaff596cf259d] Merge branch 'x86/asm'
git bisect good e2c403557ebbcd1f0052e1ae51cfaff596cf259d
# good: [33f0df8d843deb9ec24116dcd79a40ca0ea8e8a9] x86/boot: Search for RSDP in the EFI tables
git bisect good 33f0df8d843deb9ec24116dcd79a40ca0ea8e8a9
# bad: [3a63f70bf4c3a17f5d9c9bf3bc3288a23bdfefce] x86/boot: Early parse RSDP and save it in boot_params
git bisect bad 3a63f70bf4c3a17f5d9c9bf3bc3288a23bdfefce
# good: [93a209aaaad495d7d0bc9b6186a4495934f70402] x86/boot: Search for RSDP in memory
git bisect good 93a209aaaad495d7d0bc9b6186a4495934f70402
# first bad commit: [3a63f70bf4c3a17f5d9c9bf3bc3288a23bdfefce] x86/boot: Early parse RSDP and save it in boot_params

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

* Re: [tip:x86/boot] x86/boot: Early parse RSDP and save it in boot_params
  2019-02-08 19:02     ` Guenter Roeck
@ 2019-02-08 19:10       ` Borislav Petkov
  2019-02-08 20:44         ` Guenter Roeck
  2019-02-11  1:07         ` Chao Fan
  2019-02-11  9:30       ` Chao Fan
                         ` (2 subsequent siblings)
  3 siblings, 2 replies; 54+ messages in thread
From: Borislav Petkov @ 2019-02-08 19:10 UTC (permalink / raw)
  To: Guenter Roeck, fanc.fnst
  Cc: tglx, linux-kernel, kirill.shutemov, mingo, thomas.lendacky,
	yamada.masahiro, caoj.fnst, jgross, mingo, keescook, x86, hpa,
	linux-tip-commits

On Fri, Feb 08, 2019 at 11:02:48AM -0800, Guenter Roeck wrote:
> Hi,
> 
> On Fri, Feb 01, 2019 at 03:01:11AM -0800, tip-bot for Chao Fan wrote:
> > Commit-ID:  3a63f70bf4c3a17f5d9c9bf3bc3288a23bdfefce
> > Gitweb:     https://git.kernel.org/tip/3a63f70bf4c3a17f5d9c9bf3bc3288a23bdfefce
> > Author:     Chao Fan <fanc.fnst@cn.fujitsu.com>
> > AuthorDate: Wed, 23 Jan 2019 19:08:48 +0800
> > Committer:  Borislav Petkov <bp@suse.de>
> > CommitDate: Fri, 1 Feb 2019 11:52:55 +0100
> > 
> > x86/boot: Early parse RSDP and save it in boot_params
> > 
> > The RSDP is needed by KASLR so parse it early and save it in
> > boot_params.acpi_rsdp_addr, before KASLR setup runs.
> > 
> > RSDP is needed by other kernel facilities so have the parsing code
> > built-in instead of a long "depends on" line in Kconfig.
> > 
> >  [ bp:
> >     - Trim commit message and comments
> >     - Add CONFIG_ACPI dependency in the Makefile
> >     - Move ->acpi_rsdp_addr assignment with the rest of boot_params massaging in extract_kernel().
> >  ]
> > 
> 
> This patch causes x86_64 boots with efi32 bios to crash early and hard
> (before any console output is seen).
> 
> Sample qemu command line:
> 
> qemu-system-x86_64 -kernel arch/x86/boot/bzImage -M q35 -cpu SandyBridge \
> 	-no-reboot -snapshot -smp 4 \
> 	-bios OVMF-pure-efi-32.fd \
> 	-m 1G \
> 	-usb -device usb-storage,drive=d0 \
> 	-drive file=rootfs.squashfs,if=none,id=d0,format=raw \
> 	--append 'earlycon=uart8250,io,0x3f8,9600n8 root=/dev/sda rootwait panic=-1 console=ttyS0' \
> 	-nographic
> 
> This is with qemu 3.1, though details other than "-bios OVMF-pure-efi-32.fd"
> don't really matter.
> 
> Files used above are available from https://github.com/groeck/linux-build-test/.
> 
> The patch can not be reverted alone, but
> 
> Revert "x86/boot/KASLR: Limit KASLR to extract the kernel in immovable memory only"
> Revert "x86/boot: Parse SRAT table and count immovable memory regions"
> Revert "x86/boot: Early parse RSDP and save it in boot_params"
> 
> fixes the problem.

Does it per chance at least continue booting if you return 0 and early
from efi_get_rsdp_addr() ?

Chao, pls take a look.

Thx.

-- 
Regards/Gruss,
    Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

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

* Re: [tip:x86/boot] x86/boot: Early parse RSDP and save it in boot_params
  2019-02-08 19:10       ` Borislav Petkov
@ 2019-02-08 20:44         ` Guenter Roeck
  2019-02-08 21:53           ` Borislav Petkov
  2019-02-11  1:07         ` Chao Fan
  1 sibling, 1 reply; 54+ messages in thread
From: Guenter Roeck @ 2019-02-08 20:44 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: fanc.fnst, tglx, linux-kernel, kirill.shutemov, mingo,
	thomas.lendacky, yamada.masahiro, caoj.fnst, jgross, mingo,
	keescook, x86, hpa, linux-tip-commits

On Fri, Feb 08, 2019 at 08:10:24PM +0100, Borislav Petkov wrote:
> On Fri, Feb 08, 2019 at 11:02:48AM -0800, Guenter Roeck wrote:
> > Hi,
> > 
> > On Fri, Feb 01, 2019 at 03:01:11AM -0800, tip-bot for Chao Fan wrote:
> > > Commit-ID:  3a63f70bf4c3a17f5d9c9bf3bc3288a23bdfefce
> > > Gitweb:     https://git.kernel.org/tip/3a63f70bf4c3a17f5d9c9bf3bc3288a23bdfefce
> > > Author:     Chao Fan <fanc.fnst@cn.fujitsu.com>
> > > AuthorDate: Wed, 23 Jan 2019 19:08:48 +0800
> > > Committer:  Borislav Petkov <bp@suse.de>
> > > CommitDate: Fri, 1 Feb 2019 11:52:55 +0100
> > > 
> > > x86/boot: Early parse RSDP and save it in boot_params
> > > 
> > > The RSDP is needed by KASLR so parse it early and save it in
> > > boot_params.acpi_rsdp_addr, before KASLR setup runs.
> > > 
> > > RSDP is needed by other kernel facilities so have the parsing code
> > > built-in instead of a long "depends on" line in Kconfig.
> > > 
> > >  [ bp:
> > >     - Trim commit message and comments
> > >     - Add CONFIG_ACPI dependency in the Makefile
> > >     - Move ->acpi_rsdp_addr assignment with the rest of boot_params massaging in extract_kernel().
> > >  ]
> > > 
> > 
> > This patch causes x86_64 boots with efi32 bios to crash early and hard
> > (before any console output is seen).
> > 
> > Sample qemu command line:
> > 
> > qemu-system-x86_64 -kernel arch/x86/boot/bzImage -M q35 -cpu SandyBridge \
> > 	-no-reboot -snapshot -smp 4 \
> > 	-bios OVMF-pure-efi-32.fd \
> > 	-m 1G \
> > 	-usb -device usb-storage,drive=d0 \
> > 	-drive file=rootfs.squashfs,if=none,id=d0,format=raw \
> > 	--append 'earlycon=uart8250,io,0x3f8,9600n8 root=/dev/sda rootwait panic=-1 console=ttyS0' \
> > 	-nographic
> > 
> > This is with qemu 3.1, though details other than "-bios OVMF-pure-efi-32.fd"
> > don't really matter.
> > 
> > Files used above are available from https://github.com/groeck/linux-build-test/.
> > 
> > The patch can not be reverted alone, but
> > 
> > Revert "x86/boot/KASLR: Limit KASLR to extract the kernel in immovable memory only"
> > Revert "x86/boot: Parse SRAT table and count immovable memory regions"
> > Revert "x86/boot: Early parse RSDP and save it in boot_params"
> > 
> > fixes the problem.
> 
> Does it per chance at least continue booting if you return 0 and early
> from efi_get_rsdp_addr() ?
> 
Yes, the kernel boots if I comment out that function and have it return 0.

Guenter

> Chao, pls take a look.
> 
> Thx.
> 
> -- 
> Regards/Gruss,
>     Boris.
> 
> Good mailing practices for 400: avoid top-posting and trim the reply.

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

* Re: [tip:x86/boot] x86/boot: Early parse RSDP and save it in boot_params
  2019-02-08 20:44         ` Guenter Roeck
@ 2019-02-08 21:53           ` Borislav Petkov
  2019-02-11  0:22             ` Borislav Petkov
  0 siblings, 1 reply; 54+ messages in thread
From: Borislav Petkov @ 2019-02-08 21:53 UTC (permalink / raw)
  To: Guenter Roeck
  Cc: fanc.fnst, tglx, linux-kernel, kirill.shutemov, mingo,
	thomas.lendacky, yamada.masahiro, caoj.fnst, jgross, mingo,
	keescook, x86, hpa, linux-tip-commits

On Fri, Feb 08, 2019 at 12:44:51PM -0800, Guenter Roeck wrote:
> Yes, the kernel boots if I comment out that function and have it return 0.

Thanks, this localizes the issue significantly.

-- 
Regards/Gruss,
    Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

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

* Re: [tip:x86/boot] x86/boot: Early parse RSDP and save it in boot_params
  2019-02-08 21:53           ` Borislav Petkov
@ 2019-02-11  0:22             ` Borislav Petkov
  2019-02-11  1:33               ` Chao Fan
  2019-02-11  9:46               ` Ard Biesheuvel
  0 siblings, 2 replies; 54+ messages in thread
From: Borislav Petkov @ 2019-02-11  0:22 UTC (permalink / raw)
  To: Guenter Roeck
  Cc: fanc.fnst, tglx, linux-kernel, kirill.shutemov, mingo,
	thomas.lendacky, yamada.masahiro, caoj.fnst, jgross, mingo,
	keescook, x86, hpa, linux-tip-commits, Ard Biesheuvel,
	Matt Fleming

On Fri, Feb 08, 2019 at 10:53:22PM +0100, Borislav Petkov wrote:
> On Fri, Feb 08, 2019 at 12:44:51PM -0800, Guenter Roeck wrote:
> > Yes, the kernel boots if I comment out that function and have it return 0.
> 
> Thanks, this localizes the issue significantly.

Some observations:

                } else {
                        efi_config_table_32_t *tmp_table;

                        tmp_table = config_tables;
                        guid = tmp_table->guid;			<--- *
                        table = tmp_table->table;
                }

It blows up at that tmp_table->guid deref above. Singlestepping through
it with gdb shows:

# arch/x86/boot/compressed/acpi.c:114: 			guid = tmp_table->guid;
	movq	(%rdi), %rax	# MEM[(struct efi_config_table_32_t *)config_tables_37].guid, guid
	movq	8(%rdi), %rsi	# MEM[(struct efi_config_table_32_t *)config_tables_37].guid, guid
# arch/x86/boot/compressed/acpi.c:115: 			table = tmp_table->table;
	movl	16(%rdi), %r10d	# MEM[(struct efi_config_table_32_t *)config_tables_37].table, table
	jmp	.L30	#

and %rdi has:

	rdi            0x630646870

which is an address above 4G but we're using a 32-bit EFI BIOS.

Which begs the question whether EFI system tables can even be mapped at
something above 4G with a 32-bit EFI and whether that could work ok.
Hmm.

Lemme add Ard and mfleming for insight here.

Thx.

-- 
Regards/Gruss,
    Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

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

* Re: [tip:x86/boot] x86/boot: Early parse RSDP and save it in boot_params
  2019-02-08 19:10       ` Borislav Petkov
  2019-02-08 20:44         ` Guenter Roeck
@ 2019-02-11  1:07         ` Chao Fan
  1 sibling, 0 replies; 54+ messages in thread
From: Chao Fan @ 2019-02-11  1:07 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: Guenter Roeck, tglx, linux-kernel, kirill.shutemov, mingo,
	thomas.lendacky, yamada.masahiro, caoj.fnst, jgross, mingo,
	keescook, x86, hpa, linux-tip-commits

On Fri, Feb 08, 2019 at 08:10:24PM +0100, Borislav Petkov wrote:
>On Fri, Feb 08, 2019 at 11:02:48AM -0800, Guenter Roeck wrote:
>> Hi,
>> 
>> On Fri, Feb 01, 2019 at 03:01:11AM -0800, tip-bot for Chao Fan wrote:
>> > Commit-ID:  3a63f70bf4c3a17f5d9c9bf3bc3288a23bdfefce
>> > Gitweb:     https://git.kernel.org/tip/3a63f70bf4c3a17f5d9c9bf3bc3288a23bdfefce
>> > Author:     Chao Fan <fanc.fnst@cn.fujitsu.com>
>> > AuthorDate: Wed, 23 Jan 2019 19:08:48 +0800
>> > Committer:  Borislav Petkov <bp@suse.de>
>> > CommitDate: Fri, 1 Feb 2019 11:52:55 +0100
>> > 
>> > x86/boot: Early parse RSDP and save it in boot_params
>> > 
>> > The RSDP is needed by KASLR so parse it early and save it in
>> > boot_params.acpi_rsdp_addr, before KASLR setup runs.
>> > 
>> > RSDP is needed by other kernel facilities so have the parsing code
>> > built-in instead of a long "depends on" line in Kconfig.
>> > 
>> >  [ bp:
>> >     - Trim commit message and comments
>> >     - Add CONFIG_ACPI dependency in the Makefile
>> >     - Move ->acpi_rsdp_addr assignment with the rest of boot_params massaging in extract_kernel().
>> >  ]
>> > 
>> 
>> This patch causes x86_64 boots with efi32 bios to crash early and hard
>> (before any console output is seen).
>> 
>> Sample qemu command line:
>> 
>> qemu-system-x86_64 -kernel arch/x86/boot/bzImage -M q35 -cpu SandyBridge \
>> 	-no-reboot -snapshot -smp 4 \
>> 	-bios OVMF-pure-efi-32.fd \
>> 	-m 1G \
>> 	-usb -device usb-storage,drive=d0 \
>> 	-drive file=rootfs.squashfs,if=none,id=d0,format=raw \
>> 	--append 'earlycon=uart8250,io,0x3f8,9600n8 root=/dev/sda rootwait panic=-1 console=ttyS0' \
>> 	-nographic
>> 
>> This is with qemu 3.1, though details other than "-bios OVMF-pure-efi-32.fd"
>> don't really matter.
>> 
>> Files used above are available from https://github.com/groeck/linux-build-test/.
>> 
>> The patch can not be reverted alone, but
>> 
>> Revert "x86/boot/KASLR: Limit KASLR to extract the kernel in immovable memory only"
>> Revert "x86/boot: Parse SRAT table and count immovable memory regions"
>> Revert "x86/boot: Early parse RSDP and save it in boot_params"
>> 
>> fixes the problem.
>
>Does it per chance at least continue booting if you return 0 and early
>from efi_get_rsdp_addr() ?
>
>Chao, pls take a look.

Sorry for delay, last several days were holiday, so I was away from
keyboard. I will take a look.

Thanks,
Chao Fan
>
>Thx.
>
>-- 
>Regards/Gruss,
>    Boris.
>
>Good mailing practices for 400: avoid top-posting and trim the reply.
>
>



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

* Re: [tip:x86/boot] x86/boot: Early parse RSDP and save it in boot_params
  2019-02-11  0:22             ` Borislav Petkov
@ 2019-02-11  1:33               ` Chao Fan
  2019-02-11  9:46               ` Ard Biesheuvel
  1 sibling, 0 replies; 54+ messages in thread
From: Chao Fan @ 2019-02-11  1:33 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: Guenter Roeck, tglx, linux-kernel, kirill.shutemov, mingo,
	thomas.lendacky, yamada.masahiro, caoj.fnst, jgross, mingo,
	keescook, x86, hpa, linux-tip-commits, Ard Biesheuvel,
	Matt Fleming

On Mon, Feb 11, 2019 at 01:22:20AM +0100, Borislav Petkov wrote:
>On Fri, Feb 08, 2019 at 10:53:22PM +0100, Borislav Petkov wrote:
>> On Fri, Feb 08, 2019 at 12:44:51PM -0800, Guenter Roeck wrote:
>> > Yes, the kernel boots if I comment out that function and have it return 0.
>> 
>> Thanks, this localizes the issue significantly.
>
>Some observations:
>
>                } else {
>                        efi_config_table_32_t *tmp_table;
>
>                        tmp_table = config_tables;
>                        guid = tmp_table->guid;			<--- *
>                        table = tmp_table->table;
>                }
>
>It blows up at that tmp_table->guid deref above. Singlestepping through
>it with gdb shows:
>
># arch/x86/boot/compressed/acpi.c:114: 			guid = tmp_table->guid;
>	movq	(%rdi), %rax	# MEM[(struct efi_config_table_32_t *)config_tables_37].guid, guid
>	movq	8(%rdi), %rsi	# MEM[(struct efi_config_table_32_t *)config_tables_37].guid, guid
># arch/x86/boot/compressed/acpi.c:115: 			table = tmp_table->table;
>	movl	16(%rdi), %r10d	# MEM[(struct efi_config_table_32_t *)config_tables_37].table, table
>	jmp	.L30	#
>
>and %rdi has:
>
>	rdi            0x630646870
>
>which is an address above 4G but we're using a 32-bit EFI BIOS.
>
>Which begs the question whether EFI system tables can even be mapped at
>something above 4G with a 32-bit EFI and whether that could work ok.
>Hmm.

Thanks for your help. As you said, I am not wure whether 32-bit EFI can
map table address above 4G.
If the map method has problem, I think adding a check here can work.

Thanks,
Chao Fan

>
>Lemme add Ard and mfleming for insight here.
>
>Thx.
>
>-- 
>Regards/Gruss,
>    Boris.
>
>Good mailing practices for 400: avoid top-posting and trim the reply.
>
>



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

* Re: [tip:x86/boot] x86/boot: Early parse RSDP and save it in boot_params
  2019-02-08 19:02     ` Guenter Roeck
  2019-02-08 19:10       ` Borislav Petkov
@ 2019-02-11  9:30       ` Chao Fan
  2019-02-11 10:08         ` Borislav Petkov
  2019-02-13  9:06       ` [tip:x86/boot] x86/boot: Correct RSDP parsing with 32-bit EFI tip-bot for Borislav Petkov
  2019-02-13 11:27       ` tip-bot for Borislav Petkov
  3 siblings, 1 reply; 54+ messages in thread
From: Chao Fan @ 2019-02-11  9:30 UTC (permalink / raw)
  To: Guenter Roeck
  Cc: tglx, linux-kernel, kirill.shutemov, bp, mingo, thomas.lendacky,
	yamada.masahiro, caoj.fnst, jgross, mingo, keescook, x86, hpa,
	linux-tip-commits

On Fri, Feb 08, 2019 at 11:02:48AM -0800, Guenter Roeck wrote:
>Hi,
>
>On Fri, Feb 01, 2019 at 03:01:11AM -0800, tip-bot for Chao Fan wrote:
>> Commit-ID:  3a63f70bf4c3a17f5d9c9bf3bc3288a23bdfefce
>> Gitweb:     https://git.kernel.org/tip/3a63f70bf4c3a17f5d9c9bf3bc3288a23bdfefce
>> Author:     Chao Fan <fanc.fnst@cn.fujitsu.com>
>> AuthorDate: Wed, 23 Jan 2019 19:08:48 +0800
>> Committer:  Borislav Petkov <bp@suse.de>
>> CommitDate: Fri, 1 Feb 2019 11:52:55 +0100
>> 
>> x86/boot: Early parse RSDP and save it in boot_params
>> 
>> The RSDP is needed by KASLR so parse it early and save it in
>> boot_params.acpi_rsdp_addr, before KASLR setup runs.
>> 
>> RSDP is needed by other kernel facilities so have the parsing code
>> built-in instead of a long "depends on" line in Kconfig.
>> 
>>  [ bp:
>>     - Trim commit message and comments
>>     - Add CONFIG_ACPI dependency in the Makefile
>>     - Move ->acpi_rsdp_addr assignment with the rest of boot_params massaging in extract_kernel().
>>  ]
>> 
>
>This patch causes x86_64 boots with efi32 bios to crash early and hard
>(before any console output is seen).
>
>Sample qemu command line:
>
>qemu-system-x86_64 -kernel arch/x86/boot/bzImage -M q35 -cpu SandyBridge \
>	-no-reboot -snapshot -smp 4 \
>	-bios OVMF-pure-efi-32.fd \
>	-m 1G \
>	-usb -device usb-storage,drive=d0 \
>	-drive file=rootfs.squashfs,if=none,id=d0,format=raw \
>	--append 'earlycon=uart8250,io,0x3f8,9600n8 root=/dev/sda rootwait panic=-1 console=ttyS0' \
>	-nographic
>
>This is with qemu 3.1, though details other than "-bios OVMF-pure-efi-32.fd"
>don't really matter.

Yes, I download your ovmf file in linux-build-test/rootfs/firmware/ from
your link. There are two files, efi32 and efi64. Then I try to run:

BIOS=/usr/share/edk2/ovmf/OVMF-pure-efi-32.fd
qemu-system-x86_64 \
-bios $BIOS \
-cdrom /var/lib/libvirt/images/iso/Fedora-Workstation-Live-x86_64-29-1.2.iso \
-hda /var/lib/libvirt/images/fedora-efi32.qcow2 \
-enable-kvm \
-m 5G \
-serial stdio

It can't boot, but if I changed as:
BIOS=/usr/share/edk2/ovmf/OVMF-pure-efi-64.fd

Then the machine booted. So I am not sure how to use this
OVMF-pure-efi-32.fd. If there is somethins wrong in my understand,
please let me know.

Thanks,
Chao Fan

>
>Files used above are available from https://github.com/groeck/linux-build-test/.
>
>The patch can not be reverted alone, but
>
>Revert "x86/boot/KASLR: Limit KASLR to extract the kernel in immovable memory only"
>Revert "x86/boot: Parse SRAT table and count immovable memory regions"
>Revert "x86/boot: Early parse RSDP and save it in boot_params"
>
>fixes the problem.
>
>Bisect log attached below.
>
>Guenter
>
>---
># bad: [a46228f6598a191e25ca160870f20c3cd1743d13] Add linux-next specific files for 20190208
># good: [8834f5600cf3c8db365e18a3d5cac2c2780c81e5] Linux 5.0-rc5
>git bisect start 'HEAD' 'v5.0-rc5'
># good: [d5ee02f33ec5ade9c9afb9d45bfc4f5cb1375e58] Merge remote-tracking branch 'spi-nor/spi-nor/next'
>git bisect good d5ee02f33ec5ade9c9afb9d45bfc4f5cb1375e58
># good: [f34bff29873986d260d7a491fb6f543d12fbe7cd] Merge remote-tracking branch 'devicetree/for-next'
>git bisect good f34bff29873986d260d7a491fb6f543d12fbe7cd
># bad: [68182cb929ec6a676655887cbfb12b09662c1e5b] Merge remote-tracking branch 'icc/icc-next'
>git bisect bad 68182cb929ec6a676655887cbfb12b09662c1e5b
># bad: [0a5c6189664123753c298d90dec3a5a6b907f06f] Merge remote-tracking branch 'driver-core/driver-core-next'
>git bisect bad 0a5c6189664123753c298d90dec3a5a6b907f06f
># bad: [e2a43b09bfc24369719437b5f8f703c5d7003af2] Merge remote-tracking branch 'tip/auto-latest'
>git bisect bad e2a43b09bfc24369719437b5f8f703c5d7003af2
># good: [ba1ef96ac73d2a9851dc64d0a991ac8699aa6a22] Merge branch 'timers/core'
>git bisect good ba1ef96ac73d2a9851dc64d0a991ac8699aa6a22
># good: [473a78a7bbeb7c77b81b596095f59ce4fbbd49dc] spi-atmel: support inter-word delay
>git bisect good 473a78a7bbeb7c77b81b596095f59ce4fbbd49dc
># bad: [132dc31173c99bd252f6a54e3a9fba90f7417a43] Merge branch 'x86/cleanups'
>git bisect bad 132dc31173c99bd252f6a54e3a9fba90f7417a43
># bad: [6eb09d138a331121740a4cf7458ab317979d9a17] Merge branch 'x86/boot'
>git bisect bad 6eb09d138a331121740a4cf7458ab317979d9a17
># good: [e2c403557ebbcd1f0052e1ae51cfaff596cf259d] Merge branch 'x86/asm'
>git bisect good e2c403557ebbcd1f0052e1ae51cfaff596cf259d
># good: [33f0df8d843deb9ec24116dcd79a40ca0ea8e8a9] x86/boot: Search for RSDP in the EFI tables
>git bisect good 33f0df8d843deb9ec24116dcd79a40ca0ea8e8a9
># bad: [3a63f70bf4c3a17f5d9c9bf3bc3288a23bdfefce] x86/boot: Early parse RSDP and save it in boot_params
>git bisect bad 3a63f70bf4c3a17f5d9c9bf3bc3288a23bdfefce
># good: [93a209aaaad495d7d0bc9b6186a4495934f70402] x86/boot: Search for RSDP in memory
>git bisect good 93a209aaaad495d7d0bc9b6186a4495934f70402
># first bad commit: [3a63f70bf4c3a17f5d9c9bf3bc3288a23bdfefce] x86/boot: Early parse RSDP and save it in boot_params
>
>



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

* Re: [tip:x86/boot] x86/boot: Early parse RSDP and save it in boot_params
  2019-02-11  0:22             ` Borislav Petkov
  2019-02-11  1:33               ` Chao Fan
@ 2019-02-11  9:46               ` Ard Biesheuvel
  2019-02-11  9:55                 ` Chao Fan
  1 sibling, 1 reply; 54+ messages in thread
From: Ard Biesheuvel @ 2019-02-11  9:46 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: Guenter Roeck, fanc.fnst, Thomas Gleixner,
	Linux Kernel Mailing List, Kirill A. Shutemov, Ingo Molnar,
	Lendacky, Thomas, Masahiro Yamada, caoj.fnst, Juergen Gross,
	Ingo Molnar, Kees Cook, the arch/x86 maintainers, H. Peter Anvin,
	linux-tip-commits, Matt Fleming

On Mon, 11 Feb 2019 at 01:22, Borislav Petkov <bp@alien8.de> wrote:
>
> On Fri, Feb 08, 2019 at 10:53:22PM +0100, Borislav Petkov wrote:
> > On Fri, Feb 08, 2019 at 12:44:51PM -0800, Guenter Roeck wrote:
> > > Yes, the kernel boots if I comment out that function and have it return 0.
> >
> > Thanks, this localizes the issue significantly.
>
> Some observations:
>
>                 } else {
>                         efi_config_table_32_t *tmp_table;
>
>                         tmp_table = config_tables;
>                         guid = tmp_table->guid;                 <--- *
>                         table = tmp_table->table;
>                 }
>
> It blows up at that tmp_table->guid deref above. Singlestepping through
> it with gdb shows:
>
> # arch/x86/boot/compressed/acpi.c:114:                  guid = tmp_table->guid;
>         movq    (%rdi), %rax    # MEM[(struct efi_config_table_32_t *)config_tables_37].guid, guid
>         movq    8(%rdi), %rsi   # MEM[(struct efi_config_table_32_t *)config_tables_37].guid, guid
> # arch/x86/boot/compressed/acpi.c:115:                  table = tmp_table->table;
>         movl    16(%rdi), %r10d # MEM[(struct efi_config_table_32_t *)config_tables_37].table, table
>         jmp     .L30    #
>
> and %rdi has:
>
>         rdi            0x630646870
>
> which is an address above 4G but we're using a 32-bit EFI BIOS.
>
> Which begs the question whether EFI system tables can even be mapped at
> something above 4G with a 32-bit EFI and whether that could work ok.
> Hmm.
>
> Lemme add Ard and mfleming for insight here.
>

-ENOCONTEXT, but let me try in any case:

linux/efi.h has

typedef struct {
  efi_guid_t guid;
  u32 table;
} efi_config_table_32_t;

so if we end up with more than 32 bits set in table, there is
something seriously wrong.

The size of efi_config_table_32_t deviates from efi_config_table_64_t,
so you will have to ensure that you are using the correct stride when
iterating over config_tables.

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

* Re: [tip:x86/boot] x86/boot: Early parse RSDP and save it in boot_params
  2019-02-11  9:46               ` Ard Biesheuvel
@ 2019-02-11  9:55                 ` Chao Fan
  2019-02-11  9:57                   ` Ard Biesheuvel
  0 siblings, 1 reply; 54+ messages in thread
From: Chao Fan @ 2019-02-11  9:55 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Borislav Petkov, Guenter Roeck, Thomas Gleixner,
	Linux Kernel Mailing List, Kirill A. Shutemov, Ingo Molnar,
	Lendacky, Thomas, Masahiro Yamada, caoj.fnst, Juergen Gross,
	Ingo Molnar, Kees Cook, the arch/x86 maintainers, H. Peter Anvin,
	linux-tip-commits, Matt Fleming

On Mon, Feb 11, 2019 at 09:46:03AM +0000, Ard Biesheuvel wrote:
>On Mon, 11 Feb 2019 at 01:22, Borislav Petkov <bp@alien8.de> wrote:
>>
>> On Fri, Feb 08, 2019 at 10:53:22PM +0100, Borislav Petkov wrote:
>> > On Fri, Feb 08, 2019 at 12:44:51PM -0800, Guenter Roeck wrote:
>> > > Yes, the kernel boots if I comment out that function and have it return 0.
>> >
>> > Thanks, this localizes the issue significantly.
>>
>> Some observations:
>>
>>                 } else {
>>                         efi_config_table_32_t *tmp_table;
>>
>>                         tmp_table = config_tables;
>>                         guid = tmp_table->guid;                 <--- *
>>                         table = tmp_table->table;
>>                 }
>>
>> It blows up at that tmp_table->guid deref above. Singlestepping through
>> it with gdb shows:
>>
>> # arch/x86/boot/compressed/acpi.c:114:                  guid = tmp_table->guid;
>>         movq    (%rdi), %rax    # MEM[(struct efi_config_table_32_t *)config_tables_37].guid, guid
>>         movq    8(%rdi), %rsi   # MEM[(struct efi_config_table_32_t *)config_tables_37].guid, guid
>> # arch/x86/boot/compressed/acpi.c:115:                  table = tmp_table->table;
>>         movl    16(%rdi), %r10d # MEM[(struct efi_config_table_32_t *)config_tables_37].table, table
>>         jmp     .L30    #
>>
>> and %rdi has:
>>
>>         rdi            0x630646870
>>
>> which is an address above 4G but we're using a 32-bit EFI BIOS.
>>
>> Which begs the question whether EFI system tables can even be mapped at
>> something above 4G with a 32-bit EFI and whether that could work ok.
>> Hmm.
>>
>> Lemme add Ard and mfleming for insight here.
>>
>
>-ENOCONTEXT, but let me try in any case:
>
>linux/efi.h has
>
>typedef struct {
>  efi_guid_t guid;
>  u32 table;
>} efi_config_table_32_t;
>
>so if we end up with more than 32 bits set in table, there is
>something seriously wrong.
>
>The size of efi_config_table_32_t deviates from efi_config_table_64_t,
>so you will have to ensure that you are using the correct stride when
>iterating over config_tables.

Here I use signature to judge it.
If the signature is EFI64_LOADER_SIGNATURE, I will use efi_config_table_64_t,
if the signature is EFI32_LOADER_SIGNATURE, I will use efi_config_table_32_t.
But the efi32 whose signature is EFI32_LOADER_SIGNATURE points to a
address above 4G, I am not sure whether this is normal and works well.

Thanks,
Chao Fan

>
>



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

* Re: [tip:x86/boot] x86/boot: Early parse RSDP and save it in boot_params
  2019-02-11  9:55                 ` Chao Fan
@ 2019-02-11  9:57                   ` Ard Biesheuvel
  2019-02-11 10:10                     ` Chao Fan
  0 siblings, 1 reply; 54+ messages in thread
From: Ard Biesheuvel @ 2019-02-11  9:57 UTC (permalink / raw)
  To: Chao Fan
  Cc: Borislav Petkov, Guenter Roeck, Thomas Gleixner,
	Linux Kernel Mailing List, Kirill A. Shutemov, Ingo Molnar,
	Lendacky, Thomas, Masahiro Yamada, caoj.fnst, Juergen Gross,
	Ingo Molnar, Kees Cook, the arch/x86 maintainers, H. Peter Anvin,
	linux-tip-commits, Matt Fleming

On Mon, 11 Feb 2019 at 10:56, Chao Fan <fanc.fnst@cn.fujitsu.com> wrote:
>
> On Mon, Feb 11, 2019 at 09:46:03AM +0000, Ard Biesheuvel wrote:
> >On Mon, 11 Feb 2019 at 01:22, Borislav Petkov <bp@alien8.de> wrote:
> >>
> >> On Fri, Feb 08, 2019 at 10:53:22PM +0100, Borislav Petkov wrote:
> >> > On Fri, Feb 08, 2019 at 12:44:51PM -0800, Guenter Roeck wrote:
> >> > > Yes, the kernel boots if I comment out that function and have it return 0.
> >> >
> >> > Thanks, this localizes the issue significantly.
> >>
> >> Some observations:
> >>
> >>                 } else {
> >>                         efi_config_table_32_t *tmp_table;
> >>
> >>                         tmp_table = config_tables;
> >>                         guid = tmp_table->guid;                 <--- *
> >>                         table = tmp_table->table;
> >>                 }
> >>
> >> It blows up at that tmp_table->guid deref above. Singlestepping through
> >> it with gdb shows:
> >>
> >> # arch/x86/boot/compressed/acpi.c:114:                  guid = tmp_table->guid;
> >>         movq    (%rdi), %rax    # MEM[(struct efi_config_table_32_t *)config_tables_37].guid, guid
> >>         movq    8(%rdi), %rsi   # MEM[(struct efi_config_table_32_t *)config_tables_37].guid, guid
> >> # arch/x86/boot/compressed/acpi.c:115:                  table = tmp_table->table;
> >>         movl    16(%rdi), %r10d # MEM[(struct efi_config_table_32_t *)config_tables_37].table, table
> >>         jmp     .L30    #
> >>
> >> and %rdi has:
> >>
> >>         rdi            0x630646870
> >>
> >> which is an address above 4G but we're using a 32-bit EFI BIOS.
> >>
> >> Which begs the question whether EFI system tables can even be mapped at
> >> something above 4G with a 32-bit EFI and whether that could work ok.
> >> Hmm.
> >>
> >> Lemme add Ard and mfleming for insight here.
> >>
> >
> >-ENOCONTEXT, but let me try in any case:
> >
> >linux/efi.h has
> >
> >typedef struct {
> >  efi_guid_t guid;
> >  u32 table;
> >} efi_config_table_32_t;
> >
> >so if we end up with more than 32 bits set in table, there is
> >something seriously wrong.
> >
> >The size of efi_config_table_32_t deviates from efi_config_table_64_t,
> >so you will have to ensure that you are using the correct stride when
> >iterating over config_tables.
>
> Here I use signature to judge it.
> If the signature is EFI64_LOADER_SIGNATURE, I will use efi_config_table_64_t,
> if the signature is EFI32_LOADER_SIGNATURE, I will use efi_config_table_32_t.
> But the efi32 whose signature is EFI32_LOADER_SIGNATURE points to a
> address above 4G, I am not sure whether this is normal and works well.
>

This is impossible. The 'table' member of efi_config_table_32_t is
only 32 bits wide, so how can it contain an address over 4 GB ?

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

* Re: [tip:x86/boot] x86/boot: Early parse RSDP and save it in boot_params
  2019-02-11  9:30       ` Chao Fan
@ 2019-02-11 10:08         ` Borislav Petkov
  2019-02-11 13:03           ` Chao Fan
  2019-02-11 14:08           ` Guenter Roeck
  0 siblings, 2 replies; 54+ messages in thread
From: Borislav Petkov @ 2019-02-11 10:08 UTC (permalink / raw)
  To: Chao Fan
  Cc: Guenter Roeck, tglx, linux-kernel, kirill.shutemov, mingo,
	thomas.lendacky, yamada.masahiro, caoj.fnst, jgross, mingo,
	keescook, x86, hpa, linux-tip-commits

On Mon, Feb 11, 2019 at 05:30:33PM +0800, Chao Fan wrote:
> Yes, I download your ovmf file in linux-build-test/rootfs/firmware/ from
> your link. There are two files, efi32 and efi64. Then I try to run:

You need both OVMF-pure-efi-32.fd and rootfs.squashfs from the repo. And
then this works here. Just put the script below and the two files in a
directory and point to the kernel where you're building with -kernel.

---
#!/bin/bash

qemu-system-x86_64 -kernel ~/kernel/linux/arch/x86/boot/bzImage -M q35 -cpu SandyBridge \
        -no-reboot -snapshot -smp 1 \
        -gdb tcp::1235 \
        -bios OVMF-pure-efi-32.fd \
        -m 1G \
        -net nic,model=rtl8139,macaddr=12:34:56:78:12:34 \
        -usb -device usb-storage,drive=d0 \
        -drive file=rootfs.squashfs,if=none,id=d0,format=raw \
        --append 'earlycon=uart8250,io,0x3f8,9600n8 root=/dev/sda rootwait panic=-1 earlyprintk=ttyS0,115200,keep console=ttyS0,115200' \
        -monitor pty \
        -serial file:log

I've added some options for debugging.

-- 
Regards/Gruss,
    Boris.

SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)

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

* Re: [tip:x86/boot] x86/boot: Early parse RSDP and save it in boot_params
  2019-02-11  9:57                   ` Ard Biesheuvel
@ 2019-02-11 10:10                     ` Chao Fan
  2019-02-11 10:17                       ` Ard Biesheuvel
  0 siblings, 1 reply; 54+ messages in thread
From: Chao Fan @ 2019-02-11 10:10 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Borislav Petkov, Guenter Roeck, Thomas Gleixner,
	Linux Kernel Mailing List, Kirill A. Shutemov, Ingo Molnar,
	Lendacky, Thomas, Masahiro Yamada, caoj.fnst, Juergen Gross,
	Ingo Molnar, Kees Cook, the arch/x86 maintainers, H. Peter Anvin,
	linux-tip-commits, Matt Fleming

On Mon, Feb 11, 2019 at 09:57:02AM +0000, Ard Biesheuvel wrote:
>On Mon, 11 Feb 2019 at 10:56, Chao Fan <fanc.fnst@cn.fujitsu.com> wrote:
>>
>> On Mon, Feb 11, 2019 at 09:46:03AM +0000, Ard Biesheuvel wrote:
>> >On Mon, 11 Feb 2019 at 01:22, Borislav Petkov <bp@alien8.de> wrote:
>> >>
>> >> On Fri, Feb 08, 2019 at 10:53:22PM +0100, Borislav Petkov wrote:
>> >> > On Fri, Feb 08, 2019 at 12:44:51PM -0800, Guenter Roeck wrote:
>> >> > > Yes, the kernel boots if I comment out that function and have it return 0.
>> >> >
>> >> > Thanks, this localizes the issue significantly.
>> >>
>> >> Some observations:
>> >>
>> >>                 } else {
>> >>                         efi_config_table_32_t *tmp_table;
>> >>
>> >>                         tmp_table = config_tables;
>> >>                         guid = tmp_table->guid;                 <--- *
>> >>                         table = tmp_table->table;
>> >>                 }
>> >>
>> >> It blows up at that tmp_table->guid deref above. Singlestepping through
>> >> it with gdb shows:
>> >>
>> >> # arch/x86/boot/compressed/acpi.c:114:                  guid = tmp_table->guid;
>> >>         movq    (%rdi), %rax    # MEM[(struct efi_config_table_32_t *)config_tables_37].guid, guid
>> >>         movq    8(%rdi), %rsi   # MEM[(struct efi_config_table_32_t *)config_tables_37].guid, guid
>> >> # arch/x86/boot/compressed/acpi.c:115:                  table = tmp_table->table;
>> >>         movl    16(%rdi), %r10d # MEM[(struct efi_config_table_32_t *)config_tables_37].table, table
>> >>         jmp     .L30    #
>> >>
>> >> and %rdi has:
>> >>
>> >>         rdi            0x630646870
>> >>
>> >> which is an address above 4G but we're using a 32-bit EFI BIOS.
>> >>
>> >> Which begs the question whether EFI system tables can even be mapped at
>> >> something above 4G with a 32-bit EFI and whether that could work ok.
>> >> Hmm.
>> >>
>> >> Lemme add Ard and mfleming for insight here.
>> >>
>> >
>> >-ENOCONTEXT, but let me try in any case:
>> >
>> >linux/efi.h has
>> >
>> >typedef struct {
>> >  efi_guid_t guid;
>> >  u32 table;
>> >} efi_config_table_32_t;
>> >
>> >so if we end up with more than 32 bits set in table, there is
>> >something seriously wrong.
>> >
>> >The size of efi_config_table_32_t deviates from efi_config_table_64_t,
>> >so you will have to ensure that you are using the correct stride when
>> >iterating over config_tables.
>>
>> Here I use signature to judge it.
>> If the signature is EFI64_LOADER_SIGNATURE, I will use efi_config_table_64_t,
>> if the signature is EFI32_LOADER_SIGNATURE, I will use efi_config_table_32_t.
>> But the efi32 whose signature is EFI32_LOADER_SIGNATURE points to a
>> address above 4G, I am not sure whether this is normal and works well.
>>
>
>This is impossible. The 'table' member of efi_config_table_32_t is
>only 32 bits wide, so how can it contain an address over 4 GB ?

Maybe I mislead you. In my code, I need to find the eficonfig_table_*.
After that, I should type cast it to right
efi_config_table_32_t or efi_config_table_64_t.

Then my judgment is to compare its efi_info->efi_loader_signature.
If it's EFI64_LOADER_SIGNATURE, I will type cast it to efi_config_table_64_t.
If it's EFI32_LOADER_SIGNATURE, I will type cast it to efi_config_table_32_t.

But here is a issue, its signature matches EFI32_LOADER_SIGNATURE, but
it's table member is above 4G, but I use efi_config_table_32_t. That cause a problem.

Thanks,
Chao Fan

>
>



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

* Re: [tip:x86/boot] x86/boot: Early parse RSDP and save it in boot_params
  2019-02-11 10:10                     ` Chao Fan
@ 2019-02-11 10:17                       ` Ard Biesheuvel
  2019-02-11 10:24                         ` Borislav Petkov
  0 siblings, 1 reply; 54+ messages in thread
From: Ard Biesheuvel @ 2019-02-11 10:17 UTC (permalink / raw)
  To: Chao Fan
  Cc: Borislav Petkov, Guenter Roeck, Thomas Gleixner,
	Linux Kernel Mailing List, Kirill A. Shutemov, Ingo Molnar,
	Lendacky, Thomas, Masahiro Yamada, caoj.fnst, Juergen Gross,
	Ingo Molnar, Kees Cook, the arch/x86 maintainers, H. Peter Anvin,
	linux-tip-commits, Matt Fleming

On Mon, 11 Feb 2019 at 11:10, Chao Fan <fanc.fnst@cn.fujitsu.com> wrote:
>
> On Mon, Feb 11, 2019 at 09:57:02AM +0000, Ard Biesheuvel wrote:
> >On Mon, 11 Feb 2019 at 10:56, Chao Fan <fanc.fnst@cn.fujitsu.com> wrote:
> >>
> >> On Mon, Feb 11, 2019 at 09:46:03AM +0000, Ard Biesheuvel wrote:
> >> >On Mon, 11 Feb 2019 at 01:22, Borislav Petkov <bp@alien8.de> wrote:
> >> >>
> >> >> On Fri, Feb 08, 2019 at 10:53:22PM +0100, Borislav Petkov wrote:
> >> >> > On Fri, Feb 08, 2019 at 12:44:51PM -0800, Guenter Roeck wrote:
> >> >> > > Yes, the kernel boots if I comment out that function and have it return 0.
> >> >> >
> >> >> > Thanks, this localizes the issue significantly.
> >> >>
> >> >> Some observations:
> >> >>
> >> >>                 } else {
> >> >>                         efi_config_table_32_t *tmp_table;
> >> >>
> >> >>                         tmp_table = config_tables;
> >> >>                         guid = tmp_table->guid;                 <--- *
> >> >>                         table = tmp_table->table;
> >> >>                 }
> >> >>
> >> >> It blows up at that tmp_table->guid deref above. Singlestepping through
> >> >> it with gdb shows:
> >> >>
> >> >> # arch/x86/boot/compressed/acpi.c:114:                  guid = tmp_table->guid;
> >> >>         movq    (%rdi), %rax    # MEM[(struct efi_config_table_32_t *)config_tables_37].guid, guid
> >> >>         movq    8(%rdi), %rsi   # MEM[(struct efi_config_table_32_t *)config_tables_37].guid, guid
> >> >> # arch/x86/boot/compressed/acpi.c:115:                  table = tmp_table->table;
> >> >>         movl    16(%rdi), %r10d # MEM[(struct efi_config_table_32_t *)config_tables_37].table, table
> >> >>         jmp     .L30    #
> >> >>
> >> >> and %rdi has:
> >> >>
> >> >>         rdi            0x630646870
> >> >>
> >> >> which is an address above 4G but we're using a 32-bit EFI BIOS.
> >> >>
> >> >> Which begs the question whether EFI system tables can even be mapped at
> >> >> something above 4G with a 32-bit EFI and whether that could work ok.
> >> >> Hmm.
> >> >>
> >> >> Lemme add Ard and mfleming for insight here.
> >> >>
> >> >
> >> >-ENOCONTEXT, but let me try in any case:
> >> >
> >> >linux/efi.h has
> >> >
> >> >typedef struct {
> >> >  efi_guid_t guid;
> >> >  u32 table;
> >> >} efi_config_table_32_t;
> >> >
> >> >so if we end up with more than 32 bits set in table, there is
> >> >something seriously wrong.
> >> >
> >> >The size of efi_config_table_32_t deviates from efi_config_table_64_t,
> >> >so you will have to ensure that you are using the correct stride when
> >> >iterating over config_tables.
> >>
> >> Here I use signature to judge it.
> >> If the signature is EFI64_LOADER_SIGNATURE, I will use efi_config_table_64_t,
> >> if the signature is EFI32_LOADER_SIGNATURE, I will use efi_config_table_32_t.
> >> But the efi32 whose signature is EFI32_LOADER_SIGNATURE points to a
> >> address above 4G, I am not sure whether this is normal and works well.
> >>
> >
> >This is impossible. The 'table' member of efi_config_table_32_t is
> >only 32 bits wide, so how can it contain an address over 4 GB ?
>
> Maybe I mislead you. In my code, I need to find the eficonfig_table_*.
> After that, I should type cast it to right
> efi_config_table_32_t or efi_config_table_64_t.
>
> Then my judgment is to compare its efi_info->efi_loader_signature.
> If it's EFI64_LOADER_SIGNATURE, I will type cast it to efi_config_table_64_t.
> If it's EFI32_LOADER_SIGNATURE, I will type cast it to efi_config_table_32_t.
>
> But here is a issue, its signature matches EFI32_LOADER_SIGNATURE, but
> it's table member is above 4G, but I use efi_config_table_32_t. That cause a problem.
>

That still does not explain how 'table' can assume a value > 4 GB
after assigning the contents of a u32 to it.

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

* Re: [tip:x86/boot] x86/boot: Early parse RSDP and save it in boot_params
  2019-02-11 10:17                       ` Ard Biesheuvel
@ 2019-02-11 10:24                         ` Borislav Petkov
  2019-02-11 10:33                           ` Ard Biesheuvel
  2019-02-11 10:42                           ` Borislav Petkov
  0 siblings, 2 replies; 54+ messages in thread
From: Borislav Petkov @ 2019-02-11 10:24 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Chao Fan, Guenter Roeck, Thomas Gleixner,
	Linux Kernel Mailing List, Kirill A. Shutemov, Ingo Molnar,
	Lendacky, Thomas, Masahiro Yamada, caoj.fnst, Juergen Gross,
	Ingo Molnar, Kees Cook, the arch/x86 maintainers, H. Peter Anvin,
	linux-tip-commits, Matt Fleming

On Mon, Feb 11, 2019 at 10:17:36AM +0000, Ard Biesheuvel wrote:
> That still does not explain how 'table' can assume a value > 4 GB
> after assigning the contents of a u32 to it.

See efi_get_rsdp_addr() in tip/master and especially that systable address
computation:

#ifdef CONFIG_X86_64
        systab = (efi_system_table_t *)(ei->efi_systab | ((__u64)ei->efi_systab_hi<<32));
#else
        if (ei->efi_systab_hi || ei->efi_memmap_hi) {
                debug_putstr("Error getting RSDP address: EFI system table located above 4GB.\n");
                return 0;
        }
        systab = (efi_system_table_t *)ei->efi_systab;
#endif

	...

	config_tables = (void *)(systab->tables + size * i);

It is hard to debug that early but I managed to singlestep it last night
to this deref:

              } else {
                        efi_config_table_32_t *tmp_table;

                        tmp_table = config_tables;
                        guid = tmp_table->guid;
				^^^^^^^^^^^^^^

                        table = tmp_table->table;

which in asm is:

# arch/x86/boot/compressed/acpi.c:114: 			guid = tmp_table->guid;
#NO_APP
	movq	(%rdi), %rax	# MEM[(struct efi_config_table_32_t *)config_tables_37].guid, guid
	movq	8(%rdi), %rsi	# MEM[(struct efi_config_table_32_t *)config_tables_37].guid, guid
# arch/x86/boot/compressed/acpi.c:115: 			table = tmp_table->table;
	movl	16(%rdi), %r10d	# MEM[(struct efi_config_table_32_t *)config_tables_37].table, table

and %rdi has 0x630646870 so either we got the wrong address or qemu
mapped it above 4G...

It is only an observation for now though...

Thx.

-- 
Regards/Gruss,
    Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

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

* Re: [tip:x86/boot] x86/boot: Early parse RSDP and save it in boot_params
  2019-02-11 10:24                         ` Borislav Petkov
@ 2019-02-11 10:33                           ` Ard Biesheuvel
  2019-02-11 10:42                           ` Borislav Petkov
  1 sibling, 0 replies; 54+ messages in thread
From: Ard Biesheuvel @ 2019-02-11 10:33 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: Chao Fan, Guenter Roeck, Thomas Gleixner,
	Linux Kernel Mailing List, Kirill A. Shutemov, Ingo Molnar,
	Lendacky, Thomas, Masahiro Yamada, caoj.fnst, Juergen Gross,
	Ingo Molnar, Kees Cook, the arch/x86 maintainers, H. Peter Anvin,
	linux-tip-commits, Matt Fleming

On Mon, 11 Feb 2019 at 11:24, Borislav Petkov <bp@alien8.de> wrote:
>
> On Mon, Feb 11, 2019 at 10:17:36AM +0000, Ard Biesheuvel wrote:
> > That still does not explain how 'table' can assume a value > 4 GB
> > after assigning the contents of a u32 to it.
>
> See efi_get_rsdp_addr() in tip/master and especially that systable address
> computation:
>
> #ifdef CONFIG_X86_64
>         systab = (efi_system_table_t *)(ei->efi_systab | ((__u64)ei->efi_systab_hi<<32));
> #else
>         if (ei->efi_systab_hi || ei->efi_memmap_hi) {
>                 debug_putstr("Error getting RSDP address: EFI system table located above 4GB.\n");
>                 return 0;
>         }
>         systab = (efi_system_table_t *)ei->efi_systab;
> #endif
>
>         ...
>
>         config_tables = (void *)(systab->tables + size * i);
>
> It is hard to debug that early but I managed to singlestep it last night
> to this deref:
>
>               } else {
>                         efi_config_table_32_t *tmp_table;
>
>                         tmp_table = config_tables;
>                         guid = tmp_table->guid;
>                                 ^^^^^^^^^^^^^^
>
>                         table = tmp_table->table;
>
> which in asm is:
>
> # arch/x86/boot/compressed/acpi.c:114:                  guid = tmp_table->guid;
> #NO_APP
>         movq    (%rdi), %rax    # MEM[(struct efi_config_table_32_t *)config_tables_37].guid, guid
>         movq    8(%rdi), %rsi   # MEM[(struct efi_config_table_32_t *)config_tables_37].guid, guid
> # arch/x86/boot/compressed/acpi.c:115:                  table = tmp_table->table;
>         movl    16(%rdi), %r10d # MEM[(struct efi_config_table_32_t *)config_tables_37].table, table
>
> and %rdi has 0x630646870 so either we got the wrong address or qemu
> mapped it above 4G...
>
> It is only an observation for now though...
>

I think the problem is that efi_system_table_t is native, so if you
want to access a 32-bit EFI system table from a 64-bit build, you will
need to use efi_system_table_32_t explicitly.

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

* Re: [tip:x86/boot] x86/boot: Early parse RSDP and save it in boot_params
  2019-02-11 10:24                         ` Borislav Petkov
  2019-02-11 10:33                           ` Ard Biesheuvel
@ 2019-02-11 10:42                           ` Borislav Petkov
  2019-02-11 10:46                             ` Ard Biesheuvel
  1 sibling, 1 reply; 54+ messages in thread
From: Borislav Petkov @ 2019-02-11 10:42 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Chao Fan, Guenter Roeck, Thomas Gleixner,
	Linux Kernel Mailing List, Kirill A. Shutemov, Ingo Molnar,
	Lendacky, Thomas, Masahiro Yamada, caoj.fnst, Juergen Gross,
	Ingo Molnar, Kees Cook, the arch/x86 maintainers, H. Peter Anvin,
	linux-tip-commits, Matt Fleming

On Mon, Feb 11, 2019 at 11:24:26AM +0100, Borislav Petkov wrote:
> It is only an observation for now though...

Ok, now I did this:

        for (i = 0; i < systab->nr_tables; i++) {
                acpi_physical_address table;
                void *config_tables;
                efi_guid_t guid;

                if ((unsigned long)systab->tables >> 32)			<---
                        asm volatile("1:\n jmp 1b");

                config_tables = (void *)(systab->tables + size * i);

It did stop at the endless loop there which would mean that
systab->tables is simply pointing somewhere into the weeds.

Asm is:

---
# arch/x86/boot/compressed/acpi.c:96: 			asm volatile("1:\n jmp 1b");
#APP
# 96 "arch/x86/boot/compressed/acpi.c" 1
	1:
 jmp 1b
# 0 "" 2
#NO_APP
	movq	112(%rcx), %rdi	# systab_147->tables, _31
.L29:
# arch/x86/boot/compressed/acpi.c:98: 		config_tables = (void *)(systab->tables + size * i);
	addq	%r9, %rdi	# ivtmp.64, config_tables
# arch/x86/boot/compressed/acpi.c:104: 			guid = tmp_table->guid;
---

and RDI is

rdi            0x630646870

in gdb.

systab itself gets computed to something low: 0x3fedb010.

Hmmm. Could it be that that EDK BIOS image is buggy?

[    0.000000] efi: EFI v2.70 by EDK II
[    0.000000] efi:  SMBIOS=0x3feb9000  ACPI=0x3fee7000  ACPI 2.0=0x3fee7014  MEMATTR=0x3f524110

-- 
Regards/Gruss,
    Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

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

* Re: [tip:x86/boot] x86/boot: Early parse RSDP and save it in boot_params
  2019-02-11 10:42                           ` Borislav Petkov
@ 2019-02-11 10:46                             ` Ard Biesheuvel
  2019-02-11 11:04                               ` Borislav Petkov
  2019-02-11 11:20                               ` Borislav Petkov
  0 siblings, 2 replies; 54+ messages in thread
From: Ard Biesheuvel @ 2019-02-11 10:46 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: Chao Fan, Guenter Roeck, Thomas Gleixner,
	Linux Kernel Mailing List, Kirill A. Shutemov, Ingo Molnar,
	Lendacky, Thomas, Masahiro Yamada, caoj.fnst, Juergen Gross,
	Ingo Molnar, Kees Cook, the arch/x86 maintainers, H. Peter Anvin,
	linux-tip-commits, Matt Fleming

On Mon, 11 Feb 2019 at 11:43, Borislav Petkov <bp@alien8.de> wrote:
>
> On Mon, Feb 11, 2019 at 11:24:26AM +0100, Borislav Petkov wrote:
> > It is only an observation for now though...
>
> Ok, now I did this:
>
>         for (i = 0; i < systab->nr_tables; i++) {
>                 acpi_physical_address table;
>                 void *config_tables;
>                 efi_guid_t guid;
>
>                 if ((unsigned long)systab->tables >> 32)                        <---
>                         asm volatile("1:\n jmp 1b");
>
>                 config_tables = (void *)(systab->tables + size * i);
>
> It did stop at the endless loop there which would mean that
> systab->tables is simply pointing somewhere into the weeds.
>


As I pointed out in my previous reply, systab will be the wrong type
on 32-bit firmware, it needs to be efi_system_table_32_t


> Asm is:
>
> ---
> # arch/x86/boot/compressed/acpi.c:96:                   asm volatile("1:\n jmp 1b");
> #APP
> # 96 "arch/x86/boot/compressed/acpi.c" 1
>         1:
>  jmp 1b
> # 0 "" 2
> #NO_APP
>         movq    112(%rcx), %rdi # systab_147->tables, _31
> .L29:
> # arch/x86/boot/compressed/acpi.c:98:           config_tables = (void *)(systab->tables + size * i);
>         addq    %r9, %rdi       # ivtmp.64, config_tables
> # arch/x86/boot/compressed/acpi.c:104:                  guid = tmp_table->guid;
> ---
>
> and RDI is
>
> rdi            0x630646870
>
> in gdb.
>
> systab itself gets computed to something low: 0x3fedb010.
>
> Hmmm. Could it be that that EDK BIOS image is buggy?
>
> [    0.000000] efi: EFI v2.70 by EDK II
> [    0.000000] efi:  SMBIOS=0x3feb9000  ACPI=0x3fee7000  ACPI 2.0=0x3fee7014  MEMATTR=0x3f524110
>
> --
> Regards/Gruss,
>     Boris.
>
> Good mailing practices for 400: avoid top-posting and trim the reply.

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

* Re: [tip:x86/boot] x86/boot: Early parse RSDP and save it in boot_params
  2019-02-11 10:46                             ` Ard Biesheuvel
@ 2019-02-11 11:04                               ` Borislav Petkov
  2019-02-11 11:55                                 ` Ard Biesheuvel
  2019-02-11 11:20                               ` Borislav Petkov
  1 sibling, 1 reply; 54+ messages in thread
From: Borislav Petkov @ 2019-02-11 11:04 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Chao Fan, Guenter Roeck, Thomas Gleixner,
	Linux Kernel Mailing List, Kirill A. Shutemov, Ingo Molnar,
	Lendacky, Thomas, Masahiro Yamada, caoj.fnst, Juergen Gross,
	Ingo Molnar, Kees Cook, the arch/x86 maintainers, H. Peter Anvin,
	linux-tip-commits, Matt Fleming

On Mon, Feb 11, 2019 at 10:46:18AM +0000, Ard Biesheuvel wrote:
> As I pointed out in my previous reply, systab will be the wrong type
> on 32-bit firmware, it needs to be efi_system_table_32_t

Yeah, that seems to work. It boots now and it says:

[    0.000000] efi: No EFI runtime due to 32/64-bit mismatch with kernel

Do you think we should mirror that behavoir early too, so that people
don't get any ideas?

Or should we limit that only to the RDSP address computation and
anything else where kernel and EFI bitness mismatch should be disabled?

Thanks Ard!

-- 
Regards/Gruss,
    Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

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

* Re: [tip:x86/boot] x86/boot: Early parse RSDP and save it in boot_params
  2019-02-11 10:46                             ` Ard Biesheuvel
  2019-02-11 11:04                               ` Borislav Petkov
@ 2019-02-11 11:20                               ` Borislav Petkov
  2019-02-11 13:21                                 ` Chao Fan
  2019-02-13  1:54                                 ` Chao Fan
  1 sibling, 2 replies; 54+ messages in thread
From: Borislav Petkov @ 2019-02-11 11:20 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Chao Fan, Guenter Roeck, Thomas Gleixner,
	Linux Kernel Mailing List, Kirill A. Shutemov, Ingo Molnar,
	Lendacky, Thomas, Masahiro Yamada, caoj.fnst, Juergen Gross,
	Ingo Molnar, Kees Cook, the arch/x86 maintainers, H. Peter Anvin,
	linux-tip-commits, Matt Fleming

On Mon, Feb 11, 2019 at 10:46:18AM +0000, Ard Biesheuvel wrote:
> As I pointed out in my previous reply, systab will be the wrong type
> on 32-bit firmware, it needs to be efi_system_table_32_t

This seems to work. Chao, please run it too.

Thx.

---
diff --git a/arch/x86/boot/compressed/acpi.c b/arch/x86/boot/compressed/acpi.c
index c5a949335d8b..0d97aa8bd01f 100644
--- a/arch/x86/boot/compressed/acpi.c
+++ b/arch/x86/boot/compressed/acpi.c
@@ -50,7 +50,8 @@ static acpi_physical_address efi_get_rsdp_addr(void)
 	acpi_physical_address rsdp_addr = 0;
 
 #ifdef CONFIG_EFI
-	efi_system_table_t *systab;
+	unsigned long systab, systab_tables, config_tables;
+	unsigned int nr_tables;
 	struct efi_info *ei;
 	bool efi_64;
 	int size, i;
@@ -70,13 +71,13 @@ static acpi_physical_address efi_get_rsdp_addr(void)
 
 	/* Get systab from boot params. */
 #ifdef CONFIG_X86_64
-	systab = (efi_system_table_t *)(ei->efi_systab | ((__u64)ei->efi_systab_hi<<32));
+	systab = ei->efi_systab | ((__u64)ei->efi_systab_hi << 32);
 #else
 	if (ei->efi_systab_hi || ei->efi_memmap_hi) {
 		debug_putstr("Error getting RSDP address: EFI system table located above 4GB.\n");
 		return 0;
 	}
-	systab = (efi_system_table_t *)ei->efi_systab;
+	systab = ei->efi_systab;
 #endif
 	if (!systab)
 		error("EFI system table not found.");
@@ -87,16 +88,30 @@ static acpi_physical_address efi_get_rsdp_addr(void)
 	size = efi_64 ? sizeof(efi_config_table_64_t) :
 			sizeof(efi_config_table_32_t);
 
-	for (i = 0; i < systab->nr_tables; i++) {
+	if (efi_64) {
+		efi_system_table_64_t *st_tbl = (efi_system_table_64_t *)systab;
+
+		config_tables	= st_tbl->tables;
+		nr_tables	= st_tbl->nr_tables;
+	} else {
+		efi_system_table_32_t *st_tbl = (efi_system_table_32_t *)systab;
+
+		config_tables	= st_tbl->tables;
+		nr_tables	= st_tbl->nr_tables;
+	}
+
+	if (!config_tables)
+		error("EFI config tables not found.");
+
+	for (i = 0; i < nr_tables; i++) {
 		acpi_physical_address table;
-		void *config_tables;
 		efi_guid_t guid;
 
-		config_tables = (void *)(systab->tables + size * i);
+		config_tables += size * i;
+
 		if (efi_64) {
-			efi_config_table_64_t *tmp_table;
+			efi_config_table_64_t *tmp_table = (efi_config_table_64_t *)config_tables;
 
-			tmp_table = config_tables;
 			guid = tmp_table->guid;
 			table = tmp_table->table;
 
@@ -105,9 +120,8 @@ static acpi_physical_address efi_get_rsdp_addr(void)
 				return 0;
 			}
 		} else {
-			efi_config_table_32_t *tmp_table;
+			efi_config_table_32_t *tmp_table = (efi_config_table_32_t *)config_tables;
 
-			tmp_table = config_tables;
 			guid = tmp_table->guid;
 			table = tmp_table->table;
 		}

-- 
Regards/Gruss,
    Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

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

* Re: [tip:x86/boot] x86/boot: Early parse RSDP and save it in boot_params
  2019-02-11 11:04                               ` Borislav Petkov
@ 2019-02-11 11:55                                 ` Ard Biesheuvel
  2019-02-11 12:16                                   ` Borislav Petkov
  0 siblings, 1 reply; 54+ messages in thread
From: Ard Biesheuvel @ 2019-02-11 11:55 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: Chao Fan, Guenter Roeck, Thomas Gleixner,
	Linux Kernel Mailing List, Kirill A. Shutemov, Ingo Molnar,
	Lendacky, Thomas, Masahiro Yamada, caoj.fnst, Juergen Gross,
	Ingo Molnar, Kees Cook, the arch/x86 maintainers, H. Peter Anvin,
	linux-tip-commits, Matt Fleming

On Mon, 11 Feb 2019 at 12:04, Borislav Petkov <bp@alien8.de> wrote:
>
> On Mon, Feb 11, 2019 at 10:46:18AM +0000, Ard Biesheuvel wrote:
> > As I pointed out in my previous reply, systab will be the wrong type
> > on 32-bit firmware, it needs to be efi_system_table_32_t
>
> Yeah, that seems to work. It boots now and it says:
>
> [    0.000000] efi: No EFI runtime due to 32/64-bit mismatch with kernel
>
> Do you think we should mirror that behavoir early too, so that people
> don't get any ideas?
>

It you have CONFIG_EFI_MIXED enabled, you can in fact use 32-bit UEFI
runtime services from 64-bit Linux, so just using the tables should be
fine as well, and I don't think we should hide that behind a Kconfig
option. (Note that ACPI defines its table layouts without regard for
architecture bitness, so this is just about the minimal EFI table
parsing that is required to get at the RDSP)


> Or should we limit that only to the RDSP address computation and
> anything else where kernel and EFI bitness mismatch should be disabled?
>
> Thanks Ard!
>
> --
> Regards/Gruss,
>     Boris.
>
> Good mailing practices for 400: avoid top-posting and trim the reply.

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

* Re: [tip:x86/boot] x86/boot: Early parse RSDP and save it in boot_params
  2019-02-11 11:55                                 ` Ard Biesheuvel
@ 2019-02-11 12:16                                   ` Borislav Petkov
  0 siblings, 0 replies; 54+ messages in thread
From: Borislav Petkov @ 2019-02-11 12:16 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Chao Fan, Guenter Roeck, Thomas Gleixner,
	Linux Kernel Mailing List, Kirill A. Shutemov, Ingo Molnar,
	Lendacky, Thomas, Masahiro Yamada, caoj.fnst, Juergen Gross,
	Ingo Molnar, Kees Cook, the arch/x86 maintainers, H. Peter Anvin,
	linux-tip-commits, Matt Fleming

On Mon, Feb 11, 2019 at 11:55:27AM +0000, Ard Biesheuvel wrote:
> It you have CONFIG_EFI_MIXED enabled, you can in fact use 32-bit UEFI
> runtime services from 64-bit Linux, so just using the tables should be
> fine as well, and I don't think we should hide that behind a Kconfig
> option. (Note that ACPI defines its table layouts without regard for
> architecture bitness, so this is just about the minimal EFI table
> parsing that is required to get at the RDSP)

Ok, understood.

Thx.

-- 
Regards/Gruss,
    Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

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

* Re: [tip:x86/boot] x86/boot: Early parse RSDP and save it in boot_params
  2019-02-11 10:08         ` Borislav Petkov
@ 2019-02-11 13:03           ` Chao Fan
  2019-02-11 14:08           ` Guenter Roeck
  1 sibling, 0 replies; 54+ messages in thread
From: Chao Fan @ 2019-02-11 13:03 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: Guenter Roeck, tglx, linux-kernel, kirill.shutemov, mingo,
	thomas.lendacky, yamada.masahiro, caoj.fnst, jgross, mingo,
	keescook, x86, hpa, linux-tip-commits

On Mon, Feb 11, 2019 at 11:08:00AM +0100, Borislav Petkov wrote:
>On Mon, Feb 11, 2019 at 05:30:33PM +0800, Chao Fan wrote:
>> Yes, I download your ovmf file in linux-build-test/rootfs/firmware/ from
>> your link. There are two files, efi32 and efi64. Then I try to run:
>
>You need both OVMF-pure-efi-32.fd and rootfs.squashfs from the repo. And
>then this works here. Just put the script below and the two files in a
>directory and point to the kernel where you're building with -kernel.
>
>---
>#!/bin/bash
>
>qemu-system-x86_64 -kernel ~/kernel/linux/arch/x86/boot/bzImage -M q35 -cpu SandyBridge \
>        -no-reboot -snapshot -smp 1 \
>        -gdb tcp::1235 \
>        -bios OVMF-pure-efi-32.fd \
>        -m 1G \
>        -net nic,model=rtl8139,macaddr=12:34:56:78:12:34 \
>        -usb -device usb-storage,drive=d0 \
>        -drive file=rootfs.squashfs,if=none,id=d0,format=raw \
>        --append 'earlycon=uart8250,io,0x3f8,9600n8 root=/dev/sda rootwait panic=-1 earlyprintk=ttyS0,115200,keep console=ttyS0,115200' \
>        -monitor pty \
>        -serial file:log
>
>I've added some options for debugging.

So many thanks!
Since I learn much about how to debug kernel code before
start_kernel(). I only tried to debug code after start_kernel().
Seems you can debug the code in compressed code.

Thanks,
Chao Fan
>
>-- 
>Regards/Gruss,
>    Boris.
>
>SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
>
>



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

* Re: [tip:x86/boot] x86/boot: Early parse RSDP and save it in boot_params
  2019-02-11 11:20                               ` Borislav Petkov
@ 2019-02-11 13:21                                 ` Chao Fan
  2019-02-13  1:54                                 ` Chao Fan
  1 sibling, 0 replies; 54+ messages in thread
From: Chao Fan @ 2019-02-11 13:21 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: Ard Biesheuvel, Guenter Roeck, Thomas Gleixner,
	Linux Kernel Mailing List, Kirill A. Shutemov, Ingo Molnar,
	Lendacky, Thomas, Masahiro Yamada, caoj.fnst, Juergen Gross,
	Ingo Molnar, Kees Cook, the arch/x86 maintainers, H. Peter Anvin,
	linux-tip-commits, Matt Fleming

On Mon, Feb 11, 2019 at 12:20:09PM +0100, Borislav Petkov wrote:
>On Mon, Feb 11, 2019 at 10:46:18AM +0000, Ard Biesheuvel wrote:
>> As I pointed out in my previous reply, systab will be the wrong type
>> on 32-bit firmware, it needs to be efi_system_table_32_t
>
>This seems to work. Chao, please run it too.

Ah, I will try and test more then reply to mail list.

Thanks,
Chao Fan

>
>Thx.
>
>---
>diff --git a/arch/x86/boot/compressed/acpi.c b/arch/x86/boot/compressed/acpi.c
>index c5a949335d8b..0d97aa8bd01f 100644
>--- a/arch/x86/boot/compressed/acpi.c
>+++ b/arch/x86/boot/compressed/acpi.c
>@@ -50,7 +50,8 @@ static acpi_physical_address efi_get_rsdp_addr(void)
> 	acpi_physical_address rsdp_addr = 0;
> 
> #ifdef CONFIG_EFI
>-	efi_system_table_t *systab;
>+	unsigned long systab, systab_tables, config_tables;
>+	unsigned int nr_tables;
> 	struct efi_info *ei;
> 	bool efi_64;
> 	int size, i;
>@@ -70,13 +71,13 @@ static acpi_physical_address efi_get_rsdp_addr(void)
> 
> 	/* Get systab from boot params. */
> #ifdef CONFIG_X86_64
>-	systab = (efi_system_table_t *)(ei->efi_systab | ((__u64)ei->efi_systab_hi<<32));
>+	systab = ei->efi_systab | ((__u64)ei->efi_systab_hi << 32);
> #else
> 	if (ei->efi_systab_hi || ei->efi_memmap_hi) {
> 		debug_putstr("Error getting RSDP address: EFI system table located above 4GB.\n");
> 		return 0;
> 	}
>-	systab = (efi_system_table_t *)ei->efi_systab;
>+	systab = ei->efi_systab;
> #endif
> 	if (!systab)
> 		error("EFI system table not found.");
>@@ -87,16 +88,30 @@ static acpi_physical_address efi_get_rsdp_addr(void)
> 	size = efi_64 ? sizeof(efi_config_table_64_t) :
> 			sizeof(efi_config_table_32_t);
> 
>-	for (i = 0; i < systab->nr_tables; i++) {
>+	if (efi_64) {
>+		efi_system_table_64_t *st_tbl = (efi_system_table_64_t *)systab;
>+
>+		config_tables	= st_tbl->tables;
>+		nr_tables	= st_tbl->nr_tables;
>+	} else {
>+		efi_system_table_32_t *st_tbl = (efi_system_table_32_t *)systab;
>+
>+		config_tables	= st_tbl->tables;
>+		nr_tables	= st_tbl->nr_tables;
>+	}
>+
>+	if (!config_tables)
>+		error("EFI config tables not found.");
>+
>+	for (i = 0; i < nr_tables; i++) {
> 		acpi_physical_address table;
>-		void *config_tables;
> 		efi_guid_t guid;
> 
>-		config_tables = (void *)(systab->tables + size * i);
>+		config_tables += size * i;
>+
> 		if (efi_64) {
>-			efi_config_table_64_t *tmp_table;
>+			efi_config_table_64_t *tmp_table = (efi_config_table_64_t *)config_tables;
> 
>-			tmp_table = config_tables;
> 			guid = tmp_table->guid;
> 			table = tmp_table->table;
> 
>@@ -105,9 +120,8 @@ static acpi_physical_address efi_get_rsdp_addr(void)
> 				return 0;
> 			}
> 		} else {
>-			efi_config_table_32_t *tmp_table;
>+			efi_config_table_32_t *tmp_table = (efi_config_table_32_t *)config_tables;
> 
>-			tmp_table = config_tables;
> 			guid = tmp_table->guid;
> 			table = tmp_table->table;
> 		}
>
>-- 
>Regards/Gruss,
>    Boris.
>
>Good mailing practices for 400: avoid top-posting and trim the reply.
>
>



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

* Re: [tip:x86/boot] x86/boot: Early parse RSDP and save it in boot_params
  2019-02-11 10:08         ` Borislav Petkov
  2019-02-11 13:03           ` Chao Fan
@ 2019-02-11 14:08           ` Guenter Roeck
  1 sibling, 0 replies; 54+ messages in thread
From: Guenter Roeck @ 2019-02-11 14:08 UTC (permalink / raw)
  To: Borislav Petkov, Chao Fan
  Cc: tglx, linux-kernel, kirill.shutemov, mingo, thomas.lendacky,
	yamada.masahiro, caoj.fnst, jgross, mingo, keescook, x86, hpa,
	linux-tip-commits

On 2/11/19 2:08 AM, Borislav Petkov wrote:
> On Mon, Feb 11, 2019 at 05:30:33PM +0800, Chao Fan wrote:
>> Yes, I download your ovmf file in linux-build-test/rootfs/firmware/ from
>> your link. There are two files, efi32 and efi64. Then I try to run:
> 
> You need both OVMF-pure-efi-32.fd and rootfs.squashfs from the repo. And
> then this works here. Just put the script below and the two files in a
> directory and point to the kernel where you're building with -kernel.
> 
> ---
> #!/bin/bash
> 
> qemu-system-x86_64 -kernel ~/kernel/linux/arch/x86/boot/bzImage -M q35 -cpu SandyBridge \
>          -no-reboot -snapshot -smp 1 \
>          -gdb tcp::1235 \
>          -bios OVMF-pure-efi-32.fd \
>          -m 1G \
>          -net nic,model=rtl8139,macaddr=12:34:56:78:12:34 \
>          -usb -device usb-storage,drive=d0 \
>          -drive file=rootfs.squashfs,if=none,id=d0,format=raw \
>          --append 'earlycon=uart8250,io,0x3f8,9600n8 root=/dev/sda rootwait panic=-1 earlyprintk=ttyS0,115200,keep console=ttyS0,115200' \
>          -monitor pty \
>          -serial file:log
> 
> I've added some options for debugging.
> 

If you use my rootfs, you can also add "noreboot" as boot parameter and it
won't reboot but stay in a shell. You can also use any of the other root
file systems in the repository - it doesn't have to be squashfs.

The whole point of booting with OVMF-pure-efi-32.fd is just that. I have
other test runs which boot with the 64 bit efi version. The idea is to
test as many combinations as possible. This is also why this specific
boot is from USB drive and with squashfs/q35/SandyBridge.

Thanks,
Guenter

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

* Re: [tip:x86/boot] x86/boot: Early parse RSDP and save it in boot_params
  2019-02-11 11:20                               ` Borislav Petkov
  2019-02-11 13:21                                 ` Chao Fan
@ 2019-02-13  1:54                                 ` Chao Fan
  2019-02-13  7:36                                   ` Boris Petkov
  1 sibling, 1 reply; 54+ messages in thread
From: Chao Fan @ 2019-02-13  1:54 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: Ard Biesheuvel, Guenter Roeck, Thomas Gleixner,
	Linux Kernel Mailing List, Kirill A. Shutemov, Ingo Molnar,
	Lendacky, Thomas, Masahiro Yamada, caoj.fnst, Juergen Gross,
	Ingo Molnar, Kees Cook, the arch/x86 maintainers, H. Peter Anvin,
	linux-tip-commits, Matt Fleming

On Mon, Feb 11, 2019 at 12:20:09PM +0100, Borislav Petkov wrote:
>On Mon, Feb 11, 2019 at 10:46:18AM +0000, Ard Biesheuvel wrote:
>> As I pointed out in my previous reply, systab will be the wrong type
>> on 32-bit firmware, it needs to be efi_system_table_32_t
>
>This seems to work. Chao, please run it too.

Yes, your PATCH really works well. I tried both efi32 OVMF and efi64
OVMF, all boot.

Thanks,
Chao Fan

>
>Thx.
>
>---
>diff --git a/arch/x86/boot/compressed/acpi.c b/arch/x86/boot/compressed/acpi.c
>index c5a949335d8b..0d97aa8bd01f 100644
>--- a/arch/x86/boot/compressed/acpi.c
>+++ b/arch/x86/boot/compressed/acpi.c
>@@ -50,7 +50,8 @@ static acpi_physical_address efi_get_rsdp_addr(void)
> 	acpi_physical_address rsdp_addr = 0;
> 
> #ifdef CONFIG_EFI
>-	efi_system_table_t *systab;
>+	unsigned long systab, systab_tables, config_tables;
>+	unsigned int nr_tables;
> 	struct efi_info *ei;
> 	bool efi_64;
> 	int size, i;
>@@ -70,13 +71,13 @@ static acpi_physical_address efi_get_rsdp_addr(void)
> 
> 	/* Get systab from boot params. */
> #ifdef CONFIG_X86_64
>-	systab = (efi_system_table_t *)(ei->efi_systab | ((__u64)ei->efi_systab_hi<<32));
>+	systab = ei->efi_systab | ((__u64)ei->efi_systab_hi << 32);
> #else
> 	if (ei->efi_systab_hi || ei->efi_memmap_hi) {
> 		debug_putstr("Error getting RSDP address: EFI system table located above 4GB.\n");
> 		return 0;
> 	}
>-	systab = (efi_system_table_t *)ei->efi_systab;
>+	systab = ei->efi_systab;
> #endif
> 	if (!systab)
> 		error("EFI system table not found.");
>@@ -87,16 +88,30 @@ static acpi_physical_address efi_get_rsdp_addr(void)
> 	size = efi_64 ? sizeof(efi_config_table_64_t) :
> 			sizeof(efi_config_table_32_t);
> 
>-	for (i = 0; i < systab->nr_tables; i++) {
>+	if (efi_64) {
>+		efi_system_table_64_t *st_tbl = (efi_system_table_64_t *)systab;
>+
>+		config_tables	= st_tbl->tables;
>+		nr_tables	= st_tbl->nr_tables;
>+	} else {
>+		efi_system_table_32_t *st_tbl = (efi_system_table_32_t *)systab;
>+
>+		config_tables	= st_tbl->tables;
>+		nr_tables	= st_tbl->nr_tables;
>+	}
>+
>+	if (!config_tables)
>+		error("EFI config tables not found.");
>+
>+	for (i = 0; i < nr_tables; i++) {
> 		acpi_physical_address table;
>-		void *config_tables;
> 		efi_guid_t guid;
> 
>-		config_tables = (void *)(systab->tables + size * i);
>+		config_tables += size * i;
>+
> 		if (efi_64) {
>-			efi_config_table_64_t *tmp_table;
>+			efi_config_table_64_t *tmp_table = (efi_config_table_64_t *)config_tables;
> 
>-			tmp_table = config_tables;
> 			guid = tmp_table->guid;
> 			table = tmp_table->table;
> 
>@@ -105,9 +120,8 @@ static acpi_physical_address efi_get_rsdp_addr(void)
> 				return 0;
> 			}
> 		} else {
>-			efi_config_table_32_t *tmp_table;
>+			efi_config_table_32_t *tmp_table = (efi_config_table_32_t *)config_tables;
> 
>-			tmp_table = config_tables;
> 			guid = tmp_table->guid;
> 			table = tmp_table->table;
> 		}
>
>-- 
>Regards/Gruss,
>    Boris.
>
>Good mailing practices for 400: avoid top-posting and trim the reply.
>
>



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

* Re: [tip:x86/boot] x86/boot: Early parse RSDP and save it in boot_params
  2019-02-13  1:54                                 ` Chao Fan
@ 2019-02-13  7:36                                   ` Boris Petkov
  2019-02-13  7:58                                     ` Chao Fan
  0 siblings, 1 reply; 54+ messages in thread
From: Boris Petkov @ 2019-02-13  7:36 UTC (permalink / raw)
  To: Chao Fan
  Cc: Ard Biesheuvel, Guenter Roeck, Thomas Gleixner,
	Linux Kernel Mailing List, Kirill A. Shutemov, Ingo Molnar,
	Lendacky, Thomas, Masahiro Yamada, caoj.fnst, Juergen Gross,
	Ingo Molnar, Kees Cook, the arch/x86 maintainers, H. Peter Anvin,
	linux-tip-commits, Matt Fleming

On February 13, 2019 2:54:29 AM GMT+01:00, Chao Fan <fanc.fnst@cn.fujitsu.com> wrote:
>Yes, your PATCH really works well. I tried both efi32 OVMF and efi64
>OVMF, all boot.

What about the real hardware you are normally testing on? Boots there too?

Thx.

-- 
Sent from a small device: formatting sux and brevity is inevitable.

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

* Re: [tip:x86/boot] x86/boot: Early parse RSDP and save it in boot_params
  2019-02-13  7:36                                   ` Boris Petkov
@ 2019-02-13  7:58                                     ` Chao Fan
  2019-02-13  8:01                                       ` Ard Biesheuvel
  0 siblings, 1 reply; 54+ messages in thread
From: Chao Fan @ 2019-02-13  7:58 UTC (permalink / raw)
  To: Boris Petkov
  Cc: Ard Biesheuvel, Guenter Roeck, Thomas Gleixner,
	Linux Kernel Mailing List, Kirill A. Shutemov, Ingo Molnar,
	Lendacky, Thomas, Masahiro Yamada, caoj.fnst, Juergen Gross,
	Ingo Molnar, Kees Cook, the arch/x86 maintainers, H. Peter Anvin,
	linux-tip-commits, Matt Fleming

On Wed, Feb 13, 2019 at 08:36:12AM +0100, Boris Petkov wrote:
>On February 13, 2019 2:54:29 AM GMT+01:00, Chao Fan <fanc.fnst@cn.fujitsu.com> wrote:
>>Yes, your PATCH really works well. I tried both efi32 OVMF and efi64
>>OVMF, all boot.
>
>What about the real hardware you are normally testing on? Boots there too?

I testet it in a real EFI machine, it booted, but from command:
> cat /sys/firmware/efi/fw_platform_size
64

We can see it's a 64-bit EFI firmware, and there is no 32-bit EFI firmware available.

Thanks,
Chao Fan

>
>Thx.
>
>-- 
>Sent from a small device: formatting sux and brevity is inevitable.
>
>



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

* Re: [tip:x86/boot] x86/boot: Early parse RSDP and save it in boot_params
  2019-02-13  7:58                                     ` Chao Fan
@ 2019-02-13  8:01                                       ` Ard Biesheuvel
  2019-02-13  8:12                                         ` Chao Fan
  0 siblings, 1 reply; 54+ messages in thread
From: Ard Biesheuvel @ 2019-02-13  8:01 UTC (permalink / raw)
  To: Chao Fan
  Cc: Boris Petkov, Guenter Roeck, Thomas Gleixner,
	Linux Kernel Mailing List, Kirill A. Shutemov, Ingo Molnar,
	Lendacky, Thomas, Masahiro Yamada, caoj.fnst, Juergen Gross,
	Ingo Molnar, Kees Cook, the arch/x86 maintainers, H. Peter Anvin,
	linux-tip-commits, Matt Fleming

On Wed, 13 Feb 2019 at 08:59, Chao Fan <fanc.fnst@cn.fujitsu.com> wrote:
>
> On Wed, Feb 13, 2019 at 08:36:12AM +0100, Boris Petkov wrote:
> >On February 13, 2019 2:54:29 AM GMT+01:00, Chao Fan <fanc.fnst@cn.fujitsu.com> wrote:
> >>Yes, your PATCH really works well. I tried both efi32 OVMF and efi64
> >>OVMF, all boot.
> >
> >What about the real hardware you are normally testing on? Boots there too?
>
> I testet it in a real EFI machine, it booted, but from command:
> > cat /sys/firmware/efi/fw_platform_size
> 64
>
> We can see it's a 64-bit EFI firmware, and there is no 32-bit EFI firmware available.
>

Did you try booting 32-bit OVMF from 64-bit QEMU?

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

* Re: [tip:x86/boot] x86/boot: Early parse RSDP and save it in boot_params
  2019-02-13  8:01                                       ` Ard Biesheuvel
@ 2019-02-13  8:12                                         ` Chao Fan
  2019-02-13  8:50                                           ` Borislav Petkov
  0 siblings, 1 reply; 54+ messages in thread
From: Chao Fan @ 2019-02-13  8:12 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Boris Petkov, Guenter Roeck, Thomas Gleixner,
	Linux Kernel Mailing List, Kirill A. Shutemov, Ingo Molnar,
	Lendacky, Thomas, Masahiro Yamada, caoj.fnst, Juergen Gross,
	Ingo Molnar, Kees Cook, the arch/x86 maintainers, H. Peter Anvin,
	linux-tip-commits, Matt Fleming

On Wed, Feb 13, 2019 at 09:01:27AM +0100, Ard Biesheuvel wrote:
>On Wed, 13 Feb 2019 at 08:59, Chao Fan <fanc.fnst@cn.fujitsu.com> wrote:
>>
>> On Wed, Feb 13, 2019 at 08:36:12AM +0100, Boris Petkov wrote:
>> >On February 13, 2019 2:54:29 AM GMT+01:00, Chao Fan <fanc.fnst@cn.fujitsu.com> wrote:
>> >>Yes, your PATCH really works well. I tried both efi32 OVMF and efi64
>> >>OVMF, all boot.
>> >
>> >What about the real hardware you are normally testing on? Boots there too?
>>
>> I testet it in a real EFI machine, it booted, but from command:
>> > cat /sys/firmware/efi/fw_platform_size
>> 64
>>
>> We can see it's a 64-bit EFI firmware, and there is no 32-bit EFI firmware available.
>>
>
>Did you try booting 32-bit OVMF from 64-bit QEMU?

Yes, I tried the 32-bit OVMF and rootfs from Guenter.
Used as suggested by Boris:

qemu-system-x86_64 -kernel /home/cfan/code/tip/arch/x86/boot/bzImage -M q35 -cpu SandyBridge \
-no-reboot -snapshot -smp 1 \
-bios OVMF-pure-efi-32.fd \
-net nic,model=rtl8139,macaddr=12:34:56:78:12:34 \
-usb -device usb-storage,drive=d0 \
-m 1G \
-drive file=rootfs.squashfs,if=none,id=d0,format=raw \
--append 'earlycon=uart8250,io,0x3f8,9600n8 root=/dev/sda rootwait panic=-1 earlyprintk=ttyS0,115200,keep console=ttyS0,115200' \
-monitor pty \
-serial stdio

Since I used to watch the log, so I just change the "serial file:log" to
"serial stdio".

Thanks,
Chao Fan
>
>



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

* Re: [tip:x86/boot] x86/boot: Early parse RSDP and save it in boot_params
  2019-02-13  8:12                                         ` Chao Fan
@ 2019-02-13  8:50                                           ` Borislav Petkov
  2019-02-13  8:57                                             ` Chao Fan
  0 siblings, 1 reply; 54+ messages in thread
From: Borislav Petkov @ 2019-02-13  8:50 UTC (permalink / raw)
  To: Chao Fan
  Cc: Ard Biesheuvel, Guenter Roeck, Thomas Gleixner,
	Linux Kernel Mailing List, Kirill A. Shutemov, Ingo Molnar,
	Lendacky, Thomas, Masahiro Yamada, caoj.fnst, Juergen Gross,
	Ingo Molnar, Kees Cook, the arch/x86 maintainers, H. Peter Anvin,
	linux-tip-commits, Matt Fleming

On Wed, Feb 13, 2019 at 04:12:21PM +0800, Chao Fan wrote:
> Yes, I tried the 32-bit OVMF and rootfs from Guenter.

Ok, thanks.

Final version of the fix coming up...

-- 
Regards/Gruss,
    Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

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

* Re: [tip:x86/boot] x86/boot: Early parse RSDP and save it in boot_params
  2019-02-13  8:50                                           ` Borislav Petkov
@ 2019-02-13  8:57                                             ` Chao Fan
  0 siblings, 0 replies; 54+ messages in thread
From: Chao Fan @ 2019-02-13  8:57 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: Ard Biesheuvel, Guenter Roeck, Thomas Gleixner,
	Linux Kernel Mailing List, Kirill A. Shutemov, Ingo Molnar,
	Lendacky, Thomas, Masahiro Yamada, caoj.fnst, Juergen Gross,
	Ingo Molnar, Kees Cook, the arch/x86 maintainers, H. Peter Anvin,
	linux-tip-commits, Matt Fleming

On Wed, Feb 13, 2019 at 09:50:10AM +0100, Borislav Petkov wrote:
>On Wed, Feb 13, 2019 at 04:12:21PM +0800, Chao Fan wrote:
>> Yes, I tried the 32-bit OVMF and rootfs from Guenter.
>
>Ok, thanks.
>
>Final version of the fix coming up...

Thanks so much for your help.

Thanks,
Chao Fan

>
>-- 
>Regards/Gruss,
>    Boris.
>
>Good mailing practices for 400: avoid top-posting and trim the reply.
>
>



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

* [tip:x86/boot] x86/boot: Correct RSDP parsing with 32-bit EFI
  2019-02-08 19:02     ` Guenter Roeck
  2019-02-08 19:10       ` Borislav Petkov
  2019-02-11  9:30       ` Chao Fan
@ 2019-02-13  9:06       ` tip-bot for Borislav Petkov
  2019-02-13 11:27       ` tip-bot for Borislav Petkov
  3 siblings, 0 replies; 54+ messages in thread
From: tip-bot for Borislav Petkov @ 2019-02-13  9:06 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: keescook, linux-kernel, tglx, x86, linux, bp, hpa, fanc.fnst,
	mingo, ard.biesheuvel, mingo

Commit-ID:  022442cbec93433ac260a417ab89a960ae6058f8
Gitweb:     https://git.kernel.org/tip/022442cbec93433ac260a417ab89a960ae6058f8
Author:     Borislav Petkov <bp@suse.de>
AuthorDate: Mon, 11 Feb 2019 12:19:45 +0100
Committer:  Borislav Petkov <bp@suse.de>
CommitDate: Wed, 13 Feb 2019 09:59:35 +0100

x86/boot: Correct RSDP parsing with 32-bit EFI

Guenter Roeck reported triple faults of a 64-bit VM using a 32-bit OVMF
EFI image. After some singlestepping of the image in gdb, it turned out
that some of the EFI config tables were at bogus addresses. Which, as
Ard pointed out, results from using the wrong efi_config_table typedef.

So switch all EFI table pointers to unsigned longs and convert them to
the proper typedef only when accessing them. This way, the proper table
type is being used.

Shorten variable names, while at it.

Fixes: 33f0df8d843d ("x86/boot: Search for RSDP in the EFI tables")
Reported-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Borislav Petkov <bp@suse.de>
Tested-by: Chao Fan <fanc.fnst@cn.fujitsu.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: bhe@redhat.com
Cc: caoj.fnst@cn.fujitsu.com
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: indou.takao@jp.fujitsu.com
Cc: Ingo Molnar <mingo@redhat.com>
Cc: kasong@redhat.com
Cc: Kees Cook <keescook@chromium.org>
Cc: msys.mizuma@gmail.com
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: x86-ml <x86@kernel.org>
Link: https://lkml.kernel.org/r/20190208190248.GA10854@roeck-us.net
---
 arch/x86/boot/compressed/acpi.c | 50 +++++++++++++++++++++++++----------------
 1 file changed, 31 insertions(+), 19 deletions(-)

diff --git a/arch/x86/boot/compressed/acpi.c b/arch/x86/boot/compressed/acpi.c
index c5a949335d8b..f8a321e30cc0 100644
--- a/arch/x86/boot/compressed/acpi.c
+++ b/arch/x86/boot/compressed/acpi.c
@@ -50,7 +50,8 @@ static acpi_physical_address efi_get_rsdp_addr(void)
 	acpi_physical_address rsdp_addr = 0;
 
 #ifdef CONFIG_EFI
-	efi_system_table_t *systab;
+	unsigned long systab, systab_tables, config_tables;
+	unsigned int nr_tables;
 	struct efi_info *ei;
 	bool efi_64;
 	int size, i;
@@ -70,46 +71,57 @@ static acpi_physical_address efi_get_rsdp_addr(void)
 
 	/* Get systab from boot params. */
 #ifdef CONFIG_X86_64
-	systab = (efi_system_table_t *)(ei->efi_systab | ((__u64)ei->efi_systab_hi<<32));
+	systab = ei->efi_systab | ((__u64)ei->efi_systab_hi << 32);
 #else
 	if (ei->efi_systab_hi || ei->efi_memmap_hi) {
 		debug_putstr("Error getting RSDP address: EFI system table located above 4GB.\n");
 		return 0;
 	}
-	systab = (efi_system_table_t *)ei->efi_systab;
+	systab = ei->efi_systab;
 #endif
 	if (!systab)
 		error("EFI system table not found.");
 
-	/*
-	 * Get EFI tables from systab.
-	 */
-	size = efi_64 ? sizeof(efi_config_table_64_t) :
-			sizeof(efi_config_table_32_t);
+	/* Handle EFI bitness properly */
+	if (efi_64) {
+		efi_system_table_64_t *stbl = (efi_system_table_64_t *)systab;
+
+		config_tables	= stbl->tables;
+		nr_tables	= stbl->nr_tables;
+		size		= sizeof(efi_config_table_64_t);
+	} else {
+		efi_system_table_32_t *stbl = (efi_system_table_32_t *)systab;
 
-	for (i = 0; i < systab->nr_tables; i++) {
+		config_tables	= stbl->tables;
+		nr_tables	= stbl->nr_tables;
+		size		= sizeof(efi_config_table_32_t);
+	}
+
+	if (!config_tables)
+		error("EFI config tables not found.");
+
+	/* Get EFI tables from systab. */
+	for (i = 0; i < nr_tables; i++) {
 		acpi_physical_address table;
-		void *config_tables;
 		efi_guid_t guid;
 
-		config_tables = (void *)(systab->tables + size * i);
+		config_tables += size * i;
+
 		if (efi_64) {
-			efi_config_table_64_t *tmp_table;
+			efi_config_table_64_t *tbl = (efi_config_table_64_t *)config_tables;
 
-			tmp_table = config_tables;
-			guid = tmp_table->guid;
-			table = tmp_table->table;
+			guid  = tbl->guid;
+			table = tbl->table;
 
 			if (!IS_ENABLED(CONFIG_X86_64) && table >> 32) {
 				debug_putstr("Error getting RSDP address: EFI config table located above 4GB.\n");
 				return 0;
 			}
 		} else {
-			efi_config_table_32_t *tmp_table;
+			efi_config_table_32_t *tbl = (efi_config_table_32_t *)config_tables;
 
-			tmp_table = config_tables;
-			guid = tmp_table->guid;
-			table = tmp_table->table;
+			guid  = tbl->guid;
+			table = tbl->table;
 		}
 
 		if (!(efi_guidcmp(guid, ACPI_TABLE_GUID)))

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

* [tip:x86/boot] x86/boot: Correct RSDP parsing with 32-bit EFI
  2019-02-08 19:02     ` Guenter Roeck
                         ` (2 preceding siblings ...)
  2019-02-13  9:06       ` [tip:x86/boot] x86/boot: Correct RSDP parsing with 32-bit EFI tip-bot for Borislav Petkov
@ 2019-02-13 11:27       ` tip-bot for Borislav Petkov
  3 siblings, 0 replies; 54+ messages in thread
From: tip-bot for Borislav Petkov @ 2019-02-13 11:27 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux, mingo, linux-kernel, fanc.fnst, tglx, x86, mingo, hpa,
	ard.biesheuvel, bp, keescook

Commit-ID:  f9d230e893e864f13ce5ded9a49990fd024bfed5
Gitweb:     https://git.kernel.org/tip/f9d230e893e864f13ce5ded9a49990fd024bfed5
Author:     Borislav Petkov <bp@suse.de>
AuthorDate: Mon, 11 Feb 2019 12:19:45 +0100
Committer:  Borislav Petkov <bp@suse.de>
CommitDate: Wed, 13 Feb 2019 12:19:05 +0100

x86/boot: Correct RSDP parsing with 32-bit EFI

Guenter Roeck reported triple faults of a 64-bit VM using a 32-bit OVMF
EFI image. After some singlestepping of the image in gdb, it turned out
that some of the EFI config tables were at bogus addresses. Which, as
Ard pointed out, results from using the wrong efi_config_table typedef.

So switch all EFI table pointers to unsigned longs and convert them to
the proper typedef only when accessing them. This way, the proper table
type is being used.

Shorten variable names, while at it.

Fixes: 33f0df8d843d ("x86/boot: Search for RSDP in the EFI tables")
Reported-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Borislav Petkov <bp@suse.de>
Tested-by: Chao Fan <fanc.fnst@cn.fujitsu.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: bhe@redhat.com
Cc: caoj.fnst@cn.fujitsu.com
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: indou.takao@jp.fujitsu.com
Cc: Ingo Molnar <mingo@redhat.com>
Cc: kasong@redhat.com
Cc: Kees Cook <keescook@chromium.org>
Cc: msys.mizuma@gmail.com
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: x86-ml <x86@kernel.org>
Link: https://lkml.kernel.org/r/20190208190248.GA10854@roeck-us.net
---
 arch/x86/boot/compressed/acpi.c | 50 +++++++++++++++++++++++++----------------
 1 file changed, 31 insertions(+), 19 deletions(-)

diff --git a/arch/x86/boot/compressed/acpi.c b/arch/x86/boot/compressed/acpi.c
index c5a949335d8b..0ef4ad55b29b 100644
--- a/arch/x86/boot/compressed/acpi.c
+++ b/arch/x86/boot/compressed/acpi.c
@@ -50,7 +50,8 @@ static acpi_physical_address efi_get_rsdp_addr(void)
 	acpi_physical_address rsdp_addr = 0;
 
 #ifdef CONFIG_EFI
-	efi_system_table_t *systab;
+	unsigned long systab, systab_tables, config_tables;
+	unsigned int nr_tables;
 	struct efi_info *ei;
 	bool efi_64;
 	int size, i;
@@ -70,46 +71,57 @@ static acpi_physical_address efi_get_rsdp_addr(void)
 
 	/* Get systab from boot params. */
 #ifdef CONFIG_X86_64
-	systab = (efi_system_table_t *)(ei->efi_systab | ((__u64)ei->efi_systab_hi<<32));
+	systab = ei->efi_systab | ((__u64)ei->efi_systab_hi << 32);
 #else
 	if (ei->efi_systab_hi || ei->efi_memmap_hi) {
 		debug_putstr("Error getting RSDP address: EFI system table located above 4GB.\n");
 		return 0;
 	}
-	systab = (efi_system_table_t *)ei->efi_systab;
+	systab = ei->efi_systab;
 #endif
 	if (!systab)
 		error("EFI system table not found.");
 
-	/*
-	 * Get EFI tables from systab.
-	 */
-	size = efi_64 ? sizeof(efi_config_table_64_t) :
-			sizeof(efi_config_table_32_t);
+	/* Handle EFI bitness properly */
+	if (efi_64) {
+		efi_system_table_64_t *stbl = (efi_system_table_64_t *)systab;
+
+		config_tables	= stbl->tables;
+		nr_tables	= stbl->nr_tables;
+		size		= sizeof(efi_config_table_64_t);
+	} else {
+		efi_system_table_32_t *stbl = (efi_system_table_32_t *)systab;
 
-	for (i = 0; i < systab->nr_tables; i++) {
+		config_tables	= stbl->tables;
+		nr_tables	= stbl->nr_tables;
+		size		= sizeof(efi_config_table_32_t);
+	}
+
+	if (!config_tables)
+		error("EFI config tables not found.");
+
+	/* Get EFI tables from systab. */
+	for (i = 0; i < nr_tables; i++) {
 		acpi_physical_address table;
-		void *config_tables;
 		efi_guid_t guid;
 
-		config_tables = (void *)(systab->tables + size * i);
+		config_tables += size;
+
 		if (efi_64) {
-			efi_config_table_64_t *tmp_table;
+			efi_config_table_64_t *tbl = (efi_config_table_64_t *)config_tables;
 
-			tmp_table = config_tables;
-			guid = tmp_table->guid;
-			table = tmp_table->table;
+			guid  = tbl->guid;
+			table = tbl->table;
 
 			if (!IS_ENABLED(CONFIG_X86_64) && table >> 32) {
 				debug_putstr("Error getting RSDP address: EFI config table located above 4GB.\n");
 				return 0;
 			}
 		} else {
-			efi_config_table_32_t *tmp_table;
+			efi_config_table_32_t *tbl = (efi_config_table_32_t *)config_tables;
 
-			tmp_table = config_tables;
-			guid = tmp_table->guid;
-			table = tmp_table->table;
+			guid  = tbl->guid;
+			table = tbl->table;
 		}
 
 		if (!(efi_guidcmp(guid, ACPI_TABLE_GUID)))

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

end of thread, other threads:[~2019-02-13 11:28 UTC | newest]

Thread overview: 54+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-23 11:08 [PATCH v16 0/7] Parse ACPI table and limit KASLR to choosing immovable memory Chao Fan
2019-01-23 11:08 ` [PATCH v16 1/7] x86/boot: Copy kstrtoull() to boot/string.c instead of simple_strtoull() Chao Fan
2019-02-01 10:58   ` [tip:x86/boot] x86/boot: Copy kstrtoull() to boot/string.c tip-bot for Chao Fan
2019-01-23 11:08 ` [PATCH v16 2/7] x86/boot: Introduce get_acpi_rsdp() to parse RSDP in cmdline from KEXEC Chao Fan
2019-02-01 10:59   ` [tip:x86/boot] x86/boot: Add "acpi_rsdp=" early parsing tip-bot for Chao Fan
2019-01-23 11:08 ` [PATCH v16 3/7] x86/boot: Introduce efi_get_rsdp_addr() to find RSDP from EFI table Chao Fan
2019-02-01 10:59   ` [tip:x86/boot] x86/boot: Search for RSDP in the EFI tables tip-bot for Chao Fan
2019-01-23 11:08 ` [PATCH v16 4/7] x86/boot: Introduce bios_get_rsdp_addr() to search RSDP in memory Chao Fan
2019-02-01 11:00   ` [tip:x86/boot] x86/boot: Search for " tip-bot for Chao Fan
2019-01-23 11:08 ` [PATCH v16 5/7] x86/boot: Early parse RSDP and fill in boot_params Chao Fan
2019-01-23 11:17   ` Chao Fan
2019-02-01 11:01   ` [tip:x86/boot] x86/boot: Early parse RSDP and save it " tip-bot for Chao Fan
2019-02-08 19:02     ` Guenter Roeck
2019-02-08 19:10       ` Borislav Petkov
2019-02-08 20:44         ` Guenter Roeck
2019-02-08 21:53           ` Borislav Petkov
2019-02-11  0:22             ` Borislav Petkov
2019-02-11  1:33               ` Chao Fan
2019-02-11  9:46               ` Ard Biesheuvel
2019-02-11  9:55                 ` Chao Fan
2019-02-11  9:57                   ` Ard Biesheuvel
2019-02-11 10:10                     ` Chao Fan
2019-02-11 10:17                       ` Ard Biesheuvel
2019-02-11 10:24                         ` Borislav Petkov
2019-02-11 10:33                           ` Ard Biesheuvel
2019-02-11 10:42                           ` Borislav Petkov
2019-02-11 10:46                             ` Ard Biesheuvel
2019-02-11 11:04                               ` Borislav Petkov
2019-02-11 11:55                                 ` Ard Biesheuvel
2019-02-11 12:16                                   ` Borislav Petkov
2019-02-11 11:20                               ` Borislav Petkov
2019-02-11 13:21                                 ` Chao Fan
2019-02-13  1:54                                 ` Chao Fan
2019-02-13  7:36                                   ` Boris Petkov
2019-02-13  7:58                                     ` Chao Fan
2019-02-13  8:01                                       ` Ard Biesheuvel
2019-02-13  8:12                                         ` Chao Fan
2019-02-13  8:50                                           ` Borislav Petkov
2019-02-13  8:57                                             ` Chao Fan
2019-02-11  1:07         ` Chao Fan
2019-02-11  9:30       ` Chao Fan
2019-02-11 10:08         ` Borislav Petkov
2019-02-11 13:03           ` Chao Fan
2019-02-11 14:08           ` Guenter Roeck
2019-02-13  9:06       ` [tip:x86/boot] x86/boot: Correct RSDP parsing with 32-bit EFI tip-bot for Borislav Petkov
2019-02-13 11:27       ` tip-bot for Borislav Petkov
2019-01-23 11:08 ` [PATCH v16 6/7] x86/boot: Parse SRAT address from RSDP and store immovable memory Chao Fan
2019-02-01 11:01   ` [tip:x86/boot] x86/boot: Parse SRAT table and count immovable memory regions tip-bot for Chao Fan
2019-01-23 11:08 ` [PATCH v16 7/7] x86/boot/KASLR: Limit KASLR to extracting kernel in immovable memory Chao Fan
2019-02-01 11:02   ` [tip:x86/boot] x86/boot/KASLR: Limit KASLR to extract the kernel in immovable memory only tip-bot for Chao Fan
2019-01-28 17:51 ` [PATCH v16 0/7] Parse ACPI table and limit KASLR to choosing immovable memory Borislav Petkov
2019-01-30  5:58   ` Chao Fan
2019-01-30 11:22     ` [PATCH] x86/boot: Build the command line parsing code unconditionally (was: Re: [PATCH v16 0/7] Parse ACPI table and limit KASLR to choosing immovable memory) Borislav Petkov
2019-02-01 10:57       ` [tip:x86/boot] x86/boot: Build the command line parsing code unconditionally tip-bot for Borislav Petkov

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.