diff options
| -rw-r--r-- | arch/x86/kernel/msr.c | 14 | ||||
| -rw-r--r-- | arch/x86/lib/msr-on-cpu.c | 22 | ||||
| -rw-r--r-- | include/asm-x86/msr.h | 11 |
3 files changed, 28 insertions, 19 deletions
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c index e43938086885..9c34a1005dba 100644 --- a/arch/x86/kernel/msr.c +++ b/arch/x86/kernel/msr.c | |||
| @@ -79,8 +79,11 @@ static ssize_t msr_read(struct file *file, char __user *buf, | |||
| 79 | 79 | ||
| 80 | for (; count; count -= 8) { | 80 | for (; count; count -= 8) { |
| 81 | err = rdmsr_safe_on_cpu(cpu, reg, &data[0], &data[1]); | 81 | err = rdmsr_safe_on_cpu(cpu, reg, &data[0], &data[1]); |
| 82 | if (err) | 82 | if (err) { |
| 83 | return -EIO; | 83 | if (err == -EFAULT) /* Fix idiotic error code */ |
| 84 | err = -EIO; | ||
| 85 | return err; | ||
| 86 | } | ||
| 84 | if (copy_to_user(tmp, &data, 8)) | 87 | if (copy_to_user(tmp, &data, 8)) |
| 85 | return -EFAULT; | 88 | return -EFAULT; |
| 86 | tmp += 2; | 89 | tmp += 2; |
| @@ -105,8 +108,11 @@ static ssize_t msr_write(struct file *file, const char __user *buf, | |||
| 105 | if (copy_from_user(&data, tmp, 8)) | 108 | if (copy_from_user(&data, tmp, 8)) |
| 106 | return -EFAULT; | 109 | return -EFAULT; |
| 107 | err = wrmsr_safe_on_cpu(cpu, reg, data[0], data[1]); | 110 | err = wrmsr_safe_on_cpu(cpu, reg, data[0], data[1]); |
| 108 | if (err) | 111 | if (err) { |
| 109 | return -EIO; | 112 | if (err == -EFAULT) /* Fix idiotic error code */ |
| 113 | err = -EIO; | ||
| 114 | return err; | ||
| 115 | } | ||
| 110 | tmp += 2; | 116 | tmp += 2; |
| 111 | } | 117 | } |
| 112 | 118 | ||
diff --git a/arch/x86/lib/msr-on-cpu.c b/arch/x86/lib/msr-on-cpu.c index d5a2b39f882b..01b868ba82f8 100644 --- a/arch/x86/lib/msr-on-cpu.c +++ b/arch/x86/lib/msr-on-cpu.c | |||
| @@ -30,10 +30,11 @@ static int _rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h, int safe) | |||
| 30 | 30 | ||
| 31 | rv.msr_no = msr_no; | 31 | rv.msr_no = msr_no; |
| 32 | if (safe) { | 32 | if (safe) { |
| 33 | smp_call_function_single(cpu, __rdmsr_safe_on_cpu, &rv, 1); | 33 | err = smp_call_function_single(cpu, __rdmsr_safe_on_cpu, |
| 34 | err = rv.err; | 34 | &rv, 1); |
| 35 | err = err ? err : rv.err; | ||
| 35 | } else { | 36 | } else { |
| 36 | smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 1); | 37 | err = smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 1); |
| 37 | } | 38 | } |
| 38 | *l = rv.l; | 39 | *l = rv.l; |
| 39 | *h = rv.h; | 40 | *h = rv.h; |
| @@ -64,23 +65,24 @@ static int _wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h, int safe) | |||
| 64 | rv.l = l; | 65 | rv.l = l; |
| 65 | rv.h = h; | 66 | rv.h = h; |
| 66 | if (safe) { | 67 | if (safe) { |
| 67 | smp_call_function_single(cpu, __wrmsr_safe_on_cpu, &rv, 1); | 68 | err = smp_call_function_single(cpu, __wrmsr_safe_on_cpu, |
| 68 | err = rv.err; | 69 | &rv, 1); |
| 70 | err = err ? err : rv.err; | ||
| 69 | } else { | 71 | } else { |
| 70 | smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 1); | 72 | err = smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 1); |
| 71 | } | 73 | } |
| 72 | 74 | ||
| 73 | return err; | 75 | return err; |
| 74 | } | 76 | } |
| 75 | 77 | ||
| 76 | void wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) | 78 | int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) |
| 77 | { | 79 | { |
| 78 | _wrmsr_on_cpu(cpu, msr_no, l, h, 0); | 80 | return _wrmsr_on_cpu(cpu, msr_no, l, h, 0); |
| 79 | } | 81 | } |
| 80 | 82 | ||
| 81 | void rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h) | 83 | int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h) |
| 82 | { | 84 | { |
| 83 | _rdmsr_on_cpu(cpu, msr_no, l, h, 0); | 85 | return _rdmsr_on_cpu(cpu, msr_no, l, h, 0); |
| 84 | } | 86 | } |
| 85 | 87 | ||
| 86 | /* These "safe" variants are slower and should be used when the target MSR | 88 | /* These "safe" variants are slower and should be used when the target MSR |
diff --git a/include/asm-x86/msr.h b/include/asm-x86/msr.h index ca110ee73f07..ad5f2decf7f7 100644 --- a/include/asm-x86/msr.h +++ b/include/asm-x86/msr.h | |||
| @@ -192,19 +192,20 @@ do { \ | |||
| 192 | #define write_rdtscp_aux(val) wrmsr(0xc0000103, (val), 0) | 192 | #define write_rdtscp_aux(val) wrmsr(0xc0000103, (val), 0) |
| 193 | 193 | ||
| 194 | #ifdef CONFIG_SMP | 194 | #ifdef CONFIG_SMP |
| 195 | void rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); | 195 | int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); |
| 196 | void wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h); | 196 | int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h); |
| 197 | int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); | 197 | int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); |
| 198 | |||
| 199 | int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h); | 198 | int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h); |
| 200 | #else /* CONFIG_SMP */ | 199 | #else /* CONFIG_SMP */ |
| 201 | static inline void rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h) | 200 | static inline int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h) |
| 202 | { | 201 | { |
| 203 | rdmsr(msr_no, *l, *h); | 202 | rdmsr(msr_no, *l, *h); |
| 203 | return 0; | ||
| 204 | } | 204 | } |
| 205 | static inline void wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) | 205 | static inline int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) |
| 206 | { | 206 | { |
| 207 | wrmsr(msr_no, l, h); | 207 | wrmsr(msr_no, l, h); |
| 208 | return 0; | ||
| 208 | } | 209 | } |
| 209 | static inline int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, | 210 | static inline int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, |
| 210 | u32 *l, u32 *h) | 211 | u32 *l, u32 *h) |
