2023-03-09 16:02:42

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 000/101] fbdev: Fix memory leak in option parsing

Introduce struct option_iter and helpers to parse command-line
options with comma-separated key-value pairs. Then convert fbdev
drivers to the new interface. Fixes a memory leak in the parsing of
the video= option.

Before commit 73ce73c30ba9 ("fbdev: Transfer video= option strings to
caller; clarify ownership"), a call to fb_get_options() either
returned an internal string or a duplicated string; hence ownership of
the string's memory buffer was not well defined, but depended on how
users specified the video= option on the kernel command line. For
global settings, the caller owned the returned memory and for per-driver
settings, fb_get_options() owned the memory. As calling drivers were
unable to detect the case, they had no option but to leak the the memory.

Commit 73ce73c30ba9 ("fbdev: Transfer video= option strings to caller;
clarify ownership") changed semantics to caller-owned strings. Drivers
still leaked the memory, but at least ownership was clear.

This patchset fixes the memory leak and changes string ownership back
to fb_get_options(). Patch 1 introduces struct option_iter and a few
helpers. The interface takes an option string, such as video=, in the
common form value1,key2:value2,value3 etc and returns the individual
comma-separated pairs. Various modules use this pattern, so the code
is located under lib/.

Patches 2 to 100 go through fbdev drivers and convert them to the new
interface. This often requires a number of cleanups. A driver would
typically refer to the option string's video mode. Such strings are now
copied to driver-allocated memory so that drivers don't refer directly
to the option string's memory. The option iterator then replaces manual
parsing loops based on strsep(","). All driver-allocated memory is
released by removing the device or unloading the module.

Patch 101 finally changes the ownership of the option string to be
internal to fb_get_option(); thereby fixing the memory leak. The option
iterator holds its own copy of the string and is not affected by the
change.

Most fbdev drivers only support to parse option strings if they are
built-in. I assume that's because of the original fuzzy semantics of
fb_get_options(). A later patchset could change the driver to respect
video= settings in any configuration.

v2:
* use kstrdup()/kfree() for video strings (Geert, Timur)
* fix iterator docs (Randy)
* update iterator interface

Thomas Zimmermann (101):
lib: Add option iterator
fbdev/68328fb: Remove trailing whitespaces
fbdev/68328fb: Remove unused option string
fbdev/acornfb: Only init fb_info once
fbdev/acornfb: Parse option string with struct option_iter
fbdev/amifb: Duplicate video-mode option string
fbdev/amifb: Parse option string with struct option_iter
fbdev/arkfb: Duplicate video-mode option string
fbdev/atafb: Duplicate video-mode option string
fbdev/atafb: Parse option string with struct option_iter
fbdev/aty: Duplicate video-mode option string
fbdev/aty: Parse option string with struct option_iter
fbdev/au1100fb: Parse option string with struct option_iter
fbdev/au1200fb: Parse option string with struct option_iter
fbdev/cirrusfb: Duplicate video-mode option string
fbdev/cirrusfb: Parse option string with struct option_iter
fbdev/controlfb: Remove trailing whitespaces
fbdev/controlfb: Parse option string with struct option_iter
fbdev/cyber2000fb: Parse option string with struct option_iter
fbdev/efifb: Parse option string with struct option_iter
fbdev/fm2fb: Parse option string with struct option_iter
fbdev/fsl-diu-fb: Duplicate video-mode option string
fbdev/fsl-diu-fb: Parse option string with struct option_iter
fbdev/gbefb: Duplicate video-mode option string
fbdev/gbefb: Parse option string with struct option_iter
fbdev/geode: Duplicate video-mode option string
fbdev/geode: Parse option string with struct option_iter
fbdev/grvga: Duplicate video-mode option string
fbdev/grvga: Parse option string with struct option_iter
fbdev/gxt4500: Duplicate video-mode option string
fbdev/hyperv_fb: Duplicate video-mode option string
fbdev/i740fb: Duplicate video-mode option string
fbdev/i740fb: Parse option string with struct option_iter
fbdev/i810: Duplicate video-mode option string
fbdev/i810: Parse option string with struct option_iter
fbdev/imsttfb: Parse option string with struct option_iter
fbdev/intelfb: Duplicate video-mode option string
fbdev/intelfb: Parse option string with struct option_iter
fbdev/imxfb: Duplicate video-mode option string
fbdev/imxfb: Parse option string with struct option_iter
fbdev/kyrofb: Duplicate video-mode option string
fbdev/kyrofb: Parse option string with struct option_iter
fbdev/macfb: Remove trailing whitespaces
fbdev/macfb: Parse option string with struct option_iter
fbdev/matroxfb: Parse option string with struct option_iter
fbdev/mx3fb: Duplicate video-mode option string
fbdev/mx3fb: Parse option string with struct option_iter
fbdev/neofb: Duplicate video-mode option string
fbdev/neofb: Parse option string with struct option_iter
fbdev/nvidiafb: Duplicate video-mode option string
fbdev/nvidiafb: Parse option string with struct option_iter
fbdev/ocfb: Duplicate video-mode option string
fbdev/ocfb: Parse option string with struct option_iter
fbdev/omapfb: Parse option string with struct option_iter
fbdev/platinumfb: Remove trailing whitespaces
fbdev/platinumfb: Parse option string with struct option_iter
fbdev/pm2fb: Duplicate video-mode option string
fbdev/pm2fb: Parse option string with struct option_iter
fbdev/pm3fb: Duplicate video-mode option string
fbdev/pm3fb: Parse option string with struct option_iter
fbdev/ps3fb: Duplicate video-mode option string
fbdev/ps3fb: Parse option string with struct option_iter
fbdev/pvr2fb: Duplicate video-mode option string
fbdev/pvr2fb: Parse option string with struct option_iter
fbdev/pxafb: Parse option string with struct option_iter
fbdev/rivafb: Duplicate video-mode option string
fbdev/rivafb: Parse option string with struct option_iter
fbdev/s3fb: Duplicate video-mode option string
fbdev/s3fb: Parse option string with struct option_iter
fbdev/savagefb: Duplicate video-mode option string
fbdev/savagefb: Parse option string with struct option_iter
fbdev/sisfb: Constify mode string
fbdev/sisfb: Parse option string with struct option_iter
fbdev/skeletonfb: Parse option string with struct option_iter
fbdev/sm712fb: Duplicate video-mode option string
fbdev/sstfb: Duplicate video-mode option string
fbdev/sstfb: Parse option string with struct option_iter
fbdev/stifb: Remove trailing whitespaces
fbdev/stifb: Constify option string
fbdev/tdfxfb: Duplicate video-mode option string
fbdev/tdfxfb: Parse option string with struct option_iter
fbdev/tgafb: Duplicate video-mode option string
fbdev/tgafb: Parse option string with struct option_iter
fbdev/tmiofb: Remove unused option string
fbdev/tridentfb: Duplicate video-mode option string
fbdev/tridentfb: Parse option string with struct option_iter
fbdev/uvesafb: Duplicate video-mode option string
fbdev/uvesafb: Parse option string with struct option_iter
fbdev/valkyriefb: Remove trailing whitespaces
fbdev/valkyriefb: Parse option string with struct option_iter
fbdev/vermilion: Remove unused option string
fbdev/vesafb: Parse option string with struct option_iter
fbdev/vfb: Remove trailing whitespaces
fbdev/vfb: Duplicate video-mode option string
fbdev/vfb: Parse option string with struct option_iter
fbdev/viafb: Parse option string with struct option_iter
fbdev/vt8623fb: Duplicate video-mode option string
staging/sm750fb: Release g_settings in module-exit function
staging/sm750fb: Duplicate video-mode option string
staging/sm750fb: Parse option string with struct option_iter
fbdev: Constify option strings

Documentation/core-api/kernel-api.rst | 9 ++
drivers/staging/sm750fb/sm750.c | 63 ++++----
drivers/video/fbdev/68328fb.c | 24 +--
drivers/video/fbdev/acornfb.c | 23 ++-
drivers/video/fbdev/amifb.c | 23 +--
drivers/video/fbdev/arkfb.c | 10 +-
drivers/video/fbdev/atafb.c | 21 +--
drivers/video/fbdev/aty/aty128fb.c | 22 ++-
drivers/video/fbdev/aty/atyfb_base.c | 23 ++-
drivers/video/fbdev/aty/radeon_base.c | 26 +--
drivers/video/fbdev/au1100fb.c | 13 +-
drivers/video/fbdev/au1200fb.c | 15 +-
drivers/video/fbdev/cirrusfb.c | 30 ++--
drivers/video/fbdev/controlfb.c | 47 +++---
drivers/video/fbdev/core/fb_cmdline.c | 13 +-
drivers/video/fbdev/core/modedb.c | 8 +-
drivers/video/fbdev/cyber2000fb.c | 17 +-
drivers/video/fbdev/efifb.c | 44 ++---
drivers/video/fbdev/ep93xx-fb.c | 2 +-
drivers/video/fbdev/fm2fb.c | 14 +-
drivers/video/fbdev/fsl-diu-fb.c | 24 +--
drivers/video/fbdev/gbefb.c | 23 +--
drivers/video/fbdev/geode/gx1fb_core.c | 16 +-
drivers/video/fbdev/geode/gxfb_core.c | 23 +--
drivers/video/fbdev/geode/lxfb_core.c | 25 +--
drivers/video/fbdev/grvga.c | 18 ++-
drivers/video/fbdev/gxt4500.c | 13 +-
drivers/video/fbdev/hyperv_fb.c | 18 ++-
drivers/video/fbdev/i740fb.c | 26 +--
drivers/video/fbdev/i810/i810_main.c | 26 ++-
drivers/video/fbdev/imsttfb.c | 16 +-
drivers/video/fbdev/imxfb.c | 21 +--
drivers/video/fbdev/intelfb/intelfbdrv.c | 23 ++-
drivers/video/fbdev/kyro/fbdev.c | 21 ++-
drivers/video/fbdev/macfb.c | 26 +--
drivers/video/fbdev/matrox/matroxfb_base.c | 19 +--
drivers/video/fbdev/mx3fb.c | 23 ++-
drivers/video/fbdev/neofb.c | 26 +--
drivers/video/fbdev/nvidia/nvidia.c | 26 ++-
drivers/video/fbdev/ocfb.c | 21 ++-
drivers/video/fbdev/omap/omapfb_main.c | 15 +-
drivers/video/fbdev/platinumfb.c | 44 ++---
drivers/video/fbdev/pm2fb.c | 25 +--
drivers/video/fbdev/pm3fb.c | 27 ++--
drivers/video/fbdev/ps3fb.c | 28 ++--
drivers/video/fbdev/pvr2fb.c | 32 ++--
drivers/video/fbdev/pxafb.c | 18 ++-
drivers/video/fbdev/riva/fbdev.c | 26 ++-
drivers/video/fbdev/s3fb.c | 27 ++--
drivers/video/fbdev/savage/savagefb_driver.c | 20 ++-
drivers/video/fbdev/sis/sis_main.c | 24 +--
drivers/video/fbdev/skeletonfb.c | 17 +-
drivers/video/fbdev/sm712fb.c | 12 +-
drivers/video/fbdev/sstfb.c | 25 +--
drivers/video/fbdev/stifb.c | 162 +++++++++----------
drivers/video/fbdev/tdfxfb.c | 21 ++-
drivers/video/fbdev/tgafb.c | 30 ++--
drivers/video/fbdev/tmiofb.c | 24 +--
drivers/video/fbdev/tridentfb.c | 27 ++--
drivers/video/fbdev/uvesafb.c | 21 ++-
drivers/video/fbdev/valkyriefb.c | 30 ++--
drivers/video/fbdev/vermilion/vermilion.c | 7 +-
drivers/video/fbdev/vesafb.c | 16 +-
drivers/video/fbdev/vfb.c | 35 ++--
drivers/video/fbdev/via/viafbdev.c | 15 +-
drivers/video/fbdev/vt8623fb.c | 11 +-
include/linux/cmdline.h | 36 +++++
include/linux/fb.h | 2 +-
lib/Makefile | 2 +-
lib/cmdline_iter.c | 109 +++++++++++++
70 files changed, 1087 insertions(+), 682 deletions(-)
create mode 100644 include/linux/cmdline.h
create mode 100644 lib/cmdline_iter.c

--
2.39.2



2023-03-09 16:03:13

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 007/101] fbdev/amifb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/amifb.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/video/fbdev/amifb.c b/drivers/video/fbdev/amifb.c
index 9517aa5bd2c0..a09edc576437 100644
--- a/drivers/video/fbdev/amifb.c
+++ b/drivers/video/fbdev/amifb.c
@@ -40,6 +40,7 @@
* for more details.
*/

+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -2345,16 +2346,14 @@ static void __init amifb_setup_mcap(char *spec)
amifb_vfmax = vmax;
}

-static int __init amifb_setup(char *options, struct platform_device *pdev)
+static int __init amifb_setup(const char *options, struct platform_device *pdev)
{
+ struct option_iter iter;
char *this_opt;

- if (!options || !*options)
- return 0;
+ option_iter_init(&iter, options);

- while ((this_opt = strsep(&options, ",")) != NULL) {
- if (!*this_opt)
- continue;
+ while (option_iter_next(&iter, &this_opt)) {
if (!strcmp(this_opt, "inverse")) {
fb_invert_cmaps();
} else if (!strcmp(this_opt, "ilbm"))
@@ -2369,6 +2368,8 @@ static int __init amifb_setup(char *options, struct platform_device *pdev)
}
}

+ option_iter_release(&iter);
+
if (min_fstrt < 48)
min_fstrt = 48;

--
2.39.2


2023-03-09 16:03:16

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 005/101] fbdev/acornfb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/acornfb.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/video/fbdev/acornfb.c b/drivers/video/fbdev/acornfb.c
index 8642136a6bdc..3fed89e03554 100644
--- a/drivers/video/fbdev/acornfb.c
+++ b/drivers/video/fbdev/acornfb.c
@@ -14,6 +14,7 @@
* - Blanking 8bpp displays with VIDC
*/

+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -879,17 +880,15 @@ static struct options {
{ NULL, NULL }
};

-static int acornfb_setup(char *options)
+static int acornfb_setup(const char *options)
{
- struct options *optp;
+ struct option_iter iter;
char *opt;

- if (!options || !*options)
- return 0;
+ option_iter_init(&iter, options);

- while ((opt = strsep(&options, ",")) != NULL) {
- if (!*opt)
- continue;
+ while (option_iter_next(&iter, &opt)) {
+ struct options *optp;

for (optp = opt_table; optp->name; optp++) {
int optlen;
@@ -907,6 +906,9 @@ static int acornfb_setup(char *options)
printk(KERN_ERR "acornfb: unknown parameter: %s\n",
opt);
}
+
+ option_iter_release(&iter);
+
return 0;
}

--
2.39.2


2023-03-09 16:03:15

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 006/101] fbdev/amifb: Duplicate video-mode option string

Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with devm_kstrdup(), as the driver parses the option string
once per probed device. Linux will automatically free the memory upon
releasing the device.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/amifb.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/video/fbdev/amifb.c b/drivers/video/fbdev/amifb.c
index d88265dbebf4..9517aa5bd2c0 100644
--- a/drivers/video/fbdev/amifb.c
+++ b/drivers/video/fbdev/amifb.c
@@ -2345,7 +2345,7 @@ static void __init amifb_setup_mcap(char *spec)
amifb_vfmax = vmax;
}

-static int __init amifb_setup(char *options)
+static int __init amifb_setup(char *options, struct platform_device *pdev)
{
char *this_opt;

@@ -2363,8 +2363,10 @@ static int __init amifb_setup(char *options)
amifb_setup_mcap(this_opt + 11);
else if (!strncmp(this_opt, "fstart:", 7))
min_fstrt = simple_strtoul(this_opt + 7, NULL, 0);
- else
- mode_option = this_opt;
+ else {
+ // ignore errors
+ mode_option = devm_kstrdup(&pdev->dev, this_opt, GFP_KERNEL);
+ }
}

if (min_fstrt < 48)
@@ -3542,7 +3544,7 @@ static int __init amifb_probe(struct platform_device *pdev)
amifb_video_off();
return -ENODEV;
}
- amifb_setup(option);
+ amifb_setup(option, pdev);
#endif
custom.dmacon = DMAF_ALL | DMAF_MASTER;

--
2.39.2


2023-03-09 16:03:44

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 010/101] fbdev/atafb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

v2:
* add missing call to option_iter_init()

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/atafb.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/video/fbdev/atafb.c b/drivers/video/fbdev/atafb.c
index f0cc7c992c88..6e625ac020b5 100644
--- a/drivers/video/fbdev/atafb.c
+++ b/drivers/video/fbdev/atafb.c
@@ -47,6 +47,7 @@
#define ATAFB_EXT
#define ATAFB_FALCON

+#include <linux/cmdline.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
@@ -2934,17 +2935,15 @@ static void __init atafb_setup_user(char *spec)
}
}

-static int __init atafb_setup(char *options, struct platform_device *pdev)
+static int __init atafb_setup(const char *options, struct platform_device *pdev)
{
+ struct option_iter iter;
char *this_opt;
int temp;

- if (!options || !*options)
- return 0;
+ option_iter_init(&iter, options);

- while ((this_opt = strsep(&options, ",")) != NULL) {
- if (!*this_opt)
- continue;
+ while (option_iter_next(&iter, &this_opt)) {
if ((temp = get_video_mode(this_opt))) {
// ignore errors
mode_option = devm_kstrdup(&pdev->dev, this_opt, GFP_KERNEL);
@@ -2981,6 +2980,9 @@ static int __init atafb_setup(char *options, struct platform_device *pdev)
else if (!strncmp(this_opt, "R", 1))
atafb_setup_user(this_opt + 1);
}
+
+ option_iter_release(&iter);
+
return 0;
}

--
2.39.2


2023-03-09 16:03:46

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 009/101] fbdev/atafb: Duplicate video-mode option string

Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with devm_kstrdup(), as the driver parses the option string
once per probed device. Linux will automatically free the memory upon
releasing the device.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/atafb.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/video/fbdev/atafb.c b/drivers/video/fbdev/atafb.c
index 2bc4089865e6..f0cc7c992c88 100644
--- a/drivers/video/fbdev/atafb.c
+++ b/drivers/video/fbdev/atafb.c
@@ -2934,7 +2934,7 @@ static void __init atafb_setup_user(char *spec)
}
}

-static int __init atafb_setup(char *options)
+static int __init atafb_setup(char *options, struct platform_device *pdev)
{
char *this_opt;
int temp;
@@ -2946,8 +2946,9 @@ static int __init atafb_setup(char *options)
if (!*this_opt)
continue;
if ((temp = get_video_mode(this_opt))) {
+ // ignore errors
+ mode_option = devm_kstrdup(&pdev->dev, this_opt, GFP_KERNEL);
default_par = temp;
- mode_option = this_opt;
} else if (!strcmp(this_opt, "inverse"))
fb_invert_cmaps();
else if (!strncmp(this_opt, "hwscroll_", 9)) {
@@ -2992,7 +2993,7 @@ static int __init atafb_probe(struct platform_device *pdev)

if (fb_get_options("atafb", &option))
return -ENODEV;
- atafb_setup(option);
+ atafb_setup(option, pdev);
dev_dbg(&pdev->dev, "%s: start\n", __func__);

do {
--
2.39.2


2023-03-09 16:03:47

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 008/101] fbdev/arkfb: Duplicate video-mode option string

Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with kstrdup() and free it in the module's exit function.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

v2:
* replace static memory with kstrdup()/kfree() (Geert)

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/arkfb.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/arkfb.c b/drivers/video/fbdev/arkfb.c
index 60a96fdb5dd8..98c710cadaab 100644
--- a/drivers/video/fbdev/arkfb.c
+++ b/drivers/video/fbdev/arkfb.c
@@ -97,6 +97,7 @@ static const struct svga_timing_regs ark_timing_regs = {

/* Module parameters */

+static char *mode_option_buf;
static char *mode_option = "640x480-8@60";

MODULE_AUTHOR("(c) 2007 Ondrej Zajicek <[email protected]>");
@@ -1178,6 +1179,7 @@ static void __exit arkfb_cleanup(void)
{
pr_debug("arkfb: cleaning up\n");
pci_unregister_driver(&arkfb_pci_driver);
+ kfree(mode_option_buf);
}

/* Driver Initialisation */
@@ -1196,8 +1198,10 @@ static int __init arkfb_init(void)
if (fb_get_options("arkfb", &option))
return -ENODEV;

- if (option && *option)
- mode_option = option;
+ if (option && *option) {
+ mode_option_buf = kstrdup(option, GFP_KERNEL); // ignore errors
+ mode_option = mode_option_buf;
+ }
#endif

pr_debug("arkfb: initializing\n");
--
2.39.2


2023-03-09 16:03:47

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 011/101] fbdev/aty: Duplicate video-mode option string

Assume that the drivers do not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with kstrdup() and free it in each module's exit function.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

v2:
* replace static memory with kstrdup()/kfree() (Geert)

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/aty/aty128fb.c | 8 +++++++-
drivers/video/fbdev/aty/atyfb_base.c | 9 +++++++--
drivers/video/fbdev/aty/radeon_base.c | 9 +++++++--
3 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/drivers/video/fbdev/aty/aty128fb.c b/drivers/video/fbdev/aty/aty128fb.c
index 36a9ac05a340..0e725a6eb40b 100644
--- a/drivers/video/fbdev/aty/aty128fb.c
+++ b/drivers/video/fbdev/aty/aty128fb.c
@@ -383,6 +383,7 @@ static const struct fb_fix_screeninfo aty128fb_fix = {
.accel = FB_ACCEL_ATI_RAGE128,
};

+static char *mode_option_buf;
static char *mode_option = NULL;

#ifdef CONFIG_PPC_PMAC
@@ -1723,7 +1724,11 @@ static int aty128fb_setup(char *options)
continue;
}
#endif /* CONFIG_PPC_PMAC */
- mode_option = this_opt;
+ {
+ kfree(mode_option_buf);
+ mode_option_buf = kstrdup(this_opt, GFP_KERNEL); // ignore errors
+ mode_option = mode_option_buf;
+ }
}
return 0;
}
@@ -2518,6 +2523,7 @@ static int aty128fb_init(void)
static void __exit aty128fb_exit(void)
{
pci_unregister_driver(&aty128fb_driver);
+ kfree(mode_option_buf);
}

module_init(aty128fb_init);
diff --git a/drivers/video/fbdev/aty/atyfb_base.c b/drivers/video/fbdev/aty/atyfb_base.c
index b02e4e645035..d83b3dae795b 100644
--- a/drivers/video/fbdev/aty/atyfb_base.c
+++ b/drivers/video/fbdev/aty/atyfb_base.c
@@ -326,6 +326,7 @@ static int pll;
static int mclk;
static int xclk;
static int comp_sync = -1;
+static char *mode_buf;
static char *mode;
static int backlight = IS_BUILTIN(CONFIG_PMAC_BACKLIGHT);

@@ -3896,8 +3897,11 @@ static int __init atyfb_setup(char *options)
}
}
#endif
- else
- mode = this_opt;
+ else {
+ kfree(mode_buf);
+ mode_buf = kstrdup(this_opt, GFP_KERNEL); // ignore errors
+ mode = mode_buf;
+ }
}
return 0;
}
@@ -3995,6 +3999,7 @@ static void __exit atyfb_exit(void)
#ifdef CONFIG_PCI
pci_unregister_driver(&atyfb_driver);
#endif
+ kfree(mode_buf);
}

module_init(atyfb_init);
diff --git a/drivers/video/fbdev/aty/radeon_base.c b/drivers/video/fbdev/aty/radeon_base.c
index 657064227de8..dc2657ae96f2 100644
--- a/drivers/video/fbdev/aty/radeon_base.c
+++ b/drivers/video/fbdev/aty/radeon_base.c
@@ -257,6 +257,7 @@ static reg_val common_regs[] = {
* globals
*/

+static char *mode_option_buf;
static char *mode_option;
static char *monitor_layout;
static bool noaccel = 0;
@@ -2596,8 +2597,11 @@ static int __init radeonfb_setup (char *options)
} else if (!strncmp(this_opt, "ignore_devlist", 14)) {
ignore_devlist = 1;
#endif
- } else
- mode_option = this_opt;
+ } else {
+ kfree(mode_option_buf);
+ mode_option_buf = kstrdup(this_opt, GFP_KERNEL); // ignore errors
+ mode_option = mode_option_buf;
+ }
}
return 0;
}
@@ -2624,6 +2628,7 @@ static int __init radeonfb_init (void)
static void __exit radeonfb_exit (void)
{
pci_unregister_driver (&radeonfb_driver);
+ kfree(mode_option_buf);
}

module_init(radeonfb_init);
--
2.39.2


2023-03-09 16:04:16

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 012/101] fbdev/aty: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/aty/aty128fb.c | 12 ++++++++----
drivers/video/fbdev/aty/atyfb_base.c | 12 ++++++++----
drivers/video/fbdev/aty/radeon_base.c | 15 ++++++++-------
3 files changed, 24 insertions(+), 15 deletions(-)

diff --git a/drivers/video/fbdev/aty/aty128fb.c b/drivers/video/fbdev/aty/aty128fb.c
index 0e725a6eb40b..ee2be122de2d 100644
--- a/drivers/video/fbdev/aty/aty128fb.c
+++ b/drivers/video/fbdev/aty/aty128fb.c
@@ -48,6 +48,7 @@


#include <linux/aperture.h>
+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
@@ -1674,14 +1675,14 @@ static int aty128fb_sync(struct fb_info *info)
}

#ifndef MODULE
-static int aty128fb_setup(char *options)
+static int aty128fb_setup(const char *options)
{
+ struct option_iter iter;
char *this_opt;

- if (!options || !*options)
- return 0;
+ option_iter_init(&iter, options);

- while ((this_opt = strsep(&options, ",")) != NULL) {
+ while (option_iter_next(&iter, &this_opt)) {
if (!strncmp(this_opt, "lcd:", 4)) {
default_lcd_on = simple_strtoul(this_opt+4, NULL, 0);
continue;
@@ -1730,6 +1731,9 @@ static int aty128fb_setup(char *options)
mode_option = mode_option_buf;
}
}
+
+ option_iter_release(&iter);
+
return 0;
}
#endif /* MODULE */
diff --git a/drivers/video/fbdev/aty/atyfb_base.c b/drivers/video/fbdev/aty/atyfb_base.c
index d83b3dae795b..f4b22d2f0d3d 100644
--- a/drivers/video/fbdev/aty/atyfb_base.c
+++ b/drivers/video/fbdev/aty/atyfb_base.c
@@ -49,6 +49,7 @@
******************************************************************************/

#include <linux/aperture.h>
+#include <linux/cmdline.h>
#include <linux/compat.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
@@ -3832,14 +3833,14 @@ static struct pci_driver atyfb_driver = {
#endif /* CONFIG_PCI */

#ifndef MODULE
-static int __init atyfb_setup(char *options)
+static int __init atyfb_setup(const char *options)
{
+ struct option_iter iter;
char *this_opt;

- if (!options || !*options)
- return 0;
+ option_iter_init(&iter, options);

- while ((this_opt = strsep(&options, ",")) != NULL) {
+ while (option_iter_next(&iter, &this_opt)) {
if (!strncmp(this_opt, "noaccel", 7)) {
noaccel = true;
} else if (!strncmp(this_opt, "nomtrr", 6)) {
@@ -3903,6 +3904,9 @@ static int __init atyfb_setup(char *options)
mode = mode_buf;
}
}
+
+ option_iter_release(&iter);
+
return 0;
}
#endif /* MODULE */
diff --git a/drivers/video/fbdev/aty/radeon_base.c b/drivers/video/fbdev/aty/radeon_base.c
index dc2657ae96f2..975323e82f52 100644
--- a/drivers/video/fbdev/aty/radeon_base.c
+++ b/drivers/video/fbdev/aty/radeon_base.c
@@ -55,6 +55,7 @@
#include "radeonfb.h"

#include <linux/aperture.h>
+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
@@ -2562,17 +2563,14 @@ static struct pci_driver radeonfb_driver = {
};

#ifndef MODULE
-static int __init radeonfb_setup (char *options)
+static int __init radeonfb_setup (const char *options)
{
+ struct option_iter iter;
char *this_opt;

- if (!options || !*options)
- return 0;
-
- while ((this_opt = strsep (&options, ",")) != NULL) {
- if (!*this_opt)
- continue;
+ option_iter_init(&iter, options);

+ while (option_iter_next(&iter, &this_opt)) {
if (!strncmp(this_opt, "noaccel", 7)) {
noaccel = 1;
} else if (!strncmp(this_opt, "mirror", 6)) {
@@ -2603,6 +2601,9 @@ static int __init radeonfb_setup (char *options)
mode_option = mode_option_buf;
}
}
+
+ option_iter_release(&iter);
+
return 0;
}
#endif /* MODULE */
--
2.39.2


2023-03-09 16:04:17

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 013/101] fbdev/au1100fb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/au1100fb.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/video/fbdev/au1100fb.c b/drivers/video/fbdev/au1100fb.c
index 519313b8bb00..0c063c8e6312 100644
--- a/drivers/video/fbdev/au1100fb.c
+++ b/drivers/video/fbdev/au1100fb.c
@@ -42,6 +42,7 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/clk.h>
+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -365,7 +366,9 @@ static const struct fb_ops au1100fb_ops =

static int au1100fb_setup(struct au1100fb_device *fbdev)
{
- char *this_opt, *options;
+ char *options;
+ struct option_iter iter;
+ char *this_opt;
int num_panels = ARRAY_SIZE(known_lcd_panels);

if (num_panels <= 0) {
@@ -375,10 +378,10 @@ static int au1100fb_setup(struct au1100fb_device *fbdev)

if (fb_get_options(DRIVER_NAME, &options))
return -ENODEV;
- if (!options)
- return -ENODEV;

- while ((this_opt = strsep(&options, ",")) != NULL) {
+ option_iter_init(&iter, options);
+
+ while (option_iter_next(&iter, &this_opt)) {
/* Panel option */
if (!strncmp(this_opt, "panel:", 6)) {
int i;
@@ -401,6 +404,8 @@ static int au1100fb_setup(struct au1100fb_device *fbdev)
print_warn("Unsupported option \"%s\"", this_opt);
}

+ option_iter_release(&iter);
+
print_info("Panel=%s", fbdev->panel->name);

return 0;
--
2.39.2


2023-03-09 16:04:17

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 015/101] fbdev/cirrusfb: Duplicate video-mode option string

Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with kstrdup() and free it in the module's exit function.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

v2:
* replace static memory with kstrdup()/kfree() (Geert)

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/cirrusfb.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/video/fbdev/cirrusfb.c b/drivers/video/fbdev/cirrusfb.c
index ba45e2147c52..85b9442031b3 100644
--- a/drivers/video/fbdev/cirrusfb.c
+++ b/drivers/video/fbdev/cirrusfb.c
@@ -367,6 +367,7 @@ struct cirrusfb_info {
};

static bool noaccel;
+static char *mode_option_buf;
static char *mode_option = "640x480@60";

/****************************************************************************/
@@ -2336,10 +2337,13 @@ static int __init cirrusfb_setup(char *options)

if (!strcmp(this_opt, "noaccel"))
noaccel = 1;
- else if (!strncmp(this_opt, "mode:", 5))
- mode_option = this_opt + 5;
- else
- mode_option = this_opt;
+ else {
+ if (!strncmp(this_opt, "mode:", 5))
+ this_opt += 5;
+ kfree(mode_option_buf);
+ mode_option_buf = kstrdup(this_opt, GFP_KERNEL); // ignore errors
+ mode_option = mode_option_buf;
+ }
}
return 0;
}
@@ -2387,6 +2391,7 @@ static void __exit cirrusfb_exit(void)
#ifdef CONFIG_ZORRO
zorro_unregister_driver(&cirrusfb_zorro_driver);
#endif
+ kfree(mode_option_buf);
}

module_init(cirrusfb_init);
--
2.39.2


2023-03-09 16:04:18

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 014/101] fbdev/au1200fb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/au1200fb.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/video/fbdev/au1200fb.c b/drivers/video/fbdev/au1200fb.c
index 81c315454428..43b6a9dfeec4 100644
--- a/drivers/video/fbdev/au1200fb.c
+++ b/drivers/video/fbdev/au1200fb.c
@@ -31,6 +31,7 @@
*/

#include <linux/clk.h>
+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/kernel.h>
@@ -1578,16 +1579,17 @@ static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev)
static int au1200fb_setup(struct au1200fb_platdata *pd)
{
char *options = NULL;
- char *this_opt, *endptr;
+ struct option_iter iter;
+ char *this_opt;
+ char *endptr;
int num_panels = ARRAY_SIZE(known_lcd_panels);
int panel_idx = -1;

fb_get_options(DRIVER_NAME, &options);

- if (!options)
- goto out;
+ option_iter_init(&iter, options);

- while ((this_opt = strsep(&options, ",")) != NULL) {
+ while (option_iter_next(&iter, &this_opt)) {
/* Panel option - can be panel name,
* "bs" for board-switch, or number/index */
if (!strncmp(this_opt, "panel:", 6)) {
@@ -1636,7 +1638,8 @@ static int au1200fb_setup(struct au1200fb_platdata *pd)
print_warn("Unsupported option \"%s\"", this_opt);
}

-out:
+ option_iter_release(&iter);
+
return 0;
}

--
2.39.2


2023-03-09 16:04:19

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 017/101] fbdev/controlfb: Remove trailing whitespaces

Fix coding style. No functional changes.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/controlfb.c | 34 ++++++++++++++++-----------------
1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/drivers/video/fbdev/controlfb.c b/drivers/video/fbdev/controlfb.c
index 77dbf94aae5f..82eeb139c4eb 100644
--- a/drivers/video/fbdev/controlfb.c
+++ b/drivers/video/fbdev/controlfb.c
@@ -113,14 +113,14 @@ struct fb_info_control {
struct fb_info info;
struct fb_par_control par;
u32 pseudo_palette[16];
-
+
struct cmap_regs __iomem *cmap_regs;
unsigned long cmap_regs_phys;
-
+
struct control_regs __iomem *control_regs;
unsigned long control_regs_phys;
unsigned long control_regs_size;
-
+
__u8 __iomem *frame_buffer;
unsigned long frame_buffer_phys;
unsigned long fb_orig_base;
@@ -196,7 +196,7 @@ static void set_control_clock(unsigned char *params)
while (!req.complete)
cuda_poll();
}
-#endif
+#endif
}

/*
@@ -233,19 +233,19 @@ static void control_set_hardware(struct fb_info_control *p, struct fb_par_contro
if (p->par.xoffset != par->xoffset ||
p->par.yoffset != par->yoffset)
set_screen_start(par->xoffset, par->yoffset, p);
-
+
return;
}
-
+
p->par = *par;
cmode = p->par.cmode;
r = &par->regvals;
-
+
/* Turn off display */
out_le32(CNTRL_REG(p,ctrl), 0x400 | par->ctrl);
-
+
set_control_clock(r->clock_params);
-
+
RADACAL_WRITE(0x20, r->radacal_ctrl);
RADACAL_WRITE(0x21, p->control_use_bank2 ? 0 : 1);
RADACAL_WRITE(0x10, 0);
@@ -254,7 +254,7 @@ static void control_set_hardware(struct fb_info_control *p, struct fb_par_contro
rp = &p->control_regs->vswin;
for (i = 0; i < 16; ++i, ++rp)
out_le32(&rp->r, r->regs[i]);
-
+
out_le32(CNTRL_REG(p,pitch), par->pitch);
out_le32(CNTRL_REG(p,mode), r->mode);
out_le32(CNTRL_REG(p,vram_attr), p->vram_attr);
@@ -366,7 +366,7 @@ static int read_control_sense(struct fb_info_control *p)
sense |= (in_le32(CNTRL_REG(p,mon_sense)) & 0x180) >> 7;

out_le32(CNTRL_REG(p,mon_sense), 077); /* turn off drivers */
-
+
return sense;
}

@@ -558,9 +558,9 @@ static int control_var_to_par(struct fb_var_screeninfo *var,
static void control_par_to_var(struct fb_par_control *par, struct fb_var_screeninfo *var)
{
struct control_regints *rv;
-
+
rv = (struct control_regints *) par->regvals.regs;
-
+
memset(var, 0, sizeof(*var));
var->xres = par->xres;
var->yres = par->yres;
@@ -568,7 +568,7 @@ static void control_par_to_var(struct fb_par_control *par, struct fb_var_screeni
var->yres_virtual = par->vyres;
var->xoffset = par->xoffset;
var->yoffset = par->yoffset;
-
+
switch(par->cmode) {
default:
case CMODE_8:
@@ -634,7 +634,7 @@ static int controlfb_check_var (struct fb_var_screeninfo *var, struct fb_info *i

err = control_var_to_par(var, &par, info);
if (err)
- return err;
+ return err;
control_par_to_var(&par, var);

return 0;
@@ -655,7 +655,7 @@ static int controlfb_set_par (struct fb_info *info)
" control_var_to_par: %d.\n", err);
return err;
}
-
+
control_set_hardware(p, &par);

info->fix.visual = (p->par.cmode == CMODE_8) ?
@@ -840,7 +840,7 @@ static int __init init_control(struct fb_info_control *p)
int full, sense, vmode, cmode, vyres;
struct fb_var_screeninfo var;
int rc;
-
+
printk(KERN_INFO "controlfb: ");

full = p->total_vram == 0x400000;
--
2.39.2


2023-03-09 16:04:20

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 016/101] fbdev/cirrusfb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/cirrusfb.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/video/fbdev/cirrusfb.c b/drivers/video/fbdev/cirrusfb.c
index 85b9442031b3..a5e99a8feadd 100644
--- a/drivers/video/fbdev/cirrusfb.c
+++ b/drivers/video/fbdev/cirrusfb.c
@@ -35,6 +35,7 @@
*/

#include <linux/aperture.h>
+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -2324,17 +2325,14 @@ static struct zorro_driver cirrusfb_zorro_driver = {
#endif /* CONFIG_ZORRO */

#ifndef MODULE
-static int __init cirrusfb_setup(char *options)
+static int __init cirrusfb_setup(const char *options)
{
+ struct option_iter iter;
char *this_opt;

- if (!options || !*options)
- return 0;
-
- while ((this_opt = strsep(&options, ",")) != NULL) {
- if (!*this_opt)
- continue;
+ option_iter_init(&iter, options);

+ while (option_iter_next(&iter, &this_opt)) {
if (!strcmp(this_opt, "noaccel"))
noaccel = 1;
else {
@@ -2345,6 +2343,9 @@ static int __init cirrusfb_setup(char *options)
mode_option = mode_option_buf;
}
}
+
+ option_iter_release(&iter);
+
return 0;
}
#endif
--
2.39.2


2023-03-09 16:04:21

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 019/101] fbdev/cyber2000fb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/cyber2000fb.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/video/fbdev/cyber2000fb.c b/drivers/video/fbdev/cyber2000fb.c
index 38c0a6866d76..f21d11a73455 100644
--- a/drivers/video/fbdev/cyber2000fb.c
+++ b/drivers/video/fbdev/cyber2000fb.c
@@ -34,6 +34,7 @@
* entering standby mode.)
*/
#include <linux/aperture.h>
+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -1486,17 +1487,14 @@ static void cyberpro_free_fb_info(struct cfb_info *cfb)
* video=cyber2000:font:fontname
*/
#ifndef MODULE
-static int cyber2000fb_setup(char *options)
+static int cyber2000fb_setup(const char *options)
{
+ struct option_iter iter;
char *opt;

- if (!options || !*options)
- return 0;
-
- while ((opt = strsep(&options, ",")) != NULL) {
- if (!*opt)
- continue;
+ option_iter_init(&iter, options);

+ while (option_iter_next(&iter, &opt)) {
if (strncmp(opt, "font:", 5) == 0) {
static char default_font_storage[40];

@@ -1508,6 +1506,9 @@ static int cyber2000fb_setup(char *options)

printk(KERN_ERR "CyberPro20x0: unknown parameter: %s\n", opt);
}
+
+ option_iter_release(&iter);
+
return 0;
}
#endif /* MODULE */
--
2.39.2


2023-03-09 16:04:23

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 018/101] fbdev/controlfb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/controlfb.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/video/fbdev/controlfb.c b/drivers/video/fbdev/controlfb.c
index 82eeb139c4eb..65e2f9949420 100644
--- a/drivers/video/fbdev/controlfb.c
+++ b/drivers/video/fbdev/controlfb.c
@@ -31,6 +31,7 @@
* more details.
*/

+#include <linux/cmdline.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
@@ -795,14 +796,14 @@ static void __init control_init_info(struct fb_info *info, struct fb_info_contro
/*
* Parse user specified options (`video=controlfb:')
*/
-static void __init control_setup(char *options)
+static void __init control_setup(const char *options)
{
+ struct option_iter iter;
char *this_opt;

- if (!options || !*options)
- return;
+ option_iter_init(&iter, options);

- while ((this_opt = strsep(&options, ",")) != NULL) {
+ while (option_iter_next(&iter, &this_opt)) {
if (!strncmp(this_opt, "vmode:", 6)) {
int vmode = simple_strtoul(this_opt+6, NULL, 0);
if (vmode > 0 && vmode <= VMODE_MAX &&
@@ -830,6 +831,8 @@ static void __init control_setup(char *options)
}
}
}
+
+ option_iter_release(&iter);
}

/*
--
2.39.2


2023-03-09 16:04:31

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 025/101] fbdev/gbefb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/gbefb.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/video/fbdev/gbefb.c b/drivers/video/fbdev/gbefb.c
index 6afccd4ef0a8..d20ef48263f3 100644
--- a/drivers/video/fbdev/gbefb.c
+++ b/drivers/video/fbdev/gbefb.c
@@ -9,6 +9,7 @@
* more details.
*/

+#include <linux/cmdline.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
@@ -1083,14 +1084,14 @@ ATTRIBUTE_GROUPS(gbefb);
* Initialization
*/

-static int gbefb_setup(char *options, struct device *dev)
+static int gbefb_setup(const char *options, struct device *dev)
{
+ struct option_iter iter;
char *this_opt;

- if (!options || !*options)
- return 0;
+ option_iter_init(&iter, options);

- while ((this_opt = strsep(&options, ",")) != NULL) {
+ while (option_iter_next(&iter, &this_opt)) {
if (!strncmp(this_opt, "monitor:", 8)) {
if (!strncmp(this_opt + 8, "crt", 3)) {
flat_panel_enabled = 0;
@@ -1103,7 +1104,7 @@ static int gbefb_setup(char *options, struct device *dev)
default_mode = &default_mode_LCD;
}
} else if (!strncmp(this_opt, "mem:", 4)) {
- gbe_mem_size = memparse(this_opt + 4, &this_opt);
+ gbe_mem_size = memparse(this_opt + 4, NULL);
if (gbe_mem_size > CONFIG_FB_GBE_MEM * 1024 * 1024)
gbe_mem_size = CONFIG_FB_GBE_MEM * 1024 * 1024;
if (gbe_mem_size < TILE_SIZE)
@@ -1112,6 +1113,9 @@ static int gbefb_setup(char *options, struct device *dev)
mode_option = devm_kstrdup(dev, this_opt, GFP_KERNEL); // ignore errors
}
}
+
+ option_iter_release(&iter);
+
return 0;
}

--
2.39.2


2023-03-09 16:04:36

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 024/101] fbdev/gbefb: Duplicate video-mode option string

Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with devm_kstrdup(), as the driver parses the option string
once per probed device. Linux will automatically free the memory upon
releasing the device.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/gbefb.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/video/fbdev/gbefb.c b/drivers/video/fbdev/gbefb.c
index 000b4aa44241..6afccd4ef0a8 100644
--- a/drivers/video/fbdev/gbefb.c
+++ b/drivers/video/fbdev/gbefb.c
@@ -1083,7 +1083,7 @@ ATTRIBUTE_GROUPS(gbefb);
* Initialization
*/

-static int gbefb_setup(char *options)
+static int gbefb_setup(char *options, struct device *dev)
{
char *this_opt;

@@ -1108,8 +1108,9 @@ static int gbefb_setup(char *options)
gbe_mem_size = CONFIG_FB_GBE_MEM * 1024 * 1024;
if (gbe_mem_size < TILE_SIZE)
gbe_mem_size = TILE_SIZE;
- } else
- mode_option = this_opt;
+ } else {
+ mode_option = devm_kstrdup(dev, this_opt, GFP_KERNEL); // ignore errors
+ }
}
return 0;
}
@@ -1132,7 +1133,7 @@ static int gbefb_probe(struct platform_device *p_dev)
ret = -ENODEV;
goto out_release_framebuffer;
}
- gbefb_setup(options);
+ gbefb_setup(options, &p_dev->dev);
#endif

if (!request_mem_region(GBE_BASE, sizeof(struct sgi_gbe), "GBE")) {
--
2.39.2


2023-03-09 16:04:43

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 023/101] fbdev/fsl-diu-fb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/fsl-diu-fb.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/video/fbdev/fsl-diu-fb.c b/drivers/video/fbdev/fsl-diu-fb.c
index 033bbf0c40b7..78996995568c 100644
--- a/drivers/video/fbdev/fsl-diu-fb.c
+++ b/drivers/video/fbdev/fsl-diu-fb.c
@@ -12,6 +12,7 @@
* Based on imxfb.c Copyright (C) 2004 S.Hauer, Pengutronix
*/

+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -1843,17 +1844,15 @@ static int fsl_diu_remove(struct platform_device *pdev)
}

#ifndef MODULE
-static int __init fsl_diu_setup(char *options)
+static int __init fsl_diu_setup(const char *options)
{
+ struct option_iter iter;
char *opt;
unsigned long val;

- if (!options || !*options)
- return 0;
+ option_iter_init(&iter, options);

- while ((opt = strsep(&options, ",")) != NULL) {
- if (!*opt)
- continue;
+ while (option_iter_next(&iter, &opt)) {
if (!strncmp(opt, "monitor=", 8)) {
monitor_port = fsl_diu_name_to_port(opt + 8);
} else if (!strncmp(opt, "bpp=", 4)) {
@@ -1866,6 +1865,8 @@ static int __init fsl_diu_setup(char *options)
}
}

+ option_iter_release(&iter);
+
return 0;
}
#endif
--
2.39.2


2023-03-09 16:05:26

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 022/101] fbdev/fsl-diu-fb: Duplicate video-mode option string

Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with kstrdup() and free it in the module's exit function.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

v2:
* replace static memory with kstrdup()/kfree() (Geert, Timur)

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/fsl-diu-fb.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/fsl-diu-fb.c b/drivers/video/fbdev/fsl-diu-fb.c
index e332017c6af6..033bbf0c40b7 100644
--- a/drivers/video/fbdev/fsl-diu-fb.c
+++ b/drivers/video/fbdev/fsl-diu-fb.c
@@ -307,6 +307,7 @@ static struct fb_videomode fsl_diu_mode_db[] = {
},
};

+static char *fb_mode_buf;
static char *fb_mode;
static unsigned long default_bpp = 32;
static enum fsl_diu_monitor_port monitor_port;
@@ -1858,8 +1859,11 @@ static int __init fsl_diu_setup(char *options)
} else if (!strncmp(opt, "bpp=", 4)) {
if (!kstrtoul(opt + 4, 10, &val))
default_bpp = val;
- } else
- fb_mode = opt;
+ } else {
+ kfree(fb_mode_buf);
+ fb_mode_buf = kstrdup(opt, GFP_KERNEL); // ignore errors
+ fb_mode = fb_mode_buf;
+ }
}

return 0;
@@ -1978,6 +1982,7 @@ static void __exit fsl_diu_exit(void)
#if defined(CONFIG_NOT_COHERENT_CACHE)
vfree(coherence_data);
#endif
+ kfree(fb_mode_buf);
}

module_init(fsl_diu_init);
--
2.39.2


2023-03-09 16:05:26

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 020/101] fbdev/efifb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/efifb.c | 42 +++++++++++++++++++------------------
1 file changed, 22 insertions(+), 20 deletions(-)

diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c
index a5779fb453a2..be77a76f7d1d 100644
--- a/drivers/video/fbdev/efifb.c
+++ b/drivers/video/fbdev/efifb.c
@@ -8,6 +8,7 @@
*/

#include <linux/aperture.h>
+#include <linux/cmdline.h>
#include <linux/kernel.h>
#include <linux/efi.h>
#include <linux/efi-bgrt.h>
@@ -284,31 +285,32 @@ static const struct fb_ops efifb_ops = {
.fb_imageblit = cfb_imageblit,
};

-static int efifb_setup(char *options)
+static int efifb_setup(const char *options)
{
+ struct option_iter iter;
char *this_opt;

- if (options && *options) {
- while ((this_opt = strsep(&options, ",")) != NULL) {
- if (!*this_opt) continue;
-
- efifb_setup_from_dmi(&screen_info, this_opt);
-
- if (!strncmp(this_opt, "base:", 5))
- screen_info.lfb_base = simple_strtoul(this_opt+5, NULL, 0);
- else if (!strncmp(this_opt, "stride:", 7))
- screen_info.lfb_linelength = simple_strtoul(this_opt+7, NULL, 0) * 4;
- else if (!strncmp(this_opt, "height:", 7))
- screen_info.lfb_height = simple_strtoul(this_opt+7, NULL, 0);
- else if (!strncmp(this_opt, "width:", 6))
- screen_info.lfb_width = simple_strtoul(this_opt+6, NULL, 0);
- else if (!strcmp(this_opt, "nowc"))
- mem_flags &= ~EFI_MEMORY_WC;
- else if (!strcmp(this_opt, "nobgrt"))
- use_bgrt = false;
- }
+ option_iter_init(&iter, options);
+
+ while (option_iter_next(&iter, &this_opt)) {
+ efifb_setup_from_dmi(&screen_info, this_opt);
+
+ if (!strncmp(this_opt, "base:", 5))
+ screen_info.lfb_base = simple_strtoul(this_opt+5, NULL, 0);
+ else if (!strncmp(this_opt, "stride:", 7))
+ screen_info.lfb_linelength = simple_strtoul(this_opt+7, NULL, 0) * 4;
+ else if (!strncmp(this_opt, "height:", 7))
+ screen_info.lfb_height = simple_strtoul(this_opt+7, NULL, 0);
+ else if (!strncmp(this_opt, "width:", 6))
+ screen_info.lfb_width = simple_strtoul(this_opt+6, NULL, 0);
+ else if (!strcmp(this_opt, "nowc"))
+ mem_flags &= ~EFI_MEMORY_WC;
+ else if (!strcmp(this_opt, "nobgrt"))
+ use_bgrt = false;
}

+ option_iter_release(&iter);
+
return 0;
}

--
2.39.2


2023-03-09 16:05:27

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 021/101] fbdev/fm2fb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/fm2fb.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/video/fbdev/fm2fb.c b/drivers/video/fbdev/fm2fb.c
index 942e382cf1cf..a787884a6a7f 100644
--- a/drivers/video/fbdev/fm2fb.c
+++ b/drivers/video/fbdev/fm2fb.c
@@ -14,6 +14,7 @@
* more details.
*/

+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/fb.h>
@@ -293,19 +294,22 @@ static int fm2fb_probe(struct zorro_dev *z, const struct zorro_device_id *id)
return 0;
}

-static int __init fm2fb_setup(char *options)
+static int __init fm2fb_setup(const char *options)
{
+ struct option_iter iter;
char *this_opt;

- if (!options || !*options)
- return 0;
+ option_iter_init(&iter, options);

- while ((this_opt = strsep(&options, ",")) != NULL) {
+ while (option_iter_next(&iter, &this_opt)) {
if (!strncmp(this_opt, "pal", 3))
fm2fb_mode = FM2FB_MODE_PAL;
else if (!strncmp(this_opt, "ntsc", 4))
fm2fb_mode = FM2FB_MODE_NTSC;
}
+
+ option_iter_release(&iter);
+
return 0;
}

--
2.39.2


2023-03-09 16:05:27

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 026/101] fbdev/geode: Duplicate video-mode option string

Assume that the drivers do not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with kstrdup() and free it in each module's exit function.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

v2:
* replace static memory with kstrdup()/kfree() (Geert)

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/geode/gxfb_core.c | 6 +++++-
drivers/video/fbdev/geode/lxfb_core.c | 9 +++++++--
2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/video/fbdev/geode/gxfb_core.c b/drivers/video/fbdev/geode/gxfb_core.c
index 8e05e76de075..491de0ac5876 100644
--- a/drivers/video/fbdev/geode/gxfb_core.c
+++ b/drivers/video/fbdev/geode/gxfb_core.c
@@ -33,6 +33,7 @@

#include "gxfb.h"

+static char *mode_option_buf;
static char *mode_option;
static int vram;
static int vt_switch;
@@ -500,7 +501,9 @@ static int __init gxfb_setup(char *options)
if (!*opt)
continue;

- mode_option = opt;
+ kfree(mode_option_buf);
+ mode_option_buf = kstrdup(opt, GFP_KERNEL); // ignore errors
+ mode_option = mode_option_buf;
}

return 0;
@@ -528,6 +531,7 @@ static int __init gxfb_init(void)
static void __exit gxfb_cleanup(void)
{
pci_unregister_driver(&gxfb_driver);
+ kfree(mode_option_buf);
}

module_init(gxfb_init);
diff --git a/drivers/video/fbdev/geode/lxfb_core.c b/drivers/video/fbdev/geode/lxfb_core.c
index 8130e9eee2b4..6863ee858d8d 100644
--- a/drivers/video/fbdev/geode/lxfb_core.c
+++ b/drivers/video/fbdev/geode/lxfb_core.c
@@ -24,6 +24,7 @@

#include "lxfb.h"

+static char *mode_option_buf;
static char *mode_option;
static int noclear, nopanel, nocrt;
static int vram;
@@ -635,8 +636,11 @@ static int __init lxfb_setup(char *options)
nopanel = 1;
else if (!strcmp(opt, "nocrt"))
nocrt = 1;
- else
- mode_option = opt;
+ else {
+ kfree(mode_option_buf);
+ mode_option_buf = kstrdup(opt, GFP_KERNEL); // ignore errors
+ mode_option = mode_option_buf;
+ }
}

return 0;
@@ -663,6 +667,7 @@ static int __init lxfb_init(void)
static void __exit lxfb_cleanup(void)
{
pci_unregister_driver(&lxfb_driver);
+ kfree(mode_option_buf);
}

module_init(lxfb_init);
--
2.39.2


2023-03-09 16:05:28

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 027/101] fbdev/geode: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

v2:
* add missing call to option_iter_release()

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/geode/gx1fb_core.c | 14 +++++++-------
drivers/video/fbdev/geode/gxfb_core.c | 15 +++++++--------
drivers/video/fbdev/geode/lxfb_core.c | 14 +++++++-------
3 files changed, 21 insertions(+), 22 deletions(-)

diff --git a/drivers/video/fbdev/geode/gx1fb_core.c b/drivers/video/fbdev/geode/gx1fb_core.c
index 9c942001ac10..6f1e9aadc192 100644
--- a/drivers/video/fbdev/geode/gx1fb_core.c
+++ b/drivers/video/fbdev/geode/gx1fb_core.c
@@ -7,6 +7,7 @@
*/

#include <linux/aperture.h>
+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -403,17 +404,14 @@ static void gx1fb_remove(struct pci_dev *pdev)
}

#ifndef MODULE
-static void __init gx1fb_setup(char *options)
+static void __init gx1fb_setup(const char *options)
{
+ struct option_iter iter;
char *this_opt;

- if (!options || !*options)
- return;
-
- while ((this_opt = strsep(&options, ","))) {
- if (!*this_opt)
- continue;
+ option_iter_init(&iter, options);

+ while (option_iter_next(&iter, &this_opt)) {
if (!strncmp(this_opt, "mode:", 5))
strscpy(mode_option, this_opt + 5, sizeof(mode_option));
else if (!strncmp(this_opt, "crt:", 4))
@@ -423,6 +421,8 @@ static void __init gx1fb_setup(char *options)
else
strscpy(mode_option, this_opt, sizeof(mode_option));
}
+
+ option_iter_release(&iter);
}
#endif

diff --git a/drivers/video/fbdev/geode/gxfb_core.c b/drivers/video/fbdev/geode/gxfb_core.c
index 491de0ac5876..aede22566775 100644
--- a/drivers/video/fbdev/geode/gxfb_core.c
+++ b/drivers/video/fbdev/geode/gxfb_core.c
@@ -16,6 +16,7 @@
* 16 MiB of framebuffer memory is assumed to be available.
*/
#include <linux/aperture.h>
+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -489,23 +490,21 @@ static struct pci_driver gxfb_driver = {
};

#ifndef MODULE
-static int __init gxfb_setup(char *options)
+static int __init gxfb_setup(const char *options)
{
-
+ struct option_iter iter;
char *opt;

- if (!options || !*options)
- return 0;
-
- while ((opt = strsep(&options, ",")) != NULL) {
- if (!*opt)
- continue;
+ option_iter_init(&iter, options);

+ while (option_iter_next(&iter, &opt)) {
kfree(mode_option_buf);
mode_option_buf = kstrdup(opt, GFP_KERNEL); // ignore errors
mode_option = mode_option_buf;
}

+ option_iter_release(&iter);
+
return 0;
}
#endif
diff --git a/drivers/video/fbdev/geode/lxfb_core.c b/drivers/video/fbdev/geode/lxfb_core.c
index 6863ee858d8d..855dc96b5669 100644
--- a/drivers/video/fbdev/geode/lxfb_core.c
+++ b/drivers/video/fbdev/geode/lxfb_core.c
@@ -7,6 +7,7 @@
*/

#include <linux/aperture.h>
+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -619,17 +620,14 @@ static struct pci_driver lxfb_driver = {
};

#ifndef MODULE
-static int __init lxfb_setup(char *options)
+static int __init lxfb_setup(const char *options)
{
+ struct option_iter iter;
char *opt;

- if (!options || !*options)
- return 0;
-
- while ((opt = strsep(&options, ",")) != NULL) {
- if (!*opt)
- continue;
+ option_iter_init(&iter, options);

+ while (option_iter_next(&iter, &opt)) {
if (!strcmp(opt, "noclear"))
noclear = 1;
else if (!strcmp(opt, "nopanel"))
@@ -643,6 +641,8 @@ static int __init lxfb_setup(char *options)
}
}

+ option_iter_release(&iter);
+
return 0;
}
#endif
--
2.39.2


2023-03-09 16:05:28

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 028/101] fbdev/grvga: Duplicate video-mode option string

Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with devm_kstrdup(), as the driver parses the option string
once per probed device. Linux will automatically free the memory upon
releasing the device.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/grvga.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/grvga.c b/drivers/video/fbdev/grvga.c
index 24818b276241..28c2e0e0763a 100644
--- a/drivers/video/fbdev/grvga.c
+++ b/drivers/video/fbdev/grvga.c
@@ -370,7 +370,7 @@ static int grvga_probe(struct platform_device *dev)
else if (!strncmp(this_opt, "size", 4))
grvga_mem_size = simple_strtoul(this_opt + 5, NULL, 0);
else
- mode_opt = this_opt;
+ mode_opt = devm_kstrdup(&dev->dev, opt, GFP_KERNEL); // ignore errors
}

par = info->par;
--
2.39.2


2023-03-09 16:05:29

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 029/101] fbdev/grvga: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/grvga.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/video/fbdev/grvga.c b/drivers/video/fbdev/grvga.c
index 28c2e0e0763a..742331d0f08b 100644
--- a/drivers/video/fbdev/grvga.c
+++ b/drivers/video/fbdev/grvga.c
@@ -10,6 +10,7 @@
* Contributors: Kristoffer Glembo <[email protected]>
*/

+#include <linux/cmdline.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/of_platform.h>
@@ -334,6 +335,8 @@ static int grvga_probe(struct platform_device *dev)
unsigned long grvga_mem_size = 0;
struct grvga_par *par = NULL;
char *options = NULL, *mode_opt = NULL;
+ struct option_iter iter;
+ char *this_opt;

info = framebuffer_alloc(sizeof(struct grvga_par), &dev->dev);
if (!info)
@@ -353,15 +356,13 @@ static int grvga_probe(struct platform_device *dev)
if (!options || !*options)
options = "640x480-8@60";

- while (1) {
- char *this_opt = strsep(&options, ",");
-
- if (!this_opt)
- break;
+ option_iter_init(&iter, options);

+ while (option_iter_next(&iter, &this_opt)) {
if (!strncmp(this_opt, "custom", 6)) {
if (grvga_parse_custom(this_opt, &info->var) < 0) {
dev_err(&dev->dev, "Failed to parse custom mode (%s).\n", this_opt);
+ option_iter_release(&iter);
retval = -EINVAL;
goto free_fb;
}
@@ -373,6 +374,8 @@ static int grvga_probe(struct platform_device *dev)
mode_opt = devm_kstrdup(&dev->dev, opt, GFP_KERNEL); // ignore errors
}

+ option_iter_release(&iter);
+
par = info->par;
info->fbops = &grvga_ops;
info->fix = grvga_fix;
--
2.39.2


2023-03-09 16:05:29

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 033/101] fbdev/i740fb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/i740fb.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/video/fbdev/i740fb.c b/drivers/video/fbdev/i740fb.c
index 61c022b8d5de..6da2f3b7846d 100644
--- a/drivers/video/fbdev/i740fb.c
+++ b/drivers/video/fbdev/i740fb.c
@@ -13,6 +13,7 @@
*/

#include <linux/aperture.h>
+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -1262,17 +1263,15 @@ static struct pci_driver i740fb_driver = {
};

#ifndef MODULE
-static int __init i740fb_setup(char *options)
+static int __init i740fb_setup(const char *options)
{
+ struct option_iter iter;
char *opt;

- if (!options || !*options)
- return 0;
+ option_iter_init(&iter, options);

- while ((opt = strsep(&options, ",")) != NULL) {
- if (!*opt)
- continue;
- else if (!strncmp(opt, "mtrr:", 5))
+ while (option_iter_next(&iter, &opt)) {
+ if (!strncmp(opt, "mtrr:", 5))
mtrr = simple_strtoul(opt + 5, NULL, 0);
else {
kfree(mode_option_buf);
@@ -1281,6 +1280,8 @@ static int __init i740fb_setup(char *options)
}
}

+ option_iter_release(&iter);
+
return 0;
}
#endif
--
2.39.2


2023-03-09 16:05:29

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 030/101] fbdev/gxt4500: Duplicate video-mode option string

Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with kstrdup() and free it in the module's exit function.

Done in preparation of constifying the option string.

v2:
* replace static memory with kstrdup()/kfree() (Geert)

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/gxt4500.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/gxt4500.c b/drivers/video/fbdev/gxt4500.c
index 5f42d3d9d6ce..65cb44c281c1 100644
--- a/drivers/video/fbdev/gxt4500.c
+++ b/drivers/video/fbdev/gxt4500.c
@@ -158,6 +158,7 @@ struct gxt4500_par {
};

/* mode requested by user */
+static char *mode_option_buf;
static char *mode_option;

/* default mode: 1280x1024 @ 60 Hz, 8 bpp */
@@ -779,12 +780,21 @@ static struct pci_driver gxt4500_driver = {

static int gxt4500_init(void)
{
+#ifndef MODULE
+ char *options;
+#endif
+
if (fb_modesetting_disabled("gxt4500"))
return -ENODEV;

#ifndef MODULE
- if (fb_get_options("gxt4500", &mode_option))
+ if (fb_get_options("gxt4500", &options))
return -ENODEV;
+
+ if (options && *options) {
+ mode_option_buf = kstrdup(options, GFP_KERNEL); // ignore errors
+ mode_option = mode_option_buf;
+ }
#endif

return pci_register_driver(&gxt4500_driver);
@@ -794,6 +804,7 @@ module_init(gxt4500_init);
static void __exit gxt4500_exit(void)
{
pci_unregister_driver(&gxt4500_driver);
+ kfree(mode_option_buf);
}
module_exit(gxt4500_exit);

--
2.39.2


2023-03-09 16:05:32

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 031/101] fbdev/hyperv_fb: Duplicate video-mode option string

Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. As the driver
implements a very simple mode parser in a fairly unstructured way, just
duplicate the option string and parse the duplicated memory buffer. Free
the buffer afterwards.

Done in preparation of constifying the option string and switching the
driver to struct option_iter.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/hyperv_fb.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
index 4a6a3303b6b4..edb0555239c6 100644
--- a/drivers/video/fbdev/hyperv_fb.c
+++ b/drivers/video/fbdev/hyperv_fb.c
@@ -903,17 +903,23 @@ static const struct fb_ops hvfb_ops = {
static void hvfb_get_option(struct fb_info *info)
{
struct hvfb_par *par = info->par;
- char *opt = NULL, *p;
+ char *options = NULL;
+ char *optbuf, *opt, *p;
uint x = 0, y = 0;

- if (fb_get_options(KBUILD_MODNAME, &opt) || !opt || !*opt)
+ if (fb_get_options(KBUILD_MODNAME, &options) || !options || !*options)
return;

+ optbuf = kstrdup(options, GFP_KERNEL);
+ if (!optbuf)
+ return;
+ opt = optbuf;
+
p = strsep(&opt, "x");
if (!*p || kstrtouint(p, 0, &x) ||
!opt || !*opt || kstrtouint(opt, 0, &y)) {
pr_err("Screen option is invalid: skipped\n");
- return;
+ goto out;
}

if (x < HVFB_WIDTH_MIN || y < HVFB_HEIGHT_MIN ||
@@ -922,12 +928,14 @@ static void hvfb_get_option(struct fb_info *info)
(par->synthvid_version == SYNTHVID_VERSION_WIN8 &&
x * y * screen_depth / 8 > SYNTHVID_FB_SIZE_WIN8)) {
pr_err("Screen resolution option is out of range: skipped\n");
- return;
+ goto out;
}

screen_width = x;
screen_height = y;
- return;
+
+out:
+ kfree(optbuf);
}

/*
--
2.39.2


2023-03-09 16:05:37

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 036/101] fbdev/imsttfb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/imsttfb.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/video/fbdev/imsttfb.c b/drivers/video/fbdev/imsttfb.c
index bea45647184e..1e2b45faa26b 100644
--- a/drivers/video/fbdev/imsttfb.c
+++ b/drivers/video/fbdev/imsttfb.c
@@ -17,6 +17,7 @@
*/

#include <linux/aperture.h>
+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -1560,16 +1561,16 @@ static void imsttfb_remove(struct pci_dev *pdev)

#ifndef MODULE
static int __init
-imsttfb_setup(char *options)
+imsttfb_setup(const char *options)
{
+ struct option_iter iter;
char *this_opt;

- if (!options || !*options)
- return 0;
+ option_iter_init(&iter, options);

- while ((this_opt = strsep(&options, ",")) != NULL) {
+ while (option_iter_next(&iter, &this_opt)) {
if (!strncmp(this_opt, "font:", 5)) {
- char *p;
+ const char *p;
int i;

p = this_opt + 5;
@@ -1608,6 +1609,9 @@ imsttfb_setup(char *options)
}
#endif
}
+
+ option_iter_release(&iter);
+
return 0;
}

--
2.39.2


2023-03-09 16:05:41

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 035/101] fbdev/i810: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/i810/i810_main.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/video/fbdev/i810/i810_main.c b/drivers/video/fbdev/i810/i810_main.c
index 3b2648a2de29..952d1a69dfb9 100644
--- a/drivers/video/fbdev/i810/i810_main.c
+++ b/drivers/video/fbdev/i810/i810_main.c
@@ -29,6 +29,7 @@
*/

#include <linux/aperture.h>
+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -1959,14 +1960,15 @@ static void i810fb_find_init_mode(struct fb_info *info)
}

#ifndef MODULE
-static int i810fb_setup(char *options)
+static int i810fb_setup(const char *options)
{
- char *this_opt, *suffix = NULL;
+ char *suffix = NULL;
+ struct option_iter iter;
+ char *this_opt;

- if (!options || !*options)
- return 0;
+ option_iter_init(&iter, options);

- while ((this_opt = strsep(&options, ",")) != NULL) {
+ while (option_iter_next(&iter, &this_opt)) {
if (!strncmp(this_opt, "mtrr", 4))
mtrr = true;
else if (!strncmp(this_opt, "accel", 5))
@@ -2009,6 +2011,9 @@ static int i810fb_setup(char *options)
mode_option = mode_option_buf;
}
}
+
+ option_iter_release(&iter);
+
return 0;
}
#endif
--
2.39.2


2023-03-09 16:05:45

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 034/101] fbdev/i810: Duplicate video-mode option string

Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with kstrdup() and free it in the module's exit function.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

v2:
* replace static memory with kstrdup()/kfree() (Geert)

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/i810/i810_main.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/i810/i810_main.c b/drivers/video/fbdev/i810/i810_main.c
index 85abb65f07d7..3b2648a2de29 100644
--- a/drivers/video/fbdev/i810/i810_main.c
+++ b/drivers/video/fbdev/i810/i810_main.c
@@ -134,6 +134,7 @@ static struct pci_driver i810fb_driver = {
.resume = i810fb_resume,
};

+static char *mode_option_buf;
static char *mode_option = NULL;
static int vram = 4;
static int bpp = 8;
@@ -2002,8 +2003,11 @@ static int i810fb_setup(char *options)
dcolor = true;
else if (!strncmp(this_opt, "ddc3", 4))
ddc3 = true;
- else
- mode_option = this_opt;
+ else {
+ kfree(mode_option_buf);
+ mode_option_buf = kstrdup(this_opt, GFP_KERNEL); // ignore errors
+ mode_option = mode_option_buf;
+ }
}
return 0;
}
@@ -2224,6 +2228,7 @@ MODULE_LICENSE("GPL");
static void __exit i810fb_exit(void)
{
pci_unregister_driver(&i810fb_driver);
+ kfree(mode_option_buf);
}
module_exit(i810fb_exit);

--
2.39.2


2023-03-09 16:05:51

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 032/101] fbdev/i740fb: Duplicate video-mode option string

Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with kstrdup() and free it in the module's exit function.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

v2:
* replace static memory with kstrdup()/kfree() (Geert)

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/i740fb.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/i740fb.c b/drivers/video/fbdev/i740fb.c
index 3860b137b86a..61c022b8d5de 100644
--- a/drivers/video/fbdev/i740fb.c
+++ b/drivers/video/fbdev/i740fb.c
@@ -31,6 +31,7 @@

#include "i740_reg.h"

+static char *mode_option_buf;
static char *mode_option;
static int mtrr = 1;

@@ -1273,8 +1274,11 @@ static int __init i740fb_setup(char *options)
continue;
else if (!strncmp(opt, "mtrr:", 5))
mtrr = simple_strtoul(opt + 5, NULL, 0);
- else
- mode_option = opt;
+ else {
+ kfree(mode_option_buf);
+ mode_option_buf = kstrdup(opt, GFP_KERNEL); // ignore errors
+ mode_option = mode_option_buf;
+ }
}

return 0;
@@ -1302,6 +1306,7 @@ static int __init i740fb_init(void)
static void __exit i740fb_exit(void)
{
pci_unregister_driver(&i740fb_driver);
+ kfree(mode_option_buf);
}

module_init(i740fb_init);
--
2.39.2


2023-03-09 16:05:59

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 037/101] fbdev/intelfb: Duplicate video-mode option string

Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with kstrdup() and free it in the module's exit function.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

v2:
* replace static memory with kstrdup()/kfree() (Geert)

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/intelfb/intelfbdrv.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/intelfb/intelfbdrv.c b/drivers/video/fbdev/intelfb/intelfbdrv.c
index 0a9e5067b201..8368c3601cdb 100644
--- a/drivers/video/fbdev/intelfb/intelfbdrv.c
+++ b/drivers/video/fbdev/intelfb/intelfbdrv.c
@@ -238,6 +238,7 @@ static bool probeonly = 0;
static bool idonly = 0;
static int bailearly = 0;
static int voffset = 48;
+static char *mode_buf;
static char *mode = NULL;

module_param(accel, bool, S_IRUGO);
@@ -365,8 +366,11 @@ static int __init intelfb_setup(char *options)
noinit = !noinit;
else if (OPT_EQUAL(this_opt, "mode="))
mode = get_opt_string(this_opt, "mode=");
- else
- mode = this_opt;
+ else {
+ kfree(mode_buf);
+ mode_buf = kstrdup(this_opt, GFP_KERNEL); // ignore errors
+ mode = mode_buf;
+ }
}

return 0;
@@ -405,6 +409,7 @@ static void __exit intelfb_exit(void)
{
DBG_MSG("intelfb_exit\n");
pci_unregister_driver(&intelfb_driver);
+ kfree(mode_buf);
}

module_init(intelfb_init);
--
2.39.2


2023-03-09 16:06:04

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 039/101] fbdev/imxfb: Duplicate video-mode option string

Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with devm_kstrdup(), as the driver parses the option string
once per probed device. Linux will automatically free the memory upon
releasing the device.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/imxfb.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/video/fbdev/imxfb.c b/drivers/video/fbdev/imxfb.c
index 51fde1b2a793..aad7d447385c 100644
--- a/drivers/video/fbdev/imxfb.c
+++ b/drivers/video/fbdev/imxfb.c
@@ -843,7 +843,7 @@ static struct lcd_ops imxfb_lcd_ops = {
.set_power = imxfb_lcd_set_power,
};

-static int imxfb_setup(void)
+static int imxfb_setup(struct platform_device *pdev)
{
char *opt, *options = NULL;

@@ -856,8 +856,8 @@ static int imxfb_setup(void)
while ((opt = strsep(&options, ",")) != NULL) {
if (!*opt)
continue;
- else
- fb_mode = opt;
+
+ fb_mode = devm_kstrdup(&pdev->dev, opt, GFP_KERNEL); // ignore errors
}

return 0;
@@ -877,7 +877,7 @@ static int imxfb_probe(struct platform_device *pdev)

dev_info(&pdev->dev, "i.MX Framebuffer driver\n");

- ret = imxfb_setup();
+ ret = imxfb_setup(pdev);
if (ret < 0)
return ret;

--
2.39.2


2023-03-09 16:06:11

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 038/101] fbdev/intelfb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/intelfb/intelfbdrv.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/video/fbdev/intelfb/intelfbdrv.c b/drivers/video/fbdev/intelfb/intelfbdrv.c
index 8368c3601cdb..43d677897392 100644
--- a/drivers/video/fbdev/intelfb/intelfbdrv.c
+++ b/drivers/video/fbdev/intelfb/intelfbdrv.c
@@ -108,6 +108,7 @@
*/

#include <linux/aperture.h>
+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -324,8 +325,9 @@ static __inline__ int get_opt_bool(const char *this_opt, const char *name,
return 1;
}

-static int __init intelfb_setup(char *options)
+static int __init intelfb_setup(const char *options)
{
+ struct option_iter iter;
char *this_opt;

DBG_MSG("intelfb_setup\n");
@@ -349,9 +351,9 @@ static int __init intelfb_setup(char *options)
* video=intelfb:1024x768-16@75,accel=0
*/

- while ((this_opt = strsep(&options, ","))) {
- if (!*this_opt)
- continue;
+ option_iter_init(&iter, options);
+
+ while (option_iter_next(&iter, &this_opt)) {
if (get_opt_bool(this_opt, "accel", &accel))
;
else if (get_opt_int(this_opt, "vram", &vram))
@@ -373,6 +375,8 @@ static int __init intelfb_setup(char *options)
}
}

+ option_iter_release(&iter);
+
return 0;
}

--
2.39.2


2023-03-09 16:06:19

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 045/101] fbdev/matroxfb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/matrox/matroxfb_base.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/video/fbdev/matrox/matroxfb_base.c b/drivers/video/fbdev/matrox/matroxfb_base.c
index a043a737ea9f..4c2086136e9b 100644
--- a/drivers/video/fbdev/matrox/matroxfb_base.c
+++ b/drivers/video/fbdev/matrox/matroxfb_base.c
@@ -101,6 +101,7 @@
*/

#include <linux/aperture.h>
+#include <linux/cmdline.h>
#include <linux/version.h>

#include "matroxfb_base.h"
@@ -2333,17 +2334,14 @@ static void __exit matrox_done(void) {

/* ************************* init in-kernel code ************************** */

-static int __init matroxfb_setup(char *options) {
+static int __init matroxfb_setup(const char *options)
+{
+ struct option_iter iter;
char *this_opt;

- DBG(__func__)
-
- if (!options || !*options)
- return 0;
-
- while ((this_opt = strsep(&options, ",")) != NULL) {
- if (!*this_opt) continue;
+ option_iter_init(&iter, options);

+ while (option_iter_next(&iter, &this_opt)) {
dprintk("matroxfb_setup: option %s\n", this_opt);

if (!strncmp(this_opt, "dev:", 4))
@@ -2467,6 +2465,9 @@ static int __init matroxfb_setup(char *options) {
}
}
}
+
+ option_iter_release(&iter);
+
return 0;
}

--
2.39.2


2023-03-09 16:06:24

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 041/101] fbdev/kyrofb: Duplicate video-mode option string

Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with kstrdup() and free it in the module's exit function.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

v2:
* replace static memory with kstrdup()/kfree() (Geert)

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/kyro/fbdev.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/kyro/fbdev.c b/drivers/video/fbdev/kyro/fbdev.c
index 0596573ef140..97f4d8995e36 100644
--- a/drivers/video/fbdev/kyro/fbdev.c
+++ b/drivers/video/fbdev/kyro/fbdev.c
@@ -79,6 +79,7 @@ typedef struct {
/* global graphics card info structure (one per card) */
static device_info_t deviceInfo;

+static char *mode_option_buf;
static char *mode_option = NULL;
static int nopan = 0;
static int nowrap = 1;
@@ -579,7 +580,9 @@ static int __init kyrofb_setup(char *options)
} else if (strcmp(this_opt, "nomtrr") == 0) {
nomtrr = 1;
} else {
- mode_option = this_opt;
+ kfree(mode_option_buf);
+ mode_option_buf = kstrdup(this_opt, GFP_KERNEL); // ignore errors
+ mode_option = mode_option_buf;
}
}

@@ -805,6 +808,7 @@ static int __init kyrofb_init(void)
static void __exit kyrofb_exit(void)
{
pci_unregister_driver(&kyrofb_pci_driver);
+ kfree(mode_option_buf);
}

module_init(kyrofb_init);
--
2.39.2


2023-03-09 16:06:28

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 043/101] fbdev/macfb: Remove trailing whitespaces

Fix coding style. No functional changes.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/macfb.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/video/fbdev/macfb.c b/drivers/video/fbdev/macfb.c
index 312e35c9aa6c..44ff860a3f37 100644
--- a/drivers/video/fbdev/macfb.c
+++ b/drivers/video/fbdev/macfb.c
@@ -339,7 +339,7 @@ static int civic_setpalette(unsigned int regno, unsigned int red,
{
unsigned long flags;
int clut_status;
-
+
local_irq_save(flags);

/* Set the register address */
@@ -439,7 +439,7 @@ static int macfb_setcolreg(unsigned regno, unsigned red, unsigned green,
* (according to the entries in the `var' structure).
* Return non-zero for invalid regno.
*/
-
+
if (regno >= fb_info->cmap.len)
return 1;

@@ -548,7 +548,7 @@ static int __init macfb_init(void)
return -ENODEV;
macfb_setup(option);

- if (!MACH_IS_MAC)
+ if (!MACH_IS_MAC)
return -ENODEV;

if (mac_bi_data.id == MAC_MODEL_Q630 ||
@@ -644,7 +644,7 @@ static int __init macfb_init(void)
err = -EINVAL;
goto fail_unmap;
}
-
+
/*
* We take a wild guess that if the video physical address is
* in nubus slot space, that the nubus card is driving video.
@@ -774,7 +774,7 @@ static int __init macfb_init(void)
civic_cmap_regs = ioremap(CIVIC_BASE, 0x1000);
break;

-
+
/*
* Assorted weirdos
* We think this may be like the LC II
--
2.39.2


2023-03-09 16:06:35

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 042/101] fbdev/kyrofb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/kyro/fbdev.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/video/fbdev/kyro/fbdev.c b/drivers/video/fbdev/kyro/fbdev.c
index 97f4d8995e36..ccfec4e55ecf 100644
--- a/drivers/video/fbdev/kyro/fbdev.c
+++ b/drivers/video/fbdev/kyro/fbdev.c
@@ -10,6 +10,7 @@
*/

#include <linux/aperture.h>
+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
@@ -563,16 +564,14 @@ static int kyrofb_setcolreg(u_int regno, u_int red, u_int green,
}

#ifndef MODULE
-static int __init kyrofb_setup(char *options)
+static int __init kyrofb_setup(const char *options)
{
+ struct option_iter iter;
char *this_opt;

- if (!options || !*options)
- return 0;
+ option_iter_init(&iter, options);

- while ((this_opt = strsep(&options, ","))) {
- if (!*this_opt)
- continue;
+ while (option_iter_next(&iter, &this_opt)) {
if (strcmp(this_opt, "nopan") == 0) {
nopan = 1;
} else if (strcmp(this_opt, "nowrap") == 0) {
@@ -586,6 +585,8 @@ static int __init kyrofb_setup(char *options)
}
}

+ option_iter_release(&iter);
+
return 0;
}
#endif
--
2.39.2


2023-03-09 16:06:38

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 040/101] fbdev/imxfb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/imxfb.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/video/fbdev/imxfb.c b/drivers/video/fbdev/imxfb.c
index aad7d447385c..d4e347aca0b0 100644
--- a/drivers/video/fbdev/imxfb.c
+++ b/drivers/video/fbdev/imxfb.c
@@ -14,6 +14,7 @@
* [email protected]
*/

+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -845,21 +846,21 @@ static struct lcd_ops imxfb_lcd_ops = {

static int imxfb_setup(struct platform_device *pdev)
{
- char *opt, *options = NULL;
+ char *options = NULL;
+ struct option_iter iter;
+ char *opt;

if (fb_get_options("imxfb", &options))
return -ENODEV;

- if (!options || !*options)
- return 0;
-
- while ((opt = strsep(&options, ",")) != NULL) {
- if (!*opt)
- continue;
+ option_iter_init(&iter, options);

+ while (option_iter_next(&iter, &opt)) {
fb_mode = devm_kstrdup(&pdev->dev, opt, GFP_KERNEL); // ignore errors
}

+ option_iter_release(&iter);
+
return 0;
}

--
2.39.2


2023-03-09 16:06:43

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 047/101] fbdev/mx3fb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/mx3fb.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/video/fbdev/mx3fb.c b/drivers/video/fbdev/mx3fb.c
index e33ad125318f..ca58afe366b4 100644
--- a/drivers/video/fbdev/mx3fb.c
+++ b/drivers/video/fbdev/mx3fb.c
@@ -6,6 +6,7 @@
* Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
*/

+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
@@ -1654,17 +1655,16 @@ static struct platform_driver mx3fb_driver = {
static int __init mx3fb_setup(void)
{
#ifndef MODULE
- char *opt, *options = NULL;
+ char *options = NULL;
+ struct option_iter iter;
+ char *opt;

if (fb_get_options("mx3fb", &options))
return -ENODEV;

- if (!options || !*options)
- return 0;
+ option_iter_init(&iter, options);

- while ((opt = strsep(&options, ",")) != NULL) {
- if (!*opt)
- continue;
+ while (option_iter_next(&iter, &opt)) {
if (!strncmp(opt, "bpp=", 4))
default_bpp = simple_strtoul(opt + 4, NULL, 0);
else {
@@ -1673,6 +1673,8 @@ static int __init mx3fb_setup(void)
fb_mode = fb_mode_buf;
}
}
+
+ option_iter_release(&iter);
#endif

return 0;
--
2.39.2


2023-03-09 16:06:50

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 046/101] fbdev/mx3fb: Duplicate video-mode option string

Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with kstrdup() and free it in the module's exit function.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

v2:
* replace static memory with kstrdup()/kfree() (Geert)

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/mx3fb.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/mx3fb.c b/drivers/video/fbdev/mx3fb.c
index 76771e126d0a..e33ad125318f 100644
--- a/drivers/video/fbdev/mx3fb.c
+++ b/drivers/video/fbdev/mx3fb.c
@@ -332,6 +332,7 @@ static void mx3fb_exit_backlight(struct mx3fb_data *fbd)
static void mx3fb_dma_done(void *);

/* Used fb-mode and bpp. Can be set on kernel command line, therefore file-static. */
+static const char *fb_mode_buf;
static const char *fb_mode;
static unsigned long default_bpp = 16;

@@ -1666,8 +1667,11 @@ static int __init mx3fb_setup(void)
continue;
if (!strncmp(opt, "bpp=", 4))
default_bpp = simple_strtoul(opt + 4, NULL, 0);
- else
- fb_mode = opt;
+ else {
+ kfree(fb_mode_buf);
+ fb_mode_buf = kstrdup(opt, GFP_KERNEL); // ignore errors
+ fb_mode = fb_mode_buf;
+ }
}
#endif

@@ -1688,6 +1692,7 @@ static int __init mx3fb_init(void)
static void __exit mx3fb_exit(void)
{
platform_driver_unregister(&mx3fb_driver);
+ kfree(fb_mode_buf);
}

module_init(mx3fb_init);
--
2.39.2


2023-03-09 16:06:59

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 060/101] fbdev/pm3fb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/pm3fb.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/video/fbdev/pm3fb.c b/drivers/video/fbdev/pm3fb.c
index b6b378e7554d..c4d4f08b4114 100644
--- a/drivers/video/fbdev/pm3fb.c
+++ b/drivers/video/fbdev/pm3fb.c
@@ -23,6 +23,7 @@
*/

#include <linux/aperture.h>
+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -1510,18 +1511,16 @@ MODULE_DEVICE_TABLE(pci, pm3fb_id_table);
* Only necessary if your driver takes special options,
* otherwise we fall back on the generic fb_setup().
*/
-static int __init pm3fb_setup(char *options)
+static int __init pm3fb_setup(const char *options)
{
+ struct option_iter iter;
char *this_opt;

/* Parse user specified options (`video=pm3fb:') */
- if (!options || !*options)
- return 0;
+ option_iter_init(&iter, options);

- while ((this_opt = strsep(&options, ",")) != NULL) {
- if (!*this_opt)
- continue;
- else if (!strncmp(this_opt, "noaccel", 7))
+ while (option_iter_next(&iter, &this_opt)) {
+ if (!strncmp(this_opt, "noaccel", 7))
noaccel = 1;
else if (!strncmp(this_opt, "hwcursor=", 9))
hwcursor = simple_strtoul(this_opt + 9, NULL, 0);
@@ -1533,6 +1532,9 @@ static int __init pm3fb_setup(char *options)
mode_option = mode_option_buf;
}
}
+
+ option_iter_release(&iter);
+
return 0;
}
#endif /* MODULE */
--
2.39.2


2023-03-09 16:07:03

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 058/101] fbdev/pm2fb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/pm2fb.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/video/fbdev/pm2fb.c b/drivers/video/fbdev/pm2fb.c
index 69a0b2216a86..38c5c57ce2b0 100644
--- a/drivers/video/fbdev/pm2fb.c
+++ b/drivers/video/fbdev/pm2fb.c
@@ -28,6 +28,7 @@
*/

#include <linux/aperture.h>
+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
@@ -1773,16 +1774,14 @@ MODULE_DEVICE_TABLE(pci, pm2fb_id_table);
*
* This is, comma-separated options following `video=pm2fb:'.
*/
-static int __init pm2fb_setup(char *options)
+static int __init pm2fb_setup(const char *options)
{
+ struct option_iter iter;
char *this_opt;

- if (!options || !*options)
- return 0;
+ option_iter_init(&iter, options);

- while ((this_opt = strsep(&options, ",")) != NULL) {
- if (!*this_opt)
- continue;
+ while (option_iter_next(&iter, &this_opt)) {
if (!strcmp(this_opt, "lowhsync"))
lowhsync = 1;
else if (!strcmp(this_opt, "lowvsync"))
@@ -1799,6 +1798,9 @@ static int __init pm2fb_setup(char *options)
mode_option = mode_option_buf;
}
}
+
+ option_iter_release(&iter);
+
return 0;
}
#endif
--
2.39.2


2023-03-09 16:07:09

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 057/101] fbdev/pm2fb: Duplicate video-mode option string

Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with kstrdup() and free it in the module's exit function.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

v2:
* replace static memory with kstrdup()/kfree() (Geert)

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/pm2fb.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/pm2fb.c b/drivers/video/fbdev/pm2fb.c
index 47d212944f30..69a0b2216a86 100644
--- a/drivers/video/fbdev/pm2fb.c
+++ b/drivers/video/fbdev/pm2fb.c
@@ -64,6 +64,7 @@
* Driver data
*/
static int hwcursor = 1;
+static char *mode_option_buf;
static char *mode_option;

/*
@@ -1792,8 +1793,11 @@ static int __init pm2fb_setup(char *options)
nomtrr = 1;
else if (!strncmp(this_opt, "noaccel", 7))
noaccel = 1;
- else
- mode_option = this_opt;
+ else {
+ kfree(mode_option_buf);
+ mode_option_buf = kstrdup(this_opt, GFP_KERNEL); // ignore errors
+ mode_option = mode_option_buf;
+ }
}
return 0;
}
@@ -1828,6 +1832,7 @@ module_init(pm2fb_init);
static void __exit pm2fb_exit(void)
{
pci_unregister_driver(&pm2fb_driver);
+ kfree(mode_option_buf);
}
#endif

--
2.39.2


2023-03-09 16:07:14

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 051/101] fbdev/nvidiafb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/nvidia/nvidia.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/video/fbdev/nvidia/nvidia.c b/drivers/video/fbdev/nvidia/nvidia.c
index 8ad4bcff84df..d779163f919a 100644
--- a/drivers/video/fbdev/nvidia/nvidia.c
+++ b/drivers/video/fbdev/nvidia/nvidia.c
@@ -10,6 +10,7 @@
*/

#include <linux/aperture.h>
+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -1459,17 +1460,18 @@ static void nvidiafb_remove(struct pci_dev *pd)
* ------------------------------------------------------------------------- */

#ifndef MODULE
-static int nvidiafb_setup(char *options)
+static int nvidiafb_setup(const char *options)
{
+ struct option_iter iter;
char *this_opt;

NVTRACE_ENTER();
- if (!options || !*options)
- return 0;

- while ((this_opt = strsep(&options, ",")) != NULL) {
+ option_iter_init(&iter, options);
+
+ while (option_iter_next(&iter, &this_opt)) {
if (!strncmp(this_opt, "forceCRTC", 9)) {
- char *p;
+ const char *p;

p = this_opt + 9;
if (!*p || !*(++p))
@@ -1505,6 +1507,9 @@ static int nvidiafb_setup(char *options)
mode_option = mode_option_buf;
}
}
+
+ option_iter_release(&iter);
+
NVTRACE_LEAVE();
return 0;
}
--
2.39.2


2023-03-09 16:07:19

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 055/101] fbdev/platinumfb: Remove trailing whitespaces

Fix coding style. No functional changes.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/platinumfb.c | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/video/fbdev/platinumfb.c b/drivers/video/fbdev/platinumfb.c
index 5b9e26ea6449..c7172174c1b7 100644
--- a/drivers/video/fbdev/platinumfb.c
+++ b/drivers/video/fbdev/platinumfb.c
@@ -52,17 +52,17 @@ struct fb_info_platinum {
__u8 red, green, blue;
} palette[256];
u32 pseudo_palette[16];
-
+
volatile struct cmap_regs __iomem *cmap_regs;
unsigned long cmap_regs_phys;
-
+
volatile struct platinum_regs __iomem *platinum_regs;
unsigned long platinum_regs_phys;
-
+
__u8 __iomem *frame_buffer;
volatile __u8 __iomem *base_frame_buffer;
unsigned long frame_buffer_phys;
-
+
unsigned long total_vram;
int clktype;
int dactype;
@@ -133,7 +133,7 @@ static int platinumfb_set_par (struct fb_info *info)
platinum_set_hardware(pinfo);

init = platinum_reg_init[pinfo->vmode-1];
-
+
if ((pinfo->vmode == VMODE_832_624_75) && (pinfo->cmode > CMODE_8))
offset = 0x10;

@@ -214,7 +214,7 @@ static int platinumfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
break;
}
}
-
+
return 0;
}

@@ -269,7 +269,7 @@ static void platinum_set_hardware(struct fb_info_platinum *pinfo)
struct platinum_regvals *init;
int i;
int vmode, cmode;
-
+
vmode = pinfo->vmode;
cmode = pinfo->cmode;

@@ -436,7 +436,7 @@ static int read_platinum_sense(struct fb_info_platinum *info)
* This routine takes a user-supplied var, and picks the best vmode/cmode from it.
* It also updates the var structure to the actual mode data obtained
*/
-static int platinum_var_to_par(struct fb_var_screeninfo *var,
+static int platinum_var_to_par(struct fb_var_screeninfo *var,
struct fb_info_platinum *pinfo,
int check_only)
{
@@ -478,12 +478,12 @@ static int platinum_var_to_par(struct fb_var_screeninfo *var,
pinfo->yoffset = 0;
pinfo->vxres = pinfo->xres;
pinfo->vyres = pinfo->yres;
-
+
return 0;
}


-/*
+/*
* Parse user specified options (`video=platinumfb:')
*/
static int __init platinumfb_setup(char *options)
@@ -624,7 +624,7 @@ static int platinumfb_probe(struct platform_device* odev)
break;
}
dev_set_drvdata(&odev->dev, info);
-
+
rc = platinum_init_fb(info);
if (rc != 0) {
iounmap(pinfo->frame_buffer);
@@ -640,9 +640,9 @@ static int platinumfb_remove(struct platform_device* odev)
{
struct fb_info *info = dev_get_drvdata(&odev->dev);
struct fb_info_platinum *pinfo = info->par;
-
+
unregister_framebuffer (info);
-
+
/* Unmap frame buffer and registers */
iounmap(pinfo->frame_buffer);
iounmap(pinfo->platinum_regs);
@@ -658,7 +658,7 @@ static int platinumfb_remove(struct platform_device* odev)
return 0;
}

-static struct of_device_id platinumfb_match[] =
+static struct of_device_id platinumfb_match[] =
{
{
.name = "platinum",
@@ -666,7 +666,7 @@ static struct of_device_id platinumfb_match[] =
{},
};

-static struct platform_driver platinum_driver =
+static struct platform_driver platinum_driver =
{
.driver = {
.name = "platinumfb",
--
2.39.2


2023-03-09 16:07:24

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 049/101] fbdev/neofb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/neofb.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/video/fbdev/neofb.c b/drivers/video/fbdev/neofb.c
index 98edb6822832..01ed78d987b1 100644
--- a/drivers/video/fbdev/neofb.c
+++ b/drivers/video/fbdev/neofb.c
@@ -55,6 +55,7 @@
*/

#include <linux/aperture.h>
+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -2176,19 +2177,16 @@ static struct pci_driver neofb_driver = {
/* ************************* init in-kernel code ************************** */

#ifndef MODULE
-static int __init neofb_setup(char *options)
+static int __init neofb_setup(const char *options)
{
+ struct option_iter iter;
char *this_opt;

DBG("neofb_setup");

- if (!options || !*options)
- return 0;
-
- while ((this_opt = strsep(&options, ",")) != NULL) {
- if (!*this_opt)
- continue;
+ option_iter_init(&iter, options);

+ while (option_iter_next(&iter, &this_opt)) {
if (!strncmp(this_opt, "internal", 8))
internal = 1;
else if (!strncmp(this_opt, "external", 8))
@@ -2205,6 +2203,9 @@ static int __init neofb_setup(char *options)
mode_option = mode_option_buf;
}
}
+
+ option_iter_release(&iter);
+
return 0;
}
#endif /* MODULE */
--
2.39.2


2023-03-09 16:07:30

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 048/101] fbdev/neofb: Duplicate video-mode option string

Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with kstrdup() and free it in the module's exit function.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

v2:
* replace static memory with kstrdup()/kfree() (Geert)

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/neofb.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/neofb.c b/drivers/video/fbdev/neofb.c
index 39d8cdef5c97..98edb6822832 100644
--- a/drivers/video/fbdev/neofb.c
+++ b/drivers/video/fbdev/neofb.c
@@ -83,6 +83,7 @@ static bool external;
static bool libretto;
static bool nostretch;
static bool nopciburst;
+static char *mode_option_buf;
static char *mode_option = NULL;

#ifdef MODULE
@@ -2198,8 +2199,11 @@ static int __init neofb_setup(char *options)
nopciburst = 1;
else if (!strncmp(this_opt, "libretto", 8))
libretto = 1;
- else
- mode_option = this_opt;
+ else {
+ kfree(mode_option_buf);
+ mode_option_buf = kstrdup(this_opt, GFP_KERNEL); // ignore errors
+ mode_option = mode_option_buf;
+ }
}
return 0;
}
@@ -2228,6 +2232,7 @@ module_init(neofb_init);
static void __exit neofb_exit(void)
{
pci_unregister_driver(&neofb_driver);
+ kfree(mode_option_buf);
}

module_exit(neofb_exit);
--
2.39.2


2023-03-09 16:07:32

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 050/101] fbdev/nvidiafb: Duplicate video-mode option string

Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with kstrdup() and free it in the module's exit function.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

v2:
* replace static memory with kstrdup()/kfree() (Geert)

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/nvidia/nvidia.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/nvidia/nvidia.c b/drivers/video/fbdev/nvidia/nvidia.c
index e60a276b4855..8ad4bcff84df 100644
--- a/drivers/video/fbdev/nvidia/nvidia.c
+++ b/drivers/video/fbdev/nvidia/nvidia.c
@@ -77,6 +77,7 @@ static int reverse_i2c;
static bool nomtrr = false;
static int backlight = IS_BUILTIN(CONFIG_PMAC_BACKLIGHT);

+static char *mode_option_buf;
static char *mode_option = NULL;

static struct fb_fix_screeninfo nvidiafb_fix = {
@@ -1498,8 +1499,11 @@ static int nvidiafb_setup(char *options)
fpdither = simple_strtol(this_opt+9, NULL, 0);
} else if (!strncmp(this_opt, "bpp:", 4)) {
bpp = simple_strtoul(this_opt+4, NULL, 0);
- } else
- mode_option = this_opt;
+ } else {
+ kfree(mode_option_buf);
+ mode_option_buf = kstrdup(this_opt, GFP_KERNEL); // ignore errors
+ mode_option = mode_option_buf;
+ }
}
NVTRACE_LEAVE();
return 0;
@@ -1542,6 +1546,7 @@ module_init(nvidiafb_init);
static void __exit nvidiafb_exit(void)
{
pci_unregister_driver(&nvidiafb_driver);
+ kfree(mode_option_buf);
}

module_exit(nvidiafb_exit);
--
2.39.2


2023-03-09 16:07:37

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 044/101] fbdev/macfb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/macfb.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/video/fbdev/macfb.c b/drivers/video/fbdev/macfb.c
index 44ff860a3f37..c7e17a14daf1 100644
--- a/drivers/video/fbdev/macfb.c
+++ b/drivers/video/fbdev/macfb.c
@@ -20,6 +20,7 @@
* http://rajsky.psych.nyu.edu/Tips/VideoBugs.html
*/

+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -504,23 +505,22 @@ static const struct fb_ops macfb_ops = {
.fb_imageblit = cfb_imageblit,
};

-static void __init macfb_setup(char *options)
+static void __init macfb_setup(const char *options)
{
+ struct option_iter iter;
char *this_opt;

- if (!options || !*options)
- return;
-
- while ((this_opt = strsep(&options, ",")) != NULL) {
- if (!*this_opt)
- continue;
+ option_iter_init(&iter, options);

+ while (option_iter_next(&iter, &this_opt)) {
if (!strcmp(this_opt, "inverse"))
fb_invert_cmaps();
else
if (!strcmp(this_opt, "vidtest"))
vidtest = 1; /* enable experimental CLUT code */
}
+
+ option_iter_release(&iter);
}

static void __init iounmap_macfb(void)
--
2.39.2


2023-03-09 16:07:41

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 059/101] fbdev/pm3fb: Duplicate video-mode option string

Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with kstrdup() and free it in the module's exit function.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

v2:
* replace static memory with kstrdup()/kfree() (Geert)

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/pm3fb.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/pm3fb.c b/drivers/video/fbdev/pm3fb.c
index b46a471df9ae..b6b378e7554d 100644
--- a/drivers/video/fbdev/pm3fb.c
+++ b/drivers/video/fbdev/pm3fb.c
@@ -54,6 +54,7 @@
* Driver data
*/
static int hwcursor = 1;
+static char *mode_option_buf;
static char *mode_option;
static bool noaccel;
static bool nomtrr;
@@ -1526,8 +1527,11 @@ static int __init pm3fb_setup(char *options)
hwcursor = simple_strtoul(this_opt + 9, NULL, 0);
else if (!strncmp(this_opt, "nomtrr", 6))
nomtrr = 1;
- else
- mode_option = this_opt;
+ else {
+ kfree(mode_option_buf);
+ mode_option_buf = kstrdup(this_opt, GFP_KERNEL); // ignore errors
+ mode_option = mode_option_buf;
+ }
}
return 0;
}
@@ -1558,6 +1562,7 @@ static int __init pm3fb_init(void)
static void __exit pm3fb_exit(void)
{
pci_unregister_driver(&pm3fb_driver);
+ kfree(mode_option_buf);
}

module_exit(pm3fb_exit);
--
2.39.2


2023-03-09 16:07:44

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 056/101] fbdev/platinumfb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/platinumfb.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/video/fbdev/platinumfb.c b/drivers/video/fbdev/platinumfb.c
index c7172174c1b7..33bf75309815 100644
--- a/drivers/video/fbdev/platinumfb.c
+++ b/drivers/video/fbdev/platinumfb.c
@@ -19,6 +19,7 @@

#undef DEBUG

+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -486,14 +487,14 @@ static int platinum_var_to_par(struct fb_var_screeninfo *var,
/*
* Parse user specified options (`video=platinumfb:')
*/
-static int __init platinumfb_setup(char *options)
+static int __init platinumfb_setup(const char *options)
{
+ struct option_iter iter;
char *this_opt;

- if (!options || !*options)
- return 0;
+ option_iter_init(&iter, options);

- while ((this_opt = strsep(&options, ",")) != NULL) {
+ while (option_iter_next(&iter, &this_opt)) {
if (!strncmp(this_opt, "vmode:", 6)) {
int vmode = simple_strtoul(this_opt+6, NULL, 0);
if (vmode > 0 && vmode <= VMODE_MAX)
@@ -516,6 +517,9 @@ static int __init platinumfb_setup(char *options)
}
}
}
+
+ option_iter_release(&iter);
+
return 0;
}

--
2.39.2


2023-03-09 16:07:47

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 065/101] fbdev/pxafb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/pxafb.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/video/fbdev/pxafb.c b/drivers/video/fbdev/pxafb.c
index c46ed78298ae..d2db9c20d515 100644
--- a/drivers/video/fbdev/pxafb.c
+++ b/drivers/video/fbdev/pxafb.c
@@ -32,6 +32,7 @@
* All Rights Reserved
*/

+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
@@ -2011,23 +2012,26 @@ static int parse_opt(struct device *dev, char *this_opt,
return 0;
}

-static int pxafb_parse_options(struct device *dev, char *options,
+static int pxafb_parse_options(struct device *dev, const char *options,
struct pxafb_mach_info *inf)
{
+ struct option_iter iter;
char *this_opt;
int ret;

- if (!options || !*options)
- return 0;
-
dev_dbg(dev, "options are \"%s\"\n", options ? options : "null");

- /* could be made table driven or similar?... */
- while ((this_opt = strsep(&options, ",")) != NULL) {
+ option_iter_init(&iter, options);
+
+ while (option_iter_next(&iter, &this_opt)) {
+ /* could be made table driven or similar?... */
ret = parse_opt(dev, this_opt, inf);
if (ret)
return ret;
}
+
+ option_iter_release(&iter);
+
return 0;
}

--
2.39.2


2023-03-09 16:07:51

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 064/101] fbdev/pvr2fb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/pvr2fb.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/video/fbdev/pvr2fb.c b/drivers/video/fbdev/pvr2fb.c
index f6be2649840d..c332f2c38114 100644
--- a/drivers/video/fbdev/pvr2fb.c
+++ b/drivers/video/fbdev/pvr2fb.c
@@ -46,6 +46,7 @@
#undef DEBUG

#include <linux/aperture.h>
+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -1025,20 +1026,18 @@ static void pvr2fb_pci_exit(void)
*/

#ifndef MODULE
-static int __init pvr2fb_setup(char *options)
+static int __init pvr2fb_setup(const char *options)
{
- char *this_opt;
char cable_arg[80];
char output_arg[80];
-
- if (!options || !*options)
- return 0;
+ struct option_iter iter;
+ char *this_opt;

cable_arg[0] = output_arg[0] = 0;

- while ((this_opt = strsep(&options, ","))) {
- if (!*this_opt)
- continue;
+ option_iter_init(&iter, options);
+
+ while (option_iter_next(&iter, &this_opt)) {
if (!strcmp(this_opt, "inverse")) {
fb_invert_cmaps();
} else if (!strncmp(this_opt, "cable:", 6)) {
@@ -1056,6 +1055,8 @@ static int __init pvr2fb_setup(char *options)
}
}

+ option_iter_release(&iter);
+
if (*cable_arg)
cable_type = pvr2_get_param_val(cables, cable_arg, 3);
if (*output_arg)
--
2.39.2


2023-03-09 16:07:58

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 062/101] fbdev/ps3fb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/ps3fb.c | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/video/fbdev/ps3fb.c b/drivers/video/fbdev/ps3fb.c
index d67ef2701b18..575b2911977a 100644
--- a/drivers/video/fbdev/ps3fb.c
+++ b/drivers/video/fbdev/ps3fb.c
@@ -17,6 +17,7 @@
* more details.
*/

+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -1257,6 +1258,8 @@ static struct ps3_system_bus_driver ps3fb_driver = {
static int __init ps3fb_setup(void)
{
char *options;
+ struct option_iter iter;
+ char *this_opt;

#ifdef MODULE
return 0;
@@ -1265,16 +1268,9 @@ static int __init ps3fb_setup(void)
if (fb_get_options(DEVICE_NAME, &options))
return -ENXIO;

- if (!options || !*options)
- return 0;
-
- while (1) {
- char *this_opt = strsep(&options, ",");
+ option_iter_init(&iter, options);

- if (!this_opt)
- break;
- if (!*this_opt)
- continue;
+ while (option_iter_next(&iter, &this_opt)) {
if (!strncmp(this_opt, "mode:", 5))
ps3fb_mode = simple_strtoul(this_opt + 5, NULL, 0);
else {
@@ -1283,6 +1279,9 @@ static int __init ps3fb_setup(void)
mode_option = mode_option_buf;
}
}
+
+ option_iter_release(&iter);
+
return 0;
}

--
2.39.2


2023-03-09 16:08:11

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 054/101] fbdev/omapfb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/omap/omapfb_main.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/video/fbdev/omap/omapfb_main.c b/drivers/video/fbdev/omap/omapfb_main.c
index 1f3df2055ff0..db5256c71f5b 100644
--- a/drivers/video/fbdev/omap/omapfb_main.c
+++ b/drivers/video/fbdev/omap/omapfb_main.c
@@ -11,6 +11,7 @@
* Dirk Behme <[email protected]> - changes for 2.6 kernel API
* Texas Instruments - H3 support
*/
+#include <linux/cmdline.h>
#include <linux/platform_device.h>
#include <linux/mm.h>
#include <linux/slab.h>
@@ -1842,17 +1843,17 @@ static struct platform_driver omapfb_driver = {
#ifndef MODULE

/* Process kernel command line parameters */
-static int __init omapfb_setup(char *options)
+static int __init omapfb_setup(const char *options)
{
- char *this_opt = NULL;
+ struct option_iter iter;
+ char *this_opt;
int r = 0;

pr_debug("omapfb: options %s\n", options);

- if (!options || !*options)
- return 0;
+ option_iter_init(&iter, options);

- while (!r && (this_opt = strsep(&options, ",")) != NULL) {
+ while (option_iter_next(&iter, &this_opt)) {
if (!strncmp(this_opt, "accel", 5))
def_accel = 1;
else if (!strncmp(this_opt, "vram:", 5)) {
@@ -1893,6 +1894,8 @@ static int __init omapfb_setup(char *options)
}
}

+ option_iter_release(&iter);
+
return r;
}

--
2.39.2


2023-03-09 16:08:16

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 052/101] fbdev/ocfb: Duplicate video-mode option string

Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with kstrdup() and free it in the module's exit function.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

v2:
* replace static memory with kstrdup()/kfree() (Geert)

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/ocfb.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/ocfb.c b/drivers/video/fbdev/ocfb.c
index da7e1457e58f..9786c3641448 100644
--- a/drivers/video/fbdev/ocfb.c
+++ b/drivers/video/fbdev/ocfb.c
@@ -47,6 +47,7 @@

#define OCFB_NAME "OC VGA/LCD"

+static char *mode_option_buf;
static char *mode_option;

static const struct fb_videomode default_mode = {
@@ -77,7 +78,10 @@ static int __init ocfb_setup(char *options)
while ((curr_opt = strsep(&options, ",")) != NULL) {
if (!*curr_opt)
continue;
- mode_option = curr_opt;
+
+ kfree(mode_option_buf);
+ mode_option_buf = kstrdup(curr_opt, GFP_KERNEL); // ignore errors
+ mode_option = mode_option_buf;
}

return 0;
@@ -420,6 +424,7 @@ static int __init ocfb_init(void)
static void __exit ocfb_exit(void)
{
platform_driver_unregister(&ocfb_driver);
+ kfree(mode_option_buf);
}

module_init(ocfb_init);
--
2.39.2


2023-03-09 16:08:27

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 053/101] fbdev/ocfb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/ocfb.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/video/fbdev/ocfb.c b/drivers/video/fbdev/ocfb.c
index 9786c3641448..fa15b932b323 100644
--- a/drivers/video/fbdev/ocfb.c
+++ b/drivers/video/fbdev/ocfb.c
@@ -8,6 +8,7 @@
* kind, whether express or implied.
*/

+#include <linux/cmdline.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/errno.h>
@@ -68,22 +69,21 @@ struct ocfb_dev {
};

#ifndef MODULE
-static int __init ocfb_setup(char *options)
+static int __init ocfb_setup(const char *options)
{
+ struct option_iter iter;
char *curr_opt;

- if (!options || !*options)
- return 0;
-
- while ((curr_opt = strsep(&options, ",")) != NULL) {
- if (!*curr_opt)
- continue;
+ option_iter_init(&iter, options);

+ while (option_iter_next(&iter, &curr_opt)) {
kfree(mode_option_buf);
mode_option_buf = kstrdup(curr_opt, GFP_KERNEL); // ignore errors
mode_option = mode_option_buf;
}

+ option_iter_release(&iter);
+
return 0;
}
#endif
--
2.39.2


2023-03-09 16:08:34

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 061/101] fbdev/ps3fb: Duplicate video-mode option string

Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with kstrdup() and free it in the module's exit function.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

v2:
* replace static memory with kstrdup()/kfree() (Geert)

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/ps3fb.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/ps3fb.c b/drivers/video/fbdev/ps3fb.c
index 2fe08b67eda7..d67ef2701b18 100644
--- a/drivers/video/fbdev/ps3fb.c
+++ b/drivers/video/fbdev/ps3fb.c
@@ -260,6 +260,7 @@ static const struct fb_videomode ps3fb_modedb[] = {
static int ps3fb_mode;
module_param(ps3fb_mode, int, 0);

+static char *mode_option_buf;
static char *mode_option;

static int ps3fb_cmp_mode(const struct fb_videomode *vmode,
@@ -1276,8 +1277,11 @@ static int __init ps3fb_setup(void)
continue;
if (!strncmp(this_opt, "mode:", 5))
ps3fb_mode = simple_strtoul(this_opt + 5, NULL, 0);
- else
- mode_option = this_opt;
+ else {
+ kfree(mode_option_buf);
+ mode_option_buf = kstrdup(this_opt, GFP_KERNEL); // ignore errors
+ mode_option = mode_option_buf;
+ }
}
return 0;
}
@@ -1294,6 +1298,7 @@ static void __exit ps3fb_exit(void)
{
pr_debug(" -> %s:%d\n", __func__, __LINE__);
ps3_system_bus_driver_unregister(&ps3fb_driver);
+ kfree(mode_option_buf);
pr_debug(" <- %s:%d\n", __func__, __LINE__);
}

--
2.39.2


2023-03-09 16:08:39

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 068/101] fbdev/s3fb: Duplicate video-mode option string

Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with kstrdup() and free it in the module's exit function.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

v2:
* replace static memory with kstrdup()/kfree() (Geert)

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/s3fb.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/s3fb.c b/drivers/video/fbdev/s3fb.c
index 7d257489edcc..6bcedcde8aad 100644
--- a/drivers/video/fbdev/s3fb.c
+++ b/drivers/video/fbdev/s3fb.c
@@ -150,6 +150,7 @@ static const struct svga_timing_regs s3_timing_regs = {
/* Module parameters */


+static char *mode_option_buf;
static char *mode_option;
static int mtrr = 1;
static int fasttext = 1;
@@ -1535,8 +1536,11 @@ static int __init s3fb_setup(char *options)
mtrr = simple_strtoul(opt + 5, NULL, 0);
else if (!strncmp(opt, "fasttext:", 9))
fasttext = simple_strtoul(opt + 9, NULL, 0);
- else
- mode_option = opt;
+ else {
+ kfree(mode_option_buf);
+ mode_option_buf = kstrdup(opt, GFP_KERNEL); // ignore errors
+ mode_option = mode_option_buf;
+ }
}

return 0;
@@ -1549,6 +1553,7 @@ static void __exit s3fb_cleanup(void)
{
pr_debug("s3fb: cleaning up\n");
pci_unregister_driver(&s3fb_pci_driver);
+ kfree(mode_option_buf);
}

/* Driver Initialisation */
--
2.39.2


2023-03-09 16:08:44

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 069/101] fbdev/s3fb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/s3fb.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/video/fbdev/s3fb.c b/drivers/video/fbdev/s3fb.c
index 6bcedcde8aad..37f5ea25efd6 100644
--- a/drivers/video/fbdev/s3fb.c
+++ b/drivers/video/fbdev/s3fb.c
@@ -12,6 +12,7 @@
*/

#include <linux/aperture.h>
+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -1521,18 +1522,15 @@ static struct pci_driver s3fb_pci_driver = {
/* Parse user specified options */

#ifndef MODULE
-static int __init s3fb_setup(char *options)
+static int __init s3fb_setup(const char *options)
{
+ struct option_iter iter;
char *opt;

- if (!options || !*options)
- return 0;
-
- while ((opt = strsep(&options, ",")) != NULL) {
+ option_iter_init(&iter, options);

- if (!*opt)
- continue;
- else if (!strncmp(opt, "mtrr:", 5))
+ while (option_iter_next(&iter, &opt)) {
+ if (!strncmp(opt, "mtrr:", 5))
mtrr = simple_strtoul(opt + 5, NULL, 0);
else if (!strncmp(opt, "fasttext:", 9))
fasttext = simple_strtoul(opt + 9, NULL, 0);
@@ -1543,6 +1541,8 @@ static int __init s3fb_setup(char *options)
}
}

+ option_iter_release(&iter);
+
return 0;
}
#endif
--
2.39.2


2023-03-09 16:08:50

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 063/101] fbdev/pvr2fb: Duplicate video-mode option string

Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with kstrdup() and free it in the module's exit function,
as well as the init function's error handling.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

v2:
* replace static memory with kstrdup()/kfree() (Geert)

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/pvr2fb.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/pvr2fb.c b/drivers/video/fbdev/pvr2fb.c
index 6888127a5eb8..f6be2649840d 100644
--- a/drivers/video/fbdev/pvr2fb.c
+++ b/drivers/video/fbdev/pvr2fb.c
@@ -225,6 +225,7 @@ static struct fb_videomode pvr2_modedb[] = {
#define DEFMODE_VGA 2

static int defmode = DEFMODE_NTSC;
+static char *mode_option_buf;
static char *mode_option = NULL;

static inline void pvr2fb_set_pal_type(unsigned int type)
@@ -1049,7 +1050,9 @@ static int __init pvr2fb_setup(char *options)
} else if (!strncmp(this_opt, "nowrap", 6)) {
nowrap = 1;
} else {
- mode_option = this_opt;
+ kfree(mode_option_buf);
+ mode_option_buf = kstrdup(this_opt, GFP_KERNEL); // ignore errors
+ mode_option = mode_option_buf;
}
}

@@ -1094,8 +1097,11 @@ static int __init pvr2fb_init(void)
#endif

fb_info = framebuffer_alloc(sizeof(struct pvr2fb_par), NULL);
- if (!fb_info)
+ if (!fb_info) {
+ kfree(mode_option_buf);
+ mode_option_buf = NULL;
return -ENOMEM;
+ }

currentpar = fb_info->par;

@@ -1111,6 +1117,8 @@ static int __init pvr2fb_init(void)
printk(KERN_ERR "pvr2fb: Failed init of %s device\n",
pvr_board->name);
framebuffer_release(fb_info);
+ kfree(mode_option_buf);
+ mode_option_buf = NULL;
break;
}
}
@@ -1135,6 +1143,7 @@ static void __exit pvr2fb_exit(void)

unregister_framebuffer(fb_info);
framebuffer_release(fb_info);
+ kfree(mode_option_buf);
}

module_init(pvr2fb_init);
--
2.39.2


2023-03-09 16:08:54

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 066/101] fbdev/rivafb: Duplicate video-mode option string

Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with kstrdup() and free it in the module's exit function.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

v2:
* replace static memory with kstrdup()/kfree() (Geert)

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/riva/fbdev.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/riva/fbdev.c b/drivers/video/fbdev/riva/fbdev.c
index 41edc6e79460..8a7dc7452938 100644
--- a/drivers/video/fbdev/riva/fbdev.c
+++ b/drivers/video/fbdev/riva/fbdev.c
@@ -205,6 +205,7 @@ static bool noaccel = 0;
static bool nomtrr = 0;
static int backlight = IS_BUILTIN(CONFIG_PMAC_BACKLIGHT);

+static char *mode_option_buf;
static char *mode_option = NULL;
static bool strictmode = 0;

@@ -2132,8 +2133,11 @@ static int rivafb_setup(char *options)
strictmode = 1;
} else if (!strncmp(this_opt, "noaccel", 7)) {
noaccel = 1;
- } else
- mode_option = this_opt;
+ } else {
+ kfree(mode_option_buf);
+ mode_option_buf = kstrdup(this_opt, GFP_KERNEL); // ignore errors
+ mode_option = mode_option_buf;
+ }
}
NVTRACE_LEAVE();
return 0;
@@ -2178,6 +2182,7 @@ module_init(rivafb_init);
static void __exit rivafb_exit(void)
{
pci_unregister_driver(&rivafb_driver);
+ kfree(mode_option_buf);
}

module_exit(rivafb_exit);
--
2.39.2


2023-03-09 16:09:00

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 067/101] fbdev/rivafb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/riva/fbdev.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/video/fbdev/riva/fbdev.c b/drivers/video/fbdev/riva/fbdev.c
index 8a7dc7452938..7f35edad249e 100644
--- a/drivers/video/fbdev/riva/fbdev.c
+++ b/drivers/video/fbdev/riva/fbdev.c
@@ -30,6 +30,7 @@
*/

#include <linux/aperture.h>
+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -2106,17 +2107,18 @@ static void rivafb_remove(struct pci_dev *pd)
* ------------------------------------------------------------------------- */

#ifndef MODULE
-static int rivafb_setup(char *options)
+static int rivafb_setup(const char *options)
{
+ struct option_iter iter;
char *this_opt;

NVTRACE_ENTER();
- if (!options || !*options)
- return 0;

- while ((this_opt = strsep(&options, ",")) != NULL) {
+ option_iter_init(&iter, options);
+
+ while (option_iter_next(&iter, &this_opt)) {
if (!strncmp(this_opt, "forceCRTC", 9)) {
- char *p;
+ const char *p;

p = this_opt + 9;
if (!*p || !*(++p)) continue;
@@ -2139,6 +2141,9 @@ static int rivafb_setup(char *options)
mode_option = mode_option_buf;
}
}
+
+ option_iter_release(&iter);
+
NVTRACE_LEAVE();
return 0;
}
--
2.39.2


2023-03-09 16:09:05

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 070/101] fbdev/savagefb: Duplicate video-mode option string

Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with kstrdup() and free it in the module's exit function.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

v2:
* replace static memory with kstrdup()/kfree() (Geert)

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/savage/savagefb_driver.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/savage/savagefb_driver.c b/drivers/video/fbdev/savage/savagefb_driver.c
index 4a27b68798bf..0ca5894114c9 100644
--- a/drivers/video/fbdev/savage/savagefb_driver.c
+++ b/drivers/video/fbdev/savage/savagefb_driver.c
@@ -65,6 +65,7 @@
/* --------------------------------------------------------------------- */


+static char *mode_option_buf;
static char *mode_option = NULL;

#ifdef MODULE
@@ -2530,6 +2531,7 @@ static void __exit savage_done(void)
{
DBG("savage_done");
pci_unregister_driver(&savagefb_driver);
+ kfree(mode_option_buf);
}


@@ -2544,7 +2546,9 @@ static int __init savagefb_setup(char *options)
return 0;

while ((this_opt = strsep(&options, ",")) != NULL) {
- mode_option = this_opt;
+ kfree(mode_option_buf);
+ mode_option_buf = kstrdup(this_opt, GFP_KERNEL); // ignore errors
+ mode_option = mode_option_buf;
}
#endif /* !MODULE */
return 0;
--
2.39.2


2023-03-09 16:09:11

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 073/101] fbdev/sisfb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/sis/sis_main.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/video/fbdev/sis/sis_main.c b/drivers/video/fbdev/sis/sis_main.c
index c16493d3ac4f..9f63812a5f66 100644
--- a/drivers/video/fbdev/sis/sis_main.c
+++ b/drivers/video/fbdev/sis/sis_main.c
@@ -20,6 +20,7 @@
*/

#include <linux/aperture.h>
+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
@@ -54,7 +55,7 @@

/* Interface used by the world */
#ifndef MODULE
-static int sisfb_setup(char *options);
+static int sisfb_setup(const char *options);
#endif

/* Interface to the low level console driver */
@@ -3987,19 +3988,16 @@ sisfb_handle_command(struct sis_video_info *ivideo, struct sisfb_cmd *sisfb_comm
}

#ifndef MODULE
-static int __init sisfb_setup(char *options)
+static int __init sisfb_setup(const char *options)
{
+ struct option_iter iter;
char *this_opt;

sisfb_setdefaultparms();

- if(!options || !(*options))
- return 0;
-
- while((this_opt = strsep(&options, ",")) != NULL) {
-
- if(!(*this_opt)) continue;
+ option_iter_init(&iter, options);

+ while (option_iter_next(&iter, &this_opt)) {
if(!strncasecmp(this_opt, "off", 3)) {
sisfb_off = 1;
} else if(!strncasecmp(this_opt, "forcecrt2type:", 14)) {
@@ -4081,6 +4079,8 @@ static int __init sisfb_setup(char *options)

}

+ option_iter_release(&iter);
+
return 0;
}
#endif
--
2.39.2


2023-03-09 16:09:15

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 074/101] fbdev/skeletonfb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/skeletonfb.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/skeletonfb.c b/drivers/video/fbdev/skeletonfb.c
index 40c130ab6b38..ee6944d0ebc1 100644
--- a/drivers/video/fbdev/skeletonfb.c
+++ b/drivers/video/fbdev/skeletonfb.c
@@ -43,6 +43,7 @@
*/

#include <linux/aperture.h>
+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -973,9 +974,19 @@ static struct platform_device *xxxfb_device;
* Only necessary if your driver takes special options,
* otherwise we fall back on the generic fb_setup().
*/
-static int __init xxxfb_setup(char *options)
+static int __init xxxfb_setup(const char *options)
{
- /* Parse user specified options (`video=xxxfb:') */
+ /* Parse user-specified options (`video=xxxfb:') */
+
+ struct option_iter iter;
+ char *this_opt;
+
+ option_iter_init(&iter, options);
+
+ while (option_iter_next(&iter, &this_opt)) {
+ }
+
+ option_iter_release(&iter);
}
#endif /* MODULE */

--
2.39.2


2023-03-09 16:09:21

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 076/101] fbdev/sstfb: Duplicate video-mode option string

Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with kstrdup() and free it in the module's exit function.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

v2:
* replace static memory with kstrdup()/kfree() (Geert)

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/sstfb.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/sstfb.c b/drivers/video/fbdev/sstfb.c
index da296b2ab54a..f422b1882950 100644
--- a/drivers/video/fbdev/sstfb.c
+++ b/drivers/video/fbdev/sstfb.c
@@ -106,6 +106,7 @@ static bool slowpci; /* slow PCI settings */
*/
#define DEFAULT_VIDEO_MODE "640x480@60"

+static char *mode_option_buf;
static char *mode_option = DEFAULT_VIDEO_MODE;

enum {
@@ -1301,8 +1302,11 @@ static int sstfb_setup(char *options)
mem = simple_strtoul (this_opt+4, NULL, 0);
else if (!strncmp(this_opt, "gfxclk:",7))
gfxclk = simple_strtoul (this_opt+7, NULL, 0);
- else
- mode_option = this_opt;
+ else {
+ kfree(mode_option_buf);
+ mode_option_buf = kstrdup(this_opt, GFP_KERNEL); // ignore errors
+ mode_option = mode_option_buf;
+ }
}
return 0;
}
@@ -1516,6 +1520,7 @@ static int sstfb_init(void)
static void sstfb_exit(void)
{
pci_unregister_driver(&sstfb_driver);
+ kfree(mode_option_buf);
}


--
2.39.2


2023-03-09 16:09:27

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 075/101] fbdev/sm712fb: Duplicate video-mode option string

Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with kstrdup() and free it in the module's exit function.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

v2:
* replace static memory with kstrdup()/kfree() (Geert)

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/sm712fb.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/sm712fb.c b/drivers/video/fbdev/sm712fb.c
index b528776c7612..a83f48fce5b1 100644
--- a/drivers/video/fbdev/sm712fb.c
+++ b/drivers/video/fbdev/sm712fb.c
@@ -831,6 +831,7 @@ static const struct modeinit vgamode[] = {

static struct screen_info smtc_scr_info;

+static char *mode_option_buf;
static char *mode_option;

/* process command line options, get vga parameter */
@@ -1761,8 +1762,12 @@ static int __init sm712fb_init(void)

if (fb_get_options("sm712fb", &option))
return -ENODEV;
- if (option && *option)
- mode_option = option;
+
+ if (option && *option) {
+ mode_option_buf = kstrdup(option, GFP_KERNEL); // ignore errors
+ mode_option = mode_option_buf;
+ }
+
sm7xx_vga_setup(mode_option);

return pci_register_driver(&smtcfb_driver);
@@ -1773,6 +1778,7 @@ module_init(sm712fb_init);
static void __exit sm712fb_exit(void)
{
pci_unregister_driver(&smtcfb_driver);
+ kfree(mode_option_buf);
}

module_exit(sm712fb_exit);
--
2.39.2


2023-03-09 16:09:32

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 071/101] fbdev/savagefb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/savage/savagefb_driver.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/video/fbdev/savage/savagefb_driver.c b/drivers/video/fbdev/savage/savagefb_driver.c
index 0ca5894114c9..4650688fd23c 100644
--- a/drivers/video/fbdev/savage/savagefb_driver.c
+++ b/drivers/video/fbdev/savage/savagefb_driver.c
@@ -42,6 +42,7 @@
*/

#include <linux/aperture.h>
+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -2537,19 +2538,22 @@ static void __exit savage_done(void)

/* ************************* init in-kernel code ************************** */

-static int __init savagefb_setup(char *options)
+static int __init savagefb_setup(const char *options)
{
#ifndef MODULE
+ struct option_iter iter;
char *this_opt;

- if (!options || !*options)
- return 0;
+ option_iter_init(&iter, options);

- while ((this_opt = strsep(&options, ",")) != NULL) {
+ while (option_iter_next(&iter, &this_opt)) {
kfree(mode_option_buf);
mode_option_buf = kstrdup(this_opt, GFP_KERNEL); // ignore errors
mode_option = mode_option_buf;
}
+
+ option_iter_release(&iter);
+
#endif /* !MODULE */
return 0;
}
--
2.39.2


2023-03-09 16:09:35

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 072/101] fbdev/sisfb: Constify mode string

Constify the intenal video-mode string that is passed around among
functions. The caller owns the memory and callees do not modify its
content. This change will later allow to constify the option string.
No functional changes.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/sis/sis_main.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/video/fbdev/sis/sis_main.c b/drivers/video/fbdev/sis/sis_main.c
index cfba776afcea..c16493d3ac4f 100644
--- a/drivers/video/fbdev/sis/sis_main.c
+++ b/drivers/video/fbdev/sis/sis_main.c
@@ -73,7 +73,7 @@ static int sisfb_blank(int blank,
static void sisfb_handle_command(struct sis_video_info *ivideo,
struct sisfb_cmd *sisfb_command);

-static void sisfb_search_mode(char *name, bool quiet);
+static void sisfb_search_mode(const char *name, bool quiet);
static int sisfb_validate_mode(struct sis_video_info *ivideo, int modeindex, u32 vbflags);
static u8 sisfb_search_refresh_rate(struct sis_video_info *ivideo, unsigned int rate,
int index);
@@ -180,12 +180,12 @@ static void sisfb_search_vesamode(unsigned int vesamode, bool quiet)
printk(KERN_ERR "sisfb: Invalid VESA mode 0x%x'\n", vesamode);
}

-static void sisfb_search_mode(char *name, bool quiet)
+static void sisfb_search_mode(const char *name, bool quiet)
{
unsigned int j = 0, xres = 0, yres = 0, depth = 0, rate = 0;
int i = 0;
char strbuf[16], strbuf1[20];
- char *nameptr = name;
+ const char *nameptr = name;

/* We don't know the hardware specs yet and there is no ivideo */

--
2.39.2


2023-03-09 16:09:39

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 081/101] fbdev/tdfxfb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/tdfxfb.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/video/fbdev/tdfxfb.c b/drivers/video/fbdev/tdfxfb.c
index ccce6dac443d..1fdaf328f03e 100644
--- a/drivers/video/fbdev/tdfxfb.c
+++ b/drivers/video/fbdev/tdfxfb.c
@@ -65,6 +65,7 @@
*/

#include <linux/aperture.h>
+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -1571,16 +1572,14 @@ static int tdfxfb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
}

#ifndef MODULE
-static void __init tdfxfb_setup(char *options)
+static void __init tdfxfb_setup(const char *options)
{
+ struct option_iter iter;
char *this_opt;

- if (!options || !*options)
- return;
+ option_iter_init(&iter, options);

- while ((this_opt = strsep(&options, ",")) != NULL) {
- if (!*this_opt)
- continue;
+ while (option_iter_next(&iter, &this_opt)) {
if (!strcmp(this_opt, "nopan")) {
nopan = 1;
} else if (!strcmp(this_opt, "nowrap")) {
@@ -1595,6 +1594,8 @@ static void __init tdfxfb_setup(char *options)
mode_option = mode_option_buf;
}
}
+
+ option_iter_release(&iter);
}
#endif

--
2.39.2


2023-03-09 16:09:44

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 083/101] fbdev/tgafb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/tgafb.c | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/video/fbdev/tgafb.c b/drivers/video/fbdev/tgafb.c
index cf00b8a91bfb..0862d9a54aef 100644
--- a/drivers/video/fbdev/tgafb.c
+++ b/drivers/video/fbdev/tgafb.c
@@ -14,6 +14,7 @@

#include <linux/aperture.h>
#include <linux/bitrev.h>
+#include <linux/cmdline.h>
#include <linux/compiler.h>
#include <linux/delay.h>
#include <linux/device.h>
@@ -1573,25 +1574,24 @@ static void tgafb_exit(void)
}

#ifndef MODULE
-static int tgafb_setup(char *arg)
+static int tgafb_setup(const char *arg)
{
+ struct option_iter iter;
char *this_opt;

- if (arg && *arg) {
- while ((this_opt = strsep(&arg, ","))) {
- if (!*this_opt)
- continue;
- if (!strncmp(this_opt, "mode:", 5)) {
- kfree(mode_option_buf);
- mode_option_buf = kstrdup(this_opt, GFP_KERNEL); // ignore errors
- mode_option = mode_option_buf;
- } else
- printk(KERN_ERR
- "tgafb: unknown parameter %s\n",
- this_opt);
- }
+ option_iter_init(&iter, arg);
+
+ while (option_iter_next(&iter, &this_opt)) {
+ if (!strncmp(this_opt, "mode:", 5)) {
+ kfree(mode_option_buf);
+ mode_option_buf = kstrdup(this_opt, GFP_KERNEL); // ignore errors
+ mode_option = mode_option_buf;
+ } else
+ printk(KERN_ERR "tgafb: unknown parameter %s\n", this_opt);
}

+ option_iter_release(&iter);
+
return 0;
}
#endif /* !MODULE */
--
2.39.2


2023-03-09 16:11:26

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 084/101] fbdev/tmiofb: Remove unused option string

The option string is unused. Remove the variable and a related
helper function. No functional change.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/tmiofb.c | 24 ++----------------------
1 file changed, 2 insertions(+), 22 deletions(-)

diff --git a/drivers/video/fbdev/tmiofb.c b/drivers/video/fbdev/tmiofb.c
index 50111966c981..8920cee52d7f 100644
--- a/drivers/video/fbdev/tmiofb.c
+++ b/drivers/video/fbdev/tmiofb.c
@@ -11,6 +11,7 @@
* code written by Sharp/Lineo for 2.4 kernels
*/

+#include <linux/cmdline.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
@@ -997,32 +998,11 @@ static struct platform_driver tmiofb_driver = {

/*--------------------------------------------------------------------------*/

-#ifndef MODULE
-static void __init tmiofb_setup(char *options)
-{
- char *this_opt;
-
- if (!options || !*options)
- return;
-
- while ((this_opt = strsep(&options, ",")) != NULL) {
- if (!*this_opt)
- continue;
- /*
- * FIXME
- */
- }
-}
-#endif
-
static int __init tmiofb_init(void)
{
#ifndef MODULE
- char *option = NULL;
-
- if (fb_get_options("tmiofb", &option))
+ if (fb_get_options("tmiofb", NULL))
return -ENODEV;
- tmiofb_setup(option);
#endif
return platform_driver_register(&tmiofb_driver);
}
--
2.39.2


2023-03-09 16:11:26

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 080/101] fbdev/tdfxfb: Duplicate video-mode option string

Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with kstrdup() and free it in the module's exit function.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

v2:
* replace static memory with kstrdup()/kfree() (Geert)

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/tdfxfb.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/tdfxfb.c b/drivers/video/fbdev/tdfxfb.c
index d17e5e1472aa..ccce6dac443d 100644
--- a/drivers/video/fbdev/tdfxfb.c
+++ b/drivers/video/fbdev/tdfxfb.c
@@ -150,6 +150,7 @@ MODULE_DEVICE_TABLE(pci, tdfxfb_id_table);
static int nopan;
static int nowrap = 1; /* not implemented (yet) */
static int hwcursor = 1;
+static char *mode_option_buf;
static char *mode_option;
static bool nomtrr;

@@ -1589,7 +1590,9 @@ static void __init tdfxfb_setup(char *options)
} else if (!strncmp(this_opt, "nomtrr", 6)) {
nomtrr = 1;
} else {
- mode_option = this_opt;
+ kfree(mode_option_buf);
+ mode_option_buf = kstrdup(this_opt, GFP_KERNEL); // ignore errors
+ mode_option = mode_option_buf;
}
}
}
@@ -1649,6 +1652,7 @@ static int __init tdfxfb_init(void)
static void __exit tdfxfb_exit(void)
{
pci_unregister_driver(&tdfxfb_driver);
+ kfree(mode_option_buf);
}

MODULE_AUTHOR("Hannu Mallat <[email protected]>");
--
2.39.2


2023-03-09 16:11:26

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 077/101] fbdev/sstfb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/sstfb.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/video/fbdev/sstfb.c b/drivers/video/fbdev/sstfb.c
index f422b1882950..b509020fed74 100644
--- a/drivers/video/fbdev/sstfb.c
+++ b/drivers/video/fbdev/sstfb.c
@@ -81,6 +81,7 @@
*/

#include <linux/aperture.h>
+#include <linux/cmdline.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/module.h>
@@ -1274,16 +1275,14 @@ static void sst_shutdown(struct fb_info *info)
/*
* Interface to the world
*/
-static int sstfb_setup(char *options)
+static int sstfb_setup(const char *options)
{
+ struct option_iter iter;
char *this_opt;

- if (!options || !*options)
- return 0;
-
- while ((this_opt = strsep(&options, ",")) != NULL) {
- if (!*this_opt) continue;
+ option_iter_init(&iter, options);

+ while (option_iter_next(&iter, &this_opt)) {
f_ddprintk("option %s\n", this_opt);

if (!strcmp(this_opt, "vganopass"))
@@ -1308,6 +1307,9 @@ static int sstfb_setup(char *options)
mode_option = mode_option_buf;
}
}
+
+ option_iter_release(&iter);
+
return 0;
}

--
2.39.2


2023-03-09 16:11:26

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 082/101] fbdev/tgafb: Duplicate video-mode option string

Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with kstrdup() and free it in the module's exit function.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

v2:
* replace static memory with kstrdup()/kfree() (Geert)

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/tgafb.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/video/fbdev/tgafb.c b/drivers/video/fbdev/tgafb.c
index 14d37c49633c..cf00b8a91bfb 100644
--- a/drivers/video/fbdev/tgafb.c
+++ b/drivers/video/fbdev/tgafb.c
@@ -59,6 +59,7 @@ static int tgafb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info
static int tgafb_register(struct device *dev);
static void tgafb_unregister(struct device *dev);

+static const char *mode_option_buf;
static const char *mode_option;
static const char *mode_option_pci = "640x480@60";
static const char *mode_option_tc = "1280x1024@72";
@@ -1568,6 +1569,7 @@ static void tgafb_exit(void)
{
tc_unregister_driver(&tgafb_tc_driver);
pci_unregister_driver(&tgafb_pci_driver);
+ kfree(mode_option_buf);
}

#ifndef MODULE
@@ -1579,9 +1581,11 @@ static int tgafb_setup(char *arg)
while ((this_opt = strsep(&arg, ","))) {
if (!*this_opt)
continue;
- if (!strncmp(this_opt, "mode:", 5))
- mode_option = this_opt+5;
- else
+ if (!strncmp(this_opt, "mode:", 5)) {
+ kfree(mode_option_buf);
+ mode_option_buf = kstrdup(this_opt, GFP_KERNEL); // ignore errors
+ mode_option = mode_option_buf;
+ } else
printk(KERN_ERR
"tgafb: unknown parameter %s\n",
this_opt);
--
2.39.2


2023-03-09 16:11:28

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 086/101] fbdev/tridentfb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/tridentfb.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/video/fbdev/tridentfb.c b/drivers/video/fbdev/tridentfb.c
index dbde64aef91f..3299806c0f58 100644
--- a/drivers/video/fbdev/tridentfb.c
+++ b/drivers/video/fbdev/tridentfb.c
@@ -17,6 +17,7 @@
*/

#include <linux/aperture.h>
+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/fb.h>
#include <linux/init.h>
@@ -1775,14 +1776,14 @@ static struct pci_driver tridentfb_pci_driver = {
* video=trident:800x600,bpp=16,noaccel
*/
#ifndef MODULE
-static int __init tridentfb_setup(char *options)
+static int __init tridentfb_setup(const char *options)
{
+ struct option_iter iter;
char *opt;
- if (!options || !*options)
- return 0;
- while ((opt = strsep(&options, ",")) != NULL) {
- if (!*opt)
- continue;
+
+ option_iter_init(&iter, options);
+
+ while (option_iter_next(&iter, &opt)) {
if (!strncmp(opt, "noaccel", 7))
noaccel = 1;
else if (!strncmp(opt, "fp", 2))
@@ -1807,6 +1808,9 @@ static int __init tridentfb_setup(char *options)
mode_option = mode_option_buf;
}
}
+
+ option_iter_release(&iter);
+
return 0;
}
#endif
--
2.39.2


2023-03-09 16:11:28

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 079/101] fbdev/stifb: Constify option string

Constify the internal option string that is passed around among
functions. The caller owns the memory and callees do not modify
its content. This change will later allow to constify the caller's
option string as well. No functional changes.

v2:
* say 'stifb' and fix typos in commit message

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/stifb.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/stifb.c b/drivers/video/fbdev/stifb.c
index a151377f5b45..304ce8fcb9f8 100644
--- a/drivers/video/fbdev/stifb.c
+++ b/drivers/video/fbdev/stifb.c
@@ -1392,7 +1392,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
static int stifb_disabled __initdata;

int __init
-stifb_setup(char *options);
+stifb_setup(const char *options);

static int __init stifb_init(void)
{
@@ -1465,7 +1465,7 @@ stifb_cleanup(void)
}

int __init
-stifb_setup(char *options)
+stifb_setup(const char *options)
{
int i;

--
2.39.2


2023-03-09 16:11:26

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 078/101] fbdev/stifb: Remove trailing whitespaces

Fix coding style. No functional changes.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/stifb.c | 156 ++++++++++++++++++------------------
1 file changed, 78 insertions(+), 78 deletions(-)

