]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 28 Dec 2020 11:34:41 +0000 (12:34 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 28 Dec 2020 11:34:41 +0000 (12:34 +0100)
added patches:
iio-adc-rockchip_saradc-fix-missing-clk_disable_unprepare-on-error-in-rockchip_saradc_resume.patch
iio-pressure-mpl3115-force-alignment-of-buffer.patch
jfs-fix-array-index-bounds-check-in-dbadjtree.patch
mtd-parser-cmdline-fix-parsing-of-part-names-with-colons.patch
spi-rb4xx-don-t-leak-spi-master-in-probe-error-path.patch
xen-xenbus-add-will_handle-callback-support-in-xenbus_watch_path.patch
xen-xenbus-allow-watches-discard-events-before-queueing.patch
xen-xenbus-count-pending-messages-for-each-watch.patch
xen-xenbus-xen_bus_type-support-will_handle-watch-callback.patch
xenbus-xenbus_backend-disallow-pending-watch-messages.patch

queue-4.4/iio-adc-rockchip_saradc-fix-missing-clk_disable_unprepare-on-error-in-rockchip_saradc_resume.patch [new file with mode: 0644]
queue-4.4/iio-pressure-mpl3115-force-alignment-of-buffer.patch [new file with mode: 0644]
queue-4.4/jfs-fix-array-index-bounds-check-in-dbadjtree.patch [new file with mode: 0644]
queue-4.4/mtd-parser-cmdline-fix-parsing-of-part-names-with-colons.patch [new file with mode: 0644]
queue-4.4/series
queue-4.4/spi-rb4xx-don-t-leak-spi-master-in-probe-error-path.patch [new file with mode: 0644]
queue-4.4/xen-xenbus-add-will_handle-callback-support-in-xenbus_watch_path.patch [new file with mode: 0644]
queue-4.4/xen-xenbus-allow-watches-discard-events-before-queueing.patch [new file with mode: 0644]
queue-4.4/xen-xenbus-count-pending-messages-for-each-watch.patch [new file with mode: 0644]
queue-4.4/xen-xenbus-xen_bus_type-support-will_handle-watch-callback.patch [new file with mode: 0644]
queue-4.4/xenbus-xenbus_backend-disallow-pending-watch-messages.patch [new file with mode: 0644]

diff --git a/queue-4.4/iio-adc-rockchip_saradc-fix-missing-clk_disable_unprepare-on-error-in-rockchip_saradc_resume.patch b/queue-4.4/iio-adc-rockchip_saradc-fix-missing-clk_disable_unprepare-on-error-in-rockchip_saradc_resume.patch
new file mode 100644 (file)
index 0000000..d742e47
--- /dev/null
@@ -0,0 +1,36 @@
+From 560c6b914c6ec7d9d9a69fddbb5bf3bf71433e8b Mon Sep 17 00:00:00 2001
+From: Qinglang Miao <miaoqinglang@huawei.com>
+Date: Tue, 3 Nov 2020 20:07:43 +0800
+Subject: iio: adc: rockchip_saradc: fix missing clk_disable_unprepare() on error in rockchip_saradc_resume
+
+From: Qinglang Miao <miaoqinglang@huawei.com>
+
+commit 560c6b914c6ec7d9d9a69fddbb5bf3bf71433e8b upstream.
+
+Fix the missing clk_disable_unprepare() of info->pclk
+before return from rockchip_saradc_resume in the error
+handling case when fails to prepare and enable info->clk.
+
+Suggested-by: Robin Murphy <robin.murphy@arm.com>
+Fixes: 44d6f2ef94f9 ("iio: adc: add driver for Rockchip saradc")
+Signed-off-by: Qinglang Miao <miaoqinglang@huawei.com>
+Cc: <Stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20201103120743.110662-1-miaoqinglang@huawei.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/adc/rockchip_saradc.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iio/adc/rockchip_saradc.c
++++ b/drivers/iio/adc/rockchip_saradc.c
+@@ -359,7 +359,7 @@ static int rockchip_saradc_resume(struct
+       ret = clk_prepare_enable(info->clk);
+       if (ret)
+-              return ret;
++              clk_disable_unprepare(info->pclk);
+       return ret;
+ }
diff --git a/queue-4.4/iio-pressure-mpl3115-force-alignment-of-buffer.patch b/queue-4.4/iio-pressure-mpl3115-force-alignment-of-buffer.patch
new file mode 100644 (file)
index 0000000..777c39a
--- /dev/null
@@ -0,0 +1,55 @@
+From 198cf32f0503d2ad60d320b95ef6fb8243db857f Mon Sep 17 00:00:00 2001
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Date: Sun, 20 Sep 2020 12:27:40 +0100
+Subject: iio:pressure:mpl3115: Force alignment of buffer
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+commit 198cf32f0503d2ad60d320b95ef6fb8243db857f upstream.
+
+Whilst this is another case of the issue Lars reported with
+an array of elements of smaller than 8 bytes being passed
+to iio_push_to_buffers_with_timestamp(), the solution here is
+a bit different from the other cases and relies on __aligned
+working on the stack (true since 4.6?)
+
+This one is unusual.  We have to do an explicit memset() each time
+as we are reading 3 bytes into a potential 4 byte channel which
+may sometimes be a 2 byte channel depending on what is enabled.
+As such, moving the buffer to the heap in the iio_priv structure
+doesn't save us much.  We can't use a nice explicit structure
+on the stack either as the data channels have different storage
+sizes and are all separately controlled.
+
+Fixes: cc26ad455f57 ("iio: Add Freescale MPL3115A2 pressure / temperature sensor driver")
+Reported-by: Lars-Peter Clausen <lars@metafoo.de>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Reviewed-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
+Cc: Peter Meerwald <pmeerw@pmeerw.net>
+Cc: <Stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200920112742.170751-7-jic23@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/pressure/mpl3115.c |    9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/drivers/iio/pressure/mpl3115.c
++++ b/drivers/iio/pressure/mpl3115.c
+@@ -139,7 +139,14 @@ static irqreturn_t mpl3115_trigger_handl
+       struct iio_poll_func *pf = p;
+       struct iio_dev *indio_dev = pf->indio_dev;
+       struct mpl3115_data *data = iio_priv(indio_dev);
+-      u8 buffer[16]; /* 32-bit channel + 16-bit channel + padding + ts */
++      /*
++       * 32-bit channel + 16-bit channel + padding + ts
++       * Note that it is possible for only one of the first 2
++       * channels to be enabled. If that happens, the first element
++       * of the buffer may be either 16 or 32-bits.  As such we cannot
++       * use a simple structure definition to express this data layout.
++       */
++      u8 buffer[16] __aligned(8);
+       int ret, pos = 0;
+       mutex_lock(&data->lock);
diff --git a/queue-4.4/jfs-fix-array-index-bounds-check-in-dbadjtree.patch b/queue-4.4/jfs-fix-array-index-bounds-check-in-dbadjtree.patch
new file mode 100644 (file)
index 0000000..497cfac
--- /dev/null
@@ -0,0 +1,33 @@
+From c61b3e4839007668360ed8b87d7da96d2e59fc6c Mon Sep 17 00:00:00 2001
+From: Dave Kleikamp <dave.kleikamp@oracle.com>
+Date: Fri, 13 Nov 2020 14:58:46 -0600
+Subject: jfs: Fix array index bounds check in dbAdjTree
+
+From: Dave Kleikamp <dave.kleikamp@oracle.com>
+
+commit c61b3e4839007668360ed8b87d7da96d2e59fc6c upstream.
+
+Bounds checking tools can flag a bug in dbAdjTree() for an array index
+out of bounds in dmt_stree. Since dmt_stree can refer to the stree in
+both structures dmaptree and dmapctl, use the larger array to eliminate
+the false positive.
+
+Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>
+Reported-by: butt3rflyh4ck <butterflyhuangxx@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/jfs/jfs_dmap.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/jfs/jfs_dmap.h
++++ b/fs/jfs/jfs_dmap.h
+@@ -196,7 +196,7 @@ typedef union dmtree {
+ #define       dmt_leafidx     t1.leafidx
+ #define       dmt_height      t1.height
+ #define       dmt_budmin      t1.budmin
+-#define       dmt_stree       t1.stree
++#define       dmt_stree       t2.stree
+ /*
+  *    on-disk aggregate disk allocation map descriptor.
diff --git a/queue-4.4/mtd-parser-cmdline-fix-parsing-of-part-names-with-colons.patch b/queue-4.4/mtd-parser-cmdline-fix-parsing-of-part-names-with-colons.patch
new file mode 100644 (file)
index 0000000..48ddd1d
--- /dev/null
@@ -0,0 +1,75 @@
+From 639a82434f16a6df0ce0e7c8595976f1293940fd Mon Sep 17 00:00:00 2001
+From: Sven Eckelmann <sven@narfation.org>
+Date: Tue, 24 Nov 2020 07:25:06 +0100
+Subject: mtd: parser: cmdline: Fix parsing of part-names with colons
+
+From: Sven Eckelmann <sven@narfation.org>
+
+commit 639a82434f16a6df0ce0e7c8595976f1293940fd upstream.
+
+Some devices (especially QCA ones) are already using hardcoded partition
+names with colons in it. The OpenMesh A62 for example provides following
+mtd relevant information via cmdline:
+
+  root=31:11 mtdparts=spi0.0:256k(0:SBL1),128k(0:MIBIB),384k(0:QSEE),64k(0:CDT),64k(0:DDRPARAMS),64k(0:APPSBLENV),512k(0:APPSBL),64k(0:ART),64k(custom),64k(0:KEYS),0x002b0000(kernel),0x00c80000(rootfs),15552k(inactive) rootfsname=rootfs rootwait
+
+The change to split only on the last colon between mtd-id and partitions
+will cause newpart to see following string for the first partition:
+
+  KEYS),0x002b0000(kernel),0x00c80000(rootfs),15552k(inactive)
+
+Such a partition list cannot be parsed and thus the device fails to boot.
+
+Avoid this behavior by making sure that the start of the first part-name
+("(") will also be the last byte the mtd-id split algorithm is using for
+its colon search.
+
+Fixes: eb13fa022741 ("mtd: parser: cmdline: Support MTD names containing one or more colons")
+Cc: stable@vger.kernel.org
+Cc: Ron Minnich <rminnich@google.com>
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20201124062506.185392-1-sven@narfation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mtd/cmdlinepart.c |   14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+--- a/drivers/mtd/cmdlinepart.c
++++ b/drivers/mtd/cmdlinepart.c
+@@ -228,7 +228,7 @@ static int mtdpart_setup_real(char *s)
+               struct cmdline_mtd_partition *this_mtd;
+               struct mtd_partition *parts;
+               int mtd_id_len, num_parts;
+-              char *p, *mtd_id, *semicol;
++              char *p, *mtd_id, *semicol, *open_parenth;
+               /*
+                * Replace the first ';' by a NULL char so strrchr can work
+@@ -238,6 +238,14 @@ static int mtdpart_setup_real(char *s)
+               if (semicol)
+                       *semicol = '\0';
++              /*
++               * make sure that part-names with ":" will not be handled as
++               * part of the mtd-id with an ":"
++               */
++              open_parenth = strchr(s, '(');
++              if (open_parenth)
++                      *open_parenth = '\0';
++
+               mtd_id = s;
+               /*
+@@ -247,6 +255,10 @@ static int mtdpart_setup_real(char *s)
+                */
+               p = strrchr(s, ':');
++              /* Restore the '(' now. */
++              if (open_parenth)
++                      *open_parenth = '(';
++
+               /* Restore the ';' now. */
+               if (semicol)
+                       *semicol = ';';
index d40280654f1079e793ab327ab97c803e5010740c..669fa476d5abec6aeebaf17fff72fb0ac7275010 100644 (file)
@@ -119,3 +119,13 @@ btrfs-fix-return-value-mixup-in-btrfs_get_extent.patch
 ext4-fix-a-memory-leak-of-ext4_free_data.patch
 ceph-fix-race-in-concurrent-__ceph_remove_cap-invocations.patch
 jffs2-fix-gc-exit-abnormally.patch
+jfs-fix-array-index-bounds-check-in-dbadjtree.patch
+spi-rb4xx-don-t-leak-spi-master-in-probe-error-path.patch
+mtd-parser-cmdline-fix-parsing-of-part-names-with-colons.patch
+iio-adc-rockchip_saradc-fix-missing-clk_disable_unprepare-on-error-in-rockchip_saradc_resume.patch
+iio-pressure-mpl3115-force-alignment-of-buffer.patch
+xen-xenbus-allow-watches-discard-events-before-queueing.patch
+xen-xenbus-add-will_handle-callback-support-in-xenbus_watch_path.patch
+xen-xenbus-xen_bus_type-support-will_handle-watch-callback.patch
+xen-xenbus-count-pending-messages-for-each-watch.patch
+xenbus-xenbus_backend-disallow-pending-watch-messages.patch
diff --git a/queue-4.4/spi-rb4xx-don-t-leak-spi-master-in-probe-error-path.patch b/queue-4.4/spi-rb4xx-don-t-leak-spi-master-in-probe-error-path.patch
new file mode 100644 (file)
index 0000000..d6d3610
--- /dev/null
@@ -0,0 +1,39 @@
+From a4729c3506c3eb1a6ca5c0289f4e7cafa4115065 Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Mon, 7 Dec 2020 09:17:10 +0100
+Subject: spi: rb4xx: Don't leak SPI master in probe error path
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit a4729c3506c3eb1a6ca5c0289f4e7cafa4115065 upstream.
+
+If the calls to devm_clk_get(), devm_spi_register_master() or
+clk_prepare_enable() fail on probe of the Mikrotik RB4xx SPI driver,
+the spi_master struct is erroneously not freed.
+
+Fix by switching over to the new devm_spi_alloc_master() helper.
+
+Fixes: 05aec357871f ("spi: Add SPI driver for Mikrotik RB4xx series boards")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Cc: <stable@vger.kernel.org> # v4.2+: 5e844cc37a5c: spi: Introduce device-managed SPI controller allocation
+Cc: <stable@vger.kernel.org> # v4.2+
+Cc: Bert Vermeulen <bert@biot.com>
+Link: https://lore.kernel.org/r/369bf26d71927f60943b1d9d8f51810f00b0237d.1607286887.git.lukas@wunner.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/spi/spi-rb4xx.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/spi/spi-rb4xx.c
++++ b/drivers/spi/spi-rb4xx.c
+@@ -148,7 +148,7 @@ static int rb4xx_spi_probe(struct platfo
+       if (IS_ERR(spi_base))
+               return PTR_ERR(spi_base);
+-      master = spi_alloc_master(&pdev->dev, sizeof(*rbspi));
++      master = devm_spi_alloc_master(&pdev->dev, sizeof(*rbspi));
+       if (!master)
+               return -ENOMEM;
diff --git a/queue-4.4/xen-xenbus-add-will_handle-callback-support-in-xenbus_watch_path.patch b/queue-4.4/xen-xenbus-add-will_handle-callback-support-in-xenbus_watch_path.patch
new file mode 100644 (file)
index 0000000..85977ed
--- /dev/null
@@ -0,0 +1,141 @@
+From 2e85d32b1c865bec703ce0c962221a5e955c52c2 Mon Sep 17 00:00:00 2001
+From: SeongJae Park <sjpark@amazon.de>
+Date: Mon, 14 Dec 2020 10:04:18 +0100
+Subject: xen/xenbus: Add 'will_handle' callback support in xenbus_watch_path()
+
+From: SeongJae Park <sjpark@amazon.de>
+
+commit 2e85d32b1c865bec703ce0c962221a5e955c52c2 upstream.
+
+Some code does not directly make 'xenbus_watch' object and call
+'register_xenbus_watch()' but use 'xenbus_watch_path()' instead.  This
+commit adds support of 'will_handle' callback in the
+'xenbus_watch_path()' and it's wrapper, 'xenbus_watch_pathfmt()'.
+
+This is part of XSA-349
+
+Cc: stable@vger.kernel.org
+Signed-off-by: SeongJae Park <sjpark@amazon.de>
+Reported-by: Michael Kurth <mku@amazon.de>
+Reported-by: Pawel Wieczorkiewicz <wipawel@amazon.de>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ drivers/block/xen-blkback/xenbus.c |    3 ++-
+ drivers/net/xen-netback/xenbus.c   |    2 +-
+ drivers/xen/xen-pciback/xenbus.c   |    2 +-
+ drivers/xen/xenbus/xenbus_client.c |    9 +++++++--
+ drivers/xen/xenbus/xenbus_probe.c  |    2 +-
+ include/xen/xenbus.h               |    6 +++++-
+ 6 files changed, 17 insertions(+), 7 deletions(-)
+
+--- a/drivers/block/xen-blkback/xenbus.c
++++ b/drivers/block/xen-blkback/xenbus.c
+@@ -553,7 +553,8 @@ static int xen_blkbk_probe(struct xenbus
+       /* setup back pointer */
+       be->blkif->be = be;
+-      err = xenbus_watch_pathfmt(dev, &be->backend_watch, backend_changed,
++      err = xenbus_watch_pathfmt(dev, &be->backend_watch, NULL,
++                                 backend_changed,
+                                  "%s/%s", dev->nodename, "physical-device");
+       if (err)
+               goto fail;
+--- a/drivers/net/xen-netback/xenbus.c
++++ b/drivers/net/xen-netback/xenbus.c
+@@ -849,7 +849,7 @@ static void connect(struct backend_info
+       xenvif_carrier_on(be->vif);
+       unregister_hotplug_status_watch(be);
+-      err = xenbus_watch_pathfmt(dev, &be->hotplug_status_watch,
++      err = xenbus_watch_pathfmt(dev, &be->hotplug_status_watch, NULL,
+                                  hotplug_status_changed,
+                                  "%s/%s", dev->nodename, "hotplug-status");
+       if (!err)
+--- a/drivers/xen/xen-pciback/xenbus.c
++++ b/drivers/xen/xen-pciback/xenbus.c
+@@ -691,7 +691,7 @@ static int xen_pcibk_xenbus_probe(struct
+       /* watch the backend node for backend configuration information */
+       err = xenbus_watch_path(dev, dev->nodename, &pdev->be_watch,
+-                              xen_pcibk_be_watch);
++                              NULL, xen_pcibk_be_watch);
+       if (err)
+               goto out;
+--- a/drivers/xen/xenbus/xenbus_client.c
++++ b/drivers/xen/xenbus/xenbus_client.c
+@@ -114,19 +114,22 @@ EXPORT_SYMBOL_GPL(xenbus_strstate);
+  */
+ int xenbus_watch_path(struct xenbus_device *dev, const char *path,
+                     struct xenbus_watch *watch,
++                    bool (*will_handle)(struct xenbus_watch *,
++                                        const char **, unsigned int),
+                     void (*callback)(struct xenbus_watch *,
+                                      const char **, unsigned int))
+ {
+       int err;
+       watch->node = path;
+-      watch->will_handle = NULL;
++      watch->will_handle = will_handle;
+       watch->callback = callback;
+       err = register_xenbus_watch(watch);
+       if (err) {
+               watch->node = NULL;
++              watch->will_handle = NULL;
+               watch->callback = NULL;
+               xenbus_dev_fatal(dev, err, "adding watch on %s", path);
+       }
+@@ -153,6 +156,8 @@ EXPORT_SYMBOL_GPL(xenbus_watch_path);
+  */
+ int xenbus_watch_pathfmt(struct xenbus_device *dev,
+                        struct xenbus_watch *watch,
++                       bool (*will_handle)(struct xenbus_watch *,
++                                           const char **, unsigned int),
+                        void (*callback)(struct xenbus_watch *,
+                                       const char **, unsigned int),
+                        const char *pathfmt, ...)
+@@ -169,7 +174,7 @@ int xenbus_watch_pathfmt(struct xenbus_d
+               xenbus_dev_fatal(dev, -ENOMEM, "allocating path for watch");
+               return -ENOMEM;
+       }
+-      err = xenbus_watch_path(dev, path, watch, callback);
++      err = xenbus_watch_path(dev, path, watch, will_handle, callback);
+       if (err)
+               kfree(path);
+--- a/drivers/xen/xenbus/xenbus_probe.c
++++ b/drivers/xen/xenbus/xenbus_probe.c
+@@ -137,7 +137,7 @@ static int watch_otherend(struct xenbus_
+               container_of(dev->dev.bus, struct xen_bus_type, bus);
+       return xenbus_watch_pathfmt(dev, &dev->otherend_watch,
+-                                  bus->otherend_changed,
++                                  NULL, bus->otherend_changed,
+                                   "%s/%s", dev->otherend, "state");
+ }
+--- a/include/xen/xenbus.h
++++ b/include/xen/xenbus.h
+@@ -201,10 +201,14 @@ void xenbus_suspend_cancel(void);
+ int xenbus_watch_path(struct xenbus_device *dev, const char *path,
+                     struct xenbus_watch *watch,
++                    bool (*will_handle)(struct xenbus_watch *,
++                                        const char **, unsigned int),
+                     void (*callback)(struct xenbus_watch *,
+                                      const char **, unsigned int));
+-__printf(4, 5)
++__printf(5, 6)
+ int xenbus_watch_pathfmt(struct xenbus_device *dev, struct xenbus_watch *watch,
++                       bool (*will_handle)(struct xenbus_watch *,
++                                           const char **, unsigned int),
+                        void (*callback)(struct xenbus_watch *,
+                                         const char **, unsigned int),
+                        const char *pathfmt, ...);
diff --git a/queue-4.4/xen-xenbus-allow-watches-discard-events-before-queueing.patch b/queue-4.4/xen-xenbus-allow-watches-discard-events-before-queueing.patch
new file mode 100644 (file)
index 0000000..cc71adf
--- /dev/null
@@ -0,0 +1,102 @@
+From fed1755b118147721f2c87b37b9d66e62c39b668 Mon Sep 17 00:00:00 2001
+From: SeongJae Park <sjpark@amazon.de>
+Date: Mon, 14 Dec 2020 10:02:45 +0100
+Subject: xen/xenbus: Allow watches discard events before queueing
+
+From: SeongJae Park <sjpark@amazon.de>
+
+commit fed1755b118147721f2c87b37b9d66e62c39b668 upstream.
+
+If handling logics of watch events are slower than the events enqueue
+logic and the events can be created from the guests, the guests could
+trigger memory pressure by intensively inducing the events, because it
+will create a huge number of pending events that exhausting the memory.
+
+Fortunately, some watch events could be ignored, depending on its
+handler callback.  For example, if the callback has interest in only one
+single path, the watch wouldn't want multiple pending events.  Or, some
+watches could ignore events to same path.
+
+To let such watches to volutarily help avoiding the memory pressure
+situation, this commit introduces new watch callback, 'will_handle'.  If
+it is not NULL, it will be called for each new event just before
+enqueuing it.  Then, if the callback returns false, the event will be
+discarded.  No watch is using the callback for now, though.
+
+This is part of XSA-349
+
+Cc: stable@vger.kernel.org
+Signed-off-by: SeongJae Park <sjpark@amazon.de>
+Reported-by: Michael Kurth <mku@amazon.de>
+Reported-by: Pawel Wieczorkiewicz <wipawel@amazon.de>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ drivers/net/xen-netback/xenbus.c   |    2 ++
+ drivers/xen/xenbus/xenbus_client.c |    1 +
+ drivers/xen/xenbus/xenbus_xs.c     |    7 ++++++-
+ include/xen/xenbus.h               |    7 +++++++
+ 4 files changed, 16 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/xen-netback/xenbus.c
++++ b/drivers/net/xen-netback/xenbus.c
+@@ -697,12 +697,14 @@ static int xen_register_watchers(struct
+               return -ENOMEM;
+       snprintf(node, maxlen, "%s/rate", dev->nodename);
+       vif->credit_watch.node = node;
++      vif->credit_watch.will_handle = NULL;
+       vif->credit_watch.callback = xen_net_rate_changed;
+       err = register_xenbus_watch(&vif->credit_watch);
+       if (err) {
+               pr_err("Failed to set watcher %s\n", vif->credit_watch.node);
+               kfree(node);
+               vif->credit_watch.node = NULL;
++              vif->credit_watch.will_handle = NULL;
+               vif->credit_watch.callback = NULL;
+       }
+       return err;
+--- a/drivers/xen/xenbus/xenbus_client.c
++++ b/drivers/xen/xenbus/xenbus_client.c
+@@ -120,6 +120,7 @@ int xenbus_watch_path(struct xenbus_devi
+       int err;
+       watch->node = path;
++      watch->will_handle = NULL;
+       watch->callback = callback;
+       err = register_xenbus_watch(watch);
+--- a/drivers/xen/xenbus/xenbus_xs.c
++++ b/drivers/xen/xenbus/xenbus_xs.c
+@@ -903,7 +903,12 @@ static int process_msg(void)
+               spin_lock(&watches_lock);
+               msg->u.watch.handle = find_watch(
+                       msg->u.watch.vec[XS_WATCH_TOKEN]);
+-              if (msg->u.watch.handle != NULL) {
++              if (msg->u.watch.handle != NULL &&
++                              (!msg->u.watch.handle->will_handle ||
++                               msg->u.watch.handle->will_handle(
++                                       msg->u.watch.handle,
++                                       (const char **)msg->u.watch.vec,
++                                       msg->u.watch.vec_size))) {
+                       spin_lock(&watch_events_lock);
+                       list_add_tail(&msg->list, &watch_events);
+                       wake_up(&watch_events_waitq);
+--- a/include/xen/xenbus.h
++++ b/include/xen/xenbus.h
+@@ -58,6 +58,13 @@ struct xenbus_watch
+       /* Path being watched. */
+       const char *node;
++      /*
++       * Called just before enqueing new event while a spinlock is held.
++       * The event will be discarded if this callback returns false.
++       */
++      bool (*will_handle)(struct xenbus_watch *,
++                          const char **vec, unsigned int len);
++
+       /* Callback (executed in a process context with no locks held). */
+       void (*callback)(struct xenbus_watch *,
+                        const char **vec, unsigned int len);
diff --git a/queue-4.4/xen-xenbus-count-pending-messages-for-each-watch.patch b/queue-4.4/xen-xenbus-count-pending-messages-for-each-watch.patch
new file mode 100644 (file)
index 0000000..98611e2
--- /dev/null
@@ -0,0 +1,111 @@
+From 3dc86ca6b4c8cfcba9da7996189d1b5a358a94fc Mon Sep 17 00:00:00 2001
+From: SeongJae Park <sjpark@amazon.de>
+Date: Mon, 14 Dec 2020 10:07:13 +0100
+Subject: xen/xenbus: Count pending messages for each watch
+
+From: SeongJae Park <sjpark@amazon.de>
+
+commit 3dc86ca6b4c8cfcba9da7996189d1b5a358a94fc upstream.
+
+This commit adds a counter of pending messages for each watch in the
+struct.  It is used to skip unnecessary pending messages lookup in
+'unregister_xenbus_watch()'.  It could also be used in 'will_handle'
+callback.
+
+This is part of XSA-349
+
+Cc: stable@vger.kernel.org
+Signed-off-by: SeongJae Park <sjpark@amazon.de>
+Reported-by: Michael Kurth <mku@amazon.de>
+Reported-by: Pawel Wieczorkiewicz <wipawel@amazon.de>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ drivers/xen/xenbus/xenbus_xs.c |   31 +++++++++++++++++++------------
+ include/xen/xenbus.h           |    2 ++
+ 2 files changed, 21 insertions(+), 12 deletions(-)
+
+--- a/drivers/xen/xenbus/xenbus_xs.c
++++ b/drivers/xen/xenbus/xenbus_xs.c
+@@ -701,6 +701,8 @@ int register_xenbus_watch(struct xenbus_
+       sprintf(token, "%lX", (long)watch);
++      watch->nr_pending = 0;
++
+       down_read(&xs_state.watch_mutex);
+       spin_lock(&watches_lock);
+@@ -750,12 +752,15 @@ void unregister_xenbus_watch(struct xenb
+       /* Cancel pending watch events. */
+       spin_lock(&watch_events_lock);
+-      list_for_each_entry_safe(msg, tmp, &watch_events, list) {
+-              if (msg->u.watch.handle != watch)
+-                      continue;
+-              list_del(&msg->list);
+-              kfree(msg->u.watch.vec);
+-              kfree(msg);
++      if (watch->nr_pending) {
++              list_for_each_entry_safe(msg, tmp, &watch_events, list) {
++                      if (msg->u.watch.handle != watch)
++                              continue;
++                      list_del(&msg->list);
++                      kfree(msg->u.watch.vec);
++                      kfree(msg);
++              }
++              watch->nr_pending = 0;
+       }
+       spin_unlock(&watch_events_lock);
+@@ -802,7 +807,6 @@ void xs_suspend_cancel(void)
+ static int xenwatch_thread(void *unused)
+ {
+-      struct list_head *ent;
+       struct xs_stored_msg *msg;
+       for (;;) {
+@@ -815,13 +819,15 @@ static int xenwatch_thread(void *unused)
+               mutex_lock(&xenwatch_mutex);
+               spin_lock(&watch_events_lock);
+-              ent = watch_events.next;
+-              if (ent != &watch_events)
+-                      list_del(ent);
++              msg = list_first_entry_or_null(&watch_events,
++                              struct xs_stored_msg, list);
++              if (msg) {
++                      list_del(&msg->list);
++                      msg->u.watch.handle->nr_pending--;
++              }
+               spin_unlock(&watch_events_lock);
+-              if (ent != &watch_events) {
+-                      msg = list_entry(ent, struct xs_stored_msg, list);
++              if (msg) {
+                       msg->u.watch.handle->callback(
+                               msg->u.watch.handle,
+                               (const char **)msg->u.watch.vec,
+@@ -911,6 +917,7 @@ static int process_msg(void)
+                                        msg->u.watch.vec_size))) {
+                       spin_lock(&watch_events_lock);
+                       list_add_tail(&msg->list, &watch_events);
++                      msg->u.watch.handle->nr_pending++;
+                       wake_up(&watch_events_waitq);
+                       spin_unlock(&watch_events_lock);
+               } else {
+--- a/include/xen/xenbus.h
++++ b/include/xen/xenbus.h
+@@ -58,6 +58,8 @@ struct xenbus_watch
+       /* Path being watched. */
+       const char *node;
++      unsigned int nr_pending;
++
+       /*
+        * Called just before enqueing new event while a spinlock is held.
+        * The event will be discarded if this callback returns false.
diff --git a/queue-4.4/xen-xenbus-xen_bus_type-support-will_handle-watch-callback.patch b/queue-4.4/xen-xenbus-xen_bus_type-support-will_handle-watch-callback.patch
new file mode 100644 (file)
index 0000000..abb5f24
--- /dev/null
@@ -0,0 +1,51 @@
+From be987200fbaceaef340872841d4f7af2c5ee8dc3 Mon Sep 17 00:00:00 2001
+From: SeongJae Park <sjpark@amazon.de>
+Date: Mon, 14 Dec 2020 10:05:47 +0100
+Subject: xen/xenbus/xen_bus_type: Support will_handle watch callback
+
+From: SeongJae Park <sjpark@amazon.de>
+
+commit be987200fbaceaef340872841d4f7af2c5ee8dc3 upstream.
+
+This commit adds support of the 'will_handle' watch callback for
+'xen_bus_type' users.
+
+This is part of XSA-349
+
+Cc: stable@vger.kernel.org
+Signed-off-by: SeongJae Park <sjpark@amazon.de>
+Reported-by: Michael Kurth <mku@amazon.de>
+Reported-by: Pawel Wieczorkiewicz <wipawel@amazon.de>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ drivers/xen/xenbus/xenbus_probe.c |    3 ++-
+ drivers/xen/xenbus/xenbus_probe.h |    2 ++
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/xen/xenbus/xenbus_probe.c
++++ b/drivers/xen/xenbus/xenbus_probe.c
+@@ -137,7 +137,8 @@ static int watch_otherend(struct xenbus_
+               container_of(dev->dev.bus, struct xen_bus_type, bus);
+       return xenbus_watch_pathfmt(dev, &dev->otherend_watch,
+-                                  NULL, bus->otherend_changed,
++                                  bus->otherend_will_handle,
++                                  bus->otherend_changed,
+                                   "%s/%s", dev->otherend, "state");
+ }
+--- a/drivers/xen/xenbus/xenbus_probe.h
++++ b/drivers/xen/xenbus/xenbus_probe.h
+@@ -42,6 +42,8 @@ struct xen_bus_type {
+       int (*get_bus_id)(char bus_id[XEN_BUS_ID_SIZE], const char *nodename);
+       int (*probe)(struct xen_bus_type *bus, const char *type,
+                    const char *dir);
++      bool (*otherend_will_handle)(struct xenbus_watch *watch,
++                                   const char **vec, unsigned int len);
+       void (*otherend_changed)(struct xenbus_watch *watch, const char **vec,
+                                unsigned int len);
+       struct bus_type bus;
diff --git a/queue-4.4/xenbus-xenbus_backend-disallow-pending-watch-messages.patch b/queue-4.4/xenbus-xenbus_backend-disallow-pending-watch-messages.patch
new file mode 100644 (file)
index 0000000..b8991a3
--- /dev/null
@@ -0,0 +1,57 @@
+From 9996bd494794a2fe393e97e7a982388c6249aa76 Mon Sep 17 00:00:00 2001
+From: SeongJae Park <sjpark@amazon.de>
+Date: Mon, 14 Dec 2020 10:08:40 +0100
+Subject: xenbus/xenbus_backend: Disallow pending watch messages
+
+From: SeongJae Park <sjpark@amazon.de>
+
+commit 9996bd494794a2fe393e97e7a982388c6249aa76 upstream.
+
+'xenbus_backend' watches 'state' of devices, which is writable by
+guests.  Hence, if guests intensively updates it, dom0 will have lots of
+pending events that exhausting memory of dom0.  In other words, guests
+can trigger dom0 memory pressure.  This is known as XSA-349.  However,
+the watch callback of it, 'frontend_changed()', reads only 'state', so
+doesn't need to have the pending events.
+
+To avoid the problem, this commit disallows pending watch messages for
+'xenbus_backend' using the 'will_handle()' watch callback.
+
+This is part of XSA-349
+
+Cc: stable@vger.kernel.org
+Signed-off-by: SeongJae Park <sjpark@amazon.de>
+Reported-by: Michael Kurth <mku@amazon.de>
+Reported-by: Pawel Wieczorkiewicz <wipawel@amazon.de>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ drivers/xen/xenbus/xenbus_probe_backend.c |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/xen/xenbus/xenbus_probe_backend.c
++++ b/drivers/xen/xenbus/xenbus_probe_backend.c
+@@ -181,6 +181,12 @@ static int xenbus_probe_backend(struct x
+       return err;
+ }
++static bool frontend_will_handle(struct xenbus_watch *watch,
++                               const char **vec, unsigned int len)
++{
++      return watch->nr_pending == 0;
++}
++
+ static void frontend_changed(struct xenbus_watch *watch,
+                           const char **vec, unsigned int len)
+ {
+@@ -192,6 +198,7 @@ static struct xen_bus_type xenbus_backen
+       .levels = 3,            /* backend/type/<frontend>/<id> */
+       .get_bus_id = backend_bus_id,
+       .probe = xenbus_probe_backend,
++      .otherend_will_handle = frontend_will_handle,
+       .otherend_changed = frontend_changed,
+       .bus = {
+               .name           = "xen-backend",