From nobody Sat Oct 11 04:17:29 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6367C2222A0 for ; Thu, 12 Jun 2025 08:14:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749716085; cv=none; b=MsLegX6UGmb9t5PHe5fXtatbT4IY4Gg5zMg9kEkPYSgAxcm5aUk8IheHFTMwmh4ntxDMJ0Z/tOrTrr7MUb35ceAiAyEQ9H1Ghax2YlKkwjjY1cHfJ808ZxGXvopGTHAHfvOhLf14KGZ1/lvPcX1yVefS4FOUas51kgR3y+FICq0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749716085; c=relaxed/simple; bh=6UepdPUEtlA/yuVvjH3xcZaLGc7hN6ie/sR8eWFjzsc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=pDq956Mlbt3CpKvDMbZ4sWmU7by/KYcwsjq9K4N8dUMjnYqW59pIHY1KRY6rvvWoKfYQs+teteFLGR9SgpJ/hvvJhQi0s1R3HQUKPHP1qJErUxaG9LFvCPkB5DbSQw+EgRv9SpDu5YWcdDKsWyE/uOPRO27TaUArQmlXQuispGw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=cZ2Skl7T; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="cZ2Skl7T" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1749716082; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=3hlLPpWohQaWgUywPRD8IibJwztrb/smWwJmxETpRN4=; b=cZ2Skl7TWt7gq90NGOOxOSO6dOE6KuOm5xNM05pr1zFCk2ADv7cuEkssmHctJ7s9RreTnr VfoMg4w7NeqQXMyvUwAvV2FRKzj4SYBuziOCQhdQROYe+BG2dGGhLtyzLBdXX56PH98aUQ dgSbGIHJlxx8uGJYrq803/JBK/y9YYY= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-67-DAwxVZByOBS0srJ91RYkfw-1; Thu, 12 Jun 2025 04:14:39 -0400 X-MC-Unique: DAwxVZByOBS0srJ91RYkfw-1 X-Mimecast-MFC-AGG-ID: DAwxVZByOBS0srJ91RYkfw_1749716077 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 151551956059; Thu, 12 Jun 2025 08:14:37 +0000 (UTC) Received: from hydra.redhat.com (unknown [10.45.225.28]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id A35191956048; Thu, 12 Jun 2025 08:14:31 +0000 (UTC) From: Jocelyn Falempe To: Jani Nikula , Rodrigo Vivi , Joonas Lahtinen , Tvrtko Ursulin , =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= , David Airlie , Simona Vetter , Christian Koenig , Huang Rui , Matthew Auld , Matthew Brost , Maxime Ripard , Thomas Zimmermann , intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org Cc: Jocelyn Falempe Subject: [PATCH v9 5/9] drm/i915: Add intel_bo_panic_setup and intel_bo_panic_finish Date: Thu, 12 Jun 2025 10:01:02 +0200 Message-ID: <20250612081344.225200-6-jfalempe@redhat.com> In-Reply-To: <20250612081344.225200-1-jfalempe@redhat.com> References: <20250612081344.225200-1-jfalempe@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 Implement both functions for i915 and xe, they prepare the work for drm_panic support. They both use kmap_try_from_panic(), and map one page at a time, to write the panic screen on the framebuffer. Signed-off-by: Jocelyn Falempe --- v5: * Use iosys_map for intel_bo_panic_map(). v7: * Return int for i915_gem_object_panic_map() (Ville Syrj=C3=A4l=C3=A4) v8: * Complete rewrite, to use kmap_try_from_panic() which is safe to call from a panic handler. v9: * Fix missing kfree() for i915_panic_pages in i915_gem_object_panic_finish= () Also change i915_panic_pages allocation to kmalloc, as kvmalloc is not safe to call from the panic handler. drivers/gpu/drm/i915/display/intel_bo.c | 11 +++ drivers/gpu/drm/i915/display/intel_bo.h | 3 + drivers/gpu/drm/i915/gem/i915_gem_object.h | 4 + drivers/gpu/drm/i915/gem/i915_gem_pages.c | 95 ++++++++++++++++++++++ drivers/gpu/drm/xe/display/intel_bo.c | 56 +++++++++++++ 5 files changed, 169 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_bo.c b/drivers/gpu/drm/i915= /display/intel_bo.c index fbd16d7b58d9..83dbd8ae16fe 100644 --- a/drivers/gpu/drm/i915/display/intel_bo.c +++ b/drivers/gpu/drm/i915/display/intel_bo.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: MIT /* Copyright =C2=A9 2024 Intel Corporation */ =20 +#include #include "gem/i915_gem_mman.h" #include "gem/i915_gem_object.h" #include "gem/i915_gem_object_frontbuffer.h" @@ -57,3 +58,13 @@ void intel_bo_describe(struct seq_file *m, struct drm_ge= m_object *obj) { i915_debugfs_describe_obj(m, to_intel_bo(obj)); } + +int intel_bo_panic_setup(struct drm_gem_object *obj, struct drm_scanout_bu= ffer *sb) +{ + return i915_gem_object_panic_setup(to_intel_bo(obj), sb); +} + +void intel_bo_panic_finish(struct drm_gem_object *obj) +{ + return i915_gem_object_panic_finish(to_intel_bo(obj)); +} diff --git a/drivers/gpu/drm/i915/display/intel_bo.h b/drivers/gpu/drm/i915= /display/intel_bo.h index ea7a2253aaa5..9ac087ea275d 100644 --- a/drivers/gpu/drm/i915/display/intel_bo.h +++ b/drivers/gpu/drm/i915/display/intel_bo.h @@ -4,6 +4,7 @@ #ifndef __INTEL_BO__ #define __INTEL_BO__ =20 +#include #include =20 struct drm_gem_object; @@ -23,5 +24,7 @@ struct intel_frontbuffer *intel_bo_set_frontbuffer(struct= drm_gem_object *obj, struct intel_frontbuffer *front); =20 void intel_bo_describe(struct seq_file *m, struct drm_gem_object *obj); +int intel_bo_panic_setup(struct drm_gem_object *obj, struct drm_scanout_bu= ffer *sb); +void intel_bo_panic_finish(struct drm_gem_object *obj); =20 #endif /* __INTEL_BO__ */ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i= 915/gem/i915_gem_object.h index c34f41605b46..9a0c1019dcad 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h @@ -9,6 +9,7 @@ #include #include #include +#include =20 #include "intel_memory_region.h" #include "i915_gem_object_types.h" @@ -691,6 +692,9 @@ i915_gem_object_unpin_pages(struct drm_i915_gem_object = *obj) int __i915_gem_object_put_pages(struct drm_i915_gem_object *obj); int i915_gem_object_truncate(struct drm_i915_gem_object *obj); =20 +int i915_gem_object_panic_setup(struct drm_i915_gem_object *obj, struct dr= m_scanout_buffer *sb); +void i915_gem_object_panic_finish(struct drm_i915_gem_object *obj); + /** * i915_gem_object_pin_map - return a contiguous mapping of the entire obj= ect * @obj: the object to map into kernel address space diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i9= 15/gem/i915_gem_pages.c index 7f83f8bdc8fb..81cda0a7f4d3 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c @@ -3,6 +3,7 @@ * Copyright =C2=A9 2014-2016 Intel Corporation */ =20 +#include #include #include =20 @@ -354,6 +355,100 @@ static void *i915_gem_object_map_pfn(struct drm_i915_= gem_object *obj, return vaddr ?: ERR_PTR(-ENOMEM); } =20 +static struct page **i915_panic_pages; +static int i915_panic_page =3D -1; +static void *i915_panic_vaddr; + +static void i915_panic_kunmap(void) +{ + if (i915_panic_vaddr) { + drm_clflush_virt_range(i915_panic_vaddr, PAGE_SIZE); + kunmap_local(i915_panic_vaddr); + i915_panic_vaddr =3D NULL; + } +} + +static struct page **i915_gem_object_panic_pages(struct drm_i915_gem_objec= t *obj) +{ + unsigned long n_pages =3D obj->base.size >> PAGE_SHIFT, i; + struct page *page; + struct page **pages; + struct sgt_iter iter; + + /* For a 3840x2160 32 bits Framebuffer, this should require ~64K */ + pages =3D kmalloc_array(n_pages, sizeof(*pages), GFP_ATOMIC); + if (!pages) + return NULL; + + i =3D 0; + for_each_sgt_page(page, iter, obj->mm.pages) + pages[i++] =3D page; + return pages; +} + +/* + * The scanout buffer pages are not mapped, so for each pixel, + * use kmap_local_page_try_from_panic() to map the page, and write the pix= el. + * Try to keep the map from the previous pixel, to avoid too much map/unma= p. + */ +static void i915_gem_object_panic_page_set_pixel(struct drm_scanout_buffer= *sb, unsigned int x, + unsigned int y, u32 color) +{ + unsigned int new_page; + unsigned int offset; + + offset =3D y * sb->pitch[0] + x * sb->format->cpp[0]; + + new_page =3D offset >> PAGE_SHIFT; + offset =3D offset % PAGE_SIZE; + if (new_page !=3D i915_panic_page) { + i915_panic_kunmap(); + i915_panic_page =3D new_page; + i915_panic_vaddr =3D + kmap_local_page_try_from_panic(i915_panic_pages[i915_panic_page]); + } + if (i915_panic_vaddr) { + u32 *pix =3D i915_panic_vaddr + offset; + *pix =3D color; + } +} + +/* + * Setup the gem framebuffer for drm_panic access. + * Use current vaddr if it exists, or setup a list of pages. + * pfn is not supported yet. + */ +int i915_gem_object_panic_setup(struct drm_i915_gem_object *obj, struct dr= m_scanout_buffer *sb) +{ + enum i915_map_type has_type; + void *ptr; + + ptr =3D page_unpack_bits(obj->mm.mapping, &has_type); + if (ptr) { + if (i915_gem_object_has_iomem(obj)) + iosys_map_set_vaddr_iomem(&sb->map[0], (void __iomem *)ptr); + else + iosys_map_set_vaddr(&sb->map[0], ptr); + + return 0; + } + if (i915_gem_object_has_struct_page(obj)) { + i915_panic_pages =3D i915_gem_object_panic_pages(obj); + sb->set_pixel =3D i915_gem_object_panic_page_set_pixel; + i915_panic_page =3D -1; + return 0; + } + return -EOPNOTSUPP; +} + +void i915_gem_object_panic_finish(struct drm_i915_gem_object *obj) +{ + i915_panic_kunmap(); + i915_panic_page =3D -1; + kfree(i915_panic_pages); + i915_panic_pages =3D NULL; +} + /* get, pin, and map the pages of the object into kernel space */ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj, enum i915_map_type type) diff --git a/drivers/gpu/drm/xe/display/intel_bo.c b/drivers/gpu/drm/xe/dis= play/intel_bo.c index 27437c22bd70..19b74ebaff2a 100644 --- a/drivers/gpu/drm/xe/display/intel_bo.c +++ b/drivers/gpu/drm/xe/display/intel_bo.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: MIT /* Copyright =C2=A9 2024 Intel Corporation */ =20 +#include #include =20 #include "xe_bo.h" @@ -59,3 +60,58 @@ void intel_bo_describe(struct seq_file *m, struct drm_ge= m_object *obj) { /* FIXME */ } + +static int xe_panic_page =3D -1; +static void *xe_panic_vaddr; +static struct xe_bo *xe_panic_bo; + +static void xe_panic_kunmap(void) +{ + if (xe_panic_vaddr) { + drm_clflush_virt_range(xe_panic_vaddr, PAGE_SIZE); + kunmap_local(xe_panic_vaddr); + xe_panic_vaddr =3D NULL; + } +} + +/* + * The scanout buffer pages are not mapped, so for each pixel, + * use kmap_local_page_try_from_panic() to map the page, and write the pix= el. + * Try to keep the map from the previous pixel, to avoid too much map/unma= p. + */ +static void xe_panic_page_set_pixel(struct drm_scanout_buffer *sb, unsigne= d int x, + unsigned int y, u32 color) +{ + unsigned int new_page; + unsigned int offset; + + offset =3D y * sb->pitch[0] + x * sb->format->cpp[0]; + + new_page =3D offset >> PAGE_SHIFT; + offset =3D offset % PAGE_SIZE; + if (new_page !=3D xe_panic_page) { + xe_panic_kunmap(); + xe_panic_page =3D new_page; + xe_panic_vaddr =3D ttm_bo_kmap_try_from_panic(&xe_panic_bo->ttm, + xe_panic_page); + } + if (xe_panic_vaddr) { + u32 *pix =3D xe_panic_vaddr + offset; + *pix =3D color; + } +} + +int intel_bo_panic_setup(struct drm_gem_object *obj, struct drm_scanout_bu= ffer *sb) +{ + struct xe_bo *bo =3D gem_to_xe_bo(obj); + + xe_panic_bo =3D bo; + sb->set_pixel =3D xe_panic_page_set_pixel; + return 0; +} + +void intel_bo_panic_finish(struct drm_gem_object *obj) +{ + xe_panic_kunmap(); + xe_panic_page =3D -1; +} --=20 2.49.0