From: Sasha Levin Date: Sun, 25 Aug 2024 23:46:18 +0000 (-0400) Subject: Fixes for 6.10 X-Git-Tag: v6.1.107~66 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=47972288814241a73d3427a75611234469843143;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.10 Signed-off-by: Sasha Levin --- diff --git a/queue-6.10/drm-i915-hdcp-use-correct-cp_irq_count.patch b/queue-6.10/drm-i915-hdcp-use-correct-cp_irq_count.patch new file mode 100644 index 00000000000..d9685487275 --- /dev/null +++ b/queue-6.10/drm-i915-hdcp-use-correct-cp_irq_count.patch @@ -0,0 +1,49 @@ +From 5803aff837622f3bed7e77a0487af65cc88bdd38 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 9 Aug 2024 17:11:28 +0530 +Subject: drm/i915/hdcp: Use correct cp_irq_count + +From: Suraj Kandpal + +[ Upstream commit 5d41eeb6725e3e24853629e5d7635e4bc45d736e ] + +We are checking cp_irq_count from the wrong hdcp structure which +ends up giving timed out errors. We only increment the cp_irq_count +of the primary connector's hdcp structure but here in case of +multidisplay setup we end up checking the secondary connector's hdcp +structure, which will not have its cp_irq_count incremented. This leads +to a timed out at CP_IRQ error even though a CP_IRQ was raised. Extract +it from the correct intel_hdcp structure. + +--v2 +-Explain why it was the wrong hdcp structure [Jani] + +Fixes: 8c9e4f68b861 ("drm/i915/hdcp: Use per-device debugs") +Signed-off-by: Suraj Kandpal +Reviewed-by: Ankit Nautiyal +Link: https://patchwork.freedesktop.org/patch/msgid/20240809114127.3940699-2-suraj.kandpal@intel.com +(cherry picked from commit dd925902634def895690426bf10e0a8b3e56f56d) +Signed-off-by: Joonas Lahtinen +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c +index 92b03073acdd5..555428606e127 100644 +--- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c ++++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c +@@ -39,7 +39,9 @@ static u32 transcoder_to_stream_enc_status(enum transcoder cpu_transcoder) + static void intel_dp_hdcp_wait_for_cp_irq(struct intel_connector *connector, + int timeout) + { +- struct intel_hdcp *hdcp = &connector->hdcp; ++ struct intel_digital_port *dig_port = intel_attached_dig_port(connector); ++ struct intel_dp *dp = &dig_port->dp; ++ struct intel_hdcp *hdcp = &dp->attached_connector->hdcp; + long ret; + + #define C (hdcp->cp_irq_count_cached != atomic_read(&hdcp->cp_irq_count)) +-- +2.43.0 + diff --git a/queue-6.10/drm-msm-dp-fix-the-max-supported-bpp-logic.patch b/queue-6.10/drm-msm-dp-fix-the-max-supported-bpp-logic.patch new file mode 100644 index 00000000000..fcdc66f570c --- /dev/null +++ b/queue-6.10/drm-msm-dp-fix-the-max-supported-bpp-logic.patch @@ -0,0 +1,91 @@ +From 53637a4dd22de8561bf8848eddb9b1d93dea139f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 5 Aug 2024 13:20:08 -0700 +Subject: drm/msm/dp: fix the max supported bpp logic + +From: Abhinav Kumar + +[ Upstream commit d19d5b8d8f6dab942ce5ddbcf34bf7275e778250 ] + +Fix the dp_panel_get_supported_bpp() API to return the minimum +supported bpp correctly for relevant cases and use this API +to correct the behavior of DP driver which hard-codes the max supported +bpp to 30. + +This is incorrect because the number of lanes and max data rate +supported by the lanes need to be taken into account. + +Replace the hardcoded limit with the appropriate math which accounts +for the accurate number of lanes and max data rate. + +changes in v2: + - Fix the dp_panel_get_supported_bpp() and use it + - Drop the max_t usage as dp_panel_get_supported_bpp() already + returns the min_bpp correctly now + +changes in v3: + - replace min_t with just min as all params are u32 + +Fixes: c943b4948b58 ("drm/msm/dp: add displayPort driver support") +Reported-by: Dmitry Baryshkov +Closes: https://gitlab.freedesktop.org/drm/msm/-/issues/43 +Tested-by: Dmitry Baryshkov # SM8350-HDK +Reviewed-by: Stephen Boyd +Patchwork: https://patchwork.freedesktop.org/patch/607073/ +Link: https://lore.kernel.org/r/20240805202009.1120981-1-quic_abhinavk@quicinc.com +Signed-off-by: Stephen Boyd +Signed-off-by: Abhinav Kumar +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/dp/dp_panel.c | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/msm/dp/dp_panel.c b/drivers/gpu/drm/msm/dp/dp_panel.c +index 07db8f37cd06a..017fb8cc8ab67 100644 +--- a/drivers/gpu/drm/msm/dp/dp_panel.c ++++ b/drivers/gpu/drm/msm/dp/dp_panel.c +@@ -90,22 +90,22 @@ static int dp_panel_read_dpcd(struct dp_panel *dp_panel) + static u32 dp_panel_get_supported_bpp(struct dp_panel *dp_panel, + u32 mode_edid_bpp, u32 mode_pclk_khz) + { +- struct dp_link_info *link_info; ++ const struct dp_link_info *link_info; + const u32 max_supported_bpp = 30, min_supported_bpp = 18; +- u32 bpp = 0, data_rate_khz = 0; ++ u32 bpp, data_rate_khz; + +- bpp = min_t(u32, mode_edid_bpp, max_supported_bpp); ++ bpp = min(mode_edid_bpp, max_supported_bpp); + + link_info = &dp_panel->link_info; + data_rate_khz = link_info->num_lanes * link_info->rate * 8; + +- while (bpp > min_supported_bpp) { ++ do { + if (mode_pclk_khz * bpp <= data_rate_khz) +- break; ++ return bpp; + bpp -= 6; +- } ++ } while (bpp > min_supported_bpp); + +- return bpp; ++ return min_supported_bpp; + } + + static int dp_panel_update_modes(struct drm_connector *connector, +@@ -442,8 +442,9 @@ int dp_panel_init_panel_info(struct dp_panel *dp_panel) + drm_mode->clock); + drm_dbg_dp(panel->drm_dev, "bpp = %d\n", dp_panel->dp_mode.bpp); + +- dp_panel->dp_mode.bpp = max_t(u32, 18, +- min_t(u32, dp_panel->dp_mode.bpp, 30)); ++ dp_panel->dp_mode.bpp = dp_panel_get_mode_bpp(dp_panel, dp_panel->dp_mode.bpp, ++ dp_panel->dp_mode.drm_mode.clock); ++ + drm_dbg_dp(panel->drm_dev, "updated bpp = %d\n", + dp_panel->dp_mode.bpp); + +-- +2.43.0 + diff --git a/queue-6.10/drm-msm-dp-reset-the-link-phy-params-before-link-tra.patch b/queue-6.10/drm-msm-dp-reset-the-link-phy-params-before-link-tra.patch new file mode 100644 index 00000000000..cee82a5c096 --- /dev/null +++ b/queue-6.10/drm-msm-dp-reset-the-link-phy-params-before-link-tra.patch @@ -0,0 +1,42 @@ +From bf835cd6a85eed3b96d38dae9568a9e87456cc0d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 25 Jul 2024 15:04:50 -0700 +Subject: drm/msm/dp: reset the link phy params before link training + +From: Abhinav Kumar + +[ Upstream commit 319aca883bfa1b85ee08411541b51b9a934ac858 ] + +Before re-starting link training reset the link phy params namely +the pre-emphasis and voltage swing levels otherwise the next +link training begins at the previously cached levels which can result +in link training failures. + +Fixes: 8ede2ecc3e5e ("drm/msm/dp: Add DP compliance tests on Snapdragon Chipsets") +Reviewed-by: Dmitry Baryshkov +Tested-by: Dmitry Baryshkov # SM8350-HDK +Reviewed-by: Stephen Boyd +Patchwork: https://patchwork.freedesktop.org/patch/605946/ +Link: https://lore.kernel.org/r/20240725220450.131245-1-quic_abhinavk@quicinc.com +Signed-off-by: Abhinav Kumar +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/dp/dp_ctrl.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c +index 7bc8a9f0657a9..f342fc5ae41ec 100644 +--- a/drivers/gpu/drm/msm/dp/dp_ctrl.c ++++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c +@@ -1286,6 +1286,8 @@ static int dp_ctrl_link_train(struct dp_ctrl_private *ctrl, + link_info.rate = ctrl->link->link_params.rate; + link_info.capabilities = DP_LINK_CAP_ENHANCED_FRAMING; + ++ dp_link_reset_phy_params_vx_px(ctrl->link); ++ + dp_aux_link_configure(ctrl->aux, &link_info); + + if (drm_dp_max_downspread(dpcd)) +-- +2.43.0 + diff --git a/queue-6.10/drm-msm-dpu-cleanup-fb-if-dpu_format_populate_layout.patch b/queue-6.10/drm-msm-dpu-cleanup-fb-if-dpu_format_populate_layout.patch new file mode 100644 index 00000000000..4e64a70ba81 --- /dev/null +++ b/queue-6.10/drm-msm-dpu-cleanup-fb-if-dpu_format_populate_layout.patch @@ -0,0 +1,70 @@ +From 00c9c40af914b0d4c9e91e19f934440e9f3415d6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Jun 2024 00:13:41 +0300 +Subject: drm/msm/dpu: cleanup FB if dpu_format_populate_layout fails + +From: Dmitry Baryshkov + +[ Upstream commit bfa1a6283be390947d3649c482e5167186a37016 ] + +If the dpu_format_populate_layout() fails, then FB is prepared, but not +cleaned up. This ends up leaking the pin_count on the GEM object and +causes a splat during DRM file closure: + +msm_obj->pin_count +WARNING: CPU: 2 PID: 569 at drivers/gpu/drm/msm/msm_gem.c:121 update_lru_locked+0xc4/0xcc +[...] +Call trace: + update_lru_locked+0xc4/0xcc + put_pages+0xac/0x100 + msm_gem_free_object+0x138/0x180 + drm_gem_object_free+0x1c/0x30 + drm_gem_object_handle_put_unlocked+0x108/0x10c + drm_gem_object_release_handle+0x58/0x70 + idr_for_each+0x68/0xec + drm_gem_release+0x28/0x40 + drm_file_free+0x174/0x234 + drm_release+0xb0/0x160 + __fput+0xc0/0x2c8 + __fput_sync+0x50/0x5c + __arm64_sys_close+0x38/0x7c + invoke_syscall+0x48/0x118 + el0_svc_common.constprop.0+0x40/0xe0 + do_el0_svc+0x1c/0x28 + el0_svc+0x4c/0x120 + el0t_64_sync_handler+0x100/0x12c + el0t_64_sync+0x190/0x194 +irq event stamp: 129818 +hardirqs last enabled at (129817): [] console_unlock+0x118/0x124 +hardirqs last disabled at (129818): [] el1_dbg+0x24/0x8c +softirqs last enabled at (129808): [] handle_softirqs+0x4c8/0x4e8 +softirqs last disabled at (129785): [] __do_softirq+0x14/0x20 + +Fixes: 25fdd5933e4c ("drm/msm: Add SDM845 DPU support") +Signed-off-by: Dmitry Baryshkov +Reviewed-by: Abhinav Kumar +Patchwork: https://patchwork.freedesktop.org/patch/600714/ +Link: https://lore.kernel.org/r/20240625-dpu-mode-config-width-v5-1-501d984d634f@linaro.org +Signed-off-by: Abhinav Kumar +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +index 1c3a2657450c6..eabc4813c649c 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +@@ -680,6 +680,9 @@ static int dpu_plane_prepare_fb(struct drm_plane *plane, + new_state->fb, &layout); + if (ret) { + DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret); ++ if (pstate->aspace) ++ msm_framebuffer_cleanup(new_state->fb, pstate->aspace, ++ pstate->needs_dirtyfb); + return ret; + } + +-- +2.43.0 + diff --git a/queue-6.10/drm-msm-dpu-don-t-play-tricks-with-debug-macros.patch b/queue-6.10/drm-msm-dpu-don-t-play-tricks-with-debug-macros.patch new file mode 100644 index 00000000000..cce57261b69 --- /dev/null +++ b/queue-6.10/drm-msm-dpu-don-t-play-tricks-with-debug-macros.patch @@ -0,0 +1,66 @@ +From 3f8f69f13996f8f4c79bd300703ce0b0f780e8b2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 2 Aug 2024 22:47:34 +0300 +Subject: drm/msm/dpu: don't play tricks with debug macros + +From: Dmitry Baryshkov + +[ Upstream commit df24373435f5899a2a98b7d377479c8d4376613b ] + +DPU debugging macros need to be converted to a proper drm_debug_* +macros, however this is a going an intrusive patch, not suitable for a +fix. Wire DPU_DEBUG and DPU_DEBUG_DRIVER to always use DRM_DEBUG_DRIVER +to make sure that DPU debugging messages always end up in the drm debug +messages and are controlled via the usual drm.debug mask. + +I don't think that it is a good idea for a generic DPU_DEBUG macro to be +tied to DRM_UT_KMS. It is used to report a debug message from driver, so by +default it should go to the DRM_UT_DRIVER channel. While refactoring +debug macros later on we might end up with particular messages going to +ATOMIC or KMS, but DRIVER should be the default. + +Fixes: 25fdd5933e4c ("drm/msm: Add SDM845 DPU support") +Signed-off-by: Dmitry Baryshkov +Reviewed-by: Abhinav Kumar +Patchwork: https://patchwork.freedesktop.org/patch/606932/ +Link: https://lore.kernel.org/r/20240802-dpu-fix-wb-v2-2-7eac9eb8e895@linaro.org +Signed-off-by: Abhinav Kumar +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 14 ++------------ + 1 file changed, 2 insertions(+), 12 deletions(-) + +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +index e2adc937ea63b..935ff6fd172c4 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +@@ -31,24 +31,14 @@ + * @fmt: Pointer to format string + */ + #define DPU_DEBUG(fmt, ...) \ +- do { \ +- if (drm_debug_enabled(DRM_UT_KMS)) \ +- DRM_DEBUG(fmt, ##__VA_ARGS__); \ +- else \ +- pr_debug(fmt, ##__VA_ARGS__); \ +- } while (0) ++ DRM_DEBUG_DRIVER(fmt, ##__VA_ARGS__) + + /** + * DPU_DEBUG_DRIVER - macro for hardware driver logging + * @fmt: Pointer to format string + */ + #define DPU_DEBUG_DRIVER(fmt, ...) \ +- do { \ +- if (drm_debug_enabled(DRM_UT_DRIVER)) \ +- DRM_ERROR(fmt, ##__VA_ARGS__); \ +- else \ +- pr_debug(fmt, ##__VA_ARGS__); \ +- } while (0) ++ DRM_DEBUG_DRIVER(fmt, ##__VA_ARGS__) + + #define DPU_ERROR(fmt, ...) pr_err("[dpu error]" fmt, ##__VA_ARGS__) + #define DPU_ERROR_RATELIMITED(fmt, ...) pr_err_ratelimited("[dpu error]" fmt, ##__VA_ARGS__) +-- +2.43.0 + diff --git a/queue-6.10/drm-msm-dpu-limit-qcm2290-to-rgb-formats-only.patch b/queue-6.10/drm-msm-dpu-limit-qcm2290-to-rgb-formats-only.patch new file mode 100644 index 00000000000..08f5244c999 --- /dev/null +++ b/queue-6.10/drm-msm-dpu-limit-qcm2290-to-rgb-formats-only.patch @@ -0,0 +1,41 @@ +From 9d305ea45a0c08c4848cff74dbf7cc0946edfa57 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Jun 2024 00:45:55 +0300 +Subject: drm/msm/dpu: limit QCM2290 to RGB formats only + +From: Dmitry Baryshkov + +[ Upstream commit 2db13c4a631505029ada9404e09a2b06a268c1c4 ] + +The QCM2290 doesn't have CSC blocks, so it can not support YUV formats +even on ViG blocks. Fix the formats declared by _VIG_SBLK_NOSCALE(). + +Fixes: 5334087ee743 ("drm/msm: add support for QCM2290 MDSS") +Signed-off-by: Dmitry Baryshkov +Reviewed-by: Abhinav Kumar +Patchwork: https://patchwork.freedesktop.org/patch/601048/ +Link: https://lore.kernel.org/r/20240627-dpu-virtual-wide-v5-1-5efb90cbb8be@linaro.org +Signed-off-by: Abhinav Kumar +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +index 9b72977feafa4..e61b5681f3bbd 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +@@ -308,8 +308,8 @@ static const u32 wb2_formats_rgb_yuv[] = { + { \ + .maxdwnscale = SSPP_UNITY_SCALE, \ + .maxupscale = SSPP_UNITY_SCALE, \ +- .format_list = plane_formats_yuv, \ +- .num_formats = ARRAY_SIZE(plane_formats_yuv), \ ++ .format_list = plane_formats, \ ++ .num_formats = ARRAY_SIZE(plane_formats), \ + .virt_format_list = plane_formats, \ + .virt_num_formats = ARRAY_SIZE(plane_formats), \ + } +-- +2.43.0 + diff --git a/queue-6.10/drm-msm-dpu-move-dpu_encoder-s-connector-assignment-.patch b/queue-6.10/drm-msm-dpu-move-dpu_encoder-s-connector-assignment-.patch new file mode 100644 index 00000000000..585759ff1a0 --- /dev/null +++ b/queue-6.10/drm-msm-dpu-move-dpu_encoder-s-connector-assignment-.patch @@ -0,0 +1,61 @@ +From 7f38661e3cdf7929bd731a2edaeffb5fb166fd40 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 31 Jul 2024 12:17:22 -0700 +Subject: drm/msm/dpu: move dpu_encoder's connector assignment to + atomic_enable() + +From: Abhinav Kumar + +[ Upstream commit aedf02e46eb549dac8db4821a6b9f0c6bf6e3990 ] + +For cases where the crtc's connectors_changed was set without enable/active +getting toggled , there is an atomic_enable() call followed by an +atomic_disable() but without an atomic_mode_set(). + +This results in a NULL ptr access for the dpu_encoder_get_drm_fmt() call in +the atomic_enable() as the dpu_encoder's connector was cleared in the +atomic_disable() but not re-assigned as there was no atomic_mode_set() call. + +Fix the NULL ptr access by moving the assignment for atomic_enable() and also +use drm_atomic_get_new_connector_for_encoder() to get the connector from +the atomic_state. + +Fixes: 25fdd5933e4c ("drm/msm: Add SDM845 DPU support") +Reported-by: Dmitry Baryshkov +Closes: https://gitlab.freedesktop.org/drm/msm/-/issues/59 +Suggested-by: Dmitry Baryshkov +Reviewed-by: Dmitry Baryshkov +Tested-by: Dmitry Baryshkov # SM8350-HDK +Patchwork: https://patchwork.freedesktop.org/patch/606729/ +Link: https://lore.kernel.org/r/20240731191723.3050932-1-quic_abhinavk@quicinc.com +Signed-off-by: Abhinav Kumar +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +index 697ad4a640516..a6c5e3bc9bf15 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +@@ -1179,8 +1179,6 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, + + cstate->num_mixers = num_lm; + +- dpu_enc->connector = conn_state->connector; +- + for (i = 0; i < dpu_enc->num_phys_encs; i++) { + struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; + +@@ -1277,6 +1275,8 @@ static void dpu_encoder_virt_atomic_enable(struct drm_encoder *drm_enc, + + dpu_enc->commit_done_timedout = false; + ++ dpu_enc->connector = drm_atomic_get_new_connector_for_encoder(state, drm_enc); ++ + cur_mode = &dpu_enc->base.crtc->state->adjusted_mode; + + dpu_enc->wide_bus_en = dpu_encoder_is_widebus_enabled(drm_enc); +-- +2.43.0 + diff --git a/queue-6.10/drm-msm-dpu-relax-yuv-requirements.patch b/queue-6.10/drm-msm-dpu-relax-yuv-requirements.patch new file mode 100644 index 00000000000..d83c98a2292 --- /dev/null +++ b/queue-6.10/drm-msm-dpu-relax-yuv-requirements.patch @@ -0,0 +1,44 @@ +From 3deb908f4b2a9305715a938c33b08736addd33f4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Jun 2024 00:45:56 +0300 +Subject: drm/msm/dpu: relax YUV requirements + +From: Dmitry Baryshkov + +[ Upstream commit cb18195914e353ece0e789e365a5a16872169805 ] + +YUV formats require only CSC to be enabled. Even decimated formats +should not require scaler. Relax the requirement and don't check for the +scaler block while checking if YUV format can be enabled. + +Fixes: 25fdd5933e4c ("drm/msm: Add SDM845 DPU support") +Signed-off-by: Dmitry Baryshkov +Reviewed-by: Abhinav Kumar +Patchwork: https://patchwork.freedesktop.org/patch/601049/ +Link: https://lore.kernel.org/r/20240627-dpu-virtual-wide-v5-2-5efb90cbb8be@linaro.org +Signed-off-by: Abhinav Kumar +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +index eabc4813c649c..cbdb9628d962d 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +@@ -746,10 +746,9 @@ static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu, + min_src_size = MSM_FORMAT_IS_YUV(fmt) ? 2 : 1; + + if (MSM_FORMAT_IS_YUV(fmt) && +- (!pipe->sspp->cap->sblk->scaler_blk.len || +- !pipe->sspp->cap->sblk->csc_blk.len)) { ++ !pipe->sspp->cap->sblk->csc_blk.len) { + DPU_DEBUG_PLANE(pdpu, +- "plane doesn't have scaler/csc for yuv\n"); ++ "plane doesn't have csc for yuv\n"); + return -EINVAL; + } + +-- +2.43.0 + diff --git a/queue-6.10/drm-msm-dpu-take-plane-rotation-into-account-for-wid.patch b/queue-6.10/drm-msm-dpu-take-plane-rotation-into-account-for-wid.patch new file mode 100644 index 00000000000..7c9e533a360 --- /dev/null +++ b/queue-6.10/drm-msm-dpu-take-plane-rotation-into-account-for-wid.patch @@ -0,0 +1,62 @@ +From 049534483fc24d831403e6593097ccaab8b6500c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Jun 2024 00:45:57 +0300 +Subject: drm/msm/dpu: take plane rotation into account for wide planes + +From: Dmitry Baryshkov + +[ Upstream commit d3a785e4f983f523380e023d8a05fb6d04402957 ] + +Take into account the plane rotation and flipping when calculating src +positions for the wide plane parts. + +This is not an issue yet, because rotation is only supported for the +UBWC planes and wide UBWC planes are rejected anyway because in parallel +multirect case only the half of the usual width is supported for tiled +formats. However it's better to fix this now rather than stumbling upon +it later. + +Fixes: 80e8ae3b38ab ("drm/msm/dpu: add support for wide planes") +Reviewed-by: Abhinav Kumar +Signed-off-by: Dmitry Baryshkov +Patchwork: https://patchwork.freedesktop.org/patch/601059/ +Link: https://lore.kernel.org/r/20240627-dpu-virtual-wide-v5-3-5efb90cbb8be@linaro.org +Signed-off-by: Abhinav Kumar +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +index cbdb9628d962d..c31d283d1c6c1 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +@@ -865,6 +865,10 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, + + max_linewidth = pdpu->catalog->caps->max_linewidth; + ++ drm_rect_rotate(&pipe_cfg->src_rect, ++ new_plane_state->fb->width, new_plane_state->fb->height, ++ new_plane_state->rotation); ++ + if ((drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) || + _dpu_plane_calc_clk(&crtc_state->adjusted_mode, pipe_cfg) > max_mdp_clk_rate) { + /* +@@ -914,6 +918,14 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, + r_pipe_cfg->dst_rect.x1 = pipe_cfg->dst_rect.x2; + } + ++ drm_rect_rotate_inv(&pipe_cfg->src_rect, ++ new_plane_state->fb->width, new_plane_state->fb->height, ++ new_plane_state->rotation); ++ if (r_pipe->sspp) ++ drm_rect_rotate_inv(&r_pipe_cfg->src_rect, ++ new_plane_state->fb->width, new_plane_state->fb->height, ++ new_plane_state->rotation); ++ + ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, fmt, &crtc_state->adjusted_mode); + if (ret) + return ret; +-- +2.43.0 + diff --git a/queue-6.10/drm-msm-fix-the-highest_bank_bit-for-sc7180.patch b/queue-6.10/drm-msm-fix-the-highest_bank_bit-for-sc7180.patch new file mode 100644 index 00000000000..37b867e465f --- /dev/null +++ b/queue-6.10/drm-msm-fix-the-highest_bank_bit-for-sc7180.patch @@ -0,0 +1,46 @@ +From 4a746fa3f64f612ab37f0c314535592f7c04e4cf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 8 Aug 2024 16:52:27 -0700 +Subject: drm/msm: fix the highest_bank_bit for sc7180 + +From: Abhinav Kumar + +[ Upstream commit 3e30296b374af33cb4c12ff93df0b1e5b2d0f80b ] + +sc7180 programs the ubwc settings as 0x1e as that would mean a +highest bank bit of 14 which matches what the GPU sets as well. + +However, the highest_bank_bit field of the msm_mdss_data which is +being used to program the SSPP's fetch configuration is programmed +to a highest bank bit of 16 as 0x3 translates to 16 and not 14. + +Fix the highest bank bit field used for the SSPP to match the mdss +and gpu settings. + +Fixes: 6f410b246209 ("drm/msm/mdss: populate missing data") +Reviewed-by: Rob Clark +Tested-by: Stephen Boyd # Trogdor.Lazor +Patchwork: https://patchwork.freedesktop.org/patch/607625/ +Link: https://lore.kernel.org/r/20240808235227.2701479-1-quic_abhinavk@quicinc.com +Signed-off-by: Abhinav Kumar +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/msm_mdss.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/msm/msm_mdss.c b/drivers/gpu/drm/msm/msm_mdss.c +index fab6ad4e5107c..ec75274178028 100644 +--- a/drivers/gpu/drm/msm/msm_mdss.c ++++ b/drivers/gpu/drm/msm/msm_mdss.c +@@ -577,7 +577,7 @@ static const struct msm_mdss_data sc7180_data = { + .ubwc_enc_version = UBWC_2_0, + .ubwc_dec_version = UBWC_2_0, + .ubwc_static = 0x1e, +- .highest_bank_bit = 0x3, ++ .highest_bank_bit = 0x1, + .reg_bus_bw = 76800, + }; + +-- +2.43.0 + diff --git a/queue-6.10/drm-xe-decouple-job-seqno-and-lrc-seqno.patch b/queue-6.10/drm-xe-decouple-job-seqno-and-lrc-seqno.patch new file mode 100644 index 00000000000..20c38ec8686 --- /dev/null +++ b/queue-6.10/drm-xe-decouple-job-seqno-and-lrc-seqno.patch @@ -0,0 +1,235 @@ +From 515bfd7752e9c7e6944d2e6c4b5261ec1cd1f3d9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 May 2024 15:59:08 +0200 +Subject: drm/xe: Decouple job seqno and lrc seqno +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Matthew Brost + +[ Upstream commit 08f7200899ca72dec550af092ae424b7db099abd ] + +Tightly coupling these seqno presents problems if alternative fences for +jobs are used. Decouple these for correctness. + +v2: +- Slightly reword commit message (Thomas) +- Make sure the lrc fence ops are used in comparison (Thomas) +- Assume seqno is unsigned rather than signed in format string (Thomas) + +Cc: Thomas Hellström +Signed-off-by: Matthew Brost +Signed-off-by: Thomas Hellström +Reviewed-by: Rodrigo Vivi +Link: https://patchwork.freedesktop.org/patch/msgid/20240527135912.152156-2-thomas.hellstrom@linux.intel.com +Stable-dep-of: 9e7f30563677 ("drm/xe: Free job before xe_exec_queue_put") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_exec_queue.c | 2 +- + drivers/gpu/drm/xe/xe_guc_submit.c | 5 +++-- + drivers/gpu/drm/xe/xe_ring_ops.c | 12 ++++++------ + drivers/gpu/drm/xe/xe_sched_job.c | 16 ++++++++-------- + drivers/gpu/drm/xe/xe_sched_job.h | 5 +++++ + drivers/gpu/drm/xe/xe_sched_job_types.h | 2 ++ + drivers/gpu/drm/xe/xe_trace.h | 7 +++++-- + 7 files changed, 30 insertions(+), 19 deletions(-) + +diff --git a/drivers/gpu/drm/xe/xe_exec_queue.c b/drivers/gpu/drm/xe/xe_exec_queue.c +index 33b03605a1d15..79d099e054916 100644 +--- a/drivers/gpu/drm/xe/xe_exec_queue.c ++++ b/drivers/gpu/drm/xe/xe_exec_queue.c +@@ -98,7 +98,7 @@ static struct xe_exec_queue *__xe_exec_queue_alloc(struct xe_device *xe, + + if (xe_exec_queue_is_parallel(q)) { + q->parallel.composite_fence_ctx = dma_fence_context_alloc(1); +- q->parallel.composite_fence_seqno = XE_FENCE_INITIAL_SEQNO; ++ q->parallel.composite_fence_seqno = 0; + } + + return q; +diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c +index 8c75791cbc4fb..e48285c81bf57 100644 +--- a/drivers/gpu/drm/xe/xe_guc_submit.c ++++ b/drivers/gpu/drm/xe/xe_guc_submit.c +@@ -917,8 +917,9 @@ guc_exec_queue_timedout_job(struct drm_sched_job *drm_job) + return DRM_GPU_SCHED_STAT_NOMINAL; + } + +- drm_notice(&xe->drm, "Timedout job: seqno=%u, guc_id=%d, flags=0x%lx", +- xe_sched_job_seqno(job), q->guc->id, q->flags); ++ drm_notice(&xe->drm, "Timedout job: seqno=%u, lrc_seqno=%u, guc_id=%d, flags=0x%lx", ++ xe_sched_job_seqno(job), xe_sched_job_lrc_seqno(job), ++ q->guc->id, q->flags); + xe_gt_WARN(q->gt, q->flags & EXEC_QUEUE_FLAG_KERNEL, + "Kernel-submitted job timed out\n"); + xe_gt_WARN(q->gt, q->flags & EXEC_QUEUE_FLAG_VM && !exec_queue_killed(q), +diff --git a/drivers/gpu/drm/xe/xe_ring_ops.c b/drivers/gpu/drm/xe/xe_ring_ops.c +index aca7a9af6e846..3b6aad8dea99a 100644 +--- a/drivers/gpu/drm/xe/xe_ring_ops.c ++++ b/drivers/gpu/drm/xe/xe_ring_ops.c +@@ -412,7 +412,7 @@ static void emit_job_gen12_gsc(struct xe_sched_job *job) + + __emit_job_gen12_simple(job, job->q->lrc, + job->batch_addr[0], +- xe_sched_job_seqno(job)); ++ xe_sched_job_lrc_seqno(job)); + } + + static void emit_job_gen12_copy(struct xe_sched_job *job) +@@ -421,14 +421,14 @@ static void emit_job_gen12_copy(struct xe_sched_job *job) + + if (xe_sched_job_is_migration(job->q)) { + emit_migration_job_gen12(job, job->q->lrc, +- xe_sched_job_seqno(job)); ++ xe_sched_job_lrc_seqno(job)); + return; + } + + for (i = 0; i < job->q->width; ++i) + __emit_job_gen12_simple(job, job->q->lrc + i, +- job->batch_addr[i], +- xe_sched_job_seqno(job)); ++ job->batch_addr[i], ++ xe_sched_job_lrc_seqno(job)); + } + + static void emit_job_gen12_video(struct xe_sched_job *job) +@@ -439,7 +439,7 @@ static void emit_job_gen12_video(struct xe_sched_job *job) + for (i = 0; i < job->q->width; ++i) + __emit_job_gen12_video(job, job->q->lrc + i, + job->batch_addr[i], +- xe_sched_job_seqno(job)); ++ xe_sched_job_lrc_seqno(job)); + } + + static void emit_job_gen12_render_compute(struct xe_sched_job *job) +@@ -449,7 +449,7 @@ static void emit_job_gen12_render_compute(struct xe_sched_job *job) + for (i = 0; i < job->q->width; ++i) + __emit_job_gen12_render_compute(job, job->q->lrc + i, + job->batch_addr[i], +- xe_sched_job_seqno(job)); ++ xe_sched_job_lrc_seqno(job)); + } + + static const struct xe_ring_ops ring_ops_gen12_gsc = { +diff --git a/drivers/gpu/drm/xe/xe_sched_job.c b/drivers/gpu/drm/xe/xe_sched_job.c +index a4e030f5e019a..874450be327ec 100644 +--- a/drivers/gpu/drm/xe/xe_sched_job.c ++++ b/drivers/gpu/drm/xe/xe_sched_job.c +@@ -117,6 +117,7 @@ struct xe_sched_job *xe_sched_job_create(struct xe_exec_queue *q, + err = PTR_ERR(job->fence); + goto err_sched_job; + } ++ job->lrc_seqno = job->fence->seqno; + } else { + struct dma_fence_array *cf; + +@@ -132,6 +133,8 @@ struct xe_sched_job *xe_sched_job_create(struct xe_exec_queue *q, + err = PTR_ERR(fences[j]); + goto err_fences; + } ++ if (!j) ++ job->lrc_seqno = fences[0]->seqno; + } + + cf = dma_fence_array_create(q->width, fences, +@@ -144,10 +147,6 @@ struct xe_sched_job *xe_sched_job_create(struct xe_exec_queue *q, + goto err_fences; + } + +- /* Sanity check */ +- for (j = 0; j < q->width; ++j) +- xe_assert(job_to_xe(job), cf->base.seqno == fences[j]->seqno); +- + job->fence = &cf->base; + } + +@@ -229,9 +228,9 @@ bool xe_sched_job_started(struct xe_sched_job *job) + { + struct xe_lrc *lrc = job->q->lrc; + +- return !__dma_fence_is_later(xe_sched_job_seqno(job), ++ return !__dma_fence_is_later(xe_sched_job_lrc_seqno(job), + xe_lrc_start_seqno(lrc), +- job->fence->ops); ++ dma_fence_array_first(job->fence)->ops); + } + + bool xe_sched_job_completed(struct xe_sched_job *job) +@@ -243,8 +242,9 @@ bool xe_sched_job_completed(struct xe_sched_job *job) + * parallel handshake is done. + */ + +- return !__dma_fence_is_later(xe_sched_job_seqno(job), xe_lrc_seqno(lrc), +- job->fence->ops); ++ return !__dma_fence_is_later(xe_sched_job_lrc_seqno(job), ++ xe_lrc_seqno(lrc), ++ dma_fence_array_first(job->fence)->ops); + } + + void xe_sched_job_arm(struct xe_sched_job *job) +diff --git a/drivers/gpu/drm/xe/xe_sched_job.h b/drivers/gpu/drm/xe/xe_sched_job.h +index c75018f4660dc..002c3b5c0a5cb 100644 +--- a/drivers/gpu/drm/xe/xe_sched_job.h ++++ b/drivers/gpu/drm/xe/xe_sched_job.h +@@ -73,6 +73,11 @@ static inline u32 xe_sched_job_seqno(struct xe_sched_job *job) + return job->fence->seqno; + } + ++static inline u32 xe_sched_job_lrc_seqno(struct xe_sched_job *job) ++{ ++ return job->lrc_seqno; ++} ++ + static inline void + xe_sched_job_add_migrate_flush(struct xe_sched_job *job, u32 flags) + { +diff --git a/drivers/gpu/drm/xe/xe_sched_job_types.h b/drivers/gpu/drm/xe/xe_sched_job_types.h +index 5e12724219fdd..990ddac55ed62 100644 +--- a/drivers/gpu/drm/xe/xe_sched_job_types.h ++++ b/drivers/gpu/drm/xe/xe_sched_job_types.h +@@ -37,6 +37,8 @@ struct xe_sched_job { + /** @user_fence.value: write back value */ + u64 value; + } user_fence; ++ /** @lrc_seqno: LRC seqno */ ++ u32 lrc_seqno; + /** @migrate_flush_flags: Additional flush flags for migration jobs */ + u32 migrate_flush_flags; + /** @ring_ops_flush_tlb: The ring ops need to flush TLB before payload. */ +diff --git a/drivers/gpu/drm/xe/xe_trace.h b/drivers/gpu/drm/xe/xe_trace.h +index 2d56cfc09e421..6c6cecc58f63b 100644 +--- a/drivers/gpu/drm/xe/xe_trace.h ++++ b/drivers/gpu/drm/xe/xe_trace.h +@@ -254,6 +254,7 @@ DECLARE_EVENT_CLASS(xe_sched_job, + + TP_STRUCT__entry( + __field(u32, seqno) ++ __field(u32, lrc_seqno) + __field(u16, guc_id) + __field(u32, guc_state) + __field(u32, flags) +@@ -264,6 +265,7 @@ DECLARE_EVENT_CLASS(xe_sched_job, + + TP_fast_assign( + __entry->seqno = xe_sched_job_seqno(job); ++ __entry->lrc_seqno = xe_sched_job_lrc_seqno(job); + __entry->guc_id = job->q->guc->id; + __entry->guc_state = + atomic_read(&job->q->guc->state); +@@ -273,8 +275,9 @@ DECLARE_EVENT_CLASS(xe_sched_job, + __entry->batch_addr = (u64)job->batch_addr[0]; + ), + +- TP_printk("fence=%p, seqno=%u, guc_id=%d, batch_addr=0x%012llx, guc_state=0x%x, flags=0x%x, error=%d", +- __entry->fence, __entry->seqno, __entry->guc_id, ++ TP_printk("fence=%p, seqno=%u, lrc_seqno=%u, guc_id=%d, batch_addr=0x%012llx, guc_state=0x%x, flags=0x%x, error=%d", ++ __entry->fence, __entry->seqno, ++ __entry->lrc_seqno, __entry->guc_id, + __entry->batch_addr, __entry->guc_state, + __entry->flags, __entry->error) + ); +-- +2.43.0 + diff --git a/queue-6.10/drm-xe-display-stop-calling-domains_driver_remove-tw.patch b/queue-6.10/drm-xe-display-stop-calling-domains_driver_remove-tw.patch new file mode 100644 index 00000000000..6c2421a788b --- /dev/null +++ b/queue-6.10/drm-xe-display-stop-calling-domains_driver_remove-tw.patch @@ -0,0 +1,37 @@ +From d8feaf92f7c6d767e1691801c4f7f179a47f7717 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 May 2024 11:22:00 +0100 +Subject: drm/xe/display: stop calling domains_driver_remove twice + +From: Matthew Auld + +[ Upstream commit 48d74a0a45201de4efa016fb2f556889db37ed28 ] + +Unclear why we call this twice. + +Signed-off-by: Matthew Auld +Cc: Andrzej Hajda +Cc: Rodrigo Vivi +Reviewed-by: Andrzej Hajda +Link: https://patchwork.freedesktop.org/patch/msgid/20240522102143.128069-35-matthew.auld@intel.com +Stable-dep-of: f4b2a0ae1a31 ("drm/xe: Fix opregion leak") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/display/xe_display.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c +index 0de0566e5b394..6ecaf83264d55 100644 +--- a/drivers/gpu/drm/xe/display/xe_display.c ++++ b/drivers/gpu/drm/xe/display/xe_display.c +@@ -134,7 +134,6 @@ static void xe_display_fini_noirq(struct drm_device *dev, void *dummy) + return; + + intel_display_driver_remove_noirq(xe); +- intel_power_domains_driver_remove(xe); + } + + int xe_display_init_noirq(struct xe_device *xe) +-- +2.43.0 + diff --git a/queue-6.10/drm-xe-don-t-initialize-fences-at-xe_sched_job_creat.patch b/queue-6.10/drm-xe-don-t-initialize-fences-at-xe_sched_job_creat.patch new file mode 100644 index 00000000000..f0ee016c1ef --- /dev/null +++ b/queue-6.10/drm-xe-don-t-initialize-fences-at-xe_sched_job_creat.patch @@ -0,0 +1,477 @@ +From 8f0ae1eaea33228f0f81df5441884e47f3c1c5da Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 May 2024 15:59:10 +0200 +Subject: drm/xe: Don't initialize fences at xe_sched_job_create() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Thomas Hellström + +[ Upstream commit 0ac7a2c745e8a42803378b944fa0f4455b7240f6 ] + +Pre-allocate but don't initialize fences at xe_sched_job_create(), +and initialize / arm them instead at xe_sched_job_arm(). This +makes it possible to move xe_sched_job_create() with its memory +allocation out of any lock that is required for fence +initialization, and that may not allow memory allocation under it. + +Replaces the struct dma_fence_array for parallell jobs with a +struct dma_fence_chain, since the former doesn't allow +a split-up between allocation and initialization. + +v2: +- Rebase. +- Don't always use the first lrc when initializing parallel + lrc fences. +- Use dma_fence_chain_contained() to access the lrc fences. + +v4: +- Add an assert that job->lrc_seqno == fence->seqno. + (Matthew Brost) + +Signed-off-by: Thomas Hellström +Reviewed-by: Matthew Brost +Reviewed-by: Rodrigo Vivi #v2 +Link: https://patchwork.freedesktop.org/patch/msgid/20240527135912.152156-4-thomas.hellstrom@linux.intel.com +Stable-dep-of: 9e7f30563677 ("drm/xe: Free job before xe_exec_queue_put") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_exec_queue.c | 5 - + drivers/gpu/drm/xe/xe_exec_queue_types.h | 10 -- + drivers/gpu/drm/xe/xe_ring_ops.c | 12 +- + drivers/gpu/drm/xe/xe_sched_job.c | 161 +++++++++++++---------- + drivers/gpu/drm/xe/xe_sched_job_types.h | 18 ++- + drivers/gpu/drm/xe/xe_trace.h | 2 +- + 6 files changed, 115 insertions(+), 93 deletions(-) + +diff --git a/drivers/gpu/drm/xe/xe_exec_queue.c b/drivers/gpu/drm/xe/xe_exec_queue.c +index 79d099e054916..2ae4420e29353 100644 +--- a/drivers/gpu/drm/xe/xe_exec_queue.c ++++ b/drivers/gpu/drm/xe/xe_exec_queue.c +@@ -96,11 +96,6 @@ static struct xe_exec_queue *__xe_exec_queue_alloc(struct xe_device *xe, + } + } + +- if (xe_exec_queue_is_parallel(q)) { +- q->parallel.composite_fence_ctx = dma_fence_context_alloc(1); +- q->parallel.composite_fence_seqno = 0; +- } +- + return q; + } + +diff --git a/drivers/gpu/drm/xe/xe_exec_queue_types.h b/drivers/gpu/drm/xe/xe_exec_queue_types.h +index ee78d497d838a..f0c40e8ad80a1 100644 +--- a/drivers/gpu/drm/xe/xe_exec_queue_types.h ++++ b/drivers/gpu/drm/xe/xe_exec_queue_types.h +@@ -103,16 +103,6 @@ struct xe_exec_queue { + struct xe_guc_exec_queue *guc; + }; + +- /** +- * @parallel: parallel submission state +- */ +- struct { +- /** @parallel.composite_fence_ctx: context composite fence */ +- u64 composite_fence_ctx; +- /** @parallel.composite_fence_seqno: seqno for composite fence */ +- u32 composite_fence_seqno; +- } parallel; +- + /** @sched_props: scheduling properties */ + struct { + /** @sched_props.timeslice_us: timeslice period in micro-seconds */ +diff --git a/drivers/gpu/drm/xe/xe_ring_ops.c b/drivers/gpu/drm/xe/xe_ring_ops.c +index 3b6aad8dea99a..c59c4373aefad 100644 +--- a/drivers/gpu/drm/xe/xe_ring_ops.c ++++ b/drivers/gpu/drm/xe/xe_ring_ops.c +@@ -380,7 +380,7 @@ static void emit_migration_job_gen12(struct xe_sched_job *job, + + dw[i++] = MI_ARB_ON_OFF | MI_ARB_DISABLE; /* Enabled again below */ + +- i = emit_bb_start(job->batch_addr[0], BIT(8), dw, i); ++ i = emit_bb_start(job->ptrs[0].batch_addr, BIT(8), dw, i); + + if (!IS_SRIOV_VF(gt_to_xe(job->q->gt))) { + /* XXX: Do we need this? Leaving for now. */ +@@ -389,7 +389,7 @@ static void emit_migration_job_gen12(struct xe_sched_job *job, + dw[i++] = preparser_disable(false); + } + +- i = emit_bb_start(job->batch_addr[1], BIT(8), dw, i); ++ i = emit_bb_start(job->ptrs[1].batch_addr, BIT(8), dw, i); + + dw[i++] = MI_FLUSH_DW | MI_INVALIDATE_TLB | job->migrate_flush_flags | + MI_FLUSH_DW_OP_STOREDW | MI_FLUSH_IMM_DW; +@@ -411,7 +411,7 @@ static void emit_job_gen12_gsc(struct xe_sched_job *job) + xe_gt_assert(gt, job->q->width <= 1); /* no parallel submission for GSCCS */ + + __emit_job_gen12_simple(job, job->q->lrc, +- job->batch_addr[0], ++ job->ptrs[0].batch_addr, + xe_sched_job_lrc_seqno(job)); + } + +@@ -427,7 +427,7 @@ static void emit_job_gen12_copy(struct xe_sched_job *job) + + for (i = 0; i < job->q->width; ++i) + __emit_job_gen12_simple(job, job->q->lrc + i, +- job->batch_addr[i], ++ job->ptrs[i].batch_addr, + xe_sched_job_lrc_seqno(job)); + } + +@@ -438,7 +438,7 @@ static void emit_job_gen12_video(struct xe_sched_job *job) + /* FIXME: Not doing parallel handshake for now */ + for (i = 0; i < job->q->width; ++i) + __emit_job_gen12_video(job, job->q->lrc + i, +- job->batch_addr[i], ++ job->ptrs[i].batch_addr, + xe_sched_job_lrc_seqno(job)); + } + +@@ -448,7 +448,7 @@ static void emit_job_gen12_render_compute(struct xe_sched_job *job) + + for (i = 0; i < job->q->width; ++i) + __emit_job_gen12_render_compute(job, job->q->lrc + i, +- job->batch_addr[i], ++ job->ptrs[i].batch_addr, + xe_sched_job_lrc_seqno(job)); + } + +diff --git a/drivers/gpu/drm/xe/xe_sched_job.c b/drivers/gpu/drm/xe/xe_sched_job.c +index 874450be327ec..29f3201d7dfac 100644 +--- a/drivers/gpu/drm/xe/xe_sched_job.c ++++ b/drivers/gpu/drm/xe/xe_sched_job.c +@@ -6,7 +6,7 @@ + #include "xe_sched_job.h" + + #include +-#include ++#include + #include + + #include "xe_device.h" +@@ -29,7 +29,7 @@ int __init xe_sched_job_module_init(void) + xe_sched_job_slab = + kmem_cache_create("xe_sched_job", + sizeof(struct xe_sched_job) + +- sizeof(u64), 0, ++ sizeof(struct xe_job_ptrs), 0, + SLAB_HWCACHE_ALIGN, NULL); + if (!xe_sched_job_slab) + return -ENOMEM; +@@ -37,7 +37,7 @@ int __init xe_sched_job_module_init(void) + xe_sched_job_parallel_slab = + kmem_cache_create("xe_sched_job_parallel", + sizeof(struct xe_sched_job) + +- sizeof(u64) * ++ sizeof(struct xe_job_ptrs) * + XE_HW_ENGINE_MAX_INSTANCE, 0, + SLAB_HWCACHE_ALIGN, NULL); + if (!xe_sched_job_parallel_slab) { +@@ -79,26 +79,33 @@ static struct xe_device *job_to_xe(struct xe_sched_job *job) + return gt_to_xe(job->q->gt); + } + ++/* Free unused pre-allocated fences */ ++static void xe_sched_job_free_fences(struct xe_sched_job *job) ++{ ++ int i; ++ ++ for (i = 0; i < job->q->width; ++i) { ++ struct xe_job_ptrs *ptrs = &job->ptrs[i]; ++ ++ if (ptrs->lrc_fence) ++ xe_lrc_free_seqno_fence(ptrs->lrc_fence); ++ if (ptrs->chain_fence) ++ dma_fence_chain_free(ptrs->chain_fence); ++ } ++} ++ + struct xe_sched_job *xe_sched_job_create(struct xe_exec_queue *q, + u64 *batch_addr) + { +- struct xe_sched_job *job; +- struct dma_fence **fences; + bool is_migration = xe_sched_job_is_migration(q); ++ struct xe_sched_job *job; + int err; +- int i, j; ++ int i; + u32 width; + + /* only a kernel context can submit a vm-less job */ + XE_WARN_ON(!q->vm && !(q->flags & EXEC_QUEUE_FLAG_KERNEL)); + +- /* Migration and kernel engines have their own locking */ +- if (!(q->flags & (EXEC_QUEUE_FLAG_KERNEL | EXEC_QUEUE_FLAG_VM))) { +- lockdep_assert_held(&q->vm->lock); +- if (!xe_vm_in_lr_mode(q->vm)) +- xe_vm_assert_held(q->vm); +- } +- + job = job_alloc(xe_exec_queue_is_parallel(q) || is_migration); + if (!job) + return ERR_PTR(-ENOMEM); +@@ -111,43 +118,25 @@ struct xe_sched_job *xe_sched_job_create(struct xe_exec_queue *q, + if (err) + goto err_free; + +- if (!xe_exec_queue_is_parallel(q)) { +- job->fence = xe_lrc_create_seqno_fence(q->lrc); +- if (IS_ERR(job->fence)) { +- err = PTR_ERR(job->fence); +- goto err_sched_job; +- } +- job->lrc_seqno = job->fence->seqno; +- } else { +- struct dma_fence_array *cf; ++ for (i = 0; i < q->width; ++i) { ++ struct dma_fence *fence = xe_lrc_alloc_seqno_fence(); ++ struct dma_fence_chain *chain; + +- fences = kmalloc_array(q->width, sizeof(*fences), GFP_KERNEL); +- if (!fences) { +- err = -ENOMEM; ++ if (IS_ERR(fence)) { ++ err = PTR_ERR(fence); + goto err_sched_job; + } ++ job->ptrs[i].lrc_fence = fence; + +- for (j = 0; j < q->width; ++j) { +- fences[j] = xe_lrc_create_seqno_fence(q->lrc + j); +- if (IS_ERR(fences[j])) { +- err = PTR_ERR(fences[j]); +- goto err_fences; +- } +- if (!j) +- job->lrc_seqno = fences[0]->seqno; +- } ++ if (i + 1 == q->width) ++ continue; + +- cf = dma_fence_array_create(q->width, fences, +- q->parallel.composite_fence_ctx, +- q->parallel.composite_fence_seqno++, +- false); +- if (!cf) { +- --q->parallel.composite_fence_seqno; ++ chain = dma_fence_chain_alloc(); ++ if (!chain) { + err = -ENOMEM; +- goto err_fences; ++ goto err_sched_job; + } +- +- job->fence = &cf->base; ++ job->ptrs[i].chain_fence = chain; + } + + width = q->width; +@@ -155,19 +144,14 @@ struct xe_sched_job *xe_sched_job_create(struct xe_exec_queue *q, + width = 2; + + for (i = 0; i < width; ++i) +- job->batch_addr[i] = batch_addr[i]; ++ job->ptrs[i].batch_addr = batch_addr[i]; + + xe_pm_runtime_get_noresume(job_to_xe(job)); + trace_xe_sched_job_create(job); + return job; + +-err_fences: +- for (j = j - 1; j >= 0; --j) { +- --q->lrc[j].fence_ctx.next_seqno; +- dma_fence_put(fences[j]); +- } +- kfree(fences); + err_sched_job: ++ xe_sched_job_free_fences(job); + drm_sched_job_cleanup(&job->drm); + err_free: + xe_exec_queue_put(q); +@@ -188,6 +172,7 @@ void xe_sched_job_destroy(struct kref *ref) + container_of(ref, struct xe_sched_job, refcount); + struct xe_device *xe = job_to_xe(job); + ++ xe_sched_job_free_fences(job); + xe_exec_queue_put(job->q); + dma_fence_put(job->fence); + drm_sched_job_cleanup(&job->drm); +@@ -195,27 +180,32 @@ void xe_sched_job_destroy(struct kref *ref) + xe_pm_runtime_put(xe); + } + +-void xe_sched_job_set_error(struct xe_sched_job *job, int error) ++/* Set the error status under the fence to avoid racing with signaling */ ++static bool xe_fence_set_error(struct dma_fence *fence, int error) + { +- if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &job->fence->flags)) +- return; ++ unsigned long irq_flags; ++ bool signaled; ++ ++ spin_lock_irqsave(fence->lock, irq_flags); ++ signaled = test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags); ++ if (!signaled) ++ dma_fence_set_error(fence, error); ++ spin_unlock_irqrestore(fence->lock, irq_flags); + +- dma_fence_set_error(job->fence, error); ++ return signaled; ++} + +- if (dma_fence_is_array(job->fence)) { +- struct dma_fence_array *array = +- to_dma_fence_array(job->fence); +- struct dma_fence **child = array->fences; +- unsigned int nchild = array->num_fences; ++void xe_sched_job_set_error(struct xe_sched_job *job, int error) ++{ ++ if (xe_fence_set_error(job->fence, error)) ++ return; + +- do { +- struct dma_fence *current_fence = *child++; ++ if (dma_fence_is_chain(job->fence)) { ++ struct dma_fence *iter; + +- if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, +- ¤t_fence->flags)) +- continue; +- dma_fence_set_error(current_fence, error); +- } while (--nchild); ++ dma_fence_chain_for_each(iter, job->fence) ++ xe_fence_set_error(dma_fence_chain_contained(iter), ++ error); + } + + trace_xe_sched_job_set_error(job); +@@ -230,7 +220,7 @@ bool xe_sched_job_started(struct xe_sched_job *job) + + return !__dma_fence_is_later(xe_sched_job_lrc_seqno(job), + xe_lrc_start_seqno(lrc), +- dma_fence_array_first(job->fence)->ops); ++ dma_fence_chain_contained(job->fence)->ops); + } + + bool xe_sched_job_completed(struct xe_sched_job *job) +@@ -244,13 +234,24 @@ bool xe_sched_job_completed(struct xe_sched_job *job) + + return !__dma_fence_is_later(xe_sched_job_lrc_seqno(job), + xe_lrc_seqno(lrc), +- dma_fence_array_first(job->fence)->ops); ++ dma_fence_chain_contained(job->fence)->ops); + } + + void xe_sched_job_arm(struct xe_sched_job *job) + { + struct xe_exec_queue *q = job->q; ++ struct dma_fence *fence, *prev; + struct xe_vm *vm = q->vm; ++ u64 seqno = 0; ++ int i; ++ ++ /* Migration and kernel engines have their own locking */ ++ if (IS_ENABLED(CONFIG_LOCKDEP) && ++ !(q->flags & (EXEC_QUEUE_FLAG_KERNEL | EXEC_QUEUE_FLAG_VM))) { ++ lockdep_assert_held(&q->vm->lock); ++ if (!xe_vm_in_lr_mode(q->vm)) ++ xe_vm_assert_held(q->vm); ++ } + + if (vm && !xe_sched_job_is_migration(q) && !xe_vm_in_lr_mode(vm) && + (vm->batch_invalidate_tlb || vm->tlb_flush_seqno != q->tlb_flush_seqno)) { +@@ -259,6 +260,27 @@ void xe_sched_job_arm(struct xe_sched_job *job) + job->ring_ops_flush_tlb = true; + } + ++ /* Arm the pre-allocated fences */ ++ for (i = 0; i < q->width; prev = fence, ++i) { ++ struct dma_fence_chain *chain; ++ ++ fence = job->ptrs[i].lrc_fence; ++ xe_lrc_init_seqno_fence(&q->lrc[i], fence); ++ job->ptrs[i].lrc_fence = NULL; ++ if (!i) { ++ job->lrc_seqno = fence->seqno; ++ continue; ++ } else { ++ xe_assert(gt_to_xe(q->gt), job->lrc_seqno == fence->seqno); ++ } ++ ++ chain = job->ptrs[i - 1].chain_fence; ++ dma_fence_chain_init(chain, prev, fence, seqno++); ++ job->ptrs[i - 1].chain_fence = NULL; ++ fence = &chain->base; ++ } ++ ++ job->fence = fence; + drm_sched_job_arm(&job->drm); + } + +@@ -318,7 +340,8 @@ xe_sched_job_snapshot_capture(struct xe_sched_job *job) + + snapshot->batch_addr_len = q->width; + for (i = 0; i < q->width; i++) +- snapshot->batch_addr[i] = xe_device_uncanonicalize_addr(xe, job->batch_addr[i]); ++ snapshot->batch_addr[i] = ++ xe_device_uncanonicalize_addr(xe, job->ptrs[i].batch_addr); + + return snapshot; + } +diff --git a/drivers/gpu/drm/xe/xe_sched_job_types.h b/drivers/gpu/drm/xe/xe_sched_job_types.h +index 990ddac55ed62..0d3f76fb05cea 100644 +--- a/drivers/gpu/drm/xe/xe_sched_job_types.h ++++ b/drivers/gpu/drm/xe/xe_sched_job_types.h +@@ -11,6 +11,20 @@ + #include + + struct xe_exec_queue; ++struct dma_fence; ++struct dma_fence_chain; ++ ++/** ++ * struct xe_job_ptrs - Per hw engine instance data ++ */ ++struct xe_job_ptrs { ++ /** @lrc_fence: Pre-allocated uinitialized lrc fence.*/ ++ struct dma_fence *lrc_fence; ++ /** @chain_fence: Pre-allocated ninitialized fence chain node. */ ++ struct dma_fence_chain *chain_fence; ++ /** @batch_addr: Batch buffer address. */ ++ u64 batch_addr; ++}; + + /** + * struct xe_sched_job - XE schedule job (batch buffer tracking) +@@ -43,8 +57,8 @@ struct xe_sched_job { + u32 migrate_flush_flags; + /** @ring_ops_flush_tlb: The ring ops need to flush TLB before payload. */ + bool ring_ops_flush_tlb; +- /** @batch_addr: batch buffer address of job */ +- u64 batch_addr[]; ++ /** @ptrs: per instance pointers. */ ++ struct xe_job_ptrs ptrs[]; + }; + + struct xe_sched_job_snapshot { +diff --git a/drivers/gpu/drm/xe/xe_trace.h b/drivers/gpu/drm/xe/xe_trace.h +index 6c6cecc58f63b..450f407c66e8f 100644 +--- a/drivers/gpu/drm/xe/xe_trace.h ++++ b/drivers/gpu/drm/xe/xe_trace.h +@@ -272,7 +272,7 @@ DECLARE_EVENT_CLASS(xe_sched_job, + __entry->flags = job->q->flags; + __entry->error = job->fence->error; + __entry->fence = job->fence; +- __entry->batch_addr = (u64)job->batch_addr[0]; ++ __entry->batch_addr = (u64)job->ptrs[0].batch_addr; + ), + + TP_printk("fence=%p, seqno=%u, lrc_seqno=%u, guc_id=%d, batch_addr=0x%012llx, guc_state=0x%x, flags=0x%x, error=%d", +-- +2.43.0 + diff --git a/queue-6.10/drm-xe-fix-missing-workqueue-destroy-in-xe_gt_pagefa.patch b/queue-6.10/drm-xe-fix-missing-workqueue-destroy-in-xe_gt_pagefa.patch new file mode 100644 index 00000000000..9841eb902e2 --- /dev/null +++ b/queue-6.10/drm-xe-fix-missing-workqueue-destroy-in-xe_gt_pagefa.patch @@ -0,0 +1,65 @@ +From d666baaf55a89bec4b4780d5623ad813276d5322 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 17 Aug 2024 02:47:30 +0000 +Subject: drm/xe: Fix missing workqueue destroy in xe_gt_pagefault + +From: Stuart Summers + +[ Upstream commit a6f78359ac75f24cac3c1bdd753c49c1877bcd82 ] + +On driver reload we never free up the memory for the pagefault and +access counter workqueues. Add those destroy calls here. + +Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs") +Signed-off-by: Stuart Summers +Reviewed-by: Rodrigo Vivi +Signed-off-by: Matthew Brost +Link: https://patchwork.freedesktop.org/patch/msgid/c9a951505271dc3a7aee76de7656679f69c11518.1723862633.git.stuart.summers@intel.com +(cherry picked from commit 7586fc52b14e0b8edd0d1f8a434e0de2078b7b2b) +Signed-off-by: Rodrigo Vivi +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_gt_pagefault.c | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/xe/xe_gt_pagefault.c b/drivers/gpu/drm/xe/xe_gt_pagefault.c +index fa9e9853c53ba..67e8efcaa93f1 100644 +--- a/drivers/gpu/drm/xe/xe_gt_pagefault.c ++++ b/drivers/gpu/drm/xe/xe_gt_pagefault.c +@@ -402,6 +402,18 @@ static void pf_queue_work_func(struct work_struct *w) + + static void acc_queue_work_func(struct work_struct *w); + ++static void pagefault_fini(void *arg) ++{ ++ struct xe_gt *gt = arg; ++ struct xe_device *xe = gt_to_xe(gt); ++ ++ if (!xe->info.has_usm) ++ return; ++ ++ destroy_workqueue(gt->usm.acc_wq); ++ destroy_workqueue(gt->usm.pf_wq); ++} ++ + int xe_gt_pagefault_init(struct xe_gt *gt) + { + struct xe_device *xe = gt_to_xe(gt); +@@ -429,10 +441,12 @@ int xe_gt_pagefault_init(struct xe_gt *gt) + gt->usm.acc_wq = alloc_workqueue("xe_gt_access_counter_work_queue", + WQ_UNBOUND | WQ_HIGHPRI, + NUM_ACC_QUEUE); +- if (!gt->usm.acc_wq) ++ if (!gt->usm.acc_wq) { ++ destroy_workqueue(gt->usm.pf_wq); + return -ENOMEM; ++ } + +- return 0; ++ return devm_add_action_or_reset(xe->drm.dev, pagefault_fini, gt); + } + + void xe_gt_pagefault_reset(struct xe_gt *gt) +-- +2.43.0 + diff --git a/queue-6.10/drm-xe-fix-opregion-leak.patch b/queue-6.10/drm-xe-fix-opregion-leak.patch new file mode 100644 index 00000000000..e72499b5871 --- /dev/null +++ b/queue-6.10/drm-xe-fix-opregion-leak.patch @@ -0,0 +1,73 @@ +From d7b9cf1dcdf98c38c940215fdc3f639028630070 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 Jul 2024 14:53:09 -0700 +Subject: drm/xe: Fix opregion leak + +From: Lucas De Marchi + +[ Upstream commit f4b2a0ae1a31fd3d1b5ca18ee08319b479cf9b5f ] + +Being part o the display, ideally the setup and cleanup would be done by +display itself. However this is a bigger refactor that needs to be done +on both i915 and xe. For now, just fix the leak: + +unreferenced object 0xffff8881a0300008 (size 192): + comm "modprobe", pid 4354, jiffies 4295647021 + hex dump (first 32 bytes): + 00 00 87 27 81 88 ff ff 18 80 9b 00 00 c9 ff ff ...'............ + 18 81 9b 00 00 c9 ff ff 00 00 00 00 00 00 00 00 ................ + backtrace (crc 99260e31): + [] kmemleak_alloc+0x4b/0x80 + [] kmalloc_trace_noprof+0x312/0x3d0 + [] intel_opregion_setup+0x89/0x700 [xe] + [] xe_display_init_noirq+0x2f/0x90 [xe] + [] xe_device_probe+0x7a3/0xbf0 [xe] + [] xe_pci_probe+0x333/0x5b0 [xe] + [] local_pci_probe+0x48/0xb0 + [] pci_device_probe+0xc8/0x280 + [] really_probe+0xf8/0x390 + [] __driver_probe_device+0x8a/0x170 + [] driver_probe_device+0x23/0xb0 + [] __driver_attach+0xc7/0x190 + [] bus_for_each_dev+0x7d/0xd0 + [] driver_attach+0x1e/0x30 + [] bus_add_driver+0x117/0x250 + +Fixes: 44e694958b95 ("drm/xe/display: Implement display support") +Reviewed-by: Rodrigo Vivi +Link: https://patchwork.freedesktop.org/patch/msgid/20240724215309.644423-1-lucas.demarchi@intel.com +Signed-off-by: Lucas De Marchi +(cherry picked from commit 6f4e43a2f771b737d991142ec4f6d4b7ff31fbb4) +Signed-off-by: Rodrigo Vivi +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/display/xe_display.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c +index 6ecaf83264d55..7cdc03dc40ed9 100644 +--- a/drivers/gpu/drm/xe/display/xe_display.c ++++ b/drivers/gpu/drm/xe/display/xe_display.c +@@ -134,6 +134,7 @@ static void xe_display_fini_noirq(struct drm_device *dev, void *dummy) + return; + + intel_display_driver_remove_noirq(xe); ++ intel_opregion_cleanup(xe); + } + + int xe_display_init_noirq(struct xe_device *xe) +@@ -159,8 +160,10 @@ int xe_display_init_noirq(struct xe_device *xe) + intel_display_device_info_runtime_init(xe); + + err = intel_display_driver_probe_noirq(xe); +- if (err) ++ if (err) { ++ intel_opregion_cleanup(xe); + return err; ++ } + + return drmm_add_action_or_reset(&xe->drm, xe_display_fini_noirq, NULL); + } +-- +2.43.0 + diff --git a/queue-6.10/drm-xe-fix-tile-fini-sequence.patch b/queue-6.10/drm-xe-fix-tile-fini-sequence.patch new file mode 100644 index 00000000000..7e5dd6e899c --- /dev/null +++ b/queue-6.10/drm-xe-fix-tile-fini-sequence.patch @@ -0,0 +1,54 @@ +From 459c473d917a44e21abc18718853f4f24bf64745 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 9 Aug 2024 16:28:30 -0700 +Subject: drm/xe: Fix tile fini sequence + +From: Matthew Brost + +[ Upstream commit 15939ca77d4424f736e1e4953b4da2351cc9689d ] + +Only set tile->mmio.regs to NULL if not the root tile in tile_fini. The +root tile mmio regs is setup ealier in MMIO init thus it should be set +to NULL in mmio_fini. + +Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs") +Signed-off-by: Matthew Brost +Reviewed-by: Lucas De Marchi +Reviewed-by: Himal Prasad Ghimiray +Link: https://patchwork.freedesktop.org/patch/msgid/20240809232830.3302251-1-matthew.brost@intel.com +(cherry picked from commit 3396900aa273903639a1792afa4d23dc09bec291) +Signed-off-by: Rodrigo Vivi +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_mmio.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/xe/xe_mmio.c b/drivers/gpu/drm/xe/xe_mmio.c +index 9d8fafdf51453..beb4e276ba845 100644 +--- a/drivers/gpu/drm/xe/xe_mmio.c ++++ b/drivers/gpu/drm/xe/xe_mmio.c +@@ -355,7 +355,8 @@ static void tiles_fini(void *arg) + int id; + + for_each_tile(tile, xe, id) +- tile->mmio.regs = NULL; ++ if (tile != xe_device_get_root_tile(xe)) ++ tile->mmio.regs = NULL; + } + + int xe_mmio_probe_tiles(struct xe_device *xe) +@@ -416,9 +417,11 @@ int xe_mmio_probe_tiles(struct xe_device *xe) + static void mmio_fini(void *arg) + { + struct xe_device *xe = arg; ++ struct xe_tile *root_tile = xe_device_get_root_tile(xe); + + pci_iounmap(to_pci_dev(xe->drm.dev), xe->mmio.regs); + xe->mmio.regs = NULL; ++ root_tile->mmio.regs = NULL; + } + + int xe_mmio_init(struct xe_device *xe) +-- +2.43.0 + diff --git a/queue-6.10/drm-xe-free-job-before-xe_exec_queue_put.patch b/queue-6.10/drm-xe-free-job-before-xe_exec_queue_put.patch new file mode 100644 index 00000000000..73a9a4b6271 --- /dev/null +++ b/queue-6.10/drm-xe-free-job-before-xe_exec_queue_put.patch @@ -0,0 +1,46 @@ +From 3af646198a591741c8ac519ec6c8f16acf3e4a51 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 20 Aug 2024 13:23:09 -0700 +Subject: drm/xe: Free job before xe_exec_queue_put + +From: Matthew Brost + +[ Upstream commit 9e7f30563677fbeff62d368d5d2a5ac7aaa9746a ] + +Free job depends on job->vm being valid, the last xe_exec_queue_put can +destroy the VM. Prevent UAF by freeing job before xe_exec_queue_put. + +Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs") +Signed-off-by: Matthew Brost +Reviewed-by: Nirmoy Das +Reviewed-by: Jagmeet Randhawa +Link: https://patchwork.freedesktop.org/patch/msgid/20240820202309.1260755-1-matthew.brost@intel.com +(cherry picked from commit 32a42c93b74c8ca6d0915ea3eba21bceff53042f) +Signed-off-by: Rodrigo Vivi +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_sched_job.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/xe/xe_sched_job.c b/drivers/gpu/drm/xe/xe_sched_job.c +index 29f3201d7dfac..2b064680abb96 100644 +--- a/drivers/gpu/drm/xe/xe_sched_job.c ++++ b/drivers/gpu/drm/xe/xe_sched_job.c +@@ -171,12 +171,13 @@ void xe_sched_job_destroy(struct kref *ref) + struct xe_sched_job *job = + container_of(ref, struct xe_sched_job, refcount); + struct xe_device *xe = job_to_xe(job); ++ struct xe_exec_queue *q = job->q; + + xe_sched_job_free_fences(job); +- xe_exec_queue_put(job->q); + dma_fence_put(job->fence); + drm_sched_job_cleanup(&job->drm); + job_free(job); ++ xe_exec_queue_put(q); + xe_pm_runtime_put(xe); + } + +-- +2.43.0 + diff --git a/queue-6.10/drm-xe-mmio-move-mmio_fini-over-to-devm.patch b/queue-6.10/drm-xe-mmio-move-mmio_fini-over-to-devm.patch new file mode 100644 index 00000000000..76e98896000 --- /dev/null +++ b/queue-6.10/drm-xe-mmio-move-mmio_fini-over-to-devm.patch @@ -0,0 +1,58 @@ +From 3ee036f86d3041441eeda0b64c2f4920cf53464f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 May 2024 11:21:57 +0100 +Subject: drm/xe/mmio: move mmio_fini over to devm + +From: Matthew Auld + +[ Upstream commit a0b834c8957a7d2848face008a12382a0ad11ffc ] + +Not valid to touch mmio once the device is removed, so make sure we +unmap on removal and not just when driver instance goes away. Also set +the mmio pointers to NULL to hopefully catch such issues more easily. + +Signed-off-by: Matthew Auld +Cc: Andrzej Hajda +Cc: Rodrigo Vivi +Reviewed-by: Andrzej Hajda +Link: https://patchwork.freedesktop.org/patch/msgid/20240522102143.128069-32-matthew.auld@intel.com +Stable-dep-of: 15939ca77d44 ("drm/xe: Fix tile fini sequence") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_mmio.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/xe/xe_mmio.c b/drivers/gpu/drm/xe/xe_mmio.c +index 334637511e750..2ebb2f0d6874e 100644 +--- a/drivers/gpu/drm/xe/xe_mmio.c ++++ b/drivers/gpu/drm/xe/xe_mmio.c +@@ -386,13 +386,16 @@ void xe_mmio_probe_tiles(struct xe_device *xe) + } + } + +-static void mmio_fini(struct drm_device *drm, void *arg) ++static void mmio_fini(void *arg) + { + struct xe_device *xe = arg; + + pci_iounmap(to_pci_dev(xe->drm.dev), xe->mmio.regs); + if (xe->mem.vram.mapping) + iounmap(xe->mem.vram.mapping); ++ ++ xe->mem.vram.mapping = NULL; ++ xe->mmio.regs = NULL; + } + + int xe_mmio_init(struct xe_device *xe) +@@ -417,7 +420,7 @@ int xe_mmio_init(struct xe_device *xe) + root_tile->mmio.size = SZ_16M; + root_tile->mmio.regs = xe->mmio.regs; + +- return drmm_add_action_or_reset(&xe->drm, mmio_fini, xe); ++ return devm_add_action_or_reset(xe->drm.dev, mmio_fini, xe); + } + + u8 xe_mmio_read8(struct xe_gt *gt, struct xe_reg reg) +-- +2.43.0 + diff --git a/queue-6.10/drm-xe-relax-runtime-pm-protection-during-execution.patch b/queue-6.10/drm-xe-relax-runtime-pm-protection-during-execution.patch new file mode 100644 index 00000000000..b67327574ce --- /dev/null +++ b/queue-6.10/drm-xe-relax-runtime-pm-protection-during-execution.patch @@ -0,0 +1,142 @@ +From c658360775890856ec80e584a44a87d25429aeee Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 May 2024 13:01:01 -0400 +Subject: drm/xe: Relax runtime pm protection during execution +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Rodrigo Vivi + +[ Upstream commit ad1e331fc451a2cffc72ae193b843682ce237e24 ] + +Limit the protection only during moments of actual job execution, +and introduce protection for guc submit fini, which is currently +unprotected due to the absence of exec_queue life protection. + +In the regular use case scenario, user space will create an +exec queue, and keep it alive to reuse that until it is done +with that kind of workload. + +For the regular desktop cases, it means that the exec_queue +is alive even on idle scenarios where display goes off. This +is unacceptable since this would entirely block runtime PM +indefinitely, blocking deeper Package-C state. This would be +a waste drainage of power. + +Cc: Matthew Brost +Tested-by: Francois Dugast +Reviewed-by: Thomas Hellström +Link: https://patchwork.freedesktop.org/patch/msgid/20240522170105.327472-3-rodrigo.vivi@intel.com +Signed-off-by: Rodrigo Vivi +Stable-dep-of: 9e7f30563677 ("drm/xe: Free job before xe_exec_queue_put") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_exec_queue.c | 14 -------------- + drivers/gpu/drm/xe/xe_guc_submit.c | 3 +++ + drivers/gpu/drm/xe/xe_sched_job.c | 10 +++------- + 3 files changed, 6 insertions(+), 21 deletions(-) + +diff --git a/drivers/gpu/drm/xe/xe_exec_queue.c b/drivers/gpu/drm/xe/xe_exec_queue.c +index 395de93579fa6..33b03605a1d15 100644 +--- a/drivers/gpu/drm/xe/xe_exec_queue.c ++++ b/drivers/gpu/drm/xe/xe_exec_queue.c +@@ -106,7 +106,6 @@ static struct xe_exec_queue *__xe_exec_queue_alloc(struct xe_device *xe, + + static int __xe_exec_queue_init(struct xe_exec_queue *q) + { +- struct xe_device *xe = gt_to_xe(q->gt); + int i, err; + + for (i = 0; i < q->width; ++i) { +@@ -119,17 +118,6 @@ static int __xe_exec_queue_init(struct xe_exec_queue *q) + if (err) + goto err_lrc; + +- /* +- * Normally the user vm holds an rpm ref to keep the device +- * awake, and the context holds a ref for the vm, however for +- * some engines we use the kernels migrate vm underneath which offers no +- * such rpm ref, or we lack a vm. Make sure we keep a ref here, so we +- * can perform GuC CT actions when needed. Caller is expected to have +- * already grabbed the rpm ref outside any sensitive locks. +- */ +- if (!(q->flags & EXEC_QUEUE_FLAG_PERMANENT) && (q->flags & EXEC_QUEUE_FLAG_VM || !q->vm)) +- xe_pm_runtime_get_noresume(xe); +- + return 0; + + err_lrc: +@@ -216,8 +204,6 @@ void xe_exec_queue_fini(struct xe_exec_queue *q) + + for (i = 0; i < q->width; ++i) + xe_lrc_finish(q->lrc + i); +- if (!(q->flags & EXEC_QUEUE_FLAG_PERMANENT) && (q->flags & EXEC_QUEUE_FLAG_VM || !q->vm)) +- xe_pm_runtime_put(gt_to_xe(q->gt)); + __xe_exec_queue_free(q); + } + +diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c +index 0f42971ff0a83..8c75791cbc4fb 100644 +--- a/drivers/gpu/drm/xe/xe_guc_submit.c ++++ b/drivers/gpu/drm/xe/xe_guc_submit.c +@@ -35,6 +35,7 @@ + #include "xe_macros.h" + #include "xe_map.h" + #include "xe_mocs.h" ++#include "xe_pm.h" + #include "xe_ring_ops_types.h" + #include "xe_sched_job.h" + #include "xe_trace.h" +@@ -1011,6 +1012,7 @@ static void __guc_exec_queue_fini_async(struct work_struct *w) + struct xe_exec_queue *q = ge->q; + struct xe_guc *guc = exec_queue_to_guc(q); + ++ xe_pm_runtime_get(guc_to_xe(guc)); + trace_xe_exec_queue_destroy(q); + + if (xe_exec_queue_is_lr(q)) +@@ -1021,6 +1023,7 @@ static void __guc_exec_queue_fini_async(struct work_struct *w) + + kfree(ge); + xe_exec_queue_fini(q); ++ xe_pm_runtime_put(guc_to_xe(guc)); + } + + static void guc_exec_queue_fini_async(struct xe_exec_queue *q) +diff --git a/drivers/gpu/drm/xe/xe_sched_job.c b/drivers/gpu/drm/xe/xe_sched_job.c +index cd8a2fba54389..a4e030f5e019a 100644 +--- a/drivers/gpu/drm/xe/xe_sched_job.c ++++ b/drivers/gpu/drm/xe/xe_sched_job.c +@@ -158,11 +158,7 @@ struct xe_sched_job *xe_sched_job_create(struct xe_exec_queue *q, + for (i = 0; i < width; ++i) + job->batch_addr[i] = batch_addr[i]; + +- /* All other jobs require a VM to be open which has a ref */ +- if (unlikely(q->flags & EXEC_QUEUE_FLAG_KERNEL)) +- xe_pm_runtime_get_noresume(job_to_xe(job)); +- xe_device_assert_mem_access(job_to_xe(job)); +- ++ xe_pm_runtime_get_noresume(job_to_xe(job)); + trace_xe_sched_job_create(job); + return job; + +@@ -191,13 +187,13 @@ void xe_sched_job_destroy(struct kref *ref) + { + struct xe_sched_job *job = + container_of(ref, struct xe_sched_job, refcount); ++ struct xe_device *xe = job_to_xe(job); + +- if (unlikely(job->q->flags & EXEC_QUEUE_FLAG_KERNEL)) +- xe_pm_runtime_put(job_to_xe(job)); + xe_exec_queue_put(job->q); + dma_fence_put(job->fence); + drm_sched_job_cleanup(&job->drm); + job_free(job); ++ xe_pm_runtime_put(xe); + } + + void xe_sched_job_set_error(struct xe_sched_job *job, int error) +-- +2.43.0 + diff --git a/queue-6.10/drm-xe-reset-mmio-mappings-with-devm.patch b/queue-6.10/drm-xe-reset-mmio-mappings-with-devm.patch new file mode 100644 index 00000000000..fdf21faba75 --- /dev/null +++ b/queue-6.10/drm-xe-reset-mmio-mappings-with-devm.patch @@ -0,0 +1,128 @@ +From aa27bef6d4f08db256a4d1b27313e91f98f75fc6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 May 2024 11:21:58 +0100 +Subject: drm/xe: reset mmio mappings with devm + +From: Matthew Auld + +[ Upstream commit c7117419784f612d59ee565145f722e8b5541fe6 ] + +Set our various mmio mappings to NULL. This should make it easier to +catch something rogue trying to mess with mmio after device removal. For +example, we might unmap everything and then start hitting some mmio +address which has already been unmamped by us and then remapped by +something else, causing all kinds of carnage. + +Signed-off-by: Matthew Auld +Cc: Andrzej Hajda +Cc: Rodrigo Vivi +Reviewed-by: Andrzej Hajda +Link: https://patchwork.freedesktop.org/patch/msgid/20240522102143.128069-33-matthew.auld@intel.com +Stable-dep-of: 15939ca77d44 ("drm/xe: Fix tile fini sequence") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_device.c | 4 +++- + drivers/gpu/drm/xe/xe_mmio.c | 35 ++++++++++++++++++++++++++++------ + drivers/gpu/drm/xe/xe_mmio.h | 2 +- + 3 files changed, 33 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c +index 5ef9b50a20d01..a1cbdafbff75e 100644 +--- a/drivers/gpu/drm/xe/xe_device.c ++++ b/drivers/gpu/drm/xe/xe_device.c +@@ -551,7 +551,9 @@ int xe_device_probe(struct xe_device *xe) + if (err) + return err; + +- xe_mmio_probe_tiles(xe); ++ err = xe_mmio_probe_tiles(xe); ++ if (err) ++ return err; + + xe_ttm_sys_mgr_init(xe); + +diff --git a/drivers/gpu/drm/xe/xe_mmio.c b/drivers/gpu/drm/xe/xe_mmio.c +index 2ebb2f0d6874e..9d8fafdf51453 100644 +--- a/drivers/gpu/drm/xe/xe_mmio.c ++++ b/drivers/gpu/drm/xe/xe_mmio.c +@@ -254,6 +254,21 @@ static int xe_mmio_tile_vram_size(struct xe_tile *tile, u64 *vram_size, + return xe_force_wake_put(gt_to_fw(gt), XE_FW_GT); + } + ++static void vram_fini(void *arg) ++{ ++ struct xe_device *xe = arg; ++ struct xe_tile *tile; ++ int id; ++ ++ if (xe->mem.vram.mapping) ++ iounmap(xe->mem.vram.mapping); ++ ++ xe->mem.vram.mapping = NULL; ++ ++ for_each_tile(tile, xe, id) ++ tile->mem.vram.mapping = NULL; ++} ++ + int xe_mmio_probe_vram(struct xe_device *xe) + { + struct xe_tile *tile; +@@ -330,10 +345,20 @@ int xe_mmio_probe_vram(struct xe_device *xe) + drm_info(&xe->drm, "Available VRAM: %pa, %pa\n", &xe->mem.vram.io_start, + &available_size); + +- return 0; ++ return devm_add_action_or_reset(xe->drm.dev, vram_fini, xe); + } + +-void xe_mmio_probe_tiles(struct xe_device *xe) ++static void tiles_fini(void *arg) ++{ ++ struct xe_device *xe = arg; ++ struct xe_tile *tile; ++ int id; ++ ++ for_each_tile(tile, xe, id) ++ tile->mmio.regs = NULL; ++} ++ ++int xe_mmio_probe_tiles(struct xe_device *xe) + { + size_t tile_mmio_size = SZ_16M, tile_mmio_ext_size = xe->info.tile_mmio_ext_size; + u8 id, tile_count = xe->info.tile_count; +@@ -384,6 +409,8 @@ void xe_mmio_probe_tiles(struct xe_device *xe) + regs += tile_mmio_ext_size; + } + } ++ ++ return devm_add_action_or_reset(xe->drm.dev, tiles_fini, xe); + } + + static void mmio_fini(void *arg) +@@ -391,10 +418,6 @@ static void mmio_fini(void *arg) + struct xe_device *xe = arg; + + pci_iounmap(to_pci_dev(xe->drm.dev), xe->mmio.regs); +- if (xe->mem.vram.mapping) +- iounmap(xe->mem.vram.mapping); +- +- xe->mem.vram.mapping = NULL; + xe->mmio.regs = NULL; + } + +diff --git a/drivers/gpu/drm/xe/xe_mmio.h b/drivers/gpu/drm/xe/xe_mmio.h +index a3cd7b3036c73..a929d090bb2f1 100644 +--- a/drivers/gpu/drm/xe/xe_mmio.h ++++ b/drivers/gpu/drm/xe/xe_mmio.h +@@ -21,7 +21,7 @@ struct xe_device; + #define LMEM_BAR 2 + + int xe_mmio_init(struct xe_device *xe); +-void xe_mmio_probe_tiles(struct xe_device *xe); ++int xe_mmio_probe_tiles(struct xe_device *xe); + + u8 xe_mmio_read8(struct xe_gt *gt, struct xe_reg reg); + u16 xe_mmio_read16(struct xe_gt *gt, struct xe_reg reg); +-- +2.43.0 + diff --git a/queue-6.10/drm-xe-split-lrc-seqno-fence-creation-up.patch b/queue-6.10/drm-xe-split-lrc-seqno-fence-creation-up.patch new file mode 100644 index 00000000000..f18c9473648 --- /dev/null +++ b/queue-6.10/drm-xe-split-lrc-seqno-fence-creation-up.patch @@ -0,0 +1,204 @@ +From 3ab821a97aff3ace512b8751120aa396f747ab68 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 May 2024 15:59:09 +0200 +Subject: drm/xe: Split lrc seqno fence creation up +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Thomas Hellström + +[ Upstream commit e183910ae4015214475b3248ce0b4c70f104f254 ] + +Since sometimes a lock is required to initialize a seqno fence, +and it might be desirable not to hold that lock while performing +memory allocations, split the lrc seqno fence creation up into an +allocation phase and an initialization phase. + +Since lrc seqno fences under the hood are hw_fences, do the same +for these and remove the xe_hw_fence_create() function since it +is not used anymore. + +Signed-off-by: Thomas Hellström +Reviewed-by: Matthew Brost +Reviewed-by: Rodrigo Vivi +Link: https://patchwork.freedesktop.org/patch/msgid/20240527135912.152156-3-thomas.hellstrom@linux.intel.com +Stable-dep-of: 9e7f30563677 ("drm/xe: Free job before xe_exec_queue_put") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_hw_fence.c | 59 +++++++++++++++++++++++++------- + drivers/gpu/drm/xe/xe_hw_fence.h | 7 ++-- + drivers/gpu/drm/xe/xe_lrc.c | 48 ++++++++++++++++++++++++-- + drivers/gpu/drm/xe/xe_lrc.h | 3 ++ + 4 files changed, 101 insertions(+), 16 deletions(-) + +diff --git a/drivers/gpu/drm/xe/xe_hw_fence.c b/drivers/gpu/drm/xe/xe_hw_fence.c +index f872ef1031272..35c0063a831af 100644 +--- a/drivers/gpu/drm/xe/xe_hw_fence.c ++++ b/drivers/gpu/drm/xe/xe_hw_fence.c +@@ -208,23 +208,58 @@ static struct xe_hw_fence *to_xe_hw_fence(struct dma_fence *fence) + return container_of(fence, struct xe_hw_fence, dma); + } + +-struct xe_hw_fence *xe_hw_fence_create(struct xe_hw_fence_ctx *ctx, +- struct iosys_map seqno_map) ++/** ++ * xe_hw_fence_alloc() - Allocate an hw fence. ++ * ++ * Allocate but don't initialize an hw fence. ++ * ++ * Return: Pointer to the allocated fence or ++ * negative error pointer on error. ++ */ ++struct dma_fence *xe_hw_fence_alloc(void) + { +- struct xe_hw_fence *fence; ++ struct xe_hw_fence *hw_fence = fence_alloc(); + +- fence = fence_alloc(); +- if (!fence) ++ if (!hw_fence) + return ERR_PTR(-ENOMEM); + +- fence->ctx = ctx; +- fence->seqno_map = seqno_map; +- INIT_LIST_HEAD(&fence->irq_link); ++ return &hw_fence->dma; ++} + +- dma_fence_init(&fence->dma, &xe_hw_fence_ops, &ctx->irq->lock, +- ctx->dma_fence_ctx, ctx->next_seqno++); ++/** ++ * xe_hw_fence_free() - Free an hw fence. ++ * @fence: Pointer to the fence to free. ++ * ++ * Frees an hw fence that hasn't yet been ++ * initialized. ++ */ ++void xe_hw_fence_free(struct dma_fence *fence) ++{ ++ fence_free(&fence->rcu); ++} + +- trace_xe_hw_fence_create(fence); ++/** ++ * xe_hw_fence_init() - Initialize an hw fence. ++ * @fence: Pointer to the fence to initialize. ++ * @ctx: Pointer to the struct xe_hw_fence_ctx fence context. ++ * @seqno_map: Pointer to the map into where the seqno is blitted. ++ * ++ * Initializes a pre-allocated hw fence. ++ * After initialization, the fence is subject to normal ++ * dma-fence refcounting. ++ */ ++void xe_hw_fence_init(struct dma_fence *fence, struct xe_hw_fence_ctx *ctx, ++ struct iosys_map seqno_map) ++{ ++ struct xe_hw_fence *hw_fence = ++ container_of(fence, typeof(*hw_fence), dma); ++ ++ hw_fence->ctx = ctx; ++ hw_fence->seqno_map = seqno_map; ++ INIT_LIST_HEAD(&hw_fence->irq_link); ++ ++ dma_fence_init(fence, &xe_hw_fence_ops, &ctx->irq->lock, ++ ctx->dma_fence_ctx, ctx->next_seqno++); + +- return fence; ++ trace_xe_hw_fence_create(hw_fence); + } +diff --git a/drivers/gpu/drm/xe/xe_hw_fence.h b/drivers/gpu/drm/xe/xe_hw_fence.h +index cfe5fd603787e..f13a1c4982c73 100644 +--- a/drivers/gpu/drm/xe/xe_hw_fence.h ++++ b/drivers/gpu/drm/xe/xe_hw_fence.h +@@ -24,7 +24,10 @@ void xe_hw_fence_ctx_init(struct xe_hw_fence_ctx *ctx, struct xe_gt *gt, + struct xe_hw_fence_irq *irq, const char *name); + void xe_hw_fence_ctx_finish(struct xe_hw_fence_ctx *ctx); + +-struct xe_hw_fence *xe_hw_fence_create(struct xe_hw_fence_ctx *ctx, +- struct iosys_map seqno_map); ++struct dma_fence *xe_hw_fence_alloc(void); + ++void xe_hw_fence_free(struct dma_fence *fence); ++ ++void xe_hw_fence_init(struct dma_fence *fence, struct xe_hw_fence_ctx *ctx, ++ struct iosys_map seqno_map); + #endif +diff --git a/drivers/gpu/drm/xe/xe_lrc.c b/drivers/gpu/drm/xe/xe_lrc.c +index d7bf7bc9dc145..995f47eb365c3 100644 +--- a/drivers/gpu/drm/xe/xe_lrc.c ++++ b/drivers/gpu/drm/xe/xe_lrc.c +@@ -901,10 +901,54 @@ u32 xe_lrc_seqno_ggtt_addr(struct xe_lrc *lrc) + return __xe_lrc_seqno_ggtt_addr(lrc); + } + ++/** ++ * xe_lrc_alloc_seqno_fence() - Allocate an lrc seqno fence. ++ * ++ * Allocate but don't initialize an lrc seqno fence. ++ * ++ * Return: Pointer to the allocated fence or ++ * negative error pointer on error. ++ */ ++struct dma_fence *xe_lrc_alloc_seqno_fence(void) ++{ ++ return xe_hw_fence_alloc(); ++} ++ ++/** ++ * xe_lrc_free_seqno_fence() - Free an lrc seqno fence. ++ * @fence: Pointer to the fence to free. ++ * ++ * Frees an lrc seqno fence that hasn't yet been ++ * initialized. ++ */ ++void xe_lrc_free_seqno_fence(struct dma_fence *fence) ++{ ++ xe_hw_fence_free(fence); ++} ++ ++/** ++ * xe_lrc_init_seqno_fence() - Initialize an lrc seqno fence. ++ * @lrc: Pointer to the lrc. ++ * @fence: Pointer to the fence to initialize. ++ * ++ * Initializes a pre-allocated lrc seqno fence. ++ * After initialization, the fence is subject to normal ++ * dma-fence refcounting. ++ */ ++void xe_lrc_init_seqno_fence(struct xe_lrc *lrc, struct dma_fence *fence) ++{ ++ xe_hw_fence_init(fence, &lrc->fence_ctx, __xe_lrc_seqno_map(lrc)); ++} ++ + struct dma_fence *xe_lrc_create_seqno_fence(struct xe_lrc *lrc) + { +- return &xe_hw_fence_create(&lrc->fence_ctx, +- __xe_lrc_seqno_map(lrc))->dma; ++ struct dma_fence *fence = xe_lrc_alloc_seqno_fence(); ++ ++ if (IS_ERR(fence)) ++ return fence; ++ ++ xe_lrc_init_seqno_fence(lrc, fence); ++ return fence; + } + + s32 xe_lrc_seqno(struct xe_lrc *lrc) +diff --git a/drivers/gpu/drm/xe/xe_lrc.h b/drivers/gpu/drm/xe/xe_lrc.h +index d32fa31faa2cf..f57c5836dab87 100644 +--- a/drivers/gpu/drm/xe/xe_lrc.h ++++ b/drivers/gpu/drm/xe/xe_lrc.h +@@ -38,6 +38,9 @@ void xe_lrc_write_ctx_reg(struct xe_lrc *lrc, int reg_nr, u32 val); + u64 xe_lrc_descriptor(struct xe_lrc *lrc); + + u32 xe_lrc_seqno_ggtt_addr(struct xe_lrc *lrc); ++struct dma_fence *xe_lrc_alloc_seqno_fence(void); ++void xe_lrc_free_seqno_fence(struct dma_fence *fence); ++void xe_lrc_init_seqno_fence(struct xe_lrc *lrc, struct dma_fence *fence); + struct dma_fence *xe_lrc_create_seqno_fence(struct xe_lrc *lrc); + s32 xe_lrc_seqno(struct xe_lrc *lrc); + +-- +2.43.0 + diff --git a/queue-6.10/io_uring-kbuf-sanitize-peek-buffer-setup.patch b/queue-6.10/io_uring-kbuf-sanitize-peek-buffer-setup.patch new file mode 100644 index 00000000000..6b753d83e27 --- /dev/null +++ b/queue-6.10/io_uring-kbuf-sanitize-peek-buffer-setup.patch @@ -0,0 +1,47 @@ +From 6513e8ece426ad00a0c34fe6b9d700d2cc930213 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 20 Aug 2024 18:31:58 -0600 +Subject: io_uring/kbuf: sanitize peek buffer setup + +From: Jens Axboe + +[ Upstream commit e0ee967630c8ee67bb47a5b38d235cd5a8789c48 ] + +Harden the buffer peeking a bit, by adding a sanity check for it having +a valid size. Outside of that, arg->max_len is a size_t, though it's +only ever set to a 32-bit value (as it's governed by MAX_RW_COUNT). +Bump our needed check to a size_t so we know it fits. Finally, cap the +calculated needed iov value to the PEEK_MAX_IMPORT, which is the +maximum number of segments that should be peeked. + +Fixes: 35c8711c8fc4 ("io_uring/kbuf: add helpers for getting/peeking multiple buffers") +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + io_uring/kbuf.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/io_uring/kbuf.c b/io_uring/kbuf.c +index c95dc1736dd93..1af2bd56af44a 100644 +--- a/io_uring/kbuf.c ++++ b/io_uring/kbuf.c +@@ -218,10 +218,13 @@ static int io_ring_buffers_peek(struct io_kiocb *req, struct buf_sel_arg *arg, + + buf = io_ring_head_to_buf(br, head, bl->mask); + if (arg->max_len) { +- int needed; ++ u32 len = READ_ONCE(buf->len); ++ size_t needed; + +- needed = (arg->max_len + buf->len - 1) / buf->len; +- needed = min(needed, PEEK_MAX_IMPORT); ++ if (unlikely(!len)) ++ return -ENOBUFS; ++ needed = (arg->max_len + len - 1) / len; ++ needed = min_not_zero(needed, (size_t) PEEK_MAX_IMPORT); + if (nr_avail > needed) + nr_avail = needed; + } +-- +2.43.0 + diff --git a/queue-6.10/mmc-mmc_test-fix-null-dereference-on-allocation-fail.patch b/queue-6.10/mmc-mmc_test-fix-null-dereference-on-allocation-fail.patch new file mode 100644 index 00000000000..07848e425ae --- /dev/null +++ b/queue-6.10/mmc-mmc_test-fix-null-dereference-on-allocation-fail.patch @@ -0,0 +1,55 @@ +From b25768055caea946b37dfb2fba4bc5a0271ac829 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 20 Aug 2024 11:44:08 +0300 +Subject: mmc: mmc_test: Fix NULL dereference on allocation failure + +From: Dan Carpenter + +[ Upstream commit a1e627af32ed60713941cbfc8075d44cad07f6dd ] + +If the "test->highmem = alloc_pages()" allocation fails then calling +__free_pages(test->highmem) will result in a NULL dereference. Also +change the error code to -ENOMEM instead of returning success. + +Fixes: 2661081f5ab9 ("mmc_test: highmem tests") +Signed-off-by: Dan Carpenter +Link: https://lore.kernel.org/r/8c90be28-67b4-4b0d-a105-034dc72a0b31@stanley.mountain +Signed-off-by: Ulf Hansson +Signed-off-by: Sasha Levin +--- + drivers/mmc/core/mmc_test.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/drivers/mmc/core/mmc_test.c b/drivers/mmc/core/mmc_test.c +index 8f7f587a0025b..b7f627a9fdeab 100644 +--- a/drivers/mmc/core/mmc_test.c ++++ b/drivers/mmc/core/mmc_test.c +@@ -3125,13 +3125,13 @@ static ssize_t mtf_test_write(struct file *file, const char __user *buf, + test->buffer = kzalloc(BUFFER_SIZE, GFP_KERNEL); + #ifdef CONFIG_HIGHMEM + test->highmem = alloc_pages(GFP_KERNEL | __GFP_HIGHMEM, BUFFER_ORDER); ++ if (!test->highmem) { ++ count = -ENOMEM; ++ goto free_test_buffer; ++ } + #endif + +-#ifdef CONFIG_HIGHMEM +- if (test->buffer && test->highmem) { +-#else + if (test->buffer) { +-#endif + mutex_lock(&mmc_test_lock); + mmc_test_run(test, testcase); + mutex_unlock(&mmc_test_lock); +@@ -3139,6 +3139,7 @@ static ssize_t mtf_test_write(struct file *file, const char __user *buf, + + #ifdef CONFIG_HIGHMEM + __free_pages(test->highmem, BUFFER_ORDER); ++free_test_buffer: + #endif + kfree(test->buffer); + kfree(test); +-- +2.43.0 + diff --git a/queue-6.10/nvme-move-stopping-keep-alive-into-nvme_uninit_ctrl.patch b/queue-6.10/nvme-move-stopping-keep-alive-into-nvme_uninit_ctrl.patch new file mode 100644 index 00000000000..0ce22f4d8b4 --- /dev/null +++ b/queue-6.10/nvme-move-stopping-keep-alive-into-nvme_uninit_ctrl.patch @@ -0,0 +1,59 @@ +From 3a46b5b6dc39543d8eb658cd339e1853725c31d3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 13 Aug 2024 09:35:27 +0800 +Subject: nvme: move stopping keep-alive into nvme_uninit_ctrl() + +From: Ming Lei + +[ Upstream commit a54a93d0e3599b05856971734e15418ac551a14c ] + +Commit 4733b65d82bd ("nvme: start keep-alive after admin queue setup") +moves starting keep-alive from nvme_start_ctrl() into +nvme_init_ctrl_finish(), but don't move stopping keep-alive into +nvme_uninit_ctrl(), so keep-alive work can be started and keep pending +after failing to start controller, finally use-after-free is triggered if +nvme host driver is unloaded. + +This patch fixes kernel panic when running nvme/004 in case that connection +failure is triggered, by moving stopping keep-alive into nvme_uninit_ctrl(). + +This way is reasonable because keep-alive is now started in +nvme_init_ctrl_finish(). + +Fixes: 3af755a46881 ("nvme: move nvme_stop_keep_alive() back to original position") +Cc: Hannes Reinecke +Cc: Mark O'Donovan +Reported-by: Changhui Zhong +Reviewed-by: Christoph Hellwig +Reviewed-by: Sagi Grimberg +Reviewed-by: Hannes Reinecke +Signed-off-by: Ming Lei +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c +index 782090ce0bc10..d973d063bbf50 100644 +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -4522,7 +4522,6 @@ void nvme_stop_ctrl(struct nvme_ctrl *ctrl) + { + nvme_mpath_stop(ctrl); + nvme_auth_stop(ctrl); +- nvme_stop_keep_alive(ctrl); + nvme_stop_failfast_work(ctrl); + flush_work(&ctrl->async_event_work); + cancel_work_sync(&ctrl->fw_act_work); +@@ -4558,6 +4557,7 @@ EXPORT_SYMBOL_GPL(nvme_start_ctrl); + + void nvme_uninit_ctrl(struct nvme_ctrl *ctrl) + { ++ nvme_stop_keep_alive(ctrl); + nvme_hwmon_exit(ctrl); + nvme_fault_inject_fini(&ctrl->fault_inject); + dev_pm_qos_hide_latency_tolerance(ctrl->device); +-- +2.43.0 + diff --git a/queue-6.10/s390-boot-avoid-possible-physmem_info-segment-corrup.patch b/queue-6.10/s390-boot-avoid-possible-physmem_info-segment-corrup.patch new file mode 100644 index 00000000000..1d08d274d97 --- /dev/null +++ b/queue-6.10/s390-boot-avoid-possible-physmem_info-segment-corrup.patch @@ -0,0 +1,43 @@ +From c9fc3e6f11c891837278d2aaa7345c20f3b378ef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 Aug 2024 18:55:06 +0200 +Subject: s390/boot: Avoid possible physmem_info segment corruption + +From: Alexander Gordeev + +[ Upstream commit d7fd2941ae9a67423d1c7bee985f240e4686634f ] + +When physical memory for the kernel image is allocated it does not +consider extra memory required for offsetting the image start to +match it with the lower 20 bits of KASLR virtual base address. That +might lead to kernel access beyond its memory range. + +Suggested-by: Vasily Gorbik +Fixes: 693d41f7c938 ("s390/mm: Restore mapping of kernel image using large pages") +Signed-off-by: Alexander Gordeev +Acked-by: Vasily Gorbik +Signed-off-by: Vasily Gorbik +Signed-off-by: Sasha Levin +--- + arch/s390/boot/startup.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/s390/boot/startup.c b/arch/s390/boot/startup.c +index 5a36d5538dae8..7797446620b64 100644 +--- a/arch/s390/boot/startup.c ++++ b/arch/s390/boot/startup.c +@@ -446,9 +446,9 @@ void startup_kernel(void) + */ + kaslr_large_page_offset = __kaslr_offset & ~_SEGMENT_MASK; + if (kaslr_enabled()) { +- unsigned long end = ident_map_size - kaslr_large_page_offset; ++ unsigned long size = kernel_size + kaslr_large_page_offset; + +- __kaslr_offset_phys = randomize_within_range(kernel_size, _SEGMENT_SIZE, 0, end); ++ __kaslr_offset_phys = randomize_within_range(size, _SEGMENT_SIZE, 0, ident_map_size); + } + if (!__kaslr_offset_phys) + __kaslr_offset_phys = nokaslr_offset_phys; +-- +2.43.0 + diff --git a/queue-6.10/s390-boot-fix-kaslr-base-offset-off-by-__start_kerne.patch b/queue-6.10/s390-boot-fix-kaslr-base-offset-off-by-__start_kerne.patch new file mode 100644 index 00000000000..edce72e57d0 --- /dev/null +++ b/queue-6.10/s390-boot-fix-kaslr-base-offset-off-by-__start_kerne.patch @@ -0,0 +1,265 @@ +From 30c85c77a391ce7fbda32de92fc79a72648fd6f0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 Aug 2024 18:55:07 +0200 +Subject: s390/boot: Fix KASLR base offset off by __START_KERNEL bytes + +From: Alexander Gordeev + +[ Upstream commit 1642285e511c2a40b14e87a41aa8feace6123036 ] + +Symbol offsets to the KASLR base do not match symbol address in +the vmlinux image. That is the result of setting the KASLR base +to the beginning of .text section as result of an optimization. + +Revert that optimization and allocate virtual memory for the +whole kernel image including __START_KERNEL bytes as per the +linker script. That allows keeping the semantics of the KASLR +base offset in sync with other architectures. + +Rename __START_KERNEL to TEXT_OFFSET, since it represents the +offset of the .text section within the kernel image, rather than +a virtual address. + +Still skip mapping TEXT_OFFSET bytes to save memory on pgtables +and provoke exceptions in case an attempt to access this area is +made, as no kernel symbol may reside there. + +In case CONFIG_KASAN is enabled the location counter might exceed +the value of TEXT_OFFSET, while the decompressor linker script +forcefully resets it to TEXT_OFFSET, which leads to a sections +overlap link failure. Use MAX() expression to avoid that. + +Reported-by: Omar Sandoval +Closes: https://lore.kernel.org/linux-s390/ZnS8dycxhtXBZVky@telecaster.dhcp.thefacebook.com/ +Fixes: 56b1069c40c7 ("s390/boot: Rework deployment of the kernel image") +Signed-off-by: Alexander Gordeev +Acked-by: Vasily Gorbik +Signed-off-by: Vasily Gorbik +Signed-off-by: Sasha Levin +--- + arch/s390/boot/startup.c | 55 ++++++++++++++++++---------------- + arch/s390/boot/vmem.c | 14 +++++++-- + arch/s390/boot/vmlinux.lds.S | 7 ++++- + arch/s390/include/asm/page.h | 3 +- + arch/s390/kernel/vmlinux.lds.S | 2 +- + arch/s390/tools/relocs.c | 2 +- + 6 files changed, 52 insertions(+), 31 deletions(-) + +diff --git a/arch/s390/boot/startup.c b/arch/s390/boot/startup.c +index 7797446620b64..6d88f241dd43a 100644 +--- a/arch/s390/boot/startup.c ++++ b/arch/s390/boot/startup.c +@@ -161,7 +161,7 @@ static void kaslr_adjust_relocs(unsigned long min_addr, unsigned long max_addr, + loc = (long)*reloc + phys_offset; + if (loc < min_addr || loc > max_addr) + error("64-bit relocation outside of kernel!\n"); +- *(u64 *)loc += offset - __START_KERNEL; ++ *(u64 *)loc += offset; + } + } + +@@ -176,7 +176,7 @@ static void kaslr_adjust_got(unsigned long offset) + */ + for (entry = (u64 *)vmlinux.got_start; entry < (u64 *)vmlinux.got_end; entry++) { + if (*entry) +- *entry += offset - __START_KERNEL; ++ *entry += offset; + } + } + +@@ -251,7 +251,7 @@ static unsigned long setup_kernel_memory_layout(unsigned long kernel_size) + vmemmap_size = SECTION_ALIGN_UP(pages) * sizeof(struct page); + + /* choose kernel address space layout: 4 or 3 levels. */ +- BUILD_BUG_ON(!IS_ALIGNED(__START_KERNEL, THREAD_SIZE)); ++ BUILD_BUG_ON(!IS_ALIGNED(TEXT_OFFSET, THREAD_SIZE)); + BUILD_BUG_ON(!IS_ALIGNED(__NO_KASLR_START_KERNEL, THREAD_SIZE)); + BUILD_BUG_ON(__NO_KASLR_END_KERNEL > _REGION1_SIZE); + vsize = get_vmem_size(ident_map_size, vmemmap_size, vmalloc_size, _REGION3_SIZE); +@@ -378,31 +378,25 @@ static void kaslr_adjust_vmlinux_info(long offset) + #endif + } + +-static void fixup_vmlinux_info(void) +-{ +- vmlinux.entry -= __START_KERNEL; +- kaslr_adjust_vmlinux_info(-__START_KERNEL); +-} +- + void startup_kernel(void) + { +- unsigned long kernel_size = vmlinux.image_size + vmlinux.bss_size; +- unsigned long nokaslr_offset_phys, kaslr_large_page_offset; +- unsigned long amode31_lma = 0; ++ unsigned long vmlinux_size = vmlinux.image_size + vmlinux.bss_size; ++ unsigned long nokaslr_text_lma, text_lma = 0, amode31_lma = 0; ++ unsigned long kernel_size = TEXT_OFFSET + vmlinux_size; ++ unsigned long kaslr_large_page_offset; + unsigned long max_physmem_end; + unsigned long asce_limit; + unsigned long safe_addr; + psw_t psw; + +- fixup_vmlinux_info(); + setup_lpp(); + + /* + * Non-randomized kernel physical start address must be _SEGMENT_SIZE + * aligned (see blow). + */ +- nokaslr_offset_phys = ALIGN(mem_safe_offset(), _SEGMENT_SIZE); +- safe_addr = PAGE_ALIGN(nokaslr_offset_phys + kernel_size); ++ nokaslr_text_lma = ALIGN(mem_safe_offset(), _SEGMENT_SIZE); ++ safe_addr = PAGE_ALIGN(nokaslr_text_lma + vmlinux_size); + + /* + * Reserve decompressor memory together with decompression heap, +@@ -446,16 +440,27 @@ void startup_kernel(void) + */ + kaslr_large_page_offset = __kaslr_offset & ~_SEGMENT_MASK; + if (kaslr_enabled()) { +- unsigned long size = kernel_size + kaslr_large_page_offset; ++ unsigned long size = vmlinux_size + kaslr_large_page_offset; + +- __kaslr_offset_phys = randomize_within_range(size, _SEGMENT_SIZE, 0, ident_map_size); ++ text_lma = randomize_within_range(size, _SEGMENT_SIZE, TEXT_OFFSET, ident_map_size); + } +- if (!__kaslr_offset_phys) +- __kaslr_offset_phys = nokaslr_offset_phys; +- __kaslr_offset_phys |= kaslr_large_page_offset; ++ if (!text_lma) ++ text_lma = nokaslr_text_lma; ++ text_lma |= kaslr_large_page_offset; ++ ++ /* ++ * [__kaslr_offset_phys..__kaslr_offset_phys + TEXT_OFFSET] region is ++ * never accessed via the kernel image mapping as per the linker script: ++ * ++ * . = TEXT_OFFSET; ++ * ++ * Therefore, this region could be used for something else and does ++ * not need to be reserved. See how it is skipped in setup_vmem(). ++ */ ++ __kaslr_offset_phys = text_lma - TEXT_OFFSET; + kaslr_adjust_vmlinux_info(__kaslr_offset_phys); +- physmem_reserve(RR_VMLINUX, __kaslr_offset_phys, kernel_size); +- deploy_kernel((void *)__kaslr_offset_phys); ++ physmem_reserve(RR_VMLINUX, text_lma, vmlinux_size); ++ deploy_kernel((void *)text_lma); + + /* vmlinux decompression is done, shrink reserved low memory */ + physmem_reserve(RR_DECOMPRESSOR, 0, (unsigned long)_decompressor_end); +@@ -474,7 +479,7 @@ void startup_kernel(void) + if (kaslr_enabled()) + amode31_lma = randomize_within_range(vmlinux.amode31_size, PAGE_SIZE, 0, SZ_2G); + if (!amode31_lma) +- amode31_lma = __kaslr_offset_phys - vmlinux.amode31_size; ++ amode31_lma = text_lma - vmlinux.amode31_size; + physmem_reserve(RR_AMODE31, amode31_lma, vmlinux.amode31_size); + + /* +@@ -490,8 +495,8 @@ void startup_kernel(void) + * - copy_bootdata() must follow setup_vmem() to propagate changes + * to bootdata made by setup_vmem() + */ +- clear_bss_section(__kaslr_offset_phys); +- kaslr_adjust_relocs(__kaslr_offset_phys, __kaslr_offset_phys + vmlinux.image_size, ++ clear_bss_section(text_lma); ++ kaslr_adjust_relocs(text_lma, text_lma + vmlinux.image_size, + __kaslr_offset, __kaslr_offset_phys); + kaslr_adjust_got(__kaslr_offset); + setup_vmem(__kaslr_offset, __kaslr_offset + kernel_size, asce_limit); +diff --git a/arch/s390/boot/vmem.c b/arch/s390/boot/vmem.c +index 40cfce2687c43..3d4dae9905cd8 100644 +--- a/arch/s390/boot/vmem.c ++++ b/arch/s390/boot/vmem.c +@@ -89,7 +89,7 @@ static void kasan_populate_shadow(unsigned long kernel_start, unsigned long kern + } + memgap_start = end; + } +- kasan_populate(kernel_start, kernel_end, POPULATE_KASAN_MAP_SHADOW); ++ kasan_populate(kernel_start + TEXT_OFFSET, kernel_end, POPULATE_KASAN_MAP_SHADOW); + kasan_populate(0, (unsigned long)__identity_va(0), POPULATE_KASAN_ZERO_SHADOW); + kasan_populate(AMODE31_START, AMODE31_END, POPULATE_KASAN_ZERO_SHADOW); + if (IS_ENABLED(CONFIG_KASAN_VMALLOC)) { +@@ -466,7 +466,17 @@ void setup_vmem(unsigned long kernel_start, unsigned long kernel_end, unsigned l + (unsigned long)__identity_va(end), + POPULATE_IDENTITY); + } +- pgtable_populate(kernel_start, kernel_end, POPULATE_KERNEL); ++ ++ /* ++ * [kernel_start..kernel_start + TEXT_OFFSET] region is never ++ * accessed as per the linker script: ++ * ++ * . = TEXT_OFFSET; ++ * ++ * Therefore, skip mapping TEXT_OFFSET bytes to prevent access to ++ * [__kaslr_offset_phys..__kaslr_offset_phys + TEXT_OFFSET] region. ++ */ ++ pgtable_populate(kernel_start + TEXT_OFFSET, kernel_end, POPULATE_KERNEL); + pgtable_populate(AMODE31_START, AMODE31_END, POPULATE_DIRECT); + pgtable_populate(__abs_lowcore, __abs_lowcore + sizeof(struct lowcore), + POPULATE_ABS_LOWCORE); +diff --git a/arch/s390/boot/vmlinux.lds.S b/arch/s390/boot/vmlinux.lds.S +index a750711d44c86..66670212a3611 100644 +--- a/arch/s390/boot/vmlinux.lds.S ++++ b/arch/s390/boot/vmlinux.lds.S +@@ -109,7 +109,12 @@ SECTIONS + #ifdef CONFIG_KERNEL_UNCOMPRESSED + . = ALIGN(PAGE_SIZE); + . += AMODE31_SIZE; /* .amode31 section */ +- . = ALIGN(1 << 20); /* _SEGMENT_SIZE */ ++ ++ /* ++ * Make sure the location counter is not less than TEXT_OFFSET. ++ * _SEGMENT_SIZE is not available, use ALIGN(1 << 20) instead. ++ */ ++ . = MAX(TEXT_OFFSET, ALIGN(1 << 20)); + #else + . = ALIGN(8); + #endif +diff --git a/arch/s390/include/asm/page.h b/arch/s390/include/asm/page.h +index 224ff9d433ead..8cac1a737424d 100644 +--- a/arch/s390/include/asm/page.h ++++ b/arch/s390/include/asm/page.h +@@ -276,8 +276,9 @@ static inline unsigned long virt_to_pfn(const void *kaddr) + #define AMODE31_SIZE (3 * PAGE_SIZE) + + #define KERNEL_IMAGE_SIZE (512 * 1024 * 1024) +-#define __START_KERNEL 0x100000 + #define __NO_KASLR_START_KERNEL CONFIG_KERNEL_IMAGE_BASE + #define __NO_KASLR_END_KERNEL (__NO_KASLR_START_KERNEL + KERNEL_IMAGE_SIZE) + ++#define TEXT_OFFSET 0x100000 ++ + #endif /* _S390_PAGE_H */ +diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S +index a1ce3925ec719..52bd969b28283 100644 +--- a/arch/s390/kernel/vmlinux.lds.S ++++ b/arch/s390/kernel/vmlinux.lds.S +@@ -39,7 +39,7 @@ PHDRS { + + SECTIONS + { +- . = __START_KERNEL; ++ . = TEXT_OFFSET; + .text : { + _stext = .; /* Start of text section */ + _text = .; /* Text and read-only data */ +diff --git a/arch/s390/tools/relocs.c b/arch/s390/tools/relocs.c +index a74dbd5c9896a..30a732c808f35 100644 +--- a/arch/s390/tools/relocs.c ++++ b/arch/s390/tools/relocs.c +@@ -280,7 +280,7 @@ static int do_reloc(struct section *sec, Elf_Rel *rel) + case R_390_GOTOFF64: + break; + case R_390_64: +- add_reloc(&relocs64, offset - ehdr.e_entry); ++ add_reloc(&relocs64, offset); + break; + default: + die("Unsupported relocation type: %d\n", r_type); +-- +2.43.0 + diff --git a/queue-6.10/series b/queue-6.10/series index f0f2600db59..b5b4da4b971 100644 --- a/queue-6.10/series +++ b/queue-6.10/series @@ -189,3 +189,34 @@ net-xilinx-axienet-always-disable-promiscuous-mode.patch net-xilinx-axienet-fix-dangling-multicast-addresses.patch net-ovs-fix-ovs_drop_reasons-error.patch s390-iucv-fix-vargs-handling-in-iucv_alloc_device.patch +drm-msm-dpu-don-t-play-tricks-with-debug-macros.patch +drm-msm-dp-fix-the-max-supported-bpp-logic.patch +drm-msm-dpu-move-dpu_encoder-s-connector-assignment-.patch +drm-msm-dp-reset-the-link-phy-params-before-link-tra.patch +drm-msm-dpu-cleanup-fb-if-dpu_format_populate_layout.patch +drm-msm-dpu-limit-qcm2290-to-rgb-formats-only.patch +drm-msm-dpu-relax-yuv-requirements.patch +drm-msm-dpu-take-plane-rotation-into-account-for-wid.patch +workqueue-fix-ubsan-subtraction-overflow-error-in-sh.patch +workqueue-fix-spruious-data-race-in-__flush_work.patch +drm-msm-fix-the-highest_bank_bit-for-sc7180.patch +spi-spi-cadence-quadspi-fix-ospi-nor-failures-during.patch +drm-i915-hdcp-use-correct-cp_irq_count.patch +drm-xe-display-stop-calling-domains_driver_remove-tw.patch +drm-xe-fix-opregion-leak.patch +drm-xe-mmio-move-mmio_fini-over-to-devm.patch +drm-xe-reset-mmio-mappings-with-devm.patch +drm-xe-fix-tile-fini-sequence.patch +mmc-mmc_test-fix-null-dereference-on-allocation-fail.patch +io_uring-kbuf-sanitize-peek-buffer-setup.patch +drm-xe-fix-missing-workqueue-destroy-in-xe_gt_pagefa.patch +drm-xe-relax-runtime-pm-protection-during-execution.patch +drm-xe-decouple-job-seqno-and-lrc-seqno.patch +drm-xe-split-lrc-seqno-fence-creation-up.patch +drm-xe-don-t-initialize-fences-at-xe_sched_job_creat.patch +drm-xe-free-job-before-xe_exec_queue_put.patch +thermal-debugfs-fix-the-null-vs-is_err-confusion-in-.patch +s390-boot-avoid-possible-physmem_info-segment-corrup.patch +s390-boot-fix-kaslr-base-offset-off-by-__start_kerne.patch +smb-client-ignore-unhandled-reparse-tags.patch +nvme-move-stopping-keep-alive-into-nvme_uninit_ctrl.patch diff --git a/queue-6.10/smb-client-ignore-unhandled-reparse-tags.patch b/queue-6.10/smb-client-ignore-unhandled-reparse-tags.patch new file mode 100644 index 00000000000..9eca2e35f08 --- /dev/null +++ b/queue-6.10/smb-client-ignore-unhandled-reparse-tags.patch @@ -0,0 +1,57 @@ +From b17c68d9dba3f16bd0440a8f1ef5f59acf208e11 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 Aug 2024 00:45:03 -0300 +Subject: smb: client: ignore unhandled reparse tags + +From: Paulo Alcantara + +[ Upstream commit ec686804117a0421cf31d54427768aaf93aa0069 ] + +Just ignore reparse points that the client can't parse rather than +bailing out and not opening the file or directory. + +Reported-by: Marc <1marc1@gmail.com> +Closes: https://lore.kernel.org/r/CAMHwNVv-B+Q6wa0FEXrAuzdchzcJRsPKDDRrNaYZJd6X-+iJzw@mail.gmail.com +Fixes: 539aad7f14da ("smb: client: introduce ->parse_reparse_point()") +Tested-by: Anthony Nandaa (Microsoft) +Signed-off-by: Paulo Alcantara (Red Hat) +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/client/reparse.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/fs/smb/client/reparse.c b/fs/smb/client/reparse.c +index 689d8a506d459..48c27581ec511 100644 +--- a/fs/smb/client/reparse.c ++++ b/fs/smb/client/reparse.c +@@ -378,6 +378,8 @@ int parse_reparse_point(struct reparse_data_buffer *buf, + u32 plen, struct cifs_sb_info *cifs_sb, + bool unicode, struct cifs_open_info_data *data) + { ++ struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); ++ + data->reparse.buf = buf; + + /* See MS-FSCC 2.1.2 */ +@@ -394,12 +396,13 @@ int parse_reparse_point(struct reparse_data_buffer *buf, + case IO_REPARSE_TAG_LX_FIFO: + case IO_REPARSE_TAG_LX_CHR: + case IO_REPARSE_TAG_LX_BLK: +- return 0; ++ break; + default: +- cifs_dbg(VFS, "%s: unhandled reparse tag: 0x%08x\n", +- __func__, le32_to_cpu(buf->ReparseTag)); +- return -EOPNOTSUPP; ++ cifs_tcon_dbg(VFS | ONCE, "unhandled reparse tag: 0x%08x\n", ++ le32_to_cpu(buf->ReparseTag)); ++ break; + } ++ return 0; + } + + int smb2_parse_reparse_point(struct cifs_sb_info *cifs_sb, +-- +2.43.0 + diff --git a/queue-6.10/spi-spi-cadence-quadspi-fix-ospi-nor-failures-during.patch b/queue-6.10/spi-spi-cadence-quadspi-fix-ospi-nor-failures-during.patch new file mode 100644 index 00000000000..0b4f6416ff6 --- /dev/null +++ b/queue-6.10/spi-spi-cadence-quadspi-fix-ospi-nor-failures-during.patch @@ -0,0 +1,61 @@ +From e85e394d4232677c13e5d5fde6ed488e29fabe95 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 14 Aug 2024 20:42:37 +0530 +Subject: spi: spi-cadence-quadspi: Fix OSPI NOR failures during system resume + +From: Vignesh Raghavendra + +[ Upstream commit 57d5af2660e9443b081eeaf1c373b3ce48477828 ] + +Its necessary to call pm_runtime_force_*() hooks as part of system +suspend/resume calls so that the runtime_pm hooks get called. This +ensures latest state of the IP is cached and restored during system +sleep. This is especially true if runtime autosuspend is enabled as +runtime suspend hooks may not be called at all before system sleeps. + +Without this patch, OSPI NOR enumeration (READ_ID) fails during resume +as context saved during suspend path is inconsistent. + +Fixes: 078d62de433b ("spi: cadence-qspi: add system-wide suspend and resume callbacks") +Signed-off-by: Vignesh Raghavendra +Link: https://patch.msgid.link/20240814151237.3856184-1-vigneshr@ti.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-cadence-quadspi.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c +index 05ebb03d319fc..d4607cb89c484 100644 +--- a/drivers/spi/spi-cadence-quadspi.c ++++ b/drivers/spi/spi-cadence-quadspi.c +@@ -2000,13 +2000,25 @@ static int cqspi_runtime_resume(struct device *dev) + static int cqspi_suspend(struct device *dev) + { + struct cqspi_st *cqspi = dev_get_drvdata(dev); ++ int ret; + +- return spi_controller_suspend(cqspi->host); ++ ret = spi_controller_suspend(cqspi->host); ++ if (ret) ++ return ret; ++ ++ return pm_runtime_force_suspend(dev); + } + + static int cqspi_resume(struct device *dev) + { + struct cqspi_st *cqspi = dev_get_drvdata(dev); ++ int ret; ++ ++ ret = pm_runtime_force_resume(dev); ++ if (ret) { ++ dev_err(dev, "pm_runtime_force_resume failed on resume\n"); ++ return ret; ++ } + + return spi_controller_resume(cqspi->host); + } +-- +2.43.0 + diff --git a/queue-6.10/thermal-debugfs-fix-the-null-vs-is_err-confusion-in-.patch b/queue-6.10/thermal-debugfs-fix-the-null-vs-is_err-confusion-in-.patch new file mode 100644 index 00000000000..c1d5ea497e8 --- /dev/null +++ b/queue-6.10/thermal-debugfs-fix-the-null-vs-is_err-confusion-in-.patch @@ -0,0 +1,56 @@ +From e1fe8197b0f5296d2ec666817f75c5d6b83b8522 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 Aug 2024 03:59:33 -0400 +Subject: thermal/debugfs: Fix the NULL vs IS_ERR() confusion in + debugfs_create_dir() + +From: Yang Ruibin <11162571@vivo.com> + +[ Upstream commit 57df60e1f981fa8c288a49012a4bbb02ae0ecdbc ] + +The debugfs_create_dir() return value is never NULL, it is either a +valid pointer or an error one. + +Use IS_ERR() to check it. + +Fixes: 7ef01f228c9f ("thermal/debugfs: Add thermal debugfs information for mitigation episodes") +Fixes: 755113d76786 ("thermal/debugfs: Add thermal cooling device debugfs information") +Signed-off-by: Yang Ruibin <11162571@vivo.com> +Link: https://patch.msgid.link/20240821075934.12145-1-11162571@vivo.com +[ rjw: Subject and changelog edits ] +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/thermal/thermal_debugfs.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/thermal/thermal_debugfs.c b/drivers/thermal/thermal_debugfs.c +index 9424472291570..6d55f5fc4ca0f 100644 +--- a/drivers/thermal/thermal_debugfs.c ++++ b/drivers/thermal/thermal_debugfs.c +@@ -178,11 +178,11 @@ struct thermal_debugfs { + void thermal_debug_init(void) + { + d_root = debugfs_create_dir("thermal", NULL); +- if (!d_root) ++ if (IS_ERR(d_root)) + return; + + d_cdev = debugfs_create_dir("cooling_devices", d_root); +- if (!d_cdev) ++ if (IS_ERR(d_cdev)) + return; + + d_tz = debugfs_create_dir("thermal_zones", d_root); +@@ -202,7 +202,7 @@ static struct thermal_debugfs *thermal_debugfs_add_id(struct dentry *d, int id) + snprintf(ids, IDSLENGTH, "%d", id); + + thermal_dbg->d_top = debugfs_create_dir(ids, d); +- if (!thermal_dbg->d_top) { ++ if (IS_ERR(thermal_dbg->d_top)) { + kfree(thermal_dbg); + return NULL; + } +-- +2.43.0 + diff --git a/queue-6.10/workqueue-fix-spruious-data-race-in-__flush_work.patch b/queue-6.10/workqueue-fix-spruious-data-race-in-__flush_work.patch new file mode 100644 index 00000000000..06156440859 --- /dev/null +++ b/queue-6.10/workqueue-fix-spruious-data-race-in-__flush_work.patch @@ -0,0 +1,130 @@ +From aa9797bef1f118706e73b6719191b83e35e696e2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 5 Aug 2024 09:37:25 -1000 +Subject: workqueue: Fix spruious data race in __flush_work() + +From: Tejun Heo + +[ Upstream commit 8bc35475ef1a23b0e224f3242eb11c76cab0ea88 ] + +When flushing a work item for cancellation, __flush_work() knows that it +exclusively owns the work item through its PENDING bit. 134874e2eee9 +("workqueue: Allow cancel_work_sync() and disable_work() from atomic +contexts on BH work items") added a read of @work->data to determine whether +to use busy wait for BH work items that are being canceled. While the read +is safe when @from_cancel, @work->data was read before testing @from_cancel +to simplify code structure: + + data = *work_data_bits(work); + if (from_cancel && + !WARN_ON_ONCE(data & WORK_STRUCT_PWQ) && (data & WORK_OFFQ_BH)) { + +While the read data was never used if !@from_cancel, this could trigger +KCSAN data race detection spuriously: + + ================================================================== + BUG: KCSAN: data-race in __flush_work / __flush_work + + write to 0xffff8881223aa3e8 of 8 bytes by task 3998 on cpu 0: + instrument_write include/linux/instrumented.h:41 [inline] + ___set_bit include/asm-generic/bitops/instrumented-non-atomic.h:28 [inline] + insert_wq_barrier kernel/workqueue.c:3790 [inline] + start_flush_work kernel/workqueue.c:4142 [inline] + __flush_work+0x30b/0x570 kernel/workqueue.c:4178 + flush_work kernel/workqueue.c:4229 [inline] + ... + + read to 0xffff8881223aa3e8 of 8 bytes by task 50 on cpu 1: + __flush_work+0x42a/0x570 kernel/workqueue.c:4188 + flush_work kernel/workqueue.c:4229 [inline] + flush_delayed_work+0x66/0x70 kernel/workqueue.c:4251 + ... + + value changed: 0x0000000000400000 -> 0xffff88810006c00d + +Reorganize the code so that @from_cancel is tested before @work->data is +accessed. The only problem is triggering KCSAN detection spuriously. This +shouldn't need READ_ONCE() or other access qualifiers. + +No functional changes. + +Signed-off-by: Tejun Heo +Reported-by: syzbot+b3e4f2f51ed645fd5df2@syzkaller.appspotmail.com +Fixes: 134874e2eee9 ("workqueue: Allow cancel_work_sync() and disable_work() from atomic contexts on BH work items") +Link: http://lkml.kernel.org/r/000000000000ae429e061eea2157@google.com +Cc: Jens Axboe +Signed-off-by: Sasha Levin +--- + kernel/workqueue.c | 45 +++++++++++++++++++++++++-------------------- + 1 file changed, 25 insertions(+), 20 deletions(-) + +diff --git a/kernel/workqueue.c b/kernel/workqueue.c +index c8687c0ab3645..c970eec25c5a0 100644 +--- a/kernel/workqueue.c ++++ b/kernel/workqueue.c +@@ -4190,7 +4190,6 @@ static bool start_flush_work(struct work_struct *work, struct wq_barrier *barr, + static bool __flush_work(struct work_struct *work, bool from_cancel) + { + struct wq_barrier barr; +- unsigned long data; + + if (WARN_ON(!wq_online)) + return false; +@@ -4208,29 +4207,35 @@ static bool __flush_work(struct work_struct *work, bool from_cancel) + * was queued on a BH workqueue, we also know that it was running in the + * BH context and thus can be busy-waited. + */ +- data = *work_data_bits(work); +- if (from_cancel && +- !WARN_ON_ONCE(data & WORK_STRUCT_PWQ) && (data & WORK_OFFQ_BH)) { +- /* +- * On RT, prevent a live lock when %current preempted soft +- * interrupt processing or prevents ksoftirqd from running by +- * keeping flipping BH. If the BH work item runs on a different +- * CPU then this has no effect other than doing the BH +- * disable/enable dance for nothing. This is copied from +- * kernel/softirq.c::tasklet_unlock_spin_wait(). +- */ +- while (!try_wait_for_completion(&barr.done)) { +- if (IS_ENABLED(CONFIG_PREEMPT_RT)) { +- local_bh_disable(); +- local_bh_enable(); +- } else { +- cpu_relax(); ++ if (from_cancel) { ++ unsigned long data = *work_data_bits(work); ++ ++ if (!WARN_ON_ONCE(data & WORK_STRUCT_PWQ) && ++ (data & WORK_OFFQ_BH)) { ++ /* ++ * On RT, prevent a live lock when %current preempted ++ * soft interrupt processing or prevents ksoftirqd from ++ * running by keeping flipping BH. If the BH work item ++ * runs on a different CPU then this has no effect other ++ * than doing the BH disable/enable dance for nothing. ++ * This is copied from ++ * kernel/softirq.c::tasklet_unlock_spin_wait(). ++ */ ++ while (!try_wait_for_completion(&barr.done)) { ++ if (IS_ENABLED(CONFIG_PREEMPT_RT)) { ++ local_bh_disable(); ++ local_bh_enable(); ++ } else { ++ cpu_relax(); ++ } + } ++ goto out_destroy; + } +- } else { +- wait_for_completion(&barr.done); + } + ++ wait_for_completion(&barr.done); ++ ++out_destroy: + destroy_work_on_stack(&barr.work); + return true; + } +-- +2.43.0 + diff --git a/queue-6.10/workqueue-fix-ubsan-subtraction-overflow-error-in-sh.patch b/queue-6.10/workqueue-fix-ubsan-subtraction-overflow-error-in-sh.patch new file mode 100644 index 00000000000..6d140286992 --- /dev/null +++ b/queue-6.10/workqueue-fix-ubsan-subtraction-overflow-error-in-sh.patch @@ -0,0 +1,79 @@ +From ccfc760de58a533ae59b73d57676f4720ddf508a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Jul 2024 12:44:31 +0100 +Subject: workqueue: Fix UBSAN 'subtraction overflow' error in shift_and_mask() + +From: Will Deacon + +[ Upstream commit 38f7e14519d39cf524ddc02d4caee9b337dad703 ] + +UBSAN reports the following 'subtraction overflow' error when booting +in a virtual machine on Android: + + | Internal error: UBSAN: integer subtraction overflow: 00000000f2005515 [#1] PREEMPT SMP + | Modules linked in: + | CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.10.0-00006-g3cbe9e5abd46-dirty #4 + | Hardware name: linux,dummy-virt (DT) + | pstate: 600000c5 (nZCv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--) + | pc : cancel_delayed_work+0x34/0x44 + | lr : cancel_delayed_work+0x2c/0x44 + | sp : ffff80008002ba60 + | x29: ffff80008002ba60 x28: 0000000000000000 x27: 0000000000000000 + | x26: 0000000000000000 x25: 0000000000000000 x24: 0000000000000000 + | x23: 0000000000000000 x22: 0000000000000000 x21: ffff1f65014cd3c0 + | x20: ffffc0e84c9d0da0 x19: ffffc0e84cab3558 x18: ffff800080009058 + | x17: 00000000247ee1f8 x16: 00000000247ee1f8 x15: 00000000bdcb279d + | x14: 0000000000000001 x13: 0000000000000075 x12: 00000a0000000000 + | x11: ffff1f6501499018 x10: 00984901651fffff x9 : ffff5e7cc35af000 + | x8 : 0000000000000001 x7 : 3d4d455453595342 x6 : 000000004e514553 + | x5 : ffff1f6501499265 x4 : ffff1f650ff60b10 x3 : 0000000000000620 + | x2 : ffff80008002ba78 x1 : 0000000000000000 x0 : 0000000000000000 + | Call trace: + | cancel_delayed_work+0x34/0x44 + | deferred_probe_extend_timeout+0x20/0x70 + | driver_register+0xa8/0x110 + | __platform_driver_register+0x28/0x3c + | syscon_init+0x24/0x38 + | do_one_initcall+0xe4/0x338 + | do_initcall_level+0xac/0x178 + | do_initcalls+0x5c/0xa0 + | do_basic_setup+0x20/0x30 + | kernel_init_freeable+0x8c/0xf8 + | kernel_init+0x28/0x1b4 + | ret_from_fork+0x10/0x20 + | Code: f9000fbf 97fffa2f 39400268 37100048 (d42aa2a0) + | ---[ end trace 0000000000000000 ]--- + | Kernel panic - not syncing: UBSAN: integer subtraction overflow: Fatal exception + +This is due to shift_and_mask() using a signed immediate to construct +the mask and being called with a shift of 31 (WORK_OFFQ_POOL_SHIFT) so +that it ends up decrementing from INT_MIN. + +Use an unsigned constant '1U' to generate the mask in shift_and_mask(). + +Cc: Tejun Heo +Cc: Lai Jiangshan +Fixes: 1211f3b21c2a ("workqueue: Preserve OFFQ bits in cancel[_sync] paths") +Signed-off-by: Will Deacon +Signed-off-by: Tejun Heo +Signed-off-by: Sasha Levin +--- + kernel/workqueue.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/workqueue.c b/kernel/workqueue.c +index f98247ec99c20..c8687c0ab3645 100644 +--- a/kernel/workqueue.c ++++ b/kernel/workqueue.c +@@ -896,7 +896,7 @@ static struct worker_pool *get_work_pool(struct work_struct *work) + + static unsigned long shift_and_mask(unsigned long v, u32 shift, u32 bits) + { +- return (v >> shift) & ((1 << bits) - 1); ++ return (v >> shift) & ((1U << bits) - 1); + } + + static void work_offqd_unpack(struct work_offq_data *offqd, unsigned long data) +-- +2.43.0 +