diff --git gdb/Makefile.in gdb/Makefile.in
index 4808357e65..982af063b8 100644
--- gdb/Makefile.in
+++ gdb/Makefile.in
@@ -665,6 +665,7 @@ TARGET_OBS = @TARGET_OBS@
 # All target-dependent objects files that require 64-bit CORE_ADDR
 # (used with --enable-targets=all --enable-64-bit-bfd).
 ALL_64_TARGET_OBS = \
+	aarch64-fbsd-kern.o \
 	aarch64-fbsd-tdep.o \
 	aarch64-linux-tdep.o \
 	aarch64-newlib-tdep.o \
@@ -679,6 +680,7 @@ ALL_64_TARGET_OBS = \
 	amd64-darwin-tdep.o \
 	amd64-dicos-tdep.o \
 	amd64-fbsd-tdep.o \
+	amd64fbsd-kern.o \
 	amd64-linux-tdep.o \
 	amd64-nbsd-tdep.o \
 	amd64-obsd-tdep.o \
@@ -693,6 +695,7 @@ ALL_64_TARGET_OBS = \
 	ia64-vms-tdep.o \
 	mips64-obsd-tdep.o \
 	sparc64-fbsd-tdep.o \
+	sparc64fbsd-kern.o \
 	sparc64-linux-tdep.o \
 	sparc64-nbsd-tdep.o \
 	sparc64-obsd-tdep.o \
@@ -713,6 +716,7 @@ ALL_TARGET_OBS = \
 	arch/ppc-linux-common.o \
 	arch/riscv.o \
 	arm-bsd-tdep.o \
+	arm-fbsd-kern.o \
 	arm-fbsd-tdep.o \
 	arm-linux-tdep.o \
 	arm-nbsd-tdep.o \
@@ -731,6 +735,8 @@ ALL_TARGET_OBS = \
 	csky-linux-tdep.o \
 	csky-tdep.o \
 	dicos-tdep.o \
+	fbsd-kld.o \
+	fbsd-kthr.o \
 	fbsd-tdep.o \
 	frv-linux-tdep.o \
 	frv-tdep.o \
@@ -746,6 +752,7 @@ ALL_TARGET_OBS = \
 	i386-darwin-tdep.o \
 	i386-dicos-tdep.o \
 	i386-fbsd-tdep.o \
+	i386fbsd-kern.o \
 	i386-gnu-tdep.o \
 	i386-go32-tdep.o \
 	i386-linux-tdep.o \
@@ -770,6 +777,7 @@ ALL_TARGET_OBS = \
 	mep-tdep.o \
 	microblaze-linux-tdep.o \
 	microblaze-tdep.o \
+	mipsfbsd-kern.o \
 	mips-fbsd-tdep.o \
 	mips-linux-tdep.o \
 	mips-nbsd-tdep.o \
@@ -788,6 +796,7 @@ ALL_TARGET_OBS = \
 	or1k-linux-tdep.o \
 	or1k-tdep.o \
 	ppc-fbsd-tdep.o \
+	ppcfbsd-kern.o \
 	ppc-linux-tdep.o \
 	ppc-nbsd-tdep.o \
 	ppc-obsd-tdep.o \
@@ -795,6 +804,7 @@ ALL_TARGET_OBS = \
 	ppc-sysv-tdep.o \
 	ppc64-tdep.o \
 	ravenscar-thread.o \
+	riscv-fbsd-kern.o \
 	riscv-fbsd-tdep.o \
 	riscv-linux-tdep.o \
 	riscv-ravenscar-thread.o \
@@ -1606,7 +1616,7 @@ generated_files = \
 # Flags needed to compile Python code
 PYTHON_CFLAGS = @PYTHON_CFLAGS@
 
-all: gdb$(EXEEXT) $(CONFIG_ALL) gdb-gdb.py gdb-gdb.gdb
+all: gdb$(EXEEXT) kgdb$(EXEEXT) $(CONFIG_ALL) gdb-gdb.py gdb-gdb.gdb
 	@$(MAKE) $(FLAGS_TO_PASS) DO=all "DODIRS=`echo $(SUBDIRS) | sed 's/testsuite//'`" subdir_do
 
 # Rule for compiling .c files in the top-level gdb directory.
@@ -1871,6 +1881,12 @@ ifneq ($(CODESIGN_CERT),)
 	$(ECHO_SIGN) $(CODESIGN) -s $(CODESIGN_CERT) gdb$(EXEEXT)
 endif
 
