From: Sasha Levin Date: Sat, 25 Apr 2020 23:30:19 +0000 (-0400) Subject: Fixes for 5.4 X-Git-Tag: v4.19.119~47 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=722a4727342672391f43ec403d4104ae99a6a25e;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.4 Signed-off-by: Sasha Levin --- diff --git a/queue-5.4/alsa-usb-audio-add-pioneer-dj-djm-250mk2-quirk.patch b/queue-5.4/alsa-usb-audio-add-pioneer-dj-djm-250mk2-quirk.patch new file mode 100644 index 00000000000..3bd90d229b0 --- /dev/null +++ b/queue-5.4/alsa-usb-audio-add-pioneer-dj-djm-250mk2-quirk.patch @@ -0,0 +1,80 @@ +From ca7ffe642db7ca2aaeef40b64de39375a1216c7f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://lore.kernel.org/r/20200401095907.3387-1-konference@frantovo.cz +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/usb/quirks-table.h | 42 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 42 insertions(+) + +diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h +index d187aa6d50db0..dcaf9eed9a415 100644 +--- a/sound/usb/quirks-table.h ++++ b/sound/usb/quirks-table.h +@@ -3592,5 +3592,47 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"), + } + } + }, ++{ ++ /* ++ * Pioneer DJ DJM-250MK2 ++ * PCM is 8 channels out @ 48 fixed (endpoints 0x01). ++ * The output from computer to the mixer is usable. ++ * ++ * The input (phono or line to computer) is not working. ++ * It should be at endpoint 0x82 and probably also 8 channels, ++ * but it seems that it works only with Pioneer proprietary software. ++ * Even on officially supported OS, the Audacity was unable to record ++ * and Mixxx to recognize the control vinyls. ++ */ ++ USB_DEVICE_VENDOR_SPEC(0x2b73, 0x0017), ++ .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { ++ .ifnum = QUIRK_ANY_INTERFACE, ++ .type = QUIRK_COMPOSITE, ++ .data = (const struct snd_usb_audio_quirk[]) { ++ { ++ .ifnum = 0, ++ .type = QUIRK_AUDIO_FIXED_ENDPOINT, ++ .data = &(const struct audioformat) { ++ .formats = SNDRV_PCM_FMTBIT_S24_3LE, ++ .channels = 8, // outputs ++ .iface = 0, ++ .altsetting = 1, ++ .altset_idx = 1, ++ .endpoint = 0x01, ++ .ep_attr = USB_ENDPOINT_XFER_ISOC| ++ USB_ENDPOINT_SYNC_ASYNC, ++ .rates = SNDRV_PCM_RATE_48000, ++ .rate_min = 48000, ++ .rate_max = 48000, ++ .nr_rates = 1, ++ .rate_table = (unsigned int[]) { 48000 } ++ } ++ }, ++ { ++ .ifnum = -1 ++ } ++ } ++ } ++}, + + #undef USB_DEVICE_VENDOR_SPEC +-- +2.20.1 + diff --git a/queue-5.4/asoc-intel-atom-take-the-drv-lock-mutex-before-calli.patch b/queue-5.4/asoc-intel-atom-take-the-drv-lock-mutex-before-calli.patch new file mode 100644 index 00000000000..585579429a5 --- /dev/null +++ b/queue-5.4/asoc-intel-atom-take-the-drv-lock-mutex-before-calli.patch @@ -0,0 +1,43 @@ +From 86e7421795030f87d324e3029a463eaf938104c6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Acked-by: Pierre-Louis Bossart +Link: https://lore.kernel.org/r/20200402185359.3424-1-hdegoede@redhat.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/intel/atom/sst-atom-controls.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/sound/soc/intel/atom/sst-atom-controls.c b/sound/soc/intel/atom/sst-atom-controls.c +index f883c9340eeee..df8f7994d3b7a 100644 +--- a/sound/soc/intel/atom/sst-atom-controls.c ++++ b/sound/soc/intel/atom/sst-atom-controls.c +@@ -966,7 +966,9 @@ static int sst_set_be_modules(struct snd_soc_dapm_widget *w, + dev_dbg(c->dev, "Enter: widget=%s\n", w->name); + + if (SND_SOC_DAPM_EVENT_ON(event)) { ++ mutex_lock(&drv->lock); + ret = sst_send_slot_map(drv); ++ mutex_unlock(&drv->lock); + if (ret) + return ret; + ret = sst_send_pipe_module_params(w, k); +-- +2.20.1 + diff --git a/queue-5.4/asoc-intel-bytcr_rt5640-add-quirk-for-mpman-mpwin895.patch b/queue-5.4/asoc-intel-bytcr_rt5640-add-quirk-for-mpman-mpwin895.patch new file mode 100644 index 00000000000..e7115b76015 --- /dev/null +++ b/queue-5.4/asoc-intel-bytcr_rt5640-add-quirk-for-mpman-mpwin895.patch @@ -0,0 +1,49 @@ +From 8602c6b7f2177910da69acd6b2e19d6862a71a0c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 5 Apr 2020 15:37:26 +0200 +Subject: ASoC: Intel: bytcr_rt5640: Add quirk for MPMAN MPWIN895CL tablet + +From: Hans de Goede + +[ 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 +Acked-by: Pierre-Louis Bossart +Link: https://lore.kernel.org/r/20200405133726.24154-1-hdegoede@redhat.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/intel/boards/bytcr_rt5640.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c +index 243f683bc02a7..e62e1d7815aa9 100644 +--- a/sound/soc/intel/boards/bytcr_rt5640.c ++++ b/sound/soc/intel/boards/bytcr_rt5640.c +@@ -591,6 +591,17 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { + BYT_RT5640_SSP0_AIF1 | + BYT_RT5640_MCLK_EN), + }, ++ { ++ /* MPMAN MPWIN895CL */ ++ .matches = { ++ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "MPMAN"), ++ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MPWIN8900CL"), ++ }, ++ .driver_data = (void *)(BYTCR_INPUT_DEFAULTS | ++ BYT_RT5640_MONO_SPEAKER | ++ BYT_RT5640_SSP0_AIF1 | ++ BYT_RT5640_MCLK_EN), ++ }, + { /* MSI S100 tablet */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Micro-Star International Co., Ltd."), +-- +2.20.1 + diff --git a/queue-5.4/asoc-sof-trace-fix-unconditional-free-in-trace-relea.patch b/queue-5.4/asoc-sof-trace-fix-unconditional-free-in-trace-relea.patch new file mode 100644 index 00000000000..d10a7a3e00e --- /dev/null +++ b/queue-5.4/asoc-sof-trace-fix-unconditional-free-in-trace-relea.patch @@ -0,0 +1,43 @@ +From f468cc6740f1bcf75bcff63857d5eda137e2c39c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Jan 2020 15:36:22 -0600 +Subject: ASoC: SOF: trace: fix unconditional free in trace release + +From: Kai Vehmanen + +[ 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 +Signed-off-by: Pierre-Louis Bossart +Link: https://lore.kernel.org/r/20200124213625.30186-5-pierre-louis.bossart@linux.intel.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/sof/trace.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/sof/trace.c b/sound/soc/sof/trace.c +index 4c3cff031fd66..fd6f5913782bf 100644 +--- a/sound/soc/sof/trace.c ++++ b/sound/soc/sof/trace.c +@@ -328,7 +328,10 @@ void snd_sof_free_trace(struct snd_sof_dev *sdev) + { + snd_sof_release_trace(sdev); + +- snd_dma_free_pages(&sdev->dmatb); +- snd_dma_free_pages(&sdev->dmatp); ++ if (sdev->dma_trace_pages) { ++ snd_dma_free_pages(&sdev->dmatb); ++ snd_dma_free_pages(&sdev->dmatp); ++ sdev->dma_trace_pages = 0; ++ } + } + EXPORT_SYMBOL(snd_sof_free_trace); +-- +2.20.1 + diff --git a/queue-5.4/ceph-don-t-skip-updating-wanted-caps-when-cap-is-sta.patch b/queue-5.4/ceph-don-t-skip-updating-wanted-caps-when-cap-is-sta.patch new file mode 100644 index 00000000000..a2a0c7556dc --- /dev/null +++ b/queue-5.4/ceph-don-t-skip-updating-wanted-caps-when-cap-is-sta.patch @@ -0,0 +1,49 @@ +From 39938c6f8793666b6c8619e61f2f70e1b338806c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Mar 2020 19:34:20 +0800 +Subject: ceph: don't skip updating wanted caps when cap is stale + +From: Yan, Zheng + +[ 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" +Reviewed-by: Jeff Layton +Signed-off-by: Ilya Dryomov +Signed-off-by: Sasha Levin +--- + fs/ceph/caps.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c +index f5a38910a82bf..703945cce0e5d 100644 +--- a/fs/ceph/caps.c ++++ b/fs/ceph/caps.c +@@ -1976,8 +1976,12 @@ retry_locked: + } + + /* want more caps from mds? */ +- if (want & ~(cap->mds_wanted | cap->issued)) +- goto ack; ++ if (want & ~cap->mds_wanted) { ++ if (want & ~(cap->mds_wanted | cap->issued)) ++ goto ack; ++ if (!__cap_is_valid(cap)) ++ goto ack; ++ } + + /* things we might delay */ + if ((cap->issued & ~retain) == 0) +-- +2.20.1 + diff --git a/queue-5.4/ceph-return-ceph_mdsc_do_request-errors-from-__get_p.patch b/queue-5.4/ceph-return-ceph_mdsc_do_request-errors-from-__get_p.patch new file mode 100644 index 00000000000..4343762a033 --- /dev/null +++ b/queue-5.4/ceph-return-ceph_mdsc_do_request-errors-from-__get_p.patch @@ -0,0 +1,40 @@ +From 6111786969995cf1c1c8ae30d67e16282f3bbb8f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Mar 2020 09:34:20 +0800 +Subject: ceph: return ceph_mdsc_do_request() errors from __get_parent() + +From: Qiujun Huang + +[ 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 +Reviewed-by: Jeff Layton +Signed-off-by: Ilya Dryomov +Signed-off-by: Sasha Levin +--- + fs/ceph/export.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/fs/ceph/export.c b/fs/ceph/export.c +index b6bfa94332c30..79dc06881e78e 100644 +--- a/fs/ceph/export.c ++++ b/fs/ceph/export.c +@@ -315,6 +315,11 @@ static struct dentry *__get_parent(struct super_block *sb, + + req->r_num_caps = 1; + err = ceph_mdsc_do_request(mdsc, NULL, req); ++ if (err) { ++ ceph_mdsc_put_request(req); ++ return ERR_PTR(err); ++ } ++ + inode = req->r_target_inode; + if (inode) + ihold(inode); +-- +2.20.1 + diff --git a/queue-5.4/dma-direct-fix-data-truncation-in-dma_direct_get_req.patch b/queue-5.4/dma-direct-fix-data-truncation-in-dma_direct_get_req.patch new file mode 100644 index 00000000000..96bf49aca3a --- /dev/null +++ b/queue-5.4/dma-direct-fix-data-truncation-in-dma_direct_get_req.patch @@ -0,0 +1,41 @@ +From 5b36b997163cc9457692fd60de0cca48e5b85f6e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Christoph Hellwig +Signed-off-by: Sasha Levin +--- + kernel/dma/direct.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c +index 867fd72cb2605..0a093a675b632 100644 +--- a/kernel/dma/direct.c ++++ b/kernel/dma/direct.c +@@ -45,7 +45,8 @@ static inline dma_addr_t phys_to_dma_direct(struct device *dev, + + u64 dma_direct_get_required_mask(struct device *dev) + { +- u64 max_dma = phys_to_dma_direct(dev, (max_pfn - 1) << PAGE_SHIFT); ++ phys_addr_t phys = (phys_addr_t)(max_pfn - 1) << PAGE_SHIFT; ++ u64 max_dma = phys_to_dma_direct(dev, phys); + + return (1ULL << (fls64(max_dma) - 1)) * 2 - 1; + } +-- +2.20.1 + diff --git a/queue-5.4/drm-amd-display-calculate-scaling-ratios-on-every-me.patch b/queue-5.4/drm-amd-display-calculate-scaling-ratios-on-every-me.patch new file mode 100644 index 00000000000..f6128b4b541 --- /dev/null +++ b/queue-5.4/drm-amd-display-calculate-scaling-ratios-on-every-me.patch @@ -0,0 +1,69 @@ +From 22afe4ffeae7e3494ba426b9d6415e8a088efba6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 5 Apr 2020 16:40:57 -0400 +Subject: drm/amd/display: Calculate scaling ratios on every medium/full update + +From: Nicholas Kazlauskas + +[ 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 +Reviewed-by: Aric Cyr +Acked-by: Rodrigo Siqueira +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/core/dc.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c +index 89bd0ba3db1df..71c574d1e8be2 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c +@@ -2154,7 +2154,7 @@ void dc_commit_updates_for_stream(struct dc *dc, + enum surface_update_type update_type; + struct dc_state *context; + struct dc_context *dc_ctx = dc->ctx; +- int i; ++ int i, j; + + stream_status = dc_stream_get_status(stream); + context = dc->current_state; +@@ -2192,6 +2192,17 @@ void dc_commit_updates_for_stream(struct dc *dc, + + copy_surface_update_to_plane(surface, &srf_updates[i]); + ++ if (update_type >= UPDATE_TYPE_MED) { ++ for (j = 0; j < dc->res_pool->pipe_count; j++) { ++ struct pipe_ctx *pipe_ctx = ++ &context->res_ctx.pipe_ctx[j]; ++ ++ if (pipe_ctx->plane_state != surface) ++ continue; ++ ++ resource_build_scaling_params(pipe_ctx); ++ } ++ } + } + + copy_stream_update_to_stream(dc, context, stream, stream_update); +-- +2.20.1 + diff --git a/queue-5.4/drm-amd-display-not-doing-optimize-bandwidth-if-flip.patch b/queue-5.4/drm-amd-display-not-doing-optimize-bandwidth-if-flip.patch new file mode 100644 index 00000000000..ed7d4846bca --- /dev/null +++ b/queue-5.4/drm-amd-display-not-doing-optimize-bandwidth-if-flip.patch @@ -0,0 +1,73 @@ +From 3aa67c551413349265c8054bd927e9c8688bb5ac Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Mar 2020 17:13:02 -0400 +Subject: drm/amd/display: Not doing optimize bandwidth if flip pending. + +From: Yongqiang Sun + +[ 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 +Reviewed-by: Tony Cheng +Acked-by: Rodrigo Siqueira +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/core/dc.c | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c +index 71c574d1e8be2..2028dc017f7a0 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c +@@ -1182,6 +1182,26 @@ bool dc_commit_state(struct dc *dc, struct dc_state *context) + return (result == DC_OK); + } + ++static bool is_flip_pending_in_pipes(struct dc *dc, struct dc_state *context) ++{ ++ int i; ++ struct pipe_ctx *pipe; ++ ++ for (i = 0; i < MAX_PIPES; i++) { ++ pipe = &context->res_ctx.pipe_ctx[i]; ++ ++ if (!pipe->plane_state) ++ continue; ++ ++ /* Must set to false to start with, due to OR in update function */ ++ pipe->plane_state->status.is_flip_pending = false; ++ dc->hwss.update_pending_status(pipe); ++ if (pipe->plane_state->status.is_flip_pending) ++ return true; ++ } ++ return false; ++} ++ + bool dc_post_update_surfaces_to_stream(struct dc *dc) + { + int i; +@@ -1192,6 +1212,9 @@ bool dc_post_update_surfaces_to_stream(struct dc *dc) + + post_surface_trace(dc); + ++ if (is_flip_pending_in_pipes(dc, context)) ++ return true; ++ + for (i = 0; i < dc->res_pool->pipe_count; i++) + if (context->res_ctx.pipe_ctx[i].stream == NULL || + context->res_ctx.pipe_ctx[i].plane_state == NULL) { +-- +2.20.1 + diff --git a/queue-5.4/drm-amd-display-update-stream-adjust-in-dc_stream_ad.patch b/queue-5.4/drm-amd-display-update-stream-adjust-in-dc_stream_ad.patch new file mode 100644 index 00000000000..7c95d1b3906 --- /dev/null +++ b/queue-5.4/drm-amd-display-update-stream-adjust-in-dc_stream_ad.patch @@ -0,0 +1,43 @@ +From 103701480ed34bff87c2ad640e39ed465b8f1e2c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Alvin Lee +Acked-by: Rodrigo Siqueira +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/core/dc.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c +index 4704aac336c29..89bd0ba3db1df 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c +@@ -283,6 +283,8 @@ bool dc_stream_adjust_vmin_vmax(struct dc *dc, + int i = 0; + bool ret = false; + ++ stream->adjust = *adjust; ++ + for (i = 0; i < MAX_PIPES; i++) { + struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i]; + +-- +2.20.1 + diff --git a/queue-5.4/ipc-util.c-sysvipc_find_ipc-should-increase-position.patch b/queue-5.4/ipc-util.c-sysvipc_find_ipc-should-increase-position.patch new file mode 100644 index 00000000000..74e1f7a0f05 --- /dev/null +++ b/queue-5.4/ipc-util.c-sysvipc_find_ipc-should-increase-position.patch @@ -0,0 +1,52 @@ +From f5d106221d9907e66a728a0780472b554b0060c5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Apr 2020 14:34:13 -0700 +Subject: ipc/util.c: sysvipc_find_ipc() should increase position index + +From: Vasily Averin + +[ 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 +Signed-off-by: Andrew Morton +Acked-by: Waiman Long +Cc: Davidlohr Bueso +Cc: Manfred Spraul +Cc: Al Viro +Cc: Ingo Molnar +Cc: NeilBrown +Cc: Peter Oberparleiter +Cc: Steven Rostedt +Link: http://lkml.kernel.org/r/b7a20945-e315-8bb0-21e6-3875c14a8494@virtuozzo.com +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +--- + ipc/util.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ipc/util.c b/ipc/util.c +index d126d156efc64..594871610d454 100644 +--- a/ipc/util.c ++++ b/ipc/util.c +@@ -764,13 +764,13 @@ static struct kern_ipc_perm *sysvipc_find_ipc(struct ipc_ids *ids, loff_t pos, + total++; + } + ++ *new_pos = pos + 1; + if (total >= ids->in_use) + return NULL; + + for (; pos < ipc_mni; pos++) { + ipc = idr_find(&ids->ipcs_idr, pos); + if (ipc != NULL) { +- *new_pos = pos + 1; + rcu_read_lock(); + ipc_lock_object(ipc); + return ipc; +-- +2.20.1 + diff --git a/queue-5.4/kconfig-qconf-fix-a-few-alignment-issues.patch b/queue-5.4/kconfig-qconf-fix-a-few-alignment-issues.patch new file mode 100644 index 00000000000..087b3b78aef --- /dev/null +++ b/queue-5.4/kconfig-qconf-fix-a-few-alignment-issues.patch @@ -0,0 +1,59 @@ +From a4c558fc705c2703766a752905bf04c65f134442 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Apr 2020 11:28:03 +0200 +Subject: kconfig: qconf: Fix a few alignment issues + +From: Mauro Carvalho Chehab + +[ Upstream commit 60969f02f07ae1445730c7b293c421d179da729c ] + +There are a few items with wrong alignments. Solve them. + +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Masahiro Yamada +Signed-off-by: Sasha Levin +--- + scripts/kconfig/qconf.cc | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc +index 82773cc35d356..0f8c77f847114 100644 +--- a/scripts/kconfig/qconf.cc ++++ b/scripts/kconfig/qconf.cc +@@ -627,7 +627,7 @@ void ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu) + last = item; + continue; + } +- hide: ++hide: + if (item && item->menu == child) { + last = parent->firstChild(); + if (last == item) +@@ -692,7 +692,7 @@ void ConfigList::updateMenuList(ConfigList *parent, struct menu* menu) + last = item; + continue; + } +- hide: ++hide: + if (item && item->menu == child) { + last = (ConfigItem*)parent->topLevelItem(0); + if (last == item) +@@ -1225,10 +1225,11 @@ QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos) + { + QMenu* popup = Parent::createStandardContextMenu(pos); + QAction* action = new QAction("Show Debug Info", popup); +- action->setCheckable(true); +- connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool))); +- connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool))); +- action->setChecked(showDebug()); ++ ++ action->setCheckable(true); ++ connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool))); ++ connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool))); ++ action->setChecked(showDebug()); + popup->addSeparator(); + popup->addAction(action); + return popup; +-- +2.20.1 + diff --git a/queue-5.4/kernel-gcov-fs.c-gcov_seq_next-should-increase-posit.patch b/queue-5.4/kernel-gcov-fs.c-gcov_seq_next-should-increase-posit.patch new file mode 100644 index 00000000000..ff6feb4fae8 --- /dev/null +++ b/queue-5.4/kernel-gcov-fs.c-gcov_seq_next-should-increase-posit.patch @@ -0,0 +1,48 @@ +From a50078f82674c4c3461268ef119ad0e6b7d81f3c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Apr 2020 14:34:10 -0700 +Subject: kernel/gcov/fs.c: gcov_seq_next() should increase position index + +From: Vasily Averin + +[ 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 +Signed-off-by: Andrew Morton +Acked-by: Peter Oberparleiter +Cc: Al Viro +Cc: Davidlohr Bueso +Cc: Ingo Molnar +Cc: Manfred Spraul +Cc: NeilBrown +Cc: Steven Rostedt +Cc: Waiman Long +Link: http://lkml.kernel.org/r/f65c6ee7-bd00-f910-2f8a-37cc67e4ff88@virtuozzo.com +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +--- + kernel/gcov/fs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/gcov/fs.c b/kernel/gcov/fs.c +index e5eb5ea7ea598..cc4ee482d3fba 100644 +--- a/kernel/gcov/fs.c ++++ b/kernel/gcov/fs.c +@@ -108,9 +108,9 @@ static void *gcov_seq_next(struct seq_file *seq, void *data, loff_t *pos) + { + struct gcov_iterator *iter = data; + ++ (*pos)++; + if (gcov_iter_next(iter)) + return NULL; +- (*pos)++; + + return iter; + } +-- +2.20.1 + diff --git a/queue-5.4/lib-raid6-test-fix-build-on-distros-whose-bin-sh-is-.patch b/queue-5.4/lib-raid6-test-fix-build-on-distros-whose-bin-sh-is-.patch new file mode 100644 index 00000000000..2628c96d984 --- /dev/null +++ b/queue-5.4/lib-raid6-test-fix-build-on-distros-whose-bin-sh-is-.patch @@ -0,0 +1,69 @@ +From ef619d689969b09966e7529fb735043cab7e26e9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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= 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 +Acked-by: H. Peter Anvin (Intel) +Reviewed-by: Jason A. Donenfeld +Acked-by: Ingo Molnar +Reviewed-by: Nick Desaulniers +Signed-off-by: Sasha Levin +--- + lib/raid6/test/Makefile | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/lib/raid6/test/Makefile b/lib/raid6/test/Makefile +index 3ab8720aa2f84..b9e6c3648be1a 100644 +--- a/lib/raid6/test/Makefile ++++ b/lib/raid6/test/Makefile +@@ -35,13 +35,13 @@ endif + ifeq ($(IS_X86),yes) + OBJS += mmx.o sse1.o sse2.o avx2.o recov_ssse3.o recov_avx2.o avx512.o recov_avx512.o + CFLAGS += $(shell echo "pshufb %xmm0, %xmm0" | \ +- gcc -c -x assembler - >&/dev/null && \ ++ gcc -c -x assembler - >/dev/null 2>&1 && \ + rm ./-.o && echo -DCONFIG_AS_SSSE3=1) + CFLAGS += $(shell echo "vpbroadcastb %xmm0, %ymm1" | \ +- gcc -c -x assembler - >&/dev/null && \ ++ gcc -c -x assembler - >/dev/null 2>&1 && \ + rm ./-.o && echo -DCONFIG_AS_AVX2=1) + CFLAGS += $(shell echo "vpmovm2b %k1, %zmm5" | \ +- gcc -c -x assembler - >&/dev/null && \ ++ gcc -c -x assembler - >/dev/null 2>&1 && \ + rm ./-.o && echo -DCONFIG_AS_AVX512=1) + else ifeq ($(HAS_NEON),yes) + OBJS += neon.o neon1.o neon2.o neon4.o neon8.o recov_neon.o recov_neon_inner.o +-- +2.20.1 + diff --git a/queue-5.4/libbpf-fix-readelf-output-parsing-on-powerpc-with-re.patch b/queue-5.4/libbpf-fix-readelf-output-parsing-on-powerpc-with-re.patch new file mode 100644 index 00000000000..786f3e07b98 --- /dev/null +++ b/queue-5.4/libbpf-fix-readelf-output-parsing-on-powerpc-with-re.patch @@ -0,0 +1,54 @@ +From f70c936fb05d5b1fa674420a4d4b87b8e753d8dd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 1 Dec 2019 20:57:28 +0100 +Subject: libbpf: Fix readelf output parsing on powerpc with recent binutils + +From: Aurelien Jarno + +[ 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 [: 8] 1 btf_is_struct + +The extra "[: 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 +Signed-off-by: Daniel Borkmann +Tested-by: Michael Ellerman +Link: https://lore.kernel.org/bpf/20191201195728.4161537-1-aurelien@aurel32.net +Signed-off-by: Sasha Levin +--- + tools/lib/bpf/Makefile | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile +index 33e2638ef7f0d..122321d549227 100644 +--- a/tools/lib/bpf/Makefile ++++ b/tools/lib/bpf/Makefile +@@ -145,7 +145,7 @@ PC_FILE := $(addprefix $(OUTPUT),$(PC_FILE)) + + GLOBAL_SYM_COUNT = $(shell readelf -s --wide $(BPF_IN_SHARED) | \ + cut -d "@" -f1 | sed 's/_v[0-9]_[0-9]_[0-9].*//' | \ +- awk '/GLOBAL/ && /DEFAULT/ && !/UND/ {print $$8}' | \ ++ awk '/GLOBAL/ && /DEFAULT/ && !/UND/ {print $$NF}' | \ + sort -u | wc -l) + VERSIONED_SYM_COUNT = $(shell readelf -s --wide $(OUTPUT)libbpf.so | \ + grep -Eo '[^ ]+@LIBBPF_' | cut -d@ -f1 | sort -u | wc -l) +@@ -217,7 +217,7 @@ check_abi: $(OUTPUT)libbpf.so + "versioned in $(VERSION_SCRIPT)." >&2; \ + readelf -s --wide $(BPF_IN_SHARED) | \ + cut -d "@" -f1 | sed 's/_v[0-9]_[0-9]_[0-9].*//' | \ +- awk '/GLOBAL/ && /DEFAULT/ && !/UND/ {print $$8}'| \ ++ awk '/GLOBAL/ && /DEFAULT/ && !/UND/ {print $$NF}'| \ + sort -u > $(OUTPUT)libbpf_global_syms.tmp; \ + readelf -s --wide $(OUTPUT)libbpf.so | \ + grep -Eo '[^ ]+@LIBBPF_' | cut -d@ -f1 | \ +-- +2.20.1 + diff --git a/queue-5.4/loop-better-discard-support-for-block-devices.patch b/queue-5.4/loop-better-discard-support-for-block-devices.patch new file mode 100644 index 00000000000..9c5a380865e --- /dev/null +++ b/queue-5.4/loop-better-discard-support-for-block-devices.patch @@ -0,0 +1,117 @@ +From 90d4aa83a89e945c554bfff7e05441b8006e8276 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Apr 2020 16:43:04 +0200 +Subject: loop: Better discard support for block devices + +From: Evan Green + +[ 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 +Reviewed-by: Gwendal Grignou +Reviewed-by: Chaitanya Kulkarni +[used updated version of Evan's comment in loop_config_discard()] +[moved backingq to local scope, removed redundant braces] +Signed-off-by: Andrzej Pietrasiewicz +Reviewed-by: Christoph Hellwig +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/block/loop.c | 42 +++++++++++++++++++++++++++++++----------- + 1 file changed, 31 insertions(+), 11 deletions(-) + +diff --git a/drivers/block/loop.c b/drivers/block/loop.c +index ef6e251857c8c..57ed6b70d2950 100644 +--- a/drivers/block/loop.c ++++ b/drivers/block/loop.c +@@ -427,11 +427,12 @@ static int lo_fallocate(struct loop_device *lo, struct request *rq, loff_t pos, + * information. + */ + struct file *file = lo->lo_backing_file; ++ struct request_queue *q = lo->lo_queue; + int ret; + + mode |= FALLOC_FL_KEEP_SIZE; + +- if ((!file->f_op->fallocate) || lo->lo_encrypt_key_size) { ++ if (!blk_queue_discard(q)) { + ret = -EOPNOTSUPP; + goto out; + } +@@ -863,28 +864,47 @@ static void loop_config_discard(struct loop_device *lo) + struct inode *inode = file->f_mapping->host; + struct request_queue *q = lo->lo_queue; + ++ /* ++ * If the backing device is a block device, mirror its zeroing ++ * capability. Set the discard sectors to the block device's zeroing ++ * capabilities because loop discards result in blkdev_issue_zeroout(), ++ * not blkdev_issue_discard(). This maintains consistent behavior with ++ * file-backed loop devices: discarded regions read back as zero. ++ */ ++ if (S_ISBLK(inode->i_mode) && !lo->lo_encrypt_key_size) { ++ struct request_queue *backingq; ++ ++ backingq = bdev_get_queue(inode->i_bdev); ++ blk_queue_max_discard_sectors(q, ++ backingq->limits.max_write_zeroes_sectors); ++ ++ blk_queue_max_write_zeroes_sectors(q, ++ backingq->limits.max_write_zeroes_sectors); ++ + /* + * We use punch hole to reclaim the free space used by the + * image a.k.a. discard. However we do not support discard if + * encryption is enabled, because it may give an attacker + * useful information. + */ +- if ((!file->f_op->fallocate) || +- lo->lo_encrypt_key_size) { ++ } else if (!file->f_op->fallocate || lo->lo_encrypt_key_size) { + q->limits.discard_granularity = 0; + q->limits.discard_alignment = 0; + blk_queue_max_discard_sectors(q, 0); + blk_queue_max_write_zeroes_sectors(q, 0); +- blk_queue_flag_clear(QUEUE_FLAG_DISCARD, q); +- return; +- } + +- q->limits.discard_granularity = inode->i_sb->s_blocksize; +- q->limits.discard_alignment = 0; ++ } else { ++ q->limits.discard_granularity = inode->i_sb->s_blocksize; ++ q->limits.discard_alignment = 0; + +- blk_queue_max_discard_sectors(q, UINT_MAX >> 9); +- blk_queue_max_write_zeroes_sectors(q, UINT_MAX >> 9); +- blk_queue_flag_set(QUEUE_FLAG_DISCARD, q); ++ blk_queue_max_discard_sectors(q, UINT_MAX >> 9); ++ blk_queue_max_write_zeroes_sectors(q, UINT_MAX >> 9); ++ } ++ ++ if (q->limits.max_write_zeroes_sectors) ++ blk_queue_flag_set(QUEUE_FLAG_DISCARD, q); ++ else ++ blk_queue_flag_clear(QUEUE_FLAG_DISCARD, q); + } + + static void loop_unprepare_queue(struct loop_device *lo) +-- +2.20.1 + diff --git a/queue-5.4/nvme-fix-compat-address-handling-in-several-ioctls.patch b/queue-5.4/nvme-fix-compat-address-handling-in-several-ioctls.patch new file mode 100644 index 00000000000..7528e053616 --- /dev/null +++ b/queue-5.4/nvme-fix-compat-address-handling-in-several-ioctls.patch @@ -0,0 +1,116 @@ +From 9e286069af17b94f806eb01e85396ea6ee4763f9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 28 Mar 2020 01:09:09 -0400 +Subject: nvme: fix compat address handling in several ioctls + +From: Nick Bowler + +[ 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 +Signed-off-by: Christoph Hellwig +Signed-off-by: Sasha Levin +--- + 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 + #include ++#include + #include + #include + #include +@@ -1244,6 +1245,18 @@ static void nvme_enable_aen(struct nvme_ctrl *ctrl) + queue_work(nvme_wq, &ctrl->async_event_work); + } + ++/* ++ * Convert integer values from ioctl structures to user pointers, silently ++ * ignoring the upper bits in the compat case to match behaviour of 32-bit ++ * kernels. ++ */ ++static void __user *nvme_to_user_ptr(uintptr_t ptrval) ++{ ++ if (in_compat_syscall()) ++ ptrval = (compat_uptr_t)ptrval; ++ return (void __user *)ptrval; ++} ++ + static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio) + { + struct nvme_user_io io; +@@ -1267,7 +1280,7 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio) + + length = (io.nblocks + 1) << ns->lba_shift; + meta_len = (io.nblocks + 1) * ns->ms; +- metadata = (void __user *)(uintptr_t)io.metadata; ++ metadata = nvme_to_user_ptr(io.metadata); + + if (ns->ext) { + length += meta_len; +@@ -1290,7 +1303,7 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio) + c.rw.appmask = cpu_to_le16(io.appmask); + + return nvme_submit_user_cmd(ns->queue, &c, +- (void __user *)(uintptr_t)io.addr, length, ++ nvme_to_user_ptr(io.addr), length, + metadata, meta_len, lower_32_bits(io.slba), NULL, 0); + } + +@@ -1410,9 +1423,9 @@ static int nvme_user_cmd(struct nvme_ctrl *ctrl, struct nvme_ns *ns, + + effects = nvme_passthru_start(ctrl, ns, cmd.opcode); + status = nvme_submit_user_cmd(ns ? ns->queue : ctrl->admin_q, &c, +- (void __user *)(uintptr_t)cmd.addr, cmd.data_len, +- (void __user *)(uintptr_t)cmd.metadata, +- cmd.metadata_len, 0, &result, timeout); ++ nvme_to_user_ptr(cmd.addr), cmd.data_len, ++ nvme_to_user_ptr(cmd.metadata), cmd.metadata_len, ++ 0, &result, timeout); + nvme_passthru_end(ctrl, effects); + + if (status >= 0) { +@@ -1457,8 +1470,8 @@ static int nvme_user_cmd64(struct nvme_ctrl *ctrl, struct nvme_ns *ns, + + effects = nvme_passthru_start(ctrl, ns, cmd.opcode); + status = nvme_submit_user_cmd(ns ? ns->queue : ctrl->admin_q, &c, +- (void __user *)(uintptr_t)cmd.addr, cmd.data_len, +- (void __user *)(uintptr_t)cmd.metadata, cmd.metadata_len, ++ nvme_to_user_ptr(cmd.addr), cmd.data_len, ++ nvme_to_user_ptr(cmd.metadata), cmd.metadata_len, + 0, &cmd.result, timeout); + nvme_passthru_end(ctrl, effects); + +-- +2.20.1 + diff --git a/queue-5.4/nvme-fix-deadlock-caused-by-ana-update-wrong-locking.patch b/queue-5.4/nvme-fix-deadlock-caused-by-ana-update-wrong-locking.patch new file mode 100644 index 00000000000..4e746c62d52 --- /dev/null +++ b/queue-5.4/nvme-fix-deadlock-caused-by-ana-update-wrong-locking.patch @@ -0,0 +1,72 @@ +From f357ec28e1a5314004b2ca0e474a50b304c14fad Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Apr 2020 09:34:54 -0700 +Subject: nvme: fix deadlock caused by ANA update wrong locking + +From: Sagi Grimberg + +[ 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 +Reviewed-by: Keith Busch +Reviewed-by: Hannes Reinecke +Signed-off-by: Christoph Hellwig +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/multipath.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c +index aed6354cb2717..56caddeabb5e5 100644 +--- a/drivers/nvme/host/multipath.c ++++ b/drivers/nvme/host/multipath.c +@@ -510,7 +510,7 @@ static int nvme_update_ana_state(struct nvme_ctrl *ctrl, + if (!nr_nsids) + return 0; + +- down_write(&ctrl->namespaces_rwsem); ++ down_read(&ctrl->namespaces_rwsem); + list_for_each_entry(ns, &ctrl->namespaces, list) { + unsigned nsid = le32_to_cpu(desc->nsids[n]); + +@@ -521,7 +521,7 @@ static int nvme_update_ana_state(struct nvme_ctrl *ctrl, + if (++n == nr_nsids) + break; + } +- up_write(&ctrl->namespaces_rwsem); ++ up_read(&ctrl->namespaces_rwsem); + return 0; + } + +-- +2.20.1 + diff --git a/queue-5.4/nvme-tcp-fix-possible-crash-in-write_zeroes-processi.patch b/queue-5.4/nvme-tcp-fix-possible-crash-in-write_zeroes-processi.patch new file mode 100644 index 00000000000..ec4bf4be5dd --- /dev/null +++ b/queue-5.4/nvme-tcp-fix-possible-crash-in-write_zeroes-processi.patch @@ -0,0 +1,73 @@ +From 9c5f0da52a2097b40d02abf5ad94e7037da50d27 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 Mar 2020 15:06:30 -0700 +Subject: nvme-tcp: fix possible crash in write_zeroes processing + +From: Sagi Grimberg + +[ 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 +Suggested-by: Chaitanya Kulkarni +Signed-off-by: Sagi Grimberg +Signed-off-by: Keith Busch +Signed-off-by: Christoph Hellwig +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/tcp.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c +index 244984420b41b..11e84ed4de361 100644 +--- a/drivers/nvme/host/tcp.c ++++ b/drivers/nvme/host/tcp.c +@@ -164,16 +164,14 @@ static inline bool nvme_tcp_async_req(struct nvme_tcp_request *req) + static inline bool nvme_tcp_has_inline_data(struct nvme_tcp_request *req) + { + struct request *rq; +- unsigned int bytes; + + if (unlikely(nvme_tcp_async_req(req))) + return false; /* async events don't have a request */ + + rq = blk_mq_rq_from_pdu(req); +- bytes = blk_rq_payload_bytes(rq); + +- return rq_data_dir(rq) == WRITE && bytes && +- bytes <= nvme_tcp_inline_data_size(req->queue); ++ return rq_data_dir(rq) == WRITE && req->data_len && ++ req->data_len <= nvme_tcp_inline_data_size(req->queue); + } + + static inline struct page *nvme_tcp_req_cur_page(struct nvme_tcp_request *req) +@@ -2090,7 +2088,9 @@ static blk_status_t nvme_tcp_map_data(struct nvme_tcp_queue *queue, + + c->common.flags |= NVME_CMD_SGL_METABUF; + +- if (rq_data_dir(rq) == WRITE && req->data_len && ++ if (!blk_rq_nr_phys_segments(rq)) ++ nvme_tcp_set_sg_null(c); ++ else if (rq_data_dir(rq) == WRITE && + req->data_len <= nvme_tcp_inline_data_size(queue)) + nvme_tcp_set_sg_inline(queue, c, req->data_len); + else +@@ -2117,7 +2117,8 @@ static blk_status_t nvme_tcp_setup_cmd_pdu(struct nvme_ns *ns, + req->data_sent = 0; + req->pdu_len = 0; + req->pdu_sent = 0; +- req->data_len = blk_rq_payload_bytes(rq); ++ req->data_len = blk_rq_nr_phys_segments(rq) ? ++ blk_rq_payload_bytes(rq) : 0; + req->curr_bio = rq->bio; + + if (rq_data_dir(rq) == WRITE && +-- +2.20.1 + diff --git a/queue-5.4/pci-aspm-allow-re-enabling-clock-pm.patch b/queue-5.4/pci-aspm-allow-re-enabling-clock-pm.patch new file mode 100644 index 00000000000..fd325c7f6d7 --- /dev/null +++ b/queue-5.4/pci-aspm-allow-re-enabling-clock-pm.patch @@ -0,0 +1,74 @@ +From 534051578b67ac32772566998c31f592af3eac1b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 5 Oct 2019 14:03:57 +0200 +Subject: PCI/ASPM: Allow re-enabling Clock PM + +From: Heiner Kallweit + +[ 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 +Signed-off-by: Bjorn Helgaas +Signed-off-by: Sasha Levin +--- + drivers/pci/pcie/aspm.c | 18 +++++++++++------- + 1 file changed, 11 insertions(+), 7 deletions(-) + +diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c +index 32c34330e5a67..5a1bbf2cb7e98 100644 +--- a/drivers/pci/pcie/aspm.c ++++ b/drivers/pci/pcie/aspm.c +@@ -64,6 +64,7 @@ struct pcie_link_state { + u32 clkpm_capable:1; /* Clock PM capable? */ + u32 clkpm_enabled:1; /* Current Clock PM state */ + u32 clkpm_default:1; /* Default Clock PM state by BIOS */ ++ u32 clkpm_disable:1; /* Clock PM disabled */ + + /* Exit latencies */ + struct aspm_latency latency_up; /* Upstream direction exit latency */ +@@ -161,8 +162,11 @@ static void pcie_set_clkpm_nocheck(struct pcie_link_state *link, int enable) + + static void pcie_set_clkpm(struct pcie_link_state *link, int enable) + { +- /* Don't enable Clock PM if the link is not Clock PM capable */ +- if (!link->clkpm_capable) ++ /* ++ * Don't enable Clock PM if the link is not Clock PM capable ++ * or Clock PM is disabled ++ */ ++ if (!link->clkpm_capable || link->clkpm_disable) + enable = 0; + /* Need nothing if the specified equals to current state */ + if (link->clkpm_enabled == enable) +@@ -192,7 +196,8 @@ static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist) + } + link->clkpm_enabled = enabled; + link->clkpm_default = enabled; +- link->clkpm_capable = (blacklist) ? 0 : capable; ++ link->clkpm_capable = capable; ++ link->clkpm_disable = blacklist ? 1 : 0; + } + + static bool pcie_retrain_link(struct pcie_link_state *link) +@@ -1097,10 +1102,9 @@ static int __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem) + link->aspm_disable |= ASPM_STATE_L1; + pcie_config_aspm_link(link, policy_to_aspm_state(link)); + +- if (state & PCIE_LINK_STATE_CLKPM) { +- link->clkpm_capable = 0; +- pcie_set_clkpm(link, 0); +- } ++ if (state & PCIE_LINK_STATE_CLKPM) ++ link->clkpm_disable = 1; ++ pcie_set_clkpm(link, policy_to_clkpm_state(link)); + mutex_unlock(&aspm_lock); + if (sem) + up_read(&pci_bus_sem); +-- +2.20.1 + diff --git a/queue-5.4/pci-pciehp-prevent-deadlock-on-disconnect.patch b/queue-5.4/pci-pciehp-prevent-deadlock-on-disconnect.patch new file mode 100644 index 00000000000..b8302fb656e --- /dev/null +++ b/queue-5.4/pci-pciehp-prevent-deadlock-on-disconnect.patch @@ -0,0 +1,277 @@ +From 53b907da74951dd7372033d3217490a0da85ab1b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Oct 2019 20:00:22 +0300 +Subject: PCI: pciehp: Prevent deadlock on disconnect + +From: Mika Westerberg + +[ 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 +Signed-off-by: Mika Westerberg +Signed-off-by: Bjorn Helgaas +Signed-off-by: Sasha Levin +--- + drivers/pci/hotplug/pciehp.h | 6 ++-- + drivers/pci/hotplug/pciehp_core.c | 11 ++++-- + drivers/pci/hotplug/pciehp_ctrl.c | 4 +-- + drivers/pci/hotplug/pciehp_hpc.c | 59 +++++++++++++++++++++++++------ + 4 files changed, 61 insertions(+), 19 deletions(-) + +diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h +index 882ce82c46990..aa61d4c219d7b 100644 +--- a/drivers/pci/hotplug/pciehp.h ++++ b/drivers/pci/hotplug/pciehp.h +@@ -174,10 +174,10 @@ void pciehp_set_indicators(struct controller *ctrl, int pwr, int attn); + + void pciehp_get_latch_status(struct controller *ctrl, u8 *status); + int pciehp_query_power_fault(struct controller *ctrl); +-bool pciehp_card_present(struct controller *ctrl); +-bool pciehp_card_present_or_link_active(struct controller *ctrl); ++int pciehp_card_present(struct controller *ctrl); ++int pciehp_card_present_or_link_active(struct controller *ctrl); + int pciehp_check_link_status(struct controller *ctrl); +-bool pciehp_check_link_active(struct controller *ctrl); ++int pciehp_check_link_active(struct controller *ctrl); + void pciehp_release_ctrl(struct controller *ctrl); + + int pciehp_sysfs_enable_slot(struct hotplug_slot *hotplug_slot); +diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c +index 56daad828c9e0..312cc45c44c78 100644 +--- a/drivers/pci/hotplug/pciehp_core.c ++++ b/drivers/pci/hotplug/pciehp_core.c +@@ -139,10 +139,15 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) + { + struct controller *ctrl = to_ctrl(hotplug_slot); + struct pci_dev *pdev = ctrl->pcie->port; ++ int ret; + + pci_config_pm_runtime_get(pdev); +- *value = pciehp_card_present_or_link_active(ctrl); ++ ret = pciehp_card_present_or_link_active(ctrl); + pci_config_pm_runtime_put(pdev); ++ if (ret < 0) ++ return ret; ++ ++ *value = ret; + return 0; + } + +@@ -158,13 +163,13 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) + */ + static void pciehp_check_presence(struct controller *ctrl) + { +- bool occupied; ++ int occupied; + + down_read(&ctrl->reset_lock); + mutex_lock(&ctrl->state_lock); + + occupied = pciehp_card_present_or_link_active(ctrl); +- if ((occupied && (ctrl->state == OFF_STATE || ++ if ((occupied > 0 && (ctrl->state == OFF_STATE || + ctrl->state == BLINKINGON_STATE)) || + (!occupied && (ctrl->state == ON_STATE || + ctrl->state == BLINKINGOFF_STATE))) +diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c +index dd8e4a5fb2826..6503d15effbbd 100644 +--- a/drivers/pci/hotplug/pciehp_ctrl.c ++++ b/drivers/pci/hotplug/pciehp_ctrl.c +@@ -226,7 +226,7 @@ void pciehp_handle_disable_request(struct controller *ctrl) + + void pciehp_handle_presence_or_link_change(struct controller *ctrl, u32 events) + { +- bool present, link_active; ++ int present, link_active; + + /* + * If the slot is on and presence or link has changed, turn it off. +@@ -257,7 +257,7 @@ void pciehp_handle_presence_or_link_change(struct controller *ctrl, u32 events) + mutex_lock(&ctrl->state_lock); + present = pciehp_card_present(ctrl); + link_active = pciehp_check_link_active(ctrl); +- if (!present && !link_active) { ++ if (present <= 0 && link_active <= 0) { + mutex_unlock(&ctrl->state_lock); + return; + } +diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c +index d74a71712cde4..356786a3b7f4b 100644 +--- a/drivers/pci/hotplug/pciehp_hpc.c ++++ b/drivers/pci/hotplug/pciehp_hpc.c +@@ -201,17 +201,29 @@ static void pcie_write_cmd_nowait(struct controller *ctrl, u16 cmd, u16 mask) + pcie_do_write_cmd(ctrl, cmd, mask, false); + } + +-bool pciehp_check_link_active(struct controller *ctrl) ++/** ++ * pciehp_check_link_active() - Is the link active ++ * @ctrl: PCIe hotplug controller ++ * ++ * Check whether the downstream link is currently active. Note it is ++ * possible that the card is removed immediately after this so the ++ * caller may need to take it into account. ++ * ++ * If the hotplug controller itself is not available anymore returns ++ * %-ENODEV. ++ */ ++int pciehp_check_link_active(struct controller *ctrl) + { + struct pci_dev *pdev = ctrl_dev(ctrl); + u16 lnk_status; +- bool ret; ++ int ret; + +- pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lnk_status); +- ret = !!(lnk_status & PCI_EXP_LNKSTA_DLLLA); ++ ret = pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lnk_status); ++ if (ret == PCIBIOS_DEVICE_NOT_FOUND || lnk_status == (u16)~0) ++ return -ENODEV; + +- if (ret) +- ctrl_dbg(ctrl, "%s: lnk_status = %x\n", __func__, lnk_status); ++ ret = !!(lnk_status & PCI_EXP_LNKSTA_DLLLA); ++ ctrl_dbg(ctrl, "%s: lnk_status = %x\n", __func__, lnk_status); + + return ret; + } +@@ -373,13 +385,29 @@ void pciehp_get_latch_status(struct controller *ctrl, u8 *status) + *status = !!(slot_status & PCI_EXP_SLTSTA_MRLSS); + } + +-bool pciehp_card_present(struct controller *ctrl) ++/** ++ * pciehp_card_present() - Is the card present ++ * @ctrl: PCIe hotplug controller ++ * ++ * Function checks whether the card is currently present in the slot and ++ * in that case returns true. Note it is possible that the card is ++ * removed immediately after the check so the caller may need to take ++ * this into account. ++ * ++ * It the hotplug controller itself is not available anymore returns ++ * %-ENODEV. ++ */ ++int pciehp_card_present(struct controller *ctrl) + { + struct pci_dev *pdev = ctrl_dev(ctrl); + u16 slot_status; ++ int ret; + +- pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status); +- return slot_status & PCI_EXP_SLTSTA_PDS; ++ ret = pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status); ++ if (ret == PCIBIOS_DEVICE_NOT_FOUND || slot_status == (u16)~0) ++ return -ENODEV; ++ ++ return !!(slot_status & PCI_EXP_SLTSTA_PDS); + } + + /** +@@ -390,10 +418,19 @@ bool pciehp_card_present(struct controller *ctrl) + * Presence Detect State bit, this helper also returns true if the Link Active + * bit is set. This is a concession to broken hotplug ports which hardwire + * Presence Detect State to zero, such as Wilocity's [1ae9:0200]. ++ * ++ * Returns: %1 if the slot is occupied and %0 if it is not. If the hotplug ++ * port is not present anymore returns %-ENODEV. + */ +-bool pciehp_card_present_or_link_active(struct controller *ctrl) ++int pciehp_card_present_or_link_active(struct controller *ctrl) + { +- return pciehp_card_present(ctrl) || pciehp_check_link_active(ctrl); ++ int ret; ++ ++ ret = pciehp_card_present(ctrl); ++ if (ret) ++ return ret; ++ ++ return pciehp_check_link_active(ctrl); + } + + int pciehp_query_power_fault(struct controller *ctrl) +-- +2.20.1 + diff --git a/queue-5.4/pci-pm-add-missing-link-delays-required-by-the-pcie-.patch b/queue-5.4/pci-pm-add-missing-link-delays-required-by-the-pcie-.patch new file mode 100644 index 00000000000..08a15c41a5c --- /dev/null +++ b/queue-5.4/pci-pm-add-missing-link-delays-required-by-the-pcie-.patch @@ -0,0 +1,332 @@ +From 2d4903a6784d8465fc4b8e21d59bc4d05827c163 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 Nov 2019 16:51:50 +0800 +Subject: PCI/PM: Add missing link delays required by the PCIe spec + +From: Mika Westerberg + +[ 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 +Tested-by: Kai-Heng Feng +Signed-off-by: Mika Westerberg +Signed-off-by: Bjorn Helgaas +Signed-off-by: Sasha Levin +--- + drivers/pci/pci-driver.c | 11 +++- + drivers/pci/pci.c | 121 ++++++++++++++++++++++++++++++++++++++- + drivers/pci/pci.h | 1 + + 3 files changed, 130 insertions(+), 3 deletions(-) + +diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c +index 0c3086793e4ec..5ea612a15550e 100644 +--- a/drivers/pci/pci-driver.c ++++ b/drivers/pci/pci-driver.c +@@ -919,6 +919,8 @@ static int pci_pm_resume_noirq(struct device *dev) + struct pci_dev *pci_dev = to_pci_dev(dev); + struct device_driver *drv = dev->driver; + int error = 0; ++ pci_power_t prev_state = pci_dev->current_state; ++ bool skip_bus_pm = pci_dev->skip_bus_pm; + + if (dev_pm_may_skip_resume(dev)) + return 0; +@@ -937,12 +939,15 @@ static int pci_pm_resume_noirq(struct device *dev) + * configuration here and attempting to put them into D0 again is + * pointless, so avoid doing that. + */ +- if (!(pci_dev->skip_bus_pm && pm_suspend_no_platform())) ++ if (!(skip_bus_pm && pm_suspend_no_platform())) + pci_pm_default_resume_early(pci_dev); + + pci_fixup_device(pci_fixup_resume_early, pci_dev); + pcie_pme_root_status_cleanup(pci_dev); + ++ if (!skip_bus_pm && prev_state == PCI_D3cold) ++ pci_bridge_wait_for_secondary_bus(pci_dev); ++ + if (pci_has_legacy_pm_support(pci_dev)) + return pci_legacy_resume_early(dev); + +@@ -1333,6 +1338,7 @@ static int pci_pm_runtime_resume(struct device *dev) + int rc = 0; + struct pci_dev *pci_dev = to_pci_dev(dev); + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; ++ pci_power_t prev_state = pci_dev->current_state; + + /* + * Restoring config space is necessary even if the device is not bound +@@ -1348,6 +1354,9 @@ static int pci_pm_runtime_resume(struct device *dev) + pci_enable_wake(pci_dev, PCI_D0, false); + pci_fixup_device(pci_fixup_resume, pci_dev); + ++ if (prev_state == PCI_D3cold) ++ pci_bridge_wait_for_secondary_bus(pci_dev); ++ + if (pm && pm->runtime_resume) + rc = pm->runtime_resume(dev); + +diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c +index 94d6e120b4734..779132aef0fb9 100644 +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -1019,8 +1019,6 @@ static void __pci_start_power_transition(struct pci_dev *dev, pci_power_t state) + * because have already delayed for the bridge. + */ + if (dev->runtime_d3cold) { +- if (dev->d3cold_delay && !dev->imm_ready) +- msleep(dev->d3cold_delay); + /* + * When powering on a bridge from D3cold, the + * whole hierarchy may be powered on into +@@ -4671,6 +4669,125 @@ bool pcie_wait_for_link(struct pci_dev *pdev, bool active) + return pcie_wait_for_link_delay(pdev, active, 100); + } + ++/* ++ * Find maximum D3cold delay required by all the devices on the bus. The ++ * spec says 100 ms, but firmware can lower it and we allow drivers to ++ * increase it as well. ++ * ++ * Called with @pci_bus_sem locked for reading. ++ */ ++static int pci_bus_max_d3cold_delay(const struct pci_bus *bus) ++{ ++ const struct pci_dev *pdev; ++ int min_delay = 100; ++ int max_delay = 0; ++ ++ list_for_each_entry(pdev, &bus->devices, bus_list) { ++ if (pdev->d3cold_delay < min_delay) ++ min_delay = pdev->d3cold_delay; ++ if (pdev->d3cold_delay > max_delay) ++ max_delay = pdev->d3cold_delay; ++ } ++ ++ return max(min_delay, max_delay); ++} ++ ++/** ++ * pci_bridge_wait_for_secondary_bus - Wait for secondary bus to be accessible ++ * @dev: PCI bridge ++ * ++ * Handle necessary delays before access to the devices on the secondary ++ * side of the bridge are permitted after D3cold to D0 transition. ++ * ++ * For PCIe this means the delays in PCIe 5.0 section 6.6.1. For ++ * conventional PCI it means Tpvrh + Trhfa specified in PCI 3.0 section ++ * 4.3.2. ++ */ ++void pci_bridge_wait_for_secondary_bus(struct pci_dev *dev) ++{ ++ struct pci_dev *child; ++ int delay; ++ ++ if (pci_dev_is_disconnected(dev)) ++ return; ++ ++ if (!pci_is_bridge(dev) || !dev->bridge_d3) ++ return; ++ ++ down_read(&pci_bus_sem); ++ ++ /* ++ * We only deal with devices that are present currently on the bus. ++ * For any hot-added devices the access delay is handled in pciehp ++ * board_added(). In case of ACPI hotplug the firmware is expected ++ * to configure the devices before OS is notified. ++ */ ++ if (!dev->subordinate || list_empty(&dev->subordinate->devices)) { ++ up_read(&pci_bus_sem); ++ return; ++ } ++ ++ /* Take d3cold_delay requirements into account */ ++ delay = pci_bus_max_d3cold_delay(dev->subordinate); ++ if (!delay) { ++ up_read(&pci_bus_sem); ++ return; ++ } ++ ++ child = list_first_entry(&dev->subordinate->devices, struct pci_dev, ++ bus_list); ++ up_read(&pci_bus_sem); ++ ++ /* ++ * Conventional PCI and PCI-X we need to wait Tpvrh + Trhfa before ++ * accessing the device after reset (that is 1000 ms + 100 ms). In ++ * practice this should not be needed because we don't do power ++ * management for them (see pci_bridge_d3_possible()). ++ */ ++ if (!pci_is_pcie(dev)) { ++ pci_dbg(dev, "waiting %d ms for secondary bus\n", 1000 + delay); ++ msleep(1000 + delay); ++ return; ++ } ++ ++ /* ++ * For PCIe downstream and root ports that do not support speeds ++ * greater than 5 GT/s need to wait minimum 100 ms. For higher ++ * speeds (gen3) we need to wait first for the data link layer to ++ * become active. ++ * ++ * However, 100 ms is the minimum and the PCIe spec says the ++ * software must allow at least 1s before it can determine that the ++ * device that did not respond is a broken device. There is ++ * evidence that 100 ms is not always enough, for example certain ++ * Titan Ridge xHCI controller does not always respond to ++ * configuration requests if we only wait for 100 ms (see ++ * https://bugzilla.kernel.org/show_bug.cgi?id=203885). ++ * ++ * Therefore we wait for 100 ms and check for the device presence. ++ * If it is still not present give it an additional 100 ms. ++ */ ++ if (!pcie_downstream_port(dev)) ++ return; ++ ++ if (pcie_get_speed_cap(dev) <= PCIE_SPEED_5_0GT) { ++ pci_dbg(dev, "waiting %d ms for downstream link\n", delay); ++ msleep(delay); ++ } else { ++ pci_dbg(dev, "waiting %d ms for downstream link, after activation\n", ++ delay); ++ if (!pcie_wait_for_link_delay(dev, true, delay)) { ++ /* Did not train, no need to wait any further */ ++ return; ++ } ++ } ++ ++ if (!pci_device_is_present(child)) { ++ pci_dbg(child, "waiting additional %d ms to become accessible\n", delay); ++ msleep(delay); ++ } ++} ++ + void pci_reset_secondary_bus(struct pci_dev *dev) + { + u16 ctrl; +diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h +index 273d60cb0762d..a5adc2e2c351d 100644 +--- a/drivers/pci/pci.h ++++ b/drivers/pci/pci.h +@@ -107,6 +107,7 @@ void pci_allocate_cap_save_buffers(struct pci_dev *dev); + void pci_free_cap_save_buffers(struct pci_dev *dev); + bool pci_bridge_d3_possible(struct pci_dev *dev); + void pci_bridge_d3_update(struct pci_dev *dev); ++void pci_bridge_wait_for_secondary_bus(struct pci_dev *dev); + + static inline void pci_wakeup_event(struct pci_dev *dev) + { +-- +2.20.1 + diff --git a/queue-5.4/pci-pm-add-pcie_wait_for_link_delay.patch b/queue-5.4/pci-pm-add-pcie_wait_for_link_delay.patch new file mode 100644 index 00000000000..1b2c57f0d9c --- /dev/null +++ b/queue-5.4/pci-pm-add-pcie_wait_for_link_delay.patch @@ -0,0 +1,75 @@ +From e925c1f6da0e9f4ad4203b2d97c92f2b3102d549 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Nov 2019 12:16:16 +0300 +Subject: PCI/PM: Add pcie_wait_for_link_delay() + +From: Mika Westerberg + +[ 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 +Signed-off-by: Bjorn Helgaas +Reviewed-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/pci/pci.c | 21 ++++++++++++++++++--- + 1 file changed, 18 insertions(+), 3 deletions(-) + +diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c +index 981ae16f935bc..94d6e120b4734 100644 +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -4605,14 +4605,17 @@ static int pci_pm_reset(struct pci_dev *dev, int probe) + + return pci_dev_wait(dev, "PM D3->D0", PCIE_RESET_READY_POLL_MS); + } ++ + /** +- * pcie_wait_for_link - Wait until link is active or inactive ++ * pcie_wait_for_link_delay - Wait until link is active or inactive + * @pdev: Bridge device + * @active: waiting for active or inactive? ++ * @delay: Delay to wait after link has become active (in ms) + * + * Use this to wait till link becomes active or inactive. + */ +-bool pcie_wait_for_link(struct pci_dev *pdev, bool active) ++static bool pcie_wait_for_link_delay(struct pci_dev *pdev, bool active, ++ int delay) + { + int timeout = 1000; + bool ret; +@@ -4649,13 +4652,25 @@ bool pcie_wait_for_link(struct pci_dev *pdev, bool active) + timeout -= 10; + } + if (active && ret) +- msleep(100); ++ msleep(delay); + else if (ret != active) + pci_info(pdev, "Data Link Layer Link Active not %s in 1000 msec\n", + active ? "set" : "cleared"); + return ret == active; + } + ++/** ++ * pcie_wait_for_link - Wait until link is active or inactive ++ * @pdev: Bridge device ++ * @active: waiting for active or inactive? ++ * ++ * Use this to wait till link becomes active or inactive. ++ */ ++bool pcie_wait_for_link(struct pci_dev *pdev, bool active) ++{ ++ return pcie_wait_for_link_delay(pdev, active, 100); ++} ++ + void pci_reset_secondary_bus(struct pci_dev *dev) + { + u16 ctrl; +-- +2.20.1 + diff --git a/queue-5.4/perf-core-disable-page-faults-when-getting-phys-addr.patch b/queue-5.4/perf-core-disable-page-faults-when-getting-phys-addr.patch new file mode 100644 index 00000000000..5e269c15d6c --- /dev/null +++ b/queue-5.4/perf-core-disable-page-faults-when-getting-phys-addr.patch @@ -0,0 +1,71 @@ +From 752b1de67e20c611dd0d4009edf7caacb61387ec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Apr 2020 16:14:27 +0200 +Subject: perf/core: Disable page faults when getting phys address + +From: Jiri Olsa + +[ 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 +Signed-off-by: Jiri Olsa +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Ingo Molnar +Link: https://lkml.kernel.org/r/20200407141427.3184722-1-jolsa@kernel.org +Signed-off-by: Sasha Levin +--- + kernel/events/core.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/kernel/events/core.c b/kernel/events/core.c +index 15b123bdcaf53..72d0cfd73cf11 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -6537,9 +6537,12 @@ static u64 perf_virt_to_phys(u64 virt) + * Try IRQ-safe __get_user_pages_fast first. + * If failed, leave phys_addr as 0. + */ +- if ((current->mm != NULL) && +- (__get_user_pages_fast(virt, 1, 0, &p) == 1)) +- phys_addr = page_to_phys(p) + virt % PAGE_SIZE; ++ if (current->mm != NULL) { ++ pagefault_disable(); ++ if (__get_user_pages_fast(virt, 1, 0, &p) == 1) ++ phys_addr = page_to_phys(p) + virt % PAGE_SIZE; ++ pagefault_enable(); ++ } + + if (p) + put_page(p); +-- +2.20.1 + diff --git a/queue-5.4/powerpc-pseries-fix-mce-handling-on-pseries.patch b/queue-5.4/powerpc-pseries-fix-mce-handling-on-pseries.patch new file mode 100644 index 00000000000..7b486593e4d --- /dev/null +++ b/queue-5.4/powerpc-pseries-fix-mce-handling-on-pseries.patch @@ -0,0 +1,87 @@ +From ba46c6a60b230dc4ae321c9e0cd62a7db54ebc8c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Mar 2020 16:31:19 +0530 +Subject: powerpc/pseries: Fix MCE handling on pseries + +From: Ganesh Goudar + +[ 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 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 +Reviewed-by: Nicholas Piggin +Signed-off-by: Ganesh Goudar +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/20200320110119.10207-1-ganeshgr@linux.ibm.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/platforms/pseries/ras.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c +index 3acdcc3bb908c..753adeb624f23 100644 +--- a/arch/powerpc/platforms/pseries/ras.c ++++ b/arch/powerpc/platforms/pseries/ras.c +@@ -683,6 +683,17 @@ static int mce_handle_error(struct pt_regs *regs, struct rtas_error_log *errp) + #endif + + out: ++ /* ++ * Enable translation as we will be accessing per-cpu variables ++ * in save_mce_event() which may fall outside RMO region, also ++ * leave it enabled because subsequently we will be queuing work ++ * to workqueues where again per-cpu variables accessed, besides ++ * fwnmi_release_errinfo() crashes when called in realmode on ++ * pseries. ++ * Note: All the realmode handling like flushing SLB entries for ++ * SLB multihit is done by now. ++ */ ++ mtmsr(mfmsr() | MSR_IR | MSR_DR); + save_mce_event(regs, disposition == RTAS_DISP_FULLY_RECOVERED, + &mce_err, regs->nip, eaddr, paddr); + +-- +2.20.1 + diff --git a/queue-5.4/pwm-bcm2835-dynamically-allocate-base.patch b/queue-5.4/pwm-bcm2835-dynamically-allocate-base.patch new file mode 100644 index 00000000000..08e928bd84e --- /dev/null +++ b/queue-5.4/pwm-bcm2835-dynamically-allocate-base.patch @@ -0,0 +1,42 @@ +From 12592503600512d3fc90c3411030b5f64a84ee6d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Acked-by: Uwe Kleine-König +Reviewed-by: Nicolas Saenz Julienne +Signed-off-by: Thierry Reding +Signed-off-by: Sasha Levin +--- + drivers/pwm/pwm-bcm2835.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/pwm/pwm-bcm2835.c b/drivers/pwm/pwm-bcm2835.c +index 91e24f01b54ed..d78f86f8e4621 100644 +--- a/drivers/pwm/pwm-bcm2835.c ++++ b/drivers/pwm/pwm-bcm2835.c +@@ -166,6 +166,7 @@ static int bcm2835_pwm_probe(struct platform_device *pdev) + + pc->chip.dev = &pdev->dev; + pc->chip.ops = &bcm2835_pwm_ops; ++ pc->chip.base = -1; + pc->chip.npwm = 2; + pc->chip.of_xlate = of_pwm_xlate_with_flags; + pc->chip.of_pwm_n_cells = 3; +-- +2.20.1 + diff --git a/queue-5.4/pwm-rcar-fix-late-runtime-pm-enablement.patch b/queue-5.4/pwm-rcar-fix-late-runtime-pm-enablement.patch new file mode 100644 index 00000000000..cfb6b9f8dba --- /dev/null +++ b/queue-5.4/pwm-rcar-fix-late-runtime-pm-enablement.patch @@ -0,0 +1,66 @@ +From fc1cd28772e69e3c0ad0168fd3b4f60c1f5adbca Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Uwe Kleine-König +Reviewed-by: Laurent Pinchart +Signed-off-by: Thierry Reding +Signed-off-by: Sasha Levin +--- + drivers/pwm/pwm-rcar.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/drivers/pwm/pwm-rcar.c b/drivers/pwm/pwm-rcar.c +index 852eb2347954d..b98ec8847b488 100644 +--- a/drivers/pwm/pwm-rcar.c ++++ b/drivers/pwm/pwm-rcar.c +@@ -228,24 +228,28 @@ static int rcar_pwm_probe(struct platform_device *pdev) + rcar_pwm->chip.base = -1; + rcar_pwm->chip.npwm = 1; + ++ pm_runtime_enable(&pdev->dev); ++ + ret = pwmchip_add(&rcar_pwm->chip); + if (ret < 0) { + dev_err(&pdev->dev, "failed to register PWM chip: %d\n", ret); ++ pm_runtime_disable(&pdev->dev); + return ret; + } + +- pm_runtime_enable(&pdev->dev); +- + return 0; + } + + static int rcar_pwm_remove(struct platform_device *pdev) + { + struct rcar_pwm_chip *rcar_pwm = platform_get_drvdata(pdev); ++ int ret; ++ ++ ret = pwmchip_remove(&rcar_pwm->chip); + + pm_runtime_disable(&pdev->dev); + +- return pwmchip_remove(&rcar_pwm->chip); ++ return ret; + } + + static const struct of_device_id rcar_pwm_of_table[] = { +-- +2.20.1 + diff --git a/queue-5.4/pwm-renesas-tpu-fix-late-runtime-pm-enablement.patch b/queue-5.4/pwm-renesas-tpu-fix-late-runtime-pm-enablement.patch new file mode 100644 index 00000000000..596ec9bf855 --- /dev/null +++ b/queue-5.4/pwm-renesas-tpu-fix-late-runtime-pm-enablement.patch @@ -0,0 +1,63 @@ +From a176f3fec7b57dc08e36e71ddcdb5bad23cd7e2f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Mar 2020 11:32:15 +0100 +Subject: pwm: renesas-tpu: Fix late Runtime PM enablement + +From: Geert Uytterhoeven + +[ 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 +Signed-off-by: Thierry Reding +Signed-off-by: Sasha Levin +--- + drivers/pwm/pwm-renesas-tpu.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/drivers/pwm/pwm-renesas-tpu.c b/drivers/pwm/pwm-renesas-tpu.c +index 4a855a21b782d..8032acc84161a 100644 +--- a/drivers/pwm/pwm-renesas-tpu.c ++++ b/drivers/pwm/pwm-renesas-tpu.c +@@ -415,16 +415,17 @@ static int tpu_probe(struct platform_device *pdev) + tpu->chip.base = -1; + tpu->chip.npwm = TPU_CHANNEL_MAX; + ++ pm_runtime_enable(&pdev->dev); ++ + ret = pwmchip_add(&tpu->chip); + if (ret < 0) { + dev_err(&pdev->dev, "failed to register PWM chip\n"); ++ pm_runtime_disable(&pdev->dev); + return ret; + } + + dev_info(&pdev->dev, "TPU PWM %d registered\n", tpu->pdev->id); + +- pm_runtime_enable(&pdev->dev); +- + return 0; + } + +@@ -434,12 +435,10 @@ static int tpu_remove(struct platform_device *pdev) + int ret; + + ret = pwmchip_remove(&tpu->chip); +- if (ret) +- return ret; + + pm_runtime_disable(&pdev->dev); + +- return 0; ++ return ret; + } + + #ifdef CONFIG_OF +-- +2.20.1 + diff --git a/queue-5.4/revert-powerpc-64-irq_work-avoid-interrupt-when-call.patch b/queue-5.4/revert-powerpc-64-irq_work-avoid-interrupt-when-call.patch new file mode 100644 index 00000000000..598351848d2 --- /dev/null +++ b/queue-5.4/revert-powerpc-64-irq_work-avoid-interrupt-when-call.patch @@ -0,0 +1,111 @@ +From 1af9f0f6a6f268342a71e679e356ea1c269449f0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/20200402120401.1115883-1-npiggin@gmail.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/kernel/time.c | 44 +++++++++++--------------------------- + 1 file changed, 13 insertions(+), 31 deletions(-) + +diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c +index 11301a1187f33..0e0a2227af7d7 100644 +--- a/arch/powerpc/kernel/time.c ++++ b/arch/powerpc/kernel/time.c +@@ -522,35 +522,6 @@ static inline void clear_irq_work_pending(void) + "i" (offsetof(struct paca_struct, irq_work_pending))); + } + +-void arch_irq_work_raise(void) +-{ +- preempt_disable(); +- set_irq_work_pending_flag(); +- /* +- * Non-nmi code running with interrupts disabled will replay +- * irq_happened before it re-enables interrupts, so setthe +- * decrementer there instead of causing a hardware exception +- * which would immediately hit the masked interrupt handler +- * and have the net effect of setting the decrementer in +- * irq_happened. +- * +- * NMI interrupts can not check this when they return, so the +- * decrementer hardware exception is raised, which will fire +- * when interrupts are next enabled. +- * +- * BookE does not support this yet, it must audit all NMI +- * interrupt handlers to ensure they call nmi_enter() so this +- * check would be correct. +- */ +- if (IS_ENABLED(CONFIG_BOOKE) || !irqs_disabled() || in_nmi()) { +- set_dec(1); +- } else { +- hard_irq_disable(); +- local_paca->irq_happened |= PACA_IRQ_DEC; +- } +- preempt_enable(); +-} +- + #else /* 32-bit */ + + DEFINE_PER_CPU(u8, irq_work_pending); +@@ -559,16 +530,27 @@ DEFINE_PER_CPU(u8, irq_work_pending); + #define test_irq_work_pending() __this_cpu_read(irq_work_pending) + #define clear_irq_work_pending() __this_cpu_write(irq_work_pending, 0) + ++#endif /* 32 vs 64 bit */ ++ + void arch_irq_work_raise(void) + { ++ /* ++ * 64-bit code that uses irq soft-mask can just cause an immediate ++ * interrupt here that gets soft masked, if this is called under ++ * local_irq_disable(). It might be possible to prevent that happening ++ * by noticing interrupts are disabled and setting decrementer pending ++ * to be replayed when irqs are enabled. The problem there is that ++ * tracing can call irq_work_raise, including in code that does low ++ * level manipulations of irq soft-mask state (e.g., trace_hardirqs_on) ++ * which could get tangled up if we're messing with the same state ++ * here. ++ */ + preempt_disable(); + set_irq_work_pending_flag(); + set_dec(1); + preempt_enable(); + } + +-#endif /* 32 vs 64 bit */ +- + #else /* CONFIG_IRQ_WORK */ + + #define test_irq_work_pending() 0 +-- +2.20.1 + diff --git a/queue-5.4/s390-cio-avoid-duplicated-add-uevents.patch b/queue-5.4/s390-cio-avoid-duplicated-add-uevents.patch new file mode 100644 index 00000000000..edf5e9bde39 --- /dev/null +++ b/queue-5.4/s390-cio-avoid-duplicated-add-uevents.patch @@ -0,0 +1,65 @@ +From 6a16cd505486f62967425ab42db7b319d1146fff Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 27 Mar 2020 13:45:02 +0100 +Subject: s390/cio: avoid duplicated 'ADD' uevents + +From: Cornelia Huck + +[ 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 +Reviewed-by: Peter Oberparleiter +Reviewed-by: Boris Fiuczynski +Signed-off-by: Cornelia Huck +Signed-off-by: Vasily Gorbik +Signed-off-by: Sasha Levin +--- + drivers/s390/cio/device.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c +index 0c6245fc77069..983f9c9e08deb 100644 +--- a/drivers/s390/cio/device.c ++++ b/drivers/s390/cio/device.c +@@ -849,8 +849,10 @@ static void io_subchannel_register(struct ccw_device *cdev) + * Now we know this subchannel will stay, we can throw + * our delayed uevent. + */ +- dev_set_uevent_suppress(&sch->dev, 0); +- kobject_uevent(&sch->dev.kobj, KOBJ_ADD); ++ if (dev_get_uevent_suppress(&sch->dev)) { ++ dev_set_uevent_suppress(&sch->dev, 0); ++ kobject_uevent(&sch->dev.kobj, KOBJ_ADD); ++ } + /* make it known to the system */ + ret = ccw_device_add(cdev); + if (ret) { +@@ -1058,8 +1060,11 @@ static int io_subchannel_probe(struct subchannel *sch) + * Throw the delayed uevent for the subchannel, register + * the ccw_device and exit. + */ +- dev_set_uevent_suppress(&sch->dev, 0); +- kobject_uevent(&sch->dev.kobj, KOBJ_ADD); ++ if (dev_get_uevent_suppress(&sch->dev)) { ++ /* should always be the case for the console */ ++ dev_set_uevent_suppress(&sch->dev, 0); ++ kobject_uevent(&sch->dev.kobj, KOBJ_ADD); ++ } + cdev = sch_get_cdev(sch); + rc = ccw_device_add(cdev); + if (rc) { +-- +2.20.1 + diff --git a/queue-5.4/s390-cio-generate-delayed-uevent-for-vfio-ccw-subcha.patch b/queue-5.4/s390-cio-generate-delayed-uevent-for-vfio-ccw-subcha.patch new file mode 100644 index 00000000000..5b12bd14c54 --- /dev/null +++ b/queue-5.4/s390-cio-generate-delayed-uevent-for-vfio-ccw-subcha.patch @@ -0,0 +1,48 @@ +From 21109933a0a0b42c99574162bebf46521fbd406b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 27 Mar 2020 13:45:03 +0100 +Subject: s390/cio: generate delayed uevent for vfio-ccw subchannels + +From: Cornelia Huck + +[ 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 +Signed-off-by: Cornelia Huck +Signed-off-by: Vasily Gorbik +Signed-off-by: Sasha Levin +--- + drivers/s390/cio/vfio_ccw_drv.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c +index e401a3d0aa570..339a6bc0339b0 100644 +--- a/drivers/s390/cio/vfio_ccw_drv.c ++++ b/drivers/s390/cio/vfio_ccw_drv.c +@@ -167,6 +167,11 @@ static int vfio_ccw_sch_probe(struct subchannel *sch) + if (ret) + goto out_disable; + ++ if (dev_get_uevent_suppress(&sch->dev)) { ++ dev_set_uevent_suppress(&sch->dev, 0); ++ kobject_uevent(&sch->dev.kobj, KOBJ_ADD); ++ } ++ + VFIO_CCW_MSG_EVENT(4, "bound to subchannel %x.%x.%04x\n", + sch->schid.cssid, sch->schid.ssid, + sch->schid.sch_no); +-- +2.20.1 + diff --git a/queue-5.4/scsi-iscsi-report-unbind-session-event-when-the-targ.patch b/queue-5.4/scsi-iscsi-report-unbind-session-event-when-the-targ.patch new file mode 100644 index 00000000000..a7e01ac8014 --- /dev/null +++ b/queue-5.4/scsi-iscsi-report-unbind-session-event-when-the-targ.patch @@ -0,0 +1,61 @@ +From 8474dbecfad4b70cfa84d6ffca90ccd00d9de867 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Wu Bo +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/scsi_transport_iscsi.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c +index 271afea654e2b..a5c78b38d3022 100644 +--- a/drivers/scsi/scsi_transport_iscsi.c ++++ b/drivers/scsi/scsi_transport_iscsi.c +@@ -2012,7 +2012,7 @@ static void __iscsi_unbind_session(struct work_struct *work) + if (session->target_id == ISCSI_MAX_TARGET) { + spin_unlock_irqrestore(&session->lock, flags); + mutex_unlock(&ihost->mutex); +- return; ++ goto unbind_session_exit; + } + + target_id = session->target_id; +@@ -2024,6 +2024,8 @@ static void __iscsi_unbind_session(struct work_struct *work) + ida_simple_remove(&iscsi_sess_ida, target_id); + + scsi_remove_target(&session->dev); ++ ++unbind_session_exit: + iscsi_session_event(session, ISCSI_KEVENT_UNBIND_SESSION); + ISCSI_DBG_TRANS_SESSION(session, "Completed target removal\n"); + } +-- +2.20.1 + diff --git a/queue-5.4/scsi-libfc-if-prli-rejected-move-rport-to-plogi-stat.patch b/queue-5.4/scsi-libfc-if-prli-rejected-move-rport-to-plogi-stat.patch new file mode 100644 index 00000000000..0fe4f6a4696 --- /dev/null +++ b/queue-5.4/scsi-libfc-if-prli-rejected-move-rport-to-plogi-stat.patch @@ -0,0 +1,45 @@ +From ab048989b4a22071c50737df55b7960824f8ff12 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 26 Mar 2020 23:02:07 -0700 +Subject: scsi: libfc: If PRLI rejected, move rport to PLOGI state + +From: Javed Hasan + +[ 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 +Signed-off-by: Saurav Kashyap +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/libfc/fc_rport.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c +index da6e97d8dc3bb..6bb8917b99a19 100644 +--- a/drivers/scsi/libfc/fc_rport.c ++++ b/drivers/scsi/libfc/fc_rport.c +@@ -1208,9 +1208,15 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp, + rjt = fc_frame_payload_get(fp, sizeof(*rjt)); + if (!rjt) + FC_RPORT_DBG(rdata, "PRLI bad response\n"); +- else ++ else { + FC_RPORT_DBG(rdata, "PRLI ELS rejected, reason %x expl %x\n", + rjt->er_reason, rjt->er_explan); ++ if (rjt->er_reason == ELS_RJT_UNAB && ++ rjt->er_explan == ELS_EXPL_PLOGI_REQD) { ++ fc_rport_enter_plogi(rdata); ++ goto out; ++ } ++ } + fc_rport_error_retry(rdata, FC_EX_ELS_RJT); + } + +-- +2.20.1 + diff --git a/queue-5.4/scsi-lpfc-fix-crash-after-handling-a-pci-error.patch b/queue-5.4/scsi-lpfc-fix-crash-after-handling-a-pci-error.patch new file mode 100644 index 00000000000..5db7c273853 --- /dev/null +++ b/queue-5.4/scsi-lpfc-fix-crash-after-handling-a-pci-error.patch @@ -0,0 +1,47 @@ +From e639de2b39b09d3eaf29ed82cae4fc39332ba8e0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 22 Mar 2020 11:12:57 -0700 +Subject: scsi: lpfc: Fix crash after handling a pci error + +From: James Smart + +[ 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 +Signed-off-by: Dick Kennedy +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/lpfc/lpfc_sli.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c +index 1692ce913b7f0..a951e1c8165ed 100644 +--- a/drivers/scsi/lpfc/lpfc_sli.c ++++ b/drivers/scsi/lpfc/lpfc_sli.c +@@ -4013,6 +4013,11 @@ lpfc_sli_flush_io_rings(struct lpfc_hba *phba) + struct lpfc_iocbq *piocb, *next_iocb; + + spin_lock_irq(&phba->hbalock); ++ if (phba->hba_flag & HBA_IOQ_FLUSH || ++ !phba->sli4_hba.hdwq) { ++ spin_unlock_irq(&phba->hbalock); ++ return; ++ } + /* Indicate the I/O queues are flushed */ + phba->hba_flag |= HBA_IOQ_FLUSH; + spin_unlock_irq(&phba->hbalock); +-- +2.20.1 + diff --git a/queue-5.4/scsi-lpfc-fix-crash-in-target-side-cable-pulls-hitti.patch b/queue-5.4/scsi-lpfc-fix-crash-in-target-side-cable-pulls-hitti.patch new file mode 100644 index 00000000000..fb685a485c0 --- /dev/null +++ b/queue-5.4/scsi-lpfc-fix-crash-in-target-side-cable-pulls-hitti.patch @@ -0,0 +1,76 @@ +From 3f2a904e6b77a68e7f25d51e423df382610fb0ce Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Dick Kennedy +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/lpfc/lpfc_nvme.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c +index a227e36cbdc2b..5a86a1ee0de3b 100644 +--- a/drivers/scsi/lpfc/lpfc_nvme.c ++++ b/drivers/scsi/lpfc/lpfc_nvme.c +@@ -342,13 +342,15 @@ lpfc_nvme_remoteport_delete(struct nvme_fc_remote_port *remoteport) + if (ndlp->upcall_flags & NLP_WAIT_FOR_UNREG) { + ndlp->nrport = NULL; + ndlp->upcall_flags &= ~NLP_WAIT_FOR_UNREG; +- } +- spin_unlock_irq(&vport->phba->hbalock); ++ spin_unlock_irq(&vport->phba->hbalock); + +- /* Remove original register reference. The host transport +- * won't reference this rport/remoteport any further. +- */ +- lpfc_nlp_put(ndlp); ++ /* Remove original register reference. The host transport ++ * won't reference this rport/remoteport any further. ++ */ ++ lpfc_nlp_put(ndlp); ++ } else { ++ spin_unlock_irq(&vport->phba->hbalock); ++ } + + rport_err: + return; +-- +2.20.1 + diff --git a/queue-5.4/scsi-lpfc-fix-kasan-slab-out-of-bounds-error-in-lpfc.patch b/queue-5.4/scsi-lpfc-fix-kasan-slab-out-of-bounds-error-in-lpfc.patch new file mode 100644 index 00000000000..c73dc57f3f0 --- /dev/null +++ b/queue-5.4/scsi-lpfc-fix-kasan-slab-out-of-bounds-error-in-lpfc.patch @@ -0,0 +1,62 @@ +From f4ba5286ac43dba1873de8f4d28ab094d653c860 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Dick Kennedy +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/lpfc/lpfc_sli.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c +index 0717e850bcbfd..1692ce913b7f0 100644 +--- a/drivers/scsi/lpfc/lpfc_sli.c ++++ b/drivers/scsi/lpfc/lpfc_sli.c +@@ -2481,6 +2481,8 @@ lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) + !pmb->u.mb.mbxStatus) { + rpi = pmb->u.mb.un.varWords[0]; + vpi = pmb->u.mb.un.varRegLogin.vpi; ++ if (phba->sli_rev == LPFC_SLI_REV4) ++ vpi -= phba->sli4_hba.max_cfg_param.vpi_base; + lpfc_unreg_login(phba, vpi, rpi, pmb); + pmb->vport = vport; + pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; +-- +2.20.1 + diff --git a/queue-5.4/scsi-smartpqi-fix-call-trace-in-device-discovery.patch b/queue-5.4/scsi-smartpqi-fix-call-trace-in-device-discovery.patch new file mode 100644 index 00000000000..5562e3b39ff --- /dev/null +++ b/queue-5.4/scsi-smartpqi-fix-call-trace-in-device-discovery.patch @@ -0,0 +1,43 @@ +From 9ceb0a0635e9bff75d4a341b2fb5a175d703ee73 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 7 Oct 2019 17:31:28 -0500 +Subject: scsi: smartpqi: fix call trace in device discovery + +From: Murthy Bhat + +[ 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 +Reviewed-by: Scott Teel +Reviewed-by: Kevin Barnett +Signed-off-by: Murthy Bhat +Signed-off-by: Don Brace +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/smartpqi/smartpqi_sas_transport.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/scsi/smartpqi/smartpqi_sas_transport.c b/drivers/scsi/smartpqi/smartpqi_sas_transport.c +index 6776dfc1d317c..b7e28b9f8589f 100644 +--- a/drivers/scsi/smartpqi/smartpqi_sas_transport.c ++++ b/drivers/scsi/smartpqi/smartpqi_sas_transport.c +@@ -45,9 +45,9 @@ static void pqi_free_sas_phy(struct pqi_sas_phy *pqi_sas_phy) + struct sas_phy *phy = pqi_sas_phy->phy; + + sas_port_delete_phy(pqi_sas_phy->parent_port->port, phy); +- sas_phy_free(phy); + if (pqi_sas_phy->added_to_port) + list_del(&pqi_sas_phy->phy_list_entry); ++ sas_phy_delete(phy); + kfree(pqi_sas_phy); + } + +-- +2.20.1 + diff --git a/queue-5.4/scsi-smartpqi-fix-controller-lockup-observed-during-.patch b/queue-5.4/scsi-smartpqi-fix-controller-lockup-observed-during-.patch new file mode 100644 index 00000000000..2933ac406e1 --- /dev/null +++ b/queue-5.4/scsi-smartpqi-fix-controller-lockup-observed-during-.patch @@ -0,0 +1,305 @@ +From 36b25e80acb230949b881331982657a1ee37baf7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 7 Oct 2019 17:31:23 -0500 +Subject: scsi: smartpqi: fix controller lockup observed during force reboot + +From: Kevin Barnett + +[ Upstream commit 0530736e40a0695b1ee2762e2684d00549699da4 ] + +Link: https://lore.kernel.org/r/157048748297.11757.3872221216800537383.stgit@brunhilda +Reviewed-by: Scott Benesh +Reviewed-by: Scott Teel +Signed-off-by: Kevin Barnett +Signed-off-by: Don Brace +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/smartpqi/smartpqi.h | 9 +- + drivers/scsi/smartpqi/smartpqi_init.c | 126 ++++++++++++++++++++++---- + 2 files changed, 115 insertions(+), 20 deletions(-) + +diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h +index 79d2af36f6552..2aa81b22f2695 100644 +--- a/drivers/scsi/smartpqi/smartpqi.h ++++ b/drivers/scsi/smartpqi/smartpqi.h +@@ -1130,8 +1130,9 @@ struct pqi_ctrl_info { + struct mutex ofa_mutex; /* serialize ofa */ + bool controller_online; + bool block_requests; +- bool in_shutdown; ++ bool block_device_reset; + bool in_ofa; ++ bool in_shutdown; + u8 inbound_spanning_supported : 1; + u8 outbound_spanning_supported : 1; + u8 pqi_mode_enabled : 1; +@@ -1173,6 +1174,7 @@ struct pqi_ctrl_info { + struct pqi_ofa_memory *pqi_ofa_mem_virt_addr; + dma_addr_t pqi_ofa_mem_dma_handle; + void **pqi_ofa_chunk_virt_addr; ++ atomic_t sync_cmds_outstanding; + }; + + enum pqi_ctrl_mode { +@@ -1423,6 +1425,11 @@ static inline bool pqi_ctrl_blocked(struct pqi_ctrl_info *ctrl_info) + return ctrl_info->block_requests; + } + ++static inline bool pqi_device_reset_blocked(struct pqi_ctrl_info *ctrl_info) ++{ ++ return ctrl_info->block_device_reset; ++} ++ + void pqi_sas_smp_handler(struct bsg_job *job, struct Scsi_Host *shost, + struct sas_rphy *rphy); + +diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c +index ea5409bebf578..793793343950e 100644 +--- a/drivers/scsi/smartpqi/smartpqi_init.c ++++ b/drivers/scsi/smartpqi/smartpqi_init.c +@@ -249,6 +249,11 @@ static inline void pqi_ctrl_unblock_requests(struct pqi_ctrl_info *ctrl_info) + scsi_unblock_requests(ctrl_info->scsi_host); + } + ++static inline void pqi_ctrl_block_device_reset(struct pqi_ctrl_info *ctrl_info) ++{ ++ ctrl_info->block_device_reset = true; ++} ++ + static unsigned long pqi_wait_if_ctrl_blocked(struct pqi_ctrl_info *ctrl_info, + unsigned long timeout_msecs) + { +@@ -331,6 +336,16 @@ static inline bool pqi_device_in_remove(struct pqi_ctrl_info *ctrl_info, + return device->in_remove && !ctrl_info->in_shutdown; + } + ++static inline void pqi_ctrl_shutdown_start(struct pqi_ctrl_info *ctrl_info) ++{ ++ ctrl_info->in_shutdown = true; ++} ++ ++static inline bool pqi_ctrl_in_shutdown(struct pqi_ctrl_info *ctrl_info) ++{ ++ return ctrl_info->in_shutdown; ++} ++ + static inline void pqi_schedule_rescan_worker_with_delay( + struct pqi_ctrl_info *ctrl_info, unsigned long delay) + { +@@ -360,6 +375,11 @@ static inline void pqi_cancel_rescan_worker(struct pqi_ctrl_info *ctrl_info) + cancel_delayed_work_sync(&ctrl_info->rescan_work); + } + ++static inline void pqi_cancel_event_worker(struct pqi_ctrl_info *ctrl_info) ++{ ++ cancel_work_sync(&ctrl_info->event_work); ++} ++ + static inline u32 pqi_read_heartbeat_counter(struct pqi_ctrl_info *ctrl_info) + { + if (!ctrl_info->heartbeat_counter) +@@ -4122,6 +4142,8 @@ static int pqi_submit_raid_request_synchronous(struct pqi_ctrl_info *ctrl_info, + goto out; + } + ++ atomic_inc(&ctrl_info->sync_cmds_outstanding); ++ + io_request = pqi_alloc_io_request(ctrl_info); + + put_unaligned_le16(io_request->index, +@@ -4168,6 +4190,7 @@ static int pqi_submit_raid_request_synchronous(struct pqi_ctrl_info *ctrl_info, + + pqi_free_io_request(io_request); + ++ atomic_dec(&ctrl_info->sync_cmds_outstanding); + out: + up(&ctrl_info->sync_request_sem); + +@@ -5402,7 +5425,7 @@ static int pqi_scsi_queue_command(struct Scsi_Host *shost, + + pqi_ctrl_busy(ctrl_info); + if (pqi_ctrl_blocked(ctrl_info) || pqi_device_in_reset(device) || +- pqi_ctrl_in_ofa(ctrl_info)) { ++ pqi_ctrl_in_ofa(ctrl_info) || pqi_ctrl_in_shutdown(ctrl_info)) { + rc = SCSI_MLQUEUE_HOST_BUSY; + goto out; + } +@@ -5650,6 +5673,18 @@ static int pqi_ctrl_wait_for_pending_io(struct pqi_ctrl_info *ctrl_info, + return 0; + } + ++static int pqi_ctrl_wait_for_pending_sync_cmds(struct pqi_ctrl_info *ctrl_info) ++{ ++ while (atomic_read(&ctrl_info->sync_cmds_outstanding)) { ++ pqi_check_ctrl_health(ctrl_info); ++ if (pqi_ctrl_offline(ctrl_info)) ++ return -ENXIO; ++ usleep_range(1000, 2000); ++ } ++ ++ return 0; ++} ++ + static void pqi_lun_reset_complete(struct pqi_io_request *io_request, + void *context) + { +@@ -5787,17 +5822,17 @@ static int pqi_eh_device_reset_handler(struct scsi_cmnd *scmd) + shost->host_no, device->bus, device->target, device->lun); + + pqi_check_ctrl_health(ctrl_info); +- if (pqi_ctrl_offline(ctrl_info)) { +- dev_err(&ctrl_info->pci_dev->dev, +- "controller %u offlined - cannot send device reset\n", +- ctrl_info->ctrl_id); ++ if (pqi_ctrl_offline(ctrl_info) || ++ pqi_device_reset_blocked(ctrl_info)) { + rc = FAILED; + goto out; + } + + pqi_wait_until_ofa_finished(ctrl_info); + ++ atomic_inc(&ctrl_info->sync_cmds_outstanding); + rc = pqi_device_reset(ctrl_info, device); ++ atomic_dec(&ctrl_info->sync_cmds_outstanding); + + out: + dev_err(&ctrl_info->pci_dev->dev, +@@ -6119,7 +6154,8 @@ static int pqi_ioctl(struct scsi_device *sdev, unsigned int cmd, + + ctrl_info = shost_to_hba(sdev->host); + +- if (pqi_ctrl_in_ofa(ctrl_info)) ++ if (pqi_ctrl_in_ofa(ctrl_info) || ++ pqi_ctrl_in_shutdown(ctrl_info)) + return -EBUSY; + + switch (cmd) { +@@ -7074,13 +7110,20 @@ static int pqi_force_sis_mode(struct pqi_ctrl_info *ctrl_info) + return pqi_revert_to_sis_mode(ctrl_info); + } + ++#define PQI_POST_RESET_DELAY_B4_MSGU_READY 5000 ++ + static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info) + { + int rc; + +- rc = pqi_force_sis_mode(ctrl_info); +- if (rc) +- return rc; ++ if (reset_devices) { ++ sis_soft_reset(ctrl_info); ++ msleep(PQI_POST_RESET_DELAY_B4_MSGU_READY); ++ } else { ++ rc = pqi_force_sis_mode(ctrl_info); ++ if (rc) ++ return rc; ++ } + + /* + * Wait until the controller is ready to start accepting SIS +@@ -7514,6 +7557,7 @@ static struct pqi_ctrl_info *pqi_alloc_ctrl_info(int numa_node) + + INIT_WORK(&ctrl_info->event_work, pqi_event_worker); + atomic_set(&ctrl_info->num_interrupts, 0); ++ atomic_set(&ctrl_info->sync_cmds_outstanding, 0); + + INIT_DELAYED_WORK(&ctrl_info->rescan_work, pqi_rescan_worker); + INIT_DELAYED_WORK(&ctrl_info->update_time_work, pqi_update_time_worker); +@@ -7787,8 +7831,6 @@ static int pqi_ofa_host_memory_update(struct pqi_ctrl_info *ctrl_info) + 0, NULL, NO_TIMEOUT); + } + +-#define PQI_POST_RESET_DELAY_B4_MSGU_READY 5000 +- + static int pqi_ofa_ctrl_restart(struct pqi_ctrl_info *ctrl_info) + { + msleep(PQI_POST_RESET_DELAY_B4_MSGU_READY); +@@ -7956,28 +7998,74 @@ static void pqi_pci_remove(struct pci_dev *pci_dev) + pqi_remove_ctrl(ctrl_info); + } + ++static void pqi_crash_if_pending_command(struct pqi_ctrl_info *ctrl_info) ++{ ++ unsigned int i; ++ struct pqi_io_request *io_request; ++ struct scsi_cmnd *scmd; ++ ++ for (i = 0; i < ctrl_info->max_io_slots; i++) { ++ io_request = &ctrl_info->io_request_pool[i]; ++ if (atomic_read(&io_request->refcount) == 0) ++ continue; ++ scmd = io_request->scmd; ++ WARN_ON(scmd != NULL); /* IO command from SML */ ++ WARN_ON(scmd == NULL); /* Non-IO cmd or driver initiated*/ ++ } ++} ++ + static void pqi_shutdown(struct pci_dev *pci_dev) + { + int rc; + struct pqi_ctrl_info *ctrl_info; + + ctrl_info = pci_get_drvdata(pci_dev); +- if (!ctrl_info) +- goto error; ++ if (!ctrl_info) { ++ dev_err(&pci_dev->dev, ++ "cache could not be flushed\n"); ++ return; ++ } ++ ++ pqi_disable_events(ctrl_info); ++ pqi_wait_until_ofa_finished(ctrl_info); ++ pqi_cancel_update_time_worker(ctrl_info); ++ pqi_cancel_rescan_worker(ctrl_info); ++ pqi_cancel_event_worker(ctrl_info); ++ ++ pqi_ctrl_shutdown_start(ctrl_info); ++ pqi_ctrl_wait_until_quiesced(ctrl_info); ++ ++ rc = pqi_ctrl_wait_for_pending_io(ctrl_info, NO_TIMEOUT); ++ if (rc) { ++ dev_err(&pci_dev->dev, ++ "wait for pending I/O failed\n"); ++ return; ++ } ++ ++ pqi_ctrl_block_device_reset(ctrl_info); ++ pqi_wait_until_lun_reset_finished(ctrl_info); + + /* + * Write all data in the controller's battery-backed cache to + * storage. + */ + rc = pqi_flush_cache(ctrl_info, SHUTDOWN); +- pqi_free_interrupts(ctrl_info); +- pqi_reset(ctrl_info); +- if (rc == 0) ++ if (rc) ++ dev_err(&pci_dev->dev, ++ "unable to flush controller cache\n"); ++ ++ pqi_ctrl_block_requests(ctrl_info); ++ ++ rc = pqi_ctrl_wait_for_pending_sync_cmds(ctrl_info); ++ if (rc) { ++ dev_err(&pci_dev->dev, ++ "wait for pending sync cmds failed\n"); + return; ++ } ++ ++ pqi_crash_if_pending_command(ctrl_info); ++ pqi_reset(ctrl_info); + +-error: +- dev_warn(&pci_dev->dev, +- "unable to flush controller cache\n"); + } + + static void pqi_process_lockup_action_param(void) +-- +2.20.1 + diff --git a/queue-5.4/scsi-smartpqi-fix-problem-with-unique-id-for-physica.patch b/queue-5.4/scsi-smartpqi-fix-problem-with-unique-id-for-physica.patch new file mode 100644 index 00000000000..a59db78a572 --- /dev/null +++ b/queue-5.4/scsi-smartpqi-fix-problem-with-unique-id-for-physica.patch @@ -0,0 +1,174 @@ +From 1b716e73dc70bea0aa8feafd8001cbd229db10eb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 7 Oct 2019 17:31:58 -0500 +Subject: scsi: smartpqi: fix problem with unique ID for physical device + +From: Kevin Barnett + +[ 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 +Reviewed-by: Scott Teel +Signed-off-by: Kevin Barnett +Signed-off-by: Don Brace +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/smartpqi/smartpqi.h | 1 - + drivers/scsi/smartpqi/smartpqi_init.c | 99 ++++----------------------- + 2 files changed, 12 insertions(+), 88 deletions(-) + +diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h +index 2aa81b22f2695..7a3a942b40df0 100644 +--- a/drivers/scsi/smartpqi/smartpqi.h ++++ b/drivers/scsi/smartpqi/smartpqi.h +@@ -907,7 +907,6 @@ struct pqi_scsi_dev { + u8 scsi3addr[8]; + __be64 wwid; + u8 volume_id[16]; +- u8 unique_id[16]; + u8 is_physical_device : 1; + u8 is_external_raid_device : 1; + u8 is_expander_smp_device : 1; +diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c +index 793793343950e..5ae074505386a 100644 +--- a/drivers/scsi/smartpqi/smartpqi_init.c ++++ b/drivers/scsi/smartpqi/smartpqi_init.c +@@ -648,79 +648,6 @@ static inline int pqi_scsi_inquiry(struct pqi_ctrl_info *ctrl_info, + buffer, buffer_length, vpd_page, NULL, NO_TIMEOUT); + } + +-static bool pqi_vpd_page_supported(struct pqi_ctrl_info *ctrl_info, +- u8 *scsi3addr, u16 vpd_page) +-{ +- int rc; +- int i; +- int pages; +- unsigned char *buf, bufsize; +- +- buf = kzalloc(256, GFP_KERNEL); +- if (!buf) +- return false; +- +- /* Get the size of the page list first */ +- rc = pqi_scsi_inquiry(ctrl_info, scsi3addr, +- VPD_PAGE | SCSI_VPD_SUPPORTED_PAGES, +- buf, SCSI_VPD_HEADER_SZ); +- if (rc != 0) +- goto exit_unsupported; +- +- pages = buf[3]; +- if ((pages + SCSI_VPD_HEADER_SZ) <= 255) +- bufsize = pages + SCSI_VPD_HEADER_SZ; +- else +- bufsize = 255; +- +- /* Get the whole VPD page list */ +- rc = pqi_scsi_inquiry(ctrl_info, scsi3addr, +- VPD_PAGE | SCSI_VPD_SUPPORTED_PAGES, +- buf, bufsize); +- if (rc != 0) +- goto exit_unsupported; +- +- pages = buf[3]; +- for (i = 1; i <= pages; i++) +- if (buf[3 + i] == vpd_page) +- goto exit_supported; +- +-exit_unsupported: +- kfree(buf); +- return false; +- +-exit_supported: +- kfree(buf); +- return true; +-} +- +-static int pqi_get_device_id(struct pqi_ctrl_info *ctrl_info, +- u8 *scsi3addr, u8 *device_id, int buflen) +-{ +- int rc; +- unsigned char *buf; +- +- if (!pqi_vpd_page_supported(ctrl_info, scsi3addr, SCSI_VPD_DEVICE_ID)) +- return 1; /* function not supported */ +- +- buf = kzalloc(64, GFP_KERNEL); +- if (!buf) +- return -ENOMEM; +- +- rc = pqi_scsi_inquiry(ctrl_info, scsi3addr, +- VPD_PAGE | SCSI_VPD_DEVICE_ID, +- buf, 64); +- if (rc == 0) { +- if (buflen > 16) +- buflen = 16; +- memcpy(device_id, &buf[SCSI_VPD_DEVICE_ID_IDX], buflen); +- } +- +- kfree(buf); +- +- return rc; +-} +- + static int pqi_identify_physical_device(struct pqi_ctrl_info *ctrl_info, + struct pqi_scsi_dev *device, + struct bmic_identify_physical_device *buffer, +@@ -1405,14 +1332,6 @@ static int pqi_get_device_info(struct pqi_ctrl_info *ctrl_info, + } + } + +- if (pqi_get_device_id(ctrl_info, device->scsi3addr, +- device->unique_id, sizeof(device->unique_id)) < 0) +- dev_warn(&ctrl_info->pci_dev->dev, +- "Can't get device id for scsi %d:%d:%d:%d\n", +- ctrl_info->scsi_host->host_no, +- device->bus, device->target, +- device->lun); +- + out: + kfree(buffer); + +@@ -6319,7 +6238,7 @@ static ssize_t pqi_unique_id_show(struct device *dev, + struct scsi_device *sdev; + struct pqi_scsi_dev *device; + unsigned long flags; +- unsigned char uid[16]; ++ u8 unique_id[16]; + + sdev = to_scsi_device(dev); + ctrl_info = shost_to_hba(sdev->host); +@@ -6332,16 +6251,22 @@ static ssize_t pqi_unique_id_show(struct device *dev, + flags); + return -ENODEV; + } +- memcpy(uid, device->unique_id, sizeof(uid)); ++ ++ if (device->is_physical_device) { ++ memset(unique_id, 0, 8); ++ memcpy(unique_id + 8, &device->wwid, sizeof(device->wwid)); ++ } else { ++ memcpy(unique_id, device->volume_id, sizeof(device->volume_id)); ++ } + + spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); + + return snprintf(buffer, PAGE_SIZE, + "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n", +- uid[0], uid[1], uid[2], uid[3], +- uid[4], uid[5], uid[6], uid[7], +- uid[8], uid[9], uid[10], uid[11], +- uid[12], uid[13], uid[14], uid[15]); ++ unique_id[0], unique_id[1], unique_id[2], unique_id[3], ++ unique_id[4], unique_id[5], unique_id[6], unique_id[7], ++ unique_id[8], unique_id[9], unique_id[10], unique_id[11], ++ unique_id[12], unique_id[13], unique_id[14], unique_id[15]); + } + + static ssize_t pqi_lunid_show(struct device *dev, +-- +2.20.1 + diff --git a/queue-5.4/selftests-kmod-fix-handling-test-numbers-above-9.patch b/queue-5.4/selftests-kmod-fix-handling-test-numbers-above-9.patch new file mode 100644 index 00000000000..63a6cb1fe22 --- /dev/null +++ b/queue-5.4/selftests-kmod-fix-handling-test-numbers-above-9.patch @@ -0,0 +1,64 @@ +From 319de692ef923eafa7b5f08e33b00409b59d1fc6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Apr 2020 14:33:53 -0700 +Subject: selftests: kmod: fix handling test numbers above 9 + +From: Eric Biggers + +[ 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 +Signed-off-by: Andrew Morton +Acked-by: Luis Chamberlain +Cc: Alexei Starovoitov +Cc: Greg Kroah-Hartman +Cc: Jeff Vander Stoep +Cc: Jessica Yu +Cc: Kees Cook +Cc: NeilBrown +Link: http://lkml.kernel.org/r/20200318230515.171692-5-ebiggers@kernel.org +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.4/series b/queue-5.4/series index c427fbc52a2..5ded7088941 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -5,3 +5,51 @@ arm64-errata-hide-ctr_el0.dic-on-systems-affected-by.patch arm64-fake-the-iminline-size-on-systems-affected-by-.patch arm64-compat-workaround-neoverse-n1-1542419-for-comp.patch arm64-silence-clang-warning-on-mismatched-value-regi.patch +tools-testing-nvdimm-fix-compilation-failure-without.patch +watchdog-reset-last_hw_keepalive-time-at-start.patch +scsi-lpfc-fix-kasan-slab-out-of-bounds-error-in-lpfc.patch +scsi-lpfc-fix-crash-after-handling-a-pci-error.patch +scsi-lpfc-fix-crash-in-target-side-cable-pulls-hitti.patch +scsi-libfc-if-prli-rejected-move-rport-to-plogi-stat.patch +ceph-return-ceph_mdsc_do_request-errors-from-__get_p.patch +ceph-don-t-skip-updating-wanted-caps-when-cap-is-sta.patch +pwm-rcar-fix-late-runtime-pm-enablement.patch +nvme-tcp-fix-possible-crash-in-write_zeroes-processi.patch +scsi-iscsi-report-unbind-session-event-when-the-targ.patch +tools-test-nvdimm-fix-out-of-tree-build.patch +asoc-intel-atom-take-the-drv-lock-mutex-before-calli.patch +nvme-fix-deadlock-caused-by-ana-update-wrong-locking.patch +drm-amd-display-update-stream-adjust-in-dc_stream_ad.patch +dma-direct-fix-data-truncation-in-dma_direct_get_req.patch +kernel-gcov-fs.c-gcov_seq_next-should-increase-posit.patch +selftests-kmod-fix-handling-test-numbers-above-9.patch +ipc-util.c-sysvipc_find_ipc-should-increase-position.patch +kconfig-qconf-fix-a-few-alignment-issues.patch +lib-raid6-test-fix-build-on-distros-whose-bin-sh-is-.patch +s390-cio-generate-delayed-uevent-for-vfio-ccw-subcha.patch +s390-cio-avoid-duplicated-add-uevents.patch +loop-better-discard-support-for-block-devices.patch +revert-powerpc-64-irq_work-avoid-interrupt-when-call.patch +powerpc-pseries-fix-mce-handling-on-pseries.patch +nvme-fix-compat-address-handling-in-several-ioctls.patch +pwm-renesas-tpu-fix-late-runtime-pm-enablement.patch +pwm-bcm2835-dynamically-allocate-base.patch +perf-core-disable-page-faults-when-getting-phys-addr.patch +drm-amd-display-calculate-scaling-ratios-on-every-me.patch +asoc-intel-bytcr_rt5640-add-quirk-for-mpman-mpwin895.patch +alsa-usb-audio-add-pioneer-dj-djm-250mk2-quirk.patch +xhci-ensure-link-state-is-u3-after-setting-usb_ss_po.patch +xhci-wait-until-link-state-trainsits-to-u0-after-set.patch +xhci-finetune-host-initiated-usb3-rootport-link-susp.patch +drm-amd-display-not-doing-optimize-bandwidth-if-flip.patch +pci-pm-add-pcie_wait_for_link_delay.patch +libbpf-fix-readelf-output-parsing-on-powerpc-with-re.patch +pci-pciehp-prevent-deadlock-on-disconnect.patch +asoc-sof-trace-fix-unconditional-free-in-trace-relea.patch +tracing-selftests-turn-off-timeout-setting.patch +virtio-blk-improve-virtqueue-error-to-blk_sts.patch +scsi-smartpqi-fix-controller-lockup-observed-during-.patch +scsi-smartpqi-fix-call-trace-in-device-discovery.patch +scsi-smartpqi-fix-problem-with-unique-id-for-physica.patch +pci-aspm-allow-re-enabling-clock-pm.patch +pci-pm-add-missing-link-delays-required-by-the-pcie-.patch diff --git a/queue-5.4/tools-test-nvdimm-fix-out-of-tree-build.patch b/queue-5.4/tools-test-nvdimm-fix-out-of-tree-build.patch new file mode 100644 index 00000000000..9e200e893cf --- /dev/null +++ b/queue-5.4/tools-test-nvdimm-fix-out-of-tree-build.patch @@ -0,0 +1,67 @@ +From 7d9393657b05fbba005e77ef836383904d17de21 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Jan 2020 11:10:51 +0530 +Subject: tools/test/nvdimm: Fix out of tree build + +From: Santosh Sivaraj + +[ 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 + | ^~~~~~~~~~~ +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 +Signed-off-by: Santosh Sivaraj +Link: https://lore.kernel.org/r/20200114054051.4115790-1-santosh@fossix.org +Signed-off-by: Dan Williams +Signed-off-by: Sasha Levin +--- + tools/testing/nvdimm/Kbuild | 4 ++-- + tools/testing/nvdimm/test/Kbuild | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/tools/testing/nvdimm/Kbuild b/tools/testing/nvdimm/Kbuild +index c4a9196d794c9..cb80d3b811792 100644 +--- a/tools/testing/nvdimm/Kbuild ++++ b/tools/testing/nvdimm/Kbuild +@@ -21,8 +21,8 @@ DRIVERS := ../../../drivers + NVDIMM_SRC := $(DRIVERS)/nvdimm + ACPI_SRC := $(DRIVERS)/acpi/nfit + DAX_SRC := $(DRIVERS)/dax +-ccflags-y := -I$(src)/$(NVDIMM_SRC)/ +-ccflags-y += -I$(src)/$(ACPI_SRC)/ ++ccflags-y := -I$(srctree)/drivers/nvdimm/ ++ccflags-y += -I$(srctree)/drivers/acpi/nfit/ + + obj-$(CONFIG_LIBNVDIMM) += libnvdimm.o + obj-$(CONFIG_BLK_DEV_PMEM) += nd_pmem.o +diff --git a/tools/testing/nvdimm/test/Kbuild b/tools/testing/nvdimm/test/Kbuild +index fb3c3d7cdb9bd..75baebf8f4ba1 100644 +--- a/tools/testing/nvdimm/test/Kbuild ++++ b/tools/testing/nvdimm/test/Kbuild +@@ -1,6 +1,6 @@ + # SPDX-License-Identifier: GPL-2.0 +-ccflags-y := -I$(src)/../../../../drivers/nvdimm/ +-ccflags-y += -I$(src)/../../../../drivers/acpi/nfit/ ++ccflags-y := -I$(srctree)/drivers/nvdimm/ ++ccflags-y += -I$(srctree)/drivers/acpi/nfit/ + + obj-m += nfit_test.o + obj-m += nfit_test_iomap.o +-- +2.20.1 + diff --git a/queue-5.4/tools-testing-nvdimm-fix-compilation-failure-without.patch b/queue-5.4/tools-testing-nvdimm-fix-compilation-failure-without.patch new file mode 100644 index 00000000000..67e33f3e178 --- /dev/null +++ b/queue-5.4/tools-testing-nvdimm-fix-compilation-failure-without.patch @@ -0,0 +1,45 @@ +From 29234079c578bfbb26aeb6be7509694c6b38224d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://lore.kernel.org/r/20200123154720.12097-1-jack@suse.cz +Signed-off-by: Dan Williams +Signed-off-by: Sasha Levin +--- + tools/testing/nvdimm/test/nfit.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c +index bf6422a6af7ff..a8ee5c4d41ebb 100644 +--- a/tools/testing/nvdimm/test/nfit.c ++++ b/tools/testing/nvdimm/test/nfit.c +@@ -3164,7 +3164,9 @@ static __init int nfit_test_init(void) + mcsafe_test(); + dax_pmem_test(); + dax_pmem_core_test(); ++#ifdef CONFIG_DEV_DAX_PMEM_COMPAT + dax_pmem_compat_test(); ++#endif + + nfit_test_setup(nfit_test_lookup, nfit_test_evaluate_dsm); + +-- +2.20.1 + diff --git a/queue-5.4/tracing-selftests-turn-off-timeout-setting.patch b/queue-5.4/tracing-selftests-turn-off-timeout-setting.patch new file mode 100644 index 00000000000..7f94abc09aa --- /dev/null +++ b/queue-5.4/tracing-selftests-turn-off-timeout-setting.patch @@ -0,0 +1,35 @@ +From fd0c6a4017aeaf954ee7ecff8daebb1fdb5726fe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Nov 2019 11:48:39 -0500 +Subject: tracing/selftests: Turn off timeout setting + +From: Steven Rostedt (VMware) + +[ 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 +Tested-by: Miroslav Benes +Reviewed-by: Miroslav Benes +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/ftrace/settings | 1 + + 1 file changed, 1 insertion(+) + create mode 100644 tools/testing/selftests/ftrace/settings + +diff --git a/tools/testing/selftests/ftrace/settings b/tools/testing/selftests/ftrace/settings +new file mode 100644 +index 0000000000000..e7b9417537fbc +--- /dev/null ++++ b/tools/testing/selftests/ftrace/settings +@@ -0,0 +1 @@ ++timeout=0 +-- +2.20.1 + diff --git a/queue-5.4/virtio-blk-improve-virtqueue-error-to-blk_sts.patch b/queue-5.4/virtio-blk-improve-virtqueue-error-to-blk_sts.patch new file mode 100644 index 00000000000..ce0592369ea --- /dev/null +++ b/queue-5.4/virtio-blk-improve-virtqueue-error-to-blk_sts.patch @@ -0,0 +1,47 @@ +From 3e226fbd70234cdd197ba7113fa4b461554d5550 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Feb 2020 13:37:28 +0100 +Subject: virtio-blk: improve virtqueue error to BLK_STS + +From: Halil Pasic + +[ 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 +Link: https://lore.kernel.org/r/20200213123728.61216-3-pasic@linux.ibm.com +Signed-off-by: Michael S. Tsirkin +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Sasha Levin +--- + drivers/block/virtio_blk.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c +index c2ed3e9128e3a..a55383b139df9 100644 +--- a/drivers/block/virtio_blk.c ++++ b/drivers/block/virtio_blk.c +@@ -345,9 +345,14 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx, + if (err == -ENOSPC) + blk_mq_stop_hw_queue(hctx); + spin_unlock_irqrestore(&vblk->vqs[qid].lock, flags); +- if (err == -ENOMEM || err == -ENOSPC) ++ switch (err) { ++ case -ENOSPC: + return BLK_STS_DEV_RESOURCE; +- return BLK_STS_IOERR; ++ case -ENOMEM: ++ return BLK_STS_RESOURCE; ++ default: ++ return BLK_STS_IOERR; ++ } + } + + if (bd->last && virtqueue_kick_prepare(vblk->vqs[qid].vq)) +-- +2.20.1 + diff --git a/queue-5.4/watchdog-reset-last_hw_keepalive-time-at-start.patch b/queue-5.4/watchdog-reset-last_hw_keepalive-time-at-start.patch new file mode 100644 index 00000000000..4591071967f --- /dev/null +++ b/queue-5.4/watchdog-reset-last_hw_keepalive-time-at-start.patch @@ -0,0 +1,42 @@ +From 5b9ecd7cc78b444cf0f792ed831949123f971e86 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Mar 2020 11:58:06 +0200 +Subject: watchdog: reset last_hw_keepalive time at start + +From: Tero Kristo + +[ 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 +Reviewed-by: Guenter Roeck +Link: https://lore.kernel.org/r/20200302200426.6492-3-t-kristo@ti.com +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Sasha Levin +--- + drivers/watchdog/watchdog_dev.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c +index ce04edc69e5f0..c4147e93aa7d4 100644 +--- a/drivers/watchdog/watchdog_dev.c ++++ b/drivers/watchdog/watchdog_dev.c +@@ -282,6 +282,7 @@ static int watchdog_start(struct watchdog_device *wdd) + if (err == 0) { + set_bit(WDOG_ACTIVE, &wdd->status); + wd_data->last_keepalive = started_at; ++ wd_data->last_hw_keepalive = started_at; + watchdog_update_worker(wdd); + } + +-- +2.20.1 + diff --git a/queue-5.4/xhci-ensure-link-state-is-u3-after-setting-usb_ss_po.patch b/queue-5.4/xhci-ensure-link-state-is-u3-after-setting-usb_ss_po.patch new file mode 100644 index 00000000000..38d3e14cbff --- /dev/null +++ b/queue-5.4/xhci-ensure-link-state-is-u3-after-setting-usb_ss_po.patch @@ -0,0 +1,54 @@ +From 82d48e68841d77c8fa61a8586e937aab8d41cdff Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20200312144517.1593-7-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/host/xhci-hub.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c +index af92b2576fe91..712cd44f05ace 100644 +--- a/drivers/usb/host/xhci-hub.c ++++ b/drivers/usb/host/xhci-hub.c +@@ -1322,7 +1322,16 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, + xhci_set_link_state(xhci, ports[wIndex], link_state); + + spin_unlock_irqrestore(&xhci->lock, flags); +- msleep(20); /* wait device to enter */ ++ if (link_state == USB_SS_PORT_LS_U3) { ++ int retries = 16; ++ ++ while (retries--) { ++ usleep_range(4000, 8000); ++ temp = readl(ports[wIndex]->addr); ++ if ((temp & PORT_PLS_MASK) == XDEV_U3) ++ break; ++ } ++ } + spin_lock_irqsave(&xhci->lock, flags); + + temp = readl(ports[wIndex]->addr); +-- +2.20.1 + diff --git a/queue-5.4/xhci-finetune-host-initiated-usb3-rootport-link-susp.patch b/queue-5.4/xhci-finetune-host-initiated-usb3-rootport-link-susp.patch new file mode 100644 index 00000000000..a543661933d --- /dev/null +++ b/queue-5.4/xhci-finetune-host-initiated-usb3-rootport-link-susp.patch @@ -0,0 +1,82 @@ +From 19f4998c462345f0d6f62a89077ddb87efbfbb59 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Mar 2020 16:45:16 +0200 +Subject: xhci: Finetune host initiated USB3 rootport link suspend and resume + +From: Mathias Nyman + +[ 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 +Link: https://lore.kernel.org/r/20200312144517.1593-9-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/host/xhci-hub.c | 36 +++++++++++++++++++++++++----------- + 1 file changed, 25 insertions(+), 11 deletions(-) + +diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c +index 02f52d4f74df8..a9c87eb8951e8 100644 +--- a/drivers/usb/host/xhci-hub.c ++++ b/drivers/usb/host/xhci-hub.c +@@ -1307,20 +1307,34 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, + goto error; + } + ++ /* ++ * set link to U0, steps depend on current link state. ++ * U3: set link to U0 and wait for u3exit completion. ++ * U1/U2: no PLC complete event, only set link to U0. ++ * Resume/Recovery: device initiated U0, only wait for ++ * completion ++ */ + if (link_state == USB_SS_PORT_LS_U0) { +- if ((temp & PORT_PLS_MASK) == XDEV_U0) +- break; ++ u32 pls = temp & PORT_PLS_MASK; ++ bool wait_u0 = false; + +- if (!((temp & PORT_PLS_MASK) == XDEV_U1 || +- (temp & PORT_PLS_MASK) == XDEV_U2 || +- (temp & PORT_PLS_MASK) == XDEV_U3)) { +- xhci_warn(xhci, "Can only set port %d to U0 from U state\n", +- wIndex); +- goto error; ++ /* already in U0 */ ++ if (pls == XDEV_U0) ++ break; ++ if (pls == XDEV_U3 || ++ pls == XDEV_RESUME || ++ pls == XDEV_RECOVERY) { ++ wait_u0 = true; ++ reinit_completion(&bus_state->u3exit_done[wIndex]); ++ } ++ if (pls <= XDEV_U3) /* U1, U2, U3 */ ++ xhci_set_link_state(xhci, ports[wIndex], ++ USB_SS_PORT_LS_U0); ++ if (!wait_u0) { ++ if (pls > XDEV_U3) ++ goto error; ++ break; + } +- reinit_completion(&bus_state->u3exit_done[wIndex]); +- xhci_set_link_state(xhci, ports[wIndex], +- USB_SS_PORT_LS_U0); + spin_unlock_irqrestore(&xhci->lock, flags); + if (!wait_for_completion_timeout(&bus_state->u3exit_done[wIndex], + msecs_to_jiffies(100))) +-- +2.20.1 + diff --git a/queue-5.4/xhci-wait-until-link-state-trainsits-to-u0-after-set.patch b/queue-5.4/xhci-wait-until-link-state-trainsits-to-u0-after-set.patch new file mode 100644 index 00000000000..f6244f1f9e5 --- /dev/null +++ b/queue-5.4/xhci-wait-until-link-state-trainsits-to-u0-after-set.patch @@ -0,0 +1,140 @@ +From c374aaae6b9a5505775dcf9d46bab8e940c061e9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20200312144517.1593-8-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 +