From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 74189C33CB1 for ; Wed, 15 Jan 2020 10:28:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3D25E2467C for ; Wed, 15 Jan 2020 10:28:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729693AbgAOK2m convert rfc822-to-8bit (ORCPT ); Wed, 15 Jan 2020 05:28:42 -0500 Received: from mga02.intel.com ([134.134.136.20]:57005 "EHLO mga02.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729657AbgAOK2m (ORCPT ); Wed, 15 Jan 2020 05:28:42 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 15 Jan 2020 02:28:41 -0800 X-IronPort-AV: E=Sophos;i="5.70,322,1574150400"; d="scan'208";a="218081469" Received: from jnikula-mobl3.fi.intel.com (HELO localhost) ([10.237.66.161]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 15 Jan 2020 02:28:35 -0800 From: Jani Nikula To: Sean Paul , dri-devel@lists.freedesktop.org Cc: Sean Paul , Daniel Vetter , David Airlie , Joonas Lahtinen , Pekka Paalanen , Rob Clark , Steven Rostedt , Thomas Zimmermann , Ville =?utf-8?B?U3lyasOkbMOk?= , Maarten Lankhorst , Maxime Ripard , David Airlie , Daniel Vetter , Jonathan Corbet , linux-doc@vger.kernel.org Subject: Re: [PATCH v4] drm/trace: Buffer DRM logs in a ringbuffer accessible via debugfs In-Reply-To: <20200114172155.215463-1-sean@poorly.run> Organization: Intel Finland Oy - BIC 0357606-4 - Westendinkatu 7, 02160 Espoo References: <20200114172155.215463-1-sean@poorly.run> Date: Wed, 15 Jan 2020 12:28:31 +0200 Message-ID: <87v9pdj9o0.fsf@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8BIT Sender: linux-doc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-doc@vger.kernel.org On Tue, 14 Jan 2020, Sean Paul wrote: > From: Sean Paul > > This patch uses a ring_buffer to keep a "flight recorder" (name credit Weston) > of DRM logs for a specified set of debug categories. The user writes a > bitmask of debug categories to the "trace_mask" node and can read log > messages from the "trace" node. > > These nodes currently exist in debugfs under the dri directory. I > intended on exposing all of this through tracefs originally, but the > tracefs entry points are not exposed, so there's no way to create > tracefs files from drivers at the moment. I think it would be a > worthwhile endeavour, but one requiring more time and conversation to > ensure the drm traces fit somewhere sensible. > > Cc: Daniel Vetter > Cc: David Airlie > Cc: Jani Nikula > Cc: Joonas Lahtinen > Cc: Pekka Paalanen > Cc: Rob Clark > Cc: Steven Rostedt > Cc: Thomas Zimmermann > Cc: Ville Syrjälä > Signed-off-by: Sean Paul > Link: https://patchwork.freedesktop.org/patch/msgid/20191010204823.195540-1-sean@poorly.run #v1 > Link: https://lists.freedesktop.org/archives/dri-devel/2019-November/243230.html #v2 > Link: https://patchwork.freedesktop.org/patch/msgid/20191212203301.142437-1-sean@poorly.run #v3 > > Changes in v2: > - Went with a completely different approach: > https://lists.freedesktop.org/archives/dri-devel/2019-November/243230.html > > Changes in v3: > - Changed commit message to be a bit less RFC-y > - Make class_drm_category_log an actual trace class > > Changes in v4: > - Instead of [ab]using trace events and the system trace buffer, use our > own ringbuffer > --- > --- > Documentation/gpu/drm-uapi.rst | 9 + > drivers/gpu/drm/Kconfig | 1 + > drivers/gpu/drm/Makefile | 2 +- > drivers/gpu/drm/drm_drv.c | 3 + > drivers/gpu/drm/drm_print.c | 80 +++++-- > drivers/gpu/drm/drm_trace.c | 376 +++++++++++++++++++++++++++++++++ > include/drm/drm_print.h | 39 ++++ > 7 files changed, 487 insertions(+), 23 deletions(-) > create mode 100644 drivers/gpu/drm/drm_trace.c > > diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst > index 56fec6ed1ad8..089eb6fd3e94 100644 > --- a/Documentation/gpu/drm-uapi.rst > +++ b/Documentation/gpu/drm-uapi.rst > @@ -312,6 +312,15 @@ Debugfs Support > .. kernel-doc:: drivers/gpu/drm/drm_debugfs.c > :export: > > +DRM Tracing > +--------------- > + > +.. kernel-doc:: drivers/gpu/drm/drm_trace.c > + :doc: DRM Tracing > + > +.. kernel-doc:: drivers/gpu/drm/drm_trace.c > + :internal: > + > Sysfs Support > ============= > > diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig > index d0aa6cff2e02..9d8077e87afe 100644 > --- a/drivers/gpu/drm/Kconfig > +++ b/drivers/gpu/drm/Kconfig > @@ -14,6 +14,7 @@ menuconfig DRM > select I2C > select I2C_ALGOBIT > select DMA_SHARED_BUFFER > + select RING_BUFFER > select SYNC_FILE > help > Kernel-level support for the Direct Rendering Infrastructure (DRI) > diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile > index 6493088a0fdd..88b4674934e6 100644 > --- a/drivers/gpu/drm/Makefile > +++ b/drivers/gpu/drm/Makefile > @@ -29,7 +29,7 @@ drm-$(CONFIG_DRM_PANEL) += drm_panel.o > drm-$(CONFIG_OF) += drm_of.o > drm-$(CONFIG_AGP) += drm_agpsupport.o > drm-$(CONFIG_PCI) += drm_pci.o > -drm-$(CONFIG_DEBUG_FS) += drm_debugfs.o drm_debugfs_crc.o > +drm-$(CONFIG_DEBUG_FS) += drm_debugfs.o drm_debugfs_crc.o drm_trace.o > drm-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o > > drm_vram_helper-y := drm_gem_vram_helper.o \ > diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c > index 7c18a980cd4b..98260b9f8004 100644 > --- a/drivers/gpu/drm/drm_drv.c > +++ b/drivers/gpu/drm/drm_drv.c > @@ -1114,6 +1114,7 @@ static const struct file_operations drm_stub_fops = { > static void drm_core_exit(void) > { > unregister_chrdev(DRM_MAJOR, "drm"); > + drm_trace_cleanup(); > debugfs_remove(drm_debugfs_root); > drm_sysfs_destroy(); > idr_destroy(&drm_minors_idr); > @@ -1135,6 +1136,8 @@ static int __init drm_core_init(void) > > drm_debugfs_root = debugfs_create_dir("dri", NULL); > > + WARN_ON(drm_trace_init(drm_debugfs_root)); > + > ret = register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops); > if (ret < 0) > goto error; > diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c > index 111b932cf2a9..0ac1867937bf 100644 > --- a/drivers/gpu/drm/drm_print.c > +++ b/drivers/gpu/drm/drm_print.c > @@ -262,21 +262,37 @@ void drm_dev_dbg(const struct device *dev, enum drm_debug_category category, > struct va_format vaf; > va_list args; > > - if (!drm_debug_enabled(category)) > - return; > - > - va_start(args, format); > - vaf.fmt = format; > - vaf.va = &args; > - > - if (dev) > - dev_printk(KERN_DEBUG, dev, "[" DRM_NAME ":%ps] %pV", > - __builtin_return_address(0), &vaf); > - else > - printk(KERN_DEBUG "[" DRM_NAME ":%ps] %pV", > - __builtin_return_address(0), &vaf); > + if (drm_debug_enabled(category)) { > + va_start(args, format); > + vaf.fmt = format; > + vaf.va = &args; > + > + if (dev) > + dev_printk(KERN_DEBUG, dev, "[" DRM_NAME ":%ps] %pV", > + __builtin_return_address(0), &vaf); > + else > + printk(KERN_DEBUG "[" DRM_NAME ":%ps] %pV", > + __builtin_return_address(0), &vaf); > + > + va_end(args); > + } > > - va_end(args); > + if (drm_trace_enabled(category)) { > + va_start(args, format); > + vaf.fmt = format; > + vaf.va = &args; > + > + if (dev) > + drm_dev_trace_printf(dev, "[%ps] %pV", > + __builtin_return_address(0), > + &vaf); > + else > + drm_trace_printf("[%ps] %pV", > + __builtin_return_address(0), > + &vaf); > + > + va_end(args); > + } > } > EXPORT_SYMBOL(drm_dev_dbg); > > @@ -285,17 +301,28 @@ void __drm_dbg(enum drm_debug_category category, const char *format, ...) > struct va_format vaf; > va_list args; > > - if (!drm_debug_enabled(category)) > - return; > > - va_start(args, format); > - vaf.fmt = format; > - vaf.va = &args; > + if (drm_debug_enabled(category)) { > + va_start(args, format); > + vaf.fmt = format; > + vaf.va = &args; > > - printk(KERN_DEBUG "[" DRM_NAME ":%ps] %pV", > - __builtin_return_address(0), &vaf); > + printk(KERN_DEBUG "[" DRM_NAME ":%ps] %pV", > + __builtin_return_address(0), &vaf); > > - va_end(args); > + va_end(args); > + } > + > + if (drm_trace_enabled(category)) { > + va_start(args, format); > + vaf.fmt = format; > + vaf.va = &args; > + > + drm_trace_printf("[%ps] %pV", __builtin_return_address(0), > + &vaf); > + > + va_end(args); > + } > } > EXPORT_SYMBOL(__drm_dbg); > > @@ -312,6 +339,15 @@ void __drm_err(const char *format, ...) > __builtin_return_address(0), &vaf); > > va_end(args); > + > + va_start(args, format); > + vaf.fmt = format; > + vaf.va = &args; > + > + drm_trace_printf("[%ps] *ERROR* %pV", __builtin_return_address(0), > + &vaf); > + > + va_end(args); All the new non-debug struct drm_device based logging macros I added are just thin wrappers around the dev_ ones. The only benefit of __drm_err() is adding __builtin_return_address(0), which I think should not be relevant in an error level print; it should be non-ambiguous without it. IMO the function names are noise in non-debug logging. I'd consider removing the __drm_err() function altogether: #define DRM_ERROR(fmt, ...) \ - __drm_err(fmt, ##__VA_ARGS__) + _DRM_PRINTK(, ERR, "*ERROR* " fmt, ##__VA_ARGS__) What this means is that you wouldn't get the drm trace on error level logging. However, you already weren't getting it on any of the other levels either, nor were you getting it for DRM_DEV_ERROR() which uses drm_dev_printk(). BR, Jani. > } > EXPORT_SYMBOL(__drm_err); > > diff --git a/drivers/gpu/drm/drm_trace.c b/drivers/gpu/drm/drm_trace.c > new file mode 100644 > index 000000000000..0e7cf342d1d9 > --- /dev/null > +++ b/drivers/gpu/drm/drm_trace.c > @@ -0,0 +1,376 @@ > +/* SPDX-License-Identifier: MIT */ > +/* > + * Copyright (C) 2020 Google, Inc. > + * > + * Authors: > + * Sean Paul > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > + > +#define DRM_TRACE_MAX_LEN 256 > + > +/** > + * DOC: DRM Tracing > + * > + * *tl;dr* DRM tracing is a lightweight alternative to traditional DRM debug > + * logging. > + * > + * While DRM logging is quite convenient when reproducing a specific issue, it > + * doesn't help when something goes wrong unexpectedly. There are a couple > + * reasons why one does not want to enable DRM logging at all times: > + * > + * 1. We don't want to overwhelm syslog with drm spam, others have to use it too > + * 2. Console logging is slow > + * > + * DRM tracing aims to solve both these problems. > + * > + * To use DRM tracing, write a DRM debug category mask (this is a bitmask of > + * &drm_debug_category values) to the trace_mask file: > + * :: > + * > + * eg: echo 0x106 > /sys/kernel/debug/dri/trace_mask > + * > + * Once active, all log messages in the specified categories will be written to > + * the DRM trace. Once at capacity, the trace will overwrite old messages with > + * new ones. At any point, one can read the trace file to extract the previous N > + * DRM messages: > + * :: > + * > + * eg: cat /sys/kernel/debug/dri/trace > + * > + * Considerations > + * ************** > + * The contents of the DRM Trace are **not** considered UABI. **DO NOT depend on > + * the values of these traces in your userspace.** These traces are intended for > + * entertainment purposes only. The contents of these logs carry no warranty, > + * expressed or implied. > + * > + * New traces can not be added to the trace buffer while it is being read. If > + * this proves to be a problem, it can be mitigated by making a copy of the > + * buffer on start of read. Since DRM trace is not meant to be continuously > + * read, this loss is acceptable. > + * > + * The timestamps on logs are CPU-local. As such, log messages from different > + * CPUs may have slightly different ideas about time. > + * > + * Since each CPU has its own buffer, they won't all overflow at the same rate. > + * This means that messages from a particularly active CPU could be dropped > + * while an inactive CPU might have much older log messages. So don't be fooled > + * if you seem to be missing log messages when you see a switch between CPUs in > + * the logs. > + * > + * Internals > + * ********* > + * The DRM Tracing functions are intentionally unexported, they are not meant to > + * be used by drivers directly. The reasons are twofold: > + * > + * 1. All messages going to traces should also go to the console logs. This > + * ensures users can choose their logging medium without fear they're losing > + * messages. > + * 2. Writing directly to the trace skips category filtering, resulting in trace > + * spam. > + */ > + > +struct drm_trace_info { > + struct ring_buffer *buffer; > + struct dentry *debugfs; > + struct dentry *debugfs_mask; > + enum drm_debug_category category_mask; > +}; > +static struct drm_trace_info drm_trace; > + > +struct drm_trace_seq_iter { > + loff_t pos; > + cpumask_var_t cpu_mask; > + int cpu; > + u64 ts; > +}; > + > +static void *drm_trace_seq_start(struct seq_file *seq_file, loff_t *pos) > +{ > + struct drm_trace_info *info = seq_file->private; > + struct drm_trace_seq_iter *iter; > + int cpu; > + > + iter = kzalloc(sizeof(*iter), GFP_KERNEL); > + if (!iter) > + return NULL; > + > + if (!zalloc_cpumask_var(&iter->cpu_mask, GFP_KERNEL)) > + return NULL; > + > + /* > + * TODO: We could do better than stopping record for the entirety of the > + * read session. > + */ > + ring_buffer_record_off(info->buffer); > + > + /* > + * pos is only used as a means of determining whether we're at the start > + * of the virtual file, or continuing a read. We don't want to skip over > + * log lines since that's not a meaningful thing to do. > + */ > + iter->pos = *pos; > + > + iter->cpu = -1; > + > + /* > + * There's no way to extract the ring buffer's cpumask, so we'll try > + * every possible cpu and skip the invalid entries. > + */ > + for_each_possible_cpu(cpu) { > + if (ring_buffer_entries_cpu(info->buffer, cpu)) > + cpumask_set_cpu(cpu, iter->cpu_mask); > + } > + > + return iter; > +} > + > +static void *drm_trace_seq_next(struct seq_file *seq_file, void *data, > + loff_t *pos) > +{ > + struct drm_trace_info *info = seq_file->private; > + struct drm_trace_seq_iter *iter = data; > + int cpu; > + > + *pos = ++iter->pos; > + iter->cpu = -1; > + iter->ts = 0; > + > + /* Find the oldest event across our cpu_mask */ > + for_each_cpu(cpu, iter->cpu_mask) { > + u64 ts; > + > + if (!ring_buffer_peek(info->buffer, cpu, &ts, NULL)) { > + cpumask_clear_cpu(cpu, iter->cpu_mask); > + continue; > + } > + if (iter->cpu == -1 || ts < iter->ts) { > + iter->ts = ts; > + iter->cpu = cpu; > + } > + } > + if (iter->cpu == -1) > + return NULL; > + > + return iter; > +} > + > +static void drm_trace_seq_stop(struct seq_file *seq_file, void *data) > +{ > + struct drm_trace_info *info = seq_file->private; > + struct drm_trace_seq_iter *iter = data; > + > + free_cpumask_var(iter->cpu_mask); > + kfree(iter); > + > + ring_buffer_record_on(info->buffer); > +} > + > +static int drm_trace_seq_show(struct seq_file *seq_file, void *data) > +{ > + struct drm_trace_info *info = seq_file->private; > + struct drm_trace_seq_iter *iter = data; > + struct ring_buffer_event *event; > + u64 ts, usec; > + > + if (iter->pos == 0) { > + seq_printf(seq_file, "[%3s %12s] %s\n", "cpu", "timestamp", > + "message"); > + return 0; > + } else if (iter->cpu == -1) { > + /* This happens when we start a session with position > 0 */ > + return SEQ_SKIP; > + } > + > + event = ring_buffer_consume(info->buffer, iter->cpu, &ts, NULL); > + > + ts += 500; > + /* ts converts from ns->us */ > + do_div(ts, 1000); > + /* ts converts from us->s */ > + usec = do_div(ts, USEC_PER_SEC); > + > + seq_printf(seq_file, "[%3u %5llu.%06llu] %s", iter->cpu, ts, usec, > + (const char *)ring_buffer_event_data(event)); > + > + return 0; > +} > + > +static const struct seq_operations drm_trace_sops = { > + .start = drm_trace_seq_start, > + .next = drm_trace_seq_next, > + .stop = drm_trace_seq_stop, > + .show = drm_trace_seq_show > +}; > + > +static int drm_trace_fop_open(struct inode *inode, struct file *file) > +{ > + struct seq_file *seq_file; > + int ret; > + > + ret = seq_open(file, &drm_trace_sops); > + if (ret) > + return ret; > + > + seq_file = (struct seq_file *)file->private_data; > + seq_file->private = inode->i_private; /* this is drm_trace_info */ > + > + return 0; > +} > + > +static const struct file_operations drm_trace_fops = { > + .open = drm_trace_fop_open, > + .read = seq_read, > + .llseek = seq_lseek, > + .release = seq_release, > +}; > + > +/** > + * drm_trace_init - initializes tracing for drm core > + * @debugfs_root: the dentry for drm core's debugfs root > + * > + * This function is called on drm core init. It is responsible for initializing > + * drm tracing. This function must be matched by a call to drm_trace_cleanup(). > + * > + * Returns: 0 on success, -errno on failure > + */ > +int drm_trace_init(struct dentry *debugfs_root) > +{ > + struct drm_trace_info *info = &drm_trace; > + int ret; > + > + info->buffer = ring_buffer_alloc(PAGE_SIZE * 2, RB_FL_OVERWRITE); > + if (!info->buffer) > + return -ENOMEM; > + > + info->debugfs_mask = debugfs_create_u32("trace_mask", > + S_IFREG | S_IRUGO | S_IWUSR, > + debugfs_root, > + &info->category_mask); > + if (IS_ERR(info->debugfs)) { > + ret = PTR_ERR(info->debugfs); > + goto err_debugfs_mask; > + } > + > + info->debugfs = debugfs_create_file("trace", S_IFREG | S_IRUGO, > + debugfs_root, info, > + &drm_trace_fops); > + if (IS_ERR(info->debugfs)) { > + ret = PTR_ERR(info->debugfs); > + goto err_debugfs; > + } > + > + return 0; > + > +err_debugfs_mask: > + debugfs_remove(info->debugfs_mask); > +err_debugfs: > + ring_buffer_free(info->buffer); > + return ret; > +} > + > +/** > + * drm_trace_cleanup - cleans up tracing for drm core > + * > + * This function is responsible for cleaning up anything that was previously > + * initialized in drm_trace_init() > + */ > +void drm_trace_cleanup() > +{ > + struct drm_trace_info *info = &drm_trace; > + > + debugfs_remove(info->debugfs); > + debugfs_remove(info->debugfs_mask); > + ring_buffer_free(info->buffer); > + memset(info, 0, sizeof(*info)); > +} > + > +/** > + * drm_trace_enabled - check if a debug category has traces enabled > + * @category: the debug category to check > + * > + * Returns true if the given category has drm traces enabled, false otherwise. > + */ > +bool drm_trace_enabled(enum drm_debug_category category) > +{ > + return READ_ONCE(drm_trace.category_mask) & category; > +} > + > +static int drm_trace_write(const void *data, unsigned int len) > +{ > + struct drm_trace_info *info = &drm_trace; > + struct ring_buffer_event *event; > + void *event_body; > + > + event = ring_buffer_lock_reserve(info->buffer, len); > + if (!event) > + return -ENOMEM; > + > + event_body = ring_buffer_event_data(event); > + memcpy(event_body, data, len); > + > + return ring_buffer_unlock_commit(info->buffer, event); > +} > + > +/** > + * drm_trace_printf - adds an entry to the drm trace > + * @format: printf format of the message to add to the trace > + * > + * This function adds a new entry in the drm trace. > + */ > +void drm_trace_printf(const char *format, ...) > +{ > + char buf[DRM_TRACE_MAX_LEN]; > + va_list args; > + int ret; > + > + va_start(args, format); > + ret = vsnprintf(buf, sizeof(buf), format, args); > + va_end(args); > + > + if (ret < 0) > + return; > + else if (ret >= sizeof(buf)) > + ret = sizeof(buf) - 1; > + > + drm_trace_write(buf, ret + 1); > +} > + > +/** > + * drm_dev_trace_printf - adds an entry to the drm trace > + * @dev: pointer to device so we can print the name > + * @format: printf format of the message to add to the trace > + * > + * This function adds a new entry in the drm trace. > + */ > +void drm_dev_trace_printf(const struct device *dev, const char *format, ...) > +{ > + char buf[DRM_TRACE_MAX_LEN]; > + struct va_format vaf; > + va_list args; > + int ret; > + > + va_start(args, format); > + vaf.fmt = format; > + vaf.va = &args; > + ret = snprintf(buf, sizeof(buf), "%s %s: %pV", dev_driver_string(dev), > + dev_name(dev), &vaf); > + va_end(args); > + > + if (ret < 0) > + return; > + else if (ret >= sizeof(buf)) > + ret = sizeof(buf) - 1; > + > + drm_trace_write(buf, ret + 1); > +} > diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h > index 8f99d389792d..1f3dae7150f0 100644 > --- a/include/drm/drm_print.h > +++ b/include/drm/drm_print.h > @@ -320,6 +320,45 @@ static inline bool drm_debug_enabled(enum drm_debug_category category) > return unlikely(__drm_debug & category); > } > > +#ifdef CONFIG_DEBUG_FS > + > +int drm_trace_init(struct dentry *debugfs_root); > +bool drm_trace_enabled(enum drm_debug_category category); > +__printf(1, 2) > +void drm_trace_printf(const char *format, ...); > +__printf(2, 3) > +void drm_dev_trace_printf(const struct device *dev, const char *format, ...); > +void drm_trace_cleanup(void); > + > +#else > + > +static inline int drm_trace_init(struct dentry *debugfs_root) > +{ > + return 0; > +} > + > +static inline bool drm_trace_enabled(enum drm_debug_category category) > +{ > + return false; > +} > + > +__printf(1, 2) > +static inline void drm_trace_printf(const char *format, ...) > +{ > +} > + > +__printf(2, 3) > +static inline void drm_dev_trace_printf(const struct device *dev, > + const char *format, ...) > +{ > +} > + > +static inline void drm_trace_cleanup(void) > +{ > +} > + > +#endif > + > /* > * struct device based logging > * -- Jani Nikula, Intel Open Source Graphics Center From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8DA41C33CB3 for ; Wed, 15 Jan 2020 10:28:43 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6E6602075B for ; Wed, 15 Jan 2020 10:28:43 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6E6602075B Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id E46F66E8FE; Wed, 15 Jan 2020 10:28:42 +0000 (UTC) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by gabe.freedesktop.org (Postfix) with ESMTPS id DE1A86E8FE for ; Wed, 15 Jan 2020 10:28:41 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 15 Jan 2020 02:28:41 -0800 X-IronPort-AV: E=Sophos;i="5.70,322,1574150400"; d="scan'208";a="218081469" Received: from jnikula-mobl3.fi.intel.com (HELO localhost) ([10.237.66.161]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 15 Jan 2020 02:28:35 -0800 From: Jani Nikula To: Sean Paul , dri-devel@lists.freedesktop.org Subject: Re: [PATCH v4] drm/trace: Buffer DRM logs in a ringbuffer accessible via debugfs In-Reply-To: <20200114172155.215463-1-sean@poorly.run> Organization: Intel Finland Oy - BIC 0357606-4 - Westendinkatu 7, 02160 Espoo References: <20200114172155.215463-1-sean@poorly.run> Date: Wed, 15 Jan 2020 12:28:31 +0200 Message-ID: <87v9pdj9o0.fsf@intel.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Jonathan Corbet , David Airlie , Daniel Vetter , Steven Rostedt , linux-doc@vger.kernel.org, Sean Paul , Thomas Zimmermann Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" T24gVHVlLCAxNCBKYW4gMjAyMCwgU2VhbiBQYXVsIDxzZWFuQHBvb3JseS5ydW4+IHdyb3RlOgo+ IEZyb206IFNlYW4gUGF1bCA8c2VhbnBhdWxAY2hyb21pdW0ub3JnPgo+Cj4gVGhpcyBwYXRjaCB1 c2VzIGEgcmluZ19idWZmZXIgdG8ga2VlcCBhICJmbGlnaHQgcmVjb3JkZXIiIChuYW1lIGNyZWRp dCBXZXN0b24pCj4gb2YgRFJNIGxvZ3MgZm9yIGEgc3BlY2lmaWVkIHNldCBvZiBkZWJ1ZyBjYXRl Z29yaWVzLiBUaGUgdXNlciB3cml0ZXMgYQo+IGJpdG1hc2sgb2YgZGVidWcgY2F0ZWdvcmllcyB0 byB0aGUgInRyYWNlX21hc2siIG5vZGUgYW5kIGNhbiByZWFkIGxvZwo+IG1lc3NhZ2VzIGZyb20g dGhlICJ0cmFjZSIgbm9kZS4KPgo+IFRoZXNlIG5vZGVzIGN1cnJlbnRseSBleGlzdCBpbiBkZWJ1 Z2ZzIHVuZGVyIHRoZSBkcmkgZGlyZWN0b3J5LiBJCj4gaW50ZW5kZWQgb24gZXhwb3NpbmcgYWxs IG9mIHRoaXMgdGhyb3VnaCB0cmFjZWZzIG9yaWdpbmFsbHksIGJ1dCB0aGUKPiB0cmFjZWZzIGVu dHJ5IHBvaW50cyBhcmUgbm90IGV4cG9zZWQsIHNvIHRoZXJlJ3Mgbm8gd2F5IHRvIGNyZWF0ZQo+ IHRyYWNlZnMgZmlsZXMgZnJvbSBkcml2ZXJzIGF0IHRoZSBtb21lbnQuIEkgdGhpbmsgaXQgd291 bGQgYmUgYQo+IHdvcnRod2hpbGUgZW5kZWF2b3VyLCBidXQgb25lIHJlcXVpcmluZyBtb3JlIHRp bWUgYW5kIGNvbnZlcnNhdGlvbiB0bwo+IGVuc3VyZSB0aGUgZHJtIHRyYWNlcyBmaXQgc29tZXdo ZXJlIHNlbnNpYmxlLgo+Cj4gQ2M6IERhbmllbCBWZXR0ZXIgPGRhbmllbC52ZXR0ZXJAZmZ3bGwu Y2g+Cj4gQ2M6IERhdmlkIEFpcmxpZSA8YWlybGllZEBnbWFpbC5jb20+Cj4gQ2M6IEphbmkgTmlr dWxhIDxqYW5pLm5pa3VsYUBsaW51eC5pbnRlbC5jb20+Cj4gQ2M6IEpvb25hcyBMYWh0aW5lbiA8 am9vbmFzLmxhaHRpbmVuQGxpbnV4LmludGVsLmNvbT4KPiBDYzogUGVra2EgUGFhbGFuZW4gPHBw YWFsYW5lbkBnbWFpbC5jb20+Cj4gQ2M6IFJvYiBDbGFyayA8cm9iZGNsYXJrQGdtYWlsLmNvbT4K PiBDYzogU3RldmVuIFJvc3RlZHQgPHJvc3RlZHRAZ29vZG1pcy5vcmc+Cj4gQ2M6IFRob21hcyBa aW1tZXJtYW5uIDx0emltbWVybWFubkBzdXNlLmRlPgo+IENjOiBWaWxsZSBTeXJqw6Rsw6QgPHZp bGxlLnN5cmphbGFAbGludXguaW50ZWwuY29tPgo+IFNpZ25lZC1vZmYtYnk6IFNlYW4gUGF1bCA8 c2VhbnBhdWxAY2hyb21pdW0ub3JnPgo+IExpbms6IGh0dHBzOi8vcGF0Y2h3b3JrLmZyZWVkZXNr dG9wLm9yZy9wYXRjaC9tc2dpZC8yMDE5MTAxMDIwNDgyMy4xOTU1NDAtMS1zZWFuQHBvb3JseS5y dW4gI3YxCj4gTGluazogaHR0cHM6Ly9saXN0cy5mcmVlZGVza3RvcC5vcmcvYXJjaGl2ZXMvZHJp LWRldmVsLzIwMTktTm92ZW1iZXIvMjQzMjMwLmh0bWwgI3YyCj4gTGluazogaHR0cHM6Ly9wYXRj aHdvcmsuZnJlZWRlc2t0b3Aub3JnL3BhdGNoL21zZ2lkLzIwMTkxMjEyMjAzMzAxLjE0MjQzNy0x LXNlYW5AcG9vcmx5LnJ1biAjdjMKPgo+IENoYW5nZXMgaW4gdjI6Cj4gLSBXZW50IHdpdGggYSBj b21wbGV0ZWx5IGRpZmZlcmVudCBhcHByb2FjaDoKPiBodHRwczovL2xpc3RzLmZyZWVkZXNrdG9w Lm9yZy9hcmNoaXZlcy9kcmktZGV2ZWwvMjAxOS1Ob3ZlbWJlci8yNDMyMzAuaHRtbAo+Cj4gQ2hh bmdlcyBpbiB2MzoKPiAtIENoYW5nZWQgY29tbWl0IG1lc3NhZ2UgdG8gYmUgYSBiaXQgbGVzcyBS RkMteQo+IC0gTWFrZSBjbGFzc19kcm1fY2F0ZWdvcnlfbG9nIGFuIGFjdHVhbCB0cmFjZSBjbGFz cwo+Cj4gQ2hhbmdlcyBpbiB2NDoKPiAtIEluc3RlYWQgb2YgW2FiXXVzaW5nIHRyYWNlIGV2ZW50 cyBhbmQgdGhlIHN5c3RlbSB0cmFjZSBidWZmZXIsIHVzZSBvdXIKPiAgIG93biByaW5nYnVmZmVy Cj4gLS0tCj4gLS0tCj4gIERvY3VtZW50YXRpb24vZ3B1L2RybS11YXBpLnJzdCB8ICAgOSArCj4g IGRyaXZlcnMvZ3B1L2RybS9LY29uZmlnICAgICAgICB8ICAgMSArCj4gIGRyaXZlcnMvZ3B1L2Ry bS9NYWtlZmlsZSAgICAgICB8ICAgMiArLQo+ICBkcml2ZXJzL2dwdS9kcm0vZHJtX2Rydi5jICAg ICAgfCAgIDMgKwo+ICBkcml2ZXJzL2dwdS9kcm0vZHJtX3ByaW50LmMgICAgfCAgODAgKysrKyst LQo+ICBkcml2ZXJzL2dwdS9kcm0vZHJtX3RyYWNlLmMgICAgfCAzNzYgKysrKysrKysrKysrKysr KysrKysrKysrKysrKysrKysrCj4gIGluY2x1ZGUvZHJtL2RybV9wcmludC5oICAgICAgICB8ICAz OSArKysrCj4gIDcgZmlsZXMgY2hhbmdlZCwgNDg3IGluc2VydGlvbnMoKyksIDIzIGRlbGV0aW9u cygtKQo+ICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9ncHUvZHJtL2RybV90cmFjZS5jCj4K PiBkaWZmIC0tZ2l0IGEvRG9jdW1lbnRhdGlvbi9ncHUvZHJtLXVhcGkucnN0IGIvRG9jdW1lbnRh dGlvbi9ncHUvZHJtLXVhcGkucnN0Cj4gaW5kZXggNTZmZWM2ZWQxYWQ4Li4wODllYjZmZDNlOTQg MTAwNjQ0Cj4gLS0tIGEvRG9jdW1lbnRhdGlvbi9ncHUvZHJtLXVhcGkucnN0Cj4gKysrIGIvRG9j dW1lbnRhdGlvbi9ncHUvZHJtLXVhcGkucnN0Cj4gQEAgLTMxMiw2ICszMTIsMTUgQEAgRGVidWdm cyBTdXBwb3J0Cj4gIC4uIGtlcm5lbC1kb2M6OiBkcml2ZXJzL2dwdS9kcm0vZHJtX2RlYnVnZnMu Ywo+ICAgICA6ZXhwb3J0Ogo+ICAKPiArRFJNIFRyYWNpbmcKPiArLS0tLS0tLS0tLS0tLS0tCj4g Kwo+ICsuLiBrZXJuZWwtZG9jOjogZHJpdmVycy9ncHUvZHJtL2RybV90cmFjZS5jCj4gKyAgIDpk b2M6IERSTSBUcmFjaW5nCj4gKwo+ICsuLiBrZXJuZWwtZG9jOjogZHJpdmVycy9ncHUvZHJtL2Ry bV90cmFjZS5jCj4gKyAgIDppbnRlcm5hbDoKPiArCj4gIFN5c2ZzIFN1cHBvcnQKPiAgPT09PT09 PT09PT09PQo+ICAKPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL0tjb25maWcgYi9kcml2 ZXJzL2dwdS9kcm0vS2NvbmZpZwo+IGluZGV4IGQwYWE2Y2ZmMmUwMi4uOWQ4MDc3ZTg3YWZlIDEw MDY0NAo+IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS9LY29uZmlnCj4gKysrIGIvZHJpdmVycy9ncHUv ZHJtL0tjb25maWcKPiBAQCAtMTQsNiArMTQsNyBAQCBtZW51Y29uZmlnIERSTQo+ICAJc2VsZWN0 IEkyQwo+ICAJc2VsZWN0IEkyQ19BTEdPQklUCj4gIAlzZWxlY3QgRE1BX1NIQVJFRF9CVUZGRVIK PiArCXNlbGVjdCBSSU5HX0JVRkZFUgo+ICAJc2VsZWN0IFNZTkNfRklMRQo+ICAJaGVscAo+ICAJ ICBLZXJuZWwtbGV2ZWwgc3VwcG9ydCBmb3IgdGhlIERpcmVjdCBSZW5kZXJpbmcgSW5mcmFzdHJ1 Y3R1cmUgKERSSSkKPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL01ha2VmaWxlIGIvZHJp dmVycy9ncHUvZHJtL01ha2VmaWxlCj4gaW5kZXggNjQ5MzA4OGEwZmRkLi44OGI0Njc0OTM0ZTYg MTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL01ha2VmaWxlCj4gKysrIGIvZHJpdmVycy9n cHUvZHJtL01ha2VmaWxlCj4gQEAgLTI5LDcgKzI5LDcgQEAgZHJtLSQoQ09ORklHX0RSTV9QQU5F TCkgKz0gZHJtX3BhbmVsLm8KPiAgZHJtLSQoQ09ORklHX09GKSArPSBkcm1fb2Yubwo+ICBkcm0t JChDT05GSUdfQUdQKSArPSBkcm1fYWdwc3VwcG9ydC5vCj4gIGRybS0kKENPTkZJR19QQ0kpICs9 IGRybV9wY2kubwo+IC1kcm0tJChDT05GSUdfREVCVUdfRlMpICs9IGRybV9kZWJ1Z2ZzLm8gZHJt X2RlYnVnZnNfY3JjLm8KPiArZHJtLSQoQ09ORklHX0RFQlVHX0ZTKSArPSBkcm1fZGVidWdmcy5v IGRybV9kZWJ1Z2ZzX2NyYy5vIGRybV90cmFjZS5vCj4gIGRybS0kKENPTkZJR19EUk1fTE9BRF9F RElEX0ZJUk1XQVJFKSArPSBkcm1fZWRpZF9sb2FkLm8KPiAgCj4gIGRybV92cmFtX2hlbHBlci15 IDo9IGRybV9nZW1fdnJhbV9oZWxwZXIubyBcCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2Ry bS9kcm1fZHJ2LmMgYi9kcml2ZXJzL2dwdS9kcm0vZHJtX2Rydi5jCj4gaW5kZXggN2MxOGE5ODBj ZDRiLi45ODI2MGI5ZjgwMDQgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL2RybV9kcnYu Ywo+ICsrKyBiL2RyaXZlcnMvZ3B1L2RybS9kcm1fZHJ2LmMKPiBAQCAtMTExNCw2ICsxMTE0LDcg QEAgc3RhdGljIGNvbnN0IHN0cnVjdCBmaWxlX29wZXJhdGlvbnMgZHJtX3N0dWJfZm9wcyA9IHsK PiAgc3RhdGljIHZvaWQgZHJtX2NvcmVfZXhpdCh2b2lkKQo+ICB7Cj4gIAl1bnJlZ2lzdGVyX2No cmRldihEUk1fTUFKT1IsICJkcm0iKTsKPiArCWRybV90cmFjZV9jbGVhbnVwKCk7Cj4gIAlkZWJ1 Z2ZzX3JlbW92ZShkcm1fZGVidWdmc19yb290KTsKPiAgCWRybV9zeXNmc19kZXN0cm95KCk7Cj4g IAlpZHJfZGVzdHJveSgmZHJtX21pbm9yc19pZHIpOwo+IEBAIC0xMTM1LDYgKzExMzYsOCBAQCBz dGF0aWMgaW50IF9faW5pdCBkcm1fY29yZV9pbml0KHZvaWQpCj4gIAo+ICAJZHJtX2RlYnVnZnNf cm9vdCA9IGRlYnVnZnNfY3JlYXRlX2RpcigiZHJpIiwgTlVMTCk7Cj4gIAo+ICsJV0FSTl9PTihk cm1fdHJhY2VfaW5pdChkcm1fZGVidWdmc19yb290KSk7Cj4gKwo+ICAJcmV0ID0gcmVnaXN0ZXJf Y2hyZGV2KERSTV9NQUpPUiwgImRybSIsICZkcm1fc3R1Yl9mb3BzKTsKPiAgCWlmIChyZXQgPCAw KQo+ICAJCWdvdG8gZXJyb3I7Cj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9kcm1fcHJp bnQuYyBiL2RyaXZlcnMvZ3B1L2RybS9kcm1fcHJpbnQuYwo+IGluZGV4IDExMWI5MzJjZjJhOS4u MGFjMTg2NzkzN2JmIDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS9kcm1fcHJpbnQuYwo+ ICsrKyBiL2RyaXZlcnMvZ3B1L2RybS9kcm1fcHJpbnQuYwo+IEBAIC0yNjIsMjEgKzI2MiwzNyBA QCB2b2lkIGRybV9kZXZfZGJnKGNvbnN0IHN0cnVjdCBkZXZpY2UgKmRldiwgZW51bSBkcm1fZGVi dWdfY2F0ZWdvcnkgY2F0ZWdvcnksCj4gIAlzdHJ1Y3QgdmFfZm9ybWF0IHZhZjsKPiAgCXZhX2xp c3QgYXJnczsKPiAgCj4gLQlpZiAoIWRybV9kZWJ1Z19lbmFibGVkKGNhdGVnb3J5KSkKPiAtCQly ZXR1cm47Cj4gLQo+IC0JdmFfc3RhcnQoYXJncywgZm9ybWF0KTsKPiAtCXZhZi5mbXQgPSBmb3Jt YXQ7Cj4gLQl2YWYudmEgPSAmYXJnczsKPiAtCj4gLQlpZiAoZGV2KQo+IC0JCWRldl9wcmludGso S0VSTl9ERUJVRywgZGV2LCAiWyIgRFJNX05BTUUgIjolcHNdICVwViIsCj4gLQkJCSAgIF9fYnVp bHRpbl9yZXR1cm5fYWRkcmVzcygwKSwgJnZhZik7Cj4gLQllbHNlCj4gLQkJcHJpbnRrKEtFUk5f REVCVUcgIlsiIERSTV9OQU1FICI6JXBzXSAlcFYiLAo+IC0JCSAgICAgICBfX2J1aWx0aW5fcmV0 dXJuX2FkZHJlc3MoMCksICZ2YWYpOwo+ICsJaWYgKGRybV9kZWJ1Z19lbmFibGVkKGNhdGVnb3J5 KSkgewo+ICsJCXZhX3N0YXJ0KGFyZ3MsIGZvcm1hdCk7Cj4gKwkJdmFmLmZtdCA9IGZvcm1hdDsK PiArCQl2YWYudmEgPSAmYXJnczsKPiArCj4gKwkJaWYgKGRldikKPiArCQkJZGV2X3ByaW50ayhL RVJOX0RFQlVHLCBkZXYsICJbIiBEUk1fTkFNRSAiOiVwc10gJXBWIiwKPiArCQkJCSAgIF9fYnVp bHRpbl9yZXR1cm5fYWRkcmVzcygwKSwgJnZhZik7Cj4gKwkJZWxzZQo+ICsJCQlwcmludGsoS0VS Tl9ERUJVRyAiWyIgRFJNX05BTUUgIjolcHNdICVwViIsCj4gKwkJCSAgICAgICBfX2J1aWx0aW5f cmV0dXJuX2FkZHJlc3MoMCksICZ2YWYpOwo+ICsKPiArCQl2YV9lbmQoYXJncyk7Cj4gKwl9Cj4g IAo+IC0JdmFfZW5kKGFyZ3MpOwo+ICsJaWYgKGRybV90cmFjZV9lbmFibGVkKGNhdGVnb3J5KSkg ewo+ICsJCXZhX3N0YXJ0KGFyZ3MsIGZvcm1hdCk7Cj4gKwkJdmFmLmZtdCA9IGZvcm1hdDsKPiAr CQl2YWYudmEgPSAmYXJnczsKPiArCj4gKwkJaWYgKGRldikKPiArCQkJZHJtX2Rldl90cmFjZV9w cmludGYoZGV2LCAiWyVwc10gJXBWIiwKPiArCQkJCQkgICAgIF9fYnVpbHRpbl9yZXR1cm5fYWRk cmVzcygwKSwKPiArCQkJCQkgICAgICZ2YWYpOwo+ICsJCWVsc2UKPiArCQkJZHJtX3RyYWNlX3By aW50ZigiWyVwc10gJXBWIiwKPiArCQkJCQkgX19idWlsdGluX3JldHVybl9hZGRyZXNzKDApLAo+ ICsJCQkJCSAmdmFmKTsKPiArCj4gKwkJdmFfZW5kKGFyZ3MpOwo+ICsJfQo+ICB9Cj4gIEVYUE9S VF9TWU1CT0woZHJtX2Rldl9kYmcpOwo+ICAKPiBAQCAtMjg1LDE3ICszMDEsMjggQEAgdm9pZCBf X2RybV9kYmcoZW51bSBkcm1fZGVidWdfY2F0ZWdvcnkgY2F0ZWdvcnksIGNvbnN0IGNoYXIgKmZv cm1hdCwgLi4uKQo+ICAJc3RydWN0IHZhX2Zvcm1hdCB2YWY7Cj4gIAl2YV9saXN0IGFyZ3M7Cj4g IAo+IC0JaWYgKCFkcm1fZGVidWdfZW5hYmxlZChjYXRlZ29yeSkpCj4gLQkJcmV0dXJuOwo+ICAK PiAtCXZhX3N0YXJ0KGFyZ3MsIGZvcm1hdCk7Cj4gLQl2YWYuZm10ID0gZm9ybWF0Owo+IC0JdmFm LnZhID0gJmFyZ3M7Cj4gKwlpZiAoZHJtX2RlYnVnX2VuYWJsZWQoY2F0ZWdvcnkpKSB7Cj4gKwkJ dmFfc3RhcnQoYXJncywgZm9ybWF0KTsKPiArCQl2YWYuZm10ID0gZm9ybWF0Owo+ICsJCXZhZi52 YSA9ICZhcmdzOwo+ICAKPiAtCXByaW50ayhLRVJOX0RFQlVHICJbIiBEUk1fTkFNRSAiOiVwc10g JXBWIiwKPiAtCSAgICAgICBfX2J1aWx0aW5fcmV0dXJuX2FkZHJlc3MoMCksICZ2YWYpOwo+ICsJ CXByaW50ayhLRVJOX0RFQlVHICJbIiBEUk1fTkFNRSAiOiVwc10gJXBWIiwKPiArCQkgICAgICAg X19idWlsdGluX3JldHVybl9hZGRyZXNzKDApLCAmdmFmKTsKPiAgCj4gLQl2YV9lbmQoYXJncyk7 Cj4gKwkJdmFfZW5kKGFyZ3MpOwo+ICsJfQo+ICsKPiArCWlmIChkcm1fdHJhY2VfZW5hYmxlZChj YXRlZ29yeSkpIHsKPiArCQl2YV9zdGFydChhcmdzLCBmb3JtYXQpOwo+ICsJCXZhZi5mbXQgPSBm b3JtYXQ7Cj4gKwkJdmFmLnZhID0gJmFyZ3M7Cj4gKwo+ICsJCWRybV90cmFjZV9wcmludGYoIlsl cHNdICVwViIsIF9fYnVpbHRpbl9yZXR1cm5fYWRkcmVzcygwKSwKPiArCQkJCSAmdmFmKTsKPiAr Cj4gKwkJdmFfZW5kKGFyZ3MpOwo+ICsJfQo+ICB9Cj4gIEVYUE9SVF9TWU1CT0woX19kcm1fZGJn KTsKPiAgCj4gQEAgLTMxMiw2ICszMzksMTUgQEAgdm9pZCBfX2RybV9lcnIoY29uc3QgY2hhciAq Zm9ybWF0LCAuLi4pCj4gIAkgICAgICAgX19idWlsdGluX3JldHVybl9hZGRyZXNzKDApLCAmdmFm KTsKPiAgCj4gIAl2YV9lbmQoYXJncyk7Cj4gKwo+ICsJdmFfc3RhcnQoYXJncywgZm9ybWF0KTsK PiArCXZhZi5mbXQgPSBmb3JtYXQ7Cj4gKwl2YWYudmEgPSAmYXJnczsKPiArCj4gKwlkcm1fdHJh Y2VfcHJpbnRmKCJbJXBzXSAqRVJST1IqICVwViIsIF9fYnVpbHRpbl9yZXR1cm5fYWRkcmVzcygw KSwKPiArCQkJICZ2YWYpOwo+ICsKPiArCXZhX2VuZChhcmdzKTsKCkFsbCB0aGUgbmV3IG5vbi1k ZWJ1ZyBzdHJ1Y3QgZHJtX2RldmljZSBiYXNlZCBsb2dnaW5nIG1hY3JvcyBJIGFkZGVkIGFyZQpq dXN0IHRoaW4gd3JhcHBlcnMgYXJvdW5kIHRoZSBkZXZfPGxldmVsPiBvbmVzLiBUaGUgb25seSBi ZW5lZml0IG9mCl9fZHJtX2VycigpIGlzIGFkZGluZyBfX2J1aWx0aW5fcmV0dXJuX2FkZHJlc3Mo MCksIHdoaWNoIEkgdGhpbmsgc2hvdWxkCm5vdCBiZSByZWxldmFudCBpbiBhbiBlcnJvciBsZXZl bCBwcmludDsgaXQgc2hvdWxkIGJlIG5vbi1hbWJpZ3VvdXMKd2l0aG91dCBpdC4gSU1PIHRoZSBm dW5jdGlvbiBuYW1lcyBhcmUgbm9pc2UgaW4gbm9uLWRlYnVnIGxvZ2dpbmcuIEknZApjb25zaWRl ciByZW1vdmluZyB0aGUgX19kcm1fZXJyKCkgZnVuY3Rpb24gYWx0b2dldGhlcjoKCiAjZGVmaW5l IERSTV9FUlJPUihmbXQsIC4uLikJCQkJCQlcCi0JX19kcm1fZXJyKGZtdCwgIyNfX1ZBX0FSR1Nf XykKKwlfRFJNX1BSSU5USygsIEVSUiwgIipFUlJPUiogIiBmbXQsICMjX19WQV9BUkdTX18pCgpX aGF0IHRoaXMgbWVhbnMgaXMgdGhhdCB5b3Ugd291bGRuJ3QgZ2V0IHRoZSBkcm0gdHJhY2Ugb24g ZXJyb3IgbGV2ZWwKbG9nZ2luZy4gSG93ZXZlciwgeW91IGFscmVhZHkgd2VyZW4ndCBnZXR0aW5n IGl0IG9uIGFueSBvZiB0aGUgb3RoZXIKbGV2ZWxzIGVpdGhlciwgbm9yIHdlcmUgeW91IGdldHRp bmcgaXQgZm9yIERSTV9ERVZfRVJST1IoKSB3aGljaCB1c2VzCmRybV9kZXZfcHJpbnRrKCkuCgoK QlIsCkphbmkuCgoKPiAgfQo+ICBFWFBPUlRfU1lNQk9MKF9fZHJtX2Vycik7Cj4gIAo+IGRpZmYg LS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vZHJtX3RyYWNlLmMgYi9kcml2ZXJzL2dwdS9kcm0vZHJt X3RyYWNlLmMKPiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+IGluZGV4IDAwMDAwMDAwMDAwMC4uMGU3 Y2YzNDJkMWQ5Cj4gLS0tIC9kZXYvbnVsbAo+ICsrKyBiL2RyaXZlcnMvZ3B1L2RybS9kcm1fdHJh Y2UuYwo+IEBAIC0wLDAgKzEsMzc2IEBACj4gKy8qIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBN SVQgKi8KPiArLyoKPiArICogQ29weXJpZ2h0IChDKSAyMDIwIEdvb2dsZSwgSW5jLgo+ICsgKgo+ ICsgKiBBdXRob3JzOgo+ICsgKiBTZWFuIFBhdWwgPHNlYW5wYXVsQGNocm9taXVtLm9yZz4KPiAr ICovCj4gKwo+ICsjaW5jbHVkZSA8bGludXgvY3B1bWFzay5oPgo+ICsjaW5jbHVkZSA8bGludXgv ZGVidWdmcy5oPgo+ICsjaW5jbHVkZSA8bGludXgva2VybmVsLmg+Cj4gKyNpbmNsdWRlIDxsaW51 eC9yaW5nX2J1ZmZlci5oPgo+ICsjaW5jbHVkZSA8bGludXgvc2xhYi5oPgo+ICsjaW5jbHVkZSA8 bGludXgvc3RhdC5oPgo+ICsKPiArI2luY2x1ZGUgPGRybS9kcm1fZGV2aWNlLmg+Cj4gKyNpbmNs dWRlIDxkcm0vZHJtX3ByaW50Lmg+Cj4gKwo+ICsjZGVmaW5lIERSTV9UUkFDRV9NQVhfTEVOCTI1 Ngo+ICsKPiArLyoqCj4gKyAqIERPQzogRFJNIFRyYWNpbmcKPiArICoKPiArICogKnRsO2RyKiBE Uk0gdHJhY2luZyBpcyBhIGxpZ2h0d2VpZ2h0IGFsdGVybmF0aXZlIHRvIHRyYWRpdGlvbmFsIERS TSBkZWJ1Zwo+ICsgKiBsb2dnaW5nLgo+ICsgKgo+ICsgKiBXaGlsZSBEUk0gbG9nZ2luZyBpcyBx dWl0ZSBjb252ZW5pZW50IHdoZW4gcmVwcm9kdWNpbmcgYSBzcGVjaWZpYyBpc3N1ZSwgaXQKPiAr ICogZG9lc24ndCBoZWxwIHdoZW4gc29tZXRoaW5nIGdvZXMgd3JvbmcgdW5leHBlY3RlZGx5LiBU aGVyZSBhcmUgYSBjb3VwbGUKPiArICogcmVhc29ucyB3aHkgb25lIGRvZXMgbm90IHdhbnQgdG8g ZW5hYmxlIERSTSBsb2dnaW5nIGF0IGFsbCB0aW1lczoKPiArICoKPiArICogMS4gV2UgZG9uJ3Qg d2FudCB0byBvdmVyd2hlbG0gc3lzbG9nIHdpdGggZHJtIHNwYW0sIG90aGVycyBoYXZlIHRvIHVz ZSBpdCB0b28KPiArICogMi4gQ29uc29sZSBsb2dnaW5nIGlzIHNsb3cKPiArICoKPiArICogRFJN IHRyYWNpbmcgYWltcyB0byBzb2x2ZSBib3RoIHRoZXNlIHByb2JsZW1zLgo+ICsgKgo+ICsgKiBU byB1c2UgRFJNIHRyYWNpbmcsIHdyaXRlIGEgRFJNIGRlYnVnIGNhdGVnb3J5IG1hc2sgKHRoaXMg aXMgYSBiaXRtYXNrIG9mCj4gKyAqICZkcm1fZGVidWdfY2F0ZWdvcnkgdmFsdWVzKSB0byB0aGUg dHJhY2VfbWFzayBmaWxlOgo+ICsgKiA6Ogo+ICsgKgo+ICsgKiAgICBlZzogZWNobyAweDEwNiA+ IC9zeXMva2VybmVsL2RlYnVnL2RyaS90cmFjZV9tYXNrCj4gKyAqCj4gKyAqIE9uY2UgYWN0aXZl LCBhbGwgbG9nIG1lc3NhZ2VzIGluIHRoZSBzcGVjaWZpZWQgY2F0ZWdvcmllcyB3aWxsIGJlIHdy aXR0ZW4gdG8KPiArICogdGhlIERSTSB0cmFjZS4gT25jZSBhdCBjYXBhY2l0eSwgdGhlIHRyYWNl IHdpbGwgb3ZlcndyaXRlIG9sZCBtZXNzYWdlcyB3aXRoCj4gKyAqIG5ldyBvbmVzLiBBdCBhbnkg cG9pbnQsIG9uZSBjYW4gcmVhZCB0aGUgdHJhY2UgZmlsZSB0byBleHRyYWN0IHRoZSBwcmV2aW91 cyBOCj4gKyAqIERSTSBtZXNzYWdlczoKPiArICogOjoKPiArICoKPiArICogICAgZWc6IGNhdCAv c3lzL2tlcm5lbC9kZWJ1Zy9kcmkvdHJhY2UKPiArICoKPiArICogQ29uc2lkZXJhdGlvbnMKPiAr ICogKioqKioqKioqKioqKioKPiArICogVGhlIGNvbnRlbnRzIG9mIHRoZSBEUk0gVHJhY2UgYXJl ICoqbm90KiogY29uc2lkZXJlZCBVQUJJLiAqKkRPIE5PVCBkZXBlbmQgb24KPiArICogdGhlIHZh bHVlcyBvZiB0aGVzZSB0cmFjZXMgaW4geW91ciB1c2Vyc3BhY2UuKiogVGhlc2UgdHJhY2VzIGFy ZSBpbnRlbmRlZCBmb3IKPiArICogZW50ZXJ0YWlubWVudCBwdXJwb3NlcyBvbmx5LiBUaGUgY29u dGVudHMgb2YgdGhlc2UgbG9ncyBjYXJyeSBubyB3YXJyYW50eSwKPiArICogZXhwcmVzc2VkIG9y IGltcGxpZWQuCj4gKyAqCj4gKyAqIE5ldyB0cmFjZXMgY2FuIG5vdCBiZSBhZGRlZCB0byB0aGUg dHJhY2UgYnVmZmVyIHdoaWxlIGl0IGlzIGJlaW5nIHJlYWQuIElmCj4gKyAqIHRoaXMgcHJvdmVz IHRvIGJlIGEgcHJvYmxlbSwgaXQgY2FuIGJlIG1pdGlnYXRlZCBieSBtYWtpbmcgYSBjb3B5IG9m IHRoZQo+ICsgKiBidWZmZXIgb24gc3RhcnQgb2YgcmVhZC4gU2luY2UgRFJNIHRyYWNlIGlzIG5v dCBtZWFudCB0byBiZSBjb250aW51b3VzbHkKPiArICogcmVhZCwgdGhpcyBsb3NzIGlzIGFjY2Vw dGFibGUuCj4gKyAqCj4gKyAqIFRoZSB0aW1lc3RhbXBzIG9uIGxvZ3MgYXJlIENQVS1sb2NhbC4g QXMgc3VjaCwgbG9nIG1lc3NhZ2VzIGZyb20gZGlmZmVyZW50Cj4gKyAqIENQVXMgbWF5IGhhdmUg c2xpZ2h0bHkgZGlmZmVyZW50IGlkZWFzIGFib3V0IHRpbWUuCj4gKyAqCj4gKyAqIFNpbmNlIGVh Y2ggQ1BVIGhhcyBpdHMgb3duIGJ1ZmZlciwgdGhleSB3b24ndCBhbGwgb3ZlcmZsb3cgYXQgdGhl IHNhbWUgcmF0ZS4KPiArICogVGhpcyBtZWFucyB0aGF0IG1lc3NhZ2VzIGZyb20gYSBwYXJ0aWN1 bGFybHkgYWN0aXZlIENQVSBjb3VsZCBiZSBkcm9wcGVkCj4gKyAqIHdoaWxlIGFuIGluYWN0aXZl IENQVSBtaWdodCBoYXZlIG11Y2ggb2xkZXIgbG9nIG1lc3NhZ2VzLiBTbyBkb24ndCBiZSBmb29s ZWQKPiArICogaWYgeW91IHNlZW0gdG8gYmUgbWlzc2luZyBsb2cgbWVzc2FnZXMgd2hlbiB5b3Ug c2VlIGEgc3dpdGNoIGJldHdlZW4gQ1BVcyBpbgo+ICsgKiB0aGUgbG9ncy4KPiArICoKPiArICog SW50ZXJuYWxzCj4gKyAqICoqKioqKioqKgo+ICsgKiBUaGUgRFJNIFRyYWNpbmcgZnVuY3Rpb25z IGFyZSBpbnRlbnRpb25hbGx5IHVuZXhwb3J0ZWQsIHRoZXkgYXJlIG5vdCBtZWFudCB0bwo+ICsg KiBiZSB1c2VkIGJ5IGRyaXZlcnMgZGlyZWN0bHkuIFRoZSByZWFzb25zIGFyZSB0d29mb2xkOgo+ ICsgKgo+ICsgKiAxLiBBbGwgbWVzc2FnZXMgZ29pbmcgdG8gdHJhY2VzIHNob3VsZCBhbHNvIGdv IHRvIHRoZSBjb25zb2xlIGxvZ3MuIFRoaXMKPiArICogICAgZW5zdXJlcyB1c2VycyBjYW4gY2hv b3NlIHRoZWlyIGxvZ2dpbmcgbWVkaXVtIHdpdGhvdXQgZmVhciB0aGV5J3JlIGxvc2luZwo+ICsg KiAgICBtZXNzYWdlcy4KPiArICogMi4gV3JpdGluZyBkaXJlY3RseSB0byB0aGUgdHJhY2Ugc2tp cHMgY2F0ZWdvcnkgZmlsdGVyaW5nLCByZXN1bHRpbmcgaW4gdHJhY2UKPiArICogICAgc3BhbS4K PiArICovCj4gKwo+ICtzdHJ1Y3QgZHJtX3RyYWNlX2luZm8gewo+ICsJc3RydWN0IHJpbmdfYnVm ZmVyICpidWZmZXI7Cj4gKwlzdHJ1Y3QgZGVudHJ5ICpkZWJ1Z2ZzOwo+ICsJc3RydWN0IGRlbnRy eSAqZGVidWdmc19tYXNrOwo+ICsJZW51bSBkcm1fZGVidWdfY2F0ZWdvcnkgY2F0ZWdvcnlfbWFz azsKPiArfTsKPiArc3RhdGljIHN0cnVjdCBkcm1fdHJhY2VfaW5mbyBkcm1fdHJhY2U7Cj4gKwo+ ICtzdHJ1Y3QgZHJtX3RyYWNlX3NlcV9pdGVyIHsKPiArCWxvZmZfdCBwb3M7Cj4gKwljcHVtYXNr X3Zhcl90IGNwdV9tYXNrOwo+ICsJaW50IGNwdTsKPiArCXU2NCB0czsKPiArfTsKPiArCj4gK3N0 YXRpYyB2b2lkICpkcm1fdHJhY2Vfc2VxX3N0YXJ0KHN0cnVjdCBzZXFfZmlsZSAqc2VxX2ZpbGUs IGxvZmZfdCAqcG9zKQo+ICt7Cj4gKwlzdHJ1Y3QgZHJtX3RyYWNlX2luZm8gKmluZm8gPSBzZXFf ZmlsZS0+cHJpdmF0ZTsKPiArCXN0cnVjdCBkcm1fdHJhY2Vfc2VxX2l0ZXIgKml0ZXI7Cj4gKwlp bnQgY3B1Owo+ICsKPiArCWl0ZXIgPSBremFsbG9jKHNpemVvZigqaXRlciksIEdGUF9LRVJORUwp Owo+ICsJaWYgKCFpdGVyKQo+ICsJCXJldHVybiBOVUxMOwo+ICsKPiArCWlmICghemFsbG9jX2Nw dW1hc2tfdmFyKCZpdGVyLT5jcHVfbWFzaywgR0ZQX0tFUk5FTCkpCj4gKwkJcmV0dXJuIE5VTEw7 Cj4gKwo+ICsJLyoKPiArCSAqIFRPRE86IFdlIGNvdWxkIGRvIGJldHRlciB0aGFuIHN0b3BwaW5n IHJlY29yZCBmb3IgdGhlIGVudGlyZXR5IG9mIHRoZQo+ICsJICoJIHJlYWQgc2Vzc2lvbi4KPiAr CSAqLwo+ICsJcmluZ19idWZmZXJfcmVjb3JkX29mZihpbmZvLT5idWZmZXIpOwo+ICsKPiArCS8q Cj4gKwkgKiBwb3MgaXMgb25seSB1c2VkIGFzIGEgbWVhbnMgb2YgZGV0ZXJtaW5pbmcgd2hldGhl ciB3ZSdyZSBhdCB0aGUgc3RhcnQKPiArCSAqIG9mIHRoZSB2aXJ0dWFsIGZpbGUsIG9yIGNvbnRp bnVpbmcgYSByZWFkLiBXZSBkb24ndCB3YW50IHRvIHNraXAgb3Zlcgo+ICsJICogbG9nIGxpbmVz IHNpbmNlIHRoYXQncyBub3QgYSBtZWFuaW5nZnVsIHRoaW5nIHRvIGRvLgo+ICsJICovCj4gKwlp dGVyLT5wb3MgPSAqcG9zOwo+ICsKPiArCWl0ZXItPmNwdSA9IC0xOwo+ICsKPiArCS8qCj4gKwkg KiBUaGVyZSdzIG5vIHdheSB0byBleHRyYWN0IHRoZSByaW5nIGJ1ZmZlcidzIGNwdW1hc2ssIHNv IHdlJ2xsIHRyeQo+ICsJICogZXZlcnkgcG9zc2libGUgY3B1IGFuZCBza2lwIHRoZSBpbnZhbGlk IGVudHJpZXMuCj4gKwkgKi8KPiArCWZvcl9lYWNoX3Bvc3NpYmxlX2NwdShjcHUpIHsKPiArCQlp ZiAocmluZ19idWZmZXJfZW50cmllc19jcHUoaW5mby0+YnVmZmVyLCBjcHUpKQo+ICsJCQljcHVt YXNrX3NldF9jcHUoY3B1LCBpdGVyLT5jcHVfbWFzayk7Cj4gKwl9Cj4gKwo+ICsJcmV0dXJuIGl0 ZXI7Cj4gK30KPiArCj4gK3N0YXRpYyB2b2lkICpkcm1fdHJhY2Vfc2VxX25leHQoc3RydWN0IHNl cV9maWxlICpzZXFfZmlsZSwgdm9pZCAqZGF0YSwKPiArCQkJCWxvZmZfdCAqcG9zKQo+ICt7Cj4g KwlzdHJ1Y3QgZHJtX3RyYWNlX2luZm8gKmluZm8gPSBzZXFfZmlsZS0+cHJpdmF0ZTsKPiArCXN0 cnVjdCBkcm1fdHJhY2Vfc2VxX2l0ZXIgKml0ZXIgPSBkYXRhOwo+ICsJaW50IGNwdTsKPiArCj4g KwkqcG9zID0gKytpdGVyLT5wb3M7Cj4gKwlpdGVyLT5jcHUgPSAtMTsKPiArCWl0ZXItPnRzID0g MDsKPiArCj4gKwkvKiBGaW5kIHRoZSBvbGRlc3QgZXZlbnQgYWNyb3NzIG91ciBjcHVfbWFzayAq Lwo+ICsJZm9yX2VhY2hfY3B1KGNwdSwgaXRlci0+Y3B1X21hc2spIHsKPiArCQl1NjQgdHM7Cj4g Kwo+ICsJCWlmICghcmluZ19idWZmZXJfcGVlayhpbmZvLT5idWZmZXIsIGNwdSwgJnRzLCBOVUxM KSkgewo+ICsJCQljcHVtYXNrX2NsZWFyX2NwdShjcHUsIGl0ZXItPmNwdV9tYXNrKTsKPiArCQkJ Y29udGludWU7Cj4gKwkJfQo+ICsJCWlmIChpdGVyLT5jcHUgPT0gLTEgfHwgdHMgPCBpdGVyLT50 cykgewo+ICsJCQlpdGVyLT50cyA9IHRzOwo+ICsJCQlpdGVyLT5jcHUgPSBjcHU7Cj4gKwkJfQo+ ICsJfQo+ICsJaWYgKGl0ZXItPmNwdSA9PSAtMSkKPiArCQlyZXR1cm4gTlVMTDsKPiArCj4gKwly ZXR1cm4gaXRlcjsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgZHJtX3RyYWNlX3NlcV9zdG9wKHN0 cnVjdCBzZXFfZmlsZSAqc2VxX2ZpbGUsIHZvaWQgKmRhdGEpCj4gK3sKPiArCXN0cnVjdCBkcm1f dHJhY2VfaW5mbyAqaW5mbyA9IHNlcV9maWxlLT5wcml2YXRlOwo+ICsJc3RydWN0IGRybV90cmFj ZV9zZXFfaXRlciAqaXRlciA9IGRhdGE7Cj4gKwo+ICsJZnJlZV9jcHVtYXNrX3ZhcihpdGVyLT5j cHVfbWFzayk7Cj4gKwlrZnJlZShpdGVyKTsKPiArCj4gKwlyaW5nX2J1ZmZlcl9yZWNvcmRfb24o aW5mby0+YnVmZmVyKTsKPiArfQo+ICsKPiArc3RhdGljIGludCBkcm1fdHJhY2Vfc2VxX3Nob3co c3RydWN0IHNlcV9maWxlICpzZXFfZmlsZSwgdm9pZCAqZGF0YSkKPiArewo+ICsJc3RydWN0IGRy bV90cmFjZV9pbmZvICppbmZvID0gc2VxX2ZpbGUtPnByaXZhdGU7Cj4gKwlzdHJ1Y3QgZHJtX3Ry YWNlX3NlcV9pdGVyICppdGVyID0gZGF0YTsKPiArCXN0cnVjdCByaW5nX2J1ZmZlcl9ldmVudCAq ZXZlbnQ7Cj4gKwl1NjQgdHMsIHVzZWM7Cj4gKwo+ICsJaWYgKGl0ZXItPnBvcyA9PSAwKSB7Cj4g KwkJc2VxX3ByaW50ZihzZXFfZmlsZSwgIlslM3MgJTEyc10gJXNcbiIsICJjcHUiLCAidGltZXN0 YW1wIiwKPiArCQkJICAgIm1lc3NhZ2UiKTsKPiArCQlyZXR1cm4gMDsKPiArCX0gZWxzZSBpZiAo aXRlci0+Y3B1ID09IC0xKSB7Cj4gKwkJLyogVGhpcyBoYXBwZW5zIHdoZW4gd2Ugc3RhcnQgYSBz ZXNzaW9uIHdpdGggcG9zaXRpb24gPiAwICovCj4gKwkJcmV0dXJuIFNFUV9TS0lQOwo+ICsJfQo+ ICsKPiArCWV2ZW50ID0gcmluZ19idWZmZXJfY29uc3VtZShpbmZvLT5idWZmZXIsIGl0ZXItPmNw dSwgJnRzLCBOVUxMKTsKPiArCj4gKwl0cyArPSA1MDA7Cj4gKwkvKiB0cyBjb252ZXJ0cyBmcm9t IG5zLT51cyAqLwo+ICsJZG9fZGl2KHRzLCAxMDAwKTsKPiArCS8qIHRzIGNvbnZlcnRzIGZyb20g dXMtPnMgKi8KPiArCXVzZWMgPSBkb19kaXYodHMsIFVTRUNfUEVSX1NFQyk7Cj4gKwo+ICsJc2Vx X3ByaW50ZihzZXFfZmlsZSwgIlslM3UgJTVsbHUuJTA2bGx1XSAlcyIsIGl0ZXItPmNwdSwgdHMs IHVzZWMsCj4gKwkJICAgKGNvbnN0IGNoYXIgKilyaW5nX2J1ZmZlcl9ldmVudF9kYXRhKGV2ZW50 KSk7Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3Qgc2Vx X29wZXJhdGlvbnMgZHJtX3RyYWNlX3NvcHMgPSB7Cj4gKwkuc3RhcnQgPSBkcm1fdHJhY2Vfc2Vx X3N0YXJ0LAo+ICsJLm5leHQgPSBkcm1fdHJhY2Vfc2VxX25leHQsCj4gKwkuc3RvcCA9IGRybV90 cmFjZV9zZXFfc3RvcCwKPiArCS5zaG93ICA9IGRybV90cmFjZV9zZXFfc2hvdwo+ICt9Owo+ICsK PiArc3RhdGljIGludCBkcm1fdHJhY2VfZm9wX29wZW4oc3RydWN0IGlub2RlICppbm9kZSwgc3Ry dWN0IGZpbGUgKmZpbGUpCj4gK3sKPiArCXN0cnVjdCBzZXFfZmlsZSAqc2VxX2ZpbGU7Cj4gKwlp bnQgcmV0Owo+ICsKPiArCXJldCA9IHNlcV9vcGVuKGZpbGUsICZkcm1fdHJhY2Vfc29wcyk7Cj4g KwlpZiAocmV0KQo+ICsJCXJldHVybiByZXQ7Cj4gKwo+ICsJc2VxX2ZpbGUgPSAoc3RydWN0IHNl cV9maWxlICopZmlsZS0+cHJpdmF0ZV9kYXRhOwo+ICsJc2VxX2ZpbGUtPnByaXZhdGUgPSBpbm9k ZS0+aV9wcml2YXRlOyAvKiB0aGlzIGlzIGRybV90cmFjZV9pbmZvICovCj4gKwo+ICsJcmV0dXJu IDA7Cj4gK30KPiArCj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgZmlsZV9vcGVyYXRpb25zIGRybV90 cmFjZV9mb3BzID0gewo+ICsJLm9wZW4gPSBkcm1fdHJhY2VfZm9wX29wZW4sCj4gKwkucmVhZCA9 IHNlcV9yZWFkLAo+ICsJLmxsc2VlayA9IHNlcV9sc2VlaywKPiArCS5yZWxlYXNlID0gc2VxX3Jl bGVhc2UsCj4gK307Cj4gKwo+ICsvKioKPiArICogZHJtX3RyYWNlX2luaXQgLSBpbml0aWFsaXpl cyB0cmFjaW5nIGZvciBkcm0gY29yZQo+ICsgKiBAZGVidWdmc19yb290OiB0aGUgZGVudHJ5IGZv ciBkcm0gY29yZSdzIGRlYnVnZnMgcm9vdAo+ICsgKgo+ICsgKiBUaGlzIGZ1bmN0aW9uIGlzIGNh bGxlZCBvbiBkcm0gY29yZSBpbml0LiBJdCBpcyByZXNwb25zaWJsZSBmb3IgaW5pdGlhbGl6aW5n Cj4gKyAqIGRybSB0cmFjaW5nLiBUaGlzIGZ1bmN0aW9uIG11c3QgYmUgbWF0Y2hlZCBieSBhIGNh bGwgdG8gZHJtX3RyYWNlX2NsZWFudXAoKS4KPiArICoKPiArICogUmV0dXJuczogMCBvbiBzdWNj ZXNzLCAtZXJybm8gb24gZmFpbHVyZQo+ICsgKi8KPiAraW50IGRybV90cmFjZV9pbml0KHN0cnVj dCBkZW50cnkgKmRlYnVnZnNfcm9vdCkKPiArewo+ICsJc3RydWN0IGRybV90cmFjZV9pbmZvICpp bmZvID0gJmRybV90cmFjZTsKPiArCWludCByZXQ7Cj4gKwo+ICsJaW5mby0+YnVmZmVyID0gcmlu Z19idWZmZXJfYWxsb2MoUEFHRV9TSVpFICogMiwgUkJfRkxfT1ZFUldSSVRFKTsKPiArCWlmICgh aW5mby0+YnVmZmVyKQo+ICsJCXJldHVybiAtRU5PTUVNOwo+ICsKPiArCWluZm8tPmRlYnVnZnNf bWFzayA9IGRlYnVnZnNfY3JlYXRlX3UzMigidHJhY2VfbWFzayIsCj4gKwkJCQkJCVNfSUZSRUcg fCBTX0lSVUdPIHwgU19JV1VTUiwKPiArCQkJCQkJZGVidWdmc19yb290LAo+ICsJCQkJCQkmaW5m by0+Y2F0ZWdvcnlfbWFzayk7Cj4gKwlpZiAoSVNfRVJSKGluZm8tPmRlYnVnZnMpKSB7Cj4gKwkJ cmV0ID0gUFRSX0VSUihpbmZvLT5kZWJ1Z2ZzKTsKPiArCQlnb3RvIGVycl9kZWJ1Z2ZzX21hc2s7 Cj4gKwl9Cj4gKwo+ICsJaW5mby0+ZGVidWdmcyA9IGRlYnVnZnNfY3JlYXRlX2ZpbGUoInRyYWNl IiwgU19JRlJFRyB8IFNfSVJVR08sCj4gKwkJCQkJICAgIGRlYnVnZnNfcm9vdCwgaW5mbywKPiAr CQkJCQkgICAgJmRybV90cmFjZV9mb3BzKTsKPiArCWlmIChJU19FUlIoaW5mby0+ZGVidWdmcykp IHsKPiArCQlyZXQgPSBQVFJfRVJSKGluZm8tPmRlYnVnZnMpOwo+ICsJCWdvdG8gZXJyX2RlYnVn ZnM7Cj4gKwl9Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gKwo+ICtlcnJfZGVidWdmc19tYXNrOgo+ICsJ ZGVidWdmc19yZW1vdmUoaW5mby0+ZGVidWdmc19tYXNrKTsKPiArZXJyX2RlYnVnZnM6Cj4gKwly aW5nX2J1ZmZlcl9mcmVlKGluZm8tPmJ1ZmZlcik7Cj4gKwlyZXR1cm4gcmV0Owo+ICt9Cj4gKwo+ ICsvKioKPiArICogZHJtX3RyYWNlX2NsZWFudXAgLSBjbGVhbnMgdXAgdHJhY2luZyBmb3IgZHJt IGNvcmUKPiArICoKPiArICogVGhpcyBmdW5jdGlvbiBpcyByZXNwb25zaWJsZSBmb3IgY2xlYW5p bmcgdXAgYW55dGhpbmcgdGhhdCB3YXMgcHJldmlvdXNseQo+ICsgKiBpbml0aWFsaXplZCBpbiBk cm1fdHJhY2VfaW5pdCgpCj4gKyAqLwo+ICt2b2lkIGRybV90cmFjZV9jbGVhbnVwKCkKPiArewo+ ICsJc3RydWN0IGRybV90cmFjZV9pbmZvICppbmZvID0gJmRybV90cmFjZTsKPiArCj4gKwlkZWJ1 Z2ZzX3JlbW92ZShpbmZvLT5kZWJ1Z2ZzKTsKPiArCWRlYnVnZnNfcmVtb3ZlKGluZm8tPmRlYnVn ZnNfbWFzayk7Cj4gKwlyaW5nX2J1ZmZlcl9mcmVlKGluZm8tPmJ1ZmZlcik7Cj4gKwltZW1zZXQo aW5mbywgMCwgc2l6ZW9mKCppbmZvKSk7Cj4gK30KPiArCj4gKy8qKgo+ICsgKiBkcm1fdHJhY2Vf ZW5hYmxlZCAtIGNoZWNrIGlmIGEgZGVidWcgY2F0ZWdvcnkgaGFzIHRyYWNlcyBlbmFibGVkCj4g KyAqIEBjYXRlZ29yeTogdGhlIGRlYnVnIGNhdGVnb3J5IHRvIGNoZWNrCj4gKyAqCj4gKyAqIFJl dHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gY2F0ZWdvcnkgaGFzIGRybSB0cmFjZXMgZW5hYmxlZCwg ZmFsc2Ugb3RoZXJ3aXNlLgo+ICsgKi8KPiArYm9vbCBkcm1fdHJhY2VfZW5hYmxlZChlbnVtIGRy bV9kZWJ1Z19jYXRlZ29yeSBjYXRlZ29yeSkKPiArewo+ICsJcmV0dXJuIFJFQURfT05DRShkcm1f dHJhY2UuY2F0ZWdvcnlfbWFzaykgJiBjYXRlZ29yeTsKPiArfQo+ICsKPiArc3RhdGljIGludCBk cm1fdHJhY2Vfd3JpdGUoY29uc3Qgdm9pZCAqZGF0YSwgdW5zaWduZWQgaW50IGxlbikKPiArewo+ ICsJc3RydWN0IGRybV90cmFjZV9pbmZvICppbmZvID0gJmRybV90cmFjZTsKPiArCXN0cnVjdCBy aW5nX2J1ZmZlcl9ldmVudCAqZXZlbnQ7Cj4gKwl2b2lkICpldmVudF9ib2R5Owo+ICsKPiArCWV2 ZW50ID0gcmluZ19idWZmZXJfbG9ja19yZXNlcnZlKGluZm8tPmJ1ZmZlciwgbGVuKTsKPiArCWlm ICghZXZlbnQpCj4gKwkJcmV0dXJuIC1FTk9NRU07Cj4gKwo+ICsJZXZlbnRfYm9keSA9IHJpbmdf YnVmZmVyX2V2ZW50X2RhdGEoZXZlbnQpOwo+ICsJbWVtY3B5KGV2ZW50X2JvZHksIGRhdGEsIGxl bik7Cj4gKwo+ICsJcmV0dXJuIHJpbmdfYnVmZmVyX3VubG9ja19jb21taXQoaW5mby0+YnVmZmVy LCBldmVudCk7Cj4gK30KPiArCj4gKy8qKgo+ICsgKiBkcm1fdHJhY2VfcHJpbnRmIC0gYWRkcyBh biBlbnRyeSB0byB0aGUgZHJtIHRyYWNlCj4gKyAqIEBmb3JtYXQ6IHByaW50ZiBmb3JtYXQgb2Yg dGhlIG1lc3NhZ2UgdG8gYWRkIHRvIHRoZSB0cmFjZQo+ICsgKgo+ICsgKiBUaGlzIGZ1bmN0aW9u IGFkZHMgYSBuZXcgZW50cnkgaW4gdGhlIGRybSB0cmFjZS4KPiArICovCj4gK3ZvaWQgZHJtX3Ry YWNlX3ByaW50Zihjb25zdCBjaGFyICpmb3JtYXQsIC4uLikKPiArewo+ICsJY2hhciBidWZbRFJN X1RSQUNFX01BWF9MRU5dOwo+ICsJdmFfbGlzdCBhcmdzOwo+ICsJaW50IHJldDsKPiArCj4gKwl2 YV9zdGFydChhcmdzLCBmb3JtYXQpOwo+ICsJcmV0ID0gdnNucHJpbnRmKGJ1Ziwgc2l6ZW9mKGJ1 ZiksIGZvcm1hdCwgYXJncyk7Cj4gKwl2YV9lbmQoYXJncyk7Cj4gKwo+ICsJaWYgKHJldCA8IDAp Cj4gKwkJcmV0dXJuOwo+ICsJZWxzZSBpZiAocmV0ID49IHNpemVvZihidWYpKQo+ICsJCXJldCA9 IHNpemVvZihidWYpIC0gMTsKPiArCj4gKwlkcm1fdHJhY2Vfd3JpdGUoYnVmLCByZXQgKyAxKTsK PiArfQo+ICsKPiArLyoqCj4gKyAqIGRybV9kZXZfdHJhY2VfcHJpbnRmIC0gYWRkcyBhbiBlbnRy eSB0byB0aGUgZHJtIHRyYWNlCj4gKyAqIEBkZXY6IHBvaW50ZXIgdG8gZGV2aWNlIHNvIHdlIGNh biBwcmludCB0aGUgbmFtZQo+ICsgKiBAZm9ybWF0OiBwcmludGYgZm9ybWF0IG9mIHRoZSBtZXNz YWdlIHRvIGFkZCB0byB0aGUgdHJhY2UKPiArICoKPiArICogVGhpcyBmdW5jdGlvbiBhZGRzIGEg bmV3IGVudHJ5IGluIHRoZSBkcm0gdHJhY2UuCj4gKyAqLwo+ICt2b2lkIGRybV9kZXZfdHJhY2Vf cHJpbnRmKGNvbnN0IHN0cnVjdCBkZXZpY2UgKmRldiwgY29uc3QgY2hhciAqZm9ybWF0LCAuLi4p Cj4gK3sKPiArCWNoYXIgYnVmW0RSTV9UUkFDRV9NQVhfTEVOXTsKPiArCXN0cnVjdCB2YV9mb3Jt YXQgdmFmOwo+ICsJdmFfbGlzdCBhcmdzOwo+ICsJaW50IHJldDsKPiArCj4gKwl2YV9zdGFydChh cmdzLCBmb3JtYXQpOwo+ICsJdmFmLmZtdCA9IGZvcm1hdDsKPiArCXZhZi52YSA9ICZhcmdzOwo+ ICsJcmV0ID0gc25wcmludGYoYnVmLCBzaXplb2YoYnVmKSwgIiVzICVzOiAlcFYiLCBkZXZfZHJp dmVyX3N0cmluZyhkZXYpLAo+ICsJCSAgICAgICBkZXZfbmFtZShkZXYpLCAmdmFmKTsKPiArCXZh X2VuZChhcmdzKTsKPiArCj4gKwlpZiAocmV0IDwgMCkKPiArCQlyZXR1cm47Cj4gKwllbHNlIGlm IChyZXQgPj0gc2l6ZW9mKGJ1ZikpCj4gKwkJcmV0ID0gc2l6ZW9mKGJ1ZikgLSAxOwo+ICsKPiAr CWRybV90cmFjZV93cml0ZShidWYsIHJldCArIDEpOwo+ICt9Cj4gZGlmZiAtLWdpdCBhL2luY2x1 ZGUvZHJtL2RybV9wcmludC5oIGIvaW5jbHVkZS9kcm0vZHJtX3ByaW50LmgKPiBpbmRleCA4Zjk5 ZDM4OTc5MmQuLjFmM2RhZTcxNTBmMCAxMDA2NDQKPiAtLS0gYS9pbmNsdWRlL2RybS9kcm1fcHJp bnQuaAo+ICsrKyBiL2luY2x1ZGUvZHJtL2RybV9wcmludC5oCj4gQEAgLTMyMCw2ICszMjAsNDUg QEAgc3RhdGljIGlubGluZSBib29sIGRybV9kZWJ1Z19lbmFibGVkKGVudW0gZHJtX2RlYnVnX2Nh dGVnb3J5IGNhdGVnb3J5KQo+ICAJcmV0dXJuIHVubGlrZWx5KF9fZHJtX2RlYnVnICYgY2F0ZWdv cnkpOwo+ICB9Cj4gIAo+ICsjaWZkZWYgQ09ORklHX0RFQlVHX0ZTCj4gKwo+ICtpbnQgZHJtX3Ry YWNlX2luaXQoc3RydWN0IGRlbnRyeSAqZGVidWdmc19yb290KTsKPiArYm9vbCBkcm1fdHJhY2Vf ZW5hYmxlZChlbnVtIGRybV9kZWJ1Z19jYXRlZ29yeSBjYXRlZ29yeSk7Cj4gK19fcHJpbnRmKDEs IDIpCj4gK3ZvaWQgZHJtX3RyYWNlX3ByaW50Zihjb25zdCBjaGFyICpmb3JtYXQsIC4uLik7Cj4g K19fcHJpbnRmKDIsIDMpCj4gK3ZvaWQgZHJtX2Rldl90cmFjZV9wcmludGYoY29uc3Qgc3RydWN0 IGRldmljZSAqZGV2LCBjb25zdCBjaGFyICpmb3JtYXQsIC4uLik7Cj4gK3ZvaWQgZHJtX3RyYWNl X2NsZWFudXAodm9pZCk7Cj4gKwo+ICsjZWxzZQo+ICsKPiArc3RhdGljIGlubGluZSBpbnQgZHJt X3RyYWNlX2luaXQoc3RydWN0IGRlbnRyeSAqZGVidWdmc19yb290KQo+ICt7Cj4gKwlyZXR1cm4g MDsKPiArfQo+ICsKPiArc3RhdGljIGlubGluZSBib29sIGRybV90cmFjZV9lbmFibGVkKGVudW0g ZHJtX2RlYnVnX2NhdGVnb3J5IGNhdGVnb3J5KQo+ICt7Cj4gKwlyZXR1cm4gZmFsc2U7Cj4gK30K PiArCj4gK19fcHJpbnRmKDEsIDIpCj4gK3N0YXRpYyBpbmxpbmUgdm9pZCBkcm1fdHJhY2VfcHJp bnRmKGNvbnN0IGNoYXIgKmZvcm1hdCwgLi4uKQo+ICt7Cj4gK30KPiArCj4gK19fcHJpbnRmKDIs IDMpCj4gK3N0YXRpYyBpbmxpbmUgdm9pZCBkcm1fZGV2X3RyYWNlX3ByaW50Zihjb25zdCBzdHJ1 Y3QgZGV2aWNlICpkZXYsCj4gKwkJCQkJY29uc3QgY2hhciAqZm9ybWF0LCAuLi4pCj4gK3sKPiAr fQo+ICsKPiArc3RhdGljIGlubGluZSB2b2lkIGRybV90cmFjZV9jbGVhbnVwKHZvaWQpCj4gK3sK PiArfQo+ICsKPiArI2VuZGlmCj4gKwo+ICAvKgo+ICAgKiBzdHJ1Y3QgZGV2aWNlIGJhc2VkIGxv Z2dpbmcKPiAgICoKCi0tIApKYW5pIE5pa3VsYSwgSW50ZWwgT3BlbiBTb3VyY2UgR3JhcGhpY3Mg Q2VudGVyCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmRy aS1kZXZlbCBtYWlsaW5nIGxpc3QKZHJpLWRldmVsQGxpc3RzLmZyZWVkZXNrdG9wLm9yZwpodHRw czovL2xpc3RzLmZyZWVkZXNrdG9wLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2RyaS1kZXZlbAo=