Skip to content

Commit

Permalink
libdrgn: x86_64: allow phys_base to be 0
Browse files Browse the repository at this point in the history
Mark reported recursive address translation errors when debugging a QEMU
guest memory dump. We're supposed to be handling this in
linux_kernel_pgtable_iterator_next_x86_64() by translating
swapper_pg_dir to a physical address. However, it decides whether
phys_base was present in the VMCOREINFO by comparing phys_base to 0, and
this dump legitimately had a phys_base of 0. Add a separate flag so we
can distinguish missing vs 0.

Reported-and-tested-by: Mark Harmstone <maharmstone@fb.com>
Fixes: 5b39bfb ("libdrgn: x86_64: avoid recursive address translation for swapper_pg_dir")
Signed-off-by: Omar Sandoval <osandov@osandov.com>
  • Loading branch information
osandov committed Dec 18, 2024
1 parent 7ad4022 commit 36030b9
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 8 deletions.
14 changes: 6 additions & 8 deletions libdrgn/arch_x86_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -607,15 +607,13 @@ linux_kernel_pgtable_iterator_next_x86_64(struct drgn_program *prog,
for (;; level--) {
uint64_t table;
bool table_physical;
if (level == levels && prog->vmcoreinfo.phys_base &&
if (level == levels && prog->vmcoreinfo.have_phys_base &&
it->it.pgtable == prog->vmcoreinfo.swapper_pg_dir) {
// Avoid recursive address translation on swapper_pg_dir by
// directly resolving to a physical address. Don't do
// this if phys_base is 0, since that likely means it
// was not present in the vmcoreinfo. It has been
// present since Linux kernel commit 401721ecd1dc
// ("kexec: export the value of phys_base instead of
// symbol address") (in v4.10).
// Avoid recursive address translation on swapper_pg_dir
// by directly resolving to a physical address.
// phys_base has been present since Linux kernel commit
// 401721ecd1dc ("kexec: export the value of phys_base
// instead of symbol address") (in v4.10).
table = it->it.pgtable + prog->vmcoreinfo.phys_base - START_KERNEL_MAP;
table_physical = true;
} else if (level == levels) {
Expand Down
1 change: 1 addition & 0 deletions libdrgn/drgn_program_parse_vmcoreinfo.inc.strswitch
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ struct drgn_error *drgn_program_parse_vmcoreinfo(struct drgn_program *prog,
&prog->vmcoreinfo.phys_base);
if (err)
return err;
prog->vmcoreinfo.have_phys_base = true;
break;
}
@case "NUMBER(KERNELPACMASK)"@
Expand Down
2 changes: 2 additions & 0 deletions libdrgn/program.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ struct drgn_program {
bool arm_lpae;
/** Whether `CRASHTIME` was in the VMCOREINFO. */
bool have_crashtime;
/** Whether `phys_base` was in the VMCOREINFO. */
bool have_phys_base;
/**
* `PAGE_SHIFT` of the kernel (derived from
* `PAGE_SIZE`).
Expand Down

0 comments on commit 36030b9

Please sign in to comment.