^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <linux/preempt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/completion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <asm/msr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) static void __rdmsr_on_cpu(void *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) struct msr_info *rv = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) struct msr *reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) int this_cpu = raw_smp_processor_id();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) if (rv->msrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) reg = per_cpu_ptr(rv->msrs, this_cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) reg = &rv->reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) rdmsr(rv->msr_no, reg->l, reg->h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) static void __wrmsr_on_cpu(void *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct msr_info *rv = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct msr *reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) int this_cpu = raw_smp_processor_id();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) if (rv->msrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) reg = per_cpu_ptr(rv->msrs, this_cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) reg = &rv->reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) wrmsr(rv->msr_no, reg->l, reg->h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct msr_info rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) memset(&rv, 0, sizeof(rv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) rv.msr_no = msr_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) err = smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) *l = rv.reg.l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) *h = rv.reg.h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) EXPORT_SYMBOL(rdmsr_on_cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) int rdmsrl_on_cpu(unsigned int cpu, u32 msr_no, u64 *q)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct msr_info rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) memset(&rv, 0, sizeof(rv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) rv.msr_no = msr_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) err = smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) *q = rv.reg.q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) EXPORT_SYMBOL(rdmsrl_on_cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct msr_info rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) memset(&rv, 0, sizeof(rv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) rv.msr_no = msr_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) rv.reg.l = l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) rv.reg.h = h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) err = smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) EXPORT_SYMBOL(wrmsr_on_cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) int wrmsrl_on_cpu(unsigned int cpu, u32 msr_no, u64 q)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct msr_info rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) memset(&rv, 0, sizeof(rv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) rv.msr_no = msr_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) rv.reg.q = q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) err = smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) EXPORT_SYMBOL(wrmsrl_on_cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static void __rwmsr_on_cpus(const struct cpumask *mask, u32 msr_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct msr *msrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) void (*msr_func) (void *info))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct msr_info rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) int this_cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) memset(&rv, 0, sizeof(rv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) rv.msrs = msrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) rv.msr_no = msr_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) this_cpu = get_cpu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (cpumask_test_cpu(this_cpu, mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) msr_func(&rv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) smp_call_function_many(mask, msr_func, &rv, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) put_cpu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /* rdmsr on a bunch of CPUs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * @mask: which CPUs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * @msr_no: which MSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * @msrs: array of MSR values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) void rdmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) __rwmsr_on_cpus(mask, msr_no, msrs, __rdmsr_on_cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) EXPORT_SYMBOL(rdmsr_on_cpus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * wrmsr on a bunch of CPUs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * @mask: which CPUs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * @msr_no: which MSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * @msrs: array of MSR values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) __rwmsr_on_cpus(mask, msr_no, msrs, __wrmsr_on_cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) EXPORT_SYMBOL(wrmsr_on_cpus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) struct msr_info_completion {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) struct msr_info msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) struct completion done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) /* These "safe" variants are slower and should be used when the target MSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) may not actually exist. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static void __rdmsr_safe_on_cpu(void *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) struct msr_info_completion *rv = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) rv->msr.err = rdmsr_safe(rv->msr.msr_no, &rv->msr.reg.l, &rv->msr.reg.h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) complete(&rv->done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static void __wrmsr_safe_on_cpu(void *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) struct msr_info *rv = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) rv->err = wrmsr_safe(rv->msr_no, rv->reg.l, rv->reg.h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct msr_info_completion rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) call_single_data_t csd = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) .func = __rdmsr_safe_on_cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) .info = &rv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) memset(&rv, 0, sizeof(rv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) init_completion(&rv.done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) rv.msr.msr_no = msr_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) err = smp_call_function_single_async(cpu, &csd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) wait_for_completion(&rv.done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) err = rv.msr.err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) *l = rv.msr.reg.l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) *h = rv.msr.reg.h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) EXPORT_SYMBOL(rdmsr_safe_on_cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct msr_info rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) memset(&rv, 0, sizeof(rv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) rv.msr_no = msr_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) rv.reg.l = l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) rv.reg.h = h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) err = smp_call_function_single(cpu, __wrmsr_safe_on_cpu, &rv, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) return err ? err : rv.err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) EXPORT_SYMBOL(wrmsr_safe_on_cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) int wrmsrl_safe_on_cpu(unsigned int cpu, u32 msr_no, u64 q)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) struct msr_info rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) memset(&rv, 0, sizeof(rv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) rv.msr_no = msr_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) rv.reg.q = q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) err = smp_call_function_single(cpu, __wrmsr_safe_on_cpu, &rv, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return err ? err : rv.err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) EXPORT_SYMBOL(wrmsrl_safe_on_cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) int rdmsrl_safe_on_cpu(unsigned int cpu, u32 msr_no, u64 *q)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) u32 low, high;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) err = rdmsr_safe_on_cpu(cpu, msr_no, &low, &high);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) *q = (u64)high << 32 | low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) EXPORT_SYMBOL(rdmsrl_safe_on_cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * These variants are significantly slower, but allows control over
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * the entire 32-bit GPR set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static void __rdmsr_safe_regs_on_cpu(void *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) struct msr_regs_info *rv = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) rv->err = rdmsr_safe_regs(rv->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) static void __wrmsr_safe_regs_on_cpu(void *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) struct msr_regs_info *rv = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) rv->err = wrmsr_safe_regs(rv->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) struct msr_regs_info rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) rv.regs = regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) rv.err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) err = smp_call_function_single(cpu, __rdmsr_safe_regs_on_cpu, &rv, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return err ? err : rv.err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) EXPORT_SYMBOL(rdmsr_safe_regs_on_cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) struct msr_regs_info rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) rv.regs = regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) rv.err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) err = smp_call_function_single(cpu, __wrmsr_safe_regs_on_cpu, &rv, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) return err ? err : rv.err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) EXPORT_SYMBOL(wrmsr_safe_regs_on_cpu);