Date: Thu, 5 Aug 2021 15:50:08 GMT From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: d0bc4b466683 - main - x86_msr_op: extend the KPI to allow MSR read and single-CPU operations Message-ID: <202108051550.175Fo8qv018081@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=d0bc4b466683d17b84f9acafe4c3cc746f860dbf commit d0bc4b466683d17b84f9acafe4c3cc746f860dbf Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2021-08-02 19:52:26 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2021-08-05 15:46:37 +0000 x86_msr_op: extend the KPI to allow MSR read and single-CPU operations Reivewed by: markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D31386 --- sys/dev/hwpmc/hwpmc_core.c | 8 +++--- sys/x86/include/x86_var.h | 18 ++++++++++--- sys/x86/x86/cpu_machdep.c | 65 +++++++++++++++++++++++++++++++++++----------- 3 files changed, 69 insertions(+), 22 deletions(-) diff --git a/sys/dev/hwpmc/hwpmc_core.c b/sys/dev/hwpmc/hwpmc_core.c index b0773227fac7..afd587296e01 100644 --- a/sys/dev/hwpmc/hwpmc_core.c +++ b/sys/dev/hwpmc/hwpmc_core.c @@ -261,8 +261,8 @@ iaf_allocate_pmc(int cpu, int ri, struct pmc *pm, if ((cpu_stdext_feature3 & CPUID_STDEXT3_TSXFA) != 0 && !pmc_tsx_force_abort_set) { pmc_tsx_force_abort_set = true; - x86_msr_op(MSR_TSX_FORCE_ABORT, MSR_OP_RENDEZVOUS | - MSR_OP_WRITE, 1); + x86_msr_op(MSR_TSX_FORCE_ABORT, MSR_OP_RENDEZVOUS_ALL | + MSR_OP_WRITE, 1, NULL); } flags = 0; @@ -403,8 +403,8 @@ iaf_release_pmc(int cpu, int ri, struct pmc *pmc) MPASS(pmc_alloc_refs > 0); if (pmc_alloc_refs-- == 1 && pmc_tsx_force_abort_set) { pmc_tsx_force_abort_set = false; - x86_msr_op(MSR_TSX_FORCE_ABORT, MSR_OP_RENDEZVOUS | - MSR_OP_WRITE, 0); + x86_msr_op(MSR_TSX_FORCE_ABORT, MSR_OP_RENDEZVOUS_ALL | + MSR_OP_WRITE, 0, NULL); } return (0); diff --git a/sys/x86/include/x86_var.h b/sys/x86/include/x86_var.h index 983c353327fd..0fdff68638cf 100644 --- a/sys/x86/include/x86_var.h +++ b/sys/x86/include/x86_var.h @@ -154,12 +154,24 @@ int user_dbreg_trap(register_t dr6); int minidumpsys(struct dumperinfo *); struct pcb *get_pcb_td(struct thread *td); +/* + * MSR ops for x86_msr_op() + */ #define MSR_OP_ANDNOT 0x00000001 #define MSR_OP_OR 0x00000002 #define MSR_OP_WRITE 0x00000003 +#define MSR_OP_READ 0x00000004 + +/* + * Where and which execution mode + */ #define MSR_OP_LOCAL 0x10000000 -#define MSR_OP_SCHED 0x20000000 -#define MSR_OP_RENDEZVOUS 0x30000000 -void x86_msr_op(u_int msr, u_int op, uint64_t arg1); +#define MSR_OP_SCHED_ALL 0x20000000 +#define MSR_OP_SCHED_ONE 0x30000000 +#define MSR_OP_RENDEZVOUS_ALL 0x40000000 +#define MSR_OP_RENDEZVOUS_ONE 0x50000000 +#define MSR_OP_CPUID(id) ((id) << 8) + +void x86_msr_op(u_int msr, u_int op, uint64_t arg1, uint64_t *res); #endif diff --git a/sys/x86/x86/cpu_machdep.c b/sys/x86/x86/cpu_machdep.c index eb94285ad606..bfc1a697cde0 100644 --- a/sys/x86/x86/cpu_machdep.c +++ b/sys/x86/x86/cpu_machdep.c @@ -119,6 +119,7 @@ struct msr_op_arg { u_int msr; int op; uint64_t arg1; + uint64_t *res; }; static void @@ -142,33 +143,41 @@ x86_msr_op_one(void *argp) case MSR_OP_WRITE: wrmsr(a->msr, a->arg1); break; + case MSR_OP_READ: + v = rdmsr(a->msr); + *a->res = v; + break; } } #define MSR_OP_EXMODE_MASK 0xf0000000 #define MSR_OP_OP_MASK 0x000000ff +#define MSR_OP_GET_CPUID(x) (((x) & ~MSR_OP_EXMODE_MASK) >> 8) void -x86_msr_op(u_int msr, u_int op, uint64_t arg1) +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; u_int exmode; - int bound_cpu, i, is_bound; + int bound_cpu, cpu, i, is_bound; a.op = op & MSR_OP_OP_MASK; MPASS(a.op == MSR_OP_ANDNOT || a.op == MSR_OP_OR || - a.op == MSR_OP_WRITE); + a.op == MSR_OP_WRITE || a.op == MSR_OP_READ); exmode = op & MSR_OP_EXMODE_MASK; - MPASS(exmode == MSR_OP_LOCAL || exmode == MSR_OP_SCHED || - exmode == MSR_OP_RENDEZVOUS); + MPASS(exmode == MSR_OP_LOCAL || exmode == MSR_OP_SCHED_ALL || + exmode == MSR_OP_SCHED_ONE || exmode == MSR_OP_RENDEZVOUS_ALL || + exmode == MSR_OP_RENDEZVOUS_ONE); a.msr = msr; a.arg1 = arg1; + a.res = res; switch (exmode) { case MSR_OP_LOCAL: x86_msr_op_one(&a); break; - case MSR_OP_SCHED: + case MSR_OP_SCHED_ALL: td = curthread; thread_lock(td); is_bound = sched_is_bound(td); @@ -183,8 +192,32 @@ x86_msr_op(u_int msr, u_int op, uint64_t arg1) sched_unbind(td); thread_unlock(td); break; - case MSR_OP_RENDEZVOUS: - smp_rendezvous(NULL, x86_msr_op_one, NULL, &a); + case MSR_OP_SCHED_ONE: + td = curthread; + cpu = MSR_OP_GET_CPUID(op); + thread_lock(td); + is_bound = sched_is_bound(td); + bound_cpu = td->td_oncpu; + if (!is_bound || bound_cpu != cpu) + sched_bind(td, cpu); + x86_msr_op_one(&a); + if (is_bound) { + if (bound_cpu != cpu) + sched_bind(td, bound_cpu); + } else { + sched_unbind(td); + } + thread_unlock(td); + break; + case MSR_OP_RENDEZVOUS_ALL: + smp_rendezvous(smp_no_rendezvous_barrier, x86_msr_op_one, + smp_no_rendezvous_barrier, &a); + break; + case MSR_OP_RENDEZVOUS_ONE: + cpu = MSR_OP_GET_CPUID(op); + CPU_SETOF(cpu, &set); + smp_rendezvous_cpus(set, smp_no_rendezvous_barrier, + x86_msr_op_one, smp_no_rendezvous_barrier, &a); break; } } @@ -872,9 +905,9 @@ hw_ibrs_recalculate(bool for_all_cpus) { if ((cpu_ia32_arch_caps & IA32_ARCH_CAP_IBRS_ALL) != 0) { x86_msr_op(MSR_IA32_SPEC_CTRL, (for_all_cpus ? - MSR_OP_RENDEZVOUS : MSR_OP_LOCAL) | + MSR_OP_RENDEZVOUS_ALL : MSR_OP_LOCAL) | (hw_ibrs_disable != 0 ? MSR_OP_ANDNOT : MSR_OP_OR), - IA32_SPEC_CTRL_IBRS); + IA32_SPEC_CTRL_IBRS, NULL); hw_ibrs_active = hw_ibrs_disable == 0; hw_ibrs_ibpb_active = 0; } else { @@ -930,7 +963,8 @@ hw_ssb_set(bool enable, bool for_all_cpus) hw_ssb_active = enable; x86_msr_op(MSR_IA32_SPEC_CTRL, (enable ? MSR_OP_OR : MSR_OP_ANDNOT) | - (for_all_cpus ? MSR_OP_SCHED : MSR_OP_LOCAL), IA32_SPEC_CTRL_SSBD); + (for_all_cpus ? MSR_OP_SCHED_ALL : MSR_OP_LOCAL), + IA32_SPEC_CTRL_SSBD, NULL); } void @@ -1221,8 +1255,9 @@ taa_set(bool enable, bool all) x86_msr_op(MSR_IA32_TSX_CTRL, (enable ? MSR_OP_OR : MSR_OP_ANDNOT) | - (all ? MSR_OP_RENDEZVOUS : MSR_OP_LOCAL), - IA32_TSX_CTRL_RTM_DISABLE | IA32_TSX_CTRL_TSX_CPUID_CLEAR); + (all ? MSR_OP_RENDEZVOUS_ALL : MSR_OP_LOCAL), + IA32_TSX_CTRL_RTM_DISABLE | IA32_TSX_CTRL_TSX_CPUID_CLEAR, + NULL); } void @@ -1386,8 +1421,8 @@ x86_rngds_mitg_recalculate(bool all_cpus) return; x86_msr_op(MSR_IA32_MCU_OPT_CTRL, (x86_rngds_mitg_enable ? MSR_OP_OR : MSR_OP_ANDNOT) | - (all_cpus ? MSR_OP_RENDEZVOUS : MSR_OP_LOCAL), - IA32_RNGDS_MITG_DIS); + (all_cpus ? MSR_OP_RENDEZVOUS_ALL : MSR_OP_LOCAL), + IA32_RNGDS_MITG_DIS, NULL); } static int
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202108051550.175Fo8qv018081>