diff options
author | Pratyush Anand <panand@redhat.com> | 2017-05-26 12:06:53 +0900 |
---|---|---|
committer | Atsushi Kumagai <ats-kumagai@wm.jp.nec.com> | 2017-06-08 15:52:31 +0900 |
commit | 4944f934845c81f28667b4d7d6452edba062e8e2 (patch) | |
tree | a3084b33f124c96b979955458f288802a2532214 /arch | |
parent | 2bfb7f1afefb30144f2d82f21e9aca7b266c54f5 (diff) |
[PATCH v5 2/2] x86_64: Calculate page_offset in case of re-filtering/sadump/virsh dump
we do not call get_elf_info() in case of refiltering and sadump.
Therefore, we will not have any pt_load in that case, and so we get:
get_page_offset_x86_64: Can't get any pt_load to calculate page offset.
However, we will have vmcoreinfo and vmlinux information in case of
re-filtering. So, we are able to find kaslr offset and we can get
page_offset_base address. Thus we can read the page offset as well.
If kaslr is not enabled and also we do not have valid PT_LOAD to
calculate page offset then use old method to find fixed page
offset.
In case of virsh dump virtual addresses in PT_LOAD are 0. Ignore such
addresses for the page_offset calculation.
Suggested-by: HATAYAMA Daisuke <d.hatayama@jp.fujitsu.com>
Signed-off-by: Pratyush Anand <panand@redhat.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86_64.c | 36 |
1 files changed, 29 insertions, 7 deletions
diff --git a/arch/x86_64.c b/arch/x86_64.c index fd2e8ac..18384a8 100644 --- a/arch/x86_64.c +++ b/arch/x86_64.c @@ -75,17 +75,39 @@ get_page_offset_x86_64(void) int i; unsigned long long phys_start; unsigned long long virt_start; + unsigned long page_offset_base; + + if (info->kaslr_offset) { + page_offset_base = get_symbol_addr("page_offset_base"); + page_offset_base += info->kaslr_offset; + if (!readmem(VADDR, page_offset_base, &info->page_offset, + sizeof(info->page_offset))) { + ERRMSG("Can't read page_offset_base.\n"); + return FALSE; + } + return TRUE; + } - for (i = 0; get_pt_load(i, &phys_start, NULL, &virt_start, NULL); i++) { - if (virt_start < __START_KERNEL_map - && phys_start != NOT_PADDR) { - info->page_offset = virt_start - phys_start; - return TRUE; + if (get_num_pt_loads()) { + for (i = 0; + get_pt_load(i, &phys_start, NULL, &virt_start, NULL); + i++) { + if (virt_start != NOT_KV_ADDR + && virt_start < __START_KERNEL_map + && phys_start != NOT_PADDR) { + info->page_offset = virt_start - phys_start; + return TRUE; + } } } - ERRMSG("Can't get any pt_load to calculate page offset.\n"); - return FALSE; + if (info->kernel_version < KERNEL_VERSION(2, 6, 27)) { + info->page_offset = __PAGE_OFFSET_ORIG; + } else { + info->page_offset = __PAGE_OFFSET_2_6_27; + } + + return TRUE; } int |