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(a)jp.fujitsu.com>
Signed-off-by: HATAYAMA Daisuke <d.hatayama(a)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