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) {
