Commit 3d08a425 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'drm-fixes-2025-10-24' of https://gitlab.freedesktop.org/drm/kernel

Pull drm fixes from Simona Vetter:
 "Very quiet, all just small stuff and nothing scary pending to my
  knowledge:

   - drm_panic: bunch of size calculation fixes

   - pantor: fix kernel panic on partial gpu va unmap

   - rockchip: hdmi hotplug setup fix

   - amdgpu: dp mst, dc/display fixes

   - i915: fix panic structure leak

   - xe: madvise uapi fix, wq alloc error, vma flag handling fix"

* tag 'drm-fixes-2025-10-24' of https://gitlab.freedesktop.org/drm/kernel:
  drm/xe: Check return value of GGTT workqueue allocation
  drm/amd/display: use GFP_NOWAIT for allocation in interrupt handler
  drm/amd/display: increase max link count and fix link->enc NULL pointer access
  drm/amd/display: Fix NULL pointer dereference
  drm/panic: Fix 24bit pixel crossing page boundaries
  drm/panic: Fix divide by 0 if the screen width < font width
  drm/panic: Fix kmsg text drawing rectangle
  drm/panic: Fix qr_code, ensure vmargin is positive
  drm/panic: Fix overlap between qr code and logo
  drm/panic: Fix drawing the logo on a small narrow screen
  drm/xe/uapi: Hide the madvise autoreset behind a VM_BIND flag
  drm/xe: Retain vma flags when recreating and splitting vmas for madvise
  drm/i915/panic: fix panic structure allocation memory leak
  drm/panthor: Fix kernel panic on partial unmap of a GPU VA region
  drm/rockchip: dw_hdmi: use correct SCLIN mask for RK3228
parents 31009296 18b1ce0b
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -551,13 +551,13 @@ static void schedule_dc_vmin_vmax(struct amdgpu_device *adev,
	struct dc_stream_state *stream,
	struct dc_crtc_timing_adjust *adjust)
{
	struct vupdate_offload_work *offload_work = kzalloc(sizeof(*offload_work), GFP_KERNEL);
	struct vupdate_offload_work *offload_work = kzalloc(sizeof(*offload_work), GFP_NOWAIT);
	if (!offload_work) {
		drm_dbg_driver(adev_to_drm(adev), "Failed to allocate vupdate_offload_work\n");
		return;
	}

	struct dc_crtc_timing_adjust *adjust_copy = kzalloc(sizeof(*adjust_copy), GFP_KERNEL);
	struct dc_crtc_timing_adjust *adjust_copy = kzalloc(sizeof(*adjust_copy), GFP_NOWAIT);
	if (!adjust_copy) {
		drm_dbg_driver(adev_to_drm(adev), "Failed to allocate adjust_copy\n");
		kfree(offload_work);
+3 −0
Original line number Diff line number Diff line
@@ -200,6 +200,9 @@ void dcn401_init_hw(struct dc *dc)
		 */
		struct dc_link *link = dc->links[i];

		if (link->ep_type != DISPLAY_ENDPOINT_PHY)
			continue;

		link->link_enc->funcs->hw_init(link->link_enc);

		/* Check for enabled DIG to identify enabled display */
+7 −1
Original line number Diff line number Diff line
@@ -44,7 +44,13 @@
 */
#define MAX_PIPES 6
#define MAX_PHANTOM_PIPES (MAX_PIPES / 2)
#define MAX_LINKS (MAX_PIPES * 2 +2)

#define MAX_DPIA 6
#define MAX_CONNECTOR 6
#define MAX_VIRTUAL_LINKS 4

#define MAX_LINKS (MAX_DPIA + MAX_CONNECTOR + MAX_VIRTUAL_LINKS)

#define MAX_DIG_LINK_ENCODERS 7
#define MAX_DWB_PIPES	1
#define MAX_HPO_DP2_ENCODERS	4
+2 −1
Original line number Diff line number Diff line
@@ -78,6 +78,7 @@ static void dp_retrain_link_dp_test(struct dc_link *link,
	struct audio_output audio_output[MAX_PIPES];
	struct dc_stream_state *streams_on_link[MAX_PIPES];
	int num_streams_on_link = 0;
	struct dc *dc = (struct dc *)link->dc;

	needs_divider_update = (link->dc->link_srv->dp_get_encoding_format(link_setting) !=
	link->dc->link_srv->dp_get_encoding_format((const struct dc_link_settings *) &link->cur_link_settings));
@@ -150,7 +151,7 @@ static void dp_retrain_link_dp_test(struct dc_link *link,
		if (streams_on_link[i] && streams_on_link[i]->link && streams_on_link[i]->link == link) {
			stream_update.stream = streams_on_link[i];
			stream_update.dpms_off = &dpms_off;
			dc_update_planes_and_stream(state->clk_mgr->ctx->dc, NULL, 0, streams_on_link[i], &stream_update);
			dc_update_planes_and_stream(dc, NULL, 0, streams_on_link[i], &stream_update);
		}
	}
}
+54 −6
Original line number Diff line number Diff line
@@ -174,6 +174,33 @@ static void drm_panic_write_pixel24(void *vaddr, unsigned int offset, u32 color)
	*p = color & 0xff;
}

/*
 * Special case if the pixel crosses page boundaries
 */
static void drm_panic_write_pixel24_xpage(void *vaddr, struct page *next_page,
					  unsigned int offset, u32 color)
{
	u8 *vaddr2;
	u8 *p = vaddr + offset;

	vaddr2 = kmap_local_page_try_from_panic(next_page);

	*p++ = color & 0xff;
	color >>= 8;

	if (offset == PAGE_SIZE - 1)
		p = vaddr2;

	*p++ = color & 0xff;
	color >>= 8;

	if (offset == PAGE_SIZE - 2)
		p = vaddr2;

	*p = color & 0xff;
	kunmap_local(vaddr2);
}

static void drm_panic_write_pixel32(void *vaddr, unsigned int offset, u32 color)
{
	u32 *p = vaddr + offset;
@@ -231,7 +258,14 @@ static void drm_panic_blit_page(struct page **pages, unsigned int dpitch,
					page = new_page;
					vaddr = kmap_local_page_try_from_panic(pages[page]);
				}
				if (vaddr)
				if (!vaddr)
					continue;

				// Special case for 24bit, as a pixel might cross page boundaries
				if (cpp == 3 && offset + 3 > PAGE_SIZE)
					drm_panic_write_pixel24_xpage(vaddr, pages[page + 1],
								      offset, fg32);
				else
					drm_panic_write_pixel(vaddr, offset, fg32, cpp);
			}
		}
