[PATCH 1/2] makedumpfile: Initialize for vmalloc address translation support in PPC64 arch
Atsushi Kumagai
kumagai-atsushi at mxc.nes.nec.co.jp
Wed Jul 23 04:07:28 PDT 2014
Hello Hari,
>In this patch, initializing of page table information that is to be
>used for virtual to physical address translation of vmalloc region
>is added to the initialization sequence.
>
>Signed-off-by: Hari Bathini <hbathini at linux.vnet.ibm.com>
Thanks for your work, I have some comments:
>---
> arch/ppc64.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++
> makedumpfile.c | 7 +++++
> makedumpfile.h | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
> 3 files changed, 158 insertions(+), 1 deletion(-)
>
>diff --git a/arch/ppc64.c b/arch/ppc64.c
>index 09c0eb3..dabf2e7 100644
>--- a/arch/ppc64.c
>+++ b/arch/ppc64.c
>@@ -149,6 +149,58 @@ ppc64_vmemmap_init(void)
> return TRUE;
> }
>
>+static int
>+ppc64_vmalloc_init(void)
>+{
>+ info->page_buf = (char *)calloc(1, PAGESIZE());
>+ if (info->page_buf == NULL) {
>+ ERRMSG("Can't allocate memory for page tables. %s\n",
>+ strerror(errno));
>+ return FALSE;
>+ }
>+
>+ /* 2.6.14 layout */
>+ if (info->page_size == 65536) {
>+ /* 64K pagesize */
>+ if (info->kernel_version >= KERNEL_VERSION(3, 10, 0)) {
>+ info->l1_index_size = PTE_INDEX_SIZE_L4_64K_3_10;
>+ info->l2_index_size = PMD_INDEX_SIZE_L4_64K_3_10;
>+ info->l3_index_size = PUD_INDEX_SIZE_L4_64K;
>+ } else {
>+ info->l1_index_size = PTE_INDEX_SIZE_L4_64K;
>+ info->l2_index_size = PMD_INDEX_SIZE_L4_64K;
>+ info->l3_index_size = PUD_INDEX_SIZE_L4_64K;
>+ }
>+
>+ info->pte_shift = SYMBOL(demote_segment_4k) ?
>+ PTE_SHIFT_L4_64K_V2 : PTE_SHIFT_L4_64K_V1;
>+ info->l2_masked_bits = PMD_MASKED_BITS_64K;
>+ } else {
>+ /* 4K pagesize */
>+ info->l1_index_size = PTE_INDEX_SIZE_L4_4K;
>+ info->l2_index_size = PMD_INDEX_SIZE_L4_4K;
>+ info->l3_index_size = PUD_INDEX_SIZE_L4_4K;
>+
>+ info->pte_shift = PTE_SHIFT_L4_4K;
>+ info->l2_masked_bits = PMD_MASKED_BITS_4K;
>+ }
>+
>+ /* Compute ptrs per each level */
>+ info->l1_shift = info->page_shift;
>+ info->ptrs_per_l1 = (1 << info->l1_index_size);
>+ info->ptrs_per_l2 = (1 << info->l2_index_size);
>+ info->ptrs_per_l3 = (1 << info->l3_index_size);
>+
>+ info->ptrs_per_pgd = info->ptrs_per_l3;
>+
>+ /* Compute shifts */
>+ info->l2_shift = info->l1_shift + info->l1_index_size;
>+ info->l3_shift = info->l2_shift + info->l2_index_size;
>+ info->l4_shift = info->l3_shift + info->l3_index_size;
>+
>+ return TRUE;
>+}
>+
> /*
> * If the vmemmap address translation information is stored in the kernel,
> * make the translation.
>@@ -251,6 +303,15 @@ get_machdep_info_ppc64(void)
> info->vmalloc_start = vmalloc_start;
> DEBUG_MSG("vmalloc_start: %lx\n", vmalloc_start);
>
>+ if (SYMBOL(swapper_pg_dir) != NOT_FOUND_SYMBOL) {
>+ info->kernel_pgd = SYMBOL(swapper_pg_dir);
>+ } else if (SYMBOL(cpu_pgd) != NOT_FOUND_SYMBOL) {
>+ info->kernel_pgd = SYMBOL(cpu_pgd);
>+ } else {
>+ ERRMSG("No swapper_pg_dir or cpu_pgd symbols exist\n");
>+ return FALSE;
>+ }
>+
> if (SYMBOL(vmemmap_list) != NOT_FOUND_SYMBOL) {
> info->vmemmap_start = VMEMMAP_REGION_ID << REGION_SHIFT;
> info->vmemmap_end = info->vmemmap_start;
>@@ -265,6 +326,17 @@ get_machdep_info_ppc64(void)
> }
>
> int
>+get_versiondep_info_ppc64()
>+{
>+ if (ppc64_vmalloc_init() == FALSE) {
>+ ERRMSG("Can't initialize for vmalloc translation\n");
>+ return FALSE;
>+ }
>+
>+ return TRUE;
>+}
>+
>+int
> is_vmalloc_addr_ppc64(unsigned long vaddr)
> {
> return (info->vmalloc_start && vaddr >= info->vmalloc_start);
>diff --git a/makedumpfile.c b/makedumpfile.c
>index 3884aa5..f54ff8f 100644
>--- a/makedumpfile.c
>+++ b/makedumpfile.c
>@@ -1181,6 +1181,9 @@ get_symbol_info(void)
> SYMBOL_INIT(mmu_psize_defs, "mmu_psize_defs");
> SYMBOL_INIT(mmu_vmemmap_psize, "mmu_vmemmap_psize");
>
>+ SYMBOL_INIT(cpu_pgd, "cpu_pgd");
>+ SYMBOL_INIT(demote_segment_4k, "demote_segment_4k");
>+
> return TRUE;
> }
>
>@@ -1694,6 +1697,8 @@ write_vmcoreinfo_data(void)
> WRITE_SYMBOL("vmemmap_list", vmemmap_list);
> WRITE_SYMBOL("mmu_psize_defs", mmu_psize_defs);
> WRITE_SYMBOL("mmu_vmemmap_psize", mmu_vmemmap_psize);
>+ WRITE_SYMBOL("cpu_pgd", cpu_pgd);
>+ WRITE_SYMBOL("demote_segment_4k", demote_segment_4k);
>
> /*
> * write the structure size of 1st kernel
>@@ -2033,6 +2038,8 @@ read_vmcoreinfo(void)
> READ_SYMBOL("vmemmap_list", vmemmap_list);
> READ_SYMBOL("mmu_psize_defs", mmu_psize_defs);
> READ_SYMBOL("mmu_vmemmap_psize", mmu_vmemmap_psize);
>+ READ_SYMBOL("cpu_pgd", cpu_pgd);
>+ READ_SYMBOL("demote_segment_4k", demote_segment_4k);
>
> READ_STRUCTURE_SIZE("page", page);
> READ_STRUCTURE_SIZE("mem_section", mem_section);
>diff --git a/makedumpfile.h b/makedumpfile.h
>index 9402f05..7816241 100644
>--- a/makedumpfile.h
>+++ b/makedumpfile.h
>@@ -586,6 +586,58 @@ do { \
> #define _MAX_PHYSMEM_BITS_3_7 (46)
> #define REGION_SHIFT (60UL)
> #define VMEMMAP_REGION_ID (0xfUL)
>+
>+#define PGDIR_SHIFT \
>+ (info->page_shift + (info->page_shift -3) + (info->page_shift - 2))
>+#define PMD_SHIFT (info->page_shift + (info->page_shift - 3))
Please use PAGESHIFT() instead of info->page_shift like other arches.
>+
>+/* shift to put page number into pte */
>+#define PTE_SHIFT 16
>+
>+#define PTE_INDEX_SIZE 9
>+#define PMD_INDEX_SIZE 10
>+#define PGD_INDEX_SIZE 10
>+
>+#define PTRS_PER_PTE (1 << PTE_INDEX_SIZE)
>+#define PTRS_PER_PMD (1 << PMD_INDEX_SIZE)
>+#define PTRS_PER_PGD (1 << PGD_INDEX_SIZE)
>+
>+#define PGD_OFFSET(vaddr) ((vaddr >> PGDIR_SHIFT) & 0x7ff)
>+#define PMD_OFFSET(vaddr) ((vaddr >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
>+
>+/* 4-level page table support */
>+
>+/* 4K pagesize */
>+#define PTE_INDEX_SIZE_L4_4K 9
>+#define PMD_INDEX_SIZE_L4_4K 7
>+#define PUD_INDEX_SIZE_L4_4K 7
>+#define PGD_INDEX_SIZE_L4_4K 9
>+#define PTE_SHIFT_L4_4K 17
>+#define PMD_MASKED_BITS_4K 0
>+
>+/* 64K pagesize */
>+#define PTE_INDEX_SIZE_L4_64K 12
>+#define PMD_INDEX_SIZE_L4_64K 12
>+#define PUD_INDEX_SIZE_L4_64K 0
>+#define PGD_INDEX_SIZE_L4_64K 4
>+#define PTE_INDEX_SIZE_L4_64K_3_10 8
>+#define PMD_INDEX_SIZE_L4_64K_3_10 10
>+#define PGD_INDEX_SIZE_L4_64K_3_10 12
>+#define PTE_SHIFT_L4_64K_V1 32
>+#define PTE_SHIFT_L4_64K_V2 30
>+#define PMD_MASKED_BITS_64K 0x1ff
>+
>+#define L4_MASK \
>+ (info->kernel_version >= KERNEL_VERSION(3, 10, 0) ? 0xfff : 0x1ff)
>+#define L4_OFFSET(vaddr) ((vaddr >> (info->l4_shift)) & L4_MASK)
>+
>+#define PGD_OFFSET_L4(vaddr) \
>+ ((vaddr >> (info->l3_shift)) & (info->ptrs_per_l3 - 1))
>+
>+#define PMD_OFFSET_L4(vaddr) \
>+ ((vaddr >> (info->l2_shift)) & (info->ptrs_per_l2 - 1))
>+
>+#define _PAGE_PRESENT 0x1UL
> #endif
>
> #ifdef __powerpc32__
>@@ -731,10 +783,11 @@ unsigned long long vaddr_to_paddr_x86_64(unsigned long vaddr);
>
> #ifdef __powerpc64__ /* powerpc64 */
> int get_machdep_info_ppc64(void);
>+int get_versiondep_info_ppc64(void);
> unsigned long long vaddr_to_paddr_ppc64(unsigned long vaddr);
> #define get_phys_base() TRUE
> #define get_machdep_info() get_machdep_info_ppc64()
>-#define get_versiondep_info() TRUE
>+#define get_versiondep_info() get_versiondep_info_ppc64()
> #define vaddr_to_paddr(X) vaddr_to_paddr_ppc64(X)
> #endif /* powerpc64 */
>
>@@ -932,6 +985,25 @@ struct DumpInfo {
> struct ppc64_vmemmap *vmemmap_list;
>
> /*
>+ * page table info for ppc64
>+ */
>+ int ptrs_per_pgd;
>+ uint l3_index_size;
>+ uint l2_index_size;
>+ uint l1_index_size;
>+ uint ptrs_per_l3;
>+ uint ptrs_per_l2;
>+ uint ptrs_per_l1;
>+ uint l4_shift;
>+ uint l3_shift;
>+ uint l2_shift;
>+ uint l1_shift;
>+ uint pte_shift;
>+ uint l2_masked_bits;
>+ ulong kernel_pgd;
>+ char *page_buf; /* A page buffer to hold page table data */
Is it necessary to define page_buf as a member of struct DumpInfo ?
It's used only in ppc64_vtop_level4().
BTW, [PATCH 2/2] includes some spaces, I hope you will convert them
into tabs.
Thanks
Atsushi Kumagai
>+ /*
> * Filter config file containing filter commands to filter out kernel
> * data from vmcore.
> */
>@@ -1192,6 +1264,12 @@ struct symbol_table {
> unsigned long long vmemmap_list;
> unsigned long long mmu_vmemmap_psize;
> unsigned long long mmu_psize_defs;
>+
>+ /*
>+ * vm related symbols for ppc64 arch
>+ */
>+ unsigned long long cpu_pgd;
>+ unsigned long long demote_segment_4k;
> };
>
> struct size_table {
More information about the kexec
mailing list