+kgdb$(EXEEXT): kgdb-main.o $(LIBGDB_OBS) $(ADD_DEPS) $(CDEPS) $(TDEPLIBS)
+	$(SILENCE) rm -f kgdb$(EXEEXT)
+	$(ECHO_CXXLD) $(CC_LD) $(INTERNAL_LDFLAGS) $(WIN32LDAPP) \
+		-o kgdb$(EXEEXT) kgdb-main.o $(LIBGDB_OBS) \
+		$(TDEPLIBS) $(TUI_LIBRARY) $(CLIBS) $(LOADLIBES)
+
 # Convenience rule to handle recursion.
 .PHONY: all-data-directory
 all-data-directory: data-directory/Makefile
@@ -1911,6 +1927,7 @@ clean mostlyclean: $(CONFIG_CLEAN)
 	rm -f init.c stamp-init version.c stamp-version
 	rm -f gdb$(EXEEXT) core make.log
 	rm -f gdb[0-9]$(EXEEXT)
+	rm -f kgdb$(EXEEXT)
 	rm -f test-cp-name-parser$(EXEEXT)
 	rm -f xml-builtin.c stamp-xml
 	rm -f $(DEPDIR)/*
@@ -2106,6 +2123,7 @@ MAKEOVERRIDES =
 
 ALLDEPFILES = \
 	aarch32-tdep.c \
+	aarch64-fbsd-kern.c \
 	aarch64-fbsd-nat.c \
 	aarch64-fbsd-tdep.c \
 	aarch64-linux-nat.c \
@@ -2125,6 +2143,7 @@ ALLDEPFILES = \
 	amd64-bsd-nat.c \
 	amd64-darwin-tdep.c \
 	amd64-dicos-tdep.c \
+	amd64fbsd-kern.c \
 	amd64-fbsd-nat.c \
 	amd64-fbsd-tdep.c \
 	amd64-linux-nat.c \
@@ -2139,6 +2158,7 @@ ALLDEPFILES = \
 	arc-tdep.c \
 	arm.c \
 	arm-bsd-tdep.c \
+	arm-fbsd-kern.c \
 	arm-fbsd-nat.c \
 	arm-fbsd-tdep.c \
 	arm-get-next-pcs.c \
@@ -2160,6 +2180,9 @@ ALLDEPFILES = \
 	csky-tdep.c \
 	darwin-nat.c \
 	dicos-tdep.c \
+	fbsd-kld.c \
+	fbsd-kthr.c \
+	fbsd-kvm.c \
 	fbsd-nat.c \
 	fbsd-tdep.c \
 	fork-child.c \
@@ -2180,6 +2203,7 @@ ALLDEPFILES = \
 	i386-darwin-nat.c \
 	i386-darwin-tdep.c \
 	i386-dicos-tdep.c \
+	i386fbsd-kern.c \
 	i386-fbsd-nat.c \
 	i386-fbsd-tdep.c \
 	i386-gnu-nat.c \
@@ -2217,6 +2241,7 @@ ALLDEPFILES = \
 	microblaze-linux-tdep.c \
 	microblaze-tdep.c \
 	mingw-hdep.c \
+	mipsfbsd-kern.c \
 	mips-fbsd-nat.c \
 	mips-fbsd-tdep.c \
 	mips-linux-nat.c \
@@ -2236,6 +2261,7 @@ ALLDEPFILES = \
 	obsd-nat.c \
 	obsd-tdep.c \
 	posix-hdep.c \
+	ppcfbsd-kern.c \
 	ppc-fbsd-nat.c \
 	ppc-fbsd-tdep.c \
 	ppc-linux-nat.c \
@@ -2250,6 +2276,7 @@ ALLDEPFILES = \
 	procfs.c \
 	ravenscar-thread.c \
 	remote-sim.c \
+	riscv-fbsd-kern.c \
 	riscv-fbsd-nat.c \
 	riscv-fbsd-tdep.c \
 	riscv-linux-nat.c \
@@ -2286,6 +2313,7 @@ ALLDEPFILES = \
 	sparc-sol2-nat.c \
 	sparc-sol2-tdep.c \
 	sparc-tdep.c \
+	sparc64fbsd-kern.c \
 	sparc64-fbsd-nat.c \
 	sparc64-fbsd-tdep.c \
 	sparc64-linux-nat.c \
@@ -2544,7 +2572,7 @@ endif
 
 # A list of all the objects we might care about in this build, for
 # dependency tracking.
-all_object_files = gdb.o $(LIBGDB_OBS) gdbtk-main.o \
+all_object_files = kgdb-main.o gdb.o $(LIBGDB_OBS) gdbtk-main.o \
 	test-cp-name-parser.o
 
 # All the .deps files to include.
diff --git gdb/config.in gdb/config.in
index 9755458f9c..4a1f7a924c 100644
--- gdb/config.in
+++ gdb/config.in
@@ -217,6 +217,12 @@
 /* Define to 1 if your system has the kinfo_getvmmap function. */
 #undef HAVE_KINFO_GETVMMAP
 
