Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 22 Jun 2025 03:58:10 GMT
From:      Ahmad Khalifa <vexeduxr@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 308659acbff3 - main - libkvm/kvm_amd64: account for relocatable kernels
Message-ID:  <202506220358.55M3wAfg041035@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by vexeduxr:

URL: https://cgit.FreeBSD.org/src/commit/?id=308659acbff34c51e57693e4dbfa43cbbc910fa1

commit 308659acbff34c51e57693e4dbfa43cbbc910fa1
Author:     Ahmad Khalifa <vexeduxr@FreeBSD.org>
AuthorDate: 2025-05-21 20:41:15 +0000
Commit:     Ahmad Khalifa <vexeduxr@FreeBSD.org>
CommitDate: 2025-06-22 03:49:32 +0000

    libkvm/kvm_amd64: account for relocatable kernels
    
    amd64 kernels don't have to be loaded at 2M physical anymore, they can
    be anywhere in the lower 4G of the physical address space. The kernel
    now provides its physical address in an ELF section in the dump, so
    account for it.
    
    Reviewed by: markj
    Approved by: imp (mentor)
    Pull Request: https://github.com/freebsd/freebsd-src/pull/1706
---
 lib/libkvm/kvm_amd64.c | 46 +++++++++++++++++++++++++++++++++++++---------
 1 file changed, 37 insertions(+), 9 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);
 	}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202506220358.55M3wAfg041035>