--- /dev/null
+From 1566f5675a1fed592c963cdcc3786a1983eeb7d2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Jun 2020 16:00:58 -0400
+Subject: dm: do not use waitqueue for request-based DM
+
+From: Ming Lei <ming.lei@redhat.com>
+
+[ Upstream commit 85067747cf9888249fa11fa49ef75af5192d3988 ]
+
+Given request-based DM now uses blk-mq's blk_mq_queue_inflight() to
+determine if outstanding IO has completed (and DM has no control over
+the blk-mq state machine used to track outstanding IO) it is unsafe to
+wakeup waiter (dm_wait_for_completion) before blk-mq has cleared a
+request's state bits (e.g. MQ_RQ_IN_FLIGHT or MQ_RQ_COMPLETE). As
+such dm_wait_for_completion() could be left to wait indefinitely if no
+other requests complete.
+
+Fix this by eliminating request-based DM's use of waitqueue to wait
+for blk-mq requests to complete in dm_wait_for_completion.
+
+Signed-off-by: Ming Lei <ming.lei@redhat.com>
+Depends-on: 3c94d83cb3526 ("blk-mq: change blk_mq_queue_busy() to blk_mq_queue_inflight()")
+Cc: stable@vger.kernel.org
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm-rq.c | 4 ---
+ drivers/md/dm.c | 64 ++++++++++++++++++++++++++++------------------
+ 2 files changed, 39 insertions(+), 29 deletions(-)
+
+diff --git a/drivers/md/dm-rq.c b/drivers/md/dm-rq.c
+index 3f8577e2c13be..9fb46a6301d80 100644
+--- a/drivers/md/dm-rq.c
++++ b/drivers/md/dm-rq.c
+@@ -146,10 +146,6 @@ static void rq_end_stats(struct mapped_device *md, struct request *orig)
+ */
+ static void rq_completed(struct mapped_device *md)
+ {
+- /* nudge anyone waiting on suspend queue */
+- if (unlikely(wq_has_sleeper(&md->wait)))
+- wake_up(&md->wait);
+-
+ /*
+ * dm_put() must be at the end of this function. See the comment above
+ */
+diff --git a/drivers/md/dm.c b/drivers/md/dm.c
+index cefda95c9abb7..e70f22d7874fa 100644
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -654,28 +654,6 @@ static void free_tio(struct dm_target_io *tio)
+ bio_put(&tio->clone);
+ }
+
+-static bool md_in_flight_bios(struct mapped_device *md)
+-{
+- int cpu;
+- struct hd_struct *part = &dm_disk(md)->part0;
+- long sum = 0;
+-
+- for_each_possible_cpu(cpu) {
+- sum += part_stat_local_read_cpu(part, in_flight[0], cpu);
+- sum += part_stat_local_read_cpu(part, in_flight[1], cpu);
+- }
+-
+- return sum != 0;
+-}
+-
+-static bool md_in_flight(struct mapped_device *md)
+-{
+- if (queue_is_mq(md->queue))
+- return blk_mq_queue_inflight(md->queue);
+- else
+- return md_in_flight_bios(md);
+-}
+-
+ u64 dm_start_time_ns_from_clone(struct bio *bio)
+ {
+ struct dm_target_io *tio = container_of(bio, struct dm_target_io, clone);
+@@ -2447,15 +2425,29 @@ void dm_put(struct mapped_device *md)
+ }
+ EXPORT_SYMBOL_GPL(dm_put);
+
+-static int dm_wait_for_completion(struct mapped_device *md, long task_state)
++static bool md_in_flight_bios(struct mapped_device *md)
++{
++ int cpu;
++ struct hd_struct *part = &dm_disk(md)->part0;
++ long sum = 0;
++
++ for_each_possible_cpu(cpu) {
++ sum += part_stat_local_read_cpu(part, in_flight[0], cpu);
++ sum += part_stat_local_read_cpu(part, in_flight[1], cpu);
++ }
++
++ return sum != 0;
++}
++
++static int dm_wait_for_bios_completion(struct mapped_device *md, long task_state)
+ {
+ int r = 0;
+ DEFINE_WAIT(wait);
+
+- while (1) {
++ while (true) {
+ prepare_to_wait(&md->wait, &wait, task_state);
+
+- if (!md_in_flight(md))
++ if (!md_in_flight_bios(md))
+ break;
+
+ if (signal_pending_state(task_state, current)) {
+@@ -2470,6 +2462,28 @@ static int dm_wait_for_completion(struct mapped_device *md, long task_state)
+ return r;
+ }
+
++static int dm_wait_for_completion(struct mapped_device *md, long task_state)
++{
++ int r = 0;
++
++ if (!queue_is_mq(md->queue))
++ return dm_wait_for_bios_completion(md, task_state);
++
++ while (true) {
++ if (!blk_mq_queue_inflight(md->queue))
++ break;
++
++ if (signal_pending_state(task_state, current)) {
++ r = -EINTR;
++ break;
++ }
++
++ msleep(5);
++ }
++
++ return r;
++}
++
+ /*
+ * Process the deferred bios
+ */
+--
+2.25.1
+
--- /dev/null
+From a45cbc3d80352780654f270b02d15c169f6b473b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Apr 2020 16:48:29 -0400
+Subject: dm mpath: pass IO start time to path selector
+
+From: Gabriel Krisman Bertazi <krisman@collabora.com>
+
+[ Upstream commit 087615bf3acdafd0ba7c7c9ed5286e7b7c80fe1b ]
+
+The HST path selector needs this information to perform path
+prediction. For request-based mpath, struct request's io_start_time_ns
+is used, while for bio-based, use the start_time stored in dm_io.
+
+Signed-off-by: Gabriel Krisman Bertazi <krisman@collabora.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm-mpath.c | 9 ++++++---
+ drivers/md/dm-path-selector.h | 2 +-
+ drivers/md/dm-queue-length.c | 2 +-
+ drivers/md/dm-service-time.c | 2 +-
+ drivers/md/dm.c | 9 +++++++++
+ include/linux/device-mapper.h | 2 ++
+ 6 files changed, 20 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
+index e0c800cf87a9b..74246d7c7d68e 100644
+--- a/drivers/md/dm-mpath.c
++++ b/drivers/md/dm-mpath.c
+@@ -567,7 +567,8 @@ static void multipath_release_clone(struct request *clone,
+ if (pgpath && pgpath->pg->ps.type->end_io)
+ pgpath->pg->ps.type->end_io(&pgpath->pg->ps,
+ &pgpath->path,
+- mpio->nr_bytes);
++ mpio->nr_bytes,
++ clone->io_start_time_ns);
+ }
+
+ blk_put_request(clone);
+@@ -1617,7 +1618,8 @@ static int multipath_end_io(struct dm_target *ti, struct request *clone,
+ struct path_selector *ps = &pgpath->pg->ps;
+
+ if (ps->type->end_io)
+- ps->type->end_io(ps, &pgpath->path, mpio->nr_bytes);
++ ps->type->end_io(ps, &pgpath->path, mpio->nr_bytes,
++ clone->io_start_time_ns);
+ }
+
+ return r;
+@@ -1661,7 +1663,8 @@ static int multipath_end_io_bio(struct dm_target *ti, struct bio *clone,
+ struct path_selector *ps = &pgpath->pg->ps;
+
+ if (ps->type->end_io)
+- ps->type->end_io(ps, &pgpath->path, mpio->nr_bytes);
++ ps->type->end_io(ps, &pgpath->path, mpio->nr_bytes,
++ dm_start_time_ns_from_clone(clone));
+ }
+
+ return r;
+diff --git a/drivers/md/dm-path-selector.h b/drivers/md/dm-path-selector.h
+index b6eb5365b1a46..c47bc0e20275b 100644
+--- a/drivers/md/dm-path-selector.h
++++ b/drivers/md/dm-path-selector.h
+@@ -74,7 +74,7 @@ struct path_selector_type {
+ int (*start_io) (struct path_selector *ps, struct dm_path *path,
+ size_t nr_bytes);
+ int (*end_io) (struct path_selector *ps, struct dm_path *path,
+- size_t nr_bytes);
++ size_t nr_bytes, u64 start_time);
+ };
+
+ /* Register a path selector */
+diff --git a/drivers/md/dm-queue-length.c b/drivers/md/dm-queue-length.c
+index 969c4f1a36336..5fd018d184187 100644
+--- a/drivers/md/dm-queue-length.c
++++ b/drivers/md/dm-queue-length.c
+@@ -227,7 +227,7 @@ static int ql_start_io(struct path_selector *ps, struct dm_path *path,
+ }
+
+ static int ql_end_io(struct path_selector *ps, struct dm_path *path,
+- size_t nr_bytes)
++ size_t nr_bytes, u64 start_time)
+ {
+ struct path_info *pi = path->pscontext;
+
+diff --git a/drivers/md/dm-service-time.c b/drivers/md/dm-service-time.c
+index f006a9005593b..9cfda665e9ebd 100644
+--- a/drivers/md/dm-service-time.c
++++ b/drivers/md/dm-service-time.c
+@@ -309,7 +309,7 @@ static int st_start_io(struct path_selector *ps, struct dm_path *path,
+ }
+
+ static int st_end_io(struct path_selector *ps, struct dm_path *path,
+- size_t nr_bytes)
++ size_t nr_bytes, u64 start_time)
+ {
+ struct path_info *pi = path->pscontext;
+
+diff --git a/drivers/md/dm.c b/drivers/md/dm.c
+index 9793b04e9ff3b..cefda95c9abb7 100644
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -676,6 +676,15 @@ static bool md_in_flight(struct mapped_device *md)
+ return md_in_flight_bios(md);
+ }
+
++u64 dm_start_time_ns_from_clone(struct bio *bio)
++{
++ struct dm_target_io *tio = container_of(bio, struct dm_target_io, clone);
++ struct dm_io *io = tio->io;
++
++ return jiffies_to_nsecs(io->start_time);
++}
++EXPORT_SYMBOL_GPL(dm_start_time_ns_from_clone);
++
+ static void start_io_acct(struct dm_io *io)
+ {
+ struct mapped_device *md = io->md;
+diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
+index af48d9da39160..934037d938b9a 100644
+--- a/include/linux/device-mapper.h
++++ b/include/linux/device-mapper.h
+@@ -332,6 +332,8 @@ void *dm_per_bio_data(struct bio *bio, size_t data_size);
+ struct bio *dm_bio_from_per_bio_data(void *data, size_t data_size);
+ unsigned dm_bio_get_target_bio_nr(const struct bio *bio);
+
++u64 dm_start_time_ns_from_clone(struct bio *bio);
++
+ int dm_register_target(struct target_type *t);
+ void dm_unregister_target(struct target_type *t);
+
+--
+2.25.1
+
--- /dev/null
+From 8b8b2ed322b0ec4e69613d04205a411913c4841d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jul 2020 04:16:22 -0400
+Subject: drm/amd/display: add dmcub check on RENOIR
+
+From: Aaron Ma <aaron.ma@canonical.com>
+
+[ Upstream commit 3b2e973dff59d88bee1d814ddf8762a24fc02b60 ]
+
+RENOIR loads dmub fw not dmcu, check dmcu only will prevent loading iram,
+it breaks backlight control.
+
+Bug: https://bugzilla.kernel.org/show_bug.cgi?id=208277
+Acked-by: Alex Deucher <alexander.deucher@amd.com>
+Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Signed-off-by: Aaron Ma <aaron.ma@canonical.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index 7da2a22dbde7e..837a286469ecf 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -1345,7 +1345,7 @@ static int dm_late_init(void *handle)
+ struct dmcu *dmcu = NULL;
+ bool ret;
+
+- if (!adev->dm.fw_dmcu)
++ if (!adev->dm.fw_dmcu && !adev->dm.dmub_fw)
+ return detect_mst_link_for_all_connectors(adev->ddev);
+
+ dmcu = adev->dm.dc->res_pool->dmcu;
+--
+2.25.1
+
--- /dev/null
+From 3bb2457f0dcee045cd2166716b29e743d5e8d190 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Apr 2020 14:09:23 -0400
+Subject: drm/amd/display: Check DMCU Exists Before Loading
+
+From: Jerry (Fangzhi) Zuo <Jerry.Zuo@amd.com>
+
+[ Upstream commit 17bdb4a82fe5014c8aa5b2103c80c5729744a096 ]
+
+Signed-off-by: Jerry (Fangzhi) Zuo <Jerry.Zuo@amd.com>
+Reviewed-by: Hersen Wu <hersenxs.wu@amd.com>
+Acked-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index d06fa63801799..7da2a22dbde7e 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -1342,9 +1342,14 @@ static int dm_late_init(void *handle)
+ struct dmcu_iram_parameters params;
+ unsigned int linear_lut[16];
+ int i;
+- struct dmcu *dmcu = adev->dm.dc->res_pool->dmcu;
++ struct dmcu *dmcu = NULL;
+ bool ret;
+
++ if (!adev->dm.fw_dmcu)
++ return detect_mst_link_for_all_connectors(adev->ddev);
++
++ dmcu = adev->dm.dc->res_pool->dmcu;
++
+ for (i = 0; i < 16; i++)
+ linear_lut[i] = 0xFFFF * i / 15;
+
+--
+2.25.1
+
--- /dev/null
+From 03a3f6ffdfd9b99afef3cb5707c6b606777401b0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 Jun 2020 14:03:37 -0700
+Subject: drm/nouveau/nouveau: fix page fault on device private memory
+
+From: Ralph Campbell <rcampbell@nvidia.com>
+
+[ Upstream commit ed710a6ed797430026aa5116dd0ab22378798b69 ]
+
+If system memory is migrated to device private memory and no GPU MMU
+page table entry exists, the GPU will fault and call hmm_range_fault()
+to get the PFN for the page. Since the .dev_private_owner pointer in
+struct hmm_range is not set, hmm_range_fault returns an error which
+results in the GPU program stopping with a fatal fault.
+Fix this by setting .dev_private_owner appropriately.
+
+Fixes: 08ddddda667b ("mm/hmm: check the device private page owner in hmm_range_fault()")
+Cc: stable@vger.kernel.org
+Signed-off-by: Ralph Campbell <rcampbell@nvidia.com>
+Reviewed-by: Jason Gunthorpe <jgg@mellanox.com>
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/nouveau/nouveau_svm.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/nouveau/nouveau_svm.c b/drivers/gpu/drm/nouveau/nouveau_svm.c
+index 645fedd77e21b..a9ce86740799f 100644
+--- a/drivers/gpu/drm/nouveau/nouveau_svm.c
++++ b/drivers/gpu/drm/nouveau/nouveau_svm.c
+@@ -534,6 +534,7 @@ static int nouveau_range_fault(struct nouveau_svmm *svmm,
+ .flags = nouveau_svm_pfn_flags,
+ .values = nouveau_svm_pfn_values,
+ .pfn_shift = NVIF_VMM_PFNMAP_V0_ADDR_SHIFT,
++ .dev_private_owner = drm->dev,
+ };
+ struct mm_struct *mm = notifier->notifier.mm;
+ long ret;
+--
+2.25.1
+
--- /dev/null
+From 7321c3cc6b6e5f089b30c628cfb3e0126b481373 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Jul 2020 15:54:59 -0300
+Subject: fuse: fix weird page warning
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+commit a5005c3cda6eeb6b95645e6cc32f58dafeffc976 upstream.
+
+When PageWaiters was added, updating this check was missed.
+
+Reported-by: Nikolaus Rath <Nikolaus@rath.org>
+Reported-by: Hugh Dickins <hughd@google.com>
+Fixes: 62906027091f ("mm: add PageWaiters indicating tasks are waiting for a page bit")
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: André Almeida <andrealmeid@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/fuse/dev.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
+index 5c155437a455d..ec02c3240176c 100644
+--- a/fs/fuse/dev.c
++++ b/fs/fuse/dev.c
+@@ -771,7 +771,8 @@ static int fuse_check_page(struct page *page)
+ 1 << PG_uptodate |
+ 1 << PG_lru |
+ 1 << PG_active |
+- 1 << PG_reclaim))) {
++ 1 << PG_reclaim |
++ 1 << PG_waiters))) {
+ pr_warn("trying to steal weird page\n");
+ pr_warn(" page=%p index=%li flags=%08lx, count=%i, mapcount=%i, mapping=%p\n", page, page->index, page->flags, page_count(page), page_mapcount(page), page->mapping);
+ return 1;
+--
+2.25.1
+
--- /dev/null
+From a2286a3bf636f2f2ac81ab26df5b96358607cd19 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jul 2020 11:53:06 +0200
+Subject: irqdomain/treewide: Keep firmware node unconditionally allocated
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+[ Upstream commit e3beca48a45b5e0e6e6a4e0124276b8248dcc9bb ]
+
+Quite some non OF/ACPI users of irqdomains allocate firmware nodes of type
+IRQCHIP_FWNODE_NAMED or IRQCHIP_FWNODE_NAMED_ID and free them right after
+creating the irqdomain. The only purpose of these FW nodes is to convey
+name information. When this was introduced the core code did not store the
+pointer to the node in the irqdomain. A recent change stored the firmware
+node pointer in irqdomain for other reasons and missed to notice that the
+usage sites which do the alloc_fwnode/create_domain/free_fwnode sequence
+are broken by this. Storing a dangling pointer is dangerous itself, but in
+case that the domain is destroyed later on this leads to a double free.
+
+Remove the freeing of the firmware node after creating the irqdomain from
+all affected call sites to cure this.
+
+Fixes: 711419e504eb ("irqdomain: Add the missing assignment of domain->fwnode for named fwnode")
+Reported-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Acked-by: Bjorn Helgaas <bhelgaas@google.com>
+Acked-by: Marc Zyngier <maz@kernel.org>
+Cc: stable@vger.kernel.org
+Link: https://lkml.kernel.org/r/873661qakd.fsf@nanos.tec.linutronix.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/pci/pci-xtalk-bridge.c | 5 +++--
+ arch/x86/kernel/apic/io_apic.c | 10 +++++-----
+ arch/x86/kernel/apic/msi.c | 18 ++++++++++++------
+ arch/x86/kernel/apic/vector.c | 1 -
+ arch/x86/platform/uv/uv_irq.c | 3 ++-
+ drivers/iommu/amd_iommu.c | 5 +++--
+ drivers/iommu/hyperv-iommu.c | 5 ++++-
+ drivers/iommu/intel_irq_remapping.c | 2 +-
+ drivers/mfd/ioc3.c | 5 +++--
+ drivers/pci/controller/vmd.c | 5 +++--
+ 10 files changed, 36 insertions(+), 23 deletions(-)
+
+diff --git a/arch/mips/pci/pci-xtalk-bridge.c b/arch/mips/pci/pci-xtalk-bridge.c
+index 3b2552fb77351..5958217861b86 100644
+--- a/arch/mips/pci/pci-xtalk-bridge.c
++++ b/arch/mips/pci/pci-xtalk-bridge.c
+@@ -627,9 +627,10 @@ static int bridge_probe(struct platform_device *pdev)
+ return -ENOMEM;
+ domain = irq_domain_create_hierarchy(parent, 0, 8, fn,
+ &bridge_domain_ops, NULL);
+- irq_domain_free_fwnode(fn);
+- if (!domain)
++ if (!domain) {
++ irq_domain_free_fwnode(fn);
+ return -ENOMEM;
++ }
+
+ pci_set_flags(PCI_PROBE_ONLY);
+
+diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
+index 913c88617848b..57447f03ee87c 100644
+--- a/arch/x86/kernel/apic/io_apic.c
++++ b/arch/x86/kernel/apic/io_apic.c
+@@ -2329,12 +2329,12 @@ static int mp_irqdomain_create(int ioapic)
+ ip->irqdomain = irq_domain_create_linear(fn, hwirqs, cfg->ops,
+ (void *)(long)ioapic);
+
+- /* Release fw handle if it was allocated above */
+- if (!cfg->dev)
+- irq_domain_free_fwnode(fn);
+-
+- if (!ip->irqdomain)
++ if (!ip->irqdomain) {
++ /* Release fw handle if it was allocated above */
++ if (!cfg->dev)
++ irq_domain_free_fwnode(fn);
+ return -ENOMEM;
++ }
+
+ ip->irqdomain->parent = parent;
+
+diff --git a/arch/x86/kernel/apic/msi.c b/arch/x86/kernel/apic/msi.c
+index 159bd0cb85486..a20873bbbed67 100644
+--- a/arch/x86/kernel/apic/msi.c
++++ b/arch/x86/kernel/apic/msi.c
+@@ -262,12 +262,13 @@ void __init arch_init_msi_domain(struct irq_domain *parent)
+ msi_default_domain =
+ pci_msi_create_irq_domain(fn, &pci_msi_domain_info,
+ parent);
+- irq_domain_free_fwnode(fn);
+ }
+- if (!msi_default_domain)
++ if (!msi_default_domain) {
++ irq_domain_free_fwnode(fn);
+ pr_warn("failed to initialize irqdomain for MSI/MSI-x.\n");
+- else
++ } else {
+ msi_default_domain->flags |= IRQ_DOMAIN_MSI_NOMASK_QUIRK;
++ }
+ }
+
+ #ifdef CONFIG_IRQ_REMAP
+@@ -300,7 +301,8 @@ struct irq_domain *arch_create_remap_msi_irq_domain(struct irq_domain *parent,
+ if (!fn)
+ return NULL;
+ d = pci_msi_create_irq_domain(fn, &pci_msi_ir_domain_info, parent);
+- irq_domain_free_fwnode(fn);
++ if (!d)
++ irq_domain_free_fwnode(fn);
+ return d;
+ }
+ #endif
+@@ -363,7 +365,8 @@ static struct irq_domain *dmar_get_irq_domain(void)
+ if (fn) {
+ dmar_domain = msi_create_irq_domain(fn, &dmar_msi_domain_info,
+ x86_vector_domain);
+- irq_domain_free_fwnode(fn);
++ if (!dmar_domain)
++ irq_domain_free_fwnode(fn);
+ }
+ out:
+ mutex_unlock(&dmar_lock);
+@@ -488,7 +491,10 @@ struct irq_domain *hpet_create_irq_domain(int hpet_id)
+ }
+
+ d = msi_create_irq_domain(fn, domain_info, parent);
+- irq_domain_free_fwnode(fn);
++ if (!d) {
++ irq_domain_free_fwnode(fn);
++ kfree(domain_info);
++ }
+ return d;
+ }
+
+diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
+index cf8b6ebc60314..410363e60968f 100644
+--- a/arch/x86/kernel/apic/vector.c
++++ b/arch/x86/kernel/apic/vector.c
+@@ -707,7 +707,6 @@ int __init arch_early_irq_init(void)
+ x86_vector_domain = irq_domain_create_tree(fn, &x86_vector_domain_ops,
+ NULL);
+ BUG_ON(x86_vector_domain == NULL);
+- irq_domain_free_fwnode(fn);
+ irq_set_default_host(x86_vector_domain);
+
+ arch_init_msi_domain(x86_vector_domain);
+diff --git a/arch/x86/platform/uv/uv_irq.c b/arch/x86/platform/uv/uv_irq.c
+index fc13cbbb2dce2..abb6075397f05 100644
+--- a/arch/x86/platform/uv/uv_irq.c
++++ b/arch/x86/platform/uv/uv_irq.c
+@@ -167,9 +167,10 @@ static struct irq_domain *uv_get_irq_domain(void)
+ goto out;
+
+ uv_domain = irq_domain_create_tree(fn, &uv_domain_ops, NULL);
+- irq_domain_free_fwnode(fn);
+ if (uv_domain)
+ uv_domain->parent = x86_vector_domain;
++ else
++ irq_domain_free_fwnode(fn);
+ out:
+ mutex_unlock(&uv_lock);
+
+diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
+index 2883ac389abbe..9c2e2ed828267 100644
+--- a/drivers/iommu/amd_iommu.c
++++ b/drivers/iommu/amd_iommu.c
+@@ -4090,9 +4090,10 @@ int amd_iommu_create_irq_domain(struct amd_iommu *iommu)
+ if (!fn)
+ return -ENOMEM;
+ iommu->ir_domain = irq_domain_create_tree(fn, &amd_ir_domain_ops, iommu);
+- irq_domain_free_fwnode(fn);
+- if (!iommu->ir_domain)
++ if (!iommu->ir_domain) {
++ irq_domain_free_fwnode(fn);
+ return -ENOMEM;
++ }
+
+ iommu->ir_domain->parent = arch_get_ir_parent_domain();
+ iommu->msi_domain = arch_create_remap_msi_irq_domain(iommu->ir_domain,
+diff --git a/drivers/iommu/hyperv-iommu.c b/drivers/iommu/hyperv-iommu.c
+index a386b83e0e34b..f0fe5030acd36 100644
+--- a/drivers/iommu/hyperv-iommu.c
++++ b/drivers/iommu/hyperv-iommu.c
+@@ -155,7 +155,10 @@ static int __init hyperv_prepare_irq_remapping(void)
+ 0, IOAPIC_REMAPPING_ENTRY, fn,
+ &hyperv_ir_domain_ops, NULL);
+
+- irq_domain_free_fwnode(fn);
++ if (!ioapic_ir_domain) {
++ irq_domain_free_fwnode(fn);
++ return -ENOMEM;
++ }
+
+ /*
+ * Hyper-V doesn't provide irq remapping function for
+diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c
+index 81e43c1df7ecb..982d796b686b8 100644
+--- a/drivers/iommu/intel_irq_remapping.c
++++ b/drivers/iommu/intel_irq_remapping.c
+@@ -563,8 +563,8 @@ static int intel_setup_irq_remapping(struct intel_iommu *iommu)
+ 0, INTR_REMAP_TABLE_ENTRIES,
+ fn, &intel_ir_domain_ops,
+ iommu);
+- irq_domain_free_fwnode(fn);
+ if (!iommu->ir_domain) {
++ irq_domain_free_fwnode(fn);
+ pr_err("IR%d: failed to allocate irqdomain\n", iommu->seq_id);
+ goto out_free_bitmap;
+ }
+diff --git a/drivers/mfd/ioc3.c b/drivers/mfd/ioc3.c
+index 02998d4eb74b0..74cee7cb0afc9 100644
+--- a/drivers/mfd/ioc3.c
++++ b/drivers/mfd/ioc3.c
+@@ -142,10 +142,11 @@ static int ioc3_irq_domain_setup(struct ioc3_priv_data *ipd, int irq)
+ goto err;
+
+ domain = irq_domain_create_linear(fn, 24, &ioc3_irq_domain_ops, ipd);
+- if (!domain)
++ if (!domain) {
++ irq_domain_free_fwnode(fn);
+ goto err;
++ }
+
+- irq_domain_free_fwnode(fn);
+ ipd->domain = domain;
+
+ irq_set_chained_handler_and_data(irq, ioc3_irq_handler, domain);
+diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c
+index e386d4eac4070..9a64cf90c291b 100644
+--- a/drivers/pci/controller/vmd.c
++++ b/drivers/pci/controller/vmd.c
+@@ -546,9 +546,10 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)
+
+ vmd->irq_domain = pci_msi_create_irq_domain(fn, &vmd_msi_domain_info,
+ x86_vector_domain);
+- irq_domain_free_fwnode(fn);
+- if (!vmd->irq_domain)
++ if (!vmd->irq_domain) {
++ irq_domain_free_fwnode(fn);
+ return -ENODEV;
++ }
+
+ pci_add_resource(&resources, &vmd->resources[0]);
+ pci_add_resource_offset(&resources, &vmd->resources[1], offset[0]);
+--
+2.25.1
+
scsi-dh-add-fujitsu-device-to-devinfo-and-dh-lists.patch
dm-use-bio_uninit-instead-of-bio_disassociate_blkg.patch
drivers-firmware-psci-fix-memory-leakage-in-alloc_in.patch
+fuse-fix-weird-page-warning.patch
+irqdomain-treewide-keep-firmware-node-unconditionall.patch
+drm-nouveau-nouveau-fix-page-fault-on-device-private.patch
+drm-amd-display-check-dmcu-exists-before-loading.patch
+drm-amd-display-add-dmcub-check-on-renoir.patch
+dm-mpath-pass-io-start-time-to-path-selector.patch
+dm-do-not-use-waitqueue-for-request-based-dm.patch