git: 2761de0832c1 - main - kern: add extended errors support

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Sat, 31 May 2025 19:52:48 UTC
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=2761de0832c1c4342e2f8cca60c794815fda01e3

commit 2761de0832c1c4342e2f8cca60c794815fda01e3
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2025-05-23 06:39:50 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2025-05-31 19:52:41 +0000

    kern: add extended errors support
    
    Reviewed by:    brooks
    Sponsored by:   The FreeBSD Foundation
    MFC after:      2 weeks
    Differential revision:  https://reviews.freebsd.org/D50483
---
 sys/conf/options       |  1 +
 sys/kern/kern_thread.c |  8 +++----
 sys/sys/_exterr.h      | 25 ++++++++++++++++++++++
 sys/sys/exterr_cat.h   | 18 ++++++++++++++++
 sys/sys/exterrvar.h    | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++
 sys/sys/proc.h         |  3 +++
 6 files changed, 109 insertions(+), 4 deletions(-)

diff --git a/sys/conf/options b/sys/conf/options
index 48018e3b6adf..b5e8971dfa54 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -53,6 +53,7 @@ DDB_CAPTURE_MAXBUFSIZE	opt_ddb.h
 DDB_CTF		opt_ddb.h
 DDB_NUMSYM	opt_ddb.h
 EARLY_PRINTF	opt_global.h
+BLOW_KERNEL_WITH_EXTERR	opt_global.h
 FULL_BUF_TRACKING	opt_global.h
 GDB
 KDB		opt_global.h
diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c
index 4ccd6b26528e..2dff461e932a 100644
--- a/sys/kern/kern_thread.c
+++ b/sys/kern/kern_thread.c
@@ -86,9 +86,9 @@ _Static_assert(offsetof(struct thread, td_flags) == 0x108,
     "struct thread KBI td_flags");
 _Static_assert(offsetof(struct thread, td_pflags) == 0x114,
     "struct thread KBI td_pflags");
