In commit d0ceea662d45 ("x86/mm: Add _PAGE_NOPTISHADOW bit to avoid updating userspace page tables") we started setting _PAGE_NOPTISHADOW (bit 58) in identity map PTEs created by kernel_ident_mapping_init. In configure_5level_paging when transiting from 5-level paging to 4-level paging we copy the first p4d to become our new (4-level) pgd by dereferencing the first entry in the current pgd, but we only mask off the low 12 bits in the pgd entry.
When kexecing, the previous kernel sets up an identity map using kernel_ident_mapping_init before transiting to the new kernel, which means the new kernel gets a pgd with entries with bit 58 set. Then we mask off only the low 12 bits, resulting in a non-canonical address, and try to copy from it, and fault.
Fixes: d0ceea662d45 ("x86/mm: Add _PAGE_NOPTISHADOW bit to avoid updating userspace page tables") Signed-off-by: Eric Hagberg ehagberg@janestreet.com Cc: stable@vger.kernel.org --- arch/x86/boot/compressed/pgtable_64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/boot/compressed/pgtable_64.c b/arch/x86/boot/compressed/pgtable_64.c index bdd26050dff7..c785c5d54a11 100644 --- a/arch/x86/boot/compressed/pgtable_64.c +++ b/arch/x86/boot/compressed/pgtable_64.c @@ -180,7 +180,7 @@ asmlinkage void configure_5level_paging(struct boot_params *bp, void *pgtable) * We cannot just point to the page table from trampoline as it * may be above 4G. */ - src = *(unsigned long *)__native_read_cr3() & PAGE_MASK; + src = *(unsigned long *)__native_read_cr3() & PTE_PFN_MASK; memcpy(trampoline_32bit, (void *)src, PAGE_SIZE); }
linux-stable-mirror@lists.linaro.org