git: ae5ad9c6a79b - stable/15 - amd64: do not allow to set IOPL to 3 when FRED is used
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 03 Nov 2026 09:02:05 UTC
The branch stable/15 has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=ae5ad9c6a79b29b7092323b3bc284fa3f21c213d
commit ae5ad9c6a79b29b7092323b3bc284fa3f21c213d
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2026-10-27 09:10:09 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2026-11-03 09:01:14 +0000
amd64: do not allow to set IOPL to 3 when FRED is used
(cherry picked from commit 5bc997b6f5b1265ff28d11405eb980bf471c3db4)
---
sys/amd64/amd64/io.c | 16 ++++++++++++----
sys/amd64/linux/linux_machdep.c | 3 +++
sys/amd64/linux32/linux32_machdep.c | 3 +++
sys/dev/syscons/syscons.c | 3 +++
sys/dev/vt/vt_core.c | 3 +++
5 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/sys/amd64/amd64/io.c b/sys/amd64/amd64/io.c
index 6c36d5fb20e1..ba34675c0cc5 100644
--- a/sys/amd64/amd64/io.c
+++ b/sys/amd64/amd64/io.c
@@ -31,21 +31,29 @@
#include <machine/frame.h>
#include <machine/iodev.h>
+#include <machine/md_var.h>
#include <machine/psl.h>
int
iodev_open(struct thread *td)
{
-
- td->td_frame->tf_rflags |= PSL_IOPL;
+ /*
+ * SDM rev. 93 vol.3 8.4.2.1 Loading and Checking the Return State:
+ * Checking IOPL ensures that, when FRED transitions are
+ * enabled, IOPL is always 0 when CPL = 3.
+ *
+ * As result, io(4) cannot enable the IOPL for usermode on FRED.
+ */
+ if (!fred)
+ td->td_frame->tf_rflags |= PSL_IOPL;
return (0);
}
int
iodev_close(struct thread *td)
{
-
- td->td_frame->tf_rflags &= ~PSL_IOPL;
+ if (!fred)
+ td->td_frame->tf_rflags &= ~PSL_IOPL;
return (0);
}
diff --git a/sys/amd64/linux/linux_machdep.c b/sys/amd64/linux/linux_machdep.c
index dc7f55f6f198..e22a3ed22c31 100644
--- a/sys/amd64/linux/linux_machdep.c
+++ b/sys/amd64/linux/linux_machdep.c
@@ -88,6 +88,9 @@ linux_iopl(struct thread *td, struct linux_iopl_args *args)
return (error);
if ((error = securelevel_gt(td->td_ucred, 0)) != 0)
return (error);
+ /* See comment in sys/amd64/amd64/io.c. */
+ if (fred && args->level != 0)
+ return (ENOSYS);
td->td_frame->tf_rflags = (td->td_frame->tf_rflags & ~PSL_IOPL) |
(args->level * (PSL_IOPL / 3));
diff --git a/sys/amd64/linux32/linux32_machdep.c b/sys/amd64/linux32/linux32_machdep.c
index a9517b42a4d9..a62965308c33 100644
--- a/sys/amd64/linux32/linux32_machdep.c
+++ b/sys/amd64/linux32/linux32_machdep.c
@@ -332,6 +332,9 @@ linux_iopl(struct thread *td, struct linux_iopl_args *args)
return (error);
if ((error = securelevel_gt(td->td_ucred, 0)) != 0)
return (error);
+ /* See comment in sys/amd64/amd64/io.c. */
+ if (fred && args->level != 0)
+ return (ENOSYS);
td->td_frame->tf_rflags = (td->td_frame->tf_rflags & ~PSL_IOPL) |
(args->level * (PSL_IOPL / 3));
diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c
index e9d664f51a1f..29892d4caa92 100644
--- a/sys/dev/syscons/syscons.c
+++ b/sys/dev/syscons/syscons.c
@@ -72,6 +72,7 @@
#if defined(__i386__) || defined(__amd64__)
#include <machine/psl.h>
#include <machine/frame.h>
+#include <machine/md_var.h>
#endif
#if defined(__amd64__) || defined(__i386__)
@@ -1338,6 +1339,8 @@ sctty_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
#ifdef __i386__
td->td_frame->tf_eflags |= PSL_IOPL;
#elif defined(__amd64__)
+ if (fred)
+ return (EINVAL);
td->td_frame->tf_rflags |= PSL_IOPL;
#endif
return 0;
diff --git a/sys/dev/vt/vt_core.c b/sys/dev/vt/vt_core.c
index 922b44028a23..f28515b0771a 100644
--- a/sys/dev/vt/vt_core.c
+++ b/sys/dev/vt/vt_core.c
@@ -61,6 +61,7 @@
#if defined(__i386__) || defined(__amd64__)
#include <machine/psl.h>
#include <machine/frame.h>
+#include <machine/md_var.h>
#endif
static int vtterm_cngrab_noswitch(struct vt_device *, struct vt_window *);
@@ -2937,6 +2938,8 @@ skip_thunk:
#if defined(__i386__)
td->td_frame->tf_eflags |= PSL_IOPL;
#elif defined(__amd64__)
+ if (fred)
+ return (EINVAL);
td->td_frame->tf_rflags |= PSL_IOPL;
#endif
return (0);