From: David Woodhouse <dwmw@xxxxxxxxxxxx> The control_code_page should be explicitly mapped into the identity mapped page tables for the relocate_kernel environment. This only seems to have worked by luck before, because it tended to be within the same 2MiB or 1GiB large page already mapped for another reason. A subsequent commit will reduce the control_code_page to a single 4KiB page instead of a higher-order allocation, and seems to make it much *less* likely that we get lucky with its placement. This leads to a fault when relocate_kernel() first tries to access the page through its identity-mapped virtual address. Signed-off-by: David Woodhouse <dwmw@xxxxxxxxxxxx> Cc: stable@xxxxxxxxxxxxxxx --- arch/x86/kernel/machine_kexec_64.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c index 9c9ac606893e..b9b6243ee223 100644 --- a/arch/x86/kernel/machine_kexec_64.c +++ b/arch/x86/kernel/machine_kexec_64.c @@ -240,6 +240,12 @@ static int init_pgtable(struct kimage *image, unsigned long start_pgtable) if (direct_gbpages) info.direct_gbpages = true; + /* Ensure the control code page itself is in the direct map */ + result = kernel_ident_mapping_init(&info, level4p, start_pgtable + PAGE_SIZE, + start_pgtable + KEXEC_CONTROL_CODE_MAX_SIZE); + if (result) + return result; + for (i = 0; i < nr_pfn_mapped; i++) { mstart = pfn_mapped[i].start << PAGE_SHIFT; mend = pfn_mapped[i].end << PAGE_SHIFT; -- 2.47.0