aboutsummaryrefslogtreecommitdiff
path: root/lib/libkvm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libkvm')
-rw-r--r--lib/libkvm/kvm_amd64.c46
-rw-r--r--lib/libkvm/kvm_open.315
2 files changed, 51 insertions, 10 deletions
diff --git a/lib/libkvm/kvm_amd64.c b/lib/libkvm/kvm_amd64.c
index e3640cf12243..acc7ac017a3c 100644
--- a/lib/libkvm/kvm_amd64.c
+++ b/lib/libkvm/kvm_amd64.c
@@ -109,8 +109,9 @@ _amd64_initvtop(kvm_t *kd)
{
struct kvm_nlist nl[2];
amd64_physaddr_t pa;
- kvaddr_t kernbase;
+ kvaddr_t kernbase, kernphys;
amd64_pml4e_t *PML4;
+ int found = 0;
kd->vmst = (struct vmstate *)_kvm_malloc(kd, sizeof(*kd->vmst));
if (kd->vmst == NULL) {
@@ -123,16 +124,43 @@ _amd64_initvtop(kvm_t *kd)
if (_kvm_read_core_phdrs(kd, &kd->vmst->phnum,
&kd->vmst->phdr) == -1)
return (-1);
+
+ for (size_t i = 0; i < kd->vmst->phnum; i++) {
+ if (kd->vmst->phdr[i].p_type == PT_DUMP_DELTA) {
+ /* Account for the 2M hole at KERNBASE. */
+ kernphys = kd->vmst->phdr[i].p_paddr -
+ kd->vmst->phdr[i].p_align;
+ kernbase = kd->vmst->phdr[i].p_vaddr;
+
+ found = 1;
+ break;
+ }
+ }
}
- nl[0].n_name = "kernbase";
- nl[1].n_name = 0;
+ if (found == 0) {
+ nl[0].n_name = "kernbase";
+ nl[1].n_name = 0;
- if (kvm_nlist2(kd, nl) != 0) {
- _kvm_err(kd, kd->program, "bad namelist - no kernbase");
- return (-1);
+ if (kvm_nlist2(kd, nl) != 0) {
+ _kvm_err(kd, kd->program, "bad namelist - no kernbase");
+ return (-1);
+ }
+
+ nl[0].n_name = "kernphys";
+ nl[1].n_name = 0;
+
+ /* XXX
+ * Relocatable kernels can still be loaded at 2M.
+ */
+ if (kvm_nlist2(kd, nl) != 1) {
+ _kvm_err(kd, kd->program, "cannot determine kernphys");
+ return (-1);
+ }
+
+ kernphys = 0;
+ kernbase = nl[0].n_value;
}
- kernbase = nl[0].n_value;
nl[0].n_name = "KPML4phys";
nl[1].n_name = 0;
@@ -141,8 +169,8 @@ _amd64_initvtop(kvm_t *kd)
_kvm_err(kd, kd->program, "bad namelist - no KPML4phys");
return (-1);
}
- if (kvm_read2(kd, (nl[0].n_value - kernbase), &pa, sizeof(pa)) !=
- sizeof(pa)) {
+ if (kvm_read2(kd, (nl[0].n_value - kernbase + kernphys), &pa,
+ sizeof(pa)) != sizeof(pa)) {
_kvm_err(kd, kd->program, "cannot read KPML4phys");
return (-1);
}
diff --git a/lib/libkvm/kvm_open.3 b/lib/libkvm/kvm_open.3
index a7e428748215..9a32719d537b 100644
--- a/lib/libkvm/kvm_open.3
+++ b/lib/libkvm/kvm_open.3
@@ -29,7 +29,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd March 20, 2017
+.Dd June 22, 2025
.Dt KVM_OPEN 3
.Os
.Sh NAME
@@ -245,7 +245,20 @@ The value passed via
was
.Dv NULL .
.El
+.Sh NOTE
+Full memory dumps taken on 13.x (excluding 13.0) and 14.x amd64 kernels
+will cause both
+.Fn kvm_open
+and
+.Fn kvm_open2
+to fail since they do not provide sufficient information to figure out
+where in physical memory the kernel was loaded.
+Full memory dumps have to be explicitly enabled by setting the
+.Va debug.minidump
+.Xr sysctl 8
+to 0.
.Sh SEE ALSO
+.Xr dumpon 8 ,
.Xr close 2 ,
.Xr open 2 ,
.Xr kvm 3 ,