]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.15
authorSasha Levin <sashal@kernel.org>
Mon, 15 May 2023 01:42:10 +0000 (21:42 -0400)
committerSasha Levin <sashal@kernel.org>
Mon, 15 May 2023 01:42:10 +0000 (21:42 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
17 files changed:
queue-5.15/drm-amd-display-add-null-plane_state-check-for-curso.patch [new file with mode: 0644]
queue-5.15/drm-amd-display-refine-condition-of-cursor-visibilit.patch [new file with mode: 0644]
queue-5.15/drm-i915-dg2-add-additional-hdmi-pixel-clock-frequen.patch [new file with mode: 0644]
queue-5.15/drm-i915-dg2-add-hdmi-pixel-clock-frequencies-267.30.patch [new file with mode: 0644]
queue-5.15/drm-i915-dg2-support-4k-30-on-hdmi.patch [new file with mode: 0644]
queue-5.15/drm-msm-adreno-fix-runtime-pm-imbalance-at-gpu-load.patch [new file with mode: 0644]
queue-5.15/drm-msm-remove-struct_mutex-usage.patch [new file with mode: 0644]
queue-5.15/ksmbd-add-channel-rwlock.patch [new file with mode: 0644]
queue-5.15/ksmbd-fix-deadlock-in-ksmbd_find_crypto_ctx.patch [new file with mode: 0644]
queue-5.15/ksmbd-fix-kernel-oops-from-idr_remove.patch [new file with mode: 0644]
queue-5.15/ksmbd-fix-multi-session-connection-failure.patch [new file with mode: 0644]
queue-5.15/ksmbd-fix-racy-issue-while-destroying-session-on-mul.patch [new file with mode: 0644]
queue-5.15/ksmbd-not-allow-guest-user-on-multichannel.patch [new file with mode: 0644]
queue-5.15/ksmbd-replace-sessions-list-in-connection-with-xarra.patch [new file with mode: 0644]
queue-5.15/ksmbd-set-rss-capable-in-fsctl_query_network_interfa.patch [new file with mode: 0644]
queue-5.15/series
queue-5.15/wifi-rtw88-rtw8821c-fix-rfe_option-field-width.patch [new file with mode: 0644]

diff --git a/queue-5.15/drm-amd-display-add-null-plane_state-check-for-curso.patch b/queue-5.15/drm-amd-display-add-null-plane_state-check-for-curso.patch
new file mode 100644 (file)
index 0000000..8da5045
--- /dev/null
@@ -0,0 +1,48 @@
+From aaaeb1f496a41bc5c232bb302489c1fb47ac214f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Mar 2023 09:11:29 -0500
+Subject: drm/amd/display: Add NULL plane_state check for cursor disable logic
+
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+
+[ Upstream commit d29fb7baab09b6a1dc484c9c67933253883e770a ]
+
+[Why]
+While scanning the top_pipe connections we can run into a case where
+the bottom pipe is still connected to a top_pipe but with a NULL
+plane_state.
+
+[How]
+Treat a NULL plane_state the same as the plane being invisible for
+pipe cursor disable logic.
+
+Cc: stable@vger.kernel.org
+Cc: Mario Limonciello <mario.limonciello@amd.com>
+Reviewed-by: Charlene Liu <Charlene.Liu@amd.com>
+Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
+Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+index eef6e4c80a37f..73457c32f3e7f 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+@@ -3225,7 +3225,9 @@ static bool dcn10_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx)
+       for (test_pipe = pipe_ctx->top_pipe; test_pipe;
+            test_pipe = test_pipe->top_pipe) {
+               // Skip invisible layer and pipe-split plane on same layer
+-              if (!test_pipe->plane_state->visible || test_pipe->plane_state->layer_index == cur_layer)
++              if (!test_pipe->plane_state ||
++                  !test_pipe->plane_state->visible ||
++                  test_pipe->plane_state->layer_index == cur_layer)
+                       continue;
+               r2 = test_pipe->plane_res.scl_data.recout;
+-- 
+2.39.2
+
diff --git a/queue-5.15/drm-amd-display-refine-condition-of-cursor-visibilit.patch b/queue-5.15/drm-amd-display-refine-condition-of-cursor-visibilit.patch
new file mode 100644 (file)
index 0000000..ca0c551
--- /dev/null
@@ -0,0 +1,102 @@
+From fd496132ad6ffe4d8bd6b7ee1fcea67a7e21110f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 Aug 2021 16:44:37 +0800
+Subject: drm/amd/display: Refine condition of cursor visibility for pipe-split
+
+From: Dale Zhao <dale.zhao@amd.com>
+
+[ Upstream commit 63f8bee439c0e3f94cff90d0f9c7b719be693265 ]
+
+[Why]
+In some scenarios like fullscreen game, major plane is scaled. Then
+if a upper layer owns the cursor, cursor is invisiable in the
+majority of the screen.
+
+[How]
+Instead assuming upper plane handles cursor, summing up upper
+split planes on the same layer. If whole upper plane covers current
+half/whole pipe plane, disable cursor.
+
+Reviewed-by: Krunoslav Kovac <Krunoslav.Kovac@amd.com>
+Acked-by: Mikita Lipski <mikita.lipski@amd.com>
+Signed-off-by: Dale Zhao <dale.zhao@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: d29fb7baab09 ("drm/amd/display: Add NULL plane_state check for cursor disable logic")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 43 +++++++++++--------
+ 1 file changed, 24 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+index c655d03ef754d..eef6e4c80a37f 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+@@ -3211,13 +3211,11 @@ void dcn10_update_dchub(struct dce_hwseq *hws, struct dchub_init_data *dh_data)
+ static bool dcn10_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx)
+ {
+-      struct pipe_ctx *test_pipe;
++      struct pipe_ctx *test_pipe, *split_pipe;
+       const struct scaler_data *scl_data = &pipe_ctx->plane_res.scl_data;
+-      const struct rect *r1 = &scl_data->recout, *r2;
+-      int r1_r = r1->x + r1->width, r1_b = r1->y + r1->height, r2_r, r2_b;
++      struct rect r1 = scl_data->recout, r2, r2_half;
++      int r1_r = r1.x + r1.width, r1_b = r1.y + r1.height, r2_r, r2_b;
+       int cur_layer = pipe_ctx->plane_state->layer_index;
+-      bool upper_pipe_exists = false;
+-      struct fixed31_32 one = dc_fixpt_from_int(1);
+       /**
+        * Disable the cursor if there's another pipe above this with a
+@@ -3226,26 +3224,33 @@ static bool dcn10_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx)
+        */
+       for (test_pipe = pipe_ctx->top_pipe; test_pipe;
+            test_pipe = test_pipe->top_pipe) {
+-              if (!test_pipe->plane_state->visible)
++              // Skip invisible layer and pipe-split plane on same layer
++              if (!test_pipe->plane_state->visible || test_pipe->plane_state->layer_index == cur_layer)
+                       continue;
+-              r2 = &test_pipe->plane_res.scl_data.recout;
+-              r2_r = r2->x + r2->width;
+-              r2_b = r2->y + r2->height;
++              r2 = test_pipe->plane_res.scl_data.recout;
++              r2_r = r2.x + r2.width;
++              r2_b = r2.y + r2.height;
++              split_pipe = test_pipe;
+-              if (r1->x >= r2->x && r1->y >= r2->y && r1_r <= r2_r && r1_b <= r2_b)
+-                      return true;
++              /**
++               * There is another half plane on same layer because of
++               * pipe-split, merge together per same height.
++               */
++              for (split_pipe = pipe_ctx->top_pipe; split_pipe;
++                   split_pipe = split_pipe->top_pipe)
++                      if (split_pipe->plane_state->layer_index == test_pipe->plane_state->layer_index) {
++                              r2_half = split_pipe->plane_res.scl_data.recout;
++                              r2.x = (r2_half.x < r2.x) ? r2_half.x : r2.x;
++                              r2.width = r2.width + r2_half.width;
++                              r2_r = r2.x + r2.width;
++                              break;
++                      }
+-              if (test_pipe->plane_state->layer_index < cur_layer)
+-                      upper_pipe_exists = true;
++              if (r1.x >= r2.x && r1.y >= r2.y && r1_r <= r2_r && r1_b <= r2_b)
++                      return true;
+       }
+-      // if plane scaled, assume an upper plane can handle cursor if it exists.
+-      if (upper_pipe_exists &&
+-                      (scl_data->ratios.horz.value != one.value ||
+-                      scl_data->ratios.vert.value != one.value))
+-              return true;
+-
+       return false;
+ }
+-- 
+2.39.2
+
diff --git a/queue-5.15/drm-i915-dg2-add-additional-hdmi-pixel-clock-frequen.patch b/queue-5.15/drm-i915-dg2-add-additional-hdmi-pixel-clock-frequen.patch
new file mode 100644 (file)
index 0000000..58ca50e
--- /dev/null
@@ -0,0 +1,1164 @@
+From 37f0743735931f63d8b34afa9047b159605aa62a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Aug 2022 16:48:56 -0700
+Subject: drm/i915/dg2: Add additional HDMI pixel clock frequencies
+
+From: Taylor, Clinton A <clinton.a.taylor@intel.com>
+
+[ Upstream commit 11c7faa61d136cef92506e4e77d0e6c6e01428bc ]
+
+Using the BSPEC algorithm add addition HDMI pixel clocks to the existing
+table.
+
+v2: remove 297000 unused entry
+
+Cc: Matt Roper <matthew.d.roper@intel.com>
+Cc: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
+Signed-off-by: Taylor, Clinton A <clinton.a.taylor@intel.com>
+Reviewed-by: Balasubramani Vivekanandan <balasubramani.vivekanandan@intel.com>
+[mattrope: Fixed minor whitepsace issue flagged by checkpatch]
+Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220801234856.2832317-1-clinton.a.taylor@intel.com
+Stable-dep-of: d46746b8b13c ("drm/i915/dg2: Add HDMI pixel clock frequencies 267.30 and 319.89 MHz")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/display/intel_snps_phy.c | 1116 +++++++++++++++++
+ 1 file changed, 1116 insertions(+)
+
+diff --git a/drivers/gpu/drm/i915/display/intel_snps_phy.c b/drivers/gpu/drm/i915/display/intel_snps_phy.c
+index 1e6ba0a377265..2030ef0b599f0 100644
+--- a/drivers/gpu/drm/i915/display/intel_snps_phy.c
++++ b/drivers/gpu/drm/i915/display/intel_snps_phy.c
+@@ -583,6 +583,1086 @@ static const struct intel_mpllb_state dg2_hdmi_148_5 = {
+ };
+ /* values in the below table are calculted using the algo */
++static const struct intel_mpllb_state dg2_hdmi_25200 = {
++      .clock = 25200,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 7) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 5) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 0),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 128) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 41943) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 2621),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_27027 = {
++      .clock = 27027,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 5) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 0),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 140) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 31876) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 46555),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_28320 = {
++      .clock = 28320,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 5) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 0),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 148) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 40894) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 30408),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_30240 = {
++      .clock = 30240,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 5) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 0),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 160) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 50331) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 42466),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_31500 = {
++      .clock = 31500,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 7) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 4) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 68) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 26214) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 26214),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_36000 = {
++      .clock = 36000,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 4) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 82) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 39321) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 39320),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_40000 = {
++      .clock = 40000,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 4) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 0) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 2),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 96) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 0) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 0) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 0),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_49500 = {
++      .clock = 49500,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 4) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 1),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 126) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 13107) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 13107),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_50000 = {
++      .clock = 50000,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 4) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 0) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 1),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 128) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 0) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 0) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 0),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_57284 = {
++      .clock = 57284,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 4) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 0),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 150) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 42886) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 49701),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_58000 = {
++      .clock = 58000,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 4) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 0),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 152) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 52428) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 52427),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_65000 = {
++      .clock = 65000,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 7) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 3) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 0) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 72) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 0) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 0) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 0),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_71000 = {
++      .clock = 71000,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 3) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 80) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 52428) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 52427),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_74176 = {
++      .clock = 74176,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 3) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 86) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 22334) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 43829),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_75000 = {
++      .clock = 75000,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 3) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 0) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 88) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 0) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 0) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 0),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_78750 = {
++      .clock = 78750,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 3) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 0) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 2),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 94) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 0) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 0) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 0),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_85500 = {
++      .clock = 85500,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 3) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 2),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 104) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 26214) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 26214),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_88750 = {
++      .clock = 88750,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 7) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 15) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 3) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 0) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 1),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 110) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 0) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 0) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 0),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_106500 = {
++      .clock = 106500,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 3) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 0),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 138) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 13107) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 13107),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_108000 = {
++      .clock = 108000,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 3) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 0),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 140) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 26214) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 26214),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_115500 = {
++      .clock = 115500,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 3) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 0),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 152) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 26214) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 26214),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_119000 = {
++      .clock = 119000,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 3) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 0),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 158) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 13107) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 13107),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_135000 = {
++      .clock = 135000,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 7) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 15) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 0) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 76) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 0) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 0) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 0),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_138500 = {
++      .clock = 138500,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 78) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 26214) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 26214),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_147160 = {
++      .clock = 147160,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 84) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 56623) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 6815),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_148352 = {
++      .clock = 148352,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 86) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 22334) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 43829),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_154000 = {
++      .clock = 154000,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 13) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 2),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 90) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 39321) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 39320),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_162000 = {
++      .clock = 162000,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 2),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 96) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 52428) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 52427),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_209800 = {
++      .clock = 209800,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 7) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 0),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 134) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 60293) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 7864),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_262750 = {
++      .clock = 262750,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 7) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 72) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 36044) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 52427),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_268500 = {
++      .clock = 268500,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 7) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 74) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 45875) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 13107),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_296703 = {
++      .clock = 296703,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 86) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 22321) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 36804),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_241500 = {
++      .clock = 241500,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 0),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 160) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 39321) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 39320),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_497750 = {
++      .clock = 497750,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 15) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 0),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 166) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 36044) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 52427),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_592000 = {
++      .clock = 592000,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 0) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 86) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 13107) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 13107),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
++static const struct intel_mpllb_state dg2_hdmi_593407 = {
++      .clock = 593407,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 0) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 86) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 22328) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 7549),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
+ static const struct intel_mpllb_state dg2_hdmi_297 = {
+       .clock = 297000,
+       .ref_control =
+@@ -649,6 +1729,42 @@ static const struct intel_mpllb_state *dg2_hdmi_tables[] = {
+       &dg2_hdmi_148_5,
+       &dg2_hdmi_297,
+       &dg2_hdmi_594,
++      &dg2_hdmi_25200,
++      &dg2_hdmi_27027,
++      &dg2_hdmi_28320,
++      &dg2_hdmi_30240,
++      &dg2_hdmi_31500,
++      &dg2_hdmi_36000,
++      &dg2_hdmi_40000,
++      &dg2_hdmi_49500,
++      &dg2_hdmi_50000,
++      &dg2_hdmi_57284,
++      &dg2_hdmi_58000,
++      &dg2_hdmi_65000,
++      &dg2_hdmi_71000,
++      &dg2_hdmi_74176,
++      &dg2_hdmi_75000,
++      &dg2_hdmi_78750,
++      &dg2_hdmi_85500,
++      &dg2_hdmi_88750,
++      &dg2_hdmi_106500,
++      &dg2_hdmi_108000,
++      &dg2_hdmi_115500,
++      &dg2_hdmi_119000,
++      &dg2_hdmi_135000,
++      &dg2_hdmi_138500,
++      &dg2_hdmi_147160,
++      &dg2_hdmi_148352,
++      &dg2_hdmi_154000,
++      &dg2_hdmi_162000,
++      &dg2_hdmi_209800,
++      &dg2_hdmi_241500,
++      &dg2_hdmi_262750,
++      &dg2_hdmi_268500,
++      &dg2_hdmi_296703,
++      &dg2_hdmi_497750,
++      &dg2_hdmi_592000,
++      &dg2_hdmi_593407,
+       NULL,
+ };
+-- 
+2.39.2
+
diff --git a/queue-5.15/drm-i915-dg2-add-hdmi-pixel-clock-frequencies-267.30.patch b/queue-5.15/drm-i915-dg2-add-hdmi-pixel-clock-frequencies-267.30.patch
new file mode 100644 (file)
index 0000000..81da49b
--- /dev/null
@@ -0,0 +1,116 @@
+From dde85629344dc14f02b8de7e9574745e00538403 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Feb 2023 10:06:19 +0530
+Subject: drm/i915/dg2: Add HDMI pixel clock frequencies 267.30 and 319.89 MHz
+
+From: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
+
+[ Upstream commit d46746b8b13cbd377ffc733e465d25800459a31b ]
+
+Add snps phy table values for HDMI pixel clocks 267.30 MHz and
+319.89 MHz. Values are based on the Bspec algorithm for
+PLL programming for HDMI.
+
+Cc: stable@vger.kernel.org
+Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/8008
+Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
+Reviewed-by: Uma Shankar <uma.shankar@intel.com>
+Signed-off-by: Uma Shankar <uma.shankar@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230223043619.3941382-1-ankit.k.nautiyal@intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/display/intel_snps_phy.c | 62 +++++++++++++++++++
+ 1 file changed, 62 insertions(+)
+
+diff --git a/drivers/gpu/drm/i915/display/intel_snps_phy.c b/drivers/gpu/drm/i915/display/intel_snps_phy.c
+index 2030ef0b599f0..170690fc735b5 100644
+--- a/drivers/gpu/drm/i915/display/intel_snps_phy.c
++++ b/drivers/gpu/drm/i915/display/intel_snps_phy.c
+@@ -1483,6 +1483,36 @@ static const struct intel_mpllb_state dg2_hdmi_262750 = {
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
+ };
++static const struct intel_mpllb_state dg2_hdmi_267300 = {
++      .clock = 267300,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 7) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 74) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 30146) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 36699),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
+ static const struct intel_mpllb_state dg2_hdmi_268500 = {
+       .clock = 268500,
+       .ref_control =
+@@ -1573,6 +1603,36 @@ static const struct intel_mpllb_state dg2_hdmi_241500 = {
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
+ };
++static const struct intel_mpllb_state dg2_hdmi_319890 = {
++      .clock = 319890,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 2),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 94) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 64094) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 13631),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
+ static const struct intel_mpllb_state dg2_hdmi_497750 = {
+       .clock = 497750,
+       .ref_control =
+@@ -1760,8 +1820,10 @@ static const struct intel_mpllb_state *dg2_hdmi_tables[] = {
+       &dg2_hdmi_209800,
+       &dg2_hdmi_241500,
+       &dg2_hdmi_262750,
++      &dg2_hdmi_267300,
+       &dg2_hdmi_268500,
+       &dg2_hdmi_296703,
++      &dg2_hdmi_319890,
+       &dg2_hdmi_497750,
+       &dg2_hdmi_592000,
+       &dg2_hdmi_593407,
+-- 
+2.39.2
+
diff --git a/queue-5.15/drm-i915-dg2-support-4k-30-on-hdmi.patch b/queue-5.15/drm-i915-dg2-support-4k-30-on-hdmi.patch
new file mode 100644 (file)
index 0000000..2dc5e4f
--- /dev/null
@@ -0,0 +1,82 @@
+From a2c357aa377de55ac7e5a6eb0b75fb713513b951 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 May 2022 13:34:01 +0530
+Subject: drm/i915/dg2: Support 4k@30 on HDMI
+
+From: Vandita Kulkarni <vandita.kulkarni@intel.com>
+
+[ Upstream commit edd34368c4c3b45b1386b15f78b2229420f8c6d4 ]
+
+This patch adds a fix to support 297MHz of dot clock by calculating
+the pll values using synopsis algorithm.
+This will help to support 4k@30 mode for HDMI monitors on DG2.
+
+v2: As per the algorithm, set MPLLB VCO range control bits to 3,
+in register SNPS_PHY_MPLLB_DIV for 297Mhz. (Matt)
+
+v3: Fix typo. (Ankit)
+
+Signed-off-by: Vandita Kulkarni <vandita.kulkarni@intel.com>
+Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
+Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
+Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220525080401.1253511-1-ankit.k.nautiyal@intel.com
+Stable-dep-of: d46746b8b13c ("drm/i915/dg2: Add HDMI pixel clock frequencies 267.30 and 319.89 MHz")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/display/intel_snps_phy.c | 32 +++++++++++++++++++
+ 1 file changed, 32 insertions(+)
+
+diff --git a/drivers/gpu/drm/i915/display/intel_snps_phy.c b/drivers/gpu/drm/i915/display/intel_snps_phy.c
+index 536b319ffe5ba..1e6ba0a377265 100644
+--- a/drivers/gpu/drm/i915/display/intel_snps_phy.c
++++ b/drivers/gpu/drm/i915/display/intel_snps_phy.c
+@@ -582,6 +582,37 @@ static const struct intel_mpllb_state dg2_hdmi_148_5 = {
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
+ };
++/* values in the below table are calculted using the algo */
++static const struct intel_mpllb_state dg2_hdmi_297 = {
++      .clock = 297000,
++      .ref_control =
++              REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
++      .mpllb_cp =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
++      .mpllb_div =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
++      .mpllb_div2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 86) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
++      .mpllb_fracn1 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
++      .mpllb_fracn2 =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 26214) |
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 26214),
++      .mpllb_sscen =
++              REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
++};
++
+ static const struct intel_mpllb_state dg2_hdmi_594 = {
+       .clock = 594000,
+       .ref_control =
+@@ -616,6 +647,7 @@ static const struct intel_mpllb_state *dg2_hdmi_tables[] = {
+       &dg2_hdmi_27_0,
+       &dg2_hdmi_74_25,
+       &dg2_hdmi_148_5,
++      &dg2_hdmi_297,
+       &dg2_hdmi_594,
+       NULL,
+ };
+-- 
+2.39.2
+
diff --git a/queue-5.15/drm-msm-adreno-fix-runtime-pm-imbalance-at-gpu-load.patch b/queue-5.15/drm-msm-adreno-fix-runtime-pm-imbalance-at-gpu-load.patch
new file mode 100644 (file)
index 0000000..42a1279
--- /dev/null
@@ -0,0 +1,76 @@
+From 854bbaeef7c21e7ac7894cccf342c41245ffebfc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Mar 2023 17:48:05 +0100
+Subject: drm/msm/adreno: fix runtime PM imbalance at gpu load
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+[ Upstream commit 0d997f95b70f98987ae031a89677c13e0e223670 ]
+
+A recent commit moved enabling of runtime PM to GPU load time (first
+open()) but failed to update the error paths so that runtime PM is
+disabled if initialisation of the GPU fails. This would trigger a
+warning about the unbalanced disable count on the next open() attempt.
+
+Note that pm_runtime_put_noidle() is sufficient to balance the usage
+count when pm_runtime_put_sync() fails (and is chosen over
+pm_runtime_resume_and_get() for consistency reasons).
+
+Fixes: 4b18299b3365 ("drm/msm/adreno: Defer enabling runpm until hw_init()")
+Cc: stable@vger.kernel.org      # 6.0
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Patchwork: https://patchwork.freedesktop.org/patch/524971/
+Link: https://lore.kernel.org/r/20230303164807.13124-3-johan+linaro@kernel.org
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/adreno/adreno_device.c | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c
+index afdfa9edbea3d..7c3d80e78fb8b 100644
+--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
++++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
+@@ -406,20 +406,21 @@ struct msm_gpu *adreno_load_gpu(struct drm_device *dev)
+       ret = pm_runtime_get_sync(&pdev->dev);
+       if (ret < 0) {
+-              pm_runtime_put_sync(&pdev->dev);
++              pm_runtime_put_noidle(&pdev->dev);
+               DRM_DEV_ERROR(dev->dev, "Couldn't power up the GPU: %d\n", ret);
+-              return NULL;
++              goto err_disable_rpm;
+       }
+       mutex_lock(&gpu->lock);
+       ret = msm_gpu_hw_init(gpu);
+       mutex_unlock(&gpu->lock);
+-      pm_runtime_put_autosuspend(&pdev->dev);
+       if (ret) {
+               DRM_DEV_ERROR(dev->dev, "gpu hw init failed: %d\n", ret);
+-              return NULL;
++              goto err_put_rpm;
+       }
++      pm_runtime_put_autosuspend(&pdev->dev);
++
+ #ifdef CONFIG_DEBUG_FS
+       if (gpu->funcs->debugfs_init) {
+               gpu->funcs->debugfs_init(gpu, dev->primary);
+@@ -428,6 +429,13 @@ struct msm_gpu *adreno_load_gpu(struct drm_device *dev)
+ #endif
+       return gpu;
++
++err_put_rpm:
++      pm_runtime_put_sync(&pdev->dev);
++err_disable_rpm:
++      pm_runtime_disable(&pdev->dev);
++
++      return NULL;
+ }
+ static void set_gpu_pdev(struct drm_device *dev,
+-- 
+2.39.2
+
diff --git a/queue-5.15/drm-msm-remove-struct_mutex-usage.patch b/queue-5.15/drm-msm-remove-struct_mutex-usage.patch
new file mode 100644 (file)
index 0000000..8467348
--- /dev/null
@@ -0,0 +1,359 @@
+From 23803255296607d4300e3f257062071bda6cfb9d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Nov 2021 10:11:03 -0800
+Subject: drm/msm: Remove struct_mutex usage
+
+From: Rob Clark <robdclark@chromium.org>
+
+[ Upstream commit c28e2f2b417ed747bfbc5f900c87f3ec9cc6b25e ]
+
+The remaining struct_mutex usage is just to serialize various gpu
+related things (submit/retire/recover/fault/etc), so replace
+struct_mutex with gpu->lock.
+
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Link: https://lore.kernel.org/r/20211109181117.591148-4-robdclark@gmail.com
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Stable-dep-of: 0d997f95b70f ("drm/msm/adreno: fix runtime PM imbalance at gpu load")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/adreno/a5xx_debugfs.c  |  4 ++--
+ drivers/gpu/drm/msm/adreno/adreno_device.c |  4 ++--
+ drivers/gpu/drm/msm/msm_debugfs.c          | 12 ++++++------
+ drivers/gpu/drm/msm/msm_gpu.c              | 14 +++++++-------
+ drivers/gpu/drm/msm/msm_gpu.h              | 20 +++++++++++++++-----
+ drivers/gpu/drm/msm/msm_perf.c             |  9 ++++++---
+ drivers/gpu/drm/msm/msm_rd.c               | 16 +++++++++-------
+ drivers/gpu/drm/msm/msm_ringbuffer.c       |  4 ++--
+ 8 files changed, 49 insertions(+), 34 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/adreno/a5xx_debugfs.c b/drivers/gpu/drm/msm/adreno/a5xx_debugfs.c
+index c9d11d57aed66..1aa39aa73e745 100644
+--- a/drivers/gpu/drm/msm/adreno/a5xx_debugfs.c
++++ b/drivers/gpu/drm/msm/adreno/a5xx_debugfs.c
+@@ -107,7 +107,7 @@ reset_set(void *data, u64 val)
+        * try to reset an active GPU.
+        */
+-      mutex_lock(&dev->struct_mutex);
++      mutex_lock(&gpu->lock);
+       release_firmware(adreno_gpu->fw[ADRENO_FW_PM4]);
+       adreno_gpu->fw[ADRENO_FW_PM4] = NULL;
+@@ -133,7 +133,7 @@ reset_set(void *data, u64 val)
+       gpu->funcs->recover(gpu);
+       pm_runtime_put_sync(&gpu->pdev->dev);
+-      mutex_unlock(&dev->struct_mutex);
++      mutex_unlock(&gpu->lock);
+       return 0;
+ }
+diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c
+index 3eb9146653444..afdfa9edbea3d 100644
+--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
++++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
+@@ -411,9 +411,9 @@ struct msm_gpu *adreno_load_gpu(struct drm_device *dev)
+               return NULL;
+       }
+-      mutex_lock(&dev->struct_mutex);
++      mutex_lock(&gpu->lock);
+       ret = msm_gpu_hw_init(gpu);
+-      mutex_unlock(&dev->struct_mutex);
++      mutex_unlock(&gpu->lock);
+       pm_runtime_put_autosuspend(&pdev->dev);
+       if (ret) {
+               DRM_DEV_ERROR(dev->dev, "gpu hw init failed: %d\n", ret);
+diff --git a/drivers/gpu/drm/msm/msm_debugfs.c b/drivers/gpu/drm/msm/msm_debugfs.c
+index dee13fedee3b5..f970a14b66336 100644
+--- a/drivers/gpu/drm/msm/msm_debugfs.c
++++ b/drivers/gpu/drm/msm/msm_debugfs.c
+@@ -29,14 +29,14 @@ static int msm_gpu_show(struct seq_file *m, void *arg)
+       struct msm_gpu *gpu = priv->gpu;
+       int ret;
+-      ret = mutex_lock_interruptible(&show_priv->dev->struct_mutex);
++      ret = mutex_lock_interruptible(&gpu->lock);
+       if (ret)
+               return ret;
+       drm_printf(&p, "%s Status:\n", gpu->name);
+       gpu->funcs->show(gpu, show_priv->state, &p);
+-      mutex_unlock(&show_priv->dev->struct_mutex);
++      mutex_unlock(&gpu->lock);
+       return 0;
+ }
+@@ -48,9 +48,9 @@ static int msm_gpu_release(struct inode *inode, struct file *file)
+       struct msm_drm_private *priv = show_priv->dev->dev_private;
+       struct msm_gpu *gpu = priv->gpu;
+-      mutex_lock(&show_priv->dev->struct_mutex);
++      mutex_lock(&gpu->lock);
+       gpu->funcs->gpu_state_put(show_priv->state);
+-      mutex_unlock(&show_priv->dev->struct_mutex);
++      mutex_unlock(&gpu->lock);
+       kfree(show_priv);
+@@ -72,7 +72,7 @@ static int msm_gpu_open(struct inode *inode, struct file *file)
+       if (!show_priv)
+               return -ENOMEM;
+-      ret = mutex_lock_interruptible(&dev->struct_mutex);
++      ret = mutex_lock_interruptible(&gpu->lock);
+       if (ret)
+               goto free_priv;
+@@ -81,7 +81,7 @@ static int msm_gpu_open(struct inode *inode, struct file *file)
+       show_priv->state = gpu->funcs->gpu_state_get(gpu);
+       pm_runtime_put_sync(&gpu->pdev->dev);
+-      mutex_unlock(&dev->struct_mutex);
++      mutex_unlock(&gpu->lock);
+       if (IS_ERR(show_priv->state)) {
+               ret = PTR_ERR(show_priv->state);
+diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
+index b01d0a521c908..a2f21b89d077c 100644
+--- a/drivers/gpu/drm/msm/msm_gpu.c
++++ b/drivers/gpu/drm/msm/msm_gpu.c
+@@ -150,7 +150,7 @@ int msm_gpu_hw_init(struct msm_gpu *gpu)
+ {
+       int ret;
+-      WARN_ON(!mutex_is_locked(&gpu->dev->struct_mutex));
++      WARN_ON(!mutex_is_locked(&gpu->lock));
+       if (!gpu->needs_hw_init)
+               return 0;
+@@ -361,7 +361,7 @@ static void recover_worker(struct kthread_work *work)
+       char *comm = NULL, *cmd = NULL;
+       int i;
+-      mutex_lock(&dev->struct_mutex);
++      mutex_lock(&gpu->lock);
+       DRM_DEV_ERROR(dev->dev, "%s: hangcheck recover!\n", gpu->name);
+@@ -442,7 +442,7 @@ static void recover_worker(struct kthread_work *work)
+               }
+       }
+-      mutex_unlock(&dev->struct_mutex);
++      mutex_unlock(&gpu->lock);
+       msm_gpu_retire(gpu);
+ }
+@@ -450,12 +450,11 @@ static void recover_worker(struct kthread_work *work)
+ static void fault_worker(struct kthread_work *work)
+ {
+       struct msm_gpu *gpu = container_of(work, struct msm_gpu, fault_work);
+-      struct drm_device *dev = gpu->dev;
+       struct msm_gem_submit *submit;
+       struct msm_ringbuffer *cur_ring = gpu->funcs->active_ring(gpu);
+       char *comm = NULL, *cmd = NULL;
+-      mutex_lock(&dev->struct_mutex);
++      mutex_lock(&gpu->lock);
+       submit = find_submit(cur_ring, cur_ring->memptrs->fence + 1);
+       if (submit && submit->fault_dumped)
+@@ -490,7 +489,7 @@ static void fault_worker(struct kthread_work *work)
+       memset(&gpu->fault_info, 0, sizeof(gpu->fault_info));
+       gpu->aspace->mmu->funcs->resume_translation(gpu->aspace->mmu);
+-      mutex_unlock(&dev->struct_mutex);
++      mutex_unlock(&gpu->lock);
+ }
+ static void hangcheck_timer_reset(struct msm_gpu *gpu)
+@@ -734,7 +733,7 @@ void msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
+       struct msm_ringbuffer *ring = submit->ring;
+       unsigned long flags;
+-      WARN_ON(!mutex_is_locked(&dev->struct_mutex));
++      WARN_ON(!mutex_is_locked(&gpu->lock));
+       pm_runtime_get_sync(&gpu->pdev->dev);
+@@ -849,6 +848,7 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
+       INIT_LIST_HEAD(&gpu->active_list);
+       mutex_init(&gpu->active_lock);
++      mutex_init(&gpu->lock);
+       kthread_init_work(&gpu->retire_work, retire_worker);
+       kthread_init_work(&gpu->recover_work, recover_worker);
+       kthread_init_work(&gpu->fault_work, fault_worker);
+diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
+index 2e2424066e701..461ff5a5aa5bb 100644
+--- a/drivers/gpu/drm/msm/msm_gpu.h
++++ b/drivers/gpu/drm/msm/msm_gpu.h
+@@ -143,13 +143,23 @@ struct msm_gpu {
+        */
+       struct list_head active_list;
++      /**
++       * lock:
++       *
++       * General lock for serializing all the gpu things.
++       *
++       * TODO move to per-ring locking where feasible (ie. submit/retire
++       * path, etc)
++       */
++      struct mutex lock;
++
+       /**
+        * active_submits:
+        *
+        * The number of submitted but not yet retired submits, used to
+        * determine transitions between active and idle.
+        *
+-       * Protected by lock
++       * Protected by active_lock
+        */
+       int active_submits;
+@@ -530,28 +540,28 @@ static inline struct msm_gpu_state *msm_gpu_crashstate_get(struct msm_gpu *gpu)
+ {
+       struct msm_gpu_state *state = NULL;
+-      mutex_lock(&gpu->dev->struct_mutex);
++      mutex_lock(&gpu->lock);
+       if (gpu->crashstate) {
+               kref_get(&gpu->crashstate->ref);
+               state = gpu->crashstate;
+       }
+-      mutex_unlock(&gpu->dev->struct_mutex);
++      mutex_unlock(&gpu->lock);
+       return state;
+ }
+ static inline void msm_gpu_crashstate_put(struct msm_gpu *gpu)
+ {
+-      mutex_lock(&gpu->dev->struct_mutex);
++      mutex_lock(&gpu->lock);
+       if (gpu->crashstate) {
+               if (gpu->funcs->gpu_state_put(gpu->crashstate))
+                       gpu->crashstate = NULL;
+       }
+-      mutex_unlock(&gpu->dev->struct_mutex);
++      mutex_unlock(&gpu->lock);
+ }
+ /*
+diff --git a/drivers/gpu/drm/msm/msm_perf.c b/drivers/gpu/drm/msm/msm_perf.c
+index 3a27153eef084..3d3da79fec2aa 100644
+--- a/drivers/gpu/drm/msm/msm_perf.c
++++ b/drivers/gpu/drm/msm/msm_perf.c
+@@ -155,9 +155,12 @@ static int perf_open(struct inode *inode, struct file *file)
+       struct msm_gpu *gpu = priv->gpu;
+       int ret = 0;
+-      mutex_lock(&dev->struct_mutex);
++      if (!gpu)
++              return -ENODEV;
+-      if (perf->open || !gpu) {
++      mutex_lock(&gpu->lock);
++
++      if (perf->open) {
+               ret = -EBUSY;
+               goto out;
+       }
+@@ -171,7 +174,7 @@ static int perf_open(struct inode *inode, struct file *file)
+       perf->next_jiffies = jiffies + SAMPLE_TIME;
+ out:
+-      mutex_unlock(&dev->struct_mutex);
++      mutex_unlock(&gpu->lock);
+       return ret;
+ }
+diff --git a/drivers/gpu/drm/msm/msm_rd.c b/drivers/gpu/drm/msm/msm_rd.c
+index e3f0dd4a36792..15a44491a42c3 100644
+--- a/drivers/gpu/drm/msm/msm_rd.c
++++ b/drivers/gpu/drm/msm/msm_rd.c
+@@ -86,7 +86,7 @@ struct msm_rd_state {
+       struct msm_gem_submit *submit;
+       /* fifo access is synchronized on the producer side by
+-       * struct_mutex held by submit code (otherwise we could
++       * gpu->lock held by submit code (otherwise we could
+        * end up w/ cmds logged in different order than they
+        * were executed).  And read_lock synchronizes the reads
+        */
+@@ -181,9 +181,12 @@ static int rd_open(struct inode *inode, struct file *file)
+       uint32_t gpu_id;
+       int ret = 0;
+-      mutex_lock(&dev->struct_mutex);
++      if (!gpu)
++              return -ENODEV;
+-      if (rd->open || !gpu) {
++      mutex_lock(&gpu->lock);
++
++      if (rd->open) {
+               ret = -EBUSY;
+               goto out;
+       }
+@@ -203,7 +206,7 @@ static int rd_open(struct inode *inode, struct file *file)
+       rd_write_section(rd, RD_GPU_ID, &gpu_id, sizeof(gpu_id));
+ out:
+-      mutex_unlock(&dev->struct_mutex);
++      mutex_unlock(&gpu->lock);
+       return ret;
+ }
+@@ -343,11 +346,10 @@ static void snapshot_buf(struct msm_rd_state *rd,
+       msm_gem_unlock(&obj->base);
+ }
+-/* called under struct_mutex */
++/* called under gpu->lock */
+ void msm_rd_dump_submit(struct msm_rd_state *rd, struct msm_gem_submit *submit,
+               const char *fmt, ...)
+ {
+-      struct drm_device *dev = submit->dev;
+       struct task_struct *task;
+       char msg[256];
+       int i, n;
+@@ -358,7 +360,7 @@ void msm_rd_dump_submit(struct msm_rd_state *rd, struct msm_gem_submit *submit,
+       /* writing into fifo is serialized by caller, and
+        * rd->read_lock is used to serialize the reads
+        */
+-      WARN_ON(!mutex_is_locked(&dev->struct_mutex));
++      WARN_ON(!mutex_is_locked(&submit->gpu->lock));
+       if (fmt) {
+               va_list args;
+diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.c b/drivers/gpu/drm/msm/msm_ringbuffer.c
+index bd54c14126497..a2314b75962fd 100644
+--- a/drivers/gpu/drm/msm/msm_ringbuffer.c
++++ b/drivers/gpu/drm/msm/msm_ringbuffer.c
+@@ -32,11 +32,11 @@ static struct dma_fence *msm_job_run(struct drm_sched_job *job)
+       pm_runtime_get_sync(&gpu->pdev->dev);
+       /* TODO move submit path over to using a per-ring lock.. */
+-      mutex_lock(&gpu->dev->struct_mutex);
++      mutex_lock(&gpu->lock);
+       msm_gpu_submit(gpu, submit);
+-      mutex_unlock(&gpu->dev->struct_mutex);
++      mutex_unlock(&gpu->lock);
+       pm_runtime_put(&gpu->pdev->dev);
+-- 
+2.39.2
+
diff --git a/queue-5.15/ksmbd-add-channel-rwlock.patch b/queue-5.15/ksmbd-add-channel-rwlock.patch
new file mode 100644 (file)
index 0000000..dd1cd7f
--- /dev/null
@@ -0,0 +1,139 @@
+From 7584fe5f147216d18ccb3b13f90cdeaad6cd6ecd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Jul 2022 10:15:57 +0900
+Subject: ksmbd: add channel rwlock
+
+From: Namjae Jeon <linkinjeon@kernel.org>
+
+[ Upstream commit 8e06b31e348107c5d78e2c90bb7e69388cb97fb6 ]
+
+Add missing rwlock for channel list in session.
+
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Stable-dep-of: 7b4323373d84 ("ksmbd: fix deadlock in ksmbd_find_crypto_ctx()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ksmbd/mgmt/user_session.c |  3 +++
+ fs/ksmbd/mgmt/user_session.h |  1 +
+ fs/ksmbd/smb2pdu.c           | 20 ++++++++++++++++++--
+ 3 files changed, 22 insertions(+), 2 deletions(-)
+
+diff --git a/fs/ksmbd/mgmt/user_session.c b/fs/ksmbd/mgmt/user_session.c
+index 8fe08df668582..0c7b5335c12af 100644
+--- a/fs/ksmbd/mgmt/user_session.c
++++ b/fs/ksmbd/mgmt/user_session.c
+@@ -32,11 +32,13 @@ static void free_channel_list(struct ksmbd_session *sess)
+ {
+       struct channel *chann, *tmp;
++      write_lock(&sess->chann_lock);
+       list_for_each_entry_safe(chann, tmp, &sess->ksmbd_chann_list,
+                                chann_list) {
+               list_del(&chann->chann_list);
+               kfree(chann);
+       }
++      write_unlock(&sess->chann_lock);
+ }
+ static void __session_rpc_close(struct ksmbd_session *sess,
+@@ -305,6 +307,7 @@ static struct ksmbd_session *__session_create(int protocol)
+       INIT_LIST_HEAD(&sess->rpc_handle_list);
+       sess->sequence_number = 1;
+       atomic_set(&sess->refcnt, 1);
++      rwlock_init(&sess->chann_lock);
+       switch (protocol) {
+       case CIFDS_SESSION_FLAG_SMB2:
+diff --git a/fs/ksmbd/mgmt/user_session.h b/fs/ksmbd/mgmt/user_session.h
+index 8b08189be3fc2..1ec659f0151bf 100644
+--- a/fs/ksmbd/mgmt/user_session.h
++++ b/fs/ksmbd/mgmt/user_session.h
+@@ -48,6 +48,7 @@ struct ksmbd_session {
+       char                            sess_key[CIFS_KEY_SIZE];
+       struct hlist_node               hlist;
++      rwlock_t                        chann_lock;
+       struct list_head                ksmbd_chann_list;
+       struct xarray                   tree_conns;
+       struct ida                      tree_conn_ida;
+diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c
+index d41995f89befe..e17f7a5dd9974 100644
+--- a/fs/ksmbd/smb2pdu.c
++++ b/fs/ksmbd/smb2pdu.c
+@@ -1525,7 +1525,9 @@ static int ntlm_authenticate(struct ksmbd_work *work)
+ binding_session:
+       if (conn->dialect >= SMB30_PROT_ID) {
++              read_lock(&sess->chann_lock);
+               chann = lookup_chann_list(sess, conn);
++              read_unlock(&sess->chann_lock);
+               if (!chann) {
+                       chann = kmalloc(sizeof(struct channel), GFP_KERNEL);
+                       if (!chann)
+@@ -1533,7 +1535,9 @@ static int ntlm_authenticate(struct ksmbd_work *work)
+                       chann->conn = conn;
+                       INIT_LIST_HEAD(&chann->chann_list);
++                      write_lock(&sess->chann_lock);
+                       list_add(&chann->chann_list, &sess->ksmbd_chann_list);
++                      write_unlock(&sess->chann_lock);
+               }
+       }
+@@ -1608,7 +1612,9 @@ static int krb5_authenticate(struct ksmbd_work *work)
+       }
+       if (conn->dialect >= SMB30_PROT_ID) {
++              read_lock(&sess->chann_lock);
+               chann = lookup_chann_list(sess, conn);
++              read_unlock(&sess->chann_lock);
+               if (!chann) {
+                       chann = kmalloc(sizeof(struct channel), GFP_KERNEL);
+                       if (!chann)
+@@ -1616,7 +1622,9 @@ static int krb5_authenticate(struct ksmbd_work *work)
+                       chann->conn = conn;
+                       INIT_LIST_HEAD(&chann->chann_list);
++                      write_lock(&sess->chann_lock);
+                       list_add(&chann->chann_list, &sess->ksmbd_chann_list);
++                      write_unlock(&sess->chann_lock);
+               }
+       }
+@@ -8388,10 +8396,14 @@ int smb3_check_sign_req(struct ksmbd_work *work)
+       if (le16_to_cpu(hdr->Command) == SMB2_SESSION_SETUP_HE) {
+               signing_key = work->sess->smb3signingkey;
+       } else {
++              read_lock(&work->sess->chann_lock);
+               chann = lookup_chann_list(work->sess, conn);
+-              if (!chann)
++              if (!chann) {
++                      read_unlock(&work->sess->chann_lock);
+                       return 0;
++              }
+               signing_key = chann->smb3signingkey;
++              read_unlock(&work->sess->chann_lock);
+       }
+       if (!signing_key) {
+@@ -8451,10 +8463,14 @@ void smb3_set_sign_rsp(struct ksmbd_work *work)
+           le16_to_cpu(hdr->Command) == SMB2_SESSION_SETUP_HE) {
+               signing_key = work->sess->smb3signingkey;
+       } else {
++              read_lock(&work->sess->chann_lock);
+               chann = lookup_chann_list(work->sess, work->conn);
+-              if (!chann)
++              if (!chann) {
++                      read_unlock(&work->sess->chann_lock);
+                       return;
++              }
+               signing_key = chann->smb3signingkey;
++              read_unlock(&work->sess->chann_lock);
+       }
+       if (!signing_key)
+-- 
+2.39.2
+
diff --git a/queue-5.15/ksmbd-fix-deadlock-in-ksmbd_find_crypto_ctx.patch b/queue-5.15/ksmbd-fix-deadlock-in-ksmbd_find_crypto_ctx.patch
new file mode 100644 (file)
index 0000000..d29d30a
--- /dev/null
@@ -0,0 +1,79 @@
+From d1aed81d3f634902eb47a032a4579d5a78b29b1e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 May 2023 08:44:14 +0900
+Subject: ksmbd: fix deadlock in ksmbd_find_crypto_ctx()
+
+From: Namjae Jeon <linkinjeon@kernel.org>
+
+[ Upstream commit 7b4323373d844954bb76e0e9f39c4e5fc785fa7b ]
+
+Deadlock is triggered by sending multiple concurrent session setup
+requests. It should be reused after releasing when getting ctx for crypto.
+Multiple consecutive ctx uses cause deadlock while waiting for releasing
+due to the limited number of ctx.
+
+Cc: stable@vger.kernel.org
+Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-20591
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ksmbd/auth.c | 19 +++++++++++--------
+ 1 file changed, 11 insertions(+), 8 deletions(-)
+
+diff --git a/fs/ksmbd/auth.c b/fs/ksmbd/auth.c
+index c1408e922fc6b..59d2059467465 100644
+--- a/fs/ksmbd/auth.c
++++ b/fs/ksmbd/auth.c
+@@ -220,22 +220,22 @@ int ksmbd_auth_ntlmv2(struct ksmbd_conn *conn, struct ksmbd_session *sess,
+ {
+       char ntlmv2_hash[CIFS_ENCPWD_SIZE];
+       char ntlmv2_rsp[CIFS_HMAC_MD5_HASH_SIZE];
+-      struct ksmbd_crypto_ctx *ctx;
++      struct ksmbd_crypto_ctx *ctx = NULL;
+       char *construct = NULL;
+       int rc, len;
+-      ctx = ksmbd_crypto_ctx_find_hmacmd5();
+-      if (!ctx) {
+-              ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
+-              return -ENOMEM;
+-      }
+-
+       rc = calc_ntlmv2_hash(conn, sess, ntlmv2_hash, domain_name);
+       if (rc) {
+               ksmbd_debug(AUTH, "could not get v2 hash rc %d\n", rc);
+               goto out;
+       }
++      ctx = ksmbd_crypto_ctx_find_hmacmd5();
++      if (!ctx) {
++              ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
++              return -ENOMEM;
++      }
++
+       rc = crypto_shash_setkey(CRYPTO_HMACMD5_TFM(ctx),
+                                ntlmv2_hash,
+                                CIFS_HMAC_MD5_HASH_SIZE);
+@@ -271,6 +271,8 @@ int ksmbd_auth_ntlmv2(struct ksmbd_conn *conn, struct ksmbd_session *sess,
+               ksmbd_debug(AUTH, "Could not generate md5 hash\n");
+               goto out;
+       }
++      ksmbd_release_crypto_ctx(ctx);
++      ctx = NULL;
+       rc = ksmbd_gen_sess_key(sess, ntlmv2_hash, ntlmv2_rsp);
+       if (rc) {
+@@ -281,7 +283,8 @@ int ksmbd_auth_ntlmv2(struct ksmbd_conn *conn, struct ksmbd_session *sess,
+       if (memcmp(ntlmv2->ntlmv2_hash, ntlmv2_rsp, CIFS_HMAC_MD5_HASH_SIZE) != 0)
+               rc = -EINVAL;
+ out:
+-      ksmbd_release_crypto_ctx(ctx);
++      if (ctx)
++              ksmbd_release_crypto_ctx(ctx);
+       kfree(construct);
+       return rc;
+ }
+-- 
+2.39.2
+
diff --git a/queue-5.15/ksmbd-fix-kernel-oops-from-idr_remove.patch b/queue-5.15/ksmbd-fix-kernel-oops-from-idr_remove.patch
new file mode 100644 (file)
index 0000000..128424c
--- /dev/null
@@ -0,0 +1,88 @@
+From e422c48bc373790c7a99f05459d85a5335552b26 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Jul 2022 10:17:06 +0900
+Subject: ksmbd: fix kernel oops from idr_remove()
+
+From: Namjae Jeon <linkinjeon@kernel.org>
+
+[ Upstream commit 17ea92a9f6d0b9a97aaec5ab748e4591d70a562c ]
+
+There is a report that kernel oops happen from idr_remove().
+
+kernel: BUG: kernel NULL pointer dereference, address: 0000000000000010
+kernel: RIP: 0010:idr_remove+0x1/0x20
+kernel:  __ksmbd_close_fd+0xb2/0x2d0 [ksmbd]
+kernel:  ksmbd_vfs_read+0x91/0x190 [ksmbd]
+kernel:  ksmbd_fd_put+0x29/0x40 [ksmbd]
+kernel:  smb2_read+0x210/0x390 [ksmbd]
+kernel:  __process_request+0xa4/0x180 [ksmbd]
+kernel:  __handle_ksmbd_work+0xf0/0x290 [ksmbd]
+kernel:  handle_ksmbd_work+0x2d/0x50 [ksmbd]
+kernel:  process_one_work+0x21d/0x3f0
+kernel:  worker_thread+0x50/0x3d0
+kernel:  rescuer_thread+0x390/0x390
+kernel:  kthread+0xee/0x120
+kthread_complete_and_exit+0x20/0x20
+kernel:  ret_from_fork+0x22/0x30
+
+While accessing files, If connection is disconnected, windows send
+session setup request included previous session destroy. But while still
+processing requests on previous session, this request destroy file
+table, which mean file table idr will be freed and set to NULL.
+So kernel oops happen from ft->idr in __ksmbd_close_fd().
+This patch don't directly destroy session in destroy_previous_session().
+It just set to KSMBD_SESS_EXITING so that connection will be
+terminated after finishing the rest of requests.
+
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Stable-dep-of: 7b4323373d84 ("ksmbd: fix deadlock in ksmbd_find_crypto_ctx()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ksmbd/mgmt/user_session.c | 2 ++
+ fs/ksmbd/smb2pdu.c           | 8 ++++++--
+ 2 files changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/fs/ksmbd/mgmt/user_session.c b/fs/ksmbd/mgmt/user_session.c
+index 0c7b5335c12af..9c4a9c8c02795 100644
+--- a/fs/ksmbd/mgmt/user_session.c
++++ b/fs/ksmbd/mgmt/user_session.c
+@@ -241,6 +241,8 @@ struct ksmbd_session *ksmbd_session_lookup_all(struct ksmbd_conn *conn,
+       sess = ksmbd_session_lookup(conn, id);
+       if (!sess && conn->binding)
+               sess = ksmbd_session_lookup_slowpath(id);
++      if (sess && sess->state != SMB2_SESSION_VALID)
++              sess = NULL;
+       return sess;
+ }
+diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c
+index e17f7a5dd9974..8bfe2a6c05f92 100644
+--- a/fs/ksmbd/smb2pdu.c
++++ b/fs/ksmbd/smb2pdu.c
+@@ -600,6 +600,7 @@ static void destroy_previous_session(struct ksmbd_conn *conn,
+ {
+       struct ksmbd_session *prev_sess = ksmbd_session_lookup_slowpath(id);
+       struct ksmbd_user *prev_user;
++      struct channel *chann;
+       if (!prev_sess)
+               return;
+@@ -615,8 +616,11 @@ static void destroy_previous_session(struct ksmbd_conn *conn,
+       }
+       put_session(prev_sess);
+-      xa_erase(&conn->sessions, prev_sess->id);
+-      ksmbd_session_destroy(prev_sess);
++      prev_sess->state = SMB2_SESSION_EXPIRED;
++      write_lock(&prev_sess->chann_lock);
++      list_for_each_entry(chann, &prev_sess->ksmbd_chann_list, chann_list)
++              chann->conn->status = KSMBD_SESS_EXITING;
++      write_unlock(&prev_sess->chann_lock);
+ }
+ /**
+-- 
+2.39.2
+
diff --git a/queue-5.15/ksmbd-fix-multi-session-connection-failure.patch b/queue-5.15/ksmbd-fix-multi-session-connection-failure.patch
new file mode 100644 (file)
index 0000000..3f6db34
--- /dev/null
@@ -0,0 +1,241 @@
+From a8bbd42d76ead12063d0340271c6043606a71c05 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Dec 2021 14:57:27 +0900
+Subject: ksmbd: fix multi session connection failure
+
+From: Namjae Jeon <linkinjeon@kernel.org>
+
+[ Upstream commit ce53d365378cde71bb6596d79c257e600d951d29 ]
+
+When RSS mode is enable, windows client do simultaneously send several
+session requests to server. There is racy issue using
+sess->ntlmssp.cryptkey on N connection : 1 session. So authetication
+failed using wrong cryptkey on some session. This patch move cryptkey
+to ksmbd_conn structure to use each cryptkey on connection.
+
+Tested-by: Ziwei Xie <zw.xie@high-flyer.cn>
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Stable-dep-of: 7b4323373d84 ("ksmbd: fix deadlock in ksmbd_find_crypto_ctx()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ksmbd/auth.c              | 27 ++++++++++++++-------------
+ fs/ksmbd/auth.h              | 10 +++++-----
+ fs/ksmbd/connection.h        |  7 +------
+ fs/ksmbd/mgmt/user_session.h |  1 -
+ fs/ksmbd/smb2pdu.c           |  8 ++++----
+ 5 files changed, 24 insertions(+), 29 deletions(-)
+
+diff --git a/fs/ksmbd/auth.c b/fs/ksmbd/auth.c
+index b962b16e5aeb7..4867da417c23a 100644
+--- a/fs/ksmbd/auth.c
++++ b/fs/ksmbd/auth.c
+@@ -215,7 +215,7 @@ static int calc_ntlmv2_hash(struct ksmbd_session *sess, char *ntlmv2_hash,
+  * Return:    0 on success, error number on error
+  */
+ int ksmbd_auth_ntlmv2(struct ksmbd_session *sess, struct ntlmv2_resp *ntlmv2,
+-                    int blen, char *domain_name)
++                    int blen, char *domain_name, char *cryptkey)
+ {
+       char ntlmv2_hash[CIFS_ENCPWD_SIZE];
+       char ntlmv2_rsp[CIFS_HMAC_MD5_HASH_SIZE];
+@@ -256,7 +256,7 @@ int ksmbd_auth_ntlmv2(struct ksmbd_session *sess, struct ntlmv2_resp *ntlmv2,
+               goto out;
+       }
+-      memcpy(construct, sess->ntlmssp.cryptkey, CIFS_CRYPTO_KEY_SIZE);
++      memcpy(construct, cryptkey, CIFS_CRYPTO_KEY_SIZE);
+       memcpy(construct + CIFS_CRYPTO_KEY_SIZE, &ntlmv2->blob_signature, blen);
+       rc = crypto_shash_update(CRYPTO_HMACMD5(ctx), construct, len);
+@@ -295,7 +295,8 @@ int ksmbd_auth_ntlmv2(struct ksmbd_session *sess, struct ntlmv2_resp *ntlmv2,
+  * Return:    0 on success, error number on error
+  */
+ int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
+-                                 int blob_len, struct ksmbd_session *sess)
++                                 int blob_len, struct ksmbd_conn *conn,
++                                 struct ksmbd_session *sess)
+ {
+       char *domain_name;
+       unsigned int nt_off, dn_off;
+@@ -325,7 +326,7 @@ int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
+       /* TODO : use domain name that imported from configuration file */
+       domain_name = smb_strndup_from_utf16((const char *)authblob + dn_off,
+-                                           dn_len, true, sess->conn->local_nls);
++                                           dn_len, true, conn->local_nls);
+       if (IS_ERR(domain_name))
+               return PTR_ERR(domain_name);
+@@ -334,7 +335,7 @@ int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
+                   domain_name);
+       ret = ksmbd_auth_ntlmv2(sess, (struct ntlmv2_resp *)((char *)authblob + nt_off),
+                               nt_len - CIFS_ENCPWD_SIZE,
+-                              domain_name);
++                              domain_name, conn->ntlmssp.cryptkey);
+       kfree(domain_name);
+       return ret;
+ }
+@@ -348,7 +349,7 @@ int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
+  *
+  */
+ int ksmbd_decode_ntlmssp_neg_blob(struct negotiate_message *negblob,
+-                                int blob_len, struct ksmbd_session *sess)
++                                int blob_len, struct ksmbd_conn *conn)
+ {
+       if (blob_len < sizeof(struct negotiate_message)) {
+               ksmbd_debug(AUTH, "negotiate blob len %d too small\n",
+@@ -362,7 +363,7 @@ int ksmbd_decode_ntlmssp_neg_blob(struct negotiate_message *negblob,
+               return -EINVAL;
+       }
+-      sess->ntlmssp.client_flags = le32_to_cpu(negblob->NegotiateFlags);
++      conn->ntlmssp.client_flags = le32_to_cpu(negblob->NegotiateFlags);
+       return 0;
+ }
+@@ -376,14 +377,14 @@ int ksmbd_decode_ntlmssp_neg_blob(struct negotiate_message *negblob,
+  */
+ unsigned int
+ ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,
+-                                 struct ksmbd_session *sess)
++                                 struct ksmbd_conn *conn)
+ {
+       struct target_info *tinfo;
+       wchar_t *name;
+       __u8 *target_name;
+       unsigned int flags, blob_off, blob_len, type, target_info_len = 0;
+       int len, uni_len, conv_len;
+-      int cflags = sess->ntlmssp.client_flags;
++      int cflags = conn->ntlmssp.client_flags;
+       memcpy(chgblob->Signature, NTLMSSP_SIGNATURE, 8);
+       chgblob->MessageType = NtLmChallenge;
+@@ -404,7 +405,7 @@ ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,
+       if (cflags & NTLMSSP_REQUEST_TARGET)
+               flags |= NTLMSSP_REQUEST_TARGET;
+-      if (sess->conn->use_spnego &&
++      if (conn->use_spnego &&
+           (cflags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
+               flags |= NTLMSSP_NEGOTIATE_EXTENDED_SEC;
+@@ -415,7 +416,7 @@ ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,
+               return -ENOMEM;
+       conv_len = smb_strtoUTF16((__le16 *)name, ksmbd_netbios_name(), len,
+-                                sess->conn->local_nls);
++                                conn->local_nls);
+       if (conv_len < 0 || conv_len > len) {
+               kfree(name);
+               return -EINVAL;
+@@ -431,8 +432,8 @@ ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,
+       chgblob->TargetName.BufferOffset = cpu_to_le32(blob_off);
+       /* Initialize random conn challenge */
+-      get_random_bytes(sess->ntlmssp.cryptkey, sizeof(__u64));
+-      memcpy(chgblob->Challenge, sess->ntlmssp.cryptkey,
++      get_random_bytes(conn->ntlmssp.cryptkey, sizeof(__u64));
++      memcpy(chgblob->Challenge, conn->ntlmssp.cryptkey,
+              CIFS_CRYPTO_KEY_SIZE);
+       /* Add Target Information to security buffer */
+diff --git a/fs/ksmbd/auth.h b/fs/ksmbd/auth.h
+index 9c2d4badd05d1..95629651cf266 100644
+--- a/fs/ksmbd/auth.h
++++ b/fs/ksmbd/auth.h
+@@ -38,16 +38,16 @@ struct kvec;
+ int ksmbd_crypt_message(struct ksmbd_conn *conn, struct kvec *iov,
+                       unsigned int nvec, int enc);
+ void ksmbd_copy_gss_neg_header(void *buf);
+-int ksmbd_auth_ntlm(struct ksmbd_session *sess, char *pw_buf);
+ int ksmbd_auth_ntlmv2(struct ksmbd_session *sess, struct ntlmv2_resp *ntlmv2,
+-                    int blen, char *domain_name);
++                    int blen, char *domain_name, char *cryptkey);
+ int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
+-                                 int blob_len, struct ksmbd_session *sess);
++                                 int blob_len, struct ksmbd_conn *conn,
++                                 struct ksmbd_session *sess);
+ int ksmbd_decode_ntlmssp_neg_blob(struct negotiate_message *negblob,
+-                                int blob_len, struct ksmbd_session *sess);
++                                int blob_len, struct ksmbd_conn *conn);
+ unsigned int
+ ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,
+-                                 struct ksmbd_session *sess);
++                                 struct ksmbd_conn *conn);
+ int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
+                           int in_len, char *out_blob, int *out_len);
+ int ksmbd_sign_smb2_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
+diff --git a/fs/ksmbd/connection.h b/fs/ksmbd/connection.h
+index 4b15c5e673d92..f3367d7760d7e 100644
+--- a/fs/ksmbd/connection.h
++++ b/fs/ksmbd/connection.h
+@@ -72,12 +72,7 @@ struct ksmbd_conn {
+       int                             connection_type;
+       struct ksmbd_stats              stats;
+       char                            ClientGUID[SMB2_CLIENT_GUID_SIZE];
+-      union {
+-              /* pending trans request table */
+-              struct trans_state      *recent_trans;
+-              /* Used by ntlmssp */
+-              char                    *ntlmssp_cryptkey;
+-      };
++      struct ntlmssp_auth             ntlmssp;
+       spinlock_t                      llist_lock;
+       struct list_head                lock_list;
+diff --git a/fs/ksmbd/mgmt/user_session.h b/fs/ksmbd/mgmt/user_session.h
+index 82289c3cbd2bc..e241f16a38512 100644
+--- a/fs/ksmbd/mgmt/user_session.h
++++ b/fs/ksmbd/mgmt/user_session.h
+@@ -45,7 +45,6 @@ struct ksmbd_session {
+       int                             state;
+       __u8                            *Preauth_HashValue;
+-      struct ntlmssp_auth             ntlmssp;
+       char                            sess_key[CIFS_KEY_SIZE];
+       struct hlist_node               hlist;
+diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c
+index c8c2b326ee042..bb8126deeaf29 100644
+--- a/fs/ksmbd/smb2pdu.c
++++ b/fs/ksmbd/smb2pdu.c
+@@ -1316,7 +1316,7 @@ static int ntlm_negotiate(struct ksmbd_work *work,
+       int sz, rc;
+       ksmbd_debug(SMB, "negotiate phase\n");
+-      rc = ksmbd_decode_ntlmssp_neg_blob(negblob, negblob_len, work->sess);
++      rc = ksmbd_decode_ntlmssp_neg_blob(negblob, negblob_len, work->conn);
+       if (rc)
+               return rc;
+@@ -1326,7 +1326,7 @@ static int ntlm_negotiate(struct ksmbd_work *work,
+       memset(chgblob, 0, sizeof(struct challenge_message));
+       if (!work->conn->use_spnego) {
+-              sz = ksmbd_build_ntlmssp_challenge_blob(chgblob, work->sess);
++              sz = ksmbd_build_ntlmssp_challenge_blob(chgblob, work->conn);
+               if (sz < 0)
+                       return -ENOMEM;
+@@ -1342,7 +1342,7 @@ static int ntlm_negotiate(struct ksmbd_work *work,
+               return -ENOMEM;
+       chgblob = (struct challenge_message *)neg_blob;
+-      sz = ksmbd_build_ntlmssp_challenge_blob(chgblob, work->sess);
++      sz = ksmbd_build_ntlmssp_challenge_blob(chgblob, work->conn);
+       if (sz < 0) {
+               rc = -ENOMEM;
+               goto out;
+@@ -1480,7 +1480,7 @@ static int ntlm_authenticate(struct ksmbd_work *work)
+               authblob = user_authblob(conn, req);
+               sz = le16_to_cpu(req->SecurityBufferLength);
+-              rc = ksmbd_decode_ntlmssp_auth_blob(authblob, sz, sess);
++              rc = ksmbd_decode_ntlmssp_auth_blob(authblob, sz, conn, sess);
+               if (rc) {
+                       set_user_flag(sess->user, KSMBD_USER_FLAG_BAD_PASSWORD);
+                       ksmbd_debug(SMB, "authentication failed\n");
+-- 
+2.39.2
+
diff --git a/queue-5.15/ksmbd-fix-racy-issue-while-destroying-session-on-mul.patch b/queue-5.15/ksmbd-fix-racy-issue-while-destroying-session-on-mul.patch
new file mode 100644 (file)
index 0000000..99a4451
--- /dev/null
@@ -0,0 +1,646 @@
+From 07bc60603620513e77b5e4d64a1c0786aa9536fd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Jul 2022 13:36:52 +0900
+Subject: ksmbd: fix racy issue while destroying session on multichannel
+
+From: Namjae Jeon <linkinjeon@kernel.org>
+
+[ Upstream commit af7c39d971e43cd0af488729bca362427ad99488 ]
+
+After multi-channel connection with windows, Several channels of
+session are connected. Among them, if there is a problem in one channel,
+Windows connects again after disconnecting the channel. In this process,
+the session is released and a kernel oop can occurs while processing
+requests to other channels. When the channel is disconnected, if other
+channels still exist in the session after deleting the channel from
+the channel list in the session, the session should not be released.
+Finally, the session will be released after all channels are disconnected.
+
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Stable-dep-of: 7b4323373d84 ("ksmbd: fix deadlock in ksmbd_find_crypto_ctx()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ksmbd/auth.c              | 56 ++++++++++++++++--------------
+ fs/ksmbd/auth.h              | 11 +++---
+ fs/ksmbd/connection.h        |  7 ----
+ fs/ksmbd/mgmt/tree_connect.c |  5 +--
+ fs/ksmbd/mgmt/tree_connect.h |  4 ++-
+ fs/ksmbd/mgmt/user_session.c | 67 ++++++++++++++++++++++++------------
+ fs/ksmbd/mgmt/user_session.h |  7 ++--
+ fs/ksmbd/oplock.c            | 11 +++---
+ fs/ksmbd/smb2pdu.c           | 21 +++++------
+ fs/ksmbd/smb_common.h        |  2 +-
+ fs/ksmbd/vfs.c               |  3 +-
+ fs/ksmbd/vfs_cache.c         |  2 +-
+ 12 files changed, 110 insertions(+), 86 deletions(-)
+
+diff --git a/fs/ksmbd/auth.c b/fs/ksmbd/auth.c
+index 4867da417c23a..c1408e922fc6b 100644
+--- a/fs/ksmbd/auth.c
++++ b/fs/ksmbd/auth.c
+@@ -120,8 +120,8 @@ static int ksmbd_gen_sess_key(struct ksmbd_session *sess, char *hash,
+       return rc;
+ }
+-static int calc_ntlmv2_hash(struct ksmbd_session *sess, char *ntlmv2_hash,
+-                          char *dname)
++static int calc_ntlmv2_hash(struct ksmbd_conn *conn, struct ksmbd_session *sess,
++                          char *ntlmv2_hash, char *dname)
+ {
+       int ret, len, conv_len;
+       wchar_t *domain = NULL;
+@@ -157,7 +157,7 @@ static int calc_ntlmv2_hash(struct ksmbd_session *sess, char *ntlmv2_hash,
+       }
+       conv_len = smb_strtoUTF16(uniname, user_name(sess->user), len,
+-                                sess->conn->local_nls);
++                                conn->local_nls);
+       if (conv_len < 0 || conv_len > len) {
+               ret = -EINVAL;
+               goto out;
+@@ -181,7 +181,7 @@ static int calc_ntlmv2_hash(struct ksmbd_session *sess, char *ntlmv2_hash,
+       }
+       conv_len = smb_strtoUTF16((__le16 *)domain, dname, len,
+-                                sess->conn->local_nls);
++                                conn->local_nls);
+       if (conv_len < 0 || conv_len > len) {
+               ret = -EINVAL;
+               goto out;
+@@ -214,8 +214,9 @@ static int calc_ntlmv2_hash(struct ksmbd_session *sess, char *ntlmv2_hash,
+  *
+  * Return:    0 on success, error number on error
+  */
+-int ksmbd_auth_ntlmv2(struct ksmbd_session *sess, struct ntlmv2_resp *ntlmv2,
+-                    int blen, char *domain_name, char *cryptkey)
++int ksmbd_auth_ntlmv2(struct ksmbd_conn *conn, struct ksmbd_session *sess,
++                    struct ntlmv2_resp *ntlmv2, int blen, char *domain_name,
++                    char *cryptkey)
+ {
+       char ntlmv2_hash[CIFS_ENCPWD_SIZE];
+       char ntlmv2_rsp[CIFS_HMAC_MD5_HASH_SIZE];
+@@ -229,7 +230,7 @@ int ksmbd_auth_ntlmv2(struct ksmbd_session *sess, struct ntlmv2_resp *ntlmv2,
+               return -ENOMEM;
+       }
+-      rc = calc_ntlmv2_hash(sess, ntlmv2_hash, domain_name);
++      rc = calc_ntlmv2_hash(conn, sess, ntlmv2_hash, domain_name);
+       if (rc) {
+               ksmbd_debug(AUTH, "could not get v2 hash rc %d\n", rc);
+               goto out;
+@@ -333,7 +334,8 @@ int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
+       /* process NTLMv2 authentication */
+       ksmbd_debug(AUTH, "decode_ntlmssp_authenticate_blob dname%s\n",
+                   domain_name);
+-      ret = ksmbd_auth_ntlmv2(sess, (struct ntlmv2_resp *)((char *)authblob + nt_off),
++      ret = ksmbd_auth_ntlmv2(conn, sess,
++                              (struct ntlmv2_resp *)((char *)authblob + nt_off),
+                               nt_len - CIFS_ENCPWD_SIZE,
+                               domain_name, conn->ntlmssp.cryptkey);
+       kfree(domain_name);
+@@ -633,8 +635,9 @@ struct derivation {
+       bool binding;
+ };
+-static int generate_key(struct ksmbd_session *sess, struct kvec label,
+-                      struct kvec context, __u8 *key, unsigned int key_size)
++static int generate_key(struct ksmbd_conn *conn, struct ksmbd_session *sess,
++                      struct kvec label, struct kvec context, __u8 *key,
++                      unsigned int key_size)
+ {
+       unsigned char zero = 0x0;
+       __u8 i[4] = {0, 0, 0, 1};
+@@ -694,8 +697,8 @@ static int generate_key(struct ksmbd_session *sess, struct kvec label,
+               goto smb3signkey_ret;
+       }
+-      if (sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
+-          sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
++      if (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
++          conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
+               rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), L256, 4);
+       else
+               rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), L128, 4);
+@@ -730,17 +733,17 @@ static int generate_smb3signingkey(struct ksmbd_session *sess,
+       if (!chann)
+               return 0;
+-      if (sess->conn->dialect >= SMB30_PROT_ID && signing->binding)
++      if (conn->dialect >= SMB30_PROT_ID && signing->binding)
+               key = chann->smb3signingkey;
+       else
+               key = sess->smb3signingkey;
+-      rc = generate_key(sess, signing->label, signing->context, key,
++      rc = generate_key(conn, sess, signing->label, signing->context, key,
+                         SMB3_SIGN_KEY_SIZE);
+       if (rc)
+               return rc;
+-      if (!(sess->conn->dialect >= SMB30_PROT_ID && signing->binding))
++      if (!(conn->dialect >= SMB30_PROT_ID && signing->binding))
+               memcpy(chann->smb3signingkey, key, SMB3_SIGN_KEY_SIZE);
+       ksmbd_debug(AUTH, "dumping generated AES signing keys\n");
+@@ -794,30 +797,31 @@ struct derivation_twin {
+       struct derivation decryption;
+ };
+-static int generate_smb3encryptionkey(struct ksmbd_session *sess,
++static int generate_smb3encryptionkey(struct ksmbd_conn *conn,
++                                    struct ksmbd_session *sess,
+                                     const struct derivation_twin *ptwin)
+ {
+       int rc;
+-      rc = generate_key(sess, ptwin->encryption.label,
++      rc = generate_key(conn, sess, ptwin->encryption.label,
+                         ptwin->encryption.context, sess->smb3encryptionkey,
+                         SMB3_ENC_DEC_KEY_SIZE);
+       if (rc)
+               return rc;
+-      rc = generate_key(sess, ptwin->decryption.label,
++      rc = generate_key(conn, sess, ptwin->decryption.label,
+                         ptwin->decryption.context,
+                         sess->smb3decryptionkey, SMB3_ENC_DEC_KEY_SIZE);
+       if (rc)
+               return rc;
+       ksmbd_debug(AUTH, "dumping generated AES encryption keys\n");
+-      ksmbd_debug(AUTH, "Cipher type   %d\n", sess->conn->cipher_type);
++      ksmbd_debug(AUTH, "Cipher type   %d\n", conn->cipher_type);
+       ksmbd_debug(AUTH, "Session Id    %llu\n", sess->id);
+       ksmbd_debug(AUTH, "Session Key   %*ph\n",
+                   SMB2_NTLMV2_SESSKEY_SIZE, sess->sess_key);
+-      if (sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
+-          sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) {
++      if (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
++          conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) {
+               ksmbd_debug(AUTH, "ServerIn Key  %*ph\n",
+                           SMB3_GCM256_CRYPTKEY_SIZE, sess->smb3encryptionkey);
+               ksmbd_debug(AUTH, "ServerOut Key %*ph\n",
+@@ -831,7 +835,8 @@ static int generate_smb3encryptionkey(struct ksmbd_session *sess,
+       return 0;
+ }
+-int ksmbd_gen_smb30_encryptionkey(struct ksmbd_session *sess)
++int ksmbd_gen_smb30_encryptionkey(struct ksmbd_conn *conn,
++                                struct ksmbd_session *sess)
+ {
+       struct derivation_twin twin;
+       struct derivation *d;
+@@ -848,10 +853,11 @@ int ksmbd_gen_smb30_encryptionkey(struct ksmbd_session *sess)
+       d->context.iov_base = "ServerIn ";
+       d->context.iov_len = 10;
+-      return generate_smb3encryptionkey(sess, &twin);
++      return generate_smb3encryptionkey(conn, sess, &twin);
+ }
+-int ksmbd_gen_smb311_encryptionkey(struct ksmbd_session *sess)
++int ksmbd_gen_smb311_encryptionkey(struct ksmbd_conn *conn,
++                                 struct ksmbd_session *sess)
+ {
+       struct derivation_twin twin;
+       struct derivation *d;
+@@ -868,7 +874,7 @@ int ksmbd_gen_smb311_encryptionkey(struct ksmbd_session *sess)
+       d->context.iov_base = sess->Preauth_HashValue;
+       d->context.iov_len = 64;
+-      return generate_smb3encryptionkey(sess, &twin);
++      return generate_smb3encryptionkey(conn, sess, &twin);
+ }
+ int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn, char *buf,
+diff --git a/fs/ksmbd/auth.h b/fs/ksmbd/auth.h
+index 95629651cf266..25b772653de0a 100644
+--- a/fs/ksmbd/auth.h
++++ b/fs/ksmbd/auth.h
+@@ -38,8 +38,9 @@ struct kvec;
+ int ksmbd_crypt_message(struct ksmbd_conn *conn, struct kvec *iov,
+                       unsigned int nvec, int enc);
+ void ksmbd_copy_gss_neg_header(void *buf);
+-int ksmbd_auth_ntlmv2(struct ksmbd_session *sess, struct ntlmv2_resp *ntlmv2,
+-                    int blen, char *domain_name, char *cryptkey);
++int ksmbd_auth_ntlmv2(struct ksmbd_conn *conn, struct ksmbd_session *sess,
++                    struct ntlmv2_resp *ntlmv2, int blen, char *domain_name,
++                    char *cryptkey);
+ int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
+                                  int blob_len, struct ksmbd_conn *conn,
+                                  struct ksmbd_session *sess);
+@@ -58,8 +59,10 @@ int ksmbd_gen_smb30_signingkey(struct ksmbd_session *sess,
+                              struct ksmbd_conn *conn);
+ int ksmbd_gen_smb311_signingkey(struct ksmbd_session *sess,
+                               struct ksmbd_conn *conn);
+-int ksmbd_gen_smb30_encryptionkey(struct ksmbd_session *sess);
+-int ksmbd_gen_smb311_encryptionkey(struct ksmbd_session *sess);
++int ksmbd_gen_smb30_encryptionkey(struct ksmbd_conn *conn,
++                                struct ksmbd_session *sess);
++int ksmbd_gen_smb311_encryptionkey(struct ksmbd_conn *conn,
++                                 struct ksmbd_session *sess);
+ int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn, char *buf,
+                                    __u8 *pi_hash);
+ int ksmbd_gen_sd_hash(struct ksmbd_conn *conn, char *sd_buf, int len,
+diff --git a/fs/ksmbd/connection.h b/fs/ksmbd/connection.h
+index 7838cc46497d6..89eb41bbd1601 100644
+--- a/fs/ksmbd/connection.h
++++ b/fs/ksmbd/connection.h
+@@ -20,13 +20,6 @@
+ #define KSMBD_SOCKET_BACKLOG          16
+-/*
+- * WARNING
+- *
+- * This is nothing but a HACK. Session status should move to channel
+- * or to session. As of now we have 1 tcp_conn : 1 ksmbd_session, but
+- * we need to change it to 1 tcp_conn : N ksmbd_sessions.
+- */
+ enum {
+       KSMBD_SESS_NEW = 0,
+       KSMBD_SESS_GOOD,
+diff --git a/fs/ksmbd/mgmt/tree_connect.c b/fs/ksmbd/mgmt/tree_connect.c
+index 940385c6a9135..dd262daa2c4a5 100644
+--- a/fs/ksmbd/mgmt/tree_connect.c
++++ b/fs/ksmbd/mgmt/tree_connect.c
+@@ -16,7 +16,8 @@
+ #include "user_session.h"
+ struct ksmbd_tree_conn_status
+-ksmbd_tree_conn_connect(struct ksmbd_session *sess, char *share_name)
++ksmbd_tree_conn_connect(struct ksmbd_conn *conn, struct ksmbd_session *sess,
++                      char *share_name)
+ {
+       struct ksmbd_tree_conn_status status = {-ENOENT, NULL};
+       struct ksmbd_tree_connect_response *resp = NULL;
+@@ -41,7 +42,7 @@ ksmbd_tree_conn_connect(struct ksmbd_session *sess, char *share_name)
+               goto out_error;
+       }
+-      peer_addr = KSMBD_TCP_PEER_SOCKADDR(sess->conn);
++      peer_addr = KSMBD_TCP_PEER_SOCKADDR(conn);
+       resp = ksmbd_ipc_tree_connect_request(sess,
+                                             sc,
+                                             tree_conn,
+diff --git a/fs/ksmbd/mgmt/tree_connect.h b/fs/ksmbd/mgmt/tree_connect.h
+index 18e2a996e0aab..71e50271dccf0 100644
+--- a/fs/ksmbd/mgmt/tree_connect.h
++++ b/fs/ksmbd/mgmt/tree_connect.h
+@@ -12,6 +12,7 @@
+ struct ksmbd_share_config;
+ struct ksmbd_user;
++struct ksmbd_conn;
+ struct ksmbd_tree_connect {
+       int                             id;
+@@ -40,7 +41,8 @@ static inline int test_tree_conn_flag(struct ksmbd_tree_connect *tree_conn,
+ struct ksmbd_session;
+ struct ksmbd_tree_conn_status
+-ksmbd_tree_conn_connect(struct ksmbd_session *sess, char *share_name);
++ksmbd_tree_conn_connect(struct ksmbd_conn *conn, struct ksmbd_session *sess,
++                      char *share_name);
+ int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess,
+                              struct ksmbd_tree_connect *tree_conn);
+diff --git a/fs/ksmbd/mgmt/user_session.c b/fs/ksmbd/mgmt/user_session.c
+index 9c4a9c8c02795..92b1603b5abeb 100644
+--- a/fs/ksmbd/mgmt/user_session.c
++++ b/fs/ksmbd/mgmt/user_session.c
+@@ -153,9 +153,6 @@ void ksmbd_session_destroy(struct ksmbd_session *sess)
+       if (!sess)
+               return;
+-      if (!atomic_dec_and_test(&sess->refcnt))
+-              return;
+-
+       down_write(&sessions_table_lock);
+       hash_del(&sess->hlist);
+       up_write(&sessions_table_lock);
+@@ -186,16 +183,58 @@ static struct ksmbd_session *__session_lookup(unsigned long long id)
+ int ksmbd_session_register(struct ksmbd_conn *conn,
+                          struct ksmbd_session *sess)
+ {
+-      sess->conn = conn;
++      sess->dialect = conn->dialect;
++      memcpy(sess->ClientGUID, conn->ClientGUID, SMB2_CLIENT_GUID_SIZE);
+       return xa_err(xa_store(&conn->sessions, sess->id, sess, GFP_KERNEL));
+ }
++static int ksmbd_chann_del(struct ksmbd_conn *conn, struct ksmbd_session *sess)
++{
++      struct channel *chann, *tmp;
++
++      write_lock(&sess->chann_lock);
++      list_for_each_entry_safe(chann, tmp, &sess->ksmbd_chann_list,
++                               chann_list) {
++              if (chann->conn == conn) {
++                      list_del(&chann->chann_list);
++                      kfree(chann);
++                      write_unlock(&sess->chann_lock);
++                      return 0;
++              }
++      }
++      write_unlock(&sess->chann_lock);
++
++      return -ENOENT;
++}
++
+ void ksmbd_sessions_deregister(struct ksmbd_conn *conn)
+ {
+       struct ksmbd_session *sess;
+-      unsigned long id;
+-      xa_for_each(&conn->sessions, id, sess) {
++      if (conn->binding) {
++              int bkt;
++
++              down_write(&sessions_table_lock);
++              hash_for_each(sessions_table, bkt, sess, hlist) {
++                      if (!ksmbd_chann_del(conn, sess)) {
++                              up_write(&sessions_table_lock);
++                              goto sess_destroy;
++                      }
++              }
++              up_write(&sessions_table_lock);
++      } else {
++              unsigned long id;
++
++              xa_for_each(&conn->sessions, id, sess) {
++                      if (!ksmbd_chann_del(conn, sess))
++                              goto sess_destroy;
++              }
++      }
++
++      return;
++
++sess_destroy:
++      if (list_empty(&sess->ksmbd_chann_list)) {
+               xa_erase(&conn->sessions, sess->id);
+               ksmbd_session_destroy(sess);
+       }
+@@ -207,27 +246,12 @@ struct ksmbd_session *ksmbd_session_lookup(struct ksmbd_conn *conn,
+       return xa_load(&conn->sessions, id);
+ }
+-int get_session(struct ksmbd_session *sess)
+-{
+-      return atomic_inc_not_zero(&sess->refcnt);
+-}
+-
+-void put_session(struct ksmbd_session *sess)
+-{
+-      if (atomic_dec_and_test(&sess->refcnt))
+-              pr_err("get/%s seems to be mismatched.", __func__);
+-}
+-
+ struct ksmbd_session *ksmbd_session_lookup_slowpath(unsigned long long id)
+ {
+       struct ksmbd_session *sess;
+       down_read(&sessions_table_lock);
+       sess = __session_lookup(id);
+-      if (sess) {
+-              if (!get_session(sess))
+-                      sess = NULL;
+-      }
+       up_read(&sessions_table_lock);
+       return sess;
+@@ -308,7 +332,6 @@ static struct ksmbd_session *__session_create(int protocol)
+       INIT_LIST_HEAD(&sess->ksmbd_chann_list);
+       INIT_LIST_HEAD(&sess->rpc_handle_list);
+       sess->sequence_number = 1;
+-      atomic_set(&sess->refcnt, 1);
+       rwlock_init(&sess->chann_lock);
+       switch (protocol) {
+diff --git a/fs/ksmbd/mgmt/user_session.h b/fs/ksmbd/mgmt/user_session.h
+index 1ec659f0151bf..8934b8ee275ba 100644
+--- a/fs/ksmbd/mgmt/user_session.h
++++ b/fs/ksmbd/mgmt/user_session.h
+@@ -33,8 +33,10 @@ struct preauth_session {
+ struct ksmbd_session {
+       u64                             id;
++      __u16                           dialect;
++      char                            ClientGUID[SMB2_CLIENT_GUID_SIZE];
++
+       struct ksmbd_user               *user;
+-      struct ksmbd_conn               *conn;
+       unsigned int                    sequence_number;
+       unsigned int                    flags;
+@@ -59,7 +61,6 @@ struct ksmbd_session {
+       __u8                            smb3signingkey[SMB3_SIGN_KEY_SIZE];
+       struct ksmbd_file_table         file_table;
+-      atomic_t                        refcnt;
+ };
+ static inline int test_session_flag(struct ksmbd_session *sess, int bit)
+@@ -100,6 +101,4 @@ void ksmbd_release_tree_conn_id(struct ksmbd_session *sess, int id);
+ int ksmbd_session_rpc_open(struct ksmbd_session *sess, char *rpc_name);
+ void ksmbd_session_rpc_close(struct ksmbd_session *sess, int id);
+ int ksmbd_session_rpc_method(struct ksmbd_session *sess, int id);
+-int get_session(struct ksmbd_session *sess);
+-void put_session(struct ksmbd_session *sess);
+ #endif /* __USER_SESSION_MANAGEMENT_H__ */
+diff --git a/fs/ksmbd/oplock.c b/fs/ksmbd/oplock.c
+index f9dae6ef21150..3f759f9123ea7 100644
+--- a/fs/ksmbd/oplock.c
++++ b/fs/ksmbd/oplock.c
+@@ -30,6 +30,7 @@ static DEFINE_RWLOCK(lease_list_lock);
+ static struct oplock_info *alloc_opinfo(struct ksmbd_work *work,
+                                       u64 id, __u16 Tid)
+ {
++      struct ksmbd_conn *conn = work->conn;
+       struct ksmbd_session *sess = work->sess;
+       struct oplock_info *opinfo;
+@@ -38,7 +39,7 @@ static struct oplock_info *alloc_opinfo(struct ksmbd_work *work,
+               return NULL;
+       opinfo->sess = sess;
+-      opinfo->conn = sess->conn;
++      opinfo->conn = conn;
+       opinfo->level = SMB2_OPLOCK_LEVEL_NONE;
+       opinfo->op_state = OPLOCK_STATE_NONE;
+       opinfo->pending_break = 0;
+@@ -972,7 +973,7 @@ int find_same_lease_key(struct ksmbd_session *sess, struct ksmbd_inode *ci,
+       }
+       list_for_each_entry(lb, &lease_table_list, l_entry) {
+-              if (!memcmp(lb->client_guid, sess->conn->ClientGUID,
++              if (!memcmp(lb->client_guid, sess->ClientGUID,
+                           SMB2_CLIENT_GUID_SIZE))
+                       goto found;
+       }
+@@ -988,7 +989,7 @@ int find_same_lease_key(struct ksmbd_session *sess, struct ksmbd_inode *ci,
+               rcu_read_unlock();
+               if (opinfo->o_fp->f_ci == ci)
+                       goto op_next;
+-              err = compare_guid_key(opinfo, sess->conn->ClientGUID,
++              err = compare_guid_key(opinfo, sess->ClientGUID,
+                                      lctx->lease_key);
+               if (err) {
+                       err = -EINVAL;
+@@ -1122,7 +1123,7 @@ int smb_grant_oplock(struct ksmbd_work *work, int req_op_level, u64 pid,
+               struct oplock_info *m_opinfo;
+               /* is lease already granted ? */
+-              m_opinfo = same_client_has_lease(ci, sess->conn->ClientGUID,
++              m_opinfo = same_client_has_lease(ci, sess->ClientGUID,
+                                                lctx);
+               if (m_opinfo) {
+                       copy_lease(m_opinfo, opinfo);
+@@ -1240,7 +1241,7 @@ void smb_break_all_levII_oplock(struct ksmbd_work *work, struct ksmbd_file *fp,
+ {
+       struct oplock_info *op, *brk_op;
+       struct ksmbd_inode *ci;
+-      struct ksmbd_conn *conn = work->sess->conn;
++      struct ksmbd_conn *conn = work->conn;
+       if (!test_share_config_flag(work->tcon->share_conf,
+                                   KSMBD_SHARE_FLAG_OPLOCKS))
+diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c
+index 8bfe2a6c05f92..61d6d4b6b56ac 100644
+--- a/fs/ksmbd/smb2pdu.c
++++ b/fs/ksmbd/smb2pdu.c
+@@ -610,12 +610,9 @@ static void destroy_previous_session(struct ksmbd_conn *conn,
+       if (!prev_user ||
+           strcmp(user->name, prev_user->name) ||
+           user->passkey_sz != prev_user->passkey_sz ||
+-          memcmp(user->passkey, prev_user->passkey, user->passkey_sz)) {
+-              put_session(prev_sess);
++          memcmp(user->passkey, prev_user->passkey, user->passkey_sz))
+               return;
+-      }
+-      put_session(prev_sess);
+       prev_sess->state = SMB2_SESSION_EXPIRED;
+       write_lock(&prev_sess->chann_lock);
+       list_for_each_entry(chann, &prev_sess->ksmbd_chann_list, chann_list)
+@@ -1512,7 +1509,7 @@ static int ntlm_authenticate(struct ksmbd_work *work)
+       if (smb3_encryption_negotiated(conn) &&
+                       !(req->Flags & SMB2_SESSION_REQ_FLAG_BINDING)) {
+-              rc = conn->ops->generate_encryptionkey(sess);
++              rc = conn->ops->generate_encryptionkey(conn, sess);
+               if (rc) {
+                       ksmbd_debug(SMB,
+                                       "SMB3 encryption key generation failed\n");
+@@ -1604,7 +1601,7 @@ static int krb5_authenticate(struct ksmbd_work *work)
+               sess->sign = true;
+       if (smb3_encryption_negotiated(conn)) {
+-              retval = conn->ops->generate_encryptionkey(sess);
++              retval = conn->ops->generate_encryptionkey(conn, sess);
+               if (retval) {
+                       ksmbd_debug(SMB,
+                                   "SMB3 encryption key generation failed\n");
+@@ -1692,7 +1689,7 @@ int smb2_sess_setup(struct ksmbd_work *work)
+                       goto out_err;
+               }
+-              if (conn->dialect != sess->conn->dialect) {
++              if (conn->dialect != sess->dialect) {
+                       rc = -EINVAL;
+                       goto out_err;
+               }
+@@ -1702,7 +1699,7 @@ int smb2_sess_setup(struct ksmbd_work *work)
+                       goto out_err;
+               }
+-              if (strncmp(conn->ClientGUID, sess->conn->ClientGUID,
++              if (strncmp(conn->ClientGUID, sess->ClientGUID,
+                           SMB2_CLIENT_GUID_SIZE)) {
+                       rc = -ENOENT;
+                       goto out_err;
+@@ -1907,7 +1904,7 @@ int smb2_tree_connect(struct ksmbd_work *work)
+       ksmbd_debug(SMB, "tree connect request for tree %s treename %s\n",
+                   name, treename);
+-      status = ksmbd_tree_conn_connect(sess, name);
++      status = ksmbd_tree_conn_connect(conn, sess, name);
+       if (status.ret == KSMBD_TREE_CONN_STATUS_OK)
+               rsp->hdr.Id.SyncId.TreeId = cpu_to_le32(status.tree_conn->id);
+       else
+@@ -4895,7 +4892,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
+                                   struct smb2_query_info_rsp *rsp, void *rsp_org)
+ {
+       struct ksmbd_session *sess = work->sess;
+-      struct ksmbd_conn *conn = sess->conn;
++      struct ksmbd_conn *conn = work->conn;
+       struct ksmbd_share_config *share = work->tcon->share_conf;
+       int fsinfoclass = 0;
+       struct kstatfs stfs;
+@@ -5831,7 +5828,7 @@ static int set_rename_info(struct ksmbd_work *work, struct ksmbd_file *fp,
+       }
+ next:
+       return smb2_rename(work, fp, user_ns, rename_info,
+-                         work->sess->conn->local_nls);
++                         work->conn->local_nls);
+ }
+ static int set_file_disposition_info(struct ksmbd_file *fp,
+@@ -5965,7 +5962,7 @@ static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp,
+               return smb2_create_link(work, work->tcon->share_conf,
+                                       (struct smb2_file_link_info *)req->Buffer,
+                                       buf_len, fp->filp,
+-                                      work->sess->conn->local_nls);
++                                      work->conn->local_nls);
+       }
+       case FILE_DISPOSITION_INFORMATION:
+       {
+diff --git a/fs/ksmbd/smb_common.h b/fs/ksmbd/smb_common.h
+index b9fe3fa149c2e..48cbaa0321400 100644
+--- a/fs/ksmbd/smb_common.h
++++ b/fs/ksmbd/smb_common.h
+@@ -454,7 +454,7 @@ struct smb_version_ops {
+       int (*check_sign_req)(struct ksmbd_work *work);
+       void (*set_sign_rsp)(struct ksmbd_work *work);
+       int (*generate_signingkey)(struct ksmbd_session *sess, struct ksmbd_conn *conn);
+-      int (*generate_encryptionkey)(struct ksmbd_session *sess);
++      int (*generate_encryptionkey)(struct ksmbd_conn *conn, struct ksmbd_session *sess);
+       bool (*is_transform_hdr)(void *buf);
+       int (*decrypt_req)(struct ksmbd_work *work);
+       int (*encrypt_resp)(struct ksmbd_work *work);
+diff --git a/fs/ksmbd/vfs.c b/fs/ksmbd/vfs.c
+index 5d40a00fbce50..52cc6a9627ed7 100644
+--- a/fs/ksmbd/vfs.c
++++ b/fs/ksmbd/vfs.c
+@@ -483,12 +483,11 @@ int ksmbd_vfs_write(struct ksmbd_work *work, struct ksmbd_file *fp,
+                   char *buf, size_t count, loff_t *pos, bool sync,
+                   ssize_t *written)
+ {
+-      struct ksmbd_session *sess = work->sess;
+       struct file *filp;
+       loff_t  offset = *pos;
+       int err = 0;
+-      if (sess->conn->connection_type) {
++      if (work->conn->connection_type) {
+               if (!(fp->daccess & FILE_WRITE_DATA_LE)) {
+                       pr_err("no right to write(%pd)\n",
+                              fp->filp->f_path.dentry);
+diff --git a/fs/ksmbd/vfs_cache.c b/fs/ksmbd/vfs_cache.c
+index 8b873d92d7854..0df8467af39af 100644
+--- a/fs/ksmbd/vfs_cache.c
++++ b/fs/ksmbd/vfs_cache.c
+@@ -570,7 +570,7 @@ struct ksmbd_file *ksmbd_open_fd(struct ksmbd_work *work, struct file *filp)
+       atomic_set(&fp->refcount, 1);
+       fp->filp                = filp;
+-      fp->conn                = work->sess->conn;
++      fp->conn                = work->conn;
+       fp->tcon                = work->tcon;
+       fp->volatile_id         = KSMBD_NO_FID;
+       fp->persistent_id       = KSMBD_NO_FID;
+-- 
+2.39.2
+
diff --git a/queue-5.15/ksmbd-not-allow-guest-user-on-multichannel.patch b/queue-5.15/ksmbd-not-allow-guest-user-on-multichannel.patch
new file mode 100644 (file)
index 0000000..a28e363
--- /dev/null
@@ -0,0 +1,66 @@
+From fad4b1d8a9cb53e6994d1d833c87daf421122327 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 May 2023 08:45:08 +0900
+Subject: ksmbd: not allow guest user on multichannel
+
+From: Namjae Jeon <linkinjeon@kernel.org>
+
+[ Upstream commit 3353ab2df5f68dab7da8d5ebb427a2d265a1f2b2 ]
+
+This patch return STATUS_NOT_SUPPORTED if binding session is guest.
+
+Cc: stable@vger.kernel.org
+Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-20480
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ksmbd/smb2pdu.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c
+index 61d6d4b6b56ac..51d495688f45e 100644
+--- a/fs/ksmbd/smb2pdu.c
++++ b/fs/ksmbd/smb2pdu.c
+@@ -1462,7 +1462,7 @@ static int ntlm_authenticate(struct ksmbd_work *work)
+                * Reuse session if anonymous try to connect
+                * on reauthetication.
+                */
+-              if (ksmbd_anonymous_user(user)) {
++              if (conn->binding == false && ksmbd_anonymous_user(user)) {
+                       ksmbd_free_user(user);
+                       return 0;
+               }
+@@ -1476,7 +1476,7 @@ static int ntlm_authenticate(struct ksmbd_work *work)
+               sess->user = user;
+       }
+-      if (user_guest(sess->user)) {
++      if (conn->binding == false && user_guest(sess->user)) {
+               rsp->SessionFlags = SMB2_SESSION_FLAG_IS_GUEST_LE;
+       } else {
+               struct authenticate_message *authblob;
+@@ -1720,6 +1720,11 @@ int smb2_sess_setup(struct ksmbd_work *work)
+                       goto out_err;
+               }
++              if (user_guest(sess->user)) {
++                      rc = -EOPNOTSUPP;
++                      goto out_err;
++              }
++
+               conn->binding = true;
+       } else if ((conn->dialect < SMB30_PROT_ID ||
+                   server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL) &&
+@@ -1831,6 +1836,8 @@ int smb2_sess_setup(struct ksmbd_work *work)
+               rsp->hdr.Status = STATUS_NETWORK_SESSION_EXPIRED;
+       else if (rc == -ENOMEM)
+               rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES;
++      else if (rc == -EOPNOTSUPP)
++              rsp->hdr.Status = STATUS_NOT_SUPPORTED;
+       else if (rc)
+               rsp->hdr.Status = STATUS_LOGON_FAILURE;
+-- 
+2.39.2
+
diff --git a/queue-5.15/ksmbd-replace-sessions-list-in-connection-with-xarra.patch b/queue-5.15/ksmbd-replace-sessions-list-in-connection-with-xarra.patch
new file mode 100644 (file)
index 0000000..d422868
--- /dev/null
@@ -0,0 +1,219 @@
+From 1f1cf3e477e086b8bac077b54318929343b36823 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Jul 2022 10:15:10 +0900
+Subject: ksmbd: replace sessions list in connection with xarray
+
+From: Namjae Jeon <linkinjeon@kernel.org>
+
+[ Upstream commit e4d3e6b524c0c928f7fc9e03e047885c4951ae60 ]
+
+Replace sessions list in connection with xarray.
+
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Stable-dep-of: 7b4323373d84 ("ksmbd: fix deadlock in ksmbd_find_crypto_ctx()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ksmbd/connection.c        |  3 ++-
+ fs/ksmbd/connection.h        |  2 +-
+ fs/ksmbd/mgmt/user_session.c | 31 +++++++------------------------
+ fs/ksmbd/mgmt/user_session.h |  5 ++---
+ fs/ksmbd/smb2pdu.c           | 13 +++++++++----
+ 5 files changed, 21 insertions(+), 33 deletions(-)
+
+diff --git a/fs/ksmbd/connection.c b/fs/ksmbd/connection.c
+index 21cda82f156de..b4c79359ef8b7 100644
+--- a/fs/ksmbd/connection.c
++++ b/fs/ksmbd/connection.c
+@@ -36,6 +36,7 @@ void ksmbd_conn_free(struct ksmbd_conn *conn)
+       list_del(&conn->conns_list);
+       write_unlock(&conn_list_lock);
++      xa_destroy(&conn->sessions);
+       kvfree(conn->request_buf);
+       kfree(conn->preauth_info);
+       kfree(conn);
+@@ -66,12 +67,12 @@ struct ksmbd_conn *ksmbd_conn_alloc(void)
+       init_waitqueue_head(&conn->req_running_q);
+       INIT_LIST_HEAD(&conn->conns_list);
+-      INIT_LIST_HEAD(&conn->sessions);
+       INIT_LIST_HEAD(&conn->requests);
+       INIT_LIST_HEAD(&conn->async_requests);
+       spin_lock_init(&conn->request_lock);
+       spin_lock_init(&conn->credits_lock);
+       ida_init(&conn->async_ida);
++      xa_init(&conn->sessions);
+       spin_lock_init(&conn->llist_lock);
+       INIT_LIST_HEAD(&conn->lock_list);
+diff --git a/fs/ksmbd/connection.h b/fs/ksmbd/connection.h
+index f3367d7760d7e..7838cc46497d6 100644
+--- a/fs/ksmbd/connection.h
++++ b/fs/ksmbd/connection.h
+@@ -55,7 +55,7 @@ struct ksmbd_conn {
+       struct nls_table                *local_nls;
+       struct list_head                conns_list;
+       /* smb session 1 per user */
+-      struct list_head                sessions;
++      struct xarray                   sessions;
+       unsigned long                   last_active;
+       /* How many request are running currently */
+       atomic_t                        req_running;
+diff --git a/fs/ksmbd/mgmt/user_session.c b/fs/ksmbd/mgmt/user_session.c
+index 0fa467f2c8973..8fe08df668582 100644
+--- a/fs/ksmbd/mgmt/user_session.c
++++ b/fs/ksmbd/mgmt/user_session.c
+@@ -154,8 +154,6 @@ void ksmbd_session_destroy(struct ksmbd_session *sess)
+       if (!atomic_dec_and_test(&sess->refcnt))
+               return;
+-      list_del(&sess->sessions_entry);
+-
+       down_write(&sessions_table_lock);
+       hash_del(&sess->hlist);
+       up_write(&sessions_table_lock);
+@@ -183,42 +181,28 @@ static struct ksmbd_session *__session_lookup(unsigned long long id)
+       return NULL;
+ }
+-void ksmbd_session_register(struct ksmbd_conn *conn,
+-                          struct ksmbd_session *sess)
++int ksmbd_session_register(struct ksmbd_conn *conn,
++                         struct ksmbd_session *sess)
+ {
+       sess->conn = conn;
+-      list_add(&sess->sessions_entry, &conn->sessions);
++      return xa_err(xa_store(&conn->sessions, sess->id, sess, GFP_KERNEL));
+ }
+ void ksmbd_sessions_deregister(struct ksmbd_conn *conn)
+ {
+       struct ksmbd_session *sess;
++      unsigned long id;
+-      while (!list_empty(&conn->sessions)) {
+-              sess = list_entry(conn->sessions.next,
+-                                struct ksmbd_session,
+-                                sessions_entry);
+-
++      xa_for_each(&conn->sessions, id, sess) {
++              xa_erase(&conn->sessions, sess->id);
+               ksmbd_session_destroy(sess);
+       }
+ }
+-static bool ksmbd_session_id_match(struct ksmbd_session *sess,
+-                                 unsigned long long id)
+-{
+-      return sess->id == id;
+-}
+-
+ struct ksmbd_session *ksmbd_session_lookup(struct ksmbd_conn *conn,
+                                          unsigned long long id)
+ {
+-      struct ksmbd_session *sess = NULL;
+-
+-      list_for_each_entry(sess, &conn->sessions, sessions_entry) {
+-              if (ksmbd_session_id_match(sess, id))
+-                      return sess;
+-      }
+-      return NULL;
++      return xa_load(&conn->sessions, id);
+ }
+ int get_session(struct ksmbd_session *sess)
+@@ -316,7 +300,6 @@ static struct ksmbd_session *__session_create(int protocol)
+               goto error;
+       set_session_flag(sess, protocol);
+-      INIT_LIST_HEAD(&sess->sessions_entry);
+       xa_init(&sess->tree_conns);
+       INIT_LIST_HEAD(&sess->ksmbd_chann_list);
+       INIT_LIST_HEAD(&sess->rpc_handle_list);
+diff --git a/fs/ksmbd/mgmt/user_session.h b/fs/ksmbd/mgmt/user_session.h
+index e241f16a38512..8b08189be3fc2 100644
+--- a/fs/ksmbd/mgmt/user_session.h
++++ b/fs/ksmbd/mgmt/user_session.h
+@@ -57,7 +57,6 @@ struct ksmbd_session {
+       __u8                            smb3decryptionkey[SMB3_ENC_DEC_KEY_SIZE];
+       __u8                            smb3signingkey[SMB3_SIGN_KEY_SIZE];
+-      struct list_head                sessions_entry;
+       struct ksmbd_file_table         file_table;
+       atomic_t                        refcnt;
+ };
+@@ -84,8 +83,8 @@ void ksmbd_session_destroy(struct ksmbd_session *sess);
+ struct ksmbd_session *ksmbd_session_lookup_slowpath(unsigned long long id);
+ struct ksmbd_session *ksmbd_session_lookup(struct ksmbd_conn *conn,
+                                          unsigned long long id);
+-void ksmbd_session_register(struct ksmbd_conn *conn,
+-                          struct ksmbd_session *sess);
++int ksmbd_session_register(struct ksmbd_conn *conn,
++                         struct ksmbd_session *sess);
+ void ksmbd_sessions_deregister(struct ksmbd_conn *conn);
+ struct ksmbd_session *ksmbd_session_lookup_all(struct ksmbd_conn *conn,
+                                              unsigned long long id);
+diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c
+index bb8126deeaf29..d41995f89befe 100644
+--- a/fs/ksmbd/smb2pdu.c
++++ b/fs/ksmbd/smb2pdu.c
+@@ -595,7 +595,8 @@ int smb2_check_user_session(struct ksmbd_work *work)
+       return -EINVAL;
+ }
+-static void destroy_previous_session(struct ksmbd_user *user, u64 id)
++static void destroy_previous_session(struct ksmbd_conn *conn,
++                                   struct ksmbd_user *user, u64 id)
+ {
+       struct ksmbd_session *prev_sess = ksmbd_session_lookup_slowpath(id);
+       struct ksmbd_user *prev_user;
+@@ -614,6 +615,7 @@ static void destroy_previous_session(struct ksmbd_user *user, u64 id)
+       }
+       put_session(prev_sess);
++      xa_erase(&conn->sessions, prev_sess->id);
+       ksmbd_session_destroy(prev_sess);
+ }
+@@ -1452,7 +1454,7 @@ static int ntlm_authenticate(struct ksmbd_work *work)
+       /* Check for previous session */
+       prev_id = le64_to_cpu(req->PreviousSessionId);
+       if (prev_id && prev_id != sess->id)
+-              destroy_previous_session(user, prev_id);
++              destroy_previous_session(conn, user, prev_id);
+       if (sess->state == SMB2_SESSION_VALID) {
+               /*
+@@ -1575,7 +1577,7 @@ static int krb5_authenticate(struct ksmbd_work *work)
+       /* Check previous session */
+       prev_sess_id = le64_to_cpu(req->PreviousSessionId);
+       if (prev_sess_id && prev_sess_id != sess->id)
+-              destroy_previous_session(sess->user, prev_sess_id);
++              destroy_previous_session(conn, sess->user, prev_sess_id);
+       if (sess->state == SMB2_SESSION_VALID)
+               ksmbd_free_user(sess->user);
+@@ -1664,7 +1666,9 @@ int smb2_sess_setup(struct ksmbd_work *work)
+                       goto out_err;
+               }
+               rsp->hdr.SessionId = cpu_to_le64(sess->id);
+-              ksmbd_session_register(conn, sess);
++              rc = ksmbd_session_register(conn, sess);
++              if (rc)
++                      goto out_err;
+       } else if (conn->dialect >= SMB30_PROT_ID &&
+                  (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL) &&
+                  req->Flags & SMB2_SESSION_REQ_FLAG_BINDING) {
+@@ -1845,6 +1849,7 @@ int smb2_sess_setup(struct ksmbd_work *work)
+                       if (sess->user && sess->user->flags & KSMBD_USER_FLAG_DELAY_SESSION)
+                               try_delay = true;
++                      xa_erase(&conn->sessions, sess->id);
+                       ksmbd_session_destroy(sess);
+                       work->sess = NULL;
+                       if (try_delay)
+-- 
+2.39.2
+
diff --git a/queue-5.15/ksmbd-set-rss-capable-in-fsctl_query_network_interfa.patch b/queue-5.15/ksmbd-set-rss-capable-in-fsctl_query_network_interfa.patch
new file mode 100644 (file)
index 0000000..3822beb
--- /dev/null
@@ -0,0 +1,98 @@
+From 2e51f3e34f664076b1f2292e990f84b18a40bfc3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Dec 2021 10:26:43 +0900
+Subject: ksmbd: set RSS capable in FSCTL_QUERY_NETWORK_INTERFACE_INFO
+
+From: Namjae Jeon <linkinjeon@kernel.org>
+
+[ Upstream commit a58b45a4dbfd0bf2ebb157789da4d8e6368afb1b ]
+
+Set RSS capable in FSCTL_QUERY_NETWORK_INTERFACE_INFO if netdev has
+multi tx queues. And add ksmbd_compare_user() to avoid racy condition
+issue in ksmbd_free_user(). because windows client is simultaneously used
+to send session setup requests for multichannel connection.
+
+Tested-by: Ziwei Xie <zw.xie@high-flyer.cn>
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Stable-dep-of: 7b4323373d84 ("ksmbd: fix deadlock in ksmbd_find_crypto_ctx()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ksmbd/mgmt/user_config.c | 10 ++++++++++
+ fs/ksmbd/mgmt/user_config.h |  1 +
+ fs/ksmbd/smb2pdu.c          | 15 ++++++++++-----
+ 3 files changed, 21 insertions(+), 5 deletions(-)
+
+diff --git a/fs/ksmbd/mgmt/user_config.c b/fs/ksmbd/mgmt/user_config.c
+index 1019d3677d553..279d00feff216 100644
+--- a/fs/ksmbd/mgmt/user_config.c
++++ b/fs/ksmbd/mgmt/user_config.c
+@@ -67,3 +67,13 @@ int ksmbd_anonymous_user(struct ksmbd_user *user)
+               return 1;
+       return 0;
+ }
++
++bool ksmbd_compare_user(struct ksmbd_user *u1, struct ksmbd_user *u2)
++{
++      if (strcmp(u1->name, u2->name))
++              return false;
++      if (memcmp(u1->passkey, u2->passkey, u1->passkey_sz))
++              return false;
++
++      return true;
++}
+diff --git a/fs/ksmbd/mgmt/user_config.h b/fs/ksmbd/mgmt/user_config.h
+index aff80b0295790..6a44109617f14 100644
+--- a/fs/ksmbd/mgmt/user_config.h
++++ b/fs/ksmbd/mgmt/user_config.h
+@@ -64,4 +64,5 @@ struct ksmbd_user *ksmbd_login_user(const char *account);
+ struct ksmbd_user *ksmbd_alloc_user(struct ksmbd_login_response *resp);
+ void ksmbd_free_user(struct ksmbd_user *user);
+ int ksmbd_anonymous_user(struct ksmbd_user *user);
++bool ksmbd_compare_user(struct ksmbd_user *u1, struct ksmbd_user *u2);
+ #endif /* __USER_CONFIG_MANAGEMENT_H__ */
+diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c
+index 22d9fcb5f7ca4..c8c2b326ee042 100644
+--- a/fs/ksmbd/smb2pdu.c
++++ b/fs/ksmbd/smb2pdu.c
+@@ -1463,10 +1463,16 @@ static int ntlm_authenticate(struct ksmbd_work *work)
+                       ksmbd_free_user(user);
+                       return 0;
+               }
+-              ksmbd_free_user(sess->user);
++
++              if (!ksmbd_compare_user(sess->user, user)) {
++                      ksmbd_free_user(user);
++                      return -EPERM;
++              }
++              ksmbd_free_user(user);
++      } else {
++              sess->user = user;
+       }
+-      sess->user = user;
+       if (user_guest(sess->user)) {
+               rsp->SessionFlags = SMB2_SESSION_FLAG_IS_GUEST_LE;
+       } else {
+@@ -2071,9 +2077,6 @@ int smb2_session_logoff(struct ksmbd_work *work)
+       ksmbd_debug(SMB, "request\n");
+-      /* Got a valid session, set connection state */
+-      WARN_ON(sess->conn != conn);
+-
+       /* setting CifsExiting here may race with start_tcp_sess */
+       ksmbd_conn_set_need_reconnect(work);
+       ksmbd_close_session_fds(work);
+@@ -7302,6 +7305,8 @@ static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn,
+               nii_rsp->IfIndex = cpu_to_le32(netdev->ifindex);
+               nii_rsp->Capability = 0;
++              if (netdev->real_num_tx_queues > 1)
++                      nii_rsp->Capability |= cpu_to_le32(RSS_CAPABLE);
+               if (ksmbd_rdma_capable_netdev(netdev))
+                       nii_rsp->Capability |= cpu_to_le32(RDMA_CAPABLE);
+-- 
+2.39.2
+
index 5d1584e50ca8c5981c50649f5cedb4c3df77bb71..79750c36473f8474b83345319534b7eb43f38172 100644 (file)
@@ -100,3 +100,19 @@ asoc-soc-compress-inherit-atomicity-from-dai-link-for-compress-fe.patch
 asoc-soc-pcm-move-debugfs-removal-out-of-spinlock.patch
 asoc-dpcm-don-t-pick-up-be-without-substream.patch
 asoc-soc-pcm.c-call-__soc_pcm_close-in-soc_pcm_close.patch
+drm-i915-dg2-support-4k-30-on-hdmi.patch
+drm-i915-dg2-add-additional-hdmi-pixel-clock-frequen.patch
+drm-i915-dg2-add-hdmi-pixel-clock-frequencies-267.30.patch
+drm-msm-remove-struct_mutex-usage.patch
+drm-msm-adreno-fix-runtime-pm-imbalance-at-gpu-load.patch
+drm-amd-display-refine-condition-of-cursor-visibilit.patch
+drm-amd-display-add-null-plane_state-check-for-curso.patch
+wifi-rtw88-rtw8821c-fix-rfe_option-field-width.patch
+ksmbd-set-rss-capable-in-fsctl_query_network_interfa.patch
+ksmbd-fix-multi-session-connection-failure.patch
+ksmbd-replace-sessions-list-in-connection-with-xarra.patch
+ksmbd-add-channel-rwlock.patch
+ksmbd-fix-kernel-oops-from-idr_remove.patch
+ksmbd-fix-racy-issue-while-destroying-session-on-mul.patch
+ksmbd-fix-deadlock-in-ksmbd_find_crypto_ctx.patch
+ksmbd-not-allow-guest-user-on-multichannel.patch
diff --git a/queue-5.15/wifi-rtw88-rtw8821c-fix-rfe_option-field-width.patch b/queue-5.15/wifi-rtw88-rtw8821c-fix-rfe_option-field-width.patch
new file mode 100644 (file)
index 0000000..2f37ed2
--- /dev/null
@@ -0,0 +1,60 @@
+From 8228ea44695e99e6db63c07c111d7d45c8bfc77a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Apr 2023 16:03:56 +0200
+Subject: wifi: rtw88: rtw8821c: Fix rfe_option field width
+
+From: Sascha Hauer <s.hauer@pengutronix.de>
+
+[ Upstream commit 14705f969d98187a1cc2682e0c9bd2e230b8098f ]
+
+On my RTW8821CU chipset rfe_option reads as 0x22. Looking at the
+vendor driver suggests that the field width of rfe_option is 5 bit,
+so rfe_option should be masked with 0x1f.
+
+Without this the rfe_option comparisons with 2 further down the
+driver evaluate as false when they should really evaluate as true.
+The effect is that 2G channels do not work.
+
+rfe_option is also used as an array index into rtw8821c_rfe_defs[].
+rtw8821c_rfe_defs[34] (0x22) was added as part of adding USB support,
+likely because rfe_option reads as 0x22. As this now becomes 0x2,
+rtw8821c_rfe_defs[34] is no longer used and can be removed.
+
+Note that this might not be the whole truth. In the vendor driver
+there are indeed places where the unmasked rfe_option value is used.
+However, the driver has several places where rfe_option is tested
+with the pattern if (rfe_option == 2 || rfe_option == 0x22) or
+if (rfe_option == 4 || rfe_option == 0x24), so that rfe_option BIT(5)
+has no influence on the code path taken. We therefore mask BIT(5)
+out from rfe_option entirely until this assumption is proved wrong
+by some chip variant we do not know yet.
+
+Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
+Tested-by: Alexandru gagniuc <mr.nuke.me@gmail.com>
+Tested-by: Larry Finger <Larry.Finger@lwfinger.net>
+Tested-by: ValdikSS <iam@valdikss.org.ru>
+Cc: stable@vger.kernel.org
+Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20230417140358.2240429-3-s.hauer@pengutronix.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtw88/rtw8821c.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
+index 897da3ed2f029..280602a34fe67 100644
+--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c
++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
+@@ -40,7 +40,7 @@ static int rtw8821c_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
+       map = (struct rtw8821c_efuse *)log_map;
+-      efuse->rfe_option = map->rfe_option;
++      efuse->rfe_option = map->rfe_option & 0x1f;
+       efuse->rf_board_option = map->rf_board_option;
+       efuse->crystal_cap = map->xtal_k;
+       efuse->pa_type_2g = map->pa_type;
+-- 
+2.39.2
+