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