aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/power
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-08-08 09:31:31 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-08-08 16:04:30 -0400
commite4630fdd47637168927905983205d7b7c5c08c09 (patch)
tree3528e218e396d17ab5db1e74346e39b59424ec74 /arch/x86/power
parentc226fab474291e3c6ac5fa30a2b0778acc311e61 (diff)
x86/power/64: Always create temporary identity mapping correctly
The low-level resume-from-hibernation code on x86-64 uses kernel_ident_mapping_init() to create the temoprary identity mapping, but that function assumes that the offset between kernel virtual addresses and physical addresses is aligned on the PGD level. However, with a randomized identity mapping base, it may be aligned on the PUD level and if that happens, the temporary identity mapping created by set_up_temporary_mappings() will not reflect the actual kernel identity mapping and the image restoration will fail as a result (leading to a kernel panic most of the time). To fix this problem, rework kernel_ident_mapping_init() to support unaligned offsets between KVA and PA up to the PMD level and make set_up_temporary_mappings() use it as approprtiate. Reported-and-tested-by: Thomas Garnier <thgarnie@google.com> Reported-by: Borislav Petkov <bp@suse.de> Suggested-by: Yinghai Lu <yinghai@kernel.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Yinghai Lu <yinghai@kernel.org>
Diffstat (limited to 'arch/x86/power')
-rw-r--r--arch/x86/power/hibernate_64.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/arch/x86/power/hibernate_64.c b/arch/x86/power/hibernate_64.c
index f0b5f2d402af..a3e3ccc87138 100644
--- a/arch/x86/power/hibernate_64.c
+++ b/arch/x86/power/hibernate_64.c
@@ -87,7 +87,7 @@ static int set_up_temporary_mappings(void)
87 struct x86_mapping_info info = { 87 struct x86_mapping_info info = {
88 .alloc_pgt_page = alloc_pgt_page, 88 .alloc_pgt_page = alloc_pgt_page,
89 .pmd_flag = __PAGE_KERNEL_LARGE_EXEC, 89 .pmd_flag = __PAGE_KERNEL_LARGE_EXEC,
90 .kernel_mapping = true, 90 .offset = __PAGE_OFFSET,
91 }; 91 };
92 unsigned long mstart, mend; 92 unsigned long mstart, mend;
93 pgd_t *pgd; 93 pgd_t *pgd;