summaryrefslogtreecommitdiff
path: root/arch/x86
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-06-15 15:08:14 +0530
committerLinus Torvalds <torvalds@linux-foundation.org>2026-06-15 15:08:14 +0530
commit7561361d7655828d50482cd9e80fa3bf73d9c92e (patch)
treec302cc2596cfd14478ba87e32a993020bdfcc9ae /arch/x86
parent2cbf335f8ccc7a6418159858dc03e36df8e3e5cf (diff)
parentb5884070f9da9ffecd5141b5811cfdbaa274809a (diff)
downloadlinux-next-7561361d7655828d50482cd9e80fa3bf73d9c92e.tar.gz
linux-next-7561361d7655828d50482cd9e80fa3bf73d9c92e.zip
Merge tag 'x86-msr-2026-06-14' of gitolite.kernel.org:pub/scm/linux/kernel/git/tip/tip
Pull x86/msr updates from Ingo Molnar: - Large series to reorganize the rdmsr/wrmsr APIs to remove 32-bit variants and convert to 64-bit variants (Juergen Gross) - Fix W=1 warning (HyeongJun An) * tag 'x86-msr-2026-06-14' of gitolite.kernel.org:pub/scm/linux/kernel/git/tip/tip: x86/msr: Remove wrmsrl() x86/msr: Switch wrmsrl() users to wrmsrq() x86/msr: Remove rdmsrl() x86/msr: Switch rdmsrl() users to rdmsrq() x86/msr: Remove wrmsr_safe_on_cpu() x86/msr: Switch wrmsr_safe_on_cpu() users to wrmsrq_safe_on_cpu() x86/msr: Remove rdmsr_safe_on_cpu() x86/msr: Switch rdmsr_safe_on_cpu() users to rdmsrq_safe_on_cpu() x86/msr: Don't use rdmsr_safe_on_cpu() in rdmsrq_safe_on_cpu() x86/msr: Remove wrmsr_on_cpu() x86/msr: Switch wrmsr_on_cpu() users to wrmsrq_on_cpu() x86/msr: Remove rdmsr_on_cpu() x86/msr: Switch rdmsr_on_cpu() users to rdmsrq_on_cpu() x86/msr: Remove rdmsrl_on_cpu() x86/msr: Switch rdmsrl_on_cpu() user to rdmsrq_on_cpu() x86/process: Convert rdmsr() to rdmsrq() in arch_post_acpi_subsys_init() to address W=1 warning
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/events/amd/uncore.c4
-rw-r--r--arch/x86/events/intel/core.c4
-rw-r--r--arch/x86/events/intel/ds.c11
-rw-r--r--arch/x86/include/asm/msr.h33
-rw-r--r--arch/x86/kernel/cpu/mce/amd.c6
-rw-r--r--arch/x86/kernel/cpu/mce/inject.c8
-rw-r--r--arch/x86/kernel/cpu/resctrl/monitor.c4
-rw-r--r--arch/x86/kernel/msr.c8
-rw-r--r--arch/x86/kernel/process.c6
-rw-r--r--arch/x86/kernel/process_64.c2
-rw-r--r--arch/x86/kvm/pmu.c6
-rw-r--r--arch/x86/kvm/vmx/tdx.c6
-rw-r--r--arch/x86/lib/msr-smp.c89
13 files changed, 47 insertions, 140 deletions
diff --git a/arch/x86/events/amd/uncore.c b/arch/x86/events/amd/uncore.c
index a0364ca2f917..ea97fec0f391 100644
--- a/arch/x86/events/amd/uncore.c
+++ b/arch/x86/events/amd/uncore.c
@@ -966,7 +966,7 @@ static void amd_uncore_umc_read(struct perf_event *event)
* UMC counters do not have RDPMC assignments. Read counts directly
* from the corresponding PERF_CTR.
*/
- rdmsrl(hwc->event_base, new);
+ rdmsrq(hwc->event_base, new);
/*
* Unlike the other uncore counters, UMC counters saturate and set the
@@ -975,7 +975,7 @@ static void amd_uncore_umc_read(struct perf_event *event)
* that the counter never gets a chance to saturate.
*/
if (new & BIT_ULL(63 - COUNTER_SHIFT)) {
- wrmsrl(hwc->event_base, 0);
+ wrmsrq(hwc->event_base, 0);
local64_set(&hwc->prev_count, 0);
} else {
local64_set(&hwc->prev_count, new);
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 6f4e0e5a2416..c819b060603f 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -3417,12 +3417,12 @@ static void intel_pmu_config_acr(int idx, u64 mask, u32 reload)
}
if (cpuc->acr_cfg_b[idx] != mask) {
- wrmsrl(msr_b + msr_offset, mask);
+ wrmsrq(msr_b + msr_offset, mask);
cpuc->acr_cfg_b[idx] = mask;
}
/* Only update CFG_C reload when ACR is actively enabled (mask != 0) */
if (mask && ((cpuc->cfg_c_val[idx] & ARCH_PEBS_RELOAD) != reload)) {
- wrmsrl(msr_c + msr_offset, reload);
+ wrmsrq(msr_c + msr_offset, reload);
cpuc->cfg_c_val[idx] = reload;
}
}
diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
index cb72af9b61ce..91a093d8cf2e 100644
--- a/arch/x86/events/intel/ds.c
+++ b/arch/x86/events/intel/ds.c
@@ -780,9 +780,7 @@ void init_debug_store_on_cpu(int cpu)
if (!ds)
return;
- wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA,
- (u32)((u64)(unsigned long)ds),
- (u32)((u64)(unsigned long)ds >> 32));
+ wrmsrq_on_cpu(cpu, MSR_IA32_DS_AREA, (u64)(unsigned long)ds);
}
void fini_debug_store_on_cpu(int cpu)
@@ -790,7 +788,7 @@ void fini_debug_store_on_cpu(int cpu)
if (!per_cpu(cpu_hw_events, cpu).ds)
return;
- wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA, 0, 0);
+ wrmsrq_on_cpu(cpu, MSR_IA32_DS_AREA, 0);
}
static DEFINE_PER_CPU(void *, insn_buffer);
@@ -1095,8 +1093,7 @@ void init_arch_pebs_on_cpu(int cpu)
* contiguous physical buffer (__alloc_pages_node() with order)
*/
arch_pebs_base = virt_to_phys(cpuc->pebs_vaddr) | PEBS_BUFFER_SHIFT;
- wrmsr_on_cpu(cpu, MSR_IA32_PEBS_BASE, (u32)arch_pebs_base,
- (u32)(arch_pebs_base >> 32));
+ wrmsrq_on_cpu(cpu, MSR_IA32_PEBS_BASE, arch_pebs_base);
x86_pmu.pebs_active = 1;
}
@@ -1105,7 +1102,7 @@ inline void fini_arch_pebs_on_cpu(int cpu)
if (!x86_pmu.arch_pebs)
return;
- wrmsr_on_cpu(cpu, MSR_IA32_PEBS_BASE, 0, 0);
+ wrmsrq_on_cpu(cpu, MSR_IA32_PEBS_BASE, 0);
}
/*
diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h
index 9c2ea29e12a9..2f41a9289d79 100644
--- a/arch/x86/include/asm/msr.h
+++ b/arch/x86/include/asm/msr.h
@@ -256,29 +256,15 @@ int msr_set_bit(u32 msr, u8 bit);
int msr_clear_bit(u32 msr, u8 bit);
#ifdef CONFIG_SMP
-int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
-int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
int rdmsrq_on_cpu(unsigned int cpu, u32 msr_no, u64 *q);
int wrmsrq_on_cpu(unsigned int cpu, u32 msr_no, u64 q);
void rdmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr __percpu *msrs);
void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr __percpu *msrs);
-int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
-int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
int rdmsrq_safe_on_cpu(unsigned int cpu, u32 msr_no, u64 *q);
int wrmsrq_safe_on_cpu(unsigned int cpu, u32 msr_no, u64 q);
int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]);
int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]);
#else /* CONFIG_SMP */
-static inline int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
-{
- rdmsr(msr_no, *l, *h);
- return 0;
-}
-static inline int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
-{
- wrmsr(msr_no, l, h);
- return 0;
-}
static inline int rdmsrq_on_cpu(unsigned int cpu, u32 msr_no, u64 *q)
{
rdmsrq(msr_no, *q);
@@ -292,21 +278,12 @@ static inline int wrmsrq_on_cpu(unsigned int cpu, u32 msr_no, u64 q)
static inline void rdmsr_on_cpus(const struct cpumask *m, u32 msr_no,
struct msr __percpu *msrs)
{
- rdmsr_on_cpu(0, msr_no, raw_cpu_ptr(&msrs->l), raw_cpu_ptr(&msrs->h));
+ rdmsrq_on_cpu(0, msr_no, raw_cpu_ptr(&msrs->q));
}
static inline void wrmsr_on_cpus(const struct cpumask *m, u32 msr_no,
struct msr __percpu *msrs)
{
- wrmsr_on_cpu(0, msr_no, raw_cpu_read(msrs->l), raw_cpu_read(msrs->h));
-}
-static inline int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no,
- u32 *l, u32 *h)
-{
- return rdmsr_safe(msr_no, l, h);
-}
-static inline int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
-{
- return wrmsr_safe(msr_no, l, h);
+ wrmsrq_on_cpu(0, msr_no, raw_cpu_read(msrs->q));
}
static inline int rdmsrq_safe_on_cpu(unsigned int cpu, u32 msr_no, u64 *q)
{
@@ -325,11 +302,5 @@ static inline int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8])
return wrmsr_safe_regs(regs);
}
#endif /* CONFIG_SMP */
-
-/* Compatibility wrappers: */
-#define rdmsrl(msr, val) rdmsrq(msr, val)
-#define wrmsrl(msr, val) wrmsrq(msr, val)
-#define rdmsrl_on_cpu(cpu, msr, q) rdmsrq_on_cpu(cpu, msr, q)
-
#endif /* __ASSEMBLER__ */
#endif /* _ASM_X86_MSR_H */
diff --git a/arch/x86/kernel/cpu/mce/amd.c b/arch/x86/kernel/cpu/mce/amd.c
index 222fa9cb181b..36e0df4d1342 100644
--- a/arch/x86/kernel/cpu/mce/amd.c
+++ b/arch/x86/kernel/cpu/mce/amd.c
@@ -969,13 +969,13 @@ store_threshold_limit(struct threshold_block *b, const char *buf, size_t size)
static ssize_t show_error_count(struct threshold_block *b, char *buf)
{
- u32 lo, hi;
+ struct msr val;
/* CPU might be offline by now */
- if (rdmsr_on_cpu(b->cpu, b->address, &lo, &hi))
+ if (rdmsrq_on_cpu(b->cpu, b->address, &val.q))
return -ENODEV;
- return sprintf(buf, "%u\n", ((hi & THRESHOLD_MAX) -
+ return sprintf(buf, "%u\n", ((val.h & THRESHOLD_MAX) -
(THRESHOLD_MAX - b->threshold_limit)));
}
diff --git a/arch/x86/kernel/cpu/mce/inject.c b/arch/x86/kernel/cpu/mce/inject.c
index d02c4f556cd0..6d30e7720f31 100644
--- a/arch/x86/kernel/cpu/mce/inject.c
+++ b/arch/x86/kernel/cpu/mce/inject.c
@@ -316,18 +316,18 @@ static struct notifier_block inject_nb = {
*/
static int toggle_hw_mce_inject(unsigned int cpu, bool enable)
{
- u32 l, h;
+ struct msr val;
int err;
- err = rdmsr_on_cpu(cpu, MSR_K7_HWCR, &l, &h);
+ err = rdmsrq_on_cpu(cpu, MSR_K7_HWCR, &val.q);
if (err) {
pr_err("%s: error reading HWCR\n", __func__);
return err;
}
- enable ? (l |= BIT(18)) : (l &= ~BIT(18));
+ enable ? (val.l |= BIT(18)) : (val.l &= ~BIT(18));
- err = wrmsr_on_cpu(cpu, MSR_K7_HWCR, l, h);
+ err = wrmsrq_on_cpu(cpu, MSR_K7_HWCR, val.q);
if (err)
pr_err("%s: error writing HWCR\n", __func__);
diff --git a/arch/x86/kernel/cpu/resctrl/monitor.c b/arch/x86/kernel/cpu/resctrl/monitor.c
index 59215fef3924..e4918c32a822 100644
--- a/arch/x86/kernel/cpu/resctrl/monitor.c
+++ b/arch/x86/kernel/cpu/resctrl/monitor.c
@@ -301,7 +301,7 @@ static int __cntr_id_read(u32 cntr_id, u64 *val)
* is set if the counter data is unavailable.
*/
wrmsr(MSR_IA32_QM_EVTSEL, ABMC_EXTENDED_EVT_ID | ABMC_EVT_ID, cntr_id);
- rdmsrl(MSR_IA32_QM_CTR, msr_val);
+ rdmsrq(MSR_IA32_QM_CTR, msr_val);
if (msr_val & RMID_VAL_ERROR)
return -EIO;
@@ -532,7 +532,7 @@ static void resctrl_abmc_config_one_amd(void *info)
{
union l3_qos_abmc_cfg *abmc_cfg = info;
- wrmsrl(MSR_IA32_L3_QOS_ABMC_CFG, abmc_cfg->full);
+ wrmsrq(MSR_IA32_L3_QOS_ABMC_CFG, abmc_cfg->full);
}
/*
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c
index 4469c784eaa0..34bdb752f892 100644
--- a/arch/x86/kernel/msr.c
+++ b/arch/x86/kernel/msr.c
@@ -53,7 +53,7 @@ static ssize_t msr_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
u32 __user *tmp = (u32 __user *) buf;
- u32 data[2];
+ u64 data;
u32 reg = *ppos;
int cpu = iminor(file_inode(file));
int err = 0;
@@ -63,7 +63,7 @@ static ssize_t msr_read(struct file *file, char __user *buf,
return -EINVAL; /* Invalid chunk size */
for (; count; count -= 8) {
- err = rdmsr_safe_on_cpu(cpu, reg, &data[0], &data[1]);
+ err = rdmsrq_safe_on_cpu(cpu, reg, &data);
if (err)
break;
if (copy_to_user(tmp, &data, 8)) {
@@ -109,7 +109,7 @@ static ssize_t msr_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
const u32 __user *tmp = (const u32 __user *)buf;
- u32 data[2];
+ u64 data;
u32 reg = *ppos;
int cpu = iminor(file_inode(file));
int err = 0;
@@ -134,7 +134,7 @@ static ssize_t msr_write(struct file *file, const char __user *buf,
add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_STILL_OK);
- err = wrmsr_safe_on_cpu(cpu, reg, data[0], data[1]);
+ err = wrmsrq_safe_on_cpu(cpu, reg, data);
if (err)
break;
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 4c718f8adc59..a554f19c9973 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -969,7 +969,7 @@ void amd_e400_c1e_apic_setup(void)
void __init arch_post_acpi_subsys_init(void)
{
- u32 lo, hi;
+ u64 val;
if (!boot_cpu_has_bug(X86_BUG_AMD_E400))
return;
@@ -979,8 +979,8 @@ void __init arch_post_acpi_subsys_init(void)
* the machine is affected K8_INTP_C1E_ACTIVE_MASK bits are set in
* MSR_K8_INT_PENDING_MSG.
*/
- rdmsr(MSR_K8_INT_PENDING_MSG, lo, hi);
- if (!(lo & K8_INTP_C1E_ACTIVE_MASK))
+ rdmsrq(MSR_K8_INT_PENDING_MSG, val);
+ if (!(val & K8_INTP_C1E_ACTIVE_MASK))
return;
boot_cpu_set_bug(X86_BUG_AMD_APIC_C1E);
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index b85e715ebb30..d44afbe005bb 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -708,7 +708,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
/* Reset hw history on AMD CPUs */
if (cpu_feature_enabled(X86_FEATURE_AMD_WORKLOAD_CLASS))
- wrmsrl(MSR_AMD_WORKLOAD_HRST, 0x1);
+ wrmsrq(MSR_AMD_WORKLOAD_HRST, 0x1);
return prev_p;
}
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index e218352e3423..aee70e5dc15d 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -1313,14 +1313,14 @@ static void kvm_pmu_load_guest_pmcs(struct kvm_vcpu *vcpu)
pmc = &pmu->gp_counters[i];
if (pmc->counter != rdpmc(i))
- wrmsrl(gp_counter_msr(i), pmc->counter);
- wrmsrl(gp_eventsel_msr(i), pmc->eventsel_hw);
+ wrmsrq(gp_counter_msr(i), pmc->counter);
+ wrmsrq(gp_eventsel_msr(i), pmc->eventsel_hw);
}
for (i = 0; i < pmu->nr_arch_fixed_counters; i++) {
pmc = &pmu->fixed_counters[i];
if (pmc->counter != rdpmc(INTEL_PMC_FIXED_RDPMC_BASE | i))
- wrmsrl(fixed_counter_msr(i), pmc->counter);
+ wrmsrq(fixed_counter_msr(i), pmc->counter);
}
}
diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c
index 04ce321ebdf3..cb50e23c39ca 100644
--- a/arch/x86/kvm/vmx/tdx.c
+++ b/arch/x86/kvm/vmx/tdx.c
@@ -823,7 +823,7 @@ static void tdx_prepare_switch_to_host(struct kvm_vcpu *vcpu)
return;
++vcpu->stat.host_state_reload;
- wrmsrl(MSR_KERNEL_GS_BASE, vt->msr_host_kernel_gs_base);
+ wrmsrq(MSR_KERNEL_GS_BASE, vt->msr_host_kernel_gs_base);
vt->guest_state_loaded = false;
}
@@ -1048,10 +1048,10 @@ static void tdx_load_host_xsave_state(struct kvm_vcpu *vcpu)
/*
* Likewise, even if a TDX hosts didn't support XSS both arms of
- * the comparison would be 0 and the wrmsrl would be skipped.
+ * the comparison would be 0 and the wrmsrq would be skipped.
*/
if (kvm_host.xss != (kvm_tdx->xfam & kvm_caps.supported_xss))
- wrmsrl(MSR_IA32_XSS, kvm_host.xss);
+ wrmsrq(MSR_IA32_XSS, kvm_host.xss);
}
#define TDX_DEBUGCTL_PRESERVED (DEBUGCTLMSR_BTF | \
diff --git a/arch/x86/lib/msr-smp.c b/arch/x86/lib/msr-smp.c
index b8f63419e6ae..0c6627773c80 100644
--- a/arch/x86/lib/msr-smp.c
+++ b/arch/x86/lib/msr-smp.c
@@ -31,22 +31,6 @@ static void __wrmsr_on_cpu(void *info)
wrmsr(rv->msr_no, reg->l, reg->h);
}
-int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
-{
- int err;
- struct msr_info rv;
-
- memset(&rv, 0, sizeof(rv));
-
- rv.msr_no = msr_no;
- err = smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 1);
- *l = rv.reg.l;
- *h = rv.reg.h;
-
- return err;
-}
-EXPORT_SYMBOL(rdmsr_on_cpu);
-
int rdmsrq_on_cpu(unsigned int cpu, u32 msr_no, u64 *q)
{
int err;
@@ -62,22 +46,6 @@ int rdmsrq_on_cpu(unsigned int cpu, u32 msr_no, u64 *q)
}
EXPORT_SYMBOL(rdmsrq_on_cpu);
-int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
-{
- int err;
- struct msr_info rv;
-
- memset(&rv, 0, sizeof(rv));
-
- rv.msr_no = msr_no;
- rv.reg.l = l;
- rv.reg.h = h;
- err = smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 1);
-
- return err;
-}
-EXPORT_SYMBOL(wrmsr_on_cpu);
-
int wrmsrq_on_cpu(unsigned int cpu, u32 msr_no, u64 q)
{
int err;
@@ -164,46 +132,6 @@ static void __wrmsr_safe_on_cpu(void *info)
rv->err = wrmsr_safe(rv->msr_no, rv->reg.l, rv->reg.h);
}
-int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
-{
- struct msr_info_completion rv;
- call_single_data_t csd;
- int err;
-
- INIT_CSD(&csd, __rdmsr_safe_on_cpu, &rv);
-
- memset(&rv, 0, sizeof(rv));
- init_completion(&rv.done);
- rv.msr.msr_no = msr_no;
-
- err = smp_call_function_single_async(cpu, &csd);
- if (!err) {
- wait_for_completion(&rv.done);
- err = rv.msr.err;
- }
- *l = rv.msr.reg.l;
- *h = rv.msr.reg.h;
-
- return err;
-}
-EXPORT_SYMBOL(rdmsr_safe_on_cpu);
-
-int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
-{
- int err;
- struct msr_info rv;
-
- memset(&rv, 0, sizeof(rv));
-
- rv.msr_no = msr_no;
- rv.reg.l = l;
- rv.reg.h = h;
- err = smp_call_function_single(cpu, __wrmsr_safe_on_cpu, &rv, 1);
-
- return err ? err : rv.err;
-}
-EXPORT_SYMBOL(wrmsr_safe_on_cpu);
-
int wrmsrq_safe_on_cpu(unsigned int cpu, u32 msr_no, u64 q)
{
int err;
@@ -222,11 +150,22 @@ EXPORT_SYMBOL(wrmsrq_safe_on_cpu);
int rdmsrq_safe_on_cpu(unsigned int cpu, u32 msr_no, u64 *q)
{
- u32 low, high;
+ struct msr_info_completion rv;
+ call_single_data_t csd;
int err;
- err = rdmsr_safe_on_cpu(cpu, msr_no, &low, &high);
- *q = (u64)high << 32 | low;
+ INIT_CSD(&csd, __rdmsr_safe_on_cpu, &rv);
+
+ memset(&rv, 0, sizeof(rv));
+ init_completion(&rv.done);
+ rv.msr.msr_no = msr_no;
+
+ err = smp_call_function_single_async(cpu, &csd);
+ if (!err) {
+ wait_for_completion(&rv.done);
+ err = rv.msr.err;
+ }
+ *q = rv.msr.reg.q;
return err;
}