From patchwork Mon Oct 22 09:37:14 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chao Fan X-Patchwork-Id: 10651877 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0683E14E2 for ; Mon, 22 Oct 2018 09:38:36 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F134726253 for ; Mon, 22 Oct 2018 09:38:35 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E55D326E74; Mon, 22 Oct 2018 09:38:35 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8705D26253 for ; Mon, 22 Oct 2018 09:38:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728406AbeJVR4O (ORCPT ); Mon, 22 Oct 2018 13:56:14 -0400 Received: from mail.cn.fujitsu.com ([183.91.158.132]:58630 "EHLO heian.cn.fujitsu.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728385AbeJVR4N (ORCPT ); Mon, 22 Oct 2018 13:56:13 -0400 X-IronPort-AV: E=Sophos;i="5.43,368,1503331200"; d="scan'208";a="46549085" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 22 Oct 2018 17:38:24 +0800 Received: from G08CNEXCHPEKD01.g08.fujitsu.local (unknown [10.167.33.80]) by cn.fujitsu.com (Postfix) with ESMTP id 8EABF4B710F1; Mon, 22 Oct 2018 17:38:21 +0800 (CST) Received: from localhost.localdomain (10.167.225.56) by G08CNEXCHPEKD01.g08.fujitsu.local (10.167.33.89) with Microsoft SMTP Server (TLS) id 14.3.408.0; Mon, 22 Oct 2018 17:38:25 +0800 From: Chao Fan To: , , , , , , , , , , CC: , , Subject: [PATCH v10 1/7] x86/boot: Introduce cmdline_find_option_arg()to detect if option=arg in cmdline Date: Mon, 22 Oct 2018 17:37:14 +0800 Message-ID: <20181022093720.21426-2-fanc.fnst@cn.fujitsu.com> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20181022093720.21426-1-fanc.fnst@cn.fujitsu.com> References: <20181022093720.21426-1-fanc.fnst@cn.fujitsu.com> MIME-Version: 1.0 X-Originating-IP: [10.167.225.56] X-yoursite-MailScanner-ID: 8EABF4B710F1.A8D7C X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: fanc.fnst@cn.fujitsu.com Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Now, there are cmdline_find_option() and cmdline_find_option_bool() in cmdline.c. Sometimes, when detecting such as whether 'acpi=off' is in cmdline, we need to cmdline_find_option() first, then compare the argument. Now splite the operation as a independent function. Introduce a new function cmdline_find_option_arg() to detect whether option is in command line and the value is arg. Signed-off-by: Chao Fan --- arch/x86/boot/compressed/cmdline.c | 15 +++++++++++++++ arch/x86/boot/compressed/misc.h | 1 + 2 files changed, 16 insertions(+) diff --git a/arch/x86/boot/compressed/cmdline.c b/arch/x86/boot/compressed/cmdline.c index af6cda0b7900..61118c69feb8 100644 --- a/arch/x86/boot/compressed/cmdline.c +++ b/arch/x86/boot/compressed/cmdline.c @@ -1,5 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include "misc.h" +#define STATIC +#include #if CONFIG_EARLY_PRINTK || CONFIG_RANDOMIZE_BASE || CONFIG_X86_5LEVEL @@ -30,5 +32,18 @@ int cmdline_find_option_bool(const char *option) { return __cmdline_find_option_bool(get_cmd_line_ptr(), option); } +bool cmdline_find_option_arg(const char *option, const char *arg, int argsize) +{ + char *buffer = malloc(argsize+1); + bool find = false; + int ret; + + ret = cmdline_find_option(option, buffer, argsize+1); + if (ret == argsize && !strncmp(buffer, arg, argsize)) + find = true; + + free(buffer); + return find; +} #endif diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h index a1d5918765f3..008fdc47a29c 100644 --- a/arch/x86/boot/compressed/misc.h +++ b/arch/x86/boot/compressed/misc.h @@ -67,6 +67,7 @@ static inline void debug_puthex(const char *s) /* cmdline.c */ int cmdline_find_option(const char *option, char *buffer, int bufsize); int cmdline_find_option_bool(const char *option); +bool cmdline_find_option_arg(const char *option, const char *arg, int argsize); #endif From patchwork Mon Oct 22 09:37:15 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chao Fan X-Patchwork-Id: 10651875 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7BE3914E2 for ; Mon, 22 Oct 2018 09:38:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7208D25826 for ; Mon, 22 Oct 2018 09:38:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 666622654B; Mon, 22 Oct 2018 09:38:27 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E5A2D25826 for ; Mon, 22 Oct 2018 09:38:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728386AbeJVR4L (ORCPT ); Mon, 22 Oct 2018 13:56:11 -0400 Received: from mail.cn.fujitsu.com ([183.91.158.132]:7650 "EHLO heian.cn.fujitsu.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727519AbeJVR4L (ORCPT ); Mon, 22 Oct 2018 13:56:11 -0400 X-IronPort-AV: E=Sophos;i="5.43,368,1503331200"; d="scan'208";a="46549071" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 22 Oct 2018 17:38:24 +0800 Received: from G08CNEXCHPEKD01.g08.fujitsu.local (unknown [10.167.33.80]) by cn.fujitsu.com (Postfix) with ESMTP id 3FA714B71107; Mon, 22 Oct 2018 17:38:24 +0800 (CST) Received: from localhost.localdomain (10.167.225.56) by G08CNEXCHPEKD01.g08.fujitsu.local (10.167.33.89) with Microsoft SMTP Server (TLS) id 14.3.408.0; Mon, 22 Oct 2018 17:38:28 +0800 From: Chao Fan To: , , , , , , , , , , CC: , , Subject: [PATCH v10 2/7] x86/boot: Copy kstrtoull() to compressed period Date: Mon, 22 Oct 2018 17:37:15 +0800 Message-ID: <20181022093720.21426-3-fanc.fnst@cn.fujitsu.com> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20181022093720.21426-1-fanc.fnst@cn.fujitsu.com> References: <20181022093720.21426-1-fanc.fnst@cn.fujitsu.com> MIME-Version: 1.0 X-Originating-IP: [10.167.225.56] X-yoursite-MailScanner-ID: 3FA714B71107.A6D94 X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: fanc.fnst@cn.fujitsu.com Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP kstrtoull() lives in 'uncompressed' period, used to convert a string to an unsigned long long. Copy to 'compressed' so that we can use it to convert the memory address from sting to unsigned long long in 'compressed' period. Signed-off-by: Chao Fan --- arch/x86/boot/compressed/misc.c | 88 +++++++++++++++++++++++++++++++++ arch/x86/boot/compressed/misc.h | 4 ++ 2 files changed, 92 insertions(+) diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index 8dd1d5ccae58..5b9b24949337 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c @@ -426,3 +426,91 @@ void fortify_panic(const char *name) { error("detected buffer overflow"); } + +#define KSTRTOX_OVERFLOW (1U << 31) + +static inline char _tolower(const char c) +{ + return c | 0x20; +} + +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; +} + +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; +} + +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; +} + +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/compressed/misc.h b/arch/x86/boot/compressed/misc.h index 008fdc47a29c..40378408d980 100644 --- a/arch/x86/boot/compressed/misc.h +++ b/arch/x86/boot/compressed/misc.h @@ -63,6 +63,10 @@ static inline void debug_puthex(const char *s) #endif +#if (defined CONFIG_RANDOMIZE_BASE) && (defined CONFIG_RANDOMIZE_BASE) +int kstrtoull(const char *s, unsigned int base, unsigned long long *res); +#endif + #if CONFIG_EARLY_PRINTK || CONFIG_RANDOMIZE_BASE /* cmdline.c */ int cmdline_find_option(const char *option, char *buffer, int bufsize); From patchwork Mon Oct 22 09:37:16 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chao Fan X-Patchwork-Id: 10651883 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 127EF14E2 for ; Mon, 22 Oct 2018 09:39:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 07555288AE for ; Mon, 22 Oct 2018 09:39:00 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EFC11288B3; Mon, 22 Oct 2018 09:38:59 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8A319288AE for ; Mon, 22 Oct 2018 09:38:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727519AbeJVR40 (ORCPT ); Mon, 22 Oct 2018 13:56:26 -0400 Received: from mail.cn.fujitsu.com ([183.91.158.132]:58656 "EHLO heian.cn.fujitsu.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728385AbeJVR4Z (ORCPT ); Mon, 22 Oct 2018 13:56:25 -0400 X-IronPort-AV: E=Sophos;i="5.43,368,1503331200"; d="scan'208";a="46549110" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 22 Oct 2018 17:38:31 +0800 Received: from G08CNEXCHPEKD01.g08.fujitsu.local (unknown [10.167.33.80]) by cn.fujitsu.com (Postfix) with ESMTP id C4B624B6EDB7; Mon, 22 Oct 2018 17:38:26 +0800 (CST) Received: from localhost.localdomain (10.167.225.56) by G08CNEXCHPEKD01.g08.fujitsu.local (10.167.33.89) with Microsoft SMTP Server (TLS) id 14.3.408.0; Mon, 22 Oct 2018 17:38:30 +0800 From: Chao Fan To: , , , , , , , , , , CC: , , Subject: [PATCH v10 3/7] x86/boot: Add efi_get_rsdp_addr() to dig out RSDP from EFI table Date: Mon, 22 Oct 2018 17:37:16 +0800 Message-ID: <20181022093720.21426-4-fanc.fnst@cn.fujitsu.com> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20181022093720.21426-1-fanc.fnst@cn.fujitsu.com> References: <20181022093720.21426-1-fanc.fnst@cn.fujitsu.com> MIME-Version: 1.0 X-Originating-IP: [10.167.225.56] X-yoursite-MailScanner-ID: C4B624B6EDB7.AAEC8 X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: fanc.fnst@cn.fujitsu.com Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Imitate ACPI code and EFI code to dig RSDP pointer from EFI tables. Process: boot_param->systab->efi_config_table->RSDP. Based on efi_init(), efi_config_init(), efi_config_parse_tables(). Used for later patch to dig out SRAT table and get the memory information. So that we can figure out the immovable memory regions to avoid KASLR extracts kernel on movable memory, so slove the conflict between KASLR and movable_node feature. Signed-off-by: Chao Fan --- arch/x86/boot/compressed/acpitb.c | 96 +++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 arch/x86/boot/compressed/acpitb.c diff --git a/arch/x86/boot/compressed/acpitb.c b/arch/x86/boot/compressed/acpitb.c new file mode 100644 index 000000000000..56b54b0e0889 --- /dev/null +++ b/arch/x86/boot/compressed/acpitb.c @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: GPL-2.0 +#define BOOT_CTYPE_H +#include "misc.h" +#include "error.h" + +#include +#include +#include +#include + +/* Search EFI table for RSDP table. */ +static void efi_get_rsdp_addr(acpi_physical_address *rsdp_addr) +{ +#ifdef CONFIG_EFI + efi_system_table_t *systab; + bool efi_64 = false; + void *config_tables; + struct efi_info *e; + char *sig; + int size; + int i; + + e = &boot_params->efi_info; + sig = (char *)&e->efi_loader_signature; + + if (!strncmp(sig, EFI64_LOADER_SIGNATURE, 4)) + efi_64 = true; + else if (!strncmp(sig, EFI32_LOADER_SIGNATURE, 4)) + efi_64 = false; + else { + debug_putstr("Wrong EFI loader signature.\n"); + return; + } + + /* Get systab from boot params. Based on efi_init(). */ +#ifdef CONFIG_X86_64 + systab = (efi_system_table_t *)( + e->efi_systab | ((__u64)e->efi_systab_hi<<32)); +#else + if (e->efi_systab_hi || e->efi_memmap_hi) { + debug_putstr("Table located above 4GB. EFI should be disabled.\n"); + return; + } + systab = (efi_system_table_t *)e->efi_systab; +#endif + + if (!systab) + return; + + /* + * Get EFI tables from systab. Based on efi_config_init() and + * efi_config_parse_tables(). Only dig out the config_table. + */ + size = efi_64 ? sizeof(efi_config_table_64_t) : + sizeof(efi_config_table_32_t); + + for (i = 0; i < systab->nr_tables; i++) { + efi_guid_t guid; + unsigned long table; + + config_tables = (void *)(systab->tables + size * i); + if (efi_64) { + efi_config_table_64_t *tmp_table; + + tmp_table = (efi_config_table_64_t *)config_tables; + guid = tmp_table->guid; + table = tmp_table->table; +#ifndef CONFIG_64BIT + if (table >> 32) { + debug_putstr("Table located above 4G. EFI should be disabled.\n"); + return; + } +#endif + } else { + efi_config_table_32_t *tmp_table; + + tmp_table = (efi_config_table_32_t *)config_tables; + guid = tmp_table->guid; + table = tmp_table->table; + } + + /* + * Get RSDP from EFI tables. + * If ACPI20 table found, use it. + * If ACPI20 table not found, but ACPI table found, + * use the ACPI table. + */ + if (!(efi_guidcmp(guid, ACPI_TABLE_GUID))) { + *rsdp_addr = (acpi_physical_address)table; + } else if (!(efi_guidcmp(guid, ACPI_20_TABLE_GUID))) { + *rsdp_addr = (acpi_physical_address)table; + return; + } + } +#endif +} From patchwork Mon Oct 22 09:37:17 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chao Fan X-Patchwork-Id: 10651887 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 86C2B13A9 for ; Mon, 22 Oct 2018 09:39:06 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7C446288AE for ; Mon, 22 Oct 2018 09:39:06 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 709A6288B3; Mon, 22 Oct 2018 09:39:06 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0448C288AE for ; Mon, 22 Oct 2018 09:39:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728255AbeJVR4V (ORCPT ); Mon, 22 Oct 2018 13:56:21 -0400 Received: from mail.cn.fujitsu.com ([183.91.158.132]:58640 "EHLO heian.cn.fujitsu.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728385AbeJVR4V (ORCPT ); Mon, 22 Oct 2018 13:56:21 -0400 X-IronPort-AV: E=Sophos;i="5.43,368,1503331200"; d="scan'208";a="46549108" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 22 Oct 2018 17:38:31 +0800 Received: from G08CNEXCHPEKD01.g08.fujitsu.local (unknown [10.167.33.80]) by cn.fujitsu.com (Postfix) with ESMTP id BF2654B71108; Mon, 22 Oct 2018 17:38:28 +0800 (CST) Received: from localhost.localdomain (10.167.225.56) by G08CNEXCHPEKD01.g08.fujitsu.local (10.167.33.89) with Microsoft SMTP Server (TLS) id 14.3.408.0; Mon, 22 Oct 2018 17:38:32 +0800 From: Chao Fan To: , , , , , , , , , , CC: , , Subject: [PATCH v10 4/7] x86/boot: Add bios_get_rsdp_addr() to search RSDP in memory Date: Mon, 22 Oct 2018 17:37:17 +0800 Message-ID: <20181022093720.21426-5-fanc.fnst@cn.fujitsu.com> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20181022093720.21426-1-fanc.fnst@cn.fujitsu.com> References: <20181022093720.21426-1-fanc.fnst@cn.fujitsu.com> MIME-Version: 1.0 X-Originating-IP: [10.167.225.56] X-yoursite-MailScanner-ID: BF2654B71108.A89F0 X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: fanc.fnst@cn.fujitsu.com Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Imitate ACPI code to search RSDP pointer from memory. Walk memory and check the signature until get the RSDP signature. Based on acpi_tb_scan_memory_for_rsdp() and acpi_find_root_pointer(). If didn't get RSDP from EFI table, will run this function. Used for later patch to dig out SRAT table and get the memory information. So that we can figure out the immovable memory regions to avoid KASLR extracts kernel on movable memory, so slove the conflict between KASLR and movable_node feature. Signed-off-by: Chao Fan --- arch/x86/boot/compressed/acpitb.c | 106 ++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) diff --git a/arch/x86/boot/compressed/acpitb.c b/arch/x86/boot/compressed/acpitb.c index 56b54b0e0889..50fa65cf824d 100644 --- a/arch/x86/boot/compressed/acpitb.c +++ b/arch/x86/boot/compressed/acpitb.c @@ -94,3 +94,109 @@ static void efi_get_rsdp_addr(acpi_physical_address *rsdp_addr) } #endif } + +static u8 compute_checksum(u8 *buffer, u32 length) +{ + u8 sum = 0; + u8 *end = buffer + length; + + while (buffer < end) + sum = (u8)(sum + *(buffer++)); + + return sum; +} + +/* + * Used to search a block of memory for the RSDP signature. + * Return Pointer to the RSDP if found, otherwise NULL. + * Based on acpi_tb_scan_memory_for_rsdp(). + */ +static u8 *scan_mem_for_rsdp(u8 *start, u32 length) +{ + struct acpi_table_rsdp *rsdp; + u8 *end; + u8 *rover; + + end = start + length; + + /* Search from given start address for the requested length */ + for (rover = start; rover < end; rover += ACPI_RSDP_SCAN_STEP) { + /* + * The RSDP signature and checksum must both 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 *)rover; + + /* Nope, 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; + + /* Sig and checksum valid, we have found a real RSDP */ + return rover; + } + return NULL; +} + +/* + * Used to search RSDP physical address. + * Based on acpi_find_root_pointer(). Since only use physical address + * in this period, so there is no need to do the memory map jobs. + */ +static void bios_get_rsdp_addr(acpi_physical_address *rsdp_addr) +{ + struct acpi_table_rsdp *rsdp; + u8 *table_ptr; + u8 *mem_rover; + u32 address; + + /* + * Get the location of the Extended BIOS Data Area (EBDA) + * Since we use physical address directely, so + * acpi_os_map_memory() and acpi_os_unmap_memory() are + * not needed here. + */ + table_ptr = (u8 *)ACPI_EBDA_PTR_LOCATION; + *(u32 *)(void *)&address = *(u16 *)(void *)table_ptr; + address <<= 4; + table_ptr = (u8 *)address; + + /* + * Search EBDA paragraphs (EBDA is required to be a minimum of + * 1K length) + */ + if (address > 0x400) { + mem_rover = scan_mem_for_rsdp(table_ptr, ACPI_EBDA_WINDOW_SIZE); + + if (mem_rover) { + address += (u32)ACPI_PTR_DIFF(mem_rover, table_ptr); + *rsdp_addr = (acpi_physical_address)address; + return; + } + } + + table_ptr = (u8 *)ACPI_HI_RSDP_WINDOW_BASE; + mem_rover = scan_mem_for_rsdp(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE); + + /* + * Search upper memory: 16-byte boundaries in E0000h-FFFFFh + * Since we use physical address directely, so + * acpi_os_map_memory() and acpi_os_unmap_memory() are + * not needed here. + */ + if (mem_rover) { + address = (u32)(ACPI_HI_RSDP_WINDOW_BASE + + ACPI_PTR_DIFF(mem_rover, table_ptr)); + *rsdp_addr = (acpi_physical_address)address; + } +} From patchwork Mon Oct 22 09:37:18 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chao Fan X-Patchwork-Id: 10651885 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BA80914E2 for ; Mon, 22 Oct 2018 09:39:02 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B0064288AE for ; Mon, 22 Oct 2018 09:39:02 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A4595288B3; Mon, 22 Oct 2018 09:39:02 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 304A9288AE for ; Mon, 22 Oct 2018 09:39:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728444AbeJVR4X (ORCPT ); Mon, 22 Oct 2018 13:56:23 -0400 Received: from mail.cn.fujitsu.com ([183.91.158.132]:58640 "EHLO heian.cn.fujitsu.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727519AbeJVR4W (ORCPT ); Mon, 22 Oct 2018 13:56:22 -0400 X-IronPort-AV: E=Sophos;i="5.43,368,1503331200"; d="scan'208";a="46549109" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 22 Oct 2018 17:38:31 +0800 Received: from G08CNEXCHPEKD01.g08.fujitsu.local (unknown [10.167.33.80]) by cn.fujitsu.com (Postfix) with ESMTP id C17864B71140; Mon, 22 Oct 2018 17:38:31 +0800 (CST) Received: from localhost.localdomain (10.167.225.56) by G08CNEXCHPEKD01.g08.fujitsu.local (10.167.33.89) with Microsoft SMTP Server (TLS) id 14.3.408.0; Mon, 22 Oct 2018 17:38:35 +0800 From: Chao Fan To: , , , , , , , , , , CC: , , Subject: [PATCH v10 5/7] x86/boot: Add get_acpi_rsdp() to parse RSDP in cmdline from kexec Date: Mon, 22 Oct 2018 17:37:18 +0800 Message-ID: <20181022093720.21426-6-fanc.fnst@cn.fujitsu.com> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20181022093720.21426-1-fanc.fnst@cn.fujitsu.com> References: <20181022093720.21426-1-fanc.fnst@cn.fujitsu.com> MIME-Version: 1.0 X-Originating-IP: [10.167.225.56] X-yoursite-MailScanner-ID: C17864B71140.A6519 X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: fanc.fnst@cn.fujitsu.com Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Imitate setup_acpi_rsdp() for the early_param of "acpi_rsdp". KEXEC writes the RSDP pointer to cmdline for EFI booting. So if "acpi_rsdp" found in cmdline, use it directely. Signed-off-by: Chao Fan --- arch/x86/boot/compressed/acpitb.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/arch/x86/boot/compressed/acpitb.c b/arch/x86/boot/compressed/acpitb.c index 50fa65cf824d..fa63a584d7ec 100644 --- a/arch/x86/boot/compressed/acpitb.c +++ b/arch/x86/boot/compressed/acpitb.c @@ -8,6 +8,9 @@ #include #include +#define STATIC +#include + /* Search EFI table for RSDP table. */ static void efi_get_rsdp_addr(acpi_physical_address *rsdp_addr) { @@ -200,3 +203,23 @@ static void bios_get_rsdp_addr(acpi_physical_address *rsdp_addr) *rsdp_addr = (acpi_physical_address)address; } } + +static void get_acpi_rsdp(acpi_physical_address *rsdp_addr) +{ +#ifdef CONFIG_KEXEC + unsigned long long res; + int len = 0; + char *val; + + val = malloc(19); + len = cmdline_find_option("acpi_rsdp", val, 19); + + if (len == -1) + return; + + if (len > 0) { + val[len] = 0; + *rsdp_addr = (acpi_physical_address)kstrtoull(val, 16, &res); + } +#endif +} From patchwork Mon Oct 22 09:37:19 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chao Fan X-Patchwork-Id: 10651879 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 43A3013A9 for ; Mon, 22 Oct 2018 09:38:56 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 06C5328528 for ; Mon, 22 Oct 2018 09:38:56 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id ED33A285D3; Mon, 22 Oct 2018 09:38:55 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5833628528 for ; Mon, 22 Oct 2018 09:38:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728478AbeJVR42 (ORCPT ); Mon, 22 Oct 2018 13:56:28 -0400 Received: from mail.cn.fujitsu.com ([183.91.158.132]:58640 "EHLO heian.cn.fujitsu.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728439AbeJVR41 (ORCPT ); Mon, 22 Oct 2018 13:56:27 -0400 X-IronPort-AV: E=Sophos;i="5.43,368,1503331200"; d="scan'208";a="46549137" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 22 Oct 2018 17:38:37 +0800 Received: from G08CNEXCHPEKD01.g08.fujitsu.local (unknown [10.167.33.80]) by cn.fujitsu.com (Postfix) with ESMTP id D30604B710E8; Mon, 22 Oct 2018 17:38:33 +0800 (CST) Received: from localhost.localdomain (10.167.225.56) by G08CNEXCHPEKD01.g08.fujitsu.local (10.167.33.89) with Microsoft SMTP Server (TLS) id 14.3.408.0; Mon, 22 Oct 2018 17:38:37 +0800 From: Chao Fan To: , , , , , , , , , , CC: , , Subject: [PATCH v10 6/7] x86/boot: Dig out SRAT table from RSDP and find immovable memory Date: Mon, 22 Oct 2018 17:37:19 +0800 Message-ID: <20181022093720.21426-7-fanc.fnst@cn.fujitsu.com> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20181022093720.21426-1-fanc.fnst@cn.fujitsu.com> References: <20181022093720.21426-1-fanc.fnst@cn.fujitsu.com> MIME-Version: 1.0 X-Originating-IP: [10.167.225.56] X-yoursite-MailScanner-ID: D30604B710E8.A7D7D X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: fanc.fnst@cn.fujitsu.com Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP To avoid KASLR extracting kernel on movable memory, and slove the conflict between KASLR and movable_node feature, dig the SRAT tables from RSDP pointer. Walk the SRAT tables and store the immovable memory regions in immovable_mem[]. The code is imitated from ACPI code, based on acpi_os_get_root_pointer(). Process: RSDP->RSDT/XSDT->ACPI root table->SRAT. Signed-off-by: Chao Fan --- arch/x86/boot/compressed/Makefile | 4 + arch/x86/boot/compressed/acpitb.c | 127 ++++++++++++++++++++++++++++++ arch/x86/boot/compressed/kaslr.c | 4 - arch/x86/boot/compressed/misc.h | 15 ++++ 4 files changed, 146 insertions(+), 4 deletions(-) diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index 28764dacf018..0f631c5613d7 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile @@ -83,6 +83,10 @@ ifdef CONFIG_X86_64 vmlinux-objs-y += $(obj)/pgtable_64.o endif +#if (defined CONFIG_MEMORY_HOTREMOVE) && (defined CONFIG_RANDOMIZE_BASE) +vmlinux-objs-$(CONFIG_RANDOMIZE_BASE) += $(obj)/acpitb.o +#endif + $(obj)/eboot.o: KBUILD_CFLAGS += -fshort-wchar -mno-red-zone vmlinux-objs-$(CONFIG_EFI_STUB) += $(obj)/eboot.o $(obj)/efi_stub_$(BITS).o \ diff --git a/arch/x86/boot/compressed/acpitb.c b/arch/x86/boot/compressed/acpitb.c index fa63a584d7ec..a9dbd42e5ab9 100644 --- a/arch/x86/boot/compressed/acpitb.c +++ b/arch/x86/boot/compressed/acpitb.c @@ -11,6 +11,11 @@ #define STATIC #include +#ifdef CONFIG_MEMORY_HOTREMOVE +/* Store the immovable memory regions */ +struct mem_vector immovable_mem[MAX_NUMNODES*2]; +#endif + /* Search EFI table for RSDP table. */ static void efi_get_rsdp_addr(acpi_physical_address *rsdp_addr) { @@ -223,3 +228,125 @@ static void get_acpi_rsdp(acpi_physical_address *rsdp_addr) } #endif } + +/* + * Used to dig RSDP table from EFI table or BIOS. + * If RSDP table found in EFI table, use it. Or search BIOS. + * Based on acpi_os_get_root_pointer(). + */ +static acpi_physical_address get_rsdp_addr(void) +{ + acpi_physical_address pa = 0; + + get_acpi_rsdp(&pa); + + if (!pa) + efi_get_rsdp_addr(&pa); + + if (!pa) + bios_get_rsdp_addr(&pa); + + return pa; +} + +static struct acpi_table_header *get_acpi_srat_table(void) +{ + acpi_physical_address acpi_table; + acpi_physical_address root_table; + struct acpi_table_header *header; + struct acpi_table_rsdp *rsdp; + char *signature; + u8 *entry; + u32 count; + u32 size; + int i, j; + u32 len; + + rsdp = (struct acpi_table_rsdp *)get_rsdp_addr(); + if (!rsdp) + return NULL; + + /* Get RSDT or XSDT from RSDP. */ + if (!cmdline_find_option_arg("acpi", "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; + } + + /* Get ACPI root table from RSDT or XSDT.*/ + header = (struct acpi_table_header *)root_table; + len = header->length; + count = (u32)((len - sizeof(struct acpi_table_header)) / size); + entry = ACPI_ADD_PTR(u8, header, sizeof(struct acpi_table_header)); + + for (i = 0; i < count; i++) { + u64 address64; + + if (size == ACPI_RSDT_ENTRY_SIZE) + acpi_table = ((acpi_physical_address) + (*ACPI_CAST_PTR(u32, entry))); + else { + *(u64 *)(void *)&address64 = *(u64 *)(void *)entry; + acpi_table = (acpi_physical_address) address64; + } + + if (acpi_table) { + header = (struct acpi_table_header *)acpi_table; + signature = header->signature; + + if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_SRAT)) + return header; + } + entry += size; + } + return NULL; +} + +/* + * According to ACPI table, filter the immvoable memory regions + * and store them in immovable_mem[]. + */ +void get_immovable_mem(void) +{ + struct acpi_table_header *table_header; + struct acpi_subtable_header *table; + struct acpi_srat_mem_affinity *ma; + unsigned long table_end; + int i = 0; + + if (!cmdline_find_option_bool("movable_node") || + cmdline_find_option_arg("acpi", "off", 3)) + return; + + table_header = get_acpi_srat_table(); + if (!table_header) + return; + + table_end = (unsigned long)table_header + table_header->length; + + table = (struct acpi_subtable_header *) + ((unsigned long)table_header + sizeof(struct acpi_table_srat)); + + while (((unsigned long)table) + + sizeof(struct acpi_subtable_header) < table_end) { + if (table->type == ACPI_SRAT_TYPE_MEMORY_AFFINITY) { + ma = (struct acpi_srat_mem_affinity *)table; + if (!(ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)) { + immovable_mem[i].start = ma->base_address; + immovable_mem[i].size = ma->length; + i++; + } + + if (i >= MAX_NUMNODES*2) { + debug_putstr("Too many immovable memory regions, aborted.\n"); + break; + } + } + table = (struct acpi_subtable_header *) + ((unsigned long)table + table->length); + } + num_immovable_mem = i; +} 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 40378408d980..83075b9c6eea 100644 --- a/arch/x86/boot/compressed/misc.h +++ b/arch/x86/boot/compressed/misc.h @@ -82,6 +82,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 @@ -121,3 +126,13 @@ static inline void console_init(void) void set_sev_encryption_mask(void); #endif + +/* acpitb.c */ +#ifdef CONFIG_RANDOMIZE_BASE +int num_immovable_mem; +#ifdef CONFIG_MEMORY_HOTREMOVE +/* Store the amount of immovable memory regions */ +#define ACPI_MAX_TABLES 128 +void get_immovable_mem(void); +#endif +#endif From patchwork Mon Oct 22 09:37:20 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chao Fan X-Patchwork-Id: 10651881 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6751E1508 for ; Mon, 22 Oct 2018 09:38:56 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 399A72852D for ; Mon, 22 Oct 2018 09:38:56 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2E0CD285D3; Mon, 22 Oct 2018 09:38:56 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A44D22852D for ; Mon, 22 Oct 2018 09:38:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728348AbeJVR42 (ORCPT ); Mon, 22 Oct 2018 13:56:28 -0400 Received: from mail.cn.fujitsu.com ([183.91.158.132]:58661 "EHLO heian.cn.fujitsu.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728452AbeJVR42 (ORCPT ); Mon, 22 Oct 2018 13:56:28 -0400 X-IronPort-AV: E=Sophos;i="5.43,368,1503331200"; d="scan'208";a="46549139" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 22 Oct 2018 17:38:37 +0800 Received: from G08CNEXCHPEKD01.g08.fujitsu.local (unknown [10.167.33.80]) by cn.fujitsu.com (Postfix) with ESMTP id 104924B71100; Mon, 22 Oct 2018 17:38:36 +0800 (CST) Received: from localhost.localdomain (10.167.225.56) by G08CNEXCHPEKD01.g08.fujitsu.local (10.167.33.89) with Microsoft SMTP Server (TLS) id 14.3.408.0; Mon, 22 Oct 2018 17:38:39 +0800 From: Chao Fan To: , , , , , , , , , , CC: , , Subject: [PATCH v10 7/7] x86/boot/KASLR: Limit kaslr to choosing the immovable memory Date: Mon, 22 Oct 2018 17:37:20 +0800 Message-ID: <20181022093720.21426-8-fanc.fnst@cn.fujitsu.com> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20181022093720.21426-1-fanc.fnst@cn.fujitsu.com> References: <20181022093720.21426-1-fanc.fnst@cn.fujitsu.com> MIME-Version: 1.0 X-Originating-IP: [10.167.225.56] X-yoursite-MailScanner-ID: 104924B71100.A662F X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: fanc.fnst@cn.fujitsu.com Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP If CONFIG_MEMORY_HOTREMOVE enabled, walk through the SRAT memory tables and store those immovable memory regions so that KASLR can get where to choose for randomization. If the amount of immovable memory regions is not zero, which means the immovable memory regions existing. Calculate the intersection between memory regions from e820/efi memory table and immovable memory regions. Signed-off-by: Chao Fan --- arch/x86/boot/compressed/kaslr.c | 77 +++++++++++++++++++++++++++----- 1 file changed, 66 insertions(+), 11 deletions(-) diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c index b251572e77af..174d2114045e 100644 --- a/arch/x86/boot/compressed/kaslr.c +++ b/arch/x86/boot/compressed/kaslr.c @@ -97,6 +97,11 @@ 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; +#ifdef CONFIG_MEMORY_HOTREMOVE +/* Store the immovable memory regions */ +extern struct mem_vector immovable_mem[MAX_NUMNODES*2]; +#endif + enum mem_avoid_index { MEM_AVOID_ZO_RANGE = 0, @@ -413,6 +418,11 @@ static void mem_avoid_init(unsigned long input, unsigned long input_size, /* Mark the memmap regions we need to avoid */ handle_mem_options(); +#ifdef CONFIG_MEMORY_HOTREMOVE + /* Mark the immovable regions we need to choose */ + get_immovable_mem(); +#endif + #ifdef CONFIG_X86_VERBOSE_BOOTUP /* Make sure video RAM can be used. */ add_identity_map(0, PMD_SIZE); @@ -568,9 +578,9 @@ static unsigned long slots_fetch_random(void) return 0; } -static void process_mem_region(struct mem_vector *entry, - unsigned long minimum, - unsigned long image_size) +static void slots_count(struct mem_vector *entry, + unsigned long minimum, + unsigned long image_size) { struct mem_vector region, overlap; unsigned long start_orig, end; @@ -646,6 +656,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 directely. + */ + if (num_immovable_mem == 0) { + slots_count(region, minimum, image_size); + + if (slot_area_index == MAX_SLOT_AREA) { + debug_putstr("Aborted e820/efi memmap scan (slot_areas full)!\n"); + return 1; + } + return 0; + } + +#ifdef CONFIG_MEMORY_HOTREMOVE + /* + * If immovable memory found, filter the intersection between + * immovable memory and region to slots_count. + * Otherwise, go on old code. + */ + for (i = 0; i < num_immovable_mem; i++) { + struct mem_vector entry; + unsigned long long start, end, entry_end, region_end; + + 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; + + slots_count(&entry, minimum, image_size); + + if (slot_area_index == MAX_SLOT_AREA) { + debug_putstr("Aborted e820/efi memmap scan (slot_areas full)!\n"); + return 1; + } + } + return 0; +#endif +} + #ifdef CONFIG_EFI /* * Returns true if mirror region found (and must have been processed @@ -711,11 +772,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(®ion, minimum, image_size); - if (slot_area_index == MAX_SLOT_AREA) { - debug_putstr("Aborted EFI scan (slot_areas full)!\n"); + if (process_mem_region(®ion, minimum, image_size)) break; - } } return true; } @@ -742,11 +800,8 @@ static void process_e820_entries(unsigned long minimum, continue; region.start = entry->addr; region.size = entry->size; - process_mem_region(®ion, minimum, image_size); - if (slot_area_index == MAX_SLOT_AREA) { - debug_putstr("Aborted e820 scan (slot_areas full)!\n"); + if (process_mem_region(®ion, minimum, image_size)) break; - } } }