]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.4
authorSasha Levin <sashal@kernel.org>
Sat, 25 Apr 2020 23:30:19 +0000 (19:30 -0400)
committerSasha Levin <sashal@kernel.org>
Sat, 25 Apr 2020 23:30:19 +0000 (19:30 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
49 files changed:
queue-5.4/alsa-usb-audio-add-pioneer-dj-djm-250mk2-quirk.patch [new file with mode: 0644]
queue-5.4/asoc-intel-atom-take-the-drv-lock-mutex-before-calli.patch [new file with mode: 0644]
queue-5.4/asoc-intel-bytcr_rt5640-add-quirk-for-mpman-mpwin895.patch [new file with mode: 0644]
queue-5.4/asoc-sof-trace-fix-unconditional-free-in-trace-relea.patch [new file with mode: 0644]
queue-5.4/ceph-don-t-skip-updating-wanted-caps-when-cap-is-sta.patch [new file with mode: 0644]
queue-5.4/ceph-return-ceph_mdsc_do_request-errors-from-__get_p.patch [new file with mode: 0644]
queue-5.4/dma-direct-fix-data-truncation-in-dma_direct_get_req.patch [new file with mode: 0644]
queue-5.4/drm-amd-display-calculate-scaling-ratios-on-every-me.patch [new file with mode: 0644]
queue-5.4/drm-amd-display-not-doing-optimize-bandwidth-if-flip.patch [new file with mode: 0644]
queue-5.4/drm-amd-display-update-stream-adjust-in-dc_stream_ad.patch [new file with mode: 0644]
queue-5.4/ipc-util.c-sysvipc_find_ipc-should-increase-position.patch [new file with mode: 0644]
queue-5.4/kconfig-qconf-fix-a-few-alignment-issues.patch [new file with mode: 0644]
queue-5.4/kernel-gcov-fs.c-gcov_seq_next-should-increase-posit.patch [new file with mode: 0644]
queue-5.4/lib-raid6-test-fix-build-on-distros-whose-bin-sh-is-.patch [new file with mode: 0644]
queue-5.4/libbpf-fix-readelf-output-parsing-on-powerpc-with-re.patch [new file with mode: 0644]
queue-5.4/loop-better-discard-support-for-block-devices.patch [new file with mode: 0644]
queue-5.4/nvme-fix-compat-address-handling-in-several-ioctls.patch [new file with mode: 0644]
queue-5.4/nvme-fix-deadlock-caused-by-ana-update-wrong-locking.patch [new file with mode: 0644]
queue-5.4/nvme-tcp-fix-possible-crash-in-write_zeroes-processi.patch [new file with mode: 0644]
queue-5.4/pci-aspm-allow-re-enabling-clock-pm.patch [new file with mode: 0644]
queue-5.4/pci-pciehp-prevent-deadlock-on-disconnect.patch [new file with mode: 0644]
queue-5.4/pci-pm-add-missing-link-delays-required-by-the-pcie-.patch [new file with mode: 0644]
queue-5.4/pci-pm-add-pcie_wait_for_link_delay.patch [new file with mode: 0644]
queue-5.4/perf-core-disable-page-faults-when-getting-phys-addr.patch [new file with mode: 0644]
queue-5.4/powerpc-pseries-fix-mce-handling-on-pseries.patch [new file with mode: 0644]
queue-5.4/pwm-bcm2835-dynamically-allocate-base.patch [new file with mode: 0644]
queue-5.4/pwm-rcar-fix-late-runtime-pm-enablement.patch [new file with mode: 0644]
queue-5.4/pwm-renesas-tpu-fix-late-runtime-pm-enablement.patch [new file with mode: 0644]
queue-5.4/revert-powerpc-64-irq_work-avoid-interrupt-when-call.patch [new file with mode: 0644]
queue-5.4/s390-cio-avoid-duplicated-add-uevents.patch [new file with mode: 0644]
queue-5.4/s390-cio-generate-delayed-uevent-for-vfio-ccw-subcha.patch [new file with mode: 0644]
queue-5.4/scsi-iscsi-report-unbind-session-event-when-the-targ.patch [new file with mode: 0644]
queue-5.4/scsi-libfc-if-prli-rejected-move-rport-to-plogi-stat.patch [new file with mode: 0644]
queue-5.4/scsi-lpfc-fix-crash-after-handling-a-pci-error.patch [new file with mode: 0644]
queue-5.4/scsi-lpfc-fix-crash-in-target-side-cable-pulls-hitti.patch [new file with mode: 0644]
queue-5.4/scsi-lpfc-fix-kasan-slab-out-of-bounds-error-in-lpfc.patch [new file with mode: 0644]
queue-5.4/scsi-smartpqi-fix-call-trace-in-device-discovery.patch [new file with mode: 0644]
queue-5.4/scsi-smartpqi-fix-controller-lockup-observed-during-.patch [new file with mode: 0644]
queue-5.4/scsi-smartpqi-fix-problem-with-unique-id-for-physica.patch [new file with mode: 0644]
queue-5.4/selftests-kmod-fix-handling-test-numbers-above-9.patch [new file with mode: 0644]
queue-5.4/series
queue-5.4/tools-test-nvdimm-fix-out-of-tree-build.patch [new file with mode: 0644]
queue-5.4/tools-testing-nvdimm-fix-compilation-failure-without.patch [new file with mode: 0644]
queue-5.4/tracing-selftests-turn-off-timeout-setting.patch [new file with mode: 0644]
queue-5.4/virtio-blk-improve-virtqueue-error-to-blk_sts.patch [new file with mode: 0644]
queue-5.4/watchdog-reset-last_hw_keepalive-time-at-start.patch [new file with mode: 0644]
queue-5.4/xhci-ensure-link-state-is-u3-after-setting-usb_ss_po.patch [new file with mode: 0644]
queue-5.4/xhci-finetune-host-initiated-usb3-rootport-link-susp.patch [new file with mode: 0644]
queue-5.4/xhci-wait-until-link-state-trainsits-to-u0-after-set.patch [new file with mode: 0644]

diff --git a/queue-5.4/alsa-usb-audio-add-pioneer-dj-djm-250mk2-quirk.patch b/queue-5.4/alsa-usb-audio-add-pioneer-dj-djm-250mk2-quirk.patch
new file mode 100644 (file)
index 0000000..3bd90d2
--- /dev/null
@@ -0,0 +1,80 @@
+From ca7ffe642db7ca2aaeef40b64de39375a1216c7f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Apr 2020 11:59:07 +0200
+Subject: ALSA: usb-audio: Add Pioneer DJ DJM-250MK2 quirk
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: František Kučera <franta-linux@frantovo.cz>
+
+[ Upstream commit 73d8c94084341e2895169a0462dbc18167f01683 ]
+
+Pioneer DJ DJM-250MK2 is a mixer that acts like a USB sound card.
+The MIDI controller part is standard but the PCM part is "vendor specific".
+Output is enabled by this quirk: 8 channels, 48 000 Hz, S24_3LE.
+Input is not working.
+
+Signed-off-by: František Kučera <franta-linux@frantovo.cz>
+Link: https://lore.kernel.org/r/20200401095907.3387-1-konference@frantovo.cz
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/usb/quirks-table.h | 42 ++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 42 insertions(+)
+
+diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
+index d187aa6d50db0..dcaf9eed9a415 100644
+--- a/sound/usb/quirks-table.h
++++ b/sound/usb/quirks-table.h
+@@ -3592,5 +3592,47 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"),
+               }
+       }
+ },
++{
++      /*
++       * Pioneer DJ DJM-250MK2
++       * PCM is 8 channels out @ 48 fixed (endpoints 0x01).
++       * The output from computer to the mixer is usable.
++       *
++       * The input (phono or line to computer) is not working.
++       * It should be at endpoint 0x82 and probably also 8 channels,
++       * but it seems that it works only with Pioneer proprietary software.
++       * Even on officially supported OS, the Audacity was unable to record
++       * and Mixxx to recognize the control vinyls.
++       */
++      USB_DEVICE_VENDOR_SPEC(0x2b73, 0x0017),
++      .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
++              .ifnum = QUIRK_ANY_INTERFACE,
++              .type = QUIRK_COMPOSITE,
++              .data = (const struct snd_usb_audio_quirk[]) {
++                      {
++                              .ifnum = 0,
++                              .type = QUIRK_AUDIO_FIXED_ENDPOINT,
++                              .data = &(const struct audioformat) {
++                                      .formats = SNDRV_PCM_FMTBIT_S24_3LE,
++                                      .channels = 8, // outputs
++                                      .iface = 0,
++                                      .altsetting = 1,
++                                      .altset_idx = 1,
++                                      .endpoint = 0x01,
++                                      .ep_attr = USB_ENDPOINT_XFER_ISOC|
++                                              USB_ENDPOINT_SYNC_ASYNC,
++                                      .rates = SNDRV_PCM_RATE_48000,
++                                      .rate_min = 48000,
++                                      .rate_max = 48000,
++                                      .nr_rates = 1,
++                                      .rate_table = (unsigned int[]) { 48000 }
++                              }
++                      },
++                      {
++                              .ifnum = -1
++                      }
++              }
++      }
++},
+ #undef USB_DEVICE_VENDOR_SPEC
+-- 
+2.20.1
+
diff --git a/queue-5.4/asoc-intel-atom-take-the-drv-lock-mutex-before-calli.patch b/queue-5.4/asoc-intel-atom-take-the-drv-lock-mutex-before-calli.patch
new file mode 100644 (file)
index 0000000..5855794
--- /dev/null
@@ -0,0 +1,43 @@
+From 86e7421795030f87d324e3029a463eaf938104c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Apr 2020 20:53:57 +0200
+Subject: ASoC: Intel: atom: Take the drv->lock mutex before calling
+ sst_send_slot_map()
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 81630dc042af998b9f58cd8e2c29dab9777ea176 ]
+
+sst_send_slot_map() uses sst_fill_and_send_cmd_unlocked() because in some
+places it is called with the drv->lock mutex already held.
+
+So it must always be called with the mutex locked. This commit adds missing
+locking in the sst_set_be_modules() code-path.
+
+Fixes: 24c8d14192cc ("ASoC: Intel: mrfld: add DSP core controls")
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20200402185359.3424-1-hdegoede@redhat.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/atom/sst-atom-controls.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/sound/soc/intel/atom/sst-atom-controls.c b/sound/soc/intel/atom/sst-atom-controls.c
+index f883c9340eeee..df8f7994d3b7a 100644
+--- a/sound/soc/intel/atom/sst-atom-controls.c
++++ b/sound/soc/intel/atom/sst-atom-controls.c
+@@ -966,7 +966,9 @@ static int sst_set_be_modules(struct snd_soc_dapm_widget *w,
+       dev_dbg(c->dev, "Enter: widget=%s\n", w->name);
+       if (SND_SOC_DAPM_EVENT_ON(event)) {
++              mutex_lock(&drv->lock);
+               ret = sst_send_slot_map(drv);
++              mutex_unlock(&drv->lock);
+               if (ret)
+                       return ret;
+               ret = sst_send_pipe_module_params(w, k);
+-- 
+2.20.1
+
diff --git a/queue-5.4/asoc-intel-bytcr_rt5640-add-quirk-for-mpman-mpwin895.patch b/queue-5.4/asoc-intel-bytcr_rt5640-add-quirk-for-mpman-mpwin895.patch
new file mode 100644 (file)
index 0000000..e7115b7
--- /dev/null
@@ -0,0 +1,49 @@
+From 8602c6b7f2177910da69acd6b2e19d6862a71a0c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Apr 2020 15:37:26 +0200
+Subject: ASoC: Intel: bytcr_rt5640: Add quirk for MPMAN MPWIN895CL tablet
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit c8b78f24c1247b7bd0882885c672d9dec5800bc6 ]
+
+The MPMAN MPWIN895CL tablet almost fully works with out default settings.
+The only problem is that it has only 1 speaker so any sounds only playing
+on the right channel get lost.
+
+Add a quirk for this model using the default settings + MONO_SPEAKER.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20200405133726.24154-1-hdegoede@redhat.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/boards/bytcr_rt5640.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
+index 243f683bc02a7..e62e1d7815aa9 100644
+--- a/sound/soc/intel/boards/bytcr_rt5640.c
++++ b/sound/soc/intel/boards/bytcr_rt5640.c
+@@ -591,6 +591,17 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
+                                       BYT_RT5640_SSP0_AIF1 |
+                                       BYT_RT5640_MCLK_EN),
+       },
++      {
++              /* MPMAN MPWIN895CL */
++              .matches = {
++                      DMI_EXACT_MATCH(DMI_SYS_VENDOR, "MPMAN"),
++                      DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MPWIN8900CL"),
++              },
++              .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
++                                      BYT_RT5640_MONO_SPEAKER |
++                                      BYT_RT5640_SSP0_AIF1 |
++                                      BYT_RT5640_MCLK_EN),
++      },
+       {       /* MSI S100 tablet */
+               .matches = {
+                       DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Micro-Star International Co., Ltd."),
+-- 
+2.20.1
+
diff --git a/queue-5.4/asoc-sof-trace-fix-unconditional-free-in-trace-relea.patch b/queue-5.4/asoc-sof-trace-fix-unconditional-free-in-trace-relea.patch
new file mode 100644 (file)
index 0000000..d10a7a3
--- /dev/null
@@ -0,0 +1,43 @@
+From f468cc6740f1bcf75bcff63857d5eda137e2c39c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jan 2020 15:36:22 -0600
+Subject: ASoC: SOF: trace: fix unconditional free in trace release
+
+From: Kai Vehmanen <kai.vehmanen@linux.intel.com>
+
+[ Upstream commit e6110114d18d330c05fd6de9f31283fd086a5a3a ]
+
+Check if DMA pages were successfully allocated in initialization
+before calling free. For many types of memory (like sgbufs)
+the extra free is harmless, but not all backends track allocation
+state, so add an explicit check.
+
+Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20200124213625.30186-5-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/sof/trace.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/sof/trace.c b/sound/soc/sof/trace.c
+index 4c3cff031fd66..fd6f5913782bf 100644
+--- a/sound/soc/sof/trace.c
++++ b/sound/soc/sof/trace.c
+@@ -328,7 +328,10 @@ void snd_sof_free_trace(struct snd_sof_dev *sdev)
+ {
+       snd_sof_release_trace(sdev);
+-      snd_dma_free_pages(&sdev->dmatb);
+-      snd_dma_free_pages(&sdev->dmatp);
++      if (sdev->dma_trace_pages) {
++              snd_dma_free_pages(&sdev->dmatb);
++              snd_dma_free_pages(&sdev->dmatp);
++              sdev->dma_trace_pages = 0;
++      }
+ }
+ EXPORT_SYMBOL(snd_sof_free_trace);
+-- 
+2.20.1
+
diff --git a/queue-5.4/ceph-don-t-skip-updating-wanted-caps-when-cap-is-sta.patch b/queue-5.4/ceph-don-t-skip-updating-wanted-caps-when-cap-is-sta.patch
new file mode 100644 (file)
index 0000000..a2a0c75
--- /dev/null
@@ -0,0 +1,49 @@
+From 39938c6f8793666b6c8619e61f2f70e1b338806c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Mar 2020 19:34:20 +0800
+Subject: ceph: don't skip updating wanted caps when cap is stale
+
+From: Yan, Zheng <zyan@redhat.com>
+
+[ Upstream commit 0aa971b6fd3f92afef6afe24ef78d9bb14471519 ]
+
+1. try_get_cap_refs() fails to get caps and finds that mds_wanted
+   does not include what it wants. It returns -ESTALE.
+2. ceph_get_caps() calls ceph_renew_caps(). ceph_renew_caps() finds
+   that inode has cap, so it calls ceph_check_caps().
+3. ceph_check_caps() finds that issued caps (without checking if it's
+   stale) already includes caps wanted by open file, so it skips
+   updating wanted caps.
+
+Above events can cause an infinite loop inside ceph_get_caps().
+
+Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ceph/caps.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
+index f5a38910a82bf..703945cce0e5d 100644
+--- a/fs/ceph/caps.c
++++ b/fs/ceph/caps.c
+@@ -1976,8 +1976,12 @@ retry_locked:
+               }
+               /* want more caps from mds? */
+-              if (want & ~(cap->mds_wanted | cap->issued))
+-                      goto ack;
++              if (want & ~cap->mds_wanted) {
++                      if (want & ~(cap->mds_wanted | cap->issued))
++                              goto ack;
++                      if (!__cap_is_valid(cap))
++                              goto ack;
++              }
+               /* things we might delay */
+               if ((cap->issued & ~retain) == 0)
+-- 
+2.20.1
+
diff --git a/queue-5.4/ceph-return-ceph_mdsc_do_request-errors-from-__get_p.patch b/queue-5.4/ceph-return-ceph_mdsc_do_request-errors-from-__get_p.patch
new file mode 100644 (file)
index 0000000..4343762
--- /dev/null
@@ -0,0 +1,40 @@
+From 6111786969995cf1c1c8ae30d67e16282f3bbb8f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Mar 2020 09:34:20 +0800
+Subject: ceph: return ceph_mdsc_do_request() errors from __get_parent()
+
+From: Qiujun Huang <hqjagain@gmail.com>
+
+[ Upstream commit c6d50296032f0b97473eb2e274dc7cc5d0173847 ]
+
+Return the error returned by ceph_mdsc_do_request(). Otherwise,
+r_target_inode ends up being NULL this ends up returning ENOENT
+regardless of the error.
+
+Signed-off-by: Qiujun Huang <hqjagain@gmail.com>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ceph/export.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/fs/ceph/export.c b/fs/ceph/export.c
+index b6bfa94332c30..79dc06881e78e 100644
+--- a/fs/ceph/export.c
++++ b/fs/ceph/export.c
+@@ -315,6 +315,11 @@ static struct dentry *__get_parent(struct super_block *sb,
+       req->r_num_caps = 1;
+       err = ceph_mdsc_do_request(mdsc, NULL, req);
++      if (err) {
++              ceph_mdsc_put_request(req);
++              return ERR_PTR(err);
++      }
++
+       inode = req->r_target_inode;
+       if (inode)
+               ihold(inode);
+-- 
+2.20.1
+
diff --git a/queue-5.4/dma-direct-fix-data-truncation-in-dma_direct_get_req.patch b/queue-5.4/dma-direct-fix-data-truncation-in-dma_direct_get_req.patch
new file mode 100644 (file)
index 0000000..96bf49a
--- /dev/null
@@ -0,0 +1,41 @@
+From 5b36b997163cc9457692fd60de0cca48e5b85f6e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Apr 2020 10:58:36 +0530
+Subject: dma-direct: fix data truncation in dma_direct_get_required_mask()
+
+From: Kishon Vijay Abraham I <kishon@ti.com>
+
+[ Upstream commit cdcda0d1f8f4ab84efe7cd9921c98364398aefd7 ]
+
+The upper 32-bit physical address gets truncated inadvertently
+when dma_direct_get_required_mask() invokes phys_to_dma_direct().
+This results in dma_addressing_limited() return incorrect value
+when used in platforms with LPAE enabled.
+Fix it here by explicitly type casting 'max_pfn' to phys_addr_t
+in order to prevent overflow of intermediate value while evaluating
+'(max_pfn - 1) << PAGE_SHIFT'.
+
+Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/dma/direct.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
+index 867fd72cb2605..0a093a675b632 100644
+--- a/kernel/dma/direct.c
++++ b/kernel/dma/direct.c
+@@ -45,7 +45,8 @@ static inline dma_addr_t phys_to_dma_direct(struct device *dev,
+ u64 dma_direct_get_required_mask(struct device *dev)
+ {
+-      u64 max_dma = phys_to_dma_direct(dev, (max_pfn - 1) << PAGE_SHIFT);
++      phys_addr_t phys = (phys_addr_t)(max_pfn - 1) << PAGE_SHIFT;
++      u64 max_dma = phys_to_dma_direct(dev, phys);
+       return (1ULL << (fls64(max_dma) - 1)) * 2 - 1;
+ }
+-- 
+2.20.1
+
diff --git a/queue-5.4/drm-amd-display-calculate-scaling-ratios-on-every-me.patch b/queue-5.4/drm-amd-display-calculate-scaling-ratios-on-every-me.patch
new file mode 100644 (file)
index 0000000..f6128b4
--- /dev/null
@@ -0,0 +1,69 @@
+From 22afe4ffeae7e3494ba426b9d6415e8a088efba6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Apr 2020 16:40:57 -0400
+Subject: drm/amd/display: Calculate scaling ratios on every medium/full update
+
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+
+[ Upstream commit 3bae20137cae6c03f58f96c0bc9f3d46f0bc17d4 ]
+
+[Why]
+If a plane isn't being actively enabled or disabled then DC won't
+always recalculate scaling rects and ratios for the primary plane.
+
+This results in only a partial or corrupted rect being displayed on
+the screen instead of scaling to fit the screen.
+
+[How]
+Add back the logic to recalculate the scaling rects into
+dc_commit_updates_for_stream since this is the expected place to
+do it in DC.
+
+This was previously removed a few years ago to fix an underscan issue
+but underscan is still functional now with this change - and it should
+be, since this is only updating to the latest plane state getting passed
+in.
+
+Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Reviewed-by: Aric Cyr <Aric.Cyr@amd.com>
+Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/core/dc.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
+index 89bd0ba3db1df..71c574d1e8be2 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
+@@ -2154,7 +2154,7 @@ void dc_commit_updates_for_stream(struct dc *dc,
+       enum surface_update_type update_type;
+       struct dc_state *context;
+       struct dc_context *dc_ctx = dc->ctx;
+-      int i;
++      int i, j;
+       stream_status = dc_stream_get_status(stream);
+       context = dc->current_state;
+@@ -2192,6 +2192,17 @@ void dc_commit_updates_for_stream(struct dc *dc,
+               copy_surface_update_to_plane(surface, &srf_updates[i]);
++              if (update_type >= UPDATE_TYPE_MED) {
++                      for (j = 0; j < dc->res_pool->pipe_count; j++) {
++                              struct pipe_ctx *pipe_ctx =
++                                      &context->res_ctx.pipe_ctx[j];
++
++                              if (pipe_ctx->plane_state != surface)
++                                      continue;
++
++                              resource_build_scaling_params(pipe_ctx);
++                      }
++              }
+       }
+       copy_stream_update_to_stream(dc, context, stream, stream_update);
+-- 
+2.20.1
+
diff --git a/queue-5.4/drm-amd-display-not-doing-optimize-bandwidth-if-flip.patch b/queue-5.4/drm-amd-display-not-doing-optimize-bandwidth-if-flip.patch
new file mode 100644 (file)
index 0000000..ed7d484
--- /dev/null
@@ -0,0 +1,73 @@
+From 3aa67c551413349265c8054bd927e9c8688bb5ac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Mar 2020 17:13:02 -0400
+Subject: drm/amd/display: Not doing optimize bandwidth if flip pending.
+
+From: Yongqiang Sun <yongqiang.sun@amd.com>
+
+[ Upstream commit 9941b8129030c9202aaf39114477a0e58c0d6ffc ]
+
+[Why]
+In some scenario like 1366x768 VSR enabled connected with a 4K monitor
+and playing 4K video in clone mode, underflow will be observed due to
+decrease dppclk when previouse surface scan isn't finished
+
+[How]
+In this use case, surface flip is switching between 4K and 1366x768,
+1366x768 needs smaller dppclk, and when decrease the clk and previous
+surface scan is for 4K and scan isn't done, underflow will happen.  Not
+doing optimize bandwidth in case of flip pending.
+
+Signed-off-by: Yongqiang Sun <yongqiang.sun@amd.com>
+Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
+Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/core/dc.c | 23 +++++++++++++++++++++++
+ 1 file changed, 23 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
+index 71c574d1e8be2..2028dc017f7a0 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
+@@ -1182,6 +1182,26 @@ bool dc_commit_state(struct dc *dc, struct dc_state *context)
+       return (result == DC_OK);
+ }
++static bool is_flip_pending_in_pipes(struct dc *dc, struct dc_state *context)
++{
++      int i;
++      struct pipe_ctx *pipe;
++
++      for (i = 0; i < MAX_PIPES; i++) {
++              pipe = &context->res_ctx.pipe_ctx[i];
++
++              if (!pipe->plane_state)
++                      continue;
++
++              /* Must set to false to start with, due to OR in update function */
++              pipe->plane_state->status.is_flip_pending = false;
++              dc->hwss.update_pending_status(pipe);
++              if (pipe->plane_state->status.is_flip_pending)
++                      return true;
++      }
++      return false;
++}
++
+ bool dc_post_update_surfaces_to_stream(struct dc *dc)
+ {
+       int i;
+@@ -1192,6 +1212,9 @@ bool dc_post_update_surfaces_to_stream(struct dc *dc)
+       post_surface_trace(dc);
++      if (is_flip_pending_in_pipes(dc, context))
++              return true;
++
+       for (i = 0; i < dc->res_pool->pipe_count; i++)
+               if (context->res_ctx.pipe_ctx[i].stream == NULL ||
+                   context->res_ctx.pipe_ctx[i].plane_state == NULL) {
+-- 
+2.20.1
+
diff --git a/queue-5.4/drm-amd-display-update-stream-adjust-in-dc_stream_ad.patch b/queue-5.4/drm-amd-display-update-stream-adjust-in-dc_stream_ad.patch
new file mode 100644 (file)
index 0000000..7c95d1b
--- /dev/null
@@ -0,0 +1,43 @@
+From 103701480ed34bff87c2ad640e39ed465b8f1e2c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Apr 2020 16:41:01 -0400
+Subject: drm/amd/display: Update stream adjust in dc_stream_adjust_vmin_vmax
+
+From: Isabel Zhang <isabel.zhang@amd.com>
+
+[ Upstream commit 346d8a0a3c91888a412c2735d69daa09c00f0203 ]
+
+[Why]
+After v_total_min and max are updated in vrr structure, the changes are
+not reflected in stream adjust. When these values are read from stream
+adjust it does not reflect the actual state of the system.
+
+[How]
+Set stream adjust values equal to vrr adjust values after vrr adjust
+values are updated.
+
+Signed-off-by: Isabel Zhang <isabel.zhang@amd.com>
+Reviewed-by: Alvin Lee <Alvin.Lee2@amd.com>
+Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/core/dc.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
+index 4704aac336c29..89bd0ba3db1df 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
+@@ -283,6 +283,8 @@ bool dc_stream_adjust_vmin_vmax(struct dc *dc,
+       int i = 0;
+       bool ret = false;
++      stream->adjust = *adjust;
++
+       for (i = 0; i < MAX_PIPES; i++) {
+               struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+-- 
+2.20.1
+
diff --git a/queue-5.4/ipc-util.c-sysvipc_find_ipc-should-increase-position.patch b/queue-5.4/ipc-util.c-sysvipc_find_ipc-should-increase-position.patch
new file mode 100644 (file)
index 0000000..74e1f7a
--- /dev/null
@@ -0,0 +1,52 @@
+From f5d106221d9907e66a728a0780472b554b0060c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Apr 2020 14:34:13 -0700
+Subject: ipc/util.c: sysvipc_find_ipc() should increase position index
+
+From: Vasily Averin <vvs@virtuozzo.com>
+
+[ Upstream commit 89163f93c6f969da5811af5377cc10173583123b ]
+
+If seq_file .next function does not change position index, read after
+some lseek can generate unexpected output.
+
+https://bugzilla.kernel.org/show_bug.cgi?id=206283
+Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Acked-by: Waiman Long <longman@redhat.com>
+Cc: Davidlohr Bueso <dave@stgolabs.net>
+Cc: Manfred Spraul <manfred@colorfullife.com>
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: NeilBrown <neilb@suse.com>
+Cc: Peter Oberparleiter <oberpar@linux.ibm.com>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Link: http://lkml.kernel.org/r/b7a20945-e315-8bb0-21e6-3875c14a8494@virtuozzo.com
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ ipc/util.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ipc/util.c b/ipc/util.c
+index d126d156efc64..594871610d454 100644
+--- a/ipc/util.c
++++ b/ipc/util.c
+@@ -764,13 +764,13 @@ static struct kern_ipc_perm *sysvipc_find_ipc(struct ipc_ids *ids, loff_t pos,
+                       total++;
+       }
++      *new_pos = pos + 1;
+       if (total >= ids->in_use)
+               return NULL;
+       for (; pos < ipc_mni; pos++) {
+               ipc = idr_find(&ids->ipcs_idr, pos);
+               if (ipc != NULL) {
+-                      *new_pos = pos + 1;
+                       rcu_read_lock();
+                       ipc_lock_object(ipc);
+                       return ipc;
+-- 
+2.20.1
+
diff --git a/queue-5.4/kconfig-qconf-fix-a-few-alignment-issues.patch b/queue-5.4/kconfig-qconf-fix-a-few-alignment-issues.patch
new file mode 100644 (file)
index 0000000..087b3b7
--- /dev/null
@@ -0,0 +1,59 @@
+From a4c558fc705c2703766a752905bf04c65f134442 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Apr 2020 11:28:03 +0200
+Subject: kconfig: qconf: Fix a few alignment issues
+
+From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+[ Upstream commit 60969f02f07ae1445730c7b293c421d179da729c ]
+
+There are a few items with wrong alignments. Solve them.
+
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/kconfig/qconf.cc | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc
+index 82773cc35d356..0f8c77f847114 100644
+--- a/scripts/kconfig/qconf.cc
++++ b/scripts/kconfig/qconf.cc
+@@ -627,7 +627,7 @@ void ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu)
+                       last = item;
+                       continue;
+               }
+-      hide:
++hide:
+               if (item && item->menu == child) {
+                       last = parent->firstChild();
+                       if (last == item)
+@@ -692,7 +692,7 @@ void ConfigList::updateMenuList(ConfigList *parent, struct menu* menu)
+                       last = item;
+                       continue;
+               }
+-      hide:
++hide:
+               if (item && item->menu == child) {
+                       last = (ConfigItem*)parent->topLevelItem(0);
+                       if (last == item)
+@@ -1225,10 +1225,11 @@ QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos)
+ {
+       QMenu* popup = Parent::createStandardContextMenu(pos);
+       QAction* action = new QAction("Show Debug Info", popup);
+-        action->setCheckable(true);
+-        connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
+-        connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
+-        action->setChecked(showDebug());
++
++      action->setCheckable(true);
++      connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
++      connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
++      action->setChecked(showDebug());
+       popup->addSeparator();
+       popup->addAction(action);
+       return popup;
+-- 
+2.20.1
+
diff --git a/queue-5.4/kernel-gcov-fs.c-gcov_seq_next-should-increase-posit.patch b/queue-5.4/kernel-gcov-fs.c-gcov_seq_next-should-increase-posit.patch
new file mode 100644 (file)
index 0000000..ff6feb4
--- /dev/null
@@ -0,0 +1,48 @@
+From a50078f82674c4c3461268ef119ad0e6b7d81f3c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Apr 2020 14:34:10 -0700
+Subject: kernel/gcov/fs.c: gcov_seq_next() should increase position index
+
+From: Vasily Averin <vvs@virtuozzo.com>
+
+[ Upstream commit f4d74ef6220c1eda0875da30457bef5c7111ab06 ]
+
+If seq_file .next function does not change position index, read after
+some lseek can generate unexpected output.
+
+https://bugzilla.kernel.org/show_bug.cgi?id=206283
+Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Acked-by: Peter Oberparleiter <oberpar@linux.ibm.com>
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Cc: Davidlohr Bueso <dave@stgolabs.net>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Manfred Spraul <manfred@colorfullife.com>
+Cc: NeilBrown <neilb@suse.com>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Cc: Waiman Long <longman@redhat.com>
+Link: http://lkml.kernel.org/r/f65c6ee7-bd00-f910-2f8a-37cc67e4ff88@virtuozzo.com
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/gcov/fs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/gcov/fs.c b/kernel/gcov/fs.c
+index e5eb5ea7ea598..cc4ee482d3fba 100644
+--- a/kernel/gcov/fs.c
++++ b/kernel/gcov/fs.c
+@@ -108,9 +108,9 @@ static void *gcov_seq_next(struct seq_file *seq, void *data, loff_t *pos)
+ {
+       struct gcov_iterator *iter = data;
++      (*pos)++;
+       if (gcov_iter_next(iter))
+               return NULL;
+-      (*pos)++;
+       return iter;
+ }
+-- 
+2.20.1
+
diff --git a/queue-5.4/lib-raid6-test-fix-build-on-distros-whose-bin-sh-is-.patch b/queue-5.4/lib-raid6-test-fix-build-on-distros-whose-bin-sh-is-.patch
new file mode 100644 (file)
index 0000000..2628c96
--- /dev/null
@@ -0,0 +1,69 @@
+From ef619d689969b09966e7529fb735043cab7e26e9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 Mar 2020 17:00:49 +0900
+Subject: lib/raid6/test: fix build on distros whose /bin/sh is not bash
+
+From: Masahiro Yamada <masahiroy@kernel.org>
+
+[ Upstream commit 06bd48b6cd97ef3889b68c8e09014d81dbc463f1 ]
+
+You can build a user-space test program for the raid6 library code,
+like this:
+
+  $ cd lib/raid6/test
+  $ make
+
+The command in $(shell ...) function is evaluated by /bin/sh by default.
+(or, you can specify the shell by passing SHELL=<shell> from command line)
+
+Currently '>&/dev/null' is used to sink both stdout and stderr. Because
+this code is bash-ism, it only works when /bin/sh is a symbolic link to
+bash (this is the case on RHEL etc.)
+
+This does not work on Ubuntu where /bin/sh is a symbolic link to dash.
+
+I see lots of
+
+  /bin/sh: 1: Syntax error: Bad fd number
+
+and
+
+  warning "your version of binutils lacks ... support"
+
+Replace it with portable '>/dev/null 2>&1'.
+
+Fixes: 4f8c55c5ad49 ("lib/raid6: build proper files on corresponding arch")
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Acked-by: H. Peter Anvin (Intel) <hpa@zytor.com>
+Reviewed-by: Jason A. Donenfeld <Jason@zx2c4.com>
+Acked-by: Ingo Molnar <mingo@kernel.org>
+Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/raid6/test/Makefile | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/lib/raid6/test/Makefile b/lib/raid6/test/Makefile
+index 3ab8720aa2f84..b9e6c3648be1a 100644
+--- a/lib/raid6/test/Makefile
++++ b/lib/raid6/test/Makefile
+@@ -35,13 +35,13 @@ endif
+ ifeq ($(IS_X86),yes)
+         OBJS   += mmx.o sse1.o sse2.o avx2.o recov_ssse3.o recov_avx2.o avx512.o recov_avx512.o
+         CFLAGS += $(shell echo "pshufb %xmm0, %xmm0" |                \
+-                    gcc -c -x assembler - >&/dev/null &&      \
++                    gcc -c -x assembler - >/dev/null 2>&1 &&  \
+                     rm ./-.o && echo -DCONFIG_AS_SSSE3=1)
+         CFLAGS += $(shell echo "vpbroadcastb %xmm0, %ymm1" |  \
+-                    gcc -c -x assembler - >&/dev/null &&      \
++                    gcc -c -x assembler - >/dev/null 2>&1 &&  \
+                     rm ./-.o && echo -DCONFIG_AS_AVX2=1)
+       CFLAGS += $(shell echo "vpmovm2b %k1, %zmm5" |          \
+-                  gcc -c -x assembler - >&/dev/null &&        \
++                  gcc -c -x assembler - >/dev/null 2>&1 &&    \
+                   rm ./-.o && echo -DCONFIG_AS_AVX512=1)
+ else ifeq ($(HAS_NEON),yes)
+         OBJS   += neon.o neon1.o neon2.o neon4.o neon8.o recov_neon.o recov_neon_inner.o
+-- 
+2.20.1
+
diff --git a/queue-5.4/libbpf-fix-readelf-output-parsing-on-powerpc-with-re.patch b/queue-5.4/libbpf-fix-readelf-output-parsing-on-powerpc-with-re.patch
new file mode 100644 (file)
index 0000000..786f3e0
--- /dev/null
@@ -0,0 +1,54 @@
+From f70c936fb05d5b1fa674420a4d4b87b8e753d8dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 1 Dec 2019 20:57:28 +0100
+Subject: libbpf: Fix readelf output parsing on powerpc with recent binutils
+
+From: Aurelien Jarno <aurelien@aurel32.net>
+
+[ Upstream commit 3464afdf11f9a1e031e7858a05351ceca1792fea ]
+
+On powerpc with recent versions of binutils, readelf outputs an extra
+field when dumping the symbols of an object file. For example:
+
+    35: 0000000000000838    96 FUNC    LOCAL  DEFAULT [<localentry>: 8]     1 btf_is_struct
+
+The extra "[<localentry>: 8]" prevents the GLOBAL_SYM_COUNT variable to
+be computed correctly and causes the check_abi target to fail.
+
+Fix that by looking for the symbol name in the last field instead of the
+8th one. This way it should also cope with future extra fields.
+
+Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Tested-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/bpf/20191201195728.4161537-1-aurelien@aurel32.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/Makefile | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile
+index 33e2638ef7f0d..122321d549227 100644
+--- a/tools/lib/bpf/Makefile
++++ b/tools/lib/bpf/Makefile
+@@ -145,7 +145,7 @@ PC_FILE            := $(addprefix $(OUTPUT),$(PC_FILE))
+ GLOBAL_SYM_COUNT = $(shell readelf -s --wide $(BPF_IN_SHARED) | \
+                          cut -d "@" -f1 | sed 's/_v[0-9]_[0-9]_[0-9].*//' | \
+-                         awk '/GLOBAL/ && /DEFAULT/ && !/UND/ {print $$8}' | \
++                         awk '/GLOBAL/ && /DEFAULT/ && !/UND/ {print $$NF}' | \
+                          sort -u | wc -l)
+ VERSIONED_SYM_COUNT = $(shell readelf -s --wide $(OUTPUT)libbpf.so | \
+                             grep -Eo '[^ ]+@LIBBPF_' | cut -d@ -f1 | sort -u | wc -l)
+@@ -217,7 +217,7 @@ check_abi: $(OUTPUT)libbpf.so
+                    "versioned in $(VERSION_SCRIPT)." >&2;              \
+               readelf -s --wide $(BPF_IN_SHARED) |                     \
+                   cut -d "@" -f1 | sed 's/_v[0-9]_[0-9]_[0-9].*//' |   \
+-                  awk '/GLOBAL/ && /DEFAULT/ && !/UND/ {print $$8}'|   \
++                  awk '/GLOBAL/ && /DEFAULT/ && !/UND/ {print $$NF}'|  \
+                   sort -u > $(OUTPUT)libbpf_global_syms.tmp;           \
+               readelf -s --wide $(OUTPUT)libbpf.so |                   \
+                   grep -Eo '[^ ]+@LIBBPF_' | cut -d@ -f1 |             \
+-- 
+2.20.1
+
diff --git a/queue-5.4/loop-better-discard-support-for-block-devices.patch b/queue-5.4/loop-better-discard-support-for-block-devices.patch
new file mode 100644 (file)
index 0000000..9c5a380
--- /dev/null
@@ -0,0 +1,117 @@
+From 90d4aa83a89e945c554bfff7e05441b8006e8276 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Apr 2020 16:43:04 +0200
+Subject: loop: Better discard support for block devices
+
+From: Evan Green <evgreen@chromium.org>
+
+[ Upstream commit c52abf563049e787c1341cdf15c7dbe1bfbc951b ]
+
+If the backing device for a loop device is itself a block device,
+then mirror the "write zeroes" capabilities of the underlying
+block device into the loop device. Copy this capability into both
+max_write_zeroes_sectors and max_discard_sectors of the loop device.
+
+The reason for this is that REQ_OP_DISCARD on a loop device translates
+into blkdev_issue_zeroout(), rather than blkdev_issue_discard(). This
+presents a consistent interface for loop devices (that discarded data
+is zeroed), regardless of the backing device type of the loop device.
+There should be no behavior change for loop devices backed by regular
+files.
+
+This change fixes blktest block/003, and removes an extraneous
+error print in block/013 when testing on a loop device backed
+by a block device that does not support discard.
+
+Signed-off-by: Evan Green <evgreen@chromium.org>
+Reviewed-by: Gwendal Grignou <gwendal@chromium.org>
+Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
+[used updated version of Evan's comment in loop_config_discard()]
+[moved backingq to local scope, removed redundant braces]
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/loop.c | 42 +++++++++++++++++++++++++++++++-----------
+ 1 file changed, 31 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/block/loop.c b/drivers/block/loop.c
+index ef6e251857c8c..57ed6b70d2950 100644
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -427,11 +427,12 @@ static int lo_fallocate(struct loop_device *lo, struct request *rq, loff_t pos,
+        * information.
+        */
+       struct file *file = lo->lo_backing_file;
++      struct request_queue *q = lo->lo_queue;
+       int ret;
+       mode |= FALLOC_FL_KEEP_SIZE;
+-      if ((!file->f_op->fallocate) || lo->lo_encrypt_key_size) {
++      if (!blk_queue_discard(q)) {
+               ret = -EOPNOTSUPP;
+               goto out;
+       }
+@@ -863,28 +864,47 @@ static void loop_config_discard(struct loop_device *lo)
+       struct inode *inode = file->f_mapping->host;
+       struct request_queue *q = lo->lo_queue;
++      /*
++       * If the backing device is a block device, mirror its zeroing
++       * capability. Set the discard sectors to the block device's zeroing
++       * capabilities because loop discards result in blkdev_issue_zeroout(),
++       * not blkdev_issue_discard(). This maintains consistent behavior with
++       * file-backed loop devices: discarded regions read back as zero.
++       */
++      if (S_ISBLK(inode->i_mode) && !lo->lo_encrypt_key_size) {
++              struct request_queue *backingq;
++
++              backingq = bdev_get_queue(inode->i_bdev);
++              blk_queue_max_discard_sectors(q,
++                      backingq->limits.max_write_zeroes_sectors);
++
++              blk_queue_max_write_zeroes_sectors(q,
++                      backingq->limits.max_write_zeroes_sectors);
++
+       /*
+        * We use punch hole to reclaim the free space used by the
+        * image a.k.a. discard. However we do not support discard if
+        * encryption is enabled, because it may give an attacker
+        * useful information.
+        */
+-      if ((!file->f_op->fallocate) ||
+-          lo->lo_encrypt_key_size) {
++      } else if (!file->f_op->fallocate || lo->lo_encrypt_key_size) {
+               q->limits.discard_granularity = 0;
+               q->limits.discard_alignment = 0;
+               blk_queue_max_discard_sectors(q, 0);
+               blk_queue_max_write_zeroes_sectors(q, 0);
+-              blk_queue_flag_clear(QUEUE_FLAG_DISCARD, q);
+-              return;
+-      }
+-      q->limits.discard_granularity = inode->i_sb->s_blocksize;
+-      q->limits.discard_alignment = 0;
++      } else {
++              q->limits.discard_granularity = inode->i_sb->s_blocksize;
++              q->limits.discard_alignment = 0;
+-      blk_queue_max_discard_sectors(q, UINT_MAX >> 9);
+-      blk_queue_max_write_zeroes_sectors(q, UINT_MAX >> 9);
+-      blk_queue_flag_set(QUEUE_FLAG_DISCARD, q);
++              blk_queue_max_discard_sectors(q, UINT_MAX >> 9);
++              blk_queue_max_write_zeroes_sectors(q, UINT_MAX >> 9);
++      }
++
++      if (q->limits.max_write_zeroes_sectors)
++              blk_queue_flag_set(QUEUE_FLAG_DISCARD, q);
++      else
++              blk_queue_flag_clear(QUEUE_FLAG_DISCARD, q);
+ }
+ static void loop_unprepare_queue(struct loop_device *lo)
+-- 
+2.20.1
+
diff --git a/queue-5.4/nvme-fix-compat-address-handling-in-several-ioctls.patch b/queue-5.4/nvme-fix-compat-address-handling-in-several-ioctls.patch
new file mode 100644 (file)
index 0000000..7528e05
--- /dev/null
@@ -0,0 +1,116 @@
+From 9e286069af17b94f806eb01e85396ea6ee4763f9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 28 Mar 2020 01:09:09 -0400
+Subject: nvme: fix compat address handling in several ioctls
+
+From: Nick Bowler <nbowler@draconx.ca>
+
+[ Upstream commit c95b708d5fa65b4e51f088ee077d127fd5a57b70 ]
+
+On a 32-bit kernel, the upper bits of userspace addresses passed via
+various ioctls are silently ignored by the nvme driver.
+
+However on a 64-bit kernel running a compat task, these upper bits are
+not ignored and are in fact required to be zero for the ioctls to work.
+
+Unfortunately, this difference matters.  32-bit smartctl submits the
+NVME_IOCTL_ADMIN_CMD ioctl with garbage in these upper bits because it
+seems the pointer value it puts into the nvme_passthru_cmd structure is
+sign extended.  This works fine on 32-bit kernels but fails on a 64-bit
+one because (at least on my setup) the addresses smartctl uses are
+consistently above 2G.  For example:
+
+  # smartctl -x /dev/nvme0n1
+  smartctl 7.1 2019-12-30 r5022 [x86_64-linux-5.5.11] (local build)
+  Copyright (C) 2002-19, Bruce Allen, Christian Franke, www.smartmontools.org
+
+  Read NVMe Identify Controller failed: NVME_IOCTL_ADMIN_CMD: Bad address
+
+Since changing 32-bit kernels to actually check all of the submitted
+address bits now would break existing userspace, this patch fixes the
+compat problem by explicitly zeroing the upper bits in the compat case.
+This enables 32-bit smartctl to work on a 64-bit kernel.
+
+Signed-off-by: Nick Bowler <nbowler@draconx.ca>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/core.c | 27 ++++++++++++++++++++-------
+ 1 file changed, 20 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index b8fe42f4b3c5b..f97c48fd3edae 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -6,6 +6,7 @@
+ #include <linux/blkdev.h>
+ #include <linux/blk-mq.h>
++#include <linux/compat.h>
+ #include <linux/delay.h>
+ #include <linux/errno.h>
+ #include <linux/hdreg.h>
+@@ -1244,6 +1245,18 @@ static void nvme_enable_aen(struct nvme_ctrl *ctrl)
+       queue_work(nvme_wq, &ctrl->async_event_work);
+ }
++/*
++ * Convert integer values from ioctl structures to user pointers, silently
++ * ignoring the upper bits in the compat case to match behaviour of 32-bit
++ * kernels.
++ */
++static void __user *nvme_to_user_ptr(uintptr_t ptrval)
++{
++      if (in_compat_syscall())
++              ptrval = (compat_uptr_t)ptrval;
++      return (void __user *)ptrval;
++}
++
+ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio)
+ {
+       struct nvme_user_io io;
+@@ -1267,7 +1280,7 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio)
+       length = (io.nblocks + 1) << ns->lba_shift;
+       meta_len = (io.nblocks + 1) * ns->ms;
+-      metadata = (void __user *)(uintptr_t)io.metadata;
++      metadata = nvme_to_user_ptr(io.metadata);
+       if (ns->ext) {
+               length += meta_len;
+@@ -1290,7 +1303,7 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio)
+       c.rw.appmask = cpu_to_le16(io.appmask);
+       return nvme_submit_user_cmd(ns->queue, &c,
+-                      (void __user *)(uintptr_t)io.addr, length,
++                      nvme_to_user_ptr(io.addr), length,
+                       metadata, meta_len, lower_32_bits(io.slba), NULL, 0);
+ }
+@@ -1410,9 +1423,9 @@ static int nvme_user_cmd(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
+       effects = nvme_passthru_start(ctrl, ns, cmd.opcode);
+       status = nvme_submit_user_cmd(ns ? ns->queue : ctrl->admin_q, &c,
+-                      (void __user *)(uintptr_t)cmd.addr, cmd.data_len,
+-                      (void __user *)(uintptr_t)cmd.metadata,
+-                      cmd.metadata_len, 0, &result, timeout);
++                      nvme_to_user_ptr(cmd.addr), cmd.data_len,
++                      nvme_to_user_ptr(cmd.metadata), cmd.metadata_len,
++                      0, &result, timeout);
+       nvme_passthru_end(ctrl, effects);
+       if (status >= 0) {
+@@ -1457,8 +1470,8 @@ static int nvme_user_cmd64(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
+       effects = nvme_passthru_start(ctrl, ns, cmd.opcode);
+       status = nvme_submit_user_cmd(ns ? ns->queue : ctrl->admin_q, &c,
+-                      (void __user *)(uintptr_t)cmd.addr, cmd.data_len,
+-                      (void __user *)(uintptr_t)cmd.metadata, cmd.metadata_len,
++                      nvme_to_user_ptr(cmd.addr), cmd.data_len,
++                      nvme_to_user_ptr(cmd.metadata), cmd.metadata_len,
+                       0, &cmd.result, timeout);
+       nvme_passthru_end(ctrl, effects);
+-- 
+2.20.1
+
diff --git a/queue-5.4/nvme-fix-deadlock-caused-by-ana-update-wrong-locking.patch b/queue-5.4/nvme-fix-deadlock-caused-by-ana-update-wrong-locking.patch
new file mode 100644 (file)
index 0000000..4e746c6
--- /dev/null
@@ -0,0 +1,72 @@
+From f357ec28e1a5314004b2ca0e474a50b304c14fad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Apr 2020 09:34:54 -0700
+Subject: nvme: fix deadlock caused by ANA update wrong locking
+
+From: Sagi Grimberg <sagi@grimberg.me>
+
+[ Upstream commit 657f1975e9d9c880fa13030e88ba6cc84964f1db ]
+
+The deadlock combines 4 flows in parallel:
+- ns scanning (triggered from reconnect)
+- request timeout
+- ANA update (triggered from reconnect)
+- I/O coming into the mpath device
+
+(1) ns scanning triggers disk revalidation -> update disk info ->
+    freeze queue -> but blocked, due to (2)
+
+(2) timeout handler reference the g_usage_counter - > but blocks in
+    the transport .timeout() handler, due to (3)
+
+(3) the transport timeout handler (indirectly) calls nvme_stop_queue() ->
+    which takes the (down_read) namespaces_rwsem - > but blocks, due to (4)
+
+(4) ANA update takes the (down_write) namespaces_rwsem -> calls
+    nvme_mpath_set_live() -> which synchronize the ns_head srcu
+    (see commit 504db087aacc) -> but blocks, due to (5)
+
+(5) I/O came into nvme_mpath_make_request -> took srcu_read_lock ->
+    direct_make_request > blk_queue_enter -> but blocked, due to (1)
+
+==> the request queue is under freeze -> deadlock.
+
+The fix is making ANA update take a read lock as the namespaces list
+is not manipulated, it is just the ns and ns->head that are being
+updated (which is protected with the ns->head lock).
+
+Fixes: 0d0b660f214dc ("nvme: add ANA support")
+Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
+Reviewed-by: Keith Busch <kbusch@kernel.org>
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/multipath.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
+index aed6354cb2717..56caddeabb5e5 100644
+--- a/drivers/nvme/host/multipath.c
++++ b/drivers/nvme/host/multipath.c
+@@ -510,7 +510,7 @@ static int nvme_update_ana_state(struct nvme_ctrl *ctrl,
+       if (!nr_nsids)
+               return 0;
+-      down_write(&ctrl->namespaces_rwsem);
++      down_read(&ctrl->namespaces_rwsem);
+       list_for_each_entry(ns, &ctrl->namespaces, list) {
+               unsigned nsid = le32_to_cpu(desc->nsids[n]);
+@@ -521,7 +521,7 @@ static int nvme_update_ana_state(struct nvme_ctrl *ctrl,
+               if (++n == nr_nsids)
+                       break;
+       }
+-      up_write(&ctrl->namespaces_rwsem);
++      up_read(&ctrl->namespaces_rwsem);
+       return 0;
+ }
+-- 
+2.20.1
+
diff --git a/queue-5.4/nvme-tcp-fix-possible-crash-in-write_zeroes-processi.patch b/queue-5.4/nvme-tcp-fix-possible-crash-in-write_zeroes-processi.patch
new file mode 100644 (file)
index 0000000..ec4bf4b
--- /dev/null
@@ -0,0 +1,73 @@
+From 9c5f0da52a2097b40d02abf5ad94e7037da50d27 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 Mar 2020 15:06:30 -0700
+Subject: nvme-tcp: fix possible crash in write_zeroes processing
+
+From: Sagi Grimberg <sagi@grimberg.me>
+
+[ Upstream commit 25e5cb780e62bde432b401f312bb847edc78b432 ]
+
+We cannot look at blk_rq_payload_bytes without first checking
+that the request has a mappable physical segments first (e.g.
+blk_rq_nr_phys_segments(rq) != 0) and only then to take the
+request payload bytes. This caused us to send a wrong sgl to
+the target or even dereference a non-existing buffer in case
+we actually got to the data send sequence (if it was in-capsule).
+
+Reported-by: Tony Asleson <tasleson@redhat.com>
+Suggested-by: Chaitanya Kulkarni <Chaitanya.Kulkarni@wdc.com>
+Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/tcp.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
+index 244984420b41b..11e84ed4de361 100644
+--- a/drivers/nvme/host/tcp.c
++++ b/drivers/nvme/host/tcp.c
+@@ -164,16 +164,14 @@ static inline bool nvme_tcp_async_req(struct nvme_tcp_request *req)
+ static inline bool nvme_tcp_has_inline_data(struct nvme_tcp_request *req)
+ {
+       struct request *rq;
+-      unsigned int bytes;
+       if (unlikely(nvme_tcp_async_req(req)))
+               return false; /* async events don't have a request */
+       rq = blk_mq_rq_from_pdu(req);
+-      bytes = blk_rq_payload_bytes(rq);
+-      return rq_data_dir(rq) == WRITE && bytes &&
+-              bytes <= nvme_tcp_inline_data_size(req->queue);
++      return rq_data_dir(rq) == WRITE && req->data_len &&
++              req->data_len <= nvme_tcp_inline_data_size(req->queue);
+ }
+ static inline struct page *nvme_tcp_req_cur_page(struct nvme_tcp_request *req)
+@@ -2090,7 +2088,9 @@ static blk_status_t nvme_tcp_map_data(struct nvme_tcp_queue *queue,
+       c->common.flags |= NVME_CMD_SGL_METABUF;
+-      if (rq_data_dir(rq) == WRITE && req->data_len &&
++      if (!blk_rq_nr_phys_segments(rq))
++              nvme_tcp_set_sg_null(c);
++      else if (rq_data_dir(rq) == WRITE &&
+           req->data_len <= nvme_tcp_inline_data_size(queue))
+               nvme_tcp_set_sg_inline(queue, c, req->data_len);
+       else
+@@ -2117,7 +2117,8 @@ static blk_status_t nvme_tcp_setup_cmd_pdu(struct nvme_ns *ns,
+       req->data_sent = 0;
+       req->pdu_len = 0;
+       req->pdu_sent = 0;
+-      req->data_len = blk_rq_payload_bytes(rq);
++      req->data_len = blk_rq_nr_phys_segments(rq) ?
++                              blk_rq_payload_bytes(rq) : 0;
+       req->curr_bio = rq->bio;
+       if (rq_data_dir(rq) == WRITE &&
+-- 
+2.20.1
+
diff --git a/queue-5.4/pci-aspm-allow-re-enabling-clock-pm.patch b/queue-5.4/pci-aspm-allow-re-enabling-clock-pm.patch
new file mode 100644 (file)
index 0000000..fd325c7
--- /dev/null
@@ -0,0 +1,74 @@
+From 534051578b67ac32772566998c31f592af3eac1b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 5 Oct 2019 14:03:57 +0200
+Subject: PCI/ASPM: Allow re-enabling Clock PM
+
+From: Heiner Kallweit <hkallweit1@gmail.com>
+
+[ Upstream commit 35efea32b26f9aacc99bf07e0d2cdfba2028b099 ]
+
+Previously Clock PM could not be re-enabled after being disabled by
+pci_disable_link_state() because clkpm_capable was reset.  Change this by
+adding a clkpm_disable field similar to aspm_disable.
+
+Link: https://lore.kernel.org/r/4e8a66db-7d53-4a66-c26c-f0037ffaa705@gmail.com
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pcie/aspm.c | 18 +++++++++++-------
+ 1 file changed, 11 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
+index 32c34330e5a67..5a1bbf2cb7e98 100644
+--- a/drivers/pci/pcie/aspm.c
++++ b/drivers/pci/pcie/aspm.c
+@@ -64,6 +64,7 @@ struct pcie_link_state {
+       u32 clkpm_capable:1;            /* Clock PM capable? */
+       u32 clkpm_enabled:1;            /* Current Clock PM state */
+       u32 clkpm_default:1;            /* Default Clock PM state by BIOS */
++      u32 clkpm_disable:1;            /* Clock PM disabled */
+       /* Exit latencies */
+       struct aspm_latency latency_up; /* Upstream direction exit latency */
+@@ -161,8 +162,11 @@ static void pcie_set_clkpm_nocheck(struct pcie_link_state *link, int enable)
+ static void pcie_set_clkpm(struct pcie_link_state *link, int enable)
+ {
+-      /* Don't enable Clock PM if the link is not Clock PM capable */
+-      if (!link->clkpm_capable)
++      /*
++       * Don't enable Clock PM if the link is not Clock PM capable
++       * or Clock PM is disabled
++       */
++      if (!link->clkpm_capable || link->clkpm_disable)
+               enable = 0;
+       /* Need nothing if the specified equals to current state */
+       if (link->clkpm_enabled == enable)
+@@ -192,7 +196,8 @@ static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist)
+       }
+       link->clkpm_enabled = enabled;
+       link->clkpm_default = enabled;
+-      link->clkpm_capable = (blacklist) ? 0 : capable;
++      link->clkpm_capable = capable;
++      link->clkpm_disable = blacklist ? 1 : 0;
+ }
+ static bool pcie_retrain_link(struct pcie_link_state *link)
+@@ -1097,10 +1102,9 @@ static int __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)
+               link->aspm_disable |= ASPM_STATE_L1;
+       pcie_config_aspm_link(link, policy_to_aspm_state(link));
+-      if (state & PCIE_LINK_STATE_CLKPM) {
+-              link->clkpm_capable = 0;
+-              pcie_set_clkpm(link, 0);
+-      }
++      if (state & PCIE_LINK_STATE_CLKPM)
++              link->clkpm_disable = 1;
++      pcie_set_clkpm(link, policy_to_clkpm_state(link));
+       mutex_unlock(&aspm_lock);
+       if (sem)
+               up_read(&pci_bus_sem);
+-- 
+2.20.1
+
diff --git a/queue-5.4/pci-pciehp-prevent-deadlock-on-disconnect.patch b/queue-5.4/pci-pciehp-prevent-deadlock-on-disconnect.patch
new file mode 100644 (file)
index 0000000..b8302fb
--- /dev/null
@@ -0,0 +1,277 @@
+From 53b907da74951dd7372033d3217490a0da85ab1b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Oct 2019 20:00:22 +0300
+Subject: PCI: pciehp: Prevent deadlock on disconnect
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+[ Upstream commit 87d0f2a5536fdf5053a6d341880f96135549a644 ]
+
+This addresses deadlocks in these common cases in hierarchies containing
+two switches:
+
+  - All involved ports are runtime suspended and they are unplugged. This
+    can happen easily if the drivers involved automatically enable runtime
+    PM (xHCI for example does that).
+
+  - System is suspended (e.g., closing the lid on a laptop) with a dock +
+    something else connected, and the dock is unplugged while suspended.
+
+These cases lead to the following deadlock:
+
+  INFO: task irq/126-pciehp:198 blocked for more than 120 seconds.
+  irq/126-pciehp  D    0   198      2 0x80000000
+  Call Trace:
+   schedule+0x2c/0x80
+   schedule_timeout+0x246/0x350
+   wait_for_completion+0xb7/0x140
+   kthread_stop+0x49/0x110
+   free_irq+0x32/0x70
+   pcie_shutdown_notification+0x2f/0x50
+   pciehp_remove+0x27/0x50
+   pcie_port_remove_service+0x36/0x50
+   device_release_driver+0x12/0x20
+   bus_remove_device+0xec/0x160
+   device_del+0x13b/0x350
+   device_unregister+0x1a/0x60
+   remove_iter+0x1e/0x30
+   device_for_each_child+0x56/0x90
+   pcie_port_device_remove+0x22/0x40
+   pcie_portdrv_remove+0x20/0x60
+   pci_device_remove+0x3e/0xc0
+   device_release_driver_internal+0x18c/0x250
+   device_release_driver+0x12/0x20
+   pci_stop_bus_device+0x6f/0x90
+   pci_stop_bus_device+0x31/0x90
+   pci_stop_and_remove_bus_device+0x12/0x20
+   pciehp_unconfigure_device+0x88/0x140
+   pciehp_disable_slot+0x6a/0x110
+   pciehp_handle_presence_or_link_change+0x263/0x400
+   pciehp_ist+0x1c9/0x1d0
+   irq_thread_fn+0x24/0x60
+   irq_thread+0xeb/0x190
+   kthread+0x120/0x140
+
+  INFO: task irq/190-pciehp:2288 blocked for more than 120 seconds.
+  irq/190-pciehp  D    0  2288      2 0x80000000
+  Call Trace:
+   __schedule+0x2a2/0x880
+   schedule+0x2c/0x80
+   schedule_preempt_disabled+0xe/0x10
+   mutex_lock+0x2c/0x30
+   pci_lock_rescan_remove+0x15/0x20
+   pciehp_unconfigure_device+0x4d/0x140
+   pciehp_disable_slot+0x6a/0x110
+   pciehp_handle_presence_or_link_change+0x263/0x400
+   pciehp_ist+0x1c9/0x1d0
+   irq_thread_fn+0x24/0x60
+   irq_thread+0xeb/0x190
+   kthread+0x120/0x140
+
+What happens here is that the whole hierarchy is runtime resumed and the
+parent PCIe downstream port, which got the hot-remove event, starts
+removing devices below it, taking pci_lock_rescan_remove() lock. When the
+child PCIe port is runtime resumed it calls pciehp_check_presence() which
+ends up calling pciehp_card_present() and pciehp_check_link_active().  Both
+of these use pcie_capability_read_word(), which notices that the underlying
+device is already gone and returns PCIBIOS_DEVICE_NOT_FOUND with the
+capability value set to 0. When pciehp gets this value it thinks that its
+child device is also hot-removed and schedules its IRQ thread to handle the
+event.
+
+The deadlock happens when the child's IRQ thread runs and tries to acquire
+pci_lock_rescan_remove() which is already taken by the parent and the
+parent waits for the child's IRQ thread to finish.
+
+Prevent this from happening by checking the return value of
+pcie_capability_read_word() and if it is PCIBIOS_DEVICE_NOT_FOUND stop
+performing any hot-removal activities.
+
+[bhelgaas: add common scenarios to commit log]
+Link: https://lore.kernel.org/r/20191029170022.57528-2-mika.westerberg@linux.intel.com
+Tested-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/hotplug/pciehp.h      |  6 ++--
+ drivers/pci/hotplug/pciehp_core.c | 11 ++++--
+ drivers/pci/hotplug/pciehp_ctrl.c |  4 +--
+ drivers/pci/hotplug/pciehp_hpc.c  | 59 +++++++++++++++++++++++++------
+ 4 files changed, 61 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
+index 882ce82c46990..aa61d4c219d7b 100644
+--- a/drivers/pci/hotplug/pciehp.h
++++ b/drivers/pci/hotplug/pciehp.h
+@@ -174,10 +174,10 @@ void pciehp_set_indicators(struct controller *ctrl, int pwr, int attn);
+ void pciehp_get_latch_status(struct controller *ctrl, u8 *status);
+ int pciehp_query_power_fault(struct controller *ctrl);
+-bool pciehp_card_present(struct controller *ctrl);
+-bool pciehp_card_present_or_link_active(struct controller *ctrl);
++int pciehp_card_present(struct controller *ctrl);
++int pciehp_card_present_or_link_active(struct controller *ctrl);
+ int pciehp_check_link_status(struct controller *ctrl);
+-bool pciehp_check_link_active(struct controller *ctrl);
++int pciehp_check_link_active(struct controller *ctrl);
+ void pciehp_release_ctrl(struct controller *ctrl);
+ int pciehp_sysfs_enable_slot(struct hotplug_slot *hotplug_slot);
+diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
+index 56daad828c9e0..312cc45c44c78 100644
+--- a/drivers/pci/hotplug/pciehp_core.c
++++ b/drivers/pci/hotplug/pciehp_core.c
+@@ -139,10 +139,15 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
+ {
+       struct controller *ctrl = to_ctrl(hotplug_slot);
+       struct pci_dev *pdev = ctrl->pcie->port;
++      int ret;
+       pci_config_pm_runtime_get(pdev);
+-      *value = pciehp_card_present_or_link_active(ctrl);
++      ret = pciehp_card_present_or_link_active(ctrl);
+       pci_config_pm_runtime_put(pdev);
++      if (ret < 0)
++              return ret;
++
++      *value = ret;
+       return 0;
+ }
+@@ -158,13 +163,13 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
+  */
+ static void pciehp_check_presence(struct controller *ctrl)
+ {
+-      bool occupied;
++      int occupied;
+       down_read(&ctrl->reset_lock);
+       mutex_lock(&ctrl->state_lock);
+       occupied = pciehp_card_present_or_link_active(ctrl);
+-      if ((occupied && (ctrl->state == OFF_STATE ||
++      if ((occupied > 0 && (ctrl->state == OFF_STATE ||
+                         ctrl->state == BLINKINGON_STATE)) ||
+           (!occupied && (ctrl->state == ON_STATE ||
+                          ctrl->state == BLINKINGOFF_STATE)))
+diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
+index dd8e4a5fb2826..6503d15effbbd 100644
+--- a/drivers/pci/hotplug/pciehp_ctrl.c
++++ b/drivers/pci/hotplug/pciehp_ctrl.c
+@@ -226,7 +226,7 @@ void pciehp_handle_disable_request(struct controller *ctrl)
+ void pciehp_handle_presence_or_link_change(struct controller *ctrl, u32 events)
+ {
+-      bool present, link_active;
++      int present, link_active;
+       /*
+        * If the slot is on and presence or link has changed, turn it off.
+@@ -257,7 +257,7 @@ void pciehp_handle_presence_or_link_change(struct controller *ctrl, u32 events)
+       mutex_lock(&ctrl->state_lock);
+       present = pciehp_card_present(ctrl);
+       link_active = pciehp_check_link_active(ctrl);
+-      if (!present && !link_active) {
++      if (present <= 0 && link_active <= 0) {
+               mutex_unlock(&ctrl->state_lock);
+               return;
+       }
+diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
+index d74a71712cde4..356786a3b7f4b 100644
+--- a/drivers/pci/hotplug/pciehp_hpc.c
++++ b/drivers/pci/hotplug/pciehp_hpc.c
+@@ -201,17 +201,29 @@ static void pcie_write_cmd_nowait(struct controller *ctrl, u16 cmd, u16 mask)
+       pcie_do_write_cmd(ctrl, cmd, mask, false);
+ }
+-bool pciehp_check_link_active(struct controller *ctrl)
++/**
++ * pciehp_check_link_active() - Is the link active
++ * @ctrl: PCIe hotplug controller
++ *
++ * Check whether the downstream link is currently active. Note it is
++ * possible that the card is removed immediately after this so the
++ * caller may need to take it into account.
++ *
++ * If the hotplug controller itself is not available anymore returns
++ * %-ENODEV.
++ */
++int pciehp_check_link_active(struct controller *ctrl)
+ {
+       struct pci_dev *pdev = ctrl_dev(ctrl);
+       u16 lnk_status;
+-      bool ret;
++      int ret;
+-      pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lnk_status);
+-      ret = !!(lnk_status & PCI_EXP_LNKSTA_DLLLA);
++      ret = pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lnk_status);
++      if (ret == PCIBIOS_DEVICE_NOT_FOUND || lnk_status == (u16)~0)
++              return -ENODEV;
+-      if (ret)
+-              ctrl_dbg(ctrl, "%s: lnk_status = %x\n", __func__, lnk_status);
++      ret = !!(lnk_status & PCI_EXP_LNKSTA_DLLLA);
++      ctrl_dbg(ctrl, "%s: lnk_status = %x\n", __func__, lnk_status);
+       return ret;
+ }
+@@ -373,13 +385,29 @@ void pciehp_get_latch_status(struct controller *ctrl, u8 *status)
+       *status = !!(slot_status & PCI_EXP_SLTSTA_MRLSS);
+ }
+-bool pciehp_card_present(struct controller *ctrl)
++/**
++ * pciehp_card_present() - Is the card present
++ * @ctrl: PCIe hotplug controller
++ *
++ * Function checks whether the card is currently present in the slot and
++ * in that case returns true. Note it is possible that the card is
++ * removed immediately after the check so the caller may need to take
++ * this into account.
++ *
++ * It the hotplug controller itself is not available anymore returns
++ * %-ENODEV.
++ */
++int pciehp_card_present(struct controller *ctrl)
+ {
+       struct pci_dev *pdev = ctrl_dev(ctrl);
+       u16 slot_status;
++      int ret;
+-      pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status);
+-      return slot_status & PCI_EXP_SLTSTA_PDS;
++      ret = pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status);
++      if (ret == PCIBIOS_DEVICE_NOT_FOUND || slot_status == (u16)~0)
++              return -ENODEV;
++
++      return !!(slot_status & PCI_EXP_SLTSTA_PDS);
+ }
+ /**
+@@ -390,10 +418,19 @@ bool pciehp_card_present(struct controller *ctrl)
+  * Presence Detect State bit, this helper also returns true if the Link Active
+  * bit is set.  This is a concession to broken hotplug ports which hardwire
+  * Presence Detect State to zero, such as Wilocity's [1ae9:0200].
++ *
++ * Returns: %1 if the slot is occupied and %0 if it is not. If the hotplug
++ *        port is not present anymore returns %-ENODEV.
+  */
+-bool pciehp_card_present_or_link_active(struct controller *ctrl)
++int pciehp_card_present_or_link_active(struct controller *ctrl)
+ {
+-      return pciehp_card_present(ctrl) || pciehp_check_link_active(ctrl);
++      int ret;
++
++      ret = pciehp_card_present(ctrl);
++      if (ret)
++              return ret;
++
++      return pciehp_check_link_active(ctrl);
+ }
+ int pciehp_query_power_fault(struct controller *ctrl)
+-- 
+2.20.1
+
diff --git a/queue-5.4/pci-pm-add-missing-link-delays-required-by-the-pcie-.patch b/queue-5.4/pci-pm-add-missing-link-delays-required-by-the-pcie-.patch
new file mode 100644 (file)
index 0000000..08a15c4
--- /dev/null
@@ -0,0 +1,332 @@
+From 2d4903a6784d8465fc4b8e21d59bc4d05827c163 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Nov 2019 16:51:50 +0800
+Subject: PCI/PM: Add missing link delays required by the PCIe spec
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+[ Upstream commit ad9001f2f41198784b0423646450ba2cb24793a3 ]
+
+Currently Linux does not follow PCIe spec regarding the required delays
+after reset. A concrete example is a Thunderbolt add-in-card that consists
+of a PCIe switch and two PCIe endpoints:
+
+  +-1b.0-[01-6b]----00.0-[02-6b]--+-00.0-[03]----00.0 TBT controller
+                                  +-01.0-[04-36]-- DS hotplug port
+                                  +-02.0-[37]----00.0 xHCI controller
+                                  \-04.0-[38-6b]-- DS hotplug port
+
+The root port (1b.0) and the PCIe switch downstream ports are all PCIe Gen3
+so they support 8GT/s link speeds.
+
+We wait for the PCIe hierarchy to enter D3cold (runtime):
+
+  pcieport 0000:00:1b.0: power state changed by ACPI to D3cold
+
+When it wakes up from D3cold, according to the PCIe 5.0 section 5.8 the
+PCIe switch is put to reset and its power is re-applied. This means that we
+must follow the rules in PCIe 5.0 section 6.6.1.
+
+For the PCIe Gen3 ports we are dealing with here, the following applies:
+
+  With a Downstream Port that supports Link speeds greater than 5.0 GT/s,
+  software must wait a minimum of 100 ms after Link training completes
+  before sending a Configuration Request to the device immediately below
+  that Port. Software can determine when Link training completes by polling
+  the Data Link Layer Link Active bit or by setting up an associated
+  interrupt (see Section 6.7.3.3).
+
+Translating this into the above topology we would need to do this (DLLLA
+stands for Data Link Layer Link Active):
+
+  0000:00:1b.0: wait for 100 ms after DLLLA is set before access to 0000:01:00.0
+  0000:02:00.0: wait for 100 ms after DLLLA is set before access to 0000:03:00.0
+  0000:02:02.0: wait for 100 ms after DLLLA is set before access to 0000:37:00.0
+
+I've instrumented the kernel with some additional logging so we can see the
+actual delays performed:
+
+  pcieport 0000:00:1b.0: power state changed by ACPI to D0
+  pcieport 0000:00:1b.0: waiting for D3cold delay of 100 ms
+  pcieport 0000:00:1b.0: waiting for D3hot delay of 10 ms
+  pcieport 0000:02:01.0: waiting for D3hot delay of 10 ms
+  pcieport 0000:02:04.0: waiting for D3hot delay of 10 ms
+
+For the switch upstream port (01:00.0 reachable through 00:1b.0 root port)
+we wait for 100 ms but not taking into account the DLLLA requirement. We
+then wait 10 ms for D3hot -> D0 transition of the root port and the two
+downstream hotplug ports. This means that we deviate from what the spec
+requires.
+
+Performing the same check for system sleep (s2idle) transitions it turns
+out to be even worse. None of the mandatory delays are performed. If this
+would be S3 instead of s2idle then according to PCI FW spec 3.2 section
+4.6.8. there is a specific _DSM that allows the OS to skip the delays but
+this platform does not provide the _DSM and does not go to S3 anyway so no
+firmware is involved that could already handle these delays.
+
+On this particular platform these delays are not actually needed because
+there is an additional delay as part of the ACPI power resource that is
+used to turn on power to the hierarchy but since that additional delay is
+not required by any of standards (PCIe, ACPI) it is not present in the
+Intel Ice Lake, for example where missing the mandatory delays causes
+pciehp to start tearing down the stack too early (links are not yet
+trained). Below is an example how it looks like when this happens:
+
+  pcieport 0000:83:04.0: pciehp: Slot(4): Card not present
+  pcieport 0000:87:04.0: PME# disabled
+  pcieport 0000:83:04.0: pciehp: pciehp_unconfigure_device: domain:bus:dev = 0000:86:00
+  pcieport 0000:86:00.0: Refused to change power state, currently in D3
+  pcieport 0000:86:00.0: restoring config space at offset 0x3c (was 0xffffffff, writing 0x201ff)
+  pcieport 0000:86:00.0: restoring config space at offset 0x38 (was 0xffffffff, writing 0x0)
+  ...
+
+There is also one reported case (see the bugzilla link below) where the
+missing delay causes xHCI on a Titan Ridge controller fail to runtime
+resume when USB-C dock is plugged. This does not involve pciehp but instead
+the PCI core fails to runtime resume the xHCI device:
+
+  pcieport 0000:04:02.0: restoring config space at offset 0xc (was 0x10000, writing 0x10020)
+  pcieport 0000:04:02.0: restoring config space at offset 0x4 (was 0x100000, writing 0x100406)
+  xhci_hcd 0000:39:00.0: Refused to change power state, currently in D3
+  xhci_hcd 0000:39:00.0: restoring config space at offset 0x3c (was 0xffffffff, writing 0x1ff)
+  xhci_hcd 0000:39:00.0: restoring config space at offset 0x38 (was 0xffffffff, writing 0x0)
+  ...
+
+Add a new function pci_bridge_wait_for_secondary_bus() that is called on
+PCI core resume and runtime resume paths accordingly if the bridge entered
+D3cold (and thus went through reset).
+
+This is second attempt to add the missing delays. The previous solution in
+c2bf1fc212f7 ("PCI: Add missing link delays required by the PCIe spec") was
+reverted because of two issues it caused:
+
+  1. One system become unresponsive after S3 resume due to PME service
+     spinning in pcie_pme_work_fn(). The root port in question reports that
+     the xHCI sent PME but the xHCI device itself does not have PME status
+     set. The PME status bit is never cleared in the root port resulting
+     the indefinite loop in pcie_pme_work_fn().
+
+  2. Slows down resume if the root/downstream port does not support Data
+     Link Layer Active Reporting because pcie_wait_for_link_delay() waits
+     1100 ms in that case.
+
+This version should avoid the above issues because we restrict the delay to
+happen only if the port went into D3cold.
+
+Link: https://lore.kernel.org/linux-pci/SL2P216MB01878BBCD75F21D882AEEA2880C60@SL2P216MB0187.KORP216.PROD.OUTLOOK.COM/
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=203885
+Link: https://lore.kernel.org/r/20191112091617.70282-3-mika.westerberg@linux.intel.com
+Reported-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Tested-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pci-driver.c |  11 +++-
+ drivers/pci/pci.c        | 121 ++++++++++++++++++++++++++++++++++++++-
+ drivers/pci/pci.h        |   1 +
+ 3 files changed, 130 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
+index 0c3086793e4ec..5ea612a15550e 100644
+--- a/drivers/pci/pci-driver.c
++++ b/drivers/pci/pci-driver.c
+@@ -919,6 +919,8 @@ static int pci_pm_resume_noirq(struct device *dev)
+       struct pci_dev *pci_dev = to_pci_dev(dev);
+       struct device_driver *drv = dev->driver;
+       int error = 0;
++      pci_power_t prev_state = pci_dev->current_state;
++      bool skip_bus_pm = pci_dev->skip_bus_pm;
+       if (dev_pm_may_skip_resume(dev))
+               return 0;
+@@ -937,12 +939,15 @@ static int pci_pm_resume_noirq(struct device *dev)
+        * configuration here and attempting to put them into D0 again is
+        * pointless, so avoid doing that.
+        */
+-      if (!(pci_dev->skip_bus_pm && pm_suspend_no_platform()))
++      if (!(skip_bus_pm && pm_suspend_no_platform()))
+               pci_pm_default_resume_early(pci_dev);
+       pci_fixup_device(pci_fixup_resume_early, pci_dev);
+       pcie_pme_root_status_cleanup(pci_dev);
++      if (!skip_bus_pm && prev_state == PCI_D3cold)
++              pci_bridge_wait_for_secondary_bus(pci_dev);
++
+       if (pci_has_legacy_pm_support(pci_dev))
+               return pci_legacy_resume_early(dev);
+@@ -1333,6 +1338,7 @@ static int pci_pm_runtime_resume(struct device *dev)
+       int rc = 0;
+       struct pci_dev *pci_dev = to_pci_dev(dev);
+       const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
++      pci_power_t prev_state = pci_dev->current_state;
+       /*
+        * Restoring config space is necessary even if the device is not bound
+@@ -1348,6 +1354,9 @@ static int pci_pm_runtime_resume(struct device *dev)
+       pci_enable_wake(pci_dev, PCI_D0, false);
+       pci_fixup_device(pci_fixup_resume, pci_dev);
++      if (prev_state == PCI_D3cold)
++              pci_bridge_wait_for_secondary_bus(pci_dev);
++
+       if (pm && pm->runtime_resume)
+               rc = pm->runtime_resume(dev);
+diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
+index 94d6e120b4734..779132aef0fb9 100644
+--- a/drivers/pci/pci.c
++++ b/drivers/pci/pci.c
+@@ -1019,8 +1019,6 @@ static void __pci_start_power_transition(struct pci_dev *dev, pci_power_t state)
+                * because have already delayed for the bridge.
+                */
+               if (dev->runtime_d3cold) {
+-                      if (dev->d3cold_delay && !dev->imm_ready)
+-                              msleep(dev->d3cold_delay);
+                       /*
+                        * When powering on a bridge from D3cold, the
+                        * whole hierarchy may be powered on into
+@@ -4671,6 +4669,125 @@ bool pcie_wait_for_link(struct pci_dev *pdev, bool active)
+       return pcie_wait_for_link_delay(pdev, active, 100);
+ }
++/*
++ * Find maximum D3cold delay required by all the devices on the bus.  The
++ * spec says 100 ms, but firmware can lower it and we allow drivers to
++ * increase it as well.
++ *
++ * Called with @pci_bus_sem locked for reading.
++ */
++static int pci_bus_max_d3cold_delay(const struct pci_bus *bus)
++{
++      const struct pci_dev *pdev;
++      int min_delay = 100;
++      int max_delay = 0;
++
++      list_for_each_entry(pdev, &bus->devices, bus_list) {
++              if (pdev->d3cold_delay < min_delay)
++                      min_delay = pdev->d3cold_delay;
++              if (pdev->d3cold_delay > max_delay)
++                      max_delay = pdev->d3cold_delay;
++      }
++
++      return max(min_delay, max_delay);
++}
++
++/**
++ * pci_bridge_wait_for_secondary_bus - Wait for secondary bus to be accessible
++ * @dev: PCI bridge
++ *
++ * Handle necessary delays before access to the devices on the secondary
++ * side of the bridge are permitted after D3cold to D0 transition.
++ *
++ * For PCIe this means the delays in PCIe 5.0 section 6.6.1. For
++ * conventional PCI it means Tpvrh + Trhfa specified in PCI 3.0 section
++ * 4.3.2.
++ */
++void pci_bridge_wait_for_secondary_bus(struct pci_dev *dev)
++{
++      struct pci_dev *child;
++      int delay;
++
++      if (pci_dev_is_disconnected(dev))
++              return;
++
++      if (!pci_is_bridge(dev) || !dev->bridge_d3)
++              return;
++
++      down_read(&pci_bus_sem);
++
++      /*
++       * We only deal with devices that are present currently on the bus.
++       * For any hot-added devices the access delay is handled in pciehp
++       * board_added(). In case of ACPI hotplug the firmware is expected
++       * to configure the devices before OS is notified.
++       */
++      if (!dev->subordinate || list_empty(&dev->subordinate->devices)) {
++              up_read(&pci_bus_sem);
++              return;
++      }
++
++      /* Take d3cold_delay requirements into account */
++      delay = pci_bus_max_d3cold_delay(dev->subordinate);
++      if (!delay) {
++              up_read(&pci_bus_sem);
++              return;
++      }
++
++      child = list_first_entry(&dev->subordinate->devices, struct pci_dev,
++                               bus_list);
++      up_read(&pci_bus_sem);
++
++      /*
++       * Conventional PCI and PCI-X we need to wait Tpvrh + Trhfa before
++       * accessing the device after reset (that is 1000 ms + 100 ms). In
++       * practice this should not be needed because we don't do power
++       * management for them (see pci_bridge_d3_possible()).
++       */
++      if (!pci_is_pcie(dev)) {
++              pci_dbg(dev, "waiting %d ms for secondary bus\n", 1000 + delay);
++              msleep(1000 + delay);
++              return;
++      }
++
++      /*
++       * For PCIe downstream and root ports that do not support speeds
++       * greater than 5 GT/s need to wait minimum 100 ms. For higher
++       * speeds (gen3) we need to wait first for the data link layer to
++       * become active.
++       *
++       * However, 100 ms is the minimum and the PCIe spec says the
++       * software must allow at least 1s before it can determine that the
++       * device that did not respond is a broken device. There is
++       * evidence that 100 ms is not always enough, for example certain
++       * Titan Ridge xHCI controller does not always respond to
++       * configuration requests if we only wait for 100 ms (see
++       * https://bugzilla.kernel.org/show_bug.cgi?id=203885).
++       *
++       * Therefore we wait for 100 ms and check for the device presence.
++       * If it is still not present give it an additional 100 ms.
++       */
++      if (!pcie_downstream_port(dev))
++              return;
++
++      if (pcie_get_speed_cap(dev) <= PCIE_SPEED_5_0GT) {
++              pci_dbg(dev, "waiting %d ms for downstream link\n", delay);
++              msleep(delay);
++      } else {
++              pci_dbg(dev, "waiting %d ms for downstream link, after activation\n",
++                      delay);
++              if (!pcie_wait_for_link_delay(dev, true, delay)) {
++                      /* Did not train, no need to wait any further */
++                      return;
++              }
++      }
++
++      if (!pci_device_is_present(child)) {
++              pci_dbg(child, "waiting additional %d ms to become accessible\n", delay);
++              msleep(delay);
++      }
++}
++
+ void pci_reset_secondary_bus(struct pci_dev *dev)
+ {
+       u16 ctrl;
+diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
+index 273d60cb0762d..a5adc2e2c351d 100644
+--- a/drivers/pci/pci.h
++++ b/drivers/pci/pci.h
+@@ -107,6 +107,7 @@ void pci_allocate_cap_save_buffers(struct pci_dev *dev);
+ void pci_free_cap_save_buffers(struct pci_dev *dev);
+ bool pci_bridge_d3_possible(struct pci_dev *dev);
+ void pci_bridge_d3_update(struct pci_dev *dev);
++void pci_bridge_wait_for_secondary_bus(struct pci_dev *dev);
+ static inline void pci_wakeup_event(struct pci_dev *dev)
+ {
+-- 
+2.20.1
+
diff --git a/queue-5.4/pci-pm-add-pcie_wait_for_link_delay.patch b/queue-5.4/pci-pm-add-pcie_wait_for_link_delay.patch
new file mode 100644 (file)
index 0000000..1b2c57f
--- /dev/null
@@ -0,0 +1,75 @@
+From e925c1f6da0e9f4ad4203b2d97c92f2b3102d549 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Nov 2019 12:16:16 +0300
+Subject: PCI/PM: Add pcie_wait_for_link_delay()
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+[ Upstream commit 4827d63891b6a839dac49c6ab62e61c4b011c4f2 ]
+
+Add pcie_wait_for_link_delay().  Similar to pcie_wait_for_link() but allows
+passing custom activation delay in milliseconds.
+
+Link: https://lore.kernel.org/r/20191112091617.70282-2-mika.westerberg@linux.intel.com
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pci.c | 21 ++++++++++++++++++---
+ 1 file changed, 18 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
+index 981ae16f935bc..94d6e120b4734 100644
+--- a/drivers/pci/pci.c
++++ b/drivers/pci/pci.c
+@@ -4605,14 +4605,17 @@ static int pci_pm_reset(struct pci_dev *dev, int probe)
+       return pci_dev_wait(dev, "PM D3->D0", PCIE_RESET_READY_POLL_MS);
+ }
++
+ /**
+- * pcie_wait_for_link - Wait until link is active or inactive
++ * pcie_wait_for_link_delay - Wait until link is active or inactive
+  * @pdev: Bridge device
+  * @active: waiting for active or inactive?
++ * @delay: Delay to wait after link has become active (in ms)
+  *
+  * Use this to wait till link becomes active or inactive.
+  */
+-bool pcie_wait_for_link(struct pci_dev *pdev, bool active)
++static bool pcie_wait_for_link_delay(struct pci_dev *pdev, bool active,
++                                   int delay)
+ {
+       int timeout = 1000;
+       bool ret;
+@@ -4649,13 +4652,25 @@ bool pcie_wait_for_link(struct pci_dev *pdev, bool active)
+               timeout -= 10;
+       }
+       if (active && ret)
+-              msleep(100);
++              msleep(delay);
+       else if (ret != active)
+               pci_info(pdev, "Data Link Layer Link Active not %s in 1000 msec\n",
+                       active ? "set" : "cleared");
+       return ret == active;
+ }
++/**
++ * pcie_wait_for_link - Wait until link is active or inactive
++ * @pdev: Bridge device
++ * @active: waiting for active or inactive?
++ *
++ * Use this to wait till link becomes active or inactive.
++ */
++bool pcie_wait_for_link(struct pci_dev *pdev, bool active)
++{
++      return pcie_wait_for_link_delay(pdev, active, 100);
++}
++
+ void pci_reset_secondary_bus(struct pci_dev *dev)
+ {
+       u16 ctrl;
+-- 
+2.20.1
+
diff --git a/queue-5.4/perf-core-disable-page-faults-when-getting-phys-addr.patch b/queue-5.4/perf-core-disable-page-faults-when-getting-phys-addr.patch
new file mode 100644 (file)
index 0000000..5e269c1
--- /dev/null
@@ -0,0 +1,71 @@
+From 752b1de67e20c611dd0d4009edf7caacb61387ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Apr 2020 16:14:27 +0200
+Subject: perf/core: Disable page faults when getting phys address
+
+From: Jiri Olsa <jolsa@kernel.org>
+
+[ Upstream commit d3296fb372bf7497b0e5d0478c4e7a677ec6f6e9 ]
+
+We hit following warning when running tests on kernel
+compiled with CONFIG_DEBUG_ATOMIC_SLEEP=y:
+
+ WARNING: CPU: 19 PID: 4472 at mm/gup.c:2381 __get_user_pages_fast+0x1a4/0x200
+ CPU: 19 PID: 4472 Comm: dummy Not tainted 5.6.0-rc6+ #3
+ RIP: 0010:__get_user_pages_fast+0x1a4/0x200
+ ...
+ Call Trace:
+  perf_prepare_sample+0xff1/0x1d90
+  perf_event_output_forward+0xe8/0x210
+  __perf_event_overflow+0x11a/0x310
+  __intel_pmu_pebs_event+0x657/0x850
+  intel_pmu_drain_pebs_nhm+0x7de/0x11d0
+  handle_pmi_common+0x1b2/0x650
+  intel_pmu_handle_irq+0x17b/0x370
+  perf_event_nmi_handler+0x40/0x60
+  nmi_handle+0x192/0x590
+  default_do_nmi+0x6d/0x150
+  do_nmi+0x2f9/0x3c0
+  nmi+0x8e/0xd7
+
+While __get_user_pages_fast() is IRQ-safe, it calls access_ok(),
+which warns on:
+
+  WARN_ON_ONCE(!in_task() && !pagefault_disabled())
+
+Peter suggested disabling page faults around __get_user_pages_fast(),
+which gets rid of the warning in access_ok() call.
+
+Suggested-by: Peter Zijlstra <peterz@infradead.org>
+Signed-off-by: Jiri Olsa <jolsa@kernel.org>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Link: https://lkml.kernel.org/r/20200407141427.3184722-1-jolsa@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/events/core.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index 15b123bdcaf53..72d0cfd73cf11 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -6537,9 +6537,12 @@ static u64 perf_virt_to_phys(u64 virt)
+                * Try IRQ-safe __get_user_pages_fast first.
+                * If failed, leave phys_addr as 0.
+                */
+-              if ((current->mm != NULL) &&
+-                  (__get_user_pages_fast(virt, 1, 0, &p) == 1))
+-                      phys_addr = page_to_phys(p) + virt % PAGE_SIZE;
++              if (current->mm != NULL) {
++                      pagefault_disable();
++                      if (__get_user_pages_fast(virt, 1, 0, &p) == 1)
++                              phys_addr = page_to_phys(p) + virt % PAGE_SIZE;
++                      pagefault_enable();
++              }
+               if (p)
+                       put_page(p);
+-- 
+2.20.1
+
diff --git a/queue-5.4/powerpc-pseries-fix-mce-handling-on-pseries.patch b/queue-5.4/powerpc-pseries-fix-mce-handling-on-pseries.patch
new file mode 100644 (file)
index 0000000..7b48659
--- /dev/null
@@ -0,0 +1,87 @@
+From ba46c6a60b230dc4ae321c9e0cd62a7db54ebc8c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Mar 2020 16:31:19 +0530
+Subject: powerpc/pseries: Fix MCE handling on pseries
+
+From: Ganesh Goudar <ganeshgr@linux.ibm.com>
+
+[ Upstream commit a95a0a1654f16366360399574e10efd87e867b39 ]
+
+MCE handling on pSeries platform fails as recent rework to use common
+code for pSeries and PowerNV in machine check error handling tries to
+access per-cpu variables in realmode. The per-cpu variables may be
+outside the RMO region on pSeries platform and needs translation to be
+enabled for access. Just moving these per-cpu variable into RMO region
+did'nt help because we queue some work to workqueues in real mode, which
+again tries to touch per-cpu variables. Also fwnmi_release_errinfo()
+cannot be called when translation is not enabled.
+
+This patch fixes this by enabling translation in the exception handler
+when all required real mode handling is done. This change only affects
+the pSeries platform.
+
+Without this fix below kernel crash is seen on injecting
+SLB multihit:
+
+BUG: Unable to handle kernel data access on read at 0xc00000027b205950
+Faulting instruction address: 0xc00000000003b7e0
+Oops: Kernel access of bad area, sig: 11 [#1]
+LE PAGE_SIZE=64K MMU=Hash SMP NR_CPUS=2048 NUMA pSeries
+Modules linked in: mcetest_slb(OE+) af_packet(E) xt_tcpudp(E) ip6t_rpfilter(E) ip6t_REJECT(E) ipt_REJECT(E) xt_conntrack(E) ip_set(E) nfnetlink(E) ebtable_nat(E) ebtable_broute(E) ip6table_nat(E) ip6table_mangle(E) ip6table_raw(E) ip6table_security(E) iptable_nat(E) nf_nat(E) nf_conntrack(E) nf_defrag_ipv6(E) nf_defrag_ipv4(E) iptable_mangle(E) iptable_raw(E) iptable_security(E) ebtable_filter(E) ebtables(E) ip6table_filter(E) ip6_tables(E) iptable_filter(E) ip_tables(E) x_tables(E) xfs(E) ibmveth(E) vmx_crypto(E) gf128mul(E) uio_pdrv_genirq(E) uio(E) crct10dif_vpmsum(E) rtc_generic(E) btrfs(E) libcrc32c(E) xor(E) zstd_decompress(E) zstd_compress(E) raid6_pq(E) sr_mod(E) sd_mod(E) cdrom(E) ibmvscsi(E) scsi_transport_srp(E) crc32c_vpmsum(E) dm_mod(E) sg(E) scsi_mod(E)
+CPU: 34 PID: 8154 Comm: insmod Kdump: loaded Tainted: G OE 5.5.0-mahesh #1
+NIP: c00000000003b7e0 LR: c0000000000f2218 CTR: 0000000000000000
+REGS: c000000007dcb960 TRAP: 0300 Tainted: G OE (5.5.0-mahesh)
+MSR: 8000000000001003 <SF,ME,RI,LE> CR: 28002428 XER: 20040000
+CFAR: c0000000000f2214 DAR: c00000027b205950 DSISR: 40000000 IRQMASK: 0
+GPR00: c0000000000f2218 c000000007dcbbf0 c000000001544800 c000000007dcbd70
+GPR04: 0000000000000001 c000000007dcbc98 c008000000d00258 c0080000011c0000
+GPR08: 0000000000000000 0000000300000003 c000000001035950 0000000003000048
+GPR12: 000000027a1d0000 c000000007f9c000 0000000000000558 0000000000000000
+GPR16: 0000000000000540 c008000001110000 c008000001110540 0000000000000000
+GPR20: c00000000022af10 c00000025480fd70 c008000001280000 c00000004bfbb300
+GPR24: c000000001442330 c00800000800000d c008000008000000 4009287a77000510
+GPR28: 0000000000000000 0000000000000002 c000000001033d30 0000000000000001
+NIP [c00000000003b7e0] save_mce_event+0x30/0x240
+LR [c0000000000f2218] pseries_machine_check_realmode+0x2c8/0x4f0
+Call Trace:
+Instruction dump:
+3c4c0151 38429050 7c0802a6 60000000 fbc1fff0 fbe1fff8 f821ffd1 3d42ffaf
+3fc2ffaf e98d0030 394a1150 3bdef530 <7d6a62aa> 1d2b0048 2f8b0063 380b0001
+---[ end trace 46fd63f36bbdd940 ]---
+
+Fixes: 9ca766f9891d ("powerpc/64s/pseries: machine check convert to use common event code")
+Reviewed-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
+Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
+Signed-off-by: Ganesh Goudar <ganeshgr@linux.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20200320110119.10207-1-ganeshgr@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/pseries/ras.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c
+index 3acdcc3bb908c..753adeb624f23 100644
+--- a/arch/powerpc/platforms/pseries/ras.c
++++ b/arch/powerpc/platforms/pseries/ras.c
+@@ -683,6 +683,17 @@ static int mce_handle_error(struct pt_regs *regs, struct rtas_error_log *errp)
+ #endif
+ out:
++      /*
++       * Enable translation as we will be accessing per-cpu variables
++       * in save_mce_event() which may fall outside RMO region, also
++       * leave it enabled because subsequently we will be queuing work
++       * to workqueues where again per-cpu variables accessed, besides
++       * fwnmi_release_errinfo() crashes when called in realmode on
++       * pseries.
++       * Note: All the realmode handling like flushing SLB entries for
++       *       SLB multihit is done by now.
++       */
++      mtmsr(mfmsr() | MSR_IR | MSR_DR);
+       save_mce_event(regs, disposition == RTAS_DISP_FULLY_RECOVERED,
+                       &mce_err, regs->nip, eaddr, paddr);
+-- 
+2.20.1
+
diff --git a/queue-5.4/pwm-bcm2835-dynamically-allocate-base.patch b/queue-5.4/pwm-bcm2835-dynamically-allocate-base.patch
new file mode 100644 (file)
index 0000000..08e928b
--- /dev/null
@@ -0,0 +1,42 @@
+From 12592503600512d3fc90c3411030b5f64a84ee6d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Feb 2020 13:35:35 -0800
+Subject: pwm: bcm2835: Dynamically allocate base
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Florian Fainelli <f.fainelli@gmail.com>
+
+[ Upstream commit 2c25b07e5ec119cab609e41407a1fb3fa61442f5 ]
+
+The newer 2711 and 7211 chips have two PWM controllers and failure to
+dynamically allocate the PWM base would prevent the second PWM
+controller instance being probed for succeeding with an -EEXIST error
+from alloc_pwms().
+
+Fixes: e5a06dc5ac1f ("pwm: Add BCM2835 PWM driver")
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Reviewed-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pwm/pwm-bcm2835.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/pwm/pwm-bcm2835.c b/drivers/pwm/pwm-bcm2835.c
+index 91e24f01b54ed..d78f86f8e4621 100644
+--- a/drivers/pwm/pwm-bcm2835.c
++++ b/drivers/pwm/pwm-bcm2835.c
+@@ -166,6 +166,7 @@ static int bcm2835_pwm_probe(struct platform_device *pdev)
+       pc->chip.dev = &pdev->dev;
+       pc->chip.ops = &bcm2835_pwm_ops;
++      pc->chip.base = -1;
+       pc->chip.npwm = 2;
+       pc->chip.of_xlate = of_pwm_xlate_with_flags;
+       pc->chip.of_pwm_n_cells = 3;
+-- 
+2.20.1
+
diff --git a/queue-5.4/pwm-rcar-fix-late-runtime-pm-enablement.patch b/queue-5.4/pwm-rcar-fix-late-runtime-pm-enablement.patch
new file mode 100644 (file)
index 0000000..cfb6b9f
--- /dev/null
@@ -0,0 +1,66 @@
+From fc1cd28772e69e3c0ad0168fd3b4f60c1f5adbca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Mar 2020 11:32:14 +0100
+Subject: pwm: rcar: Fix late Runtime PM enablement
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 1451a3eed24b5fd6a604683f0b6995e0e7e16c79 ]
+
+Runtime PM should be enabled before calling pwmchip_add(), as PWM users
+can appear immediately after the PWM chip has been added.
+Likewise, Runtime PM should be disabled after the removal of the PWM
+chip.
+
+Fixes: ed6c1476bf7f16d5 ("pwm: Add support for R-Car PWM Timer")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pwm/pwm-rcar.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/pwm/pwm-rcar.c b/drivers/pwm/pwm-rcar.c
+index 852eb2347954d..b98ec8847b488 100644
+--- a/drivers/pwm/pwm-rcar.c
++++ b/drivers/pwm/pwm-rcar.c
+@@ -228,24 +228,28 @@ static int rcar_pwm_probe(struct platform_device *pdev)
+       rcar_pwm->chip.base = -1;
+       rcar_pwm->chip.npwm = 1;
++      pm_runtime_enable(&pdev->dev);
++
+       ret = pwmchip_add(&rcar_pwm->chip);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "failed to register PWM chip: %d\n", ret);
++              pm_runtime_disable(&pdev->dev);
+               return ret;
+       }
+-      pm_runtime_enable(&pdev->dev);
+-
+       return 0;
+ }
+ static int rcar_pwm_remove(struct platform_device *pdev)
+ {
+       struct rcar_pwm_chip *rcar_pwm = platform_get_drvdata(pdev);
++      int ret;
++
++      ret = pwmchip_remove(&rcar_pwm->chip);
+       pm_runtime_disable(&pdev->dev);
+-      return pwmchip_remove(&rcar_pwm->chip);
++      return ret;
+ }
+ static const struct of_device_id rcar_pwm_of_table[] = {
+-- 
+2.20.1
+
diff --git a/queue-5.4/pwm-renesas-tpu-fix-late-runtime-pm-enablement.patch b/queue-5.4/pwm-renesas-tpu-fix-late-runtime-pm-enablement.patch
new file mode 100644 (file)
index 0000000..596ec9b
--- /dev/null
@@ -0,0 +1,63 @@
+From a176f3fec7b57dc08e36e71ddcdb5bad23cd7e2f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Mar 2020 11:32:15 +0100
+Subject: pwm: renesas-tpu: Fix late Runtime PM enablement
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit d5a3c7a4536e1329a758e14340efd0e65252bd3d ]
+
+Runtime PM should be enabled before calling pwmchip_add(), as PWM users
+can appear immediately after the PWM chip has been added.
+Likewise, Runtime PM should always be disabled after the removal of the
+PWM chip, even if the latter failed.
+
+Fixes: 99b82abb0a35b073 ("pwm: Add Renesas TPU PWM driver")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pwm/pwm-renesas-tpu.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/pwm/pwm-renesas-tpu.c b/drivers/pwm/pwm-renesas-tpu.c
+index 4a855a21b782d..8032acc84161a 100644
+--- a/drivers/pwm/pwm-renesas-tpu.c
++++ b/drivers/pwm/pwm-renesas-tpu.c
+@@ -415,16 +415,17 @@ static int tpu_probe(struct platform_device *pdev)
+       tpu->chip.base = -1;
+       tpu->chip.npwm = TPU_CHANNEL_MAX;
++      pm_runtime_enable(&pdev->dev);
++
+       ret = pwmchip_add(&tpu->chip);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "failed to register PWM chip\n");
++              pm_runtime_disable(&pdev->dev);
+               return ret;
+       }
+       dev_info(&pdev->dev, "TPU PWM %d registered\n", tpu->pdev->id);
+-      pm_runtime_enable(&pdev->dev);
+-
+       return 0;
+ }
+@@ -434,12 +435,10 @@ static int tpu_remove(struct platform_device *pdev)
+       int ret;
+       ret = pwmchip_remove(&tpu->chip);
+-      if (ret)
+-              return ret;
+       pm_runtime_disable(&pdev->dev);
+-      return 0;
++      return ret;
+ }
+ #ifdef CONFIG_OF
+-- 
+2.20.1
+
diff --git a/queue-5.4/revert-powerpc-64-irq_work-avoid-interrupt-when-call.patch b/queue-5.4/revert-powerpc-64-irq_work-avoid-interrupt-when-call.patch
new file mode 100644 (file)
index 0000000..5983518
--- /dev/null
@@ -0,0 +1,111 @@
+From 1af9f0f6a6f268342a71e679e356ea1c269449f0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Apr 2020 22:04:01 +1000
+Subject: Revert "powerpc/64: irq_work avoid interrupt when called with
+ hardware irqs enabled"
+
+From: Nicholas Piggin <npiggin@gmail.com>
+
+[ Upstream commit abc3fce76adbdfa8f87272c784b388cd20b46049 ]
+
+This reverts commit ebb37cf3ffd39fdb6ec5b07111f8bb2f11d92c5f.
+
+That commit does not play well with soft-masked irq state
+manipulations in idle, interrupt replay, and possibly others due to
+tracing code sometimes using irq_work_queue (e.g., in
+trace_hardirqs_on()). That can cause PACA_IRQ_DEC to become set when
+it is not expected, and be ignored or cleared or cause warnings.
+
+The net result seems to be missing an irq_work until the next timer
+interrupt in the worst case which is usually not going to be noticed,
+however it could be a long time if the tick is disabled, which is
+against the spirit of irq_work and might cause real problems.
+
+The idea is still solid, but it would need more work. It's not really
+clear if it would be worth added complexity, so revert this for
+now (not a straight revert, but replace with a comment explaining why
+we might see interrupts happening, and gives git blame something to
+find).
+
+Fixes: ebb37cf3ffd3 ("powerpc/64: irq_work avoid interrupt when called with hardware irqs enabled")
+Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20200402120401.1115883-1-npiggin@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/time.c | 44 +++++++++++---------------------------
+ 1 file changed, 13 insertions(+), 31 deletions(-)
+
+diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
+index 11301a1187f33..0e0a2227af7d7 100644
+--- a/arch/powerpc/kernel/time.c
++++ b/arch/powerpc/kernel/time.c
+@@ -522,35 +522,6 @@ static inline void clear_irq_work_pending(void)
+               "i" (offsetof(struct paca_struct, irq_work_pending)));
+ }
+-void arch_irq_work_raise(void)
+-{
+-      preempt_disable();
+-      set_irq_work_pending_flag();
+-      /*
+-       * Non-nmi code running with interrupts disabled will replay
+-       * irq_happened before it re-enables interrupts, so setthe
+-       * decrementer there instead of causing a hardware exception
+-       * which would immediately hit the masked interrupt handler
+-       * and have the net effect of setting the decrementer in
+-       * irq_happened.
+-       *
+-       * NMI interrupts can not check this when they return, so the
+-       * decrementer hardware exception is raised, which will fire
+-       * when interrupts are next enabled.
+-       *
+-       * BookE does not support this yet, it must audit all NMI
+-       * interrupt handlers to ensure they call nmi_enter() so this
+-       * check would be correct.
+-       */
+-      if (IS_ENABLED(CONFIG_BOOKE) || !irqs_disabled() || in_nmi()) {
+-              set_dec(1);
+-      } else {
+-              hard_irq_disable();
+-              local_paca->irq_happened |= PACA_IRQ_DEC;
+-      }
+-      preempt_enable();
+-}
+-
+ #else /* 32-bit */
+ DEFINE_PER_CPU(u8, irq_work_pending);
+@@ -559,16 +530,27 @@ DEFINE_PER_CPU(u8, irq_work_pending);
+ #define test_irq_work_pending()               __this_cpu_read(irq_work_pending)
+ #define clear_irq_work_pending()      __this_cpu_write(irq_work_pending, 0)
++#endif /* 32 vs 64 bit */
++
+ void arch_irq_work_raise(void)
+ {
++      /*
++       * 64-bit code that uses irq soft-mask can just cause an immediate
++       * interrupt here that gets soft masked, if this is called under
++       * local_irq_disable(). It might be possible to prevent that happening
++       * by noticing interrupts are disabled and setting decrementer pending
++       * to be replayed when irqs are enabled. The problem there is that
++       * tracing can call irq_work_raise, including in code that does low
++       * level manipulations of irq soft-mask state (e.g., trace_hardirqs_on)
++       * which could get tangled up if we're messing with the same state
++       * here.
++       */
+       preempt_disable();
+       set_irq_work_pending_flag();
+       set_dec(1);
+       preempt_enable();
+ }
+-#endif /* 32 vs 64 bit */
+-
+ #else  /* CONFIG_IRQ_WORK */
+ #define test_irq_work_pending()       0
+-- 
+2.20.1
+
diff --git a/queue-5.4/s390-cio-avoid-duplicated-add-uevents.patch b/queue-5.4/s390-cio-avoid-duplicated-add-uevents.patch
new file mode 100644 (file)
index 0000000..edf5e9b
--- /dev/null
@@ -0,0 +1,65 @@
+From 6a16cd505486f62967425ab42db7b319d1146fff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 Mar 2020 13:45:02 +0100
+Subject: s390/cio: avoid duplicated 'ADD' uevents
+
+From: Cornelia Huck <cohuck@redhat.com>
+
+[ Upstream commit 05ce3e53f375295c2940390b2b429e506e07655c ]
+
+The common I/O layer delays the ADD uevent for subchannels and
+delegates generating this uevent to the individual subchannel
+drivers. The io_subchannel driver will do so when the associated
+ccw_device has been registered -- but unconditionally, so more
+ADD uevents will be generated if a subchannel has been unbound
+from the io_subchannel driver and later rebound.
+
+To fix this, only generate the ADD event if uevents were still
+suppressed for the device.
+
+Fixes: fa1a8c23eb7d ("s390: cio: Delay uevents for subchannels")
+Message-Id: <20200327124503.9794-2-cohuck@redhat.com>
+Reported-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
+Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
+Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/s390/cio/device.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
+index 0c6245fc77069..983f9c9e08deb 100644
+--- a/drivers/s390/cio/device.c
++++ b/drivers/s390/cio/device.c
+@@ -849,8 +849,10 @@ static void io_subchannel_register(struct ccw_device *cdev)
+        * Now we know this subchannel will stay, we can throw
+        * our delayed uevent.
+        */
+-      dev_set_uevent_suppress(&sch->dev, 0);
+-      kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
++      if (dev_get_uevent_suppress(&sch->dev)) {
++              dev_set_uevent_suppress(&sch->dev, 0);
++              kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
++      }
+       /* make it known to the system */
+       ret = ccw_device_add(cdev);
+       if (ret) {
+@@ -1058,8 +1060,11 @@ static int io_subchannel_probe(struct subchannel *sch)
+                * Throw the delayed uevent for the subchannel, register
+                * the ccw_device and exit.
+                */
+-              dev_set_uevent_suppress(&sch->dev, 0);
+-              kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
++              if (dev_get_uevent_suppress(&sch->dev)) {
++                      /* should always be the case for the console */
++                      dev_set_uevent_suppress(&sch->dev, 0);
++                      kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
++              }
+               cdev = sch_get_cdev(sch);
+               rc = ccw_device_add(cdev);
+               if (rc) {
+-- 
+2.20.1
+
diff --git a/queue-5.4/s390-cio-generate-delayed-uevent-for-vfio-ccw-subcha.patch b/queue-5.4/s390-cio-generate-delayed-uevent-for-vfio-ccw-subcha.patch
new file mode 100644 (file)
index 0000000..5b12bd1
--- /dev/null
@@ -0,0 +1,48 @@
+From 21109933a0a0b42c99574162bebf46521fbd406b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 Mar 2020 13:45:03 +0100
+Subject: s390/cio: generate delayed uevent for vfio-ccw subchannels
+
+From: Cornelia Huck <cohuck@redhat.com>
+
+[ Upstream commit 2bc55eaeb88d30accfc1b6ac2708d4e4b81ca260 ]
+
+The common I/O layer delays the ADD uevent for subchannels and
+delegates generating this uevent to the individual subchannel
+drivers. The vfio-ccw I/O subchannel driver, however, did not
+do that, and will not generate an ADD uevent for subchannels
+that had not been bound to a different driver (or none at all,
+which also triggers the uevent).
+
+Generate the ADD uevent at the end of the probe function if
+uevents were still suppressed for the device.
+
+Message-Id: <20200327124503.9794-3-cohuck@redhat.com>
+Fixes: 63f1934d562d ("vfio: ccw: basic implementation for vfio_ccw driver")
+Reviewed-by: Eric Farman <farman@linux.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/s390/cio/vfio_ccw_drv.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c
+index e401a3d0aa570..339a6bc0339b0 100644
+--- a/drivers/s390/cio/vfio_ccw_drv.c
++++ b/drivers/s390/cio/vfio_ccw_drv.c
+@@ -167,6 +167,11 @@ static int vfio_ccw_sch_probe(struct subchannel *sch)
+       if (ret)
+               goto out_disable;
++      if (dev_get_uevent_suppress(&sch->dev)) {
++              dev_set_uevent_suppress(&sch->dev, 0);
++              kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
++      }
++
+       VFIO_CCW_MSG_EVENT(4, "bound to subchannel %x.%x.%04x\n",
+                          sch->schid.cssid, sch->schid.ssid,
+                          sch->schid.sch_no);
+-- 
+2.20.1
+
diff --git a/queue-5.4/scsi-iscsi-report-unbind-session-event-when-the-targ.patch b/queue-5.4/scsi-iscsi-report-unbind-session-event-when-the-targ.patch
new file mode 100644 (file)
index 0000000..a7e01ac
--- /dev/null
@@ -0,0 +1,61 @@
+From 8474dbecfad4b70cfa84d6ffca90ccd00d9de867 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Mar 2020 15:58:50 +0800
+Subject: scsi: iscsi: Report unbind session event when the target has been
+ removed
+
+From: Wu Bo <wubo40@huawei.com>
+
+[ Upstream commit 13e60d3ba287d96eeaf1deaadba51f71578119a3 ]
+
+If the daemon is restarted or crashes while logging out of a session, the
+unbind session event sent by the kernel is not processed and is lost.  When
+the daemon starts again, the session can't be unbound because the daemon is
+waiting for the event message. However, the kernel has already logged out
+and the event will not be resent.
+
+When iscsid restart is complete, logout session reports error:
+
+Logging out of session [sid: 6, target: iqn.xxxxx, portal: xx.xx.xx.xx,3260]
+iscsiadm: Could not logout of [sid: 6, target: iscsiadm -m node iqn.xxxxx, portal: xx.xx.xx.xx,3260].
+iscsiadm: initiator reported error (9 - internal error)
+iscsiadm: Could not logout of all requested sessions
+
+Make sure the unbind event is emitted.
+
+[mkp: commit desc and applied by hand since patch was mangled]
+
+Link: https://lore.kernel.org/r/4eab1771-2cb3-8e79-b31c-923652340e99@huawei.com
+Reviewed-by: Lee Duncan <lduncan@suse.com>
+Signed-off-by: Wu Bo <wubo40@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/scsi_transport_iscsi.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
+index 271afea654e2b..a5c78b38d3022 100644
+--- a/drivers/scsi/scsi_transport_iscsi.c
++++ b/drivers/scsi/scsi_transport_iscsi.c
+@@ -2012,7 +2012,7 @@ static void __iscsi_unbind_session(struct work_struct *work)
+       if (session->target_id == ISCSI_MAX_TARGET) {
+               spin_unlock_irqrestore(&session->lock, flags);
+               mutex_unlock(&ihost->mutex);
+-              return;
++              goto unbind_session_exit;
+       }
+       target_id = session->target_id;
+@@ -2024,6 +2024,8 @@ static void __iscsi_unbind_session(struct work_struct *work)
+               ida_simple_remove(&iscsi_sess_ida, target_id);
+       scsi_remove_target(&session->dev);
++
++unbind_session_exit:
+       iscsi_session_event(session, ISCSI_KEVENT_UNBIND_SESSION);
+       ISCSI_DBG_TRANS_SESSION(session, "Completed target removal\n");
+ }
+-- 
+2.20.1
+
diff --git a/queue-5.4/scsi-libfc-if-prli-rejected-move-rport-to-plogi-stat.patch b/queue-5.4/scsi-libfc-if-prli-rejected-move-rport-to-plogi-stat.patch
new file mode 100644 (file)
index 0000000..0fe4f6a
--- /dev/null
@@ -0,0 +1,45 @@
+From ab048989b4a22071c50737df55b7960824f8ff12 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 Mar 2020 23:02:07 -0700
+Subject: scsi: libfc: If PRLI rejected, move rport to PLOGI state
+
+From: Javed Hasan <jhasan@marvell.com>
+
+[ Upstream commit 45e544bfdab2014d11c7595b8ccc3c4715a09015 ]
+
+If PRLI reject code indicates "rejected status", move rport state machine
+back to PLOGI state.
+
+Link: https://lore.kernel.org/r/20200327060208.17104-2-skashyap@marvell.com
+Signed-off-by: Javed Hasan <jhasan@marvell.com>
+Signed-off-by: Saurav Kashyap <skashyap@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/libfc/fc_rport.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
+index da6e97d8dc3bb..6bb8917b99a19 100644
+--- a/drivers/scsi/libfc/fc_rport.c
++++ b/drivers/scsi/libfc/fc_rport.c
+@@ -1208,9 +1208,15 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp,
+               rjt = fc_frame_payload_get(fp, sizeof(*rjt));
+               if (!rjt)
+                       FC_RPORT_DBG(rdata, "PRLI bad response\n");
+-              else
++              else {
+                       FC_RPORT_DBG(rdata, "PRLI ELS rejected, reason %x expl %x\n",
+                                    rjt->er_reason, rjt->er_explan);
++                      if (rjt->er_reason == ELS_RJT_UNAB &&
++                          rjt->er_explan == ELS_EXPL_PLOGI_REQD) {
++                              fc_rport_enter_plogi(rdata);
++                              goto out;
++                      }
++              }
+               fc_rport_error_retry(rdata, FC_EX_ELS_RJT);
+       }
+-- 
+2.20.1
+
diff --git a/queue-5.4/scsi-lpfc-fix-crash-after-handling-a-pci-error.patch b/queue-5.4/scsi-lpfc-fix-crash-after-handling-a-pci-error.patch
new file mode 100644 (file)
index 0000000..5db7c27
--- /dev/null
@@ -0,0 +1,47 @@
+From e639de2b39b09d3eaf29ed82cae4fc39332ba8e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 22 Mar 2020 11:12:57 -0700
+Subject: scsi: lpfc: Fix crash after handling a pci error
+
+From: James Smart <jsmart2021@gmail.com>
+
+[ Upstream commit 4cd70891308dfb875ef31060c4a4aa8872630a2e ]
+
+Injecting EEH on a 32GB card is causing kernel oops
+
+The pci error handler is doing an IO flush and the offline code is also
+doing an IO flush. When the 1st flush is complete the hdwq is destroyed
+(freed), yet the second flush accesses the hdwq and crashes.
+
+Added a check in lpfc_sli4_fush_io_rings to check both the HBA_IOQ_FLUSH
+flag and the hdwq pointer to see if it is already set and not already
+freed.
+
+Link: https://lore.kernel.org/r/20200322181304.37655-6-jsmart2021@gmail.com
+Signed-off-by: James Smart <jsmart2021@gmail.com>
+Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/lpfc/lpfc_sli.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
+index 1692ce913b7f0..a951e1c8165ed 100644
+--- a/drivers/scsi/lpfc/lpfc_sli.c
++++ b/drivers/scsi/lpfc/lpfc_sli.c
+@@ -4013,6 +4013,11 @@ lpfc_sli_flush_io_rings(struct lpfc_hba *phba)
+       struct lpfc_iocbq *piocb, *next_iocb;
+       spin_lock_irq(&phba->hbalock);
++      if (phba->hba_flag & HBA_IOQ_FLUSH ||
++          !phba->sli4_hba.hdwq) {
++              spin_unlock_irq(&phba->hbalock);
++              return;
++      }
+       /* Indicate the I/O queues are flushed */
+       phba->hba_flag |= HBA_IOQ_FLUSH;
+       spin_unlock_irq(&phba->hbalock);
+-- 
+2.20.1
+
diff --git a/queue-5.4/scsi-lpfc-fix-crash-in-target-side-cable-pulls-hitti.patch b/queue-5.4/scsi-lpfc-fix-crash-in-target-side-cable-pulls-hitti.patch
new file mode 100644 (file)
index 0000000..fb685a4
--- /dev/null
@@ -0,0 +1,76 @@
+From 3f2a904e6b77a68e7f25d51e423df382610fb0ce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 22 Mar 2020 11:12:59 -0700
+Subject: scsi: lpfc: Fix crash in target side cable pulls hitting
+ WAIT_FOR_UNREG
+
+From: James Smart <jsmart2021@gmail.com>
+
+[ Upstream commit 807e7353d8a7105ce884d22b0dbc034993c6679c ]
+
+Kernel is crashing with the following stacktrace:
+
+  BUG: unable to handle kernel NULL pointer dereference at
+    00000000000005bc
+  IP: lpfc_nvme_register_port+0x1a8/0x3a0 [lpfc]
+  ...
+  Call Trace:
+  lpfc_nlp_state_cleanup+0x2b2/0x500 [lpfc]
+  lpfc_nlp_set_state+0xd7/0x1a0 [lpfc]
+  lpfc_cmpl_prli_prli_issue+0x1f7/0x450 [lpfc]
+  lpfc_disc_state_machine+0x7a/0x1e0 [lpfc]
+  lpfc_cmpl_els_prli+0x16f/0x1e0 [lpfc]
+  lpfc_sli_sp_handle_rspiocb+0x5b2/0x690 [lpfc]
+  lpfc_sli_handle_slow_ring_event_s4+0x182/0x230 [lpfc]
+  lpfc_do_work+0x87f/0x1570 [lpfc]
+  kthread+0x10d/0x130
+  ret_from_fork+0x35/0x40
+
+During target side fault injections, it is possible to hit the
+NLP_WAIT_FOR_UNREG case in lpfc_nvme_remoteport_delete. A prior commit
+fixed a rebind and delete race condition, but called lpfc_nlp_put
+unconditionally. This triggered a deletion and the crash.
+
+Fix by movng nlp_put to inside the NLP_WAIT_FOR_UNREG case, where the nlp
+will be being unregistered/removed. Leave the reference if the flag isn't
+set.
+
+Link: https://lore.kernel.org/r/20200322181304.37655-8-jsmart2021@gmail.com
+Fixes: b15bd3e6212e ("scsi: lpfc: Fix nvme remoteport registration race conditions")
+Signed-off-by: James Smart <jsmart2021@gmail.com>
+Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/lpfc/lpfc_nvme.c | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
+index a227e36cbdc2b..5a86a1ee0de3b 100644
+--- a/drivers/scsi/lpfc/lpfc_nvme.c
++++ b/drivers/scsi/lpfc/lpfc_nvme.c
+@@ -342,13 +342,15 @@ lpfc_nvme_remoteport_delete(struct nvme_fc_remote_port *remoteport)
+       if (ndlp->upcall_flags & NLP_WAIT_FOR_UNREG) {
+               ndlp->nrport = NULL;
+               ndlp->upcall_flags &= ~NLP_WAIT_FOR_UNREG;
+-      }
+-      spin_unlock_irq(&vport->phba->hbalock);
++              spin_unlock_irq(&vport->phba->hbalock);
+-      /* Remove original register reference. The host transport
+-       * won't reference this rport/remoteport any further.
+-       */
+-      lpfc_nlp_put(ndlp);
++              /* Remove original register reference. The host transport
++               * won't reference this rport/remoteport any further.
++               */
++              lpfc_nlp_put(ndlp);
++      } else {
++              spin_unlock_irq(&vport->phba->hbalock);
++      }
+  rport_err:
+       return;
+-- 
+2.20.1
+
diff --git a/queue-5.4/scsi-lpfc-fix-kasan-slab-out-of-bounds-error-in-lpfc.patch b/queue-5.4/scsi-lpfc-fix-kasan-slab-out-of-bounds-error-in-lpfc.patch
new file mode 100644 (file)
index 0000000..c73dc57
--- /dev/null
@@ -0,0 +1,62 @@
+From f4ba5286ac43dba1873de8f4d28ab094d653c860 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 22 Mar 2020 11:12:53 -0700
+Subject: scsi: lpfc: Fix kasan slab-out-of-bounds error in lpfc_unreg_login
+
+From: James Smart <jsmart2021@gmail.com>
+
+[ Upstream commit 38503943c89f0bafd9e3742f63f872301d44cbea ]
+
+The following kasan bug was called out:
+
+ BUG: KASAN: slab-out-of-bounds in lpfc_unreg_login+0x7c/0xc0 [lpfc]
+ Read of size 2 at addr ffff889fc7c50a22 by task lpfc_worker_3/6676
+ ...
+ Call Trace:
+ dump_stack+0x96/0xe0
+ ? lpfc_unreg_login+0x7c/0xc0 [lpfc]
+ print_address_description.constprop.6+0x1b/0x220
+ ? lpfc_unreg_login+0x7c/0xc0 [lpfc]
+ ? lpfc_unreg_login+0x7c/0xc0 [lpfc]
+ __kasan_report.cold.9+0x37/0x7c
+ ? lpfc_unreg_login+0x7c/0xc0 [lpfc]
+ kasan_report+0xe/0x20
+ lpfc_unreg_login+0x7c/0xc0 [lpfc]
+ lpfc_sli_def_mbox_cmpl+0x334/0x430 [lpfc]
+ ...
+
+When processing the completion of a "Reg Rpi" login mailbox command in
+lpfc_sli_def_mbox_cmpl, a call may be made to lpfc_unreg_login. The vpi is
+extracted from the completing mailbox context and passed as an input for
+the next. However, the vpi stored in the mailbox command context is an
+absolute vpi, which for SLI4 represents both base + offset.  When used with
+a non-zero base component, (function id > 0) this results in an
+out-of-range access beyond the allocated phba->vpi_ids array.
+
+Fix by subtracting the function's base value to get an accurate vpi number.
+
+Link: https://lore.kernel.org/r/20200322181304.37655-2-jsmart2021@gmail.com
+Signed-off-by: James Smart <jsmart2021@gmail.com>
+Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/lpfc/lpfc_sli.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
+index 0717e850bcbfd..1692ce913b7f0 100644
+--- a/drivers/scsi/lpfc/lpfc_sli.c
++++ b/drivers/scsi/lpfc/lpfc_sli.c
+@@ -2481,6 +2481,8 @@ lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
+           !pmb->u.mb.mbxStatus) {
+               rpi = pmb->u.mb.un.varWords[0];
+               vpi = pmb->u.mb.un.varRegLogin.vpi;
++              if (phba->sli_rev == LPFC_SLI_REV4)
++                      vpi -= phba->sli4_hba.max_cfg_param.vpi_base;
+               lpfc_unreg_login(phba, vpi, rpi, pmb);
+               pmb->vport = vport;
+               pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+-- 
+2.20.1
+
diff --git a/queue-5.4/scsi-smartpqi-fix-call-trace-in-device-discovery.patch b/queue-5.4/scsi-smartpqi-fix-call-trace-in-device-discovery.patch
new file mode 100644 (file)
index 0000000..5562e3b
--- /dev/null
@@ -0,0 +1,43 @@
+From 9ceb0a0635e9bff75d4a341b2fb5a175d703ee73 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Oct 2019 17:31:28 -0500
+Subject: scsi: smartpqi: fix call trace in device discovery
+
+From: Murthy Bhat <Murthy.Bhat@microsemi.com>
+
+[ Upstream commit b969261134c1b990b96ea98fe5e0fcf8ec937c04 ]
+
+Use sas_phy_delete rather than sas_phy_free which, according to
+comments, should not be called for PHYs that have been set up
+successfully.
+
+Link: https://lore.kernel.org/r/157048748876.11757.17773443136670011786.stgit@brunhilda
+Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
+Reviewed-by: Scott Teel <scott.teel@microsemi.com>
+Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
+Signed-off-by: Murthy Bhat <Murthy.Bhat@microsemi.com>
+Signed-off-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/smartpqi/smartpqi_sas_transport.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_sas_transport.c b/drivers/scsi/smartpqi/smartpqi_sas_transport.c
+index 6776dfc1d317c..b7e28b9f8589f 100644
+--- a/drivers/scsi/smartpqi/smartpqi_sas_transport.c
++++ b/drivers/scsi/smartpqi/smartpqi_sas_transport.c
+@@ -45,9 +45,9 @@ static void pqi_free_sas_phy(struct pqi_sas_phy *pqi_sas_phy)
+       struct sas_phy *phy = pqi_sas_phy->phy;
+       sas_port_delete_phy(pqi_sas_phy->parent_port->port, phy);
+-      sas_phy_free(phy);
+       if (pqi_sas_phy->added_to_port)
+               list_del(&pqi_sas_phy->phy_list_entry);
++      sas_phy_delete(phy);
+       kfree(pqi_sas_phy);
+ }
+-- 
+2.20.1
+
diff --git a/queue-5.4/scsi-smartpqi-fix-controller-lockup-observed-during-.patch b/queue-5.4/scsi-smartpqi-fix-controller-lockup-observed-during-.patch
new file mode 100644 (file)
index 0000000..2933ac4
--- /dev/null
@@ -0,0 +1,305 @@
+From 36b25e80acb230949b881331982657a1ee37baf7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Oct 2019 17:31:23 -0500
+Subject: scsi: smartpqi: fix controller lockup observed during force reboot
+
+From: Kevin Barnett <kevin.barnett@microsemi.com>
+
+[ Upstream commit 0530736e40a0695b1ee2762e2684d00549699da4 ]
+
+Link: https://lore.kernel.org/r/157048748297.11757.3872221216800537383.stgit@brunhilda
+Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
+Reviewed-by: Scott Teel <scott.teel@microsemi.com>
+Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
+Signed-off-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/smartpqi/smartpqi.h      |   9 +-
+ drivers/scsi/smartpqi/smartpqi_init.c | 126 ++++++++++++++++++++++----
+ 2 files changed, 115 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h
+index 79d2af36f6552..2aa81b22f2695 100644
+--- a/drivers/scsi/smartpqi/smartpqi.h
++++ b/drivers/scsi/smartpqi/smartpqi.h
+@@ -1130,8 +1130,9 @@ struct pqi_ctrl_info {
+       struct mutex    ofa_mutex; /* serialize ofa */
+       bool            controller_online;
+       bool            block_requests;
+-      bool            in_shutdown;
++      bool            block_device_reset;
+       bool            in_ofa;
++      bool            in_shutdown;
+       u8              inbound_spanning_supported : 1;
+       u8              outbound_spanning_supported : 1;
+       u8              pqi_mode_enabled : 1;
+@@ -1173,6 +1174,7 @@ struct pqi_ctrl_info {
+       struct          pqi_ofa_memory *pqi_ofa_mem_virt_addr;
+       dma_addr_t      pqi_ofa_mem_dma_handle;
+       void            **pqi_ofa_chunk_virt_addr;
++      atomic_t        sync_cmds_outstanding;
+ };
+ enum pqi_ctrl_mode {
+@@ -1423,6 +1425,11 @@ static inline bool pqi_ctrl_blocked(struct pqi_ctrl_info *ctrl_info)
+       return ctrl_info->block_requests;
+ }
++static inline bool pqi_device_reset_blocked(struct pqi_ctrl_info *ctrl_info)
++{
++      return ctrl_info->block_device_reset;
++}
++
+ void pqi_sas_smp_handler(struct bsg_job *job, struct Scsi_Host *shost,
+       struct sas_rphy *rphy);
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index ea5409bebf578..793793343950e 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -249,6 +249,11 @@ static inline void pqi_ctrl_unblock_requests(struct pqi_ctrl_info *ctrl_info)
+       scsi_unblock_requests(ctrl_info->scsi_host);
+ }
++static inline void pqi_ctrl_block_device_reset(struct pqi_ctrl_info *ctrl_info)
++{
++      ctrl_info->block_device_reset = true;
++}
++
+ static unsigned long pqi_wait_if_ctrl_blocked(struct pqi_ctrl_info *ctrl_info,
+       unsigned long timeout_msecs)
+ {
+@@ -331,6 +336,16 @@ static inline bool pqi_device_in_remove(struct pqi_ctrl_info *ctrl_info,
+       return device->in_remove && !ctrl_info->in_shutdown;
+ }
++static inline void pqi_ctrl_shutdown_start(struct pqi_ctrl_info *ctrl_info)
++{
++      ctrl_info->in_shutdown = true;
++}
++
++static inline bool pqi_ctrl_in_shutdown(struct pqi_ctrl_info *ctrl_info)
++{
++      return ctrl_info->in_shutdown;
++}
++
+ static inline void pqi_schedule_rescan_worker_with_delay(
+       struct pqi_ctrl_info *ctrl_info, unsigned long delay)
+ {
+@@ -360,6 +375,11 @@ static inline void pqi_cancel_rescan_worker(struct pqi_ctrl_info *ctrl_info)
+       cancel_delayed_work_sync(&ctrl_info->rescan_work);
+ }
++static inline void pqi_cancel_event_worker(struct pqi_ctrl_info *ctrl_info)
++{
++      cancel_work_sync(&ctrl_info->event_work);
++}
++
+ static inline u32 pqi_read_heartbeat_counter(struct pqi_ctrl_info *ctrl_info)
+ {
+       if (!ctrl_info->heartbeat_counter)
+@@ -4122,6 +4142,8 @@ static int pqi_submit_raid_request_synchronous(struct pqi_ctrl_info *ctrl_info,
+               goto out;
+       }
++      atomic_inc(&ctrl_info->sync_cmds_outstanding);
++
+       io_request = pqi_alloc_io_request(ctrl_info);
+       put_unaligned_le16(io_request->index,
+@@ -4168,6 +4190,7 @@ static int pqi_submit_raid_request_synchronous(struct pqi_ctrl_info *ctrl_info,
+       pqi_free_io_request(io_request);
++      atomic_dec(&ctrl_info->sync_cmds_outstanding);
+ out:
+       up(&ctrl_info->sync_request_sem);
+@@ -5402,7 +5425,7 @@ static int pqi_scsi_queue_command(struct Scsi_Host *shost,
+       pqi_ctrl_busy(ctrl_info);
+       if (pqi_ctrl_blocked(ctrl_info) || pqi_device_in_reset(device) ||
+-          pqi_ctrl_in_ofa(ctrl_info)) {
++          pqi_ctrl_in_ofa(ctrl_info) || pqi_ctrl_in_shutdown(ctrl_info)) {
+               rc = SCSI_MLQUEUE_HOST_BUSY;
+               goto out;
+       }
+@@ -5650,6 +5673,18 @@ static int pqi_ctrl_wait_for_pending_io(struct pqi_ctrl_info *ctrl_info,
+       return 0;
+ }
++static int pqi_ctrl_wait_for_pending_sync_cmds(struct pqi_ctrl_info *ctrl_info)
++{
++      while (atomic_read(&ctrl_info->sync_cmds_outstanding)) {
++              pqi_check_ctrl_health(ctrl_info);
++              if (pqi_ctrl_offline(ctrl_info))
++                      return -ENXIO;
++              usleep_range(1000, 2000);
++      }
++
++      return 0;
++}
++
+ static void pqi_lun_reset_complete(struct pqi_io_request *io_request,
+       void *context)
+ {
+@@ -5787,17 +5822,17 @@ static int pqi_eh_device_reset_handler(struct scsi_cmnd *scmd)
+               shost->host_no, device->bus, device->target, device->lun);
+       pqi_check_ctrl_health(ctrl_info);
+-      if (pqi_ctrl_offline(ctrl_info)) {
+-              dev_err(&ctrl_info->pci_dev->dev,
+-                      "controller %u offlined - cannot send device reset\n",
+-                      ctrl_info->ctrl_id);
++      if (pqi_ctrl_offline(ctrl_info) ||
++              pqi_device_reset_blocked(ctrl_info)) {
+               rc = FAILED;
+               goto out;
+       }
+       pqi_wait_until_ofa_finished(ctrl_info);
++      atomic_inc(&ctrl_info->sync_cmds_outstanding);
+       rc = pqi_device_reset(ctrl_info, device);
++      atomic_dec(&ctrl_info->sync_cmds_outstanding);
+ out:
+       dev_err(&ctrl_info->pci_dev->dev,
+@@ -6119,7 +6154,8 @@ static int pqi_ioctl(struct scsi_device *sdev, unsigned int cmd,
+       ctrl_info = shost_to_hba(sdev->host);
+-      if (pqi_ctrl_in_ofa(ctrl_info))
++      if (pqi_ctrl_in_ofa(ctrl_info) ||
++              pqi_ctrl_in_shutdown(ctrl_info))
+               return -EBUSY;
+       switch (cmd) {
+@@ -7074,13 +7110,20 @@ static int pqi_force_sis_mode(struct pqi_ctrl_info *ctrl_info)
+       return pqi_revert_to_sis_mode(ctrl_info);
+ }
++#define PQI_POST_RESET_DELAY_B4_MSGU_READY    5000
++
+ static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info)
+ {
+       int rc;
+-      rc = pqi_force_sis_mode(ctrl_info);
+-      if (rc)
+-              return rc;
++      if (reset_devices) {
++              sis_soft_reset(ctrl_info);
++              msleep(PQI_POST_RESET_DELAY_B4_MSGU_READY);
++      } else {
++              rc = pqi_force_sis_mode(ctrl_info);
++              if (rc)
++                      return rc;
++      }
+       /*
+        * Wait until the controller is ready to start accepting SIS
+@@ -7514,6 +7557,7 @@ static struct pqi_ctrl_info *pqi_alloc_ctrl_info(int numa_node)
+       INIT_WORK(&ctrl_info->event_work, pqi_event_worker);
+       atomic_set(&ctrl_info->num_interrupts, 0);
++      atomic_set(&ctrl_info->sync_cmds_outstanding, 0);
+       INIT_DELAYED_WORK(&ctrl_info->rescan_work, pqi_rescan_worker);
+       INIT_DELAYED_WORK(&ctrl_info->update_time_work, pqi_update_time_worker);
+@@ -7787,8 +7831,6 @@ static int pqi_ofa_host_memory_update(struct pqi_ctrl_info *ctrl_info)
+               0, NULL, NO_TIMEOUT);
+ }
+-#define PQI_POST_RESET_DELAY_B4_MSGU_READY    5000
+-
+ static int pqi_ofa_ctrl_restart(struct pqi_ctrl_info *ctrl_info)
+ {
+       msleep(PQI_POST_RESET_DELAY_B4_MSGU_READY);
+@@ -7956,28 +7998,74 @@ static void pqi_pci_remove(struct pci_dev *pci_dev)
+       pqi_remove_ctrl(ctrl_info);
+ }
++static void pqi_crash_if_pending_command(struct pqi_ctrl_info *ctrl_info)
++{
++      unsigned int i;
++      struct pqi_io_request *io_request;
++      struct scsi_cmnd *scmd;
++
++      for (i = 0; i < ctrl_info->max_io_slots; i++) {
++              io_request = &ctrl_info->io_request_pool[i];
++              if (atomic_read(&io_request->refcount) == 0)
++                      continue;
++              scmd = io_request->scmd;
++              WARN_ON(scmd != NULL); /* IO command from SML */
++              WARN_ON(scmd == NULL); /* Non-IO cmd or driver initiated*/
++      }
++}
++
+ static void pqi_shutdown(struct pci_dev *pci_dev)
+ {
+       int rc;
+       struct pqi_ctrl_info *ctrl_info;
+       ctrl_info = pci_get_drvdata(pci_dev);
+-      if (!ctrl_info)
+-              goto error;
++      if (!ctrl_info) {
++              dev_err(&pci_dev->dev,
++                      "cache could not be flushed\n");
++              return;
++      }
++
++      pqi_disable_events(ctrl_info);
++      pqi_wait_until_ofa_finished(ctrl_info);
++      pqi_cancel_update_time_worker(ctrl_info);
++      pqi_cancel_rescan_worker(ctrl_info);
++      pqi_cancel_event_worker(ctrl_info);
++
++      pqi_ctrl_shutdown_start(ctrl_info);
++      pqi_ctrl_wait_until_quiesced(ctrl_info);
++
++      rc = pqi_ctrl_wait_for_pending_io(ctrl_info, NO_TIMEOUT);
++      if (rc) {
++              dev_err(&pci_dev->dev,
++                      "wait for pending I/O failed\n");
++              return;
++      }
++
++      pqi_ctrl_block_device_reset(ctrl_info);
++      pqi_wait_until_lun_reset_finished(ctrl_info);
+       /*
+        * Write all data in the controller's battery-backed cache to
+        * storage.
+        */
+       rc = pqi_flush_cache(ctrl_info, SHUTDOWN);
+-      pqi_free_interrupts(ctrl_info);
+-      pqi_reset(ctrl_info);
+-      if (rc == 0)
++      if (rc)
++              dev_err(&pci_dev->dev,
++                      "unable to flush controller cache\n");
++
++      pqi_ctrl_block_requests(ctrl_info);
++
++      rc = pqi_ctrl_wait_for_pending_sync_cmds(ctrl_info);
++      if (rc) {
++              dev_err(&pci_dev->dev,
++                      "wait for pending sync cmds failed\n");
+               return;
++      }
++
++      pqi_crash_if_pending_command(ctrl_info);
++      pqi_reset(ctrl_info);
+-error:
+-      dev_warn(&pci_dev->dev,
+-              "unable to flush controller cache\n");
+ }
+ static void pqi_process_lockup_action_param(void)
+-- 
+2.20.1
+
diff --git a/queue-5.4/scsi-smartpqi-fix-problem-with-unique-id-for-physica.patch b/queue-5.4/scsi-smartpqi-fix-problem-with-unique-id-for-physica.patch
new file mode 100644 (file)
index 0000000..a59db78
--- /dev/null
@@ -0,0 +1,174 @@
+From 1b716e73dc70bea0aa8feafd8001cbd229db10eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Oct 2019 17:31:58 -0500
+Subject: scsi: smartpqi: fix problem with unique ID for physical device
+
+From: Kevin Barnett <kevin.barnett@microsemi.com>
+
+[ Upstream commit 5b083b305b49f65269b888885455b8c0cf1a52e4 ]
+
+Obtain the unique IDs from the RLL and RPL instead of VPD page 83h.
+
+Link: https://lore.kernel.org/r/157048751833.11757.11996314786914610803.stgit@brunhilda
+Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
+Reviewed-by: Scott Teel <scott.teel@microsemi.com>
+Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
+Signed-off-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/smartpqi/smartpqi.h      |  1 -
+ drivers/scsi/smartpqi/smartpqi_init.c | 99 ++++-----------------------
+ 2 files changed, 12 insertions(+), 88 deletions(-)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h
+index 2aa81b22f2695..7a3a942b40df0 100644
+--- a/drivers/scsi/smartpqi/smartpqi.h
++++ b/drivers/scsi/smartpqi/smartpqi.h
+@@ -907,7 +907,6 @@ struct pqi_scsi_dev {
+       u8      scsi3addr[8];
+       __be64  wwid;
+       u8      volume_id[16];
+-      u8      unique_id[16];
+       u8      is_physical_device : 1;
+       u8      is_external_raid_device : 1;
+       u8      is_expander_smp_device : 1;
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index 793793343950e..5ae074505386a 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -648,79 +648,6 @@ static inline int pqi_scsi_inquiry(struct pqi_ctrl_info *ctrl_info,
+               buffer, buffer_length, vpd_page, NULL, NO_TIMEOUT);
+ }
+-static bool pqi_vpd_page_supported(struct pqi_ctrl_info *ctrl_info,
+-      u8 *scsi3addr, u16 vpd_page)
+-{
+-      int rc;
+-      int i;
+-      int pages;
+-      unsigned char *buf, bufsize;
+-
+-      buf = kzalloc(256, GFP_KERNEL);
+-      if (!buf)
+-              return false;
+-
+-      /* Get the size of the page list first */
+-      rc = pqi_scsi_inquiry(ctrl_info, scsi3addr,
+-                              VPD_PAGE | SCSI_VPD_SUPPORTED_PAGES,
+-                              buf, SCSI_VPD_HEADER_SZ);
+-      if (rc != 0)
+-              goto exit_unsupported;
+-
+-      pages = buf[3];
+-      if ((pages + SCSI_VPD_HEADER_SZ) <= 255)
+-              bufsize = pages + SCSI_VPD_HEADER_SZ;
+-      else
+-              bufsize = 255;
+-
+-      /* Get the whole VPD page list */
+-      rc = pqi_scsi_inquiry(ctrl_info, scsi3addr,
+-                              VPD_PAGE | SCSI_VPD_SUPPORTED_PAGES,
+-                              buf, bufsize);
+-      if (rc != 0)
+-              goto exit_unsupported;
+-
+-      pages = buf[3];
+-      for (i = 1; i <= pages; i++)
+-              if (buf[3 + i] == vpd_page)
+-                      goto exit_supported;
+-
+-exit_unsupported:
+-      kfree(buf);
+-      return false;
+-
+-exit_supported:
+-      kfree(buf);
+-      return true;
+-}
+-
+-static int pqi_get_device_id(struct pqi_ctrl_info *ctrl_info,
+-      u8 *scsi3addr, u8 *device_id, int buflen)
+-{
+-      int rc;
+-      unsigned char *buf;
+-
+-      if (!pqi_vpd_page_supported(ctrl_info, scsi3addr, SCSI_VPD_DEVICE_ID))
+-              return 1; /* function not supported */
+-
+-      buf = kzalloc(64, GFP_KERNEL);
+-      if (!buf)
+-              return -ENOMEM;
+-
+-      rc = pqi_scsi_inquiry(ctrl_info, scsi3addr,
+-                              VPD_PAGE | SCSI_VPD_DEVICE_ID,
+-                              buf, 64);
+-      if (rc == 0) {
+-              if (buflen > 16)
+-                      buflen = 16;
+-              memcpy(device_id, &buf[SCSI_VPD_DEVICE_ID_IDX], buflen);
+-      }
+-
+-      kfree(buf);
+-
+-      return rc;
+-}
+-
+ static int pqi_identify_physical_device(struct pqi_ctrl_info *ctrl_info,
+       struct pqi_scsi_dev *device,
+       struct bmic_identify_physical_device *buffer,
+@@ -1405,14 +1332,6 @@ static int pqi_get_device_info(struct pqi_ctrl_info *ctrl_info,
+               }
+       }
+-      if (pqi_get_device_id(ctrl_info, device->scsi3addr,
+-              device->unique_id, sizeof(device->unique_id)) < 0)
+-              dev_warn(&ctrl_info->pci_dev->dev,
+-                      "Can't get device id for scsi %d:%d:%d:%d\n",
+-                      ctrl_info->scsi_host->host_no,
+-                      device->bus, device->target,
+-                      device->lun);
+-
+ out:
+       kfree(buffer);
+@@ -6319,7 +6238,7 @@ static ssize_t pqi_unique_id_show(struct device *dev,
+       struct scsi_device *sdev;
+       struct pqi_scsi_dev *device;
+       unsigned long flags;
+-      unsigned char uid[16];
++      u8 unique_id[16];
+       sdev = to_scsi_device(dev);
+       ctrl_info = shost_to_hba(sdev->host);
+@@ -6332,16 +6251,22 @@ static ssize_t pqi_unique_id_show(struct device *dev,
+                       flags);
+               return -ENODEV;
+       }
+-      memcpy(uid, device->unique_id, sizeof(uid));
++
++      if (device->is_physical_device) {
++              memset(unique_id, 0, 8);
++              memcpy(unique_id + 8, &device->wwid, sizeof(device->wwid));
++      } else {
++              memcpy(unique_id, device->volume_id, sizeof(device->volume_id));
++      }
+       spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags);
+       return snprintf(buffer, PAGE_SIZE,
+               "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n",
+-              uid[0], uid[1], uid[2], uid[3],
+-              uid[4], uid[5], uid[6], uid[7],
+-              uid[8], uid[9], uid[10], uid[11],
+-              uid[12], uid[13], uid[14], uid[15]);
++              unique_id[0], unique_id[1], unique_id[2], unique_id[3],
++              unique_id[4], unique_id[5], unique_id[6], unique_id[7],
++              unique_id[8], unique_id[9], unique_id[10], unique_id[11],
++              unique_id[12], unique_id[13], unique_id[14], unique_id[15]);
+ }
+ static ssize_t pqi_lunid_show(struct device *dev,
+-- 
+2.20.1
+
diff --git a/queue-5.4/selftests-kmod-fix-handling-test-numbers-above-9.patch b/queue-5.4/selftests-kmod-fix-handling-test-numbers-above-9.patch
new file mode 100644 (file)
index 0000000..63a6cb1
--- /dev/null
@@ -0,0 +1,64 @@
+From 319de692ef923eafa7b5f08e33b00409b59d1fc6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Apr 2020 14:33:53 -0700
+Subject: selftests: kmod: fix handling test numbers above 9
+
+From: Eric Biggers <ebiggers@google.com>
+
+[ Upstream commit 6d573a07528308eb77ec072c010819c359bebf6e ]
+
+get_test_count() and get_test_enabled() were broken for test numbers
+above 9 due to awk interpreting a field specification like '$0010' as
+octal rather than decimal.  Fix it by stripping the leading zeroes.
+
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Acked-by: Luis Chamberlain <mcgrof@kernel.org>
+Cc: Alexei Starovoitov <ast@kernel.org>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: Jeff Vander Stoep <jeffv@google.com>
+Cc: Jessica Yu <jeyu@kernel.org>
+Cc: Kees Cook <keescook@chromium.org>
+Cc: NeilBrown <neilb@suse.com>
+Link: http://lkml.kernel.org/r/20200318230515.171692-5-ebiggers@kernel.org
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/kmod/kmod.sh | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/tools/testing/selftests/kmod/kmod.sh b/tools/testing/selftests/kmod/kmod.sh
+index 8b944cf042f6c..315a43111e046 100755
+--- a/tools/testing/selftests/kmod/kmod.sh
++++ b/tools/testing/selftests/kmod/kmod.sh
+@@ -505,18 +505,23 @@ function test_num()
+       fi
+ }
+-function get_test_count()
++function get_test_data()
+ {
+       test_num $1
+-      TEST_DATA=$(echo $ALL_TESTS | awk '{print $'$1'}')
++      local field_num=$(echo $1 | sed 's/^0*//')
++      echo $ALL_TESTS | awk '{print $'$field_num'}'
++}
++
++function get_test_count()
++{
++      TEST_DATA=$(get_test_data $1)
+       LAST_TWO=${TEST_DATA#*:*}
+       echo ${LAST_TWO%:*}
+ }
+ function get_test_enabled()
+ {
+-      test_num $1
+-      TEST_DATA=$(echo $ALL_TESTS | awk '{print $'$1'}')
++      TEST_DATA=$(get_test_data $1)
+       echo ${TEST_DATA#*:*:}
+ }
+-- 
+2.20.1
+
index c427fbc52a25f0d97f1b873f7ad25ea1f41eaded..5ded708894112a09960081cd06507313a6668533 100644 (file)
@@ -5,3 +5,51 @@ arm64-errata-hide-ctr_el0.dic-on-systems-affected-by.patch
 arm64-fake-the-iminline-size-on-systems-affected-by-.patch
 arm64-compat-workaround-neoverse-n1-1542419-for-comp.patch
 arm64-silence-clang-warning-on-mismatched-value-regi.patch
+tools-testing-nvdimm-fix-compilation-failure-without.patch
+watchdog-reset-last_hw_keepalive-time-at-start.patch
+scsi-lpfc-fix-kasan-slab-out-of-bounds-error-in-lpfc.patch
+scsi-lpfc-fix-crash-after-handling-a-pci-error.patch
+scsi-lpfc-fix-crash-in-target-side-cable-pulls-hitti.patch
+scsi-libfc-if-prli-rejected-move-rport-to-plogi-stat.patch
+ceph-return-ceph_mdsc_do_request-errors-from-__get_p.patch
+ceph-don-t-skip-updating-wanted-caps-when-cap-is-sta.patch
+pwm-rcar-fix-late-runtime-pm-enablement.patch
+nvme-tcp-fix-possible-crash-in-write_zeroes-processi.patch
+scsi-iscsi-report-unbind-session-event-when-the-targ.patch
+tools-test-nvdimm-fix-out-of-tree-build.patch
+asoc-intel-atom-take-the-drv-lock-mutex-before-calli.patch
+nvme-fix-deadlock-caused-by-ana-update-wrong-locking.patch
+drm-amd-display-update-stream-adjust-in-dc_stream_ad.patch
+dma-direct-fix-data-truncation-in-dma_direct_get_req.patch
+kernel-gcov-fs.c-gcov_seq_next-should-increase-posit.patch
+selftests-kmod-fix-handling-test-numbers-above-9.patch
+ipc-util.c-sysvipc_find_ipc-should-increase-position.patch
+kconfig-qconf-fix-a-few-alignment-issues.patch
+lib-raid6-test-fix-build-on-distros-whose-bin-sh-is-.patch
+s390-cio-generate-delayed-uevent-for-vfio-ccw-subcha.patch
+s390-cio-avoid-duplicated-add-uevents.patch
+loop-better-discard-support-for-block-devices.patch
+revert-powerpc-64-irq_work-avoid-interrupt-when-call.patch
+powerpc-pseries-fix-mce-handling-on-pseries.patch
+nvme-fix-compat-address-handling-in-several-ioctls.patch
+pwm-renesas-tpu-fix-late-runtime-pm-enablement.patch
+pwm-bcm2835-dynamically-allocate-base.patch
+perf-core-disable-page-faults-when-getting-phys-addr.patch
+drm-amd-display-calculate-scaling-ratios-on-every-me.patch
+asoc-intel-bytcr_rt5640-add-quirk-for-mpman-mpwin895.patch
+alsa-usb-audio-add-pioneer-dj-djm-250mk2-quirk.patch
+xhci-ensure-link-state-is-u3-after-setting-usb_ss_po.patch
+xhci-wait-until-link-state-trainsits-to-u0-after-set.patch
+xhci-finetune-host-initiated-usb3-rootport-link-susp.patch
+drm-amd-display-not-doing-optimize-bandwidth-if-flip.patch
+pci-pm-add-pcie_wait_for_link_delay.patch
+libbpf-fix-readelf-output-parsing-on-powerpc-with-re.patch
+pci-pciehp-prevent-deadlock-on-disconnect.patch
+asoc-sof-trace-fix-unconditional-free-in-trace-relea.patch
+tracing-selftests-turn-off-timeout-setting.patch
+virtio-blk-improve-virtqueue-error-to-blk_sts.patch
+scsi-smartpqi-fix-controller-lockup-observed-during-.patch
+scsi-smartpqi-fix-call-trace-in-device-discovery.patch
+scsi-smartpqi-fix-problem-with-unique-id-for-physica.patch
+pci-aspm-allow-re-enabling-clock-pm.patch
+pci-pm-add-missing-link-delays-required-by-the-pcie-.patch
diff --git a/queue-5.4/tools-test-nvdimm-fix-out-of-tree-build.patch b/queue-5.4/tools-test-nvdimm-fix-out-of-tree-build.patch
new file mode 100644 (file)
index 0000000..9e200e8
--- /dev/null
@@ -0,0 +1,67 @@
+From 7d9393657b05fbba005e77ef836383904d17de21 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jan 2020 11:10:51 +0530
+Subject: tools/test/nvdimm: Fix out of tree build
+
+From: Santosh Sivaraj <santosh@fossix.org>
+
+[ Upstream commit 1f776799628139d0da47e710ad86eb58d987ff66 ]
+
+Out of tree build using
+
+   make M=tools/test/nvdimm O=/tmp/build -C /tmp/build
+
+fails with the following error
+
+make: Entering directory '/tmp/build'
+  CC [M]  tools/testing/nvdimm/test/nfit.o
+linux/tools/testing/nvdimm/test/nfit.c:19:10: fatal error: nd-core.h: No such file or directory
+   19 | #include <nd-core.h>
+      |          ^~~~~~~~~~~
+compilation terminated.
+
+That is because the kbuild file uses $(src) which points to
+tools/testing/nvdimm, $(srctree) correctly points to root of the linux
+source tree.
+
+Reported-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
+Signed-off-by: Santosh Sivaraj <santosh@fossix.org>
+Link: https://lore.kernel.org/r/20200114054051.4115790-1-santosh@fossix.org
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/nvdimm/Kbuild      | 4 ++--
+ tools/testing/nvdimm/test/Kbuild | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/tools/testing/nvdimm/Kbuild b/tools/testing/nvdimm/Kbuild
+index c4a9196d794c9..cb80d3b811792 100644
+--- a/tools/testing/nvdimm/Kbuild
++++ b/tools/testing/nvdimm/Kbuild
+@@ -21,8 +21,8 @@ DRIVERS := ../../../drivers
+ NVDIMM_SRC := $(DRIVERS)/nvdimm
+ ACPI_SRC := $(DRIVERS)/acpi/nfit
+ DAX_SRC := $(DRIVERS)/dax
+-ccflags-y := -I$(src)/$(NVDIMM_SRC)/
+-ccflags-y += -I$(src)/$(ACPI_SRC)/
++ccflags-y := -I$(srctree)/drivers/nvdimm/
++ccflags-y += -I$(srctree)/drivers/acpi/nfit/
+ obj-$(CONFIG_LIBNVDIMM) += libnvdimm.o
+ obj-$(CONFIG_BLK_DEV_PMEM) += nd_pmem.o
+diff --git a/tools/testing/nvdimm/test/Kbuild b/tools/testing/nvdimm/test/Kbuild
+index fb3c3d7cdb9bd..75baebf8f4ba1 100644
+--- a/tools/testing/nvdimm/test/Kbuild
++++ b/tools/testing/nvdimm/test/Kbuild
+@@ -1,6 +1,6 @@
+ # SPDX-License-Identifier: GPL-2.0
+-ccflags-y := -I$(src)/../../../../drivers/nvdimm/
+-ccflags-y += -I$(src)/../../../../drivers/acpi/nfit/
++ccflags-y := -I$(srctree)/drivers/nvdimm/
++ccflags-y += -I$(srctree)/drivers/acpi/nfit/
+ obj-m += nfit_test.o
+ obj-m += nfit_test_iomap.o
+-- 
+2.20.1
+
diff --git a/queue-5.4/tools-testing-nvdimm-fix-compilation-failure-without.patch b/queue-5.4/tools-testing-nvdimm-fix-compilation-failure-without.patch
new file mode 100644 (file)
index 0000000..67e33f3
--- /dev/null
@@ -0,0 +1,45 @@
+From 29234079c578bfbb26aeb6be7509694c6b38224d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jan 2020 16:47:20 +0100
+Subject: tools/testing/nvdimm: Fix compilation failure without
+ CONFIG_DEV_DAX_PMEM_COMPAT
+
+From: Jan Kara <jack@suse.cz>
+
+[ Upstream commit c0e71d602053e4e7637e4bc7d0bc9603ea77a33f ]
+
+When a kernel is configured without CONFIG_DEV_DAX_PMEM_COMPAT, the
+compilation of tools/testing/nvdimm fails with:
+
+  Building modules, stage 2.
+  MODPOST 11 modules
+ERROR: "dax_pmem_compat_test" [tools/testing/nvdimm/test/nfit_test.ko] undefined!
+
+Fix the problem by calling dax_pmem_compat_test() only if the kernel has
+the required functionality.
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20200123154720.12097-1-jack@suse.cz
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/nvdimm/test/nfit.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c
+index bf6422a6af7ff..a8ee5c4d41ebb 100644
+--- a/tools/testing/nvdimm/test/nfit.c
++++ b/tools/testing/nvdimm/test/nfit.c
+@@ -3164,7 +3164,9 @@ static __init int nfit_test_init(void)
+       mcsafe_test();
+       dax_pmem_test();
+       dax_pmem_core_test();
++#ifdef CONFIG_DEV_DAX_PMEM_COMPAT
+       dax_pmem_compat_test();
++#endif
+       nfit_test_setup(nfit_test_lookup, nfit_test_evaluate_dsm);
+-- 
+2.20.1
+
diff --git a/queue-5.4/tracing-selftests-turn-off-timeout-setting.patch b/queue-5.4/tracing-selftests-turn-off-timeout-setting.patch
new file mode 100644 (file)
index 0000000..7f94abc
--- /dev/null
@@ -0,0 +1,35 @@
+From fd0c6a4017aeaf954ee7ecff8daebb1fdb5726fe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Nov 2019 11:48:39 -0500
+Subject: tracing/selftests: Turn off timeout setting
+
+From: Steven Rostedt (VMware) <rostedt@goodmis.org>
+
+[ Upstream commit b43e78f65b1d35fd3e13c7b23f9b64ea83c9ad3a ]
+
+As the ftrace selftests can run for a long period of time, disable the
+timeout that the general selftests have. If a selftest hangs, then it
+probably means the machine will hang too.
+
+Link: https://lore.kernel.org/r/alpine.LSU.2.21.1911131604170.18679@pobox.suse.cz
+
+Suggested-by: Miroslav Benes <mbenes@suse.cz>
+Tested-by: Miroslav Benes <mbenes@suse.cz>
+Reviewed-by: Miroslav Benes <mbenes@suse.cz>
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/ftrace/settings | 1 +
+ 1 file changed, 1 insertion(+)
+ create mode 100644 tools/testing/selftests/ftrace/settings
+
+diff --git a/tools/testing/selftests/ftrace/settings b/tools/testing/selftests/ftrace/settings
+new file mode 100644
+index 0000000000000..e7b9417537fbc
+--- /dev/null
++++ b/tools/testing/selftests/ftrace/settings
+@@ -0,0 +1 @@
++timeout=0
+-- 
+2.20.1
+
diff --git a/queue-5.4/virtio-blk-improve-virtqueue-error-to-blk_sts.patch b/queue-5.4/virtio-blk-improve-virtqueue-error-to-blk_sts.patch
new file mode 100644 (file)
index 0000000..ce05923
--- /dev/null
@@ -0,0 +1,47 @@
+From 3e226fbd70234cdd197ba7113fa4b461554d5550 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Feb 2020 13:37:28 +0100
+Subject: virtio-blk: improve virtqueue error to BLK_STS
+
+From: Halil Pasic <pasic@linux.ibm.com>
+
+[ Upstream commit 3d973b2e9a625996ee997c7303cd793b9d197c65 ]
+
+Let's change the mapping between virtqueue_add errors to BLK_STS
+statuses, so that -ENOSPC, which indicates virtqueue full is still
+mapped to BLK_STS_DEV_RESOURCE, but -ENOMEM which indicates non-device
+specific resource outage is mapped to BLK_STS_RESOURCE.
+
+Signed-off-by: Halil Pasic <pasic@linux.ibm.com>
+Link: https://lore.kernel.org/r/20200213123728.61216-3-pasic@linux.ibm.com
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/virtio_blk.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
+index c2ed3e9128e3a..a55383b139df9 100644
+--- a/drivers/block/virtio_blk.c
++++ b/drivers/block/virtio_blk.c
+@@ -345,9 +345,14 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx,
+               if (err == -ENOSPC)
+                       blk_mq_stop_hw_queue(hctx);
+               spin_unlock_irqrestore(&vblk->vqs[qid].lock, flags);
+-              if (err == -ENOMEM || err == -ENOSPC)
++              switch (err) {
++              case -ENOSPC:
+                       return BLK_STS_DEV_RESOURCE;
+-              return BLK_STS_IOERR;
++              case -ENOMEM:
++                      return BLK_STS_RESOURCE;
++              default:
++                      return BLK_STS_IOERR;
++              }
+       }
+       if (bd->last && virtqueue_kick_prepare(vblk->vqs[qid].vq))
+-- 
+2.20.1
+
diff --git a/queue-5.4/watchdog-reset-last_hw_keepalive-time-at-start.patch b/queue-5.4/watchdog-reset-last_hw_keepalive-time-at-start.patch
new file mode 100644 (file)
index 0000000..4591071
--- /dev/null
@@ -0,0 +1,42 @@
+From 5b9ecd7cc78b444cf0f792ed831949123f971e86 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Mar 2020 11:58:06 +0200
+Subject: watchdog: reset last_hw_keepalive time at start
+
+From: Tero Kristo <t-kristo@ti.com>
+
+[ Upstream commit 982bb70517aef2225bad1d802887b733db492cc0 ]
+
+Currently the watchdog core does not initialize the last_hw_keepalive
+time during watchdog startup. This will cause the watchdog to be pinged
+immediately if enough time has passed from the system boot-up time, and
+some types of watchdogs like K3 RTI does not like this.
+
+To avoid the issue, setup the last_hw_keepalive time during watchdog
+startup.
+
+Signed-off-by: Tero Kristo <t-kristo@ti.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/20200302200426.6492-3-t-kristo@ti.com
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/watchdog/watchdog_dev.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c
+index ce04edc69e5f0..c4147e93aa7d4 100644
+--- a/drivers/watchdog/watchdog_dev.c
++++ b/drivers/watchdog/watchdog_dev.c
+@@ -282,6 +282,7 @@ static int watchdog_start(struct watchdog_device *wdd)
+       if (err == 0) {
+               set_bit(WDOG_ACTIVE, &wdd->status);
+               wd_data->last_keepalive = started_at;
++              wd_data->last_hw_keepalive = started_at;
+               watchdog_update_worker(wdd);
+       }
+-- 
+2.20.1
+
diff --git a/queue-5.4/xhci-ensure-link-state-is-u3-after-setting-usb_ss_po.patch b/queue-5.4/xhci-ensure-link-state-is-u3-after-setting-usb_ss_po.patch
new file mode 100644 (file)
index 0000000..38d3e14
--- /dev/null
@@ -0,0 +1,54 @@
+From 82d48e68841d77c8fa61a8586e937aab8d41cdff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Mar 2020 16:45:14 +0200
+Subject: xhci: Ensure link state is U3 after setting USB_SS_PORT_LS_U3
+
+From: Kai-Heng Feng <kai.heng.feng@canonical.com>
+
+[ Upstream commit eb002726fac7cefb98ff39ddb89e150a1c24fe85 ]
+
+The xHCI spec doesn't specify the upper bound of U3 transition time. For
+some devices 20ms is not enough, so we need to make sure the link state
+is in U3 before further actions.
+
+I've tried to use U3 Entry Capability by setting U3 Entry Enable in
+config register, however the port change event for U3 transition
+interrupts the system suspend process.
+
+For now let's use the less ideal method by polling PLS.
+
+[use usleep_range(), and shorten the delay time while polling -Mathias]
+Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20200312144517.1593-7-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/xhci-hub.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
+index af92b2576fe91..712cd44f05ace 100644
+--- a/drivers/usb/host/xhci-hub.c
++++ b/drivers/usb/host/xhci-hub.c
+@@ -1322,7 +1322,16 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
+                       xhci_set_link_state(xhci, ports[wIndex], link_state);
+                       spin_unlock_irqrestore(&xhci->lock, flags);
+-                      msleep(20); /* wait device to enter */
++                      if (link_state == USB_SS_PORT_LS_U3) {
++                              int retries = 16;
++
++                              while (retries--) {
++                                      usleep_range(4000, 8000);
++                                      temp = readl(ports[wIndex]->addr);
++                                      if ((temp & PORT_PLS_MASK) == XDEV_U3)
++                                              break;
++                              }
++                      }
+                       spin_lock_irqsave(&xhci->lock, flags);
+                       temp = readl(ports[wIndex]->addr);
+-- 
+2.20.1
+
diff --git a/queue-5.4/xhci-finetune-host-initiated-usb3-rootport-link-susp.patch b/queue-5.4/xhci-finetune-host-initiated-usb3-rootport-link-susp.patch
new file mode 100644 (file)
index 0000000..a543661
--- /dev/null
@@ -0,0 +1,82 @@
+From 19f4998c462345f0d6f62a89077ddb87efbfbb59 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Mar 2020 16:45:16 +0200
+Subject: xhci: Finetune host initiated USB3 rootport link suspend and resume
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+[ Upstream commit ceca49382ac20e06ce04c21279c7f2868c4ec1d4 ]
+
+Depending on the current link state the steps to resume the link to U0
+varies. The normal case when a port is suspended (U3) we set the link
+to U0 and wait for a port event when U3exit completed and port moved to
+U0.
+
+If the port is in U1/U2, then no event is issued, just set link to U0
+
+If port is in Resume or Recovery state then the device has already
+initiated resume, and this host initiated resume is racing against it.
+Port event handler for device initiated resume will set link to U0,
+just wait for the port to reach U0 before returning.
+
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20200312144517.1593-9-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/xhci-hub.c | 36 +++++++++++++++++++++++++-----------
+ 1 file changed, 25 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
+index 02f52d4f74df8..a9c87eb8951e8 100644
+--- a/drivers/usb/host/xhci-hub.c
++++ b/drivers/usb/host/xhci-hub.c
+@@ -1307,20 +1307,34 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
+                               goto error;
+                       }
++                      /*
++                       * set link to U0, steps depend on current link state.
++                       * U3: set link to U0 and wait for u3exit completion.
++                       * U1/U2:  no PLC complete event, only set link to U0.
++                       * Resume/Recovery: device initiated U0, only wait for
++                       * completion
++                       */
+                       if (link_state == USB_SS_PORT_LS_U0) {
+-                              if ((temp & PORT_PLS_MASK) == XDEV_U0)
+-                                      break;
++                              u32 pls = temp & PORT_PLS_MASK;
++                              bool wait_u0 = false;
+-                              if (!((temp & PORT_PLS_MASK) == XDEV_U1 ||
+-                                  (temp & PORT_PLS_MASK) == XDEV_U2 ||
+-                                  (temp & PORT_PLS_MASK) == XDEV_U3)) {
+-                                      xhci_warn(xhci, "Can only set port %d to U0 from U state\n",
+-                                                      wIndex);
+-                                      goto error;
++                              /* already in U0 */
++                              if (pls == XDEV_U0)
++                                      break;
++                              if (pls == XDEV_U3 ||
++                                  pls == XDEV_RESUME ||
++                                  pls == XDEV_RECOVERY) {
++                                      wait_u0 = true;
++                                      reinit_completion(&bus_state->u3exit_done[wIndex]);
++                              }
++                              if (pls <= XDEV_U3) /* U1, U2, U3 */
++                                      xhci_set_link_state(xhci, ports[wIndex],
++                                                          USB_SS_PORT_LS_U0);
++                              if (!wait_u0) {
++                                      if (pls > XDEV_U3)
++                                              goto error;
++                                      break;
+                               }
+-                              reinit_completion(&bus_state->u3exit_done[wIndex]);
+-                              xhci_set_link_state(xhci, ports[wIndex],
+-                                                  USB_SS_PORT_LS_U0);
+                               spin_unlock_irqrestore(&xhci->lock, flags);
+                               if (!wait_for_completion_timeout(&bus_state->u3exit_done[wIndex],
+                                                                msecs_to_jiffies(100)))
+-- 
+2.20.1
+
diff --git a/queue-5.4/xhci-wait-until-link-state-trainsits-to-u0-after-set.patch b/queue-5.4/xhci-wait-until-link-state-trainsits-to-u0-after-set.patch
new file mode 100644 (file)
index 0000000..f6244f1
--- /dev/null
@@ -0,0 +1,140 @@
+From c374aaae6b9a5505775dcf9d46bab8e940c061e9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Mar 2020 16:45:15 +0200
+Subject: xhci: Wait until link state trainsits to U0 after setting
+ USB_SS_PORT_LS_U0
+
+From: Kai-Heng Feng <kai.heng.feng@canonical.com>
+
+[ Upstream commit 0200b9f790b0fc9e9a42f685f5ad54b23fe959f4 ]
+
+Like U3 case, xHCI spec doesn't specify the upper bound of U0 transition
+time. The 20ms is not enough for some devices.
+
+Intead of polling PLS or PLC, we can facilitate the port change event to
+know that the link transits to U0 is completed.
+
+While at it, also separate U0 and U3 case to make the code cleaner.
+
+[variable rename to u3exit, and skip completion for usb2 ports -Mathias ]
+Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20200312144517.1593-8-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/xhci-hub.c  | 44 +++++++++++++++++++++++++-----------
+ drivers/usb/host/xhci-mem.c  |  1 +
+ drivers/usb/host/xhci-ring.c |  1 +
+ drivers/usb/host/xhci.h      |  1 +
+ 4 files changed, 34 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
+index 712cd44f05ace..02f52d4f74df8 100644
+--- a/drivers/usb/host/xhci-hub.c
++++ b/drivers/usb/host/xhci-hub.c
+@@ -1306,7 +1306,33 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
+                                        wIndex, link_state);
+                               goto error;
+                       }
++
++                      if (link_state == USB_SS_PORT_LS_U0) {
++                              if ((temp & PORT_PLS_MASK) == XDEV_U0)
++                                      break;
++
++                              if (!((temp & PORT_PLS_MASK) == XDEV_U1 ||
++                                  (temp & PORT_PLS_MASK) == XDEV_U2 ||
++                                  (temp & PORT_PLS_MASK) == XDEV_U3)) {
++                                      xhci_warn(xhci, "Can only set port %d to U0 from U state\n",
++                                                      wIndex);
++                                      goto error;
++                              }
++                              reinit_completion(&bus_state->u3exit_done[wIndex]);
++                              xhci_set_link_state(xhci, ports[wIndex],
++                                                  USB_SS_PORT_LS_U0);
++                              spin_unlock_irqrestore(&xhci->lock, flags);
++                              if (!wait_for_completion_timeout(&bus_state->u3exit_done[wIndex],
++                                                               msecs_to_jiffies(100)))
++                                      xhci_dbg(xhci, "missing U0 port change event for port %d\n",
++                                               wIndex);
++                              spin_lock_irqsave(&xhci->lock, flags);
++                              temp = readl(ports[wIndex]->addr);
++                              break;
++                      }
++
+                       if (link_state == USB_SS_PORT_LS_U3) {
++                              int retries = 16;
+                               slot_id = xhci_find_slot_id_by_port(hcd, xhci,
+                                               wIndex + 1);
+                               if (slot_id) {
+@@ -1317,26 +1343,18 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
+                                       xhci_stop_device(xhci, slot_id, 1);
+                                       spin_lock_irqsave(&xhci->lock, flags);
+                               }
+-                      }
+-
+-                      xhci_set_link_state(xhci, ports[wIndex], link_state);
+-
+-                      spin_unlock_irqrestore(&xhci->lock, flags);
+-                      if (link_state == USB_SS_PORT_LS_U3) {
+-                              int retries = 16;
+-
++                              xhci_set_link_state(xhci, ports[wIndex], USB_SS_PORT_LS_U3);
++                              spin_unlock_irqrestore(&xhci->lock, flags);
+                               while (retries--) {
+                                       usleep_range(4000, 8000);
+                                       temp = readl(ports[wIndex]->addr);
+                                       if ((temp & PORT_PLS_MASK) == XDEV_U3)
+                                               break;
+                               }
+-                      }
+-                      spin_lock_irqsave(&xhci->lock, flags);
+-
+-                      temp = readl(ports[wIndex]->addr);
+-                      if (link_state == USB_SS_PORT_LS_U3)
++                              spin_lock_irqsave(&xhci->lock, flags);
++                              temp = readl(ports[wIndex]->addr);
+                               bus_state->suspended_ports |= 1 << wIndex;
++                      }
+                       break;
+               case USB_PORT_FEAT_POWER:
+                       /*
+diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
+index 884c601bfa15f..9764122c9cdf2 100644
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -2552,6 +2552,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
+               xhci->usb3_rhub.bus_state.resume_done[i] = 0;
+               /* Only the USB 2.0 completions will ever be used. */
+               init_completion(&xhci->usb2_rhub.bus_state.rexit_done[i]);
++              init_completion(&xhci->usb3_rhub.bus_state.u3exit_done[i]);
+       }
+       if (scratchpad_alloc(xhci, flags))
+diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
+index f7a190fb2353d..a952d99f0456b 100644
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -1673,6 +1673,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
+            (portsc & PORT_PLS_MASK) == XDEV_U1 ||
+            (portsc & PORT_PLS_MASK) == XDEV_U2)) {
+               xhci_dbg(xhci, "resume SS port %d finished\n", port_id);
++              complete(&bus_state->u3exit_done[hcd_portnum]);
+               /* We've just brought the device into U0/1/2 through either the
+                * Resume state after a device remote wakeup, or through the
+                * U3Exit state after a host-initiated resume.  If it's a device
+diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
+index 98b98a0cd2a8b..3ad4f80960d08 100644
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -1694,6 +1694,7 @@ struct xhci_bus_state {
+       /* Which ports are waiting on RExit to U0 transition. */
+       unsigned long           rexit_ports;
+       struct completion       rexit_done[USB_MAXCHILDREN];
++      struct completion       u3exit_done[USB_MAXCHILDREN];
+ };
+-- 
+2.20.1
+