From: Baoquan He <bhe@redhat.com>
To: kexec@lists.infradead.org
Cc: douly.fnst@cn.fujitsu.com, indou.takao@jp.fujitsu.com,
mas-hayashi@tg.jp.nec.com, mas-tachibana@vf.jp.nec.com
Subject: [PATCH 4/4] arch/x86_64: Add 5-level paging support
Date: Fri, 2 Mar 2018 13:48:41 +0800 [thread overview]
Message-ID: <20180302054841.22195-5-bhe@redhat.com> (raw)
In-Reply-To: <20180302054841.22195-1-bhe@redhat.com>
From: Dou Liyang <douly.fnst@cn.fujitsu.com>
Now, kernel can use 5-level page tables in x86_64 system.
Add the 5-level paging support for makedumpfile.
Signed-off-by: Dou Liyang <douly.fnst@cn.fujitsu.com>
---
arch/x86_64.c | 76 ++++++++++++++++++++++++++++++++++++++++++----------------
makedumpfile.h | 17 +++++++++++++
2 files changed, 72 insertions(+), 21 deletions(-)
diff --git a/arch/x86_64.c b/arch/x86_64.c
index e88ee0b..b242f36 100644
--- a/arch/x86_64.c
+++ b/arch/x86_64.c
@@ -112,6 +112,8 @@ get_page_offset_x86_64(void)
if (info->kernel_version < KERNEL_VERSION(2, 6, 27)) {
info->page_offset = __PAGE_OFFSET_ORIG;
+ } else if(check_5level_paging()) {
+ info->page_offset = __PAGE_OFFSET_5LEVEL;
} else {
info->page_offset = __PAGE_OFFSET_2_6_27;
}
@@ -243,6 +245,8 @@ get_versiondep_info_x86_64(void)
info->max_physmem_bits = _MAX_PHYSMEM_BITS_ORIG;
else if (info->kernel_version < KERNEL_VERSION(2, 6, 31))
info->max_physmem_bits = _MAX_PHYSMEM_BITS_2_6_26;
+ else if(check_5level_paging())
+ info->max_physmem_bits = _MAX_PHYSMEM_BITS_5LEVEL;
else
info->max_physmem_bits = _MAX_PHYSMEM_BITS_2_6_31;
@@ -252,6 +256,9 @@ get_versiondep_info_x86_64(void)
if (info->kernel_version < KERNEL_VERSION(2, 6, 31)) {
info->vmemmap_start = VMEMMAP_START_ORIG;
info->vmemmap_end = VMEMMAP_END_ORIG;
+ } else if(check_5level_paging()) {
+ info->vmemmap_start = VMEMMAP_START_5LEVEL;
+ info->vmemmap_end = VMEMMAP_END_5LEVEL;
} else {
info->vmemmap_start = VMEMMAP_START_2_6_31;
info->vmemmap_end = VMEMMAP_END_2_6_31;
@@ -268,6 +275,7 @@ __vtop4_x86_64(unsigned long vaddr, unsigned long pagetable)
{
unsigned long page_dir, pgd, pud_paddr, pud_pte, pmd_paddr, pmd_pte;
unsigned long pte_paddr, pte;
+ unsigned long p4d_paddr, p4d_pte;
/*
* Get PGD.
@@ -278,23 +286,56 @@ __vtop4_x86_64(unsigned long vaddr, unsigned long pagetable)
if (page_dir == NOT_PADDR)
return NOT_PADDR;
}
- page_dir += pgd_index(vaddr) * sizeof(unsigned long);
- if (!readmem(PADDR, page_dir, &pgd, sizeof pgd)) {
- ERRMSG("Can't get pgd (page_dir:%lx).\n", page_dir);
- return NOT_PADDR;
- }
- if (info->vaddr_for_vtop == vaddr)
- MSG(" PGD : %16lx => %16lx\n", page_dir, pgd);
- if (!(pgd & _PAGE_PRESENT)) {
- ERRMSG("Can't get a valid pgd.\n");
- return NOT_PADDR;
+ if (check_5level_paging()) {
+ page_dir += pgd5_index(vaddr) * sizeof(unsigned long);
+ if (!readmem(PADDR, page_dir, &pgd, sizeof pgd)) {
+ ERRMSG("Can't get pgd (page_dir:%lx).\n", page_dir);
+ return NOT_PADDR;
+ }
+ if (info->vaddr_for_vtop == vaddr)
+ MSG(" PGD : %16lx => %16lx\n", page_dir, pgd);
+
+ if (!(pgd & _PAGE_PRESENT)) {
+ ERRMSG("Can't get a valid pgd.\n");
+ return NOT_PADDR;
+ }
+ /*
+ * Get P4D.
+ */
+ p4d_paddr = pgd & ENTRY_MASK;
+ p4d_paddr += p4d_index(vaddr) * sizeof(unsigned long);
+ if (!readmem(PADDR, p4d_paddr, &p4d_pte, sizeof p4d_pte)) {
+ ERRMSG("Can't get p4d_pte (p4d_paddr:%lx).\n", p4d_paddr);
+ return NOT_PADDR;
+ }
+ if (info->vaddr_for_vtop == vaddr)
+ MSG(" P4D : %16lx => %16lx\n", p4d_paddr, p4d_pte);
+
+ if (!(p4d_pte & _PAGE_PRESENT)) {
+ ERRMSG("Can't get a valid p4d_pte.\n");
+ return NOT_PADDR;
+ }
+ pud_paddr = p4d_pte & ENTRY_MASK;
+ }else {
+ page_dir += pgd_index(vaddr) * sizeof(unsigned long);
+ if (!readmem(PADDR, page_dir, &pgd, sizeof pgd)) {
+ ERRMSG("Can't get pgd (page_dir:%lx).\n", page_dir);
+ return NOT_PADDR;
+ }
+ if (info->vaddr_for_vtop == vaddr)
+ MSG(" PGD : %16lx => %16lx\n", page_dir, pgd);
+
+ if (!(pgd & _PAGE_PRESENT)) {
+ ERRMSG("Can't get a valid pgd.\n");
+ return NOT_PADDR;
+ }
+ pud_paddr = pgd & ENTRY_MASK;
}
/*
* Get PUD.
*/
- pud_paddr = pgd & ENTRY_MASK;
pud_paddr += pud_index(vaddr) * sizeof(unsigned long);
if (!readmem(PADDR, pud_paddr, &pud_pte, sizeof pud_pte)) {
ERRMSG("Can't get pud_pte (pud_paddr:%lx).\n", pud_paddr);
@@ -361,12 +402,7 @@ vtop4_x86_64(unsigned long vaddr)
else if (SYMBOL(init_top_pgt) != NOT_FOUND_SYMBOL)
init_level4_pgt = SYMBOL(init_top_pgt);
else {
- ERRMSG("Can't get the symbol of init_level4_pgt.\n");
- return NOT_PADDR;
- }
-
- if (SYMBOL(level4_kernel_pgt) != NOT_FOUND_SYMBOL) {
- ERRMSG("Kernel is built with 5-level page tables\n");
+ ERRMSG("Can't get the symbol of init_level4_pgt/init_top_pgt.\n");
return NOT_PADDR;
}
@@ -605,10 +641,6 @@ find_vmemmap_x86_64()
return FAILED;
}
- if (SYMBOL(level4_kernel_pgt) != NOT_FOUND_SYMBOL) {
- ERRMSG("kernel is configured for 5-level page tables\n");
- return FAILED;
- }
pagestructsize = size_table.page;
hugepagesize = PTRS_PER_PMD * info->page_size;
vaddr_base = info->vmemmap_start;
@@ -630,12 +662,14 @@ find_vmemmap_x86_64()
/* outer loop is for pud entries in the pgd */
for (pgdindex = 0, pgdp = (unsigned long *)pgd_addr; pgdindex < num_puds;
pgdindex++, pgdp++) {
+
/* read the pgd one word at a time, into pud_addr */
if (!readmem(PADDR, (unsigned long long)pgdp, (void *)&pud_addr,
sizeof(unsigned long))) {
ERRMSG("Can't get pgd entry for slot %d.\n", pgd_index);
return FAILED;
}
+
/* mask the pgd entry for the address of the pud page */
pud_addr &= PMASK;
if (pud_addr == 0)
diff --git a/makedumpfile.h b/makedumpfile.h
index a0d1c13..d26c30b 100644
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -581,16 +581,21 @@ unsigned long get_kvbase_arm64(void);
#ifdef __x86_64__
#define __PAGE_OFFSET_ORIG (0xffff810000000000) /* 2.6.26, or former */
#define __PAGE_OFFSET_2_6_27 (0xffff880000000000) /* 2.6.27, or later */
+#define __PAGE_OFFSET_5LEVEL (0xff10000000000000) /* 5-level page table */
#define VMALLOC_START_ORIG (0xffffc20000000000) /* 2.6.30, or former */
#define VMALLOC_START_2_6_31 (0xffffc90000000000) /* 2.6.31, or later */
+#define VMALLOC_START_5LEVEL (0xffa0000000000000) /* 5-level page table */
#define VMALLOC_END_ORIG (0xffffe1ffffffffff) /* 2.6.30, or former */
#define VMALLOC_END_2_6_31 (0xffffe8ffffffffff) /* 2.6.31, or later */
+#define VMALLOC_END_5LEVEL (0xffd1ffffffffffff) /* 5-level page table */
#define VMEMMAP_START_ORIG (0xffffe20000000000) /* 2.6.30, or former */
#define VMEMMAP_START_2_6_31 (0xffffea0000000000) /* 2.6.31, or later */
+#define VMEMMAP_START_5LEVEL (0xffd4000000000000) /* 5-level page table */
#define VMEMMAP_END_ORIG (0xffffe2ffffffffff) /* 2.6.30, or former */
#define VMEMMAP_END_2_6_31 (0xffffeaffffffffff) /* 2.6.31, or later */
+#define VMEMMAP_END_5LEVEL (0xffd5ffffffffffff) /* 5-level page table */
#define __START_KERNEL_map (0xffffffff80000000)
#define KVBASE PAGE_OFFSET
@@ -598,6 +603,7 @@ unsigned long get_kvbase_arm64(void);
#define _MAX_PHYSMEM_BITS_ORIG (40)
#define _MAX_PHYSMEM_BITS_2_6_26 (44)
#define _MAX_PHYSMEM_BITS_2_6_31 (46)
+#define _MAX_PHYSMEM_BITS_5LEVEL (52)
/*
* 4 Levels paging
@@ -617,7 +623,18 @@ unsigned long get_kvbase_arm64(void);
#define PMD_SIZE (1UL << PMD_SHIFT)
#define PMD_MASK (~(PMD_SIZE - 1))
+/*
+ * 5 Levels paging
+ */
+#define PGD_SHIFT_5LEVEL (48)
+#define P4D_SHIFT (39)
+
+#define PTRS_PER_PGD_5LEVEL (512)
+#define PTRS_PER_P4D (512)
+
+#define pgd5_index(address) (((address) >> PGD_SHIFT_5LEVEL) & (PTRS_PER_PGD_5LEVEL - 1))
#define pgd_index(address) (((address) >> PGD_SHIFT) & (PTRS_PER_PGD - 1))
+#define p4d_index(address) (((address) >> P4D_SHIFT) & (PTRS_PER_P4D - 1))
#define pud_index(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD - 1))
#define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
#define pte_index(address) (((address) >> PTE_SHIFT) & (PTRS_PER_PTE - 1))
--
2.13.6
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
next prev parent reply other threads:[~2018-03-02 5:49 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-03-02 5:48 [PATCH 0/4] Makedumpfile: Add 5-level paging support Baoquan He
2018-03-02 5:48 ` [PATCH 1/4] arch/x86_64: Cleanup the address translation of the 4-level page tables Baoquan He
2018-05-07 7:19 ` Masaki Tachibana
2018-05-07 7:30 ` Dou Liyang
2018-05-07 7:31 ` Baoquan He
2018-03-02 5:48 ` [PATCH 2/4] Makedumpfile: Add pgtable_l5_enabled to number_table Baoquan He
2018-05-07 7:20 ` Masaki Tachibana
2018-05-07 7:33 ` Dou Liyang
2018-03-02 5:48 ` [PATCH 3/4] Makedumpfile: Add a new function check_5level_paging() Baoquan He
2018-05-07 7:21 ` Masaki Tachibana
2018-05-07 8:03 ` Baoquan He
2018-03-02 5:48 ` Baoquan He [this message]
2018-05-07 7:22 ` [PATCH 4/4] arch/x86_64: Add 5-level paging support Masaki Tachibana
2018-04-12 2:45 ` [PATCH 0/4] Makedumpfile: " Baoquan He
2018-04-12 4:42 ` Masaki Tachibana
2018-04-12 4:55 ` Baoquan He
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=20180302054841.22195-5-bhe@redhat.com \
--to=bhe@redhat.com \
--cc=douly.fnst@cn.fujitsu.com \
--cc=indou.takao@jp.fujitsu.com \
--cc=kexec@lists.infradead.org \
--cc=mas-hayashi@tg.jp.nec.com \
--cc=mas-tachibana@vf.jp.nec.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