[PATCH v2 2/2] x86/msr: Restrict /dev/cpu/*/msr read to a single MSR per call

From: Tim Wiederhake

Date: Fri Jun 26 2026 - 16:24:29 EST


Reading /dev/cpu/*/msr with a buffer larger than 8 bytes reads not
successive MSRs, but the same one over and over. While documented,
this behavior is unintuitive: A user space caller issuing a 16-byte
read might reasonably expect to receive two consecutive MSRs rather
than the same register twice.

Remove the loop and process a single 8-byte MSR value per call to
avoid this ambiguity.

Signed-off-by: Tim Wiederhake <twiederh@xxxxxxxxxx>
---
arch/x86/kernel/msr.c | 21 +++++++--------------
1 file changed, 7 insertions(+), 14 deletions(-)

diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c
index cc719a6b2ba3..1ea7bd393072 100644
--- a/arch/x86/kernel/msr.c
+++ b/arch/x86/kernel/msr.c
@@ -60,24 +60,17 @@ static ssize_t msr_read(struct file *file, char __user *buf,
u32 reg = *ppos;
int cpu = iminor(file_inode(file));
int err = 0;
- ssize_t bytes = 0;

- if (count % 8)
+ if (count < 8)
return -EINVAL; /* Invalid chunk size */

- for (; count; count -= 8) {
- err = rdmsr_safe_on_cpu(cpu, reg, &data[0], &data[1]);
- if (err)
- break;
- if (copy_to_user(tmp, &data, 8)) {
- err = -EFAULT;
- break;
- }
- tmp += 2;
- bytes += 8;
- }
+ err = rdmsr_safe_on_cpu(cpu, reg, &data[0], &data[1]);
+ if (err)
+ return err;
+ if (copy_to_user(tmp, &data, 8))
+ return -EFAULT;

- return bytes ? bytes : err;
+ return 8;
}

static int filter_write(u32 reg)
--
2.52.0