diff --git a/drivers/video/fbdev/stifb.c b/drivers/video/fbdev/stifb.c
index 3feb6e40d56d..a151377f5b45 100644
--- a/drivers/video/fbdev/stifb.c
+++ b/drivers/video/fbdev/stifb.c
@@ -1,11 +1,11 @@
/*
- * linux/drivers/video/stifb.c -
- * Low level Frame buffer driver for HP workstations with
+ * linux/drivers/video/stifb.c -
+ * Low level Frame buffer driver for HP workstations with
* STI (standard text interface) video firmware.
*
* Copyright (C) 2001-2006 Helge Deller <[email protected]>
* Portions Copyright (C) 2001 Thomas Bogendoerfer <[email protected]>
- *
+ *
* Based on:
* - linux/drivers/video/artistfb.c -- Artist frame buffer driver
* Copyright (C) 2000 Philipp Rumpf <[email protected]>
@@ -14,7 +14,7 @@
* - HP Xhp cfb-based X11 window driver for XFree86
* (c)Copyright 1992 Hewlett-Packard Co.
*
- *
+ *
* The following graphics display devices (NGLE family) are supported by this driver:
*
* HPA4070A known as "HCRX", a 1280x1024 color device with 8 planes
@@ -30,7 +30,7 @@
* supports 1280x1024 color displays with 8 planes.
* HP710G same as HP710C, 1280x1024 grayscale only
* HP710L same as HP710C, 1024x768 color only
- * HP712 internal graphics support on HP9000s712 SPU, supports 640x480,
+ * HP712 internal graphics support on HP9000s712 SPU, supports 640x480,
* 1024x768 or 1280x1024 color displays on 8 planes (Artist)
*
* This file is subject to the terms and conditions of the GNU General Public
@@ -92,7 +92,7 @@ typedef struct {
__s32 misc_video_end;
} video_setup_t;

-typedef struct {
+typedef struct {
__s16 sizeof_ngle_data;
__s16 x_size_visible; /* visible screen dim in pixels */
__s16 y_size_visible;
@@ -177,10 +177,10 @@ static int __initdata stifb_bpp_pref[MAX_STI_ROMS];
#endif /* DEBUG_STIFB_REGS */


-#define ENABLE 1 /* for enabling/disabling screen */
+#define ENABLE 1 /* for enabling/disabling screen */
#define DISABLE 0

-#define NGLE_LOCK(fb_info) do { } while (0)
+#define NGLE_LOCK(fb_info) do { } while (0)
#define NGLE_UNLOCK(fb_info) do { } while (0)

static void
@@ -198,9 +198,9 @@ SETUP_HW(struct stifb_info *fb)

static void
SETUP_FB(struct stifb_info *fb)
-{
+{
unsigned int reg10_value = 0;
-
+
SETUP_HW(fb);
switch (fb->id)
{
@@ -210,15 +210,15 @@ SETUP_FB(struct stifb_info *fb)
reg10_value = 0x13601000;
break;
case S9000_ID_A1439A:
- if (fb->info.var.bits_per_pixel == 32)
+ if (fb->info.var.bits_per_pixel == 32)
reg10_value = 0xBBA0A000;
- else
+ else
reg10_value = 0x13601000;
break;
case S9000_ID_HCRX:
if (fb->info.var.bits_per_pixel == 32)
reg10_value = 0xBBA0A000;
- else
+ else
reg10_value = 0x13602000;
break;
case S9000_ID_TIMBER:
@@ -243,7 +243,7 @@ START_IMAGE_COLORMAP_ACCESS(struct stifb_info *fb)
}

static void
-WRITE_IMAGE_COLOR(struct stifb_info *fb, int index, int color)
+WRITE_IMAGE_COLOR(struct stifb_info *fb, int index, int color)
{
SETUP_HW(fb);
WRITE_WORD(((0x100+index)<<2), fb, REG_3);
@@ -251,30 +251,30 @@ WRITE_IMAGE_COLOR(struct stifb_info *fb, int index, int color)
}

static void
-FINISH_IMAGE_COLORMAP_ACCESS(struct stifb_info *fb)
-{
+FINISH_IMAGE_COLORMAP_ACCESS(struct stifb_info *fb)
+{
WRITE_WORD(0x400, fb, REG_2);
if (fb->info.var.bits_per_pixel == 32) {
WRITE_WORD(0x83000100, fb, REG_1);
} else {
if (fb->id == S9000_ID_ARTIST || fb->id == CRT_ID_VISUALIZE_EG)
WRITE_WORD(0x80000100, fb, REG_26);
- else
+ else
WRITE_WORD(0x80000100, fb, REG_1);
}
SETUP_FB(fb);
}

static void
-SETUP_RAMDAC(struct stifb_info *fb)
+SETUP_RAMDAC(struct stifb_info *fb)
{
SETUP_HW(fb);
WRITE_WORD(0x04000000, fb, 0x1020);
WRITE_WORD(0xff000000, fb, 0x1028);
}

-static void
-CRX24_SETUP_RAMDAC(struct stifb_info *fb)
+static void
+CRX24_SETUP_RAMDAC(struct stifb_info *fb)
{
SETUP_HW(fb);
WRITE_WORD(0x04000000, fb, 0x1000);
@@ -286,14 +286,14 @@ CRX24_SETUP_RAMDAC(struct stifb_info *fb)
}

#if 0
-static void
+static void
HCRX_SETUP_RAMDAC(struct stifb_info *fb)
{
WRITE_WORD(0xffffffff, fb, REG_32);
}
#endif

-static void
+static void
CRX24_SET_OVLY_MASK(struct stifb_info *fb)
{
SETUP_HW(fb);
@@ -314,7 +314,7 @@ ENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable)
WRITE_WORD(value, fb, 0x1038);
}

-static void
+static void
CRX24_ENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable)
{
unsigned int value = enable ? 0x10000000 : 0x30000000;
@@ -325,11 +325,11 @@ CRX24_ENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable)
}

static void
-ARTIST_ENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable)
+ARTIST_ENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable)
{
u32 DregsMiscVideo = REG_21;
u32 DregsMiscCtl = REG_27;
-
+
SETUP_HW(fb);
if (enable) {
WRITE_WORD(READ_WORD(fb, DregsMiscVideo) | 0x0A000000, fb, DregsMiscVideo);
@@ -344,7 +344,7 @@ ARTIST_ENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable)
(READ_BYTE(fb, REG_16b3) - 1)

#define HYPER_CONFIG_PLANES_24 0x00000100
-
+
#define IS_24_DEVICE(fb) \
(fb->deviceSpecificConfig & HYPER_CONFIG_PLANES_24)

@@ -470,15 +470,15 @@ SETUP_ATTR_ACCESS(struct stifb_info *fb, unsigned BufferNumber)
}

static void
-SET_ATTR_SIZE(struct stifb_info *fb, int width, int height)
+SET_ATTR_SIZE(struct stifb_info *fb, int width, int height)
{
- /* REG_6 seems to have special values when run on a
+ /* REG_6 seems to have special values when run on a
RDI precisionbook parisc laptop (INTERNAL_EG_DX1024 or
INTERNAL_EG_X1024). The values are:
0x2f0: internal (LCD) & external display enabled
0x2a0: external display only
0x000: zero on standard artist graphic cards
- */
+ */
WRITE_WORD(0x00000000, fb, REG_6);
WRITE_WORD((width<<16) | height, fb, REG_9);
WRITE_WORD(0x05000000, fb, REG_6);
@@ -486,7 +486,7 @@ SET_ATTR_SIZE(struct stifb_info *fb, int width, int height)
}

static void
-FINISH_ATTR_ACCESS(struct stifb_info *fb)
+FINISH_ATTR_ACCESS(struct stifb_info *fb)
{
SETUP_HW(fb);
WRITE_WORD(0x00000000, fb, REG_12);
@@ -499,7 +499,7 @@ elkSetupPlanes(struct stifb_info *fb)
SETUP_FB(fb);
}

-static void
+static void
ngleSetupAttrPlanes(struct stifb_info *fb, int BufferNumber)
{
SETUP_ATTR_ACCESS(fb, BufferNumber);
@@ -519,7 +519,7 @@ rattlerSetupPlanes(struct stifb_info *fb)
* read mask register for overlay planes, not image planes).
*/
CRX24_SETUP_RAMDAC(fb);
-
+
/* change fb->id temporarily to fool SETUP_FB() */
saved_id = fb->id;
fb->id = CRX24_OVERLAY_PLANES;
@@ -565,7 +565,7 @@ setNgleLutBltCtl(struct stifb_info *fb, int offsetWithinLut, int length)
lutBltCtl.all = 0x80000000;
lutBltCtl.fields.length = length;

- switch (fb->id)
+ switch (fb->id)
{
case S9000_ID_A1439A: /* CRX24 */
if (fb->var.bits_per_pixel == 8) {
@@ -576,12 +576,12 @@ setNgleLutBltCtl(struct stifb_info *fb, int offsetWithinLut, int length)
lutBltCtl.fields.lutOffset = 0 * 256;
}
break;
-
+
case S9000_ID_ARTIST:
lutBltCtl.fields.lutType = NGLE_CMAP_INDEXED0_TYPE;
lutBltCtl.fields.lutOffset = 0 * 256;
break;
-
+
default:
lutBltCtl.fields.lutType = NGLE_CMAP_INDEXED0_TYPE;
lutBltCtl.fields.lutOffset = 0;
@@ -596,7 +596,7 @@ setNgleLutBltCtl(struct stifb_info *fb, int offsetWithinLut, int length)
#endif

static NgleLutBltCtl
-setHyperLutBltCtl(struct stifb_info *fb, int offsetWithinLut, int length)
+setHyperLutBltCtl(struct stifb_info *fb, int offsetWithinLut, int length)
{
NgleLutBltCtl lutBltCtl;

@@ -633,7 +633,7 @@ static void hyperUndoITE(struct stifb_info *fb)

/* Hardware setup for full-depth write to "magic" location */
GET_FIFO_SLOTS(fb, nFreeFifoSlots, 7);
- NGLE_QUICK_SET_DST_BM_ACCESS(fb,
+ NGLE_QUICK_SET_DST_BM_ACCESS(fb,
BA(IndexedDcd, Otc04, Ots08, AddrLong,
BAJustPoint(0), BINovly, BAIndexBase(0)));
NGLE_QUICK_SET_IMAGE_BITMAP_OP(fb,
@@ -653,13 +653,13 @@ static void hyperUndoITE(struct stifb_info *fb)
NGLE_UNLOCK(fb);
}

-static void
+static void
ngleDepth8_ClearImagePlanes(struct stifb_info *fb)
{
/* FIXME! */
}

-static void
+static void
ngleDepth24_ClearImagePlanes(struct stifb_info *fb)
{
/* FIXME! */
@@ -675,7 +675,7 @@ ngleResetAttrPlanes(struct stifb_info *fb, unsigned int ctlPlaneReg)
NGLE_LOCK(fb);

GET_FIFO_SLOTS(fb, nFreeFifoSlots, 4);
- NGLE_QUICK_SET_DST_BM_ACCESS(fb,
+ NGLE_QUICK_SET_DST_BM_ACCESS(fb,
BA(IndexedDcd, Otc32, OtsIndirect,
AddrLong, BAJustPoint(0),
BINattr, BAIndexBase(0)));
@@ -713,22 +713,22 @@ ngleResetAttrPlanes(struct stifb_info *fb, unsigned int ctlPlaneReg)
/**** Finally, set the Control Plane Register back to zero: ****/
GET_FIFO_SLOTS(fb, nFreeFifoSlots, 1);
NGLE_QUICK_SET_CTL_PLN_REG(fb, 0);
-
+
NGLE_UNLOCK(fb);
}
-
+
static void
ngleClearOverlayPlanes(struct stifb_info *fb, int mask, int data)
{
int nFreeFifoSlots = 0;
u32 packed_dst;
u32 packed_len;
-
+
NGLE_LOCK(fb);

/* Hardware setup */
GET_FIFO_SLOTS(fb, nFreeFifoSlots, 8);
- NGLE_QUICK_SET_DST_BM_ACCESS(fb,
+ NGLE_QUICK_SET_DST_BM_ACCESS(fb,
BA(IndexedDcd, Otc04, Ots08, AddrLong,
BAJustPoint(0), BINovly, BAIndexBase(0)));

@@ -736,23 +736,23 @@ ngleClearOverlayPlanes(struct stifb_info *fb, int mask, int data)

NGLE_REALLY_SET_IMAGE_FG_COLOR(fb, data);
NGLE_REALLY_SET_IMAGE_PLANEMASK(fb, mask);
-
+
packed_dst = 0;
packed_len = (fb->info.var.xres << 16) | fb->info.var.yres;
NGLE_SET_DSTXY(fb, packed_dst);
-
- /* Write zeroes to overlay planes */
+
+ /* Write zeroes to overlay planes */
NGLE_QUICK_SET_IMAGE_BITMAP_OP(fb,
IBOvals(RopSrc, MaskAddrOffset(0),
BitmapExtent08, StaticReg(0),
DataDynamic, MaskOtc, BGx(0), FGx(0)));
-
+
SET_LENXY_START_RECFILL(fb, packed_len);

NGLE_UNLOCK(fb);
}

-static void
+static void
hyperResetPlanes(struct stifb_info *fb, int enable)
{
unsigned int controlPlaneReg;
@@ -783,7 +783,7 @@ hyperResetPlanes(struct stifb_info *fb, int enable)
ngleClearOverlayPlanes(fb, 0xff, 255);

/**************************************************
- ** Also need to counteract ITE settings
+ ** Also need to counteract ITE settings
**************************************************/
hyperUndoITE(fb);
break;
@@ -803,13 +803,13 @@ hyperResetPlanes(struct stifb_info *fb, int enable)
ngleResetAttrPlanes(fb, controlPlaneReg);
break;
}
-
+
NGLE_UNLOCK(fb);
}

/* Return pointer to in-memory structure holding ELK device-dependent ROM values. */

-static void
+static void
ngleGetDeviceRomData(struct stifb_info *fb)
{
#if 0
@@ -821,7 +821,7 @@ XXX: FIXME: !!!
char *pCard8;
int i;
char *mapOrigin = NULL;
-
+
int romTableIdx;

pPackedDevRomData = fb->ngle_rom;
@@ -888,7 +888,7 @@ SETUP_HCRX(struct stifb_info *fb)

/* Initialize Hyperbowl registers */
GET_FIFO_SLOTS(fb, nFreeFifoSlots, 7);
-
+
if (IS_24_DEVICE(fb)) {
hyperbowl = (fb->info.var.bits_per_pixel == 32) ?
HYPERBOWL_MODE01_8_24_LUT0_TRANSPARENT_LUT1_OPAQUE :
@@ -897,9 +897,9 @@ SETUP_HCRX(struct stifb_info *fb)
/* First write to Hyperbowl must happen twice (bug) */
WRITE_WORD(hyperbowl, fb, REG_40);
WRITE_WORD(hyperbowl, fb, REG_40);
-
+
WRITE_WORD(HYPERBOWL_MODE2_8_24, fb, REG_39);
-
+
WRITE_WORD(0x014c0148, fb, REG_42); /* Set lut 0 to be the direct color */
WRITE_WORD(0x404c4048, fb, REG_43);
WRITE_WORD(0x034c0348, fb, REG_44);
@@ -968,7 +968,7 @@ stifb_setcolreg(u_int regno, u_int red, u_int green,
0, /* Offset w/i LUT */
256); /* Load entire LUT */
NGLE_BINC_SET_SRCADDR(fb,
- NGLE_LONG_FB_ADDRESS(0, 0x100, 0));
+ NGLE_LONG_FB_ADDRESS(0, 0x100, 0));
/* 0x100 is same as used in WRITE_IMAGE_COLOR() */
START_COLORMAPLOAD(fb, lutBltCtl.all);
SETUP_FB(fb);
@@ -1006,7 +1006,7 @@ stifb_blank(int blank_mode, struct fb_info *info)
ENABLE_DISABLE_DISPLAY(fb, enable);
break;
}
-
+
SETUP_FB(fb);
return 0;
}
@@ -1092,15 +1092,15 @@ stifb_init_display(struct stifb_info *fb)

/* HCRX specific initialization */
SETUP_HCRX(fb);
-
+
/*
if (id == S9000_ID_HCRX)
hyperInitSprite(fb);
else
ngleInitSprite(fb);
*/
-
- /* Initialize the image planes. */
+
+ /* Initialize the image planes. */
switch (id) {
case S9000_ID_HCRX:
hyperResetPlanes(fb, ENABLE);
@@ -1170,7 +1170,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
fb = kzalloc(sizeof(*fb), GFP_ATOMIC);
if (!fb)
return -ENOMEM;
-
+
info = &fb->info;

/* set struct to a known state */
@@ -1211,7 +1211,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
dev_name, fb->id);
goto out_err0;
}
-
+
/* default to 8 bpp on most graphic chips */
bpp = 8;
xres = sti_onscreen_x(fb->sti);
@@ -1232,7 +1232,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
fb->id = S9000_ID_A1659A;
break;
case S9000_ID_TIMBER: /* HP9000/710 Any (may be a grayscale device) */
- if (strstr(dev_name, "GRAYSCALE") ||
+ if (strstr(dev_name, "GRAYSCALE") ||
strstr(dev_name, "Grayscale") ||
strstr(dev_name, "grayscale"))
var->grayscale = 1;
@@ -1271,16 +1271,16 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
case CRT_ID_VISUALIZE_EG:
case S9000_ID_ARTIST: /* Artist */
break;
- default:
+ default:
#ifdef FALLBACK_TO_1BPP
- printk(KERN_WARNING
+ printk(KERN_WARNING
"stifb: Unsupported graphics card (id=0x%08x) "
"- now trying 1bpp mode instead\n",
fb->id);
bpp = 1; /* default to 1 bpp */
break;
#else
- printk(KERN_WARNING
+ printk(KERN_WARNING
"stifb: Unsupported graphics card (id=0x%08x) "
"- skipping.\n",
fb->id);
@@ -1296,11 +1296,11 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
fix->line_length = (fb->sti->glob_cfg->total_x * bpp) / 8;
if (!fix->line_length)
fix->line_length = 2048; /* default */
-
+
/* limit fbsize to max visible screen size */
if (fix->smem_len > yres*fix->line_length)
fix->smem_len = ALIGN(yres*fix->line_length, 4*1024*1024);
-
+
fix->accel = FB_ACCEL_NONE;

switch (bpp) {
@@ -1326,7 +1326,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
default:
break;
}
-
+
var->xres = var->xres_virtual = xres;
var->yres = var->yres_virtual = yres;
var->bits_per_pixel = bpp;
@@ -1352,7 +1352,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
fix->smem_start, fix->smem_start+fix->smem_len);
goto out_err2;
}
-
+
if (!request_mem_region(fix->mmio_start, fix->mmio_len, "stifb mmio")) {
printk(KERN_ERR "stifb: cannot reserve sti mmio region 0x%04lx-0x%04lx\n",
fix->mmio_start, fix->mmio_start+fix->mmio_len);
@@ -1366,11 +1366,11 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)

fb_info(&fb->info, "%s %dx%d-%d frame buffer device, %s, id: %04x, mmio: 0x%04lx\n",
fix->id,
- var->xres,
+ var->xres,
var->yres,
var->bits_per_pixel,
dev_name,
- fb->id,
+ fb->id,
fix->mmio_start);

return 0;
@@ -1399,7 +1399,7 @@ static int __init stifb_init(void)
struct sti_struct *sti;
struct sti_struct *def_sti;
int i;
-
+
#ifndef MODULE
char *option = NULL;

@@ -1411,7 +1411,7 @@ static int __init stifb_init(void)
printk(KERN_INFO "stifb: disabled by \"stifb=off\" kernel parameter\n");
return -ENXIO;
}
-
+
def_sti = sti_get_rom(0);
if (def_sti) {
for (i = 1; i <= MAX_STI_ROMS; i++) {
@@ -1445,7 +1445,7 @@ stifb_cleanup(void)
{
struct sti_struct *sti;
int i;
-
+
for (i = 1; i <= MAX_STI_ROMS; i++) {
sti = sti_get_rom(i);
if (!sti)
@@ -1468,10 +1468,10 @@ int __init
stifb_setup(char *options)
{
int i;
-
+
if (!options || !*options)
return 1;
-
+
if (strncmp(options, "off", 3) == 0) {
stifb_disabled = 1;
options += 3;
--
2.39.2


2023-03-09 16:11:28

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 085/101] fbdev/tridentfb: Duplicate video-mode option string

Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with kstrdup() and free it in the module's exit function.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

v2:
* replace static memory with kstrdup()/kfree() (Geert)

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/tridentfb.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/tridentfb.c b/drivers/video/fbdev/tridentfb.c
index 6099b9768ba1..dbde64aef91f 100644
--- a/drivers/video/fbdev/tridentfb.c
+++ b/drivers/video/fbdev/tridentfb.c
@@ -61,6 +61,7 @@ static struct fb_fix_screeninfo tridentfb_fix = {
/* defaults which are normally overriden by user values */

/* video mode */
+static char *mode_option_buf;
static char *mode_option;
static int bpp = 8;

@@ -1800,8 +1801,11 @@ static int __init tridentfb_setup(char *options)
memdiff = simple_strtoul(opt + 8, NULL, 0);
else if (!strncmp(opt, "nativex=", 8))
nativex = simple_strtoul(opt + 8, NULL, 0);
- else
- mode_option = opt;
+ else {
+ kfree(mode_option_buf);
+ mode_option_buf = kstrdup(opt, GFP_KERNEL); // ignore errors
+ mode_option = mode_option_buf;
+ }
}
return 0;
}
@@ -1827,6 +1831,7 @@ static int __init tridentfb_init(void)
static void __exit tridentfb_exit(void)
{
pci_unregister_driver(&tridentfb_pci_driver);
+ kfree(mode_option_buf);
}

module_init(tridentfb_init);
--
2.39.2


2023-03-09 16:11:28

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 087/101] fbdev/uvesafb: Duplicate video-mode option string

Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with kstrdup() and free it in the module's exit function.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

v2:
* replace static memory with kstrdup()/kfree() (Geert)

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/uvesafb.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c
index f09f483c219b..ff8f511a00c2 100644
--- a/drivers/video/fbdev/uvesafb.c
+++ b/drivers/video/fbdev/uvesafb.c
@@ -56,6 +56,7 @@ static u16 maxclk; /* maximum pixel clock */
static u16 maxvf; /* maximum vertical frequency */
static u16 maxhf; /* maximum horizontal frequency */
static u16 vbemode; /* force use of a specific VBE mode */
+static char *mode_option_buf;
static char *mode_option;
static u8 dac_width = 6;

@@ -1851,7 +1852,9 @@ static int uvesafb_setup(char *options)
else if (!strncmp(this_opt, "vbemode:", 8))
vbemode = simple_strtoul(this_opt + 8, NULL, 0);
else if (this_opt[0] >= '0' && this_opt[0] <= '9') {
- mode_option = this_opt;
+ kfree(mode_option_buf);
+ mode_option_buf = kstrdup(this_opt, GFP_KERNEL); // ignore errors
+ mode_option = mode_option_buf;
} else {
pr_warn("unrecognized option %s\n", this_opt);
}
@@ -1937,6 +1940,7 @@ static void uvesafb_exit(void)
driver_remove_file(&uvesafb_driver.driver, &driver_attr_v86d);
platform_device_unregister(uvesafb_device);
platform_driver_unregister(&uvesafb_driver);
+ kfree(mode_option_buf);
}

module_exit(uvesafb_exit);
--
2.39.2


2023-03-09 16:11:28

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 088/101] fbdev/uvesafb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/uvesafb.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c
index ff8f511a00c2..13bd8503a06b 100644
--- a/drivers/video/fbdev/uvesafb.c
+++ b/drivers/video/fbdev/uvesafb.c
@@ -9,6 +9,7 @@

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

+#include <linux/cmdline.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
@@ -1809,16 +1810,14 @@ static struct platform_driver uvesafb_driver = {
static struct platform_device *uvesafb_device;

#ifndef MODULE
-static int uvesafb_setup(char *options)
+static int uvesafb_setup(const char *options)
{
+ struct option_iter iter;
char *this_opt;

- if (!options || !*options)
- return 0;
-
- while ((this_opt = strsep(&options, ",")) != NULL) {
- if (!*this_opt) continue;
+ option_iter_init(&iter, options);

+ while (option_iter_next(&iter, &this_opt)) {
if (!strcmp(this_opt, "redraw"))
ypan = 0;
else if (!strcmp(this_opt, "ypan"))
@@ -1860,6 +1859,8 @@ static int uvesafb_setup(char *options)
}
}

+ option_iter_release(&iter);
+
if (mtrr != 3 && mtrr != 0)
pr_warn("uvesafb: mtrr should be set to 0 or 3; %d is unsupported", mtrr);

--
2.39.2


2023-03-09 16:11:28

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 089/101] fbdev/valkyriefb: Remove trailing whitespaces

Fix coding style. No functional changes.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/valkyriefb.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/video/fbdev/valkyriefb.c b/drivers/video/fbdev/valkyriefb.c
index 1007023a5e88..b166b7cfe0e5 100644
--- a/drivers/video/fbdev/valkyriefb.c
+++ b/drivers/video/fbdev/valkyriefb.c
@@ -1,7 +1,7 @@
/*
* valkyriefb.c -- frame buffer device for the PowerMac 'valkyrie' display
*
- * Created 8 August 1998 by
+ * Created 8 August 1998 by
* Martin Costabel <[email protected]> and Kevin Schoedel
*
* Vmode-switching changes and vmode 15/17 modifications created 29 August
@@ -77,13 +77,13 @@ struct fb_info_valkyrie {
struct fb_par_valkyrie par;
struct cmap_regs __iomem *cmap_regs;
unsigned long cmap_regs_phys;
-
+
struct valkyrie_regs __iomem *valkyrie_regs;
unsigned long valkyrie_regs_phys;
-
+
__u8 __iomem *frame_buffer;
unsigned long frame_buffer_phys;
-
+
int sense;
unsigned long total_vram;

@@ -244,7 +244,7 @@ static inline int valkyrie_vram_reqd(int video_mode, int color_mode)
{
int pitch;
struct valkyrie_regvals *init = valkyrie_reg_init[video_mode-1];
-
+
if ((pitch = init->pitch[color_mode]) == 0)
pitch = 2 * init->pitch[0];
return init->vres * pitch;
@@ -467,7 +467,7 @@ static int valkyrie_var_to_par(struct fb_var_screeninfo *var,
printk(KERN_ERR "valkyriefb: vmode %d not valid.\n", vmode);
return -EINVAL;
}
-
+
if (cmode != CMODE_8 && cmode != CMODE_16) {
printk(KERN_ERR "valkyriefb: cmode %d not valid.\n", cmode);
return -EINVAL;
@@ -516,7 +516,7 @@ static void valkyrie_init_fix(struct fb_fix_screeninfo *fix, struct fb_info_valk
fix->ywrapstep = 0;
fix->ypanstep = 0;
fix->xpanstep = 0;
-
+
}

/* Fix must already be inited above */
--
2.39.2


2023-03-09 16:11:28

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 090/101] fbdev/valkyriefb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/valkyriefb.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/video/fbdev/valkyriefb.c b/drivers/video/fbdev/valkyriefb.c
index b166b7cfe0e5..3c20f392370a 100644
--- a/drivers/video/fbdev/valkyriefb.c
+++ b/drivers/video/fbdev/valkyriefb.c
@@ -39,6 +39,7 @@
* more details.
*/

+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -90,7 +91,7 @@ struct fb_info_valkyrie {
u32 pseudo_palette[16];
};

-static int valkyriefb_setup(char*);
+static int valkyriefb_setup(const char *options);

static int valkyriefb_check_var(struct fb_var_screeninfo *var,
struct fb_info *info);
@@ -545,14 +546,14 @@ static int __init valkyrie_init_info(struct fb_info *info,
/*
* Parse user specified options (`video=valkyriefb:')
*/
-static int __init valkyriefb_setup(char *options)
+static int __init valkyriefb_setup(const char *options)
{
+ struct option_iter iter;
char *this_opt;

- if (!options || !*options)
- return 0;
+ option_iter_init(&iter, options);

- while ((this_opt = strsep(&options, ",")) != NULL) {
+ while (option_iter_next(&iter, &this_opt)) {
if (!strncmp(this_opt, "vmode:", 6)) {
int vmode = simple_strtoul(this_opt+6, NULL, 0);
if (vmode > 0 && vmode <= VMODE_MAX)
@@ -571,6 +572,9 @@ static int __init valkyriefb_setup(char *options)
}
}
}
+
+ option_iter_release(&iter);
+
return 0;
}

--
2.39.2


2023-03-09 16:11:29

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 092/101] fbdev/vesafb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/vesafb.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/video/fbdev/vesafb.c b/drivers/video/fbdev/vesafb.c
index 3f8bdfcf51f0..7299cebb6962 100644
--- a/drivers/video/fbdev/vesafb.c
+++ b/drivers/video/fbdev/vesafb.c
@@ -10,6 +10,7 @@
*/

#include <linux/aperture.h>
+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -209,16 +210,14 @@ static struct fb_ops vesafb_ops = {
.fb_imageblit = cfb_imageblit,
};

-static int vesafb_setup(char *options)
+static int vesafb_setup(const char *options)
{
+ struct option_iter iter;
char *this_opt;

- if (!options || !*options)
- return 0;
-
- while ((this_opt = strsep(&options, ",")) != NULL) {
- if (!*this_opt) continue;
+ option_iter_init(&iter, options);

+ while (option_iter_next(&iter, &this_opt)) {
if (! strcmp(this_opt, "inverse"))
inverse=1;
else if (! strcmp(this_opt, "redraw"))
@@ -240,6 +239,9 @@ static int vesafb_setup(char *options)
else if (! strncmp(this_opt, "vremap:", 7))
vram_remap = simple_strtoul(this_opt+7, NULL, 0);
}
+
+ option_iter_release(&iter);
+
return 0;
}

--
2.39.2


2023-03-09 16:11:28

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 094/101] fbdev/vfb: Duplicate video-mode option string

Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with kstrdup() and free it in the module's exit function.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

v2:
* replace static memory with kstrdup()/kfree() (Geert)

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/vfb.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/vfb.c b/drivers/video/fbdev/vfb.c
index 680c88267ef4..de27fe84d820 100644
--- a/drivers/video/fbdev/vfb.c
+++ b/drivers/video/fbdev/vfb.c
@@ -37,6 +37,7 @@ static u_long videomemorysize = VIDEOMEMSIZE;
module_param(videomemorysize, ulong, 0);
MODULE_PARM_DESC(videomemorysize, "RAM available to frame buffer (in bytes)");

+static char *mode_option_buf;
static char *mode_option = NULL;
module_param(mode_option, charp, 0);
MODULE_PARM_DESC(mode_option, "Preferred video mode (e.g. 640x480-8@60)");
@@ -412,8 +413,11 @@ static int __init vfb_setup(char *options)
/* Test disable for backwards compatibility */
if (!strcmp(this_opt, "disable"))
vfb_enable = 0;
- else
- mode_option = this_opt;
+ else {
+ kfree(mode_option_buf);
+ mode_option_buf = kstrdup(this_opt, GFP_KERNEL); // ignore errors
+ mode_option = mode_option_buf;
+ }
}
return 1;
}
@@ -543,6 +547,7 @@ static void __exit vfb_exit(void)
{
platform_device_unregister(vfb_device);
platform_driver_unregister(&vfb_driver);
+ kfree(mode_option_buf);
}

module_exit(vfb_exit);
--
2.39.2


2023-03-09 16:11:29

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 091/101] fbdev/vermilion: Remove unused option string

The option string is unused. Remove the variable. No functional
changes.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/vermilion/vermilion.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/video/fbdev/vermilion/vermilion.c b/drivers/video/fbdev/vermilion/vermilion.c
index 0374ee6b6d03..bea318504475 100644
--- a/drivers/video/fbdev/vermilion/vermilion.c
+++ b/drivers/video/fbdev/vermilion/vermilion.c
@@ -1056,16 +1056,11 @@ static void __exit vmlfb_cleanup(void)

static int __init vmlfb_init(void)
{
-
-#ifndef MODULE
- char *option = NULL;
-#endif
-
if (fb_modesetting_disabled("vmlfb"))
return -ENODEV;

#ifndef MODULE
- if (fb_get_options(MODULE_NAME, &option))
+ if (fb_get_options(MODULE_NAME, NULL))
return -ENODEV;
#endif

--
2.39.2


2023-03-09 16:11:30

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 096/101] fbdev/viafb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/via/viafbdev.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/video/fbdev/via/viafbdev.c b/drivers/video/fbdev/via/viafbdev.c
index 2d67c92c5774..749aee9f6c56 100644
--- a/drivers/video/fbdev/via/viafbdev.c
+++ b/drivers/video/fbdev/via/viafbdev.c
@@ -5,6 +5,7 @@

*/

+#include <linux/cmdline.h>
#include <linux/compiler.h>
#include <linux/module.h>
#include <linux/seq_file.h>
@@ -1922,21 +1923,18 @@ void via_fb_pci_remove(struct pci_dev *pdev)
#ifndef MODULE
static int __init viafb_setup(void)
{
- char *this_opt;
char *options;
+ struct option_iter iter;
+ char *this_opt;

DEBUG_MSG(KERN_INFO "viafb_setup!\n");

if (fb_get_options("viafb", &options))
return -ENODEV;

- if (!options || !*options)
- return 0;
-
- while ((this_opt = strsep(&options, ",")) != NULL) {
- if (!*this_opt)
- continue;
+ option_iter_init(&iter, options);

+ while (option_iter_next(&iter, &this_opt)) {
if (!strncmp(this_opt, "viafb_mode1=", 12)) {
viafb_mode1 = kstrdup(this_opt + 12, GFP_KERNEL);
if (!viafb_mode1)
@@ -2009,6 +2007,9 @@ static int __init viafb_setup(void)
return -ENOMEM;
}
}
+
+ option_iter_release(&iter);
+
return 0;
}
#endif
--
2.39.2


2023-03-09 16:11:29

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 095/101] fbdev/vfb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/vfb.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/video/fbdev/vfb.c b/drivers/video/fbdev/vfb.c
index de27fe84d820..7694e5026155 100644
--- a/drivers/video/fbdev/vfb.c
+++ b/drivers/video/fbdev/vfb.c
@@ -10,6 +10,7 @@
* more details.
*/

+#include <linux/cmdline.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -393,8 +394,9 @@ static int vfb_mmap(struct fb_info *info,
* The virtual framebuffer driver is only enabled if explicitly
* requested by passing 'video=vfb:' (or any actual options).
*/
-static int __init vfb_setup(char *options)
+static int __init vfb_setup(const char *options)
{
+ struct option_iter iter;
char *this_opt;

vfb_enable = 0;
@@ -404,12 +406,9 @@ static int __init vfb_setup(char *options)

vfb_enable = 1;

- if (!*options)
- return 1;
+ option_iter_init(&iter, options);

- while ((this_opt = strsep(&options, ",")) != NULL) {
- if (!*this_opt)
- continue;
+ while (option_iter_next(&iter, &this_opt)) {
/* Test disable for backwards compatibility */
if (!strcmp(this_opt, "disable"))
vfb_enable = 0;
@@ -419,6 +418,9 @@ static int __init vfb_setup(char *options)
mode_option = mode_option_buf;
}
}
+
+ option_iter_release(&iter);
+
return 1;
}
#endif /* MODULE */
--
2.39.2


2023-03-09 16:11:30

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 097/101] fbdev/vt8623fb: Duplicate video-mode option string

Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with kstrdup() and free it in the module's exit function.

Done in preparation of constifying the option string.

v2:
* replace static memory with kstrdup()/kfree() (Geert)

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/vt8623fb.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/vt8623fb.c b/drivers/video/fbdev/vt8623fb.c
index 034333ee6e45..321b1813cf3c 100644
--- a/drivers/video/fbdev/vt8623fb.c
+++ b/drivers/video/fbdev/vt8623fb.c
@@ -95,6 +95,7 @@ static const struct svga_timing_regs vt8623_timing_regs = {

/* Module parameters */

+static char *mode_option_buf;
static char *mode_option = "640x480-8@60";
static int mtrr = 1;

@@ -911,6 +912,7 @@ static void __exit vt8623fb_cleanup(void)
{
pr_debug("vt8623fb: cleaning up\n");
pci_unregister_driver(&vt8623fb_pci_driver);
+ kfree(mode_option_buf);
}

/* Driver Initialisation */
@@ -929,8 +931,10 @@ static int __init vt8623fb_init(void)
if (fb_get_options("vt8623fb", &option))
return -ENODEV;

- if (option && *option)
- mode_option = option;
+ if (option && *option) {
+ mode_option_buf = kstrdup(option, GFP_KERNEL); // ignore errors
+ mode_option = mode_option_buf;
+ }
#endif

pr_debug("vt8623fb: initializing\n");
--
2.39.2


2023-03-09 16:11:30

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 098/101] staging/sm750fb: Release g_settings in module-exit function

