From patchwork Mon Mar 11 17:42:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Noralf_Tr=C3=B8nnes?= X-Patchwork-Id: 10847909 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6F1791575 for ; Mon, 11 Mar 2019 17:42:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5922C28A1F for ; Mon, 11 Mar 2019 17:42:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4D10528DD0; Mon, 11 Mar 2019 17:42:43 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 4EED828DE1 for ; Mon, 11 Mar 2019 17:42:42 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id C064689C53; Mon, 11 Mar 2019 17:42:33 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from smtp.domeneshop.no (smtp.domeneshop.no [IPv6:2a01:5b40:0:3005::1]) by gabe.freedesktop.org (Postfix) with ESMTPS id 6930489C17; Mon, 11 Mar 2019 17:42:31 +0000 (UTC) Received: from 211.81-166-168.customer.lyse.net ([81.166.168.211]:44760 helo=localhost.localdomain) by smtp.domeneshop.no with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.84_2) (envelope-from ) id 1h3OwX-0007oa-FL; Mon, 11 Mar 2019 18:42:29 +0100 From: =?utf-8?q?Noralf_Tr=C3=B8nnes?= To: dri-devel@lists.freedesktop.org Subject: [PATCH v2 1/3] drm: Add support for panic message output Date: Mon, 11 Mar 2019 18:42:16 +0100 Message-Id: <20190311174218.51899-2-noralf@tronnes.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190311174218.51899-1-noralf@tronnes.org> References: <20190311174218.51899-1-noralf@tronnes.org> MIME-Version: 1.0 X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=tronnes.org; s=ds201810; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From; bh=AYL43UC09OLtThuowsLT32JqUiAqTlqu/osntpJbXZI=; b=RgvrtAcW9FYZhmanbVlcbF7N7+HYV2Tkj4islMK1iEGnNGt86gL0ubvVawOhyDUlbnAMpE7FgJH9ycaJ7YaL8fPKvssHkyr5ePSzdQ3FN2sv/IBVpJVBvsVTdmDpIfCICGs2ZJxpw1ue/NgDMUSYlN6Q1cDvPHeobwsP7AaNsGZ6Y9TSRmHVv/tzbsfCovTUxISeyaRCKPw7NylwfQGSCUAX848hDBeIlKJ9PJ5Tv0gUaxwAiYiii08Cb0s/ungJ6D4BC6t4Ys1EJx1sEK8UHfw7dB9pHoJTCnYi03aNMVBn3Ti3zquhtM0AvALr8IIGJ+VK0IHR5TzDvS8pkibYew==; X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: daniel.vetter@ffwll.ch, intel-gfx@lists.freedesktop.org, darwish.07@gmail.com Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP This adds support for outputting kernel messages on panic(). A kernel message dumper is used to dump the log. The dumper iterates over each DRM device and it's crtc's to find suitable framebuffers. All the other dumpers are run before this one except mtdoops. Only atomic drivers are supported. Signed-off-by: Noralf Trønnes --- drivers/gpu/drm/Kconfig | 3 + drivers/gpu/drm/drm_drv.c | 3 + drivers/gpu/drm/drm_framebuffer.c | 117 ++++++++++ drivers/gpu/drm/drm_internal.h | 4 + drivers/gpu/drm/drm_panic.c | 363 ++++++++++++++++++++++++++++++ include/drm/drm_framebuffer.h | 41 ++++ 6 files changed, 531 insertions(+) create mode 100644 drivers/gpu/drm/drm_panic.c diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index bd943a71756c..74c37542f857 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -14,6 +14,9 @@ menuconfig DRM select I2C_ALGOBIT select DMA_SHARED_BUFFER select SYNC_FILE + select FONT_SUPPORT + select FONT_8x8 + select FONT_8x16 help Kernel-level support for the Direct Rendering Infrastructure (DRI) introduced in XFree86 4.0. If you say Y here, you need to select diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 50d849d1bc6e..b0b870b5dd55 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -1147,6 +1147,7 @@ static const struct file_operations drm_stub_fops = { static void drm_core_exit(void) { + drm_panic_exit(drm_debugfs_root); unregister_chrdev(DRM_MAJOR, "drm"); debugfs_remove(drm_debugfs_root); drm_sysfs_destroy(); @@ -1178,6 +1179,8 @@ static int __init drm_core_init(void) if (ret < 0) goto error; + drm_panic_init(drm_debugfs_root); + drm_core_init_complete = true; DRM_DEBUG("Initialized\n"); diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c index d8d75e25f6fb..da2285c5ae90 100644 --- a/drivers/gpu/drm/drm_framebuffer.c +++ b/drivers/gpu/drm/drm_framebuffer.c @@ -1087,3 +1087,120 @@ int drm_framebuffer_debugfs_init(struct drm_minor *minor) minor->debugfs_root, minor); } #endif + +/** + * drm_framebuffer_panic_draw_xy - draw pixel on fb during panic() + * @fb: DRM framebuffer + * @vmap: Linear virtual mapping + * @x: X coordinate + * @y: Y coordinate + * @foreground: Foreground pixel + * + * This function can be used to draw a pixel during panic message rendering. + * It requires @vmap to be a linear mapping. This is the default implementation + * used if &drm_framebuffer_funcs->panic_draw_xy is not set. + */ +void drm_framebuffer_panic_draw_xy(struct drm_framebuffer *fb, void *vmap, + int x, int y, bool foreground) +{ + void *pix = vmap + fb->offsets[0] + (y * fb->pitches[0]); + u8 *pix8 = pix; + u16 *pix16 = pix; + u32 *pix32 = pix; + + switch (fb->format->format & ~DRM_FORMAT_BIG_ENDIAN) { + case DRM_FORMAT_C8: + + case DRM_FORMAT_RGB332: + case DRM_FORMAT_BGR233: + + case DRM_FORMAT_NV12: + case DRM_FORMAT_NV21: + case DRM_FORMAT_NV16: + case DRM_FORMAT_NV61: + case DRM_FORMAT_NV24: + case DRM_FORMAT_NV42: + + case DRM_FORMAT_YUV410: + case DRM_FORMAT_YVU410: + case DRM_FORMAT_YUV411: + case DRM_FORMAT_YVU411: + case DRM_FORMAT_YUV420: + case DRM_FORMAT_YVU420: + case DRM_FORMAT_YUV422: + case DRM_FORMAT_YVU422: + case DRM_FORMAT_YUV444: + case DRM_FORMAT_YVU444: + pix8[x] = foreground ? 0xff : 0x00; + break; + + case DRM_FORMAT_XRGB4444: + case DRM_FORMAT_ARGB4444: + case DRM_FORMAT_XBGR4444: + case DRM_FORMAT_ABGR4444: + pix16[x] = foreground ? 0xffff : 0xf000; + break; + + case DRM_FORMAT_RGBX4444: + case DRM_FORMAT_RGBA4444: + case DRM_FORMAT_BGRX4444: + case DRM_FORMAT_BGRA4444: + pix16[x] = foreground ? 0xffff : 0x000f; + break; + + case DRM_FORMAT_XRGB1555: + case DRM_FORMAT_ARGB1555: + case DRM_FORMAT_XBGR1555: + case DRM_FORMAT_ABGR1555: + pix16[x] = foreground ? 0xffff : 0x8000; + break; + + case DRM_FORMAT_RGBX5551: + case DRM_FORMAT_RGBA5551: + case DRM_FORMAT_BGRX5551: + case DRM_FORMAT_BGRA5551: + pix16[x] = foreground ? 0xffff : 0x0001; + break; + + case DRM_FORMAT_RGB565: + case DRM_FORMAT_BGR565: + pix16[x] = foreground ? 0xffff : 0x0000; + break; + + case DRM_FORMAT_RGB888: + case DRM_FORMAT_BGR888: + pix8[x * 3] = foreground ? 0xff : 0x00; + pix8[(x * 3) + 1] = pix8[x]; + pix8[(x * 3) + 2] = pix8[x]; + break; + + case DRM_FORMAT_XRGB8888: + case DRM_FORMAT_ARGB8888: + case DRM_FORMAT_XBGR8888: + case DRM_FORMAT_ABGR8888: + pix32[x] = foreground ? 0xffffffff : 0xff000000; + break; + + case DRM_FORMAT_RGBX8888: + case DRM_FORMAT_RGBA8888: + case DRM_FORMAT_BGRX8888: + case DRM_FORMAT_BGRA8888: + pix32[x] = foreground ? 0xffffffff : 0x000000ff; + break; + + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_ARGB2101010: + case DRM_FORMAT_XBGR2101010: + case DRM_FORMAT_ABGR2101010: + pix32[x] = foreground ? 0xffffffff : 0xc0000000; + break; + + case DRM_FORMAT_RGBX1010102: + case DRM_FORMAT_RGBA1010102: + case DRM_FORMAT_BGRX1010102: + case DRM_FORMAT_BGRA1010102: + pix32[x] = foreground ? 0xffffffff : 0x00000003; + break; + } +} +EXPORT_SYMBOL(drm_framebuffer_panic_draw_xy); diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h index 251d67e04c2d..694a5803ac3c 100644 --- a/drivers/gpu/drm/drm_internal.h +++ b/drivers/gpu/drm/drm_internal.h @@ -191,3 +191,7 @@ int drm_syncobj_signal_ioctl(struct drm_device *dev, void *data, void drm_framebuffer_print_info(struct drm_printer *p, unsigned int indent, const struct drm_framebuffer *fb); int drm_framebuffer_debugfs_init(struct drm_minor *minor); + +/* drm_panic.c */ +void drm_panic_init(struct dentry *debugfs_root); +void drm_panic_exit(struct dentry *debugfs_root); diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c new file mode 100644 index 000000000000..4bca7f0bc369 --- /dev/null +++ b/drivers/gpu/drm/drm_panic.c @@ -0,0 +1,363 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright 2018 Noralf Trønnes + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "drm_internal.h" + +/* + * The log lines in an ARM stack dump are 92 characters long + * and 120 is a nice multiple for HD and 4K. + */ +#define DRM_PANIC_COLUMN_WIDTH 120 + +struct drm_panic_ctx { + struct drm_framebuffer *fb; + unsigned int width; + unsigned int height; + void *vmap; + + const struct font_desc *font; + unsigned int col_width; + unsigned int bottom_y; + size_t max_line_length; + + unsigned int x; + unsigned int y; +}; + +static const struct font_desc *drm_panic_font8x8, *drm_panic_font8x16; + +static void drm_panic_draw_xy(struct drm_framebuffer *fb, void *vmap, + int x, int y, bool fg) +{ + if (fb->funcs->panic_draw_xy) + fb->funcs->panic_draw_xy(fb, vmap, x, y, fg); + else + drm_framebuffer_panic_draw_xy(fb, vmap, x, y, fg); +} + +static void drm_panic_render_char(struct drm_panic_ctx *ctx, + unsigned int offset, char c) +{ + unsigned int h, w, x, y; + u8 fontline; + + for (h = 0; h < ctx->font->height; h++) { + fontline = *(u8 *)(ctx->font->data + c * ctx->font->height + h); + + for (w = 0; w < ctx->font->width; w++) { + x = ctx->x + (offset * ctx->font->width) + w; + y = ctx->y + h; + drm_panic_draw_xy(ctx->fb, ctx->vmap, x, y, + fontline & BIT(7 - w)); + } + } +} + +static void drm_panic_render_line(struct drm_panic_ctx *ctx, + const char *line, size_t len) +{ + unsigned int i; + + for (i = 0; i < len; i++) + drm_panic_render_char(ctx, i, line[i]); + + /* Clear out the rest of the line */ + for (i = len; i < ctx->max_line_length; i++) + drm_panic_render_char(ctx, i, ' '); +} + +static bool drm_panic_newline(struct drm_panic_ctx *ctx) +{ + if (ctx->x == 0 && ctx->y == 0) + return false; + if (ctx->y == 0) { + ctx->x -= ctx->col_width; + ctx->y = ctx->bottom_y; + } else { + ctx->y -= ctx->font->height; + } + + return true; +} + +/* Render from bottom right most column */ +static bool drm_panic_render_lines(struct drm_panic_ctx *ctx, + const char *str, size_t len) +{ + size_t l, line_length; + const char *pos; + int i; + + while (len) { + pos = str + len - 1; + + if (*pos == '\n') { + len--; + if (!drm_panic_newline(ctx)) + return false; + continue; + } + + while (pos > str && *(pos - 1) != '\n') + pos--; + + line_length = len - (pos - str); + + if (!line_length || len < line_length) { + pr_err("%s: Bug! line_length=%zu len=%zu\n", + __func__, line_length, len); + return false; + } + + len -= line_length; + + for (i = DIV_ROUND_UP(line_length, ctx->max_line_length) - 1; i >= 0; i--) { + l = min(ctx->max_line_length, line_length - i * ctx->max_line_length); + drm_panic_render_line(ctx, pos + (i * ctx->max_line_length), l); + if (i && !drm_panic_newline(ctx)) + return false; + } + } + + return true; +} + +static void drm_panic_kmsg_render_screen(struct drm_plane *plane, + struct kmsg_dumper *dumper) +{ + struct drm_framebuffer *fb = plane->state->fb; + bool first_iteration = true; + struct drm_panic_ctx ctx; + static char text[1024]; + size_t len; + + ctx.vmap = fb->funcs->panic_vmap(fb); + + /* Print some info when testing */ + if (dumper->max_reason == KMSG_DUMP_OOPS) { + struct drm_format_name_buf format_name; + + pr_info("%s: [FB:%d] %ux%u format=%s vmap=%p\n", + __func__, fb->base.id, fb->width, fb->height, + drm_get_format_name(fb->format->format, &format_name), + ctx.vmap); + } + + if (!ctx.vmap) + return; + + ctx.fb = fb; + ctx.width = drm_rect_width(&plane->state->src) >> 16; + ctx.height = drm_rect_height(&plane->state->src) >> 16; + + /* + * TODO: + * Find which part of the fb that is visible. + * Width and height are zero on vc4 + */ + if (!ctx.width || !ctx.height) { + ctx.width = fb->width; + ctx.height = fb->height; + } + + /* Try to fit 50 lines */ + if (ctx.height < 50 * 16 && drm_panic_font8x8) + ctx.font = drm_panic_font8x8; + else + ctx.font = drm_panic_font8x16; + + ctx.col_width = DRM_PANIC_COLUMN_WIDTH * ctx.font->width; + ctx.bottom_y = ((ctx.height / ctx.font->height) - 1) * ctx.font->height; + + if (ctx.width < 2 * ctx.col_width) + ctx.max_line_length = ctx.width / ctx.font->width; + else + ctx.max_line_length = DRM_PANIC_COLUMN_WIDTH - 2; /* border=2 */ + + ctx.x = 0; + ctx.y = ctx.bottom_y; + if (ctx.width > ctx.col_width) + ctx.x = ((ctx.width / ctx.col_width) - 1) * ctx.col_width; + + pr_debug("%s: font=%s %ux%u max_line_length=%zu (%u,%u)\n", + __func__, ctx.font->name, ctx.width, ctx.height, + ctx.max_line_length, ctx.x, ctx.y); + + kmsg_dump_rewind(dumper); + + /* The latest messages are fetched first */ + while (kmsg_dump_get_buffer(dumper, false, text, sizeof(text), &len)) { + /* Strip off the very last newline so we start at the bottom */ + if (first_iteration) { + len--; + first_iteration = false; + } + + if (!drm_panic_render_lines(&ctx, text, len)) + break; + } + + if (fb->funcs->panic_vunmap) + fb->funcs->panic_vunmap(fb, vmap); +} + +static void drm_panic_try_dev(struct drm_device *dev, struct kmsg_dumper *dumper) +{ + struct drm_framebuffer *fb; + struct drm_plane *plane; + struct drm_crtc *crtc; + + if (!drm_core_check_feature(dev, DRIVER_ATOMIC)) + return; + + if (dumper->max_reason == KMSG_DUMP_OOPS) + pr_info("%s: %s on minor %d\n", __func__, dev->driver->name, + dev->primary->index); + + drm_for_each_crtc(crtc, dev) { + if (!ww_mutex_trylock(&crtc->mutex.mutex)) + continue; + + if (!crtc->enabled || !crtc->primary) + goto crtc_unlock; + + if (!crtc->state || !crtc->state->active) + goto crtc_unlock; + + plane = crtc->primary; + if (!ww_mutex_trylock(&plane->mutex.mutex)) + goto crtc_unlock; + + /* + * TODO: Should we check plane_state->visible? + * It is not set on vc4 + if (!plane->state || !plane->state->visible) + */ + if (!plane->state) + goto plane_unlock; + + fb = plane->state->fb; + if (!fb || !fb->funcs->panic_vmap) + goto plane_unlock; + + /* + * fbcon puts out panic messages so stay away to avoid jumbled + * output. If vc->vc_mode != KD_TEXT fbcon won't put out + * messages (see vt_console_print). + */ + if (dev->fb_helper && dev->fb_helper->fb == fb) + goto plane_unlock; + + drm_panic_kmsg_render_screen(plane, dumper); +plane_unlock: + ww_mutex_unlock(&plane->mutex.mutex); +crtc_unlock: + ww_mutex_unlock(&crtc->mutex.mutex); + } +} + +static int drm_panic_dev_iter(struct device *dev, void *data) +{ + struct drm_minor *minor = dev_get_drvdata(dev); + + if (minor && minor->type == DRM_MINOR_PRIMARY) + drm_panic_try_dev(minor->dev, data); + + return 0; +} + +static void drm_panic_kmsg_dump(struct kmsg_dumper *dumper, + enum kmsg_dump_reason reason) +{ + class_for_each_device(drm_class, NULL, dumper, drm_panic_dev_iter); +} + +static struct kmsg_dumper drm_panic_kmsg_dumper = { + .dump = drm_panic_kmsg_dump, + .max_reason = KMSG_DUMP_PANIC, +}; + +static ssize_t drm_panic_file_panic_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + unsigned long long val; + char buf[24]; + size_t size; + ssize_t ret; + + size = min(sizeof(buf) - 1, count); + if (copy_from_user(buf, user_buf, size)) + return -EFAULT; + + buf[size] = '\0'; + ret = kstrtoull(buf, 0, &val); + if (ret) + return ret; + + drm_panic_kmsg_dumper.max_reason = KMSG_DUMP_OOPS; + wmb(); + + /* Do a real test with: echo c > /proc/sysrq-trigger */ + + if (val == 0) { + pr_info("Test panic screen using kmsg_dump(OOPS)\n"); + kmsg_dump(KMSG_DUMP_OOPS); + } else if (val == 1) { + char *null_pointer = NULL; + + pr_info("Test panic screen using NULL pointer dereference\n"); + *null_pointer = 1; + } else { + return -EINVAL; + } + + return count; +} + +static const struct file_operations drm_panic_panic_ops = { + .write = drm_panic_file_panic_write, + .open = simple_open, + .llseek = default_llseek, +}; + +static struct dentry *drm_panic_d_panic; + +void __init drm_panic_init(struct dentry *debugfs_root) +{ + drm_panic_font8x8 = find_font("VGA8x8"); + drm_panic_font8x16 = find_font("VGA8x16"); + if (!drm_panic_font8x16) { + DRM_WARN("Couldn't find font, panic screen disabled\n"); + return; + } + + drm_panic_d_panic = debugfs_create_file("panic-test", 0200, + debugfs_root, NULL, + &drm_panic_panic_ops); + kmsg_dump_register(&drm_panic_kmsg_dumper); +} + +void drm_panic_exit(struct dentry *debugfs_root) +{ + kmsg_dump_unregister(&drm_panic_kmsg_dumper); + debugfs_remove(drm_panic_d_panic); +} diff --git a/include/drm/drm_framebuffer.h b/include/drm/drm_framebuffer.h index f0b34c977ec5..f3274798ecfe 100644 --- a/include/drm/drm_framebuffer.h +++ b/include/drm/drm_framebuffer.h @@ -94,6 +94,44 @@ struct drm_framebuffer_funcs { struct drm_file *file_priv, unsigned flags, unsigned color, struct drm_clip_rect *clips, unsigned num_clips); + + /** + * @panic_vmap: + * + * Optional callback for panic handling. + * + * For vmapping the selected framebuffer in a panic context. Must + * be super careful about locking (only trylocking allowed). + * + * RETURNS: + * + * NULL if it didn't work out, otherwise an opaque cookie which is + * passed to @panic_draw_xy. It can be anything: vmap area, structure + * with more details, just a few flags, ... + */ + void *(*panic_vmap)(struct drm_framebuffer *fb); + + /** + * @panic_vunmap: + * + * Optional callback for cleaning up after panic testing. + * + * Crtc and plane locks are released after this callback has run. + * vmap is the cookie returned by @panic_vmap. + */ + void (*panic_vunmap)(struct drm_framebuffer *fb, void *vmap); + + /** + * @panic_draw_xy: + * + * Optional callback for drawing pixels during panic. + * + * For drawing pixels onto a framebuffer prepared with @panic_vmap. + * vmap is the cookie returned by @panic_vmap. + * If it's not set, drm_framebuffer_panic_draw_xy() is used. + */ + void (*panic_draw_xy)(struct drm_framebuffer *fb, void *vmap, + int x, int y, bool foreground); }; /** @@ -293,4 +331,7 @@ int drm_framebuffer_plane_width(int width, int drm_framebuffer_plane_height(int height, const struct drm_framebuffer *fb, int plane); +void drm_framebuffer_panic_draw_xy(struct drm_framebuffer *fb, void *vmap, + int x, int y, bool foreground); + #endif From patchwork Mon Mar 11 17:42:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Noralf_Tr=C3=B8nnes?= X-Patchwork-Id: 10847903 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A79A56C2 for ; Mon, 11 Mar 2019 17:42:38 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 934AC28AF7 for ; Mon, 11 Mar 2019 17:42:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 875EF28DE1; Mon, 11 Mar 2019 17:42:38 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 3A06A28AF7 for ; Mon, 11 Mar 2019 17:42:38 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id C33E589C48; Mon, 11 Mar 2019 17:42:32 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from smtp.domeneshop.no (smtp.domeneshop.no [IPv6:2a01:5b40:0:3005::1]) by gabe.freedesktop.org (Postfix) with ESMTPS id 9314B89BF1; Mon, 11 Mar 2019 17:42:31 +0000 (UTC) Received: from 211.81-166-168.customer.lyse.net ([81.166.168.211]:44760 helo=localhost.localdomain) by smtp.domeneshop.no with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.84_2) (envelope-from ) id 1h3OwX-0007oa-Qe; Mon, 11 Mar 2019 18:42:29 +0100 From: =?utf-8?q?Noralf_Tr=C3=B8nnes?= To: dri-devel@lists.freedesktop.org Subject: [PATCH v2 2/3] drm/cma-helper: Add support for panic screen Date: Mon, 11 Mar 2019 18:42:17 +0100 Message-Id: <20190311174218.51899-3-noralf@tronnes.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190311174218.51899-1-noralf@tronnes.org> References: <20190311174218.51899-1-noralf@tronnes.org> MIME-Version: 1.0 X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=tronnes.org; s=ds201810; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From; bh=xfGPDaGLs2dMQy9308itA4ixzFj6hNKu6TKmzEbpKxw=; b=D9+qfVEwW7mniBMKa/WJFQKFBJamuYuXw0jjHbGixkbdx99kI5Ac/IxRYZePgfF1R7urnZzMdzq9r71Wfq3gLFvzBjlbqslaVTS61XT3RFg957cYugAdlCgiJjfQW6g5BhDMjUllECFWoooYcmEImXbrYoeSYokBo337OP4IPpwZJGIT0dYbSc1t5o4y2R+s9S0pmcf5o2RAQdrjx178IB3zQqr0hylEULm2jWEJRfTEvgYSF3AjR1yVaf1kH7exs+MffpmGf3DU2rpoLvOgE0hiHoeBJtMEL4ZMxmUd7i2LKwyXTPiXaHzS9UqnieMxVy8TmJTB8LvThXP+bcvraQ==; X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: daniel.vetter@ffwll.ch, intel-gfx@lists.freedesktop.org, darwish.07@gmail.com Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Add drm_fb_cma_fb_create() which creates a framebuffer that supports panic message output. vmap PRIME buffers on import to support panic on those as well. There is no atomic way to get a virtual address on a dma_buf. Signed-off-by: Noralf Trønnes --- drivers/gpu/drm/drm_fb_cma_helper.c | 43 ++++++++++++++++++++++++++++ drivers/gpu/drm/drm_gem_cma_helper.c | 3 ++ include/drm/drm_fb_cma_helper.h | 4 ++- 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c index 5f8074ffe7d9..9d62dadf5d14 100644 --- a/drivers/gpu/drm/drm_fb_cma_helper.c +++ b/drivers/gpu/drm/drm_fb_cma_helper.c @@ -56,6 +56,49 @@ struct drm_gem_cma_object *drm_fb_cma_get_gem_obj(struct drm_framebuffer *fb, } EXPORT_SYMBOL_GPL(drm_fb_cma_get_gem_obj); +static void *drm_fb_cma_fb_panic_vmap(struct drm_framebuffer *fb) +{ + return drm_fb_cma_get_gem_obj(fb, 0)->vaddr; +} + +static const struct drm_framebuffer_funcs drm_fb_cma_fb_funcs = { + .destroy = drm_gem_fb_destroy, + .create_handle = drm_gem_fb_create_handle, + .panic_vmap = drm_fb_cma_fb_panic_vmap, +}; + +/** + * drm_fb_cma_fb_create() - &drm_mode_config_funcs.fb_create callback function + * @dev: DRM device + * @file: DRM file that holds the GEM handle(s) backing the framebuffer + * @mode_cmd: Metadata from the userspace framebuffer creation request + * + * This function creates a new framebuffer object described by + * &drm_mode_fb_cmd2. This description includes handles for the buffer(s) + * backing the framebuffer. + * + * If your hardware has special alignment or pitch requirements these should be + * checked before calling this function. The function does buffer size + * validation. + * + * Drivers can use this as their &drm_mode_config_funcs.fb_create callback. + * The ADDFB2 IOCTL calls into this callback. + * + * The &drm_framebuffer_funcs.panic_vmap() callback is set supporting panic + * screen rendering. + * + * Returns: + * Pointer to a &drm_framebuffer on success or an error pointer on failure. + */ +struct drm_framebuffer * +drm_fb_cma_fb_create(struct drm_device *dev, struct drm_file *file, + const struct drm_mode_fb_cmd2 *mode_cmd) +{ + return drm_gem_fb_create_with_funcs(dev, file, mode_cmd, + &drm_fb_cma_fb_funcs); +} +EXPORT_SYMBOL_GPL(drm_fb_cma_fb_create); + /** * drm_fb_cma_get_gem_addr() - Get physical address for framebuffer, for pixel * formats where values are grouped in blocks this will get you the beginning of diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c index cc26625b4b33..9a4721b5e26d 100644 --- a/drivers/gpu/drm/drm_gem_cma_helper.c +++ b/drivers/gpu/drm/drm_gem_cma_helper.c @@ -507,6 +507,9 @@ drm_gem_cma_prime_import_sg_table(struct drm_device *dev, cma_obj->paddr = sg_dma_address(sgt->sgl); cma_obj->sgt = sgt; + /* Try to vmap the buffer to support panic rendering */ + cma_obj->vaddr = dma_buf_vmap(attach->dmabuf); + DRM_DEBUG_PRIME("dma_addr = %pad, size = %zu\n", &cma_obj->paddr, attach->dmabuf->size); return &cma_obj->base; diff --git a/include/drm/drm_fb_cma_helper.h b/include/drm/drm_fb_cma_helper.h index 4becb09975a4..6c9e5da17140 100644 --- a/include/drm/drm_fb_cma_helper.h +++ b/include/drm/drm_fb_cma_helper.h @@ -7,7 +7,9 @@ struct drm_plane_state; struct drm_gem_cma_object *drm_fb_cma_get_gem_obj(struct drm_framebuffer *fb, unsigned int plane); - +struct drm_framebuffer * +drm_fb_cma_fb_create(struct drm_device *dev, struct drm_file *file, + const struct drm_mode_fb_cmd2 *mode_cmd); dma_addr_t drm_fb_cma_get_gem_addr(struct drm_framebuffer *fb, struct drm_plane_state *state, unsigned int plane); From patchwork Mon Mar 11 17:42:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Noralf_Tr=C3=B8nnes?= X-Patchwork-Id: 10847905 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A03CE6C2 for ; Mon, 11 Mar 2019 17:42:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8C26E28AF7 for ; Mon, 11 Mar 2019 17:42:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8037728DE1; Mon, 11 Mar 2019 17:42:40 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 3CB6428AF7 for ; Mon, 11 Mar 2019 17:42:40 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 3909B89C55; Mon, 11 Mar 2019 17:42:33 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from smtp.domeneshop.no (smtp.domeneshop.no [IPv6:2a01:5b40:0:3005::1]) by gabe.freedesktop.org (Postfix) with ESMTPS id BFB6D89C37; Mon, 11 Mar 2019 17:42:31 +0000 (UTC) Received: from 211.81-166-168.customer.lyse.net ([81.166.168.211]:44760 helo=localhost.localdomain) by smtp.domeneshop.no with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.84_2) (envelope-from ) id 1h3OwY-0007oa-3A; Mon, 11 Mar 2019 18:42:30 +0100 From: =?utf-8?q?Noralf_Tr=C3=B8nnes?= To: dri-devel@lists.freedesktop.org Subject: [PATCH v2 3/3] drm/vc4: Support for panic screen Date: Mon, 11 Mar 2019 18:42:18 +0100 Message-Id: <20190311174218.51899-4-noralf@tronnes.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190311174218.51899-1-noralf@tronnes.org> References: <20190311174218.51899-1-noralf@tronnes.org> MIME-Version: 1.0 X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=tronnes.org; s=ds201810; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From; bh=o+YHLr337iN+JEpYv7was08QqYZY8ywp8H7LAHMggvE=; b=GydP0Cytw0qiZ98ZGfWWfo4rnAJvlm+mTq+92jt3ZDHfBthZMu2CG+PyOGruyLGw+Ya6tNwVJS73zZ8quCmJ4yZweCqb7a7PqZrPIweLl2HW+oP1+aH1nKfqXq2TJbkLvPzV2pTqmjJJywFfHVnuP5ZjUdziLYtxdUp2Zu+tf3G+Ga17l1ZlY7ACjbuPS7r8xC470L+/9C8J3EFjf4xuwCcijwb/YcBs9/l8f+wkWgb3lQ2kBP2aIfAE+RYlsfg0d/ILmuXszJEyiD2xgpPAXGR/sxSLvivrIqmfCmNFgFwnioxBng/1FeFJiSEQ6I85WuaSscTr1HUAzWdZeS68UQ==; X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: daniel.vetter@ffwll.ch, intel-gfx@lists.freedesktop.org, darwish.07@gmail.com Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Use drm_fb_cma_fb_create() to get panic screen support. Signed-off-by: Noralf Trønnes --- drivers/gpu/drm/Makefile | 2 +- drivers/gpu/drm/vc4/vc4_kms.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 1ac55c65eac0..3cc57b5c9aff 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -19,7 +19,7 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \ drm_plane.o drm_color_mgmt.o drm_print.o \ drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \ drm_syncobj.o drm_lease.o drm_writeback.o drm_client.o \ - drm_atomic_uapi.o + drm_atomic_uapi.o drm_panic.o drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o drm-$(CONFIG_DRM_VM) += drm_vm.o diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c index 5160cad25fce..fb9fde08c17f 100644 --- a/drivers/gpu/drm/vc4/vc4_kms.c +++ b/drivers/gpu/drm/vc4/vc4_kms.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -336,7 +337,7 @@ static struct drm_framebuffer *vc4_fb_create(struct drm_device *dev, mode_cmd = &mode_cmd_local; } - return drm_gem_fb_create(dev, file_priv, mode_cmd); + return drm_fb_cma_fb_create(dev, file_priv, mode_cmd); } /* Our CTM has some peculiar limitations: we can only enable it for one CRTC