git: f78fd0224353 - stable/13 - linux(4): Convert the native kernel signal codes into the Linux codes

From: Dmitry Chagin <dchagin_at_FreeBSD.org>
Date: Fri, 17 Jun 2022 19:40:51 UTC
The branch stable/13 has been updated by dchagin:

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

commit f78fd022435371f9c7c1da2161e3cfe4274989eb
Author:     Dmitry Chagin <dchagin@FreeBSD.org>
AuthorDate: 2022-05-19 16:56:50 +0000
Commit:     Dmitry Chagin <dchagin@FreeBSD.org>
CommitDate: 2022-06-17 19:35:26 +0000

    linux(4): Convert the native kernel signal codes into the Linux codes
    
    MFC after:              2 weeks
    
    (cherry picked from commit a6f85b12bbe8e50243350c77b0c5879d9e72f85b)
---
 sys/compat/linux/linux_signal.c | 78 ++++++++++++++++++++++++++++++++++++++---
 1 file changed, 74 insertions(+), 4 deletions(-)

diff --git a/sys/compat/linux/linux_signal.c b/sys/compat/linux/linux_signal.c
index a9af0d726f56..9aecb8497f3b 100644
--- a/sys/compat/linux/linux_signal.c
+++ b/sys/compat/linux/linux_signal.c
@@ -65,7 +65,7 @@ static int	linux_tdksignal(struct thread *td, lwpid_t tid,
 		    int tgid, int sig, ksiginfo_t *ksi);
 static int	linux_tdsignal(struct thread *td, lwpid_t tid,
 		    int tgid, int sig);
-static void	sicode_to_lsicode(int si_code, int *lsi_code);
+static void	sicode_to_lsicode(int sig, int si_code, int *lsi_code);
 static int	linux_common_rt_sigtimedwait(struct thread *,
 		    l_sigset_t *, struct timespec *, l_siginfo_t *,
 		    l_size_t);
@@ -565,8 +565,62 @@ linux_tkill(struct thread *td, struct linux_tkill_args *args)
 	return (linux_tdsignal(td, args->tid, -1, sig));
 }
 
+static int
+sigfpe_sicode2lsicode(int si_code)
+{
+
+	switch (si_code) {
+	case FPE_INTOVF:
+		return (LINUX_FPE_INTOVF);
+	case FPE_INTDIV:
+		return (LINUX_FPE_INTDIV);
+	case FPE_FLTIDO:
+		return (LINUX_FPE_FLTUNK);
+	default:
+		return (si_code);
+	}
+}
+
+static int
+sigbus_sicode2lsicode(int si_code)
+{
+
+	switch (si_code) {
+	case BUS_OOMERR:
+		return (LINUX_BUS_MCEERR_AR);
+	default:
+		return (si_code);
+	}
+}
+
+static int
+sigsegv_sicode2lsicode(int si_code)
+{
+
+	switch (si_code) {
+	case SEGV_PKUERR:
+		return (LINUX_SEGV_PKUERR);
+	default:
+		return (si_code);
+	}
+}
+
+static int
+sigtrap_sicode2lsicode(int si_code)
+{
+
+	switch (si_code) {
+	case TRAP_DTRACE:
+		return (LINUX_TRAP_TRACE);
+	case TRAP_CAP:
+		return (LINUX_TRAP_UNK);
+	default:
+		return (si_code);
+	}
+}
+
 static void
-sicode_to_lsicode(int si_code, int *lsi_code)
+sicode_to_lsicode(int sig, int si_code, int *lsi_code)
 {
 
 	switch (si_code) {
@@ -592,7 +646,23 @@ sicode_to_lsicode(int si_code, int *lsi_code)
 		*lsi_code = LINUX_SI_TKILL;
 		break;
 	default:
-		*lsi_code = si_code;
+		switch (sig) {
+		case LINUX_SIGFPE:
+			*lsi_code = sigfpe_sicode2lsicode(si_code);
+			break;
+		case LINUX_SIGBUS:
+			*lsi_code = sigbus_sicode2lsicode(si_code);
+			break;
+		case LINUX_SIGSEGV:
+			*lsi_code = sigsegv_sicode2lsicode(si_code);
+			break;
+		case LINUX_SIGTRAP:
+			*lsi_code = sigtrap_sicode2lsicode(si_code);
+			break;
+		default:
+			*lsi_code = si_code;
+			break;
+		}
 		break;
 	}
 }
@@ -603,7 +673,7 @@ siginfo_to_lsiginfo(const siginfo_t *si, l_siginfo_t *lsi, l_int sig)
 
 	/* sig alredy converted */
 	lsi->lsi_signo = sig;
-	sicode_to_lsicode(si->si_code, &lsi->lsi_code);
+	sicode_to_lsicode(sig, si->si_code, &lsi->lsi_code);
 
 	switch (si->si_code) {
 	case SI_LWP: