--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
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
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+