dri-devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Thomas Zimmermann <tzimmermann@suse.de>
To: maarten.lankhorst@linux.intel.com, mripard@kernel.org,
	airlied@gmail.com, daniel@ffwll.ch, javierm@redhat.com,
	deller@gmx.de, geert@linux-m68k.org, sudipm.mukherjee@gmail.com,
	teddy.wang@siliconmotion.com
Cc: linux-fbdev@vger.kernel.org,
	Geert Uytterhoeven <geert+renesas@glider.be>,
	Sui Jingfeng <suijingfeng@loongson.cn>,
	Thomas Zimmermann <tzimmermann@suse.de>,
	dri-devel@lists.freedesktop.org
Subject: [PATCH v2 14/19] fbdev: Return number of bytes read or written
Date: Fri, 28 Apr 2023 14:24:47 +0200	[thread overview]
Message-ID: <20230428122452.4856-15-tzimmermann@suse.de> (raw)
In-Reply-To: <20230428122452.4856-1-tzimmermann@suse.de>

Always return the number of bytes read or written within the
framebuffer. Only return an errno code if framebuffer memory
was not touched. This is the semantics required by POSIX and
makes fb_read() and fb_write() compatible with IGT tests. [1]

This bug has been fixed for fb_write() long ago by
commit 6a2a88668e90 ("[PATCH] fbdev: Fix return error of
fb_write"). The code in fb_read() and the corresponding fb_sys_()
helpers was forgotten.

It can happen that copy_{from, to}_user() only partially copies
the given buffer. Take this into account when calculating the
number of bytes.

v2:
	* consider return value from copy_{from,to}_user() (Geert)

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Tested-by: Sui Jingfeng <suijingfeng@loongson.cn>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Helge Deller <deller@gmx.de>
Link: https://gitlab.freedesktop.org/drm/igt-gpu-tools/-/blob/master/tests/fbdev.c # 1
---
 drivers/video/fbdev/core/fb_sys_fops.c | 24 ++++++++++++++----------
 drivers/video/fbdev/core/fbmem.c       | 15 ++++++++++-----
 2 files changed, 24 insertions(+), 15 deletions(-)

diff --git a/drivers/video/fbdev/core/fb_sys_fops.c b/drivers/video/fbdev/core/fb_sys_fops.c
index ff275d7f3eaf..cefb77b9546d 100644
--- a/drivers/video/fbdev/core/fb_sys_fops.c
+++ b/drivers/video/fbdev/core/fb_sys_fops.c
@@ -19,7 +19,8 @@ ssize_t fb_sys_read(struct fb_info *info, char __user *buf, size_t count,
 	unsigned long p = *ppos;
 	void *src;
 	int err = 0;
-	unsigned long total_size;
+	unsigned long total_size, c;
+	ssize_t ret;
 
 	if (info->state != FBINFO_STATE_RUNNING)
 		return -EPERM;
@@ -43,13 +44,14 @@ ssize_t fb_sys_read(struct fb_info *info, char __user *buf, size_t count,
 	if (info->fbops->fb_sync)
 		info->fbops->fb_sync(info);
 
-	if (copy_to_user(buf, src, count))
+	c = copy_to_user(buf, src, count);
+	if (c)
 		err = -EFAULT;
+	ret = count - c;
 
-	if  (!err)
-		*ppos += count;
+	*ppos += ret;
 
-	return (err) ? err : count;
+	return ret ? ret : err;
 }
 EXPORT_SYMBOL_GPL(fb_sys_read);
 
@@ -59,7 +61,8 @@ ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
 	unsigned long p = *ppos;
 	void *dst;
 	int err = 0;
-	unsigned long total_size;
+	unsigned long total_size, c;
+	size_t ret;
 
 	if (info->state != FBINFO_STATE_RUNNING)
 		return -EPERM;
@@ -89,13 +92,14 @@ ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
 	if (info->fbops->fb_sync)
 		info->fbops->fb_sync(info);
 
-	if (copy_from_user(dst, buf, count))
+	c = copy_from_user(dst, buf, count);
+	if (c)
 		err = -EFAULT;
+	ret = count - c;
 
-	if  (!err)
-		*ppos += count;
+	*ppos += ret;
 
-	return (err) ? err : count;
+	return ret ? ret : err;
 }
 EXPORT_SYMBOL_GPL(fb_sys_write);
 
diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c
index 3fd95a79e4c3..b0881348c27f 100644
--- a/drivers/video/fbdev/core/fbmem.c
+++ b/drivers/video/fbdev/core/fbmem.c
@@ -766,7 +766,7 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
 	u8 *buffer, *dst;
 	u8 __iomem *src;
 	int c, cnt = 0, err = 0;
-	unsigned long total_size;
+	unsigned long total_size, trailing;
 
 	if (!info || ! info->screen_base)
 		return -ENODEV;
@@ -808,10 +808,13 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
 		dst += c;
 		src += c;
 
-		if (copy_to_user(buf, buffer, c)) {
+		trailing = copy_to_user(buf, buffer, c);
+		if (trailing == c) {
 			err = -EFAULT;
 			break;
 		}
+		c -= trailing;
+
 		*ppos += c;
 		buf += c;
 		cnt += c;
@@ -820,7 +823,7 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
 
 	kfree(buffer);
 
-	return (err) ? err : cnt;
+	return cnt ? cnt : err;
 }
 
 static ssize_t
@@ -831,7 +834,7 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 	u8 *buffer, *src;
 	u8 __iomem *dst;
 	int c, cnt = 0, err = 0;
-	unsigned long total_size;
+	unsigned long total_size, trailing;
 
 	if (!info || !info->screen_base)
 		return -ENODEV;
@@ -876,10 +879,12 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 		c = (count > PAGE_SIZE) ? PAGE_SIZE : count;
 		src = buffer;
 
-		if (copy_from_user(src, buf, c)) {
+		trailing = copy_from_user(src, buf, c);
+		if (trailing == c) {
 			err = -EFAULT;
 			break;
 		}
+		c -= trailing;
 
 		fb_memcpy_tofb(dst, src, c);
 		dst += c;
-- 
2.40.0


  parent reply	other threads:[~2023-04-28 12:25 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-28 12:24 [PATCH v2 00/19] drm,fbdev: Use fbdev's I/O helpers Thomas Zimmermann
2023-04-28 12:24 ` [PATCH v2 01/19] auxdisplay/cfag12864bfb: Use struct fb_info.screen_buffer Thomas Zimmermann
2023-04-28 13:33   ` Javier Martinez Canillas
2023-04-28 12:24 ` [PATCH v2 02/19] auxdisplay/ht16k33: " Thomas Zimmermann
2023-04-28 13:34   ` Javier Martinez Canillas
2023-04-28 12:24 ` [PATCH v2 03/19] hid/hid-picolcd_fb: " Thomas Zimmermann
2023-04-28 13:34   ` Javier Martinez Canillas
2023-04-28 12:24 ` [PATCH v2 04/19] fbdev/arcfb: " Thomas Zimmermann
2023-04-28 13:35   ` Javier Martinez Canillas
2023-04-28 12:24 ` [PATCH v2 05/19] fbdev/au1200fb: " Thomas Zimmermann
2023-04-28 14:27   ` Javier Martinez Canillas
2023-04-28 12:24 ` [PATCH v2 06/19] fbdev/broadsheetfb: " Thomas Zimmermann
2023-04-28 14:31   ` Javier Martinez Canillas
2023-04-28 12:24 ` [PATCH v2 07/19] fbdev/hecubafb: " Thomas Zimmermann
2023-04-28 14:32   ` Javier Martinez Canillas
2023-04-28 12:24 ` [PATCH v2 08/19] fbdev/metronomefb: " Thomas Zimmermann
2023-04-28 14:36   ` Javier Martinez Canillas
2023-04-28 12:24 ` [PATCH v2 09/19] fbdev/ps3fb: " Thomas Zimmermann
2023-04-28 14:55   ` Javier Martinez Canillas
2023-04-28 12:24 ` [PATCH v2 10/19] fbdev/smscufx: " Thomas Zimmermann
2023-04-28 15:08   ` Javier Martinez Canillas
2023-04-28 12:24 ` [PATCH v2 11/19] fbdev/udlfb: " Thomas Zimmermann
2023-04-28 15:12   ` Javier Martinez Canillas
2023-04-28 12:24 ` [PATCH v2 12/19] fbdev/vfb: " Thomas Zimmermann
2023-04-28 15:12   ` Javier Martinez Canillas
2023-04-28 12:24 ` [PATCH v2 13/19] fbdev/xen-fbfront: " Thomas Zimmermann
2023-04-28 15:13   ` Javier Martinez Canillas
2023-04-28 12:24 ` Thomas Zimmermann [this message]
2023-04-28 12:24 ` [PATCH v2 15/19] fbdev: Use screen_buffer in fb_sys_{read,write}() Thomas Zimmermann
2023-04-28 12:24 ` [PATCH v2 16/19] fbdev: Don't re-validate info->state in fb_ops implementations Thomas Zimmermann
2023-04-28 12:24 ` [PATCH v2 17/19] fbdev: Validate info->screen_{base, buffer} " Thomas Zimmermann
2023-05-03  9:51   ` [PATCH v2 17/19] fbdev: Validate info->screen_{base,buffer} " Geert Uytterhoeven
2023-05-03 14:30     ` Thomas Zimmermann
2023-05-03 15:02       ` Geert Uytterhoeven
2023-05-03 18:21         ` Thomas Zimmermann
2023-04-28 12:24 ` [PATCH v2 18/19] fbdev: Move I/O read and write code into helper functions Thomas Zimmermann
2023-04-30 18:14   ` Sam Ravnborg
2023-05-02 16:42     ` Thomas Zimmermann
2023-04-28 12:24 ` [PATCH v2 19/19] drm/fb-helper: Use fb_{cfb,sys}_{read, write}() Thomas Zimmermann
2023-04-30 18:15   ` Sam Ravnborg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230428122452.4856-15-tzimmermann@suse.de \
    --to=tzimmermann@suse.de \
    --cc=airlied@gmail.com \
    --cc=daniel@ffwll.ch \
    --cc=deller@gmx.de \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=geert+renesas@glider.be \
    --cc=geert@linux-m68k.org \
    --cc=javierm@redhat.com \
    --cc=linux-fbdev@vger.kernel.org \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=mripard@kernel.org \
    --cc=sudipm.mukherjee@gmail.com \
    --cc=suijingfeng@loongson.cn \
    --cc=teddy.wang@siliconmotion.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox