Merge branch 'upstream-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/linvil...
[linux-2.6] / arch / i386 / lib / msr-on-cpu.c
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 };
10
11 static 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
18 void 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
34 static 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
41 void 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
57 EXPORT_SYMBOL(rdmsr_on_cpu);
58 EXPORT_SYMBOL(wrmsr_on_cpu);