[PATCH 330/437] x86/kernel: convert to read/write iterators

Jens Axboe
2024-04-11T15:40:49Z

arch/x86/kernel/apm_32.c | 10 +++---
arch/x86/kernel/callthunks.c | 2 +-
arch/x86/kernel/cpu/debugfs.c | 4 +--
arch/x86/kernel/cpu/mce/dev-mcelog.c | 38 +++++++++++------------
arch/x86/kernel/cpu/mce/inject.c | 27 +++++++---------
arch/x86/kernel/cpu/mce/severity.c | 11 +++----
arch/x86/kernel/cpu/resctrl/pseudo_lock.c | 18 +++++------
arch/x86/kernel/cpuid.c | 16 +++++-----
arch/x86/kernel/kdebugfs.c | 14 ++++-----
arch/x86/kernel/msr.c | 28 +++++++----------
arch/x86/kernel/tboot.c | 17 +++++-----
11 files changed, 86 insertions(+), 99 deletions(-)

diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
index b37ab1095707..bc4c8db6b52f 100644
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -1431,13 +1431,14 @@ static int check_apm_user(struct apm_user *as, const char *func)
return 0;
}

-static ssize_t do_read(struct file *fp, char __user *buf, size_t count, loff_t *ppos)
+static ssize_t do_read(struct kiocb *iocb, struct iov_iter *to)
{
+ size_t count = iov_iter_count(to);
struct apm_user *as;
int i;
apm_event_t event;

- as = fp->private_data;
+ as = iocb->ki_filp->private_data;
if (check_apm_user(as, "read"))
return -EIO;
if ((int)count < sizeof(apm_event_t))
@@ -1448,7 +1449,7 @@ static ssize_t do_read(struct file *fp, char __user *buf, size_t count, loff_t *
i = count;
while ((i >= sizeof(event)) && !queue_empty(as)) {
event = get_queued_event(as);
- if (copy_to_user(buf, &event, sizeof(event))) {
+ if (!copy_to_iter_full(&event, sizeof(event), to)) {
if (i < count)
break;
return -EFAULT;
@@ -1464,7 +1465,6 @@ static ssize_t do_read(struct file *fp, char __user *buf, size_t count, loff_t *
as->standbys_read++;
break;
}
- buf += sizeof(event);
i -= sizeof(event);
}
if (i < count)
@@ -1876,7 +1876,7 @@ __setup("apm=", apm_setup);

static const struct file_operations apm_bios_fops = {
.owner = THIS_MODULE,
- .read = do_read,
+ .read_iter = do_read,
.poll = do_poll,
.unlocked_ioctl = do_ioctl,
.open = do_open,
diff --git a/arch/x86/kernel/callthunks.c b/arch/x86/kernel/callthunks.c
index e92ff0c11db8..bec11795ff8e 100644
--- a/arch/x86/kernel/callthunks.c
+++ b/arch/x86/kernel/callthunks.c
@@ -375,7 +375,7 @@ static int callthunks_debug_open(struct inode *inode, struct file *file)

static const struct file_operations dfs_ops = {
.open = callthunks_debug_open,
- .read = seq_read,
+ .read_iter = seq_read_iter,
.llseek = seq_lseek,
.release = single_release,
};
diff --git a/arch/x86/kernel/cpu/debugfs.c b/arch/x86/kernel/cpu/debugfs.c
index 3baf3e435834..1f29b224c8c0 100644
--- a/arch/x86/kernel/cpu/debugfs.c
+++ b/arch/x86/kernel/cpu/debugfs.c
@@ -42,7 +42,7 @@ static int cpu_debug_open(struct inode *inode, struct file *file)

static const struct file_operations dfs_cpu_ops = {
.open = cpu_debug_open,
- .read = seq_read,
+ .read_iter = seq_read_iter,
.llseek = seq_lseek,
.release = single_release,
};
@@ -76,7 +76,7 @@ static int dom_debug_open(struct inode *inode, struct file *file)

static const struct file_operations dfs_dom_ops = {
.open = dom_debug_open,
- .read = seq_read,
+ .read_iter = seq_read_iter,
.llseek = seq_lseek,
.release = single_release,
};
diff --git a/arch/x86/kernel/cpu/mce/dev-mcelog.c b/arch/x86/kernel/cpu/mce/dev-mcelog.c
index a05ac0716ecf..1d5d1b26b85b 100644
--- a/arch/x86/kernel/cpu/mce/dev-mcelog.c
+++ b/arch/x86/kernel/cpu/mce/dev-mcelog.c
@@ -159,7 +159,7 @@ static int mce_chrdev_release(struct inode *inode, struct file *file)
static int mce_apei_read_done;

/* Collect MCE record of previous boot in persistent storage via APEI ERST. */
-static int __mce_read_apei(char __user **ubuf, size_t usize)
+static int __mce_read_apei(struct iov_iter *to, size_t usize)
{
int rc;
u64 record_id;
@@ -181,7 +181,7 @@ static int __mce_read_apei(char __user **ubuf, size_t usize)
return rc;
}
rc = -EFAULT;
- if (copy_to_user(*ubuf, &m, sizeof(struct mce)))
+ if (!copy_to_iter_full(&m, sizeof(struct mce), to))
return rc;
/*
* In fact, we should have cleared the record after that has
@@ -194,51 +194,49 @@ static int __mce_read_apei(char __user **ubuf, size_t usize)
mce_apei_read_done = 1;
return rc;
}
- *ubuf += sizeof(struct mce);

return 0;
}

-static ssize_t mce_chrdev_read(struct file *filp, char __user *ubuf,
- size_t usize, loff_t *off)
+static ssize_t mce_chrdev_read(struct kiocb *iocb, struct iov_iter *to)
{
- char __user *buf = ubuf;
+ size_t copied, usize = iov_iter_count(to);
unsigned next;
int i, err;

mutex_lock(&mce_chrdev_read_mutex);

if (!mce_apei_read_done) {
- err = __mce_read_apei(&buf, usize);
- if (err || buf != ubuf)
+ err = __mce_read_apei(to, usize);
+ if (err)
goto out;
}

/* Only supports full reads right now */
err = -EINVAL;
- if (*off != 0 || usize < mcelog->len * sizeof(struct mce))
+ if (iocb->ki_pos != 0 || usize < mcelog->len * sizeof(struct mce))
goto out;

next = mcelog->next;
err = 0;
+ copied = 0;

for (i = 0; i < next; i++) {
struct mce *m = &mcelog->entry[i];

- err |= copy_to_user(buf, m, sizeof(*m));
- buf += sizeof(*m);
+ if (copy_to_iter_full(m, sizeof(*m), to))
+ copied += sizeof(*m);
+ else
+ err = -EFAULT;
}

memset(mcelog->entry, 0, next * sizeof(struct mce));
mcelog->next = 0;

- if (err)
- err = -EFAULT;
-
out:
mutex_unlock(&mce_chrdev_read_mutex);

- return err ? err : buf - ubuf;
+ return err ? err : copied;
}

static __poll_t mce_chrdev_poll(struct file *file, poll_table *wait)
@@ -290,9 +288,9 @@ void mce_unregister_injector_chain(struct notifier_block *nb)
}
EXPORT_SYMBOL_GPL(mce_unregister_injector_chain);

-static ssize_t mce_chrdev_write(struct file *filp, const char __user *ubuf,
- size_t usize, loff_t *off)
+static ssize_t mce_chrdev_write(struct kiocb *iocb, struct iov_iter *from)
{
+ size_t usize = iov_iter_count(from);
struct mce m;

if (!capable(CAP_SYS_ADMIN))
@@ -306,7 +304,7 @@ static ssize_t mce_chrdev_write(struct file *filp, const char __user *ubuf,

if ((unsigned long)usize > sizeof(struct mce))
usize = sizeof(struct mce);
- if (copy_from_user(&m, ubuf, usize))
+ if (!copy_from_iter_full(&m, usize, from))
return -EFAULT;

if (m.extcpu >= num_possible_cpus() || !cpu_online(m.extcpu))
@@ -326,8 +324,8 @@ static ssize_t mce_chrdev_write(struct file *filp, const char __user *ubuf,
static const struct file_operations mce_chrdev_ops = {
.open = mce_chrdev_open,
.release = mce_chrdev_release,
- .read = mce_chrdev_read,
- .write = mce_chrdev_write,
+ .read_iter = mce_chrdev_read,
+ .write_iter = mce_chrdev_write,
.poll = mce_chrdev_poll,
.unlocked_ioctl = mce_chrdev_ioctl,
.compat_ioctl = compat_ptr_ioctl,
diff --git a/arch/x86/kernel/cpu/mce/inject.c b/arch/x86/kernel/cpu/mce/inject.c
index 94953d749475..5d545f331d0d 100644
--- a/arch/x86/kernel/cpu/mce/inject.c
+++ b/arch/x86/kernel/cpu/mce/inject.c
@@ -349,27 +349,26 @@ static int __set_inj(const char *buf)
return -EINVAL;
}

-static ssize_t flags_read(struct file *filp, char __user *ubuf,
- size_t cnt, loff_t *ppos)
+static ssize_t flags_read(struct kiocb *iocb, struct iov_iter *to)
{
char buf[MAX_FLAG_OPT_SIZE];
int n;

n = sprintf(buf, "%s\n", flags_options[inj_type]);

- return simple_read_from_buffer(ubuf, cnt, ppos, buf, n);
+ return simple_copy_to_iter(buf, &iocb->ki_pos, n, to);
}

-static ssize_t flags_write(struct file *filp, const char __user *ubuf,
- size_t cnt, loff_t *ppos)
+static ssize_t flags_write(struct kiocb *iocb, struct iov_iter *from)
{
char buf[MAX_FLAG_OPT_SIZE], *__buf;
+ size_t cnt = iov_iter_count(from);
int err;

if (!cnt || cnt > MAX_FLAG_OPT_SIZE)
return -EINVAL;

- if (copy_from_user(&buf, ubuf, cnt))
+ if (!copy_from_iter_full(&buf, cnt, from))
return -EFAULT;

buf[cnt - 1] = 0;
@@ -383,14 +382,14 @@ static ssize_t flags_write(struct file *filp, const char __user *ubuf,
return err;
}

- *ppos += cnt;
+ iocb->ki_pos += cnt;

return cnt;
}

static const struct file_operations flags_fops = {
- .read = flags_read,
- .write = flags_write,
+ .read_iter = flags_read,
+ .write_iter = flags_write,
.llseek = generic_file_llseek,
};

@@ -679,16 +678,14 @@ static const char readme_msg[] =
"ipid:\t IPID (AMD-specific)\n"
"\n";

-static ssize_t
-inj_readme_read(struct file *filp, char __user *ubuf,
- size_t cnt, loff_t *ppos)
+static ssize_t inj_readme_read(struct kiocb *iocb, struct iov_iter *to)
{
- return simple_read_from_buffer(ubuf, cnt, ppos,
- readme_msg, strlen(readme_msg));
+ return simple_copy_to_iter(readme_msg, &iocb->ki_pos,
+ strlen(readme_msg), to);
}

static const struct file_operations readme_fops = {
- .read = inj_readme_read,
+ .read_iter = inj_readme_read,
};

static struct dfs_node {
diff --git a/arch/x86/kernel/cpu/mce/severity.c b/arch/x86/kernel/cpu/mce/severity.c
index c4477162c07d..eb648f415d55 100644
--- a/arch/x86/kernel/cpu/mce/severity.c
+++ b/arch/x86/kernel/cpu/mce/severity.c
@@ -447,21 +447,20 @@ static int severities_coverage_open(struct inode *inode, struct file *file)
return seq_open(file, &severities_seq_ops);
}

-static ssize_t severities_coverage_write(struct file *file,
- const char __user *ubuf,
- size_t count, loff_t *ppos)
+static ssize_t severities_coverage_write(struct kiocb *iocb,
+ struct iov_iter *from)
{
int i;
for (i = 0; i < ARRAY_SIZE(severities); i++)
severities[i].covered = 0;
- return count;
+ return iov_iter_count(from);
}

static const struct file_operations severities_coverage_fops = {
.open = severities_coverage_open,
.release = seq_release,
- .read = seq_read,
- .write = severities_coverage_write,
+ .read_iter = seq_read_iter,
+ .write_iter = severities_coverage_write,
.llseek = seq_lseek,
};

diff --git a/arch/x86/kernel/cpu/resctrl/pseudo_lock.c b/arch/x86/kernel/cpu/resctrl/pseudo_lock.c
index 884b88e25141..e10f1e9513ec 100644
--- a/arch/x86/kernel/cpu/resctrl/pseudo_lock.c
+++ b/arch/x86/kernel/cpu/resctrl/pseudo_lock.c
@@ -1244,18 +1244,18 @@ static int pseudo_lock_measure_cycles(struct rdtgroup *rdtgrp, int sel)
return ret;
}

-static ssize_t pseudo_lock_measure_trigger(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
+static ssize_t pseudo_lock_measure_trigger(struct kiocb *iocb,
+ struct iov_iter *from)
{
- struct rdtgroup *rdtgrp = file->private_data;
+ struct rdtgroup *rdtgrp = iocb->ki_filp->private_data;
+ size_t count = iov_iter_count(from);
size_t buf_size;
char buf[32];
int ret;
int sel;

buf_size = min(count, (sizeof(buf) - 1));
- if (copy_from_user(buf, user_buf, buf_size))
+ if (!copy_from_iter_full(buf, buf_size, from))
return -EFAULT;

buf[buf_size] = '\0';
@@ -1263,20 +1263,20 @@ static ssize_t pseudo_lock_measure_trigger(struct file *file,
if (ret == 0) {
if (sel != 1 && sel != 2 && sel != 3)
return -EINVAL;
- ret = debugfs_file_get(file->f_path.dentry);
+ ret = debugfs_file_get(iocb->ki_filp->f_path.dentry);
if (ret)
return ret;
ret = pseudo_lock_measure_cycles(rdtgrp, sel);
if (ret == 0)
ret = count;
- debugfs_file_put(file->f_path.dentry);
+ debugfs_file_put(iocb->ki_filp->f_path.dentry);
}

return ret;
}

static const struct file_operations pseudo_measure_fops = {
- .write = pseudo_lock_measure_trigger,
+ .write_iter = pseudo_lock_measure_trigger,
.open = simple_open,
.llseek = default_llseek,
};
@@ -1570,8 +1570,6 @@ static int pseudo_lock_dev_mmap(struct file *filp, struct vm_area_struct *vma)
static const struct file_operations pseudo_lock_dev_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
- .read = NULL,
- .write = NULL,
.open = pseudo_lock_dev_open,
.release = pseudo_lock_dev_release,
.mmap = pseudo_lock_dev_mmap,
diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c
index dae436253de4..f33fc680cc7d 100644
--- a/arch/x86/kernel/cpuid.c
+++ b/arch/x86/kernel/cpuid.c
@@ -58,13 +58,12 @@ static void cpuid_smp_cpuid(void *cmd_block)
complete(&cmd->done);
}

-static ssize_t cpuid_read(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
+static ssize_t cpuid_read(struct kiocb *iocb, struct iov_iter *to)
{
- char __user *tmp = buf;
struct cpuid_regs_done cmd;
- int cpu = iminor(file_inode(file));
- u64 pos = *ppos;
+ int cpu = iminor(file_inode(iocb->ki_filp));
+ size_t count = iov_iter_count(to);
+ u64 pos = iocb->ki_pos;
ssize_t bytes = 0;
int err = 0;

@@ -84,13 +83,12 @@ static ssize_t cpuid_read(struct file *file, char __user *buf,
if (err)
break;
wait_for_completion(&cmd.done);
- if (copy_to_user(tmp, &cmd.regs, 16)) {
+ if (!copy_to_iter_full(&cmd.regs, 16, to)) {
err = -EFAULT;
break;
}
- tmp += 16;
bytes += 16;
- *ppos = ++pos;
+ iocb->ki_pos = ++pos;
reinit_completion(&cmd.done);
}

@@ -119,7 +117,7 @@ static int cpuid_open(struct inode *inode, struct file *file)
static const struct file_operations cpuid_fops = {
.owner = THIS_MODULE,
.llseek = no_seek_end_llseek,
- .read = cpuid_read,
+ .read_iter = cpuid_read,
.open = cpuid_open,
};

diff --git a/arch/x86/kernel/kdebugfs.c b/arch/x86/kernel/kdebugfs.c
index e2e89bebcbc3..4b4db90ffab2 100644
--- a/arch/x86/kernel/kdebugfs.c
+++ b/arch/x86/kernel/kdebugfs.c
@@ -26,12 +26,12 @@ struct setup_data_node {
u32 len;
};

-static ssize_t setup_data_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
+static ssize_t setup_data_read(struct kiocb *iocb, struct iov_iter *to)
{
- struct setup_data_node *node = file->private_data;
+ struct setup_data_node *node = iocb->ki_filp->private_data;
+ size_t count = iov_iter_count(to);
unsigned long remain;
- loff_t pos = *ppos;
+ loff_t pos = iocb->ki_pos;
void *p;
u64 pa;

@@ -54,20 +54,20 @@ static ssize_t setup_data_read(struct file *file, char __user *user_buf,
if (!p)
return -ENOMEM;

- remain = copy_to_user(user_buf, p, count);
+ remain = !copy_to_iter_full(p, count, to);

memunmap(p);

if (remain)
return -EFAULT;

- *ppos = pos + count;
+ iocb->ki_pos = pos + count;

return count;
}

static const struct file_operations fops_setup_data = {
- .read = setup_data_read,
+ .read_iter = setup_data_read,
.open = simple_open,
.llseek = default_llseek,
};
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c
index e17c16c54a37..80cd3d83fb75 100644
--- a/arch/x86/kernel/msr.c
+++ b/arch/x86/kernel/msr.c
@@ -49,13 +49,12 @@ enum allow_write_msrs {

static enum allow_write_msrs allow_writes = MSR_WRITES_DEFAULT;

-static ssize_t msr_read(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
+static ssize_t msr_read(struct kiocb *iocb, struct iov_iter *to)
{
- u32 __user *tmp = (u32 __user *) buf;
u32 data[2];
- u32 reg = *ppos;
- int cpu = iminor(file_inode(file));
+ u32 reg = iocb->ki_pos;
+ int cpu = iminor(file_inode(iocb->ki_filp));
+ size_t count = iov_iter_count(to);
int err = 0;
ssize_t bytes = 0;

@@ -66,11 +65,10 @@ static ssize_t msr_read(struct file *file, char __user *buf,
err = rdmsr_safe_on_cpu(cpu, reg, &data[0], &data[1]);
if (err)
break;
- if (copy_to_user(tmp, &data, 8)) {
+ if (!copy_to_iter_full(&data, 8, to)) {
err = -EFAULT;
break;
}
- tmp += 2;
bytes += 8;
}

@@ -105,13 +103,12 @@ static int filter_write(u32 reg)
return 0;
}

-static ssize_t msr_write(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
+static ssize_t msr_write(struct kiocb *iocb, struct iov_iter *from)
{
- const u32 __user *tmp = (const u32 __user *)buf;
+ size_t count = iov_iter_count(from);
u32 data[2];
- u32 reg = *ppos;
- int cpu = iminor(file_inode(file));
+ u32 reg = iocb->ki_pos;
+ int cpu = iminor(file_inode(iocb->ki_filp));
int err = 0;
ssize_t bytes = 0;

@@ -127,7 +124,7 @@ static ssize_t msr_write(struct file *file, const char __user *buf,
return -EINVAL; /* Invalid chunk size */

for (; count; count -= 8) {
- if (copy_from_user(&data, tmp, 8)) {
+ if (!copy_from_iter_full(&data, 8, from)) {
err = -EFAULT;
break;
}
@@ -138,7 +135,6 @@ static ssize_t msr_write(struct file *file, const char __user *buf,
if (err)
break;

- tmp += 2;
bytes += 8;
}

@@ -227,8 +223,8 @@ static int msr_open(struct inode *inode, struct file *file)
static const struct file_operations msr_fops = {
.owner = THIS_MODULE,
.llseek = no_seek_end_llseek,
- .read = msr_read,
- .write = msr_write,
+ .read_iter = msr_read,
+ .write_iter = msr_write,
.open = msr_open,
.unlocked_ioctl = msr_ioctl,
.compat_ioctl = msr_ioctl,
diff --git a/arch/x86/kernel/tboot.c b/arch/x86/kernel/tboot.c
index 4c1bcb6053fc..59020897c7e6 100644
--- a/arch/x86/kernel/tboot.c
+++ b/arch/x86/kernel/tboot.c
@@ -356,8 +356,9 @@ static int tboot_dying_cpu(unsigned int cpu)

static uint8_t tboot_log_uuid[16] = TBOOT_LOG_UUID;

-static ssize_t tboot_log_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos)
+static ssize_t tboot_log_read(struct kiocb *iocb, struct iov_iter *to)
{
+ size_t count = iov_iter_count(to);
void __iomem *log_base;
u8 log_uuid[16];
u32 max_size;
@@ -373,13 +374,13 @@ static ssize_t tboot_log_read(struct file *file, char __user *user_buf, size_t c
goto err_iounmap;

max_size = readl(log_base + LOG_MAX_SIZE_OFF);
- if (*ppos >= max_size) {
+ if (iocb->ki_pos >= max_size) {
ret = 0;
goto err_iounmap;
}

- if (*ppos + count > max_size)
- count = max_size - *ppos;
+ if (iocb->ki_pos + count > max_size)
+ count = max_size - iocb->ki_pos;

kbuf = kmalloc(count, GFP_KERNEL);
if (!kbuf) {
@@ -387,11 +388,11 @@ static ssize_t tboot_log_read(struct file *file, char __user *user_buf, size_t c
goto err_iounmap;
}

- memcpy_fromio(kbuf, log_base + LOG_BUF_OFF + *ppos, count);
- if (copy_to_user(user_buf, kbuf, count))
+ memcpy_fromio(kbuf, log_base + LOG_BUF_OFF + iocb->ki_pos, count);
+ if (!copy_to_iter_full(kbuf, count, to))
goto err_kfree;

- *ppos += count;
+ iocb->ki_pos += count;

ret = count;

@@ -405,7 +406,7 @@ static ssize_t tboot_log_read(struct file *file, char __user *user_buf, size_t c
}

static const struct file_operations tboot_log_fops = {
- .read = tboot_log_read,
+ .read_iter = tboot_log_read,
.llseek = default_llseek,
};

--
2.43.0