+/* Define to 1 if your system has the kvm_kerndisp function. */
+#undef HAVE_KVM_DISP
+
+/* Define to 1 if your system has the kvm_open2 function. */
+#undef HAVE_KVM_OPEN2
+
 /* Define if you have <langinfo.h> and nl_langinfo(CODESET). */
 #undef HAVE_LANGINFO_CODESET
 
diff --git gdb/configure gdb/configure
index e7811e807a..0a6a1304ce 100755
--- gdb/configure
+++ gdb/configure
@@ -8331,6 +8331,126 @@ $as_echo "#define HAVE_KINFO_GETVMMAP 1" >>confdefs.h
 fi
 
 
+# kgdb needs kvm_open2 for cross-debugging
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing kvm_open2" >&5
+$as_echo_n "checking for library containing kvm_open2... " >&6; }
+if ${ac_cv_search_kvm_open2+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char kvm_open2 ();
+int
+main ()
+{
+return kvm_open2 ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' kvm; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_kvm_open2=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if ${ac_cv_search_kvm_open2+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search_kvm_open2+:} false; then :
+
+else
+  ac_cv_search_kvm_open2=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_kvm_open2" >&5
+$as_echo "$ac_cv_search_kvm_open2" >&6; }
+ac_res=$ac_cv_search_kvm_open2
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+$as_echo "#define HAVE_KVM_OPEN2 1" >>confdefs.h
+
+fi
+
+
+# kgdb needs kvm_kerndisp for relocatable kernels
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing kvm_kerndisp" >&5
+$as_echo_n "checking for library containing kvm_kerndisp... " >&6; }
+if ${ac_cv_search_kvm_kerndisp+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char kvm_kerndisp ();
+int
+main ()
+{
+return kvm_kerndisp ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' kvm; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_kvm_kerndisp=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if ${ac_cv_search_kvm_kerndisp+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search_kvm_kerndisp+:} false; then :
+
+else
+  ac_cv_search_kvm_kerndisp=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_kvm_kerndisp" >&5
+$as_echo "$ac_cv_search_kvm_kerndisp" >&6; }
+ac_res=$ac_cv_search_kvm_kerndisp
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+$as_echo "#define HAVE_KVM_DISP 1" >>confdefs.h
+
+fi
+
+
 
       if test "X$prefix" = "XNONE"; then
     acl_final_prefix="$ac_default_prefix"
diff --git gdb/configure.ac gdb/configure.ac
index 620ae23e34..9186b54386 100644
--- gdb/configure.ac
+++ gdb/configure.ac
@@ -480,6 +480,16 @@ AC_SEARCH_LIBS(kinfo_getvmmap, util util-freebsd,
   [AC_DEFINE(HAVE_KINFO_GETVMMAP, 1,
             [Define to 1 if your system has the kinfo_getvmmap function. ])])
 
+# kgdb needs kvm_open2 for cross-debugging
+AC_SEARCH_LIBS(kvm_open2, kvm,
+  [AC_DEFINE(HAVE_KVM_OPEN2, 1,
+            [Define to 1 if your system has the kvm_open2 function. ])])
+
+# kgdb needs kvm_kerndisp for relocatable kernels
+AC_SEARCH_LIBS(kvm_kerndisp, kvm,
+  [AC_DEFINE(HAVE_KVM_DISP, 1,
+            [Define to 1 if your system has the kvm_kerndisp function. ])])
+
 AM_ICONV
 
 # GDB may fork/exec the iconv program to get the list of supported character
diff --git gdb/configure.nat gdb/configure.nat
index 3e94a064ae..6b73f8dd90 100644
--- gdb/configure.nat
+++ gdb/configure.nat
@@ -63,7 +63,8 @@ case ${gdb_host} in
 	LOADLIBES='-ldl $(RDYNAMIC)'
 	;;
     fbsd*)
