git: 4a52b966727b - stable/15 - amd64: Make the SYSENTER and INTn action same as for IDT case.

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Tue, 03 Nov 2026 09:02:08 UTC
The branch stable/15 has been updated by kib:

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

commit 4a52b966727be87bbb1ae579f944eddc9cd2da54
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2026-10-27 10:08:14 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2026-11-03 09:01:14 +0000

    amd64: Make the SYSENTER and INTn action same as for IDT case.
    
    (cherry picked from commit 73b3fb41e67a11f18b9b63a5265e174e4b688661)
---
 sys/amd64/amd64/trap.c | 30 +++++++++++++++++++++++-------
 1 file changed, 23 insertions(+), 7 deletions(-)

diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index 9652ef6b6f22..f6b8c904071e 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -1569,6 +1569,24 @@ fred_inst_len(const struct trapframe_fred *frame)
 	    TF_FRED_EVINFO2_INSTLENSHIFT);
 }
 
+/*
+ * Reaction to userspace having no permissions to generate the event.
+ * Report T_PROTFLT and rewind %rip back to emulate fault instead of
+ * trap.
+ */
+static void
+trap_fred_u_noperm(struct trapframe_fred *frame, ksiginfo_t *ksi)
+{
+	frame->tf_idt.tf_rip -= fred_inst_len(frame);
+	frame->tf_idt.tf_addr = 0;
+	frame->tf_idt.tf_trapno = T_PROTFLT;
+	ksiginfo_init_trap(ksi);
+	ksi->ksi_signo = SIGBUS;
+	ksi->ksi_code = BUS_OBJERR;
+	ksi->ksi_trapno = T_PROTFLT;
+	ksi->ksi_addr = (void *)frame->tf_idt.tf_rip;
+}
+
 int fred_verbose_events;
 
 void trap_fred_u(struct trapframe_fred *frame);
@@ -1644,12 +1662,9 @@ trap_fred_u(struct trapframe_fred *frame)
 			break;
 		}
 #endif
-		frame->tf_idt.tf_trapno = vec;
-		ksiginfo_init_trap(&ksi);
-		ksi.ksi_signo = SIGBUS;
-		ksi.ksi_code = BUS_OBJERR;
-		ksi.ksi_trapno = frame->tf_idt.tf_trapno;
-		ksi.ksi_addr = (void *)frame->tf_idt.tf_rip;
+		trap_fred_u_noperm(frame, &ksi);
+		/* error code: gate selector from IDT */
+		frame->tf_idt.tf_err = (vec * 8) | 2;
 		do_trapsig = true;
 		break;
 	case TF_FRED_EVINFO2_TYPE_SYSCALL:
@@ -1661,7 +1676,8 @@ trap_fred_u(struct trapframe_fred *frame)
 			amd64_syscall(td, (frame->tf_idt.tf_rflags & PSL_T) !=
 			    0);
 		} else {
-			/* SYSENTER returns without action */
+			trap_fred_u_noperm(frame, &ksi);
+			do_trapsig = true;
 		}
 		break;
 	default: