Discussion:
[RFC PATCH] x86_64/mm/boot: Fix kernel_ident_mapping_init() failure for kexec
Xunlei Pang
2017-03-20 06:11:31 UTC
Permalink
I found that the kdump is broken on linux-4.11.0-rc2+, probably
due to the 5level-paging feature that "#define p4d_present(p4d) 1",
as a result in ident_p4d_init(), it will go into ident_pud_init()
directly without allocating the new pud.

Looks like this patch can make it work again.

Cc: Kirill A. Shutemov <***@linux.intel.com>
Signed-off-by: Xunlei Pang <***@redhat.com>
---
arch/x86/mm/ident_map.c | 22 ++++++++++------------
include/asm-generic/5level-fixup.h | 6 +++---
2 files changed, 13 insertions(+), 15 deletions(-)

diff --git a/arch/x86/mm/ident_map.c b/arch/x86/mm/ident_map.c
index 04210a2..d14bb52 100644
--- a/arch/x86/mm/ident_map.c
+++ b/arch/x86/mm/ident_map.c
@@ -97,22 +97,20 @@ int kernel_ident_mapping_init(struct x86_mapping_info *info, pgd_t *pgd_page,
continue;
}

- p4d = (p4d_t *)info->alloc_pgt_page(info->context);
- if (!p4d)
- return -ENOMEM;
+ if (IS_ENABLED(CONFIG_X86_5LEVEL)) {
+ p4d = (p4d_t *)info->alloc_pgt_page(info->context);
+ if (!p4d)
+ return -ENOMEM;
+ } else {
+ p4d = pgd;
+ }
+
result = ident_p4d_init(info, p4d, addr, next);
if (result)
return result;
- if (IS_ENABLED(CONFIG_X86_5LEVEL)) {
+
+ if (IS_ENABLED(CONFIG_X86_5LEVEL))
set_pgd(pgd, __pgd(__pa(p4d) | _KERNPG_TABLE));
- } else {
- /*
- * With p4d folded, pgd is equal to p4d.
- * The pgd entry has to point to the pud page table in this case.
- */
- pud_t *pud = pud_offset(p4d, 0);
- set_pgd(pgd, __pgd(__pa(pud) | _KERNPG_TABLE));
- }
}

return 0;
diff --git a/include/asm-generic/5level-fixup.h b/include/asm-generic/5level-fixup.h
index b5ca82d..3131ada 100644
--- a/include/asm-generic/5level-fixup.h
+++ b/include/asm-generic/5level-fixup.h
@@ -17,9 +17,9 @@

#define p4d_alloc(mm, pgd, address) (pgd)
#define p4d_offset(pgd, start) (pgd)
-#define p4d_none(p4d) 0
-#define p4d_bad(p4d) 0
-#define p4d_present(p4d) 1
+#define p4d_none(p4d) pgd_none(p4d)
+#define p4d_bad(p4d) pgd_bad(p4d)
+#define p4d_present(p4d) pgd_present(p4d)
#define p4d_ERROR(p4d) do { } while (0)
#define p4d_clear(p4d) pgd_clear(p4d)
#define p4d_val(p4d) pgd_val(p4d)
--
1.8.3.1
Kirill A. Shutemov
2017-03-24 12:04:58 UTC
Permalink
Post by Xunlei Pang
I found that the kdump is broken on linux-4.11.0-rc2+
That's actually tip tree or linux-next. The problematic change is not in
Linus' tree.
Post by Xunlei Pang
, probably
due to the 5level-paging feature that "#define p4d_present(p4d) 1",
as a result in ident_p4d_init(), it will go into ident_pud_init()
directly without allocating the new pud.
Looks like this patch can make it work again.
Okay, that's bisectability issue. Uncovered by splitting my patchset into
parts.

Could you check if applying "Part 2" of 5-level paging changes[1] would
help you?

Making the code work with both <asm-generic/5level-fixup.h> and
<asm-generic/pgtable-nop4d.h> would make it even uglier. Not sure if it
makes sense to address it on its own if second part fixes the situation.

[1] http://lkml.kernel.org/r/20170317185515.8636-1-***@linux.intel.com
--
Kirill A. Shutemov
Xunlei Pang
2017-03-30 11:21:36 UTC
Permalink
Post by Kirill A. Shutemov
Post by Xunlei Pang
I found that the kdump is broken on linux-4.11.0-rc2+
That's actually tip tree or linux-next. The problematic change is not in
Linus' tree.
Post by Xunlei Pang
, probably
due to the 5level-paging feature that "#define p4d_present(p4d) 1",
as a result in ident_p4d_init(), it will go into ident_pud_init()
directly without allocating the new pud.
Looks like this patch can make it work again.
Okay, that's bisectability issue. Uncovered by splitting my patchset into
parts.
Could you check if applying "Part 2" of 5-level paging changes[1] would
help you?
I confirmed that it works after applying your following patches:
x86: Convert the rest of the code to support p4d_t
x86/xen: Change __xen_pgd_walk() and xen_cleanmfnmap() to support p4d
x86/kasan: Prepare clear_pgds() to switch to <asm-generic/pgtable-nop4d.h>
x86/mm/pat: Add 5-level paging support
x86/efi: Add 5-level paging support
x86/kexec: Add 5-level paging support

Regards,
Xunlei
Post by Kirill A. Shutemov
Making the code work with both <asm-generic/5level-fixup.h> and
<asm-generic/pgtable-nop4d.h> would make it even uglier. Not sure if it
makes sense to address it on its own if second part fixes the situation.
Xunlei Pang
2017-03-30 12:43:01 UTC
Permalink
Post by Xunlei Pang
Post by Kirill A. Shutemov
Post by Xunlei Pang
I found that the kdump is broken on linux-4.11.0-rc2+
That's actually tip tree or linux-next. The problematic change is not in
Linus' tree.
Post by Xunlei Pang
, probably
due to the 5level-paging feature that "#define p4d_present(p4d) 1",
as a result in ident_p4d_init(), it will go into ident_pud_init()
directly without allocating the new pud.
Looks like this patch can make it work again.
Okay, that's bisectability issue. Uncovered by splitting my patchset into
parts.
Could you check if applying "Part 2" of 5-level paging changes[1] would
help you?
x86: Convert the rest of the code to support p4d_t
To be exact, this one("x86: Convert the rest of the code to support p4d_t") fixes the issue.
Post by Xunlei Pang
x86/xen: Change __xen_pgd_walk() and xen_cleanmfnmap() to support p4d
x86/kasan: Prepare clear_pgds() to switch to <asm-generic/pgtable-nop4d.h>
x86/mm/pat: Add 5-level paging support
x86/efi: Add 5-level paging support
x86/kexec: Add 5-level paging support
Regards,
Xunlei
Post by Kirill A. Shutemov
Making the code work with both <asm-generic/5level-fixup.h> and
<asm-generic/pgtable-nop4d.h> would make it even uglier. Not sure if it
makes sense to address it on its own if second part fixes the situation.
_______________________________________________
kexec mailing list
http://lists.infradead.org/mailman/listinfo/kexec
Loading...