Free g_settings in module-exit function for symmetry with its
allocation in module-init function. Fixes a possible undefined
dereference of the pointer.

The string g_settings is initialized ifrom within the module-init
function lynxfb_init() and used from within the PCI probe function.
It is later freed in the PCI device's remove function. Probing another
PCI device afterwards accesses g_settings in an undefined state.

Fix this by freeing g_settings in lynxfb_exit(). Also streamline the
code that creates g_settings in the first place.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/staging/sm750fb/sm750.c | 24 +++++++++++-------------
1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c
index effc7fcc3703..fa8ae20bb688 100644
--- a/drivers/staging/sm750fb/sm750.c
+++ b/drivers/staging/sm750fb/sm750.c
@@ -1093,13 +1093,12 @@ static void lynxfb_pci_remove(struct pci_dev *pdev)

iounmap(sm750_dev->pvReg);
iounmap(sm750_dev->pvMem);
- kfree(g_settings);
}

static int __init lynxfb_setup(char *options)
{
- int len;
- char *opt, *tmp;
+ size_t len;
+ char *opt, *outbuf;

if (!options || !*options) {
pr_warn("no options.\n");
@@ -1109,11 +1108,10 @@ static int __init lynxfb_setup(char *options)
pr_info("options:%s\n", options);

len = strlen(options) + 1;
- g_settings = kzalloc(len, GFP_KERNEL);
- if (!g_settings)
+ outbuf = kzalloc(len, GFP_KERNEL);
+ if (!outbuf)
return -ENOMEM;
-
- tmp = g_settings;
+ g_settings = outbuf;

/*
* Notes:
@@ -1133,12 +1131,11 @@ static int __init lynxfb_setup(char *options)
} else if (!strncmp(opt, "dual", strlen("dual"))) {
g_dualview = 1;
} else {
- strcat(tmp, opt);
- tmp += strlen(opt);
- if (options)
- *tmp++ = ':';
- else
- *tmp++ = 0;
+ if (outbuf != g_settings)
+ *outbuf++ = ':'; // add separator
+ len = strlen(opt);
+ memcpy(outbuf, opt, len);
+ outbuf += len;
}
}

@@ -1186,6 +1183,7 @@ module_init(lynxfb_init);
static void __exit lynxfb_exit(void)
{
pci_unregister_driver(&lynxfb_driver);
+ kfree(g_settings);
}
module_exit(lynxfb_exit);

--
2.39.2


2023-03-09 16:11:30

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 099/101] staging/sm750fb: Duplicate video-mode option string

Assume that the driver does not own the option string or its substrings
and hence duplicate the option stringis for the video mode. Allocate each
copy's memory with kstrdup() and free it in the module's exit function.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/staging/sm750fb/sm750.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c
index fa8ae20bb688..f0dbf7535ca8 100644
--- a/drivers/staging/sm750fb/sm750.c
+++ b/drivers/staging/sm750fb/sm750.c
@@ -911,11 +911,11 @@ static void sm750fb_setup(struct sm750_dev *sm750_dev, char *src)
g_hwcursor = 0;
} else {
if (!g_fbmode[0]) {
- g_fbmode[0] = opt;
+ g_fbmode[0] = kstrdup(opt, GFP_KERNEL); // ignore errors
dev_info(&sm750_dev->pdev->dev,
"find fbmode0 : %s\n", g_fbmode[0]);
} else if (!g_fbmode[1]) {
- g_fbmode[1] = opt;
+ g_fbmode[1] = kstrdup(opt, GFP_KERNEL); // ignore errors
dev_info(&sm750_dev->pdev->dev,
"find fbmode1 : %s\n", g_fbmode[1]);
} else {
@@ -1182,7 +1182,14 @@ module_init(lynxfb_init);

static void __exit lynxfb_exit(void)
{
+ size_t i = ARRAY_SIZE(g_fbmode);
+
pci_unregister_driver(&lynxfb_driver);
+
+ while (i) {
+ --i;
+ kfree(g_fbmode[i]);
+ }
kfree(g_settings);
}
module_exit(lynxfb_exit);
--
2.39.2


2023-03-09 16:11:30

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 093/101] fbdev/vfb: Remove trailing whitespaces

Fix coding style. No functional changes.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/video/fbdev/vfb.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/video/fbdev/vfb.c b/drivers/video/fbdev/vfb.c
index 95d3c59867d0..680c88267ef4 100644
--- a/drivers/video/fbdev/vfb.c
+++ b/drivers/video/fbdev/vfb.c
@@ -110,7 +110,7 @@ static u_long get_line_length(int xres_virtual, int bpp)
* First part, xxxfb_check_var, must not write anything
* to hardware, it should only verify and adjust var.
* This means it doesn't alter par but it does use hardware
- * data from it to check this var.
+ * data from it to check this var.
*/

static int vfb_check_var(struct fb_var_screeninfo *var,
@@ -168,7 +168,7 @@ static int vfb_check_var(struct fb_var_screeninfo *var,

/*
* Now that we checked it we alter var. The reason being is that the video
- * mode passed in might not work but slight changes to it might make it
+ * mode passed in might not work but slight changes to it might make it
* work. This way we let the user know what is acceptable.
*/
switch (var->bits_per_pixel) {
@@ -234,8 +234,8 @@ static int vfb_check_var(struct fb_var_screeninfo *var,
}

/* This routine actually sets the video mode. It's in here where we
- * the hardware state info->par and fix which can be affected by the
- * change in par. For this driver it doesn't do much.
+ * the hardware state info->par and fix which can be affected by the
+ * change in par. For this driver it doesn't do much.
*/
static int vfb_set_par(struct fb_info *info)
{
@@ -378,7 +378,7 @@ static int vfb_pan_display(struct fb_var_screeninfo *var,
}

/*
- * Most drivers don't need their own mmap function
+ * Most drivers don't need their own mmap function
*/

static int vfb_mmap(struct fb_info *info,
--
2.39.2


2023-03-09 16:11:30

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 100/101] staging/sm750fb: Parse option string with struct option_iter

Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

v2:
* move string handling into separate patches

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/staging/sm750fb/sm750.c | 28 +++++++++++++++-------------
1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c
index f0dbf7535ca8..0e3712fcf0e0 100644
--- a/drivers/staging/sm750fb/sm750.c
+++ b/drivers/staging/sm750fb/sm750.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/aperture.h>
+#include <linux/cmdline.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/errno.h>
@@ -867,8 +868,9 @@ static int lynxfb_set_fbinfo(struct fb_info *info, int index)
}

/* chip specific g_option configuration routine */
-static void sm750fb_setup(struct sm750_dev *sm750_dev, char *src)
+static void sm750fb_setup(struct sm750_dev *sm750_dev, const char *src)
{
+ struct option_iter iter;
char *opt;
int swap;

@@ -889,7 +891,9 @@ static void sm750fb_setup(struct sm750_dev *sm750_dev, char *src)
goto NO_PARAM;
}

- while ((opt = strsep(&src, ":")) != NULL && *opt != 0) {
+ option_iter_init(&iter, src);
+
+ while (option_iter_next(&iter, &opt)) {
dev_info(&sm750_dev->pdev->dev, "opt=%s\n", opt);
dev_info(&sm750_dev->pdev->dev, "src=%s\n", src);

@@ -924,6 +928,8 @@ static void sm750fb_setup(struct sm750_dev *sm750_dev, char *src)
}
}

+ option_iter_release(&iter);
+
NO_PARAM:
if (sm750_dev->revid != SM750LE_REVISION_ID) {
if (sm750_dev->fb_count > 1) {
@@ -1095,9 +1101,10 @@ static void lynxfb_pci_remove(struct pci_dev *pdev)
iounmap(sm750_dev->pvMem);
}

-static int __init lynxfb_setup(char *options)
+static int __init lynxfb_setup(const char *options)
{
size_t len;
+ struct option_iter iter;
char *opt, *outbuf;

if (!options || !*options) {
@@ -1113,16 +1120,9 @@ static int __init lynxfb_setup(char *options)
return -ENOMEM;
g_settings = outbuf;

- /*
- * Notes:
- * char * strsep(char **s,const char * ct);
- * @s: the string to be searched
- * @ct :the characters to search for
- *
- * strsep() updates @options to pointer after the first found token
- * it also returns the pointer ahead the token.
- */
- while ((opt = strsep(&options, ":")) != NULL) {
+ option_iter_init(&iter, options);
+
+ while (option_iter_next(&iter, &opt)) {
/* options that mean for any lynx chips are configured here */
if (!strncmp(opt, "noaccel", strlen("noaccel"))) {
g_noaccel = 1;
@@ -1139,6 +1139,8 @@ static int __init lynxfb_setup(char *options)
}
}

+ option_iter_release(&iter);
+
/* misc g_settings are transport to chip specific routines */
pr_info("parameter left for chip specific analysis:%s\n", g_settings);
return 0;
--
2.39.2


2023-03-09 16:11:30

by Thomas Zimmermann

[permalink] [raw]
Subject: [PATCH v2 101/101] fbdev: Constify option strings

Return the option string as const char* from fb_get_options() to
enforce fbdev's ownership of the memory region. Also avoids memory
allocation within fb_get_options().

Callers that have to modify the option string must create their own
copy. As most drivers use struct option_iter, this already happens
transparently in many cases.

Adapt all callers of fb_get_options().

Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/staging/sm750fb/sm750.c | 2 +-
drivers/video/fbdev/acornfb.c | 2 +-
drivers/video/fbdev/amifb.c | 2 +-
drivers/video/fbdev/arkfb.c | 2 +-
drivers/video/fbdev/atafb.c | 2 +-
drivers/video/fbdev/aty/aty128fb.c | 2 +-
drivers/video/fbdev/aty/atyfb_base.c | 2 +-
drivers/video/fbdev/aty/radeon_base.c | 2 +-
drivers/video/fbdev/au1100fb.c | 2 +-
drivers/video/fbdev/au1200fb.c | 2 +-
drivers/video/fbdev/cirrusfb.c | 2 +-
drivers/video/fbdev/controlfb.c | 2 +-
drivers/video/fbdev/core/fb_cmdline.c | 13 +++----------
drivers/video/fbdev/core/modedb.c | 8 ++------
drivers/video/fbdev/cyber2000fb.c | 2 +-
drivers/video/fbdev/efifb.c | 2 +-
drivers/video/fbdev/ep93xx-fb.c | 2 +-
drivers/video/fbdev/fm2fb.c | 2 +-
drivers/video/fbdev/fsl-diu-fb.c | 2 +-
drivers/video/fbdev/gbefb.c | 2 +-
drivers/video/fbdev/geode/gx1fb_core.c | 2 +-
drivers/video/fbdev/geode/gxfb_core.c | 2 +-
drivers/video/fbdev/geode/lxfb_core.c | 2 +-
drivers/video/fbdev/grvga.c | 3 ++-
drivers/video/fbdev/gxt4500.c | 2 +-
drivers/video/fbdev/hyperv_fb.c | 2 +-
drivers/video/fbdev/i740fb.c | 2 +-
drivers/video/fbdev/i810/i810_main.c | 2 +-
drivers/video/fbdev/imsttfb.c | 2 +-
drivers/video/fbdev/imxfb.c | 2 +-
drivers/video/fbdev/intelfb/intelfbdrv.c | 2 +-
drivers/video/fbdev/kyro/fbdev.c | 2 +-
drivers/video/fbdev/macfb.c | 2 +-
drivers/video/fbdev/matrox/matroxfb_base.c | 2 +-
drivers/video/fbdev/mx3fb.c | 2 +-
drivers/video/fbdev/neofb.c | 2 +-
drivers/video/fbdev/nvidia/nvidia.c | 2 +-
drivers/video/fbdev/ocfb.c | 2 +-
drivers/video/fbdev/omap/omapfb_main.c | 2 +-
drivers/video/fbdev/platinumfb.c | 2 +-
drivers/video/fbdev/pm2fb.c | 2 +-
drivers/video/fbdev/pm3fb.c | 2 +-
drivers/video/fbdev/ps3fb.c | 2 +-
drivers/video/fbdev/pvr2fb.c | 2 +-
drivers/video/fbdev/pxafb.c | 2 +-
drivers/video/fbdev/riva/fbdev.c | 2 +-
drivers/video/fbdev/s3fb.c | 2 +-
drivers/video/fbdev/savage/savagefb_driver.c | 2 +-
drivers/video/fbdev/sis/sis_main.c | 2 +-
drivers/video/fbdev/skeletonfb.c | 2 +-
drivers/video/fbdev/sm712fb.c | 2 +-
drivers/video/fbdev/sstfb.c | 2 +-
drivers/video/fbdev/stifb.c | 2 +-
drivers/video/fbdev/tdfxfb.c | 2 +-
drivers/video/fbdev/tgafb.c | 2 +-
drivers/video/fbdev/tridentfb.c | 2 +-
drivers/video/fbdev/uvesafb.c | 2 +-
drivers/video/fbdev/valkyriefb.c | 2 +-
drivers/video/fbdev/vesafb.c | 2 +-
drivers/video/fbdev/vfb.c | 2 +-
drivers/video/fbdev/via/viafbdev.c | 2 +-
drivers/video/fbdev/vt8623fb.c | 3 +--
include/linux/fb.h | 2 +-
63 files changed, 67 insertions(+), 78 deletions(-)

diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c
index 0e3712fcf0e0..3d7cde9add4e 100644
--- a/drivers/staging/sm750fb/sm750.c
+++ b/drivers/staging/sm750fb/sm750.c
@@ -1165,7 +1165,7 @@ static struct pci_driver lynxfb_driver = {

static int __init lynxfb_init(void)
{
- char *option;
+ const char *option;

if (fb_modesetting_disabled("sm750fb"))
return -ENODEV;
diff --git a/drivers/video/fbdev/acornfb.c b/drivers/video/fbdev/acornfb.c
index 3fed89e03554..27e6796b27b6 100644
--- a/drivers/video/fbdev/acornfb.c
+++ b/drivers/video/fbdev/acornfb.c
@@ -926,7 +926,7 @@ static int acornfb_probe(struct platform_device *dev)
unsigned long size;
u_int h_sync, v_sync;
int rc, i;
- char *option = NULL;
+ const char *option = NULL;

if (fb_get_options("acornfb", &option))
return -ENODEV;
diff --git a/drivers/video/fbdev/amifb.c b/drivers/video/fbdev/amifb.c
index a09edc576437..f0ed718a4f3c 100644
--- a/drivers/video/fbdev/amifb.c
+++ b/drivers/video/fbdev/amifb.c
@@ -3539,7 +3539,7 @@ static int __init amifb_probe(struct platform_device *pdev)
u_int defmode;

#ifndef MODULE
- char *option = NULL;
+ const char *option = NULL;

if (fb_get_options("amifb", &option)) {
amifb_video_off();
diff --git a/drivers/video/fbdev/arkfb.c b/drivers/video/fbdev/arkfb.c
index 98c710cadaab..7e9f5b37fd50 100644
--- a/drivers/video/fbdev/arkfb.c
+++ b/drivers/video/fbdev/arkfb.c
@@ -1188,7 +1188,7 @@ static int __init arkfb_init(void)
{

#ifndef MODULE
- char *option = NULL;
+ const char *option = NULL;
#endif

if (fb_modesetting_disabled("arkfb"))
diff --git a/drivers/video/fbdev/atafb.c b/drivers/video/fbdev/atafb.c
index 6e625ac020b5..2ede6ce0ec0e 100644
--- a/drivers/video/fbdev/atafb.c
+++ b/drivers/video/fbdev/atafb.c
@@ -2991,7 +2991,7 @@ static int __init atafb_probe(struct platform_device *pdev)
int pad, detected_mode, error;
unsigned int defmode = 0;
unsigned long mem_req;
- char *option = NULL;
+ const char *option = NULL;

if (fb_get_options("atafb", &option))
return -ENODEV;
diff --git a/drivers/video/fbdev/aty/aty128fb.c b/drivers/video/fbdev/aty/aty128fb.c
index ee2be122de2d..e7e1c7c0da92 100644
--- a/drivers/video/fbdev/aty/aty128fb.c
+++ b/drivers/video/fbdev/aty/aty128fb.c
@@ -2509,7 +2509,7 @@ static int __maybe_unused aty128_pci_resume(struct device *dev)
static int aty128fb_init(void)
{
#ifndef MODULE
- char *option = NULL;
+ const char *option = NULL;
#endif

if (fb_modesetting_disabled("aty128fb"))
diff --git a/drivers/video/fbdev/aty/atyfb_base.c b/drivers/video/fbdev/aty/atyfb_base.c
index f4b22d2f0d3d..73a54738f58c 100644
--- a/drivers/video/fbdev/aty/atyfb_base.c
+++ b/drivers/video/fbdev/aty/atyfb_base.c
@@ -3965,7 +3965,7 @@ static int __init atyfb_init(void)
{
int err1 = 1, err2 = 1;
#ifndef MODULE
- char *option = NULL;
+ const char *option = NULL;
#endif

if (fb_modesetting_disabled("atyfb"))
diff --git a/drivers/video/fbdev/aty/radeon_base.c b/drivers/video/fbdev/aty/radeon_base.c
index 975323e82f52..a44f9c423703 100644
--- a/drivers/video/fbdev/aty/radeon_base.c
+++ b/drivers/video/fbdev/aty/radeon_base.c
@@ -2611,7 +2611,7 @@ static int __init radeonfb_setup (const char *options)
static int __init radeonfb_init (void)
{
#ifndef MODULE
- char *option = NULL;
+ const char *option = NULL;
#endif

if (fb_modesetting_disabled("radeonfb"))
diff --git a/drivers/video/fbdev/au1100fb.c b/drivers/video/fbdev/au1100fb.c
index 0c063c8e6312..4034aeb37d45 100644
--- a/drivers/video/fbdev/au1100fb.c
+++ b/drivers/video/fbdev/au1100fb.c
@@ -366,7 +366,7 @@ static const struct fb_ops au1100fb_ops =

static int au1100fb_setup(struct au1100fb_device *fbdev)
{
- char *options;
+ const char *options;
struct option_iter iter;
char *this_opt;
int num_panels = ARRAY_SIZE(known_lcd_panels);
diff --git a/drivers/video/fbdev/au1200fb.c b/drivers/video/fbdev/au1200fb.c
index 43b6a9dfeec4..9e84a1095d2f 100644
--- a/drivers/video/fbdev/au1200fb.c
+++ b/drivers/video/fbdev/au1200fb.c
@@ -1578,7 +1578,7 @@ static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev)

static int au1200fb_setup(struct au1200fb_platdata *pd)
{
- char *options = NULL;
+ const char *options = NULL;
struct option_iter iter;
char *this_opt;
char *endptr;
diff --git a/drivers/video/fbdev/cirrusfb.c b/drivers/video/fbdev/cirrusfb.c
index a5e99a8feadd..dc900f2fcd01 100644
--- a/drivers/video/fbdev/cirrusfb.c
+++ b/drivers/video/fbdev/cirrusfb.c
@@ -2363,7 +2363,7 @@ static int __init cirrusfb_init(void)
int error = 0;

#ifndef MODULE
- char *option = NULL;
+ const char *option = NULL;
#endif

if (fb_modesetting_disabled("cirrusfb"))
diff --git a/drivers/video/fbdev/controlfb.c b/drivers/video/fbdev/controlfb.c
index 65e2f9949420..a02a5ea99a7a 100644
--- a/drivers/video/fbdev/controlfb.c
+++ b/drivers/video/fbdev/controlfb.c
@@ -1004,7 +1004,7 @@ static int __init control_of_init(struct device_node *dp)
static int __init control_init(void)
{
struct device_node *dp;
- char *option = NULL;
+ const char *option = NULL;
int ret = -ENXIO;

if (fb_get_options("controlfb", &option))
diff --git a/drivers/video/fbdev/core/fb_cmdline.c b/drivers/video/fbdev/core/fb_cmdline.c
index 4d1634c492ec..67f9df7096f1 100644
--- a/drivers/video/fbdev/core/fb_cmdline.c
+++ b/drivers/video/fbdev/core/fb_cmdline.c
@@ -28,12 +28,9 @@
* (video=<name>:<options>)
* @option: the option will be stored here
*
- * The caller owns the string returned in @option and is
- * responsible for releasing the memory.
- *
* NOTE: Needed to maintain backwards compatibility
*/
-int fb_get_options(const char *name, char **option)
+int fb_get_options(const char *name, const char **option)
{
const char *options = NULL;
bool is_of = false;
@@ -49,12 +46,8 @@ int fb_get_options(const char *name, char **option)
enabled = false;
}

- if (option) {
- if (options)
- *option = kstrdup(options, GFP_KERNEL);
- else
- *option = NULL;
- }
+ if (option)
+ *option = options;

return enabled ? 0 : 1; // 0 on success, 1 otherwise
}
diff --git a/drivers/video/fbdev/core/modedb.c b/drivers/video/fbdev/core/modedb.c
index 23cf8eba785d..5ff5a56925cc 100644
--- a/drivers/video/fbdev/core/modedb.c
+++ b/drivers/video/fbdev/core/modedb.c
@@ -620,7 +620,6 @@ int fb_find_mode(struct fb_var_screeninfo *var,
const struct fb_videomode *default_mode,
unsigned int default_bpp)
{
- char *mode_option_buf = NULL;
int i;

/* Set up defaults */
@@ -636,10 +635,8 @@ int fb_find_mode(struct fb_var_screeninfo *var,
default_bpp = 8;

/* Did the user specify a video mode? */
- if (!mode_option) {
- fb_get_options(NULL, &mode_option_buf);
- mode_option = mode_option_buf;
- }
+ if (!mode_option)
+ fb_get_options(NULL, &mode_option);
if (mode_option) {
const char *name = mode_option;
unsigned int namelen = strlen(name);
@@ -718,7 +715,6 @@ int fb_find_mode(struct fb_var_screeninfo *var,
res_specified = 1;
}
done:
- kfree(mode_option_buf);
if (cvt) {
struct fb_videomode cvt_mode;
int ret;
diff --git a/drivers/video/fbdev/cyber2000fb.c b/drivers/video/fbdev/cyber2000fb.c
index f21d11a73455..c6a46e870e98 100644
--- a/drivers/video/fbdev/cyber2000fb.c
+++ b/drivers/video/fbdev/cyber2000fb.c
@@ -1877,7 +1877,7 @@ static int __init cyber2000fb_init(void)
int ret = -1, err;

#ifndef MODULE
- char *option = NULL;
+ const char *option = NULL;
#endif

if (fb_modesetting_disabled("CyberPro"))
diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c
index be77a76f7d1d..1fc1dee75552 100644
--- a/drivers/video/fbdev/efifb.c
+++ b/drivers/video/fbdev/efifb.c
@@ -366,7 +366,7 @@ static int efifb_probe(struct platform_device *dev)
unsigned int size_vmode;
unsigned int size_remap;
unsigned int size_total;
- char *option = NULL;
+ const char *option = NULL;
efi_memory_desc_t md;

if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI || pci_dev_disabled)
diff --git a/drivers/video/fbdev/ep93xx-fb.c b/drivers/video/fbdev/ep93xx-fb.c
index 305f1587bd89..33a9aa2ecc3b 100644
--- a/drivers/video/fbdev/ep93xx-fb.c
+++ b/drivers/video/fbdev/ep93xx-fb.c
@@ -464,7 +464,7 @@ static int ep93xxfb_probe(struct platform_device *pdev)
struct fb_info *info;
struct ep93xx_fbi *fbi;
struct resource *res;
- char *video_mode;
+ const char *video_mode;
int err;

if (!mach_info)
diff --git a/drivers/video/fbdev/fm2fb.c b/drivers/video/fbdev/fm2fb.c
index a787884a6a7f..79607301e176 100644
--- a/drivers/video/fbdev/fm2fb.c
+++ b/drivers/video/fbdev/fm2fb.c
@@ -315,7 +315,7 @@ static int __init fm2fb_setup(const char *options)

static int __init fm2fb_init(void)
{
- char *option = NULL;
+ const char *option = NULL;

if (fb_get_options("fm2fb", &option))
return -ENODEV;
diff --git a/drivers/video/fbdev/fsl-diu-fb.c b/drivers/video/fbdev/fsl-diu-fb.c
index 78996995568c..c0c13135a6e1 100644
--- a/drivers/video/fbdev/fsl-diu-fb.c
+++ b/drivers/video/fbdev/fsl-diu-fb.c
@@ -1903,7 +1903,7 @@ static int __init fsl_diu_init(void)
#endif
int ret;
#ifndef MODULE
- char *option;
+ const char *option;

/*
* For kernel boot options (in 'video=xxxfb:<options>' format)
diff --git a/drivers/video/fbdev/gbefb.c b/drivers/video/fbdev/gbefb.c
index d20ef48263f3..a5e480964fa4 100644
--- a/drivers/video/fbdev/gbefb.c
+++ b/drivers/video/fbdev/gbefb.c
@@ -1125,7 +1125,7 @@ static int gbefb_probe(struct platform_device *p_dev)
struct fb_info *info;
struct gbefb_par *par;
#ifndef MODULE
- char *options = NULL;
+ const char *options = NULL;
#endif

info = framebuffer_alloc(sizeof(struct gbefb_par), &p_dev->dev);
diff --git a/drivers/video/fbdev/geode/gx1fb_core.c b/drivers/video/fbdev/geode/gx1fb_core.c
index 6f1e9aadc192..c51e69b98ba8 100644
--- a/drivers/video/fbdev/geode/gx1fb_core.c
+++ b/drivers/video/fbdev/geode/gx1fb_core.c
@@ -445,7 +445,7 @@ static struct pci_driver gx1fb_driver = {
static int __init gx1fb_init(void)
{
#ifndef MODULE
- char *option = NULL;
+ const char *option = NULL;
#endif

if (fb_modesetting_disabled("gx1fb"))
diff --git a/drivers/video/fbdev/geode/gxfb_core.c b/drivers/video/fbdev/geode/gxfb_core.c
index aede22566775..6a1391f88599 100644
--- a/drivers/video/fbdev/geode/gxfb_core.c
+++ b/drivers/video/fbdev/geode/gxfb_core.c
@@ -512,7 +512,7 @@ static int __init gxfb_setup(const char *options)
static int __init gxfb_init(void)
{
#ifndef MODULE
- char *option = NULL;
+ const char *option = NULL;
#endif

if (fb_modesetting_disabled("gxfb"))
diff --git a/drivers/video/fbdev/geode/lxfb_core.c b/drivers/video/fbdev/geode/lxfb_core.c
index 855dc96b5669..2496bf85b6f3 100644
--- a/drivers/video/fbdev/geode/lxfb_core.c
+++ b/drivers/video/fbdev/geode/lxfb_core.c
@@ -650,7 +650,7 @@ static int __init lxfb_setup(const char *options)
static int __init lxfb_init(void)
{
#ifndef MODULE
- char *option = NULL;
+ const char *option = NULL;
#endif

if (fb_modesetting_disabled("lxfb"))
diff --git a/drivers/video/fbdev/grvga.c b/drivers/video/fbdev/grvga.c
index 742331d0f08b..e39997a36ccc 100644
--- a/drivers/video/fbdev/grvga.c
+++ b/drivers/video/fbdev/grvga.c
@@ -334,7 +334,8 @@ static int grvga_probe(struct platform_device *dev)
unsigned long physical_start = 0;
unsigned long grvga_mem_size = 0;
struct grvga_par *par = NULL;
- char *options = NULL, *mode_opt = NULL;
+ const char *options = NULL;
+ const *mode_opt = NULL;
struct option_iter iter;
char *this_opt;

diff --git a/drivers/video/fbdev/gxt4500.c b/drivers/video/fbdev/gxt4500.c
index 65cb44c281c1..21c0fbddcbdb 100644
--- a/drivers/video/fbdev/gxt4500.c
+++ b/drivers/video/fbdev/gxt4500.c
@@ -781,7 +781,7 @@ static struct pci_driver gxt4500_driver = {
static int gxt4500_init(void)
{
#ifndef MODULE
- char *options;
+ const char *options;
#endif

if (fb_modesetting_disabled("gxt4500"))
diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
index edb0555239c6..c7956626eed0 100644
--- a/drivers/video/fbdev/hyperv_fb.c
+++ b/drivers/video/fbdev/hyperv_fb.c
@@ -903,7 +903,7 @@ static const struct fb_ops hvfb_ops = {
static void hvfb_get_option(struct fb_info *info)
{
struct hvfb_par *par = info->par;
- char *options = NULL;
+ const char *options = NULL;
char *optbuf, *opt, *p;
uint x = 0, y = 0;

diff --git a/drivers/video/fbdev/i740fb.c b/drivers/video/fbdev/i740fb.c
index 6da2f3b7846d..2c852f3ce450 100644
--- a/drivers/video/fbdev/i740fb.c
+++ b/drivers/video/fbdev/i740fb.c
@@ -1289,7 +1289,7 @@ static int __init i740fb_setup(const char *options)
static int __init i740fb_init(void)
{
#ifndef MODULE
- char *option = NULL;
+ const char *option = NULL;
#endif

if (fb_modesetting_disabled("i740fb"))
diff --git a/drivers/video/fbdev/i810/i810_main.c b/drivers/video/fbdev/i810/i810_main.c
index 952d1a69dfb9..428bd5b53e98 100644
--- a/drivers/video/fbdev/i810/i810_main.c
+++ b/drivers/video/fbdev/i810/i810_main.c
@@ -2150,7 +2150,7 @@ static void i810fb_remove_pci(struct pci_dev *dev)
#ifndef MODULE
static int i810fb_init(void)
{
- char *option = NULL;
+ const char *option = NULL;

if (fb_modesetting_disabled("i810fb"))
return -ENODEV;
diff --git a/drivers/video/fbdev/imsttfb.c b/drivers/video/fbdev/imsttfb.c
index 1e2b45faa26b..98a9a5891822 100644
--- a/drivers/video/fbdev/imsttfb.c
+++ b/drivers/video/fbdev/imsttfb.c
@@ -1620,7 +1620,7 @@ imsttfb_setup(const char *options)
static int __init imsttfb_init(void)
{
#ifndef MODULE
- char *option = NULL;
+ const char *option = NULL;
#endif

if (fb_modesetting_disabled("imsttfb"))
diff --git a/drivers/video/fbdev/imxfb.c b/drivers/video/fbdev/imxfb.c
index d4e347aca0b0..ca67b32a29dd 100644
--- a/drivers/video/fbdev/imxfb.c
+++ b/drivers/video/fbdev/imxfb.c
@@ -846,7 +846,7 @@ static struct lcd_ops imxfb_lcd_ops = {

static int imxfb_setup(struct platform_device *pdev)
{
- char *options = NULL;
+ const char *options = NULL;
struct option_iter iter;
char *opt;

diff --git a/drivers/video/fbdev/intelfb/intelfbdrv.c b/drivers/video/fbdev/intelfb/intelfbdrv.c
index 43d677897392..664a8625e25c 100644
--- a/drivers/video/fbdev/intelfb/intelfbdrv.c
+++ b/drivers/video/fbdev/intelfb/intelfbdrv.c
@@ -385,7 +385,7 @@ static int __init intelfb_setup(const char *options)
static int __init intelfb_init(void)
{
#ifndef MODULE
- char *option = NULL;
+ const char *option = NULL;
#endif

DBG_MSG("intelfb_init\n");
diff --git a/drivers/video/fbdev/kyro/fbdev.c b/drivers/video/fbdev/kyro/fbdev.c
index ccfec4e55ecf..903f0ac03bca 100644
--- a/drivers/video/fbdev/kyro/fbdev.c
+++ b/drivers/video/fbdev/kyro/fbdev.c
@@ -792,7 +792,7 @@ static void kyrofb_remove(struct pci_dev *pdev)
static int __init kyrofb_init(void)
{
#ifndef MODULE
- char *option = NULL;
+ const char *option = NULL;
#endif

if (fb_modesetting_disabled("kyrofb"))
diff --git a/drivers/video/fbdev/macfb.c b/drivers/video/fbdev/macfb.c
index c7e17a14daf1..dbddf9e83b2f 100644
--- a/drivers/video/fbdev/macfb.c
+++ b/drivers/video/fbdev/macfb.c
@@ -541,7 +541,7 @@ static int __init macfb_init(void)
{
int video_cmap_len, video_is_nubus = 0;
struct nubus_rsrc *ndev = NULL;
- char *option = NULL;
+ const char *option = NULL;
int err;

if (fb_get_options("macfb", &option))
diff --git a/drivers/video/fbdev/matrox/matroxfb_base.c b/drivers/video/fbdev/matrox/matroxfb_base.c
index 4c2086136e9b..c1d1076bc172 100644
--- a/drivers/video/fbdev/matrox/matroxfb_base.c
+++ b/drivers/video/fbdev/matrox/matroxfb_base.c
@@ -2475,7 +2475,7 @@ static int __initdata initialized = 0;

static int __init matroxfb_init(void)
{
- char *option = NULL;
+ const char *option = NULL;
int err = 0;

DBG(__func__)
diff --git a/drivers/video/fbdev/mx3fb.c b/drivers/video/fbdev/mx3fb.c
index ca58afe366b4..04818f352eea 100644
--- a/drivers/video/fbdev/mx3fb.c
+++ b/drivers/video/fbdev/mx3fb.c
@@ -1655,7 +1655,7 @@ static struct platform_driver mx3fb_driver = {
static int __init mx3fb_setup(void)
{
#ifndef MODULE
- char *options = NULL;
+ const char *options = NULL;
struct option_iter iter;
char *opt;

diff --git a/drivers/video/fbdev/neofb.c b/drivers/video/fbdev/neofb.c
index 01ed78d987b1..21e8a72cda90 100644
--- a/drivers/video/fbdev/neofb.c
+++ b/drivers/video/fbdev/neofb.c
@@ -2213,7 +2213,7 @@ static int __init neofb_setup(const char *options)
static int __init neofb_init(void)
{
#ifndef MODULE
- char *option = NULL;
+ const char *option = NULL;
#endif

if (fb_modesetting_disabled("neofb"))
diff --git a/drivers/video/fbdev/nvidia/nvidia.c b/drivers/video/fbdev/nvidia/nvidia.c
index d779163f919a..bd649539181f 100644
--- a/drivers/video/fbdev/nvidia/nvidia.c
+++ b/drivers/video/fbdev/nvidia/nvidia.c
@@ -1532,7 +1532,7 @@ static struct pci_driver nvidiafb_driver = {
static int nvidiafb_init(void)
{
#ifndef MODULE
- char *option = NULL;
+ const char *option = NULL;
#endif

if (fb_modesetting_disabled("nvidiafb"))
diff --git a/drivers/video/fbdev/ocfb.c b/drivers/video/fbdev/ocfb.c
index fa15b932b323..07b7d5e61895 100644
--- a/drivers/video/fbdev/ocfb.c
+++ b/drivers/video/fbdev/ocfb.c
@@ -412,7 +412,7 @@ static struct platform_driver ocfb_driver = {
static int __init ocfb_init(void)
{
#ifndef MODULE
- char *option = NULL;
+ const char *option = NULL;

if (fb_get_options("ocfb", &option))
return -ENODEV;
diff --git a/drivers/video/fbdev/omap/omapfb_main.c b/drivers/video/fbdev/omap/omapfb_main.c
index db5256c71f5b..8715eaf8ddf6 100644
--- a/drivers/video/fbdev/omap/omapfb_main.c
+++ b/drivers/video/fbdev/omap/omapfb_main.c
@@ -1905,7 +1905,7 @@ static int __init omapfb_setup(const char *options)
static int __init omapfb_init(void)
{
#ifndef MODULE
- char *option;
+ const char *option;

if (fb_get_options("omapfb", &option))
return -ENODEV;
diff --git a/drivers/video/fbdev/platinumfb.c b/drivers/video/fbdev/platinumfb.c
index 33bf75309815..ab75df9d0bb6 100644
--- a/drivers/video/fbdev/platinumfb.c
+++ b/drivers/video/fbdev/platinumfb.c
@@ -683,7 +683,7 @@ static struct platform_driver platinum_driver =
static int __init platinumfb_init(void)
{
#ifndef MODULE
- char *option = NULL;
+ const char *option = NULL;

if (fb_get_options("platinumfb", &option))
return -ENODEV;
diff --git a/drivers/video/fbdev/pm2fb.c b/drivers/video/fbdev/pm2fb.c
index 38c5c57ce2b0..d87ceaaf529d 100644
--- a/drivers/video/fbdev/pm2fb.c
+++ b/drivers/video/fbdev/pm2fb.c
@@ -1809,7 +1809,7 @@ static int __init pm2fb_setup(const char *options)
static int __init pm2fb_init(void)
{
#ifndef MODULE
- char *option = NULL;
+ const char *option = NULL;
#endif

if (fb_modesetting_disabled("pm2fb"))
diff --git a/drivers/video/fbdev/pm3fb.c b/drivers/video/fbdev/pm3fb.c
index c4d4f08b4114..500a8c1130c6 100644
--- a/drivers/video/fbdev/pm3fb.c
+++ b/drivers/video/fbdev/pm3fb.c
@@ -1545,7 +1545,7 @@ static int __init pm3fb_init(void)
* For kernel boot options (in 'video=pm3fb:<options>' format)
*/
#ifndef MODULE
- char *option = NULL;
+ const char *option = NULL;
#endif

if (fb_modesetting_disabled("pm3fb"))
diff --git a/drivers/video/fbdev/ps3fb.c b/drivers/video/fbdev/ps3fb.c
index 575b2911977a..62236bbb02b5 100644
--- a/drivers/video/fbdev/ps3fb.c
+++ b/drivers/video/fbdev/ps3fb.c
@@ -1257,7 +1257,7 @@ static struct ps3_system_bus_driver ps3fb_driver = {

static int __init ps3fb_setup(void)
{
- char *options;
+ const char *options;
struct option_iter iter;
char *this_opt;

diff --git a/drivers/video/fbdev/pvr2fb.c b/drivers/video/fbdev/pvr2fb.c
index c332f2c38114..acc81fb11da1 100644
--- a/drivers/video/fbdev/pvr2fb.c
+++ b/drivers/video/fbdev/pvr2fb.c
@@ -1085,7 +1085,7 @@ static int __init pvr2fb_init(void)
int i, ret = -ENODEV;

#ifndef MODULE
- char *option = NULL;
+ const char *option = NULL;
#endif

if (fb_modesetting_disabled("pvr2fb"))
diff --git a/drivers/video/fbdev/pxafb.c b/drivers/video/fbdev/pxafb.c
index d2db9c20d515..0699710b0beb 100644
--- a/drivers/video/fbdev/pxafb.c
+++ b/drivers/video/fbdev/pxafb.c
@@ -2040,7 +2040,7 @@ static char g_options[256] = "";
#ifndef MODULE
static int __init pxafb_setup_options(void)
{
- char *options = NULL;
+ const char *options = NULL;

if (fb_get_options("pxafb", &options))
return -ENODEV;
diff --git a/drivers/video/fbdev/riva/fbdev.c b/drivers/video/fbdev/riva/fbdev.c
index 7f35edad249e..934c6e30109b 100644
--- a/drivers/video/fbdev/riva/fbdev.c
+++ b/drivers/video/fbdev/riva/fbdev.c
@@ -2167,7 +2167,7 @@ static struct pci_driver rivafb_driver = {
static int rivafb_init(void)
{
#ifndef MODULE
- char *option = NULL;
+ const char *option = NULL;
#endif

if (fb_modesetting_disabled("rivafb"))
diff --git a/drivers/video/fbdev/s3fb.c b/drivers/video/fbdev/s3fb.c
index 37f5ea25efd6..824325eb9fbe 100644
--- a/drivers/video/fbdev/s3fb.c
+++ b/drivers/video/fbdev/s3fb.c
@@ -1562,7 +1562,7 @@ static int __init s3fb_init(void)
{

#ifndef MODULE
- char *option = NULL;
+ const char *option = NULL;
#endif

if (fb_modesetting_disabled("s3fb"))
diff --git a/drivers/video/fbdev/savage/savagefb_driver.c b/drivers/video/fbdev/savage/savagefb_driver.c
index 4650688fd23c..a6e573b2d996 100644
--- a/drivers/video/fbdev/savage/savagefb_driver.c
+++ b/drivers/video/fbdev/savage/savagefb_driver.c
@@ -2560,7 +2560,7 @@ static int __init savagefb_setup(const char *options)

static int __init savagefb_init(void)
{
- char *option;
+ const char *option;

DBG("savagefb_init");

diff --git a/drivers/video/fbdev/sis/sis_main.c b/drivers/video/fbdev/sis/sis_main.c
index 9f63812a5f66..d8109dd20bc6 100644
--- a/drivers/video/fbdev/sis/sis_main.c
+++ b/drivers/video/fbdev/sis/sis_main.c
@@ -6587,7 +6587,7 @@ static struct pci_driver sisfb_driver = {
static int __init sisfb_init(void)
{
#ifndef MODULE
- char *options = NULL;
+ const char *options = NULL;
#endif

if (fb_modesetting_disabled("sisfb"))
diff --git a/drivers/video/fbdev/skeletonfb.c b/drivers/video/fbdev/skeletonfb.c
index ee6944d0ebc1..f6efad18e4d7 100644
--- a/drivers/video/fbdev/skeletonfb.c
+++ b/drivers/video/fbdev/skeletonfb.c
@@ -899,7 +899,7 @@ static int __init xxxfb_init(void)
* For kernel boot options (in 'video=xxxfb:<options>' format)
*/
#ifndef MODULE
- char *option = NULL;
+ const char *option = NULL;

if (fb_get_options("xxxfb", &option))
return -ENODEV;
diff --git a/drivers/video/fbdev/sm712fb.c b/drivers/video/fbdev/sm712fb.c
index a83f48fce5b1..c6232bc688ea 100644
--- a/drivers/video/fbdev/sm712fb.c
+++ b/drivers/video/fbdev/sm712fb.c
@@ -1755,7 +1755,7 @@ static struct pci_driver smtcfb_driver = {

static int __init sm712fb_init(void)
{
- char *option = NULL;
+ const char *option = NULL;

if (fb_modesetting_disabled("sm712fb"))
return -ENODEV;
diff --git a/drivers/video/fbdev/sstfb.c b/drivers/video/fbdev/sstfb.c
index b509020fed74..7a0a612a7658 100644
--- a/drivers/video/fbdev/sstfb.c
+++ b/drivers/video/fbdev/sstfb.c
@@ -1507,7 +1507,7 @@ static struct pci_driver sstfb_driver = {

static int sstfb_init(void)
{
- char *option = NULL;
+ const char *option = NULL;

if (fb_modesetting_disabled("sstfb"))
return -ENODEV;
diff --git a/drivers/video/fbdev/stifb.c b/drivers/video/fbdev/stifb.c
index 304ce8fcb9f8..c1f28bb046d3 100644
--- a/drivers/video/fbdev/stifb.c
+++ b/drivers/video/fbdev/stifb.c
@@ -1401,7 +1401,7 @@ static int __init stifb_init(void)
int i;

#ifndef MODULE
- char *option = NULL;
+ const char *option = NULL;

if (fb_get_options("stifb", &option))
return -ENODEV;
diff --git a/drivers/video/fbdev/tdfxfb.c b/drivers/video/fbdev/tdfxfb.c
index 1fdaf328f03e..3158644454d7 100644
--- a/drivers/video/fbdev/tdfxfb.c
+++ b/drivers/video/fbdev/tdfxfb.c
@@ -1635,7 +1635,7 @@ static void tdfxfb_remove(struct pci_dev *pdev)
static int __init tdfxfb_init(void)
{
#ifndef MODULE
- char *option = NULL;
+ const char *option = NULL;
#endif

if (fb_modesetting_disabled("tdfxfb"))
diff --git a/drivers/video/fbdev/tgafb.c b/drivers/video/fbdev/tgafb.c
index 0862d9a54aef..ad88fc0cd01e 100644
--- a/drivers/video/fbdev/tgafb.c
+++ b/drivers/video/fbdev/tgafb.c
@@ -1600,7 +1600,7 @@ static int tgafb_init(void)
{
int status;
#ifndef MODULE
- char *option = NULL;
+ const char *option = NULL;
#endif

if (fb_modesetting_disabled("tgafb"))
diff --git a/drivers/video/fbdev/tridentfb.c b/drivers/video/fbdev/tridentfb.c
index 3299806c0f58..2a70b48e6d15 100644
--- a/drivers/video/fbdev/tridentfb.c
+++ b/drivers/video/fbdev/tridentfb.c
@@ -1818,7 +1818,7 @@ static int __init tridentfb_setup(const char *options)
static int __init tridentfb_init(void)
{
#ifndef MODULE
- char *option = NULL;
+ const char *option = NULL;
#endif

if (fb_modesetting_disabled("tridentfb"))
diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c
index 13bd8503a06b..98e074d3e61b 100644
--- a/drivers/video/fbdev/uvesafb.c
+++ b/drivers/video/fbdev/uvesafb.c
@@ -1886,7 +1886,7 @@ static int uvesafb_init(void)
int err;

#ifndef MODULE
- char *option = NULL;
+ const char *option = NULL;

if (fb_get_options("uvesafb", &option))
return -ENODEV;
diff --git a/drivers/video/fbdev/valkyriefb.c b/drivers/video/fbdev/valkyriefb.c
index 3c20f392370a..daf218632d53 100644
--- a/drivers/video/fbdev/valkyriefb.c
+++ b/drivers/video/fbdev/valkyriefb.c
@@ -304,7 +304,7 @@ static int __init valkyriefb_init(void)
struct fb_info_valkyrie *p;
unsigned long frame_buffer_phys, cmap_regs_phys;
int err;
- char *option = NULL;
+ const char *option = NULL;

if (fb_get_options("valkyriefb", &option))
return -ENODEV;
diff --git a/drivers/video/fbdev/vesafb.c b/drivers/video/fbdev/vesafb.c
index 7299cebb6962..5d909d88a251 100644
--- a/drivers/video/fbdev/vesafb.c
+++ b/drivers/video/fbdev/vesafb.c
@@ -253,7 +253,7 @@ static int vesafb_probe(struct platform_device *dev)
unsigned int size_vmode;
unsigned int size_remap;
unsigned int size_total;
- char *option = NULL;
+ const char *option = NULL;

/* ignore error return of fb_get_options */
fb_get_options("vesafb", &option);
diff --git a/drivers/video/fbdev/vfb.c b/drivers/video/fbdev/vfb.c
index 7694e5026155..b68c0dd747cf 100644
--- a/drivers/video/fbdev/vfb.c
+++ b/drivers/video/fbdev/vfb.c
@@ -513,7 +513,7 @@ static int __init vfb_init(void)
int ret = 0;

#ifndef MODULE
- char *option = NULL;
+ const char *option = NULL;

if (fb_get_options("vfb", &option))
return -ENODEV;
diff --git a/drivers/video/fbdev/via/viafbdev.c b/drivers/video/fbdev/via/viafbdev.c
index 749aee9f6c56..40a4739ff060 100644
--- a/drivers/video/fbdev/via/viafbdev.c
+++ b/drivers/video/fbdev/via/viafbdev.c
@@ -1923,7 +1923,7 @@ void via_fb_pci_remove(struct pci_dev *pdev)
#ifndef MODULE
static int __init viafb_setup(void)
{
- char *options;
+ const char *options;
struct option_iter iter;
char *this_opt;

diff --git a/drivers/video/fbdev/vt8623fb.c b/drivers/video/fbdev/vt8623fb.c
index 321b1813cf3c..9bd908dace15 100644
--- a/drivers/video/fbdev/vt8623fb.c
+++ b/drivers/video/fbdev/vt8623fb.c
@@ -919,9 +919,8 @@ static void __exit vt8623fb_cleanup(void)

static int __init vt8623fb_init(void)
{
-
#ifndef MODULE
- char *option = NULL;
+ const char *option = NULL;
#endif

if (fb_modesetting_disabled("vt8623fb"))
diff --git a/include/linux/fb.h b/include/linux/fb.h
index d96529caa35e..0bebdd03f287 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -601,7 +601,7 @@ extern void fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u3
extern void fb_set_suspend(struct fb_info *info, int state);
extern int fb_get_color_depth(struct fb_var_screeninfo *var,
struct fb_fix_screeninfo *fix);
-extern int fb_get_options(const char *name, char **option);
+extern int fb_get_options(const char *name, const char **option);
extern int fb_new_modelist(struct fb_info *info);

extern bool fb_center_logo;
--
2.39.2


2023-03-10 08:18:37

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v2 061/101] fbdev/ps3fb: Duplicate video-mode option string

Hi Thomas,

On Thu, Mar 9, 2023 at 5:02 PM Thomas Zimmermann <[email protected]> wrote:
> Assume that the driver does not own the option string or its substrings
> and hence duplicate the option string for the video mode. Allocate the
> copy's memory with kstrdup() and free it in the module's exit function.
>
> Done in preparation of switching the driver to struct option_iter and
> constifying the option string.
>
> v2:
> * replace static memory with kstrdup()/kfree() (Geert)
>
> Signed-off-by: Thomas Zimmermann <[email protected]>

Thanks for the upodate!

> --- a/drivers/video/fbdev/ps3fb.c
> +++ b/drivers/video/fbdev/ps3fb.c
> @@ -260,6 +260,7 @@ static const struct fb_videomode ps3fb_modedb[] = {
> static int ps3fb_mode;
> module_param(ps3fb_mode, int, 0);
>
> +static char *mode_option_buf;

Do you really need this variable? It contains the same value
as mode_option below.
This is a common pattern in several patches.

> static char *mode_option;
>
> static int ps3fb_cmp_mode(const struct fb_videomode *vmode,
> @@ -1276,8 +1277,11 @@ static int __init ps3fb_setup(void)
> continue;
> if (!strncmp(this_opt, "mode:", 5))
> ps3fb_mode = simple_strtoul(this_opt + 5, NULL, 0);
> - else
> - mode_option = this_opt;
> + else {
> + kfree(mode_option_buf);
> + mode_option_buf = kstrdup(this_opt, GFP_KERNEL); // ignore errors
> + mode_option = mode_option_buf;
> + }
> }
> return 0;
> }
> @@ -1294,6 +1298,7 @@ static void __exit ps3fb_exit(void)
> {
> pr_debug(" -> %s:%d\n", __func__, __LINE__);
> ps3_system_bus_driver_unregister(&ps3fb_driver);
> + kfree(mode_option_buf);
> pr_debug(" <- %s:%d\n", __func__, __LINE__);
> }

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2023-03-10 08:24:47

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v2 000/101] fbdev: Fix memory leak in option parsing

Hi Thomas,

On Thu, Mar 9, 2023 at 5:02 PM Thomas Zimmermann <[email protected]> wrote:
> Introduce struct option_iter and helpers to parse command-line
> options with comma-separated key-value pairs. Then convert fbdev
> drivers to the new interface. Fixes a memory leak in the parsing of
> the video= option.
>
> Before commit 73ce73c30ba9 ("fbdev: Transfer video= option strings to
> caller; clarify ownership"), a call to fb_get_options() either
> returned an internal string or a duplicated string; hence ownership of
> the string's memory buffer was not well defined, but depended on how
> users specified the video= option on the kernel command line. For
> global settings, the caller owned the returned memory and for per-driver
> settings, fb_get_options() owned the memory. As calling drivers were
> unable to detect the case, they had no option but to leak the the memory.
>
> Commit 73ce73c30ba9 ("fbdev: Transfer video= option strings to caller;
> clarify ownership") changed semantics to caller-owned strings. Drivers
> still leaked the memory, but at least ownership was clear.

While I can find the actual patch[1], I cannot find this commit?
Where was it applied?

[1] https://lore.kernel.org/all/[email protected]

> This patchset fixes the memory leak and changes string ownership back
> to fb_get_options(). Patch 1 introduces struct option_iter and a few
> helpers. The interface takes an option string, such as video=, in the
> common form value1,key2:value2,value3 etc and returns the individual
> comma-separated pairs. Various modules use this pattern, so the code
> is located under lib/.
>
> Patches 2 to 100 go through fbdev drivers and convert them to the new
> interface. This often requires a number of cleanups. A driver would
> typically refer to the option string's video mode. Such strings are now
> copied to driver-allocated memory so that drivers don't refer directly
> to the option string's memory. The option iterator then replaces manual
> parsing loops based on strsep(","). All driver-allocated memory is
> released by removing the device or unloading the module.
>
> Patch 101 finally changes the ownership of the option string to be
> internal to fb_get_option(); thereby fixing the memory leak. The option
> iterator holds its own copy of the string and is not affected by the
> change.
>
> Most fbdev drivers only support to parse option strings if they are
> built-in. I assume that's because of the original fuzzy semantics of
> fb_get_options(). A later patchset could change the driver to respect
> video= settings in any configuration.
>
> v2:
> * use kstrdup()/kfree() for video strings (Geert, Timur)
> * fix iterator docs (Randy)
> * update iterator interface

Thanks for the update, this looks much better!

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2023-03-10 12:21:59

by Thomas Zimmermann

[permalink] [raw]
Subject: Re: [PATCH v2 061/101] fbdev/ps3fb: Duplicate video-mode option string

Hi Geert

Am 10.03.23 um 09:18 schrieb Geert Uytterhoeven:
> Hi Thomas,
>
> On Thu, Mar 9, 2023 at 5:02 PM Thomas Zimmermann <[email protected]> wrote:
>> Assume that the driver does not own the option string or its substrings
>> and hence duplicate the option string for the video mode. Allocate the
>> copy's memory with kstrdup() and free it in the module's exit function.
>>
>> Done in preparation of switching the driver to struct option_iter and
>> constifying the option string.
>>
>> v2:
>> * replace static memory with kstrdup()/kfree() (Geert)
>>
>> Signed-off-by: Thomas Zimmermann <[email protected]>
>
> Thanks for the upodate!
>
>> --- a/drivers/video/fbdev/ps3fb.c
>> +++ b/drivers/video/fbdev/ps3fb.c
>> @@ -260,6 +260,7 @@ static const struct fb_videomode ps3fb_modedb[] = {
>> static int ps3fb_mode;
>> module_param(ps3fb_mode, int, 0);
>>
>> +static char *mode_option_buf;
>
> Do you really need this variable? It contains the same value
> as mode_option below.
> This is a common pattern in several patches.

In most cases, the extra variable is necessary. mode_option, or a
similar variable, is often also used to store module parameters or is
initialized from a static string. In those cases we obviously cannot
free the memory. Hence the additional variable for the freeing the
allocation.

I reviewed the patches and it looks like kyrofb, ps3fb, and sm712fb
might be able to work without the _buf variable. I'll try to update those.

Best regards
Thomas

>
>> static char *mode_option;
>>
>> static int ps3fb_cmp_mode(const struct fb_videomode *vmode,
>> @@ -1276,8 +1277,11 @@ static int __init ps3fb_setup(void)
>> continue;
>> if (!strncmp(this_opt, "mode:", 5))
>> ps3fb_mode = simple_strtoul(this_opt + 5, NULL, 0);
>> - else
>> - mode_option = this_opt;
>> + else {
>> + kfree(mode_option_buf);
>> + mode_option_buf = kstrdup(this_opt, GFP_KERNEL); // ignore errors
>> + mode_option = mode_option_buf;
>> + }
>> }
>> return 0;
>> }
>> @@ -1294,6 +1298,7 @@ static void __exit ps3fb_exit(void)
>> {
>> pr_debug(" -> %s:%d\n", __func__, __LINE__);
>> ps3_system_bus_driver_unregister(&ps3fb_driver);
>> + kfree(mode_option_buf);
>> pr_debug(" <- %s:%d\n", __func__, __LINE__);
>> }
>
> Gr{oetje,eeting}s,
>
> Geert
>

--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Ivo Totev


Attachments:
OpenPGP_signature (840.00 B)
OpenPGP digital signature

2023-03-10 12:45:01

by Thomas Zimmermann

[permalink] [raw]
Subject: Re: [PATCH v2 000/101] fbdev: Fix memory leak in option parsing

Hi Geert

Am 10.03.23 um 09:24 schrieb Geert Uytterhoeven:
> Hi Thomas,
>
> On Thu, Mar 9, 2023 at 5:02 PM Thomas Zimmermann <[email protected]> wrote:
>> Introduce struct option_iter and helpers to parse command-line
>> options with comma-separated key-value pairs. Then convert fbdev
>> drivers to the new interface. Fixes a memory leak in the parsing of
>> the video= option.
>>
>> Before commit 73ce73c30ba9 ("fbdev: Transfer video= option strings to
>> caller; clarify ownership"), a call to fb_get_options() either
>> returned an internal string or a duplicated string; hence ownership of
>> the string's memory buffer was not well defined, but depended on how
>> users specified the video= option on the kernel command line. For
>> global settings, the caller owned the returned memory and for per-driver
>> settings, fb_get_options() owned the memory. As calling drivers were
>> unable to detect the case, they had no option but to leak the the memory.
>>
>> Commit 73ce73c30ba9 ("fbdev: Transfer video= option strings to caller;
>> clarify ownership") changed semantics to caller-owned strings. Drivers
>> still leaked the memory, but at least ownership was clear.
>
> While I can find the actual patch[1], I cannot find this commit?
> Where was it applied?

It's currently in drm-misc-next.


https://cgit.freedesktop.org/drm/drm-misc/commit/?id=73ce73c30ba9ae4d90fdfad7ebe9104001d5d851

Best regards
Thomas

>
> [1] https://lore.kernel.org/all/[email protected]
>
>> This patchset fixes the memory leak and changes string ownership back
>> to fb_get_options(). Patch 1 introduces struct option_iter and a few
>> helpers. The interface takes an option string, such as video=, in the
>> common form value1,key2:value2,value3 etc and returns the individual
>> comma-separated pairs. Various modules use this pattern, so the code
>> is located under lib/.
>>
>> Patches 2 to 100 go through fbdev drivers and convert them to the new
>> interface. This often requires a number of cleanups. A driver would
>> typically refer to the option string's video mode. Such strings are now
>> copied to driver-allocated memory so that drivers don't refer directly
>> to the option string's memory. The option iterator then replaces manual
>> parsing loops based on strsep(","). All driver-allocated memory is
>> released by removing the device or unloading the module.
>>
>> Patch 101 finally changes the ownership of the option string to be
>> internal to fb_get_option(); thereby fixing the memory leak. The option
>> iterator holds its own copy of the string and is not affected by the
>> change.
>>
>> Most fbdev drivers only support to parse option strings if they are
>> built-in. I assume that's because of the original fuzzy semantics of
>> fb_get_options(). A later patchset could change the driver to respect
>> video= settings in any configuration.
>>
>> v2:
>> * use kstrdup()/kfree() for video strings (Geert, Timur)
>> * fix iterator docs (Randy)
>> * update iterator interface
>
> Thanks for the update, this looks much better!
>
> Gr{oetje,eeting}s,
>
> Geert
>

--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Ivo Totev


Attachments:
OpenPGP_signature (840.00 B)
OpenPGP digital signature

2023-03-12 10:51:33

by Michael Kelley (LINUX)

[permalink] [raw]
Subject: RE: [PATCH v2 031/101] fbdev/hyperv_fb: Duplicate video-mode option string

From: Thomas Zimmermann <[email protected]> Sent: Thursday, March 9, 2023 8:01 AM
>
> Assume that the driver does not own the option string or its substrings
> and hence duplicate the option string for the video mode. As the driver
> implements a very simple mode parser in a fairly unstructured way, just
> duplicate the option string and parse the duplicated memory buffer. Free
> the buffer afterwards.
>
> Done in preparation of constifying the option string and switching the
> driver to struct option_iter.
>
> Signed-off-by: Thomas Zimmermann <[email protected]>
> ---
> drivers/video/fbdev/hyperv_fb.c | 18 +++++++++++++-----
> 1 file changed, 13 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
> index 4a6a3303b6b4..edb0555239c6 100644
> --- a/drivers/video/fbdev/hyperv_fb.c
> +++ b/drivers/video/fbdev/hyperv_fb.c
> @@ -903,17 +903,23 @@ static const struct fb_ops hvfb_ops = {
> static void hvfb_get_option(struct fb_info *info)
> {
> struct hvfb_par *par = info->par;
> - char *opt = NULL, *p;
> + char *options = NULL;
> + char *optbuf, *opt, *p;
> uint x = 0, y = 0;
>
> - if (fb_get_options(KBUILD_MODNAME, &opt) || !opt || !*opt)
> + if (fb_get_options(KBUILD_MODNAME, &options) || !options || !*options)
> return;
>
> + optbuf = kstrdup(options, GFP_KERNEL);
> + if (!optbuf)
> + return;
> + opt = optbuf;
> +
> p = strsep(&opt, "x");
> if (!*p || kstrtouint(p, 0, &x) ||
> !opt || !*opt || kstrtouint(opt, 0, &y)) {
> pr_err("Screen option is invalid: skipped\n");
> - return;
> + goto out;
> }
>
> if (x < HVFB_WIDTH_MIN || y < HVFB_HEIGHT_MIN ||
> @@ -922,12 +928,14 @@ static void hvfb_get_option(struct fb_info *info)
> (par->synthvid_version == SYNTHVID_VERSION_WIN8 &&
> x * y * screen_depth / 8 > SYNTHVID_FB_SIZE_WIN8)) {
> pr_err("Screen resolution option is out of range: skipped\n");
> - return;
> + goto out;
> }
>
> screen_width = x;
> screen_height = y;
> - return;
> +
> +out:
> + kfree(optbuf);
> }
>
> /*
> --
> 2.39.2

Reviewed-by: Michael Kelley <[email protected]>


2023-03-20 10:07:51

by Thomas Zimmermann

[permalink] [raw]
Subject: Re: [PATCH v2 000/101] fbdev: Fix memory leak in option parsing

Geert, Helge? Do you have further comments? There's not really much
for a v3 yet.

Best regards
Thomas

Am 09.03.23 um 17:00 schrieb Thomas Zimmermann:
> Introduce struct option_iter and helpers to parse command-line
> options with comma-separated key-value pairs. Then convert fbdev
> drivers to the new interface. Fixes a memory leak in the parsing of
> the video= option.
>
> Before commit 73ce73c30ba9 ("fbdev: Transfer video= option strings to
> caller; clarify ownership"), a call to fb_get_options() either
> returned an internal string or a duplicated string; hence ownership of
> the string's memory buffer was not well defined, but depended on how
> users specified the video= option on the kernel command line. For
> global settings, the caller owned the returned memory and for per-driver
> settings, fb_get_options() owned the memory. As calling drivers were
> unable to detect the case, they had no option but to leak the the memory.
>
> Commit 73ce73c30ba9 ("fbdev: Transfer video= option strings to caller;
> clarify ownership") changed semantics to caller-owned strings. Drivers
> still leaked the memory, but at least ownership was clear.
>
> This patchset fixes the memory leak and changes string ownership back
> to fb_get_options(). Patch 1 introduces struct option_iter and a few
> helpers. The interface takes an option string, such as video=, in the
> common form value1,key2:value2,value3 etc and returns the individual
> comma-separated pairs. Various modules use this pattern, so the code
> is located under lib/.
>
> Patches 2 to 100 go through fbdev drivers and convert them to the new
> interface. This often requires a number of cleanups. A driver would
> typically refer to the option string's video mode. Such strings are now
> copied to driver-allocated memory so that drivers don't refer directly
> to the option string's memory. The option iterator then replaces manual
> parsing loops based on strsep(","). All driver-allocated memory is
> released by removing the device or unloading the module.
>
> Patch 101 finally changes the ownership of the option string to be
> internal to fb_get_option(); thereby fixing the memory leak. The option
> iterator holds its own copy of the string and is not affected by the
> change.
>
> Most fbdev drivers only support to parse option strings if they are
> built-in. I assume that's because of the original fuzzy semantics of
> fb_get_options(). A later patchset could change the driver to respect
> video= settings in any configuration.
>
> v2:
> * use kstrdup()/kfree() for video strings (Geert, Timur)
> * fix iterator docs (Randy)
> * update iterator interface
>
> Thomas Zimmermann (101):
> lib: Add option iterator
> fbdev/68328fb: Remove trailing whitespaces
> fbdev/68328fb: Remove unused option string
> fbdev/acornfb: Only init fb_info once
> fbdev/acornfb: Parse option string with struct option_iter
> fbdev/amifb: Duplicate video-mode option string
> fbdev/amifb: Parse option string with struct option_iter
> fbdev/arkfb: Duplicate video-mode option string
> fbdev/atafb: Duplicate video-mode option string
> fbdev/atafb: Parse option string with struct option_iter
> fbdev/aty: Duplicate video-mode option string
> fbdev/aty: Parse option string with struct option_iter
> fbdev/au1100fb: Parse option string with struct option_iter
> fbdev/au1200fb: Parse option string with struct option_iter
> fbdev/cirrusfb: Duplicate video-mode option string
> fbdev/cirrusfb: Parse option string with struct option_iter
> fbdev/controlfb: Remove trailing whitespaces
> fbdev/controlfb: Parse option string with struct option_iter
> fbdev/cyber2000fb: Parse option string with struct option_iter
> fbdev/efifb: Parse option string with struct option_iter
> fbdev/fm2fb: Parse option string with struct option_iter
> fbdev/fsl-diu-fb: Duplicate video-mode option string
> fbdev/fsl-diu-fb: Parse option string with struct option_iter
> fbdev/gbefb: Duplicate video-mode option string
> fbdev/gbefb: Parse option string with struct option_iter
> fbdev/geode: Duplicate video-mode option string
> fbdev/geode: Parse option string with struct option_iter
> fbdev/grvga: Duplicate video-mode option string
> fbdev/grvga: Parse option string with struct option_iter
> fbdev/gxt4500: Duplicate video-mode option string
> fbdev/hyperv_fb: Duplicate video-mode option string
> fbdev/i740fb: Duplicate video-mode option string
> fbdev/i740fb: Parse option string with struct option_iter
> fbdev/i810: Duplicate video-mode option string
> fbdev/i810: Parse option string with struct option_iter
> fbdev/imsttfb: Parse option string with struct option_iter
> fbdev/intelfb: Duplicate video-mode option string
> fbdev/intelfb: Parse option string with struct option_iter
> fbdev/imxfb: Duplicate video-mode option string
> fbdev/imxfb: Parse option string with struct option_iter
> fbdev/kyrofb: Duplicate video-mode option string
> fbdev/kyrofb: Parse option string with struct option_iter
> fbdev/macfb: Remove trailing whitespaces
> fbdev/macfb: Parse option string with struct option_iter
> fbdev/matroxfb: Parse option string with struct option_iter
> fbdev/mx3fb: Duplicate video-mode option string
> fbdev/mx3fb: Parse option string with struct option_iter
> fbdev/neofb: Duplicate video-mode option string
> fbdev/neofb: Parse option string with struct option_iter
> fbdev/nvidiafb: Duplicate video-mode option string
> fbdev/nvidiafb: Parse option string with struct option_iter
> fbdev/ocfb: Duplicate video-mode option string
> fbdev/ocfb: Parse option string with struct option_iter
> fbdev/omapfb: Parse option string with struct option_iter
> fbdev/platinumfb: Remove trailing whitespaces
> fbdev/platinumfb: Parse option string with struct option_iter
> fbdev/pm2fb: Duplicate video-mode option string
> fbdev/pm2fb: Parse option string with struct option_iter
> fbdev/pm3fb: Duplicate video-mode option string
> fbdev/pm3fb: Parse option string with struct option_iter
> fbdev/ps3fb: Duplicate video-mode option string
> fbdev/ps3fb: Parse option string with struct option_iter
> fbdev/pvr2fb: Duplicate video-mode option string
> fbdev/pvr2fb: Parse option string with struct option_iter
> fbdev/pxafb: Parse option string with struct option_iter
> fbdev/rivafb: Duplicate video-mode option string
> fbdev/rivafb: Parse option string with struct option_iter
> fbdev/s3fb: Duplicate video-mode option string
> fbdev/s3fb: Parse option string with struct option_iter
> fbdev/savagefb: Duplicate video-mode option string
> fbdev/savagefb: Parse option string with struct option_iter
> fbdev/sisfb: Constify mode string
> fbdev/sisfb: Parse option string with struct option_iter
> fbdev/skeletonfb: Parse option string with struct option_iter
> fbdev/sm712fb: Duplicate video-mode option string
> fbdev/sstfb: Duplicate video-mode option string
> fbdev/sstfb: Parse option string with struct option_iter
> fbdev/stifb: Remove trailing whitespaces
> fbdev/stifb: Constify option string
> fbdev/tdfxfb: Duplicate video-mode option string
> fbdev/tdfxfb: Parse option string with struct option_iter
> fbdev/tgafb: Duplicate video-mode option string
> fbdev/tgafb: Parse option string with struct option_iter
> fbdev/tmiofb: Remove unused option string
> fbdev/tridentfb: Duplicate video-mode option string
> fbdev/tridentfb: Parse option string with struct option_iter
> fbdev/uvesafb: Duplicate video-mode option string
> fbdev/uvesafb: Parse option string with struct option_iter
> fbdev/valkyriefb: Remove trailing whitespaces
> fbdev/valkyriefb: Parse option string with struct option_iter
> fbdev/vermilion: Remove unused option string
> fbdev/vesafb: Parse option string with struct option_iter
> fbdev/vfb: Remove trailing whitespaces
> fbdev/vfb: Duplicate video-mode option string
> fbdev/vfb: Parse option string with struct option_iter
> fbdev/viafb: Parse option string with struct option_iter
> fbdev/vt8623fb: Duplicate video-mode option string
> staging/sm750fb: Release g_settings in module-exit function
> staging/sm750fb: Duplicate video-mode option string
> staging/sm750fb: Parse option string with struct option_iter
> fbdev: Constify option strings
>
> Documentation/core-api/kernel-api.rst | 9 ++
> drivers/staging/sm750fb/sm750.c | 63 ++++----
> drivers/video/fbdev/68328fb.c | 24 +--
> drivers/video/fbdev/acornfb.c | 23 ++-
> drivers/video/fbdev/amifb.c | 23 +--
> drivers/video/fbdev/arkfb.c | 10 +-
> drivers/video/fbdev/atafb.c | 21 +--
> drivers/video/fbdev/aty/aty128fb.c | 22 ++-
> drivers/video/fbdev/aty/atyfb_base.c | 23 ++-
> drivers/video/fbdev/aty/radeon_base.c | 26 +--
> drivers/video/fbdev/au1100fb.c | 13 +-
> drivers/video/fbdev/au1200fb.c | 15 +-
> drivers/video/fbdev/cirrusfb.c | 30 ++--
> drivers/video/fbdev/controlfb.c | 47 +++---
> drivers/video/fbdev/core/fb_cmdline.c | 13 +-
> drivers/video/fbdev/core/modedb.c | 8 +-
> drivers/video/fbdev/cyber2000fb.c | 17 +-
> drivers/video/fbdev/efifb.c | 44 ++---
> drivers/video/fbdev/ep93xx-fb.c | 2 +-
> drivers/video/fbdev/fm2fb.c | 14 +-
> drivers/video/fbdev/fsl-diu-fb.c | 24 +--
> drivers/video/fbdev/gbefb.c | 23 +--
> drivers/video/fbdev/geode/gx1fb_core.c | 16 +-
> drivers/video/fbdev/geode/gxfb_core.c | 23 +--
> drivers/video/fbdev/geode/lxfb_core.c | 25 +--
> drivers/video/fbdev/grvga.c | 18 ++-
> drivers/video/fbdev/gxt4500.c | 13 +-
> drivers/video/fbdev/hyperv_fb.c | 18 ++-
> drivers/video/fbdev/i740fb.c | 26 +--
> drivers/video/fbdev/i810/i810_main.c | 26 ++-
> drivers/video/fbdev/imsttfb.c | 16 +-
> drivers/video/fbdev/imxfb.c | 21 +--
> drivers/video/fbdev/intelfb/intelfbdrv.c | 23 ++-
> drivers/video/fbdev/kyro/fbdev.c | 21 ++-
> drivers/video/fbdev/macfb.c | 26 +--
> drivers/video/fbdev/matrox/matroxfb_base.c | 19 +--
> drivers/video/fbdev/mx3fb.c | 23 ++-
> drivers/video/fbdev/neofb.c | 26 +--
> drivers/video/fbdev/nvidia/nvidia.c | 26 ++-
> drivers/video/fbdev/ocfb.c | 21 ++-
> drivers/video/fbdev/omap/omapfb_main.c | 15 +-
> drivers/video/fbdev/platinumfb.c | 44 ++---
> drivers/video/fbdev/pm2fb.c | 25 +--
> drivers/video/fbdev/pm3fb.c | 27 ++--
> drivers/video/fbdev/ps3fb.c | 28 ++--
> drivers/video/fbdev/pvr2fb.c | 32 ++--
> drivers/video/fbdev/pxafb.c | 18 ++-
> drivers/video/fbdev/riva/fbdev.c | 26 ++-
> drivers/video/fbdev/s3fb.c | 27 ++--
> drivers/video/fbdev/savage/savagefb_driver.c | 20 ++-
> drivers/video/fbdev/sis/sis_main.c | 24 +--
> drivers/video/fbdev/skeletonfb.c | 17 +-
> drivers/video/fbdev/sm712fb.c | 12 +-
> drivers/video/fbdev/sstfb.c | 25 +--
> drivers/video/fbdev/stifb.c | 162 +++++++++----------
> drivers/video/fbdev/tdfxfb.c | 21 ++-
> drivers/video/fbdev/tgafb.c | 30 ++--
> drivers/video/fbdev/tmiofb.c | 24 +--
> drivers/video/fbdev/tridentfb.c | 27 ++--
> drivers/video/fbdev/uvesafb.c | 21 ++-
> drivers/video/fbdev/valkyriefb.c | 30 ++--
> drivers/video/fbdev/vermilion/vermilion.c | 7 +-
> drivers/video/fbdev/vesafb.c | 16 +-
> drivers/video/fbdev/vfb.c | 35 ++--
> drivers/video/fbdev/via/viafbdev.c | 15 +-
> drivers/video/fbdev/vt8623fb.c | 11 +-
> include/linux/cmdline.h | 36 +++++
> include/linux/fb.h | 2 +-
> lib/Makefile | 2 +-
> lib/cmdline_iter.c | 109 +++++++++++++
> 70 files changed, 1087 insertions(+), 682 deletions(-)
> create mode 100644 include/linux/cmdline.h
> create mode 100644 lib/cmdline_iter.c
>

--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Ivo Totev


Attachments:
OpenPGP_signature (840.00 B)
OpenPGP digital signature

2023-03-20 19:33:12

by Helge Deller

[permalink] [raw]
Subject: Re: [PATCH v2 000/101] fbdev: Fix memory leak in option parsing

Hi Thomas,

On 3/20/23 11:07, Thomas Zimmermann wrote:
> Geert, Helge?  Do you have further comments?  There's not really much for a v3 yet.

I understand the motivation and I see you invested a lot of work on it,
which is really appreciated.
But I have mixed feelings about that patch itself.

Nevertheless, it mixes multiple things.
Regarding the possible memory leak (for the parameter) you added in various
places a kfree(), but this doesn't make it easier for the driver author to know
when to free and when not.
I wonder if it would be possible to store the kstrdup() value in the
"struct module" (or somewhere module related) instead add kfree it at a central place when the
module is unloaded (instead inside the driver itself). That way no driver needs
to be touched and there are less changes necessary.
And it would change it back to globally-owned strings.

With such a change I think the new command parsing functions wouldn't be needed
either, and ideally, where possible, a conversion to module_param() in various
places would be better.

I'm sure I haven't overlooked everything yet, but I think if we can reduce
the necessary changes by fixing things globally it makes more sense.

Helge

>
> Best regards
> Thomas
>
> Am 09.03.23 um 17:00 schrieb Thomas Zimmermann:
>> Introduce struct option_iter and helpers to parse command-line
>> options with comma-separated key-value pairs. Then convert fbdev
>> drivers to the new interface. Fixes a memory leak in the parsing of
>> the video= option.
>>
>> Before commit 73ce73c30ba9 ("fbdev: Transfer video= option strings to
>> caller; clarify ownership"), a call to fb_get_options() either
>> returned an internal string or a duplicated string; hence ownership of
>> the string's memory buffer was not well defined, but depended on how
>> users specified the video= option on the kernel command line. For
>> global settings, the caller owned the returned memory and for per-driver
>> settings, fb_get_options() owned the memory. As calling drivers were
>> unable to detect the case, they had no option but to leak the the memory.
>>
>> Commit 73ce73c30ba9 ("fbdev: Transfer video= option strings to caller;
>> clarify ownership") changed semantics to caller-owned strings. Drivers
>> still leaked the memory, but at least ownership was clear.
>>
>> This patchset fixes the memory leak and changes string ownership back
>> to fb_get_options(). Patch 1 introduces struct option_iter and a few
>> helpers. The interface takes an option string, such as video=, in the
>> common form value1,key2:value2,value3 etc and returns the individual
>> comma-separated pairs. Various modules use this pattern, so the code
>> is located under lib/.
>>
>> Patches 2 to 100 go through fbdev drivers and convert them to the new
>> interface. This often requires a number of cleanups. A driver would
>> typically refer to the option string's video mode. Such strings are now
>> copied to driver-allocated memory so that drivers don't refer directly
>> to the option string's memory. The option iterator then replaces manual
>> parsing loops based on strsep(","). All driver-allocated memory is
>> released by removing the device or unloading the module.
>>
>> Patch 101 finally changes the ownership of the option string to be
>> internal to fb_get_option(); thereby fixing the memory leak. The option
>> iterator holds its own copy of the string and is not affected by the
>> change.
>>
>> Most fbdev drivers only support to parse option strings if they are
>> built-in. I assume that's because of the original fuzzy semantics of
>> fb_get_options(). A later patchset could change the driver to respect
>> video= settings in any configuration.
>>
>> v2:
>>     * use kstrdup()/kfree() for video strings (Geert, Timur)
>>     * fix iterator docs (Randy)
>>     * update iterator interface
>>
>> Thomas Zimmermann (101):
>>    lib: Add option iterator
>>    fbdev/68328fb: Remove trailing whitespaces
>>    fbdev/68328fb: Remove unused option string
>>    fbdev/acornfb: Only init fb_info once
>>    fbdev/acornfb: Parse option string with struct option_iter
>>    fbdev/amifb: Duplicate video-mode option string
>>    fbdev/amifb: Parse option string with struct option_iter
>>    fbdev/arkfb: Duplicate video-mode option string
>>    fbdev/atafb: Duplicate video-mode option string
>>    fbdev/atafb: Parse option string with struct option_iter
>>    fbdev/aty: Duplicate video-mode option string
>>    fbdev/aty: Parse option string with struct option_iter
>>    fbdev/au1100fb: Parse option string with struct option_iter
>>    fbdev/au1200fb: Parse option string with struct option_iter
>>    fbdev/cirrusfb: Duplicate video-mode option string
>>    fbdev/cirrusfb: Parse option string with struct option_iter
>>    fbdev/controlfb: Remove trailing whitespaces
>>    fbdev/controlfb: Parse option string with struct option_iter
>>    fbdev/cyber2000fb: Parse option string with struct option_iter
>>    fbdev/efifb: Parse option string with struct option_iter
>>    fbdev/fm2fb: Parse option string with struct option_iter
>>    fbdev/fsl-diu-fb: Duplicate video-mode option string
>>    fbdev/fsl-diu-fb: Parse option string with struct option_iter
>>    fbdev/gbefb: Duplicate video-mode option string
>>    fbdev/gbefb: Parse option string with struct option_iter
>>    fbdev/geode: Duplicate video-mode option string
>>    fbdev/geode: Parse option string with struct option_iter
>>    fbdev/grvga: Duplicate video-mode option string
>>    fbdev/grvga: Parse option string with struct option_iter
>>    fbdev/gxt4500: Duplicate video-mode option string
>>    fbdev/hyperv_fb: Duplicate video-mode option string
>>    fbdev/i740fb: Duplicate video-mode option string
>>    fbdev/i740fb: Parse option string with struct option_iter
>>    fbdev/i810: Duplicate video-mode option string
>>    fbdev/i810: Parse option string with struct option_iter
>>    fbdev/imsttfb: Parse option string with struct option_iter
>>    fbdev/intelfb: Duplicate video-mode option string
>>    fbdev/intelfb: Parse option string with struct option_iter
>>    fbdev/imxfb: Duplicate video-mode option string
>>    fbdev/imxfb: Parse option string with struct option_iter
>>    fbdev/kyrofb: Duplicate video-mode option string
>>    fbdev/kyrofb: Parse option string with struct option_iter
>>    fbdev/macfb: Remove trailing whitespaces
>>    fbdev/macfb: Parse option string with struct option_iter
>>    fbdev/matroxfb: Parse option string with struct option_iter
>>    fbdev/mx3fb: Duplicate video-mode option string
>>    fbdev/mx3fb: Parse option string with struct option_iter
>>    fbdev/neofb: Duplicate video-mode option string
>>    fbdev/neofb: Parse option string with struct option_iter
>>    fbdev/nvidiafb: Duplicate video-mode option string
>>    fbdev/nvidiafb: Parse option string with struct option_iter
>>    fbdev/ocfb: Duplicate video-mode option string
>>    fbdev/ocfb: Parse option string with struct option_iter
>>    fbdev/omapfb: Parse option string with struct option_iter
>>    fbdev/platinumfb: Remove trailing whitespaces
>>    fbdev/platinumfb: Parse option string with struct option_iter
>>    fbdev/pm2fb: Duplicate video-mode option string
>>    fbdev/pm2fb: Parse option string with struct option_iter
>>    fbdev/pm3fb: Duplicate video-mode option string
>>    fbdev/pm3fb: Parse option string with struct option_iter
>>    fbdev/ps3fb: Duplicate video-mode option string
>>    fbdev/ps3fb: Parse option string with struct option_iter
>>    fbdev/pvr2fb: Duplicate video-mode option string
>>    fbdev/pvr2fb: Parse option string with struct option_iter
>>    fbdev/pxafb: Parse option string with struct option_iter
>>    fbdev/rivafb: Duplicate video-mode option string
>>    fbdev/rivafb: Parse option string with struct option_iter
>>    fbdev/s3fb: Duplicate video-mode option string
>>    fbdev/s3fb: Parse option string with struct option_iter
>>    fbdev/savagefb: Duplicate video-mode option string
>>    fbdev/savagefb: Parse option string with struct option_iter
>>    fbdev/sisfb: Constify mode string
>>    fbdev/sisfb: Parse option string with struct option_iter
>>    fbdev/skeletonfb: Parse option string with struct option_iter
>>    fbdev/sm712fb: Duplicate video-mode option string
>>    fbdev/sstfb: Duplicate video-mode option string
>>    fbdev/sstfb: Parse option string with struct option_iter
>>    fbdev/stifb: Remove trailing whitespaces
>>    fbdev/stifb: Constify option string
>>    fbdev/tdfxfb: Duplicate video-mode option string
>>    fbdev/tdfxfb: Parse option string with struct option_iter
>>    fbdev/tgafb: Duplicate video-mode option string
>>    fbdev/tgafb: Parse option string with struct option_iter
>>    fbdev/tmiofb: Remove unused option string
>>    fbdev/tridentfb: Duplicate video-mode option string
>>    fbdev/tridentfb: Parse option string with struct option_iter
>>    fbdev/uvesafb: Duplicate video-mode option string
>>    fbdev/uvesafb: Parse option string with struct option_iter
>>    fbdev/valkyriefb: Remove trailing whitespaces
>>    fbdev/valkyriefb: Parse option string with struct option_iter
>>    fbdev/vermilion: Remove unused option string
>>    fbdev/vesafb: Parse option string with struct option_iter
>>    fbdev/vfb: Remove trailing whitespaces
>>    fbdev/vfb: Duplicate video-mode option string
>>    fbdev/vfb: Parse option string with struct option_iter
>>    fbdev/viafb: Parse option string with struct option_iter
>>    fbdev/vt8623fb: Duplicate video-mode option string
>>    staging/sm750fb: Release g_settings in module-exit function
>>    staging/sm750fb: Duplicate video-mode option string
>>    staging/sm750fb: Parse option string with struct option_iter
>>    fbdev: Constify option strings
>>
>>   Documentation/core-api/kernel-api.rst        |   9 ++
>>   drivers/staging/sm750fb/sm750.c              |  63 ++++----
>>   drivers/video/fbdev/68328fb.c                |  24 +--
>>   drivers/video/fbdev/acornfb.c                |  23 ++-
>>   drivers/video/fbdev/amifb.c                  |  23 +--
>>   drivers/video/fbdev/arkfb.c                  |  10 +-
>>   drivers/video/fbdev/atafb.c                  |  21 +--
>>   drivers/video/fbdev/aty/aty128fb.c           |  22 ++-
>>   drivers/video/fbdev/aty/atyfb_base.c         |  23 ++-
>>   drivers/video/fbdev/aty/radeon_base.c        |  26 +--
>>   drivers/video/fbdev/au1100fb.c               |  13 +-
>>   drivers/video/fbdev/au1200fb.c               |  15 +-
>>   drivers/video/fbdev/cirrusfb.c               |  30 ++--
>>   drivers/video/fbdev/controlfb.c              |  47 +++---
>>   drivers/video/fbdev/core/fb_cmdline.c        |  13 +-
>>   drivers/video/fbdev/core/modedb.c            |   8 +-
>>   drivers/video/fbdev/cyber2000fb.c            |  17 +-
>>   drivers/video/fbdev/efifb.c                  |  44 ++---
>>   drivers/video/fbdev/ep93xx-fb.c              |   2 +-
>>   drivers/video/fbdev/fm2fb.c                  |  14 +-
>>   drivers/video/fbdev/fsl-diu-fb.c             |  24 +--
>>   drivers/video/fbdev/gbefb.c                  |  23 +--
>>   drivers/video/fbdev/geode/gx1fb_core.c       |  16 +-
>>   drivers/video/fbdev/geode/gxfb_core.c        |  23 +--
>>   drivers/video/fbdev/geode/lxfb_core.c        |  25 +--
>>   drivers/video/fbdev/grvga.c                  |  18 ++-
>>   drivers/video/fbdev/gxt4500.c                |  13 +-
>>   drivers/video/fbdev/hyperv_fb.c              |  18 ++-
>>   drivers/video/fbdev/i740fb.c                 |  26 +--
>>   drivers/video/fbdev/i810/i810_main.c         |  26 ++-
>>   drivers/video/fbdev/imsttfb.c                |  16 +-
>>   drivers/video/fbdev/imxfb.c                  |  21 +--
>>   drivers/video/fbdev/intelfb/intelfbdrv.c     |  23 ++-
>>   drivers/video/fbdev/kyro/fbdev.c             |  21 ++-
>>   drivers/video/fbdev/macfb.c                  |  26 +--
>>   drivers/video/fbdev/matrox/matroxfb_base.c   |  19 +--
>>   drivers/video/fbdev/mx3fb.c                  |  23 ++-
>>   drivers/video/fbdev/neofb.c                  |  26 +--
>>   drivers/video/fbdev/nvidia/nvidia.c          |  26 ++-
>>   drivers/video/fbdev/ocfb.c                   |  21 ++-
>>   drivers/video/fbdev/omap/omapfb_main.c       |  15 +-
>>   drivers/video/fbdev/platinumfb.c             |  44 ++---
>>   drivers/video/fbdev/pm2fb.c                  |  25 +--
>>   drivers/video/fbdev/pm3fb.c                  |  27 ++--
>>   drivers/video/fbdev/ps3fb.c                  |  28 ++--
>>   drivers/video/fbdev/pvr2fb.c                 |  32 ++--
>>   drivers/video/fbdev/pxafb.c                  |  18 ++-
>>   drivers/video/fbdev/riva/fbdev.c             |  26 ++-
>>   drivers/video/fbdev/s3fb.c                   |  27 ++--
>>   drivers/video/fbdev/savage/savagefb_driver.c |  20 ++-
>>   drivers/video/fbdev/sis/sis_main.c           |  24 +--
>>   drivers/video/fbdev/skeletonfb.c             |  17 +-
>>   drivers/video/fbdev/sm712fb.c                |  12 +-
>>   drivers/video/fbdev/sstfb.c                  |  25 +--
>>   drivers/video/fbdev/stifb.c                  | 162 +++++++++----------
>>   drivers/video/fbdev/tdfxfb.c                 |  21 ++-
>>   drivers/video/fbdev/tgafb.c                  |  30 ++--
>>   drivers/video/fbdev/tmiofb.c                 |  24 +--
>>   drivers/video/fbdev/tridentfb.c              |  27 ++--
>>   drivers/video/fbdev/uvesafb.c                |  21 ++-
>>   drivers/video/fbdev/valkyriefb.c             |  30 ++--
>>   drivers/video/fbdev/vermilion/vermilion.c    |   7 +-
>>   drivers/video/fbdev/vesafb.c                 |  16 +-
>>   drivers/video/fbdev/vfb.c                    |  35 ++--
>>   drivers/video/fbdev/via/viafbdev.c           |  15 +-
>>   drivers/video/fbdev/vt8623fb.c               |  11 +-
>>   include/linux/cmdline.h                      |  36 +++++
>>   include/linux/fb.h                           |   2 +-
>>   lib/Makefile                                 |   2 +-
>>   lib/cmdline_iter.c                           | 109 +++++++++++++
>>   70 files changed, 1087 insertions(+), 682 deletions(-)
>>   create mode 100644 include/linux/cmdline.h
>>   create mode 100644 lib/cmdline_iter.c
>>
>


2023-03-21 08:55:55

by Thomas Zimmermann

[permalink] [raw]
Subject: Re: [PATCH v2 000/101] fbdev: Fix memory leak in option parsing

Hi Helge,

thanks for the feedback.

Am 20.03.23 um 20:25 schrieb Helge Deller:
> Hi Thomas,
>
> On 3/20/23 11:07, Thomas Zimmermann wrote:
>> Geert, Helge?  Do you have further comments?  There's not really much
>> for a v3 yet.
>
> I understand the motivation and I see you invested a lot of work on it,
> which is really appreciated.
> But I have mixed feelings about that patch itself.

Can I have an ack on the patches that fix trailing whitespaces? Those
should be uncontroversion.

>
> Nevertheless, it mixes multiple things.
> Regarding the possible memory leak (for the parameter) you added in various
> places a kfree(), but this doesn't make it easier for the driver author
> to know
> when to free and when not.
> I wonder if it would be possible to store the kstrdup() value in the
> "struct module" (or somewhere module related) instead add kfree it at a
> central place when the
> module is unloaded (instead inside the driver itself). That way no
> driver needs
> to be touched and there are less changes necessary.
> And it would change it back to globally-owned strings.

Is there any interface in place to do this? Otherwise, tie-ing the
string to struct module impacts every single module in the kernel.
That's a no-go IMHO and I'm not going to do that.

Here's a different proposal: most drivers parse from within module_init,
but the parsing could be moved to probe time, when a device struct is
available. The allocated memory could then be managed with the devm_
infrastrcuture. This would require to drop the MODULE guards around the
options parsing; something we should consider anyway.

Gbefb and a few other already do this. See patch 24 for an example.

>
> With such a change I think the new command parsing functions wouldn't be
> needed
> either, and ideally, where possible, a conversion to module_param() in
> various
> places would be better.

A number of modules in other subsystems use the same hand-written
strsep() loops. So the idea was to use the iterator elsewhere. We could
certainly drop it from this patchset, as it's not essential to fixing
the memory leak.

Best regards
Thomas

>
> I'm sure I haven't overlooked everything yet, but I think if we can reduce
> the necessary changes by fixing things globally it makes more sense.
>
> Helge
>
>>
>> Best regards
>> Thomas
>>
>> Am 09.03.23 um 17:00 schrieb Thomas Zimmermann:
>>> Introduce struct option_iter and helpers to parse command-line
>>> options with comma-separated key-value pairs. Then convert fbdev
>>> drivers to the new interface. Fixes a memory leak in the parsing of
>>> the video= option.
>>>
>>> Before commit 73ce73c30ba9 ("fbdev: Transfer video= option strings to
>>> caller; clarify ownership"), a call to fb_get_options() either
>>> returned an internal string or a duplicated string; hence ownership of
>>> the string's memory buffer was not well defined, but depended on how
>>> users specified the video= option on the kernel command line. For
>>> global settings, the caller owned the returned memory and for per-driver
>>> settings, fb_get_options() owned the memory. As calling drivers were
>>> unable to detect the case, they had no option but to leak the the
>>> memory.
>>>
>>> Commit 73ce73c30ba9 ("fbdev: Transfer video= option strings to caller;
>>> clarify ownership") changed semantics to caller-owned strings. Drivers
>>> still leaked the memory, but at least ownership was clear.
>>>
>>> This patchset fixes the memory leak and changes string ownership back
>>> to fb_get_options(). Patch 1 introduces struct option_iter and a few
>>> helpers. The interface takes an option string, such as video=, in the
>>> common form value1,key2:value2,value3 etc and returns the individual
>>> comma-separated pairs. Various modules use this pattern, so the code
>>> is located under lib/.
>>>
>>> Patches 2 to 100 go through fbdev drivers and convert them to the new
>>> interface. This often requires a number of cleanups. A driver would
>>> typically refer to the option string's video mode. Such strings are now
>>> copied to driver-allocated memory so that drivers don't refer directly
>>> to the option string's memory. The option iterator then replaces manual
>>> parsing loops based on strsep(","). All driver-allocated memory is
>>> released by removing the device or unloading the module.
>>>
>>> Patch 101 finally changes the ownership of the option string to be
>>> internal to fb_get_option(); thereby fixing the memory leak. The option
>>> iterator holds its own copy of the string and is not affected by the
>>> change.
>>>
>>> Most fbdev drivers only support to parse option strings if they are
>>> built-in. I assume that's because of the original fuzzy semantics of
>>> fb_get_options(). A later patchset could change the driver to respect
>>> video= settings in any configuration.
>>>
>>> v2:
>>>     * use kstrdup()/kfree() for video strings (Geert, Timur)
>>>     * fix iterator docs (Randy)
>>>     * update iterator interface
>>>
>>> Thomas Zimmermann (101):
>>>    lib: Add option iterator
>>>    fbdev/68328fb: Remove trailing whitespaces
>>>    fbdev/68328fb: Remove unused option string
>>>    fbdev/acornfb: Only init fb_info once
>>>    fbdev/acornfb: Parse option string with struct option_iter
>>>    fbdev/amifb: Duplicate video-mode option string
>>>    fbdev/amifb: Parse option string with struct option_iter
>>>    fbdev/arkfb: Duplicate video-mode option string
>>>    fbdev/atafb: Duplicate video-mode option string
>>>    fbdev/atafb: Parse option string with struct option_iter
>>>    fbdev/aty: Duplicate video-mode option string
>>>    fbdev/aty: Parse option string with struct option_iter
>>>    fbdev/au1100fb: Parse option string with struct option_iter
>>>    fbdev/au1200fb: Parse option string with struct option_iter
>>>    fbdev/cirrusfb: Duplicate video-mode option string
>>>    fbdev/cirrusfb: Parse option string with struct option_iter
>>>    fbdev/controlfb: Remove trailing whitespaces
>>>    fbdev/controlfb: Parse option string with struct option_iter
>>>    fbdev/cyber2000fb: Parse option string with struct option_iter
>>>    fbdev/efifb: Parse option string with struct option_iter
>>>    fbdev/fm2fb: Parse option string with struct option_iter
>>>    fbdev/fsl-diu-fb: Duplicate video-mode option string
>>>    fbdev/fsl-diu-fb: Parse option string with struct option_iter
>>>    fbdev/gbefb: Duplicate video-mode option string
>>>    fbdev/gbefb: Parse option string with struct option_iter
>>>    fbdev/geode: Duplicate video-mode option string
>>>    fbdev/geode: Parse option string with struct option_iter
>>>    fbdev/grvga: Duplicate video-mode option string
>>>    fbdev/grvga: Parse option string with struct option_iter
>>>    fbdev/gxt4500: Duplicate video-mode option string
>>>    fbdev/hyperv_fb: Duplicate video-mode option string
>>>    fbdev/i740fb: Duplicate video-mode option string
>>>    fbdev/i740fb: Parse option string with struct option_iter
>>>    fbdev/i810: Duplicate video-mode option string
>>>    fbdev/i810: Parse option string with struct option_iter
>>>    fbdev/imsttfb: Parse option string with struct option_iter
>>>    fbdev/intelfb: Duplicate video-mode option string
>>>    fbdev/intelfb: Parse option string with struct option_iter
>>>    fbdev/imxfb: Duplicate video-mode option string
>>>    fbdev/imxfb: Parse option string with struct option_iter
>>>    fbdev/kyrofb: Duplicate video-mode option string
>>>    fbdev/kyrofb: Parse option string with struct option_iter
>>>    fbdev/macfb: Remove trailing whitespaces
>>>    fbdev/macfb: Parse option string with struct option_iter
>>>    fbdev/matroxfb: Parse option string with struct option_iter
>>>    fbdev/mx3fb: Duplicate video-mode option string
>>>    fbdev/mx3fb: Parse option string with struct option_iter
>>>    fbdev/neofb: Duplicate video-mode option string
>>>    fbdev/neofb: Parse option string with struct option_iter
>>>    fbdev/nvidiafb: Duplicate video-mode option string
>>>    fbdev/nvidiafb: Parse option string with struct option_iter
>>>    fbdev/ocfb: Duplicate video-mode option string
>>>    fbdev/ocfb: Parse option string with struct option_iter
>>>    fbdev/omapfb: Parse option string with struct option_iter
>>>    fbdev/platinumfb: Remove trailing whitespaces
>>>    fbdev/platinumfb: Parse option string with struct option_iter
>>>    fbdev/pm2fb: Duplicate video-mode option string
>>>    fbdev/pm2fb: Parse option string with struct option_iter
>>>    fbdev/pm3fb: Duplicate video-mode option string
>>>    fbdev/pm3fb: Parse option string with struct option_iter
>>>    fbdev/ps3fb: Duplicate video-mode option string
>>>    fbdev/ps3fb: Parse option string with struct option_iter
>>>    fbdev/pvr2fb: Duplicate video-mode option string
>>>    fbdev/pvr2fb: Parse option string with struct option_iter
>>>    fbdev/pxafb: Parse option string with struct option_iter
>>>    fbdev/rivafb: Duplicate video-mode option string
>>>    fbdev/rivafb: Parse option string with struct option_iter
>>>    fbdev/s3fb: Duplicate video-mode option string
>>>    fbdev/s3fb: Parse option string with struct option_iter
>>>    fbdev/savagefb: Duplicate video-mode option string
>>>    fbdev/savagefb: Parse option string with struct option_iter
>>>    fbdev/sisfb: Constify mode string
>>>    fbdev/sisfb: Parse option string with struct option_iter
>>>    fbdev/skeletonfb: Parse option string with struct option_iter
>>>    fbdev/sm712fb: Duplicate video-mode option string
>>>    fbdev/sstfb: Duplicate video-mode option string
>>>    fbdev/sstfb: Parse option string with struct option_iter
>>>    fbdev/stifb: Remove trailing whitespaces
>>>    fbdev/stifb: Constify option string
>>>    fbdev/tdfxfb: Duplicate video-mode option string
>>>    fbdev/tdfxfb: Parse option string with struct option_iter
>>>    fbdev/tgafb: Duplicate video-mode option string
>>>    fbdev/tgafb: Parse option string with struct option_iter
>>>    fbdev/tmiofb: Remove unused option string
>>>    fbdev/tridentfb: Duplicate video-mode option string
>>>    fbdev/tridentfb: Parse option string with struct option_iter
>>>    fbdev/uvesafb: Duplicate video-mode option string
>>>    fbdev/uvesafb: Parse option string with struct option_iter
>>>    fbdev/valkyriefb: Remove trailing whitespaces
>>>    fbdev/valkyriefb: Parse option string with struct option_iter
>>>    fbdev/vermilion: Remove unused option string
>>>    fbdev/vesafb: Parse option string with struct option_iter
>>>    fbdev/vfb: Remove trailing whitespaces
>>>    fbdev/vfb: Duplicate video-mode option string
>>>    fbdev/vfb: Parse option string with struct option_iter
>>>    fbdev/viafb: Parse option string with struct option_iter
>>>    fbdev/vt8623fb: Duplicate video-mode option string
>>>    staging/sm750fb: Release g_settings in module-exit function
>>>    staging/sm750fb: Duplicate video-mode option string
>>>    staging/sm750fb: Parse option string with struct option_iter
>>>    fbdev: Constify option strings
>>>
>>>   Documentation/core-api/kernel-api.rst        |   9 ++
>>>   drivers/staging/sm750fb/sm750.c              |  63 ++++----
>>>   drivers/video/fbdev/68328fb.c                |  24 +--
>>>   drivers/video/fbdev/acornfb.c                |  23 ++-
>>>   drivers/video/fbdev/amifb.c                  |  23 +--
>>>   drivers/video/fbdev/arkfb.c                  |  10 +-
>>>   drivers/video/fbdev/atafb.c                  |  21 +--
>>>   drivers/video/fbdev/aty/aty128fb.c           |  22 ++-
>>>   drivers/video/fbdev/aty/atyfb_base.c         |  23 ++-
>>>   drivers/video/fbdev/aty/radeon_base.c        |  26 +--
>>>   drivers/video/fbdev/au1100fb.c               |  13 +-
>>>   drivers/video/fbdev/au1200fb.c               |  15 +-
>>>   drivers/video/fbdev/cirrusfb.c               |  30 ++--
>>>   drivers/video/fbdev/controlfb.c              |  47 +++---
>>>   drivers/video/fbdev/core/fb_cmdline.c        |  13 +-
>>>   drivers/video/fbdev/core/modedb.c            |   8 +-
>>>   drivers/video/fbdev/cyber2000fb.c            |  17 +-
>>>   drivers/video/fbdev/efifb.c                  |  44 ++---
>>>   drivers/video/fbdev/ep93xx-fb.c              |   2 +-
>>>   drivers/video/fbdev/fm2fb.c                  |  14 +-
>>>   drivers/video/fbdev/fsl-diu-fb.c             |  24 +--
>>>   drivers/video/fbdev/gbefb.c                  |  23 +--
>>>   drivers/video/fbdev/geode/gx1fb_core.c       |  16 +-
>>>   drivers/video/fbdev/geode/gxfb_core.c        |  23 +--
>>>   drivers/video/fbdev/geode/lxfb_core.c        |  25 +--
>>>   drivers/video/fbdev/grvga.c                  |  18 ++-
>>>   drivers/video/fbdev/gxt4500.c                |  13 +-
>>>   drivers/video/fbdev/hyperv_fb.c              |  18 ++-
>>>   drivers/video/fbdev/i740fb.c                 |  26 +--
>>>   drivers/video/fbdev/i810/i810_main.c         |  26 ++-
>>>   drivers/video/fbdev/imsttfb.c                |  16 +-
>>>   drivers/video/fbdev/imxfb.c                  |  21 +--
>>>   drivers/video/fbdev/intelfb/intelfbdrv.c     |  23 ++-
>>>   drivers/video/fbdev/kyro/fbdev.c             |  21 ++-
>>>   drivers/video/fbdev/macfb.c                  |  26 +--
>>>   drivers/video/fbdev/matrox/matroxfb_base.c   |  19 +--
>>>   drivers/video/fbdev/mx3fb.c                  |  23 ++-
>>>   drivers/video/fbdev/neofb.c                  |  26 +--
>>>   drivers/video/fbdev/nvidia/nvidia.c          |  26 ++-
>>>   drivers/video/fbdev/ocfb.c                   |  21 ++-
>>>   drivers/video/fbdev/omap/omapfb_main.c       |  15 +-
>>>   drivers/video/fbdev/platinumfb.c             |  44 ++---
>>>   drivers/video/fbdev/pm2fb.c                  |  25 +--
>>>   drivers/video/fbdev/pm3fb.c                  |  27 ++--
>>>   drivers/video/fbdev/ps3fb.c                  |  28 ++--
>>>   drivers/video/fbdev/pvr2fb.c                 |  32 ++--
>>>   drivers/video/fbdev/pxafb.c                  |  18 ++-
>>>   drivers/video/fbdev/riva/fbdev.c             |  26 ++-
>>>   drivers/video/fbdev/s3fb.c                   |  27 ++--
>>>   drivers/video/fbdev/savage/savagefb_driver.c |  20 ++-
>>>   drivers/video/fbdev/sis/sis_main.c           |  24 +--
>>>   drivers/video/fbdev/skeletonfb.c             |  17 +-
>>>   drivers/video/fbdev/sm712fb.c                |  12 +-
>>>   drivers/video/fbdev/sstfb.c                  |  25 +--
>>>   drivers/video/fbdev/stifb.c                  | 162 +++++++++----------
>>>   drivers/video/fbdev/tdfxfb.c                 |  21 ++-
>>>   drivers/video/fbdev/tgafb.c                  |  30 ++--
>>>   drivers/video/fbdev/tmiofb.c                 |  24 +--
>>>   drivers/video/fbdev/tridentfb.c              |  27 ++--
>>>   drivers/video/fbdev/uvesafb.c                |  21 ++-
>>>   drivers/video/fbdev/valkyriefb.c             |  30 ++--
>>>   drivers/video/fbdev/vermilion/vermilion.c    |   7 +-
>>>   drivers/video/fbdev/vesafb.c                 |  16 +-
>>>   drivers/video/fbdev/vfb.c                    |  35 ++--
>>>   drivers/video/fbdev/via/viafbdev.c           |  15 +-
>>>   drivers/video/fbdev/vt8623fb.c               |  11 +-
>>>   include/linux/cmdline.h                      |  36 +++++
>>>   include/linux/fb.h                           |   2 +-
>>>   lib/Makefile                                 |   2 +-
>>>   lib/cmdline_iter.c                           | 109 +++++++++++++
>>>   70 files changed, 1087 insertions(+), 682 deletions(-)
>>>   create mode 100644 include/linux/cmdline.h
>>>   create mode 100644 lib/cmdline_iter.c
>>>
>>
>

--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Ivo Totev


Attachments:
OpenPGP_signature (840.00 B)
OpenPGP digital signature