aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/lib/msr-on-cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/lib/msr-on-cpu.c')
-rw-r--r--arch/i386/lib/msr-on-cpu.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/arch/i386/lib/msr-on-cpu.c b/arch/i386/lib/msr-on-cpu.c
new file mode 100644
index 000000000000..1c46bda409ff
--- /dev/null
+++ b/arch/i386/lib/msr-on-cpu.c
@@ -0,0 +1,58 @@
1#include <linux/module.h>
2#include <linux/preempt.h>
3#include <linux/smp.h>
4#include <asm/msr.h>
5
6struct msr_info {
7 u32 msr_no;
8 u32 l, h;
9};
10
11static void __rdmsr_on_cpu(void *info)
12{
13 struct msr_info *rv = info;
14
15 rdmsr(rv->msr_no, rv->l, rv->h);
16}
17
18void rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
19{
20 preempt_disable();
21 if (smp_processor_id() == cpu)
22 rdmsr(msr_no, *l, *h);
23 else {
24 struct msr_info rv;
25
26 rv.msr_no = msr_no;
27 smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 0, 1);
28 *l = rv.l;
29 *h = rv.h;
30 }
31 preempt_enable();
32}
33
34static void __wrmsr_on_cpu(void *info)
35{
36 struct msr_info *rv = info;
37
38 wrmsr(rv->msr_no, rv->l, rv->h);
39}
40
41void wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
42{
43 preempt_disable();
44 if (smp_processor_id() == cpu)
45 wrmsr(msr_no, l, h);
46 else {
47 struct msr_info rv;
48
49 rv.msr_no = msr_no;
50 rv.l = l;
51 rv.h = h;
52 smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 0, 1);
53 }
54 preempt_enable();
55}
56
57EXPORT_SYMBOL(rdmsr_on_cpu);
58EXPORT_SYMBOL(wrmsr_on_cpu);