blob: 1c46bda409ff1e20e7e3fd6ee569c274ec66e66b [file] [log] [blame]
Alexey Dobriyanb077ffb2007-02-16 01:48:11 -08001#include <linux/module.h>
2#include <linux/preempt.h>
3#include <linux/smp.h>
4#include <asm/msr.h>
5
Alexey Dobriyanb077ffb2007-02-16 01:48:11 -08006struct 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}
Alexey Dobriyanb077ffb2007-02-16 01:48:11 -080056
57EXPORT_SYMBOL(rdmsr_on_cpu);
58EXPORT_SYMBOL(wrmsr_on_cpu);