1 #include <linux/module.h>
2 #include <linux/preempt.h>
3 #include <linux/smp.h>
4 #include <asm/msr.h>
5
6 struct msr_info {
7 u32 msr_no;
8 u32 l, h;
9 int err;
10 };
11
__rdmsr_on_cpu(void * info)12 static void __rdmsr_on_cpu(void *info)
13 {
14 struct msr_info *rv = info;
15
16 rdmsr(rv->msr_no, rv->l, rv->h);
17 }
18
__wrmsr_on_cpu(void * info)19 static void __wrmsr_on_cpu(void *info)
20 {
21 struct msr_info *rv = info;
22
23 wrmsr(rv->msr_no, rv->l, rv->h);
24 }
25
rdmsr_on_cpu(unsigned int cpu,u32 msr_no,u32 * l,u32 * h)26 int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
27 {
28 int err;
29 struct msr_info rv;
30
31 rv.msr_no = msr_no;
32 err = smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 1);
33 *l = rv.l;
34 *h = rv.h;
35
36 return err;
37 }
38
wrmsr_on_cpu(unsigned int cpu,u32 msr_no,u32 l,u32 h)39 int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
40 {
41 int err;
42 struct msr_info rv;
43
44 rv.msr_no = msr_no;
45 rv.l = l;
46 rv.h = h;
47 err = smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 1);
48
49 return err;
50 }
51
52 /* These "safe" variants are slower and should be used when the target MSR
53 may not actually exist. */
__rdmsr_safe_on_cpu(void * info)54 static void __rdmsr_safe_on_cpu(void *info)
55 {
56 struct msr_info *rv = info;
57
58 rv->err = rdmsr_safe(rv->msr_no, &rv->l, &rv->h);
59 }
60
__wrmsr_safe_on_cpu(void * info)61 static void __wrmsr_safe_on_cpu(void *info)
62 {
63 struct msr_info *rv = info;
64
65 rv->err = wrmsr_safe(rv->msr_no, rv->l, rv->h);
66 }
67
rdmsr_safe_on_cpu(unsigned int cpu,u32 msr_no,u32 * l,u32 * h)68 int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
69 {
70 int err;
71 struct msr_info rv;
72
73 rv.msr_no = msr_no;
74 err = smp_call_function_single(cpu, __rdmsr_safe_on_cpu, &rv, 1);
75 *l = rv.l;
76 *h = rv.h;
77
78 return err ? err : rv.err;
79 }
80
wrmsr_safe_on_cpu(unsigned int cpu,u32 msr_no,u32 l,u32 h)81 int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
82 {
83 int err;
84 struct msr_info rv;
85
86 rv.msr_no = msr_no;
87 rv.l = l;
88 rv.h = h;
89 err = smp_call_function_single(cpu, __wrmsr_safe_on_cpu, &rv, 1);
90
91 return err ? err : rv.err;
92 }
93
94 EXPORT_SYMBOL(rdmsr_on_cpu);
95 EXPORT_SYMBOL(wrmsr_on_cpu);
96 EXPORT_SYMBOL(rdmsr_safe_on_cpu);
97 EXPORT_SYMBOL(wrmsr_safe_on_cpu);
98