• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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