powerpc-sysdev-add-missing-iounmap-on-error-in-mpic_.patch
module-delay-kobject-uevent-until-after-module-init-.patch
kdev_t-always-inline-major-minor-helper-functions.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
--- /dev/null
+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
+@@ -646,7 +646,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
+@@ -1040,7 +1040,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
+@@ -689,7 +689,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, ...);
--- /dev/null
+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
+@@ -770,12 +770,14 @@ static int xen_register_credit_watch(str
+ 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
+@@ -901,7 +901,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);
--- /dev/null
+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
+@@ -699,6 +699,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);
+@@ -748,12 +750,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);
+
+@@ -800,7 +805,6 @@ void xs_suspend_cancel(void)
+
+ static int xenwatch_thread(void *unused)
+ {
+- struct list_head *ent;
+ struct xs_stored_msg *msg;
+
+ for (;;) {
+@@ -813,13 +817,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,
+@@ -909,6 +915,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.
--- /dev/null
+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;
--- /dev/null
+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",