--- /dev/null
+From c9f6cb0646007e395bb9d2cfea56cb5eb53608d9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 1 Jan 2023 09:02:21 +0800
+Subject: btrfs: handle case when repair happens with dev-replace
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Qu Wenruo <wqu@suse.com>
+
+[ Upstream commit d73a27b86fc722c28a26ec64002e3a7dc86d1c07 ]
+
+[BUG]
+There is a bug report that a BUG_ON() in btrfs_repair_io_failure()
+(originally repair_io_failure() in v6.0 kernel) got triggered when
+replacing a unreliable disk:
+
+ BTRFS warning (device sda1): csum failed root 257 ino 2397453 off 39624704 csum 0xb0d18c75 expected csum 0x4dae9c5e mirror 3
+ kernel BUG at fs/btrfs/extent_io.c:2380!
+ invalid opcode: 0000 [#1] PREEMPT SMP NOPTI
+ CPU: 9 PID: 3614331 Comm: kworker/u257:2 Tainted: G OE 6.0.0-5-amd64 #1 Debian 6.0.10-2
+ Hardware name: Micro-Star International Co., Ltd. MS-7C60/TRX40 PRO WIFI (MS-7C60), BIOS 2.70 07/01/2021
+ Workqueue: btrfs-endio btrfs_end_bio_work [btrfs]
+ RIP: 0010:repair_io_failure+0x24a/0x260 [btrfs]
+ Call Trace:
+ <TASK>
+ clean_io_failure+0x14d/0x180 [btrfs]
+ end_bio_extent_readpage+0x412/0x6e0 [btrfs]
+ ? __switch_to+0x106/0x420
+ process_one_work+0x1c7/0x380
+ worker_thread+0x4d/0x380
+ ? rescuer_thread+0x3a0/0x3a0
+ kthread+0xe9/0x110
+ ? kthread_complete_and_exit+0x20/0x20
+ ret_from_fork+0x22/0x30
+
+[CAUSE]
+
+Before the BUG_ON(), we got some read errors from the replace target
+first, note the mirror number (3, which is beyond RAID1 duplication,
+thus it's read from the replace target device).
+
+Then at the BUG_ON() location, we are trying to writeback the repaired
+sectors back the failed device.
+
+The check looks like this:
+
+ ret = btrfs_map_block(fs_info, BTRFS_MAP_WRITE, logical,
+ &map_length, &bioc, mirror_num);
+ if (ret)
+ goto out_counter_dec;
+ BUG_ON(mirror_num != bioc->mirror_num);
+
+But inside btrfs_map_block(), we can modify bioc->mirror_num especially
+for dev-replace:
+
+ if (dev_replace_is_ongoing && mirror_num == map->num_stripes + 1 &&
+ !need_full_stripe(op) && dev_replace->tgtdev != NULL) {
+ ret = get_extra_mirror_from_replace(fs_info, logical, *length,
+ dev_replace->srcdev->devid,
+ &mirror_num,
+ &physical_to_patch_in_first_stripe);
+ patch_the_first_stripe_for_dev_replace = 1;
+ }
+
+Thus if we're repairing the replace target device, we're going to
+trigger that BUG_ON().
+
+But in reality, the read failure from the replace target device may be
+that, our replace hasn't reached the range we're reading, thus we're
+reading garbage, but with replace running, the range would be properly
+filled later.
+
+Thus in that case, we don't need to do anything but let the replace
+routine to handle it.
+
+[FIX]
+Instead of a BUG_ON(), just skip the repair if we're repairing the
+device replace target device.
+
+Reported-by: 小太 <nospam@kota.moe>
+Link: https://lore.kernel.org/linux-btrfs/CACsxjPYyJGQZ+yvjzxA1Nn2LuqkYqTCcUH43S=+wXhyf8S00Ag@mail.gmail.com/
+CC: stable@vger.kernel.org # 6.0+
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/extent_io.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
+index 4dcf22e051ff..acb3c5c3b025 100644
+--- a/fs/btrfs/extent_io.c
++++ b/fs/btrfs/extent_io.c
+@@ -580,7 +580,16 @@ static int repair_io_failure(struct btrfs_fs_info *fs_info, u64 ino, u64 start,
+ &map_length, &bioc, mirror_num);
+ if (ret)
+ goto out_counter_dec;
+- BUG_ON(mirror_num != bioc->mirror_num);
++ /*
++ * This happens when dev-replace is also running, and the
++ * mirror_num indicates the dev-replace target.
++ *
++ * In this case, we don't need to do anything, as the read
++ * error just means the replace progress hasn't reached our
++ * read range, and later replace routine would handle it well.
++ */
++ if (mirror_num != bioc->mirror_num)
++ goto out_counter_dec;
+ }
+
+ sector = bioc->stripes[bioc->mirror_num - 1].physical >> 9;
+--
+2.35.1
+
--- /dev/null
+From d12d63c7f614ce5caed503577b3a6d529600dd93 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Nov 2022 18:45:33 -0500
+Subject: drm/amd/display: Add check for DET fetch latency hiding for dcn32
+
+From: Dillon Varone <Dillon.Varone@amd.com>
+
+[ Upstream commit 6d4727c80947de0e6fad58b196a9d215e3b32608 ]
+
+[WHY?]
+Some configurations are constructed with very marginal DET buffers relative to
+the worst possible time required to fetch a swath.
+
+[HOW?]
+Add a check to see that the DET buffer allocated for each pipe can hide the
+latency for all pipes to fetch at least one swath.
+
+Reviewed-by: Alvin Lee <Alvin.Lee2@amd.com>
+Reviewed-by: Jun Lei <Jun.Lei@amd.com>
+Acked-by: Brian Chang <Brian.Chang@amd.com>
+Signed-off-by: Dillon Varone <Dillon.Varone@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: f3c23bea598a ("drm/amd/display: Uninitialized variables causing 4k60 UCLK to stay at DPM1 and not DPM0")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../dc/dml/dcn32/display_mode_vba_32.c | 39 +++++++++++
+ .../dc/dml/dcn32/display_mode_vba_util_32.c | 69 +++++++++++++++++++
+ .../dc/dml/dcn32/display_mode_vba_util_32.h | 18 +++++
+ .../drm/amd/display/dc/dml/display_mode_vba.h | 2 +
+ 4 files changed, 128 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
+index 9afd9ba23fb2..820042f6aaca 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
+@@ -670,6 +670,25 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman
+ v->cursor_bw[k] = mode_lib->vba.NumberOfCursors[k] * mode_lib->vba.CursorWidth[k][0] * mode_lib->vba.CursorBPP[k][0] / 8 / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) * mode_lib->vba.VRatio[k];
+ }
+
++ v->NotEnoughDETSwathFillLatencyHiding = dml32_CalculateDETSwathFillLatencyHiding(
++ mode_lib->vba.NumberOfActiveSurfaces,
++ mode_lib->vba.ReturnBW,
++ v->UrgentLatency,
++ mode_lib->vba.SwathHeightY,
++ mode_lib->vba.SwathHeightC,
++ v->swath_width_luma_ub,
++ v->swath_width_chroma_ub,
++ v->BytePerPixelDETY,
++ v->BytePerPixelDETC,
++ mode_lib->vba.DETBufferSizeY,
++ mode_lib->vba.DETBufferSizeC,
++ mode_lib->vba.DPPPerPlane,
++ mode_lib->vba.HTotal,
++ mode_lib->vba.PixelClock,
++ mode_lib->vba.VRatio,
++ mode_lib->vba.VRatioChroma,
++ mode_lib->vba.UsesMALLForPStateChange);
++
+ for (k = 0; k < mode_lib->vba.NumberOfActiveSurfaces; ++k) {
+ v->MaxVStartupLines[k] = ((mode_lib->vba.Interlace[k] &&
+ !mode_lib->vba.ProgressiveToInterlaceUnitInOPP) ?
+@@ -1664,6 +1683,7 @@ static void mode_support_configuration(struct vba_vars_st *v,
+ && mode_lib->vba.PTEBufferSizeNotExceeded[i][j] == true
+ && mode_lib->vba.DCCMetaBufferSizeNotExceeded[i][j] == true
+ && mode_lib->vba.NonsupportedDSCInputBPC == false
++ && mode_lib->vba.NotEnoughDETSwathFillLatencyHidingPerState[i][j] == false
+ && !mode_lib->vba.ExceededMALLSize
+ && ((mode_lib->vba.HostVMEnable == false
+ && !mode_lib->vba.ImmediateFlipRequiredFinal)
+@@ -3158,6 +3178,25 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
+ mode_lib->vba.UrgentBurstFactorChroma,
+ mode_lib->vba.UrgentBurstFactorCursor);
+
++ mode_lib->vba.NotEnoughDETSwathFillLatencyHidingPerState[i][j] = dml32_CalculateDETSwathFillLatencyHiding(
++ mode_lib->vba.NumberOfActiveSurfaces,
++ mode_lib->vba.ReturnBWPerState[i][j],
++ mode_lib->vba.UrgLatency[i],
++ mode_lib->vba.SwathHeightYThisState,
++ mode_lib->vba.SwathHeightCThisState,
++ mode_lib->vba.swath_width_luma_ub_this_state,
++ mode_lib->vba.swath_width_chroma_ub_this_state,
++ mode_lib->vba.BytePerPixelInDETY,
++ mode_lib->vba.BytePerPixelInDETC,
++ mode_lib->vba.DETBufferSizeYThisState,
++ mode_lib->vba.DETBufferSizeCThisState,
++ mode_lib->vba.NoOfDPPThisState,
++ mode_lib->vba.HTotal,
++ mode_lib->vba.PixelClock,
++ mode_lib->vba.VRatio,
++ mode_lib->vba.VRatioChroma,
++ mode_lib->vba.UsesMALLForPStateChange);
++
+ v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.VMDataOnlyReturnBWPerState = dml32_get_return_bw_mbps_vm_only(&mode_lib->vba.soc, i,
+ mode_lib->vba.DCFCLKState[i][j], mode_lib->vba.FabricClockPerState[i],
+ mode_lib->vba.DRAMSpeedPerState[i]);
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c
+index debe46b24a3e..5af601cff1a0 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c
+@@ -6228,3 +6228,72 @@ void dml32_CalculateImmediateFlipBandwithSupport(unsigned int NumberOfActiveSurf
+ *ImmediateFlipBandwidthSupport = (*TotalBandwidth <= ReturnBW);
+ *FractionOfUrgentBandwidth = *TotalBandwidth / ReturnBW;
+ }
++
++bool dml32_CalculateDETSwathFillLatencyHiding(unsigned int NumberOfActiveSurfaces,
++ double ReturnBW,
++ double UrgentLatency,
++ unsigned int SwathHeightY[],
++ unsigned int SwathHeightC[],
++ unsigned int SwathWidthY[],
++ unsigned int SwathWidthC[],
++ double BytePerPixelInDETY[],
++ double BytePerPixelInDETC[],
++ unsigned int DETBufferSizeY[],
++ unsigned int DETBufferSizeC[],
++ unsigned int NumOfDPP[],
++ unsigned int HTotal[],
++ double PixelClock[],
++ double VRatioY[],
++ double VRatioC[],
++ enum dm_use_mall_for_pstate_change_mode UsesMALLForPStateChange[DC__NUM_DPP__MAX])
++{
++ int k;
++ double SwathSizeAllSurfaces = 0;
++ double SwathSizeAllSurfacesInFetchTimeUs;
++ double DETSwathLatencyHidingUs;
++ double DETSwathLatencyHidingYUs;
++ double DETSwathLatencyHidingCUs;
++ double SwathSizePerSurfaceY[DC__NUM_DPP__MAX];
++ double SwathSizePerSurfaceC[DC__NUM_DPP__MAX];
++ bool NotEnoughDETSwathFillLatencyHiding = false;
++
++ /* calculate sum of single swath size for all pipes in bytes*/
++ for (k = 0; k < NumberOfActiveSurfaces; k++) {
++ SwathSizePerSurfaceY[k] += SwathHeightY[k] * SwathWidthY[k] * BytePerPixelInDETY[k] * NumOfDPP[k];
++
++ if (SwathHeightC[k] != 0)
++ SwathSizePerSurfaceC[k] += SwathHeightC[k] * SwathWidthC[k] * BytePerPixelInDETC[k] * NumOfDPP[k];
++ else
++ SwathSizePerSurfaceC[k] = 0;
++
++ SwathSizeAllSurfaces += SwathSizePerSurfaceY[k] + SwathSizePerSurfaceC[k];
++ }
++
++ SwathSizeAllSurfacesInFetchTimeUs = SwathSizeAllSurfaces / ReturnBW + UrgentLatency;
++
++ /* ensure all DET - 1 swath can hide a fetch for all surfaces */
++ for (k = 0; k < NumberOfActiveSurfaces; k++) {
++ double LineTime = HTotal[k] / PixelClock[k];
++
++ /* only care if surface is not phantom */
++ if (UsesMALLForPStateChange[k] != dm_use_mall_pstate_change_phantom_pipe) {
++ DETSwathLatencyHidingYUs = (dml_floor(DETBufferSizeY[k] / BytePerPixelInDETY[k] / SwathWidthY[k], 1.0) - SwathHeightY[k]) / VRatioY[k] * LineTime;
++
++ if (SwathHeightC[k] != 0) {
++ DETSwathLatencyHidingCUs = (dml_floor(DETBufferSizeC[k] / BytePerPixelInDETC[k] / SwathWidthC[k], 1.0) - SwathHeightC[k]) / VRatioC[k] * LineTime;
++
++ DETSwathLatencyHidingUs = dml_min(DETSwathLatencyHidingYUs, DETSwathLatencyHidingCUs);
++ } else {
++ DETSwathLatencyHidingUs = DETSwathLatencyHidingYUs;
++ }
++
++ /* DET must be able to hide time to fetch 1 swath for each surface */
++ if (DETSwathLatencyHidingUs < SwathSizeAllSurfacesInFetchTimeUs) {
++ NotEnoughDETSwathFillLatencyHiding = true;
++ break;
++ }
++ }
++ }
++
++ return NotEnoughDETSwathFillLatencyHiding;
++}
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h
+index 3989c2a28fae..779c6805f599 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h
+@@ -1141,4 +1141,22 @@ void dml32_CalculateImmediateFlipBandwithSupport(unsigned int NumberOfActiveSurf
+ double *FractionOfUrgentBandwidth,
+ bool *ImmediateFlipBandwidthSupport);
+
++bool dml32_CalculateDETSwathFillLatencyHiding(unsigned int NumberOfActiveSurfaces,
++ double ReturnBW,
++ double UrgentLatency,
++ unsigned int SwathHeightY[],
++ unsigned int SwathHeightC[],
++ unsigned int SwathWidthY[],
++ unsigned int SwathWidthC[],
++ double BytePerPixelInDETY[],
++ double BytePerPixelInDETC[],
++ unsigned int DETBufferSizeY[],
++ unsigned int DETBufferSizeC[],
++ unsigned int NumOfDPP[],
++ unsigned int HTotal[],
++ double PixelClock[],
++ double VRatioY[],
++ double VRatioC[],
++ enum dm_use_mall_for_pstate_change_mode UsesMALLForPStateChange[DC__NUM_DPP__MAX]);
++
+ #endif
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h
+index a0207a8f8756..2b34b02dbd45 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h
++++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h
+@@ -1041,6 +1041,7 @@ struct vba_vars_st {
+ double MinFullDETBufferingTime;
+ double AverageReadBandwidthGBytePerSecond;
+ bool FirstMainPlane;
++ bool NotEnoughDETSwathFillLatencyHiding;
+
+ unsigned int ViewportWidthChroma[DC__NUM_DPP__MAX];
+ unsigned int ViewportHeightChroma[DC__NUM_DPP__MAX];
+@@ -1224,6 +1225,7 @@ struct vba_vars_st {
+ unsigned int BlockWidthC[DC__NUM_DPP__MAX];
+ unsigned int SubViewportLinesNeededInMALL[DC__NUM_DPP__MAX];
+ bool VActiveBandwithSupport[DC__VOLTAGE_STATES][2];
++ bool NotEnoughDETSwathFillLatencyHidingPerState[DC__VOLTAGE_STATES][2];
+ struct dummy_vars dummy_vars;
+ };
+
+--
+2.35.1
+
--- /dev/null
+From 76cb7dc726e88b229d539ba1fafcd7edbe6a83df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Dec 2022 11:08:40 -0500
+Subject: drm/amd/display: Uninitialized variables causing 4k60 UCLK to stay at
+ DPM1 and not DPM0
+
+From: Samson Tam <samson.tam@amd.com>
+
+[ Upstream commit f3c23bea598ab7e8e4b8c5ca66598921310f718e ]
+
+[Why]
+SwathSizePerSurfaceY[] and SwathSizePerSurfaceC[] values are uninitialized
+ because we are using += instead of = operator.
+
+[How]
+Assign values in loop with = operator.
+
+Acked-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
+Signed-off-by: Samson Tam <samson.tam@amd.com>
+Reviewed-by: Aric Cyr <aric.cyr@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org # 6.0.x, 6.1.x
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c
+index 5af601cff1a0..b53feeaf5cf1 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c
+@@ -6257,12 +6257,12 @@ bool dml32_CalculateDETSwathFillLatencyHiding(unsigned int NumberOfActiveSurface
+ double SwathSizePerSurfaceC[DC__NUM_DPP__MAX];
+ bool NotEnoughDETSwathFillLatencyHiding = false;
+
+- /* calculate sum of single swath size for all pipes in bytes*/
++ /* calculate sum of single swath size for all pipes in bytes */
+ for (k = 0; k < NumberOfActiveSurfaces; k++) {
+- SwathSizePerSurfaceY[k] += SwathHeightY[k] * SwathWidthY[k] * BytePerPixelInDETY[k] * NumOfDPP[k];
++ SwathSizePerSurfaceY[k] = SwathHeightY[k] * SwathWidthY[k] * BytePerPixelInDETY[k] * NumOfDPP[k];
+
+ if (SwathHeightC[k] != 0)
+- SwathSizePerSurfaceC[k] += SwathHeightC[k] * SwathWidthC[k] * BytePerPixelInDETC[k] * NumOfDPP[k];
++ SwathSizePerSurfaceC[k] = SwathHeightC[k] * SwathWidthC[k] * BytePerPixelInDETC[k] * NumOfDPP[k];
+ else
+ SwathSizePerSurfaceC[k] = 0;
+
+--
+2.35.1
+
drm-amdkfd-fix-kernel-warning-during-topology-setup.patch
drm-i915-gvt-fix-gvt-debugfs-destroy.patch
drm-i915-gvt-fix-vgpu-debugfs-clean-in-remove.patch
+virtio-blk-use-a-helper-to-handle-request-queuing-er.patch
+virtio_blk-fix-signedness-bug-in-virtblk_prep_rq.patch
+drm-amd-display-add-check-for-det-fetch-latency-hidi.patch
+drm-amd-display-uninitialized-variables-causing-4k60.patch
+btrfs-handle-case-when-repair-happens-with-dev-repla.patch
--- /dev/null
+From bc6abb72bfab9a3bd0fad018c8c7be7f0b720fe1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 15 Oct 2022 23:41:26 -0400
+Subject: virtio-blk: use a helper to handle request queuing errors
+
+From: Dmitry Fomichev <dmitry.fomichev@wdc.com>
+
+[ Upstream commit 258896fcc786b4e7db238eba26f6dd080e0ff41e ]
+
+Define a new helper function, virtblk_fail_to_queue(), to
+clean up the error handling code in virtio_queue_rq().
+
+Signed-off-by: Dmitry Fomichev <dmitry.fomichev@wdc.com>
+Message-Id: <20221016034127.330942-2-dmitry.fomichev@wdc.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Stable-dep-of: a26116c1e740 ("virtio_blk: Fix signedness bug in virtblk_prep_rq()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/virtio_blk.c | 29 ++++++++++++++++-------------
+ 1 file changed, 16 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
+index 19da5defd734..3efe3da5f8c2 100644
+--- a/drivers/block/virtio_blk.c
++++ b/drivers/block/virtio_blk.c
+@@ -315,6 +315,19 @@ static void virtio_commit_rqs(struct blk_mq_hw_ctx *hctx)
+ virtqueue_notify(vq->vq);
+ }
+
++static blk_status_t virtblk_fail_to_queue(struct request *req, int rc)
++{
++ virtblk_cleanup_cmd(req);
++ switch (rc) {
++ case -ENOSPC:
++ return BLK_STS_DEV_RESOURCE;
++ case -ENOMEM:
++ return BLK_STS_RESOURCE;
++ default:
++ return BLK_STS_IOERR;
++ }
++}
++
+ static blk_status_t virtblk_prep_rq(struct blk_mq_hw_ctx *hctx,
+ struct virtio_blk *vblk,
+ struct request *req,
+@@ -327,10 +340,8 @@ static blk_status_t virtblk_prep_rq(struct blk_mq_hw_ctx *hctx,
+ return status;
+
+ vbr->sg_table.nents = virtblk_map_data(hctx, req, vbr);
+- if (unlikely(vbr->sg_table.nents < 0)) {
+- virtblk_cleanup_cmd(req);
+- return BLK_STS_RESOURCE;
+- }
++ if (unlikely(vbr->sg_table.nents < 0))
++ return virtblk_fail_to_queue(req, -ENOMEM);
+
+ blk_mq_start_request(req);
+
+@@ -364,15 +375,7 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx,
+ blk_mq_stop_hw_queue(hctx);
+ spin_unlock_irqrestore(&vblk->vqs[qid].lock, flags);
+ virtblk_unmap_data(req, vbr);
+- virtblk_cleanup_cmd(req);
+- switch (err) {
+- case -ENOSPC:
+- return BLK_STS_DEV_RESOURCE;
+- case -ENOMEM:
+- return BLK_STS_RESOURCE;
+- default:
+- return BLK_STS_IOERR;
+- }
++ return virtblk_fail_to_queue(req, err);
+ }
+
+ if (bd->last && virtqueue_kick_prepare(vblk->vqs[qid].vq))
+--
+2.35.1
+
--- /dev/null
+From cbb2e59e1d2b68825db8b13c94ffd89686df44ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Oct 2022 17:41:26 -0300
+Subject: virtio_blk: Fix signedness bug in virtblk_prep_rq()
+
+From: Rafael Mendonca <rafaelmendsr@gmail.com>
+
+[ Upstream commit a26116c1e74028914f281851488546c91cbae57d ]
+
+The virtblk_map_data() function returns negative error codes, however, the
+'nents' field of vbr->sg_table is an unsigned int, which causes the error
+handling not to work correctly.
+
+Cc: stable@vger.kernel.org
+Fixes: 0e9911fa768f ("virtio-blk: support mq_ops->queue_rqs()")
+Signed-off-by: Rafael Mendonca <rafaelmendsr@gmail.com>
+Message-Id: <20221021204126.927603-1-rafaelmendsr@gmail.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
+Reviewed-by: Suwan Kim <suwan.kim027@gmail.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Acked-by: Jason Wang <jasowang@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/virtio_blk.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
+index 3efe3da5f8c2..a7697027ce43 100644
+--- a/drivers/block/virtio_blk.c
++++ b/drivers/block/virtio_blk.c
+@@ -334,14 +334,16 @@ static blk_status_t virtblk_prep_rq(struct blk_mq_hw_ctx *hctx,
+ struct virtblk_req *vbr)
+ {
+ blk_status_t status;
++ int num;
+
+ status = virtblk_setup_cmd(vblk->vdev, req, vbr);
+ if (unlikely(status))
+ return status;
+
+- vbr->sg_table.nents = virtblk_map_data(hctx, req, vbr);
+- if (unlikely(vbr->sg_table.nents < 0))
++ num = virtblk_map_data(hctx, req, vbr);
++ if (unlikely(num < 0))
+ return virtblk_fail_to_queue(req, -ENOMEM);
++ vbr->sg_table.nents = num;
+
+ blk_mq_start_request(req);
+
+--
+2.35.1
+