git: 1adebe3cd6b1 - main - minidump: Parameterize minidumpsys()

From: Mitchell Horne <mhorne_at_FreeBSD.org>
Date: Fri, 19 Nov 2021 19:06:03 UTC
The branch main has been updated by mhorne:

URL: https://cgit.FreeBSD.org/src/commit/?id=1adebe3cd6b1eb0973969e2c4c5d41f174caa304

commit 1adebe3cd6b1eb0973969e2c4c5d41f174caa304
Author:     Mitchell Horne <mhorne@FreeBSD.org>
AuthorDate: 2021-11-17 15:26:59 +0000
Commit:     Mitchell Horne <mhorne@FreeBSD.org>
CommitDate: 2021-11-19 19:05:52 +0000

    minidump: Parameterize minidumpsys()
    
    The minidump code is written assuming that certain global state will not
    change, and rightly so, since it executes from a kernel debugger
    context. In order to support taking minidumps of a live system, we
    should allow copies of relevant global state that is likely to change to
    be passed as parameters to the minidumpsys() function.
    
    This patch does the work of parameterizing this function, by adding a
    struct minidumpstate argument. For now, this struct allows for copies of
    the kernel message buffer, and the bitset that tracks which pages should
    be dumped (vm_page_dump). Follow-up changes will actually make use of
    these arguments.
    
    Notably, dump_avail[] does not need a snapshot, since it is not expected
    to change after system initialization.
    
    The existing minidumpsys() definitions are renamed, and a thin MI
    wrapper is added to kern_dump.c, which handles the construction of
    the state struct. Thus, calling minidumpsys() remains as simple as
    before.
    
    Reviewed by:    kib, markj, jhb
    Sponsored by:   Juniper Networks, Inc.
    Sponsored by:   Klara, Inc.
    MFC after:      2 weeks
    Differential Revision:  https://reviews.freebsd.org/D31989
---
 sys/amd64/amd64/minidump_machdep.c     |  2 +-
 sys/arm/arm/minidump_machdep.c         |  2 +-
 sys/arm/include/md_var.h               |  3 ++-
 sys/arm64/arm64/minidump_machdep.c     |  2 +-
 sys/arm64/include/md_var.h             |  3 ++-
 sys/i386/i386/minidump_machdep.c       |  5 +++--
 sys/i386/i386/minidump_machdep_base.c  | 10 +++++-----
 sys/i386/include/md_var.h              |  4 ++--
 sys/kern/kern_dump.c                   | 22 +++++++++++++++++++++-
 sys/mips/include/md_var.h              |  3 ++-
 sys/mips/mips/minidump_machdep.c       |  2 +-
 sys/powerpc/include/md_var.h           |  3 ++-
 sys/powerpc/powerpc/minidump_machdep.c |  2 +-
 sys/riscv/include/md_var.h             |  3 ++-
 sys/riscv/riscv/minidump_machdep.c     |  2 +-
 sys/sys/kerneldump.h                   |  6 ++++++
 sys/x86/include/x86_var.h              |  3 ++-
 17 files changed, 55 insertions(+), 22 deletions(-)

diff --git a/sys/amd64/amd64/minidump_machdep.c b/sys/amd64/amd64/minidump_machdep.c
index d6bdbfb7e633..68333088ed5a 100644
--- a/sys/amd64/amd64/minidump_machdep.c
+++ b/sys/amd64/amd64/minidump_machdep.c
@@ -160,7 +160,7 @@ blk_write(struct dumperinfo *di, char *ptr, vm_paddr_t pa, size_t sz)
 static pd_entry_t fakepd[NPDEPG];
 
 int
