x86: x86_msr_op(): MSR_OP_LOCAL: Disable interrupts on atomic ops

On MSR_OP_LOCAL and non-naturally-atomic operations (MSR_OP_ANDNOT and
MSR_OP_OR), there is no guarantee that we are not interrupted between
reading and writing the MSR, and that interruption could actually
perform some operation on that MSR, which would be lost.

Prevent that problem by temporarily disabling interrupts around MSR
manipulation.

Reviewed by:    kib
Discussed with: markj
MFC after:      2 weeks
Sponsored by:   The FreeBSD Foundation
Differential Revision:  https://reviews.freebsd.org/D54996
This commit is contained in:
Olivier Certner
2026-01-23 21:52:46 +01:00
parent a1a8bcdfde
commit e5f8cbb86d
2 changed files with 5 additions and 0 deletions
+2
View File
@@ -171,6 +171,8 @@ uint64_t rdtsc_ordered(void);
/*
* Where and which execution mode
*
* All modes cause execution on the target CPU(s) with interrupts disabled.
*/
#define MSR_OP_LOCAL 0x10000000
#define MSR_OP_SCHED_ALL 0x20000000
+3
View File
@@ -160,6 +160,7 @@ x86_msr_op(u_int msr, u_int op, uint64_t arg1, uint64_t *res)
struct thread *td;
struct msr_op_arg a;
cpuset_t set;
register_t flags;
u_int exmode;
int bound_cpu, cpu, i, is_bound;
@@ -171,7 +172,9 @@ x86_msr_op(u_int msr, u_int op, uint64_t arg1, uint64_t *res)
switch (exmode) {
case MSR_OP_LOCAL:
flags = intr_disable();
x86_msr_op_one(&a);
intr_restore(flags);
break;
case MSR_OP_SCHED_ALL:
td = curthread;