msr-on-cpu.c 1.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. #include <linux/module.h>
  2. #include <linux/preempt.h>
  3. #include <linux/smp.h>
  4. #include <asm/msr.h>
  5. struct msr_info {
  6. u32 msr_no;
  7. u32 l, h;
  8. };
  9. static void __rdmsr_on_cpu(void *info)
  10. {
  11. struct msr_info *rv = info;
  12. rdmsr(rv->msr_no, rv->l, rv->h);
  13. }
  14. void rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
  15. {
  16. preempt_disable();
  17. if (smp_processor_id() == cpu)
  18. rdmsr(msr_no, *l, *h);
  19. else {
  20. struct msr_info rv;
  21. rv.msr_no = msr_no;
  22. smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 0, 1);
  23. *l = rv.l;
  24. *h = rv.h;
  25. }
  26. preempt_enable();
  27. }
  28. static void __wrmsr_on_cpu(void *info)
  29. {
  30. struct msr_info *rv = info;
  31. wrmsr(rv->msr_no, rv->l, rv->h);
  32. }
  33. void wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
  34. {
  35. preempt_disable();
  36. if (smp_processor_id() == cpu)
  37. wrmsr(msr_no, l, h);
  38. else {
  39. struct msr_info rv;
  40. rv.msr_no = msr_no;
  41. rv.l = l;
  42. rv.h = h;
  43. smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 0, 1);
  44. }
  45. preempt_enable();
  46. }
  47. EXPORT_SYMBOL(rdmsr_on_cpu);
  48. EXPORT_SYMBOL(wrmsr_on_cpu);