]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 4 May 2020 08:11:55 +0000 (10:11 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 4 May 2020 08:11:55 +0000 (10:11 +0200)
added patches:
drm-amd-display-fix-green-screen-issue-after-suspend.patch
drm-edid-fix-off-by-one-in-dispid-dtd-pixel-clock.patch
drm-qxl-qxl_release-leak-in-qxl_draw_dirty_fb.patch
drm-qxl-qxl_release-leak-in-qxl_hw_surface_alloc.patch
drm-qxl-qxl_release-use-after-free.patch
nfsv4.1-fix-handling-of-backchannel-binding-in-bind_conn_to_session.patch

queue-5.4/drm-amd-display-fix-green-screen-issue-after-suspend.patch [new file with mode: 0644]
queue-5.4/drm-edid-fix-off-by-one-in-dispid-dtd-pixel-clock.patch [new file with mode: 0644]
queue-5.4/drm-qxl-qxl_release-leak-in-qxl_draw_dirty_fb.patch [new file with mode: 0644]
queue-5.4/drm-qxl-qxl_release-leak-in-qxl_hw_surface_alloc.patch [new file with mode: 0644]
queue-5.4/drm-qxl-qxl_release-use-after-free.patch [new file with mode: 0644]
queue-5.4/nfsv4.1-fix-handling-of-backchannel-binding-in-bind_conn_to_session.patch [new file with mode: 0644]
queue-5.4/series

diff --git a/queue-5.4/drm-amd-display-fix-green-screen-issue-after-suspend.patch b/queue-5.4/drm-amd-display-fix-green-screen-issue-after-suspend.patch
new file mode 100644 (file)
index 0000000..4d55028
--- /dev/null
@@ -0,0 +1,170 @@
+From 87b7ebc2e16c14d32a912f18206a4d6cc9abc3e8 Mon Sep 17 00:00:00 2001
+From: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
+Date: Wed, 22 Apr 2020 17:43:26 -0400
+Subject: drm/amd/display: Fix green screen issue after suspend
+
+From: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
+
+commit 87b7ebc2e16c14d32a912f18206a4d6cc9abc3e8 upstream.
+
+[why]
+We have seen a green screen after resume from suspend in a Raven system
+connected with two displays (HDMI and DP) on X based system. We noticed
+that this issue is related to bad DCC metadata from user space which may
+generate hangs and consequently an underflow on HUBP. After taking a
+deep look at the code path we realized that after resume we try to
+restore the commit with the DCC enabled framebuffer but the framebuffer
+is no longer valid.
+
+[how]
+This problem was only reported on Raven based system and after suspend,
+for this reason, this commit adds a new parameter on
+fill_plane_dcc_attributes() to give the option of disabling DCC
+programmatically. In summary, for disabling DCC we first verify if is a
+Raven system and if it is in suspend; if both conditions are true we
+disable DCC temporarily, otherwise, it is enabled.
+
+Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1099
+Co-developed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Signed-off-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
+Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
+Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   38 ++++++++++++++++------
+ 1 file changed, 29 insertions(+), 9 deletions(-)
+
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -2698,7 +2698,8 @@ fill_plane_dcc_attributes(struct amdgpu_
+                         const union dc_tiling_info *tiling_info,
+                         const uint64_t info,
+                         struct dc_plane_dcc_param *dcc,
+-                        struct dc_plane_address *address)
++                        struct dc_plane_address *address,
++                        bool force_disable_dcc)
+ {
+       struct dc *dc = adev->dm.dc;
+       struct dc_dcc_surface_param input;
+@@ -2710,6 +2711,9 @@ fill_plane_dcc_attributes(struct amdgpu_
+       memset(&input, 0, sizeof(input));
+       memset(&output, 0, sizeof(output));
++      if (force_disable_dcc)
++              return 0;
++
+       if (!offset)
+               return 0;
+@@ -2759,7 +2763,8 @@ fill_plane_buffer_attributes(struct amdg
+                            union dc_tiling_info *tiling_info,
+                            struct plane_size *plane_size,
+                            struct dc_plane_dcc_param *dcc,
+-                           struct dc_plane_address *address)
++                           struct dc_plane_address *address,
++                           bool force_disable_dcc)
+ {
+       const struct drm_framebuffer *fb = &afb->base;
+       int ret;
+@@ -2869,7 +2874,8 @@ fill_plane_buffer_attributes(struct amdg
+               ret = fill_plane_dcc_attributes(adev, afb, format, rotation,
+                                               plane_size, tiling_info,
+-                                              tiling_flags, dcc, address);
++                                              tiling_flags, dcc, address,
++                                              force_disable_dcc);
+               if (ret)
+                       return ret;
+       }
+@@ -2961,7 +2967,8 @@ fill_dc_plane_info_and_addr(struct amdgp
+                           const struct drm_plane_state *plane_state,
+                           const uint64_t tiling_flags,
+                           struct dc_plane_info *plane_info,
+-                          struct dc_plane_address *address)
++                          struct dc_plane_address *address,
++                          bool force_disable_dcc)
+ {
+       const struct drm_framebuffer *fb = plane_state->fb;
+       const struct amdgpu_framebuffer *afb =
+@@ -3040,7 +3047,8 @@ fill_dc_plane_info_and_addr(struct amdgp
+                                          plane_info->rotation, tiling_flags,
+                                          &plane_info->tiling_info,
+                                          &plane_info->plane_size,
+-                                         &plane_info->dcc, address);
++                                         &plane_info->dcc, address,
++                                         force_disable_dcc);
+       if (ret)
+               return ret;
+@@ -3063,6 +3071,7 @@ static int fill_dc_plane_attributes(stru
+       struct dc_plane_info plane_info;
+       uint64_t tiling_flags;
+       int ret;
++      bool force_disable_dcc = false;
+       ret = fill_dc_scaling_info(plane_state, &scaling_info);
+       if (ret)
+@@ -3077,9 +3086,11 @@ static int fill_dc_plane_attributes(stru
+       if (ret)
+               return ret;
++      force_disable_dcc = adev->asic_type == CHIP_RAVEN && adev->in_suspend;
+       ret = fill_dc_plane_info_and_addr(adev, plane_state, tiling_flags,
+                                         &plane_info,
+-                                        &dc_plane_state->address);
++                                        &dc_plane_state->address,
++                                        force_disable_dcc);
+       if (ret)
+               return ret;
+@@ -4481,6 +4492,7 @@ static int dm_plane_helper_prepare_fb(st
+       uint64_t tiling_flags;
+       uint32_t domain;
+       int r;
++      bool force_disable_dcc = false;
+       dm_plane_state_old = to_dm_plane_state(plane->state);
+       dm_plane_state_new = to_dm_plane_state(new_state);
+@@ -4539,11 +4551,13 @@ static int dm_plane_helper_prepare_fb(st
+                       dm_plane_state_old->dc_state != dm_plane_state_new->dc_state) {
+               struct dc_plane_state *plane_state = dm_plane_state_new->dc_state;
++              force_disable_dcc = adev->asic_type == CHIP_RAVEN && adev->in_suspend;
+               fill_plane_buffer_attributes(
+                       adev, afb, plane_state->format, plane_state->rotation,
+                       tiling_flags, &plane_state->tiling_info,
+                       &plane_state->plane_size, &plane_state->dcc,
+-                      &plane_state->address);
++                      &plane_state->address,
++                      force_disable_dcc);
+       }
+       return 0;
+@@ -5767,7 +5781,12 @@ static void amdgpu_dm_commit_planes(stru
+               fill_dc_plane_info_and_addr(
+                       dm->adev, new_plane_state, tiling_flags,
+                       &bundle->plane_infos[planes_count],
+-                      &bundle->flip_addrs[planes_count].address);
++                      &bundle->flip_addrs[planes_count].address,
++                      false);
++
++              DRM_DEBUG_DRIVER("plane: id=%d dcc_en=%d\n",
++                               new_plane_state->plane->index,
++                               bundle->plane_infos[planes_count].dcc.enable);
+               bundle->surface_updates[planes_count].plane_info =
+                       &bundle->plane_infos[planes_count];
+@@ -7138,7 +7157,8 @@ dm_determine_update_type_for_commit(stru
+                               ret = fill_dc_plane_info_and_addr(
+                                       dm->adev, new_plane_state, tiling_flags,
+                                       &plane_info,
+-                                      &flip_addr.address);
++                                      &flip_addr.address,
++                                      false);
+                               if (ret)
+                                       goto cleanup;
diff --git a/queue-5.4/drm-edid-fix-off-by-one-in-dispid-dtd-pixel-clock.patch b/queue-5.4/drm-edid-fix-off-by-one-in-dispid-dtd-pixel-clock.patch
new file mode 100644 (file)
index 0000000..1abdfc7
--- /dev/null
@@ -0,0 +1,43 @@
+From 6292b8efe32e6be408af364132f09572aed14382 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com>
+Date: Thu, 23 Apr 2020 18:17:43 +0300
+Subject: drm/edid: Fix off-by-one in DispID DTD pixel clock
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ville Syrjälä <ville.syrjala@linux.intel.com>
+
+commit 6292b8efe32e6be408af364132f09572aed14382 upstream.
+
+The DispID DTD pixel clock is documented as:
+"00 00 00 h → FF FF FF h | Pixel clock ÷ 10,000 0.01 → 167,772.16 Mega Pixels per Sec"
+Which seems to imply that we to add one to the raw value.
+
+Reality seems to agree as there are tiled displays in the wild
+which currently show a 10kHz difference in the pixel clock
+between the tiles (one tile gets its mode from the base EDID,
+the other from the DispID block).
+
+Cc: stable@vger.kernel.org
+References: https://gitlab.freedesktop.org/drm/intel/-/issues/27
+Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20200423151743.18767-1-ville.syrjala@linux.intel.com
+Reviewed-by: Manasi Navare <manasi.d.navare@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/drm_edid.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/drm_edid.c
++++ b/drivers/gpu/drm/drm_edid.c
+@@ -4743,7 +4743,7 @@ static struct drm_display_mode *drm_mode
+       struct drm_display_mode *mode;
+       unsigned pixel_clock = (timings->pixel_clock[0] |
+                               (timings->pixel_clock[1] << 8) |
+-                              (timings->pixel_clock[2] << 16));
++                              (timings->pixel_clock[2] << 16)) + 1;
+       unsigned hactive = (timings->hactive[0] | timings->hactive[1] << 8) + 1;
+       unsigned hblank = (timings->hblank[0] | timings->hblank[1] << 8) + 1;
+       unsigned hsync = (timings->hsync[0] | (timings->hsync[1] & 0x7f) << 8) + 1;
diff --git a/queue-5.4/drm-qxl-qxl_release-leak-in-qxl_draw_dirty_fb.patch b/queue-5.4/drm-qxl-qxl_release-leak-in-qxl_draw_dirty_fb.patch
new file mode 100644 (file)
index 0000000..aac8cf0
--- /dev/null
@@ -0,0 +1,37 @@
+From 85e9b88af1e6164f19ec71381efd5e2bcfc17620 Mon Sep 17 00:00:00 2001
+From: Vasily Averin <vvs@virtuozzo.com>
+Date: Mon, 27 Apr 2020 08:32:46 +0300
+Subject: drm/qxl: qxl_release leak in qxl_draw_dirty_fb()
+
+From: Vasily Averin <vvs@virtuozzo.com>
+
+commit 85e9b88af1e6164f19ec71381efd5e2bcfc17620 upstream.
+
+ret should be changed to release allocated struct qxl_release
+
+Cc: stable@vger.kernel.org
+Fixes: 8002db6336dd ("qxl: convert qxl driver to proper use for reservations")
+Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
+Link: http://patchwork.freedesktop.org/patch/msgid/22cfd55f-07c8-95d0-a2f7-191b7153c3d4@virtuozzo.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/qxl/qxl_draw.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/qxl/qxl_draw.c
++++ b/drivers/gpu/drm/qxl/qxl_draw.c
+@@ -209,9 +209,10 @@ void qxl_draw_dirty_fb(struct qxl_device
+               goto out_release_backoff;
+       rects = drawable_set_clipping(qdev, num_clips, clips_bo);
+-      if (!rects)
++      if (!rects) {
++              ret = -EINVAL;
+               goto out_release_backoff;
+-
++      }
+       drawable = (struct qxl_drawable *)qxl_release_map(qdev, release);
+       drawable->clip.type = SPICE_CLIP_TYPE_RECTS;
diff --git a/queue-5.4/drm-qxl-qxl_release-leak-in-qxl_hw_surface_alloc.patch b/queue-5.4/drm-qxl-qxl_release-leak-in-qxl_hw_surface_alloc.patch
new file mode 100644 (file)
index 0000000..ed312cb
--- /dev/null
@@ -0,0 +1,35 @@
+From a65aa9c3676ffccb21361d52fcfedd5b5ff387d7 Mon Sep 17 00:00:00 2001
+From: Vasily Averin <vvs@virtuozzo.com>
+Date: Mon, 27 Apr 2020 08:32:51 +0300
+Subject: drm/qxl: qxl_release leak in qxl_hw_surface_alloc()
+
+From: Vasily Averin <vvs@virtuozzo.com>
+
+commit a65aa9c3676ffccb21361d52fcfedd5b5ff387d7 upstream.
+
+Cc: stable@vger.kernel.org
+Fixes: 8002db6336dd ("qxl: convert qxl driver to proper use for reservations")
+Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
+Link: http://patchwork.freedesktop.org/patch/msgid/2e5a13ae-9ab2-5401-aa4d-03d5f5593423@virtuozzo.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/qxl/qxl_cmd.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/qxl/qxl_cmd.c
++++ b/drivers/gpu/drm/qxl/qxl_cmd.c
+@@ -480,9 +480,10 @@ int qxl_hw_surface_alloc(struct qxl_devi
+               return ret;
+       ret = qxl_release_reserve_list(release, true);
+-      if (ret)
++      if (ret) {
++              qxl_release_free(qdev, release);
+               return ret;
+-
++      }
+       cmd = (struct qxl_surface_cmd *)qxl_release_map(qdev, release);
+       cmd->type = QXL_SURFACE_CMD_CREATE;
+       cmd->flags = QXL_SURF_FLAG_KEEP_DATA;
diff --git a/queue-5.4/drm-qxl-qxl_release-use-after-free.patch b/queue-5.4/drm-qxl-qxl_release-use-after-free.patch
new file mode 100644 (file)
index 0000000..f83c261
--- /dev/null
@@ -0,0 +1,115 @@
+From 933db73351d359f74b14f4af095808260aff11f9 Mon Sep 17 00:00:00 2001
+From: Vasily Averin <vvs@virtuozzo.com>
+Date: Wed, 29 Apr 2020 12:01:24 +0300
+Subject: drm/qxl: qxl_release use after free
+
+From: Vasily Averin <vvs@virtuozzo.com>
+
+commit 933db73351d359f74b14f4af095808260aff11f9 upstream.
+
+qxl_release should not be accesses after qxl_push_*_ring_release() calls:
+userspace driver can process submitted command quickly, move qxl_release
+into release_ring, generate interrupt and trigger garbage collector.
+
+It can lead to crashes in qxl driver or trigger memory corruption
+in some kmalloc-192 slab object
+
+Gerd Hoffmann proposes to swap the qxl_release_fence_buffer_objects() +
+qxl_push_{cursor,command}_ring_release() calls to close that race window.
+
+cc: stable@vger.kernel.org
+Fixes: f64122c1f6ad ("drm: add new QXL driver. (v1.4)")
+Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
+Link: http://patchwork.freedesktop.org/patch/msgid/fa17b338-66ae-f299-68fe-8d32419d9071@virtuozzo.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/qxl/qxl_cmd.c     |    5 ++---
+ drivers/gpu/drm/qxl/qxl_display.c |    6 +++---
+ drivers/gpu/drm/qxl/qxl_draw.c    |    2 +-
+ drivers/gpu/drm/qxl/qxl_ioctl.c   |    5 +----
+ 4 files changed, 7 insertions(+), 11 deletions(-)
+
+--- a/drivers/gpu/drm/qxl/qxl_cmd.c
++++ b/drivers/gpu/drm/qxl/qxl_cmd.c
+@@ -500,8 +500,8 @@ int qxl_hw_surface_alloc(struct qxl_devi
+       /* no need to add a release to the fence for this surface bo,
+          since it is only released when we ask to destroy the surface
+          and it would never signal otherwise */
+-      qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false);
+       qxl_release_fence_buffer_objects(release);
++      qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false);
+       surf->hw_surf_alloc = true;
+       spin_lock(&qdev->surf_id_idr_lock);
+@@ -543,9 +543,8 @@ int qxl_hw_surface_dealloc(struct qxl_de
+       cmd->surface_id = id;
+       qxl_release_unmap(qdev, release, &cmd->release_info);
+-      qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false);
+-
+       qxl_release_fence_buffer_objects(release);
++      qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false);
+       return 0;
+ }
+--- a/drivers/gpu/drm/qxl/qxl_display.c
++++ b/drivers/gpu/drm/qxl/qxl_display.c
+@@ -523,8 +523,8 @@ static int qxl_primary_apply_cursor(stru
+       cmd->u.set.visible = 1;
+       qxl_release_unmap(qdev, release, &cmd->release_info);
+-      qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
+       qxl_release_fence_buffer_objects(release);
++      qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
+       return ret;
+@@ -665,8 +665,8 @@ static void qxl_cursor_atomic_update(str
+       cmd->u.position.y = plane->state->crtc_y + fb->hot_y;
+       qxl_release_unmap(qdev, release, &cmd->release_info);
+-      qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
+       qxl_release_fence_buffer_objects(release);
++      qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
+       if (old_cursor_bo != NULL)
+               qxl_bo_unpin(old_cursor_bo);
+@@ -713,8 +713,8 @@ static void qxl_cursor_atomic_disable(st
+       cmd->type = QXL_CURSOR_HIDE;
+       qxl_release_unmap(qdev, release, &cmd->release_info);
+-      qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
+       qxl_release_fence_buffer_objects(release);
++      qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
+ }
+ static void qxl_update_dumb_head(struct qxl_device *qdev,
+--- a/drivers/gpu/drm/qxl/qxl_draw.c
++++ b/drivers/gpu/drm/qxl/qxl_draw.c
+@@ -243,8 +243,8 @@ void qxl_draw_dirty_fb(struct qxl_device
+       }
+       qxl_bo_kunmap(clips_bo);
+-      qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false);
+       qxl_release_fence_buffer_objects(release);
++      qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false);
+ out_release_backoff:
+       if (ret)
+--- a/drivers/gpu/drm/qxl/qxl_ioctl.c
++++ b/drivers/gpu/drm/qxl/qxl_ioctl.c
+@@ -261,11 +261,8 @@ static int qxl_process_single_command(st
+                       apply_surf_reloc(qdev, &reloc_info[i]);
+       }
++      qxl_release_fence_buffer_objects(release);
+       ret = qxl_push_command_ring_release(qdev, release, cmd->type, true);
+-      if (ret)
+-              qxl_release_backoff_reserve_list(release);
+-      else
+-              qxl_release_fence_buffer_objects(release);
+ out_free_bos:
+ out_free_release:
diff --git a/queue-5.4/nfsv4.1-fix-handling-of-backchannel-binding-in-bind_conn_to_session.patch b/queue-5.4/nfsv4.1-fix-handling-of-backchannel-binding-in-bind_conn_to_session.patch
new file mode 100644 (file)
index 0000000..b98eb59
--- /dev/null
@@ -0,0 +1,89 @@
+From dff58530c4ca8ce7ee5a74db431c6e35362cf682 Mon Sep 17 00:00:00 2001
+From: Olga Kornievskaia <olga.kornievskaia@gmail.com>
+Date: Fri, 24 Apr 2020 17:45:50 -0400
+Subject: NFSv4.1: fix handling of backchannel binding in BIND_CONN_TO_SESSION
+
+From: Olga Kornievskaia <olga.kornievskaia@gmail.com>
+
+commit dff58530c4ca8ce7ee5a74db431c6e35362cf682 upstream.
+
+Currently, if the client sends BIND_CONN_TO_SESSION with
+NFS4_CDFC4_FORE_OR_BOTH but only gets NFS4_CDFS4_FORE back it ignores
+that it wasn't able to enable a backchannel.
+
+To make sure, the client sends BIND_CONN_TO_SESSION as the first
+operation on the connections (ie., no other session compounds haven't
+been sent before), and if the client's request to bind the backchannel
+is not satisfied, then reset the connection and retry.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/nfs4proc.c           |    8 ++++++++
+ include/linux/nfs_xdr.h     |    2 ++
+ include/linux/sunrpc/clnt.h |    5 +++++
+ 3 files changed, 15 insertions(+)
+
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -7852,6 +7852,7 @@ static void
+ nfs4_bind_one_conn_to_session_done(struct rpc_task *task, void *calldata)
+ {
+       struct nfs41_bind_conn_to_session_args *args = task->tk_msg.rpc_argp;
++      struct nfs41_bind_conn_to_session_res *res = task->tk_msg.rpc_resp;
+       struct nfs_client *clp = args->client;
+       switch (task->tk_status) {
+@@ -7860,6 +7861,12 @@ nfs4_bind_one_conn_to_session_done(struc
+               nfs4_schedule_session_recovery(clp->cl_session,
+                               task->tk_status);
+       }
++      if (args->dir == NFS4_CDFC4_FORE_OR_BOTH &&
++                      res->dir != NFS4_CDFS4_BOTH) {
++              rpc_task_close_connection(task);
++              if (args->retries++ < MAX_BIND_CONN_TO_SESSION_RETRIES)
++                      rpc_restart_call(task);
++      }
+ }
+ static const struct rpc_call_ops nfs4_bind_one_conn_to_session_ops = {
+@@ -7882,6 +7889,7 @@ int nfs4_proc_bind_one_conn_to_session(s
+       struct nfs41_bind_conn_to_session_args args = {
+               .client = clp,
+               .dir = NFS4_CDFC4_FORE_OR_BOTH,
++              .retries = 0,
+       };
+       struct nfs41_bind_conn_to_session_res res;
+       struct rpc_message msg = {
+--- a/include/linux/nfs_xdr.h
++++ b/include/linux/nfs_xdr.h
+@@ -1307,11 +1307,13 @@ struct nfs41_impl_id {
+       struct nfstime4                 date;
+ };
++#define MAX_BIND_CONN_TO_SESSION_RETRIES 3
+ struct nfs41_bind_conn_to_session_args {
+       struct nfs_client               *client;
+       struct nfs4_sessionid           sessionid;
+       u32                             dir;
+       bool                            use_conn_in_rdma_mode;
++      int                             retries;
+ };
+ struct nfs41_bind_conn_to_session_res {
+--- a/include/linux/sunrpc/clnt.h
++++ b/include/linux/sunrpc/clnt.h
+@@ -237,5 +237,10 @@ static inline int rpc_reply_expected(str
+               (task->tk_msg.rpc_proc->p_decode != NULL);
+ }
++static inline void rpc_task_close_connection(struct rpc_task *task)
++{
++      if (task->tk_xprt)
++              xprt_force_disconnect(task->tk_xprt);
++}
+ #endif /* __KERNEL__ */
+ #endif /* _LINUX_SUNRPC_CLNT_H */
index c3cfb2d41067becd13fc81e6b2f8e5fc0892840b..d600046f85dbbce97148672a72ab3b36b5778074 100644 (file)
@@ -1 +1,7 @@
 dma-buf-fix-set_name-ioctl-uapi.patch
+drm-edid-fix-off-by-one-in-dispid-dtd-pixel-clock.patch
+drm-amd-display-fix-green-screen-issue-after-suspend.patch
+drm-qxl-qxl_release-leak-in-qxl_draw_dirty_fb.patch
+drm-qxl-qxl_release-leak-in-qxl_hw_surface_alloc.patch
+drm-qxl-qxl_release-use-after-free.patch
+nfsv4.1-fix-handling-of-backchannel-binding-in-bind_conn_to_session.patch