mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Chen Yu <yu.c.chen@intel.com>
To: x86@kernel.org
Cc: linux-kernel@vger.kernel.org, Yu Chen <yu.c.chen@intel.com>,
	Ingo Molnar <mingo@kernel.org>,
	"Rafael J . Wysocki" <rafael@kernel.org>,
	Ingo Molnar <mingo@redhat.com>,
	Thomas Gleixner <tglx@linutronix.de>, Len Brown <lenb@kernel.org>,
	Ying Huang <ying.huang@intel.com>
Subject: [PATCH 1/2][RFC] x86/boot/e820: Introduce e820_table_ori to represent the real original e820 layout
Date: Sat, 17 Jun 2017 13:22:14 +0800	[thread overview]
Message-ID: <8082eab4271cfea6f47d190613d09fd3faa9563e.1497675876.git.yu.c.chen@intel.com> (raw)
In-Reply-To: <cover.1497675876.git.yu.c.chen@intel.com>

Currently we try to have e820_table_firmware to represent the
original firmware memory layout passed to us by the bootloader,
however it is not the case, the e820_table_firmware might still
be modified by linux:
1. During bootup, the efi boot stub might allocate memory via
   efi service for the PCI device information structure, then
   later e820_reserve_setup_data() reserved these dynamically
   allocated structures(AKA, setup_data) in e820_table_firmware
   accordingly.
2. The kexec might also modify the e820_table_firmware.

This brings problem to the memory layout checking logic during
hibernation, because in theory that code expects to get input
from the original memory layout passed by the BIOS, otherwise
we get a force-positive failure.

So introduce a new variable e820_table_ori to record the original
BIOS provided memory layout, which is composed of two parts:
the BIOS-provided physical RAM map and extended physical RAM map.

Cc: Ingo Molnar <mingo@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Rafael J. Wysocki <rafael@kernel.org>
Cc: Len Brown <lenb@kernel.org>
Cc: Ying Huang <ying.huang@intel.com>
Cc: x86@kernel.org
Signed-off-by: Chen Yu <yu.c.chen@intel.com>
---
 arch/x86/include/asm/e820/api.h |  1 +
 arch/x86/kernel/e820.c          | 24 ++++++++++++++++++++----
 2 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/e820/api.h b/arch/x86/include/asm/e820/api.h
index 8e0f8b8..d30114b 100644
--- a/arch/x86/include/asm/e820/api.h
+++ b/arch/x86/include/asm/e820/api.h
@@ -5,6 +5,7 @@
 
 extern struct e820_table *e820_table;
 extern struct e820_table *e820_table_firmware;
+extern struct e820_table *e820_table_ori;
 
 extern unsigned long pci_mem_start;
 
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index d78a586..29dcb4c 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -20,7 +20,7 @@
 #include <asm/setup.h>
 
 /*
- * We organize the E820 table into two main data structures:
+ * We organize the E820 table into three main data structures:
  *
  * - 'e820_table_firmware': the original firmware version passed to us by the
  *   bootloader - not modified by the kernel. We use this to:
@@ -28,14 +28,18 @@
  *       - inform the user about the firmware's notion of memory layout
  *         via /sys/firmware/memmap
  *
- *       - the hibernation code uses it to generate a kernel-independent MD5
- *         fingerprint of the physical memory layout of a system.
- *
  *       - kexec, which is a bootloader in disguise, uses the original E820
  *         layout to pass to the kexec-ed kernel. This way the original kernel
  *         can have a restricted E820 map while the kexec()-ed kexec-kernel
  *         can have access to full memory - etc.
  *
+ * - 'e820_table_ori': the original firmware version passed to us by the
+ *   bootloader - not modified by the kernel or the efi boot stub.
+ *   We use this to:
+ *
+ *       - the hibernation code uses it to generate a kernel-independent MD5
+ *         fingerprint of the physical memory layout of a system.
+ *
  * - 'e820_table': this is the main E820 table that is massaged by the
  *   low level x86 platform code, or modified by boot parameters, before
  *   passed on to higher level MM layers.
@@ -47,9 +51,11 @@
  */
 static struct e820_table e820_table_init		__initdata;
 static struct e820_table e820_table_firmware_init	__initdata;
+static struct e820_table e820_table_ori_init		__initdata;
 
 struct e820_table *e820_table __refdata			= &e820_table_init;
 struct e820_table *e820_table_firmware __refdata	= &e820_table_firmware_init;
+struct e820_table *e820_table_ori __refdata		= &e820_table_ori_init;
 
 /* For PCI or other memory-mapped resources */
 unsigned long pci_mem_start = 0xaeedbabe;
@@ -648,6 +654,12 @@ __init void e820__reallocate_tables(void)
 	BUG_ON(!n);
 	memcpy(n, e820_table_firmware, size);
 	e820_table_firmware = n;
+
+	size = offsetof(struct e820_table, entries) + sizeof(struct e820_entry)*e820_table_ori->nr_entries;
+	n = kmalloc(size, GFP_KERNEL);
+	BUG_ON(!n);
+	memcpy(n, e820_table_ori, size);
+	e820_table_ori = n;
 }
 
 /*
@@ -669,6 +681,9 @@ void __init e820__memory_setup_extended(u64 phys_addr, u32 data_len)
 	__append_e820_table(extmap, entries);
 	e820__update_table(e820_table);
 
+	/* Update the original table if there's any extended memory. */
+	memcpy(e820_table_ori, e820_table, sizeof(*e820_table_ori));
+
 	early_memunmap(sdata, data_len);
 	pr_info("e820: extended physical RAM map:\n");
 	e820__print_table("extended");
@@ -1176,6 +1191,7 @@ void __init e820__memory_setup(void)
 	who = x86_init.resources.memory_setup();
 
 	memcpy(e820_table_firmware, e820_table, sizeof(*e820_table_firmware));
+	memcpy(e820_table_ori, e820_table, sizeof(*e820_table_ori));
 
 	pr_info("e820: BIOS-provided physical RAM map:\n");
 	e820__print_table(who);
-- 
2.7.4

  reply	other threads:[~2017-06-17  5:22 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-06-17  5:21 [PATCH 0/2][RFC] Introduce e820_table_ori to fix the memory inconsistent problem during hibernation Chen Yu
2017-06-17  5:22 ` Chen Yu [this message]
2017-06-22  9:40   ` [PATCH 1/2][RFC] x86/boot/e820: Introduce e820_table_ori to represent the real original e820 layout Ingo Molnar
2017-06-23  4:13     ` Chen Yu
2017-06-23  8:42       ` Ingo Molnar
2017-07-02 17:01         ` Chen Yu
2017-06-17  5:23 ` [PATCH 2/2][RFC] PM / hibernate: Utilize the original e820 map for consistent check Chen Yu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8082eab4271cfea6f47d190613d09fd3faa9563e.1497675876.git.yu.c.chen@intel.com \
    --to=yu.c.chen@intel.com \
    --cc=lenb@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=mingo@redhat.com \
    --cc=rafael@kernel.org \
    --cc=tglx@linutronix.de \
    --cc=x86@kernel.org \
    --cc=ying.huang@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®