git: e334b70a2b5b - stable/15 - x86: provide extended description for x86_msr_op(9)
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 19 Feb 2026 22:08:48 UTC
The branch stable/15 has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=e334b70a2b5b162cc82137776386fa76dc2eda48
commit e334b70a2b5b162cc82137776386fa76dc2eda48
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2026-02-04 00:22:08 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2026-02-19 22:05:20 +0000
x86: provide extended description for x86_msr_op(9)
(cherry picked from commit cb81a9c18db93a2046c47b0c7dc0bd6adcdd2495)
---
sys/x86/include/x86_var.h | 6 ++----
sys/x86/x86/cpu_machdep.c | 43 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 45 insertions(+), 4 deletions(-)
diff --git a/sys/x86/include/x86_var.h b/sys/x86/include/x86_var.h
index caaab207b57a..40dd21107436 100644
--- a/sys/x86/include/x86_var.h
+++ b/sys/x86/include/x86_var.h
@@ -162,7 +162,7 @@ void x86_set_fork_retval(struct thread *td);
uint64_t rdtsc_ordered(void);
/*
- * MSR ops for x86_msr_op()
+ * MSR ops for x86_msr_op().
*/
#define MSR_OP_ANDNOT 0x00000001
#define MSR_OP_OR 0x00000002
@@ -170,9 +170,7 @@ uint64_t rdtsc_ordered(void);
#define MSR_OP_READ 0x00000004
/*
- * Where and which execution mode
- *
- * All modes cause execution on the target CPU(s) with interrupts disabled.
+ * Where and which execution mode.
*/
#define MSR_OP_SAFE 0x08000000
#define MSR_OP_LOCAL 0x10000000
diff --git a/sys/x86/x86/cpu_machdep.c b/sys/x86/x86/cpu_machdep.c
index 6c3f4add6202..5483fbd6dd4e 100644
--- a/sys/x86/x86/cpu_machdep.c
+++ b/sys/x86/x86/cpu_machdep.c
@@ -223,6 +223,49 @@ x86_msr_op_one(void *arg)
#define MSR_OP_GET_CPUID(x) \
(((x) & ~(MSR_OP_EXMODE_MASK | MSR_OP_SAFE)) >> 8)
+/*
+ * Utility function to wrap common MSR accesses.
+ *
+ * The msr argument specifies the MSR number to operate on.
+ * arg1 is an optional additional argument which is needed by
+ * modifying ops.
+ *
+ * res is the location where the value read from MSR is placed. It is
+ * the value that was initially read from the MSR, before applying the
+ * specified operation. Can be NULL if the value is not needed. If
+ * the op is executed on more than one CPU, it is unspecified on which
+ * CPU the value was read.
+ *
+ * op encoding combines the target/mode specification and the requested
+ * operation, all or-ed together.
+ *
+ * MSR accesses are executed with interrupts disabled.
+
+ * The following targets can be specified:
+ * MSR_OP_LOCAL execute on current CPU.
+ * MSR_OP_SCHED_ALL execute on all CPUs, by migrating
+ * the current thread to them in sequence.
+ * MSR_OP_SCHED_ALL | MSR_OP_SAFE execute on all CPUs by migrating, using
+ * safe MSR access.
+ * MSR_OP_SCHED_ONE execute on specified CPU, migrate
+ * curthread to it.
+ * MSR_OP_SCHED_ONE | MSR_OP_SAFE safely execute on specified CPU,
+ * migrate curthread to it.
+ * MSR_OP_RENDEZVOUS_ALL execute on all CPUs in interrupt
+ * context.
+ * MSR_OP_RENDEZVOUS_ONE execute on specified CPU in interrupt
+ * context.
+ * If a _ONE target is specified, 'or' the op value with MSR_OP_CPUID(cpuid)
+ * to name the target CPU. _SAFE variants might return EFAULT if access to
+ * MSR faulted with #GP. Non-_SAFE variants most likely panic or reboot
+ * the machine if the MSR is not present or access is not tolerated by hw.
+ *
+ * The following operations can be specified:
+ * MSR_OP_ANDNOT *res = v = *msr; *msr = v & ~arg1
+ * MSR_OP_OR *res = v = *msr; *msr = v | arg1
+ * MSR_OP_READ *res = *msr
+ * MSR_OP_WRITE *res = *msr; *msr = arg1
+ */
int
x86_msr_op(u_int msr, u_int op, uint64_t arg1, uint64_t *res)
{