From mboxrd@z Thu Jan 1 00:00:00 1970 From: zourongrong@huawei.com (Rongrong Zou) Date: Fri, 11 Nov 2016 21:57:56 +0800 Subject: [PATCH v6 2/9] drm/hisilicon/hibmc: Add video memory management In-Reply-To: References: <1477639682-22520-1-git-send-email-zourongrong@gmail.com> <1477639682-22520-3-git-send-email-zourongrong@gmail.com> <5825A8A3.5070409@huawei.com> Message-ID: <5825CE64.5080708@huawei.com> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org ? 2016/11/11 21:25, Sean Paul ??: > On Fri, Nov 11, 2016 at 6:16 AM, Rongrong Zou wrote: >> ? 2016/11/11 1:35, Sean Paul ??: >>> >>> On Fri, Oct 28, 2016 at 3:27 AM, Rongrong Zou >>> wrote: >>>> >>>> Hibmc have 32m video memory which can be accessed through PCIe by host, >>>> we use ttm to manage these memory. >>>> >>>> Signed-off-by: Rongrong Zou >>>> --- >>>> drivers/gpu/drm/hisilicon/hibmc/Kconfig | 1 + >>>> drivers/gpu/drm/hisilicon/hibmc/Makefile | 2 +- >>>> drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 12 + >>>> drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 46 +++ >>>> drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c | 490 >>>> ++++++++++++++++++++++++ >>>> 5 files changed, 550 insertions(+), 1 deletion(-) >>>> create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c >>>> >>>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/Kconfig >>>> b/drivers/gpu/drm/hisilicon/hibmc/Kconfig >>>> index a9af90d..bcb8c18 100644 >>>> --- a/drivers/gpu/drm/hisilicon/hibmc/Kconfig >>>> +++ b/drivers/gpu/drm/hisilicon/hibmc/Kconfig >>>> @@ -1,6 +1,7 @@ >>>> config DRM_HISI_HIBMC >>>> tristate "DRM Support for Hisilicon Hibmc" >>>> depends on DRM && PCI >>>> + select DRM_TTM >>>> >>>> help >>>> Choose this option if you have a Hisilicon Hibmc soc chipset. >>>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/Makefile >>>> b/drivers/gpu/drm/hisilicon/hibmc/Makefile >>>> index 97cf4a0..d5c40b8 100644 >>>> --- a/drivers/gpu/drm/hisilicon/hibmc/Makefile >>>> +++ b/drivers/gpu/drm/hisilicon/hibmc/Makefile >>>> @@ -1,5 +1,5 @@ >>>> ccflags-y := -Iinclude/drm >>>> -hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_power.o >>>> +hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_power.o hibmc_ttm.o >>>> >>>> obj-$(CONFIG_DRM_HISI_HIBMC) +=hibmc-drm.o >>>> #obj-y += hibmc-drm.o >>>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c >>>> b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c >>>> index 4669d42..81f4301 100644 >>>> --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c >>>> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c >>>> @@ -31,6 +31,7 @@ >>>> #ifdef CONFIG_COMPAT >>>> .compat_ioctl = drm_compat_ioctl, >>>> #endif >>>> + .mmap = hibmc_mmap, >>>> .poll = drm_poll, >>>> .read = drm_read, >>>> .llseek = no_llseek, >>>> @@ -46,6 +47,8 @@ static void hibmc_disable_vblank(struct drm_device >>>> *dev, unsigned int pipe) >>>> } >>>> >>>> static struct drm_driver hibmc_driver = { >>>> + .driver_features = DRIVER_GEM, >>>> + >>> >>> >>> nit: extra space >>> >>>> .fops = &hibmc_fops, >>>> .name = "hibmc", >>>> .date = "20160828", >>>> @@ -55,6 +58,10 @@ static void hibmc_disable_vblank(struct drm_device >>>> *dev, unsigned int pipe) >>>> .get_vblank_counter = drm_vblank_no_hw_counter, >>>> .enable_vblank = hibmc_enable_vblank, >>>> .disable_vblank = hibmc_disable_vblank, >>>> + .gem_free_object_unlocked = hibmc_gem_free_object, >>>> + .dumb_create = hibmc_dumb_create, >>>> + .dumb_map_offset = hibmc_dumb_mmap_offset, >>>> + .dumb_destroy = drm_gem_dumb_destroy, >>>> }; >>>> >>>> static int hibmc_pm_suspend(struct device *dev) >>>> @@ -163,6 +170,7 @@ static int hibmc_unload(struct drm_device *dev) >>>> { >>>> struct hibmc_drm_device *hidev = dev->dev_private; >>>> >>>> + hibmc_mm_fini(hidev); >>>> hibmc_hw_fini(hidev); >>>> dev->dev_private = NULL; >>>> return 0; >>>> @@ -183,6 +191,10 @@ static int hibmc_load(struct drm_device *dev, >>>> unsigned long flags) >>>> if (ret) >>>> goto err; >>>> >>>> + ret = hibmc_mm_init(hidev); >>>> + if (ret) >>>> + goto err; >>>> + >>>> return 0; >>>> >>>> err: >>>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h >>>> b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h >>>> index 0037341..db8d80e 100644 >>>> --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h >>>> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h >>>> @@ -20,6 +20,8 @@ >>>> #define HIBMC_DRM_DRV_H >>>> >>>> #include >>>> +#include >>>> +#include >>> >>> >>> nit: alphabetize >> >> >> will fix it, thanks. >> >>> >>>> >>>> struct hibmc_drm_device { >>>> /* hw */ >>>> @@ -30,6 +32,50 @@ struct hibmc_drm_device { >>>> >>>> /* drm */ >>>> struct drm_device *dev; >>>> + >>>> + /* ttm */ >>>> + struct { >>>> + struct drm_global_reference mem_global_ref; >>>> + struct ttm_bo_global_ref bo_global_ref; >>>> + struct ttm_bo_device bdev; >>>> + bool initialized; >>>> + } ttm; >>> >>> >>> I don't think you gain anything other than keystrokes from the substruct >> >> >> I'm sorry i didn't catch you, i looked at the all drivers used ttm such >> as ast/bochs/cirrus/mgag200/qxl/virtio_gpu, they all embedded the ttm >> substruct >> into the driver-private struct. >> >> so do you mean >> struct hibmc_drm_device { >> /* hw */ >> void __iomem *mmio; >> void __iomem *fb_map; >> unsigned long fb_base; >> unsigned long fb_size; >> >> /* drm */ >> struct drm_device *dev; >> struct drm_plane plane; >> struct drm_crtc crtc; >> struct drm_encoder encoder; >> struct drm_connector connector; >> bool mode_config_initialized; >> >> /* ttm */ >> struct drm_global_reference mem_global_ref; >> struct ttm_bo_global_ref bo_global_ref; >> struct ttm_bo_device bdev; >> bool initialized; >> ... >> }; >> ? > > Yeah, that's what I was thinking > >> >>> >>>> + >>>> + bool mm_inited; >>>> }; >>>> >>>> +struct hibmc_bo { >>>> + struct ttm_buffer_object bo; >>>> + struct ttm_placement placement; >>>> + struct ttm_bo_kmap_obj kmap; >>>> + struct drm_gem_object gem; >>>> + struct ttm_place placements[3]; >>>> + int pin_count; >>>> +}; >>>> + >>>> +static inline struct hibmc_bo *hibmc_bo(struct ttm_buffer_object *bo) >>>> +{ >>>> + return container_of(bo, struct hibmc_bo, bo); >>>> +} >>>> + >>>> +static inline struct hibmc_bo *gem_to_hibmc_bo(struct drm_gem_object >>>> *gem) >>>> +{ >>>> + return container_of(gem, struct hibmc_bo, gem); >>>> +} >>>> + >>>> +#define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT) >>> >>> >>> Hide this in ttm.c >> >> >> ok, will do that. >> thanks for pointing it out. >> >> >>> >>>> + >>>> +int hibmc_gem_create(struct drm_device *dev, u32 size, bool iskernel, >>>> + struct drm_gem_object **obj); >>>> + >>>> +int hibmc_mm_init(struct hibmc_drm_device *hibmc); >>>> +void hibmc_mm_fini(struct hibmc_drm_device *hibmc); >>>> +int hibmc_bo_pin(struct hibmc_bo *bo, u32 pl_flag, u64 *gpu_addr); >>>> +void hibmc_gem_free_object(struct drm_gem_object *obj); >>>> +int hibmc_dumb_create(struct drm_file *file, struct drm_device *dev, >>>> + struct drm_mode_create_dumb *args); >>>> +int hibmc_dumb_mmap_offset(struct drm_file *file, struct drm_device >>>> *dev, >>>> + u32 handle, u64 *offset); >>>> +int hibmc_mmap(struct file *filp, struct vm_area_struct *vma); >>>> + >>>> #endif >>>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c >>>> b/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c >>>> new file mode 100644 >>>> index 0000000..0802ebd >>>> --- /dev/null >>>> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c >>>> @@ -0,0 +1,490 @@ >>>> +/* Hisilicon Hibmc SoC drm driver >>>> + * >>>> + * Based on the bochs drm driver. >>>> + * >>>> + * Copyright (c) 2016 Huawei Limited. >>>> + * >>>> + * Author: >>>> + * Rongrong Zou >>>> + * Rongrong Zou >>>> + * Jianhua Li >>>> + * >>>> + * This program is free software; you can redistribute it and/or modify >>>> + * it under the terms of the GNU General Public License as published by >>>> + * the Free Software Foundation; either version 2 of the License, or >>>> + * (at your option) any later version. >>>> + * >>>> + */ >>>> + >>>> +#include "hibmc_drm_drv.h" >>>> +#include >>>> +#include >>>> +#include >>>> + >>>> +static inline struct hibmc_drm_device * >>>> +hibmc_bdev(struct ttm_bo_device *bd) >>>> +{ >>>> + return container_of(bd, struct hibmc_drm_device, ttm.bdev); >>>> +} >>>> + >>>> +static int >>>> +hibmc_ttm_mem_global_init(struct drm_global_reference *ref) >>>> +{ >>>> + return ttm_mem_global_init(ref->object); >>>> +} >>>> + >>>> +static void >>>> +hibmc_ttm_mem_global_release(struct drm_global_reference *ref) >>>> +{ >>>> + ttm_mem_global_release(ref->object); >>>> +} >>>> + >>>> +static int hibmc_ttm_global_init(struct hibmc_drm_device *hibmc) >>>> +{ >>>> + struct drm_global_reference *global_ref; >>>> + int r; >>> >>> >>> nit: try not to use one character variable names unless it's for the >>> purpose of a loop (ie: i,j). You also use ret elsewhere in the driver, >>> so it'd be nice to remain consistent >> >> >> the whole file is delivered from bochs ttm, i didn't modify anything except >> some checkpatch warnings and the 'hibmc_' prefix. Unfortunately, some >> problems were delivered too. > > Yeah, seems like it. Perhaps you can post patches to fix these issues > in the other drivers too :) i will do after the this one get merged :) > >> >>> >>>> + >>>> + global_ref = &hibmc->ttm.mem_global_ref; >>> >>> >>> I think using the global_ref local obfuscates what you're doing here. >>> It saves you 6 characters while typing, but adds a layer of >>> indirection for all future readers. >>> >>>> + global_ref->global_type = DRM_GLOBAL_TTM_MEM; >>>> + global_ref->size = sizeof(struct ttm_mem_global); >>>> + global_ref->init = &hibmc_ttm_mem_global_init; >>>> + global_ref->release = &hibmc_ttm_mem_global_release; >>>> + r = drm_global_item_ref(global_ref); >>>> + if (r != 0) { >>> >>> >>> nit: if (r) >> >> >> will fix it, >> thanks. >> BTW, i wonder why checkpatch.pl didn't report it. >> >> >>> >>>> + DRM_ERROR("Failed setting up TTM memory accounting >>>> subsystem.\n" >>>> + ); >>> >>> >>> Breaking up the line for one character is probably not worthwhile, and >>> you should really print the error. How about: >>> >>> DRM_ERROR("Could not get ref on ttm global ret=%d.\n", ret); >> >> >> i like your solution, thanks. >> >> >>> >>> >>>> + return r; >>>> + } >>>> + >>>> + hibmc->ttm.bo_global_ref.mem_glob = >>>> + hibmc->ttm.mem_global_ref.object; >>>> + global_ref = &hibmc->ttm.bo_global_ref.ref; >>>> + global_ref->global_type = DRM_GLOBAL_TTM_BO; >>>> + global_ref->size = sizeof(struct ttm_bo_global); >>>> + global_ref->init = &ttm_bo_global_init; >>>> + global_ref->release = &ttm_bo_global_release; >>>> + r = drm_global_item_ref(global_ref); >>>> + if (r != 0) { >>>> + DRM_ERROR("Failed setting up TTM BO subsystem.\n"); >>>> + drm_global_item_unref(&hibmc->ttm.mem_global_ref); >>>> + return r; >>>> + } >>>> + return 0; >>>> +} >>>> + >>>> +static void >>>> +hibmc_ttm_global_release(struct hibmc_drm_device *hibmc) >>>> +{ >>>> + if (!hibmc->ttm.mem_global_ref.release) >>> >>> >>> Are you actually hitting this condition? This seems like it's papering >>> over something else. >> >> >> it was also delivered from others, i looked at the xxx_ttm_global_init >> function, 'mem_global_ref.release' is assigned unconditionally, so i >> think this condition never be hit, it may be hit when release twice, >> but this won't take place in my driver. >> > > Yeah, that's what I was hoping for. So perhaps we can remove this? yes, we can. Regards, Rongrong. > >>> >>>> + return; >>>> + >>>> + drm_global_item_unref(&hibmc->ttm.bo_global_ref.ref); >>>> + drm_global_item_unref(&hibmc->ttm.mem_global_ref); >>>> + hibmc->ttm.mem_global_ref.release = NULL; >>>> +} >>>> + >>>> +static void hibmc_bo_ttm_destroy(struct ttm_buffer_object *tbo) >>>> +{ >>>> + struct hibmc_bo *bo; >>>> + >>>> + bo = container_of(tbo, struct hibmc_bo, bo); >>> >>> >>> nit: No need to split this into a separate line. >> >> >> agreed, thanks. >> >>> >>>> + >>>> + drm_gem_object_release(&bo->gem); >>>> + kfree(bo); >>>> +} >>>> + >>>> +static bool hibmc_ttm_bo_is_hibmc_bo(struct ttm_buffer_object *bo) >>>> +{ >>>> + if (bo->destroy == &hibmc_bo_ttm_destroy) >>>> + return true; >>>> + return false; >>> >>> >>> return bo->destroy == &hibmc_bo_ttm_destroy; >> >> >> looks better to me. >> >> >>> >>>> +} >>>> + >>>> +static int >>>> +hibmc_bo_init_mem_type(struct ttm_bo_device *bdev, u32 type, >>>> + struct ttm_mem_type_manager *man) >>>> +{ >>>> + switch (type) { >>>> + case TTM_PL_SYSTEM: >>>> + man->flags = TTM_MEMTYPE_FLAG_MAPPABLE; >>>> + man->available_caching = TTM_PL_MASK_CACHING; >>>> + man->default_caching = TTM_PL_FLAG_CACHED; >>>> + break; >>>> + case TTM_PL_VRAM: >>>> + man->func = &ttm_bo_manager_func; >>>> + man->flags = TTM_MEMTYPE_FLAG_FIXED | >>>> + TTM_MEMTYPE_FLAG_MAPPABLE; >>>> + man->available_caching = TTM_PL_FLAG_UNCACHED | >>>> + TTM_PL_FLAG_WC; >>>> + man->default_caching = TTM_PL_FLAG_WC; >>>> + break; >>>> + default: >>>> + DRM_ERROR("Unsupported memory type %u\n", type); >>>> + return -EINVAL; >>>> + } >>>> + return 0; >>>> +} >>>> + >>>> +void hibmc_ttm_placement(struct hibmc_bo *bo, int domain) >>>> +{ >>>> + u32 c = 0; >>> >>> >>> Can you please use a more descriptive name than 'c'? >> >> >> ok, will do that. >> >>> >>>> + u32 i; >>>> + >>>> + bo->placement.placement = bo->placements; >>>> + bo->placement.busy_placement = bo->placements; >>>> + if (domain & TTM_PL_FLAG_VRAM) >>>> + bo->placements[c++].flags = TTM_PL_FLAG_WC | >>>> + TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_VRAM; >>> >>> >>> nit: you're alignment is off here and below >> >> >> is it correct? >> >> if (domain & TTM_PL_FLAG_VRAM) >> bo->placements[c++].flags = TTM_PL_FLAG_WC | >> TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_VRAM; >> if (domain & TTM_PL_FLAG_SYSTEM) >> bo->placements[c++].flags = TTM_PL_MASK_CACHING | >> TTM_PL_FLAG_SYSTEM; >> if (!c) >> bo->placements[c++].flags = TTM_PL_MASK_CACHING | >> TTM_PL_FLAG_SYSTEM; >> > > Pretty much anything other than lining them up one under the other is better > >>> >>>> + if (domain & TTM_PL_FLAG_SYSTEM) >>>> + bo->placements[c++].flags = TTM_PL_MASK_CACHING | >>>> + TTM_PL_FLAG_SYSTEM; >>>> + if (!c) >>>> + bo->placements[c++].flags = TTM_PL_MASK_CACHING | >>>> + TTM_PL_FLAG_SYSTEM; >>>> + >>>> + bo->placement.num_placement = c; >>>> + bo->placement.num_busy_placement = c; >>>> + for (i = 0; i < c; ++i) { >>> >>> >>> nit: we tend towards post-increment in kernel >> >> >> agreed, thanks. >> >> >>> >>>> + bo->placements[i].fpfn = 0; >>>> + bo->placements[i].lpfn = 0; >>>> + } >>>> +} >>>> + >>>> +static void >>>> +hibmc_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement >>>> *pl) >>>> +{ >>>> + struct hibmc_bo *hibmcbo = hibmc_bo(bo); >>>> + >>>> + if (!hibmc_ttm_bo_is_hibmc_bo(bo)) >>>> + return; >>>> + >>>> + hibmc_ttm_placement(hibmcbo, TTM_PL_FLAG_SYSTEM); >>>> + *pl = hibmcbo->placement; >>>> +} >>>> + >>>> +static int hibmc_bo_verify_access(struct ttm_buffer_object *bo, >>>> + struct file *filp) >>>> +{ >>>> + struct hibmc_bo *hibmcbo = hibmc_bo(bo); >>>> + >>>> + return drm_vma_node_verify_access(&hibmcbo->gem.vma_node, >>>> + filp->private_data); >>>> +} >>>> + >>>> +static int hibmc_ttm_io_mem_reserve(struct ttm_bo_device *bdev, >>>> + struct ttm_mem_reg *mem) >>>> +{ >>>> + struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type]; >>>> + struct hibmc_drm_device *hibmc = hibmc_bdev(bdev); >>>> + >>>> + mem->bus.addr = NULL; >>>> + mem->bus.offset = 0; >>>> + mem->bus.size = mem->num_pages << PAGE_SHIFT; >>>> + mem->bus.base = 0; >>>> + mem->bus.is_iomem = false; >>>> + if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE)) >>>> + return -EINVAL; >>>> + switch (mem->mem_type) { >>>> + case TTM_PL_SYSTEM: >>>> + /* system memory */ >>>> + return 0; >>>> + case TTM_PL_VRAM: >>>> + mem->bus.offset = mem->start << PAGE_SHIFT; >>>> + mem->bus.base = pci_resource_start(hibmc->dev->pdev, 0); >>>> + mem->bus.is_iomem = true; >>>> + break; >>>> + default: >>>> + return -EINVAL; >>>> + } >>>> + return 0; >>>> +} >>>> + >>>> +static void hibmc_ttm_io_mem_free(struct ttm_bo_device *bdev, >>>> + struct ttm_mem_reg *mem) >>>> +{ >>>> +} >>> >>> >>> No need to stub this, the caller does a NULL-check before invoking >> >> >> will delete it, thanks. >> >>> >>>> + >>>> +static void hibmc_ttm_backend_destroy(struct ttm_tt *tt) >>>> +{ >>>> + ttm_tt_fini(tt); >>>> + kfree(tt); >>>> +} >>>> + >>>> +static struct ttm_backend_func hibmc_tt_backend_func = { >>>> + .destroy = &hibmc_ttm_backend_destroy, >>>> +}; >>>> + >>>> +static struct ttm_tt *hibmc_ttm_tt_create(struct ttm_bo_device *bdev, >>>> + unsigned long size, >>>> + u32 page_flags, >>>> + struct page *dummy_read_page) >>>> +{ >>>> + struct ttm_tt *tt; >>>> + >>>> + tt = kzalloc(sizeof(*tt), GFP_KERNEL); >>>> + if (!tt) >>> >>> >>> Print error >> >> >> ok, will do that, thanks. >> >>> >>>> + return NULL; >>>> + tt->func = &hibmc_tt_backend_func; >>>> + if (ttm_tt_init(tt, bdev, size, page_flags, dummy_read_page)) { >>> >>> >>> Here too? >> >> >> ditto >> >> >>> >>>> + kfree(tt); >>>> + return NULL; >>>> + } >>>> + return tt; >>>> +} >>>> + >>>> +static int hibmc_ttm_tt_populate(struct ttm_tt *ttm) >>>> +{ >>>> + return ttm_pool_populate(ttm); >>>> +} >>>> + >>>> +static void hibmc_ttm_tt_unpopulate(struct ttm_tt *ttm) >>>> +{ >>>> + ttm_pool_unpopulate(ttm); >>>> +} >>>> + >>>> +struct ttm_bo_driver hibmc_bo_driver = { >>>> + .ttm_tt_create = hibmc_ttm_tt_create, >>>> + .ttm_tt_populate = hibmc_ttm_tt_populate, >>>> + .ttm_tt_unpopulate = hibmc_ttm_tt_unpopulate, >>>> + .init_mem_type = hibmc_bo_init_mem_type, >>>> + .evict_flags = hibmc_bo_evict_flags, >>>> + .move = NULL, >>>> + .verify_access = hibmc_bo_verify_access, >>>> + .io_mem_reserve = &hibmc_ttm_io_mem_reserve, >>>> + .io_mem_free = &hibmc_ttm_io_mem_free, >>>> + .lru_tail = &ttm_bo_default_lru_tail, >>>> + .swap_lru_tail = &ttm_bo_default_swap_lru_tail, >>>> +}; >>>> + >>>> +int hibmc_mm_init(struct hibmc_drm_device *hibmc) >>>> +{ >>>> + int ret; >>>> + struct drm_device *dev = hibmc->dev; >>>> + struct ttm_bo_device *bdev = &hibmc->ttm.bdev; >>>> + >>>> + ret = hibmc_ttm_global_init(hibmc); >>>> + if (ret) >>>> + return ret; >>>> + >>>> + ret = ttm_bo_device_init(&hibmc->ttm.bdev, >>>> + hibmc->ttm.bo_global_ref.ref.object, >>>> + &hibmc_bo_driver, >>>> + dev->anon_inode->i_mapping, >>>> + DRM_FILE_PAGE_OFFSET, >>>> + true); >>>> + if (ret) { >>> >>> >>> Call hibmc_ttm_global_release here? >> >> >> agreed, thanks for pointing it out. >> >>> >>>> + DRM_ERROR("Error initialising bo driver; %d\n", ret); >>>> + return ret; >>>> + } >>>> + >>>> + ret = ttm_bo_init_mm(bdev, TTM_PL_VRAM, >>>> + hibmc->fb_size >> PAGE_SHIFT); >>>> + if (ret) { >>> >>> >>> Clean up here as well? >> >> >> ditto >> >> >>> >>>> + DRM_ERROR("Failed ttm VRAM init: %d\n", ret); >>>> + return ret; >>>> + } >>>> + >>>> + hibmc->mm_inited = true; >>>> + return 0; >>>> +} >>>> + >>>> +void hibmc_mm_fini(struct hibmc_drm_device *hibmc) >>>> +{ >>>> + if (!hibmc->mm_inited) >>>> + return; >>>> + >>>> + ttm_bo_device_release(&hibmc->ttm.bdev); >>>> + hibmc_ttm_global_release(hibmc); >>>> + hibmc->mm_inited = false; >>>> +} >>>> + >>>> +int hibmc_bo_create(struct drm_device *dev, int size, int align, >>>> + u32 flags, struct hibmc_bo **phibmcbo) >>>> +{ >>>> + struct hibmc_drm_device *hibmc = dev->dev_private; >>>> + struct hibmc_bo *hibmcbo; >>>> + size_t acc_size; >>>> + int ret; >>>> + >>>> + hibmcbo = kzalloc(sizeof(*hibmcbo), GFP_KERNEL); >>>> + if (!hibmcbo) >>>> + return -ENOMEM; >>>> + >>>> + ret = drm_gem_object_init(dev, &hibmcbo->gem, size); >>>> + if (ret) { >>>> + kfree(hibmcbo); >>>> + return ret; >>>> + } >>>> + >>>> + hibmcbo->bo.bdev = &hibmc->ttm.bdev; >>>> + >>>> + hibmc_ttm_placement(hibmcbo, TTM_PL_FLAG_VRAM | >>>> TTM_PL_FLAG_SYSTEM); >>>> + >>>> + acc_size = ttm_bo_dma_acc_size(&hibmc->ttm.bdev, size, >>>> + sizeof(struct hibmc_bo)); >>>> + >>>> + ret = ttm_bo_init(&hibmc->ttm.bdev, &hibmcbo->bo, size, >>>> + ttm_bo_type_device, &hibmcbo->placement, >>>> + align >> PAGE_SHIFT, false, NULL, acc_size, >>>> + NULL, NULL, hibmc_bo_ttm_destroy); >>>> + if (ret) >>> >>> >>> Missing hibmcbo clean up here >> >> >> i looked at all other ttm drivers and all of them return directly when >> ttm_bo_init >> failed, however, i think it is better to clean up here, should i call >> hibmc_bo_unref(&hibmc_bo) here ? >> > > Yeah, that should work (might want to test it, though ;) > > >>> >>>> + return ret; >>>> + >>>> + *phibmcbo = hibmcbo; >>>> + return 0; >>>> +} >>>> + >>>> +static inline u64 hibmc_bo_gpu_offset(struct hibmc_bo *bo) >>>> +{ >>>> + return bo->bo.offset; >>>> +} >>> >>> >>> I don't think this function provides any value >> >> >> do you nean i use bo->bo.offset instead of calling hibmc_bo_gpu_offset()? >> > > yes > >>> >>>> + >>>> +int hibmc_bo_pin(struct hibmc_bo *bo, u32 pl_flag, u64 *gpu_addr) >>>> +{ >>>> + int i, ret; >>>> + >>>> + if (bo->pin_count) { >>>> + bo->pin_count++; >>>> + if (gpu_addr) >>>> + *gpu_addr = hibmc_bo_gpu_offset(bo); >>> >>> >>> Are you missing a return here? >> >> >> Thanks for pointing it out! >> >> >>> >>>> + } >>>> + >>>> + hibmc_ttm_placement(bo, pl_flag); >>>> + for (i = 0; i < bo->placement.num_placement; i++) >>>> + bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT; >>>> + ret = ttm_bo_validate(&bo->bo, &bo->placement, false, false); >>>> + if (ret) >>>> + return ret; >>>> + >>>> + bo->pin_count = 1; >>>> + if (gpu_addr) >>>> + *gpu_addr = hibmc_bo_gpu_offset(bo); >>>> + return 0; >>>> +} >>>> + >>>> +int hibmc_bo_push_sysram(struct hibmc_bo *bo) >>>> +{ >>>> + int i, ret; >>>> + >>>> + if (!bo->pin_count) { >>>> + DRM_ERROR("unpin bad %p\n", bo); >>>> + return 0; >>>> + } >>>> + bo->pin_count--; >>>> + if (bo->pin_count) >>>> + return 0; >>>> + >>>> + if (bo->kmap.virtual) >>> >>> >>> ttm_bo_kunmap already does this check so you don't have to >> >> >> agreed. will remove this condition. >> >>> >>>> + ttm_bo_kunmap(&bo->kmap); >>>> + >>>> + hibmc_ttm_placement(bo, TTM_PL_FLAG_SYSTEM); >>>> + for (i = 0; i < bo->placement.num_placement ; i++) >>>> + bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT; >>>> + >>>> + ret = ttm_bo_validate(&bo->bo, &bo->placement, false, false); >>>> + if (ret) { >>>> + DRM_ERROR("pushing to VRAM failed\n"); >>> >>> >>> Print ret >> >> >> ok, thanks. >> >> >>> >>>> + return ret; >>>> + } >>>> + return 0; >>>> +} >>>> + >>>> +int hibmc_mmap(struct file *filp, struct vm_area_struct *vma) >>>> +{ >>>> + struct drm_file *file_priv; >>>> + struct hibmc_drm_device *hibmc; >>>> + >>>> + if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET)) >>>> + return -EINVAL; >>>> + >>>> + file_priv = filp->private_data; >>>> + hibmc = file_priv->minor->dev->dev_private; >>>> + return ttm_bo_mmap(filp, vma, &hibmc->ttm.bdev); >>>> +} >>>> + >>>> +int hibmc_gem_create(struct drm_device *dev, u32 size, bool iskernel, >>>> + struct drm_gem_object **obj) >>>> +{ >>>> + struct hibmc_bo *hibmcbo; >>>> + int ret; >>>> + >>>> + *obj = NULL; >>>> + >>>> + size = PAGE_ALIGN(size); >>>> + if (size == 0) >>> >>> >>> Print error >> >> >> ditto >> >>> >>>> + return -EINVAL; >>>> + >>>> + ret = hibmc_bo_create(dev, size, 0, 0, &hibmcbo); >>>> + if (ret) { >>>> + if (ret != -ERESTARTSYS) >>>> + DRM_ERROR("failed to allocate GEM object\n"); >>> >>> >>> Print ret >> >> >> ditto >> >>> >>>> + return ret; >>>> + } >>>> + *obj = &hibmcbo->gem; >>>> + return 0; >>>> +} >>>> + >>>> +int hibmc_dumb_create(struct drm_file *file, struct drm_device *dev, >>>> + struct drm_mode_create_dumb *args) >>>> +{ >>>> + struct drm_gem_object *gobj; >>>> + u32 handle; >>>> + int ret; >>>> + >>>> + args->pitch = ALIGN(args->width * ((args->bpp + 7) / 8), 16); >>> >>> >>> What's up with the bpp + 7 here? Perhaps you're looking for DIV_ROUND_UP? >> >> >> Yes, that sounds sane. >> > > sane is what i usually aim for :) > > Sean > > >>> >>> >>>> + args->size = args->pitch * args->height; >>>> + >>>> + ret = hibmc_gem_create(dev, args->size, false, >>>> + &gobj); >>>> + if (ret) >>>> + return ret; >>>> + >>>> + ret = drm_gem_handle_create(file, gobj, &handle); >>>> + drm_gem_object_unreference_unlocked(gobj); >>>> + if (ret) >>> >>> >>> Print error here >> >> >> agreed. >> >> >>> >>>> + return ret; >>>> + >>>> + args->handle = handle; >>>> + return 0; >>>> +} >>>> + >>>> +static void hibmc_bo_unref(struct hibmc_bo **bo) >>>> +{ >>>> + struct ttm_buffer_object *tbo; >>>> + >>>> + if ((*bo) == NULL) >>>> + return; >>>> + >>>> + tbo = &((*bo)->bo); >>>> + ttm_bo_unref(&tbo); >>>> + *bo = NULL; >>>> +} >>>> + >>>> +void hibmc_gem_free_object(struct drm_gem_object *obj) >>>> +{ >>>> + struct hibmc_bo *hibmcbo = gem_to_hibmc_bo(obj); >>>> + >>>> + hibmc_bo_unref(&hibmcbo); >>>> +} >>>> + >>>> +static u64 hibmc_bo_mmap_offset(struct hibmc_bo *bo) >>>> +{ >>>> + return drm_vma_node_offset_addr(&bo->bo.vma_node); >>>> +} >>>> + >>>> +int hibmc_dumb_mmap_offset(struct drm_file *file, struct drm_device >>>> *dev, >>>> + u32 handle, u64 *offset) >>>> +{ >>>> + struct drm_gem_object *obj; >>>> + struct hibmc_bo *bo; >>>> + >>>> + obj = drm_gem_object_lookup(file, handle); >>>> + if (!obj) >>>> + return -ENOENT; >>>> + >>>> + bo = gem_to_hibmc_bo(obj); >>>> + *offset = hibmc_bo_mmap_offset(bo); >>>> + >>>> + drm_gem_object_unreference_unlocked(obj); >>>> + return 0; >>>> +} >> >> >> Regards, >> Rongrong. >> >>>> -- >>>> 1.9.1 >>>> >>>> >>>> _______________________________________________ >>>> linux-arm-kernel mailing list >>>> linux-arm-kernel at lists.infradead.org >>>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel >>> >>> _______________________________________________ >>> linuxarm mailing list >>> linuxarm at huawei.com >>> http://rnd-openeuler.huawei.com/mailman/listinfo/linuxarm >>> >>> . >>> >> >> >> _______________________________________________ >> linux-arm-kernel mailing list >> linux-arm-kernel at lists.infradead.org >> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel > > . > -- Regards, Rongrong From mboxrd@z Thu Jan 1 00:00:00 1970 From: Rongrong Zou Subject: Re: [PATCH v6 2/9] drm/hisilicon/hibmc: Add video memory management Date: Fri, 11 Nov 2016 21:57:56 +0800 Message-ID: <5825CE64.5080708@huawei.com> References: <1477639682-22520-1-git-send-email-zourongrong@gmail.com> <1477639682-22520-3-git-send-email-zourongrong@gmail.com> <5825A8A3.5070409@huawei.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8"; Format="flowed" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=m.gmane.org@lists.infradead.org To: Sean Paul Cc: Mark Rutland , Archit , lijianhua@huawei.com, Daniel Vetter , Tomeu Vizoso , Jonathan Corbet , Dave Airlie , catalin.marinas@arm.com, Emil Velikov , linuxarm@huawei.com, dri-devel , Xinliang Liu , james.xiong@huawei.com, shenhui@huawei.com, Rongrong Zou , Daniel Stone , Will Deacon , Linux ARM Kernel , Benjamin Gaignard List-Id: dri-devel@lists.freedesktop.org 5ZyoIDIwMTYvMTEvMTEgMjE6MjUsIFNlYW4gUGF1bCDlhpnpgZM6Cj4gT24gRnJpLCBOb3YgMTEs IDIwMTYgYXQgNjoxNiBBTSwgUm9uZ3JvbmcgWm91IDx6b3Vyb25ncm9uZ0BodWF3ZWkuY29tPiB3 cm90ZToKPj4g5ZyoIDIwMTYvMTEvMTEgMTozNSwgU2VhbiBQYXVsIOWGmemBkzoKPj4+Cj4+PiBP biBGcmksIE9jdCAyOCwgMjAxNiBhdCAzOjI3IEFNLCBSb25ncm9uZyBab3UgPHpvdXJvbmdyb25n QGdtYWlsLmNvbT4KPj4+IHdyb3RlOgo+Pj4+Cj4+Pj4gSGlibWMgaGF2ZSAzMm0gdmlkZW8gbWVt b3J5IHdoaWNoIGNhbiBiZSBhY2Nlc3NlZCB0aHJvdWdoIFBDSWUgYnkgaG9zdCwKPj4+PiB3ZSB1 c2UgdHRtIHRvIG1hbmFnZSB0aGVzZSBtZW1vcnkuCj4+Pj4KPj4+PiBTaWduZWQtb2ZmLWJ5OiBS b25ncm9uZyBab3UgPHpvdXJvbmdyb25nQGdtYWlsLmNvbT4KPj4+PiAtLS0KPj4+PiAgICBkcml2 ZXJzL2dwdS9kcm0vaGlzaWxpY29uL2hpYm1jL0tjb25maWcgICAgICAgICB8ICAgMSArCj4+Pj4g ICAgZHJpdmVycy9ncHUvZHJtL2hpc2lsaWNvbi9oaWJtYy9NYWtlZmlsZSAgICAgICAgfCAgIDIg Ky0KPj4+PiAgICBkcml2ZXJzL2dwdS9kcm0vaGlzaWxpY29uL2hpYm1jL2hpYm1jX2RybV9kcnYu YyB8ICAxMiArCj4+Pj4gICAgZHJpdmVycy9ncHUvZHJtL2hpc2lsaWNvbi9oaWJtYy9oaWJtY19k cm1fZHJ2LmggfCAgNDYgKysrCj4+Pj4gICAgZHJpdmVycy9ncHUvZHJtL2hpc2lsaWNvbi9oaWJt Yy9oaWJtY190dG0uYyAgICAgfCA0OTAKPj4+PiArKysrKysrKysrKysrKysrKysrKysrKysKPj4+ PiAgICA1IGZpbGVzIGNoYW5nZWQsIDU1MCBpbnNlcnRpb25zKCspLCAxIGRlbGV0aW9uKC0pCj4+ Pj4gICAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvZ3B1L2RybS9oaXNpbGljb24vaGlibWMv aGlibWNfdHRtLmMKPj4+Pgo+Pj4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vaGlzaWxp Y29uL2hpYm1jL0tjb25maWcKPj4+PiBiL2RyaXZlcnMvZ3B1L2RybS9oaXNpbGljb24vaGlibWMv S2NvbmZpZwo+Pj4+IGluZGV4IGE5YWY5MGQuLmJjYjhjMTggMTAwNjQ0Cj4+Pj4gLS0tIGEvZHJp dmVycy9ncHUvZHJtL2hpc2lsaWNvbi9oaWJtYy9LY29uZmlnCj4+Pj4gKysrIGIvZHJpdmVycy9n cHUvZHJtL2hpc2lsaWNvbi9oaWJtYy9LY29uZmlnCj4+Pj4gQEAgLTEsNiArMSw3IEBACj4+Pj4g ICAgY29uZmlnIERSTV9ISVNJX0hJQk1DCj4+Pj4gICAgICAgICAgIHRyaXN0YXRlICJEUk0gU3Vw cG9ydCBmb3IgSGlzaWxpY29uIEhpYm1jIgo+Pj4+ICAgICAgICAgICBkZXBlbmRzIG9uIERSTSAm JiBQQ0kKPj4+PiArICAgICAgIHNlbGVjdCBEUk1fVFRNCj4+Pj4KPj4+PiAgICAgICAgICAgaGVs cAo+Pj4+ICAgICAgICAgICAgIENob29zZSB0aGlzIG9wdGlvbiBpZiB5b3UgaGF2ZSBhIEhpc2ls aWNvbiBIaWJtYyBzb2MgY2hpcHNldC4KPj4+PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJt L2hpc2lsaWNvbi9oaWJtYy9NYWtlZmlsZQo+Pj4+IGIvZHJpdmVycy9ncHUvZHJtL2hpc2lsaWNv bi9oaWJtYy9NYWtlZmlsZQo+Pj4+IGluZGV4IDk3Y2Y0YTAuLmQ1YzQwYjggMTAwNjQ0Cj4+Pj4g LS0tIGEvZHJpdmVycy9ncHUvZHJtL2hpc2lsaWNvbi9oaWJtYy9NYWtlZmlsZQo+Pj4+ICsrKyBi L2RyaXZlcnMvZ3B1L2RybS9oaXNpbGljb24vaGlibWMvTWFrZWZpbGUKPj4+PiBAQCAtMSw1ICsx LDUgQEAKPj4+PiAgICBjY2ZsYWdzLXkgOj0gLUlpbmNsdWRlL2RybQo+Pj4+IC1oaWJtYy1kcm0t eSA6PSBoaWJtY19kcm1fZHJ2Lm8gaGlibWNfZHJtX3Bvd2VyLm8KPj4+PiAraGlibWMtZHJtLXkg Oj0gaGlibWNfZHJtX2Rydi5vIGhpYm1jX2RybV9wb3dlci5vIGhpYm1jX3R0bS5vCj4+Pj4KPj4+ PiAgICBvYmotJChDT05GSUdfRFJNX0hJU0lfSElCTUMpICAgKz1oaWJtYy1kcm0ubwo+Pj4+ICAg ICNvYmoteSArPSBoaWJtYy1kcm0ubwo+Pj4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0v aGlzaWxpY29uL2hpYm1jL2hpYm1jX2RybV9kcnYuYwo+Pj4+IGIvZHJpdmVycy9ncHUvZHJtL2hp c2lsaWNvbi9oaWJtYy9oaWJtY19kcm1fZHJ2LmMKPj4+PiBpbmRleCA0NjY5ZDQyLi44MWY0MzAx IDEwMDY0NAo+Pj4+IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS9oaXNpbGljb24vaGlibWMvaGlibWNf ZHJtX2Rydi5jCj4+Pj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL2hpc2lsaWNvbi9oaWJtYy9oaWJt Y19kcm1fZHJ2LmMKPj4+PiBAQCAtMzEsNiArMzEsNyBAQAo+Pj4+ICAgICNpZmRlZiBDT05GSUdf Q09NUEFUCj4+Pj4gICAgICAgICAgIC5jb21wYXRfaW9jdGwgICA9IGRybV9jb21wYXRfaW9jdGws Cj4+Pj4gICAgI2VuZGlmCj4+Pj4gKyAgICAgICAubW1hcCAgICAgICAgICAgPSBoaWJtY19tbWFw LAo+Pj4+ICAgICAgICAgICAucG9sbCAgICAgICAgICAgPSBkcm1fcG9sbCwKPj4+PiAgICAgICAg ICAgLnJlYWQgICAgICAgICAgID0gZHJtX3JlYWQsCj4+Pj4gICAgICAgICAgIC5sbHNlZWsgICAg ICAgICA9IG5vX2xsc2VlaywKPj4+PiBAQCAtNDYsNiArNDcsOCBAQCBzdGF0aWMgdm9pZCBoaWJt Y19kaXNhYmxlX3ZibGFuayhzdHJ1Y3QgZHJtX2RldmljZQo+Pj4+ICpkZXYsIHVuc2lnbmVkIGlu dCBwaXBlKQo+Pj4+ICAgIH0KPj4+Pgo+Pj4+ICAgIHN0YXRpYyBzdHJ1Y3QgZHJtX2RyaXZlciBo aWJtY19kcml2ZXIgPSB7Cj4+Pj4gKyAgICAgICAuZHJpdmVyX2ZlYXR1cmVzICAgICAgICA9IERS SVZFUl9HRU0sCj4+Pj4gKwo+Pj4KPj4+Cj4+PiBuaXQ6IGV4dHJhIHNwYWNlCj4+Pgo+Pj4+ICAg ICAgICAgICAuZm9wcyAgICAgICAgICAgICAgICAgICA9ICZoaWJtY19mb3BzLAo+Pj4+ICAgICAg ICAgICAubmFtZSAgICAgICAgICAgICAgICAgICA9ICJoaWJtYyIsCj4+Pj4gICAgICAgICAgIC5k YXRlICAgICAgICAgICAgICAgICAgID0gIjIwMTYwODI4IiwKPj4+PiBAQCAtNTUsNiArNTgsMTAg QEAgc3RhdGljIHZvaWQgaGlibWNfZGlzYWJsZV92Ymxhbmsoc3RydWN0IGRybV9kZXZpY2UKPj4+ PiAqZGV2LCB1bnNpZ25lZCBpbnQgcGlwZSkKPj4+PiAgICAgICAgICAgLmdldF92YmxhbmtfY291 bnRlciAgICAgPSBkcm1fdmJsYW5rX25vX2h3X2NvdW50ZXIsCj4+Pj4gICAgICAgICAgIC5lbmFi bGVfdmJsYW5rICAgICAgICAgID0gaGlibWNfZW5hYmxlX3ZibGFuaywKPj4+PiAgICAgICAgICAg LmRpc2FibGVfdmJsYW5rICAgICAgICAgPSBoaWJtY19kaXNhYmxlX3ZibGFuaywKPj4+PiArICAg ICAgIC5nZW1fZnJlZV9vYmplY3RfdW5sb2NrZWQgPSBoaWJtY19nZW1fZnJlZV9vYmplY3QsCj4+ Pj4gKyAgICAgICAuZHVtYl9jcmVhdGUgICAgICAgICAgICA9IGhpYm1jX2R1bWJfY3JlYXRlLAo+ Pj4+ICsgICAgICAgLmR1bWJfbWFwX29mZnNldCAgICAgICAgPSBoaWJtY19kdW1iX21tYXBfb2Zm c2V0LAo+Pj4+ICsgICAgICAgLmR1bWJfZGVzdHJveSAgICAgICAgICAgPSBkcm1fZ2VtX2R1bWJf ZGVzdHJveSwKPj4+PiAgICB9Owo+Pj4+Cj4+Pj4gICAgc3RhdGljIGludCBoaWJtY19wbV9zdXNw ZW5kKHN0cnVjdCBkZXZpY2UgKmRldikKPj4+PiBAQCAtMTYzLDYgKzE3MCw3IEBAIHN0YXRpYyBp bnQgaGlibWNfdW5sb2FkKHN0cnVjdCBkcm1fZGV2aWNlICpkZXYpCj4+Pj4gICAgewo+Pj4+ICAg ICAgICAgICBzdHJ1Y3QgaGlibWNfZHJtX2RldmljZSAqaGlkZXYgPSBkZXYtPmRldl9wcml2YXRl Owo+Pj4+Cj4+Pj4gKyAgICAgICBoaWJtY19tbV9maW5pKGhpZGV2KTsKPj4+PiAgICAgICAgICAg aGlibWNfaHdfZmluaShoaWRldik7Cj4+Pj4gICAgICAgICAgIGRldi0+ZGV2X3ByaXZhdGUgPSBO VUxMOwo+Pj4+ICAgICAgICAgICByZXR1cm4gMDsKPj4+PiBAQCAtMTgzLDYgKzE5MSwxMCBAQCBz dGF0aWMgaW50IGhpYm1jX2xvYWQoc3RydWN0IGRybV9kZXZpY2UgKmRldiwKPj4+PiB1bnNpZ25l ZCBsb25nIGZsYWdzKQo+Pj4+ICAgICAgICAgICBpZiAocmV0KQo+Pj4+ICAgICAgICAgICAgICAg ICAgIGdvdG8gZXJyOwo+Pj4+Cj4+Pj4gKyAgICAgICByZXQgPSBoaWJtY19tbV9pbml0KGhpZGV2 KTsKPj4+PiArICAgICAgIGlmIChyZXQpCj4+Pj4gKyAgICAgICAgICAgICAgIGdvdG8gZXJyOwo+ Pj4+ICsKPj4+PiAgICAgICAgICAgcmV0dXJuIDA7Cj4+Pj4KPj4+PiAgICBlcnI6Cj4+Pj4gZGlm ZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9oaXNpbGljb24vaGlibWMvaGlibWNfZHJtX2Rydi5o Cj4+Pj4gYi9kcml2ZXJzL2dwdS9kcm0vaGlzaWxpY29uL2hpYm1jL2hpYm1jX2RybV9kcnYuaAo+ Pj4+IGluZGV4IDAwMzczNDEuLmRiOGQ4MGUgMTAwNjQ0Cj4+Pj4gLS0tIGEvZHJpdmVycy9ncHUv ZHJtL2hpc2lsaWNvbi9oaWJtYy9oaWJtY19kcm1fZHJ2LmgKPj4+PiArKysgYi9kcml2ZXJzL2dw dS9kcm0vaGlzaWxpY29uL2hpYm1jL2hpYm1jX2RybV9kcnYuaAo+Pj4+IEBAIC0yMCw2ICsyMCw4 IEBACj4+Pj4gICAgI2RlZmluZSBISUJNQ19EUk1fRFJWX0gKPj4+Pgo+Pj4+ICAgICNpbmNsdWRl IDxkcm0vZHJtUC5oPgo+Pj4+ICsjaW5jbHVkZSA8ZHJtL3R0bS90dG1fYm9fZHJpdmVyLmg+Cj4+ Pj4gKyNpbmNsdWRlIDxkcm0vZHJtX2dlbS5oPgo+Pj4KPj4+Cj4+PiBuaXQ6IGFscGhhYmV0aXpl Cj4+Cj4+Cj4+IHdpbGwgZml4IGl0LCB0aGFua3MuCj4+Cj4+Pgo+Pj4+Cj4+Pj4gICAgc3RydWN0 IGhpYm1jX2RybV9kZXZpY2Ugewo+Pj4+ICAgICAgICAgICAvKiBodyAqLwo+Pj4+IEBAIC0zMCw2 ICszMiw1MCBAQCBzdHJ1Y3QgaGlibWNfZHJtX2RldmljZSB7Cj4+Pj4KPj4+PiAgICAgICAgICAg LyogZHJtICovCj4+Pj4gICAgICAgICAgIHN0cnVjdCBkcm1fZGV2aWNlICAqZGV2Owo+Pj4+ICsK Pj4+PiArICAgICAgIC8qIHR0bSAqLwo+Pj4+ICsgICAgICAgc3RydWN0IHsKPj4+PiArICAgICAg ICAgICAgICAgc3RydWN0IGRybV9nbG9iYWxfcmVmZXJlbmNlIG1lbV9nbG9iYWxfcmVmOwo+Pj4+ ICsgICAgICAgICAgICAgICBzdHJ1Y3QgdHRtX2JvX2dsb2JhbF9yZWYgYm9fZ2xvYmFsX3JlZjsK Pj4+PiArICAgICAgICAgICAgICAgc3RydWN0IHR0bV9ib19kZXZpY2UgYmRldjsKPj4+PiArICAg ICAgICAgICAgICAgYm9vbCBpbml0aWFsaXplZDsKPj4+PiArICAgICAgIH0gdHRtOwo+Pj4KPj4+ Cj4+PiBJIGRvbid0IHRoaW5rIHlvdSBnYWluIGFueXRoaW5nIG90aGVyIHRoYW4ga2V5c3Ryb2tl cyBmcm9tIHRoZSBzdWJzdHJ1Y3QKPj4KPj4KPj4gSSdtIHNvcnJ5IGkgZGlkbid0IGNhdGNoIHlv dSwgaSBsb29rZWQgYXQgdGhlIGFsbCBkcml2ZXJzIHVzZWQgdHRtIHN1Y2gKPj4gYXMgYXN0L2Jv Y2hzL2NpcnJ1cy9tZ2FnMjAwL3F4bC92aXJ0aW9fZ3B1LCB0aGV5IGFsbCBlbWJlZGRlZCB0aGUg dHRtCj4+IHN1YnN0cnVjdAo+PiBpbnRvIHRoZSBkcml2ZXItcHJpdmF0ZSBzdHJ1Y3QuCj4+Cj4+ IHNvIGRvIHlvdSBtZWFuCj4+IHN0cnVjdCBoaWJtY19kcm1fZGV2aWNlIHsKPj4gICAgICAgICAg LyogaHcgKi8KPj4gICAgICAgICAgdm9pZCBfX2lvbWVtICAgKm1taW87Cj4+ICAgICAgICAgIHZv aWQgX19pb21lbSAgICpmYl9tYXA7Cj4+ICAgICAgICAgIHVuc2lnbmVkIGxvbmcgIGZiX2Jhc2U7 Cj4+ICAgICAgICAgIHVuc2lnbmVkIGxvbmcgIGZiX3NpemU7Cj4+Cj4+ICAgICAgICAgIC8qIGRy bSAqLwo+PiAgICAgICAgICBzdHJ1Y3QgZHJtX2RldmljZSAgKmRldjsKPj4gICAgICAgICAgc3Ry dWN0IGRybV9wbGFuZSBwbGFuZTsKPj4gICAgICAgICAgc3RydWN0IGRybV9jcnRjIGNydGM7Cj4+ ICAgICAgICAgIHN0cnVjdCBkcm1fZW5jb2RlciBlbmNvZGVyOwo+PiAgICAgICAgICBzdHJ1Y3Qg ZHJtX2Nvbm5lY3RvciBjb25uZWN0b3I7Cj4+ICAgICAgICAgIGJvb2wgbW9kZV9jb25maWdfaW5p dGlhbGl6ZWQ7Cj4+Cj4+ICAgICAgICAgIC8qIHR0bSAqLwo+PiAgICAgICAgICBzdHJ1Y3QgZHJt X2dsb2JhbF9yZWZlcmVuY2UgbWVtX2dsb2JhbF9yZWY7Cj4+ICAgICAgICAgIHN0cnVjdCB0dG1f Ym9fZ2xvYmFsX3JlZiBib19nbG9iYWxfcmVmOwo+PiAgICAgICAgICBzdHJ1Y3QgdHRtX2JvX2Rl dmljZSBiZGV2Owo+PiAgICAgICAgICBib29sIGluaXRpYWxpemVkOwo+PiAgICAgICAgICAuLi4K Pj4gICAgICAgICAgfTsKPj4gPwo+Cj4gWWVhaCwgdGhhdCdzIHdoYXQgSSB3YXMgdGhpbmtpbmcK Pgo+Pgo+Pj4KPj4+PiArCj4+Pj4gKyAgICAgICBib29sIG1tX2luaXRlZDsKPj4+PiAgICB9Owo+ Pj4+Cj4+Pj4gK3N0cnVjdCBoaWJtY19ibyB7Cj4+Pj4gKyAgICAgICBzdHJ1Y3QgdHRtX2J1ZmZl cl9vYmplY3QgYm87Cj4+Pj4gKyAgICAgICBzdHJ1Y3QgdHRtX3BsYWNlbWVudCBwbGFjZW1lbnQ7 Cj4+Pj4gKyAgICAgICBzdHJ1Y3QgdHRtX2JvX2ttYXBfb2JqIGttYXA7Cj4+Pj4gKyAgICAgICBz dHJ1Y3QgZHJtX2dlbV9vYmplY3QgZ2VtOwo+Pj4+ICsgICAgICAgc3RydWN0IHR0bV9wbGFjZSBw bGFjZW1lbnRzWzNdOwo+Pj4+ICsgICAgICAgaW50IHBpbl9jb3VudDsKPj4+PiArfTsKPj4+PiAr Cj4+Pj4gK3N0YXRpYyBpbmxpbmUgc3RydWN0IGhpYm1jX2JvICpoaWJtY19ibyhzdHJ1Y3QgdHRt X2J1ZmZlcl9vYmplY3QgKmJvKQo+Pj4+ICt7Cj4+Pj4gKyAgICAgICByZXR1cm4gY29udGFpbmVy X29mKGJvLCBzdHJ1Y3QgaGlibWNfYm8sIGJvKTsKPj4+PiArfQo+Pj4+ICsKPj4+PiArc3RhdGlj IGlubGluZSBzdHJ1Y3QgaGlibWNfYm8gKmdlbV90b19oaWJtY19ibyhzdHJ1Y3QgZHJtX2dlbV9v YmplY3QKPj4+PiAqZ2VtKQo+Pj4+ICt7Cj4+Pj4gKyAgICAgICByZXR1cm4gY29udGFpbmVyX29m KGdlbSwgc3RydWN0IGhpYm1jX2JvLCBnZW0pOwo+Pj4+ICt9Cj4+Pj4gKwo+Pj4+ICsjZGVmaW5l IERSTV9GSUxFX1BBR0VfT0ZGU0VUICgweDEwMDAwMDAwMFVMTCA+PiBQQUdFX1NISUZUKQo+Pj4K Pj4+Cj4+PiBIaWRlIHRoaXMgaW4gdHRtLmMKPj4KPj4KPj4gb2ssIHdpbGwgZG8gdGhhdC4KPj4g dGhhbmtzIGZvciBwb2ludGluZyBpdCBvdXQuCj4+Cj4+Cj4+Pgo+Pj4+ICsKPj4+PiAraW50IGhp Ym1jX2dlbV9jcmVhdGUoc3RydWN0IGRybV9kZXZpY2UgKmRldiwgdTMyIHNpemUsIGJvb2wgaXNr ZXJuZWwsCj4+Pj4gKyAgICAgICAgICAgICAgICAgICAgc3RydWN0IGRybV9nZW1fb2JqZWN0ICoq b2JqKTsKPj4+PiArCj4+Pj4gK2ludCBoaWJtY19tbV9pbml0KHN0cnVjdCBoaWJtY19kcm1fZGV2 aWNlICpoaWJtYyk7Cj4+Pj4gK3ZvaWQgaGlibWNfbW1fZmluaShzdHJ1Y3QgaGlibWNfZHJtX2Rl dmljZSAqaGlibWMpOwo+Pj4+ICtpbnQgaGlibWNfYm9fcGluKHN0cnVjdCBoaWJtY19ibyAqYm8s IHUzMiBwbF9mbGFnLCB1NjQgKmdwdV9hZGRyKTsKPj4+PiArdm9pZCBoaWJtY19nZW1fZnJlZV9v YmplY3Qoc3RydWN0IGRybV9nZW1fb2JqZWN0ICpvYmopOwo+Pj4+ICtpbnQgaGlibWNfZHVtYl9j cmVhdGUoc3RydWN0IGRybV9maWxlICpmaWxlLCBzdHJ1Y3QgZHJtX2RldmljZSAqZGV2LAo+Pj4+ ICsgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgZHJtX21vZGVfY3JlYXRlX2R1bWIgKmFyZ3Mp Owo+Pj4+ICtpbnQgaGlibWNfZHVtYl9tbWFwX29mZnNldChzdHJ1Y3QgZHJtX2ZpbGUgKmZpbGUs IHN0cnVjdCBkcm1fZGV2aWNlCj4+Pj4gKmRldiwKPj4+PiArICAgICAgICAgICAgICAgICAgICAg ICAgICB1MzIgaGFuZGxlLCB1NjQgKm9mZnNldCk7Cj4+Pj4gK2ludCBoaWJtY19tbWFwKHN0cnVj dCBmaWxlICpmaWxwLCBzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKnZtYSk7Cj4+Pj4gKwo+Pj4+ICAg ICNlbmRpZgo+Pj4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vaGlzaWxpY29uL2hpYm1j L2hpYm1jX3R0bS5jCj4+Pj4gYi9kcml2ZXJzL2dwdS9kcm0vaGlzaWxpY29uL2hpYm1jL2hpYm1j X3R0bS5jCj4+Pj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQKPj4+PiBpbmRleCAwMDAwMDAwLi4wODAy ZWJkCj4+Pj4gLS0tIC9kZXYvbnVsbAo+Pj4+ICsrKyBiL2RyaXZlcnMvZ3B1L2RybS9oaXNpbGlj b24vaGlibWMvaGlibWNfdHRtLmMKPj4+PiBAQCAtMCwwICsxLDQ5MCBAQAo+Pj4+ICsvKiBIaXNp bGljb24gSGlibWMgU29DIGRybSBkcml2ZXIKPj4+PiArICoKPj4+PiArICogQmFzZWQgb24gdGhl IGJvY2hzIGRybSBkcml2ZXIuCj4+Pj4gKyAqCj4+Pj4gKyAqIENvcHlyaWdodCAoYykgMjAxNiBI dWF3ZWkgTGltaXRlZC4KPj4+PiArICoKPj4+PiArICogQXV0aG9yOgo+Pj4+ICsgKiAgICAgUm9u Z3JvbmcgWm91IDx6b3Vyb25ncm9uZ0BodWF3ZWkuY29tPgo+Pj4+ICsgKiAgICAgUm9uZ3Jvbmcg Wm91IDx6b3Vyb25ncm9uZ0BnbWFpbC5jb20+Cj4+Pj4gKyAqICAgICBKaWFuaHVhIExpIDxsaWpp YW5odWFAaHVhd2VpLmNvbT4KPj4+PiArICoKPj4+PiArICogVGhpcyBwcm9ncmFtIGlzIGZyZWUg c29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKPj4+PiArICog aXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBw dWJsaXNoZWQgYnkKPj4+PiArICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVy IHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IKPj4+PiArICogKGF0IHlvdXIgb3B0aW9uKSBh bnkgbGF0ZXIgdmVyc2lvbi4KPj4+PiArICoKPj4+PiArICovCj4+Pj4gKwo+Pj4+ICsjaW5jbHVk ZSAiaGlibWNfZHJtX2Rydi5oIgo+Pj4+ICsjaW5jbHVkZSA8dHRtL3R0bV9wYWdlX2FsbG9jLmg+ Cj4+Pj4gKyNpbmNsdWRlIDxkcm0vZHJtX2NydGNfaGVscGVyLmg+Cj4+Pj4gKyNpbmNsdWRlIDxk cm0vZHJtX2F0b21pY19oZWxwZXIuaD4KPj4+PiArCj4+Pj4gK3N0YXRpYyBpbmxpbmUgc3RydWN0 IGhpYm1jX2RybV9kZXZpY2UgKgo+Pj4+ICtoaWJtY19iZGV2KHN0cnVjdCB0dG1fYm9fZGV2aWNl ICpiZCkKPj4+PiArewo+Pj4+ICsgICAgICAgcmV0dXJuIGNvbnRhaW5lcl9vZihiZCwgc3RydWN0 IGhpYm1jX2RybV9kZXZpY2UsIHR0bS5iZGV2KTsKPj4+PiArfQo+Pj4+ICsKPj4+PiArc3RhdGlj IGludAo+Pj4+ICtoaWJtY190dG1fbWVtX2dsb2JhbF9pbml0KHN0cnVjdCBkcm1fZ2xvYmFsX3Jl ZmVyZW5jZSAqcmVmKQo+Pj4+ICt7Cj4+Pj4gKyAgICAgICByZXR1cm4gdHRtX21lbV9nbG9iYWxf aW5pdChyZWYtPm9iamVjdCk7Cj4+Pj4gK30KPj4+PiArCj4+Pj4gK3N0YXRpYyB2b2lkCj4+Pj4g K2hpYm1jX3R0bV9tZW1fZ2xvYmFsX3JlbGVhc2Uoc3RydWN0IGRybV9nbG9iYWxfcmVmZXJlbmNl ICpyZWYpCj4+Pj4gK3sKPj4+PiArICAgICAgIHR0bV9tZW1fZ2xvYmFsX3JlbGVhc2UocmVmLT5v YmplY3QpOwo+Pj4+ICt9Cj4+Pj4gKwo+Pj4+ICtzdGF0aWMgaW50IGhpYm1jX3R0bV9nbG9iYWxf aW5pdChzdHJ1Y3QgaGlibWNfZHJtX2RldmljZSAqaGlibWMpCj4+Pj4gK3sKPj4+PiArICAgICAg IHN0cnVjdCBkcm1fZ2xvYmFsX3JlZmVyZW5jZSAqZ2xvYmFsX3JlZjsKPj4+PiArICAgICAgIGlu dCByOwo+Pj4KPj4+Cj4+PiBuaXQ6IHRyeSBub3QgdG8gdXNlIG9uZSBjaGFyYWN0ZXIgdmFyaWFi bGUgbmFtZXMgdW5sZXNzIGl0J3MgZm9yIHRoZQo+Pj4gcHVycG9zZSBvZiBhIGxvb3AgKGllOiBp LGopLiBZb3UgYWxzbyB1c2UgcmV0IGVsc2V3aGVyZSBpbiB0aGUgZHJpdmVyLAo+Pj4gc28gaXQn ZCBiZSBuaWNlIHRvIHJlbWFpbiBjb25zaXN0ZW50Cj4+Cj4+Cj4+IHRoZSB3aG9sZSBmaWxlIGlz IGRlbGl2ZXJlZCBmcm9tIGJvY2hzIHR0bSwgaSBkaWRuJ3QgbW9kaWZ5IGFueXRoaW5nIGV4Y2Vw dAo+PiBzb21lIGNoZWNrcGF0Y2ggd2FybmluZ3MgYW5kIHRoZSAnaGlibWNfJyBwcmVmaXguIFVu Zm9ydHVuYXRlbHksIHNvbWUKPj4gcHJvYmxlbXMgd2VyZSBkZWxpdmVyZWQgdG9vLgo+Cj4gWWVh aCwgc2VlbXMgbGlrZSBpdC4gUGVyaGFwcyB5b3UgY2FuIHBvc3QgcGF0Y2hlcyB0byBmaXggdGhl c2UgaXNzdWVzCj4gaW4gdGhlIG90aGVyIGRyaXZlcnMgdG9vIDopCgppIHdpbGwgZG8gYWZ0ZXIg dGhlIHRoaXMgb25lIGdldCBtZXJnZWQgOikKCj4KPj4KPj4+Cj4+Pj4gKwo+Pj4+ICsgICAgICAg Z2xvYmFsX3JlZiA9ICZoaWJtYy0+dHRtLm1lbV9nbG9iYWxfcmVmOwo+Pj4KPj4+Cj4+PiBJIHRo aW5rIHVzaW5nIHRoZSBnbG9iYWxfcmVmIGxvY2FsIG9iZnVzY2F0ZXMgd2hhdCB5b3UncmUgZG9p bmcgaGVyZS4KPj4+IEl0IHNhdmVzIHlvdSA2IGNoYXJhY3RlcnMgd2hpbGUgdHlwaW5nLCBidXQg YWRkcyBhIGxheWVyIG9mCj4+PiBpbmRpcmVjdGlvbiBmb3IgYWxsIGZ1dHVyZSByZWFkZXJzLgo+ Pj4KPj4+PiArICAgICAgIGdsb2JhbF9yZWYtPmdsb2JhbF90eXBlID0gRFJNX0dMT0JBTF9UVE1f TUVNOwo+Pj4+ICsgICAgICAgZ2xvYmFsX3JlZi0+c2l6ZSA9IHNpemVvZihzdHJ1Y3QgdHRtX21l bV9nbG9iYWwpOwo+Pj4+ICsgICAgICAgZ2xvYmFsX3JlZi0+aW5pdCA9ICZoaWJtY190dG1fbWVt X2dsb2JhbF9pbml0Owo+Pj4+ICsgICAgICAgZ2xvYmFsX3JlZi0+cmVsZWFzZSA9ICZoaWJtY190 dG1fbWVtX2dsb2JhbF9yZWxlYXNlOwo+Pj4+ICsgICAgICAgciA9IGRybV9nbG9iYWxfaXRlbV9y ZWYoZ2xvYmFsX3JlZik7Cj4+Pj4gKyAgICAgICBpZiAociAhPSAwKSB7Cj4+Pgo+Pj4KPj4+IG5p dDogaWYgKHIpCj4+Cj4+Cj4+IHdpbGwgZml4IGl0LAo+PiB0aGFua3MuCj4+IEJUVywgaSB3b25k ZXIgd2h5IGNoZWNrcGF0Y2gucGwgZGlkbid0IHJlcG9ydCBpdC4KPj4KPj4KPj4+Cj4+Pj4gKyAg ICAgICAgICAgICAgIERSTV9FUlJPUigiRmFpbGVkIHNldHRpbmcgdXAgVFRNIG1lbW9yeSBhY2Nv dW50aW5nCj4+Pj4gc3Vic3lzdGVtLlxuIgo+Pj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAp Owo+Pj4KPj4+Cj4+PiBCcmVha2luZyB1cCB0aGUgbGluZSBmb3Igb25lIGNoYXJhY3RlciBpcyBw cm9iYWJseSBub3Qgd29ydGh3aGlsZSwgYW5kCj4+PiB5b3Ugc2hvdWxkIHJlYWxseSBwcmludCB0 aGUgZXJyb3IuIEhvdyBhYm91dDoKPj4+Cj4+PiBEUk1fRVJST1IoIkNvdWxkIG5vdCBnZXQgcmVm IG9uIHR0bSBnbG9iYWwgcmV0PSVkLlxuIiwgcmV0KTsKPj4KPj4KPj4gaSBsaWtlIHlvdXIgc29s dXRpb24sIHRoYW5rcy4KPj4KPj4KPj4+Cj4+Pgo+Pj4+ICsgICAgICAgICAgICAgICByZXR1cm4g cjsKPj4+PiArICAgICAgIH0KPj4+PiArCj4+Pj4gKyAgICAgICBoaWJtYy0+dHRtLmJvX2dsb2Jh bF9yZWYubWVtX2dsb2IgPQo+Pj4+ICsgICAgICAgICAgICAgICBoaWJtYy0+dHRtLm1lbV9nbG9i YWxfcmVmLm9iamVjdDsKPj4+PiArICAgICAgIGdsb2JhbF9yZWYgPSAmaGlibWMtPnR0bS5ib19n bG9iYWxfcmVmLnJlZjsKPj4+PiArICAgICAgIGdsb2JhbF9yZWYtPmdsb2JhbF90eXBlID0gRFJN X0dMT0JBTF9UVE1fQk87Cj4+Pj4gKyAgICAgICBnbG9iYWxfcmVmLT5zaXplID0gc2l6ZW9mKHN0 cnVjdCB0dG1fYm9fZ2xvYmFsKTsKPj4+PiArICAgICAgIGdsb2JhbF9yZWYtPmluaXQgPSAmdHRt X2JvX2dsb2JhbF9pbml0Owo+Pj4+ICsgICAgICAgZ2xvYmFsX3JlZi0+cmVsZWFzZSA9ICZ0dG1f Ym9fZ2xvYmFsX3JlbGVhc2U7Cj4+Pj4gKyAgICAgICByID0gZHJtX2dsb2JhbF9pdGVtX3JlZihn bG9iYWxfcmVmKTsKPj4+PiArICAgICAgIGlmIChyICE9IDApIHsKPj4+PiArICAgICAgICAgICAg ICAgRFJNX0VSUk9SKCJGYWlsZWQgc2V0dGluZyB1cCBUVE0gQk8gc3Vic3lzdGVtLlxuIik7Cj4+ Pj4gKyAgICAgICAgICAgICAgIGRybV9nbG9iYWxfaXRlbV91bnJlZigmaGlibWMtPnR0bS5tZW1f Z2xvYmFsX3JlZik7Cj4+Pj4gKyAgICAgICAgICAgICAgIHJldHVybiByOwo+Pj4+ICsgICAgICAg fQo+Pj4+ICsgICAgICAgcmV0dXJuIDA7Cj4+Pj4gK30KPj4+PiArCj4+Pj4gK3N0YXRpYyB2b2lk Cj4+Pj4gK2hpYm1jX3R0bV9nbG9iYWxfcmVsZWFzZShzdHJ1Y3QgaGlibWNfZHJtX2RldmljZSAq aGlibWMpCj4+Pj4gK3sKPj4+PiArICAgICAgIGlmICghaGlibWMtPnR0bS5tZW1fZ2xvYmFsX3Jl Zi5yZWxlYXNlKQo+Pj4KPj4+Cj4+PiBBcmUgeW91IGFjdHVhbGx5IGhpdHRpbmcgdGhpcyBjb25k aXRpb24/IFRoaXMgc2VlbXMgbGlrZSBpdCdzIHBhcGVyaW5nCj4+PiBvdmVyIHNvbWV0aGluZyBl bHNlLgo+Pgo+Pgo+PiBpdCB3YXMgYWxzbyBkZWxpdmVyZWQgZnJvbSBvdGhlcnMsIGkgbG9va2Vk IGF0IHRoZSB4eHhfdHRtX2dsb2JhbF9pbml0Cj4+IGZ1bmN0aW9uLCAnbWVtX2dsb2JhbF9yZWYu cmVsZWFzZScgaXMgYXNzaWduZWQgdW5jb25kaXRpb25hbGx5LCBzbyBpCj4+IHRoaW5rIHRoaXMg Y29uZGl0aW9uIG5ldmVyIGJlIGhpdCwgaXQgbWF5IGJlIGhpdCB3aGVuIHJlbGVhc2UgdHdpY2Us Cj4+IGJ1dCB0aGlzIHdvbid0IHRha2UgcGxhY2UgaW4gbXkgZHJpdmVyLgo+Pgo+Cj4gWWVhaCwg dGhhdCdzIHdoYXQgSSB3YXMgaG9waW5nIGZvci4gU28gcGVyaGFwcyB3ZSBjYW4gcmVtb3ZlIHRo aXM/Cgp5ZXMsIHdlIGNhbi4KClJlZ2FyZHMsClJvbmdyb25nLgoKPgo+Pj4KPj4+PiArICAgICAg ICAgICAgICAgcmV0dXJuOwo+Pj4+ICsKPj4+PiArICAgICAgIGRybV9nbG9iYWxfaXRlbV91bnJl ZigmaGlibWMtPnR0bS5ib19nbG9iYWxfcmVmLnJlZik7Cj4+Pj4gKyAgICAgICBkcm1fZ2xvYmFs X2l0ZW1fdW5yZWYoJmhpYm1jLT50dG0ubWVtX2dsb2JhbF9yZWYpOwo+Pj4+ICsgICAgICAgaGli bWMtPnR0bS5tZW1fZ2xvYmFsX3JlZi5yZWxlYXNlID0gTlVMTDsKPj4+PiArfQo+Pj4+ICsKPj4+ PiArc3RhdGljIHZvaWQgaGlibWNfYm9fdHRtX2Rlc3Ryb3koc3RydWN0IHR0bV9idWZmZXJfb2Jq ZWN0ICp0Ym8pCj4+Pj4gK3sKPj4+PiArICAgICAgIHN0cnVjdCBoaWJtY19ibyAqYm87Cj4+Pj4g Kwo+Pj4+ICsgICAgICAgYm8gPSBjb250YWluZXJfb2YodGJvLCBzdHJ1Y3QgaGlibWNfYm8sIGJv KTsKPj4+Cj4+Pgo+Pj4gbml0OiBObyBuZWVkIHRvIHNwbGl0IHRoaXMgaW50byBhIHNlcGFyYXRl IGxpbmUuCj4+Cj4+Cj4+IGFncmVlZCwgdGhhbmtzLgo+Pgo+Pj4KPj4+PiArCj4+Pj4gKyAgICAg ICBkcm1fZ2VtX29iamVjdF9yZWxlYXNlKCZiby0+Z2VtKTsKPj4+PiArICAgICAgIGtmcmVlKGJv KTsKPj4+PiArfQo+Pj4+ICsKPj4+PiArc3RhdGljIGJvb2wgaGlibWNfdHRtX2JvX2lzX2hpYm1j X2JvKHN0cnVjdCB0dG1fYnVmZmVyX29iamVjdCAqYm8pCj4+Pj4gK3sKPj4+PiArICAgICAgIGlm IChiby0+ZGVzdHJveSA9PSAmaGlibWNfYm9fdHRtX2Rlc3Ryb3kpCj4+Pj4gKyAgICAgICAgICAg ICAgIHJldHVybiB0cnVlOwo+Pj4+ICsgICAgICAgcmV0dXJuIGZhbHNlOwo+Pj4KPj4+Cj4+PiBy ZXR1cm4gYm8tPmRlc3Ryb3kgPT0gJmhpYm1jX2JvX3R0bV9kZXN0cm95Owo+Pgo+Pgo+PiBsb29r cyBiZXR0ZXIgdG8gbWUuCj4+Cj4+Cj4+Pgo+Pj4+ICt9Cj4+Pj4gKwo+Pj4+ICtzdGF0aWMgaW50 Cj4+Pj4gK2hpYm1jX2JvX2luaXRfbWVtX3R5cGUoc3RydWN0IHR0bV9ib19kZXZpY2UgKmJkZXYs IHUzMiB0eXBlLAo+Pj4+ICsgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IHR0bV9tZW1fdHlw ZV9tYW5hZ2VyICptYW4pCj4+Pj4gK3sKPj4+PiArICAgICAgIHN3aXRjaCAodHlwZSkgewo+Pj4+ ICsgICAgICAgY2FzZSBUVE1fUExfU1lTVEVNOgo+Pj4+ICsgICAgICAgICAgICAgICBtYW4tPmZs YWdzID0gVFRNX01FTVRZUEVfRkxBR19NQVBQQUJMRTsKPj4+PiArICAgICAgICAgICAgICAgbWFu LT5hdmFpbGFibGVfY2FjaGluZyA9IFRUTV9QTF9NQVNLX0NBQ0hJTkc7Cj4+Pj4gKyAgICAgICAg ICAgICAgIG1hbi0+ZGVmYXVsdF9jYWNoaW5nID0gVFRNX1BMX0ZMQUdfQ0FDSEVEOwo+Pj4+ICsg ICAgICAgICAgICAgICBicmVhazsKPj4+PiArICAgICAgIGNhc2UgVFRNX1BMX1ZSQU06Cj4+Pj4g KyAgICAgICAgICAgICAgIG1hbi0+ZnVuYyA9ICZ0dG1fYm9fbWFuYWdlcl9mdW5jOwo+Pj4+ICsg ICAgICAgICAgICAgICBtYW4tPmZsYWdzID0gVFRNX01FTVRZUEVfRkxBR19GSVhFRCB8Cj4+Pj4g KyAgICAgICAgICAgICAgICAgICAgICAgVFRNX01FTVRZUEVfRkxBR19NQVBQQUJMRTsKPj4+PiAr ICAgICAgICAgICAgICAgbWFuLT5hdmFpbGFibGVfY2FjaGluZyA9IFRUTV9QTF9GTEFHX1VOQ0FD SEVEIHwKPj4+PiArICAgICAgICAgICAgICAgICAgICAgICBUVE1fUExfRkxBR19XQzsKPj4+PiAr ICAgICAgICAgICAgICAgbWFuLT5kZWZhdWx0X2NhY2hpbmcgPSBUVE1fUExfRkxBR19XQzsKPj4+ PiArICAgICAgICAgICAgICAgYnJlYWs7Cj4+Pj4gKyAgICAgICBkZWZhdWx0Ogo+Pj4+ICsgICAg ICAgICAgICAgICBEUk1fRVJST1IoIlVuc3VwcG9ydGVkIG1lbW9yeSB0eXBlICV1XG4iLCB0eXBl KTsKPj4+PiArICAgICAgICAgICAgICAgcmV0dXJuIC1FSU5WQUw7Cj4+Pj4gKyAgICAgICB9Cj4+ Pj4gKyAgICAgICByZXR1cm4gMDsKPj4+PiArfQo+Pj4+ICsKPj4+PiArdm9pZCBoaWJtY190dG1f cGxhY2VtZW50KHN0cnVjdCBoaWJtY19ibyAqYm8sIGludCBkb21haW4pCj4+Pj4gK3sKPj4+PiAr ICAgICAgIHUzMiBjID0gMDsKPj4+Cj4+Pgo+Pj4gQ2FuIHlvdSBwbGVhc2UgdXNlIGEgbW9yZSBk ZXNjcmlwdGl2ZSBuYW1lIHRoYW4gJ2MnPwo+Pgo+Pgo+PiBvaywgd2lsbCBkbyB0aGF0Lgo+Pgo+ Pj4KPj4+PiArICAgICAgIHUzMiBpOwo+Pj4+ICsKPj4+PiArICAgICAgIGJvLT5wbGFjZW1lbnQu cGxhY2VtZW50ID0gYm8tPnBsYWNlbWVudHM7Cj4+Pj4gKyAgICAgICBiby0+cGxhY2VtZW50LmJ1 c3lfcGxhY2VtZW50ID0gYm8tPnBsYWNlbWVudHM7Cj4+Pj4gKyAgICAgICBpZiAoZG9tYWluICYg VFRNX1BMX0ZMQUdfVlJBTSkKPj4+PiArICAgICAgICAgICAgICAgYm8tPnBsYWNlbWVudHNbYysr XS5mbGFncyA9IFRUTV9QTF9GTEFHX1dDIHwKPj4+PiArICAgICAgICAgICAgICAgVFRNX1BMX0ZM QUdfVU5DQUNIRUQgfCBUVE1fUExfRkxBR19WUkFNOwo+Pj4KPj4+Cj4+PiBuaXQ6IHlvdSdyZSBh bGlnbm1lbnQgaXMgb2ZmIGhlcmUgYW5kIGJlbG93Cj4+Cj4+Cj4+IGlzIGl0IGNvcnJlY3Q/Cj4+ Cj4+ICAgICAgICAgIGlmIChkb21haW4gJiBUVE1fUExfRkxBR19WUkFNKQo+PiAgICAgICAgICAg ICAgICAgIGJvLT5wbGFjZW1lbnRzW2MrK10uZmxhZ3MgPSBUVE1fUExfRkxBR19XQyB8Cj4+ICAg ICAgICAgICAgICAgICAgICAgICAgICBUVE1fUExfRkxBR19VTkNBQ0hFRCB8IFRUTV9QTF9GTEFH X1ZSQU07Cj4+ICAgICAgICAgIGlmIChkb21haW4gJiBUVE1fUExfRkxBR19TWVNURU0pCj4+ICAg ICAgICAgICAgICAgICAgYm8tPnBsYWNlbWVudHNbYysrXS5mbGFncyA9IFRUTV9QTF9NQVNLX0NB Q0hJTkcgfAo+PiAgICAgICAgICAgICAgICAgICAgICAgICAgVFRNX1BMX0ZMQUdfU1lTVEVNOwo+ PiAgICAgICAgICBpZiAoIWMpCj4+ICAgICAgICAgICAgICAgICAgYm8tPnBsYWNlbWVudHNbYysr XS5mbGFncyA9IFRUTV9QTF9NQVNLX0NBQ0hJTkcgfAo+PiAgICAgICAgICAgICAgICAgICAgICAg ICAgVFRNX1BMX0ZMQUdfU1lTVEVNOwo+Pgo+Cj4gUHJldHR5IG11Y2ggYW55dGhpbmcgb3RoZXIg dGhhbiBsaW5pbmcgdGhlbSB1cCBvbmUgdW5kZXIgdGhlIG90aGVyIGlzIGJldHRlcgo+Cj4+Pgo+ Pj4+ICsgICAgICAgaWYgKGRvbWFpbiAmIFRUTV9QTF9GTEFHX1NZU1RFTSkKPj4+PiArICAgICAg ICAgICAgICAgYm8tPnBsYWNlbWVudHNbYysrXS5mbGFncyA9IFRUTV9QTF9NQVNLX0NBQ0hJTkcg fAo+Pj4+ICsgICAgICAgICAgICAgICBUVE1fUExfRkxBR19TWVNURU07Cj4+Pj4gKyAgICAgICBp ZiAoIWMpCj4+Pj4gKyAgICAgICAgICAgICAgIGJvLT5wbGFjZW1lbnRzW2MrK10uZmxhZ3MgPSBU VE1fUExfTUFTS19DQUNISU5HIHwKPj4+PiArICAgICAgICAgICAgICAgVFRNX1BMX0ZMQUdfU1lT VEVNOwo+Pj4+ICsKPj4+PiArICAgICAgIGJvLT5wbGFjZW1lbnQubnVtX3BsYWNlbWVudCA9IGM7 Cj4+Pj4gKyAgICAgICBiby0+cGxhY2VtZW50Lm51bV9idXN5X3BsYWNlbWVudCA9IGM7Cj4+Pj4g KyAgICAgICBmb3IgKGkgPSAwOyBpIDwgYzsgKytpKSB7Cj4+Pgo+Pj4KPj4+IG5pdDogd2UgdGVu ZCB0b3dhcmRzIHBvc3QtaW5jcmVtZW50IGluIGtlcm5lbAo+Pgo+Pgo+PiBhZ3JlZWQsIHRoYW5r cy4KPj4KPj4KPj4+Cj4+Pj4gKyAgICAgICAgICAgICAgIGJvLT5wbGFjZW1lbnRzW2ldLmZwZm4g PSAwOwo+Pj4+ICsgICAgICAgICAgICAgICBiby0+cGxhY2VtZW50c1tpXS5scGZuID0gMDsKPj4+ PiArICAgICAgIH0KPj4+PiArfQo+Pj4+ICsKPj4+PiArc3RhdGljIHZvaWQKPj4+PiAraGlibWNf Ym9fZXZpY3RfZmxhZ3Moc3RydWN0IHR0bV9idWZmZXJfb2JqZWN0ICpibywgc3RydWN0IHR0bV9w bGFjZW1lbnQKPj4+PiAqcGwpCj4+Pj4gK3sKPj4+PiArICAgICAgIHN0cnVjdCBoaWJtY19ibyAq aGlibWNibyA9IGhpYm1jX2JvKGJvKTsKPj4+PiArCj4+Pj4gKyAgICAgICBpZiAoIWhpYm1jX3R0 bV9ib19pc19oaWJtY19ibyhibykpCj4+Pj4gKyAgICAgICAgICAgICAgIHJldHVybjsKPj4+PiAr Cj4+Pj4gKyAgICAgICBoaWJtY190dG1fcGxhY2VtZW50KGhpYm1jYm8sIFRUTV9QTF9GTEFHX1NZ U1RFTSk7Cj4+Pj4gKyAgICAgICAqcGwgPSBoaWJtY2JvLT5wbGFjZW1lbnQ7Cj4+Pj4gK30KPj4+ PiArCj4+Pj4gK3N0YXRpYyBpbnQgaGlibWNfYm9fdmVyaWZ5X2FjY2VzcyhzdHJ1Y3QgdHRtX2J1 ZmZlcl9vYmplY3QgKmJvLAo+Pj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBz dHJ1Y3QgZmlsZSAqZmlscCkKPj4+PiArewo+Pj4+ICsgICAgICAgc3RydWN0IGhpYm1jX2JvICpo aWJtY2JvID0gaGlibWNfYm8oYm8pOwo+Pj4+ICsKPj4+PiArICAgICAgIHJldHVybiBkcm1fdm1h X25vZGVfdmVyaWZ5X2FjY2VzcygmaGlibWNiby0+Z2VtLnZtYV9ub2RlLAo+Pj4+ICsgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHAtPnByaXZhdGVfZGF0YSk7Cj4+ Pj4gK30KPj4+PiArCj4+Pj4gK3N0YXRpYyBpbnQgaGlibWNfdHRtX2lvX21lbV9yZXNlcnZlKHN0 cnVjdCB0dG1fYm9fZGV2aWNlICpiZGV2LAo+Pj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgIHN0cnVjdCB0dG1fbWVtX3JlZyAqbWVtKQo+Pj4+ICt7Cj4+Pj4gKyAgICAgICBz dHJ1Y3QgdHRtX21lbV90eXBlX21hbmFnZXIgKm1hbiA9ICZiZGV2LT5tYW5bbWVtLT5tZW1fdHlw ZV07Cj4+Pj4gKyAgICAgICBzdHJ1Y3QgaGlibWNfZHJtX2RldmljZSAqaGlibWMgPSBoaWJtY19i ZGV2KGJkZXYpOwo+Pj4+ICsKPj4+PiArICAgICAgIG1lbS0+YnVzLmFkZHIgPSBOVUxMOwo+Pj4+ ICsgICAgICAgbWVtLT5idXMub2Zmc2V0ID0gMDsKPj4+PiArICAgICAgIG1lbS0+YnVzLnNpemUg PSBtZW0tPm51bV9wYWdlcyA8PCBQQUdFX1NISUZUOwo+Pj4+ICsgICAgICAgbWVtLT5idXMuYmFz ZSA9IDA7Cj4+Pj4gKyAgICAgICBtZW0tPmJ1cy5pc19pb21lbSA9IGZhbHNlOwo+Pj4+ICsgICAg ICAgaWYgKCEobWFuLT5mbGFncyAmIFRUTV9NRU1UWVBFX0ZMQUdfTUFQUEFCTEUpKQo+Pj4+ICsg ICAgICAgICAgICAgICByZXR1cm4gLUVJTlZBTDsKPj4+PiArICAgICAgIHN3aXRjaCAobWVtLT5t ZW1fdHlwZSkgewo+Pj4+ICsgICAgICAgY2FzZSBUVE1fUExfU1lTVEVNOgo+Pj4+ICsgICAgICAg ICAgICAgICAvKiBzeXN0ZW0gbWVtb3J5ICovCj4+Pj4gKyAgICAgICAgICAgICAgIHJldHVybiAw Owo+Pj4+ICsgICAgICAgY2FzZSBUVE1fUExfVlJBTToKPj4+PiArICAgICAgICAgICAgICAgbWVt LT5idXMub2Zmc2V0ID0gbWVtLT5zdGFydCA8PCBQQUdFX1NISUZUOwo+Pj4+ICsgICAgICAgICAg ICAgICBtZW0tPmJ1cy5iYXNlID0gcGNpX3Jlc291cmNlX3N0YXJ0KGhpYm1jLT5kZXYtPnBkZXYs IDApOwo+Pj4+ICsgICAgICAgICAgICAgICBtZW0tPmJ1cy5pc19pb21lbSA9IHRydWU7Cj4+Pj4g KyAgICAgICAgICAgICAgIGJyZWFrOwo+Pj4+ICsgICAgICAgZGVmYXVsdDoKPj4+PiArICAgICAg ICAgICAgICAgcmV0dXJuIC1FSU5WQUw7Cj4+Pj4gKyAgICAgICB9Cj4+Pj4gKyAgICAgICByZXR1 cm4gMDsKPj4+PiArfQo+Pj4+ICsKPj4+PiArc3RhdGljIHZvaWQgaGlibWNfdHRtX2lvX21lbV9m cmVlKHN0cnVjdCB0dG1fYm9fZGV2aWNlICpiZGV2LAo+Pj4+ICsgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICBzdHJ1Y3QgdHRtX21lbV9yZWcgKm1lbSkKPj4+PiArewo+Pj4+ICt9Cj4+ Pgo+Pj4KPj4+IE5vIG5lZWQgdG8gc3R1YiB0aGlzLCB0aGUgY2FsbGVyIGRvZXMgYSBOVUxMLWNo ZWNrIGJlZm9yZSBpbnZva2luZwo+Pgo+Pgo+PiB3aWxsIGRlbGV0ZSBpdCwgdGhhbmtzLgo+Pgo+ Pj4KPj4+PiArCj4+Pj4gK3N0YXRpYyB2b2lkIGhpYm1jX3R0bV9iYWNrZW5kX2Rlc3Ryb3koc3Ry dWN0IHR0bV90dCAqdHQpCj4+Pj4gK3sKPj4+PiArICAgICAgIHR0bV90dF9maW5pKHR0KTsKPj4+ PiArICAgICAgIGtmcmVlKHR0KTsKPj4+PiArfQo+Pj4+ICsKPj4+PiArc3RhdGljIHN0cnVjdCB0 dG1fYmFja2VuZF9mdW5jIGhpYm1jX3R0X2JhY2tlbmRfZnVuYyA9IHsKPj4+PiArICAgICAgIC5k ZXN0cm95ID0gJmhpYm1jX3R0bV9iYWNrZW5kX2Rlc3Ryb3ksCj4+Pj4gK307Cj4+Pj4gKwo+Pj4+ ICtzdGF0aWMgc3RydWN0IHR0bV90dCAqaGlibWNfdHRtX3R0X2NyZWF0ZShzdHJ1Y3QgdHRtX2Jv X2RldmljZSAqYmRldiwKPj4+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICB1bnNpZ25lZCBsb25nIHNpemUsCj4+Pj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgdTMyIHBhZ2VfZmxhZ3MsCj4+Pj4gKyAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgc3RydWN0IHBhZ2UgKmR1bW15X3JlYWRfcGFnZSkKPj4+PiAr ewo+Pj4+ICsgICAgICAgc3RydWN0IHR0bV90dCAqdHQ7Cj4+Pj4gKwo+Pj4+ICsgICAgICAgdHQg PSBremFsbG9jKHNpemVvZigqdHQpLCBHRlBfS0VSTkVMKTsKPj4+PiArICAgICAgIGlmICghdHQp Cj4+Pgo+Pj4KPj4+IFByaW50IGVycm9yCj4+Cj4+Cj4+IG9rLCB3aWxsIGRvIHRoYXQsIHRoYW5r cy4KPj4KPj4+Cj4+Pj4gKyAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwo+Pj4+ICsgICAgICAg dHQtPmZ1bmMgPSAmaGlibWNfdHRfYmFja2VuZF9mdW5jOwo+Pj4+ICsgICAgICAgaWYgKHR0bV90 dF9pbml0KHR0LCBiZGV2LCBzaXplLCBwYWdlX2ZsYWdzLCBkdW1teV9yZWFkX3BhZ2UpKSB7Cj4+ Pgo+Pj4KPj4+IEhlcmUgdG9vPwo+Pgo+Pgo+PiBkaXR0bwo+Pgo+Pgo+Pj4KPj4+PiArICAgICAg ICAgICAgICAga2ZyZWUodHQpOwo+Pj4+ICsgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKPj4+ PiArICAgICAgIH0KPj4+PiArICAgICAgIHJldHVybiB0dDsKPj4+PiArfQo+Pj4+ICsKPj4+PiAr c3RhdGljIGludCBoaWJtY190dG1fdHRfcG9wdWxhdGUoc3RydWN0IHR0bV90dCAqdHRtKQo+Pj4+ ICt7Cj4+Pj4gKyAgICAgICByZXR1cm4gdHRtX3Bvb2xfcG9wdWxhdGUodHRtKTsKPj4+PiArfQo+ Pj4+ICsKPj4+PiArc3RhdGljIHZvaWQgaGlibWNfdHRtX3R0X3VucG9wdWxhdGUoc3RydWN0IHR0 bV90dCAqdHRtKQo+Pj4+ICt7Cj4+Pj4gKyAgICAgICB0dG1fcG9vbF91bnBvcHVsYXRlKHR0bSk7 Cj4+Pj4gK30KPj4+PiArCj4+Pj4gK3N0cnVjdCB0dG1fYm9fZHJpdmVyIGhpYm1jX2JvX2RyaXZl ciA9IHsKPj4+PiArICAgICAgIC50dG1fdHRfY3JlYXRlICAgICAgICAgID0gaGlibWNfdHRtX3R0 X2NyZWF0ZSwKPj4+PiArICAgICAgIC50dG1fdHRfcG9wdWxhdGUgICAgICAgID0gaGlibWNfdHRt X3R0X3BvcHVsYXRlLAo+Pj4+ICsgICAgICAgLnR0bV90dF91bnBvcHVsYXRlICAgICAgPSBoaWJt Y190dG1fdHRfdW5wb3B1bGF0ZSwKPj4+PiArICAgICAgIC5pbml0X21lbV90eXBlICAgICAgICAg ID0gaGlibWNfYm9faW5pdF9tZW1fdHlwZSwKPj4+PiArICAgICAgIC5ldmljdF9mbGFncyAgICAg ICAgICAgID0gaGlibWNfYm9fZXZpY3RfZmxhZ3MsCj4+Pj4gKyAgICAgICAubW92ZSAgICAgICAg ICAgICAgICAgICA9IE5VTEwsCj4+Pj4gKyAgICAgICAudmVyaWZ5X2FjY2VzcyAgICAgICAgICA9 IGhpYm1jX2JvX3ZlcmlmeV9hY2Nlc3MsCj4+Pj4gKyAgICAgICAuaW9fbWVtX3Jlc2VydmUgICAg ICAgICA9ICZoaWJtY190dG1faW9fbWVtX3Jlc2VydmUsCj4+Pj4gKyAgICAgICAuaW9fbWVtX2Zy ZWUgICAgICAgICAgICA9ICZoaWJtY190dG1faW9fbWVtX2ZyZWUsCj4+Pj4gKyAgICAgICAubHJ1 X3RhaWwgICAgICAgICAgICAgICA9ICZ0dG1fYm9fZGVmYXVsdF9scnVfdGFpbCwKPj4+PiArICAg ICAgIC5zd2FwX2xydV90YWlsICAgICAgICAgID0gJnR0bV9ib19kZWZhdWx0X3N3YXBfbHJ1X3Rh aWwsCj4+Pj4gK307Cj4+Pj4gKwo+Pj4+ICtpbnQgaGlibWNfbW1faW5pdChzdHJ1Y3QgaGlibWNf ZHJtX2RldmljZSAqaGlibWMpCj4+Pj4gK3sKPj4+PiArICAgICAgIGludCByZXQ7Cj4+Pj4gKyAg ICAgICBzdHJ1Y3QgZHJtX2RldmljZSAqZGV2ID0gaGlibWMtPmRldjsKPj4+PiArICAgICAgIHN0 cnVjdCB0dG1fYm9fZGV2aWNlICpiZGV2ID0gJmhpYm1jLT50dG0uYmRldjsKPj4+PiArCj4+Pj4g KyAgICAgICByZXQgPSBoaWJtY190dG1fZ2xvYmFsX2luaXQoaGlibWMpOwo+Pj4+ICsgICAgICAg aWYgKHJldCkKPj4+PiArICAgICAgICAgICAgICAgcmV0dXJuIHJldDsKPj4+PiArCj4+Pj4gKyAg ICAgICByZXQgPSB0dG1fYm9fZGV2aWNlX2luaXQoJmhpYm1jLT50dG0uYmRldiwKPj4+PiArICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaWJtYy0+dHRtLmJvX2dsb2JhbF9yZWYucmVm Lm9iamVjdCwKPj4+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmaGlibWNfYm9f ZHJpdmVyLAo+Pj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRldi0+YW5vbl9p bm9kZS0+aV9tYXBwaW5nLAo+Pj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERS TV9GSUxFX1BBR0VfT0ZGU0VULAo+Pj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg IHRydWUpOwo+Pj4+ICsgICAgICAgaWYgKHJldCkgewo+Pj4KPj4+Cj4+PiBDYWxsIGhpYm1jX3R0 bV9nbG9iYWxfcmVsZWFzZSBoZXJlPwo+Pgo+Pgo+PiBhZ3JlZWQsIHRoYW5rcyBmb3IgcG9pbnRp bmcgaXQgb3V0Lgo+Pgo+Pj4KPj4+PiArICAgICAgICAgICAgICAgRFJNX0VSUk9SKCJFcnJvciBp bml0aWFsaXNpbmcgYm8gZHJpdmVyOyAlZFxuIiwgcmV0KTsKPj4+PiArICAgICAgICAgICAgICAg cmV0dXJuIHJldDsKPj4+PiArICAgICAgIH0KPj4+PiArCj4+Pj4gKyAgICAgICByZXQgPSB0dG1f Ym9faW5pdF9tbShiZGV2LCBUVE1fUExfVlJBTSwKPj4+PiArICAgICAgICAgICAgICAgICAgICAg ICAgICAgIGhpYm1jLT5mYl9zaXplID4+IFBBR0VfU0hJRlQpOwo+Pj4+ICsgICAgICAgaWYgKHJl dCkgewo+Pj4KPj4+Cj4+PiBDbGVhbiB1cCBoZXJlIGFzIHdlbGw/Cj4+Cj4+Cj4+IGRpdHRvCj4+ Cj4+Cj4+Pgo+Pj4+ICsgICAgICAgICAgICAgICBEUk1fRVJST1IoIkZhaWxlZCB0dG0gVlJBTSBp bml0OiAlZFxuIiwgcmV0KTsKPj4+PiArICAgICAgICAgICAgICAgcmV0dXJuIHJldDsKPj4+PiAr ICAgICAgIH0KPj4+PiArCj4+Pj4gKyAgICAgICBoaWJtYy0+bW1faW5pdGVkID0gdHJ1ZTsKPj4+ PiArICAgICAgIHJldHVybiAwOwo+Pj4+ICt9Cj4+Pj4gKwo+Pj4+ICt2b2lkIGhpYm1jX21tX2Zp bmkoc3RydWN0IGhpYm1jX2RybV9kZXZpY2UgKmhpYm1jKQo+Pj4+ICt7Cj4+Pj4gKyAgICAgICBp ZiAoIWhpYm1jLT5tbV9pbml0ZWQpCj4+Pj4gKyAgICAgICAgICAgICAgIHJldHVybjsKPj4+PiAr Cj4+Pj4gKyAgICAgICB0dG1fYm9fZGV2aWNlX3JlbGVhc2UoJmhpYm1jLT50dG0uYmRldik7Cj4+ Pj4gKyAgICAgICBoaWJtY190dG1fZ2xvYmFsX3JlbGVhc2UoaGlibWMpOwo+Pj4+ICsgICAgICAg aGlibWMtPm1tX2luaXRlZCA9IGZhbHNlOwo+Pj4+ICt9Cj4+Pj4gKwo+Pj4+ICtpbnQgaGlibWNf Ym9fY3JlYXRlKHN0cnVjdCBkcm1fZGV2aWNlICpkZXYsIGludCBzaXplLCBpbnQgYWxpZ24sCj4+ Pj4gKyAgICAgICAgICAgICAgICAgICB1MzIgZmxhZ3MsIHN0cnVjdCBoaWJtY19ibyAqKnBoaWJt Y2JvKQo+Pj4+ICt7Cj4+Pj4gKyAgICAgICBzdHJ1Y3QgaGlibWNfZHJtX2RldmljZSAqaGlibWMg PSBkZXYtPmRldl9wcml2YXRlOwo+Pj4+ICsgICAgICAgc3RydWN0IGhpYm1jX2JvICpoaWJtY2Jv Owo+Pj4+ICsgICAgICAgc2l6ZV90IGFjY19zaXplOwo+Pj4+ICsgICAgICAgaW50IHJldDsKPj4+ PiArCj4+Pj4gKyAgICAgICBoaWJtY2JvID0ga3phbGxvYyhzaXplb2YoKmhpYm1jYm8pLCBHRlBf S0VSTkVMKTsKPj4+PiArICAgICAgIGlmICghaGlibWNibykKPj4+PiArICAgICAgICAgICAgICAg cmV0dXJuIC1FTk9NRU07Cj4+Pj4gKwo+Pj4+ICsgICAgICAgcmV0ID0gZHJtX2dlbV9vYmplY3Rf aW5pdChkZXYsICZoaWJtY2JvLT5nZW0sIHNpemUpOwo+Pj4+ICsgICAgICAgaWYgKHJldCkgewo+ Pj4+ICsgICAgICAgICAgICAgICBrZnJlZShoaWJtY2JvKTsKPj4+PiArICAgICAgICAgICAgICAg cmV0dXJuIHJldDsKPj4+PiArICAgICAgIH0KPj4+PiArCj4+Pj4gKyAgICAgICBoaWJtY2JvLT5i by5iZGV2ID0gJmhpYm1jLT50dG0uYmRldjsKPj4+PiArCj4+Pj4gKyAgICAgICBoaWJtY190dG1f cGxhY2VtZW50KGhpYm1jYm8sIFRUTV9QTF9GTEFHX1ZSQU0gfAo+Pj4+IFRUTV9QTF9GTEFHX1NZ U1RFTSk7Cj4+Pj4gKwo+Pj4+ICsgICAgICAgYWNjX3NpemUgPSB0dG1fYm9fZG1hX2FjY19zaXpl KCZoaWJtYy0+dHRtLmJkZXYsIHNpemUsCj4+Pj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgc2l6ZW9mKHN0cnVjdCBoaWJtY19ibykpOwo+Pj4+ICsKPj4+PiArICAgICAg IHJldCA9IHR0bV9ib19pbml0KCZoaWJtYy0+dHRtLmJkZXYsICZoaWJtY2JvLT5ibywgc2l6ZSwK Pj4+PiArICAgICAgICAgICAgICAgICAgICAgICAgIHR0bV9ib190eXBlX2RldmljZSwgJmhpYm1j Ym8tPnBsYWNlbWVudCwKPj4+PiArICAgICAgICAgICAgICAgICAgICAgICAgIGFsaWduID4+IFBB R0VfU0hJRlQsIGZhbHNlLCBOVUxMLCBhY2Nfc2l6ZSwKPj4+PiArICAgICAgICAgICAgICAgICAg ICAgICAgIE5VTEwsIE5VTEwsIGhpYm1jX2JvX3R0bV9kZXN0cm95KTsKPj4+PiArICAgICAgIGlm IChyZXQpCj4+Pgo+Pj4KPj4+IE1pc3NpbmcgaGlibWNibyBjbGVhbiB1cCBoZXJlCj4+Cj4+Cj4+ IGkgbG9va2VkIGF0IGFsbCBvdGhlciB0dG0gZHJpdmVycyBhbmQgYWxsIG9mIHRoZW0gcmV0dXJu IGRpcmVjdGx5IHdoZW4KPj4gdHRtX2JvX2luaXQKPj4gZmFpbGVkLCBob3dldmVyLCBpIHRoaW5r IGl0IGlzIGJldHRlciB0byBjbGVhbiB1cCBoZXJlLCBzaG91bGQgaSBjYWxsCj4+IGhpYm1jX2Jv X3VucmVmKCZoaWJtY19ibykgaGVyZSA/Cj4+Cj4KPiBZZWFoLCB0aGF0IHNob3VsZCB3b3JrICht aWdodCB3YW50IHRvIHRlc3QgaXQsIHRob3VnaCA7KQo+Cj4KPj4+Cj4+Pj4gKyAgICAgICAgICAg ICAgIHJldHVybiByZXQ7Cj4+Pj4gKwo+Pj4+ICsgICAgICAgKnBoaWJtY2JvID0gaGlibWNibzsK Pj4+PiArICAgICAgIHJldHVybiAwOwo+Pj4+ICt9Cj4+Pj4gKwo+Pj4+ICtzdGF0aWMgaW5saW5l IHU2NCBoaWJtY19ib19ncHVfb2Zmc2V0KHN0cnVjdCBoaWJtY19ibyAqYm8pCj4+Pj4gK3sKPj4+ PiArICAgICAgIHJldHVybiBiby0+Ym8ub2Zmc2V0Owo+Pj4+ICt9Cj4+Pgo+Pj4KPj4+IEkgZG9u J3QgdGhpbmsgdGhpcyBmdW5jdGlvbiBwcm92aWRlcyBhbnkgdmFsdWUKPj4KPj4KPj4gZG8geW91 IG5lYW4gaSB1c2UgYm8tPmJvLm9mZnNldCBpbnN0ZWFkIG9mIGNhbGxpbmcgaGlibWNfYm9fZ3B1 X29mZnNldCgpPwo+Pgo+Cj4geWVzCj4KPj4+Cj4+Pj4gKwo+Pj4+ICtpbnQgaGlibWNfYm9fcGlu KHN0cnVjdCBoaWJtY19ibyAqYm8sIHUzMiBwbF9mbGFnLCB1NjQgKmdwdV9hZGRyKQo+Pj4+ICt7 Cj4+Pj4gKyAgICAgICBpbnQgaSwgcmV0Owo+Pj4+ICsKPj4+PiArICAgICAgIGlmIChiby0+cGlu X2NvdW50KSB7Cj4+Pj4gKyAgICAgICAgICAgICAgIGJvLT5waW5fY291bnQrKzsKPj4+PiArICAg ICAgICAgICAgICAgaWYgKGdwdV9hZGRyKQo+Pj4+ICsgICAgICAgICAgICAgICAgICAgICAgICpn cHVfYWRkciA9IGhpYm1jX2JvX2dwdV9vZmZzZXQoYm8pOwo+Pj4KPj4+Cj4+PiBBcmUgeW91IG1p c3NpbmcgYSByZXR1cm4gaGVyZT8KPj4KPj4KPj4gVGhhbmtzIGZvciBwb2ludGluZyBpdCBvdXQh Cj4+Cj4+Cj4+Pgo+Pj4+ICsgICAgICAgfQo+Pj4+ICsKPj4+PiArICAgICAgIGhpYm1jX3R0bV9w bGFjZW1lbnQoYm8sIHBsX2ZsYWcpOwo+Pj4+ICsgICAgICAgZm9yIChpID0gMDsgaSA8IGJvLT5w bGFjZW1lbnQubnVtX3BsYWNlbWVudDsgaSsrKQo+Pj4+ICsgICAgICAgICAgICAgICBiby0+cGxh Y2VtZW50c1tpXS5mbGFncyB8PSBUVE1fUExfRkxBR19OT19FVklDVDsKPj4+PiArICAgICAgIHJl dCA9IHR0bV9ib192YWxpZGF0ZSgmYm8tPmJvLCAmYm8tPnBsYWNlbWVudCwgZmFsc2UsIGZhbHNl KTsKPj4+PiArICAgICAgIGlmIChyZXQpCj4+Pj4gKyAgICAgICAgICAgICAgIHJldHVybiByZXQ7 Cj4+Pj4gKwo+Pj4+ICsgICAgICAgYm8tPnBpbl9jb3VudCA9IDE7Cj4+Pj4gKyAgICAgICBpZiAo Z3B1X2FkZHIpCj4+Pj4gKyAgICAgICAgICAgICAgICpncHVfYWRkciA9IGhpYm1jX2JvX2dwdV9v ZmZzZXQoYm8pOwo+Pj4+ICsgICAgICAgcmV0dXJuIDA7Cj4+Pj4gK30KPj4+PiArCj4+Pj4gK2lu dCBoaWJtY19ib19wdXNoX3N5c3JhbShzdHJ1Y3QgaGlibWNfYm8gKmJvKQo+Pj4+ICt7Cj4+Pj4g KyAgICAgICBpbnQgaSwgcmV0Owo+Pj4+ICsKPj4+PiArICAgICAgIGlmICghYm8tPnBpbl9jb3Vu dCkgewo+Pj4+ICsgICAgICAgICAgICAgICBEUk1fRVJST1IoInVucGluIGJhZCAlcFxuIiwgYm8p Owo+Pj4+ICsgICAgICAgICAgICAgICByZXR1cm4gMDsKPj4+PiArICAgICAgIH0KPj4+PiArICAg ICAgIGJvLT5waW5fY291bnQtLTsKPj4+PiArICAgICAgIGlmIChiby0+cGluX2NvdW50KQo+Pj4+ ICsgICAgICAgICAgICAgICByZXR1cm4gMDsKPj4+PiArCj4+Pj4gKyAgICAgICBpZiAoYm8tPmtt YXAudmlydHVhbCkKPj4+Cj4+Pgo+Pj4gdHRtX2JvX2t1bm1hcCBhbHJlYWR5IGRvZXMgdGhpcyBj aGVjayBzbyB5b3UgZG9uJ3QgaGF2ZSB0bwo+Pgo+Pgo+PiBhZ3JlZWQuIHdpbGwgcmVtb3ZlIHRo aXMgY29uZGl0aW9uLgo+Pgo+Pj4KPj4+PiArICAgICAgICAgICAgICAgdHRtX2JvX2t1bm1hcCgm Ym8tPmttYXApOwo+Pj4+ICsKPj4+PiArICAgICAgIGhpYm1jX3R0bV9wbGFjZW1lbnQoYm8sIFRU TV9QTF9GTEFHX1NZU1RFTSk7Cj4+Pj4gKyAgICAgICBmb3IgKGkgPSAwOyBpIDwgYm8tPnBsYWNl bWVudC5udW1fcGxhY2VtZW50IDsgaSsrKQo+Pj4+ICsgICAgICAgICAgICAgICBiby0+cGxhY2Vt ZW50c1tpXS5mbGFncyB8PSBUVE1fUExfRkxBR19OT19FVklDVDsKPj4+PiArCj4+Pj4gKyAgICAg ICByZXQgPSB0dG1fYm9fdmFsaWRhdGUoJmJvLT5ibywgJmJvLT5wbGFjZW1lbnQsIGZhbHNlLCBm YWxzZSk7Cj4+Pj4gKyAgICAgICBpZiAocmV0KSB7Cj4+Pj4gKyAgICAgICAgICAgICAgIERSTV9F UlJPUigicHVzaGluZyB0byBWUkFNIGZhaWxlZFxuIik7Cj4+Pgo+Pj4KPj4+IFByaW50IHJldAo+ Pgo+Pgo+PiBvaywgdGhhbmtzLgo+Pgo+Pgo+Pj4KPj4+PiArICAgICAgICAgICAgICAgcmV0dXJu IHJldDsKPj4+PiArICAgICAgIH0KPj4+PiArICAgICAgIHJldHVybiAwOwo+Pj4+ICt9Cj4+Pj4g Kwo+Pj4+ICtpbnQgaGlibWNfbW1hcChzdHJ1Y3QgZmlsZSAqZmlscCwgc3RydWN0IHZtX2FyZWFf c3RydWN0ICp2bWEpCj4+Pj4gK3sKPj4+PiArICAgICAgIHN0cnVjdCBkcm1fZmlsZSAqZmlsZV9w cml2Owo+Pj4+ICsgICAgICAgc3RydWN0IGhpYm1jX2RybV9kZXZpY2UgKmhpYm1jOwo+Pj4+ICsK Pj4+PiArICAgICAgIGlmICh1bmxpa2VseSh2bWEtPnZtX3Bnb2ZmIDwgRFJNX0ZJTEVfUEFHRV9P RkZTRVQpKQo+Pj4+ICsgICAgICAgICAgICAgICByZXR1cm4gLUVJTlZBTDsKPj4+PiArCj4+Pj4g KyAgICAgICBmaWxlX3ByaXYgPSBmaWxwLT5wcml2YXRlX2RhdGE7Cj4+Pj4gKyAgICAgICBoaWJt YyA9IGZpbGVfcHJpdi0+bWlub3ItPmRldi0+ZGV2X3ByaXZhdGU7Cj4+Pj4gKyAgICAgICByZXR1 cm4gdHRtX2JvX21tYXAoZmlscCwgdm1hLCAmaGlibWMtPnR0bS5iZGV2KTsKPj4+PiArfQo+Pj4+ ICsKPj4+PiAraW50IGhpYm1jX2dlbV9jcmVhdGUoc3RydWN0IGRybV9kZXZpY2UgKmRldiwgdTMy IHNpemUsIGJvb2wgaXNrZXJuZWwsCj4+Pj4gKyAgICAgICAgICAgICAgICAgICAgc3RydWN0IGRy bV9nZW1fb2JqZWN0ICoqb2JqKQo+Pj4+ICt7Cj4+Pj4gKyAgICAgICBzdHJ1Y3QgaGlibWNfYm8g KmhpYm1jYm87Cj4+Pj4gKyAgICAgICBpbnQgcmV0Owo+Pj4+ICsKPj4+PiArICAgICAgICpvYmog PSBOVUxMOwo+Pj4+ICsKPj4+PiArICAgICAgIHNpemUgPSBQQUdFX0FMSUdOKHNpemUpOwo+Pj4+ ICsgICAgICAgaWYgKHNpemUgPT0gMCkKPj4+Cj4+Pgo+Pj4gUHJpbnQgZXJyb3IKPj4KPj4KPj4g ZGl0dG8KPj4KPj4+Cj4+Pj4gKyAgICAgICAgICAgICAgIHJldHVybiAtRUlOVkFMOwo+Pj4+ICsK Pj4+PiArICAgICAgIHJldCA9IGhpYm1jX2JvX2NyZWF0ZShkZXYsIHNpemUsIDAsIDAsICZoaWJt Y2JvKTsKPj4+PiArICAgICAgIGlmIChyZXQpIHsKPj4+PiArICAgICAgICAgICAgICAgaWYgKHJl dCAhPSAtRVJFU1RBUlRTWVMpCj4+Pj4gKyAgICAgICAgICAgICAgICAgICAgICAgRFJNX0VSUk9S KCJmYWlsZWQgdG8gYWxsb2NhdGUgR0VNIG9iamVjdFxuIik7Cj4+Pgo+Pj4KPj4+IFByaW50IHJl dAo+Pgo+Pgo+PiBkaXR0bwo+Pgo+Pj4KPj4+PiArICAgICAgICAgICAgICAgcmV0dXJuIHJldDsK Pj4+PiArICAgICAgIH0KPj4+PiArICAgICAgICpvYmogPSAmaGlibWNiby0+Z2VtOwo+Pj4+ICsg ICAgICAgcmV0dXJuIDA7Cj4+Pj4gK30KPj4+PiArCj4+Pj4gK2ludCBoaWJtY19kdW1iX2NyZWF0 ZShzdHJ1Y3QgZHJtX2ZpbGUgKmZpbGUsIHN0cnVjdCBkcm1fZGV2aWNlICpkZXYsCj4+Pj4gKyAg ICAgICAgICAgICAgICAgICAgIHN0cnVjdCBkcm1fbW9kZV9jcmVhdGVfZHVtYiAqYXJncykKPj4+ PiArewo+Pj4+ICsgICAgICAgc3RydWN0IGRybV9nZW1fb2JqZWN0ICpnb2JqOwo+Pj4+ICsgICAg ICAgdTMyIGhhbmRsZTsKPj4+PiArICAgICAgIGludCByZXQ7Cj4+Pj4gKwo+Pj4+ICsgICAgICAg YXJncy0+cGl0Y2ggPSBBTElHTihhcmdzLT53aWR0aCAqICgoYXJncy0+YnBwICsgNykgLyA4KSwg MTYpOwo+Pj4KPj4+Cj4+PiBXaGF0J3MgdXAgd2l0aCB0aGUgYnBwICsgNyBoZXJlPyBQZXJoYXBz IHlvdSdyZSBsb29raW5nIGZvciBESVZfUk9VTkRfVVA/Cj4+Cj4+Cj4+IFllcywgdGhhdCBzb3Vu ZHMgc2FuZS4KPj4KPgo+IHNhbmUgaXMgd2hhdCBpIHVzdWFsbHkgYWltIGZvciA6KQo+Cj4gU2Vh bgo+Cj4KPj4+Cj4+Pgo+Pj4+ICsgICAgICAgYXJncy0+c2l6ZSA9IGFyZ3MtPnBpdGNoICogYXJn cy0+aGVpZ2h0Owo+Pj4+ICsKPj4+PiArICAgICAgIHJldCA9IGhpYm1jX2dlbV9jcmVhdGUoZGV2 LCBhcmdzLT5zaXplLCBmYWxzZSwKPj4+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg JmdvYmopOwo+Pj4+ICsgICAgICAgaWYgKHJldCkKPj4+PiArICAgICAgICAgICAgICAgcmV0dXJu IHJldDsKPj4+PiArCj4+Pj4gKyAgICAgICByZXQgPSBkcm1fZ2VtX2hhbmRsZV9jcmVhdGUoZmls ZSwgZ29iaiwgJmhhbmRsZSk7Cj4+Pj4gKyAgICAgICBkcm1fZ2VtX29iamVjdF91bnJlZmVyZW5j ZV91bmxvY2tlZChnb2JqKTsKPj4+PiArICAgICAgIGlmIChyZXQpCj4+Pgo+Pj4KPj4+IFByaW50 IGVycm9yIGhlcmUKPj4KPj4KPj4gYWdyZWVkLgo+Pgo+Pgo+Pj4KPj4+PiArICAgICAgICAgICAg ICAgcmV0dXJuIHJldDsKPj4+PiArCj4+Pj4gKyAgICAgICBhcmdzLT5oYW5kbGUgPSBoYW5kbGU7 Cj4+Pj4gKyAgICAgICByZXR1cm4gMDsKPj4+PiArfQo+Pj4+ICsKPj4+PiArc3RhdGljIHZvaWQg aGlibWNfYm9fdW5yZWYoc3RydWN0IGhpYm1jX2JvICoqYm8pCj4+Pj4gK3sKPj4+PiArICAgICAg IHN0cnVjdCB0dG1fYnVmZmVyX29iamVjdCAqdGJvOwo+Pj4+ICsKPj4+PiArICAgICAgIGlmICgo KmJvKSA9PSBOVUxMKQo+Pj4+ICsgICAgICAgICAgICAgICByZXR1cm47Cj4+Pj4gKwo+Pj4+ICsg ICAgICAgdGJvID0gJigoKmJvKS0+Ym8pOwo+Pj4+ICsgICAgICAgdHRtX2JvX3VucmVmKCZ0Ym8p Owo+Pj4+ICsgICAgICAgKmJvID0gTlVMTDsKPj4+PiArfQo+Pj4+ICsKPj4+PiArdm9pZCBoaWJt Y19nZW1fZnJlZV9vYmplY3Qoc3RydWN0IGRybV9nZW1fb2JqZWN0ICpvYmopCj4+Pj4gK3sKPj4+ PiArICAgICAgIHN0cnVjdCBoaWJtY19ibyAqaGlibWNibyA9IGdlbV90b19oaWJtY19ibyhvYmop Owo+Pj4+ICsKPj4+PiArICAgICAgIGhpYm1jX2JvX3VucmVmKCZoaWJtY2JvKTsKPj4+PiArfQo+ Pj4+ICsKPj4+PiArc3RhdGljIHU2NCBoaWJtY19ib19tbWFwX29mZnNldChzdHJ1Y3QgaGlibWNf Ym8gKmJvKQo+Pj4+ICt7Cj4+Pj4gKyAgICAgICByZXR1cm4gZHJtX3ZtYV9ub2RlX29mZnNldF9h ZGRyKCZiby0+Ym8udm1hX25vZGUpOwo+Pj4+ICt9Cj4+Pj4gKwo+Pj4+ICtpbnQgaGlibWNfZHVt Yl9tbWFwX29mZnNldChzdHJ1Y3QgZHJtX2ZpbGUgKmZpbGUsIHN0cnVjdCBkcm1fZGV2aWNlCj4+ Pj4gKmRldiwKPj4+PiArICAgICAgICAgICAgICAgICAgICAgICAgICB1MzIgaGFuZGxlLCB1NjQg Km9mZnNldCkKPj4+PiArewo+Pj4+ICsgICAgICAgc3RydWN0IGRybV9nZW1fb2JqZWN0ICpvYmo7 Cj4+Pj4gKyAgICAgICBzdHJ1Y3QgaGlibWNfYm8gKmJvOwo+Pj4+ICsKPj4+PiArICAgICAgIG9i aiA9IGRybV9nZW1fb2JqZWN0X2xvb2t1cChmaWxlLCBoYW5kbGUpOwo+Pj4+ICsgICAgICAgaWYg KCFvYmopCj4+Pj4gKyAgICAgICAgICAgICAgIHJldHVybiAtRU5PRU5UOwo+Pj4+ICsKPj4+PiAr ICAgICAgIGJvID0gZ2VtX3RvX2hpYm1jX2JvKG9iaik7Cj4+Pj4gKyAgICAgICAqb2Zmc2V0ID0g aGlibWNfYm9fbW1hcF9vZmZzZXQoYm8pOwo+Pj4+ICsKPj4+PiArICAgICAgIGRybV9nZW1fb2Jq ZWN0X3VucmVmZXJlbmNlX3VubG9ja2VkKG9iaik7Cj4+Pj4gKyAgICAgICByZXR1cm4gMDsKPj4+ PiArfQo+Pgo+Pgo+PiBSZWdhcmRzLAo+PiBSb25ncm9uZy4KPj4KPj4+PiAtLQo+Pj4+IDEuOS4x Cj4+Pj4KPj4+Pgo+Pj4+IF9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fCj4+Pj4gbGludXgtYXJtLWtlcm5lbCBtYWlsaW5nIGxpc3QKPj4+PiBsaW51eC1hcm0t a2VybmVsQGxpc3RzLmluZnJhZGVhZC5vcmcKPj4+PiBodHRwOi8vbGlzdHMuaW5mcmFkZWFkLm9y Zy9tYWlsbWFuL2xpc3RpbmZvL2xpbnV4LWFybS1rZXJuZWwKPj4+Cj4+PiBfX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwo+Pj4gbGludXhhcm0gbWFpbGluZyBs aXN0Cj4+PiBsaW51eGFybUBodWF3ZWkuY29tCj4+PiBodHRwOi8vcm5kLW9wZW5ldWxlci5odWF3 ZWkuY29tL21haWxtYW4vbGlzdGluZm8vbGludXhhcm0KPj4+Cj4+PiAuCj4+Pgo+Pgo+Pgo+PiBf X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwo+PiBsaW51eC1h cm0ta2VybmVsIG1haWxpbmcgbGlzdAo+PiBsaW51eC1hcm0ta2VybmVsQGxpc3RzLmluZnJhZGVh ZC5vcmcKPj4gaHR0cDovL2xpc3RzLmluZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0aW5mby9saW51 eC1hcm0ta2VybmVsCj4KPiAuCj4KCgotLSAKUmVnYXJkcywgUm9uZ3JvbmcKCl9fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmxpbnV4LWFybS1rZXJuZWwgbWFp bGluZyBsaXN0CmxpbnV4LWFybS1rZXJuZWxAbGlzdHMuaW5mcmFkZWFkLm9yZwpodHRwOi8vbGlz dHMuaW5mcmFkZWFkLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2xpbnV4LWFybS1rZXJuZWwK