-minidumpsys(struct dumperinfo *di)
+cpu_minidumpsys(struct dumperinfo *di, const struct minidumpstate *state)
 {
 	uint32_t pmapsize;
 	vm_offset_t va;
diff --git a/sys/arm/arm/minidump_machdep.c b/sys/arm/arm/minidump_machdep.c
index 83c607c839ee..6d199d1894c3 100644
--- a/sys/arm/arm/minidump_machdep.c
+++ b/sys/arm/arm/minidump_machdep.c
@@ -153,7 +153,7 @@ static char dumpbuf[PAGE_SIZE] __aligned(sizeof(uint64_t));
 CTASSERT(sizeof(dumpbuf) % sizeof(pt2_entry_t) == 0);
 
 int
-minidumpsys(struct dumperinfo *di)
+cpu_minidumpsys(struct dumperinfo *di, const struct minidumpstate *state)
 {
 	struct minidumphdr mdhdr;
 	uint64_t dumpsize, *dump_avail_buf;
diff --git a/sys/arm/include/md_var.h b/sys/arm/include/md_var.h
index 19468bd30e02..63f9f8256672 100644
--- a/sys/arm/include/md_var.h
+++ b/sys/arm/include/md_var.h
@@ -52,9 +52,10 @@ enum cpu_class {
 extern enum cpu_class cpu_class;
 
 struct dumperinfo;
+struct minidumpstate;
 extern int busdma_swi_pending;
 void busdma_swi(void);
-int minidumpsys(struct dumperinfo *);
+int cpu_minidumpsys(struct dumperinfo *, const struct minidumpstate *);
 
 extern uint32_t initial_fpscr;
 
diff --git a/sys/arm64/arm64/minidump_machdep.c b/sys/arm64/arm64/minidump_machdep.c
index 92b172260ae0..7558e612153c 100644
--- a/sys/arm64/arm64/minidump_machdep.c
+++ b/sys/arm64/arm64/minidump_machdep.c
@@ -147,7 +147,7 @@ blk_write(struct dumperinfo *di, char *ptr, vm_paddr_t pa, size_t sz)
 }
 
 int
-minidumpsys(struct dumperinfo *di)
+cpu_minidumpsys(struct dumperinfo *di, const struct minidumpstate *state)
 {
 	struct minidumphdr mdhdr;
 	pd_entry_t *l0, *l1, *l2;
diff --git a/sys/arm64/include/md_var.h b/sys/arm64/include/md_var.h
index 1f5e6f693d60..46a4737a6247 100644
--- a/sys/arm64/include/md_var.h
+++ b/sys/arm64/include/md_var.h
@@ -44,10 +44,11 @@ extern u_long elf32_hwcap2;
 #endif
 
 struct dumperinfo;
+struct minidumpstate;
 
 extern int busdma_swi_pending;
 void busdma_swi(void);
-int minidumpsys(struct dumperinfo *);
+int cpu_minidumpsys(struct dumperinfo *, const struct minidumpstate *);
 void generic_bs_fault(void) __asm(__STRING(generic_bs_fault));
 void generic_bs_peek_1(void) __asm(__STRING(generic_bs_peek_1));
 void generic_bs_peek_2(void) __asm(__STRING(generic_bs_peek_2));
diff --git a/sys/i386/i386/minidump_machdep.c b/sys/i386/i386/minidump_machdep.c
index d2a7999cb2c3..6d3585795208 100644
--- a/sys/i386/i386/minidump_machdep.c
+++ b/sys/i386/i386/minidump_machdep.c
@@ -50,8 +50,9 @@ __FBSDID("$FreeBSD$");
 CTASSERT(sizeof(struct kerneldumpheader) == 512);
 
 int
-minidumpsys(struct dumperinfo *di)
+cpu_minidumpsys(struct dumperinfo *di, const struct minidumpstate *state)
 {
 
-	return (pae_mode ? minidumpsys_pae(di) : minidumpsys_nopae(di));
+	return (pae_mode ? cpu_minidumpsys_pae(di, state) :
+	    cpu_minidumpsys_nopae(di, state));
 }
diff --git a/sys/i386/i386/minidump_machdep_base.c b/sys/i386/i386/minidump_machdep_base.c
index e3e211bf9a46..8984ab4dd083 100644
--- a/sys/i386/i386/minidump_machdep_base.c
+++ b/sys/i386/i386/minidump_machdep_base.c
@@ -145,15 +145,15 @@ blk_write(struct dumperinfo *di, char *ptr, vm_paddr_t pa, size_t sz)
 static pt_entry_t fakept[NPTEPG];
 
 #ifdef PMAP_PAE_COMP
-#define	minidumpsys	minidumpsys_pae
-#define	IdlePTD		IdlePTD_pae
+#define	cpu_minidumpsys		cpu_minidumpsys_pae
+#define	IdlePTD			IdlePTD_pae
 #else
-#define	minidumpsys	minidumpsys_nopae
-#define	IdlePTD		IdlePTD_nopae
+#define	cpu_minidumpsys		cpu_minidumpsys_nopae
+#define	IdlePTD			IdlePTD_nopae
 #endif
 
 int
-minidumpsys(struct dumperinfo *di)
+cpu_minidumpsys(struct dumperinfo *di, const struct minidumpstate *state)
 {
 	uint64_t dumpsize;
 	uint32_t ptesize;
diff --git a/sys/i386/include/md_var.h b/sys/i386/include/md_var.h
index 95f4907a61d0..88b036a9cc24 100644
--- a/sys/i386/include/md_var.h
+++ b/sys/i386/include/md_var.h
@@ -68,8 +68,8 @@ void	doreti_popl_fs_fault(void) __asm(__STRING(doreti_popl_fs_fault));
 void	fill_based_sd(struct segment_descriptor *sdp, uint32_t base);
 void	i686_pagezero(void *addr);
 void	sse2_pagezero(void *addr);
-int	minidumpsys_nopae(struct dumperinfo *);
-int	minidumpsys_pae(struct dumperinfo *);
+int	cpu_minidumpsys_nopae(struct dumperinfo *, const struct minidumpstate *);
+int	cpu_minidumpsys_pae(struct dumperinfo *, const struct minidumpstate *);
 void	init_AMD_Elan_sc520(void);
 vm_paddr_t kvtop(void *addr);
 void	panicifcpuunsupported(void);
diff --git a/sys/kern/kern_dump.c b/sys/kern/kern_dump.c
index 4c592f446f45..278863e19a65 100644
--- a/sys/kern/kern_dump.c
+++ b/sys/kern/kern_dump.c
@@ -32,15 +32,18 @@ __FBSDID("$FreeBSD$");
 #include <sys/conf.h>
 #include <sys/cons.h>
 #include <sys/kernel.h>
-#include <sys/proc.h>
 #include <sys/kerneldump.h>
+#include <sys/msgbuf.h>
+#include <sys/proc.h>
 #include <sys/watchdog.h>
+
 #include <vm/vm.h>
 #include <vm/vm_param.h>
 #include <vm/vm_page.h>
 #include <vm/vm_phys.h>
 #include <vm/vm_dumpset.h>
 #include <vm/pmap.h>
+
 #include <machine/dump.h>
 #include <machine/elf.h>
 #include <machine/md_var.h>
@@ -386,6 +389,8 @@ dumpsys_generic(struct dumperinfo *di)
 	return (error);
 }
 
+#if MINIDUMP_PAGE_TRACKING == 1
+
 /* Minidump progress bar */
 static struct {
 	const int min_per;
@@ -454,3 +459,18 @@ dumpsys_pb_progress(size_t delta)
 		break;
 	}
 }
+
+int
+minidumpsys(struct dumperinfo *di)
+{
+	struct minidumpstate state;
+	int error;
+
+	state.msgbufp = msgbufp;
+	state.dump_bitset = vm_page_dump;
+
+	error = cpu_minidumpsys(di, &state);
+
+	return (error);
+}
+#endif /* MINIDUMP_PAGE_TRACKING == 1 */
diff --git a/sys/mips/include/md_var.h b/sys/mips/include/md_var.h
index b322c4d6323a..ca2afa9a3616 100644
--- a/sys/mips/include/md_var.h
+++ b/sys/mips/include/md_var.h
@@ -82,6 +82,7 @@ extern int busdma_swi_pending;
 void	busdma_swi(void);
 
 struct	dumperinfo;
-int	minidumpsys(struct dumperinfo *);
+struct	minidumpstate;
+int	cpu_minidumpsys(struct dumperinfo *, const struct minidumpstate *);
 
 #endif /* !_MACHINE_MD_VAR_H_ */
diff --git a/sys/mips/mips/minidump_machdep.c b/sys/mips/mips/minidump_machdep.c
index 691e1208e684..06a63834cab8 100644
--- a/sys/mips/mips/minidump_machdep.c
+++ b/sys/mips/mips/minidump_machdep.c
@@ -106,7 +106,7 @@ write_buffer(struct dumperinfo *di, char *ptr, size_t sz)
 }
 
 int
-minidumpsys(struct dumperinfo *di)
+cpu_minidumpsys(struct dumperinfo *di, const struct minidumpstate *state)
 {
 	struct minidumphdr mdhdr;
 	uint64_t *dump_avail_buf;
diff --git a/sys/powerpc/include/md_var.h b/sys/powerpc/include/md_var.h
index ab5f9e33a5bb..6e74000340b9 100644
--- a/sys/powerpc/include/md_var.h
+++ b/sys/powerpc/include/md_var.h
@@ -43,7 +43,8 @@ extern	char	sigcode64[], sigcode64_elfv2[];
 extern	int	szsigcode64, szsigcode64_elfv2;
 
 struct	dumperinfo;
-int	minidumpsys(struct dumperinfo *);
+struct	minidumpstate;
+int	cpu_minidumpsys(struct dumperinfo *, const struct minidumpstate *);
 #endif
 
 extern	long	Maxmem;
diff --git a/sys/powerpc/powerpc/minidump_machdep.c b/sys/powerpc/powerpc/minidump_machdep.c
index 908e6f7a3fc7..e6a0f3918883 100644
--- a/sys/powerpc/powerpc/minidump_machdep.c
+++ b/sys/powerpc/powerpc/minidump_machdep.c
@@ -189,7 +189,7 @@ dump_pmap(struct dumperinfo *di)
 }
 
 int
-minidumpsys(struct dumperinfo *di)
+cpu_minidumpsys(struct dumperinfo *di, const struct minidumpstate *state)
 {
 	vm_paddr_t pa;
 	int error, retry_count;
diff --git a/sys/riscv/include/md_var.h b/sys/riscv/include/md_var.h
index b36a44d7d023..56007cd0c155 100644
--- a/sys/riscv/include/md_var.h
+++ b/sys/riscv/include/md_var.h
@@ -42,8 +42,9 @@ extern register_t marchid;
 extern register_t mimpid;
 
 struct dumperinfo;
+struct minidumpstate;
 
 void busdma_swi(void);
-int minidumpsys(struct dumperinfo *);
+int cpu_minidumpsys(struct dumperinfo *, const struct minidumpstate *);
 
 #endif /* !_MACHINE_MD_VAR_H_ */
diff --git a/sys/riscv/riscv/minidump_machdep.c b/sys/riscv/riscv/minidump_machdep.c
index 992ab097e1b3..d71dde8f6da5 100644
--- a/sys/riscv/riscv/minidump_machdep.c
+++ b/sys/riscv/riscv/minidump_machdep.c
@@ -153,7 +153,7 @@ blk_write(struct dumperinfo *di, char *ptr, vm_paddr_t pa, size_t sz)
 }
 
 int
-minidumpsys(struct dumperinfo *di)
+cpu_minidumpsys(struct dumperinfo *di, const struct minidumpstate *state)
 {
 	pd_entry_t *l1, *l2;
 	pt_entry_t *l3;
diff --git a/sys/sys/kerneldump.h b/sys/sys/kerneldump.h
index c4ce9d2f13ec..54662d9cff39 100644
--- a/sys/sys/kerneldump.h
+++ b/sys/sys/kerneldump.h
@@ -135,6 +135,12 @@ struct dump_pa {
 	vm_paddr_t pa_size;
 };
 
+struct minidumpstate {
+	struct msgbuf	*msgbufp;
+	struct bitset	*dump_bitset;
+};
+
+int minidumpsys(struct dumperinfo *);
 int dumpsys_generic(struct dumperinfo *);
 
 void dumpsys_map_chunk(vm_paddr_t, size_t, void **);
diff --git a/sys/x86/include/x86_var.h b/sys/x86/include/x86_var.h
index d695822ddb7f..47b630d076d2 100644
--- a/sys/x86/include/x86_var.h
+++ b/sys/x86/include/x86_var.h
@@ -104,6 +104,7 @@ struct	fpreg;
 struct  dbreg;
 struct	dumperinfo;
 struct	trapframe;
+struct	minidumpstate;
 
 /*
  * The interface type of the interrupt handler entry point cannot be
@@ -151,7 +152,7 @@ void	pagecopy(void *from, void *to);
 void	printcpuinfo(void);
 int	pti_get_default(void);
 int	user_dbreg_trap(register_t dr6);
-int	minidumpsys(struct dumperinfo *);
+int	cpu_minidumpsys(struct dumperinfo *, const struct minidumpstate *);
 struct pcb *get_pcb_td(struct thread *td);
 void	x86_set_fork_retval(struct thread *td);
 uint64_t rdtsc_ordered(void);