-	NATDEPFILES='fork-child.o nat/fork-inferior.o inf-ptrace.o fbsd-nat.o'
+	NATDEPFILES='fork-child.o nat/fork-inferior.o inf-ptrace.o fbsd-nat.o \
+		fbsd-kvm.o'
 	HAVE_NATIVE_GCORE_HOST=1
 	LOADLIBES='-lkvm'
 	;;
diff --git gdb/configure.tgt gdb/configure.tgt
index a3e11c4b9b..1d8b6f10a0 100644
--- gdb/configure.tgt
+++ gdb/configure.tgt
@@ -101,7 +101,7 @@ esac
 
 case "${targ}" in
 *-*-freebsd* | *-*-kfreebsd*-gnu)
-	os_obs="fbsd-tdep.o solib-svr4.o";;
+	os_obs="fbsd-tdep.o solib-svr4.o fbsd-kld.o fbsd-kthr.o";;
 *-*-netbsd* | *-*-knetbsd*-gnu)
 	os_obs="nbsd-tdep.o solib-svr4.o";;
 *-*-openbsd*)
@@ -118,7 +118,7 @@ aarch64*-*-elf | aarch64*-*-rtems*)
 
 aarch64*-*-freebsd*)
 	# Target: FreeBSD/aarch64
-	gdb_target_obs="aarch64-fbsd-tdep.o"
+	gdb_target_obs="aarch64-fbsd-tdep.o aarch64-fbsd-kern.o"
 	;;
 
 aarch64*-*-linux*)
@@ -173,7 +173,7 @@ arm*-*-linux*)
 	;;
 arm*-*-freebsd*)
 	# Target: FreeBSD/arm
-	gdb_target_obs="arm-fbsd-tdep.o"
+	gdb_target_obs="arm-fbsd-tdep.o arm-fbsd-kern.o"
 	;;
 arm*-*-netbsd* | arm*-*-knetbsd*-gnu)
 	# Target: NetBSD/arm
@@ -277,7 +277,11 @@ i[34567]86-*-dicos*)
 	;;
 i[34567]86-*-freebsd* | i[34567]86-*-kfreebsd*-gnu)
 	# Target: FreeBSD/i386
-	gdb_target_obs="i386-bsd-tdep.o i386-fbsd-tdep.o "
+	gdb_target_obs="i386-bsd-tdep.o i386-fbsd-tdep.o i386fbsd-kern.o"
+	if test "x$enable_64_bit_bfd" = "xyes"; then
+	    # Target: FreeBSD amd64
+	    gdb_target_obs="amd64fbsd-tdep.o amd64fbsd-kern.o ${gdb_target_obs}"
+	fi
 	;;
 i[34567]86-*-netbsd* | i[34567]86-*-knetbsd*-gnu)
 	# Target: NetBSD/i386
@@ -423,7 +427,7 @@ mips*-*-netbsd* | mips*-*-knetbsd*-gnu)
 	;;
 mips*-*-freebsd*)
 	# Target: MIPS running FreeBSD
-	gdb_target_obs="mips-tdep.o mips-fbsd-tdep.o"
+	gdb_target_obs="mips-tdep.o mips-fbsd-tdep.o mipsfbsd-kern.o"
 	gdb_sim=../sim/mips/libsim.a
 	;;
 mips64*-*-openbsd*)
@@ -489,7 +493,7 @@ or1k-*-* | or1knd-*-*)
 powerpc*-*-freebsd*)
 	# Target: FreeBSD/powerpc
 	gdb_target_obs="rs6000-tdep.o ppc-sysv-tdep.o ppc64-tdep.o \
-		        ppc-fbsd-tdep.o \
+		        ppc-fbsd-tdep.o ppcfbsd-kern.o \
 			ravenscar-thread.o ppc-ravenscar-thread.o"
 	;;
 
@@ -541,7 +545,7 @@ s390*-*-linux*)
 
 riscv*-*-freebsd*)
 	# Target: FreeBSD/riscv
-	gdb_target_obs="riscv-fbsd-tdep.o"
+	gdb_target_obs="riscv-fbsd-tdep.o riscv-fbsd-kern.o"
 	;;
 
 riscv*-*-linux*)
