lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20240411153126.16201-331-axboe@kernel.dk>
Date: Thu, 11 Apr 2024 09:17:50 -0600
From: Jens Axboe <axboe@...nel.dk>
To: linux-kernel@...r.kernel.org
Cc: Jens Axboe <axboe@...nel.dk>
Subject: [PATCH 330/437] x86/kernel: convert to read/write iterators

Signed-off-by: Jens Axboe <axboe@...nel.dk>
---
 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


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