git: 51b1272fca66 - main - libkvm: route powerpc64 minidumps to minidump backend

From: Minsoo Choo <mchoo_at_FreeBSD.org>
Date: Mon, 28 Sep 2026 15:39:57 UTC
The branch main has been updated by mchoo:

URL: https://cgit.FreeBSD.org/src/commit/?id=51b1272fca667ad4c57d94ca24600bf68f29ebd2

commit 51b1272fca667ad4c57d94ca24600bf68f29ebd2
Author:     Minsoo Choo <mchoo@FreeBSD.org>
AuthorDate: 2026-09-16 03:26:34 +0000
Commit:     Minsoo Choo <mchoo@FreeBSD.org>
CommitDate: 2026-09-28 15:39:46 +0000

    libkvm: route powerpc64 minidumps to minidump backend
    
    The regular powerpc64 core probes only checked the kernel ELF and thus
    also matched minidumps.  In particular, the powerpc64le probe could
    claim a minidump before the minidump backend and then reject it as an
    invalid ELF core.
    
    Exclude minidumps from both regular powerpc64 probes and add a
    regression test that verifies a powerpc64le minidump reaches the
    minidump parser.
    
    Reviewed by:    jhibbits
    Approved by:    olce (mentor)
    Fixes:          f4eb39ba6bc9 ("[PowerPC64LE] libkvm powerpc64le support.")
    MFC after:      2 weeks
    Sponsored by:   FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D59719
---
 lib/libkvm/kvm_powerpc64.c        |  6 ++--
 lib/libkvm/tests/kvm_open2_test.c | 67 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 71 insertions(+), 2 deletions(-)

diff --git a/lib/libkvm/kvm_powerpc64.c b/lib/libkvm/kvm_powerpc64.c
index f0292ec8d757..b3dda7becc80 100644
--- a/lib/libkvm/kvm_powerpc64.c
+++ b/lib/libkvm/kvm_powerpc64.c
@@ -187,7 +187,8 @@ _powerpc64_probe(kvm_t *kd)
 {
 
 	return (_kvm_probe_elf_kernel(kd, ELFCLASS64, EM_PPC64) &&
-	    kd->nlehdr.e_ident[EI_DATA] == ELFDATA2MSB);
+	    kd->nlehdr.e_ident[EI_DATA] == ELFDATA2MSB &&
+	    !_kvm_is_minidump(kd));
 }
 
 static int
@@ -195,7 +196,8 @@ _powerpc64le_probe(kvm_t *kd)
 {
 
 	return (_kvm_probe_elf_kernel(kd, ELFCLASS64, EM_PPC64) &&
-	    kd->nlehdr.e_ident[EI_DATA] == ELFDATA2LSB);
+	    kd->nlehdr.e_ident[EI_DATA] == ELFDATA2LSB &&
+	    !_kvm_is_minidump(kd));
 }
 
 static int
diff --git a/lib/libkvm/tests/kvm_open2_test.c b/lib/libkvm/tests/kvm_open2_test.c
index 0ad0b47de948..5f882578c1f2 100644
--- a/lib/libkvm/tests/kvm_open2_test.c
+++ b/lib/libkvm/tests/kvm_open2_test.c
@@ -24,6 +24,8 @@
  */
 
 #include <sys/param.h>
+#include <sys/endian.h>
+#include <elf.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <kvm.h>
@@ -33,11 +35,61 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 
 #include <atf-c.h>
 
 #include "kvm_test_common.h"
 
+static int
+unresolved_symbol(const char *name __unused, kvaddr_t *value __unused)
+{
+
+	return (-1);
+}
+
+static void
+create_powerpc64le_kernel(const char *path)
+{
+	Elf64_Ehdr ehdr;
+	ssize_t n;
+	int fd;
+
+	memset(&ehdr, 0, sizeof(ehdr));
+	memcpy(ehdr.e_ident, ELFMAG, SELFMAG);
+	ehdr.e_ident[EI_CLASS] = ELFCLASS64;
+	ehdr.e_ident[EI_DATA] = ELFDATA2LSB;
+	ehdr.e_ident[EI_VERSION] = EV_CURRENT;
+	ehdr.e_type = htole16(ET_DYN);
+	ehdr.e_machine = htole16(EM_PPC64);
+	ehdr.e_version = htole32(EV_CURRENT);
+	ehdr.e_ehsize = htole16(sizeof(ehdr));
+
+	fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+	ATF_REQUIRE(fd != -1);
+	n = write(fd, &ehdr, sizeof(ehdr));
+	ATF_REQUIRE_EQ(n, (ssize_t)sizeof(ehdr));
+	ATF_REQUIRE(close(fd) == 0);
+}
+
+static void
+create_invalid_powerpc64_minidump(const char *path)
+{
+	char buf[PAGE_SIZE];
+	ssize_t n;
+	int fd;
+
+	memset(buf, 0, sizeof(buf));
+	memcpy(buf, "minidump FreeBSD/powerpc64",
+	    sizeof("minidump FreeBSD/powerpc64"));
+
+	fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+	ATF_REQUIRE(fd != -1);
+	n = write(fd, buf, sizeof(buf));
+	ATF_REQUIRE_EQ(n, (ssize_t)sizeof(buf));
+	ATF_REQUIRE(close(fd) == 0);
+}
+
 ATF_TC_WITHOUT_HEAD(kvm_open2_negative_test_nonexistent_corefile);
 ATF_TC_BODY(kvm_open2_negative_test_nonexistent_corefile, tc)
 {
@@ -101,6 +153,20 @@ ATF_TC_BODY(kvm_open2_negative_test_invalid_execfile, tc)
 	ATF_REQUIRE_MSG(kd == NULL, "kvm_open2 succeeded unexpectedly");
 }
 
+ATF_TC_WITHOUT_HEAD(kvm_open2_powerpc64le_minidump_probe);
+ATF_TC_BODY(kvm_open2_powerpc64le_minidump_probe, tc)
+{
+	kvm_t *kd;
+
+	create_powerpc64le_kernel("kernel");
+	create_invalid_powerpc64_minidump("vmcore");
+	errbuf_clear();
+	kd = kvm_open2("kernel", "vmcore", O_RDONLY, errbuf,
+	    unresolved_symbol);
+	ATF_REQUIRE_MSG(kd == NULL, "kvm_open2 succeeded unexpectedly");
+	ATF_CHECK_MATCH("wrong minidump version", errbuf);
+}
+
 ATF_TP_ADD_TCS(tp)
 {
 
@@ -108,6 +174,7 @@ ATF_TP_ADD_TCS(tp)
 	ATF_TP_ADD_TC(tp, kvm_open2_negative_test_invalid_execfile);
 	ATF_TP_ADD_TC(tp, kvm_open2_negative_test_nonexistent_corefile);
 	ATF_TP_ADD_TC(tp, kvm_open2_negative_test_nonexistent_execfile);
+	ATF_TP_ADD_TC(tp, kvm_open2_powerpc64le_minidump_probe);
 
 	return (atf_no_error());
 }