-_Static_assert(offsetof(struct thread, td_frame) == 0x4b8,
+_Static_assert(offsetof(struct thread, td_frame) == 0x4e8,
     "struct thread KBI td_frame");
-_Static_assert(offsetof(struct thread, td_emuldata) == 0x6c0,
+_Static_assert(offsetof(struct thread, td_emuldata) == 0x6f0,
     "struct thread KBI td_emuldata");
 _Static_assert(offsetof(struct proc, p_flag) == 0xb8,
     "struct proc KBI p_flag");
@@ -106,9 +106,9 @@ _Static_assert(offsetof(struct thread, td_flags) == 0x9c,
     "struct thread KBI td_flags");
 _Static_assert(offsetof(struct thread, td_pflags) == 0xa8,
     "struct thread KBI td_pflags");
-_Static_assert(offsetof(struct thread, td_frame) == 0x318,
+_Static_assert(offsetof(struct thread, td_frame) == 0x33c,
     "struct thread KBI td_frame");
-_Static_assert(offsetof(struct thread, td_emuldata) == 0x35c,
+_Static_assert(offsetof(struct thread, td_emuldata) == 0x380,
     "struct thread KBI td_emuldata");
 _Static_assert(offsetof(struct proc, p_flag) == 0x6c,
     "struct proc KBI p_flag");
diff --git a/sys/sys/_exterr.h b/sys/sys/_exterr.h
new file mode 100644
index 000000000000..4423d6a34bdb
--- /dev/null
+++ b/sys/sys/_exterr.h
@@ -0,0 +1,25 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2025 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software were developed by Konstantin Belousov <kib@FreeBSD.org>
+ * under sponsorship from the FreeBSD Foundation.
+ */
+
+#ifndef _SYS__EXTERR_H_
+#define	_SYS__EXTERR_H_
+
+#include <sys/_types.h>
+
+struct kexterr {
+	int error;
+	const char *msg;
+	__uint64_t p1;
+	__uint64_t p2;
+	unsigned cat;
+	unsigned src_line;
+};
+
+#endif
diff --git a/sys/sys/exterr_cat.h b/sys/sys/exterr_cat.h
new file mode 100644
index 000000000000..d16faa9cc2e5
--- /dev/null
+++ b/sys/sys/exterr_cat.h
@@ -0,0 +1,18 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2025 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software were developed by Konstantin Belousov <kib@FreeBSD.org>
+ * under sponsorship from the FreeBSD Foundation.
+ */
+
+#ifndef _SYS_EXTERR_CAT_H_
+#define	_SYS_EXTERR_CAT_H_
+
+#define	EXTERR_CAT_MMAP		1
+#define	EXTERR_CAT_FILEDESC	2
+
+#endif
+
diff --git a/sys/sys/exterrvar.h b/sys/sys/exterrvar.h
new file mode 100644
index 000000000000..6e392ff2c18c
--- /dev/null
+++ b/sys/sys/exterrvar.h
@@ -0,0 +1,58 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2025 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software were developed by Konstantin Belousov <kib@FreeBSD.org>
+ * under sponsorship from the FreeBSD Foundation.
+ */
+
+#ifndef _SYS_EXTERRVAR_H_
+#define	_SYS_EXTERRVAR_H_
+
+#include <sys/_exterr.h>
+#include <sys/exterr_cat.h>
+#include <sys/types.h>
+
+struct uexterror {
+	uint32_t ver;
+	uint32_t error;
+	uint32_t cat;
+	uint32_t src_line;
+	uint64_t p1;
+	uint64_t p2;
+	uint64_t rsrv1[4];
+	char msg[128];
+};
+
+#ifdef _KERNEL
+
+#ifndef EXTERR_CATEGORY
+#error "Specify error category before including sys/exterrvar.h"
+#endif
+
+#ifdef	BLOW_KERNEL_WITH_EXTERR
+#define	SET_ERROR_MSG(mmsg)	_Td->td_kexterr.msg = mmsg
+#else
+#define	SET_ERROR_MSG(mmsg)	_Td->td_kexterr.msg = NULL
+#endif
+
+#define	SET_ERROR2(eerror, mmsg, pp1, pp2) do {	\
+	struct thread *_Td = curthread;				\
+	if ((_Td->td_pflags2 & TDP2_UEXTERR) != 0) {		\
+		_Td->td_pflags2 |= TDP2_EXTERR;			\
+		_Td->td_kexterr.error = eerror;			\
+		_Td->td_kexterr.cat = EXTERR_CATEGORY;		\
+		SET_ERROR_MSG(mmsg);				\
+		_Td->td_kexterr.p1 = (uintptr_t)pp1;		\
+		_Td->td_kexterr.p2 = (uintptr_t)pp2;		\
+		_Td->td_kexterr.src_line = __LINE__;		\
+	}							\
+} while (0)
+#define	SET_ERROR0(eerror, mmsg)	SET_ERROR2(eerror, mmsg, 0, 0)
+#define	SET_ERROR1(eerror, mmsg, pp1)	SET_ERROR2(eerror, mmsg, pp1, 0)
+
+#endif	/* _KERNEL */
+
+#endif
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index fcacfec4442b..cab487719c31 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -42,6 +42,7 @@
 #ifdef _KERNEL
 #include <sys/_eventhandler.h>
 #endif
+#include <sys/_exterr.h>
 #include <sys/condvar.h>
 #ifndef _KERNEL
 #include <sys/filedesc.h>
@@ -322,6 +323,7 @@ struct thread {
 	size_t		td_vslock_sz;	/* (k) amount of vslock-ed space */
 	struct kcov_info *td_kcov_info;	/* (*) Kernel code coverage data */
 	long		td_ucredref;	/* (k) references on td_realucred */
+	struct kexterr	td_kexterr;
 #define	td_endzero td_sigmask
 
 /* Copied during fork1(), thread_create(), or kthread_add(). */
@@ -569,6 +571,7 @@ enum {
 #define	TDP2_COMPAT32RB	0x00000002 /* compat32 ABI for robust lists */
 #define	TDP2_ACCT	0x00000004 /* Doing accounting */
 #define	TDP2_SAN_QUIET	0x00000008 /* Disable warnings from K(A|M)SAN */
+#define	TDP2_EXTERR	0x00000010 /* Kernel reported ext error */
 
 /*
  * Reasons that the current thread can not be run yet.