[Crash-utility] [PATCH v2 1/2] Introduce x86_64_kvtop_pagetable

Takao Indoh indou.takao at jp.fujitsu.com
Mon Oct 16 09:41:38 UTC 2017


This patch introduces new function x86_64_kvtop_pagetable() to translate
virtual address to physical address. Unlike x86_64_kvtop(),
x86_64_kvtop_pagetable() simply converts given virtual address to
physical address using pagetable.

To solve kaslr problem of virsh dump and sadump, kaslr offset and
phys_base need to be calculated before symbol data is loaded. This
calculation needs translation of kernel virtual address to physical
address. Current kvtop() implementation tries to use x86_64_VTOP for
translation at first, but this does not work for this purpose because
x86_64_VTOP uses phys_base. So x86_64_kvtop_pagetable() is needed which
does not use phys_base.

Signed-off-by: Takao Indoh <indou.takao at jp.fujitsu.com>
Signed-off-by: HATAYAMA Daisuke <d.hatayama at jp.fujitsu.com>
---
 defs.h   |  1 +
 x86_64.c | 26 +++++++++++++++++++++++++-
 2 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/defs.h b/defs.h
index fd97ffe..cddca93 100644
--- a/defs.h
+++ b/defs.h
@@ -5622,6 +5622,7 @@ void x86_64_display_idt_table(void);
 #define display_idt_table() x86_64_display_idt_table()
 long x86_64_exception_frame(ulong, ulong, char *, struct bt_info *, FILE *);
 #define EFRAME_INIT (0)
+int x86_64_kvtop_pagetable(ulong, physaddr_t *, int);
 
 struct x86_64_pt_regs_offsets {
         long r15;
diff --git a/x86_64.c b/x86_64.c
index 44d0c98..fc48425 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -119,6 +119,7 @@ static int x86_64_verify_paddr(uint64_t);
 static void GART_init(void);
 static void x86_64_exception_stacks_init(void);
 static int in_START_KERNEL_map(ulong);
+static int __x86_64_kvtop(struct task_context *, ulong, physaddr_t *, int, int);
 
 struct machine_specific x86_64_machine_specific = { 0 };
 
@@ -1964,6 +1965,17 @@ no_upage:
 	return FALSE;
 }
 
+int
+x86_64_kvtop_pagetable(ulong kvaddr, physaddr_t *paddr, int verbose)
+{
+	return __x86_64_kvtop(NULL, kvaddr, paddr, verbose, 1);
+}
+
+static int
+x86_64_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbose)
+{
+	return __x86_64_kvtop(tc, kvaddr, paddr, verbose, 0);
+}
 
 /*
  *  Translates a kernel virtual address to its physical address.  cmd_vtop()
@@ -1971,7 +1983,7 @@ no_upage:
  *  other callers quietly accept the translation.
  */
 static int
-x86_64_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbose)
+__x86_64_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbose, int use_pagetable)
 {
 	ulong *pml4;
         ulong *pgd;
@@ -1985,6 +1997,16 @@ x86_64_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbo
 	ulong pte;
 	physaddr_t physpage;
 
+	if (use_pagetable) {
+		FILL_PML4();
+		pml4 = ((ulong *)machdep->machspec->pml4) + pml4_index(kvaddr);
+		if (verbose) {
+			fprintf(fp, "PML4 DIRECTORY: %lx\n", vt->kernel_pgd[0]);
+			fprintf(fp, "PAGE DIRECTORY: %lx\n", *pml4);
+		}
+		goto start_vtop_with_pagetable;
+	}
+
         if (!IS_KVADDR(kvaddr))
                 return FALSE;
 
@@ -2031,6 +2053,8 @@ x86_64_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbo
                		fprintf(fp, "PAGE DIRECTORY: %lx\n", *pml4);
 		}
 	}
+
+start_vtop_with_pagetable:
 	if (!(*pml4) & _PAGE_PRESENT)
 		goto no_kpage;
 	pgd_paddr = (*pml4) & PHYSICAL_PAGE_MASK;
-- 
2.9.5





More information about the Crash-utility mailing list