@@ -321,6 +355,14 @@ static void drm_panic_fill_page(struct page **pages, unsigned int dpitch,
				page = new_page;
				vaddr = kmap_local_page_try_from_panic(pages[page]);
			}
			if (!vaddr)
				continue;

			// Special case for 24bit, as a pixel might cross page boundaries
			if (cpp == 3 && offset + 3 > PAGE_SIZE)
				drm_panic_write_pixel24_xpage(vaddr, pages[page + 1],
							      offset, color);
			else
				drm_panic_write_pixel(vaddr, offset, color, cpp);
		}
	}
@@ -429,6 +471,9 @@ static void drm_panic_logo_rect(struct drm_rect *rect, const struct font_desc *f
static void drm_panic_logo_draw(struct drm_scanout_buffer *sb, struct drm_rect *rect,
				const struct font_desc *font, u32 fg_color)
{
	if (rect->x2 > sb->width || rect->y2 > sb->height)
		return;

	if (logo_mono)
		drm_panic_blit(sb, rect, logo_mono->data,
			       DIV_ROUND_UP(drm_rect_width(rect), 8), 1, fg_color);
@@ -477,7 +522,7 @@ static int draw_line_with_wrap(struct drm_scanout_buffer *sb, const struct font_
			       struct drm_panic_line *line, int yoffset, u32 fg_color)
{
	int chars_per_row = sb->width / font->width;
	struct drm_rect r_txt = DRM_RECT_INIT(0, yoffset, sb->width, sb->height);
	struct drm_rect r_txt = DRM_RECT_INIT(0, yoffset, sb->width, font->height);
	struct drm_panic_line line_wrap;

	if (line->len > chars_per_row) {
@@ -520,7 +565,7 @@ static void draw_panic_static_kmsg(struct drm_scanout_buffer *sb)
	struct drm_panic_line line;
	int yoffset;

	if (!font)
	if (!font || font->width > sb->width)
		return;

	yoffset = sb->height - font->height - (sb->height % font->height) / 2;
@@ -733,7 +778,10 @@ static int _draw_panic_static_qr_code(struct drm_scanout_buffer *sb)
	pr_debug("QR width %d and scale %d\n", qr_width, scale);
	r_qr_canvas = DRM_RECT_INIT(0, 0, qr_canvas_width * scale, qr_canvas_width * scale);

	v_margin = (sb->height - drm_rect_height(&r_qr_canvas) - drm_rect_height(&r_msg)) / 5;
	v_margin = sb->height - drm_rect_height(&r_qr_canvas) - drm_rect_height(&r_msg);
	if (v_margin < 0)
		return -ENOSPC;
	v_margin /= 5;

	drm_rect_translate(&r_qr_canvas, (sb->width - r_qr_canvas.x2) / 2, 2 * v_margin);
	r_qr = DRM_RECT_INIT(r_qr_canvas.x1 + QR_MARGIN * scale, r_qr_canvas.y1 + QR_MARGIN * scale,
@@ -746,7 +794,7 @@ static int _draw_panic_static_qr_code(struct drm_scanout_buffer *sb)
	/* Fill with the background color, and draw text on top */
	drm_panic_fill(sb, &r_screen, bg_color);

	if (!drm_rect_overlap(&r_logo, &r_msg) && !drm_rect_overlap(&r_logo, &r_qr))
	if (!drm_rect_overlap(&r_logo, &r_msg) && !drm_rect_overlap(&r_logo, &r_qr_canvas))
		drm_panic_logo_draw(sb, &r_logo, font, fg_color);

	draw_txt_rectangle(sb, font, panic_msg, panic_msg_lines, true, &r_msg, fg_color);
Loading