diff options
author | H. Peter Anvin <hpa@zytor.com> | 2009-08-31 17:13:48 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2009-08-31 19:15:57 -0400 |
commit | 8b956bf1f0f2b552ed93cf6cafe823edff298b3b (patch) | |
tree | 0a4dcb17d4107a606f3e549f52db492aaf7d1cd2 /arch/x86 | |
parent | 0cc0213e73af5963eca259c84876937c20689dbd (diff) |
x86, msr: Create _on_cpu helpers for {rw,wr}msr_safe_regs()
Create _on_cpu helpers for {rw,wr}msr_safe_regs() analogously with the
other MSR functions. This will be necessary to add support for these
to the MSR driver.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Cc: Borislav Petkov <petkovbb@gmail.com>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/include/asm/msr.h | 18 | ||||
-rw-r--r-- | arch/x86/lib/msr.c | 49 |
2 files changed, 63 insertions, 4 deletions
diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h index 943fdd572e16..8e56712aa176 100644 --- a/arch/x86/include/asm/msr.h +++ b/arch/x86/include/asm/msr.h | |||
@@ -97,8 +97,8 @@ notrace static inline int native_write_msr_safe(unsigned int msr, | |||
97 | 97 | ||
98 | extern unsigned long long native_read_tsc(void); | 98 | extern unsigned long long native_read_tsc(void); |
99 | 99 | ||
100 | extern int native_rdmsr_safe_regs(u32 *regs); | 100 | extern int native_rdmsr_safe_regs(u32 regs[8]); |
101 | extern int native_wrmsr_safe_regs(u32 *regs); | 101 | extern int native_wrmsr_safe_regs(u32 regs[8]); |
102 | 102 | ||
103 | static __always_inline unsigned long long __native_read_tsc(void) | 103 | static __always_inline unsigned long long __native_read_tsc(void) |
104 | { | 104 | { |
@@ -196,12 +196,12 @@ static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val) | |||
196 | return native_wrmsr_safe_regs(gprs); | 196 | return native_wrmsr_safe_regs(gprs); |
197 | } | 197 | } |
198 | 198 | ||
199 | static inline int rdmsr_safe_regs(u32 *regs) | 199 | static inline int rdmsr_safe_regs(u32 regs[8]) |
200 | { | 200 | { |
201 | return native_rdmsr_safe_regs(regs); | 201 | return native_rdmsr_safe_regs(regs); |
202 | } | 202 | } |
203 | 203 | ||
204 | static inline int wrmsr_safe_regs(u32 *regs) | 204 | static inline int wrmsr_safe_regs(u32 regs[8]) |
205 | { | 205 | { |
206 | return native_wrmsr_safe_regs(regs); | 206 | return native_wrmsr_safe_regs(regs); |
207 | } | 207 | } |
@@ -245,6 +245,8 @@ void rdmsr_on_cpus(const cpumask_t *mask, u32 msr_no, struct msr *msrs); | |||
245 | void wrmsr_on_cpus(const cpumask_t *mask, u32 msr_no, struct msr *msrs); | 245 | void wrmsr_on_cpus(const cpumask_t *mask, u32 msr_no, struct msr *msrs); |
246 | int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); | 246 | int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); |
247 | int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h); | 247 | int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h); |
248 | int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]); | ||
249 | int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]); | ||
248 | #else /* CONFIG_SMP */ | 250 | #else /* CONFIG_SMP */ |
249 | static inline int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h) | 251 | static inline int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h) |
250 | { | 252 | { |
@@ -275,6 +277,14 @@ static inline int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) | |||
275 | { | 277 | { |
276 | return wrmsr_safe(msr_no, l, h); | 278 | return wrmsr_safe(msr_no, l, h); |
277 | } | 279 | } |
280 | static inline int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]) | ||
281 | { | ||
282 | return rdmsr_safe_regs(regs); | ||
283 | } | ||
284 | static inline int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]) | ||
285 | { | ||
286 | return wrmsr_safe_regs(regs); | ||
287 | } | ||
278 | #endif /* CONFIG_SMP */ | 288 | #endif /* CONFIG_SMP */ |
279 | #endif /* __ASSEMBLY__ */ | 289 | #endif /* __ASSEMBLY__ */ |
280 | #endif /* __KERNEL__ */ | 290 | #endif /* __KERNEL__ */ |
diff --git a/arch/x86/lib/msr.c b/arch/x86/lib/msr.c index caa24aca8115..33a1e3ca22d8 100644 --- a/arch/x86/lib/msr.c +++ b/arch/x86/lib/msr.c | |||
@@ -175,3 +175,52 @@ int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) | |||
175 | return err ? err : rv.err; | 175 | return err ? err : rv.err; |
176 | } | 176 | } |
177 | EXPORT_SYMBOL(wrmsr_safe_on_cpu); | 177 | EXPORT_SYMBOL(wrmsr_safe_on_cpu); |
178 | |||
179 | /* | ||
180 | * These variants are significantly slower, but allows control over | ||
181 | * the entire 32-bit GPR set. | ||
182 | */ | ||
183 | struct msr_regs_info { | ||
184 | u32 *regs; | ||
185 | int err; | ||
186 | }; | ||
187 | |||
188 | static void __rdmsr_safe_regs_on_cpu(void *info) | ||
189 | { | ||
190 | struct msr_regs_info *rv = info; | ||
191 | |||
192 | rv->err = rdmsr_safe_regs(rv->regs); | ||
193 | } | ||
194 | |||
195 | static void __wrmsr_safe_regs_on_cpu(void *info) | ||
196 | { | ||
197 | struct msr_regs_info *rv = info; | ||
198 | |||
199 | rv->err = wrmsr_safe_regs(rv->regs); | ||
200 | } | ||
201 | |||
202 | int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs) | ||
203 | { | ||
204 | int err; | ||
205 | struct msr_regs_info rv; | ||
206 | |||
207 | rv.regs = regs; | ||
208 | rv.err = -EIO; | ||
209 | err = smp_call_function_single(cpu, __rdmsr_safe_regs_on_cpu, &rv, 1); | ||
210 | |||
211 | return err ? err : rv.err; | ||
212 | } | ||
213 | EXPORT_SYMBOL(rdmsr_safe_regs_on_cpu); | ||
214 | |||
215 | int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs) | ||
216 | { | ||
217 | int err; | ||
218 | struct msr_regs_info rv; | ||
219 | |||
220 | rv.regs = regs; | ||
221 | rv.err = -EIO; | ||
222 | err = smp_call_function_single(cpu, __wrmsr_safe_regs_on_cpu, &rv, 1); | ||
223 | |||
224 | return err ? err : rv.err; | ||
225 | } | ||
226 | EXPORT_SYMBOL(wrmsr_safe_regs_on_cpu); | ||