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=-1.4 required=3.0 tests=DATE_IN_PAST_03_06, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_PASS,URIBL_BLOCKED,USER_AGENT_MUTT 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 90C65C43381 for ; Wed, 27 Mar 2019 18:26:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5938F20449 for ; Wed, 27 Mar 2019 18:26:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1553711179; bh=tp4bs9pLFhnpsVuH8B58KoxTwoBEXKPx9L8+v175Nxo=; h=Date:From:To:Cc:Subject:References:In-Reply-To:List-ID:From; b=uzocFPlTIaUyAjuvs55+Mrhwa+oqbVr9xlKOxivP3KPHEQ576ZNNwkECKDP9D0v6T hNple5eceiDYvSac523GN8nlt7Bfx9yseSEhj1367f2H+vBeTYfxmWYqvPJ/emQMFe 3Cq6AIDplJdONKkdd+5JBy7+DqeI8tiQNvA7B6MA= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2404038AbfC0S0S (ORCPT ); Wed, 27 Mar 2019 14:26:18 -0400 Received: from mail.kernel.org ([198.145.29.99]:45454 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2391222AbfC0SZ7 (ORCPT ); Wed, 27 Mar 2019 14:25:59 -0400 Received: from localhost (unknown [88.128.80.233]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 480EC21738; Wed, 27 Mar 2019 18:25:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1553711158; bh=tp4bs9pLFhnpsVuH8B58KoxTwoBEXKPx9L8+v175Nxo=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=ddNzBhXOgZ+J4nZzPv798abe0MurYL7AP56toJIFfkmMnoXu09+CmzDL5Jl1BAkOf lJggKBHVMTPfWYBbX/LwpEQ6ODVw+pFApywDw8Ivzeo9llzv9VG0ZARHJVY51b28Wm h413CnkM9agaiKYkrwqzmkdyhetyEMfl+2HmZmH4= Date: Wed, 27 Mar 2019 23:53:54 +0900 From: Greg KH To: John Stultz Cc: lkml , "Andrew F. Davis" , Laura Abbott , Benjamin Gaignard , Sumit Semwal , Liam Mark , Brian Starkey , Chenbo Feng , Alistair Strachan , dri-devel@lists.freedesktop.org Subject: Re: [RFC][PATCH 1/5 v2] dma-buf: Add dma-buf heaps framework Message-ID: <20190327145354.GA4514@kroah.com> References: <1551819273-640-1-git-send-email-john.stultz@linaro.org> <1551819273-640-2-git-send-email-john.stultz@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1551819273-640-2-git-send-email-john.stultz@linaro.org> User-Agent: Mutt/1.11.4 (2019-03-13) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, Mar 05, 2019 at 12:54:29PM -0800, John Stultz wrote: > From: "Andrew F. Davis" > > This framework allows a unified userspace interface for dma-buf > exporters, allowing userland to allocate specific types of > memory for use in dma-buf sharing. > > Each heap is given its own device node, which a user can > allocate a dma-buf fd from using the DMA_HEAP_IOC_ALLOC. > > This code is an evoluiton of the Android ION implementation, > and a big thanks is due to its authors/maintainers over time > for their effort: > Rebecca Schultz Zavin, Colin Cross, Benjamin Gaignard, > Laura Abbott, and many other contributors! Comments just on the user/kernel api and how it interacts with the driver model. Not on the "real" functionality of this code :) > +#define DEVNAME "dma_heap" > + > +#define NUM_HEAP_MINORS 128 Why a max? > +static DEFINE_IDR(dma_heap_idr); > +static DEFINE_MUTEX(minor_lock); /* Protect idr accesses */ Move to use xarray now so that Matthew doesn't have to send patches converting this code later :) It also allows you to drop the mutex. > + > +dev_t dma_heap_devt; > +struct class *dma_heap_class; > +struct list_head dma_heap_list; > +struct dentry *dma_heap_debug_root; Global variables? > + > +static int dma_heap_buffer_alloc(struct dma_heap *heap, size_t len, > + unsigned int flags) > +{ > + len = PAGE_ALIGN(len); > + if (!len) > + return -EINVAL; > + > + return heap->ops->allocate(heap, len, flags); > +} > + > +static int dma_heap_open(struct inode *inode, struct file *filp) > +{ > + struct dma_heap *heap; > + > + mutex_lock(&minor_lock); > + heap = idr_find(&dma_heap_idr, iminor(inode)); > + mutex_unlock(&minor_lock); > + if (!heap) { > + pr_err("dma_heap: minor %d unknown.\n", iminor(inode)); > + return -ENODEV; > + } > + > + /* instance data as context */ > + filp->private_data = heap; > + nonseekable_open(inode, filp); > + > + return 0; > +} > + > +static int dma_heap_release(struct inode *inode, struct file *filp) > +{ > + filp->private_data = NULL; Why does this matter? release should only be called on the way out of here, no need to do anything as nothing else can be called, right? release shouldn't be needed from what I can tell. > + > + return 0; > +} > + > +static long dma_heap_ioctl(struct file *filp, unsigned int cmd, > + unsigned long arg) > +{ > + switch (cmd) { > + case DMA_HEAP_IOC_ALLOC: > + { > + struct dma_heap_allocation_data heap_allocation; > + struct dma_heap *heap = filp->private_data; > + int fd; > + > + if (copy_from_user(&heap_allocation, (void __user *)arg, > + sizeof(heap_allocation))) > + return -EFAULT; > + > + if (heap_allocation.fd || > + heap_allocation.reserved0 || > + heap_allocation.reserved1 || > + heap_allocation.reserved2) { > + pr_warn_once("dma_heap: ioctl data not valid\n"); > + return -EINVAL; > + } Good job in forcing the reserved fields to be 0! > + if (heap_allocation.flags & ~DMA_HEAP_VALID_FLAGS) { > + pr_warn_once("dma_heap: flags has invalid or unsupported flags set\n"); > + return -EINVAL; > + } > + > + fd = dma_heap_buffer_alloc(heap, heap_allocation.len, > + heap_allocation.flags); No max value checking for .len? Can you really ask for anything? > + if (fd < 0) > + return fd; > + > + heap_allocation.fd = fd; > + > + if (copy_to_user((void __user *)arg, &heap_allocation, > + sizeof(heap_allocation))) > + return -EFAULT; > + > + break; > + } > + default: > + return -ENOTTY; > + } > + > + return 0; > +} > + > +static const struct file_operations dma_heap_fops = { > + .owner = THIS_MODULE, > + .open = dma_heap_open, > + .release = dma_heap_release, > + .unlocked_ioctl = dma_heap_ioctl, > +#ifdef CONFIG_COMPAT > + .compat_ioctl = dma_heap_ioctl, > +#endif Why is compat_ioctl even needed? > +}; > + > +int dma_heap_add(struct dma_heap *heap) > +{ > + struct device *dev_ret; > + int ret; > + > + if (!heap->name || !strcmp(heap->name, "")) { > + pr_err("dma_heap: Cannot add heap without a name\n"); > + return -EINVAL; > + } > + > + if (!heap->ops || !heap->ops->allocate) { > + pr_err("dma_heap: Cannot add heap with invalid ops struct\n"); > + return -EINVAL; > + } > + > + /* Find unused minor number */ > + mutex_lock(&minor_lock); > + ret = idr_alloc(&dma_heap_idr, heap, 0, NUM_HEAP_MINORS, GFP_KERNEL); > + mutex_unlock(&minor_lock); Again, xarray. But I will ask you to back up, why need a major number at all? Why not just use the misc subsystem? How many of these are you going to have over time in a "normal" system? How about a "abnormal system"? We have seen people running Android in "containers" such that they needed binderfs to handle huge numbers of individual android systems running at the same time. Will this api break those systems if you have a tiny maximum number you an allocate? > + if (ret < 0) { > + pr_err("dma_heap: Unable to get minor number for heap\n"); > + return ret; > + } > + heap->minor = ret; > + > + /* Create device */ > + heap->heap_devt = MKDEV(MAJOR(dma_heap_devt), heap->minor); > + dev_ret = device_create(dma_heap_class, > + NULL, > + heap->heap_devt, > + NULL, > + heap->name); No parent? Can't hang this off of anything? Ok, having it show up in /sys/devices/virtual/ is probably good enough. > + if (IS_ERR(dev_ret)) { > + pr_err("dma_heap: Unable to create char device\n"); > + return PTR_ERR(dev_ret); > + } > + > + /* Add device */ > + cdev_init(&heap->heap_cdev, &dma_heap_fops); > + ret = cdev_add(&heap->heap_cdev, dma_heap_devt, NUM_HEAP_MINORS); > + if (ret < 0) { > + device_destroy(dma_heap_class, heap->heap_devt); > + pr_err("dma_heap: Unable to add char device\n"); > + return ret; > + } > + > + return 0; > +} > +EXPORT_SYMBOL(dma_heap_add); EXPORT_SYMBOL_GPL() please? For core stuff like this it's good. > + > +static int dma_heap_init(void) > +{ > + int ret; > + > + ret = alloc_chrdev_region(&dma_heap_devt, 0, NUM_HEAP_MINORS, DEVNAME); > + if (ret) > + return ret; > + > + dma_heap_class = class_create(THIS_MODULE, DEVNAME); > + if (IS_ERR(dma_heap_class)) { > + unregister_chrdev_region(dma_heap_devt, NUM_HEAP_MINORS); > + return PTR_ERR(dma_heap_class); > + } > + > + return 0; > +} > +subsys_initcall(dma_heap_init); Overall, looks sane, the comments above are all really minor. > --- /dev/null > +++ b/include/uapi/linux/dma-heap.h > @@ -0,0 +1,52 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ Wrong license for a uapi .h file :( thanks, greg k-h From mboxrd@z Thu Jan 1 00:00:00 1970 From: Greg KH Subject: Re: [RFC][PATCH 1/5 v2] dma-buf: Add dma-buf heaps framework Date: Wed, 27 Mar 2019 23:53:54 +0900 Message-ID: <20190327145354.GA4514@kroah.com> References: <1551819273-640-1-git-send-email-john.stultz@linaro.org> <1551819273-640-2-git-send-email-john.stultz@linaro.org> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by gabe.freedesktop.org (Postfix) with ESMTPS id F242F6E282 for ; Wed, 27 Mar 2019 18:25:58 +0000 (UTC) Content-Disposition: inline In-Reply-To: <1551819273-640-2-git-send-email-john.stultz@linaro.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: John Stultz Cc: Chenbo Feng , lkml , Liam Mark , "Andrew F. Davis" , Alistair Strachan , dri-devel@lists.freedesktop.org List-Id: dri-devel@lists.freedesktop.org T24gVHVlLCBNYXIgMDUsIDIwMTkgYXQgMTI6NTQ6MjlQTSAtMDgwMCwgSm9obiBTdHVsdHogd3Jv dGU6Cj4gRnJvbTogIkFuZHJldyBGLiBEYXZpcyIgPGFmZEB0aS5jb20+Cj4gCj4gVGhpcyBmcmFt ZXdvcmsgYWxsb3dzIGEgdW5pZmllZCB1c2Vyc3BhY2UgaW50ZXJmYWNlIGZvciBkbWEtYnVmCj4g ZXhwb3J0ZXJzLCBhbGxvd2luZyB1c2VybGFuZCB0byBhbGxvY2F0ZSBzcGVjaWZpYyB0eXBlcyBv Zgo+IG1lbW9yeSBmb3IgdXNlIGluIGRtYS1idWYgc2hhcmluZy4KPiAKPiBFYWNoIGhlYXAgaXMg Z2l2ZW4gaXRzIG93biBkZXZpY2Ugbm9kZSwgd2hpY2ggYSB1c2VyIGNhbgo+IGFsbG9jYXRlIGEg ZG1hLWJ1ZiBmZCBmcm9tIHVzaW5nIHRoZSBETUFfSEVBUF9JT0NfQUxMT0MuCj4gCj4gVGhpcyBj b2RlIGlzIGFuIGV2b2x1aXRvbiBvZiB0aGUgQW5kcm9pZCBJT04gaW1wbGVtZW50YXRpb24sCj4g YW5kIGEgYmlnIHRoYW5rcyBpcyBkdWUgdG8gaXRzIGF1dGhvcnMvbWFpbnRhaW5lcnMgb3ZlciB0 aW1lCj4gZm9yIHRoZWlyIGVmZm9ydDoKPiAgIFJlYmVjY2EgU2NodWx0eiBaYXZpbiwgQ29saW4g Q3Jvc3MsIEJlbmphbWluIEdhaWduYXJkLAo+ICAgTGF1cmEgQWJib3R0LCBhbmQgbWFueSBvdGhl ciBjb250cmlidXRvcnMhCgpDb21tZW50cyBqdXN0IG9uIHRoZSB1c2VyL2tlcm5lbCBhcGkgYW5k IGhvdyBpdCBpbnRlcmFjdHMgd2l0aCB0aGUKZHJpdmVyIG1vZGVsLiAgTm90IG9uIHRoZSAicmVh bCIgZnVuY3Rpb25hbGl0eSBvZiB0aGlzIGNvZGUgOikKCj4gKyNkZWZpbmUgREVWTkFNRSAiZG1h X2hlYXAiCj4gKwo+ICsjZGVmaW5lIE5VTV9IRUFQX01JTk9SUyAxMjgKCldoeSBhIG1heD8KCj4g K3N0YXRpYyBERUZJTkVfSURSKGRtYV9oZWFwX2lkcik7Cj4gK3N0YXRpYyBERUZJTkVfTVVURVgo bWlub3JfbG9jayk7IC8qIFByb3RlY3QgaWRyIGFjY2Vzc2VzICovCgpNb3ZlIHRvIHVzZSB4YXJy YXkgbm93IHNvIHRoYXQgTWF0dGhldyBkb2Vzbid0IGhhdmUgdG8gc2VuZCBwYXRjaGVzCmNvbnZl cnRpbmcgdGhpcyBjb2RlIGxhdGVyIDopCgpJdCBhbHNvIGFsbG93cyB5b3UgdG8gZHJvcCB0aGUg bXV0ZXguCgo+ICsKPiArZGV2X3QgZG1hX2hlYXBfZGV2dDsKPiArc3RydWN0IGNsYXNzICpkbWFf aGVhcF9jbGFzczsKPiArc3RydWN0IGxpc3RfaGVhZCBkbWFfaGVhcF9saXN0Owo+ICtzdHJ1Y3Qg ZGVudHJ5ICpkbWFfaGVhcF9kZWJ1Z19yb290OwoKR2xvYmFsIHZhcmlhYmxlcz8KCj4gKwo+ICtz dGF0aWMgaW50IGRtYV9oZWFwX2J1ZmZlcl9hbGxvYyhzdHJ1Y3QgZG1hX2hlYXAgKmhlYXAsIHNp emVfdCBsZW4sCj4gKwkJCQkgdW5zaWduZWQgaW50IGZsYWdzKQo+ICt7Cj4gKwlsZW4gPSBQQUdF X0FMSUdOKGxlbik7Cj4gKwlpZiAoIWxlbikKPiArCQlyZXR1cm4gLUVJTlZBTDsKPiArCj4gKwly ZXR1cm4gaGVhcC0+b3BzLT5hbGxvY2F0ZShoZWFwLCBsZW4sIGZsYWdzKTsKPiArfQo+ICsKPiAr c3RhdGljIGludCBkbWFfaGVhcF9vcGVuKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxl ICpmaWxwKQo+ICt7Cj4gKwlzdHJ1Y3QgZG1hX2hlYXAgKmhlYXA7Cj4gKwo+ICsJbXV0ZXhfbG9j aygmbWlub3JfbG9jayk7Cj4gKwloZWFwID0gaWRyX2ZpbmQoJmRtYV9oZWFwX2lkciwgaW1pbm9y KGlub2RlKSk7Cj4gKwltdXRleF91bmxvY2soJm1pbm9yX2xvY2spOwo+ICsJaWYgKCFoZWFwKSB7 Cj4gKwkJcHJfZXJyKCJkbWFfaGVhcDogbWlub3IgJWQgdW5rbm93bi5cbiIsIGltaW5vcihpbm9k ZSkpOwo+ICsJCXJldHVybiAtRU5PREVWOwo+ICsJfQo+ICsKPiArCS8qIGluc3RhbmNlIGRhdGEg YXMgY29udGV4dCAqLwo+ICsJZmlscC0+cHJpdmF0ZV9kYXRhID0gaGVhcDsKPiArCW5vbnNlZWth YmxlX29wZW4oaW5vZGUsIGZpbHApOwo+ICsKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICtzdGF0 aWMgaW50IGRtYV9oZWFwX3JlbGVhc2Uoc3RydWN0IGlub2RlICppbm9kZSwgc3RydWN0IGZpbGUg KmZpbHApCj4gK3sKPiArCWZpbHAtPnByaXZhdGVfZGF0YSA9IE5VTEw7CgpXaHkgZG9lcyB0aGlz IG1hdHRlcj8gIHJlbGVhc2Ugc2hvdWxkIG9ubHkgYmUgY2FsbGVkIG9uIHRoZSB3YXkgb3V0IG9m CmhlcmUsIG5vIG5lZWQgdG8gZG8gYW55dGhpbmcgYXMgbm90aGluZyBlbHNlIGNhbiBiZSBjYWxs ZWQsIHJpZ2h0PwoKcmVsZWFzZSBzaG91bGRuJ3QgYmUgbmVlZGVkIGZyb20gd2hhdCBJIGNhbiB0 ZWxsLgoKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIGxvbmcgZG1hX2hlYXBf aW9jdGwoc3RydWN0IGZpbGUgKmZpbHAsIHVuc2lnbmVkIGludCBjbWQsCj4gKwkJCSAgIHVuc2ln bmVkIGxvbmcgYXJnKQo+ICt7Cj4gKwlzd2l0Y2ggKGNtZCkgewo+ICsJY2FzZSBETUFfSEVBUF9J T0NfQUxMT0M6Cj4gKwl7Cj4gKwkJc3RydWN0IGRtYV9oZWFwX2FsbG9jYXRpb25fZGF0YSBoZWFw X2FsbG9jYXRpb247Cj4gKwkJc3RydWN0IGRtYV9oZWFwICpoZWFwID0gZmlscC0+cHJpdmF0ZV9k YXRhOwo+ICsJCWludCBmZDsKPiArCj4gKwkJaWYgKGNvcHlfZnJvbV91c2VyKCZoZWFwX2FsbG9j YXRpb24sICh2b2lkIF9fdXNlciAqKWFyZywKPiArCQkJCSAgIHNpemVvZihoZWFwX2FsbG9jYXRp b24pKSkKPiArCQkJcmV0dXJuIC1FRkFVTFQ7Cj4gKwo+ICsJCWlmIChoZWFwX2FsbG9jYXRpb24u ZmQgfHwKPiArCQkgICAgaGVhcF9hbGxvY2F0aW9uLnJlc2VydmVkMCB8fAo+ICsJCSAgICBoZWFw X2FsbG9jYXRpb24ucmVzZXJ2ZWQxIHx8Cj4gKwkJICAgIGhlYXBfYWxsb2NhdGlvbi5yZXNlcnZl ZDIpIHsKPiArCQkJcHJfd2Fybl9vbmNlKCJkbWFfaGVhcDogaW9jdGwgZGF0YSBub3QgdmFsaWRc biIpOwo+ICsJCQlyZXR1cm4gLUVJTlZBTDsKPiArCQl9CgpHb29kIGpvYiBpbiBmb3JjaW5nIHRo ZSByZXNlcnZlZCBmaWVsZHMgdG8gYmUgMCEKCj4gKwkJaWYgKGhlYXBfYWxsb2NhdGlvbi5mbGFn cyAmIH5ETUFfSEVBUF9WQUxJRF9GTEFHUykgewo+ICsJCQlwcl93YXJuX29uY2UoImRtYV9oZWFw OiBmbGFncyBoYXMgaW52YWxpZCBvciB1bnN1cHBvcnRlZCBmbGFncyBzZXRcbiIpOwo+ICsJCQly ZXR1cm4gLUVJTlZBTDsKPiArCQl9Cj4gKwo+ICsJCWZkID0gZG1hX2hlYXBfYnVmZmVyX2FsbG9j KGhlYXAsIGhlYXBfYWxsb2NhdGlvbi5sZW4sCj4gKwkJCQkJICAgaGVhcF9hbGxvY2F0aW9uLmZs YWdzKTsKCk5vIG1heCB2YWx1ZSBjaGVja2luZyBmb3IgLmxlbj8gIENhbiB5b3UgcmVhbGx5IGFz ayBmb3IgYW55dGhpbmc/Cgo+ICsJCWlmIChmZCA8IDApCj4gKwkJCXJldHVybiBmZDsKPiArCj4g KwkJaGVhcF9hbGxvY2F0aW9uLmZkID0gZmQ7Cj4gKwo+ICsJCWlmIChjb3B5X3RvX3VzZXIoKHZv aWQgX191c2VyICopYXJnLCAmaGVhcF9hbGxvY2F0aW9uLAo+ICsJCQkJIHNpemVvZihoZWFwX2Fs bG9jYXRpb24pKSkKPiArCQkJcmV0dXJuIC1FRkFVTFQ7Cj4gKwo+ICsJCWJyZWFrOwo+ICsJfQo+ ICsJZGVmYXVsdDoKPiArCQlyZXR1cm4gLUVOT1RUWTsKPiArCX0KPiArCj4gKwlyZXR1cm4gMDsK PiArfQo+ICsKPiArc3RhdGljIGNvbnN0IHN0cnVjdCBmaWxlX29wZXJhdGlvbnMgZG1hX2hlYXBf Zm9wcyA9IHsKPiArCS5vd25lciAgICAgICAgICA9IFRISVNfTU9EVUxFLAo+ICsJLm9wZW4JCT0g ZG1hX2hlYXBfb3BlbiwKPiArCS5yZWxlYXNlCT0gZG1hX2hlYXBfcmVsZWFzZSwKPiArCS51bmxv Y2tlZF9pb2N0bCA9IGRtYV9oZWFwX2lvY3RsLAo+ICsjaWZkZWYgQ09ORklHX0NPTVBBVAo+ICsJ LmNvbXBhdF9pb2N0bAk9IGRtYV9oZWFwX2lvY3RsLAo+ICsjZW5kaWYKCldoeSBpcyBjb21wYXRf aW9jdGwgZXZlbiBuZWVkZWQ/Cgo+ICt9Owo+ICsKPiAraW50IGRtYV9oZWFwX2FkZChzdHJ1Y3Qg ZG1hX2hlYXAgKmhlYXApCj4gK3sKPiArCXN0cnVjdCBkZXZpY2UgKmRldl9yZXQ7Cj4gKwlpbnQg cmV0Owo+ICsKPiArCWlmICghaGVhcC0+bmFtZSB8fCAhc3RyY21wKGhlYXAtPm5hbWUsICIiKSkg ewo+ICsJCXByX2VycigiZG1hX2hlYXA6IENhbm5vdCBhZGQgaGVhcCB3aXRob3V0IGEgbmFtZVxu Iik7Cj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4gKwl9Cj4gKwo+ICsJaWYgKCFoZWFwLT5vcHMgfHwg IWhlYXAtPm9wcy0+YWxsb2NhdGUpIHsKPiArCQlwcl9lcnIoImRtYV9oZWFwOiBDYW5ub3QgYWRk IGhlYXAgd2l0aCBpbnZhbGlkIG9wcyBzdHJ1Y3RcbiIpOwo+ICsJCXJldHVybiAtRUlOVkFMOwo+ ICsJfQo+ICsKPiArCS8qIEZpbmQgdW51c2VkIG1pbm9yIG51bWJlciAqLwo+ICsJbXV0ZXhfbG9j aygmbWlub3JfbG9jayk7Cj4gKwlyZXQgPSBpZHJfYWxsb2MoJmRtYV9oZWFwX2lkciwgaGVhcCwg MCwgTlVNX0hFQVBfTUlOT1JTLCBHRlBfS0VSTkVMKTsKPiArCW11dGV4X3VubG9jaygmbWlub3Jf bG9jayk7CgpBZ2FpbiwgeGFycmF5LgoKQnV0IEkgd2lsbCBhc2sgeW91IHRvIGJhY2sgdXAsIHdo eSBuZWVkIGEgbWFqb3IgbnVtYmVyIGF0IGFsbD8gIFdoeSBub3QKanVzdCB1c2UgdGhlIG1pc2Mg c3Vic3lzdGVtPyAgSG93IG1hbnkgb2YgdGhlc2UgYXJlIHlvdSBnb2luZyB0byBoYXZlCm92ZXIg dGltZSBpbiBhICJub3JtYWwiIHN5c3RlbT8gIEhvdyBhYm91dCBhICJhYm5vcm1hbCBzeXN0ZW0i PwoKV2UgaGF2ZSBzZWVuIHBlb3BsZSBydW5uaW5nIEFuZHJvaWQgaW4gImNvbnRhaW5lcnMiIHN1 Y2ggdGhhdCB0aGV5Cm5lZWRlZCBiaW5kZXJmcyB0byBoYW5kbGUgaHVnZSBudW1iZXJzIG9mIGlu ZGl2aWR1YWwgYW5kcm9pZCBzeXN0ZW1zCnJ1bm5pbmcgYXQgdGhlIHNhbWUgdGltZS4gIFdpbGwg dGhpcyBhcGkgYnJlYWsgdGhvc2Ugc3lzdGVtcyBpZiB5b3UgaGF2ZQphIHRpbnkgbWF4aW11bSBu dW1iZXIgeW91IGFuIGFsbG9jYXRlPwoKPiArCWlmIChyZXQgPCAwKSB7Cj4gKwkJcHJfZXJyKCJk bWFfaGVhcDogVW5hYmxlIHRvIGdldCBtaW5vciBudW1iZXIgZm9yIGhlYXBcbiIpOwo+ICsJCXJl dHVybiByZXQ7Cj4gKwl9Cj4gKwloZWFwLT5taW5vciA9IHJldDsKPiArCj4gKwkvKiBDcmVhdGUg ZGV2aWNlICovCj4gKwloZWFwLT5oZWFwX2RldnQgPSBNS0RFVihNQUpPUihkbWFfaGVhcF9kZXZ0 KSwgaGVhcC0+bWlub3IpOwo+ICsJZGV2X3JldCA9IGRldmljZV9jcmVhdGUoZG1hX2hlYXBfY2xh c3MsCj4gKwkJCQlOVUxMLAo+ICsJCQkJaGVhcC0+aGVhcF9kZXZ0LAo+ICsJCQkJTlVMTCwKPiAr CQkJCWhlYXAtPm5hbWUpOwoKTm8gcGFyZW50PyAgQ2FuJ3QgaGFuZyB0aGlzIG9mZiBvZiBhbnl0 aGluZz8gIE9rLCBoYXZpbmcgaXQgc2hvdyB1cCBpbgovc3lzL2RldmljZXMvdmlydHVhbC8gaXMg cHJvYmFibHkgZ29vZCBlbm91Z2guCgo+ICsJaWYgKElTX0VSUihkZXZfcmV0KSkgewo+ICsJCXBy X2VycigiZG1hX2hlYXA6IFVuYWJsZSB0byBjcmVhdGUgY2hhciBkZXZpY2VcbiIpOwo+ICsJCXJl dHVybiBQVFJfRVJSKGRldl9yZXQpOwo+ICsJfQo+ICsKPiArCS8qIEFkZCBkZXZpY2UgKi8KPiAr CWNkZXZfaW5pdCgmaGVhcC0+aGVhcF9jZGV2LCAmZG1hX2hlYXBfZm9wcyk7Cj4gKwlyZXQgPSBj ZGV2X2FkZCgmaGVhcC0+aGVhcF9jZGV2LCBkbWFfaGVhcF9kZXZ0LCBOVU1fSEVBUF9NSU5PUlMp Owo+ICsJaWYgKHJldCA8IDApIHsKPiArCQlkZXZpY2VfZGVzdHJveShkbWFfaGVhcF9jbGFzcywg aGVhcC0+aGVhcF9kZXZ0KTsKPiArCQlwcl9lcnIoImRtYV9oZWFwOiBVbmFibGUgdG8gYWRkIGNo YXIgZGV2aWNlXG4iKTsKPiArCQlyZXR1cm4gcmV0Owo+ICsJfQo+ICsKPiArCXJldHVybiAwOwo+ ICt9Cj4gK0VYUE9SVF9TWU1CT0woZG1hX2hlYXBfYWRkKTsKCkVYUE9SVF9TWU1CT0xfR1BMKCkg cGxlYXNlPyAgRm9yIGNvcmUgc3R1ZmYgbGlrZSB0aGlzIGl0J3MgZ29vZC4KCj4gKwo+ICtzdGF0 aWMgaW50IGRtYV9oZWFwX2luaXQodm9pZCkKPiArewo+ICsJaW50IHJldDsKPiArCj4gKwlyZXQg PSBhbGxvY19jaHJkZXZfcmVnaW9uKCZkbWFfaGVhcF9kZXZ0LCAwLCBOVU1fSEVBUF9NSU5PUlMs IERFVk5BTUUpOwo+ICsJaWYgKHJldCkKPiArCQlyZXR1cm4gcmV0Owo+ICsKPiArCWRtYV9oZWFw X2NsYXNzID0gY2xhc3NfY3JlYXRlKFRISVNfTU9EVUxFLCBERVZOQU1FKTsKPiArCWlmIChJU19F UlIoZG1hX2hlYXBfY2xhc3MpKSB7Cj4gKwkJdW5yZWdpc3Rlcl9jaHJkZXZfcmVnaW9uKGRtYV9o ZWFwX2RldnQsIE5VTV9IRUFQX01JTk9SUyk7Cj4gKwkJcmV0dXJuIFBUUl9FUlIoZG1hX2hlYXBf Y2xhc3MpOwo+ICsJfQo+ICsKPiArCXJldHVybiAwOwo+ICt9Cj4gK3N1YnN5c19pbml0Y2FsbChk bWFfaGVhcF9pbml0KTsKCk92ZXJhbGwsIGxvb2tzIHNhbmUsIHRoZSBjb21tZW50cyBhYm92ZSBh cmUgYWxsIHJlYWxseSBtaW5vci4KCgo+IC0tLSAvZGV2L251bGwKPiArKysgYi9pbmNsdWRlL3Vh cGkvbGludXgvZG1hLWhlYXAuaAo+IEBAIC0wLDAgKzEsNTIgQEAKPiArLyogU1BEWC1MaWNlbnNl LUlkZW50aWZpZXI6IEdQTC0yLjAgKi8KCldyb25nIGxpY2Vuc2UgZm9yIGEgdWFwaSAuaCBmaWxl IDooCgp0aGFua3MsCgpncmVnIGstaApfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fXwpkcmktZGV2ZWwgbWFpbGluZyBsaXN0CmRyaS1kZXZlbEBsaXN0cy5mcmVl ZGVza3RvcC5vcmcKaHR0cHM6Ly9saXN0cy5mcmVlZGVza3RvcC5vcmcvbWFpbG1hbi9saXN0aW5m by9kcmktZGV2ZWw=