#include #include #include #include struct msr_info { u32 msr_no; u32 l, h; int err; }; static void __rdmsr_on_cpu(void *info) { struct msr_info *rv = info; rdmsr(rv->msr_no, rv->l, rv->h); } static void __wrmsr_on_cpu(void *info) { struct msr_info *rv = info; wrmsr(rv->msr_no, rv->l, rv->h); } int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h) { int err; struct msr_info rv; rv.msr_no = msr_no; err = smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 1); *l = rv.l; *h = rv.h; return err; } int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) { int err; struct msr_info rv; rv.msr_no = msr_no; rv.l = l; rv.h = h; err = smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 1); return err; } /* These "safe" variants are slower and should be used when the target MSR may not actually exist. */ static void __rdmsr_safe_on_cpu(void *info) { struct msr_info *rv = info; rv->err = rdmsr_safe(rv->msr_no, &rv->l, &rv->h); } static void __wrmsr_safe_on_cpu(void *info) { struct msr_info *rv = info; rv->err = wrmsr_safe(rv->msr_no, rv->l, rv->h); } int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h) { int err; struct msr_info rv; rv.msr_no = msr_no; err = smp_call_function_single(cpu, __rdmsr_safe_on_cpu, &rv, 1); *l = rv.l; *h = rv.h; return err ? err : rv.err; } int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) { int err; struct msr_info rv; rv.msr_no = msr_no; rv.l = l; rv.h = h; err = smp_call_function_single(cpu, __wrmsr_safe_on_cpu, &rv, 1); return err ? err : rv.err; } EXPORT_SYMBOL(rdmsr_on_cpu); EXPORT_SYMBOL(wrmsr_on_cpu); EXPORT_SYMBOL(rdmsr_safe_on_cpu); EXPORT_SYMBOL(wrmsr_safe_on_cpu);