]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 24 May 2021 12:01:45 +0000 (14:01 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 24 May 2021 12:01:45 +0000 (14:01 +0200)
added patches:
ics932s401-fix-broken-handling-of-errors-when-word-reading-fails.patch
leds-lp5523-check-return-value-of-lp5xx_read-and-jump-to-cleanup-code.patch
qlcnic-add-null-check-after-calling-netdev_alloc_skb.patch
tty-vt-always-invoke-vc-vc_sw-con_resize-callback.patch
vgacon-record-video-mode-changes-with-vt_resizex.patch
video-hgafb-fix-potential-null-pointer-dereference.patch
vt-fix-character-height-handling-with-vt_resizex.patch
vt_ioctl-revert-vt_resizex-parameter-handling-removal.patch

queue-5.10/ics932s401-fix-broken-handling-of-errors-when-word-reading-fails.patch [new file with mode: 0644]
queue-5.10/leds-lp5523-check-return-value-of-lp5xx_read-and-jump-to-cleanup-code.patch [new file with mode: 0644]
queue-5.10/qlcnic-add-null-check-after-calling-netdev_alloc_skb.patch [new file with mode: 0644]
queue-5.10/series
queue-5.10/tty-vt-always-invoke-vc-vc_sw-con_resize-callback.patch [new file with mode: 0644]
queue-5.10/vgacon-record-video-mode-changes-with-vt_resizex.patch [new file with mode: 0644]
queue-5.10/video-hgafb-fix-potential-null-pointer-dereference.patch [new file with mode: 0644]
queue-5.10/vt-fix-character-height-handling-with-vt_resizex.patch [new file with mode: 0644]
queue-5.10/vt_ioctl-revert-vt_resizex-parameter-handling-removal.patch [new file with mode: 0644]

diff --git a/queue-5.10/ics932s401-fix-broken-handling-of-errors-when-word-reading-fails.patch b/queue-5.10/ics932s401-fix-broken-handling-of-errors-when-word-reading-fails.patch
new file mode 100644 (file)
index 0000000..69a6c7a
--- /dev/null
@@ -0,0 +1,39 @@
+From a73b6a3b4109ce2ed01dbc51a6c1551a6431b53c Mon Sep 17 00:00:00 2001
+From: "Darrick J. Wong" <djwong@kernel.org>
+Date: Wed, 28 Apr 2021 15:25:34 -0700
+Subject: ics932s401: fix broken handling of errors when word reading fails
+
+From: Darrick J. Wong <djwong@kernel.org>
+
+commit a73b6a3b4109ce2ed01dbc51a6c1551a6431b53c upstream.
+
+In commit b05ae01fdb89, someone tried to make the driver handle i2c read
+errors by simply zeroing out the register contents, but for some reason
+left unaltered the code that sets the cached register value the function
+call return value.
+
+The original patch was authored by a member of the Underhanded
+Mangle-happy Nerds, I'm not terribly surprised.  I don't have the
+hardware anymore so I can't test this, but it seems like a pretty
+obvious API usage fix to me...
+
+Fixes: b05ae01fdb89 ("misc/ics932s401: Add a missing check to i2c_smbus_read_word_data")
+Signed-off-by: Darrick J. Wong <djwong@kernel.org>
+Link: https://lore.kernel.org/r/20210428222534.GJ3122264@magnolia
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/misc/ics932s401.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/misc/ics932s401.c
++++ b/drivers/misc/ics932s401.c
+@@ -134,7 +134,7 @@ static struct ics932s401_data *ics932s40
+       for (i = 0; i < NUM_MIRRORED_REGS; i++) {
+               temp = i2c_smbus_read_word_data(client, regs_to_copy[i]);
+               if (temp < 0)
+-                      data->regs[regs_to_copy[i]] = 0;
++                      temp = 0;
+               data->regs[regs_to_copy[i]] = temp >> 8;
+       }
diff --git a/queue-5.10/leds-lp5523-check-return-value-of-lp5xx_read-and-jump-to-cleanup-code.patch b/queue-5.10/leds-lp5523-check-return-value-of-lp5xx_read-and-jump-to-cleanup-code.patch
new file mode 100644 (file)
index 0000000..a0c141d
--- /dev/null
@@ -0,0 +1,37 @@
+From 6647f7a06eb030a2384ec71f0bb2e78854afabfe Mon Sep 17 00:00:00 2001
+From: Phillip Potter <phil@philpotter.co.uk>
+Date: Mon, 3 May 2021 13:56:36 +0200
+Subject: leds: lp5523: check return value of lp5xx_read and jump to cleanup code
+
+From: Phillip Potter <phil@philpotter.co.uk>
+
+commit 6647f7a06eb030a2384ec71f0bb2e78854afabfe upstream.
+
+Check return value of lp5xx_read and if non-zero, jump to code at end of
+the function, causing lp5523_stop_all_engines to be executed before
+returning the error value up the call chain. This fixes the original
+commit (248b57015f35) which was reverted due to the University of Minnesota
+problems.
+
+Cc: stable <stable@vger.kernel.org>
+Acked-by: Jacek Anaszewski <jacek.anaszewski@gmail.com>
+Signed-off-by: Phillip Potter <phil@philpotter.co.uk>
+Link: https://lore.kernel.org/r/20210503115736.2104747-10-gregkh@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/leds/leds-lp5523.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/leds/leds-lp5523.c
++++ b/drivers/leds/leds-lp5523.c
+@@ -305,7 +305,9 @@ static int lp5523_init_program_engine(st
+       /* Let the programs run for couple of ms and check the engine status */
+       usleep_range(3000, 6000);
+-      lp55xx_read(chip, LP5523_REG_STATUS, &status);
++      ret = lp55xx_read(chip, LP5523_REG_STATUS, &status);
++      if (ret)
++              goto out;
+       status &= LP5523_ENG_STATUS_MASK;
+       if (status != LP5523_ENG_STATUS_MASK) {
diff --git a/queue-5.10/qlcnic-add-null-check-after-calling-netdev_alloc_skb.patch b/queue-5.10/qlcnic-add-null-check-after-calling-netdev_alloc_skb.patch
new file mode 100644 (file)
index 0000000..fa80bd1
--- /dev/null
@@ -0,0 +1,44 @@
+From 84460f01cba382553199bc1361f69a872d5abed4 Mon Sep 17 00:00:00 2001
+From: Tom Seewald <tseewald@gmail.com>
+Date: Mon, 3 May 2021 13:56:52 +0200
+Subject: qlcnic: Add null check after calling netdev_alloc_skb
+
+From: Tom Seewald <tseewald@gmail.com>
+
+commit 84460f01cba382553199bc1361f69a872d5abed4 upstream.
+
+The function qlcnic_dl_lb_test() currently calls netdev_alloc_skb()
+without checking afterwards that the allocation succeeded. Fix this by
+checking if the skb is NULL and returning an error in such a case.
+Breaking out of the loop if the skb is NULL is not correct as no error
+would be reported to the caller and no message would be printed for the
+user.
+
+Cc: David S. Miller <davem@davemloft.net>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Tom Seewald <tseewald@gmail.com>
+Link: https://lore.kernel.org/r/20210503115736.2104747-26-gregkh@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
+@@ -1047,6 +1047,8 @@ int qlcnic_do_lb_test(struct qlcnic_adap
+       for (i = 0; i < QLCNIC_NUM_ILB_PKT; i++) {
+               skb = netdev_alloc_skb(adapter->netdev, QLCNIC_ILB_PKT_SIZE);
++              if (!skb)
++                      goto error;
+               qlcnic_create_loopback_buff(skb->data, adapter->mac_addr);
+               skb_put(skb, QLCNIC_ILB_PKT_SIZE);
+               adapter->ahw->diag_cnt = 0;
+@@ -1070,6 +1072,7 @@ int qlcnic_do_lb_test(struct qlcnic_adap
+                       cnt++;
+       }
+       if (cnt != i) {
++error:
+               dev_err(&adapter->pdev->dev,
+                       "LB Test: failed, TX[%d], RX[%d]\n", i, cnt);
+               if (mode != QLCNIC_ILB_MODE)
index f7f171e2cb9c1681b9022459088205a0688b875b..3dbc6398ca00b1442655c705e9bda7ddf51f5024 100644 (file)
@@ -88,3 +88,11 @@ ethernet-sun-niu-fix-missing-checks-of-niu_pci_eeprom_read.patch
 net-stmicro-handle-clk_prepare-failure-during-init.patch
 scsi-ufs-handle-cleanup-correctly-on-devm_reset_control_get-error.patch
 net-rtlwifi-properly-check-for-alloc_workqueue-failure.patch
+ics932s401-fix-broken-handling-of-errors-when-word-reading-fails.patch
+leds-lp5523-check-return-value-of-lp5xx_read-and-jump-to-cleanup-code.patch
+qlcnic-add-null-check-after-calling-netdev_alloc_skb.patch
+video-hgafb-fix-potential-null-pointer-dereference.patch
+vgacon-record-video-mode-changes-with-vt_resizex.patch
+vt_ioctl-revert-vt_resizex-parameter-handling-removal.patch
+vt-fix-character-height-handling-with-vt_resizex.patch
+tty-vt-always-invoke-vc-vc_sw-con_resize-callback.patch
diff --git a/queue-5.10/tty-vt-always-invoke-vc-vc_sw-con_resize-callback.patch b/queue-5.10/tty-vt-always-invoke-vc-vc_sw-con_resize-callback.patch
new file mode 100644 (file)
index 0000000..d9c9d7a
--- /dev/null
@@ -0,0 +1,71 @@
+From ffb324e6f874121f7dce5bdae5e05d02baae7269 Mon Sep 17 00:00:00 2001
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Date: Sat, 15 May 2021 03:00:37 +0000
+Subject: tty: vt: always invoke vc->vc_sw->con_resize callback
+
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+
+commit ffb324e6f874121f7dce5bdae5e05d02baae7269 upstream.
+
+syzbot is reporting OOB write at vga16fb_imageblit() [1], for
+resize_screen() from ioctl(VT_RESIZE) returns 0 without checking whether
+requested rows/columns fit the amount of memory reserved for the graphical
+screen if current mode is KD_GRAPHICS.
+
+----------
+  #include <sys/types.h>
+  #include <sys/stat.h>
+  #include <fcntl.h>
+  #include <sys/ioctl.h>
+  #include <linux/kd.h>
+  #include <linux/vt.h>
+
+  int main(int argc, char *argv[])
+  {
+        const int fd = open("/dev/char/4:1", O_RDWR);
+        struct vt_sizes vt = { 0x4100, 2 };
+
+        ioctl(fd, KDSETMODE, KD_GRAPHICS);
+        ioctl(fd, VT_RESIZE, &vt);
+        ioctl(fd, KDSETMODE, KD_TEXT);
+        return 0;
+  }
+----------
+
+Allow framebuffer drivers to return -EINVAL, by moving vc->vc_mode !=
+KD_GRAPHICS check from resize_screen() to fbcon_resize().
+
+Link: https://syzkaller.appspot.com/bug?extid=1f29e126cf461c4de3b3 [1]
+Reported-by: syzbot <syzbot+1f29e126cf461c4de3b3@syzkaller.appspotmail.com>
+Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Tested-by: syzbot <syzbot+1f29e126cf461c4de3b3@syzkaller.appspotmail.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/vt/vt.c              |    2 +-
+ drivers/video/fbdev/core/fbcon.c |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/tty/vt/vt.c
++++ b/drivers/tty/vt/vt.c
+@@ -1172,7 +1172,7 @@ static inline int resize_screen(struct v
+       /* Resizes the resolution of the display adapater */
+       int err = 0;
+-      if (vc->vc_mode != KD_GRAPHICS && vc->vc_sw->con_resize)
++      if (vc->vc_sw->con_resize)
+               err = vc->vc_sw->con_resize(vc, width, height, user);
+       return err;
+--- a/drivers/video/fbdev/core/fbcon.c
++++ b/drivers/video/fbdev/core/fbcon.c
+@@ -2031,7 +2031,7 @@ static int fbcon_resize(struct vc_data *
+                       return -EINVAL;
+               DPRINTK("resize now %ix%i\n", var.xres, var.yres);
+-              if (con_is_visible(vc)) {
++              if (con_is_visible(vc) && vc->vc_mode == KD_TEXT) {
+                       var.activate = FB_ACTIVATE_NOW |
+                               FB_ACTIVATE_FORCE;
+                       fb_set_var(info, &var);
diff --git a/queue-5.10/vgacon-record-video-mode-changes-with-vt_resizex.patch b/queue-5.10/vgacon-record-video-mode-changes-with-vt_resizex.patch
new file mode 100644 (file)
index 0000000..41b0001
--- /dev/null
@@ -0,0 +1,65 @@
+From d4d0ad57b3865795c4cde2fb5094c594c2e8f469 Mon Sep 17 00:00:00 2001
+From: "Maciej W. Rozycki" <macro@orcam.me.uk>
+Date: Thu, 13 May 2021 11:51:41 +0200
+Subject: vgacon: Record video mode changes with VT_RESIZEX
+
+From: Maciej W. Rozycki <macro@orcam.me.uk>
+
+commit d4d0ad57b3865795c4cde2fb5094c594c2e8f469 upstream.
+
+Fix an issue with VGA console font size changes made after the initial
+video text mode has been changed with a user tool like `svgatextmode'
+calling the VT_RESIZEX ioctl.  As it stands in that case the original
+screen geometry continues being used to validate further VT resizing.
+
+Consequently when the video adapter is firstly reprogrammed from the
+original say 80x25 text mode using a 9x16 character cell (720x400 pixel
+resolution) to say 80x37 text mode and the same character cell (720x592
+pixel resolution), and secondly the CRTC character cell updated to 9x8
+(by loading a suitable font with the KD_FONT_OP_SET request of the
+KDFONTOP ioctl), the VT geometry does not get further updated from 80x37
+and only upper half of the screen is used for the VT, with the lower
+half showing rubbish corresponding to whatever happens to be there in
+the video memory that maps to that part of the screen.  Of course the
+proportions change according to text mode geometries and font sizes
+chosen.
+
+Address the problem then, by updating the text mode geometry defaults
+rather than checking against them whenever the VT is resized via a user
+ioctl.
+
+Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk>
+Fixes: e400b6ec4ede ("vt/vgacon: Check if screen resize request comes from userspace")
+Cc: stable@vger.kernel.org # v2.6.24+
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/video/console/vgacon.c |   14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+--- a/drivers/video/console/vgacon.c
++++ b/drivers/video/console/vgacon.c
+@@ -1108,12 +1108,20 @@ static int vgacon_resize(struct vc_data
+       if ((width << 1) * height > vga_vram_size)
+               return -EINVAL;
++      if (user) {
++              /*
++               * Ho ho!  Someone (svgatextmode, eh?) may have reprogrammed
++               * the video mode!  Set the new defaults then and go away.
++               */
++              screen_info.orig_video_cols = width;
++              screen_info.orig_video_lines = height;
++              vga_default_font_height = c->vc_font.height;
++              return 0;
++      }
+       if (width % 2 || width > screen_info.orig_video_cols ||
+           height > (screen_info.orig_video_lines * vga_default_font_height)/
+           c->vc_font.height)
+-              /* let svgatextmode tinker with video timings and
+-                 return success */
+-              return (user) ? 0 : -EINVAL;
++              return -EINVAL;
+       if (con_is_visible(c) && !vga_is_gfx) /* who knows */
+               vgacon_doresize(c, width, height);
diff --git a/queue-5.10/video-hgafb-fix-potential-null-pointer-dereference.patch b/queue-5.10/video-hgafb-fix-potential-null-pointer-dereference.patch
new file mode 100644 (file)
index 0000000..90f13cd
--- /dev/null
@@ -0,0 +1,76 @@
+From dc13cac4862cc68ec74348a80b6942532b7735fa Mon Sep 17 00:00:00 2001
+From: Igor Matheus Andrade Torrente <igormtorrente@gmail.com>
+Date: Mon, 3 May 2021 13:57:06 +0200
+Subject: video: hgafb: fix potential NULL pointer dereference
+
+From: Igor Matheus Andrade Torrente <igormtorrente@gmail.com>
+
+commit dc13cac4862cc68ec74348a80b6942532b7735fa upstream.
+
+The return of ioremap if not checked, and can lead to a NULL to be
+assigned to hga_vram. Potentially leading to a NULL pointer
+dereference.
+
+The fix adds code to deal with this case in the error label and
+changes how the hgafb_probe handles the return of hga_card_detect.
+
+Cc: Ferenc Bakonyi <fero@drama.obuda.kando.hu>
+Cc: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Igor Matheus Andrade Torrente <igormtorrente@gmail.com>
+Link: https://lore.kernel.org/r/20210503115736.2104747-40-gregkh@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/video/fbdev/hgafb.c |   21 +++++++++++++--------
+ 1 file changed, 13 insertions(+), 8 deletions(-)
+
+--- a/drivers/video/fbdev/hgafb.c
++++ b/drivers/video/fbdev/hgafb.c
+@@ -285,6 +285,8 @@ static int hga_card_detect(void)
+       hga_vram_len  = 0x08000;
+       hga_vram = ioremap(0xb0000, hga_vram_len);
++      if (!hga_vram)
++              return -ENOMEM;
+       if (request_region(0x3b0, 12, "hgafb"))
+               release_io_ports = 1;
+@@ -344,13 +346,18 @@ static int hga_card_detect(void)
+                       hga_type_name = "Hercules";
+                       break;
+       }
+-      return 1;
++      return 0;
+ error:
+       if (release_io_ports)
+               release_region(0x3b0, 12);
+       if (release_io_port)
+               release_region(0x3bf, 1);
+-      return 0;
++
++      iounmap(hga_vram);
++
++      pr_err("hgafb: HGA card not detected.\n");
++
++      return -EINVAL;
+ }
+ /**
+@@ -548,13 +555,11 @@ static const struct fb_ops hgafb_ops = {
+ static int hgafb_probe(struct platform_device *pdev)
+ {
+       struct fb_info *info;
++      int ret;
+-      if (! hga_card_detect()) {
+-              printk(KERN_INFO "hgafb: HGA card not detected.\n");
+-              if (hga_vram)
+-                      iounmap(hga_vram);
+-              return -EINVAL;
+-      }
++      ret = hga_card_detect();
++      if (!ret)
++              return ret;
+       printk(KERN_INFO "hgafb: %s with %ldK of memory detected.\n",
+               hga_type_name, hga_vram_len/1024);
diff --git a/queue-5.10/vt-fix-character-height-handling-with-vt_resizex.patch b/queue-5.10/vt-fix-character-height-handling-with-vt_resizex.patch
new file mode 100644 (file)
index 0000000..db548e9
--- /dev/null
@@ -0,0 +1,226 @@
+From 860dafa902595fb5f1d23bbcce1215188c3341e6 Mon Sep 17 00:00:00 2001
+From: "Maciej W. Rozycki" <macro@orcam.me.uk>
+Date: Thu, 13 May 2021 11:51:50 +0200
+Subject: vt: Fix character height handling with VT_RESIZEX
+
+From: Maciej W. Rozycki <macro@orcam.me.uk>
+
+commit 860dafa902595fb5f1d23bbcce1215188c3341e6 upstream.
+
+Restore the original intent of the VT_RESIZEX ioctl's `v_clin' parameter
+which is the number of pixel rows per character (cell) rather than the
+height of the font used.
+
+For framebuffer devices the two values are always the same, because the
+former is inferred from the latter one.  For VGA used as a true text
+mode device these two parameters are independent from each other: the
+number of pixel rows per character is set in the CRT controller, while
+font height is in fact hardwired to 32 pixel rows and fonts of heights
+below that value are handled by padding their data with blanks when
+loaded to hardware for use by the character generator.  One can change
+the setting in the CRT controller and it will update the screen contents
+accordingly regardless of the font loaded.
+
+The `v_clin' parameter is used by the `vgacon' driver to set the height
+of the character cell and then the cursor position within.  Make the
+parameter explicit then, by defining a new `vc_cell_height' struct
+member of `vc_data', set it instead of `vc_font.height' from `v_clin' in
+the VT_RESIZEX ioctl, and then use it throughout the `vgacon' driver
+except where actual font data is accessed which as noted above is
+independent from the CRTC setting.
+
+This way the framebuffer console driver is free to ignore the `v_clin'
+parameter as irrelevant, as it always should have, avoiding any issues
+attempts to give the parameter a meaning there could have caused, such
+as one that has led to commit 988d0763361b ("vt_ioctl: make VT_RESIZEX
+behave like VT_RESIZE"):
+
+ "syzbot is reporting UAF/OOB read at bit_putcs()/soft_cursor() [1][2],
+  for vt_resizex() from ioctl(VT_RESIZEX) allows setting font height
+  larger than actual font height calculated by con_font_set() from
+  ioctl(PIO_FONT). Since fbcon_set_font() from con_font_set() allocates
+  minimal amount of memory based on actual font height calculated by
+  con_font_set(), use of vt_resizex() can cause UAF/OOB read for font
+  data."
+
+The problem first appeared around Linux 2.5.66 which predates our repo
+history, but the origin could be identified with the old MIPS/Linux repo
+also at: <git://git.kernel.org/pub/scm/linux/kernel/git/ralf/linux.git>
+as commit 9736a3546de7 ("Merge with Linux 2.5.66."), where VT_RESIZEX
+code in `vt_ioctl' was updated as follows:
+
+               if (clin)
+-                      video_font_height = clin;
++                      vc->vc_font.height = clin;
+
+making the parameter apply to framebuffer devices as well, perhaps due
+to the use of "font" in the name of the original `video_font_height'
+variable.  Use "cell" in the new struct member then to avoid ambiguity.
+
+References:
+
+[1] https://syzkaller.appspot.com/bug?id=32577e96d88447ded2d3b76d71254fb855245837
+[2] https://syzkaller.appspot.com/bug?id=6b8355d27b2b94fb5cedf4655e3a59162d9e48e3
+
+Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk>
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable@vger.kernel.org # v2.6.12+
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/vt/vt_ioctl.c      |    6 ++---
+ drivers/video/console/vgacon.c |   44 ++++++++++++++++++++---------------------
+ include/linux/console_struct.h |    1 
+ 3 files changed, 26 insertions(+), 25 deletions(-)
+
+--- a/drivers/tty/vt/vt_ioctl.c
++++ b/drivers/tty/vt/vt_ioctl.c
+@@ -806,17 +806,17 @@ static int vt_resizex(struct vc_data *vc
+               if (vcp) {
+                       int ret;
+                       int save_scan_lines = vcp->vc_scan_lines;
+-                      int save_font_height = vcp->vc_font.height;
++                      int save_cell_height = vcp->vc_cell_height;
+                       if (v.v_vlin)
+                               vcp->vc_scan_lines = v.v_vlin;
+                       if (v.v_clin)
+-                              vcp->vc_font.height = v.v_clin;
++                              vcp->vc_cell_height = v.v_clin;
+                       vcp->vc_resize_user = 1;
+                       ret = vc_resize(vcp, v.v_cols, v.v_rows);
+                       if (ret) {
+                               vcp->vc_scan_lines = save_scan_lines;
+-                              vcp->vc_font.height = save_font_height;
++                              vcp->vc_cell_height = save_cell_height;
+                               console_unlock();
+                               return ret;
+                       }
+--- a/drivers/video/console/vgacon.c
++++ b/drivers/video/console/vgacon.c
+@@ -384,7 +384,7 @@ static void vgacon_init(struct vc_data *
+               vc_resize(c, vga_video_num_columns, vga_video_num_lines);
+       c->vc_scan_lines = vga_scan_lines;
+-      c->vc_font.height = vga_video_font_height;
++      c->vc_font.height = c->vc_cell_height = vga_video_font_height;
+       c->vc_complement_mask = 0x7700;
+       if (vga_512_chars)
+               c->vc_hi_font_mask = 0x0800;
+@@ -519,32 +519,32 @@ static void vgacon_cursor(struct vc_data
+               switch (CUR_SIZE(c->vc_cursor_type)) {
+               case CUR_UNDERLINE:
+                       vgacon_set_cursor_size(c->state.x,
+-                                             c->vc_font.height -
+-                                             (c->vc_font.height <
++                                             c->vc_cell_height -
++                                             (c->vc_cell_height <
+                                               10 ? 2 : 3),
+-                                             c->vc_font.height -
+-                                             (c->vc_font.height <
++                                             c->vc_cell_height -
++                                             (c->vc_cell_height <
+                                               10 ? 1 : 2));
+                       break;
+               case CUR_TWO_THIRDS:
+                       vgacon_set_cursor_size(c->state.x,
+-                                             c->vc_font.height / 3,
+-                                             c->vc_font.height -
+-                                             (c->vc_font.height <
++                                             c->vc_cell_height / 3,
++                                             c->vc_cell_height -
++                                             (c->vc_cell_height <
+                                               10 ? 1 : 2));
+                       break;
+               case CUR_LOWER_THIRD:
+                       vgacon_set_cursor_size(c->state.x,
+-                                             (c->vc_font.height * 2) / 3,
+-                                             c->vc_font.height -
+-                                             (c->vc_font.height <
++                                             (c->vc_cell_height * 2) / 3,
++                                             c->vc_cell_height -
++                                             (c->vc_cell_height <
+                                               10 ? 1 : 2));
+                       break;
+               case CUR_LOWER_HALF:
+                       vgacon_set_cursor_size(c->state.x,
+-                                             c->vc_font.height / 2,
+-                                             c->vc_font.height -
+-                                             (c->vc_font.height <
++                                             c->vc_cell_height / 2,
++                                             c->vc_cell_height -
++                                             (c->vc_cell_height <
+                                               10 ? 1 : 2));
+                       break;
+               case CUR_NONE:
+@@ -555,7 +555,7 @@ static void vgacon_cursor(struct vc_data
+                       break;
+               default:
+                       vgacon_set_cursor_size(c->state.x, 1,
+-                                             c->vc_font.height);
++                                             c->vc_cell_height);
+                       break;
+               }
+               break;
+@@ -566,13 +566,13 @@ static int vgacon_doresize(struct vc_dat
+               unsigned int width, unsigned int height)
+ {
+       unsigned long flags;
+-      unsigned int scanlines = height * c->vc_font.height;
++      unsigned int scanlines = height * c->vc_cell_height;
+       u8 scanlines_lo = 0, r7 = 0, vsync_end = 0, mode, max_scan;
+       raw_spin_lock_irqsave(&vga_lock, flags);
+       vgacon_xres = width * VGA_FONTWIDTH;
+-      vgacon_yres = height * c->vc_font.height;
++      vgacon_yres = height * c->vc_cell_height;
+       if (vga_video_type >= VIDEO_TYPE_VGAC) {
+               outb_p(VGA_CRTC_MAX_SCAN, vga_video_port_reg);
+               max_scan = inb_p(vga_video_port_val);
+@@ -627,9 +627,9 @@ static int vgacon_doresize(struct vc_dat
+ static int vgacon_switch(struct vc_data *c)
+ {
+       int x = c->vc_cols * VGA_FONTWIDTH;
+-      int y = c->vc_rows * c->vc_font.height;
++      int y = c->vc_rows * c->vc_cell_height;
+       int rows = screen_info.orig_video_lines * vga_default_font_height/
+-              c->vc_font.height;
++              c->vc_cell_height;
+       /*
+        * We need to save screen size here as it's the only way
+        * we can spot the screen has been resized and we need to
+@@ -1060,7 +1060,7 @@ static int vgacon_adjust_height(struct v
+                               cursor_size_lastto = 0;
+                               c->vc_sw->con_cursor(c, CM_DRAW);
+                       }
+-                      c->vc_font.height = fontheight;
++                      c->vc_font.height = c->vc_cell_height = fontheight;
+                       vc_resize(c, 0, rows);  /* Adjust console size */
+               }
+       }
+@@ -1115,12 +1115,12 @@ static int vgacon_resize(struct vc_data
+                */
+               screen_info.orig_video_cols = width;
+               screen_info.orig_video_lines = height;
+-              vga_default_font_height = c->vc_font.height;
++              vga_default_font_height = c->vc_cell_height;
+               return 0;
+       }
+       if (width % 2 || width > screen_info.orig_video_cols ||
+           height > (screen_info.orig_video_lines * vga_default_font_height)/
+-          c->vc_font.height)
++          c->vc_cell_height)
+               return -EINVAL;
+       if (con_is_visible(c) && !vga_is_gfx) /* who knows */
+--- a/include/linux/console_struct.h
++++ b/include/linux/console_struct.h
+@@ -101,6 +101,7 @@ struct vc_data {
+       unsigned int    vc_rows;
+       unsigned int    vc_size_row;            /* Bytes per row */
+       unsigned int    vc_scan_lines;          /* # of scan lines */
++      unsigned int    vc_cell_height;         /* CRTC character cell height */
+       unsigned long   vc_origin;              /* [!] Start of real screen */
+       unsigned long   vc_scr_end;             /* [!] End of real screen */
+       unsigned long   vc_visible_origin;      /* [!] Top of visible window */
diff --git a/queue-5.10/vt_ioctl-revert-vt_resizex-parameter-handling-removal.patch b/queue-5.10/vt_ioctl-revert-vt_resizex-parameter-handling-removal.patch
new file mode 100644 (file)
index 0000000..de47b1e
--- /dev/null
@@ -0,0 +1,103 @@
+From a90c275eb144c1b755f04769e1f29d832d6daeaf Mon Sep 17 00:00:00 2001
+From: "Maciej W. Rozycki" <macro@orcam.me.uk>
+Date: Thu, 13 May 2021 11:51:45 +0200
+Subject: vt_ioctl: Revert VT_RESIZEX parameter handling removal
+
+From: Maciej W. Rozycki <macro@orcam.me.uk>
+
+commit a90c275eb144c1b755f04769e1f29d832d6daeaf upstream.
+
+Revert the removal of code handling extra VT_RESIZEX ioctl's parameters
+beyond those that VT_RESIZE supports, fixing a functional regression
+causing `svgatextmode' not to resize the VT anymore.
+
+As a consequence of the reverted change when the video adapter is
+reprogrammed from the original say 80x25 text mode using a 9x16
+character cell (720x400 pixel resolution) to say 80x37 text mode and the
+same character cell (720x592 pixel resolution), the VT geometry does not
+get updated and only upper two thirds of the screen are used for the VT,
+and the lower part remains blank.  The proportions change according to
+text mode geometries chosen.
+
+Revert the change verbatim then, bringing back previous VT resizing.
+
+Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk>
+Fixes: 988d0763361b ("vt_ioctl: make VT_RESIZEX behave like VT_RESIZE")
+Cc: stable@vger.kernel.org # v5.10+
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/vt/vt_ioctl.c |   57 +++++++++++++++++++++++++++++++++++++---------
+ 1 file changed, 47 insertions(+), 10 deletions(-)
+
+--- a/drivers/tty/vt/vt_ioctl.c
++++ b/drivers/tty/vt/vt_ioctl.c
+@@ -771,21 +771,58 @@ static int vt_resizex(struct vc_data *vc
+       if (copy_from_user(&v, cs, sizeof(struct vt_consize)))
+               return -EFAULT;
+-      if (v.v_vlin)
+-              pr_info_once("\"struct vt_consize\"->v_vlin is ignored. Please report if you need this.\n");
+-      if (v.v_clin)
+-              pr_info_once("\"struct vt_consize\"->v_clin is ignored. Please report if you need this.\n");
++      /* FIXME: Should check the copies properly */
++      if (!v.v_vlin)
++              v.v_vlin = vc->vc_scan_lines;
++
++      if (v.v_clin) {
++              int rows = v.v_vlin / v.v_clin;
++              if (v.v_rows != rows) {
++                      if (v.v_rows) /* Parameters don't add up */
++                              return -EINVAL;
++                      v.v_rows = rows;
++              }
++      }
++
++      if (v.v_vcol && v.v_ccol) {
++              int cols = v.v_vcol / v.v_ccol;
++              if (v.v_cols != cols) {
++                      if (v.v_cols)
++                              return -EINVAL;
++                      v.v_cols = cols;
++              }
++      }
++
++      if (v.v_clin > 32)
++              return -EINVAL;
+-      console_lock();
+       for (i = 0; i < MAX_NR_CONSOLES; i++) {
+-              vc = vc_cons[i].d;
++              struct vc_data *vcp;
++
++              if (!vc_cons[i].d)
++                      continue;
++              console_lock();
++              vcp = vc_cons[i].d;
++              if (vcp) {
++                      int ret;
++                      int save_scan_lines = vcp->vc_scan_lines;
++                      int save_font_height = vcp->vc_font.height;
+-              if (vc) {
+-                      vc->vc_resize_user = 1;
+-                      vc_resize(vc, v.v_cols, v.v_rows);
++                      if (v.v_vlin)
++                              vcp->vc_scan_lines = v.v_vlin;
++                      if (v.v_clin)
++                              vcp->vc_font.height = v.v_clin;
++                      vcp->vc_resize_user = 1;
++                      ret = vc_resize(vcp, v.v_cols, v.v_rows);
++                      if (ret) {
++                              vcp->vc_scan_lines = save_scan_lines;
++                              vcp->vc_font.height = save_font_height;
++                              console_unlock();
++                              return ret;
++                      }
+               }
++              console_unlock();
+       }
+-      console_unlock();
+       return 0;
+ }