diff options
| -rw-r--r-- | arch/x86/kernel/msr.c | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c index 9c34a1005dba..2e2af5d18191 100644 --- a/arch/x86/kernel/msr.c +++ b/arch/x86/kernel/msr.c | |||
| @@ -72,7 +72,8 @@ static ssize_t msr_read(struct file *file, char __user *buf, | |||
| 72 | u32 data[2]; | 72 | u32 data[2]; |
| 73 | u32 reg = *ppos; | 73 | u32 reg = *ppos; |
| 74 | int cpu = iminor(file->f_path.dentry->d_inode); | 74 | int cpu = iminor(file->f_path.dentry->d_inode); |
| 75 | int err; | 75 | int err = 0; |
| 76 | ssize_t bytes = 0; | ||
| 76 | 77 | ||
| 77 | if (count % 8) | 78 | if (count % 8) |
| 78 | return -EINVAL; /* Invalid chunk size */ | 79 | return -EINVAL; /* Invalid chunk size */ |
| @@ -82,14 +83,17 @@ static ssize_t msr_read(struct file *file, char __user *buf, | |||
| 82 | if (err) { | 83 | if (err) { |
| 83 | if (err == -EFAULT) /* Fix idiotic error code */ | 84 | if (err == -EFAULT) /* Fix idiotic error code */ |
| 84 | err = -EIO; | 85 | err = -EIO; |
| 85 | return err; | 86 | break; |
| 87 | } | ||
| 88 | if (copy_to_user(tmp, &data, 8)) { | ||
| 89 | err = -EFAULT; | ||
| 90 | break; | ||
| 86 | } | 91 | } |
| 87 | if (copy_to_user(tmp, &data, 8)) | ||
| 88 | return -EFAULT; | ||
| 89 | tmp += 2; | 92 | tmp += 2; |
| 93 | bytes += 8; | ||
| 90 | } | 94 | } |
| 91 | 95 | ||
| 92 | return ((char __user *)tmp) - buf; | 96 | return bytes ? bytes : err; |
| 93 | } | 97 | } |
| 94 | 98 | ||
| 95 | static ssize_t msr_write(struct file *file, const char __user *buf, | 99 | static ssize_t msr_write(struct file *file, const char __user *buf, |
| @@ -99,24 +103,28 @@ static ssize_t msr_write(struct file *file, const char __user *buf, | |||
| 99 | u32 data[2]; | 103 | u32 data[2]; |
| 100 | u32 reg = *ppos; | 104 | u32 reg = *ppos; |
| 101 | int cpu = iminor(file->f_path.dentry->d_inode); | 105 | int cpu = iminor(file->f_path.dentry->d_inode); |
| 102 | int err; | 106 | int err = 0; |
| 107 | ssize_t bytes = 0; | ||
| 103 | 108 | ||
| 104 | if (count % 8) | 109 | if (count % 8) |
| 105 | return -EINVAL; /* Invalid chunk size */ | 110 | return -EINVAL; /* Invalid chunk size */ |
| 106 | 111 | ||
| 107 | for (; count; count -= 8) { | 112 | for (; count; count -= 8) { |
| 108 | if (copy_from_user(&data, tmp, 8)) | 113 | if (copy_from_user(&data, tmp, 8)) { |
| 109 | return -EFAULT; | 114 | err = -EFAULT; |
| 115 | break; | ||
| 116 | } | ||
| 110 | err = wrmsr_safe_on_cpu(cpu, reg, data[0], data[1]); | 117 | err = wrmsr_safe_on_cpu(cpu, reg, data[0], data[1]); |
| 111 | if (err) { | 118 | if (err) { |
| 112 | if (err == -EFAULT) /* Fix idiotic error code */ | 119 | if (err == -EFAULT) /* Fix idiotic error code */ |
| 113 | err = -EIO; | 120 | err = -EIO; |
| 114 | return err; | 121 | break; |
| 115 | } | 122 | } |
| 116 | tmp += 2; | 123 | tmp += 2; |
| 124 | bytes += 8; | ||
| 117 | } | 125 | } |
| 118 | 126 | ||
| 119 | return ((char __user *)tmp) - buf; | 127 | return bytes ? bytes : err; |
| 120 | } | 128 | } |
| 121 | 129 | ||
| 122 | static int msr_open(struct inode *inode, struct file *file) | 130 | static int msr_open(struct inode *inode, struct file *file) |
