diff --git a/src/addrxlat/x86_64.c b/src/addrxlat/x86_64.c index 4aa460ca..2e11fe9b 100644 --- a/src/addrxlat/x86_64.c +++ b/src/addrxlat/x86_64.c @@ -541,9 +541,10 @@ linux_ktext_extents(struct os_init_data *ctl, linearoff = ctl->sys->meth[ADDRXLAT_SYS_METH_KTEXT].param.linear.off; *high = *low; - status = highest_linear(&step, high, LINUX_KTEXT_END_NOKASLR, - linearoff); - if (status == ADDRXLAT_OK && *high == LINUX_KTEXT_END_NOKASLR) { + if (*high <= LINUX_KTEXT_END_NOKASLR) + status = highest_linear(&step, high, LINUX_KTEXT_END_NOKASLR, + linearoff); + if (status == ADDRXLAT_OK && *high >= LINUX_KTEXT_END_NOKASLR) { ++*high; status = highest_linear(&step, high, LINUX_KTEXT_END, linearoff); diff --git a/src/kdumpfile/util.c b/src/kdumpfile/util.c index d9648c15..23d698e8 100644 --- a/src/kdumpfile/util.c +++ b/src/kdumpfile/util.c @@ -1345,7 +1345,7 @@ read_blob_attr(kdump_ctx_t *ctx, unsigned fidx, off_t off, size_t size, struct fcache_chunk fch; kdump_status ret; - ret = fcache_get_chunk(ctx->shared->fcache, &fch, size, fidx, off); + ret = flatmap_get_chunk(ctx->shared->flatmap, &fch, size, fidx, off); if (ret != KDUMP_OK) return set_error(ctx, ret, "Cannot read %s (%zu bytes at %llu in %s)", diff --git a/tests/Makefile.am b/tests/Makefile.am index 6b7697fe..e751cebf 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -196,7 +196,9 @@ test_scripts = \ diskdump-empty-s390x \ diskdump-empty-x86_64 \ diskdump-basic-raw \ + diskdump-basic-vmcoreinfo \ diskdump-flat-raw \ + diskdump-flat-vmcoreinfo \ diskdump-multiread \ diskdump-excluded \ diskdump-split \ @@ -295,6 +297,7 @@ test_scripts = \ xlat-linux-x86_64-ktext-40M \ xlat-linux-x86_64-ktext-512M \ xlat-linux-x86_64-ktext-520M \ + xlat-linux-x86_64-ktext-54M-kaslr \ xlat-linux-x86_64-old \ xlat-linux-x86_64-old-nover \ xlat-linux-x86_64-2.6.11 \ @@ -392,6 +395,7 @@ dist_check_DATA = \ diskdump-split.expect.3 \ sys-xlat-x86_64-linux.expect \ sys-xlat-x86_64-linux-xen.expect \ + vmcoreinfo.data \ xlatmap.expect \ xlat-os-aarch64-none.expect \ xlat-os-ia32-none.expect \ @@ -476,6 +480,9 @@ dist_check_DATA = \ xlat-linux-x86_64-ktext-520M.data \ xlat-linux-x86_64-ktext-520M.expect \ xlat-linux-x86_64-ktext-520M.sym \ + xlat-linux-x86_64-ktext-54M-kaslr.data \ + xlat-linux-x86_64-ktext-54M-kaslr.expect \ + xlat-linux-x86_64-ktext-54M-kaslr.sym \ xlat-linux-x86_64-old.expect \ xlat-linux-x86_64-old-nover.data \ xlat-linux-x86_64-old-nover.expect \ diff --git a/tests/diskdump-basic b/tests/diskdump-basic index 1f676a05..831cc93f 100644 --- a/tests/diskdump-basic +++ b/tests/diskdump-basic @@ -14,7 +14,6 @@ echo "@0 $pageflags" > "$datafile" cat "$expectfile" >> "$datafile" ./mkdiskdump "$dumpfile" <length - : 0)); - subhdr.offset_note = htodump64(be, notes.filepos); - subhdr.size_note = htodump32(be, (notes.blob - ? notes.blob->length - : 0)); - subhdr.offset_eraseinfo = htodump64(be, eraseinfo.filepos); - subhdr.size_eraseinfo = htodump32(be, (eraseinfo.blob - ? eraseinfo.blob->length - : 0)); + if (vmcoreinfo) { + subhdr.offset_vmcoreinfo = htodump64(be, pos); + subhdr.size_vmcoreinfo = htodump32(be, vmcoreinfo->length); + if (write_chunk(f, pos, vmcoreinfo->data, vmcoreinfo->length, + "VMCOREINFO")) + return TEST_ERR; + pos += vmcoreinfo->length; + } else { + subhdr.offset_vmcoreinfo = htodump64(be, 0); + subhdr.size_vmcoreinfo = htodump32(be, 0); + } + if (notes) { + subhdr.offset_note = htodump64(be, pos); + subhdr.size_note = htodump32(be, notes->length); + if (write_chunk(f, pos, notes->data, notes->length, + "ELF notes")) + return TEST_ERR; + pos += notes->length; + } else { + subhdr.offset_note = htodump64(be, 0); + subhdr.size_note = htodump32(be, 0); + } + if (eraseinfo) { + subhdr.offset_eraseinfo = htodump64(be, pos); + subhdr.size_eraseinfo = htodump32(be, eraseinfo->length); + if (write_chunk(f, pos, notes->data, notes->length, + "eraseinfo")) + return TEST_ERR; + pos += eraseinfo->length; + } else { + subhdr.offset_eraseinfo = htodump64(be, 0); + subhdr.size_eraseinfo = htodump32(be, 0); + } subhdr.start_pfn_64 = htodump64(be, start_pfn); subhdr.end_pfn_64 = htodump64(be, end_pfn); subhdr.max_mapnr_64 = htodump64(be, max_mapnr); @@ -324,6 +342,7 @@ writeheader_64(FILE *f) struct timeval tv; struct disk_dump_header_64 hdr; struct kdump_sub_header_64 subhdr; + off_t pos; if (gettimeofday(&tv, NULL) != 0) { perror("gettimeofday"); @@ -363,23 +382,45 @@ writeheader_64(FILE *f) if (write_chunk(f, 0, &hdr, sizeof hdr, "header")) return TEST_ERR; + pos = DISKDUMP_HEADER_BLOCKS * block_size + sizeof(subhdr); subhdr.phys_base = htodump64(be, phys_base); subhdr.dump_level = htodump32(be, dump_level); subhdr.split = htodump32(be, split); subhdr.start_pfn = htodump64(be, start_pfn); subhdr.end_pfn = htodump64(be, end_pfn); - subhdr.offset_vmcoreinfo = htodump64(be, vmcoreinfo.filepos); - subhdr.size_vmcoreinfo = htodump64(be, (vmcoreinfo.blob - ? vmcoreinfo.blob->length - : 0)); - subhdr.offset_note = htodump64(be, notes.filepos); - subhdr.size_note = htodump64(be, (notes.blob - ? notes.blob->length - : 0)); - subhdr.offset_eraseinfo = htodump64(be, eraseinfo.filepos); - subhdr.size_eraseinfo = htodump64(be, (eraseinfo.blob - ? eraseinfo.blob->length - : 0)); + if (vmcoreinfo) { + subhdr.offset_vmcoreinfo = htodump64(be, pos); + subhdr.size_vmcoreinfo = htodump64(be, vmcoreinfo->length); + if (write_chunk(f, pos, vmcoreinfo->data, vmcoreinfo->length, + "VMCOREINFO")) + return TEST_ERR; + pos += vmcoreinfo->length; + } else { + subhdr.offset_vmcoreinfo = htodump64(be, 0); + subhdr.size_vmcoreinfo = htodump64(be, 0); + } + if (notes) { + subhdr.offset_note = htodump64(be, pos); + subhdr.size_note = htodump64(be, notes->length); + if (write_chunk(f, pos, notes->data, notes->length, + "ELF notes")) + return TEST_ERR; + pos += notes->length; + } else { + subhdr.offset_note = htodump64(be, 0); + subhdr.size_note = htodump64(be, 0); + } + if (eraseinfo) { + subhdr.offset_eraseinfo = htodump64(be, pos); + subhdr.size_eraseinfo = htodump64(be, eraseinfo->length); + if (write_chunk(f, pos, notes->data, notes->length, + "eraseinfo")) + return TEST_ERR; + pos += eraseinfo->length; + } else { + subhdr.offset_eraseinfo = htodump64(be, 0); + subhdr.size_eraseinfo = htodump64(be, 0); + } subhdr.start_pfn_64 = htodump64(be, start_pfn); subhdr.end_pfn_64 = htodump64(be, end_pfn); subhdr.max_mapnr_64 = htodump64(be, max_mapnr); @@ -904,20 +945,20 @@ main(int argc, char **argv) return rc; if (vmcoreinfo_file) { - vmcoreinfo.blob = slurp(vmcoreinfo_file); - if (vmcoreinfo.blob == NULL) + vmcoreinfo = slurp(vmcoreinfo_file); + if (vmcoreinfo == NULL) return TEST_ERR; } if (note_file) { - notes.blob = slurp(note_file); - if (notes.blob == NULL) + notes = slurp(note_file); + if (notes == NULL) return TEST_ERR; } if (eraseinfo_file) { - eraseinfo.blob = slurp(eraseinfo_file); - if (eraseinfo.blob == NULL) + eraseinfo = slurp(eraseinfo_file); + if (eraseinfo == NULL) return TEST_ERR; } diff --git a/tests/vmcoreinfo.data b/tests/vmcoreinfo.data new file mode 100644 index 00000000..986b6bc0 --- /dev/null +++ b/tests/vmcoreinfo.data @@ -0,0 +1,3 @@ +OSRELEASE=6.4.3-1-default +PAGESIZE=4096 +CRASHTIME=1689103980 diff --git a/tests/xlat-linux-x86_64-ktext-54M-kaslr b/tests/xlat-linux-x86_64-ktext-54M-kaslr new file mode 100755 index 00000000..7d1596e1 --- /dev/null +++ b/tests/xlat-linux-x86_64-ktext-54M-kaslr @@ -0,0 +1,14 @@ +#! /bin/bash + +# +# Check Linux X86_64 translation with a 54M kASLR ktext mapping starting +# above the fixed (non-kASLR) virtual address region. +# + +opts=( + arch=x86_64 + ostype=linux + phys_base=0x23c00000 +) + +. "$srcdir"/xlat-os-common diff --git a/tests/xlat-linux-x86_64-ktext-54M-kaslr.data b/tests/xlat-linux-x86_64-ktext-54M-kaslr.data new file mode 100644 index 00000000..2c77ff61 --- /dev/null +++ b/tests/xlat-linux-x86_64-ktext-54M-kaslr.data @@ -0,0 +1,9 @@ +# kernel text +@0x4c610ff8 +000000004c615067 +@0x4c615ff0 +000000004c616063 +@0x4c616000 +0000000000000000*313 +000000004ae001e1*27+200000 +0000000000000000*172 diff --git a/tests/xlat-linux-x86_64-ktext-54M-kaslr.expect b/tests/xlat-linux-x86_64-ktext-54M-kaslr.expect new file mode 100644 index 00000000..b03a342f --- /dev/null +++ b/tests/xlat-linux-x86_64-ktext-54M-kaslr.expect @@ -0,0 +1,40 @@ +@rootpgt: PGT + target_as=MACHPHYSADDR + root=KVADDR:0xffffffffa8a10000 + pte_mask=0x0 + pte_format=x86_64 + fields=12,9,9,9,9 + +@ktext: LINEAR + target_as=KPHYSADDR + off=0xa3c00000 + +@machphys_kphys: LINEAR + target_as=KPHYSADDR + off=0x0 + +@kphys_machphys: LINEAR + target_as=MACHPHYSADDR + off=0x0 + +KV -> HW: +0-7fffffffffff: @rootpgt +800000000000-ffff7fffffffffff: NONE +ffff800000000000-ffffffffffffffff: @rootpgt + +KV -> PHYS: +0-7fffffffffff: @rootpgt +800000000000-ffff7fffffffffff: NONE +ffff800000000000-ffffffffa71fffff: @rootpgt +ffffffffa7200000-ffffffffaa7fffff: @ktext +ffffffffaa800000-ffffffffffffffff: @rootpgt + +KPHYS -> DIRECT: + +MACHPHYS -> KPHYS: +0-fffffffffffff: @machphys_kphys +10000000000000-ffffffffffffffff: NONE + +KPHYS -> MACHPHYS: +0-fffffffffffff: @kphys_machphys +10000000000000-ffffffffffffffff: NONE diff --git a/tests/xlat-linux-x86_64-ktext-54M-kaslr.sym b/tests/xlat-linux-x86_64-ktext-54M-kaslr.sym new file mode 100644 index 00000000..3abd9936 --- /dev/null +++ b/tests/xlat-linux-x86_64-ktext-54M-kaslr.sym @@ -0,0 +1,4 @@ +@VALUE(init_top_pgt) +ffffffffa8a10000 +@VALUE(_stext) +ffffffffa7200000