The branch stable/15 has been updated by kib:

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

commit e334b70a2b5b162cc82137776386fa76dc2eda48
Author:     Konstantin Belousov <[email protected]>
AuthorDate: 2026-02-04 00:22:08 +0000
Commit:     Konstantin Belousov <[email protected]>
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)
 {

Reply via email to