@@ -616,6 +620,7 @@ sparc64-*-linux*)
 sparc*-*-freebsd* | sparc*-*-kfreebsd*-gnu)
 	# Target: FreeBSD/sparc64
 	gdb_target_obs="sparc-tdep.o sparc64-tdep.o sparc64-fbsd-tdep.o \
+			sparc64fbsd-kern.o \
 			ravenscar-thread.o sparc-ravenscar-thread.o"
 	;;
 sparc-*-netbsd* | sparc-*-knetbsd*-gnu)
@@ -735,8 +740,8 @@ x86_64-*-linux*)
 	;;
 x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu)
 	# Target: FreeBSD/amd64
-	gdb_target_obs="amd64-fbsd-tdep.o ${i386_tobjs} \
-			i386-bsd-tdep.o i386-fbsd-tdep.o"
+	gdb_target_obs="amd64-fbsd-tdep.o amd64fbsd-kern.o ${i386_tobjs} \
+			i386-bsd-tdep.o i386-fbsd-tdep.o i386fbsd-kern.o"
 	;;
 x86_64-*-mingw* | x86_64-*-cygwin*)
         # Target: MingW/amd64
diff --git gdb/osabi.c gdb/osabi.c
index 627b9d9815..45a2fc6ade 100644
--- gdb/osabi.c
+++ gdb/osabi.c
@@ -66,6 +66,7 @@ static const struct osabi_names gdb_osabi_names[] =
   { "Solaris", NULL },
   { "GNU/Linux", "linux(-gnu[^-]*)?" },
   { "FreeBSD", NULL },
+  { "FreeBSD/kernel", NULL },
   { "NetBSD", NULL },
   { "OpenBSD", NULL },
   { "WindowsCE", NULL },
diff --git gdb/osabi.h gdb/osabi.h
index a7e6a10d01..07cef9bee3 100644
--- gdb/osabi.h
+++ gdb/osabi.h
@@ -31,6 +31,7 @@ enum gdb_osabi
   GDB_OSABI_SOLARIS,
   GDB_OSABI_LINUX,
   GDB_OSABI_FREEBSD,
+  GDB_OSABI_FREEBSD_KERNEL,
   GDB_OSABI_NETBSD,
   GDB_OSABI_OPENBSD,
   GDB_OSABI_WINCE,
diff --git gdb/regcache.c gdb/regcache.c
index 91d3202b94..903b3d0d86 100644
--- gdb/regcache.c
+++ gdb/regcache.c
@@ -1108,6 +1108,22 @@ reg_buffer::raw_supply_zeroed (int regnum)
   m_register_status[regnum] = REG_VALID;
 }
 
+void
+reg_buffer::raw_supply_unsigned (int regnum, ULONGEST val)
+{
+  enum bfd_endian byte_order = gdbarch_byte_order (m_descr->gdbarch);
+  gdb_byte *regbuf;
+  size_t regsize;
+
+  assert_regnum (regnum);
+
+  regbuf = register_buffer (regnum);
+  regsize = m_descr->sizeof_register[regnum];
+
+  store_unsigned_integer (regbuf, regsize, byte_order, val);
+  m_register_status[regnum] = REG_VALID;
+}
+
 /* See gdbsupport/common-regcache.h.  */
 
 void
diff --git gdb/regcache.h gdb/regcache.h
index 9390f5708e..62920a5b7f 100644
--- gdb/regcache.h
+++ gdb/regcache.h
@@ -228,6 +228,8 @@ class reg_buffer : public reg_buffer_common
      only LEN, without editing the rest of the register.  */
   void raw_supply_part (int regnum, int offset, int len, const gdb_byte *in);
 
+  void raw_supply_unsigned (int regnum, ULONGEST val);
+
   void invalidate (int regnum);
 
   virtual ~reg_buffer () = default;
diff --git gnulib/configure gnulib/configure
index ef7f6d5e80..536a0b4812 100644
--- gnulib/configure
+++ gnulib/configure
@@ -20747,6 +20747,8 @@ else
         *-gnu* | gnu*) gl_cv_func_gettimeofday_clobber="guessing no" ;;
                        # Guess all is fine on musl systems.
         *-musl*)       gl_cv_func_gettimeofday_clobber="guessing no" ;;
+                       # Guess all is fine on FreeBSD.
+        freebsd*)      gl_cv_func_gettimeofday_clobber="guessing no" ;;
                        # Guess no on native Windows.
         mingw*)        gl_cv_func_gettimeofday_clobber="guessing no" ;;
                        # If we don't know, obey --enable-cross-guesses.
